10 #define USB_STOR_TAG 'sbsu'
11 #define USB_MAXCHILDREN (16)
15 #define HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
16 #define NTOHS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
18 #define HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
19 ((((unsigned long)(n) & 0xFF00)) << 8) | \
20 ((((unsigned long)(n) & 0xFF0000)) >> 8) | \
21 ((((unsigned long)(n) & 0xFF000000)) >> 24))
24 #define NTOHL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
25 ((((unsigned long)(n) & 0xFF00)) << 8) | \
26 ((((unsigned long)(n) & 0xFF0000)) >> 8) | \
27 ((((unsigned long)(n) & 0xFF000000)) >> 24))
29 #define USB_RECOVERABLE_ERRORS (USBD_STATUS_STALL_PID | USBD_STATUS_DEV_NOT_RESPONDING \
30 | USBD_STATUS_ENDPOINT_HALTED | USBD_STATUS_NO_BANDWIDTH)
32 typedef struct __COMMON_DEVICE_EXTENSION__
36 }USBSTOR_COMMON_DEVICE_EXTENSION
, *PUSBSTOR_COMMON_DEVICE_EXTENSION
;
40 USBSTOR_COMMON_DEVICE_EXTENSION Common
; // common device extension
42 PDEVICE_OBJECT FunctionalDeviceObject
; // functional device object
43 PDEVICE_OBJECT PhysicalDeviceObject
; // physical device object
44 PDEVICE_OBJECT LowerDeviceObject
; // lower device object
45 USB_BUS_INTERFACE_USBDI_V2 BusInterface
; // bus interface of device
46 PUSB_DEVICE_DESCRIPTOR DeviceDescriptor
; // usb device descriptor
47 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
; // usb configuration descriptor
48 PUSB_STRING_DESCRIPTOR SerialNumber
; // usb serial number
49 PUSBD_INTERFACE_INFORMATION InterfaceInformation
; // usb interface information
50 USBD_CONFIGURATION_HANDLE ConfigurationHandle
; // usb configuration handle
51 UCHAR BulkInPipeIndex
; // bulk in pipe index
52 UCHAR BulkOutPipeIndex
; // bulk out pipe index
53 UCHAR MaxLUN
; // max lun for device
54 PDEVICE_OBJECT ChildPDO
[16]; // max 16 child pdo devices
55 KSPIN_LOCK IrpListLock
; // irp list lock
56 LIST_ENTRY IrpListHead
; // irp list head
57 BOOLEAN IrpListFreeze
; // if true the irp list is freezed
58 BOOLEAN ResetInProgress
; // if hard reset is in progress
59 ULONG IrpPendingCount
; // count of irp pending
60 PSCSI_REQUEST_BLOCK ActiveSrb
; // stores the current active SRB
61 KEVENT NoPendingRequests
; // set if no pending or in progress requests
62 PSCSI_REQUEST_BLOCK LastTimerActiveSrb
; // last timer tick active srb
63 ULONG SrbErrorHandlingActive
; // error handling of srb is activated
64 ULONG TimerWorkQueueEnabled
; // timer work queue enabled
65 ULONG InstanceCount
; // pdo instance count
66 }FDO_DEVICE_EXTENSION
, *PFDO_DEVICE_EXTENSION
;
70 USBSTOR_COMMON_DEVICE_EXTENSION Common
;
71 PDEVICE_OBJECT LowerDeviceObject
; // points to FDO
73 PVOID InquiryData
; // USB SCSI inquiry data
74 PUCHAR FormatData
; // USB SCSI Read Format Capacity Data
75 UCHAR Claimed
; // indicating if it has been claimed by upper driver
76 ULONG BlockLength
; // length of block
77 ULONG LastLogicBlockAddress
; // last block address
78 PDEVICE_OBJECT
*PDODeviceObject
; // entry in pdo list
79 PDEVICE_OBJECT Self
; // self
80 UCHAR MediumTypeCode
; // floppy medium type code
81 UCHAR IsFloppy
; // is device floppy
82 }PDO_DEVICE_EXTENSION
, *PPDO_DEVICE_EXTENSION
;
85 // max lun command identifier
87 #define USB_BULK_GET_MAX_LUN 0xFE
88 #define USB_BULK_RESET_DEVICE 0xFF
93 ULONG Signature
; // CBW signature
94 ULONG Tag
; // CBW Tag of operation
95 ULONG DataTransferLength
; // data transfer length
96 UCHAR Flags
; // CBW Flags endpoint direction
97 UCHAR LUN
; // lun unit
98 UCHAR CommandBlockLength
; // Command block length
99 UCHAR CommandBlock
[16];
102 C_ASSERT(sizeof(CBW
) == 31);
105 #define CBW_SIGNATURE 0x43425355
106 #define CSW_SIGNATURE 0x53425355
112 ULONG Signature
; // CSW signature
113 ULONG Tag
; // CSW tag
114 ULONG DataResidue
; // CSW data transfer diff
115 UCHAR Status
; // CSW status
118 //--------------------------------------------------------------------------------------------------------------------------------------------
120 // UFI INQUIRY command
124 UCHAR Code
; // operation code 0x12
125 UCHAR LUN
; // lun address
126 UCHAR PageCode
; // product data information, always 0x00
127 UCHAR Reserved
; // reserved 0x00
128 UCHAR AllocationLength
; // length of inquiry data to be returned, default 36 bytes
129 UCHAR Reserved1
[7]; //reserved bytes 0x00
130 }UFI_INQUIRY_CMD
, *PUFI_INQUIRY_CMD
;
132 C_ASSERT(sizeof(UFI_INQUIRY_CMD
) == 12);
134 #define UFI_INQUIRY_CMD_LEN 0x6
137 // UFI INQUIRY command response
141 UCHAR DeviceType
; // device type
142 UCHAR RMB
; // removable media bit
143 UCHAR Version
; // contains version 0x00
144 UCHAR Format
; // response format
145 UCHAR Length
; // additional length
146 UCHAR Reserved
[3]; // reserved
147 UCHAR Vendor
[8]; // vendor identification string
148 UCHAR Product
[16]; // product identification string
149 UCHAR Revision
[4]; // product revision code
150 }UFI_INQUIRY_RESPONSE
, *PUFI_INQUIRY_RESPONSE
;
152 C_ASSERT(sizeof(UFI_INQUIRY_RESPONSE
) == 36);
154 //--------------------------------------------------------------------------------------------------------------------------------------------
160 UCHAR Code
; // operation code
162 UCHAR LogicalBlockByte0
; // lba byte 0
163 UCHAR LogicalBlockByte1
; // lba byte 1
164 UCHAR LogicalBlockByte2
; // lba byte 2
165 UCHAR LogicalBlockByte3
; // lba byte 3
166 UCHAR Reserved
; // reserved 0x00
167 UCHAR ContiguousLogicBlocksByte0
; // msb contigious logic blocks byte
168 UCHAR ContiguousLogicBlocksByte1
; // msb contigious logic blocks
169 UCHAR Reserved1
[3]; // reserved 0x00
172 C_ASSERT(sizeof(UFI_READ_WRITE_CMD
) == 12);
174 #define UFI_READ_WRITE_CMD_LEN (0xA)
176 //--------------------------------------------------------------------------------------------------------------------------------------------
178 // UFI read capacity cmd
182 UCHAR Code
; // operation code 0x25
183 UCHAR LUN
; // lun address
184 UCHAR LBA
[4]; // logical block address, should be zero
185 UCHAR Reserved1
[2]; // reserved 0x00
186 UCHAR PMI
; // PMI = 0x00
187 UCHAR Reserved2
[3]; // reserved 0x00
188 }UFI_CAPACITY_CMD
, *PUFI_CAPACITY_CMD
;
190 C_ASSERT(sizeof(UFI_CAPACITY_CMD
) == 12);
192 #define UFI_CAPACITY_CMD_LEN 0xA //FIXME support length 16 too if requested
195 // UFI Read Capcacity command response
199 ULONG LastLogicalBlockAddress
; // last logical block address
200 ULONG BlockLength
; // block length in bytes
201 }UFI_CAPACITY_RESPONSE
, *PUFI_CAPACITY_RESPONSE
;
203 #define UFI_READ_CAPACITY_CMD_LEN 0xA
204 C_ASSERT(sizeof(UFI_CAPACITY_RESPONSE
) == 8);
206 //--------------------------------------------------------------------------------------------------------------------------------------------
208 // UFI sense mode cmd
212 UCHAR Code
; // operation code
213 UCHAR LUN
; // lun address
214 UCHAR PageCode
:6; // page code selector
215 UCHAR PC
:2; // type of parameters to be returned
216 UCHAR Reserved
[4]; // reserved 0x00
217 USHORT AllocationLength
; // parameters length
219 }UFI_SENSE_CMD
, *PUFI_SENSE_CMD
;
221 C_ASSERT(sizeof(UFI_SENSE_CMD
) == 12);
223 #define UFI_SENSE_CMD_LEN (6)
227 USHORT ModeDataLength
; // length of parameters for sense cmd
228 UCHAR MediumTypeCode
; // 00 for mass storage, 0x94 for floppy
229 UCHAR WP
:1; // write protect bit
230 UCHAR Reserved1
:2; // reserved 00
231 UCHAR DPOFUA
:1; // should be zero
232 UCHAR Reserved2
:4; // reserved
233 UCHAR Reserved
[4]; // reserved
234 }UFI_MODE_PARAMETER_HEADER
, *PUFI_MODE_PARAMETER_HEADER
;
237 C_ASSERT(sizeof(UFI_MODE_PARAMETER_HEADER
) == 8);
247 }UFI_TIMER_PROTECT_PAGE
, *PUFI_TIMER_PROTECT_PAGE
;
248 C_ASSERT(sizeof(UFI_TIMER_PROTECT_PAGE
) == 8);
250 //--------------------------------------------------------------------------------------------------------------------------------------------
252 // UFI read capacity cmd
260 UCHAR AllocationLengthMsb
;
261 UCHAR AllocationLengthLsb
;
263 }UFI_READ_FORMAT_CAPACITY
, *PUFI_READ_FORMAT_CAPACITY
;
265 C_ASSERT(sizeof(UFI_READ_FORMAT_CAPACITY
) == 12);
267 #define UFI_READ_FORMAT_CAPACITY_CMD_LEN (10)
274 UCHAR CapacityLength
;
275 }UFI_CAPACITY_FORMAT_HEADER
, *PUFI_CAPACITY_FORMAT_HEADER
;
277 C_ASSERT(sizeof(UFI_CAPACITY_FORMAT_HEADER
) == 4);
283 UCHAR BlockLengthByte0
;
284 UCHAR BlockLengthByte1
;
285 UCHAR BlockLengthByte2
;
286 }UFI_CAPACITY_DESCRIPTOR
, *PUFI_CAPACITY_DESCRIPTOR
;
288 #define UNFORMATED_MEDIA_CODE_DESCRIPTORY_TYPE (1)
289 #define FORMAT_MEDIA_CODE_DESCRIPTOR_TYPE (2)
290 #define CARTRIDGE_MEDIA_CODE_DESCRIPTOR_TYPE (3)
295 //--------------------------------------------------------------------------------------------------------------------------------------------
297 // UFI test unit command
302 UCHAR Code
; // operation code 0x00
304 UCHAR Reserved
[10]; // reserved 0x00
305 }UFI_TEST_UNIT_CMD
, *PUFI_TEST_UNIT_CMD
;
307 C_ASSERT(sizeof(UFI_TEST_UNIT_CMD
) == 12);
309 #define UFI_TEST_UNIT_CMD_LEN (6)
311 //-------------------------------------------------------------------------------------------------------------------------------------------
315 }UFI_UNKNOWN_CMD
, *PUFI_UNKNOWN_CMD
;
326 ULONG TransferDataLength
;
328 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
329 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
330 PMDL TransferBufferMDL
;
333 }IRP_CONTEXT
, *PIRP_CONTEXT
;
335 typedef struct _ERRORHANDLER_WORKITEM_DATA
337 PDEVICE_OBJECT DeviceObject
;
338 PIRP_CONTEXT Context
;
339 WORK_QUEUE_ITEM WorkQueueItem
;
341 } ERRORHANDLER_WORKITEM_DATA
, *PERRORHANDLER_WORKITEM_DATA
;
344 //---------------------------------------------------------------------
349 USBSTOR_FdoHandlePnp(
350 IN PDEVICE_OBJECT DeviceObject
,
353 //---------------------------------------------------------------------
358 USBSTOR_PdoHandlePnp(
359 IN PDEVICE_OBJECT DeviceObject
,
364 IN PDEVICE_OBJECT DeviceObject
,
367 //---------------------------------------------------------------------
373 USBSTOR_SyncForwardIrp(
374 IN PDEVICE_OBJECT DeviceObject
,
379 USBSTOR_GetBusInterface(
380 IN PDEVICE_OBJECT DeviceObject
,
381 OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface
);
385 IN POOL_TYPE PoolType
,
393 USBSTOR_SyncUrbRequest(
394 IN PDEVICE_OBJECT DeviceObject
,
395 OUT PURB UrbRequest
);
399 IN PDEVICE_OBJECT DeviceObject
,
400 IN PFDO_DEVICE_EXTENSION DeviceExtension
);
404 USBSTOR_SyncForwardIrpCompletionRoutine(
405 PDEVICE_OBJECT DeviceObject
,
411 IN PDEVICE_OBJECT DeviceObject
,
412 IN PFDO_DEVICE_EXTENSION DeviceExtension
);
417 IN ULONG BufferLength
,
418 OUT PUCHAR MediumTypeCode
);
420 //---------------------------------------------------------------------
422 // descriptor.c routines
426 USBSTOR_GetDescriptors(
427 IN PDEVICE_OBJECT DeviceObject
);
430 USBSTOR_SelectConfigurationAndInterface(
431 IN PDEVICE_OBJECT DeviceObject
,
432 IN PFDO_DEVICE_EXTENSION DeviceExtension
);
435 USBSTOR_GetPipeHandles(
436 IN PFDO_DEVICE_EXTENSION DeviceExtension
);
438 //---------------------------------------------------------------------
443 USBSTOR_HandleExecuteSCSI(
444 IN PDEVICE_OBJECT DeviceObject
,
446 IN ULONG RetryCount
);
450 USBSTOR_CSWCompletionRoutine(
451 PDEVICE_OBJECT DeviceObject
,
457 PIRP_CONTEXT Context
,
462 PIRP_CONTEXT Context
,
466 //---------------------------------------------------------------------
471 USBSTOR_HandleInternalDeviceControl(
472 IN PDEVICE_OBJECT DeviceObject
,
476 USBSTOR_HandleDeviceControl(
477 IN PDEVICE_OBJECT DeviceObject
,
480 //---------------------------------------------------------------------
487 PDEVICE_OBJECT DeviceObject
,
491 USBSTOR_QueueWaitForPendingRequests(
492 IN PDEVICE_OBJECT DeviceObject
);
495 USBSTOR_QueueRelease(
496 IN PDEVICE_OBJECT DeviceObject
);
500 IN PDEVICE_OBJECT DeviceObject
,
506 IN PDEVICE_OBJECT DeviceObject
,
510 USBSTOR_QueueInitialize(
511 PFDO_DEVICE_EXTENSION FDODeviceExtension
);
515 ErrorHandlerWorkItemRoutine(
520 ResetHandlerWorkItemRoutine(
526 USBSTOR_QueueNextRequest(
527 IN PDEVICE_OBJECT DeviceObject
);
530 USBSTOR_QueueTerminateRequest(
531 IN PDEVICE_OBJECT DeviceObject
,
536 USBSTOR_GetEndpointStatus(
537 IN PDEVICE_OBJECT DeviceObject
,
538 IN UCHAR bEndpointAddress
,
542 USBSTOR_ResetPipeWithHandle(
543 IN PDEVICE_OBJECT DeviceObject
,
544 IN USBD_PIPE_HANDLE PipeHandle
);
548 USBSTOR_TimerRoutine(
549 PDEVICE_OBJECT DeviceObject
,