[USBSTOR] Keep CBW and CSW inside an IRP context.

Remove obsolete fields from the IRP context structure.
This commit is contained in:
Victor Perevertkin 2019-04-01 02:33:35 +03:00
parent c452f7dab4
commit 5046f1b3fa
3 changed files with 53 additions and 82 deletions

View file

@ -74,14 +74,13 @@ USBSTOR_HandleTransferError(
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PIRP_CONTEXT Context) PIRP_CONTEXT Context)
{ {
PPDO_DEVICE_EXTENSION PDODeviceExtension;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
PCDB pCDB; PCDB pCDB;
ASSERT(Context); ASSERT(Context);
ASSERT(Context->PDODeviceExtension);
ASSERT(Context->PDODeviceExtension->Self);
ASSERT(Context->Irp); ASSERT(Context->Irp);
// first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
@ -98,6 +97,8 @@ USBSTOR_HandleTransferError(
} }
Stack = IoGetCurrentIrpStackLocation(Context->Irp); Stack = IoGetCurrentIrpStackLocation(Context->Irp);
ASSERT(Stack->DeviceObject);
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)Stack->DeviceObject->DeviceExtension;
Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1; Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
ASSERT(Request); ASSERT(Request);
@ -111,11 +112,11 @@ USBSTOR_HandleTransferError(
// Complete the master IRP // Complete the master IRP
Context->Irp->IoStatus.Status = Status; Context->Irp->IoStatus.Status = Status;
Context->Irp->IoStatus.Information = 0; Context->Irp->IoStatus.Information = 0;
USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp); USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Context->Irp);
IoCompleteRequest(Context->Irp, IO_NO_INCREMENT); IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
// Start the next request // Start the next request
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject); USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject);
// srb handling finished // srb handling finished
Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE; Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
@ -125,10 +126,10 @@ USBSTOR_HandleTransferError(
} }
else else
{ {
DPRINT1("Retrying Count %lu %p\n", Context->RetryCount, Context->PDODeviceExtension->Self); DPRINT1("Retrying Count %lu %p\n", Context->RetryCount, Stack->DeviceObject);
// re-schedule request // re-schedule request
USBSTOR_HandleExecuteSCSI(Context->PDODeviceExtension->Self, Context->Irp, Context->RetryCount + 1); USBSTOR_HandleExecuteSCSI(Stack->DeviceObject, Context->Irp, Context->RetryCount + 1);
// srb error handling finished // srb error handling finished
Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE; Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
@ -140,7 +141,6 @@ USBSTOR_HandleTransferError(
Context->FDODeviceExtension->LastTimerActiveSrb = NULL; Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
} }
FreeItem(Context->cbw);
FreeItem(Context); FreeItem(Context);
DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status); DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status);

View file

