xref: /reactos/drivers/usb/usbstor/usbstor.h (revision 4f0b8d3d)
1 
2 #pragma once
3 
4 #include <ntddk.h>
5 #define NDEBUG
6 #include <debug.h>
7 #include <usbdi.h>
8 #include <hubbusif.h>
9 #include <usbbusif.h>
10 #include <usbioctl.h>
11 #include <usbiodef.h>
12 #include <usb.h>
13 #include <usbdlib.h>
14 #include <stdio.h>
15 #include <wdmguid.h>
16 #include <classpnp.h>
17 #include <scsi.h>
18 
19 #define USB_STOR_TAG 'sbsu'
20 #define USB_MAXCHILDREN              (16)
21 
22 
23 
24 #define HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
25 #define NTOHS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
26 
27 #define HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
28                   ((((unsigned long)(n) & 0xFF00)) << 8) | \
29                   ((((unsigned long)(n) & 0xFF0000)) >> 8) | \
30                   ((((unsigned long)(n) & 0xFF000000)) >> 24))
31 
32 
33 #define NTOHL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
34                   ((((unsigned long)(n) & 0xFF00)) << 8) | \
35                   ((((unsigned long)(n) & 0xFF0000)) >> 8) | \
36                   ((((unsigned long)(n) & 0xFF000000)) >> 24))
37 
38 #define USB_RECOVERABLE_ERRORS (USBD_STATUS_STALL_PID | USBD_STATUS_DEV_NOT_RESPONDING \
39 	| USBD_STATUS_ENDPOINT_HALTED | USBD_STATUS_NO_BANDWIDTH)
40 
41 typedef struct __COMMON_DEVICE_EXTENSION__
42 {
43     BOOLEAN IsFDO;
44 
45 }USBSTOR_COMMON_DEVICE_EXTENSION, *PUSBSTOR_COMMON_DEVICE_EXTENSION;
46 
47 typedef struct
48 {
49     USBSTOR_COMMON_DEVICE_EXTENSION Common;                                                      // common device extension
50 
51     PDEVICE_OBJECT FunctionalDeviceObject;                                               // functional device object
52     PDEVICE_OBJECT PhysicalDeviceObject;                                                 // physical device object
53     PDEVICE_OBJECT LowerDeviceObject;                                                    // lower device object
54     USB_BUS_INTERFACE_USBDI_V2 BusInterface;                                             // bus interface of device
55     PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;                                             // usb device descriptor
56     PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;                               // usb configuration descriptor
57     PUSB_STRING_DESCRIPTOR SerialNumber;                                                 // usb serial number
58     PUSBD_INTERFACE_INFORMATION InterfaceInformation;                                    // usb interface information
59     USBD_CONFIGURATION_HANDLE ConfigurationHandle;                                       // usb configuration handle
60     UCHAR BulkInPipeIndex;                                                               // bulk in pipe index
61     UCHAR BulkOutPipeIndex;                                                              // bulk out pipe index
62     UCHAR MaxLUN;                                                                        // max lun for device
63     PDEVICE_OBJECT ChildPDO[16];                                                         // max 16 child pdo devices
64     KSPIN_LOCK IrpListLock;                                                              // irp list lock
65     LIST_ENTRY IrpListHead;                                                              // irp list head
66     BOOLEAN IrpListFreeze;                                                               // if true the irp list is freezed
67     BOOLEAN ResetInProgress;                                                             // if hard reset is in progress
68     ULONG IrpPendingCount;                                                               // count of irp pending
69     PSCSI_REQUEST_BLOCK ActiveSrb;                                                       // stores the current active SRB
70     KEVENT NoPendingRequests;                                                            // set if no pending or in progress requests
71     PSCSI_REQUEST_BLOCK LastTimerActiveSrb;                                              // last timer tick active srb
72     ULONG SrbErrorHandlingActive;                                                        // error handling of srb is activated
73     ULONG TimerWorkQueueEnabled;                                                         // timer work queue enabled
74     ULONG InstanceCount;                                                                 // pdo instance count
75 }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
76 
77 typedef struct
78 {
79     USBSTOR_COMMON_DEVICE_EXTENSION Common;
80     PDEVICE_OBJECT LowerDeviceObject;                                                    // points to FDO
81     UCHAR LUN;                                                                           // lun id
82     PVOID InquiryData;                                                                   // USB SCSI inquiry data
83     PUCHAR FormatData;                                                                   // USB SCSI Read Format Capacity Data
84     UCHAR Claimed;                                                                       // indicating if it has been claimed by upper driver
85     ULONG BlockLength;                                                                   // length of block
86     ULONG LastLogicBlockAddress;                                                         // last block address
87     PDEVICE_OBJECT *PDODeviceObject;                                                     // entry in pdo list
88     PDEVICE_OBJECT Self;                                                                 // self
89     UCHAR MediumTypeCode;                                                                // floppy medium type code
90     UCHAR IsFloppy;                                                                      // is device floppy
91 }PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
92 
93 //
94 // max lun command identifier
95 //
96 #define USB_BULK_GET_MAX_LUN             0xFE
97 #define USB_BULK_RESET_DEVICE             0xFF
98 
99 #include <pshpack1.h>
100 typedef struct
101 {
102     ULONG Signature;                                                 // CBW signature
103     ULONG Tag;                                                       // CBW Tag of operation
104     ULONG DataTransferLength;                                        // data transfer length
105     UCHAR Flags;                                                     // CBW Flags endpoint direction
106     UCHAR LUN;                                                       // lun unit
107     UCHAR CommandBlockLength;                                        // Command block length
108     UCHAR CommandBlock[16];
109 }CBW, *PCBW;
110 
111 C_ASSERT(sizeof(CBW) == 31);
112 
113 
114 #define CBW_SIGNATURE 0x43425355
115 #define CSW_SIGNATURE 0x53425355
116 
117 #define MAX_LUN 0xF
118 
119 typedef struct
120 {
121     ULONG Signature;                                                 // CSW signature
122     ULONG Tag;                                                       // CSW tag
123     ULONG DataResidue;                                               // CSW data transfer diff
124     UCHAR Status;                                                    // CSW status
125 }CSW, *PCSW;
126 
127 //--------------------------------------------------------------------------------------------------------------------------------------------
128 //
129 // UFI INQUIRY command
130 //
131 typedef struct
132 {
133     UCHAR Code;                                                      // operation code 0x12
134     UCHAR LUN;                                                       // lun address
135     UCHAR PageCode;                                                  // product data information, always 0x00
136     UCHAR Reserved;                                                  // reserved 0x00
137     UCHAR AllocationLength;                                          // length of inquiry data to be returned, default 36 bytes
138     UCHAR Reserved1[7];                                              //reserved bytes 0x00
139 }UFI_INQUIRY_CMD, *PUFI_INQUIRY_CMD;
140 
141 C_ASSERT(sizeof(UFI_INQUIRY_CMD) == 12);
142 
143 #define UFI_INQUIRY_CMD_LEN 0x6
144 
145 //
146 // UFI INQUIRY command response
147 //
148 typedef struct
149 {
150     UCHAR DeviceType;                                                // device type
151     UCHAR RMB;                                                       // removable media bit
152     UCHAR Version;                                                   // contains version 0x00
153     UCHAR Format;                                                    // response format
154     UCHAR Length;                                                    // additional length
155     UCHAR Reserved[3];                                               // reserved
156     UCHAR Vendor[8];                                                 // vendor identification string
157     UCHAR Product[16];                                               // product identification string
158     UCHAR Revision[4];                                               // product revision code
159 }UFI_INQUIRY_RESPONSE, *PUFI_INQUIRY_RESPONSE;
160 
161 C_ASSERT(sizeof(UFI_INQUIRY_RESPONSE) == 36);
162 
163 //--------------------------------------------------------------------------------------------------------------------------------------------
164 //
165 // UFI read cmd
166 //
167 typedef struct
168 {
169     UCHAR Code;                                                      // operation code
170     UCHAR LUN;                                                       // lun
171     UCHAR LogicalBlockByte0;                                         // lba byte 0
172     UCHAR LogicalBlockByte1;                                         // lba byte 1
173     UCHAR LogicalBlockByte2;                                         // lba byte 2
174     UCHAR LogicalBlockByte3;                                         // lba byte 3
175     UCHAR Reserved;                                                  // reserved 0x00
176     UCHAR ContiguousLogicBlocksByte0;                                // msb contigious logic blocks byte
177     UCHAR ContiguousLogicBlocksByte1;                                // msb contigious logic blocks
178     UCHAR Reserved1[3];                                              // reserved 0x00
179 }UFI_READ_WRITE_CMD;
180 
181 C_ASSERT(sizeof(UFI_READ_WRITE_CMD) == 12);
182 
183 #define UFI_READ_WRITE_CMD_LEN (0xA)
184 
185 //--------------------------------------------------------------------------------------------------------------------------------------------
186 //
187 // UFI read capacity cmd
188 //
189 typedef struct
190 {
191     UCHAR Code;                                                      // operation code 0x25
192     UCHAR LUN;                                                       // lun address
193     UCHAR LBA[4];                                                   // logical block address, should be zero
194     UCHAR Reserved1[2];                                              // reserved 0x00
195     UCHAR PMI;                                                       // PMI = 0x00
196     UCHAR Reserved2[3];                                              // reserved 0x00
197 }UFI_CAPACITY_CMD, *PUFI_CAPACITY_CMD;
198 
199 C_ASSERT(sizeof(UFI_CAPACITY_CMD) == 12);
200 
201 #define UFI_CAPACITY_CMD_LEN 0xA //FIXME support length 16 too if requested
202 
203 //
204 // UFI Read Capcacity command response
205 //
206 typedef struct
207 {
208     ULONG LastLogicalBlockAddress;                                   // last logical block address
209     ULONG BlockLength;                                               // block length in bytes
210 }UFI_CAPACITY_RESPONSE, *PUFI_CAPACITY_RESPONSE;
211 
212 #define UFI_READ_CAPACITY_CMD_LEN 0xA
213 C_ASSERT(sizeof(UFI_CAPACITY_RESPONSE) == 8);
214 
215 //--------------------------------------------------------------------------------------------------------------------------------------------
216 //
217 // UFI sense mode cmd
218 //
219 typedef struct
220 {
221     UCHAR Code;                                                      // operation code
222     UCHAR LUN;                                                       // lun address
223     UCHAR PageCode:6;                                                // page code selector
224     UCHAR PC:2;                                                      // type of parameters to be returned
225     UCHAR Reserved[4];                                               // reserved 0x00
226     USHORT AllocationLength;                                         // parameters length
227     UCHAR Reserved1[3];
228 }UFI_SENSE_CMD, *PUFI_SENSE_CMD;
229 
230 C_ASSERT(sizeof(UFI_SENSE_CMD) == 12);
231 
232 #define UFI_SENSE_CMD_LEN (6)
233 
234 typedef struct
235 {
236     USHORT ModeDataLength;                                           // length of parameters for sense cmd
237     UCHAR MediumTypeCode;                                            // 00 for mass storage, 0x94 for floppy
238     UCHAR WP:1;                                                      // write protect bit
239     UCHAR Reserved1:2;                                                // reserved 00
240     UCHAR DPOFUA:1;                                                  // should be zero
241     UCHAR Reserved2:4;                                               // reserved
242     UCHAR Reserved[4];                                               // reserved
243 }UFI_MODE_PARAMETER_HEADER, *PUFI_MODE_PARAMETER_HEADER;
244 
245 
246 C_ASSERT(sizeof(UFI_MODE_PARAMETER_HEADER) == 8);
247 
248 typedef struct
249 {
250     UCHAR PC;
251     UCHAR PageLength;
252     UCHAR Reserved1;
253     UCHAR ITM;
254     UCHAR Flags;
255     UCHAR Reserved[3];
256 }UFI_TIMER_PROTECT_PAGE, *PUFI_TIMER_PROTECT_PAGE;
257 C_ASSERT(sizeof(UFI_TIMER_PROTECT_PAGE) == 8);
258 
259 //--------------------------------------------------------------------------------------------------------------------------------------------
260 //
261 // UFI read capacity cmd
262 //
263 
264 typedef struct
265 {
266     UCHAR Code;
267     UCHAR LUN;
268     UCHAR Reserved[5];
269     UCHAR AllocationLengthMsb;
270     UCHAR AllocationLengthLsb;
271     UCHAR Reserved1[3];
272 }UFI_READ_FORMAT_CAPACITY, *PUFI_READ_FORMAT_CAPACITY;
273 
274 C_ASSERT(sizeof(UFI_READ_FORMAT_CAPACITY) == 12);
275 
276 #define UFI_READ_FORMAT_CAPACITY_CMD_LEN (10)
277 
278 typedef struct
279 {
280     UCHAR Reserved1;
281     UCHAR Reserved2;
282     UCHAR Reserved3;
283     UCHAR CapacityLength;
284 }UFI_CAPACITY_FORMAT_HEADER, *PUFI_CAPACITY_FORMAT_HEADER;
285 
286 C_ASSERT(sizeof(UFI_CAPACITY_FORMAT_HEADER) == 4);
287 
288 typedef struct
289 {
290     ULONG BlockCount;
291     UCHAR Code;
292     UCHAR BlockLengthByte0;
293     UCHAR BlockLengthByte1;
294     UCHAR BlockLengthByte2;
295 }UFI_CAPACITY_DESCRIPTOR, *PUFI_CAPACITY_DESCRIPTOR;
296 
297 #define UNFORMATED_MEDIA_CODE_DESCRIPTORY_TYPE (1)
298 #define FORMAT_MEDIA_CODE_DESCRIPTOR_TYPE      (2)
299 #define CARTRIDGE_MEDIA_CODE_DESCRIPTOR_TYPE   (3)
300 
301 
302 
303 
304 //--------------------------------------------------------------------------------------------------------------------------------------------
305 //
306 // UFI test unit command
307 //
308 
309 typedef struct
310 {
311     UCHAR Code;                                                       // operation code 0x00
312     UCHAR LUN;                                                        // lun
313     UCHAR Reserved[10];                                               // reserved 0x00
314 }UFI_TEST_UNIT_CMD, *PUFI_TEST_UNIT_CMD;
315 
316 C_ASSERT(sizeof(UFI_TEST_UNIT_CMD) == 12);
317 
318 #define UFI_TEST_UNIT_CMD_LEN (6)
319 
320 //-------------------------------------------------------------------------------------------------------------------------------------------
321 typedef struct
322 {
323     UCHAR Bytes[16];
324 }UFI_UNKNOWN_CMD, *PUFI_UNKNOWN_CMD;
325 
326 typedef struct
327 {
328     union
329     {
330         PCBW cbw;
331         PCSW csw;
332     };
333     URB Urb;
334     PIRP Irp;
335     ULONG TransferDataLength;
336     PUCHAR TransferData;
337     PFDO_DEVICE_EXTENSION FDODeviceExtension;
338     PPDO_DEVICE_EXTENSION PDODeviceExtension;
339     PMDL TransferBufferMDL;
340     ULONG ErrorIndex;
341     ULONG RetryCount;
342 }IRP_CONTEXT, *PIRP_CONTEXT;
343 
344 typedef struct _ERRORHANDLER_WORKITEM_DATA
345 {
346     PDEVICE_OBJECT DeviceObject;
347     PIRP_CONTEXT Context;
348     WORK_QUEUE_ITEM WorkQueueItem;
349     PIRP Irp;
350 } ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA;
351 
352 
353 //---------------------------------------------------------------------
354 //
355 // fdo.c routines
356 //
357 NTSTATUS
358 USBSTOR_FdoHandlePnp(
359     IN PDEVICE_OBJECT DeviceObject,
360     IN OUT PIRP Irp);
361 
362 //---------------------------------------------------------------------
363 //
364 // pdo.c routines
365 //
366 NTSTATUS
367 USBSTOR_PdoHandlePnp(
368     IN PDEVICE_OBJECT DeviceObject,
369     IN OUT PIRP Irp);
370 
371 NTSTATUS
372 USBSTOR_CreatePDO(
373     IN PDEVICE_OBJECT DeviceObject,
374     IN UCHAR LUN);
375 
376 //---------------------------------------------------------------------
377 //
378 // misc.c routines
379 //
380 NTSTATUS
381 NTAPI
382 USBSTOR_SyncForwardIrp(
383     IN PDEVICE_OBJECT DeviceObject,
384     IN OUT PIRP Irp);
385 
386 NTSTATUS
387 NTAPI
388 USBSTOR_GetBusInterface(
389     IN PDEVICE_OBJECT DeviceObject,
390     OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface);
391 
392 PVOID
393 AllocateItem(
394     IN POOL_TYPE PoolType,
395     IN ULONG ItemSize);
396 
397 VOID
398 FreeItem(
399     IN PVOID Item);
400 
401 NTSTATUS
402 USBSTOR_SyncUrbRequest(
403     IN PDEVICE_OBJECT DeviceObject,
404     OUT PURB UrbRequest);
405 
406 NTSTATUS
407 USBSTOR_GetMaxLUN(
408     IN PDEVICE_OBJECT DeviceObject,
409     IN PFDO_DEVICE_EXTENSION DeviceExtension);
410 
411 NTSTATUS
412 NTAPI
413 USBSTOR_SyncForwardIrpCompletionRoutine(
414     PDEVICE_OBJECT DeviceObject,
415     PIRP Irp,
416     PVOID Context);
417 
418 NTSTATUS
419 USBSTOR_ResetDevice(
420     IN PDEVICE_OBJECT DeviceObject,
421     IN PFDO_DEVICE_EXTENSION DeviceExtension);
422 
423 BOOLEAN
424 USBSTOR_IsFloppy(
425     IN PUCHAR Buffer,
426     IN ULONG BufferLength,
427     OUT PUCHAR MediumTypeCode);
428 
429 //---------------------------------------------------------------------
430 //
431 // descriptor.c routines
432 //
433 
434 NTSTATUS
435 USBSTOR_GetDescriptors(
436     IN PDEVICE_OBJECT DeviceObject);
437 
438 NTSTATUS
439 USBSTOR_SelectConfigurationAndInterface(
440     IN PDEVICE_OBJECT DeviceObject,
441     IN PFDO_DEVICE_EXTENSION DeviceExtension);
442 
443 NTSTATUS
444 USBSTOR_GetPipeHandles(
445     IN PFDO_DEVICE_EXTENSION DeviceExtension);
446 
447 //---------------------------------------------------------------------
448 //
449 // scsi.c routines
450 //
451 NTSTATUS
452 USBSTOR_HandleExecuteSCSI(
453     IN PDEVICE_OBJECT DeviceObject,
454     IN PIRP Irp,
455     IN ULONG RetryCount);
456 
457 NTSTATUS
458 NTAPI
459 USBSTOR_CSWCompletionRoutine(
460     PDEVICE_OBJECT DeviceObject,
461     PIRP Irp,
462     PVOID Ctx);
463 
464 NTSTATUS
465 USBSTOR_SendCBW(
466     PIRP_CONTEXT Context,
467     PIRP Irp);
468 
469 VOID
470 USBSTOR_SendCSW(
471     PIRP_CONTEXT Context,
472     PIRP Irp);
473 
474 
475 //---------------------------------------------------------------------
476 //
477 // disk.c routines
478 //
479 NTSTATUS
480 USBSTOR_HandleInternalDeviceControl(
481     IN PDEVICE_OBJECT DeviceObject,
482     IN PIRP Irp);
483 
484 NTSTATUS
485 USBSTOR_HandleDeviceControl(
486     IN PDEVICE_OBJECT DeviceObject,
487     IN PIRP Irp);
488 
489 //---------------------------------------------------------------------
490 //
491 // queue.c routines
492 //
493 VOID
494 NTAPI
495 USBSTOR_StartIo(
496     PDEVICE_OBJECT DeviceObject,
497     PIRP Irp);
498 
499 VOID
500 USBSTOR_QueueWaitForPendingRequests(
501     IN PDEVICE_OBJECT DeviceObject);
502 
503 VOID
504 USBSTOR_QueueRelease(
505     IN PDEVICE_OBJECT DeviceObject);
506 
507 BOOLEAN
508 USBSTOR_QueueAddIrp(
509     IN PDEVICE_OBJECT DeviceObject,
510     IN PIRP Irp);
511 
512 VOID
513 NTAPI
514 USBSTOR_CancelIo(
515     IN  PDEVICE_OBJECT DeviceObject,
516     IN  PIRP Irp);
517 
518 VOID
519 USBSTOR_QueueInitialize(
520     PFDO_DEVICE_EXTENSION FDODeviceExtension);
521 
522 VOID
523 NTAPI
524 ErrorHandlerWorkItemRoutine(
525 	PVOID Context);
526 
527 VOID
528 NTAPI
529 ResetHandlerWorkItemRoutine(
530     PVOID Context);
531 
532 
533 
534 VOID
535 USBSTOR_QueueNextRequest(
536     IN PDEVICE_OBJECT DeviceObject);
537 
538 VOID
539 USBSTOR_QueueTerminateRequest(
540     IN PDEVICE_OBJECT DeviceObject,
541     IN PIRP Irp);
542 
543 /* error.c */
544 NTSTATUS
545 USBSTOR_GetEndpointStatus(
546     IN PDEVICE_OBJECT DeviceObject,
547     IN UCHAR bEndpointAddress,
548     OUT PUSHORT Value);
549 
550 NTSTATUS
551 USBSTOR_ResetPipeWithHandle(
552     IN PDEVICE_OBJECT DeviceObject,
553     IN USBD_PIPE_HANDLE PipeHandle);
554 
555 VOID
556 NTAPI
557 USBSTOR_TimerRoutine(
558     PDEVICE_OBJECT DeviceObject,
559      PVOID Context);
560 
561