[USBSTOR]

- Start implementing SCSI read

svn path=/branches/usb-bringup/; revision=51654
This commit is contained in:
Johannes Anderwald 2011-05-08 22:18:55 +00:00
parent 45f27e8b8c
commit fc34f0177d
2 changed files with 170 additions and 0 deletions

View file

@ -103,6 +103,35 @@ USBSTOR_HandleExecuteSCSI(
Request->SrbStatus = SRB_STATUS_ERROR;
}
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_READ)
{
DPRINT1("SCSIOP_READ DataTransferLength %lu\n", Request->DataTransferLength);
ASSERT(Request->DataBuffer);
//
// send read command
//
Status = USBSTOR_SendReadCmd(DeviceObject, Request, &TransferredLength);
DPRINT1("USBSTOR_SendReadCmd Status %x BytesReturned %lu\n", Status, TransferredLength);
if (NT_SUCCESS(Status))
{
//
// store returned info length
//
Irp->IoStatus.Information = TransferredLength;
Request->SrbStatus = SRB_STATUS_SUCCESS;
}
else
{
//
// failed to retrieve sense data
//
Irp->IoStatus.Information = 0;
Request->SrbStatus = SRB_STATUS_ERROR;
}
}
else
{
UNIMPLEMENTED;

View file

@ -489,6 +489,12 @@ USBSTOR_SendCapacityCmd(
CapacityData->BytesPerBlock = Response->BlockLength;
}
//
// store result in device extension
//
PDODeviceExtension->LastLogicBlockAddress = NTOHL(Response->LastLogicalBlockAddress);
PDODeviceExtension->BlockLength = NTOHL(Response->BlockLength);
//
// send csw
//
@ -672,3 +678,138 @@ USBSTOR_SendModeSenseCmd(
return Status;
}
NTSTATUS
USBSTOR_SendReadCmd(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PSCSI_REQUEST_BLOCK Request,
OUT PULONG TransferBufferLength)
{
UFI_READ_CMD Cmd;
CSW CSW;
NTSTATUS Status;
PVOID Response;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PCBW OutControl;
PCDB pCDB;
ULONG BlockCount;
//
// get SCSI command data block
//
pCDB = (PCDB)Request->Cdb;
//
// get PDO device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// allocate read buffer response from non paged pool
//
Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, Request->DataTransferLength);
if (!Response)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// FIXME: support more logical blocks
//
ASSERT(Request->DataTransferLength == PDODeviceExtension->BlockLength);
//
// block count
//
BlockCount = Request->DataTransferLength / PDODeviceExtension->BlockLength;
//
// initialize read sense cmd
//
RtlZeroMemory(&Cmd, sizeof(UFI_READ_CMD));
Cmd.Code = SCSIOP_READ;
Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
Cmd.ContiguousLogicBlocks = _byteswap_ushort(BlockCount);
RtlCopyMemory(&Cmd.LogicalBlockAddress, pCDB->READ12.LogicalBlock, sizeof(UCHAR) * 4);
DPRINT1("BlockAddress %lu BlockCount %lu BlockLength %lu\n", NTOHL(Cmd.LogicalBlockAddress), BlockCount, PDODeviceExtension->BlockLength);
//
// now send read cmd
//
Status = USBSTOR_SendCBW(DeviceObject, UFI_READ_CMD_LEN, (PUCHAR)&Cmd, Request->DataTransferLength, &OutControl);
if (!NT_SUCCESS(Status))
{
//
// failed to send CBW
//
DPRINT1("USBSTOR_SendReadCmd> USBSTOR_SendCBW failed with %x\n", Status);
FreeItem(Response);
ASSERT(FALSE);
return Status;
}
//
// now read the logical block
//
Status = USBSTOR_SendData(DeviceObject, Request->DataTransferLength, Response);
if (!NT_SUCCESS(Status))
{
//
// failed to read logical block
//
DPRINT1("USBSTOR_SendReadCmd> USBSTOR_SendData failed with %x\n", Status);
FreeItem(Response);
ASSERT(FALSE);
return Status;
}
DbgBreakPoint();
//
// 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;
}