19 #define USB_STOR_TAG 'sbsu'
20 #define USB_MAXCHILDREN (16)
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))
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))
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))
38 #define USB_RECOVERABLE_ERRORS (USBD_STATUS_STALL_PID | USBD_STATUS_DEV_NOT_RESPONDING \
39 | USBD_STATUS_ENDPOINT_HALTED | USBD_STATUS_NO_BANDWIDTH)
41 typedef struct __COMMON_DEVICE_EXTENSION__
45 }USBSTOR_COMMON_DEVICE_EXTENSION
, *PUSBSTOR_COMMON_DEVICE_EXTENSION
;
49 USBSTOR_COMMON_DEVICE_EXTENSION Common
; // common device extension
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 }FDO_DEVICE_EXTENSION
, *PFDO_DEVICE_EXTENSION
;
78 USBSTOR_COMMON_DEVICE_EXTENSION Common
;
79 PDEVICE_OBJECT LowerDeviceObject
; // points to FDO
81 PVOID InquiryData
; // USB SCSI inquiry data
82 PUCHAR FormatData
; // USB SCSI Read Format Capacity Data
83 UCHAR Claimed
; // indicating if it has been claimed by upper driver
84 ULONG BlockLength
; // length of block
85 ULONG LastLogicBlockAddress
; // last block address
86 PDEVICE_OBJECT
*PDODeviceObject
; // entry in pdo list
87 PDEVICE_OBJECT Self
; // self
88 UCHAR MediumTypeCode
; // floppy medium type code
89 UCHAR IsFloppy
; // is device floppy
90 }PDO_DEVICE_EXTENSION
, *PPDO_DEVICE_EXTENSION
;
93 // max lun command identifier
95 #define USB_BULK_GET_MAX_LUN 0xFE
96 #define USB_BULK_RESET_DEVICE 0xFF
101 ULONG Signature
; // CBW signature
102 ULONG Tag
; // CBW Tag of operation
103 ULONG DataTransferLength
; // data transfer length
104 UCHAR Flags
; // CBW Flags endpoint direction
105 UCHAR LUN
; // lun unit
106 UCHAR CommandBlockLength
; // Command block length
107 UCHAR CommandBlock
[16];
110 C_ASSERT(sizeof(CBW
) == 31);
113 #define CBW_SIGNATURE 0x43425355
114 #define CSW_SIGNATURE 0x53425355
120 ULONG Signature
; // CSW signature
121 ULONG Tag
; // CSW tag
122 ULONG DataResidue
; // CSW data transfer diff
123 UCHAR Status
; // CSW status
126 //--------------------------------------------------------------------------------------------------------------------------------------------
128 // UFI INQUIRY command
132 UCHAR Code
; // operation code 0x12
133 UCHAR LUN
; // lun address
134 UCHAR PageCode
; // product data information, always 0x00
135 UCHAR Reserved
; // reserved 0x00
136 UCHAR AllocationLength
; // length of inquiry data to be returned, default 36 bytes
137 UCHAR Reserved1
[7]; //reserved bytes 0x00
138 }UFI_INQUIRY_CMD
, *PUFI_INQUIRY_CMD
;
140 C_ASSERT(sizeof(UFI_INQUIRY_CMD
) == 12);
142 #define UFI_INQUIRY_CMD_LEN 0x6
145 // UFI INQUIRY command response
149 UCHAR DeviceType
; // device type
150 UCHAR RMB
; // removable media bit
151 UCHAR Version
; // contains version 0x00
152 UCHAR Format
; // response format
153 UCHAR Length
; // additional length
154 UCHAR Reserved
[3]; // reserved
155 UCHAR Vendor
[8]; // vendor identification string
156 UCHAR Product
[16]; // product identification string
157 UCHAR Revision
[4]; // product revision code
158 }UFI_INQUIRY_RESPONSE
, *PUFI_INQUIRY_RESPONSE
;
160 C_ASSERT(sizeof(UFI_INQUIRY_RESPONSE
) == 36);
162 //--------------------------------------------------------------------------------------------------------------------------------------------
168 UCHAR Code
; // operation code
170 UCHAR LogicalBlockByte0
; // lba byte 0
171 UCHAR LogicalBlockByte1
; // lba byte 1
172 UCHAR LogicalBlockByte2
; // lba byte 2
173 UCHAR LogicalBlockByte3
; // lba byte 3
174 UCHAR Reserved
; // reserved 0x00
175 UCHAR ContiguousLogicBlocksByte0
; // msb contigious logic blocks byte
176 UCHAR ContiguousLogicBlocksByte1
; // msb contigious logic blocks
177 UCHAR Reserved1
[3]; // reserved 0x00
180 C_ASSERT(sizeof(UFI_READ_WRITE_CMD
) == 12);
182 #define UFI_READ_WRITE_CMD_LEN (0xA)
184 //--------------------------------------------------------------------------------------------------------------------------------------------
186 // UFI read capacity cmd
190 UCHAR Code
; // operation code 0x25
191 UCHAR LUN
; // lun address
192 UCHAR LBA
[4]; // logical block address, should be zero
193 UCHAR Reserved1
[2]; // reserved 0x00
194 UCHAR PMI
; // PMI = 0x00
195 UCHAR Reserved2
[3]; // reserved 0x00
196 }UFI_CAPACITY_CMD
, *PUFI_CAPACITY_CMD
;
198 C_ASSERT(sizeof(UFI_CAPACITY_CMD
) == 12);
200 #define UFI_CAPACITY_CMD_LEN 0xA //FIXME support length 16 too if requested
203 // UFI Read Capcacity command response
207 ULONG LastLogicalBlockAddress
; // last logical block address
208 ULONG BlockLength
; // block length in bytes
209 }UFI_CAPACITY_RESPONSE
, *PUFI_CAPACITY_RESPONSE
;
211 #define UFI_READ_CAPACITY_CMD_LEN 0xA
212 C_ASSERT(sizeof(UFI_CAPACITY_RESPONSE
) == 8);
214 //--------------------------------------------------------------------------------------------------------------------------------------------
216 // UFI sense mode cmd
220 UCHAR Code
; // operation code
221 UCHAR LUN
; // lun address
222 UCHAR PageCode
:6; // page code selector
223 UCHAR PC
:2; // type of parameters to be returned
224 UCHAR Reserved
[4]; // reserved 0x00
225 USHORT AllocationLength
; // parameters length
227 }UFI_SENSE_CMD
, *PUFI_SENSE_CMD
;
229 C_ASSERT(sizeof(UFI_SENSE_CMD
) == 12);
231 #define UFI_SENSE_CMD_LEN (6)
235 USHORT ModeDataLength
; // length of parameters for sense cmd
236 UCHAR MediumTypeCode
; // 00 for mass storage, 0x94 for floppy
237 UCHAR WP
:1; // write protect bit
238 UCHAR Reserved1
:2; // reserved 00
239 UCHAR DPOFUA
:1; // should be zero
240 UCHAR Reserved2
:4; // reserved
241 UCHAR Reserved
[4]; // reserved
242 }UFI_MODE_PARAMETER_HEADER
, *PUFI_MODE_PARAMETER_HEADER
;
245 C_ASSERT(sizeof(UFI_MODE_PARAMETER_HEADER
) == 8);
255 }UFI_TIMER_PROTECT_PAGE
, *PUFI_TIMER_PROTECT_PAGE
;
256 C_ASSERT(sizeof(UFI_TIMER_PROTECT_PAGE
) == 8);
258 //--------------------------------------------------------------------------------------------------------------------------------------------
260 // UFI read capacity cmd
268 UCHAR AllocationLengthMsb
;
269 UCHAR AllocationLengthLsb
;
271 }UFI_READ_FORMAT_CAPACITY
, *PUFI_READ_FORMAT_CAPACITY
;
273 C_ASSERT(sizeof(UFI_READ_FORMAT_CAPACITY
) == 12);
275 #define UFI_READ_FORMAT_CAPACITY_CMD_LEN (10)
282 UCHAR CapacityLength
;
283 }UFI_CAPACITY_FORMAT_HEADER
, *PUFI_CAPACITY_FORMAT_HEADER
;
285 C_ASSERT(sizeof(UFI_CAPACITY_FORMAT_HEADER
) == 4);
291 UCHAR BlockLengthByte0
;
292 UCHAR BlockLengthByte1
;
293 UCHAR BlockLengthByte2
;
294 }UFI_CAPACITY_DESCRIPTOR
, *PUFI_CAPACITY_DESCRIPTOR
;
296 #define UNFORMATED_MEDIA_CODE_DESCRIPTORY_TYPE (1)
297 #define FORMAT_MEDIA_CODE_DESCRIPTOR_TYPE (2)
298 #define CARTRIDGE_MEDIA_CODE_DESCRIPTOR_TYPE (3)
303 //--------------------------------------------------------------------------------------------------------------------------------------------
305 // UFI test unit command
310 UCHAR Code
; // operation code 0x00
312 UCHAR Reserved
[10]; // reserved 0x00
313 }UFI_TEST_UNIT_CMD
, *PUFI_TEST_UNIT_CMD
;
315 C_ASSERT(sizeof(UFI_TEST_UNIT_CMD
) == 12);
317 #define UFI_TEST_UNIT_CMD_LEN (6)
328 ULONG TransferDataLength
;
330 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
331 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
332 PMDL TransferBufferMDL
;
335 }IRP_CONTEXT
, *PIRP_CONTEXT
;
337 typedef struct _ERRORHANDLER_WORKITEM_DATA
339 PDEVICE_OBJECT DeviceObject
;
340 PIRP_CONTEXT Context
;
341 WORK_QUEUE_ITEM WorkQueueItem
;
343 } ERRORHANDLER_WORKITEM_DATA
, *PERRORHANDLER_WORKITEM_DATA
;
346 //---------------------------------------------------------------------
351 USBSTOR_FdoHandlePnp(
352 IN PDEVICE_OBJECT DeviceObject
,
355 //---------------------------------------------------------------------
360 USBSTOR_PdoHandlePnp(
361 IN PDEVICE_OBJECT DeviceObject
,
366 IN PDEVICE_OBJECT DeviceObject
,
368 OUT PDEVICE_OBJECT
*ChildDeviceObject
);
370 //---------------------------------------------------------------------
376 USBSTOR_SyncForwardIrp(
377 IN PDEVICE_OBJECT DeviceObject
,
382 USBSTOR_GetBusInterface(
383 IN PDEVICE_OBJECT DeviceObject
,
384 OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface
);
388 IN POOL_TYPE PoolType
,
396 USBSTOR_SyncUrbRequest(
397 IN PDEVICE_OBJECT DeviceObject
,
398 OUT PURB UrbRequest
);
402 IN PDEVICE_OBJECT DeviceObject
,
403 IN PFDO_DEVICE_EXTENSION DeviceExtension
);
407 USBSTOR_SyncForwardIrpCompletionRoutine(
408 PDEVICE_OBJECT DeviceObject
,
414 IN PDEVICE_OBJECT DeviceObject
,
415 IN PFDO_DEVICE_EXTENSION DeviceExtension
);
420 IN ULONG BufferLength
,
421 OUT PUCHAR MediumTypeCode
);
423 //---------------------------------------------------------------------
425 // descriptor.c routines
429 USBSTOR_GetDescriptors(
430 IN PDEVICE_OBJECT DeviceObject
);
433 USBSTOR_SelectConfigurationAndInterface(
434 IN PDEVICE_OBJECT DeviceObject
,
435 IN PFDO_DEVICE_EXTENSION DeviceExtension
);
438 USBSTOR_GetPipeHandles(
439 IN PFDO_DEVICE_EXTENSION DeviceExtension
);
441 //---------------------------------------------------------------------
446 USBSTOR_HandleExecuteSCSI(
447 IN PDEVICE_OBJECT DeviceObject
,
449 IN ULONG RetryCount
);
453 USBSTOR_CSWCompletionRoutine(
454 PDEVICE_OBJECT DeviceObject
,
460 PIRP_CONTEXT Context
,
465 PIRP_CONTEXT Context
,
469 //---------------------------------------------------------------------
474 USBSTOR_HandleInternalDeviceControl(
475 IN PDEVICE_OBJECT DeviceObject
,
479 USBSTOR_HandleDeviceControl(
480 IN PDEVICE_OBJECT DeviceObject
,
483 //---------------------------------------------------------------------
490 PDEVICE_OBJECT DeviceObject
,
494 USBSTOR_QueueWaitForPendingRequests(
495 IN PDEVICE_OBJECT DeviceObject
);
498 USBSTOR_QueueRelease(
499 IN PDEVICE_OBJECT DeviceObject
);
503 IN PDEVICE_OBJECT DeviceObject
,
509 IN PDEVICE_OBJECT DeviceObject
,
513 USBSTOR_QueueInitialize(
514 PFDO_DEVICE_EXTENSION FDODeviceExtension
);
518 ErrorHandlerWorkItemRoutine(
523 ResetHandlerWorkItemRoutine(
529 USBSTOR_QueueNextRequest(
530 IN PDEVICE_OBJECT DeviceObject
);
533 USBSTOR_QueueTerminateRequest(
534 IN PDEVICE_OBJECT DeviceObject
,
539 USBSTOR_GetEndpointStatus(
540 IN PDEVICE_OBJECT DeviceObject
,
541 IN UCHAR bEndpointAddress
,
545 USBSTOR_ResetPipeWithHandle(
546 IN PDEVICE_OBJECT DeviceObject
,
547 IN USBD_PIPE_HANDLE PipeHandle
);
551 USBSTOR_TimerRoutine(
552 PDEVICE_OBJECT DeviceObject
,