]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/staging/unisys/common-spar/include/channels/iochannel.h
staging: unisys: remove U8 type
[mirror_ubuntu-zesty-kernel.git] / drivers / staging / unisys / common-spar / include / channels / iochannel.h
CommitLineData
f6d0c1e6 1/* Copyright (C) 2010 - 2013 UNISYS CORPORATION */
12e364b9
KC
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/*
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
16*
17* additional states will be used later. No locking is needed to switch between
18* states due to the following rules:
19*
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
22* CHANNEL_ATTACHING
23* 3. GuestPart is only the only partition allowed to change from
24* CHANNEL_ATTACHED
25*
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)
30*/
31
90addb02
BR
32#include <linux/uuid.h>
33
12e364b9
KC
34#include "commontypes.h"
35#include "vmcallinterface.h"
36
37#define _ULTRA_CONTROLVM_CHANNEL_INLINE_
a8d7f21d 38#include <linux/dma-direction.h>
12e364b9
KC
39#include "controlvmchannel.h"
40#include "vbuschannel.h"
41#undef _ULTRA_CONTROLVM_CHANNEL_INLINE_
42#include "channel.h"
43
44/*
45 * CHANNEL Guids
46 */
47
48#include "channel_guid.h"
49
50#define ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
51#define ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
52#define ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE \
53 ULTRA_CHANNEL_PROTOCOL_SIGNATURE
54
55/* Must increment these whenever you insert or delete fields within this channel
56* struct. Also increment whenever you change the meaning of fields within this
57* channel struct so as to break pre-existing software. Note that you can
58* usually add fields to the END of the channel struct withOUT needing to
59* increment this. */
60#define ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID 2
61#define ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID 2
62#define ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID 1
63
64#define ULTRA_VHBA_CHANNEL_OK_CLIENT(pChannel, logCtx) \
65 (ULTRA_check_channel_client(pChannel, UltraVhbaChannelProtocolGuid, \
66 "vhba", MIN_IO_CHANNEL_SIZE, \
67 ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \
68 ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE, \
69 __FILE__, __LINE__, logCtx))
70#define ULTRA_VHBA_CHANNEL_OK_SERVER(actualBytes, logCtx) \
71 (ULTRA_check_channel_server(UltraVhbaChannelProtocolGuid, \
72 "vhba", MIN_IO_CHANNEL_SIZE, actualBytes, \
73 __FILE__, __LINE__, logCtx))
74#define ULTRA_VNIC_CHANNEL_OK_CLIENT(pChannel, logCtx) \
75 (ULTRA_check_channel_client(pChannel, UltraVnicChannelProtocolGuid, \
76 "vnic", MIN_IO_CHANNEL_SIZE, \
77 ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \
78 ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE, \
79 __FILE__, __LINE__, logCtx))
80#define ULTRA_VNIC_CHANNEL_OK_SERVER(actualBytes, logCtx) \
81 (ULTRA_check_channel_server(UltraVnicChannelProtocolGuid, \
82 "vnic", MIN_IO_CHANNEL_SIZE, actualBytes, \
83 __FILE__, __LINE__, logCtx))
84#define ULTRA_VSWITCH_CHANNEL_OK_CLIENT(pChannel, logCtx) \
85 (ULTRA_check_channel_client(pChannel, UltraVswitchChannelProtocolGuid, \
86 "vswitch", MIN_IO_CHANNEL_SIZE, \
87 ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID, \
88 ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE, \
89 __FILE__, __LINE__, logCtx))
90#define ULTRA_VSWITCH_CHANNEL_OK_SERVER(actualBytes, logCtx) \
91 (ULTRA_check_channel_server(UltraVswitchChannelProtocolGuid, \
92 "vswitch", MIN_IO_CHANNEL_SIZE, \
93 actualBytes, \
94 __FILE__, __LINE__, logCtx))
95/*
96* Everything necessary to handle SCSI & NIC traffic between Guest Partition and
97* IO Partition is defined below. */
98
99
100/*
101* Defines and enums.
102*/
103
104#define MINNUM(a, b) (((a) < (b)) ? (a) : (b))
105#define MAXNUM(a, b) (((a) > (b)) ? (a) : (b))
106
107/* these define the two queues per data channel between iopart and
108 * ioguestparts */
109#define IOCHAN_TO_IOPART 0 /* used by ioguestpart to 'insert' signals to
110 * iopart */
111#define IOCHAN_FROM_GUESTPART 0 /* used by iopart to 'remove' signals from
112 * ioguestpart - same queue as previous queue */
113
114#define IOCHAN_TO_GUESTPART 1 /* used by iopart to 'insert' signals to
115 * ioguestpart */
116#define IOCHAN_FROM_IOPART 1 /* used by ioguestpart to 'remove' signals from
117 * iopart - same queue as previous queue */
118
119/* these define the two queues per control channel between controlpart and "its"
120 * guests, which includes the iopart */
121#define CTRLCHAN_TO_CTRLGUESTPART 0 /* used by ctrlguestpart to 'insert' signals
122 * to ctrlpart */
123#define CTLRCHAN_FROM_CTRLPART 0 /* used by ctrlpart to 'remove' signals from
124 * ctrlquestpart - same queue as previous
125 * queue */
126
127#define CTRLCHAN_TO_CTRLPART 1 /* used by ctrlpart to 'insert' signals to
128 * ctrlguestpart */
129#define CTRLCHAN_FROM_CTRLGUESTPART 1 /* used by ctrguestpart to 'remove'
130 * signals from ctrlpart - same queue as
131 * previous queue */
132
133/* these define the Event & Ack queues per control channel Events are generated
134* by CTRLGUESTPART and sent to CTRLPART; Acks are generated by CTRLPART and sent
135* to CTRLGUESTPART. */
136#define CTRLCHAN_EVENT_TO_CTRLPART 2 /* used by ctrlguestpart to 'insert' Events
137 * to ctrlpart */
138#define CTRLCHAN_EVENT_FROM_CTRLGUESTPART 2 /* used by ctrlpart to 'remove'
139 * Events from ctrlguestpart */
140
141#define CTRLCHAN_ACK_TO_CTRLGUESTPART 3 /* used by ctrlpart to 'insert' Acks to
142 * ctrlguestpart */
143#define CTRLCHAN_ACK_FROM_CTRLPART 3 /* used by ctrlguestpart to 'remove' Events
144 * from ctrlpart */
145
146/* size of cdb - i.e., scsi cmnd */
147#define MAX_CMND_SIZE 16
12e364b9
KC
148
149#define MAX_SENSE_SIZE 64
150
151#define MAX_PHYS_INFO 64
152
153/* Because GuestToGuestCopy is limited to 4KiB segments, and we have limited the
154* Emulex Driver to 256 scatter list segments via the lpfc_sg_seg_cnt parameter
155* to 256, the maximum I/O size is limited to 256 * 4 KiB = 1 MB */
156#define MAX_IO_SIZE (1024*1024) /* 1 MB */
157
158/* NOTE 1: lpfc defines its support for segments in
159* #define LPFC_SG_SEG_CNT 64
160*
161* NOTE 2: In Linux, frags array in skb is currently allocated to be
162* MAX_SKB_FRAGS size, which is 18 which is smaller than MAX_PHYS_INFO for
163* now. */
164
165#ifndef MAX_SERIAL_NUM
166#define MAX_SERIAL_NUM 32
167#endif /* MAX_SERIAL_NUM */
168
169#define MAX_SCSI_BUSES 1
170#define MAX_SCSI_TARGETS 8
171#define MAX_SCSI_LUNS 16
172#define MAX_SCSI_FROM_HOST 0xFFFFFFFF /* Indicator to use Physical HBA
173 * SCSI Host value */
174
175/* various types of network packets that can be sent in cmdrsp */
176typedef enum { NET_RCV_POST = 0, /* submit buffer to hold receiving
177 * incoming packet */
178 /* virtnic -> uisnic */
179 NET_RCV, /* incoming packet received */
180 /* uisnic -> virtpci */
181 NET_XMIT, /* for outgoing net packets */
182 /* virtnic -> uisnic */
183 NET_XMIT_DONE, /* outgoing packet xmitted */
184 /* uisnic -> virtpci */
185 NET_RCV_ENBDIS, /* enable/disable packet reception */
186 /* virtnic -> uisnic */
187 NET_RCV_ENBDIS_ACK, /* acknowledge enable/disable packet
188 * reception */
189 /* uisnic -> virtnic */
190 NET_RCV_PROMISC, /* enable/disable promiscuous mode */
191 /* virtnic -> uisnic */
192 NET_CONNECT_STATUS, /* indicate the loss or restoration of a network
193 * connection */
194 /* uisnic -> virtnic */
195 NET_MACADDR, /* indicates the client has requested to update
196 * its MAC addr */
fb90c609 197 NET_MACADDR_ACK, /* MAC address */
12e364b9
KC
198
199} NET_TYPES;
200
201#define ETH_HEADER_SIZE 14 /* size of ethernet header */
202
203#define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */
204#define ETH_MIN_PACKET_SIZE (ETH_HEADER_SIZE + ETH_MIN_DATA_SIZE)
205
206#define ETH_DEF_DATA_SIZE 1500 /* default data size */
207#define ETH_DEF_PACKET_SIZE (ETH_HEADER_SIZE + ETH_DEF_DATA_SIZE)
208
209#define ETH_MAX_MTU 16384 /* maximum data size */
210
211#ifndef MAX_MACADDR_LEN
212#define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */
213#endif /* MAX_MACADDR_LEN */
214
215#define ETH_IS_LOCALLY_ADMINISTERED(Address) \
c242233e 216 (((u8 *) (Address))[0] & ((u8) 0x02))
12e364b9
KC
217#define NIC_VENDOR_ID 0x0008000B
218
219/* various types of scsi task mgmt commands */
220typedef enum { TASK_MGMT_ABORT_TASK =
221 1, TASK_MGMT_BUS_RESET, TASK_MGMT_LUN_RESET,
222 TASK_MGMT_TARGET_RESET,
223} TASK_MGMT_TYPES;
224
225/* various types of vdisk mgmt commands */
226typedef enum { VDISK_MGMT_ACQUIRE = 1, VDISK_MGMT_RELEASE,
227} VDISK_MGMT_TYPES;
228
229/* this is used in the vdest field */
230#define VDEST_ALL 0xFFFF
231
232#define MIN_NUMSIGNALS 64
233#define MAX_NUMSIGNALS 4096
234
235/* MAX_NET_RCV_BUF specifies the number of rcv buffers that are created by each
236* guest's virtnic and posted to uisnic. Uisnic, for each channel, keeps the rcv
237* buffers posted and uses them to receive data on behalf of the guest's virtnic.
238* NOTE: the num_rcv_bufs is configurable for each VNIC. So the following is
239* simply an upperlimit on what each VNIC can provide. Setting it to half of the
240* NUMSIGNALS to prevent queue full deadlocks */
241#define MAX_NET_RCV_BUFS (MIN_NUMSIGNALS / 2)
242
243/*
244 * structs with pragma pack */
245
246
247/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
248/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
249
250#pragma pack(push, 1)
251
252struct guest_phys_info {
253 U64 address;
254 U64 length;
255};
256
257#define GPI_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct guest_phys_info))
258
259struct uisscsi_dest {
260 U32 channel; /* channel == bus number */
261 U32 id; /* id == target number */
262 U32 lun; /* lun == logical unit number */
263};
264
265struct vhba_wwnn {
266 U32 wwnn1;
267 U32 wwnn2;
268};
269
270/* WARNING: Values stired in this structure must contain maximum counts (not
271 * maximum values). */
272struct vhba_config_max { /* 20 bytes */
273 U32 max_channel; /* maximum channel for devices attached to this
274 * bus */
275 U32 max_id; /* maximum SCSI ID for devices attached to this
276 * bus */
277 U32 max_lun; /* maximum SCSI LUN for devices attached to this
278 * bus */
279 U32 cmd_per_lun; /* maximum number of outstanding commands per
280 * lun that are allowed at one time */
281 U32 max_io_size; /* maximum io size for devices attached to this
282 * bus */
283 /* max io size is often determined by the resource of the hba. e.g */
284 /* max scatter gather list length * page size / sector size */
285};
286
287struct uiscmdrsp_scsi {
288 void *scsicmd; /* the handle to the cmd that was received -
289 * send it back as is in the rsp packet. */
c242233e 290 u8 cmnd[MAX_CMND_SIZE]; /* the cdb for the command */
12e364b9
KC
291 U32 bufflen; /* length of data to be transferred out or in */
292 U16 guest_phys_entries; /* Number of entries in scatter-gather (sg)
293 * list */
294 struct guest_phys_info gpi_list[MAX_PHYS_INFO]; /* physical address
295 * information for each
296 * fragment */
a8d7f21d 297 enum dma_data_direction data_dir; /* direction of the data, if any */
12e364b9
KC
298 struct uisscsi_dest vdest; /* identifies the virtual hba, id,
299 * channel, lun to which cmd was sent */
300
301 /* the following fields are needed to queue the rsp back to cmd
302 * originator */
303 int linuxstat; /* the original Linux status - for use by linux
304 * vdisk code */
c242233e
BR
305 u8 scsistat; /* the scsi status */
306 u8 addlstat; /* non-scsi status - covers cases like timeout
12e364b9
KC
307 * needed by windows guests */
308#define ADDL_RESET 1
309#define ADDL_TIMEOUT 2
310#define ADDL_INTERNAL_ERROR 3
311#define ADDL_SEL_TIMEOUT 4
312#define ADDL_CMD_TIMEOUT 5
313#define ADDL_BAD_TARGET 6
314#define ADDL_RETRY 7
315
316 /* the following fields are need to determine the result of command */
c242233e 317 u8 sensebuf[MAX_SENSE_SIZE]; /* sense info in case cmd failed; */
12e364b9
KC
318 /* it holds the sense_data struct; */
319 /* see that struct for details. */
320 void *vdisk; /* contains pointer to the vdisk so that we can clean up
321 * when the IO completes. */
322 int no_disk_result; /* used to return no disk inquiry result */
323 /* when no_disk_result is set to 1, */
324 /* scsi.scsistat is SAM_STAT_GOOD */
325 /* scsi.addlstat is 0 */
326 /* scsi.linuxstat is SAM_STAT_GOOD */
327 /* That is, there is NO error. */
328};
329
330/*
331* Defines to support sending correct inquiry result when no disk is
332* configured. */
333
334/* From SCSI SPC2 -
335 *
336 * If the target is not capable of supporting a device on this logical unit, the
337 * device server shall set this field to 7Fh (PERIPHERAL QUALIFIER set to 011b
338 * and PERIPHERAL DEVICE TYPE set to 1Fh).
339 *
340 *The device server is capable of supporting the specified peripheral device
341 *type on this logical unit. However, the physical device is not currently
342 *connected to this logical unit.
343 */
344
345#define DEV_NOT_PRESENT 0x7f /* old name - compatibility */
346#define DEV_NOT_CAPABLE 0x7f /* peripheral qualifier of 0x3 */
347 /* peripheral type of 0x1f */
348 /* specifies no device but target present */
349
350#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 /* peripheral qualifier of 0x1 */
351 /* peripheral type of 0 - disk */
352 /* specifies device capable, but not present */
353
354#define DEV_PROC_CAPABLE_NOT_PRESENT 0x23 /* peripheral qualifier of 0x1 */
355 /* peripheral type of 3 - processor */
356 /* specifies device capable, but not present */
357
358#define DEV_HISUPPORT 0x10; /* HiSup = 1; shows support for report luns */
359 /* must be returned for lun 0. */
360
361/* NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length
362* in buf[4] some linux code accesses bytes beyond 5 to retrieve vendor, product
363* & revision. Yikes! So let us always send back 36 bytes, the minimum for
364* inquiry result. */
365#define NO_DISK_INQUIRY_RESULT_LEN 36
366
367#define MIN_INQUIRY_RESULT_LEN 5 /* we need at least 5 bytes minimum for inquiry
368 * result */
369
370/* SCSI device version for no disk inquiry result */
371#define SCSI_SPC2_VER 4 /* indicates SCSI SPC2 (SPC3 is 5) */
372
373/* Windows and Linux want different things for a non-existent lun. So, we'll let
374 * caller pass in the peripheral qualifier and type.
375 * NOTE:[4] SCSI returns (n-4); so we return length-1-4 or length-5. */
376
377#define SET_NO_DISK_INQUIRY_RESULT(buf, len, lun, lun0notpresent, notpresent) \
378 do { \
379 MEMSET(buf, 0, \
380 MINNUM(len, \
381 (unsigned int) NO_DISK_INQUIRY_RESULT_LEN)); \
c242233e 382 buf[2] = (u8) SCSI_SPC2_VER; \
12e364b9 383 if (lun == 0) { \
c242233e
BR
384 buf[0] = (u8) lun0notpresent; \
385 buf[3] = (u8) DEV_HISUPPORT; \
12e364b9 386 } else \
c242233e
BR
387 buf[0] = (u8) notpresent; \
388 buf[4] = (u8) ( \
12e364b9
KC
389 MINNUM(len, \
390 (unsigned int) NO_DISK_INQUIRY_RESULT_LEN) - 5); \
391 if (len >= NO_DISK_INQUIRY_RESULT_LEN) { \
392 buf[8] = 'D'; \
393 buf[9] = 'E'; \
394 buf[10] = 'L'; \
395 buf[11] = 'L'; \
396 buf[16] = 'P'; \
397 buf[17] = 'S'; \
398 buf[18] = 'E'; \
399 buf[19] = 'U'; \
400 buf[20] = 'D'; \
401 buf[21] = 'O'; \
402 buf[22] = ' '; \
403 buf[23] = 'D'; \
404 buf[24] = 'E'; \
405 buf[25] = 'V'; \
406 buf[26] = 'I'; \
407 buf[27] = 'C'; \
408 buf[28] = 'E'; \
409 buf[30] = ' '; \
410 buf[31] = '.'; \
411 } \
412 } while (0)
413
414
415/*
416* Struct & Defines to support sense information.
417*/
418
419
420/* The following struct is returned in sensebuf field in uiscmdrsp_scsi. It is
421* initialized in exactly the manner that is recommended in Windows (hence the
422* odd values).
423* When set, these fields will have the following values:
424* ErrorCode = 0x70 indicates current error
425* Valid = 1 indicates sense info is valid
426* SenseKey contains sense key as defined by SCSI specs.
427* AdditionalSenseCode contains sense key as defined by SCSI specs.
428* AdditionalSenseCodeQualifier contains qualifier to sense code as defined by
429* scsi docs.
430* AdditionalSenseLength contains will be sizeof(sense_data)-8=10.
431*/
432struct sense_data {
c242233e
BR
433 u8 ErrorCode:7;
434 u8 Valid:1;
435 u8 SegmentNumber;
436 u8 SenseKey:4;
437 u8 Reserved:1;
438 u8 IncorrectLength:1;
439 u8 EndOfMedia:1;
440 u8 FileMark:1;
441 u8 Information[4];
442 u8 AdditionalSenseLength;
443 u8 CommandSpecificInformation[4];
444 u8 AdditionalSenseCode;
445 u8 AdditionalSenseCodeQualifier;
446 u8 FieldReplaceableUnitCode;
447 u8 SenseKeySpecific[3];
12e364b9
KC
448};
449
450/* some SCSI ADSENSE codes */
451#ifndef SCSI_ADSENSE_LUN_NOT_READY
452#define SCSI_ADSENSE_LUN_NOT_READY 0x04
453#endif /* */
454#ifndef SCSI_ADSENSE_ILLEGAL_COMMAND
455#define SCSI_ADSENSE_ILLEGAL_COMMAND 0x20
456#endif /* */
457#ifndef SCSI_ADSENSE_ILLEGAL_BLOCK
458#endif /* */
459#ifndef SCSI_ADSENSE_ILLEGAL_BLOCK
460#define SCSI_ADSENSE_ILLEGAL_BLOCK 0x21
461#endif /* */
462#ifndef SCSI_ADSENSE_INVALID_CDB
463#define SCSI_ADSENSE_INVALID_CDB 0x24
464#endif /* */
465#ifndef SCSI_ADSENSE_INVALID_LUN
466#define SCSI_ADSENSE_INVALID_LUN 0x25
467#endif /* */
468#ifndef SCSI_ADWRITE_PROTECT
469#define SCSI_ADWRITE_PROTECT 0x27
470#endif /* */
471#ifndef SCSI_ADSENSE_MEDIUM_CHANGED
472#define SCSI_ADSENSE_MEDIUM_CHANGED 0x28
473#endif /* */
474#ifndef SCSI_ADSENSE_BUS_RESET
475#define SCSI_ADSENSE_BUS_RESET 0x29
476#endif /* */
477#ifndef SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
478#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE 0x3a
479#endif /* */
480
481struct net_pkt_xmt {
482 int len; /* full length of data in the packet */
483 int num_frags; /* number of fragments in frags containing data */
484 struct phys_info frags[MAX_PHYS_INFO]; /* physical page information for
485 * each fragment */
486 char ethhdr[ETH_HEADER_SIZE]; /* the ethernet header */
487 struct {
488
489 /* these are needed for csum at uisnic end */
c242233e 490 u8 valid; /* 1 = rest of this struct is valid - else
12e364b9 491 * ignore */
c242233e
BR
492 u8 hrawoffv; /* 1 = hwrafoff is valid */
493 u8 nhrawoffv; /* 1 = nhwrafoff is valid */
12e364b9
KC
494 U16 protocol; /* specifies packet protocol */
495 U32 csum; /* value used to set skb->csum at IOPart */
496 U32 hrawoff; /* value used to set skb->h.raw at IOPart */
497 /* hrawoff points to the start of the TRANSPORT LAYER HEADER */
498 U32 nhrawoff; /* value used to set skb->nh.raw at IOPart */
499 /* nhrawoff points to the start of the NETWORK LAYER HEADER */
500 } lincsum;
501
502 /* **** NOTE ****
503 * The full packet is described in frags but the ethernet header is
504 * separately kept in ethhdr so that uisnic doesn't have "MAP" the
505 * guest memory to get to the header. uisnic needs ethhdr to
506 * determine how to route the packet.
507 */
508};
509
510struct net_pkt_xmtdone {
511 U32 xmt_done_result; /* result of NET_XMIT */
512#define XMIT_SUCCESS 0
513#define XMIT_FAILED 1
514};
515
516/* RCVPOST_BUF_SIZe must be at most page_size(4096) - cache_line_size (64) The
517* reason is because dev_skb_alloc which is used to generate RCV_POST skbs in
518* virtnic requires that there is "overhead" in the buffer, and pads 16 bytes. I
519* prefer to use 1 full cache line size for "overhead" so that transfers are
520* better. IOVM requires that a buffer be represented by 1 phys_info structure
521* which can only cover page_size. */
522#define RCVPOST_BUF_SIZE 4032
523#define MAX_NET_RCV_CHAIN \
524 ((ETH_MAX_MTU+ETH_HEADER_SIZE + RCVPOST_BUF_SIZE-1) / RCVPOST_BUF_SIZE)
525
526struct net_pkt_rcvpost {
527 /* rcv buf size must be large enough to include ethernet data len +
528 * ethernet header len - we are choosing 2K because it is guaranteed
529 * to be describable */
530 struct phys_info frag; /* physical page information for the
531 * single fragment 2K rcv buf */
532 U64 UniqueNum; /* This is used to make sure that
533 * receive posts are returned to */
534 /* the Adapter which sent them origonally. */
535};
536
537struct net_pkt_rcv {
538
539 /* the number of receive buffers that can be chained */
540 /* is based on max mtu and size of each rcv buf */
541 U32 rcv_done_len; /* length of received data */
c242233e 542 u8 numrcvbufs; /* number of receive buffers that contain the */
12e364b9
KC
543 /* incoming data; guest end MUST chain these together. */
544 void *rcvbuf[MAX_NET_RCV_CHAIN]; /* the list of receive buffers
545 * that must be chained; */
546 /* each entry is a receive buffer provided by NET_RCV_POST. */
547 /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */
548 U64 UniqueNum;
549 U32 RcvsDroppedDelta;
550};
551
552struct net_pkt_enbdis {
553 void *context;
554 U16 enable; /* 1 = enable, 0 = disable */
555};
556
557struct net_pkt_macaddr {
558 void *context;
c242233e 559 u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */
12e364b9
KC
560};
561
562/* cmd rsp packet used for VNIC network traffic */
563struct uiscmdrsp_net {
564 NET_TYPES type;
565 void *buf;
566 union {
567 struct net_pkt_xmt xmt; /* used for NET_XMIT */
568 struct net_pkt_xmtdone xmtdone; /* used for NET_XMIT_DONE */
569 struct net_pkt_rcvpost rcvpost; /* used for NET_RCV_POST */
570 struct net_pkt_rcv rcv; /* used for NET_RCV */
571 struct net_pkt_enbdis enbdis; /* used for NET_RCV_ENBDIS, */
572 /* NET_RCV_ENBDIS_ACK, */
573 /* NET_RCV_PROMSIC, */
574 /* and NET_CONNECT_STATUS */
575 struct net_pkt_macaddr macaddr;
576 };
577};
578
579struct uiscmdrsp_scsitaskmgmt {
580 TASK_MGMT_TYPES tasktype;
581
582 /* the type of task */
583 struct uisscsi_dest vdest;
584
585 /* the vdisk for which this task mgmt is generated */
586 void *scsicmd;
587
588 /* This is some handle that the guest has saved off for its own use.
589 * Its value is preserved by iopart & returned as is in the task mgmt
590 * rsp. */
591 void *notify;
592
593 /* For linux guests, this is a pointer to wait_queue_head that a
594 * thread is waiting on to see if the taskmgmt command has completed.
595 * For windows guests, this is a pointer to a location that a waiting
596 * thread is testing to see if the taskmgmt command has completed.
597 * When the rsp is received by guest, the thread receiving the
598 * response uses this to notify the the thread waiting for taskmgmt
599 * command completion. Its value is preserved by iopart & returned
600 * as is in the task mgmt rsp. */
601 void *notifyresult;
602
603 /* this is a handle to location in guest where the result of the
604 * taskmgmt command (result field) is to saved off when the response
605 * is handled. Its value is preserved by iopart & returned as is in
606 * the task mgmt rsp. */
607 char result;
608
609 /* result of taskmgmt command - set by IOPart - values are: */
610#define TASK_MGMT_FAILED 0
611#define TASK_MGMT_SUCCESS 1
612};
613
614/* The following is used by uissd to send disk add/remove notifications to
615 * Guest */
616/* Note that the vHba pointer is not used by the Client/Guest side. */
617struct uiscmdrsp_disknotify {
c242233e 618 u8 add; /* 0-remove, 1-add */
12e364b9
KC
619 void *vHba; /* Pointer to vhba_info for channel info to
620 * route msg */
621 U32 channel, id, lun; /* SCSI Path of Disk to added or removed */
622};
623
624/* The following is used by virthba/vSCSI to send the Acquire/Release commands
625* to the IOVM. */
626struct uiscmdrsp_vdiskmgmt {
627 VDISK_MGMT_TYPES vdisktype;
628
629 /* the type of task */
630 struct uisscsi_dest vdest;
631
632 /* the vdisk for which this task mgmt is generated */
633 void *scsicmd;
634
635 /* This is some handle that the guest has saved off for its own use.
636 * Its value is preserved by iopart & returned as is in the task mgmt
637 * rsp. */
638 void *notify;
639
640 /* For linux guests, this is a pointer to wait_queue_head that a
641 * thread is waiting on to see if the taskmgmt command has completed.
642 * For windows guests, this is a pointer to a location that a waiting
643 * thread is testing to see if the taskmgmt command has completed.
644 * When the rsp is received by guest, the thread receiving the
645 * response uses this to notify the the thread waiting for taskmgmt
646 * command completion. Its value is preserved by iopart & returned
647 * as is in the task mgmt rsp. */
648 void *notifyresult;
649
650 /* this is a handle to location in guest where the result of the
651 * taskmgmt command (result field) is to saved off when the response
652 * is handled. Its value is preserved by iopart & returned as is in
653 * the task mgmt rsp. */
654 char result;
655
656 /* result of taskmgmt command - set by IOPart - values are: */
657#define VDISK_MGMT_FAILED 0
658#define VDISK_MGMT_SUCCESS 1
659};
660
661/* keeping cmd & rsp info in one structure for now cmd rsp packet for scsi */
662struct uiscmdrsp {
663 char cmdtype;
664
665 /* describes what type of information is in the struct */
666#define CMD_SCSI_TYPE 1
667#define CMD_NET_TYPE 2
668#define CMD_SCSITASKMGMT_TYPE 3
669#define CMD_NOTIFYGUEST_TYPE 4
670#define CMD_VDISKMGMT_TYPE 5
671 union {
672 struct uiscmdrsp_scsi scsi;
673 struct uiscmdrsp_net net;
674 struct uiscmdrsp_scsitaskmgmt scsitaskmgmt;
675 struct uiscmdrsp_disknotify disknotify;
676 struct uiscmdrsp_vdiskmgmt vdiskmgmt;
677 };
678 void *private_data; /* used to send the response when the cmd is
679 * done (scsi & scsittaskmgmt). */
680 struct uiscmdrsp *next; /* General Purpose Queue Link */
681 struct uiscmdrsp *activeQ_next; /* Used to track active commands */
682 struct uiscmdrsp *activeQ_prev; /* Used to track active commands */
683};
684
685/* This is just the header of the IO channel. It is assumed that directly after
686* this header there is a large region of memory which contains the command and
687* response queues as specified in cmdQ and rspQ SIGNAL_QUEUE_HEADERS. */
688typedef struct _ULTRA_IO_CHANNEL_PROTOCOL {
689 CHANNEL_HEADER ChannelHeader;
690 SIGNAL_QUEUE_HEADER cmdQ;
691 SIGNAL_QUEUE_HEADER rspQ;
692 union {
693 struct {
694 struct vhba_wwnn wwnn; /* 8 bytes */
695 struct vhba_config_max max; /* 20 bytes */
696 } vhba; /* 28 */
697 struct {
c242233e 698 u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */
12e364b9
KC
699 U32 num_rcv_bufs; /* 4 */
700 U32 mtu; /* 4 */
90addb02 701 uuid_le zoneGuid; /* 16 */
12e364b9
KC
702 } vnic; /* total 30 */
703 };
704
705#define MAX_CLIENTSTRING_LEN 1024
c242233e 706 u8 clientString[MAX_CLIENTSTRING_LEN]; /* NULL terminated - so holds
12e364b9
KC
707 * max - 1 bytes */
708} ULTRA_IO_CHANNEL_PROTOCOL;
709
710#pragma pack(pop)
711/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
712
713/* define offsets to members of struct uiscmdrsp */
714#define OFFSET_CMDTYPE OFFSETOF(struct uiscmdrsp, cmdtype)
715#define OFFSET_SCSI OFFSETOF(struct uiscmdrsp, scsi)
716#define OFFSET_NET OFFSETOF(struct uiscmdrsp, net)
717#define OFFSET_SCSITASKMGMT OFFSETOF(struct uiscmdrsp, scsitaskmgmt)
718#define OFFSET_NEXT OFFSETOF(struct uiscmdrsp, next)
719
720/* define offsets to members of struct uiscmdrsp_net */
721#define OFFSET_TYPE OFFSETOF(struct uiscmdrsp_net, type)
722#define OFFSET_BUF OFFSETOF(struct uiscmdrsp_net, buf)
723#define OFFSET_XMT OFFSETOF(struct uiscmdrsp_net, xmt)
724#define OFFSET_XMT_DONE_RESULT OFFSETOF(struct uiscmdrsp_net, xmtdone)
725#define OFFSET_RCVPOST OFFSETOF(struct uiscmdrsp_net, rcvpost)
726#define OFFSET_RCV_DONE_LEN OFFSETOF(struct uiscmdrsp_net, rcv)
727#define OFFSET_ENBDIS OFFSETOF(struct uiscmdrsp_net, enbdis)
728
729/* define offsets to members of struct net_pkt_rcvpost */
730#define OFFSET_TOTALLEN OFFSETOF(struct net_pkt_rcvpost, totallen)
731#define OFFSET_FRAG OFFSETOF(struct net_pkt_rcvpost, frag)
732
733/*
734* INLINE functions for initializing and accessing I/O data channels
735*/
736
737
738#define NUMSIGNALS(x, q) (((ULTRA_IO_CHANNEL_PROTOCOL *)(x))->q.MaxSignalSlots)
739#define SIZEOF_PROTOCOL (COVER(sizeof(ULTRA_IO_CHANNEL_PROTOCOL), 64))
740#define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64))
741
742#define IO_CHANNEL_SIZE(x) COVER(SIZEOF_PROTOCOL + \
743 (NUMSIGNALS(x, cmdQ) + \
744 NUMSIGNALS(x, rspQ)) * SIZEOF_CMDRSP, 4096)
745#define MIN_IO_CHANNEL_SIZE COVER(SIZEOF_PROTOCOL + \
746 2 * MIN_NUMSIGNALS * SIZEOF_CMDRSP, 4096)
747#ifdef __GNUC__
748/* These defines should only ever be used in service partitons */
749/* because they rely on the size of uiscmdrsp */
750#define QSLOTSFROMBYTES(bytes) (((bytes-SIZEOF_PROTOCOL)/2)/SIZEOF_CMDRSP)
751#define QSIZEFROMBYTES(bytes) (QSLOTSFROMBYTES(bytes)*SIZEOF_CMDRSP)
752#define SignalQInit(x) \
753 do { \
754 x->cmdQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \
755 x->cmdQ.oSignalBase = SIZEOF_PROTOCOL - \
756 OFFSETOF(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \
757 x->cmdQ.SignalSize = SIZEOF_CMDRSP; \
758 x->cmdQ.MaxSignalSlots = \
759 QSLOTSFROMBYTES(x->ChannelHeader.Size); \
760 x->cmdQ.MaxSignals = x->cmdQ.MaxSignalSlots - 1; \
761 x->rspQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \
762 x->rspQ.oSignalBase = \
763 (SIZEOF_PROTOCOL + x->cmdQ.Size) - \
764 OFFSETOF(ULTRA_IO_CHANNEL_PROTOCOL, rspQ); \
765 x->rspQ.SignalSize = SIZEOF_CMDRSP; \
766 x->rspQ.MaxSignalSlots = \
767 QSLOTSFROMBYTES(x->ChannelHeader.Size); \
768 x->rspQ.MaxSignals = x->rspQ.MaxSignalSlots - 1; \
769 x->ChannelHeader.oChannelSpace = \
770 OFFSETOF(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \
771 } while (0)
772
773#define INIT_CLIENTSTRING(chan, type, clientStr, clientStrLen) \
774 do { \
775 if (clientStr) { \
776 chan->ChannelHeader.oClientString = \
777 OFFSETOF(type, clientString); \
778 MEMCPY(chan->clientString, clientStr, \
779 MINNUM(clientStrLen, \
780 (U32) (MAX_CLIENTSTRING_LEN - 1))); \
781 chan->clientString[MINNUM(clientStrLen, \
782 (U32) (MAX_CLIENTSTRING_LEN \
783 - 1))] \
784 = '\0'; \
785 } \
786 else \
787 if (clientStrLen > 0) \
788 return 0; \
789 } while (0)
790
791
792#define ULTRA_IO_CHANNEL_SERVER_READY(x, chanId, logCtx) \
793 ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, CHANNELSRV_READY, \
794 logCtx);
795
796#define ULTRA_IO_CHANNEL_SERVER_NOTREADY(x, chanId, logCtx) \
797 ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, \
798 CHANNELSRV_UNINITIALIZED, logCtx);
799
800static inline int ULTRA_VHBA_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x,
801 struct vhba_wwnn *wwnn,
802 struct vhba_config_max *max,
803 unsigned char *clientStr,
804 U32 clientStrLen, U64 bytes) {
805 MEMSET(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
806 x->ChannelHeader.VersionId = ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID;
807 x->ChannelHeader.Signature = ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE;
808 x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED;
809 x->ChannelHeader.HeaderSize = sizeof(x->ChannelHeader);
810 x->ChannelHeader.Size = COVER(bytes, 4096);
811 x->ChannelHeader.Type = UltraVhbaChannelProtocolGuid;
90addb02 812 x->ChannelHeader.ZoneGuid = NULL_UUID_LE;
12e364b9
KC
813 x->vhba.wwnn = *wwnn;
814 x->vhba.max = *max;
815 INIT_CLIENTSTRING(x, ULTRA_IO_CHANNEL_PROTOCOL, clientStr,
816 clientStrLen);
817 SignalQInit(x);
818 if ((x->cmdQ.MaxSignalSlots > MAX_NUMSIGNALS) ||
819 (x->rspQ.MaxSignalSlots > MAX_NUMSIGNALS)) {
820 return 0;
821 }
822 if ((x->cmdQ.MaxSignalSlots < MIN_NUMSIGNALS) ||
823 (x->rspQ.MaxSignalSlots < MIN_NUMSIGNALS)) {
824 return 0;
825 }
826 return 1;
827}
828
829static inline void ULTRA_VHBA_set_max(ULTRA_IO_CHANNEL_PROTOCOL *x,
830 struct vhba_config_max *max) {
831 x->vhba.max = *max;
832}
833
834static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x,
835 unsigned char *macaddr,
836 U32 num_rcv_bufs, U32 mtu,
90addb02 837 uuid_le zoneGuid,
12e364b9
KC
838 unsigned char *clientStr,
839 U32 clientStrLen,
840 U64 bytes) {
841 MEMSET(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
842 x->ChannelHeader.VersionId = ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID;
843 x->ChannelHeader.Signature = ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE;
844 x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED;
845 x->ChannelHeader.HeaderSize = sizeof(x->ChannelHeader);
846 x->ChannelHeader.Size = COVER(bytes, 4096);
847 x->ChannelHeader.Type = UltraVnicChannelProtocolGuid;
90addb02 848 x->ChannelHeader.ZoneGuid = NULL_UUID_LE;
12e364b9
KC
849 MEMCPY(x->vnic.macaddr, macaddr, MAX_MACADDR_LEN);
850 x->vnic.num_rcv_bufs = num_rcv_bufs;
851 x->vnic.mtu = mtu;
852 x->vnic.zoneGuid = zoneGuid;
853 INIT_CLIENTSTRING(x, ULTRA_IO_CHANNEL_PROTOCOL, clientStr,
854 clientStrLen);
855 SignalQInit(x);
856 if ((x->cmdQ.MaxSignalSlots > MAX_NUMSIGNALS) ||
857 (x->rspQ.MaxSignalSlots > MAX_NUMSIGNALS)) {
858 return 0;
859 }
860 if ((x->cmdQ.MaxSignalSlots < MIN_NUMSIGNALS) ||
861 (x->rspQ.MaxSignalSlots < MIN_NUMSIGNALS)) {
862 return 0;
863 }
864 return 1;
865}
866
867#endif /* __GNUC__ */
868
869/*
870* INLINE function for expanding a guest's pfn-off-size into multiple 4K page
871* pfn-off-size entires.
872*/
873
874
875/* we deal with 4K page sizes when we it comes to passing page information
876 * between */
877/* Guest and IOPartition. */
878#define PI_PAGE_SIZE 0x1000
879#define PI_PAGE_MASK 0x0FFF
880#define PI_PAGE_SHIFT 12
881
882/* returns next non-zero index on success or zero on failure (i.e. out of
883 * room)
884 */
885static INLINE U16
886add_physinfo_entries(U32 inp_pfn, /* input - specifies the pfn to be used
887 * to add entries */
888 U16 inp_off, /* input - specifies the off to be used
889 * to add entries */
890 U32 inp_len, /* input - specifies the len to be used
891 * to add entries */
892 U16 index, /* input - index in array at which new
893 * entries are added */
894 U16 max_pi_arr_entries, /* input - specifies the maximum
895 * entries pi_arr can hold */
896 struct phys_info pi_arr[]) /* input & output - array to
897 * which entries are added */
898{
899 U32 len;
900 U16 i, firstlen;
901
902 firstlen = PI_PAGE_SIZE - inp_off;
903 if (inp_len <= firstlen) {
904
905 /* the input entry spans only one page - add as is */
906 if (index >= max_pi_arr_entries)
907 return 0;
908 pi_arr[index].pi_pfn = inp_pfn;
909 pi_arr[index].pi_off = (U16) inp_off;
910 pi_arr[index].pi_len = (U16) inp_len;
911 return index + 1;
912 }
913
914 /* this entry spans multiple pages */
915 for (len = inp_len, i = 0; len;
916 len -= pi_arr[index + i].pi_len, i++) {
917 if (index + i >= max_pi_arr_entries)
918 return 0;
919 pi_arr[index + i].pi_pfn = inp_pfn + i;
920 if (i == 0) {
921 pi_arr[index].pi_off = inp_off;
922 pi_arr[index].pi_len = firstlen;
923 }
924
925 else {
926 pi_arr[index + i].pi_off = 0;
927 pi_arr[index + i].pi_len =
928 (U16) MINNUM(len, (U32) PI_PAGE_SIZE);
929 }
930
931 }
932 return index + i;
933}
934
935#endif /* __IOCHANNEL_H__ */