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 } 593