[USBSTOR] Do not attempt additional processing of SCSI requests.

Now the driver sends all requests transparently.
Inspired by Vadim Galyant's patches to usbstor
This commit is contained in:
Victor Perevertkin
2019-03-26 14:26:06 +03:00
parent d17d15ab6c
commit b4c03399ba

View File

@@ -129,8 +129,6 @@ USBSTOR_CSWCompletionRoutine(
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
PCDB pCDB;
PREAD_CAPACITY_DATA_EX CapacityDataEx;
PREAD_CAPACITY_DATA CapacityData;
PUFI_CAPACITY_RESPONSE Response;
NTSTATUS Status;
@@ -205,29 +203,6 @@ USBSTOR_CSWCompletionRoutine(
// store in pdo
Context->PDODeviceExtension->BlockLength = NTOHL(Response->BlockLength);
Context->PDODeviceExtension->LastLogicBlockAddress = NTOHL(Response->LastLogicalBlockAddress);
if (Request->DataTransferLength == sizeof(READ_CAPACITY_DATA_EX))
{
// get input buffer
CapacityDataEx = (PREAD_CAPACITY_DATA_EX)Request->DataBuffer;
// set result
CapacityDataEx->BytesPerBlock = Response->BlockLength;
CapacityDataEx->LogicalBlockAddress.QuadPart = Response->LastLogicalBlockAddress;
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA_EX);
}
else
{
// get input buffer
CapacityData = (PREAD_CAPACITY_DATA)Request->DataBuffer;
// set result
CapacityData->BytesPerBlock = Response->BlockLength;
CapacityData->LogicalBlockAddress = Response->LastLogicalBlockAddress;
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA);
}
FreeItem(Context->TransferData);
}
FreeItem(Context->cbw);
@@ -554,350 +529,6 @@ USBSTOR_SendRequest(
return STATUS_PENDING;
}
NTSTATUS
USBSTOR_SendFormatCapacity(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
{
UFI_READ_FORMAT_CAPACITY Cmd;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
IoStack = IoGetCurrentIrpStackLocation(Irp);
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
// initialize inquiry cmd
RtlZeroMemory(&Cmd, sizeof(UFI_READ_FORMAT_CAPACITY));
Cmd.Code = SCSIOP_READ_FORMATTED_CAPACITY;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
Cmd.AllocationLengthMsb = HTONS(Request->DataTransferLength & 0xFFFF) >> 8;
Cmd.AllocationLengthLsb = HTONS(Request->DataTransferLength & 0xFFFF) & 0xFF;
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_FORMAT_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
}
NTSTATUS
USBSTOR_SendInquiry(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
{
UFI_INQUIRY_CMD Cmd;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// initialize inquiry cmd
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
Cmd.Code = SCSIOP_INQUIRY;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
Cmd.AllocationLength = sizeof(UFI_INQUIRY_RESPONSE);
ASSERT(Request->DataTransferLength >= sizeof(UFI_INQUIRY_RESPONSE));
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_INQUIRY_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
}
NTSTATUS
USBSTOR_SendCapacity(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
{
UFI_CAPACITY_CMD Cmd;
PUFI_CAPACITY_RESPONSE Response;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, PAGE_SIZE);
if (!Response)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
// initialize capacity cmd
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
Cmd.Code = SCSIOP_READ_CAPACITY;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_CAPACITY_RESPONSE), (PUCHAR)Response, RetryCount);
}
NTSTATUS
USBSTOR_SendModeSense(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
{
#if 0
UFI_SENSE_CMD Cmd;
NTSTATUS Status;
PVOID Response;
PCBW OutControl;
PCDB pCDB;
PUFI_MODE_PARAMETER_HEADER Header;
#endif
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
IoStack = IoGetCurrentIrpStackLocation(Irp);
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
RtlZeroMemory(Request->DataBuffer, Request->DataTransferLength);
Request->SrbStatus = SRB_STATUS_SUCCESS;
Irp->IoStatus.Information = Request->DataTransferLength;
Irp->IoStatus.Status = STATUS_SUCCESS;
USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject);
return STATUS_SUCCESS;
#if 0
//
// get SCSI command data block
//
pCDB = (PCDB)Request->Cdb;
//
// get PDO device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// allocate sense response from non paged pool
//
Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, Request->DataTransferLength);
if (!Response)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// sanity check
//
// Supported pages
// MODE_PAGE_ERROR_RECOVERY
// MODE_PAGE_FLEXIBILE
// MODE_PAGE_LUN_MAPPING
// MODE_PAGE_FAULT_REPORTING
// MODE_SENSE_RETURN_ALL
//
// initialize mode sense cmd
//
RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
Cmd.Code = SCSIOP_MODE_SENSE;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
Cmd.PageCode = pCDB->MODE_SENSE.PageCode;
Cmd.PC = pCDB->MODE_SENSE.Pc;
Cmd.AllocationLength = HTONS(pCDB->MODE_SENSE.AllocationLength);
DPRINT1("PageCode %x\n", pCDB->MODE_SENSE.PageCode);
DPRINT1("PC %x\n", pCDB->MODE_SENSE.Pc);
//
// now send mode sense cmd
//
Status = USBSTOR_SendCBW(DeviceObject, UFI_SENSE_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, &OutControl);
if (!NT_SUCCESS(Status))
{
//
// failed to send CBW
//
DPRINT1("USBSTOR_SendCapacityCmd> USBSTOR_SendCBW failed with %x\n", Status);
FreeItem(Response);
ASSERT(FALSE);
return Status;
}
//
// now send data block response
//
Status = USBSTOR_SendData(DeviceObject, Request->DataTransferLength, Response);
if (!NT_SUCCESS(Status))
{
//
// failed to send CBW
//
DPRINT1("USBSTOR_SendCapacityCmd> USBSTOR_SendData failed with %x\n", Status);
FreeItem(Response);
ASSERT(FALSE);
return Status;
}
Header = (PUFI_MODE_PARAMETER_HEADER)Response;
//
// TODO: build layout
//
// first struct is the header
// MODE_PARAMETER_HEADER / _MODE_PARAMETER_HEADER10
//
// followed by
// MODE_PARAMETER_BLOCK
//
//
UNIMPLEMENTED;
//
// send csw
//
Status = USBSTOR_SendCSW(DeviceObject, OutControl, 512, &CSW);
DPRINT1("------------------------\n");
DPRINT1("CSW %p\n", &CSW);
DPRINT1("Signature %x\n", CSW.Signature);
DPRINT1("Tag %x\n", CSW.Tag);
DPRINT1("DataResidue %x\n", CSW.DataResidue);
DPRINT1("Status %x\n", CSW.Status);
//
// FIXME: handle error
//
ASSERT(CSW.Status == 0);
ASSERT(CSW.DataResidue == 0);
//
// calculate transfer length
//
*TransferBufferLength = Request->DataTransferLength - CSW.DataResidue;
//
// copy buffer
//
RtlCopyMemory(Request->DataBuffer, Response, *TransferBufferLength);
//
// free item
//
FreeItem(OutControl);
//
// free response
//
FreeItem(Response);
//
// done
//
return Status;
#endif
}
NTSTATUS
USBSTOR_SendReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG RetryCount)
{
UFI_READ_WRITE_CMD Cmd;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PCDB pCDB;
ULONG BlockCount, Temp;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
pCDB = (PCDB)Request->Cdb;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
DPRINT("USBSTOR_SendReadWrite DataTransferLength %lu, BlockLength %lu\n", Request->DataTransferLength, PDODeviceExtension->BlockLength);
ASSERT(PDODeviceExtension->BlockLength);
BlockCount = Request->DataTransferLength / PDODeviceExtension->BlockLength;
// initialize read cmd
RtlZeroMemory(&Cmd, sizeof(UFI_READ_WRITE_CMD));
Cmd.Code = pCDB->AsByte[0];
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
Cmd.ContiguousLogicBlocksByte0 = pCDB->CDB10.TransferBlocksMsb;
Cmd.ContiguousLogicBlocksByte1 = pCDB->CDB10.TransferBlocksLsb;
Cmd.LogicalBlockByte0 = pCDB->CDB10.LogicalBlockByte0;
Cmd.LogicalBlockByte1 = pCDB->CDB10.LogicalBlockByte1;
Cmd.LogicalBlockByte2 = pCDB->CDB10.LogicalBlockByte2;
Cmd.LogicalBlockByte3 = pCDB->CDB10.LogicalBlockByte3;
Temp = (Cmd.ContiguousLogicBlocksByte0 << 8 | Cmd.ContiguousLogicBlocksByte1);
ASSERT(Temp == BlockCount);
DPRINT("USBSTOR_SendReadWrite BlockAddress %x%x%x%x BlockCount %lu BlockLength %lu\n", Cmd.LogicalBlockByte0, Cmd.LogicalBlockByte1, Cmd.LogicalBlockByte2, Cmd.LogicalBlockByte3, BlockCount, PDODeviceExtension->BlockLength);
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_WRITE_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer, RetryCount);
}
NTSTATUS
USBSTOR_SendTestUnit(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN ULONG RetryCount)
{
UFI_TEST_UNIT_CMD Cmd;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
ASSERT(Request->DataTransferLength == 0);
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// initialize test unit cmd
RtlZeroMemory(&Cmd, sizeof(UFI_TEST_UNIT_CMD));
Cmd.Code = SCSIOP_TEST_UNIT_READY;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
return USBSTOR_SendRequest(DeviceObject, Irp, UFI_TEST_UNIT_CMD_LEN, (PUCHAR)&Cmd, 0, NULL, RetryCount);
}
NTSTATUS
USBSTOR_SendUnknownRequest(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN ULONG RetryCount)
{
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
UFI_UNKNOWN_CMD Cmd;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Request = IoStack->Parameters.Others.Argument1;
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// check that we're sending to the right LUN
ASSERT(Request->Cdb[1] == (PDODeviceExtension->LUN & MAX_LUN));
ASSERT(Request->CdbLength <= sizeof(UFI_UNKNOWN_CMD));
RtlCopyMemory(&Cmd, Request->Cdb, Request->CdbLength);
return USBSTOR_SendRequest(DeviceObject, Irp, Request->CdbLength, (PUCHAR)&Cmd, Request->DataTransferLength, Request->DataBuffer, RetryCount);
}
NTSTATUS
USBSTOR_HandleExecuteSCSI(
IN PDEVICE_OBJECT DeviceObject,
@@ -914,71 +545,14 @@ USBSTOR_HandleExecuteSCSI(
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
IoStack = IoGetCurrentIrpStackLocation(Irp);
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
Request = IoStack->Parameters.Scsi.Srb;
pCDB = (PCDB)Request->Cdb;
DPRINT("USBSTOR_HandleExecuteSCSI Operation Code %x\n", pCDB->AsByte[0]);
DPRINT("USBSTOR_HandleExecuteSCSI Operation Code %x, Length %lu\n", pCDB->CDB10.OperationCode, Request->DataTransferLength);
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
{
ASSERT(Request->DataBuffer);
DPRINT("SCSIOP_READ_CAPACITY Length %lu\n", Request->DataTransferLength);
Status = USBSTOR_SendCapacity(DeviceObject, Irp, RetryCount);
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE)
{
DPRINT("SCSIOP_MODE_SENSE DataTransferLength %lu\n", Request->DataTransferLength);
ASSERT(pCDB->MODE_SENSE.AllocationLength == Request->DataTransferLength);
ASSERT(Request->DataBuffer);
Status = USBSTOR_SendModeSense(DeviceObject, Irp, RetryCount);
}
else if (pCDB->AsByte[0] == SCSIOP_READ_FORMATTED_CAPACITY)
{
DPRINT("SCSIOP_READ_FORMATTED_CAPACITY DataTransferLength %lu\n", Request->DataTransferLength);
Status = USBSTOR_SendFormatCapacity(DeviceObject, Irp, RetryCount);
}
else if (pCDB->AsByte[0] == SCSIOP_INQUIRY)
{
DPRINT("SCSIOP_INQUIRY DataTransferLength %lu\n", Request->DataTransferLength);
Status = USBSTOR_SendInquiry(DeviceObject, Irp, RetryCount);
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_READ || pCDB->MODE_SENSE.OperationCode == SCSIOP_WRITE)
{
DPRINT("SCSIOP_READ / SCSIOP_WRITE DataTransferLength %lu\n", Request->DataTransferLength);
Status = USBSTOR_SendReadWrite(DeviceObject, Irp, RetryCount);
}
else if (pCDB->AsByte[0] == SCSIOP_MEDIUM_REMOVAL)
{
DPRINT("SCSIOP_MEDIUM_REMOVAL\n");
// just complete the request
Request->SrbStatus = SRB_STATUS_SUCCESS;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Request->DataTransferLength;
USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject);
return STATUS_SUCCESS;
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_TEST_UNIT_READY)
{
DPRINT("SCSIOP_TEST_UNIT_READY\n");
Status = USBSTOR_SendTestUnit(DeviceObject, Irp, RetryCount);
}
else
{
// Unknown request. Simply forward
DPRINT1("Forwarding unknown Operation Code %x\n", pCDB->AsByte[0]);
Status = USBSTOR_SendUnknownRequest(DeviceObject, Irp, RetryCount);
}
// check that we're sending to the right LUN
ASSERT(pCDB->CDB10.LogicalUnitNumber == (PDODeviceExtension->LUN & MAX_LUN));
Status = USBSTOR_SendRequest(DeviceObject, Irp, Request->CdbLength, (PUCHAR)pCDB, Request->DataTransferLength, Request->DataBuffer, RetryCount);
return Status;
}