xref: /reactos/drivers/usb/usbstor/usbstor.h (revision 2a06585e)
1 
2 #pragma once
3 
4 #include <ntddk.h>
5 #define YDEBUG
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 }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
72 
73 typedef struct
74 {
75     USBSTOR_COMMON_DEVICE_EXTENSION Common;
76     PDEVICE_OBJECT LowerDeviceObject;                                                    // points to FDO
77     UCHAR LUN;                                                                           // lun id
78     PVOID InquiryData;                                                                   // USB SCSI inquiry data
79     UCHAR Claimed;                                                                       // indicating if it has been claimed by upper driver
80     ULONG BlockLength;                                                                   // length of block
81     ULONG LastLogicBlockAddress;                                                         // last block address
82     PDEVICE_OBJECT *PDODeviceObject;                                                     // entry in pdo list
83 }PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
84 
85 //
86 // max lun command identifier
87 //
88 #define USB_BULK_GET_MAX_LUN             0xFE
89 #define USB_BULK_RESET_DEVICE             0xFF
90 
91 #include <pshpack1.h>
92 typedef struct
93 {
94     ULONG Signature;                                                 // CBW signature
95     ULONG Tag;                                                       // CBW Tag of operation
96     ULONG DataTransferLength;                                        // data transfer length
97     UCHAR Flags;                                                     // CBW Flags endpoint direction
98     UCHAR LUN;                                                       // lun unit
99     UCHAR CommandBlockLength;                                        // Command block length
100     UCHAR CommandBlock[16];
101 }CBW, *PCBW;
102 
103 C_ASSERT(sizeof(CBW) == 31);
104 
105 
106 #define CBW_SIGNATURE 0x43425355
107 #define CSW_SIGNATURE 0x53425355
108 
109 #define MAX_LUN 0xF
110 
111 typedef struct
112 {
113     ULONG Signature;                                                 // CSW signature
114     ULONG Tag;                                                       // CSW tag
115     ULONG DataResidue;                                               // CSW data transfer diff
116     UCHAR Status;                                                    // CSW status
117 }CSW, *PCSW;
118 
119 //--------------------------------------------------------------------------------------------------------------------------------------------
120 //
121 // UFI INQUIRY command
122 //
123 typedef struct
124 {
125     UCHAR Code;                                                      // operation code 0x12
126     UCHAR LUN;                                                       // lun address
127     UCHAR PageCode;                                                  // product data information, always 0x00
128     UCHAR Reserved;                                                  // reserved 0x00
129     UCHAR AllocationLength;                                          // length of inquiry data to be returned, default 36 bytes
130     UCHAR Reserved1[7];                                              //reserved bytes 0x00
131 }UFI_INQUIRY_CMD, *PUFI_INQUIRY_CMD;
132 
133 C_ASSERT(sizeof(UFI_INQUIRY_CMD) == 12);
134 
135 #define UFI_INQUIRY_CMD_LEN 0x6
136 
137 //
138 // UFI INQUIRY command response
139 //
140 typedef struct
141 {
142     UCHAR DeviceType;                                                // device type
143     UCHAR RMB;                                                       // removable media bit
144     UCHAR Version;                                                   // contains version 0x00
145     UCHAR Format;                                                    // response format
146     UCHAR Length;                                                    // additional length
147     UCHAR Reserved[3];                                               // reserved
148     UCHAR Vendor[8];                                                 // vendor identification string
149     UCHAR Product[16];                                               // product identification string
150     UCHAR Revision[4];                                               // product revision code
151 }UFI_INQUIRY_RESPONSE, *PUFI_INQUIRY_RESPONSE;
152 
153 C_ASSERT(sizeof(UFI_INQUIRY_RESPONSE) == 36);
154 
155 //--------------------------------------------------------------------------------------------------------------------------------------------
156 //
157 // UFI read cmd
158 //
159 typedef struct
160 {
161     UCHAR Code;                                                      // operation code
162     UCHAR LUN;                                                       // lun
163     UCHAR LogicalBlockByte0;                                         // lba byte 0
164     UCHAR LogicalBlockByte1;                                         // lba byte 1
165     UCHAR LogicalBlockByte2;                                         // lba byte 2
166     UCHAR LogicalBlockByte3;                                         // lba byte 3
167     UCHAR Reserved;                                                  // reserved 0x00
168     UCHAR ContiguousLogicBlocksByte0;                                // msb contigious logic blocks byte
169     UCHAR ContiguousLogicBlocksByte1;                                // msb contigious logic blocks
170     UCHAR Reserved1[3];                                              // reserved 0x00
171 }UFI_READ_WRITE_CMD;
172 
173 C_ASSERT(sizeof(UFI_READ_WRITE_CMD) == 12);
174 
175 #define UFI_READ_WRITE_CMD_LEN (0xA)
176 
177 //--------------------------------------------------------------------------------------------------------------------------------------------
178 //
179 // UFI read capacity cmd
180 //
181 typedef struct
182 {
183     UCHAR Code;                                                      // operation code 0x25
184     UCHAR LUN;                                                       // lun address
185     UCHAR LBA[4];                                                   // logical block address, should be zero
186     UCHAR Reserved1[2];                                              // reserved 0x00
187     UCHAR PMI;                                                       // PMI = 0x00
188     UCHAR Reserved2[3];                                              // reserved 0x00
189 }UFI_CAPACITY_CMD, *PUFI_CAPACITY_CMD;
190 
191 C_ASSERT(sizeof(UFI_CAPACITY_CMD) == 12);
192 
193 #define UFI_CAPACITY_CMD_LEN 0xA //FIXME support length 16 too if requested
194 
195 //
196 // UFI Read Capcacity command response
197 //
198 typedef struct
199 {
200     ULONG LastLogicalBlockAddress;                                   // last logical block address
201     ULONG BlockLength;                                               // block length in bytes
202 }UFI_CAPACITY_RESPONSE, *PUFI_CAPACITY_RESPONSE;
203 
204 #define UFI_READ_CAPACITY_CMD_LEN 0xA
205 C_ASSERT(sizeof(UFI_CAPACITY_RESPONSE) == 8);
206 
207 //--------------------------------------------------------------------------------------------------------------------------------------------
208 //
209 // UFI sense mode cmd
210 //
211 typedef struct
212 {
213     UCHAR Code;                                                      // operation code
214     UCHAR LUN;                                                       // lun address
215     UCHAR PageCode:6;                                                // page code selector
216     UCHAR PC:2;                                                      // type of parameters to be returned
217     UCHAR Reserved[4];                                               // reserved 0x00
218     USHORT AllocationLength;                                         // parameters length
219     UCHAR Reserved1[3];
220 }UFI_SENSE_CMD, *PUFI_SENSE_CMD;
221 
222 C_ASSERT(sizeof(UFI_SENSE_CMD) == 12);
223 
224 #define UFI_SENSE_CMD_LEN (6)
225 
226 typedef struct
227 {
228     USHORT ModeDataLength;                                           // length of parameters for sense cmd
229     UCHAR MediumTypeCode;                                            // 00 for mass storage, 0x94 for floppy
230     UCHAR WP:1;                                                      // write protect bit
231     UCHAR Reserved1:2;                                                // reserved 00
232     UCHAR DPOFUA:1;                                                  // should be zero
233     UCHAR Reserved2:4;                                               // reserved
234     UCHAR Reserved[4];                                               // reserved
235 }UFI_MODE_PARAMETER_HEADER, *PUFI_MODE_PARAMETER_HEADER;
236 
237 
238 C_ASSERT(sizeof(UFI_MODE_PARAMETER_HEADER) == 8);
239 
240 typedef struct
241 {
242     UCHAR PC;
243     UCHAR PageLength;
244     UCHAR Reserved1;
245     UCHAR ITM;
246     UCHAR Flags;
247     UCHAR Reserved[3];
248 }UFI_TIMER_PROTECT_PAGE, *PUFI_TIMER_PROTECT_PAGE;
249 C_ASSERT(sizeof(UFI_TIMER_PROTECT_PAGE) == 8);
250 
251 //--------------------------------------------------------------------------------------------------------------------------------------------
252 //
253 // UFI test unit command
254 //
255 
256 typedef struct
257 {
258     UCHAR Code;                                                       // operation code 0x00
259     UCHAR LUN;                                                        // lun
260     UCHAR Reserved[10];                                               // reserved 0x00
261 }UFI_TEST_UNIT_CMD, *PUFI_TEST_UNIT_CMD;
262 
263 C_ASSERT(sizeof(UFI_TEST_UNIT_CMD) == 12);
264 
265 #define UFI_TEST_UNIT_CMD_LEN (6)
266 
267 typedef struct
268 {
269     union
270     {
271         PCBW cbw;
272         PCSW csw;
273     };
274     URB Urb;
275     PIRP Irp;
276     ULONG TransferDataLength;
277     PUCHAR TransferData;
278     PFDO_DEVICE_EXTENSION FDODeviceExtension;
279     PPDO_DEVICE_EXTENSION PDODeviceExtension;
280     PMDL TransferBufferMDL;
281     PKEVENT Event;
282 }IRP_CONTEXT, *PIRP_CONTEXT;
283 
284 typedef struct _ERRORHANDLER_WORKITEM_DATA
285 {
286 	PDEVICE_OBJECT DeviceObject;
287 	PIRP_CONTEXT Context;
288 	WORK_QUEUE_ITEM WorkQueueItem;
289 } ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA;
290 
291 
292 //---------------------------------------------------------------------
293 //
294 // fdo.c routines
295 //
296 NTSTATUS
297 USBSTOR_FdoHandlePnp(
298     IN PDEVICE_OBJECT DeviceObject,
299     IN OUT PIRP Irp);
300 
301 //---------------------------------------------------------------------
302 //
303 // pdo.c routines
304 //
305 NTSTATUS
306 USBSTOR_PdoHandlePnp(
307     IN PDEVICE_OBJECT DeviceObject,
308     IN OUT PIRP Irp);
309 
310 NTSTATUS
311 USBSTOR_CreatePDO(
312     IN PDEVICE_OBJECT DeviceObject,
313     OUT PDEVICE_OBJECT *ChildDeviceObject);
314 
315 //---------------------------------------------------------------------
316 //
317 // misc.c routines
318 //
319 NTSTATUS
320 NTAPI
321 USBSTOR_SyncForwardIrp(
322     IN PDEVICE_OBJECT DeviceObject,
323     IN OUT PIRP Irp);
324 
325 NTSTATUS
326 NTAPI
327 USBSTOR_GetBusInterface(
328     IN PDEVICE_OBJECT DeviceObject,
329     OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface);
330 
331 PVOID
332 AllocateItem(
333     IN POOL_TYPE PoolType,
334     IN ULONG ItemSize);
335 
336 VOID
337 FreeItem(
338     IN PVOID Item);
339 
340 NTSTATUS
341 USBSTOR_SyncUrbRequest(
342     IN PDEVICE_OBJECT DeviceObject,
343     OUT PURB UrbRequest);
344 
345 NTSTATUS
346 USBSTOR_GetMaxLUN(
347     IN PDEVICE_OBJECT DeviceObject,
348     IN PFDO_DEVICE_EXTENSION DeviceExtension);
349 
350 NTSTATUS
351 NTAPI
352 USBSTOR_SyncForwardIrpCompletionRoutine(
353     PDEVICE_OBJECT DeviceObject,
354     PIRP Irp,
355     PVOID Context);
356 
357 NTSTATUS
358 USBSTOR_ResetDevice(
359     IN PDEVICE_OBJECT DeviceObject,
360     IN PFDO_DEVICE_EXTENSION DeviceExtension);
361 
362 //---------------------------------------------------------------------
363 //
364 // descriptor.c routines
365 //
366 
367 NTSTATUS
368 USBSTOR_GetDescriptors(
369     IN PDEVICE_OBJECT DeviceObject);
370 
371 NTSTATUS
372 USBSTOR_SelectConfigurationAndInterface(
373     IN PDEVICE_OBJECT DeviceObject,
374     IN PFDO_DEVICE_EXTENSION DeviceExtension);
375 
376 NTSTATUS
377 USBSTOR_GetPipeHandles(
378     IN PFDO_DEVICE_EXTENSION DeviceExtension);
379 
380 //---------------------------------------------------------------------
381 //
382 // scsi.c routines
383 //
384 NTSTATUS
385 USBSTOR_HandleExecuteSCSI(
386     IN PDEVICE_OBJECT DeviceObject,
387     IN PIRP Irp);
388 
389 NTSTATUS
390 USBSTOR_SendInquiryCmd(
391     IN PDEVICE_OBJECT DeviceObject);
392 
393 //---------------------------------------------------------------------
394 //
395 // disk.c routines
396 //
397 NTSTATUS
398 USBSTOR_HandleInternalDeviceControl(
399     IN PDEVICE_OBJECT DeviceObject,
400     IN PIRP Irp);
401 
402 NTSTATUS
403 USBSTOR_HandleDeviceControl(
404     IN PDEVICE_OBJECT DeviceObject,
405     IN PIRP Irp);
406 
407 //---------------------------------------------------------------------
408 //
409 // queue.c routines
410 //
411 VOID
412 NTAPI
413 USBSTOR_StartIo(
414     PDEVICE_OBJECT DeviceObject,
415     PIRP Irp);
416 
417 VOID
418 USBSTOR_QueueWaitForPendingRequests(
419     IN PDEVICE_OBJECT DeviceObject);
420 
421 VOID
422 USBSTOR_QueueRelease(
423     IN PDEVICE_OBJECT DeviceObject);
424 
425 BOOLEAN
426 USBSTOR_QueueAddIrp(
427     IN PDEVICE_OBJECT DeviceObject,
428     IN PIRP Irp);
429 
430 VOID
431 NTAPI
432 USBSTOR_CancelIo(
433     IN  PDEVICE_OBJECT DeviceObject,
434     IN  PIRP Irp);
435 
436 VOID
437 USBSTOR_QueueInitialize(
438     PFDO_DEVICE_EXTENSION FDODeviceExtension);
439 
440 VOID
441 NTAPI
442 ErrorHandlerWorkItemRoutine(
443 	PVOID Context);
444 
445 VOID
446 USBSTOR_QueueNextRequest(
447     IN PDEVICE_OBJECT DeviceObject);
448 
449 VOID
450 USBSTOR_QueueTerminateRequest(
451     IN PDEVICE_OBJECT DeviceObject,
452     IN PIRP Irp);
453 
454 /* error.c */
455 NTSTATUS
456 USBSTOR_GetEndpointStatus(
457     IN PDEVICE_OBJECT DeviceObject,
458     IN UCHAR bEndpointAddress,
459     OUT PUSHORT Value);
460 
461