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/disk.c?rev=51654&r1=51653&r2=51654&view=diff
==============================================================================
--- 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/scsi.c?rev=51654&r1=51653&r2=51654&view=diff
==============================================================================
--- 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;
+}


Reply via email to