2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: USB block storage device driver.
5 * COPYRIGHT: 2005-2006 James Tabor
6 * 2011-2012 Michael Martin (michael.martin@reactos.org)
7 * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
9 * 2019 Victor Perevertkin (victor.perevertkin@reactos.org)
20 USBSTOR_SrbStatusToNtStatus(
21 IN PSCSI_REQUEST_BLOCK Srb
)
25 SrbStatus
= SRB_STATUS(Srb
->SrbStatus
);
29 case SRB_STATUS_SUCCESS
:
30 return STATUS_SUCCESS
;
32 case SRB_STATUS_DATA_OVERRUN
:
33 return STATUS_BUFFER_OVERFLOW
;
35 case SRB_STATUS_BAD_FUNCTION
:
36 case SRB_STATUS_BAD_SRB_BLOCK_LENGTH
:
37 return STATUS_INVALID_DEVICE_REQUEST
;
39 case SRB_STATUS_INVALID_LUN
:
40 case SRB_STATUS_INVALID_TARGET_ID
:
41 case SRB_STATUS_NO_HBA
:
42 case SRB_STATUS_NO_DEVICE
:
43 return STATUS_DEVICE_DOES_NOT_EXIST
;
45 case SRB_STATUS_TIMEOUT
:
46 return STATUS_IO_TIMEOUT
;
48 case SRB_STATUS_BUS_RESET
:
49 case SRB_STATUS_COMMAND_TIMEOUT
:
50 case SRB_STATUS_SELECTION_TIMEOUT
:
51 return STATUS_DEVICE_NOT_CONNECTED
;
54 return STATUS_IO_DEVICE_ERROR
;
61 IN ULONG DataTransferLength
,
63 IN UCHAR CommandBlockLength
,
64 IN PUCHAR CommandBlock
,
67 ASSERT(CommandBlockLength
<= 16);
69 Control
->Signature
= CBW_SIGNATURE
;
71 Control
->DataTransferLength
= DataTransferLength
;
72 Control
->Flags
= (CommandBlock
[0] != SCSIOP_WRITE
) ? 0x80 : 0x00;
73 Control
->LUN
= (LUN
& MAX_LUN
);
74 Control
->CommandBlockLength
= CommandBlockLength
;
76 RtlCopyMemory(Control
->CommandBlock
, CommandBlock
, CommandBlockLength
);
78 return STATUS_SUCCESS
;
82 USBSTOR_AllocateIrpContext()
86 Context
= (PIRP_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(IRP_CONTEXT
));
92 Context
->cbw
= (PCBW
)AllocateItem(NonPagedPool
, 512);
105 PIRP_CONTEXT Context
)
107 if (Context
->csw
->Signature
!= CSW_SIGNATURE
)
109 DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE
, Context
->csw
->Signature
);
113 if (Context
->csw
->Tag
!= (ULONG_PTR
)Context
->csw
)
115 DPRINT1("[USBSTOR] Expected Tag %Ix but got %x\n", (ULONG_PTR
)Context
->csw
, Context
->csw
->Tag
);
123 USBSTOR_QueueWorkItem(
124 PIRP_CONTEXT Context
,
127 PERRORHANDLER_WORKITEM_DATA ErrorHandlerWorkItemData
;
129 ErrorHandlerWorkItemData
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(ERRORHANDLER_WORKITEM_DATA
), USB_STOR_TAG
);
130 if (!ErrorHandlerWorkItemData
)
132 return STATUS_INSUFFICIENT_RESOURCES
;
135 // error handling started
136 Context
->FDODeviceExtension
->SrbErrorHandlingActive
= TRUE
;
138 // srb error handling finished
139 Context
->FDODeviceExtension
->TimerWorkQueueEnabled
= FALSE
;
141 // Initialize and queue the work item to handle the error
142 ExInitializeWorkItem(&ErrorHandlerWorkItemData
->WorkQueueItem
,
143 ErrorHandlerWorkItemRoutine
,
144 ErrorHandlerWorkItemData
);
146 ErrorHandlerWorkItemData
->DeviceObject
= Context
->FDODeviceExtension
->FunctionalDeviceObject
;
147 ErrorHandlerWorkItemData
->Context
= Context
;
148 ErrorHandlerWorkItemData
->Irp
= Irp
;
149 ErrorHandlerWorkItemData
->DeviceObject
= Context
->FDODeviceExtension
->FunctionalDeviceObject
;
151 DPRINT1("Queuing WorkItemROutine\n");
152 ExQueueWorkItem(&ErrorHandlerWorkItemData
->WorkQueueItem
, DelayedWorkQueue
);
153 return STATUS_MORE_PROCESSING_REQUIRED
;
156 IO_COMPLETION_ROUTINE USBSTOR_CSWCompletionRoutine
;
160 USBSTOR_CSWCompletionRoutine(
161 PDEVICE_OBJECT DeviceObject
,
165 PIRP_CONTEXT Context
;
166 PIO_STACK_LOCATION IoStack
;
167 PSCSI_REQUEST_BLOCK Request
;
168 PUFI_CAPACITY_RESPONSE Response
;
171 Context
= (PIRP_CONTEXT
)Ctx
;
173 if (Context
->TransferBufferMDL
&& Context
->TransferBufferMDL
!= Context
->Irp
->MdlAddress
)
175 IoFreeMdl(Context
->TransferBufferMDL
);
178 DPRINT("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp
, Ctx
, Irp
->IoStatus
.Status
);
180 // first check for Irp errors
181 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
183 if (USBD_STATUS(Context
->Urb
.UrbHeader
.Status
) == USBD_STATUS(USBD_STATUS_STALL_PID
))
185 if (Context
->RetryCount
< 2)
187 ++Context
->RetryCount
;
189 // clear stall and resend cbw
190 Context
->ErrorIndex
= 1;
191 Status
= USBSTOR_QueueWorkItem(Context
, Irp
);
192 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
194 return STATUS_MORE_PROCESSING_REQUIRED
;
199 DPRINT1("USBSTOR_CSWCompletionRoutine: Urb.Hdr.Status - %x\n", Context
->Urb
.UrbHeader
.Status
);
202 // perform reset recovery
203 Context
->ErrorIndex
= 2;
204 Status
= USBSTOR_QueueWorkItem(Context
, NULL
);
205 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
206 return STATUS_MORE_PROCESSING_REQUIRED
;
209 // now check the CSW packet validity
210 if (!USBSTOR_IsCSWValid(Context
) || Context
->csw
->Status
== CSW_STATUS_PHASE_ERROR
)
212 // perform reset recovery
213 Context
->ErrorIndex
= 2;
214 Status
= USBSTOR_QueueWorkItem(Context
, NULL
);
215 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
216 return STATUS_MORE_PROCESSING_REQUIRED
;
219 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
220 Request
= IoStack
->Parameters
.Scsi
.Srb
;
223 // finally check for CSW errors
224 if (Context
->csw
->Status
== CSW_STATUS_COMMAND_PASSED
)
226 // read capacity needs special work
227 if (Request
->Cdb
[0] == SCSIOP_READ_CAPACITY
)
230 Response
= (PUFI_CAPACITY_RESPONSE
)Context
->TransferData
;
233 Context
->PDODeviceExtension
->BlockLength
= NTOHL(Response
->BlockLength
);
234 Context
->PDODeviceExtension
->LastLogicBlockAddress
= NTOHL(Response
->LastLogicalBlockAddress
);
237 Status
= USBSTOR_SrbStatusToNtStatus(Request
);
239 else if (Context
->csw
->Status
== CSW_STATUS_COMMAND_FAILED
)
241 // the command is correct but with failed status - issue request sense
242 DPRINT("USBSTOR_CSWCompletionRoutine: CSW_STATUS_COMMAND_FAILED\n");
244 ASSERT(Context
->FDODeviceExtension
->ActiveSrb
== Request
);
246 // setting a generic error status, additional information
247 // should be read by higher-level driver from SenseInfoBuffer
248 Request
->SrbStatus
= SRB_STATUS_ERROR
;
249 Request
->ScsiStatus
= 2;
250 Request
->DataTransferLength
= 0;
252 DPRINT("Flags: %x SBL: %x, buf: %p\n", Request
->SrbFlags
, Request
->SenseInfoBufferLength
, Request
->SenseInfoBuffer
);
254 if (!(Request
->SrbFlags
& SRB_FLAGS_DISABLE_AUTOSENSE
) &&
255 Request
->SenseInfoBufferLength
&&
256 Request
->SenseInfoBuffer
)
258 // TODO: issue request sense
261 Status
= STATUS_IO_DEVICE_ERROR
;
264 Irp
->IoStatus
.Status
= Status
;
265 Irp
->IoStatus
.Information
= Request
->DataTransferLength
;
267 FreeItem(Context
->cbw
);
269 // terminate current request
270 USBSTOR_QueueTerminateRequest(Context
->PDODeviceExtension
->LowerDeviceObject
, Irp
);
271 USBSTOR_QueueNextRequest(Context
->PDODeviceExtension
->LowerDeviceObject
);
279 PIRP_CONTEXT Context
,
282 PIO_STACK_LOCATION IoStack
;
284 IoStack
= IoGetNextIrpStackLocation(Irp
);
286 // now initialize the urb for sending the csw
287 UsbBuildInterruptOrBulkTransferRequest(&Context
->Urb
,
288 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
),
289 Context
->FDODeviceExtension
->InterfaceInformation
->Pipes
[Context
->FDODeviceExtension
->BulkInPipeIndex
].PipeHandle
,
293 USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
,
296 // initialize stack location
297 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
298 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
299 IoStack
->Parameters
.Others
.Argument1
= (PVOID
)&Context
->Urb
;
300 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= Context
->Urb
.UrbHeader
.Length
;
301 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
303 IoSetCompletionRoutine(Irp
, USBSTOR_CSWCompletionRoutine
, Context
, TRUE
, TRUE
, TRUE
);
305 IoCallDriver(Context
->FDODeviceExtension
->LowerDeviceObject
, Irp
);
308 IO_COMPLETION_ROUTINE USBSTOR_DataCompletionRoutine
;
312 USBSTOR_DataCompletionRoutine(
313 PDEVICE_OBJECT DeviceObject
,
317 PIRP_CONTEXT Context
;
321 DPRINT("USBSTOR_DataCompletionRoutine Irp %p Ctx %p Status %x\n", Irp
, Ctx
, Irp
->IoStatus
.Status
);
323 Context
= (PIRP_CONTEXT
)Ctx
;
324 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
325 PSCSI_REQUEST_BLOCK Request
= IoStack
->Parameters
.Scsi
.Srb
;
327 if (NT_SUCCESS(Irp
->IoStatus
.Status
))
329 if (Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferLength
< Request
->DataTransferLength
)
331 Request
->SrbStatus
= SRB_STATUS_DATA_OVERRUN
;
335 Request
->SrbStatus
= SRB_STATUS_SUCCESS
;
338 Request
->DataTransferLength
= Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferLength
;
339 USBSTOR_SendCSW(Context
, Irp
);
341 else if (USBD_STATUS(Context
->Urb
.UrbHeader
.Status
) == USBD_STATUS(USBD_STATUS_STALL_PID
))
343 ++Context
->RetryCount
;
345 Request
->SrbStatus
= SRB_STATUS_DATA_OVERRUN
;
346 Request
->DataTransferLength
= Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferLength
;
348 // clear stall and resend cbw
349 Context
->ErrorIndex
= 1;
350 Status
= USBSTOR_QueueWorkItem(Context
, Irp
);
351 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
355 // perform reset recovery
356 Context
->ErrorIndex
= 2;
357 Status
= USBSTOR_QueueWorkItem(Context
, NULL
);
358 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
361 return STATUS_MORE_PROCESSING_REQUIRED
;
364 IO_COMPLETION_ROUTINE USBSTOR_CBWCompletionRoutine
;
368 USBSTOR_CBWCompletionRoutine(
369 PDEVICE_OBJECT DeviceObject
,
373 PIRP_CONTEXT Context
;
374 PIO_STACK_LOCATION IoStack
;
375 PSCSI_REQUEST_BLOCK Request
;
377 USBD_PIPE_HANDLE PipeHandle
;
379 DPRINT("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp
, Ctx
, Irp
->IoStatus
.Status
);
381 Context
= (PIRP_CONTEXT
)Ctx
;
382 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
383 Request
= IoStack
->Parameters
.Scsi
.Srb
;
385 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
387 // perform reset recovery
388 Context
->ErrorIndex
= 2;
389 Status
= USBSTOR_QueueWorkItem(Context
, NULL
);
390 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
391 return STATUS_MORE_PROCESSING_REQUIRED
;
394 // is there data to be submitted
395 if (Context
->TransferDataLength
)
398 Code
= Context
->cbw
->CommandBlock
[0];
400 if (Code
== SCSIOP_WRITE
)
402 // write request - use bulk out pipe
403 PipeHandle
= Context
->FDODeviceExtension
->InterfaceInformation
->Pipes
[Context
->FDODeviceExtension
->BulkOutPipeIndex
].PipeHandle
;
407 // default bulk in pipe
408 PipeHandle
= Context
->FDODeviceExtension
->InterfaceInformation
->Pipes
[Context
->FDODeviceExtension
->BulkInPipeIndex
].PipeHandle
;
411 // now initialize the urb for sending data
412 UsbBuildInterruptOrBulkTransferRequest(&Context
->Urb
,
413 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
),
416 Context
->TransferBufferMDL
,
417 Context
->TransferDataLength
,
418 ((Code
== SCSIOP_WRITE
) ? USBD_TRANSFER_DIRECTION_OUT
: (USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
)),
421 IoSetCompletionRoutine(Irp
, USBSTOR_DataCompletionRoutine
, Context
, TRUE
, TRUE
, TRUE
);
425 if (NT_SUCCESS(Irp
->IoStatus
.Status
))
427 Request
->SrbStatus
= SRB_STATUS_SUCCESS
;
430 // now initialize the urb for sending the csw
431 UsbBuildInterruptOrBulkTransferRequest(&Context
->Urb
,
432 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
),
433 Context
->FDODeviceExtension
->InterfaceInformation
->Pipes
[Context
->FDODeviceExtension
->BulkInPipeIndex
].PipeHandle
,
437 USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
,
440 IoSetCompletionRoutine(Irp
, USBSTOR_CSWCompletionRoutine
, Context
, TRUE
, TRUE
, TRUE
);
443 IoStack
= IoGetNextIrpStackLocation(Irp
);
445 // initialize stack location
446 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
447 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
448 IoStack
->Parameters
.Others
.Argument1
= (PVOID
)&Context
->Urb
;
449 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= Context
->Urb
.UrbHeader
.Length
;
450 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
452 IoCallDriver(Context
->FDODeviceExtension
->LowerDeviceObject
, Irp
);
454 return STATUS_MORE_PROCESSING_REQUIRED
;
461 DPRINT("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
462 Block
[0] & 0xFF, Block
[1] & 0xFF, Block
[2] & 0xFF, Block
[3] & 0xFF, Block
[4] & 0xFF, Block
[5] & 0xFF, Block
[6] & 0xFF, Block
[7] & 0xFF, Block
[8] & 0xFF, Block
[9] & 0xFF,
463 Block
[10] & 0xFF, Block
[11] & 0xFF, Block
[12] & 0xFF, Block
[13] & 0xFF, Block
[14] & 0xFF, Block
[15] & 0xFF, Block
[16] & 0xFF, Block
[17] & 0xFF, Block
[18] & 0xFF, Block
[19] & 0xFF,
464 Block
[20] & 0xFF, Block
[21] & 0xFF, Block
[22] & 0xFF, Block
[23] & 0xFF, Block
[24] & 0xFF, Block
[25] & 0xFF, Block
[26] & 0xFF, Block
[27] & 0xFF, Block
[28] & 0xFF, Block
[29] & 0xFF,
471 PIRP_CONTEXT Context
,
474 PIO_STACK_LOCATION IoStack
;
476 IoStack
= IoGetNextIrpStackLocation(Irp
);
478 // initialize stack location
479 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
480 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
481 IoStack
->Parameters
.Others
.Argument1
= (PVOID
)&Context
->Urb
;
482 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= Context
->Urb
.UrbHeader
.Length
;
483 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
485 IoSetCompletionRoutine(Irp
, USBSTOR_CBWCompletionRoutine
, Context
, TRUE
, TRUE
, TRUE
);
487 return IoCallDriver(Context
->FDODeviceExtension
->LowerDeviceObject
, Irp
);
492 IN PDEVICE_OBJECT DeviceObject
,
493 IN PIRP OriginalRequest
,
494 IN UCHAR CommandLength
,
496 IN ULONG TransferDataLength
,
497 IN PUCHAR TransferData
,
500 PIRP_CONTEXT Context
;
501 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
502 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
503 PUCHAR MdlVirtualAddress
;
505 Context
= USBSTOR_AllocateIrpContext();
508 return STATUS_INSUFFICIENT_RESOURCES
;
511 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
512 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)PDODeviceExtension
->LowerDeviceObject
->DeviceExtension
;
514 USBSTOR_BuildCBW(PtrToUlong(Context
->cbw
),
516 PDODeviceExtension
->LUN
,
521 DPRINT("CBW %p\n", Context
->cbw
);
522 DumpCBW((PUCHAR
)Context
->cbw
);
524 // now initialize the urb
525 UsbBuildInterruptOrBulkTransferRequest(&Context
->Urb
,
526 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
),
527 FDODeviceExtension
->InterfaceInformation
->Pipes
[FDODeviceExtension
->BulkOutPipeIndex
].PipeHandle
,
531 USBD_TRANSFER_DIRECTION_OUT
,
534 // initialize rest of context
535 Context
->Irp
= OriginalRequest
;
536 Context
->TransferData
= TransferData
;
537 Context
->TransferDataLength
= TransferDataLength
;
538 Context
->FDODeviceExtension
= FDODeviceExtension
;
539 Context
->PDODeviceExtension
= PDODeviceExtension
;
540 Context
->RetryCount
= RetryCount
;
542 // is there transfer data
543 if (Context
->TransferDataLength
)
545 // check if the original request already does have an mdl associated
546 if ((OriginalRequest
->MdlAddress
!= NULL
) &&
547 (Context
->TransferData
== NULL
|| Command
[0] == SCSIOP_READ
|| Command
[0] == SCSIOP_WRITE
))
549 // Sanity check that the Mdl does describe the TransferData for read/write
550 if (CommandLength
== UFI_READ_WRITE_CMD_LEN
)
552 MdlVirtualAddress
= MmGetMdlVirtualAddress(OriginalRequest
->MdlAddress
);
554 // is there an offset
555 if (MdlVirtualAddress
!= Context
->TransferData
)
558 Context
->TransferBufferMDL
= IoAllocateMdl(Context
->TransferData
, MmGetMdlByteCount(OriginalRequest
->MdlAddress
), FALSE
, FALSE
, NULL
);
559 if (!Context
->TransferBufferMDL
)
561 FreeItem(Context
->cbw
);
563 return STATUS_INSUFFICIENT_RESOURCES
;
566 IoBuildPartialMdl(OriginalRequest
->MdlAddress
, Context
->TransferBufferMDL
, Context
->TransferData
, Context
->TransferDataLength
);
570 if (!Context
->TransferBufferMDL
)
572 // I/O paging request
573 Context
->TransferBufferMDL
= OriginalRequest
->MdlAddress
;
578 // allocate mdl for buffer, buffer must be allocated from NonPagedPool
579 Context
->TransferBufferMDL
= IoAllocateMdl(Context
->TransferData
, Context
->TransferDataLength
, FALSE
, FALSE
, NULL
);
580 if (!Context
->TransferBufferMDL
)
582 FreeItem(Context
->cbw
);
584 return STATUS_INSUFFICIENT_RESOURCES
;
587 MmBuildMdlForNonPagedPool(Context
->TransferBufferMDL
);
591 return USBSTOR_SendCBW(Context
, OriginalRequest
);
595 USBSTOR_HandleExecuteSCSI(
596 IN PDEVICE_OBJECT DeviceObject
,
602 PIO_STACK_LOCATION IoStack
;
603 PSCSI_REQUEST_BLOCK Request
;
604 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
606 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
607 ASSERT(PDODeviceExtension
->Common
.IsFDO
== FALSE
);
609 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
610 Request
= IoStack
->Parameters
.Scsi
.Srb
;
611 pCDB
= (PCDB
)Request
->Cdb
;
613 DPRINT("USBSTOR_HandleExecuteSCSI Operation Code %x, Length %lu\n", pCDB
->CDB10
.OperationCode
, Request
->DataTransferLength
);
615 // check that we're sending to the right LUN
616 ASSERT(pCDB
->CDB10
.LogicalUnitNumber
== (PDODeviceExtension
->LUN
& MAX_LUN
));
617 Status
= USBSTOR_SendRequest(DeviceObject
, Irp
, Request
->CdbLength
, (PUCHAR
)pCDB
, Request
->DataTransferLength
, Request
->DataBuffer
, RetryCount
);