https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c7ed299aaa35d746ac167…
commit c7ed299aaa35d746ac1677144341150d5e79e373
Author: Victor Perevertkin <victor(a)perevertkin.ru>
AuthorDate: Mon Apr 1 03:03:40 2019 +0300
Commit: Victor Perevertkin <victor(a)perevertkin.ru>
CommitDate: Tue Jun 11 04:39:43 2019 +0300
[USBSTOR] Issue a SCSI Request Sense after receiving
a CSW with failed status. CORE-15884
Based on Vadim Galyant's patches to usbstor
---
drivers/usb/usbstor/scsi.c | 91 ++++++++++++++++++++++++++++++++++++++++---
drivers/usb/usbstor/usbstor.h | 1 +
2 files changed, 86 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/usbstor/scsi.c b/drivers/usb/usbstor/scsi.c
index 71dafea35cf..05ef1c925c8 100644
--- a/drivers/usb/usbstor/scsi.c
+++ b/drivers/usb/usbstor/scsi.c
@@ -150,6 +150,13 @@ USBSTOR_QueueWorkItem(
return STATUS_MORE_PROCESSING_REQUIRED;
}
+static
+NTSTATUS
+USBSTOR_IssueRequestSense(
+ IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
+ IN PIRP Irp,
+ IN PIRP_CONTEXT Context);
+
IO_COMPLETION_ROUTINE USBSTOR_CSWCompletionRoutine;
NTSTATUS
@@ -162,6 +169,7 @@ USBSTOR_CSWCompletionRoutine(
PIRP_CONTEXT Context;
PIO_STACK_LOCATION IoStack;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
+ PFDO_DEVICE_EXTENSION FDODeviceExtension;
PSCSI_REQUEST_BLOCK Request;
PUFI_CAPACITY_RESPONSE Response;
NTSTATUS Status;
@@ -211,12 +219,23 @@ USBSTOR_CSWCompletionRoutine(
IoStack = IoGetCurrentIrpStackLocation(Irp);
PDODeviceExtension =
(PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
+ FDODeviceExtension = Context->FDODeviceExtension;
Request = IoStack->Parameters.Scsi.Srb;
ASSERT(Request);
// finally check for CSW errors
if (Context->csw.Status == CSW_STATUS_COMMAND_PASSED)
{
+ // should happen only when a sense request was sent
+ if (Request != FDODeviceExtension->ActiveSrb)
+ {
+ ASSERT(IoStack->Parameters.Scsi.Srb == &Context->SenseSrb);
+ FDODeviceExtension->ActiveSrb->SenseInfoBufferLength =
Request->DataTransferLength;
+ Request = FDODeviceExtension->ActiveSrb;
+ IoStack->Parameters.Scsi.Srb = Request;
+ Request->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
+ }
+
// read capacity needs special work
if (Request->Cdb[0] == SCSIOP_READ_CAPACITY)
{
@@ -235,7 +254,7 @@ USBSTOR_CSWCompletionRoutine(
// the command is correct but with failed status - issue request sense
DPRINT("USBSTOR_CSWCompletionRoutine: CSW_STATUS_COMMAND_FAILED\n");
- ASSERT(Context->FDODeviceExtension->ActiveSrb == Request);
+ ASSERT(FDODeviceExtension->ActiveSrb == Request);
// setting a generic error status, additional information
// should be read by higher-level driver from SenseInfoBuffer
@@ -249,7 +268,8 @@ USBSTOR_CSWCompletionRoutine(
Request->SenseInfoBufferLength &&
Request->SenseInfoBuffer)
{
- // TODO: issue request sense
+ USBSTOR_IssueRequestSense(FDODeviceExtension, Irp, Context);
+ return STATUS_MORE_PROCESSING_REQUIRED;
}
Status = STATUS_IO_DEVICE_ERROR;
@@ -302,7 +322,9 @@ USBSTOR_DataCompletionRoutine(
IoStack = IoGetCurrentIrpStackLocation(Irp);
Request = IoStack->Parameters.Scsi.Srb;
- if (Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL !=
Irp->MdlAddress)
+ // for Sense Request a partial MDL was already freed (if existed)
+ if (Request == Context->FDODeviceExtension->ActiveSrb &&
+ Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL !=
Irp->MdlAddress)
{
IoFreeMdl(Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL);
}
@@ -373,8 +395,9 @@ USBSTOR_CBWCompletionRoutine(
goto ResetRecovery;
}
- // a request without the buffer
- if (!Irp->MdlAddress)
+ // a request without the buffer AND not a sense request
+ // for a sense request we provide just a TransferBuffer, an Mdl will be allocated by
usbport (see below)
+ if (!Irp->MdlAddress && Request ==
Context->FDODeviceExtension->ActiveSrb)
{
Request->SrbStatus = SRB_STATUS_SUCCESS;
USBSTOR_SendCSWRequest(Context, Irp);
@@ -400,6 +423,9 @@ USBSTOR_CBWCompletionRoutine(
goto ResetRecovery;
}
+ // if it is not a Sense Request
+ if (Request == Context->FDODeviceExtension->ActiveSrb)
+ {
if (MmGetMdlVirtualAddress(Irp->MdlAddress) == Request->DataBuffer)
{
Mdl = Irp->MdlAddress;
@@ -423,9 +449,20 @@ USBSTOR_CBWCompletionRoutine(
if (!Mdl)
{
- DPRINT1("USBSTOR_DataTransfer: Mdl - %p\n", Mdl);
+ DPRINT1("USBSTOR_CBWCompletionRoutine: Mdl - %p\n", Mdl);
goto ResetRecovery;
}
+ }
+ else
+ {
+ TransferBuffer = Request->DataBuffer;
+
+ if (!Request->DataBuffer)
+ {
+ DPRINT("USBSTOR_CBWCompletionRoutine: Request->DataBuffer ==
NULL!\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+ }
USBSTOR_IssueBulkOrInterruptRequest(Context->FDODeviceExtension,
Irp,
@@ -504,6 +541,48 @@ USBSTOR_SendCBWRequest(
Context);
}
+static
+NTSTATUS
+USBSTOR_IssueRequestSense(
+ IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
+ IN PIRP Irp,
+ IN PIRP_CONTEXT Context)
+{
+ PIO_STACK_LOCATION IoStack;
+ PSCSI_REQUEST_BLOCK CurrentSrb;
+ PSCSI_REQUEST_BLOCK SenseSrb;
+ PCDB pCDB;
+
+ DPRINT("USBSTOR_IssueRequestSense: \n");
+
+ CurrentSrb = FDODeviceExtension->ActiveSrb;
+ SenseSrb = &Context->SenseSrb;
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+ IoStack->Parameters.Scsi.Srb = SenseSrb;
+
+ RtlZeroMemory(SenseSrb, sizeof(*SenseSrb));
+
+ SenseSrb->Function = SRB_FUNCTION_EXECUTE_SCSI;
+ SenseSrb->Length = sizeof(*SenseSrb);
+ SenseSrb->CdbLength = CDB6GENERIC_LENGTH;
+ SenseSrb->SrbFlags = SRB_FLAGS_DATA_IN |
+ SRB_FLAGS_NO_QUEUE_FREEZE |
+ SRB_FLAGS_DISABLE_AUTOSENSE;
+
+ ASSERT(CurrentSrb->SenseInfoBufferLength);
+ ASSERT(CurrentSrb->SenseInfoBuffer);
+ DPRINT("SenseInfoBuffer %x, SenseInfoBufferLength %x\n",
CurrentSrb->SenseInfoBuffer, CurrentSrb->SenseInfoBufferLength);
+
+ SenseSrb->DataTransferLength = CurrentSrb->SenseInfoBufferLength;
+ SenseSrb->DataBuffer = CurrentSrb->SenseInfoBuffer;
+
+ pCDB = (PCDB)SenseSrb->Cdb;
+ pCDB->CDB6GENERIC.OperationCode = SCSIOP_REQUEST_SENSE;
+ pCDB->AsByte[4] = CurrentSrb->SenseInfoBufferLength;
+
+ return USBSTOR_SendCBWRequest(FDODeviceExtension, Irp, Context);
+}
+
NTSTATUS
USBSTOR_HandleExecuteSCSI(
IN PDEVICE_OBJECT DeviceObject,
diff --git a/drivers/usb/usbstor/usbstor.h b/drivers/usb/usbstor/usbstor.h
index 26be827f8ae..25066cc1de7 100644
--- a/drivers/usb/usbstor/usbstor.h
+++ b/drivers/usb/usbstor/usbstor.h
@@ -293,6 +293,7 @@ typedef struct
CSW csw;
};
URB Urb;
+ SCSI_REQUEST_BLOCK SenseSrb;
} IRP_CONTEXT, *PIRP_CONTEXT;
typedef struct _ERRORHANDLER_WORKITEM_DATA