be27921bd3a6b38408d0de4dd67223ab4d614abb
[reactos.git] / drivers / usb / usbstor / scsi.c
1 /*
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)
8 * 2017 Vadim Galyant
9 * 2019 Victor Perevertkin (victor.perevertkin@reactos.org)
10 */
11
12 #include "usbstor.h"
13
14 #define NDEBUG
15 #include <debug.h>
16
17
18 static
19 NTSTATUS
20 USBSTOR_SrbStatusToNtStatus(
21 IN PSCSI_REQUEST_BLOCK Srb)
22 {
23 UCHAR SrbStatus;
24
25 SrbStatus = SRB_STATUS(Srb->SrbStatus);
26
27 switch (SrbStatus)
28 {
29 case SRB_STATUS_SUCCESS:
30 return STATUS_SUCCESS;
31
32 case SRB_STATUS_DATA_OVERRUN:
33 return STATUS_BUFFER_OVERFLOW;
34
35 case SRB_STATUS_BAD_FUNCTION:
36 case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:
37 return STATUS_INVALID_DEVICE_REQUEST;
38
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;
44
45 case SRB_STATUS_TIMEOUT:
46 return STATUS_IO_TIMEOUT;
47
48 case SRB_STATUS_BUS_RESET:
49 case SRB_STATUS_COMMAND_TIMEOUT:
50 case SRB_STATUS_SELECTION_TIMEOUT:
51 return STATUS_DEVICE_NOT_CONNECTED;
52
53 default:
54 return STATUS_IO_DEVICE_ERROR;
55 }
56 }
57
58 static
59 NTSTATUS
60 USBSTOR_IssueBulkOrInterruptRequest(
61 IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
62 IN PIRP Irp,
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)
70 {
71 PIO_STACK_LOCATION NextStack;
72
73 RtlZeroMemory(&Context->Urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
74
75 Context->Urb.UrbHeader.Length = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
76 Context->Urb.UrbHeader.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
77
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;
83
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;
88
89 IoSetCompletionRoutine(Irp,
90 CompletionRoutine,
91 Context,
92 TRUE,
93 TRUE,
94 TRUE);
95
96 return IoCallDriver(FDODeviceExtension->LowerDeviceObject, Irp);
97 }
98
99 static
100 BOOLEAN
101 USBSTOR_IsCSWValid(
102 PIRP_CONTEXT Context)
103 {
104 if (Context->csw.Signature != CSW_SIGNATURE)
105 {
106 DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE, Context->csw.Signature);
107 return FALSE;
108 }
109
110 if (Context->csw.Tag != PtrToUlong(&Context->csw))
111 {
112 DPRINT1("[USBSTOR] Expected Tag %Ix but got %x\n", PtrToUlong(&Context->csw), Context->csw.Tag);
113 return FALSE;
114 }
115
116 return TRUE;
117 }
118
119 static
120 NTSTATUS
121 USBSTOR_IssueRequestSense(
122 IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
123 IN PIRP Irp,
124 IN PIRP_CONTEXT Context);
125
126 IO_COMPLETION_ROUTINE USBSTOR_CSWCompletionRoutine;
127
128 NTSTATUS
129 NTAPI
130 USBSTOR_CSWCompletionRoutine(
131 PDEVICE_OBJECT DeviceObject,
132 PIRP Irp,
133 PVOID Ctx)
134 {
135 PIRP_CONTEXT Context;
136 PIO_STACK_LOCATION IoStack;
137 PPDO_DEVICE_EXTENSION PDODeviceExtension;
138 PFDO_DEVICE_EXTENSION FDODeviceExtension;
139 PSCSI_REQUEST_BLOCK Request;
140 PUFI_CAPACITY_RESPONSE Response;
141
142 Context = (PIRP_CONTEXT)Ctx;
143
144 DPRINT("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status);
145
146 IoStack = IoGetCurrentIrpStackLocation(Irp);
147 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
148 FDODeviceExtension = Context->FDODeviceExtension;
149 Request = IoStack->Parameters.Scsi.Srb;
150 ASSERT(Request);
151
152 // first check for Irp errors
153 if (!NT_SUCCESS(Irp->IoStatus.Status))
154 {
155 if (USBD_STATUS(Context->Urb.UrbHeader.Status) == USBD_STATUS(USBD_STATUS_STALL_PID))
156 {
157 if (Context->StallRetryCount < 2)
158 {
159 ++Context->StallRetryCount;
160
161 // clear stall and resend cbw
162 USBSTOR_QueueResetPipe(FDODeviceExtension, Context);
163
164 return STATUS_MORE_PROCESSING_REQUIRED;
165 }
166 }
167 else
168 {
169 DPRINT1("USBSTOR_CSWCompletionRoutine: Urb.Hdr.Status - %x\n", Context->Urb.UrbHeader.Status);
170 }
171
172 goto ResetRecovery;
173 }
174
175 // now check the CSW packet validity
176 if (!USBSTOR_IsCSWValid(Context) || Context->csw.Status == CSW_STATUS_PHASE_ERROR)
177 {
178 goto ResetRecovery;
179 }
180
181 // finally check for CSW errors
182 if (Context->csw.Status == CSW_STATUS_COMMAND_PASSED)
183 {
184 // should happen only when a sense request was sent
185 if (Request != FDODeviceExtension->ActiveSrb)
186 {
187 ASSERT(IoStack->Parameters.Scsi.Srb == &Context->SenseSrb);
188 FDODeviceExtension->ActiveSrb->SenseInfoBufferLength = Request->DataTransferLength;
189 Request = FDODeviceExtension->ActiveSrb;
190 IoStack->Parameters.Scsi.Srb = Request;
191 Request->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
192 }
193
194 // read capacity needs special work
195 if (Request->Cdb[0] == SCSIOP_READ_CAPACITY)
196 {
197 // get output buffer
198 Response = (PUFI_CAPACITY_RESPONSE)Request->DataBuffer;
199
200 // store in pdo
201 PDODeviceExtension->BlockLength = NTOHL(Response->BlockLength);
202 PDODeviceExtension->LastLogicBlockAddress = NTOHL(Response->LastLogicalBlockAddress);
203 }
204
205 Irp->IoStatus.Status = USBSTOR_SrbStatusToNtStatus(Request);
206 }
207 else if (Context->csw.Status == CSW_STATUS_COMMAND_FAILED)
208 {
209 // the command is correct but with failed status - issue request sense
210 DPRINT("USBSTOR_CSWCompletionRoutine: CSW_STATUS_COMMAND_FAILED\n");
211
212 ASSERT(FDODeviceExtension->ActiveSrb == Request);
213
214 // setting a generic error status, additional information
215 // should be read by higher-level driver from SenseInfoBuffer
216 Request->SrbStatus = SRB_STATUS_ERROR;
217 Request->ScsiStatus = 2;
218 Request->DataTransferLength = 0;
219
220 DPRINT("Flags: %x SBL: %x, buf: %p\n", Request->SrbFlags, Request->SenseInfoBufferLength, Request->SenseInfoBuffer);
221
222 if (!(Request->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE) &&
223 Request->SenseInfoBufferLength &&
224 Request->SenseInfoBuffer)
225 {
226 USBSTOR_IssueRequestSense(FDODeviceExtension, Irp, Context);
227 return STATUS_MORE_PROCESSING_REQUIRED;
228 }
229
230 Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
231 }
232
233 Irp->IoStatus.Information = Request->DataTransferLength;
234
235 // terminate current request
236 USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
237 USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject);
238
239 ExFreePoolWithTag(Context, USB_STOR_TAG);
240 return STATUS_CONTINUE_COMPLETION;
241
242 ResetRecovery:
243
244 Request = FDODeviceExtension->ActiveSrb;
245 IoStack->Parameters.Scsi.Srb = Request;
246 Irp->IoStatus.Information = 0;
247 Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
248 Request->SrbStatus = SRB_STATUS_BUS_RESET;
249
250 USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
251 USBSTOR_QueueResetDevice(FDODeviceExtension);
252
253 ExFreePoolWithTag(Context, USB_STOR_TAG);
254 return STATUS_CONTINUE_COMPLETION;
255 }
256
257 NTSTATUS
258 USBSTOR_SendCSWRequest(
259 PIRP_CONTEXT Context,
260 PIRP Irp)
261 {
262 return USBSTOR_IssueBulkOrInterruptRequest(Context->FDODeviceExtension,
263 Irp,
264 Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle,
265 USBD_TRANSFER_DIRECTION_IN,
266 sizeof(CSW),
267 &Context->csw,
268 NULL,
269 USBSTOR_CSWCompletionRoutine,
270 Context);
271 }
272
273 IO_COMPLETION_ROUTINE USBSTOR_DataCompletionRoutine;
274
275 NTSTATUS
276 NTAPI
277 USBSTOR_DataCompletionRoutine(
278 PDEVICE_OBJECT DeviceObject,
279 PIRP Irp,
280 PVOID Ctx)
281 {
282 PIRP_CONTEXT Context;
283 PIO_STACK_LOCATION IoStack;
284 PSCSI_REQUEST_BLOCK Request;
285 PPDO_DEVICE_EXTENSION PDODeviceExtension;
286
287 DPRINT("USBSTOR_DataCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status);
288
289 Context = (PIRP_CONTEXT)Ctx;
290 IoStack = IoGetCurrentIrpStackLocation(Irp);
291 Request = IoStack->Parameters.Scsi.Srb;
292 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
293
294 // for Sense Request a partial MDL was already freed (if existed)
295 if (Request == Context->FDODeviceExtension->ActiveSrb &&
296 Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL != Irp->MdlAddress)
297 {
298 IoFreeMdl(Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL);
299 }
300
301 if (NT_SUCCESS(Irp->IoStatus.Status))
302 {
303 if (Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength < Request->DataTransferLength)
304 {
305 Request->SrbStatus = SRB_STATUS_DATA_OVERRUN;
306 }
307 else
308 {
309 Request->SrbStatus = SRB_STATUS_SUCCESS;
310 }
311
312 Request->DataTransferLength = Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength;
313 USBSTOR_SendCSWRequest(Context, Irp);
314 }
315 else if (USBD_STATUS(Context->Urb.UrbHeader.Status) == USBD_STATUS(USBD_STATUS_STALL_PID))
316 {
317 ++Context->StallRetryCount;
318
319 Request->SrbStatus = SRB_STATUS_DATA_OVERRUN;
320 Request->DataTransferLength = Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength;
321
322 // clear stall and resend cbw
323 USBSTOR_QueueResetPipe(Context->FDODeviceExtension, Context);
324 }
325 else
326 {
327 Irp->IoStatus.Information = 0;
328 Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
329 Request->SrbStatus = SRB_STATUS_BUS_RESET;
330
331 USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
332 USBSTOR_QueueResetDevice(Context->FDODeviceExtension);
333
334 ExFreePoolWithTag(Context, USB_STOR_TAG);
335 return STATUS_CONTINUE_COMPLETION;
336 }
337
338 return STATUS_MORE_PROCESSING_REQUIRED;
339 }
340
341 IO_COMPLETION_ROUTINE USBSTOR_CBWCompletionRoutine;
342
343 NTSTATUS
344 NTAPI
345 USBSTOR_CBWCompletionRoutine(
346 PDEVICE_OBJECT DeviceObject,
347 PIRP Irp,
348 PVOID Ctx)
349 {
350 PIRP_CONTEXT Context;
351 PIO_STACK_LOCATION IoStack;
352 PSCSI_REQUEST_BLOCK Request;
353 PPDO_DEVICE_EXTENSION PDODeviceExtension;
354 USBD_PIPE_HANDLE PipeHandle;
355 ULONG TransferFlags;
356 PMDL Mdl = NULL;
357 PVOID TransferBuffer = NULL;
358
359 DPRINT("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status);
360
361 Context = (PIRP_CONTEXT)Ctx;
362 IoStack = IoGetCurrentIrpStackLocation(Irp);
363 Request = IoStack->Parameters.Scsi.Srb;
364 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
365
366 if (!NT_SUCCESS(Irp->IoStatus.Status))
367 {
368 goto ResetRecovery;
369 }
370
371 // a request without the buffer AND not a sense request
372 // for a sense request we provide just a TransferBuffer, an Mdl will be allocated by usbport (see below)
373 if (!Irp->MdlAddress && Request == Context->FDODeviceExtension->ActiveSrb)
374 {
375 Request->SrbStatus = SRB_STATUS_SUCCESS;
376 USBSTOR_SendCSWRequest(Context, Irp);
377 return STATUS_MORE_PROCESSING_REQUIRED;
378 }
379
380 // a request with the data buffer
381
382 if ((Request->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) == SRB_FLAGS_DATA_IN)
383 {
384 PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle;
385 TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
386 }
387 else if ((Request->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) == SRB_FLAGS_DATA_OUT)
388 {
389 PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle;
390 TransferFlags = USBD_TRANSFER_DIRECTION_OUT;
391 }
392 else
393 {
394 // we check the validity of a request in disk.c so we should never be here
395 DPRINT1("Warning: shouldn't be here\n");
396 goto ResetRecovery;
397 }
398
399 // if it is not a Sense Request
400 if (Request == Context->FDODeviceExtension->ActiveSrb)
401 {
402 if (MmGetMdlVirtualAddress(Irp->MdlAddress) == Request->DataBuffer)
403 {
404 Mdl = Irp->MdlAddress;
405 }
406 else
407 {
408 Mdl = IoAllocateMdl(Request->DataBuffer,
409 Request->DataTransferLength,
410 FALSE,
411 FALSE,
412 NULL);
413
414 if (Mdl)
415 {
416 IoBuildPartialMdl(Irp->MdlAddress,
417 Mdl,
418 Request->DataBuffer,
419 Request->DataTransferLength);
420 }
421 }
422
423 if (!Mdl)
424 {
425 DPRINT1("USBSTOR_CBWCompletionRoutine: Mdl - %p\n", Mdl);
426 goto ResetRecovery;
427 }
428 }
429 else
430 {
431 ASSERT(Request->DataBuffer);
432 TransferBuffer = Request->DataBuffer;
433 }
434
435 USBSTOR_IssueBulkOrInterruptRequest(Context->FDODeviceExtension,
436 Irp,
437 PipeHandle,
438 TransferFlags,
439 Request->DataTransferLength,
440 TransferBuffer,
441 Mdl,
442 USBSTOR_DataCompletionRoutine,
443 Context);
444
445 return STATUS_MORE_PROCESSING_REQUIRED;
446
447 ResetRecovery:
448 Request = Context->FDODeviceExtension->ActiveSrb;
449 IoStack->Parameters.Scsi.Srb = Request;
450 Irp->IoStatus.Information = 0;
451 Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
452 Request->SrbStatus = SRB_STATUS_BUS_RESET;
453
454 USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
455 USBSTOR_QueueResetDevice(Context->FDODeviceExtension);
456
457 ExFreePoolWithTag(Context, USB_STOR_TAG);
458 return STATUS_CONTINUE_COMPLETION;
459 }
460
461 VOID
462 DumpCBW(
463 PUCHAR Block)
464 {
465 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",
466 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,
467 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,
468 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,
469 Block[30] & 0xFF);
470 }
471
472 static
473 NTSTATUS
474 USBSTOR_SendCBWRequest(
475 IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
476 IN PIRP Irp,
477 IN PIRP_CONTEXT Context)
478 {
479 PPDO_DEVICE_EXTENSION PDODeviceExtension;
480 PIO_STACK_LOCATION IoStack;
481 PSCSI_REQUEST_BLOCK Request;
482
483 RtlZeroMemory(&Context->cbw, sizeof(CBW));
484 RtlZeroMemory(&Context->Urb, sizeof(URB));
485
486 IoStack = IoGetCurrentIrpStackLocation(Irp);
487 PDODeviceExtension = IoStack->DeviceObject->DeviceExtension;
488 Request = IoStack->Parameters.Scsi.Srb;
489
490 Context->cbw.Signature = CBW_SIGNATURE;
491 Context->cbw.Tag = PtrToUlong(&Context->cbw);
492 Context->cbw.DataTransferLength = Request->DataTransferLength;
493 Context->cbw.Flags = ((UCHAR)Request->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) << 1;
494 Context->cbw.LUN = PDODeviceExtension->LUN;
495 Context->cbw.CommandBlockLength = Request->CdbLength;
496
497 RtlCopyMemory(&Context->cbw.CommandBlock, Request->Cdb, Request->CdbLength);
498
499 DPRINT("CBW for IRP %p\n", Irp);
500 DumpCBW((PUCHAR)&Context->cbw);
501
502 // initialize rest of context
503 Context->Irp = Irp;
504 Context->FDODeviceExtension = FDODeviceExtension;
505 Context->StallRetryCount = 0;
506
507 return USBSTOR_IssueBulkOrInterruptRequest(
508 FDODeviceExtension,
509 Irp,
510 FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle,
511 USBD_TRANSFER_DIRECTION_OUT,
512 sizeof(CBW),
513 &Context->cbw,
514 NULL,
515 USBSTOR_CBWCompletionRoutine,
516 Context);
517 }
518
519 static
520 NTSTATUS
521 USBSTOR_IssueRequestSense(
522 IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
523 IN PIRP Irp,
524 IN PIRP_CONTEXT Context)
525 {
526 PIO_STACK_LOCATION IoStack;
527 PSCSI_REQUEST_BLOCK CurrentSrb;
528 PSCSI_REQUEST_BLOCK SenseSrb;
529
530 DPRINT("USBSTOR_IssueRequestSense: \n");
531
532 CurrentSrb = FDODeviceExtension->ActiveSrb;
533 SenseSrb = &Context->SenseSrb;
534 IoStack = IoGetCurrentIrpStackLocation(Irp);
535 IoStack->Parameters.Scsi.Srb = SenseSrb;
536
537 RtlZeroMemory(SenseSrb, sizeof(*SenseSrb));
538
539 SenseSrb->Function = SRB_FUNCTION_EXECUTE_SCSI;
540 SenseSrb->Length = sizeof(*SenseSrb);
541 SenseSrb->CdbLength = CDB6GENERIC_LENGTH;
542 SenseSrb->SrbFlags = SRB_FLAGS_DATA_IN |
543 SRB_FLAGS_NO_QUEUE_FREEZE |
544 SRB_FLAGS_DISABLE_AUTOSENSE;
545
546 ASSERT(CurrentSrb->SenseInfoBufferLength);
547 ASSERT(CurrentSrb->SenseInfoBuffer);
548 DPRINT("SenseInfoBuffer %x, SenseInfoBufferLength %x\n", CurrentSrb->SenseInfoBuffer, CurrentSrb->SenseInfoBufferLength);
549
550 SenseSrb->DataTransferLength = CurrentSrb->SenseInfoBufferLength;
551 SenseSrb->DataBuffer = CurrentSrb->SenseInfoBuffer;
552
553 SrbGetCdb(SenseSrb)->CDB6GENERIC.OperationCode = SCSIOP_REQUEST_SENSE;
554 SrbGetCdb(SenseSrb)->AsByte[4] = CurrentSrb->SenseInfoBufferLength;
555
556 return USBSTOR_SendCBWRequest(FDODeviceExtension, Irp, Context);
557 }
558
559 NTSTATUS
560 USBSTOR_HandleExecuteSCSI(
561 IN PDEVICE_OBJECT DeviceObject,
562 IN PIRP Irp)
563 {
564 NTSTATUS Status;
565 PIO_STACK_LOCATION IoStack;
566 PSCSI_REQUEST_BLOCK Request;
567 PPDO_DEVICE_EXTENSION PDODeviceExtension;
568 PIRP_CONTEXT Context;
569
570 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
571 ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
572
573 IoStack = IoGetCurrentIrpStackLocation(Irp);
574 Request = IoStack->Parameters.Scsi.Srb;
575
576 DPRINT("USBSTOR_HandleExecuteSCSI Operation Code %x, Length %lu\n", SrbGetCdb(Request)->CDB10.OperationCode, Request->DataTransferLength);
577
578 // check that we're sending to the right LUN
579 ASSERT(SrbGetCdb(Request)->CDB10.LogicalUnitNumber == (PDODeviceExtension->LUN & MAX_LUN));
580 Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRP_CONTEXT), USB_STOR_TAG);
581
582 if (!Context)
583 {
584 Status = STATUS_INSUFFICIENT_RESOURCES;
585 }
586 else
587 {
588 Status = USBSTOR_SendCBWRequest(PDODeviceExtension->LowerDeviceObject->DeviceExtension, Irp, Context);
589 }
590
591 return Status;
592 }