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
;
60 USBSTOR_IssueBulkOrInterruptRequest(
61 IN PFDO_DEVICE_EXTENSION FDODeviceExtension
,
63 IN USBD_PIPE_HANDLE PipeHandle
,
64 IN ULONG TransferFlags
,
65 IN ULONG TransferBufferLength
,
66 IN PVOID TransferBuffer
,
67 IN PMDL TransferBufferMDL
,
68 IN PIO_COMPLETION_ROUTINE CompletionRoutine
,
69 IN PIRP_CONTEXT Context
)
71 PIO_STACK_LOCATION NextStack
;
73 RtlZeroMemory(&Context
->Urb
, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
));
75 Context
->Urb
.UrbHeader
.Length
= sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
);
76 Context
->Urb
.UrbHeader
.Function
= URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
;
78 Context
->Urb
.UrbBulkOrInterruptTransfer
.PipeHandle
= PipeHandle
;
79 Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferFlags
= TransferFlags
;
80 Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferLength
= TransferBufferLength
;
81 Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBuffer
= TransferBuffer
;
82 Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferMDL
= TransferBufferMDL
;
84 NextStack
= IoGetNextIrpStackLocation(Irp
);
85 NextStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
86 NextStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
87 NextStack
->Parameters
.Others
.Argument1
= &Context
->Urb
;
89 IoSetCompletionRoutine(Irp
,
96 return IoCallDriver(FDODeviceExtension
->LowerDeviceObject
, Irp
);
102 PIRP_CONTEXT Context
)
104 if (Context
->csw
.Signature
!= CSW_SIGNATURE
)
106 DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE
, Context
->csw
.Signature
);
110 if (Context
->csw
.Tag
!= PtrToUlong(&Context
->csw
))
112 DPRINT1("[USBSTOR] Expected Tag %Ix but got %x\n", PtrToUlong(&Context
->csw
), Context
->csw
.Tag
);
120 USBSTOR_QueueWorkItem(
121 PIRP_CONTEXT Context
,
124 PERRORHANDLER_WORKITEM_DATA ErrorHandlerWorkItemData
;
126 ErrorHandlerWorkItemData
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(ERRORHANDLER_WORKITEM_DATA
), USB_STOR_TAG
);
127 if (!ErrorHandlerWorkItemData
)
129 return STATUS_INSUFFICIENT_RESOURCES
;
132 // error handling started
133 Context
->FDODeviceExtension
->SrbErrorHandlingActive
= TRUE
;
135 // srb error handling finished
136 Context
->FDODeviceExtension
->TimerWorkQueueEnabled
= FALSE
;
138 // Initialize and queue the work item to handle the error
139 ExInitializeWorkItem(&ErrorHandlerWorkItemData
->WorkQueueItem
,
140 ErrorHandlerWorkItemRoutine
,
141 ErrorHandlerWorkItemData
);
143 ErrorHandlerWorkItemData
->DeviceObject
= Context
->FDODeviceExtension
->FunctionalDeviceObject
;
144 ErrorHandlerWorkItemData
->Context
= Context
;
145 ErrorHandlerWorkItemData
->Irp
= Irp
;
146 ErrorHandlerWorkItemData
->DeviceObject
= Context
->FDODeviceExtension
->FunctionalDeviceObject
;
148 DPRINT1("Queuing WorkItemROutine\n");
149 ExQueueWorkItem(&ErrorHandlerWorkItemData
->WorkQueueItem
, DelayedWorkQueue
);
150 return STATUS_MORE_PROCESSING_REQUIRED
;
155 USBSTOR_IssueRequestSense(
156 IN PFDO_DEVICE_EXTENSION FDODeviceExtension
,
158 IN PIRP_CONTEXT Context
);
160 IO_COMPLETION_ROUTINE USBSTOR_CSWCompletionRoutine
;
164 USBSTOR_CSWCompletionRoutine(
165 PDEVICE_OBJECT DeviceObject
,
169 PIRP_CONTEXT Context
;
170 PIO_STACK_LOCATION IoStack
;
171 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
172 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
173 PSCSI_REQUEST_BLOCK Request
;
174 PUFI_CAPACITY_RESPONSE Response
;
177 Context
= (PIRP_CONTEXT
)Ctx
;
179 DPRINT("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp
, Ctx
, Irp
->IoStatus
.Status
);
181 // first check for Irp errors
182 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
184 if (USBD_STATUS(Context
->Urb
.UrbHeader
.Status
) == USBD_STATUS(USBD_STATUS_STALL_PID
))
186 if (Context
->StallRetryCount
< 2)
188 ++Context
->StallRetryCount
;
190 // clear stall and resend cbw
191 Context
->ErrorIndex
= 1;
192 Status
= USBSTOR_QueueWorkItem(Context
, Irp
);
193 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
195 return STATUS_MORE_PROCESSING_REQUIRED
;
200 DPRINT1("USBSTOR_CSWCompletionRoutine: Urb.Hdr.Status - %x\n", Context
->Urb
.UrbHeader
.Status
);
203 // perform reset recovery
204 Context
->ErrorIndex
= 2;
205 Status
= USBSTOR_QueueWorkItem(Context
, NULL
);
206 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
207 return STATUS_MORE_PROCESSING_REQUIRED
;
210 // now check the CSW packet validity
211 if (!USBSTOR_IsCSWValid(Context
) || Context
->csw
.Status
== CSW_STATUS_PHASE_ERROR
)
213 // perform reset recovery
214 Context
->ErrorIndex
= 2;
215 Status
= USBSTOR_QueueWorkItem(Context
, NULL
);
216 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
217 return STATUS_MORE_PROCESSING_REQUIRED
;
220 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
221 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
222 FDODeviceExtension
= Context
->FDODeviceExtension
;
223 Request
= IoStack
->Parameters
.Scsi
.Srb
;
226 // finally check for CSW errors
227 if (Context
->csw
.Status
== CSW_STATUS_COMMAND_PASSED
)
229 // should happen only when a sense request was sent
230 if (Request
!= FDODeviceExtension
->ActiveSrb
)
232 ASSERT(IoStack
->Parameters
.Scsi
.Srb
== &Context
->SenseSrb
);
233 FDODeviceExtension
->ActiveSrb
->SenseInfoBufferLength
= Request
->DataTransferLength
;
234 Request
= FDODeviceExtension
->ActiveSrb
;
235 IoStack
->Parameters
.Scsi
.Srb
= Request
;
236 Request
->SrbStatus
|= SRB_STATUS_AUTOSENSE_VALID
;
239 // read capacity needs special work
240 if (Request
->Cdb
[0] == SCSIOP_READ_CAPACITY
)
243 Response
= (PUFI_CAPACITY_RESPONSE
)Request
->DataBuffer
;
246 PDODeviceExtension
->BlockLength
= NTOHL(Response
->BlockLength
);
247 PDODeviceExtension
->LastLogicBlockAddress
= NTOHL(Response
->LastLogicalBlockAddress
);
250 Status
= USBSTOR_SrbStatusToNtStatus(Request
);
252 else if (Context
->csw
.Status
== CSW_STATUS_COMMAND_FAILED
)
254 // the command is correct but with failed status - issue request sense
255 DPRINT("USBSTOR_CSWCompletionRoutine: CSW_STATUS_COMMAND_FAILED\n");
257 ASSERT(FDODeviceExtension
->ActiveSrb
== Request
);
259 // setting a generic error status, additional information
260 // should be read by higher-level driver from SenseInfoBuffer
261 Request
->SrbStatus
= SRB_STATUS_ERROR
;
262 Request
->ScsiStatus
= 2;
263 Request
->DataTransferLength
= 0;
265 DPRINT("Flags: %x SBL: %x, buf: %p\n", Request
->SrbFlags
, Request
->SenseInfoBufferLength
, Request
->SenseInfoBuffer
);
267 if (!(Request
->SrbFlags
& SRB_FLAGS_DISABLE_AUTOSENSE
) &&
268 Request
->SenseInfoBufferLength
&&
269 Request
->SenseInfoBuffer
)
271 USBSTOR_IssueRequestSense(FDODeviceExtension
, Irp
, Context
);
272 return STATUS_MORE_PROCESSING_REQUIRED
;
275 Status
= STATUS_IO_DEVICE_ERROR
;
278 Irp
->IoStatus
.Status
= Status
;
279 Irp
->IoStatus
.Information
= Request
->DataTransferLength
;
281 // terminate current request
282 USBSTOR_QueueTerminateRequest(PDODeviceExtension
->LowerDeviceObject
, Irp
);
283 USBSTOR_QueueNextRequest(PDODeviceExtension
->LowerDeviceObject
);
285 ExFreePoolWithTag(Context
, USB_STOR_TAG
);
290 USBSTOR_SendCSWRequest(
291 PIRP_CONTEXT Context
,
294 return USBSTOR_IssueBulkOrInterruptRequest(Context
->FDODeviceExtension
,
296 Context
->FDODeviceExtension
->InterfaceInformation
->Pipes
[Context
->FDODeviceExtension
->BulkInPipeIndex
].PipeHandle
,
297 USBD_TRANSFER_DIRECTION_IN
,
301 USBSTOR_CSWCompletionRoutine
,
305 IO_COMPLETION_ROUTINE USBSTOR_DataCompletionRoutine
;
309 USBSTOR_DataCompletionRoutine(
310 PDEVICE_OBJECT DeviceObject
,
314 PIRP_CONTEXT Context
;
316 PIO_STACK_LOCATION IoStack
;
317 PSCSI_REQUEST_BLOCK Request
;
319 DPRINT("USBSTOR_DataCompletionRoutine Irp %p Ctx %p Status %x\n", Irp
, Ctx
, Irp
->IoStatus
.Status
);
321 Context
= (PIRP_CONTEXT
)Ctx
;
322 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
323 Request
= IoStack
->Parameters
.Scsi
.Srb
;
325 // for Sense Request a partial MDL was already freed (if existed)
326 if (Request
== Context
->FDODeviceExtension
->ActiveSrb
&&
327 Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferMDL
!= Irp
->MdlAddress
)
329 IoFreeMdl(Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferMDL
);
332 if (NT_SUCCESS(Irp
->IoStatus
.Status
))
334 if (Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferLength
< Request
->DataTransferLength
)
336 Request
->SrbStatus
= SRB_STATUS_DATA_OVERRUN
;
340 Request
->SrbStatus
= SRB_STATUS_SUCCESS
;
343 Request
->DataTransferLength
= Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferLength
;
344 USBSTOR_SendCSWRequest(Context
, Irp
);
346 else if (USBD_STATUS(Context
->Urb
.UrbHeader
.Status
) == USBD_STATUS(USBD_STATUS_STALL_PID
))
348 ++Context
->StallRetryCount
;
350 Request
->SrbStatus
= SRB_STATUS_DATA_OVERRUN
;
351 Request
->DataTransferLength
= Context
->Urb
.UrbBulkOrInterruptTransfer
.TransferBufferLength
;
353 // clear stall and resend cbw
354 Context
->ErrorIndex
= 1;
355 Status
= USBSTOR_QueueWorkItem(Context
, Irp
);
356 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
360 // perform reset recovery
361 Context
->ErrorIndex
= 2;
362 Status
= USBSTOR_QueueWorkItem(Context
, NULL
);
363 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
366 return STATUS_MORE_PROCESSING_REQUIRED
;
369 IO_COMPLETION_ROUTINE USBSTOR_CBWCompletionRoutine
;
373 USBSTOR_CBWCompletionRoutine(
374 PDEVICE_OBJECT DeviceObject
,
378 PIRP_CONTEXT Context
;
379 PIO_STACK_LOCATION IoStack
;
380 PSCSI_REQUEST_BLOCK Request
;
381 USBD_PIPE_HANDLE PipeHandle
;
384 PVOID TransferBuffer
= NULL
;
387 DPRINT("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp
, Ctx
, Irp
->IoStatus
.Status
);
389 Context
= (PIRP_CONTEXT
)Ctx
;
390 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
391 Request
= IoStack
->Parameters
.Scsi
.Srb
;
393 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
398 // a request without the buffer AND not a sense request
399 // for a sense request we provide just a TransferBuffer, an Mdl will be allocated by usbport (see below)
400 if (!Irp
->MdlAddress
&& Request
== Context
->FDODeviceExtension
->ActiveSrb
)
402 Request
->SrbStatus
= SRB_STATUS_SUCCESS
;
403 USBSTOR_SendCSWRequest(Context
, Irp
);
404 return STATUS_MORE_PROCESSING_REQUIRED
;
407 // a request with the data buffer
409 if ((Request
->SrbFlags
& SRB_FLAGS_UNSPECIFIED_DIRECTION
) == SRB_FLAGS_DATA_IN
)
411 PipeHandle
= Context
->FDODeviceExtension
->InterfaceInformation
->Pipes
[Context
->FDODeviceExtension
->BulkInPipeIndex
].PipeHandle
;
412 TransferFlags
= USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
;
414 else if ((Request
->SrbFlags
& SRB_FLAGS_UNSPECIFIED_DIRECTION
) == SRB_FLAGS_DATA_OUT
)
416 PipeHandle
= Context
->FDODeviceExtension
->InterfaceInformation
->Pipes
[Context
->FDODeviceExtension
->BulkOutPipeIndex
].PipeHandle
;
417 TransferFlags
= USBD_TRANSFER_DIRECTION_OUT
;
421 // we check the validity of a request in disk.c so we should never be here
422 DPRINT1("Warning: shouldn't be here\n");
426 // if it is not a Sense Request
427 if (Request
== Context
->FDODeviceExtension
->ActiveSrb
)
429 if (MmGetMdlVirtualAddress(Irp
->MdlAddress
) == Request
->DataBuffer
)
431 Mdl
= Irp
->MdlAddress
;
435 Mdl
= IoAllocateMdl(Request
->DataBuffer
,
436 Request
->DataTransferLength
,
443 IoBuildPartialMdl(Irp
->MdlAddress
,
446 Request
->DataTransferLength
);
452 DPRINT1("USBSTOR_CBWCompletionRoutine: Mdl - %p\n", Mdl
);
458 TransferBuffer
= Request
->DataBuffer
;
460 if (!Request
->DataBuffer
)
462 DPRINT("USBSTOR_CBWCompletionRoutine: Request->DataBuffer == NULL!\n");
463 return STATUS_INVALID_PARAMETER
;
467 USBSTOR_IssueBulkOrInterruptRequest(Context
->FDODeviceExtension
,
471 Request
->DataTransferLength
,
474 USBSTOR_DataCompletionRoutine
,
477 return STATUS_MORE_PROCESSING_REQUIRED
;
480 Context
->ErrorIndex
= 2;
481 Status
= USBSTOR_QueueWorkItem(Context
, NULL
);
482 ASSERT(Status
== STATUS_MORE_PROCESSING_REQUIRED
);
483 return STATUS_MORE_PROCESSING_REQUIRED
;
490 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",
491 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,
492 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,
493 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,
499 USBSTOR_SendCBWRequest(
500 IN PFDO_DEVICE_EXTENSION FDODeviceExtension
,
502 IN PIRP_CONTEXT Context
)
504 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
505 PIO_STACK_LOCATION IoStack
;
506 PSCSI_REQUEST_BLOCK Request
;
508 RtlZeroMemory(&Context
->cbw
, sizeof(CBW
));
509 RtlZeroMemory(&Context
->Urb
, sizeof(URB
));
511 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
512 PDODeviceExtension
= IoStack
->DeviceObject
->DeviceExtension
;
513 Request
= IoStack
->Parameters
.Scsi
.Srb
;
515 Context
->cbw
.Signature
= CBW_SIGNATURE
;
516 Context
->cbw
.Tag
= PtrToUlong(&Context
->cbw
);
517 Context
->cbw
.DataTransferLength
= Request
->DataTransferLength
;
518 Context
->cbw
.Flags
= ((UCHAR
)Request
->SrbFlags
& SRB_FLAGS_UNSPECIFIED_DIRECTION
) << 1;
519 Context
->cbw
.LUN
= PDODeviceExtension
->LUN
;
520 Context
->cbw
.CommandBlockLength
= Request
->CdbLength
;
522 RtlCopyMemory(&Context
->cbw
.CommandBlock
, Request
->Cdb
, Request
->CdbLength
);
524 DPRINT("CBW for IRP %p\n", Irp
);
525 DumpCBW((PUCHAR
)&Context
->cbw
);
527 // initialize rest of context
529 Context
->FDODeviceExtension
= FDODeviceExtension
;
530 Context
->StallRetryCount
= 0;
532 return USBSTOR_IssueBulkOrInterruptRequest(
535 FDODeviceExtension
->InterfaceInformation
->Pipes
[FDODeviceExtension
->BulkOutPipeIndex
].PipeHandle
,
536 USBD_TRANSFER_DIRECTION_OUT
,
540 USBSTOR_CBWCompletionRoutine
,
546 USBSTOR_IssueRequestSense(
547 IN PFDO_DEVICE_EXTENSION FDODeviceExtension
,
549 IN PIRP_CONTEXT Context
)
551 PIO_STACK_LOCATION IoStack
;
552 PSCSI_REQUEST_BLOCK CurrentSrb
;
553 PSCSI_REQUEST_BLOCK SenseSrb
;
556 DPRINT("USBSTOR_IssueRequestSense: \n");
558 CurrentSrb
= FDODeviceExtension
->ActiveSrb
;
559 SenseSrb
= &Context
->SenseSrb
;
560 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
561 IoStack
->Parameters
.Scsi
.Srb
= SenseSrb
;
563 RtlZeroMemory(SenseSrb
, sizeof(*SenseSrb
));
565 SenseSrb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
566 SenseSrb
->Length
= sizeof(*SenseSrb
);
567 SenseSrb
->CdbLength
= CDB6GENERIC_LENGTH
;
568 SenseSrb
->SrbFlags
= SRB_FLAGS_DATA_IN
|
569 SRB_FLAGS_NO_QUEUE_FREEZE
|
570 SRB_FLAGS_DISABLE_AUTOSENSE
;
572 ASSERT(CurrentSrb
->SenseInfoBufferLength
);
573 ASSERT(CurrentSrb
->SenseInfoBuffer
);
574 DPRINT("SenseInfoBuffer %x, SenseInfoBufferLength %x\n", CurrentSrb
->SenseInfoBuffer
, CurrentSrb
->SenseInfoBufferLength
);
576 SenseSrb
->DataTransferLength
= CurrentSrb
->SenseInfoBufferLength
;
577 SenseSrb
->DataBuffer
= CurrentSrb
->SenseInfoBuffer
;
579 pCDB
= (PCDB
)SenseSrb
->Cdb
;
580 pCDB
->CDB6GENERIC
.OperationCode
= SCSIOP_REQUEST_SENSE
;
581 pCDB
->AsByte
[4] = CurrentSrb
->SenseInfoBufferLength
;
583 return USBSTOR_SendCBWRequest(FDODeviceExtension
, Irp
, Context
);
587 USBSTOR_HandleExecuteSCSI(
588 IN PDEVICE_OBJECT DeviceObject
,
593 PIO_STACK_LOCATION IoStack
;
594 PSCSI_REQUEST_BLOCK Request
;
595 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
596 PIRP_CONTEXT Context
;
598 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
599 ASSERT(PDODeviceExtension
->Common
.IsFDO
== FALSE
);
601 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
602 Request
= IoStack
->Parameters
.Scsi
.Srb
;
603 pCDB
= (PCDB
)Request
->Cdb
;
605 DPRINT("USBSTOR_HandleExecuteSCSI Operation Code %x, Length %lu\n", pCDB
->CDB10
.OperationCode
, Request
->DataTransferLength
);
607 // check that we're sending to the right LUN
608 ASSERT(pCDB
->CDB10
.LogicalUnitNumber
== (PDODeviceExtension
->LUN
& MAX_LUN
));
609 Context
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(IRP_CONTEXT
), USB_STOR_TAG
);
613 Status
= STATUS_INSUFFICIENT_RESOURCES
;
617 Status
= USBSTOR_SendCBWRequest(PDODeviceExtension
->LowerDeviceObject
->DeviceExtension
, Irp
, Context
);