[USBSTOR] Move PDO's Inquiry data and FDO's SCSI context

to their Device Extensions.
This way the driver can better handle low memory situations
This commit is contained in:
Victor Perevertkin 2020-06-12 16:51:42 +03:00
parent a9b97aeded
commit 94e61c3080
No known key found for this signature in database
GPG key ID: C750B7222E9C7830
5 changed files with 113 additions and 148 deletions

View file

@ -283,8 +283,7 @@ USBSTOR_HandleQueryProperty(
ASSERT(FDODeviceExtension); ASSERT(FDODeviceExtension);
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
InquiryData = PDODeviceExtension->InquiryData; InquiryData = (PINQUIRYDATA)&PDODeviceExtension->InquiryData;
ASSERT(InquiryData);
// compute extra parameters length // compute extra parameters length
FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->VendorId, 8); FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->VendorId, 8);
@ -507,7 +506,7 @@ USBSTOR_HandleDeviceControl(
// Note: INQUIRYDATA structure is larger than INQUIRYDATABUFFERSIZE // Note: INQUIRYDATA structure is larger than INQUIRYDATABUFFERSIZE
RtlZeroMemory(InquiryData, sizeof(INQUIRYDATA)); RtlZeroMemory(InquiryData, sizeof(INQUIRYDATA));
RtlCopyMemory(InquiryData, PDODeviceExtension->InquiryData, INQUIRYDATABUFFERSIZE); RtlCopyMemory(InquiryData, &PDODeviceExtension->InquiryData, sizeof(PDODeviceExtension->InquiryData));
InquiryData->Versions = 0x04; InquiryData->Versions = 0x04;
InquiryData->ResponseDataFormat = 0x02; // some devices set this to 1 InquiryData->ResponseDataFormat = 0x02; // some devices set this to 1

View file

@ -77,15 +77,15 @@ USBSTOR_ResetPipeWorkItemRoutine(
IN PVOID Ctx) IN PVOID Ctx)
{ {
NTSTATUS Status; NTSTATUS Status;
PIRP_CONTEXT Context = (PIRP_CONTEXT)Ctx; PFDO_DEVICE_EXTENSION FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Ctx;
PFDO_DEVICE_EXTENSION FDODeviceExtension = (PFDO_DEVICE_EXTENSION)FdoDevice->DeviceExtension; PIRP_CONTEXT Context = &FDODeviceExtension->CurrentIrpContext;
// clear stall on the corresponding pipe // clear stall on the corresponding pipe
Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, Context->Urb.UrbBulkOrInterruptTransfer.PipeHandle); Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, Context->Urb.UrbBulkOrInterruptTransfer.PipeHandle);
DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status); DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status);
// now resend the csw as the stall got cleared // now resend the csw as the stall got cleared
USBSTOR_SendCSWRequest(Context, Context->Irp); USBSTOR_SendCSWRequest(FDODeviceExtension, Context->Irp);
} }
VOID VOID
@ -133,15 +133,14 @@ USBSTOR_ResetDeviceWorkItemRoutine(
VOID VOID
NTAPI NTAPI
USBSTOR_QueueResetPipe( USBSTOR_QueueResetPipe(
IN PFDO_DEVICE_EXTENSION FDODeviceExtension, IN PFDO_DEVICE_EXTENSION FDODeviceExtension)
IN PIRP_CONTEXT Context)
{ {
DPRINT("USBSTOR_QueueResetPipe\n"); DPRINT("USBSTOR_QueueResetPipe\n");
IoQueueWorkItem(FDODeviceExtension->ResetDeviceWorkItem, IoQueueWorkItem(FDODeviceExtension->ResetDeviceWorkItem,
USBSTOR_ResetPipeWorkItemRoutine, USBSTOR_ResetPipeWorkItemRoutine,
CriticalWorkQueue, CriticalWorkQueue,
Context); FDODeviceExtension);
} }
VOID VOID

View file

@ -137,8 +137,7 @@ USBSTOR_PdoHandleQueryDeviceText(
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(DeviceExtension->InquiryData); InquiryData = (PINQUIRYDATA)&DeviceExtension->InquiryData;
InquiryData = DeviceExtension->InquiryData;
switch (IoStack->Parameters.QueryDeviceText.DeviceTextType) switch (IoStack->Parameters.QueryDeviceText.DeviceTextType)
{ {
@ -191,8 +190,7 @@ USBSTOR_PdoHandleQueryDeviceId(
UNICODE_STRING DeviceId; UNICODE_STRING DeviceId;
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(DeviceExtension->InquiryData); InquiryData = (PINQUIRYDATA)&DeviceExtension->InquiryData;
InquiryData = DeviceExtension->InquiryData;
DeviceType = USBSTOR_GetDeviceType(InquiryData); DeviceType = USBSTOR_GetDeviceType(InquiryData);
@ -282,7 +280,7 @@ USBSTOR_PdoHandleQueryHardwareId(
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
ASSERT(FDODeviceExtension->DeviceDescriptor); ASSERT(FDODeviceExtension->DeviceDescriptor);
InquiryData = PDODeviceExtension->InquiryData; InquiryData = (PINQUIRYDATA)&PDODeviceExtension->InquiryData;
DeviceType = USBSTOR_GetDeviceType(InquiryData); DeviceType = USBSTOR_GetDeviceType(InquiryData);
GenericType = USBSTOR_GetGenericType(InquiryData); GenericType = USBSTOR_GetGenericType(InquiryData);
@ -404,7 +402,7 @@ USBSTOR_PdoHandleQueryCompatibleId(
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
ASSERT(FDODeviceExtension->DeviceDescriptor); ASSERT(FDODeviceExtension->DeviceDescriptor);
DeviceType = USBSTOR_GetDeviceType(PDODeviceExtension->InquiryData); DeviceType = USBSTOR_GetDeviceType((PINQUIRYDATA)&PDODeviceExtension->InquiryData);
// format instance id // format instance id
Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1; Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1;
@ -573,10 +571,6 @@ USBSTOR_PdoHandlePnp(
bDelete = FALSE; bDelete = FALSE;
} }
// clean up the device extension
ASSERT(DeviceExtension->InquiryData);
ExFreePoolWithTag(DeviceExtension->InquiryData, USB_STOR_TAG);
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -804,19 +798,10 @@ USBSTOR_FillInquiryData(
IN PDEVICE_OBJECT PDODeviceObject) IN PDEVICE_OBJECT PDODeviceObject)
{ {
NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
CDB Cdb; CDB Cdb;
ULONG DataTransferLength = INQUIRYDATABUFFERSIZE; ULONG DataTransferLength = INQUIRYDATABUFFERSIZE;
PINQUIRYDATA InquiryData; PINQUIRYDATA InquiryData = (PINQUIRYDATA)&PDODeviceExtension->InquiryData;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
InquiryData = ExAllocatePoolWithTag(NonPagedPool, INQUIRYDATABUFFERSIZE, USB_STOR_TAG);
if (!InquiryData)
{
DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status);
return Status;
}
RtlZeroMemory(&Cdb, sizeof(Cdb)); RtlZeroMemory(&Cdb, sizeof(Cdb));
Cdb.CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY; Cdb.CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
@ -827,7 +812,6 @@ USBSTOR_FillInquiryData(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status); DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status);
ExFreePoolWithTag(InquiryData, USB_STOR_TAG);
return Status; return Status;
} }
@ -846,7 +830,6 @@ USBSTOR_FillInquiryData(
DPRINT("Revision %c%c%c%c\n", InquiryData->ProductRevisionLevel[0], InquiryData->ProductRevisionLevel[1], InquiryData->ProductRevisionLevel[2], InquiryData->ProductRevisionLevel[3]); DPRINT("Revision %c%c%c%c\n", InquiryData->ProductRevisionLevel[0], InquiryData->ProductRevisionLevel[1], InquiryData->ProductRevisionLevel[2], InquiryData->ProductRevisionLevel[3]);
PDODeviceExtension->InquiryData = InquiryData;
return Status; return Status;
} }
@ -859,6 +842,7 @@ USBSTOR_CreatePDO(
NTSTATUS Status; NTSTATUS Status;
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension;
PFDO_DEVICE_EXTENSION FDODeviceExtension; PFDO_DEVICE_EXTENSION FDODeviceExtension;
PINQUIRYDATA InquiryData;
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
@ -874,6 +858,7 @@ USBSTOR_CreatePDO(
PDO->StackSize = DeviceObject->StackSize; PDO->StackSize = DeviceObject->StackSize;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDO->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDO->DeviceExtension;
InquiryData = (PINQUIRYDATA)&PDODeviceExtension->InquiryData;
// initialize device extension // initialize device extension
RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION)); RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
@ -899,8 +884,8 @@ USBSTOR_CreatePDO(
return Status; return Status;
} }
if (PDODeviceExtension->InquiryData->DeviceType != DIRECT_ACCESS_DEVICE && if (InquiryData->DeviceType != DIRECT_ACCESS_DEVICE &&
PDODeviceExtension->InquiryData->DeviceType != READ_ONLY_DIRECT_ACCESS_DEVICE) InquiryData->DeviceType != READ_ONLY_DIRECT_ACCESS_DEVICE)
{ {
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }

View file

@ -65,10 +65,10 @@ USBSTOR_IssueBulkOrInterruptRequest(
IN ULONG TransferBufferLength, IN ULONG TransferBufferLength,
IN PVOID TransferBuffer, IN PVOID TransferBuffer,
IN PMDL TransferBufferMDL, IN PMDL TransferBufferMDL,
IN PIO_COMPLETION_ROUTINE CompletionRoutine, IN PIO_COMPLETION_ROUTINE CompletionRoutine)
IN PIRP_CONTEXT Context)
{ {
PIO_STACK_LOCATION NextStack; PIO_STACK_LOCATION NextStack;
PIRP_CONTEXT Context = &FDODeviceExtension->CurrentIrpContext;
RtlZeroMemory(&Context->Urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER)); RtlZeroMemory(&Context->Urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
@ -88,7 +88,7 @@ USBSTOR_IssueBulkOrInterruptRequest(
IoSetCompletionRoutine(Irp, IoSetCompletionRoutine(Irp,
CompletionRoutine, CompletionRoutine,
Context, FDODeviceExtension,
TRUE, TRUE,
TRUE, TRUE,
TRUE); TRUE);
@ -107,9 +107,9 @@ USBSTOR_IsCSWValid(
return FALSE; return FALSE;
} }
if (Context->csw.Tag != PtrToUlong(&Context->csw)) if (Context->csw.Tag != PtrToUlong(Context->Irp))
{ {
DPRINT1("[USBSTOR] Expected Tag %Ix but got %x\n", PtrToUlong(&Context->csw), Context->csw.Tag); DPRINT1("[USBSTOR] Expected Tag %Ix but got %x\n", PtrToUlong(Context->Irp), Context->csw.Tag);
return FALSE; return FALSE;
} }
@ -120,8 +120,7 @@ static
NTSTATUS NTSTATUS
USBSTOR_IssueRequestSense( USBSTOR_IssueRequestSense(
IN PFDO_DEVICE_EXTENSION FDODeviceExtension, IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
IN PIRP Irp, IN PIRP Irp);
IN PIRP_CONTEXT Context);
IO_COMPLETION_ROUTINE USBSTOR_CSWCompletionRoutine; IO_COMPLETION_ROUTINE USBSTOR_CSWCompletionRoutine;
@ -138,13 +137,12 @@ USBSTOR_CSWCompletionRoutine(
PFDO_DEVICE_EXTENSION FDODeviceExtension; PFDO_DEVICE_EXTENSION FDODeviceExtension;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
Context = (PIRP_CONTEXT)Ctx;
DPRINT("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status); DPRINT("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status);
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
FDODeviceExtension = Context->FDODeviceExtension; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Ctx;
Context = &FDODeviceExtension->CurrentIrpContext;
Request = IoStack->Parameters.Scsi.Srb; Request = IoStack->Parameters.Scsi.Srb;
ASSERT(Request); ASSERT(Request);
@ -158,7 +156,7 @@ USBSTOR_CSWCompletionRoutine(
++Context->StallRetryCount; ++Context->StallRetryCount;
// clear stall and resend cbw // clear stall and resend cbw
USBSTOR_QueueResetPipe(FDODeviceExtension, Context); USBSTOR_QueueResetPipe(FDODeviceExtension);
return STATUS_MORE_PROCESSING_REQUIRED; return STATUS_MORE_PROCESSING_REQUIRED;
} }
@ -211,7 +209,7 @@ USBSTOR_CSWCompletionRoutine(
Request->SenseInfoBufferLength && Request->SenseInfoBufferLength &&
Request->SenseInfoBuffer) Request->SenseInfoBuffer)
{ {
USBSTOR_IssueRequestSense(FDODeviceExtension, Irp, Context); USBSTOR_IssueRequestSense(FDODeviceExtension, Irp);
return STATUS_MORE_PROCESSING_REQUIRED; return STATUS_MORE_PROCESSING_REQUIRED;
} }
@ -224,7 +222,6 @@ USBSTOR_CSWCompletionRoutine(
USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp); USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject); USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject);
ExFreePoolWithTag(Context, USB_STOR_TAG);
return STATUS_CONTINUE_COMPLETION; return STATUS_CONTINUE_COMPLETION;
ResetRecovery: ResetRecovery:
@ -238,24 +235,22 @@ ResetRecovery:
USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp); USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
USBSTOR_QueueResetDevice(FDODeviceExtension); USBSTOR_QueueResetDevice(FDODeviceExtension);
ExFreePoolWithTag(Context, USB_STOR_TAG);
return STATUS_CONTINUE_COMPLETION; return STATUS_CONTINUE_COMPLETION;
} }
NTSTATUS NTSTATUS
USBSTOR_SendCSWRequest( USBSTOR_SendCSWRequest(
PIRP_CONTEXT Context, PFDO_DEVICE_EXTENSION FDODeviceExtension,
PIRP Irp) PIRP Irp)
{ {
return USBSTOR_IssueBulkOrInterruptRequest(Context->FDODeviceExtension, return USBSTOR_IssueBulkOrInterruptRequest(FDODeviceExtension,
Irp, Irp,
Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle,
USBD_TRANSFER_DIRECTION_IN, USBD_TRANSFER_DIRECTION_IN,
sizeof(CSW), sizeof(CSW),
&Context->csw, &FDODeviceExtension->CurrentIrpContext.csw,
NULL, NULL,
USBSTOR_CSWCompletionRoutine, USBSTOR_CSWCompletionRoutine);
Context);
} }
IO_COMPLETION_ROUTINE USBSTOR_DataCompletionRoutine; IO_COMPLETION_ROUTINE USBSTOR_DataCompletionRoutine;
@ -270,17 +265,19 @@ USBSTOR_DataCompletionRoutine(
PIRP_CONTEXT Context; PIRP_CONTEXT Context;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
PFDO_DEVICE_EXTENSION FDODeviceExtension;
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension;
DPRINT("USBSTOR_DataCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status); DPRINT("USBSTOR_DataCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status);
Context = (PIRP_CONTEXT)Ctx; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Ctx;
Context = &FDODeviceExtension->CurrentIrpContext;
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
Request = IoStack->Parameters.Scsi.Srb; Request = IoStack->Parameters.Scsi.Srb;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
// for Sense Request a partial MDL was already freed (if existed) // for Sense Request a partial MDL was already freed (if existed)
if (Request == Context->FDODeviceExtension->ActiveSrb && if (Request == FDODeviceExtension->ActiveSrb &&
Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL != Irp->MdlAddress) Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL != Irp->MdlAddress)
{ {
IoFreeMdl(Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL); IoFreeMdl(Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL);
@ -298,7 +295,7 @@ USBSTOR_DataCompletionRoutine(
} }
Request->DataTransferLength = Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength; Request->DataTransferLength = Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength;
USBSTOR_SendCSWRequest(Context, Irp); USBSTOR_SendCSWRequest(FDODeviceExtension, Irp);
} }
else if (USBD_STATUS(Context->Urb.UrbHeader.Status) == USBD_STATUS(USBD_STATUS_STALL_PID)) else if (USBD_STATUS(Context->Urb.UrbHeader.Status) == USBD_STATUS(USBD_STATUS_STALL_PID))
{ {
@ -308,7 +305,7 @@ USBSTOR_DataCompletionRoutine(
Request->DataTransferLength = Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength; Request->DataTransferLength = Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength;
// clear stall and resend cbw // clear stall and resend cbw
USBSTOR_QueueResetPipe(Context->FDODeviceExtension, Context); USBSTOR_QueueResetPipe(FDODeviceExtension);
} }
else else
{ {
@ -317,9 +314,8 @@ USBSTOR_DataCompletionRoutine(
Request->SrbStatus = SRB_STATUS_BUS_RESET; Request->SrbStatus = SRB_STATUS_BUS_RESET;
USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp); USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
USBSTOR_QueueResetDevice(Context->FDODeviceExtension); USBSTOR_QueueResetDevice(FDODeviceExtension);
ExFreePoolWithTag(Context, USB_STOR_TAG);
return STATUS_CONTINUE_COMPLETION; return STATUS_CONTINUE_COMPLETION;
} }
@ -339,6 +335,7 @@ USBSTOR_CBWCompletionRoutine(
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension;
PFDO_DEVICE_EXTENSION FDODeviceExtension;
USBD_PIPE_HANDLE PipeHandle; USBD_PIPE_HANDLE PipeHandle;
ULONG TransferFlags; ULONG TransferFlags;
PMDL Mdl = NULL; PMDL Mdl = NULL;
@ -346,7 +343,8 @@ USBSTOR_CBWCompletionRoutine(
DPRINT("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status); DPRINT("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p Status %x\n", Irp, Ctx, Irp->IoStatus.Status);
Context = (PIRP_CONTEXT)Ctx; FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Ctx;
Context = &FDODeviceExtension->CurrentIrpContext;
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
Request = IoStack->Parameters.Scsi.Srb; Request = IoStack->Parameters.Scsi.Srb;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
@ -358,10 +356,10 @@ USBSTOR_CBWCompletionRoutine(
// a request without the buffer AND not a sense request // 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) // 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) if (!Irp->MdlAddress && Request == FDODeviceExtension->ActiveSrb)
{ {
Request->SrbStatus = SRB_STATUS_SUCCESS; Request->SrbStatus = SRB_STATUS_SUCCESS;
USBSTOR_SendCSWRequest(Context, Irp); USBSTOR_SendCSWRequest(FDODeviceExtension, Irp);
return STATUS_MORE_PROCESSING_REQUIRED; return STATUS_MORE_PROCESSING_REQUIRED;
} }
@ -369,12 +367,12 @@ USBSTOR_CBWCompletionRoutine(
if ((Request->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) == SRB_FLAGS_DATA_IN) if ((Request->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) == SRB_FLAGS_DATA_IN)
{ {
PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle; PipeHandle = FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle;
TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK; TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
} }
else if ((Request->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) == SRB_FLAGS_DATA_OUT) else if ((Request->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) == SRB_FLAGS_DATA_OUT)
{ {
PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle; PipeHandle = FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle;
TransferFlags = USBD_TRANSFER_DIRECTION_OUT; TransferFlags = USBD_TRANSFER_DIRECTION_OUT;
} }
else else
@ -385,7 +383,7 @@ USBSTOR_CBWCompletionRoutine(
} }
// if it is not a Sense Request // if it is not a Sense Request
if (Request == Context->FDODeviceExtension->ActiveSrb) if (Request == FDODeviceExtension->ActiveSrb)
{ {
if (MmGetMdlVirtualAddress(Irp->MdlAddress) == Request->DataBuffer) if (MmGetMdlVirtualAddress(Irp->MdlAddress) == Request->DataBuffer)
{ {
@ -420,29 +418,27 @@ USBSTOR_CBWCompletionRoutine(
TransferBuffer = Request->DataBuffer; TransferBuffer = Request->DataBuffer;
} }
USBSTOR_IssueBulkOrInterruptRequest(Context->FDODeviceExtension, USBSTOR_IssueBulkOrInterruptRequest(FDODeviceExtension,
Irp, Irp,
PipeHandle, PipeHandle,
TransferFlags, TransferFlags,
Request->DataTransferLength, Request->DataTransferLength,
TransferBuffer, TransferBuffer,
Mdl, Mdl,
USBSTOR_DataCompletionRoutine, USBSTOR_DataCompletionRoutine);
Context);
return STATUS_MORE_PROCESSING_REQUIRED; return STATUS_MORE_PROCESSING_REQUIRED;
ResetRecovery: ResetRecovery:
Request = Context->FDODeviceExtension->ActiveSrb; Request = FDODeviceExtension->ActiveSrb;
IoStack->Parameters.Scsi.Srb = Request; IoStack->Parameters.Scsi.Srb = Request;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR; Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
Request->SrbStatus = SRB_STATUS_BUS_RESET; Request->SrbStatus = SRB_STATUS_BUS_RESET;
USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp); USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
USBSTOR_QueueResetDevice(Context->FDODeviceExtension); USBSTOR_QueueResetDevice(FDODeviceExtension);
ExFreePoolWithTag(Context, USB_STOR_TAG);
return STATUS_CONTINUE_COMPLETION; return STATUS_CONTINUE_COMPLETION;
} }
@ -461,12 +457,12 @@ static
NTSTATUS NTSTATUS
USBSTOR_SendCBWRequest( USBSTOR_SendCBWRequest(
IN PFDO_DEVICE_EXTENSION FDODeviceExtension, IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
IN PIRP Irp, IN PIRP Irp)
IN PIRP_CONTEXT Context)
{ {
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
PIRP_CONTEXT Context = &FDODeviceExtension->CurrentIrpContext;
RtlZeroMemory(&Context->cbw, sizeof(CBW)); RtlZeroMemory(&Context->cbw, sizeof(CBW));
RtlZeroMemory(&Context->Urb, sizeof(URB)); RtlZeroMemory(&Context->Urb, sizeof(URB));
@ -475,8 +471,9 @@ USBSTOR_SendCBWRequest(
PDODeviceExtension = IoStack->DeviceObject->DeviceExtension; PDODeviceExtension = IoStack->DeviceObject->DeviceExtension;
Request = IoStack->Parameters.Scsi.Srb; Request = IoStack->Parameters.Scsi.Srb;
// Make a CBW structure from SCSI request block
Context->cbw.Signature = CBW_SIGNATURE; Context->cbw.Signature = CBW_SIGNATURE;
Context->cbw.Tag = PtrToUlong(&Context->cbw); Context->cbw.Tag = PtrToUlong(Irp);
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;
@ -489,7 +486,6 @@ USBSTOR_SendCBWRequest(
// initialize rest of context // initialize rest of context
Context->Irp = Irp; Context->Irp = Irp;
Context->FDODeviceExtension = FDODeviceExtension;
Context->StallRetryCount = 0; Context->StallRetryCount = 0;
return USBSTOR_IssueBulkOrInterruptRequest( return USBSTOR_IssueBulkOrInterruptRequest(
@ -500,16 +496,14 @@ USBSTOR_SendCBWRequest(
sizeof(CBW), sizeof(CBW),
&Context->cbw, &Context->cbw,
NULL, NULL,
USBSTOR_CBWCompletionRoutine, USBSTOR_CBWCompletionRoutine);
Context);
} }
static static
NTSTATUS NTSTATUS
USBSTOR_IssueRequestSense( USBSTOR_IssueRequestSense(
IN PFDO_DEVICE_EXTENSION FDODeviceExtension, IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
IN PIRP Irp, IN PIRP Irp)
IN PIRP_CONTEXT Context)
{ {
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK CurrentSrb; PSCSI_REQUEST_BLOCK CurrentSrb;
@ -518,7 +512,7 @@ USBSTOR_IssueRequestSense(
DPRINT("USBSTOR_IssueRequestSense: \n"); DPRINT("USBSTOR_IssueRequestSense: \n");
CurrentSrb = FDODeviceExtension->ActiveSrb; CurrentSrb = FDODeviceExtension->ActiveSrb;
SenseSrb = &Context->SenseSrb; SenseSrb = &FDODeviceExtension->CurrentIrpContext.SenseSrb;
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
IoStack->Parameters.Scsi.Srb = SenseSrb; IoStack->Parameters.Scsi.Srb = SenseSrb;
@ -541,7 +535,7 @@ USBSTOR_IssueRequestSense(
SrbGetCdb(SenseSrb)->CDB6GENERIC.OperationCode = SCSIOP_REQUEST_SENSE; SrbGetCdb(SenseSrb)->CDB6GENERIC.OperationCode = SCSIOP_REQUEST_SENSE;
SrbGetCdb(SenseSrb)->AsByte[4] = CurrentSrb->SenseInfoBufferLength; SrbGetCdb(SenseSrb)->AsByte[4] = CurrentSrb->SenseInfoBufferLength;
return USBSTOR_SendCBWRequest(FDODeviceExtension, Irp, Context); return USBSTOR_SendCBWRequest(FDODeviceExtension, Irp);
} }
NTSTATUS NTSTATUS
@ -549,13 +543,10 @@ USBSTOR_HandleExecuteSCSI(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
NTSTATUS Status;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
PIRP_CONTEXT Context;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
@ -564,17 +555,7 @@ USBSTOR_HandleExecuteSCSI(
DPRINT("USBSTOR_HandleExecuteSCSI Operation Code %x, Length %lu\n", SrbGetCdb(Request)->CDB10.OperationCode, Request->DataTransferLength); DPRINT("USBSTOR_HandleExecuteSCSI Operation Code %x, Length %lu\n", SrbGetCdb(Request)->CDB10.OperationCode, Request->DataTransferLength);
// check that we're sending to the right LUN // check that we're sending to the right LUN
ASSERT(SrbGetCdb(Request)->CDB10.LogicalUnitNumber == (PDODeviceExtension->LUN & MAX_LUN)); ASSERT(SrbGetCdb(Request)->CDB10.LogicalUnitNumber == PDODeviceExtension->LUN);
Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRP_CONTEXT), USB_STOR_TAG);
if (!Context) return USBSTOR_SendCBWRequest(PDODeviceExtension->LowerDeviceObject->DeviceExtension, Irp);
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
Status = USBSTOR_SendCBWRequest(PDODeviceExtension->LowerDeviceObject->DeviceExtension, Irp, Context);
}
return Status;
} }

View file

@ -61,6 +61,52 @@
#define MAX_LUN 0xF #define MAX_LUN 0xF
#define USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH 0x10000 #define USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH 0x10000
#define CBW_SIGNATURE 0x43425355
#define CSW_SIGNATURE 0x53425355
#include <pshpack1.h>
typedef struct
{
ULONG Signature; // CBW signature
ULONG Tag; // CBW Tag of operation
ULONG DataTransferLength; // data transfer length
UCHAR Flags; // CBW Flags endpoint direction
UCHAR LUN; // lun unit
UCHAR CommandBlockLength; // Command block length
UCHAR CommandBlock[16];
} CBW, *PCBW;
C_ASSERT(sizeof(CBW) == 31);
#define CSW_STATUS_COMMAND_PASSED 0x00
#define CSW_STATUS_COMMAND_FAILED 0x01
#define CSW_STATUS_PHASE_ERROR 0x02
typedef struct
{
ULONG Signature; // CSW signature
ULONG Tag; // CSW tag
ULONG DataResidue; // CSW data transfer diff
UCHAR Status; // CSW status
} CSW, *PCSW;
#include <poppack.h>
typedef struct
{
PIRP Irp;
ULONG ErrorIndex;
ULONG StallRetryCount; // the number of retries after receiving USBD_STATUS_STALL_PID status
union
{
CBW cbw;
CSW csw;
};
URB Urb;
SCSI_REQUEST_BLOCK SenseSrb;
} IRP_CONTEXT, *PIRP_CONTEXT;
typedef struct __COMMON_DEVICE_EXTENSION__ typedef struct __COMMON_DEVICE_EXTENSION__
{ {
BOOLEAN IsFDO; BOOLEAN IsFDO;
@ -99,6 +145,7 @@ typedef struct
KSPIN_LOCK CommonLock; KSPIN_LOCK CommonLock;
PIO_WORKITEM ResetDeviceWorkItem; PIO_WORKITEM ResetDeviceWorkItem;
ULONG Flags; ULONG Flags;
IRP_CONTEXT CurrentIrpContext;
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
typedef struct typedef struct
@ -108,57 +155,12 @@ typedef struct
UCHAR LUN; // lun id UCHAR LUN; // lun id
BOOLEAN Claimed; // indicating if it has been claimed by upper driver BOOLEAN Claimed; // indicating if it has been claimed by upper driver
PDEVICE_OBJECT LowerDeviceObject; // points to FDO PDEVICE_OBJECT LowerDeviceObject; // points to FDO
PINQUIRYDATA InquiryData; // USB SCSI inquiry data
PDEVICE_OBJECT *PDODeviceObject; // entry in pdo list PDEVICE_OBJECT *PDODeviceObject; // entry in pdo list
PDEVICE_OBJECT Self; // self PDEVICE_OBJECT Self; // self
// the whole structure is not stored
UCHAR InquiryData[INQUIRYDATABUFFERSIZE]; // USB SCSI inquiry data
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION; }PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
#define CBW_SIGNATURE 0x43425355
#define CSW_SIGNATURE 0x53425355
#include <pshpack1.h>
typedef struct
{
ULONG Signature; // CBW signature
ULONG Tag; // CBW Tag of operation
ULONG DataTransferLength; // data transfer length
UCHAR Flags; // CBW Flags endpoint direction
UCHAR LUN; // lun unit
UCHAR CommandBlockLength; // Command block length
UCHAR CommandBlock[16];
}CBW, *PCBW;
C_ASSERT(sizeof(CBW) == 31);
#define CSW_STATUS_COMMAND_PASSED 0x00
#define CSW_STATUS_COMMAND_FAILED 0x01
#define CSW_STATUS_PHASE_ERROR 0x02
typedef struct
{
ULONG Signature; // CSW signature
ULONG Tag; // CSW tag
ULONG DataResidue; // CSW data transfer diff
UCHAR Status; // CSW status
}CSW, *PCSW;
#include <poppack.h>
typedef struct
{
PIRP Irp;
PFDO_DEVICE_EXTENSION FDODeviceExtension;
ULONG ErrorIndex;
ULONG StallRetryCount; // the number of retries after receiving USBD_STATUS_STALL_PID status
union
{
CBW cbw;
CSW csw;
};
URB Urb;
SCSI_REQUEST_BLOCK SenseSrb;
} IRP_CONTEXT, *PIRP_CONTEXT;
typedef struct _ERRORHANDLER_WORKITEM_DATA typedef struct _ERRORHANDLER_WORKITEM_DATA
{ {
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
@ -267,7 +269,7 @@ USBSTOR_HandleExecuteSCSI(
NTSTATUS NTSTATUS
USBSTOR_SendCSWRequest( USBSTOR_SendCSWRequest(
PIRP_CONTEXT Context, PFDO_DEVICE_EXTENSION FDODeviceExtension,
PIRP Irp); PIRP Irp);
@ -351,8 +353,7 @@ USBSTOR_TimerRoutine(
VOID VOID
NTAPI NTAPI
USBSTOR_QueueResetPipe( USBSTOR_QueueResetPipe(
IN PFDO_DEVICE_EXTENSION FDODeviceExtension, IN PFDO_DEVICE_EXTENSION FDODeviceExtension);
IN PIRP_CONTEXT Context);
VOID VOID
NTAPI NTAPI