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