These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / unisys / include / iochannel.h
1 /* Copyright (C) 2010 - 2013 UNISYS CORPORATION */
2 /* All rights reserved. */
3 #ifndef __IOCHANNEL_H__
4 #define __IOCHANNEL_H__
5
6 /*
7  * Everything needed for IOPart-GuestPart communication is define in
8  * this file.  Note: Everything is OS-independent because this file is
9  * used by Windows, Linux and possible EFI drivers.  */
10
11 /*
12  * Communication flow between the IOPart and GuestPart uses the channel headers
13  * channel state.  The following states are currently being used:
14  *       UNINIT(All Zeroes), CHANNEL_ATTACHING, CHANNEL_ATTACHED, CHANNEL_OPENED
15  *
16  * additional states will be used later.  No locking is needed to switch between
17  * states due to the following rules:
18  *
19  *      1.  IOPart is only the only partition allowed to change from UNIT
20  *      2.  IOPart is only the only partition allowed to change from
21  *              CHANNEL_ATTACHING
22  *      3.  GuestPart is only the only partition allowed to change from
23  *              CHANNEL_ATTACHED
24  *
25  * The state changes are the following: IOPart sees the channel is in UNINIT,
26  *        UNINIT -> CHANNEL_ATTACHING (performed only by IOPart)
27  *        CHANNEL_ATTACHING -> CHANNEL_ATTACHED (performed only by IOPart)
28  *        CHANNEL_ATTACHED -> CHANNEL_OPENED (performed only by GuestPart)
29  */
30
31 #include <linux/uuid.h>
32
33 #include <linux/dma-direction.h>
34 #include "channel.h"
35 #include "channel_guid.h"
36
37 #define ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
38 #define ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
39 #define ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE \
40         ULTRA_CHANNEL_PROTOCOL_SIGNATURE
41
42 /* Must increment these whenever you insert or delete fields within this channel
43  * struct.  Also increment whenever you change the meaning of fields within this
44  * channel struct so as to break pre-existing software.  Note that you can
45  * usually add fields to the END of the channel struct withOUT needing to
46  * increment this.
47  */
48 #define ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID 2
49 #define ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID 2
50 #define ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID 1
51
52 #define SPAR_VHBA_CHANNEL_OK_CLIENT(ch)                 \
53         (spar_check_channel_client(ch, spar_vhba_channel_protocol_uuid, \
54                                    "vhba", MIN_IO_CHANNEL_SIZE, \
55                                    ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \
56                                    ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE))
57
58 #define SPAR_VNIC_CHANNEL_OK_CLIENT(ch)                 \
59         (spar_check_channel_client(ch, spar_vnic_channel_protocol_uuid, \
60                                    "vnic", MIN_IO_CHANNEL_SIZE, \
61                                    ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \
62                                    ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE))
63
64 /*
65  * Everything necessary to handle SCSI & NIC traffic between Guest Partition and
66  * IO Partition is defined below.
67  */
68
69 /*
70  * Defines and enums.
71  */
72
73 #define MINNUM(a, b) (((a) < (b)) ? (a) : (b))
74 #define MAXNUM(a, b) (((a) > (b)) ? (a) : (b))
75
76 /* these define the two queues per data channel between iopart and
77  * ioguestparts
78  */
79 #define IOCHAN_TO_IOPART 0 /* used by ioguestpart to 'insert' signals to
80                             * iopart */
81
82 #define IOCHAN_FROM_IOPART 1 /* used by ioguestpart to 'remove' signals from
83                               * iopart - same queue as previous queue */
84
85 /* size of cdb - i.e., scsi cmnd */
86 #define MAX_CMND_SIZE 16
87
88 #define MAX_SENSE_SIZE 64
89
90 #define MAX_PHYS_INFO 64
91
92 /* various types of network packets that can be sent in cmdrsp */
93 enum net_types {
94         NET_RCV_POST = 0,       /* submit buffer to hold receiving
95                                  * incoming packet */
96         /* virtnic -> uisnic */
97         NET_RCV,                /* incoming packet received */
98         /* uisnic -> virtpci */
99         NET_XMIT,               /* for outgoing net packets      */
100         /* virtnic -> uisnic */
101         NET_XMIT_DONE,          /* outgoing packet xmitted */
102         /* uisnic -> virtpci */
103         NET_RCV_ENBDIS,         /* enable/disable packet reception */
104         /* virtnic -> uisnic */
105         NET_RCV_ENBDIS_ACK,     /* acknowledge enable/disable packet
106                                  * reception */
107         /* uisnic -> virtnic */
108         NET_RCV_PROMISC,        /* enable/disable promiscuous mode */
109         /* virtnic -> uisnic */
110         NET_CONNECT_STATUS,     /* indicate the loss or restoration of a network
111                                  * connection */
112         /* uisnic -> virtnic */
113         NET_MACADDR,            /* indicates the client has requested to update
114                                  * its MAC addr */
115         NET_MACADDR_ACK,        /* MAC address */
116
117 };
118
119 #define         ETH_HEADER_SIZE 14      /* size of ethernet header */
120
121 #define         ETH_MIN_DATA_SIZE 46    /* minimum eth data size */
122 #define         ETH_MIN_PACKET_SIZE (ETH_HEADER_SIZE + ETH_MIN_DATA_SIZE)
123
124 #define         ETH_MAX_MTU 16384       /* maximum data size */
125
126 #ifndef MAX_MACADDR_LEN
127 #define MAX_MACADDR_LEN 6       /* number of bytes in MAC address */
128 #endif                          /* MAX_MACADDR_LEN */
129
130 /* various types of scsi task mgmt commands  */
131 enum task_mgmt_types {
132         TASK_MGMT_ABORT_TASK = 1,
133         TASK_MGMT_BUS_RESET,
134         TASK_MGMT_LUN_RESET,
135         TASK_MGMT_TARGET_RESET,
136 };
137
138 /* various types of vdisk mgmt commands  */
139 enum vdisk_mgmt_types {
140         VDISK_MGMT_ACQUIRE = 1,
141         VDISK_MGMT_RELEASE,
142 };
143
144 struct phys_info {
145         u64 pi_pfn;
146         u16 pi_off;
147         u16 pi_len;
148 } __packed;
149
150 #define MIN_NUMSIGNALS 64
151
152 /* structs with pragma pack  */
153
154 struct guest_phys_info {
155         u64 address;
156         u64 length;
157 } __packed;
158
159 #define GPI_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct guest_phys_info))
160
161 struct uisscsi_dest {
162         u32 channel;            /* channel == bus number */
163         u32 id;                 /* id == target number */
164         u32 lun;                /* lun == logical unit number */
165 } __packed;
166
167 struct vhba_wwnn {
168         u32 wwnn1;
169         u32 wwnn2;
170 } __packed;
171
172 /* WARNING: Values stired in this structure must contain maximum counts (not
173  * maximum values). */
174 struct vhba_config_max {        /* 20 bytes */
175         u32 max_channel;        /* maximum channel for devices attached to this
176                                  * bus */
177         u32 max_id;             /* maximum SCSI ID for devices attached to this
178                                  * bus */
179         u32 max_lun;            /* maximum SCSI LUN for devices attached to this
180                                  * bus */
181         u32 cmd_per_lun;        /* maximum number of outstanding commands per
182                                  * lun that are allowed at one time */
183         u32 max_io_size;        /* maximum io size for devices attached to this
184                                  * bus */
185         /* max io size is often determined by the resource of the hba. e.g */
186         /* max scatter gather list length * page size / sector size */
187 } __packed;
188
189 struct uiscmdrsp_scsi {
190         u64 handle;             /* the handle to the cmd that was received -
191                                  * send it back as is in the rsp packet.  */
192         u8 cmnd[MAX_CMND_SIZE]; /* the cdb for the command */
193         u32 bufflen;            /* length of data to be transferred out or in */
194         u16 guest_phys_entries; /* Number of entries in scatter-gather (sg)
195                                  * list */
196         struct guest_phys_info gpi_list[MAX_PHYS_INFO]; /* physical address
197                                                          * information for each
198                                                          * fragment */
199         enum dma_data_direction  data_dir; /* direction of the data, if any */
200         struct uisscsi_dest vdest;      /* identifies the virtual hba, id,
201                                          * channel, lun to which cmd was sent */
202
203             /* the following fields are needed to queue the rsp back to cmd
204              * originator */
205         int linuxstat;          /* the original Linux status - for use by linux
206                                  * vdisk code */
207         u8 scsistat;            /* the scsi status */
208         u8 addlstat;            /* non-scsi status - covers cases like timeout
209                                  * needed by windows guests */
210 #define ADDL_SEL_TIMEOUT        4
211
212         /* the following fields are need to determine the result of command */
213          u8 sensebuf[MAX_SENSE_SIZE];   /* sense info in case cmd failed; */
214         /* it holds the sense_data struct; */
215         /* see that struct for details. */
216         void *vdisk; /* contains pointer to the vdisk so that we can clean up
217                       * when the IO completes. */
218         int no_disk_result;
219         /* used to return no disk inquiry result
220          * when no_disk_result is set to 1,
221          * scsi.scsistat is SAM_STAT_GOOD
222          * scsi.addlstat is 0
223          * scsi.linuxstat is SAM_STAT_GOOD
224          * That is, there is NO error.
225          */
226 } __packed;
227
228 /* Defines to support sending correct inquiry result when no disk is
229  * configured.
230  */
231
232 /* From SCSI SPC2 -
233  *
234  * If the target is not capable of supporting a device on this logical unit, the
235  * device server shall set this field to 7Fh (PERIPHERAL QUALIFIER set to 011b
236  * and PERIPHERAL DEVICE TYPE set to 1Fh).
237  *
238  *The device server is capable of supporting the specified peripheral device
239  *type on this logical unit. However, the physical device is not currently
240  *connected to this logical unit.
241  */
242
243 #define DEV_NOT_CAPABLE 0x7f    /* peripheral qualifier of 0x3  */
244                                 /* peripheral type of 0x1f */
245                                 /* specifies no device but target present */
246
247 #define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 /* peripheral qualifier of 0x1 */
248     /* peripheral type of 0 - disk */
249     /* specifies device capable, but not present */
250
251 #define DEV_HISUPPORT 0x10      /* HiSup = 1; shows support for report luns */
252                                 /* must be returned for lun 0. */
253
254 /* NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length
255  * in buf[4] some linux code accesses bytes beyond 5 to retrieve vendor, product
256  * & revision.  Yikes! So let us always send back 36 bytes, the minimum for
257  * inquiry result.
258  */
259 #define NO_DISK_INQUIRY_RESULT_LEN 36
260
261 #define MIN_INQUIRY_RESULT_LEN 5 /* we need at least 5 bytes minimum for inquiry
262                                   * result */
263
264 /* SCSI device version for no disk inquiry result */
265 #define SCSI_SPC2_VER 4         /* indicates SCSI SPC2 (SPC3 is 5) */
266
267 /* Windows and Linux want different things for a non-existent lun. So, we'll let
268  * caller pass in the peripheral qualifier and type.
269  * NOTE:[4] SCSI returns (n-4); so we return length-1-4 or length-5. */
270
271 #define SET_NO_DISK_INQUIRY_RESULT(buf, len, lun, lun0notpresent, notpresent) \
272         do {                                                            \
273                 memset(buf, 0,                                          \
274                        MINNUM(len,                                      \
275                               (unsigned int)NO_DISK_INQUIRY_RESULT_LEN)); \
276                 buf[2] = (u8)SCSI_SPC2_VER;                             \
277                 if (lun == 0) {                                         \
278                         buf[0] = (u8)lun0notpresent;                    \
279                         buf[3] = (u8)DEV_HISUPPORT;                     \
280                 } else                                                  \
281                         buf[0] = (u8)notpresent;                        \
282                 buf[4] = (u8)(                                          \
283                         MINNUM(len,                                     \
284                                (unsigned int)NO_DISK_INQUIRY_RESULT_LEN) - 5);\
285                 if (len >= NO_DISK_INQUIRY_RESULT_LEN) {                \
286                         buf[8] = 'D';                                   \
287                         buf[9] = 'E';                                   \
288                         buf[10] = 'L';                                  \
289                         buf[11] = 'L';                                  \
290                         buf[16] = 'P';                                  \
291                         buf[17] = 'S';                                  \
292                         buf[18] = 'E';                                  \
293                         buf[19] = 'U';                                  \
294                         buf[20] = 'D';                                  \
295                         buf[21] = 'O';                                  \
296                         buf[22] = ' ';                                  \
297                         buf[23] = 'D';                                  \
298                         buf[24] = 'E';                                  \
299                         buf[25] = 'V';                                  \
300                         buf[26] = 'I';                                  \
301                         buf[27] = 'C';                                  \
302                         buf[28] = 'E';                                  \
303                         buf[30] = ' ';                                  \
304                         buf[31] = '.';                                  \
305                 }                                                       \
306         } while (0)
307
308 /*
309  * Struct & Defines to support sense information.
310  */
311
312 /* The following struct is returned in sensebuf field in uiscmdrsp_scsi.  It is
313  * initialized in exactly the manner that is recommended in Windows (hence the
314  * odd values).
315  * When set, these fields will have the following values:
316  * ErrorCode = 0x70             indicates current error
317  * Valid = 1                    indicates sense info is valid
318  * SenseKey                     contains sense key as defined by SCSI specs.
319  * AdditionalSenseCode          contains sense key as defined by SCSI specs.
320  * AdditionalSenseCodeQualifier contains qualifier to sense code as defined by
321  *                              scsi docs.
322  * AdditionalSenseLength        contains will be sizeof(sense_data)-8=10.
323  */
324 struct sense_data {
325         u8 errorcode:7;
326         u8 valid:1;
327         u8 segment_number;
328         u8 sense_key:4;
329         u8 reserved:1;
330         u8 incorrect_length:1;
331         u8 end_of_media:1;
332         u8 file_mark:1;
333         u8 information[4];
334         u8 additional_sense_length;
335         u8 command_specific_information[4];
336         u8 additional_sense_code;
337         u8 additional_sense_code_qualifier;
338         u8 fru_code;
339         u8 sense_key_specific[3];
340 } __packed;
341
342 struct net_pkt_xmt {
343         int len;        /* full length of data in the packet */
344         int num_frags;  /* number of fragments in frags containing data */
345         struct phys_info frags[MAX_PHYS_INFO];  /* physical page information for
346                                                  * each fragment */
347         char ethhdr[ETH_HEADER_SIZE];   /* the ethernet header  */
348         struct {
349                     /* these are needed for csum at uisnic end */
350                 u8 valid;       /* 1 = rest of this struct is valid - else
351                                  * ignore */
352                 u8 hrawoffv;    /* 1 = hwrafoff is valid */
353                 u8 nhrawoffv;   /* 1 = nhwrafoff is valid */
354                 u16 protocol;   /* specifies packet protocol */
355                 u32 csum;       /* value used to set skb->csum at IOPart */
356                 u32 hrawoff;    /* value used to set skb->h.raw at IOPart */
357                 /* hrawoff points to the start of the TRANSPORT LAYER HEADER */
358                 u32 nhrawoff;   /* value used to set skb->nh.raw at IOPart */
359                 /* nhrawoff points to the start of the NETWORK LAYER HEADER */
360         } lincsum;
361
362             /* **** NOTE ****
363              * The full packet is described in frags but the ethernet header is
364              * separately kept in ethhdr so that uisnic doesn't have "MAP" the
365              * guest memory to get to the header. uisnic needs ethhdr to
366              * determine how to route the packet.
367              */
368 } __packed;
369
370 struct net_pkt_xmtdone {
371         u32 xmt_done_result;    /* result of NET_XMIT */
372 } __packed;
373
374 /* RCVPOST_BUF_SIZe must be at most page_size(4096) - cache_line_size (64) The
375  * reason is because dev_skb_alloc which is used to generate RCV_POST skbs in
376  * virtnic requires that there is "overhead" in the buffer, and pads 16 bytes. I
377  * prefer to use 1 full cache line size for "overhead" so that transfers are
378  * better.  IOVM requires that a buffer be represented by 1 phys_info structure
379  * which can only cover page_size.
380  */
381 #define RCVPOST_BUF_SIZE 4032
382 #define MAX_NET_RCV_CHAIN \
383         ((ETH_MAX_MTU+ETH_HEADER_SIZE + RCVPOST_BUF_SIZE-1) / RCVPOST_BUF_SIZE)
384
385 struct net_pkt_rcvpost {
386             /* rcv buf size must be large enough to include ethernet data len +
387              * ethernet header len - we are choosing 2K because it is guaranteed
388              * to be describable */
389             struct phys_info frag;      /* physical page information for the
390                                          * single fragment 2K rcv buf */
391             u64 unique_num;             /* This is used to make sure that
392                                          * receive posts are returned to  */
393             /* the Adapter which we sent them originally. */
394 } __packed;
395
396 struct net_pkt_rcv {
397         /* the number of receive buffers that can be chained  */
398         /* is based on max mtu and size of each rcv buf */
399         u32 rcv_done_len;       /* length of received data */
400         u8 numrcvbufs;          /* number of receive buffers that contain the */
401         /* incoming data; guest end MUST chain these together. */
402         void *rcvbuf[MAX_NET_RCV_CHAIN];        /* the list of receive buffers
403                                                  * that must be chained; */
404         /* each entry is a receive buffer provided by NET_RCV_POST. */
405         /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */
406         u64 unique_num;
407         u32 rcvs_dropped_delta;
408 } __packed;
409
410 struct net_pkt_enbdis {
411         void *context;
412         u16 enable;             /* 1 = enable, 0 = disable */
413 } __packed;
414
415 struct net_pkt_macaddr {
416         void *context;
417         u8 macaddr[MAX_MACADDR_LEN];    /* 6 bytes */
418 } __packed;
419
420 /* cmd rsp packet used for VNIC network traffic  */
421 struct uiscmdrsp_net {
422         enum net_types type;
423         void *buf;
424         union {
425                 struct net_pkt_xmt xmt;         /* used for NET_XMIT */
426                 struct net_pkt_xmtdone xmtdone; /* used for NET_XMIT_DONE */
427                 struct net_pkt_rcvpost rcvpost; /* used for NET_RCV_POST */
428                 struct net_pkt_rcv rcv;         /* used for NET_RCV */
429                 struct net_pkt_enbdis enbdis;   /* used for NET_RCV_ENBDIS, */
430                                                 /* NET_RCV_ENBDIS_ACK,  */
431                                                 /* NET_RCV_PROMSIC, */
432                                                 /* and NET_CONNECT_STATUS */
433                 struct net_pkt_macaddr macaddr;
434         };
435 } __packed;
436
437 struct uiscmdrsp_scsitaskmgmt {
438         enum task_mgmt_types tasktype;
439
440             /* the type of task */
441         struct uisscsi_dest vdest;
442
443             /* the vdisk for which this task mgmt is generated */
444         u64 handle;
445
446             /* This is a handle that the guest has saved off for its own use.
447              * Its value is preserved by iopart & returned as is in the task
448              * mgmt rsp.
449              */
450         u64 notify_handle;
451
452            /* For linux guests, this is a pointer to wait_queue_head that a
453             * thread is waiting on to see if the taskmgmt command has completed.
454             * When the rsp is received by guest, the thread receiving the
455             * response uses this to notify the thread waiting for taskmgmt
456             * command completion.  Its value is preserved by iopart & returned
457             * as is in the task mgmt rsp.
458             */
459         u64 notifyresult_handle;
460
461             /* this is a handle to location in guest where the result of the
462              * taskmgmt command (result field) is to saved off when the response
463              * is handled.  Its value is preserved by iopart & returned as is in
464              * the task mgmt rsp.
465              */
466         char result;
467
468             /* result of taskmgmt command - set by IOPart - values are: */
469 #define TASK_MGMT_FAILED  0
470 } __packed;
471
472 /* The following is used by uissd to send disk add/remove notifications to
473  * Guest */
474 /* Note that the vHba pointer is not used by the Client/Guest side. */
475 struct uiscmdrsp_disknotify {
476         u8 add;                 /* 0-remove, 1-add */
477         void *v_hba;            /* Pointer to vhba_info for channel info to
478                                  * route msg */
479         u32 channel, id, lun;   /* SCSI Path of Disk to added or removed */
480 } __packed;
481
482 /* The following is used by virthba/vSCSI to send the Acquire/Release commands
483  * to the IOVM. */
484 struct uiscmdrsp_vdiskmgmt {
485         enum vdisk_mgmt_types vdisktype;
486
487             /* the type of task */
488         struct uisscsi_dest vdest;
489
490             /* the vdisk for which this task mgmt is generated */
491         u64 handle;
492
493             /* This is a handle that the guest has saved off for its own use.
494              * Its value is preserved by iopart & returned as is in the task
495              * mgmt rsp.
496              */
497         u64 notify_handle;
498
499             /* For linux guests, this is a pointer to wait_queue_head that a
500              * thread is waiting on to see if the tskmgmt command has completed.
501              * When the rsp is received by guest, the thread receiving the
502              * response uses this to notify the thread waiting for taskmgmt
503              * command completion.  Its value is preserved by iopart & returned
504              * as is in the task mgmt rsp.
505              */
506         u64 notifyresult_handle;
507
508             /* this is a handle to location in guest where the result of the
509              * taskmgmt command (result field) is to saved off when the response
510              * is handled.  Its value is preserved by iopart & returned as is in
511              * the task mgmt rsp.
512              */
513         char result;
514
515             /* result of taskmgmt command - set by IOPart - values are: */
516 #define VDISK_MGMT_FAILED  0
517 } __packed;
518
519 /* keeping cmd & rsp info in one structure for now cmd rsp packet for scsi */
520 struct uiscmdrsp {
521         char cmdtype;
522
523 /* describes what type of information is in the struct */
524 #define CMD_SCSI_TYPE           1
525 #define CMD_NET_TYPE            2
526 #define CMD_SCSITASKMGMT_TYPE   3
527 #define CMD_NOTIFYGUEST_TYPE    4
528 #define CMD_VDISKMGMT_TYPE      5
529         union {
530                 struct uiscmdrsp_scsi scsi;
531                 struct uiscmdrsp_net net;
532                 struct uiscmdrsp_scsitaskmgmt scsitaskmgmt;
533                 struct uiscmdrsp_disknotify disknotify;
534                 struct uiscmdrsp_vdiskmgmt vdiskmgmt;
535         };
536         void *private_data;     /* used to send the response when the cmd is
537                                  * done (scsi & scsittaskmgmt). */
538         struct uiscmdrsp *next; /* General Purpose Queue Link */
539         struct uiscmdrsp *activeQ_next; /* Used to track active commands */
540         struct uiscmdrsp *activeQ_prev; /* Used to track active commands */
541 } __packed;
542
543 struct iochannel_vhba {
544         struct vhba_wwnn wwnn;          /* 8 bytes */
545         struct vhba_config_max max;     /* 20 bytes */
546 } __packed;                             /* total = 28 bytes */
547 struct iochannel_vnic {
548         u8 macaddr[6];                  /* 6 bytes */
549         u32 num_rcv_bufs;               /* 4 bytes */
550         u32 mtu;                        /* 4 bytes */
551         uuid_le zone_uuid;              /* 16 bytes */
552 } __packed;
553 /* This is just the header of the IO channel.  It is assumed that directly after
554  * this header there is a large region of memory which contains the command and
555  * response queues as specified in cmd_q and rsp_q SIGNAL_QUEUE_HEADERS.
556  */
557 struct spar_io_channel_protocol {
558         struct channel_header channel_header;
559         struct signal_queue_header cmd_q;
560         struct signal_queue_header rsp_q;
561         union {
562                 struct iochannel_vhba vhba;
563                 struct iochannel_vnic vnic;
564         } __packed;
565
566 #define MAX_CLIENTSTRING_LEN 1024
567          u8 client_string[MAX_CLIENTSTRING_LEN];/* NULL terminated - so holds
568                                                  * max - 1 bytes */
569 } __packed;
570
571
572 /*
573  * INLINE functions for initializing and accessing I/O data channels
574  */
575
576 #define SIZEOF_PROTOCOL (COVER(sizeof(struct spar_io_channel_protocol), 64))
577 #define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64))
578
579 #define MIN_IO_CHANNEL_SIZE COVER(SIZEOF_PROTOCOL + \
580                                   2 * MIN_NUMSIGNALS * SIZEOF_CMDRSP, 4096)
581
582 /*
583  * INLINE function for expanding a guest's pfn-off-size into multiple 4K page
584  * pfn-off-size entires.
585  */
586
587 /* we deal with 4K page sizes when we it comes to passing page information
588  * between */
589 /* Guest and IOPartition. */
590 #define PI_PAGE_SIZE  0x1000
591 #define PI_PAGE_MASK  0x0FFF
592
593 /* returns next non-zero index on success or zero on failure (i.e. out of
594  * room)
595  */
596 static inline  u16
597 add_physinfo_entries(u32 inp_pfn,       /* input - specifies the pfn to be used
598                                          * to add entries */
599                      u16 inp_off,       /* input - specifies the off to be used
600                                          * to add entries */
601                      u32 inp_len,       /* input - specifies the len to be used
602                                          * to add entries */
603                      u16 index,         /* input - index in array at which new
604                                          * entries are added */
605                      u16 max_pi_arr_entries,    /* input - specifies the maximum
606                                                  * entries pi_arr can hold */
607                      struct phys_info pi_arr[]) /* input & output - array to
608                                                   * which entries are added */
609 {
610         u32 len;
611         u16 i, firstlen;
612
613         firstlen = PI_PAGE_SIZE - inp_off;
614         if (inp_len <= firstlen) {
615                 /* the input entry spans only one page - add as is */
616                 if (index >= max_pi_arr_entries)
617                         return 0;
618                 pi_arr[index].pi_pfn = inp_pfn;
619                 pi_arr[index].pi_off = (u16)inp_off;
620                 pi_arr[index].pi_len = (u16)inp_len;
621                     return index + 1;
622         }
623
624             /* this entry spans multiple pages */
625             for (len = inp_len, i = 0; len;
626                  len -= pi_arr[index + i].pi_len, i++) {
627                 if (index + i >= max_pi_arr_entries)
628                         return 0;
629                 pi_arr[index + i].pi_pfn = inp_pfn + i;
630                 if (i == 0) {
631                         pi_arr[index].pi_off = inp_off;
632                         pi_arr[index].pi_len = firstlen;
633                 }
634
635                 else {
636                         pi_arr[index + i].pi_off = 0;
637                         pi_arr[index + i].pi_len =
638                             (u16)MINNUM(len, (u32)PI_PAGE_SIZE);
639                 }
640         }
641         return index + i;
642 }
643
644 #endif                          /* __IOCHANNEL_H__ */