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