Author: janderwald
Date: Sun May 8 22:18:55 2011
New Revision: 51654
URL:
http://svn.reactos.org/svn/reactos?rev=51654&view=rev
Log:
[USBSTOR]
- Start implementing SCSI read
Modified:
branches/usb-bringup/drivers/usb/usbstor/disk.c
branches/usb-bringup/drivers/usb/usbstor/scsi.c
Modified: branches/usb-bringup/drivers/usb/usbstor/disk.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/disk.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/disk.c [iso-8859-1] Sun May 8 22:18:55 2011
@@ -103,6 +103,35 @@
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;
Modified: branches/usb-bringup/drivers/usb/usbstor/scsi.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/scsi.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/scsi.c [iso-8859-1] Sun May 8 22:18:55 2011
@@ -488,6 +488,12 @@
CapacityData->LogicalBlockAddress = Response->LastLogicalBlockAddress;
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 @@
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;
+}