Home | History | Annotate | Download | only in include
      1 #ifndef SG_PT_WIN32_H
      2 #define SG_PT_WIN32_H
      3 /*
      4  * The information in this file was obtained from scsi-wnt.h by
      5  * Richard Stemmer, rs (at) epost.de . He in turn gives credit to
      6  * Jay A. Key (for scsipt.c).
      7  * The plscsi program (by Pat LaVarre <p.lavarre (at) ieee.org>) has
      8  * also been used as a reference.
      9  * Much of the information in this header can also be obtained
     10  * from msdn.microsoft.com .
     11  * Updated for cygwin version 1.7.17 changes 20121026
     12  */
     13 
     14 /* WIN32_LEAN_AND_MEAN may be required to prevent inclusion of <winioctl.h> */
     15 #define WIN32_LEAN_AND_MEAN
     16 #include <windows.h>
     17 
     18 #ifdef __cplusplus
     19 extern "C" {
     20 #endif
     21 
     22 #define SCSI_MAX_SENSE_LEN 64
     23 #define SCSI_MAX_CDB_LEN 16
     24 #define SCSI_MAX_INDIRECT_DATA 16384
     25 
     26 typedef struct {
     27     USHORT          Length;
     28     UCHAR           ScsiStatus;
     29     UCHAR           PathId;
     30     UCHAR           TargetId;
     31     UCHAR           Lun;
     32     UCHAR           CdbLength;
     33     UCHAR           SenseInfoLength;
     34     UCHAR           DataIn;
     35     ULONG           DataTransferLength;
     36     ULONG           TimeOutValue;
     37     ULONG_PTR       DataBufferOffset;  /* was ULONG; problem in 64 bit */
     38     ULONG           SenseInfoOffset;
     39     UCHAR           Cdb[SCSI_MAX_CDB_LEN];
     40 } SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
     41 
     42 
     43 typedef struct {
     44     USHORT          Length;
     45     UCHAR           ScsiStatus;
     46     UCHAR           PathId;
     47     UCHAR           TargetId;
     48     UCHAR           Lun;
     49     UCHAR           CdbLength;
     50     UCHAR           SenseInfoLength;
     51     UCHAR           DataIn;
     52     ULONG           DataTransferLength;
     53     ULONG           TimeOutValue;
     54     PVOID           DataBuffer;
     55     ULONG           SenseInfoOffset;
     56     UCHAR           Cdb[SCSI_MAX_CDB_LEN];
     57 } SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
     58 
     59 
     60 typedef struct {
     61     SCSI_PASS_THROUGH spt;
     62     /* plscsi shows a follow on 16 bytes allowing 32 byte cdb */
     63     ULONG           Filler;
     64     UCHAR           ucSenseBuf[SCSI_MAX_SENSE_LEN];
     65     UCHAR           ucDataBuf[SCSI_MAX_INDIRECT_DATA];
     66 } SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;
     67 
     68 
     69 typedef struct {
     70     SCSI_PASS_THROUGH_DIRECT spt;
     71     ULONG           Filler;
     72     UCHAR           ucSenseBuf[SCSI_MAX_SENSE_LEN];
     73 } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
     74 
     75 
     76 
     77 typedef struct {
     78     UCHAR           NumberOfLogicalUnits;
     79     UCHAR           InitiatorBusId;
     80     ULONG           InquiryDataOffset;
     81 } SCSI_BUS_DATA, *PSCSI_BUS_DATA;
     82 
     83 
     84 typedef struct {
     85     UCHAR           NumberOfBusses;
     86     SCSI_BUS_DATA   BusData[1];
     87 } SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO;
     88 
     89 
     90 typedef struct {
     91     UCHAR           PathId;
     92     UCHAR           TargetId;
     93     UCHAR           Lun;
     94     BOOLEAN         DeviceClaimed;
     95     ULONG           InquiryDataLength;
     96     ULONG           NextInquiryDataOffset;
     97     UCHAR           InquiryData[1];
     98 } SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
     99 
    100 
    101 typedef struct {
    102     ULONG           Length;
    103     UCHAR           PortNumber;
    104     UCHAR           PathId;
    105     UCHAR           TargetId;
    106     UCHAR           Lun;
    107 } SCSI_ADDRESS, *PSCSI_ADDRESS;
    108 
    109 /*
    110  * Standard IOCTL define
    111  */
    112 #ifndef CTL_CODE
    113 #define CTL_CODE(DevType, Function, Method, Access)             \
    114         (((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
    115 #endif
    116 
    117 /*
    118  * file access values
    119  */
    120 #ifndef FILE_ANY_ACCESS
    121 #define FILE_ANY_ACCESS         0
    122 #endif
    123 #ifndef FILE_READ_ACCESS
    124 #define FILE_READ_ACCESS        0x0001
    125 #endif
    126 #ifndef FILE_WRITE_ACCESS
    127 #define FILE_WRITE_ACCESS       0x0002
    128 #endif
    129 
    130 // IOCTL_STORAGE_QUERY_PROPERTY
    131 
    132 #define FILE_DEVICE_MASS_STORAGE    0x0000002d
    133 #define IOCTL_STORAGE_BASE          FILE_DEVICE_MASS_STORAGE
    134 #define FILE_ANY_ACCESS             0
    135 
    136 // #define METHOD_BUFFERED             0
    137 
    138 #define IOCTL_STORAGE_QUERY_PROPERTY \
    139     CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
    140 
    141 
    142 #ifndef _DEVIOCTL_
    143 typedef enum _STORAGE_BUS_TYPE {
    144     BusTypeUnknown      = 0x00,
    145     BusTypeScsi         = 0x01,
    146     BusTypeAtapi        = 0x02,
    147     BusTypeAta          = 0x03,
    148     BusType1394         = 0x04,
    149     BusTypeSsa          = 0x05,
    150     BusTypeFibre        = 0x06,
    151     BusTypeUsb          = 0x07,
    152     BusTypeRAID         = 0x08,
    153     BusTypeiScsi        = 0x09,
    154     BusTypeSas          = 0x0A,
    155     BusTypeSata         = 0x0B,
    156     BusTypeSd           = 0x0C,
    157     BusTypeMmc          = 0x0D,
    158     BusTypeVirtual             = 0xE,
    159     BusTypeFileBackedVirtual   = 0xF,
    160     BusTypeSpaces       = 0x10,
    161     BusTypeNvme         = 0x11,
    162     BusTypeSCM          = 0x12,
    163     BusTypeUfs          = 0x13,
    164     BusTypeMax          = 0x14,
    165     BusTypeMaxReserved  = 0x7F
    166 } STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;
    167 
    168 typedef enum _STORAGE_PROTOCOL_TYPE {
    169     ProtocolTypeUnknown = 0,
    170     ProtocolTypeScsi,
    171     ProtocolTypeAta,
    172     ProtocolTypeNvme,
    173     ProtocolTypeSd
    174 } STORAGE_PROTOCOL_TYPE;
    175 
    176 typedef enum _STORAGE_PROTOCOL_NVME_DATA_TYPE {
    177     NVMeDataTypeUnknown = 0,
    178     NVMeDataTypeIdentify,
    179     NVMeDataTypeLogPage,
    180     NVMeDataTypeFeature
    181 } STORAGE_PROTOCOL_NVME_DATA_TYPE;
    182 
    183 typedef struct _STORAGE_PROTOCOL_SPECIFIC_DATA {
    184     STORAGE_PROTOCOL_TYPE ProtocolType;
    185     ULONG DataType;
    186     ULONG ProtocolDataRequestValue;
    187     ULONG ProtocolDataRequestSubValue;
    188     ULONG ProtocolDataOffset;
    189     ULONG ProtocolDataLength;
    190     ULONG FixedProtocolReturnData;
    191     ULONG Reserved[3];
    192 } STORAGE_PROTOCOL_SPECIFIC_DATA;
    193 
    194 
    195 typedef struct _STORAGE_DEVICE_DESCRIPTOR {
    196     ULONG Version;
    197     ULONG Size;
    198     UCHAR DeviceType;
    199     UCHAR DeviceTypeModifier;
    200     BOOLEAN RemovableMedia;
    201     BOOLEAN CommandQueueing;
    202     ULONG VendorIdOffset;       /* 0 if not available */
    203     ULONG ProductIdOffset;      /* 0 if not available */
    204     ULONG ProductRevisionOffset;/* 0 if not available */
    205     ULONG SerialNumberOffset;   /* -1 if not available ?? */
    206     STORAGE_BUS_TYPE BusType;
    207     ULONG RawPropertiesLength;
    208     UCHAR RawDeviceProperties[1];
    209 } STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
    210 
    211 #define STORAGE_PROTOCOL_STRUCTURE_VERSION 0x1
    212 
    213 #define IOCTL_STORAGE_PROTOCOL_COMMAND \
    214         CTL_CODE(IOCTL_STORAGE_BASE, 0x04F0, METHOD_BUFFERED, \
    215                 FILE_READ_ACCESS | FILE_WRITE_ACCESS)
    216 
    217 typedef struct _STORAGE_PROTOCOL_COMMAND {
    218     DWORD         Version;        /* STORAGE_PROTOCOL_STRUCTURE_VERSION */
    219     DWORD         Length;
    220     STORAGE_PROTOCOL_TYPE   ProtocolType;
    221     DWORD         Flags;
    222     DWORD         ReturnStatus;
    223     DWORD         ErrorCode;
    224     DWORD         CommandLength;
    225     DWORD         ErrorInfoLength;
    226     DWORD         DataToDeviceTransferLength;
    227     DWORD         DataFromDeviceTransferLength;
    228     DWORD         TimeOutValue;
    229     DWORD         ErrorInfoOffset;
    230     DWORD         DataToDeviceBufferOffset;
    231     DWORD         DataFromDeviceBufferOffset;
    232     DWORD         CommandSpecific;
    233     DWORD         Reserved0;
    234     DWORD         FixedProtocolReturnData;
    235     DWORD         Reserved1[3];
    236     BYTE          Command[1];     /* has CommandLength elements */
    237 } STORAGE_PROTOCOL_COMMAND, *PSTORAGE_PROTOCOL_COMMAND;
    238 
    239 #endif          /* _DEVIOCTL_ */
    240 
    241 typedef struct _STORAGE_DEVICE_UNIQUE_IDENTIFIER {
    242     ULONG  Version;
    243     ULONG  Size;
    244     ULONG  StorageDeviceIdOffset;
    245     ULONG  StorageDeviceOffset;
    246     ULONG  DriveLayoutSignatureOffset;
    247 } STORAGE_DEVICE_UNIQUE_IDENTIFIER, *PSTORAGE_DEVICE_UNIQUE_IDENTIFIER;
    248 
    249 // Use CompareStorageDuids(PSTORAGE_DEVICE_UNIQUE_IDENTIFIER duid1, duid2)
    250 // to test for equality
    251 
    252 #ifndef _DEVIOCTL_
    253 typedef enum _STORAGE_QUERY_TYPE {
    254     PropertyStandardQuery = 0,
    255     PropertyExistsQuery,
    256     PropertyMaskQuery,
    257     PropertyQueryMaxDefined
    258 } STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
    259 
    260 typedef enum _STORAGE_PROPERTY_ID {
    261     StorageDeviceProperty = 0,
    262     StorageAdapterProperty,
    263     StorageDeviceIdProperty,
    264     StorageDeviceUniqueIdProperty,
    265     StorageDeviceWriteCacheProperty,
    266     StorageMiniportProperty,
    267     StorageAccessAlignmentProperty,
    268     /* Identify controller goes to adapter; Identify namespace to device */
    269     StorageAdapterProtocolSpecificProperty = 49,
    270     StorageDeviceProtocolSpecificProperty = 50
    271 } STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
    272 
    273 typedef struct _STORAGE_PROPERTY_QUERY {
    274     STORAGE_PROPERTY_ID PropertyId;
    275     STORAGE_QUERY_TYPE QueryType;
    276     UCHAR AdditionalParameters[1];
    277 } STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
    278 
    279 typedef struct _STORAGE_PROTOCOL_DATA_DESCRIPTOR {
    280     DWORD  Version;
    281     DWORD  Size;
    282     STORAGE_PROTOCOL_SPECIFIC_DATA ProtocolSpecificData;
    283 } STORAGE_PROTOCOL_DATA_DESCRIPTOR, *PSTORAGE_PROTOCOL_DATA_DESCRIPTOR;
    284 
    285 // Command completion status
    286 // The "Phase Tag" field and "Status Field" are separated in spec. We define
    287 // them in the same data structure to ease the memory access from software.
    288 //
    289 typedef union {
    290     struct {
    291         USHORT  P           : 1;        // Phase Tag (P)
    292 
    293         USHORT  SC          : 8;        // Status Code (SC)
    294         USHORT  SCT         : 3;        // Status Code Type (SCT)
    295         USHORT  Reserved    : 2;
    296         USHORT  M           : 1;        // More (M)
    297         USHORT  DNR         : 1;        // Do Not Retry (DNR)
    298     } DUMMYSTRUCTNAME;
    299     USHORT AsUshort;
    300 } NVME_COMMAND_STATUS, *PNVME_COMMAND_STATUS;
    301 
    302 // Information of log: NVME_LOG_PAGE_ERROR_INFO. Size: 64 bytes
    303 //
    304 typedef struct {
    305     ULONGLONG  ErrorCount;
    306     USHORT     SQID;           // Submission Queue ID
    307     USHORT     CMDID;          // Command ID
    308     NVME_COMMAND_STATUS Status; // Status Field: This field indicates the
    309                                 // Status Field for the command that
    310                                 // completed. The Status Field is located in
    311                                 // bits 15:01, bit 00 corresponds to the Phase
    312                                 // Tag posted for the command.
    313     struct {
    314         USHORT  Byte        : 8;   // Byte in command that contained error
    315         USHORT  Bit         : 3;   // Bit in command that contained error
    316         USHORT  Reserved    : 5;
    317     } ParameterErrorLocation;
    318 
    319     ULONGLONG  Lba;            // LBA: This field indicates the first LBA
    320                                // that experienced the error condition, if
    321                                // applicable.
    322     ULONG      NameSpace;      // Namespace: This field indicates the nsid
    323                                // that the error is associated with, if
    324                                // applicable.
    325     UCHAR      VendorInfoAvailable;    // Vendor Specific Information Available
    326     UCHAR      Reserved0[3];
    327     ULONGLONG  CommandSpecificInfo;    // This field contains command specific
    328                                        // information. If used, the command
    329                                        // definition specifies the information
    330                                        // returned.
    331     UCHAR      Reserved1[24];
    332 } NVME_ERROR_INFO_LOG, *PNVME_ERROR_INFO_LOG;
    333 
    334 typedef struct {
    335 
    336     ULONG   DW0;
    337     ULONG   Reserved;
    338 
    339     union {
    340         struct {
    341             USHORT  SQHD;               // SQ Head Pointer (SQHD)
    342             USHORT  SQID;               // SQ Identifier (SQID)
    343         } DUMMYSTRUCTNAME;
    344 
    345         ULONG   AsUlong;
    346     } DW2;
    347 
    348     union {
    349         struct {
    350             USHORT              CID;    // Command Identifier (CID)
    351             NVME_COMMAND_STATUS Status;
    352         } DUMMYSTRUCTNAME;
    353 
    354         ULONG   AsUlong;
    355     } DW3;
    356 
    357 } NVME_COMPLETION_ENTRY, *PNVME_COMPLETION_ENTRY;
    358 
    359 
    360 // Bit-mask values for STORAGE_PROTOCOL_COMMAND - "Flags" field.
    361 //
    362 // Flag indicates the request targeting to adapter instead of device.
    363 #define STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST    0x80000000
    364 
    365 //
    366 // Status values for STORAGE_PROTOCOL_COMMAND - "ReturnStatus" field.
    367 //
    368 #define STORAGE_PROTOCOL_STATUS_PENDING                 0x0
    369 #define STORAGE_PROTOCOL_STATUS_SUCCESS                 0x1
    370 #define STORAGE_PROTOCOL_STATUS_ERROR                   0x2
    371 #define STORAGE_PROTOCOL_STATUS_INVALID_REQUEST         0x3
    372 #define STORAGE_PROTOCOL_STATUS_NO_DEVICE               0x4
    373 #define STORAGE_PROTOCOL_STATUS_BUSY                    0x5
    374 #define STORAGE_PROTOCOL_STATUS_DATA_OVERRUN            0x6
    375 #define STORAGE_PROTOCOL_STATUS_INSUFFICIENT_RESOURCES  0x7
    376 
    377 #define STORAGE_PROTOCOL_STATUS_NOT_SUPPORTED           0xFF
    378 
    379 // Command Length for Storage Protocols.
    380 //
    381 // NVMe commands are always 64 bytes.
    382 #define STORAGE_PROTOCOL_COMMAND_LENGTH_NVME            0x40
    383 
    384 // Command Specific Information for Storage Protocols - CommandSpecific field
    385 //
    386 #define STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND    0x01
    387 #define STORAGE_PROTOCOL_SPECIFIC_NVME_NVM_COMMAND 0x02
    388 
    389 #endif          /* _DEVIOCTL_ */
    390 
    391 
    392 // NVME_PASS_THROUGH
    393 
    394 #ifndef STB_IO_CONTROL
    395 typedef struct _SRB_IO_CONTROL {
    396     ULONG HeaderLength;
    397     UCHAR Signature[8];
    398     ULONG Timeout;
    399     ULONG ControlCode;
    400     ULONG ReturnCode;
    401     ULONG Length;
    402 } SRB_IO_CONTROL, *PSRB_IO_CONTROL;
    403 #endif
    404 
    405 #ifndef NVME_PASS_THROUGH_SRB_IO_CODE
    406 
    407 #define NVME_SIG_STR "NvmeMini"
    408 #define NVME_STORPORT_DRIVER 0xe000
    409 
    410 #define NVME_PASS_THROUGH_SRB_IO_CODE \
    411   CTL_CODE(NVME_STORPORT_DRIVER, 0x0800, METHOD_BUFFERED, FILE_ANY_ACCESS)
    412 
    413 #pragma pack(1)
    414 
    415 /* Following is pre-Win10; used with DeviceIoControl(IOCTL_SCSI_MINIPORT),
    416  * in Win10 need DeviceIoControl(IOCTL_STORAGE_PROTOCOL_COMMAND) for pure
    417  * pass-through. Win10 also has "Protocol specific queries" for things like
    418  * Identify and Get feature. */
    419 typedef struct _NVME_PASS_THROUGH_IOCTL
    420 {
    421     SRB_IO_CONTROL SrbIoCtrl;
    422     ULONG VendorSpecific[6];
    423     ULONG NVMeCmd[16];      /* Command DW[0...15] */
    424     ULONG CplEntry[4];      /* Completion DW[0...3] */
    425     ULONG Direction;        /* 0=None, 1=Out, 2=In, 3=I/O */
    426     ULONG QueueId;          /* 0=AdminQ */
    427     ULONG DataBufferLen;    /* sizeof(DataBuffer) if Data In */
    428     ULONG MetaDataLen;
    429     ULONG ReturnBufferLen;  /* offsetof(DataBuffer), plus
    430                              * sizeof(DataBuffer) if Data Out */
    431     UCHAR DataBuffer[1];
    432 } NVME_PASS_THROUGH_IOCTL;
    433 #pragma pack()
    434 
    435 #endif // NVME_PASS_THROUGH_SRB_IO_CODE
    436 
    437 
    438 /*
    439  * method codes
    440  */
    441 #define METHOD_BUFFERED         0
    442 #define METHOD_IN_DIRECT        1
    443 #define METHOD_OUT_DIRECT       2
    444 #define METHOD_NEITHER          3
    445 
    446 
    447 #define IOCTL_SCSI_BASE    0x00000004
    448 
    449 /*
    450  * constants for DataIn member of SCSI_PASS_THROUGH* structures
    451  */
    452 #define SCSI_IOCTL_DATA_OUT             0
    453 #define SCSI_IOCTL_DATA_IN              1
    454 #define SCSI_IOCTL_DATA_UNSPECIFIED     2
    455 
    456 #define IOCTL_SCSI_PASS_THROUGH         CTL_CODE(IOCTL_SCSI_BASE, 0x0401, \
    457         METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
    458 #define IOCTL_SCSI_MINIPORT             CTL_CODE(IOCTL_SCSI_BASE, 0x0402, \
    459         METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
    460 #define IOCTL_SCSI_GET_INQUIRY_DATA     CTL_CODE(IOCTL_SCSI_BASE, 0x0403, \
    461         METHOD_BUFFERED, FILE_ANY_ACCESS)
    462 #define IOCTL_SCSI_GET_CAPABILITIES     CTL_CODE(IOCTL_SCSI_BASE, 0x0404, \
    463         METHOD_BUFFERED, FILE_ANY_ACCESS)
    464 #define IOCTL_SCSI_PASS_THROUGH_DIRECT  CTL_CODE(IOCTL_SCSI_BASE, 0x0405, \
    465         METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
    466 #define IOCTL_SCSI_GET_ADDRESS          CTL_CODE(IOCTL_SCSI_BASE, 0x0406, \
    467         METHOD_BUFFERED, FILE_ANY_ACCESS)
    468 
    469 #ifdef __cplusplus
    470 }
    471 #endif
    472 
    473 #endif
    474