1 /* Copyright © 2010 - 2013 UNISYS CORPORATION */
2 /* All rights reserved. */
3 #ifndef __IOCHANNEL_H__
4 #define __IOCHANNEL_H__
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. */
13 * Communication flow between the IOPart and GuestPart uses the channel headers
14 * channel state. The following states are currently being used:
15 * UNINIT(All Zeroes), CHANNEL_ATTACHING, CHANNEL_ATTACHED, CHANNEL_OPENED
17 * additional states will be used later. No locking is needed to switch between
18 * states due to the following rules:
20 * 1. IOPart is only the only partition allowed to change from UNIT
21 * 2. IOPart is only the only partition allowed to change from
23 * 3. GuestPart is only the only partition allowed to change from
26 * The state changes are the following: IOPart sees the channel is in UNINIT,
27 * UNINIT -> CHANNEL_ATTACHING (performed only by IOPart)
28 * CHANNEL_ATTACHING -> CHANNEL_ATTACHED (performed only by IOPart)
29 * CHANNEL_ATTACHED -> CHANNEL_OPENED (performed only by GuestPart)
32 #include "commontypes.h"
33 #include "vmcallinterface.h"
35 #define _ULTRA_CONTROLVM_CHANNEL_INLINE_
36 #include "controlvmchannel.h"
37 #include "vbuschannel.h"
38 #undef _ULTRA_CONTROLVM_CHANNEL_INLINE_
45 #include "channel_guid.h"
47 #define ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
48 #define ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
49 #define ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE \
50 ULTRA_CHANNEL_PROTOCOL_SIGNATURE
52 /* Must increment these whenever you insert or delete fields within this channel
53 * struct. Also increment whenever you change the meaning of fields within this
54 * channel struct so as to break pre-existing software. Note that you can
55 * usually add fields to the END of the channel struct withOUT needing to
57 #define ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID 2
58 #define ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID 2
59 #define ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID 1
61 #define ULTRA_VHBA_CHANNEL_OK_CLIENT(pChannel, logCtx) \
62 (ULTRA_check_channel_client(pChannel, UltraVhbaChannelProtocolGuid, \
63 "vhba", MIN_IO_CHANNEL_SIZE, \
64 ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \
65 ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE, \
66 __FILE__, __LINE__, logCtx))
67 #define ULTRA_VHBA_CHANNEL_OK_SERVER(actualBytes, logCtx) \
68 (ULTRA_check_channel_server(UltraVhbaChannelProtocolGuid, \
69 "vhba", MIN_IO_CHANNEL_SIZE, actualBytes, \
70 __FILE__, __LINE__, logCtx))
71 #define ULTRA_VNIC_CHANNEL_OK_CLIENT(pChannel, logCtx) \
72 (ULTRA_check_channel_client(pChannel, UltraVnicChannelProtocolGuid, \
73 "vnic", MIN_IO_CHANNEL_SIZE, \
74 ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \
75 ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE, \
76 __FILE__, __LINE__, logCtx))
77 #define ULTRA_VNIC_CHANNEL_OK_SERVER(actualBytes, logCtx) \
78 (ULTRA_check_channel_server(UltraVnicChannelProtocolGuid, \
79 "vnic", MIN_IO_CHANNEL_SIZE, actualBytes, \
80 __FILE__, __LINE__, logCtx))
81 #define ULTRA_VSWITCH_CHANNEL_OK_CLIENT(pChannel, logCtx) \
82 (ULTRA_check_channel_client(pChannel, UltraVswitchChannelProtocolGuid, \
83 "vswitch", MIN_IO_CHANNEL_SIZE, \
84 ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID, \
85 ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE, \
86 __FILE__, __LINE__, logCtx))
87 #define ULTRA_VSWITCH_CHANNEL_OK_SERVER(actualBytes, logCtx) \
88 (ULTRA_check_channel_server(UltraVswitchChannelProtocolGuid, \
89 "vswitch", MIN_IO_CHANNEL_SIZE, \
91 __FILE__, __LINE__, logCtx))
93 * Everything necessary to handle SCSI & NIC traffic between Guest Partition and
94 * IO Partition is defined below. */
101 #define MINNUM(a, b) (((a) < (b)) ? (a) : (b))
102 #define MAXNUM(a, b) (((a) > (b)) ? (a) : (b))
104 /* these define the two queues per data channel between iopart and
106 #define IOCHAN_TO_IOPART 0 /* used by ioguestpart to 'insert' signals to
108 #define IOCHAN_FROM_GUESTPART 0 /* used by iopart to 'remove' signals from
109 * ioguestpart - same queue as previous queue */
111 #define IOCHAN_TO_GUESTPART 1 /* used by iopart to 'insert' signals to
113 #define IOCHAN_FROM_IOPART 1 /* used by ioguestpart to 'remove' signals from
114 * iopart - same queue as previous queue */
116 /* these define the two queues per control channel between controlpart and "its"
117 * guests, which includes the iopart */
118 #define CTRLCHAN_TO_CTRLGUESTPART 0 /* used by ctrlguestpart to 'insert' signals
120 #define CTLRCHAN_FROM_CTRLPART 0 /* used by ctrlpart to 'remove' signals from
121 * ctrlquestpart - same queue as previous
124 #define CTRLCHAN_TO_CTRLPART 1 /* used by ctrlpart to 'insert' signals to
126 #define CTRLCHAN_FROM_CTRLGUESTPART 1 /* used by ctrguestpart to 'remove'
127 * signals from ctrlpart - same queue as
130 /* these define the Event & Ack queues per control channel Events are generated
131 * by CTRLGUESTPART and sent to CTRLPART; Acks are generated by CTRLPART and sent
132 * to CTRLGUESTPART. */
133 #define CTRLCHAN_EVENT_TO_CTRLPART 2 /* used by ctrlguestpart to 'insert' Events
135 #define CTRLCHAN_EVENT_FROM_CTRLGUESTPART 2 /* used by ctrlpart to 'remove'
136 * Events from ctrlguestpart */
138 #define CTRLCHAN_ACK_TO_CTRLGUESTPART 3 /* used by ctrlpart to 'insert' Acks to
140 #define CTRLCHAN_ACK_FROM_CTRLPART 3 /* used by ctrlguestpart to 'remove' Events
143 /* size of cdb - i.e., scsi cmnd */
144 #define MAX_CMND_SIZE 16
152 #define MAX_SENSE_SIZE 64
154 #define MAX_PHYS_INFO 64
156 /* Because GuestToGuestCopy is limited to 4KiB segments, and we have limited the
157 * Emulex Driver to 256 scatter list segments via the lpfc_sg_seg_cnt parameter
158 * to 256, the maximum I/O size is limited to 256 * 4 KiB = 1 MB */
159 #define MAX_IO_SIZE (1024*1024) /* 1 MB */
161 /* NOTE 1: lpfc defines its support for segments in
162 * #define LPFC_SG_SEG_CNT 64
164 * NOTE 2: In Linux, frags array in skb is currently allocated to be
165 * MAX_SKB_FRAGS size, which is 18 which is smaller than MAX_PHYS_INFO for
168 #ifndef MAX_SERIAL_NUM
169 #define MAX_SERIAL_NUM 32
170 #endif /* MAX_SERIAL_NUM */
172 #define MAX_SCSI_BUSES 1
173 #define MAX_SCSI_TARGETS 8
174 #define MAX_SCSI_LUNS 16
175 #define MAX_SCSI_FROM_HOST 0xFFFFFFFF /* Indicator to use Physical HBA
178 /* various types of network packets that can be sent in cmdrsp */
179 typedef enum { NET_RCV_POST
= 0, /* submit buffer to hold receiving
181 /* virtnic -> uisnic */
182 NET_RCV
, /* incoming packet received */
183 /* uisnic -> virtpci */
184 NET_XMIT
, /* for outgoing net packets */
185 /* virtnic -> uisnic */
186 NET_XMIT_DONE
, /* outgoing packet xmitted */
187 /* uisnic -> virtpci */
188 NET_RCV_ENBDIS
, /* enable/disable packet reception */
189 /* virtnic -> uisnic */
190 NET_RCV_ENBDIS_ACK
, /* acknowledge enable/disable packet
192 /* uisnic -> virtnic */
193 NET_RCV_PROMISC
, /* enable/disable promiscuous mode */
194 /* virtnic -> uisnic */
195 NET_CONNECT_STATUS
, /* indicate the loss or restoration of a network
197 /* uisnic -> virtnic */
198 NET_MACADDR
, /* indicates the client has requested to update
200 NET_MACADDR_ACK
, /* Mac addres */
204 #define ETH_HEADER_SIZE 14 /* size of ethernet header */
206 #define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */
207 #define ETH_MIN_PACKET_SIZE (ETH_HEADER_SIZE + ETH_MIN_DATA_SIZE)
209 #define ETH_DEF_DATA_SIZE 1500 /* default data size */
210 #define ETH_DEF_PACKET_SIZE (ETH_HEADER_SIZE + ETH_DEF_DATA_SIZE)
212 #define ETH_MAX_MTU 16384 /* maximum data size */
214 #ifndef MAX_MACADDR_LEN
215 #define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */
216 #endif /* MAX_MACADDR_LEN */
218 #define ETH_IS_LOCALLY_ADMINISTERED(Address) \
219 (((U8 *) (Address))[0] & ((U8) 0x02))
220 #define NIC_VENDOR_ID 0x0008000B
222 /* various types of scsi task mgmt commands */
223 typedef enum { TASK_MGMT_ABORT_TASK
=
224 1, TASK_MGMT_BUS_RESET
, TASK_MGMT_LUN_RESET
,
225 TASK_MGMT_TARGET_RESET
,
228 /* various types of vdisk mgmt commands */
229 typedef enum { VDISK_MGMT_ACQUIRE
= 1, VDISK_MGMT_RELEASE
,
232 /* this is used in the vdest field */
233 #define VDEST_ALL 0xFFFF
235 #define MIN_NUMSIGNALS 64
236 #define MAX_NUMSIGNALS 4096
238 /* MAX_NET_RCV_BUF specifies the number of rcv buffers that are created by each
239 * guest's virtnic and posted to uisnic. Uisnic, for each channel, keeps the rcv
240 * buffers posted and uses them to receive data on behalf of the guest's virtnic.
241 * NOTE: the num_rcv_bufs is configurable for each VNIC. So the following is
242 * simply an upperlimit on what each VNIC can provide. Setting it to half of the
243 * NUMSIGNALS to prevent queue full deadlocks */
244 #define MAX_NET_RCV_BUFS (MIN_NUMSIGNALS / 2)
247 * structs with pragma pack */
250 /* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
251 /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
253 #pragma pack(push, 1)
255 struct guest_phys_info
{
260 #define GPI_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct guest_phys_info))
262 struct uisscsi_dest
{
263 U32 channel
; /* channel == bus number */
264 U32 id
; /* id == target number */
265 U32 lun
; /* lun == logical unit number */
273 /* WARNING: Values stired in this structure must contain maximum counts (not
274 * maximum values). */
275 struct vhba_config_max
{ /* 20 bytes */
276 U32 max_channel
; /* maximum channel for devices attached to this
278 U32 max_id
; /* maximum SCSI ID for devices attached to this
280 U32 max_lun
; /* maximum SCSI LUN for devices attached to this
282 U32 cmd_per_lun
; /* maximum number of outstanding commands per
283 * lun that are allowed at one time */
284 U32 max_io_size
; /* maximum io size for devices attached to this
286 /* max io size is often determined by the resource of the hba. e.g */
287 /* max scatter gather list length * page size / sector size */
290 struct uiscmdrsp_scsi
{
291 void *scsicmd
; /* the handle to the cmd that was received -
292 * send it back as is in the rsp packet. */
293 U8 cmnd
[MAX_CMND_SIZE
]; /* the cdb for the command */
294 U32 bufflen
; /* length of data to be transferred out or in */
295 U16 guest_phys_entries
; /* Number of entries in scatter-gather (sg)
297 struct guest_phys_info gpi_list
[MAX_PHYS_INFO
]; /* physical address
298 * information for each
300 enum dma_data_dir data_dir
; /* direction of the data, if any */
301 struct uisscsi_dest vdest
; /* identifies the virtual hba, id,
302 * channel, lun to which cmd was sent */
304 /* the following fields are needed to queue the rsp back to cmd
306 int linuxstat
; /* the original Linux status - for use by linux
308 U8 scsistat
; /* the scsi status */
309 U8 addlstat
; /* non-scsi status - covers cases like timeout
310 * needed by windows guests */
312 #define ADDL_TIMEOUT 2
313 #define ADDL_INTERNAL_ERROR 3
314 #define ADDL_SEL_TIMEOUT 4
315 #define ADDL_CMD_TIMEOUT 5
316 #define ADDL_BAD_TARGET 6
319 /* the following fields are need to determine the result of command */
320 U8 sensebuf
[MAX_SENSE_SIZE
]; /* sense info in case cmd failed; */
321 /* it holds the sense_data struct; */
322 /* see that struct for details. */
323 void *vdisk
; /* contains pointer to the vdisk so that we can clean up
324 * when the IO completes. */
325 int no_disk_result
; /* used to return no disk inquiry result */
326 /* when no_disk_result is set to 1, */
327 /* scsi.scsistat is SAM_STAT_GOOD */
328 /* scsi.addlstat is 0 */
329 /* scsi.linuxstat is SAM_STAT_GOOD */
330 /* That is, there is NO error. */
334 * Defines to support sending correct inquiry result when no disk is
339 * If the target is not capable of supporting a device on this logical unit, the
340 * device server shall set this field to 7Fh (PERIPHERAL QUALIFIER set to 011b
341 * and PERIPHERAL DEVICE TYPE set to 1Fh).
343 *The device server is capable of supporting the specified peripheral device
344 *type on this logical unit. However, the physical device is not currently
345 *connected to this logical unit.
348 #define DEV_NOT_PRESENT 0x7f /* old name - compatibility */
349 #define DEV_NOT_CAPABLE 0x7f /* peripheral qualifier of 0x3 */
350 /* peripheral type of 0x1f */
351 /* specifies no device but target present */
353 #define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 /* peripheral qualifier of 0x1 */
354 /* peripheral type of 0 - disk */
355 /* specifies device capable, but not present */
357 #define DEV_PROC_CAPABLE_NOT_PRESENT 0x23 /* peripheral qualifier of 0x1 */
358 /* peripheral type of 3 - processor */
359 /* specifies device capable, but not present */
361 #define DEV_HISUPPORT 0x10; /* HiSup = 1; shows support for report luns */
362 /* must be returned for lun 0. */
364 /* NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length
365 * in buf[4] some linux code accesses bytes beyond 5 to retrieve vendor, product
366 * & revision. Yikes! So let us always send back 36 bytes, the minimum for
368 #define NO_DISK_INQUIRY_RESULT_LEN 36
370 #define MIN_INQUIRY_RESULT_LEN 5 /* we need at least 5 bytes minimum for inquiry
373 /* SCSI device version for no disk inquiry result */
374 #define SCSI_SPC2_VER 4 /* indicates SCSI SPC2 (SPC3 is 5) */
376 /* Windows and Linux want different things for a non-existent lun. So, we'll let
377 * caller pass in the peripheral qualifier and type.
378 * NOTE:[4] SCSI returns (n-4); so we return length-1-4 or length-5. */
380 #define SET_NO_DISK_INQUIRY_RESULT(buf, len, lun, lun0notpresent, notpresent) \
384 (unsigned int) NO_DISK_INQUIRY_RESULT_LEN)); \
385 buf[2] = (U8) SCSI_SPC2_VER; \
387 buf[0] = (U8) lun0notpresent; \
388 buf[3] = (U8) DEV_HISUPPORT; \
390 buf[0] = (U8) notpresent; \
393 (unsigned int) NO_DISK_INQUIRY_RESULT_LEN) - 5); \
394 if (len >= NO_DISK_INQUIRY_RESULT_LEN) { \
419 * Struct & Defines to support sense information.
423 /* The following struct is returned in sensebuf field in uiscmdrsp_scsi. It is
424 * initialized in exactly the manner that is recommended in Windows (hence the
426 * When set, these fields will have the following values:
427 * ErrorCode = 0x70 indicates current error
428 * Valid = 1 indicates sense info is valid
429 * SenseKey contains sense key as defined by SCSI specs.
430 * AdditionalSenseCode contains sense key as defined by SCSI specs.
431 * AdditionalSenseCodeQualifier contains qualifier to sense code as defined by
433 * AdditionalSenseLength contains will be sizeof(sense_data)-8=10.
441 U8 IncorrectLength
:1;
445 U8 AdditionalSenseLength
;
446 U8 CommandSpecificInformation
[4];
447 U8 AdditionalSenseCode
;
448 U8 AdditionalSenseCodeQualifier
;
449 U8 FieldReplaceableUnitCode
;
450 U8 SenseKeySpecific
[3];
453 /* some SCSI ADSENSE codes */
454 #ifndef SCSI_ADSENSE_LUN_NOT_READY
455 #define SCSI_ADSENSE_LUN_NOT_READY 0x04
457 #ifndef SCSI_ADSENSE_ILLEGAL_COMMAND
458 #define SCSI_ADSENSE_ILLEGAL_COMMAND 0x20
460 #ifndef SCSI_ADSENSE_ILLEGAL_BLOCK
462 #ifndef SCSI_ADSENSE_ILLEGAL_BLOCK
463 #define SCSI_ADSENSE_ILLEGAL_BLOCK 0x21
465 #ifndef SCSI_ADSENSE_INVALID_CDB
466 #define SCSI_ADSENSE_INVALID_CDB 0x24
468 #ifndef SCSI_ADSENSE_INVALID_LUN
469 #define SCSI_ADSENSE_INVALID_LUN 0x25
471 #ifndef SCSI_ADWRITE_PROTECT
472 #define SCSI_ADWRITE_PROTECT 0x27
474 #ifndef SCSI_ADSENSE_MEDIUM_CHANGED
475 #define SCSI_ADSENSE_MEDIUM_CHANGED 0x28
477 #ifndef SCSI_ADSENSE_BUS_RESET
478 #define SCSI_ADSENSE_BUS_RESET 0x29
480 #ifndef SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
481 #define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE 0x3a
485 int len
; /* full length of data in the packet */
486 int num_frags
; /* number of fragments in frags containing data */
487 struct phys_info frags
[MAX_PHYS_INFO
]; /* physical page information for
489 char ethhdr
[ETH_HEADER_SIZE
]; /* the ethernet header */
492 /* these are needed for csum at uisnic end */
493 U8 valid
; /* 1 = rest of this struct is valid - else
495 U8 hrawoffv
; /* 1 = hwrafoff is valid */
496 U8 nhrawoffv
; /* 1 = nhwrafoff is valid */
497 U16 protocol
; /* specifies packet protocol */
498 U32 csum
; /* value used to set skb->csum at IOPart */
499 U32 hrawoff
; /* value used to set skb->h.raw at IOPart */
500 /* hrawoff points to the start of the TRANSPORT LAYER HEADER */
501 U32 nhrawoff
; /* value used to set skb->nh.raw at IOPart */
502 /* nhrawoff points to the start of the NETWORK LAYER HEADER */
506 * The full packet is described in frags but the ethernet header is
507 * separately kept in ethhdr so that uisnic doesn't have "MAP" the
508 * guest memory to get to the header. uisnic needs ethhdr to
509 * determine how to route the packet.
513 struct net_pkt_xmtdone
{
514 U32 xmt_done_result
; /* result of NET_XMIT */
515 #define XMIT_SUCCESS 0
516 #define XMIT_FAILED 1
519 /* RCVPOST_BUF_SIZe must be at most page_size(4096) - cache_line_size (64) The
520 * reason is because dev_skb_alloc which is used to generate RCV_POST skbs in
521 * virtnic requires that there is "overhead" in the buffer, and pads 16 bytes. I
522 * prefer to use 1 full cache line size for "overhead" so that transfers are
523 * better. IOVM requires that a buffer be represented by 1 phys_info structure
524 * which can only cover page_size. */
525 #define RCVPOST_BUF_SIZE 4032
526 #define MAX_NET_RCV_CHAIN \
527 ((ETH_MAX_MTU+ETH_HEADER_SIZE + RCVPOST_BUF_SIZE-1) / RCVPOST_BUF_SIZE)
529 struct net_pkt_rcvpost
{
530 /* rcv buf size must be large enough to include ethernet data len +
531 * ethernet header len - we are choosing 2K because it is guaranteed
532 * to be describable */
533 struct phys_info frag
; /* physical page information for the
534 * single fragment 2K rcv buf */
535 U64 UniqueNum
; /* This is used to make sure that
536 * receive posts are returned to */
537 /* the Adapter which sent them origonally. */
542 /* the number of receive buffers that can be chained */
543 /* is based on max mtu and size of each rcv buf */
544 U32 rcv_done_len
; /* length of received data */
545 U8 numrcvbufs
; /* number of receive buffers that contain the */
546 /* incoming data; guest end MUST chain these together. */
547 void *rcvbuf
[MAX_NET_RCV_CHAIN
]; /* the list of receive buffers
548 * that must be chained; */
549 /* each entry is a receive buffer provided by NET_RCV_POST. */
550 /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */
552 U32 RcvsDroppedDelta
;
555 struct net_pkt_enbdis
{
557 U16 enable
; /* 1 = enable, 0 = disable */
560 struct net_pkt_macaddr
{
562 U8 macaddr
[MAX_MACADDR_LEN
]; /* 6 bytes */
565 /* cmd rsp packet used for VNIC network traffic */
566 struct uiscmdrsp_net
{
570 struct net_pkt_xmt xmt
; /* used for NET_XMIT */
571 struct net_pkt_xmtdone xmtdone
; /* used for NET_XMIT_DONE */
572 struct net_pkt_rcvpost rcvpost
; /* used for NET_RCV_POST */
573 struct net_pkt_rcv rcv
; /* used for NET_RCV */
574 struct net_pkt_enbdis enbdis
; /* used for NET_RCV_ENBDIS, */
575 /* NET_RCV_ENBDIS_ACK, */
576 /* NET_RCV_PROMSIC, */
577 /* and NET_CONNECT_STATUS */
578 struct net_pkt_macaddr macaddr
;
582 struct uiscmdrsp_scsitaskmgmt
{
583 TASK_MGMT_TYPES tasktype
;
585 /* the type of task */
586 struct uisscsi_dest vdest
;
588 /* the vdisk for which this task mgmt is generated */
591 /* This is some handle that the guest has saved off for its own use.
592 * Its value is preserved by iopart & returned as is in the task mgmt
596 /* For linux guests, this is a pointer to wait_queue_head that a
597 * thread is waiting on to see if the taskmgmt command has completed.
598 * For windows guests, this is a pointer to a location that a waiting
599 * thread is testing to see if the taskmgmt command has completed.
600 * When the rsp is received by guest, the thread receiving the
601 * response uses this to notify the the thread waiting for taskmgmt
602 * command completion. Its value is preserved by iopart & returned
603 * as is in the task mgmt rsp. */
606 /* this is a handle to location in guest where the result of the
607 * taskmgmt command (result field) is to saved off when the response
608 * is handled. Its value is preserved by iopart & returned as is in
609 * the task mgmt rsp. */
612 /* result of taskmgmt command - set by IOPart - values are: */
613 #define TASK_MGMT_FAILED 0
614 #define TASK_MGMT_SUCCESS 1
617 /* The following is used by uissd to send disk add/remove notifications to
619 /* Note that the vHba pointer is not used by the Client/Guest side. */
620 struct uiscmdrsp_disknotify
{
621 U8 add
; /* 0-remove, 1-add */
622 void *vHba
; /* Pointer to vhba_info for channel info to
624 U32 channel
, id
, lun
; /* SCSI Path of Disk to added or removed */
627 /* The following is used by virthba/vSCSI to send the Acquire/Release commands
629 struct uiscmdrsp_vdiskmgmt
{
630 VDISK_MGMT_TYPES vdisktype
;
632 /* the type of task */
633 struct uisscsi_dest vdest
;
635 /* the vdisk for which this task mgmt is generated */
638 /* This is some handle that the guest has saved off for its own use.
639 * Its value is preserved by iopart & returned as is in the task mgmt
643 /* For linux guests, this is a pointer to wait_queue_head that a
644 * thread is waiting on to see if the taskmgmt command has completed.
645 * For windows guests, this is a pointer to a location that a waiting
646 * thread is testing to see if the taskmgmt command has completed.
647 * When the rsp is received by guest, the thread receiving the
648 * response uses this to notify the the thread waiting for taskmgmt
649 * command completion. Its value is preserved by iopart & returned
650 * as is in the task mgmt rsp. */
653 /* this is a handle to location in guest where the result of the
654 * taskmgmt command (result field) is to saved off when the response
655 * is handled. Its value is preserved by iopart & returned as is in
656 * the task mgmt rsp. */
659 /* result of taskmgmt command - set by IOPart - values are: */
660 #define VDISK_MGMT_FAILED 0
661 #define VDISK_MGMT_SUCCESS 1
664 /* keeping cmd & rsp info in one structure for now cmd rsp packet for scsi */
668 /* describes what type of information is in the struct */
669 #define CMD_SCSI_TYPE 1
670 #define CMD_NET_TYPE 2
671 #define CMD_SCSITASKMGMT_TYPE 3
672 #define CMD_NOTIFYGUEST_TYPE 4
673 #define CMD_VDISKMGMT_TYPE 5
675 struct uiscmdrsp_scsi scsi
;
676 struct uiscmdrsp_net net
;
677 struct uiscmdrsp_scsitaskmgmt scsitaskmgmt
;
678 struct uiscmdrsp_disknotify disknotify
;
679 struct uiscmdrsp_vdiskmgmt vdiskmgmt
;
681 void *private_data
; /* used to send the response when the cmd is
682 * done (scsi & scsittaskmgmt). */
683 struct uiscmdrsp
*next
; /* General Purpose Queue Link */
684 struct uiscmdrsp
*activeQ_next
; /* Used to track active commands */
685 struct uiscmdrsp
*activeQ_prev
; /* Used to track active commands */
688 /* This is just the header of the IO channel. It is assumed that directly after
689 * this header there is a large region of memory which contains the command and
690 * response queues as specified in cmdQ and rspQ SIGNAL_QUEUE_HEADERS. */
691 typedef struct _ULTRA_IO_CHANNEL_PROTOCOL
{
692 CHANNEL_HEADER ChannelHeader
;
693 SIGNAL_QUEUE_HEADER cmdQ
;
694 SIGNAL_QUEUE_HEADER rspQ
;
697 struct vhba_wwnn wwnn
; /* 8 bytes */
698 struct vhba_config_max max
; /* 20 bytes */
701 U8 macaddr
[MAX_MACADDR_LEN
]; /* 6 bytes */
702 U32 num_rcv_bufs
; /* 4 */
704 GUID zoneGuid
; /* 16 */
705 } vnic
; /* total 30 */
708 #define MAX_CLIENTSTRING_LEN 1024
709 U8 clientString
[MAX_CLIENTSTRING_LEN
]; /* NULL terminated - so holds
711 } ULTRA_IO_CHANNEL_PROTOCOL
;
714 /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
716 /* define offsets to members of struct uiscmdrsp */
717 #define OFFSET_CMDTYPE OFFSETOF(struct uiscmdrsp, cmdtype)
718 #define OFFSET_SCSI OFFSETOF(struct uiscmdrsp, scsi)
719 #define OFFSET_NET OFFSETOF(struct uiscmdrsp, net)
720 #define OFFSET_SCSITASKMGMT OFFSETOF(struct uiscmdrsp, scsitaskmgmt)
721 #define OFFSET_NEXT OFFSETOF(struct uiscmdrsp, next)
723 /* define offsets to members of struct uiscmdrsp_net */
724 #define OFFSET_TYPE OFFSETOF(struct uiscmdrsp_net, type)
725 #define OFFSET_BUF OFFSETOF(struct uiscmdrsp_net, buf)
726 #define OFFSET_XMT OFFSETOF(struct uiscmdrsp_net, xmt)
727 #define OFFSET_XMT_DONE_RESULT OFFSETOF(struct uiscmdrsp_net, xmtdone)
728 #define OFFSET_RCVPOST OFFSETOF(struct uiscmdrsp_net, rcvpost)
729 #define OFFSET_RCV_DONE_LEN OFFSETOF(struct uiscmdrsp_net, rcv)
730 #define OFFSET_ENBDIS OFFSETOF(struct uiscmdrsp_net, enbdis)
732 /* define offsets to members of struct net_pkt_rcvpost */
733 #define OFFSET_TOTALLEN OFFSETOF(struct net_pkt_rcvpost, totallen)
734 #define OFFSET_FRAG OFFSETOF(struct net_pkt_rcvpost, frag)
737 * INLINE functions for initializing and accessing I/O data channels
741 #define NUMSIGNALS(x, q) (((ULTRA_IO_CHANNEL_PROTOCOL *)(x))->q.MaxSignalSlots)
742 #define SIZEOF_PROTOCOL (COVER(sizeof(ULTRA_IO_CHANNEL_PROTOCOL), 64))
743 #define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64))
745 #define IO_CHANNEL_SIZE(x) COVER(SIZEOF_PROTOCOL + \
746 (NUMSIGNALS(x, cmdQ) + \
747 NUMSIGNALS(x, rspQ)) * SIZEOF_CMDRSP, 4096)
748 #define MIN_IO_CHANNEL_SIZE COVER(SIZEOF_PROTOCOL + \
749 2 * MIN_NUMSIGNALS * SIZEOF_CMDRSP, 4096)
751 /* These defines should only ever be used in service partitons */
752 /* because they rely on the size of uiscmdrsp */
753 #define QSLOTSFROMBYTES(bytes) (((bytes-SIZEOF_PROTOCOL)/2)/SIZEOF_CMDRSP)
754 #define QSIZEFROMBYTES(bytes) (QSLOTSFROMBYTES(bytes)*SIZEOF_CMDRSP)
755 #define SignalQInit(x) \
757 x->cmdQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \
758 x->cmdQ.oSignalBase = SIZEOF_PROTOCOL - \
759 OFFSETOF(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \
760 x->cmdQ.SignalSize = SIZEOF_CMDRSP; \
761 x->cmdQ.MaxSignalSlots = \
762 QSLOTSFROMBYTES(x->ChannelHeader.Size); \
763 x->cmdQ.MaxSignals = x->cmdQ.MaxSignalSlots - 1; \
764 x->rspQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \
765 x->rspQ.oSignalBase = \
766 (SIZEOF_PROTOCOL + x->cmdQ.Size) - \
767 OFFSETOF(ULTRA_IO_CHANNEL_PROTOCOL, rspQ); \
768 x->rspQ.SignalSize = SIZEOF_CMDRSP; \
769 x->rspQ.MaxSignalSlots = \
770 QSLOTSFROMBYTES(x->ChannelHeader.Size); \
771 x->rspQ.MaxSignals = x->rspQ.MaxSignalSlots - 1; \
772 x->ChannelHeader.oChannelSpace = \
773 OFFSETOF(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \
776 #define INIT_CLIENTSTRING(chan, type, clientStr, clientStrLen) \
779 chan->ChannelHeader.oClientString = \
780 OFFSETOF(type, clientString); \
781 MEMCPY(chan->clientString, clientStr, \
782 MINNUM(clientStrLen, \
783 (U32) (MAX_CLIENTSTRING_LEN - 1))); \
784 chan->clientString[MINNUM(clientStrLen, \
785 (U32) (MAX_CLIENTSTRING_LEN \
790 if (clientStrLen > 0) \
795 #define ULTRA_IO_CHANNEL_SERVER_READY(x, chanId, logCtx) \
796 ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, CHANNELSRV_READY, \
799 #define ULTRA_IO_CHANNEL_SERVER_NOTREADY(x, chanId, logCtx) \
800 ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, \
801 CHANNELSRV_UNINITIALIZED, logCtx);
803 static inline int ULTRA_VHBA_init_channel(ULTRA_IO_CHANNEL_PROTOCOL
*x
,
804 struct vhba_wwnn
*wwnn
,
805 struct vhba_config_max
*max
,
806 unsigned char *clientStr
,
807 U32 clientStrLen
, U64 bytes
) {
808 MEMSET(x
, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL
));
809 x
->ChannelHeader
.VersionId
= ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID
;
810 x
->ChannelHeader
.Signature
= ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE
;
811 x
->ChannelHeader
.SrvState
= CHANNELSRV_UNINITIALIZED
;
812 x
->ChannelHeader
.HeaderSize
= sizeof(x
->ChannelHeader
);
813 x
->ChannelHeader
.Size
= COVER(bytes
, 4096);
814 x
->ChannelHeader
.Type
= UltraVhbaChannelProtocolGuid
;
815 x
->ChannelHeader
.ZoneGuid
= Guid0
;
816 x
->vhba
.wwnn
= *wwnn
;
818 INIT_CLIENTSTRING(x
, ULTRA_IO_CHANNEL_PROTOCOL
, clientStr
,
821 if ((x
->cmdQ
.MaxSignalSlots
> MAX_NUMSIGNALS
) ||
822 (x
->rspQ
.MaxSignalSlots
> MAX_NUMSIGNALS
)) {
825 if ((x
->cmdQ
.MaxSignalSlots
< MIN_NUMSIGNALS
) ||
826 (x
->rspQ
.MaxSignalSlots
< MIN_NUMSIGNALS
)) {
832 static inline void ULTRA_VHBA_set_max(ULTRA_IO_CHANNEL_PROTOCOL
*x
,
833 struct vhba_config_max
*max
) {
837 static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL
*x
,
838 unsigned char *macaddr
,
839 U32 num_rcv_bufs
, U32 mtu
,
841 unsigned char *clientStr
,
844 MEMSET(x
, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL
));
845 x
->ChannelHeader
.VersionId
= ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID
;
846 x
->ChannelHeader
.Signature
= ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE
;
847 x
->ChannelHeader
.SrvState
= CHANNELSRV_UNINITIALIZED
;
848 x
->ChannelHeader
.HeaderSize
= sizeof(x
->ChannelHeader
);
849 x
->ChannelHeader
.Size
= COVER(bytes
, 4096);
850 x
->ChannelHeader
.Type
= UltraVnicChannelProtocolGuid
;
851 x
->ChannelHeader
.ZoneGuid
= Guid0
;
852 MEMCPY(x
->vnic
.macaddr
, macaddr
, MAX_MACADDR_LEN
);
853 x
->vnic
.num_rcv_bufs
= num_rcv_bufs
;
855 x
->vnic
.zoneGuid
= zoneGuid
;
856 INIT_CLIENTSTRING(x
, ULTRA_IO_CHANNEL_PROTOCOL
, clientStr
,
859 if ((x
->cmdQ
.MaxSignalSlots
> MAX_NUMSIGNALS
) ||
860 (x
->rspQ
.MaxSignalSlots
> MAX_NUMSIGNALS
)) {
863 if ((x
->cmdQ
.MaxSignalSlots
< MIN_NUMSIGNALS
) ||
864 (x
->rspQ
.MaxSignalSlots
< MIN_NUMSIGNALS
)) {
870 #endif /* __GNUC__ */
873 * INLINE function for expanding a guest's pfn-off-size into multiple 4K page
874 * pfn-off-size entires.
878 /* we deal with 4K page sizes when we it comes to passing page information
880 /* Guest and IOPartition. */
881 #define PI_PAGE_SIZE 0x1000
882 #define PI_PAGE_MASK 0x0FFF
883 #define PI_PAGE_SHIFT 12
885 /* returns next non-zero index on success or zero on failure (i.e. out of
889 add_physinfo_entries(U32 inp_pfn
, /* input - specifies the pfn to be used
891 U16 inp_off
, /* input - specifies the off to be used
893 U32 inp_len
, /* input - specifies the len to be used
895 U16 index
, /* input - index in array at which new
896 * entries are added */
897 U16 max_pi_arr_entries
, /* input - specifies the maximum
898 * entries pi_arr can hold */
899 struct phys_info pi_arr
[]) /* input & output - array to
900 * which entries are added */
905 firstlen
= PI_PAGE_SIZE
- inp_off
;
906 if (inp_len
<= firstlen
) {
908 /* the input entry spans only one page - add as is */
909 if (index
>= max_pi_arr_entries
)
911 pi_arr
[index
].pi_pfn
= inp_pfn
;
912 pi_arr
[index
].pi_off
= (U16
) inp_off
;
913 pi_arr
[index
].pi_len
= (U16
) inp_len
;
917 /* this entry spans multiple pages */
918 for (len
= inp_len
, i
= 0; len
;
919 len
-= pi_arr
[index
+ i
].pi_len
, i
++) {
920 if (index
+ i
>= max_pi_arr_entries
)
922 pi_arr
[index
+ i
].pi_pfn
= inp_pfn
+ i
;
924 pi_arr
[index
].pi_off
= inp_off
;
925 pi_arr
[index
].pi_len
= firstlen
;
929 pi_arr
[index
+ i
].pi_off
= 0;
930 pi_arr
[index
+ i
].pi_len
=
931 (U16
) MINNUM(len
, (U32
) PI_PAGE_SIZE
);
938 #endif /* __IOCHANNEL_H__ */