@ -96,41 +96,20 @@ USBSTOR_IssueBulkOrInterruptRequest(
return IoCallDriver(FDODeviceExtension->LowerDeviceObject, Irp); return IoCallDriver(FDODeviceExtension->LowerDeviceObject, Irp);
} }
PIRP_CONTEXT
USBSTOR_AllocateIrpContext()
{
PIRP_CONTEXT Context;
Context = (PIRP_CONTEXT)AllocateItem(NonPagedPool, sizeof(IRP_CONTEXT));
if (!Context)
{
return NULL;
}
Context->cbw = (PCBW)AllocateItem(NonPagedPool, 512);
if (!Context->cbw)
{
FreeItem(Context);
return NULL;
}
return Context;
}
static static
BOOLEAN BOOLEAN
USBSTOR_IsCSWValid( USBSTOR_IsCSWValid(
PIRP_CONTEXT Context) PIRP_CONTEXT Context)
{ {
if (Context->csw->Signature != CSW_SIGNATURE) if (Context->csw.Signature != CSW_SIGNATURE)
{ {
DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE, Context->csw->Signature); DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE, Context->csw.Signature);
return FALSE; return FALSE;
} }
if (Context->csw->Tag != (ULONG_PTR)Context->csw) if (Context->csw.Tag != PtrToUlong(&Context->csw))
{ {
DPRINT1("[USBSTOR] Expected Tag %Ix but got %x\n", (ULONG_PTR)Context->csw, Context->csw->Tag); DPRINT1("[USBSTOR] Expected Tag %Ix but got %x\n", PtrToUlong(&Context->csw), Context->csw.Tag);
return FALSE; return FALSE;
} }
@ -182,6 +161,7 @@ USBSTOR_CSWCompletionRoutine(
{ {
PIRP_CONTEXT Context; PIRP_CONTEXT Context;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
PUFI_CAPACITY_RESPONSE Response; PUFI_CAPACITY_RESPONSE Response;
NTSTATUS Status; NTSTATUS Status;
@ -220,7 +200,7 @@ USBSTOR_CSWCompletionRoutine(
} }
// now check the CSW packet validity // now check the CSW packet validity
if (!USBSTOR_IsCSWValid(Context) || Context->csw->Status == CSW_STATUS_PHASE_ERROR) if (!USBSTOR_IsCSWValid(Context) || Context->csw.Status == CSW_STATUS_PHASE_ERROR)
{ {
// perform reset recovery // perform reset recovery
Context->ErrorIndex = 2; Context->ErrorIndex = 2;
@ -230,26 +210,27 @@ USBSTOR_CSWCompletionRoutine(
} }
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
Request = IoStack->Parameters.Scsi.Srb; Request = IoStack->Parameters.Scsi.Srb;
ASSERT(Request); ASSERT(Request);
// finally check for CSW errors // finally check for CSW errors
if (Context->csw->Status == CSW_STATUS_COMMAND_PASSED) if (Context->csw.Status == CSW_STATUS_COMMAND_PASSED)
{ {
// read capacity needs special work // read capacity needs special work
if (Request->Cdb[0] == SCSIOP_READ_CAPACITY) if (Request->Cdb[0] == SCSIOP_READ_CAPACITY)
{ {
// get output buffer // get output buffer
Response = (PUFI_CAPACITY_RESPONSE)Context->TransferData; Response = (PUFI_CAPACITY_RESPONSE)Request->DataBuffer;
// store in pdo // store in pdo
Context->PDODeviceExtension->BlockLength = NTOHL(Response->BlockLength); PDODeviceExtension->BlockLength = NTOHL(Response->BlockLength);
Context->PDODeviceExtension->LastLogicBlockAddress = NTOHL(Response->LastLogicalBlockAddress); PDODeviceExtension->LastLogicBlockAddress = NTOHL(Response->LastLogicalBlockAddress);
} }
Status = USBSTOR_SrbStatusToNtStatus(Request); Status = USBSTOR_SrbStatusToNtStatus(Request);
} }
else if (Context->csw->Status == CSW_STATUS_COMMAND_FAILED) else if (Context->csw.Status == CSW_STATUS_COMMAND_FAILED)
{ {
// the command is correct but with failed status - issue request sense // the command is correct but with failed status - issue request sense
DPRINT("USBSTOR_CSWCompletionRoutine: CSW_STATUS_COMMAND_FAILED\n"); DPRINT("USBSTOR_CSWCompletionRoutine: CSW_STATUS_COMMAND_FAILED\n");
@ -277,13 +258,11 @@ USBSTOR_CSWCompletionRoutine(
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Request->DataTransferLength; Irp->IoStatus.Information = Request->DataTransferLength;
FreeItem(Context->cbw);
// terminate current request // terminate current request
USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Irp); USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject); USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject);
FreeItem(Context); ExFreePoolWithTag(Context, USB_STOR_TAG);
return Status; return Status;
} }
@ -297,7 +276,7 @@ USBSTOR_SendCSWRequest(
Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle,
USBD_TRANSFER_DIRECTION_IN, USBD_TRANSFER_DIRECTION_IN,
sizeof(CSW), sizeof(CSW),
Context->csw, &Context->csw,
NULL, NULL,
USBSTOR_CSWCompletionRoutine, USBSTOR_CSWCompletionRoutine,
Context); Context);
@ -489,42 +468,28 @@ USBSTOR_SendCBWRequest(
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
if (!Context) RtlZeroMemory(&Context->cbw, sizeof(CBW));
{ RtlZeroMemory(&Context->Urb, sizeof(URB));
Context = USBSTOR_AllocateIrpContext();
if (!Context)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
RtlZeroMemory(Context->cbw, sizeof(CBW));
RtlZeroMemory(&Context->Urb, sizeof(URB));
}
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
PDODeviceExtension = IoStack->DeviceObject->DeviceExtension; PDODeviceExtension = IoStack->DeviceObject->DeviceExtension;
Request = IoStack->Parameters.Scsi.Srb; Request = IoStack->Parameters.Scsi.Srb;
Context->cbw->Signature = CBW_SIGNATURE; Context->cbw.Signature = CBW_SIGNATURE;
Context->cbw->Tag = PtrToUlong(Context->cbw); Context->cbw.Tag = PtrToUlong(&Context->cbw);
Context->cbw->DataTransferLength = Request->DataTransferLength; Context->cbw.DataTransferLength = Request->DataTransferLength;
Context->cbw->Flags = ((UCHAR)Request->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) << 1; Context->cbw.Flags = ((UCHAR)Request->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) << 1;
Context->cbw->LUN = PDODeviceExtension->LUN; Context->cbw.LUN = PDODeviceExtension->LUN;
Context->cbw->CommandBlockLength = Request->CdbLength; Context->cbw.CommandBlockLength = Request->CdbLength;
RtlCopyMemory(Context->cbw->CommandBlock, Request->Cdb, Request->CdbLength); RtlCopyMemory(&Context->cbw.CommandBlock, Request->Cdb, Request->CdbLength);
DPRINT("CBW %p\n", Context->cbw); DPRINT("CBW for IRP %p\n", Irp);
DumpCBW((PUCHAR)Context->cbw); DumpCBW((PUCHAR)&Context->cbw);
// initialize rest of context // initialize rest of context
Context->Irp = Irp; Context->Irp = Irp;
Context->TransferData = Request->DataBuffer;
Context->TransferDataLength = Request->DataTransferLength;
Context->FDODeviceExtension = FDODeviceExtension; Context->FDODeviceExtension = FDODeviceExtension;
Context->PDODeviceExtension = PDODeviceExtension;
Context->RetryCount = 0; Context->RetryCount = 0;
return USBSTOR_IssueBulkOrInterruptRequest( return USBSTOR_IssueBulkOrInterruptRequest(
@ -533,7 +498,7 @@ USBSTOR_SendCBWRequest(
FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle,
USBD_TRANSFER_DIRECTION_OUT, USBD_TRANSFER_DIRECTION_OUT,
sizeof(CBW), sizeof(CBW),
Context->cbw, &Context->cbw,
NULL, NULL,
USBSTOR_CBWCompletionRoutine, USBSTOR_CBWCompletionRoutine,
Context); Context);
@ -550,6 +515,7 @@ USBSTOR_HandleExecuteSCSI(
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension;
PIRP_CONTEXT Context;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
@ -562,7 +528,16 @@ USBSTOR_HandleExecuteSCSI(
// check that we're sending to the right LUN // check that we're sending to the right LUN
ASSERT(pCDB->CDB10.LogicalUnitNumber == (PDODeviceExtension->LUN & MAX_LUN)); ASSERT(pCDB->CDB10.LogicalUnitNumber == (PDODeviceExtension->LUN & MAX_LUN));
Status = USBSTOR_SendCBWRequest(PDODeviceExtension->LowerDeviceObject->DeviceExtension, Irp, NULL); Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRP_CONTEXT), USB_STOR_TAG);
if (!Context)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
Status = USBSTOR_SendCBWRequest(PDODeviceExtension->LowerDeviceObject->DeviceExtension, Irp, Context);
}
return Status; return Status;
} }

View file

@ -283,21 +283,17 @@ typedef struct
typedef struct typedef struct
{ {
union
{
PCBW cbw;
PCSW csw;
};
URB Urb;
PIRP Irp; PIRP Irp;
ULONG TransferDataLength;
PUCHAR TransferData;
PFDO_DEVICE_EXTENSION FDODeviceExtension; PFDO_DEVICE_EXTENSION FDODeviceExtension;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PMDL TransferBufferMDL;
ULONG ErrorIndex; ULONG ErrorIndex;
ULONG RetryCount; ULONG RetryCount;
}IRP_CONTEXT, *PIRP_CONTEXT; union
{
CBW cbw;
CSW csw;
};
URB Urb;
} IRP_CONTEXT, *PIRP_CONTEXT;
typedef struct _ERRORHANDLER_WORKITEM_DATA typedef struct _ERRORHANDLER_WORKITEM_DATA
{ {