Author: janderwald
Date: Fri May  6 17:23:19 2011
New Revision: 51609
URL: 
http://svn.reactos.org/svn/reactos?rev=51609&view=rev
Log:
[USBSTOR]
- Implement SCSI mode sense
Modified:
    branches/usb-bringup/drivers/usb/usbstor/disk.c
    branches/usb-bringup/drivers/usb/usbstor/scsi.c
    branches/usb-bringup/drivers/usb/usbstor/usbstor.h
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] Fri May  6 17:23:19 2011
@@ -20,6 +20,7 @@
 {
     PCDB pCDB;
     NTSTATUS Status;
+    ULONG TransferredLength;
     //
     // get SCSI command data block
@@ -62,6 +63,35 @@
             // store returned info length
             //
             Irp->IoStatus.Information = Request->DataTransferLength;
+            Request->SrbStatus = SRB_STATUS_SUCCESS;
+        }
+        else
+        {
+            //
+            // failed to retrieve capacity
+            //
+            Irp->IoStatus.Information = 0;
+            Request->SrbStatus = SRB_STATUS_ERROR;
+        }
+    }
+    else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE)
+    {
+        DPRINT1("SCSIOP_MODE_SENSE DataTransferLength %lu\n",
Request->DataTransferLength);
+        ASSERT(pCDB->MODE_SENSE.AllocationLength == Request->DataTransferLength);
+        ASSERT(Request->DataBuffer);
+
+        //
+        // send mode sense command
+        //
+        Status = USBSTOR_SendModeSenseCmd(DeviceObject, Request, &TransferredLength);
+        DPRINT1("USBSTOR_SendModeSenseCmd 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
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] Fri May  6 17:23:19 2011
@@ -435,7 +435,7 @@
     }
     //
-    // initialize inquiry cmd
+    // initialize capacity cmd
     //
     RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
     Cmd.Code = SCSIOP_INQUIRY;
@@ -443,7 +443,7 @@
     Cmd.AllocationLength = sizeof(UFI_INQUIRY_RESPONSE);
     //
-    // now send inquiry cmd
+    // now send capacity cmd
     //
     Status = USBSTOR_SendCBW(DeviceObject, UFI_CAPACITY_CMD_LEN, (PUCHAR)&Cmd,
sizeof(UFI_CAPACITY_RESPONSE), &OutControl);
     if (!NT_SUCCESS(Status))
@@ -523,3 +523,123 @@
     return Status;
 }
+NTSTATUS
+USBSTOR_SendModeSenseCmd(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN OUT PSCSI_REQUEST_BLOCK Request,
+    OUT PULONG TransferBufferLength)
+{
+    UFI_SENSE_CMD Cmd;
+    CSW CSW;
+    NTSTATUS Status;
+    PVOID Response;
+    PPDO_DEVICE_EXTENSION PDODeviceExtension;
+    PCBW OutControl;
+    PCDB pCDB;
+
+    //
+    // 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;
+    }
+
+    //
+    // 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 = pCDB->MODE_SENSE.AllocationLength;
+
+    //
+    // now send mode sense cmd
+    //
+    Status = USBSTOR_SendCBW(DeviceObject, UFI_CAPACITY_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;
+    }
+
+    //
+    // 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;
+}
+
Modified: branches/usb-bringup/drivers/usb/usbstor/usbstor.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/usbstor.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/usbstor.h [iso-8859-1] Fri May  6 17:23:19
2011
@@ -149,6 +149,22 @@
     ULONG BlockLength;                                               // block length in
bytes
 }UFI_CAPACITY_RESPONSE, *PUFI_CAPACITY_RESPONSE;
+//--------------------------------------------------------------------------------------------------------------------------------------------
+//
+// UFI sense mode cmd
+//
+typedef struct
+{
+    UCHAR Code;                                                      // operation code
+    UCHAR LUN;                                                       // lun address
+    UCHAR PageCode:6;                                                // page code
selector
+    UCHAR PC:2;                                                      // type of
parameters to be returned
+    UCHAR Reserved[4];                                               // reserved 0x00
+    USHORT AllocationLength;                                         // parameters length
+    UCHAR Reserved1[3];
+}UFI_SENSE_CMD, *PUFI_SENSE_CMD;
+
+C_ASSERT(sizeof(UFI_CAPACITY_CMD) == 12);
 //---------------------------------------------------------------------
 //
@@ -248,6 +264,12 @@
     OUT PREAD_CAPACITY_DATA_EX CapacityDataEx,
     OUT PREAD_CAPACITY_DATA CapacityData);
+NTSTATUS
+USBSTOR_SendModeSenseCmd(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN OUT PSCSI_REQUEST_BLOCK Request,
+    OUT PULONG TransferBufferLength);
+
 //---------------------------------------------------------------------
 //
 // disk.c routines
@@ -261,3 +283,5 @@
 USBSTOR_HandleDeviceControl(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp);
+
+