• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@epost.de . He in turn gives credit to
6  * Jay A. Key (for scsipt.c).
7  * The plscsi program (by Pat LaVarre <p.lavarre@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          /* SG_PT_WIN32_H */
474