1 /* 2 * Copyright (C) 2008-2014, VMware, Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 1. Redistributions of source code must retain the above copyright notice, 7 * this list of conditions and the following disclaimer. 8 * 2. Redistributions in binary form must reproduce the above copyright notice, 9 * this list of conditions and the following disclaimer in the documentation 10 * and/or other materials provided with the distribution. 11 * 12 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 13 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY 16 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 19 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 */ 23 24 #ifndef _PVSCSI_H_ 25 #define _PVSCSI_H_ 26 27 #include <sys/types.h> 28 29 #define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128 30 31 #define MASK(n) ((1 << (n)) - 1) /* make an n-bit mask */ 32 33 #define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0 34 35 /* 36 * host adapter status/error codes 37 */ 38 enum HostBusAdapterStatus { 39 BTSTAT_SUCCESS = 0x00, /* CCB complete normally with */ 40 /* no errors */ 41 BTSTAT_LINKED_COMMAND_COMPLETED = 0x0a, 42 BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b, 43 BTSTAT_DATA_UNDERRUN = 0x0c, 44 BTSTAT_SELTIMEO = 0x11, /* SCSI selection timeout */ 45 BTSTAT_DATARUN = 0x12, /* data overrun/underrun */ 46 BTSTAT_BUSFREE = 0x13, /* unexpected bus free */ 47 BTSTAT_INVPHASE = 0x14, /* invalid bus phase or sequence */ 48 /* requested by target */ 49 BTSTAT_LUNMISMATCH = 0x17, /* linked CCB has different LUN from */ 50 /* first CCB */ 51 BTSTAT_INVPARAM = 0x1a, /* invalid parameter in CCB */ 52 /* or segment list */ 53 BTSTAT_SENSFAILED = 0x1b, /* auto request sense failed */ 54 BTSTAT_TAGREJECT = 0x1c, /* SCSI II tagged queueing message */ 55 /* rejected by target */ 56 BTSTAT_BADMSG = 0x1d, /* unsupported message received by */ 57 /* the host adapter */ 58 BTSTAT_HAHARDWARE = 0x20, /* host adapter hardware failed */ 59 BTSTAT_NORESPONSE = 0x21, /* target did not respond to */ 60 /* SCSI ATN, sent a SCSI RST */ 61 BTSTAT_SENTRST = 0x22, /* host adapter asserted a SCSI RST */ 62 BTSTAT_RECVRST = 0x23, /* other SCSI devices asserted */ 63 /* a SCSI RST */ 64 BTSTAT_DISCONNECT = 0x24, /* target device reconnected */ 65 /* improperly (w/o tag) */ 66 BTSTAT_BUSRESET = 0x25, /* host adapter issued */ 67 /* BUS device reset */ 68 BTSTAT_ABORTQUEUE = 0x26, /* abort queue generated */ 69 BTSTAT_HASOFTWARE = 0x27, /* host adapter software error */ 70 BTSTAT_HATIMEOUT = 0x30, /* host adapter hardware */ 71 /* timeout error */ 72 BTSTAT_SCSIPARITY = 0x34, /* SCSI parity error detected */ 73 }; 74 75 /* 76 * SCSI device status values. 77 */ 78 enum ScsiDeviceStatus { 79 SDSTAT_GOOD = 0x00, /* No errors. */ 80 SDSTAT_CHECK = 0x02, /* Check condition. */ 81 }; 82 83 /* 84 * Register offsets. 85 * 86 * These registers are accessible both via i/o space and mm i/o. 87 */ 88 89 enum PVSCSIRegOffset { 90 PVSCSI_REG_OFFSET_COMMAND = 0x0, 91 PVSCSI_REG_OFFSET_COMMAND_DATA = 0x4, 92 PVSCSI_REG_OFFSET_COMMAND_STATUS = 0x8, 93 PVSCSI_REG_OFFSET_LAST_STS_0 = 0x100, 94 PVSCSI_REG_OFFSET_LAST_STS_1 = 0x104, 95 PVSCSI_REG_OFFSET_LAST_STS_2 = 0x108, 96 PVSCSI_REG_OFFSET_LAST_STS_3 = 0x10c, 97 PVSCSI_REG_OFFSET_INTR_STATUS = 0x100c, 98 PVSCSI_REG_OFFSET_INTR_MASK = 0x2010, 99 PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014, 100 PVSCSI_REG_OFFSET_DEBUG = 0x3018, 101 PVSCSI_REG_OFFSET_KICK_RW_IO = 0x4018, 102 }; 103 104 /* 105 * Virtual h/w commands. 106 */ 107 108 enum PVSCSICommands { 109 PVSCSI_CMD_FIRST = 0, /* has to be first */ 110 111 PVSCSI_CMD_ADAPTER_RESET = 1, 112 PVSCSI_CMD_ISSUE_SCSI = 2, 113 PVSCSI_CMD_SETUP_RINGS = 3, 114 PVSCSI_CMD_RESET_BUS = 4, 115 PVSCSI_CMD_RESET_DEVICE = 5, 116 PVSCSI_CMD_ABORT_CMD = 6, 117 PVSCSI_CMD_CONFIG = 7, 118 PVSCSI_CMD_SETUP_MSG_RING = 8, 119 PVSCSI_CMD_DEVICE_UNPLUG = 9, 120 PVSCSI_CMD_SETUP_REQCALLTHRESHOLD = 10, 121 122 PVSCSI_CMD_LAST = 11 /* has to be last */ 123 }; 124 125 /* 126 * Command descriptor for PVSCSI_CMD_RESET_DEVICE -- 127 */ 128 #pragma pack(1) 129 struct PVSCSICmdDescResetDevice { 130 uint32_t target; 131 uint8_t lun[8]; 132 }; 133 #pragma pack() 134 135 /* 136 * Command descriptor for PVSCSI_CMD_CONFIG -- 137 */ 138 #pragma pack(1) 139 struct PVSCSICmdDescConfigCmd { 140 uint64_t cmpAddr; 141 uint64_t configPageAddress; 142 uint32_t configPageNum; 143 uint32_t _pad; 144 }; 145 #pragma pack() 146 147 /* 148 * Command descriptor for PVSCSI_CMD_SETUP_REQCALLTHRESHOLD -- 149 */ 150 #pragma pack(1) 151 struct PVSCSICmdDescSetupReqCall { 152 uint32_t enable; 153 }; 154 #pragma pack() 155 156 enum PVSCSIConfigPageType { 157 PVSCSI_CONFIG_PAGE_CONTROLLER = 0x1958, 158 PVSCSI_CONFIG_PAGE_PHY = 0x1959, 159 PVSCSI_CONFIG_PAGE_DEVICE = 0x195a, 160 }; 161 162 enum PVSCSIConfigPageAddressType { 163 PVSCSI_CONFIG_CONTROLLER_ADDRESS = 0x2120, 164 PVSCSI_CONFIG_BUSTARGET_ADDRESS = 0x2121, 165 PVSCSI_CONFIG_PHY_ADDRESS = 0x2122, 166 }; 167 168 /* 169 * Command descriptor for PVSCSI_CMD_ABORT_CMD -- 170 * 171 * - currently does not support specifying the LUN. 172 * - _pad should be 0. 173 */ 174 175 struct PVSCSICmdDescAbortCmd { 176 uint64_t context; 177 uint32_t target; 178 uint32_t _pad; 179 } __packed; 180 181 /* 182 * Command descriptor for PVSCSI_CMD_SETUP_RINGS -- 183 * 184 * Notes: 185 * - reqRingNumPages and cmpRingNumPages need to be power of two. 186 * - reqRingNumPages and cmpRingNumPages need to be different from 0, 187 * - reqRingNumPages and cmpRingNumPages need to be inferior to 188 * PVSCSI_SETUP_RINGS_MAX_NUM_PAGES. 189 */ 190 #define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 32 191 192 #pragma pack(1) 193 struct PVSCSICmdDescSetupRings { 194 uint32_t reqRingNumPages; 195 uint32_t cmpRingNumPages; 196 uint64_t ringsStatePPN; 197 uint64_t reqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; 198 uint64_t cmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; 199 }; 200 #pragma pack() 201 202 /* 203 * Command descriptor for PVSCSI_CMD_SETUP_MSG_RING -- 204 * 205 * Notes: 206 * - this command was not supported in the initial revision of the h/w 207 * interface. Before using it, you need to check that it is supported by 208 * writing PVSCSI_CMD_SETUP_MSG_RING to the 'command' register, then 209 * immediately after read the 'command status' register: 210 * * a value of -1 means that the cmd is NOT supported, 211 * * a value != -1 means that the cmd IS supported. 212 * If it's supported the 'command status' register should return: 213 * sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(uint32_t). 214 * - this command should be issued _after_ the usual SETUP_RINGS so that the 215 * RingsState page is already setup. If not, the command is a nop. 216 * - numPages needs to be a power of two, 217 * - numPages needs to be different from 0, 218 * - _pad should be zero. 219 */ 220 #define PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES 16 221 222 #pragma pack(1) 223 struct PVSCSICmdDescSetupMsgRing { 224 uint32_t numPages; 225 uint32_t _pad; 226 uint64_t ringPPNs[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES]; 227 }; 228 #pragma pack() 229 230 enum PVSCSIMsgType { 231 PVSCSI_MSG_DEV_ADDED = 0, 232 PVSCSI_MSG_DEV_REMOVED = 1, 233 PVSCSI_MSG_LAST = 2, 234 }; 235 236 /* 237 * Msg descriptor. 238 * 239 * sizeof(struct PVSCSIRingMsgDesc) == 128. 240 * 241 * - type is of type enum PVSCSIMsgType. 242 * - the content of args depend on the type of event being delivered. 243 */ 244 #pragma pack(1) 245 struct PVSCSIRingMsgDesc { 246 uint32_t type; 247 uint32_t args[31]; 248 }; 249 #pragma pack() 250 251 #pragma pack(1) 252 struct PVSCSIMsgDescDevStatusChanged { 253 uint32_t type; /* PVSCSI_MSG_DEV _ADDED / _REMOVED */ 254 uint32_t bus; 255 uint32_t target; 256 uint8_t lun[8]; 257 uint32_t pad[27]; 258 }; 259 #pragma pack() 260 261 /* 262 * Rings state. 263 * 264 * - the fields: 265 * . msgProdIdx, 266 * . msgConsIdx, 267 * . msgNumEntriesLog2, 268 * .. are only used once the SETUP_MSG_RING cmd has been issued. 269 * - '_pad' helps to ensure that the msg related fields are on their own 270 * cache-line. 271 */ 272 #pragma pack(1) 273 struct PVSCSIRingsState { 274 uint32_t reqProdIdx; 275 uint32_t reqConsIdx; 276 uint32_t reqNumEntriesLog2; 277 278 uint32_t cmpProdIdx; 279 uint32_t cmpConsIdx; 280 uint32_t cmpNumEntriesLog2; 281 282 uint32_t reqCallThreshold; 283 284 uint8_t _pad[100]; 285 286 uint32_t msgProdIdx; 287 uint32_t msgConsIdx; 288 uint32_t msgNumEntriesLog2; 289 }; 290 #pragma pack() 291 292 /* 293 * Request descriptor. 294 * 295 * sizeof(RingReqDesc) = 128 296 * 297 * - context: is a unique identifier of a command. It could normally be any 298 * 64bit value, however we currently store it in the serialNumber variable 299 * of struct SCSI_Command, so we have the following restrictions due to the 300 * way this field is handled in the vmkernel storage stack: 301 * * this value can't be 0, 302 * * the upper 32bit need to be 0 since serialNumber is as a uint32_t. 303 * Currently tracked as PR 292060. 304 * - dataLen: contains the total number of bytes that need to be transferred. 305 * - dataAddr: 306 * * if PVSCSI_FLAG_CMD_WITH_SG_LIST is set: dataAddr is the PA of the first 307 * s/g table segment, each s/g segment is entirely contained on a single 308 * page of physical memory, 309 * * if PVSCSI_FLAG_CMD_WITH_SG_LIST is NOT set, then dataAddr is the PA of 310 * the buffer used for the DMA transfer, 311 * - flags: 312 * * PVSCSI_FLAG_CMD_WITH_SG_LIST: see dataAddr above, 313 * * PVSCSI_FLAG_CMD_DIR_NONE: no DMA involved, 314 * * PVSCSI_FLAG_CMD_DIR_TOHOST: transfer from device to main memory, 315 * * PVSCSI_FLAG_CMD_DIR_TODEVICE: transfer from main memory to device, 316 * * PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB: reserved to handle CDBs larger than 317 * 16bytes. To be specified. 318 * - vcpuHint: vcpuId of the processor that will be most likely waiting for the 319 * completion of the i/o. For guest OSes that use lowest priority message 320 * delivery mode (such as windows), we use this "hint" to deliver the 321 * completion action to the proper vcpu. For now, we can use the vcpuId of 322 * the processor that initiated the i/o as a likely candidate for the vcpu 323 * that will be waiting for the completion.. 324 * - bus should be 0: we currently only support bus 0 for now. 325 * - unused should be zero'd. 326 */ 327 #define PVSCSI_FLAG_CMD_WITH_SG_LIST (1 << 0) 328 #define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB (1 << 1) 329 #define PVSCSI_FLAG_CMD_DIR_NONE (1 << 2) 330 #define PVSCSI_FLAG_CMD_DIR_TOHOST (1 << 3) 331 #define PVSCSI_FLAG_CMD_DIR_TODEVICE (1 << 4) 332 333 #pragma pack(1) 334 struct PVSCSIRingReqDesc { 335 uint64_t context; 336 uint64_t dataAddr; 337 uint64_t dataLen; 338 uint64_t senseAddr; 339 uint32_t senseLen; 340 uint32_t flags; 341 uint8_t cdb[16]; 342 uint8_t cdbLen; 343 uint8_t lun[8]; 344 uint8_t tag; 345 uint8_t bus; 346 uint8_t target; 347 uint8_t vcpuHint; 348 uint8_t unused[59]; 349 }; 350 #pragma pack() 351 352 /* 353 * Scatter-gather list management. 354 * 355 * As described above, when PVSCSI_FLAG_CMD_WITH_SG_LIST is set in the 356 * RingReqDesc.flags, then RingReqDesc.dataAddr is the PA of the first s/g 357 * table segment. 358 * 359 * - each segment of the s/g table contain a succession of struct 360 * PVSCSISGElement. 361 * - each segment is entirely contained on a single physical page of memory. 362 * - a "chain" s/g element has the flag PVSCSI_SGE_FLAG_CHAIN_ELEMENT set in 363 * PVSCSISGElement.flags and in this case: 364 * * addr is the PA of the next s/g segment, 365 * * length is undefined, assumed to be 0. 366 */ 367 #pragma pack(1) 368 struct PVSCSISGElement { 369 uint64_t addr; 370 uint32_t length; 371 uint32_t flags; 372 }; 373 #pragma pack() 374 375 /* 376 * Completion descriptor. 377 * 378 * sizeof(RingCmpDesc) = 32 379 * 380 * - context: identifier of the command. The same thing that was specified 381 * under "context" as part of struct RingReqDesc at initiation time, 382 * - dataLen: number of bytes transferred for the actual i/o operation, 383 * - senseLen: number of bytes written into the sense buffer, 384 * - hostStatus: adapter status, 385 * - scsiStatus: device status, 386 * - _pad should be zero. 387 */ 388 #pragma pack(1) 389 struct PVSCSIRingCmpDesc { 390 uint64_t context; 391 uint64_t dataLen; 392 uint32_t senseLen; 393 uint16_t hostStatus; 394 uint16_t scsiStatus; 395 uint32_t _pad[2]; 396 }; 397 #pragma pack() 398 399 #pragma pack(1) 400 struct PVSCSIConfigPageHeader { 401 uint32_t pageNum; 402 uint16_t numDwords; 403 uint16_t hostStatus; 404 uint16_t scsiStatus; 405 uint16_t reserved[3]; 406 }; 407 #pragma pack() 408 409 #pragma pack(1) 410 struct PVSCSIConfigPageController { 411 struct PVSCSIConfigPageHeader header; 412 uint64_t nodeWWN; /* Device name as defined in the SAS spec. */ 413 uint16_t manufacturer[64]; 414 uint16_t serialNumber[64]; 415 uint16_t opromVersion[32]; 416 uint16_t hwVersion[32]; 417 uint16_t firmwareVersion[32]; 418 uint32_t numPhys; 419 uint8_t useConsecutivePhyWWNs; 420 uint8_t reserved[3]; 421 }; 422 #pragma pack() 423 424 /* 425 * Interrupt status / IRQ bits. 426 */ 427 428 #define PVSCSI_INTR_CMPL_0 (1 << 0) 429 #define PVSCSI_INTR_CMPL_1 (1 << 1) 430 #define PVSCSI_INTR_CMPL_MASK MASK(2) 431 432 #define PVSCSI_INTR_MSG_0 (1 << 2) 433 #define PVSCSI_INTR_MSG_1 (1 << 3) 434 #define PVSCSI_INTR_MSG_MASK (MASK(2) << 2) 435 436 #define PVSCSI_INTR_ALL_SUPPORTED MASK(4) 437 438 /* 439 * Number of MSI-X vectors supported. 440 */ 441 #define PVSCSI_MAX_INTRS 24 442 443 /* 444 * Enumeration of supported MSI-X vectors 445 */ 446 #define PVSCSI_VECTOR_COMPLETION 0 447 448 /* 449 * Misc constants for the rings. 450 */ 451 452 #define PVSCSI_MAX_NUM_PAGES_REQ_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 453 #define PVSCSI_MAX_NUM_PAGES_CMP_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 454 #define PVSCSI_MAX_NUM_PAGES_MSG_RING PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES 455 456 #define PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \ 457 (PAGE_SIZE / sizeof (struct PVSCSIRingReqDesc)) 458 459 #define PVSCSI_MAX_REQ_QUEUE_DEPTH \ 460 (PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE) 461 462 #define PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES 1 463 #define PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES 1 464 #define PVSCSI_MEM_SPACE_MISC_NUM_PAGES 2 465 #define PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES 2 466 #define PVSCSI_MEM_SPACE_MSIX_NUM_PAGES 2 467 468 enum PVSCSIMemSpace { 469 PVSCSI_MEM_SPACE_COMMAND_PAGE = 0, 470 PVSCSI_MEM_SPACE_INTR_STATUS_PAGE = 1, 471 PVSCSI_MEM_SPACE_MISC_PAGE = 2, 472 PVSCSI_MEM_SPACE_KICK_IO_PAGE = 4, 473 PVSCSI_MEM_SPACE_MSIX_TABLE_PAGE = 6, 474 PVSCSI_MEM_SPACE_MSIX_PBA_PAGE = 7, 475 }; 476 477 #define PVSCSI_MEM_SPACE_NUM_PAGES \ 478 (PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES + \ 479 PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES +\ 480 PVSCSI_MEM_SPACE_MISC_NUM_PAGES + \ 481 PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES + \ 482 PVSCSI_MEM_SPACE_MSIX_NUM_PAGES) 483 484 #define PVSCSI_MEM_SPACE_SIZE (PVSCSI_MEM_SPACE_NUM_PAGES * PAGE_SIZE) 485 486 #endif /* _PVSCSI_H_ */ 487