Author: janderwald
Date: Wed May 11 03:49:15 2011
New Revision: 51673

URL: http://svn.reactos.org/svn/reactos?rev=51673&view=rev
Log:
[USBSTOR]
- Rewrite scsi method to act asynchronous

Modified:
    branches/usb-bringup/drivers/usb/usbstor/disk.c
    branches/usb-bringup/drivers/usb/usbstor/scsi.c
    branches/usb-bringup/drivers/usb/usbstor/usbstor.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/disk.c?rev=51673&r1=51672&r2=51673&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] Wed May 11 
03:49:15 2011
@@ -20,7 +20,6 @@
 {
     PCDB pCDB;
     NTSTATUS Status;
-    ULONG TransferredLength;
 
     //
     // get SCSI command data block
@@ -29,6 +28,7 @@
 
     DPRINT1("USBSTOR_HandleExecuteSCSI Operation Code %x\n", pCDB->AsByte[0]);
 
+
     if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
     {
         //
@@ -36,43 +36,8 @@
         //
         ASSERT(Request->DataBuffer);
 
-        if (Request->DataTransferLength == sizeof(READ_CAPACITY_DATA_EX))
-        {
-            //
-            // retrieve capacity extended structure
-            //
-            Status = USBSTOR_SendCapacityCmd(DeviceObject, 
(PREAD_CAPACITY_DATA_EX)Request->DataBuffer, NULL);
-        }
-        else
-        {
-            //
-            // sanity check
-            //
-            ASSERT(Request->DataTransferLength == sizeof(READ_CAPACITY_DATA));
-
-            //
-            // retrieve capacity
-            //
-            Status = USBSTOR_SendCapacityCmd(DeviceObject, NULL, 
(PREAD_CAPACITY_DATA)Request->DataBuffer);
-        }
-        DPRINT1("USBSTOR_SendCapacityCmd %x\n", Status);
-
-        if (NT_SUCCESS(Status))
-        {
-            //
-            // 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;
-        }
+        DPRINT1("SCSIOP_READ_CAPACITY Length %\n", 
Request->DataTransferLength);
+        Status = USBSTOR_SendCapacityCmd(DeviceObject, Irp);
     }
     else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE)
     {
@@ -83,25 +48,7 @@
         //
         // 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
-        {
-            //
-            // failed to retrieve sense data
-            //
-            Irp->IoStatus.Information = 0;
-            Request->SrbStatus = SRB_STATUS_ERROR;
-        }
+        Status = USBSTOR_SendModeSenseCmd(DeviceObject, Irp);
     }
     else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_READ)
     {
@@ -111,25 +58,7 @@
         //
         // 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 read
-            //
-            Irp->IoStatus.Information = 0;
-            Request->SrbStatus = SRB_STATUS_ERROR;
-        }
+        Status = USBSTOR_SendReadCmd(DeviceObject, Irp);
     }
     else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_TEST_UNIT_READY)
     {
@@ -138,22 +67,7 @@
         //
         // send test unit command
         //
-        Status = USBSTOR_SendTestUnitCmd(DeviceObject, Request);
-
-        if (NT_SUCCESS(Status))
-        {
-            //
-            // store returned info length
-            //
-            Request->SrbStatus = SRB_STATUS_SUCCESS;
-        }
-        else
-        {
-            //
-            // test unit command failed
-            //
-            Request->SrbStatus = SRB_STATUS_ERROR;
-        }
+        Status = USBSTOR_SendTestUnitCmd(DeviceObject, Irp);
     }
     else
     {
@@ -202,8 +116,7 @@
         case SRB_FUNCTION_EXECUTE_SCSI:
         {
             DPRINT1("SRB_FUNCTION_EXECUTE_SCSI\n");
-            Status = USBSTOR_HandleExecuteSCSI(DeviceObject, Irp, Request, 
PDODeviceExtension);
-            break;
+            return USBSTOR_HandleExecuteSCSI(DeviceObject, Irp, Request, 
PDODeviceExtension);
         }
         case SRB_FUNCTION_RELEASE_DEVICE:
         {
@@ -280,6 +193,11 @@
         }
     }
 
+    //
+    // complete request
+    //
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 }
 

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=51673&r1=51672&r2=51673&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] Wed May 11 
03:49:15 2011
@@ -46,19 +46,363 @@
     return STATUS_SUCCESS;
 }
 
-NTSTATUS
-USBSTOR_SendCBW(
+PIRP_CONTEXT
+USBSTOR_AllocateIrpContext()
+{
+    PIRP_CONTEXT Context;
+
+    //
+    // allocate irp context
+    //
+    Context = (PIRP_CONTEXT)AllocateItem(NonPagedPool, sizeof(IRP_CONTEXT));
+    if (!Context)
+    {
+        //
+        // no memory
+        //
+        return NULL;
+    }
+
+    //
+    // allocate cbw block
+    //
+    Context->cbw = (PCBW)AllocateItem(NonPagedPool, 512);
+    if (!Context->cbw)
+    {
+        //
+        // no memory
+        //
+        FreeItem(Context);
+        return NULL;
+    }
+
+    //
+    // done
+    //
+    return Context;
+
+}
+
+//
+// driver verifier
+//
+IO_COMPLETION_ROUTINE USBSTOR_CSWCompletionRoutine;
+
+NTSTATUS
+NTAPI
+USBSTOR_CSWCompletionRoutine(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp, 
+    PVOID Ctx)
+{
+    PIRP_CONTEXT Context;
+    PIO_STACK_LOCATION IoStack;
+    PSCSI_REQUEST_BLOCK Request;
+    PCDB pCDB;
+    PREAD_CAPACITY_DATA_EX CapacityDataEx;
+    PREAD_CAPACITY_DATA CapacityData;
+    PUFI_CAPACITY_RESPONSE Response;
+
+    DPRINT1("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
+
+    //
+    // access context
+    //
+    Context = (PIRP_CONTEXT)Ctx;
+
+    if (Context->TransferBufferMDL)
+    {
+        //
+        // free mdl
+        //
+        IoFreeMdl(Context->TransferBufferMDL);
+    }
+
+    if (Context->Irp)
+    {
+        //
+        // get current stack location
+        //
+        IoStack = IoGetCurrentIrpStackLocation(Context->Irp);
+
+        //
+        // get request block
+        //
+        Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
+        ASSERT(Request);
+
+        //
+        // FIXME: check status
+        //
+        Request->SrbStatus = SRB_STATUS_SUCCESS;
+
+        //
+        // get SCSI command data block
+        //
+        pCDB = (PCDB)Request->Cdb;
+
+        //
+        // read capacity needs special work
+        //
+        if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
+        {
+            //
+            // get output buffer
+            //
+            Response = (PUFI_CAPACITY_RESPONSE)Context->TransferData;
+
+            //
+            // 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);
+            }
+
+            //
+            // free response
+            //
+            FreeItem(Context->TransferData);
+        }
+    }
+
+    //
+    // free cbw
+    //
+    FreeItem(Context->cbw);
+
+
+    if (Context->Irp)
+    {
+        //
+        // FIXME: check status
+        //
+        Context->Irp->IoStatus.Status = Irp->IoStatus.Status;
+        Context->Irp->IoStatus.Information = Context->TransferDataLength;
+
+        //
+        // complete request
+        //
+        IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
+    }
+
+    if (Context->Event)
+    {
+        //
+        // signal event
+        //
+        KeSetEvent(Context->Event, 0, FALSE);
+    }
+
+
+    //
+    // free context
+    //
+    FreeItem(Context);
+
+    //
+    // done
+    //
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+//
+// driver verifier
+//
+IO_COMPLETION_ROUTINE USBSTOR_DataCompletionRoutine;
+
+NTSTATUS
+NTAPI
+USBSTOR_DataCompletionRoutine(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp, 
+    PVOID Ctx)
+{
+    PIRP_CONTEXT Context;
+    PIO_STACK_LOCATION IoStack;
+
+    DPRINT1("USBSTOR_DataCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
+
+    //
+    // access context
+    //
+    Context = (PIRP_CONTEXT)Ctx;
+
+    //
+    // get next stack location
+    //
+    IoStack = IoGetNextIrpStackLocation(Irp);
+
+    //
+    // now initialize the urb for sending the csw
+    //
+    Context->Urb.UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
+    Context->Urb.UrbBulkOrInterruptTransfer.Hdr.Function = 
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
+    Context->Urb.UrbBulkOrInterruptTransfer.PipeHandle = 
Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle;
+    Context->Urb.UrbBulkOrInterruptTransfer.TransferBuffer = Context->csw;
+    Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength = 512; //FIXME
+    Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL = NULL;
+    Context->Urb.UrbBulkOrInterruptTransfer.TransferFlags = 
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
+
+
+    //
+    // initialize stack location
+    //
+    IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
+    IoStack->Parameters.DeviceIoControl.IoControlCode = 
IOCTL_INTERNAL_USB_SUBMIT_URB;
+    IoStack->Parameters.Others.Argument1 = (PVOID)&Context->Urb;
+    IoStack->Parameters.DeviceIoControl.InputBufferLength = 
Context->Urb.UrbHeader.Length;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+
+
+    //
+    // setup completion routine
+    //
+    IoSetCompletionRoutine(Irp, USBSTOR_CSWCompletionRoutine, Context, TRUE, 
TRUE, TRUE);
+
+    //
+    // call driver
+    //
+    IoCallDriver(Context->FDODeviceExtension->LowerDeviceObject, Irp);
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+//
+// driver verifier
+//
+IO_COMPLETION_ROUTINE USBSTOR_CBWCompletionRoutine;
+
+NTSTATUS
+NTAPI
+USBSTOR_CBWCompletionRoutine(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp, 
+    PVOID Ctx)
+{
+    PIRP_CONTEXT Context;
+    PIO_STACK_LOCATION IoStack;
+
+    DPRINT1("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
+
+    //
+    // access context
+    //
+    Context = (PIRP_CONTEXT)Ctx;
+
+
+    //
+    // get next stack location
+    //
+    IoStack = IoGetNextIrpStackLocation(Irp);
+
+    //
+    // is there data to be submitted
+    //
+    if (Context->TransferDataLength)
+    {
+        //
+        // now initialize the urb for sending data
+        //
+        Context->Urb.UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
+        Context->Urb.UrbBulkOrInterruptTransfer.Hdr.Function = 
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
+        Context->Urb.UrbBulkOrInterruptTransfer.PipeHandle = 
Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle;
+        Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferMDL = 
Context->TransferBufferMDL;
+        Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength = 
Context->TransferDataLength;
+        Context->Urb.UrbBulkOrInterruptTransfer.TransferFlags = 
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
+
+        //
+        // setup completion routine
+        //
+        IoSetCompletionRoutine(Irp, USBSTOR_DataCompletionRoutine, Context, 
TRUE, TRUE, TRUE);
+    }
+    else
+    {
+        //
+        // now initialize the urb for sending the csw
+        //
+        Context->Urb.UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
+        Context->Urb.UrbBulkOrInterruptTransfer.Hdr.Function = 
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
+        Context->Urb.UrbBulkOrInterruptTransfer.PipeHandle = 
Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle;
+        Context->Urb.UrbBulkOrInterruptTransfer.TransferBuffer = Context->csw;
+        Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength = 512; 
//FIXME
+        Context->Urb.UrbBulkOrInterruptTransfer.TransferFlags = 
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
+
+        //
+        // setup completion routine
+        //
+        IoSetCompletionRoutine(Irp, USBSTOR_CSWCompletionRoutine, Context, 
TRUE, TRUE, TRUE);
+    }
+
+    //
+    // initialize stack location
+    //
+    IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
+    IoStack->Parameters.DeviceIoControl.IoControlCode = 
IOCTL_INTERNAL_USB_SUBMIT_URB;
+    IoStack->Parameters.Others.Argument1 = (PVOID)&Context->Urb;
+    IoStack->Parameters.DeviceIoControl.InputBufferLength = 
Context->Urb.UrbHeader.Length;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+
+    //
+    // call driver
+    //
+    IoCallDriver(Context->FDODeviceExtension->LowerDeviceObject, Irp);
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS
+USBSTOR_SendRequest(
     IN PDEVICE_OBJECT DeviceObject,
-    IN UCHAR CommandBlockLength,
-    IN PUCHAR CommandBlock,
-    IN ULONG DataTransferLength,
-    OUT PCBW *OutControl)
-{
-    PCBW Control;
-    NTSTATUS Status;
-    PURB Urb;
+    IN PIRP OriginalRequest,
+    IN OPTIONAL PKEVENT Event,
+    IN ULONG CommandLength,
+    IN PUCHAR Command,
+    IN ULONG TransferDataLength,
+    IN PUCHAR TransferData)
+{
+    PIRP_CONTEXT Context;
     PPDO_DEVICE_EXTENSION PDODeviceExtension;
     PFDO_DEVICE_EXTENSION FDODeviceExtension;
+    PIRP Irp;
+    PIO_STACK_LOCATION IoStack;
+
+    //
+    // first allocate irp context
+    //
+    Context = USBSTOR_AllocateIrpContext();
+    if (!Context)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
     //
     // get PDO device extension
@@ -71,222 +415,106 @@
     FDODeviceExtension = 
(PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
 
     //
-    // first allocate CBW
-    //
-    Control = (PCBW)AllocateItem(NonPagedPool, 512);
-    if (!Control)
-    {
-        //
-        // no memory
-        //
+    // now build the cbw
+    //
+    USBSTOR_BuildCBW(0xDEADDEAD, // FIXME tag
+                     TransferDataLength,
+                     PDODeviceExtension->LUN,
+                     CommandLength,
+                     Command,
+                     Context->cbw);
+
+    //
+    // now initialize the urb
+    //
+    Context->Urb.UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
+    Context->Urb.UrbBulkOrInterruptTransfer.Hdr.Function = 
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
+    Context->Urb.UrbBulkOrInterruptTransfer.PipeHandle = 
FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle;
+    Context->Urb.UrbBulkOrInterruptTransfer.TransferBuffer = 
(PVOID)Context->cbw;
+    Context->Urb.UrbBulkOrInterruptTransfer.TransferBufferLength = sizeof(CBW);
+    Context->Urb.UrbBulkOrInterruptTransfer.TransferFlags = 
USBD_TRANSFER_DIRECTION_OUT | USBD_SHORT_TRANSFER_OK;
+
+    //
+    // initialize rest of context
+    //
+    Context->Irp = OriginalRequest;
+    Context->TransferData = TransferData;
+    Context->TransferDataLength = TransferDataLength;
+    Context->FDODeviceExtension = FDODeviceExtension;
+    Context->PDODeviceExtension = PDODeviceExtension;
+    Context->Event = Event;
+
+    //
+    // is there transfer data
+    //
+    if (Context->TransferDataLength)
+    {
+        //
+        // allocate mdl for buffer, buffer must be allocated from NonPagedPool
+        //
+        Context->TransferBufferMDL = IoAllocateMdl(Context->TransferData, 
Context->TransferDataLength, FALSE, FALSE, NULL);
+        if (!Context->TransferBufferMDL)
+        {
+            //
+            // failed to allocate MDL
+            //
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        //
+        // build mdl for nonpaged pool
+        //
+        MmBuildMdlForNonPagedPool(Context->TransferBufferMDL);
+    }
+
+    //
+    // now allocate the request
+    //
+    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+    if (!Irp)
+    {
+        FreeItem(Context->cbw);
+        FreeItem(Context);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    //
-    // first allocate CBW
-    //
-    Status = USBSTOR_BuildCBW(0xDEADDEAD, DataTransferLength, 
PDODeviceExtension->LUN, CommandBlockLength, CommandBlock, Control);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to build CBW
-        //
-        return Status;
-    }
-
-    //
-    // now build the urb
-    //
-    Urb = (PURB)AllocateItem(NonPagedPool, sizeof(URB));
-    if (!Urb)
-    {
-        //
-        // failed to allocate urb
-        //
-        FreeItem(Control);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // now initialize the urb
-    //
-    Urb->UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
-    Urb->UrbBulkOrInterruptTransfer.Hdr.Function = 
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
-    Urb->UrbBulkOrInterruptTransfer.PipeHandle = 
FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle;
-    Urb->UrbBulkOrInterruptTransfer.TransferBuffer = (PVOID)Control;
-    Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = sizeof(CBW);
-    Urb->UrbBulkOrInterruptTransfer.TransferFlags = 
USBD_TRANSFER_DIRECTION_OUT | USBD_SHORT_TRANSFER_OK;
-
-    //
-    // now send urb
-    //
-    Status = USBSTOR_SyncUrbRequest(FDODeviceExtension->LowerDeviceObject, 
Urb);
-
-    //
-    // free urb
-    //
-    FreeItem(Urb);
-
-    //
-    // store cbw
-    //
-    *OutControl = Control;
-
-    //
-    // return operation status
-    //
-    return Status;
-}
-
-NTSTATUS
-USBSTOR_SendData(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN ULONG DataTransferLength,
-    IN PVOID DataTransfer)
-{
-    PMDL TransferBufferMDL;
-    PURB Urb;
-    NTSTATUS Status;
-    PPDO_DEVICE_EXTENSION PDODeviceExtension;
-    PFDO_DEVICE_EXTENSION FDODeviceExtension;
-
-    //
-    // get PDO device extension
-    //
-    PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    //
-    // get FDO device extension
-    //
-    FDODeviceExtension = 
(PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
-
-    //
-    // allocate mdl for buffer, buffer must be allocated from NonPagedPool
-    //
-    TransferBufferMDL = IoAllocateMdl(DataTransfer, DataTransferLength, FALSE, 
FALSE, NULL);
-    if (!TransferBufferMDL)
-    {
-        //
-        // failed to allocate MDL
-        //
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // build mdl for nonpaged pool
-    //
-    MmBuildMdlForNonPagedPool(TransferBufferMDL);
-
-    //
-    // now build the urb
-    //
-    Urb = (PURB)AllocateItem(NonPagedPool, sizeof(URB));
-    if (!Urb)
-    {
-        //
-        // failed to allocate urb
-        //
-        IoFreeMdl(TransferBufferMDL);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // now initialize the urb
-    //
-    Urb->UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
-    Urb->UrbBulkOrInterruptTransfer.Hdr.Function = 
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
-    Urb->UrbBulkOrInterruptTransfer.PipeHandle = 
FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle;
-    Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL = TransferBufferMDL;
-    Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = DataTransferLength;
-    Urb->UrbBulkOrInterruptTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN 
| USBD_SHORT_TRANSFER_OK;
-
-    //
-    // now send urb
-    //
-    Status = USBSTOR_SyncUrbRequest(FDODeviceExtension->LowerDeviceObject, 
Urb);
-
-    //
-    // free urb
-    //
-    FreeItem(Urb);
-
-    //
-    // free mdl
-    //
-    IoFreeMdl(TransferBufferMDL);
+
+    //
+    // get next stack location
+    //
+    IoStack = IoGetNextIrpStackLocation(Irp);
+
+    //
+    // initialize stack location
+    //
+    IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
+    IoStack->Parameters.DeviceIoControl.IoControlCode = 
IOCTL_INTERNAL_USB_SUBMIT_URB;
+    IoStack->Parameters.Others.Argument1 = (PVOID)&Context->Urb;
+    IoStack->Parameters.DeviceIoControl.InputBufferLength = 
Context->Urb.UrbHeader.Length;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+
+    //
+    // setup completion routine
+    //
+    IoSetCompletionRoutine(Irp, USBSTOR_CBWCompletionRoutine, Context, TRUE, 
TRUE, TRUE);
+
+    if (OriginalRequest)
+    {
+        //
+        // mark orignal irp as pending
+        //
+        IoMarkIrpPending(OriginalRequest);
+    }
+
+    //
+    // call driver
+    //
+    IoCallDriver(FDODeviceExtension->LowerDeviceObject, Irp);
 
     //
     // done
     //
-    return Status;
-}
-
-NTSTATUS
-USBSTOR_SendCSW(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PVOID Data,
-    IN ULONG DataLength,
-    OUT PCSW OutCSW)
-{
-    NTSTATUS Status;
-    PPDO_DEVICE_EXTENSION PDODeviceExtension;
-    PFDO_DEVICE_EXTENSION FDODeviceExtension;
-    PURB Urb;
-
-    //
-    // get PDO device extension
-    //
-    PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    //
-    // get FDO device extension
-    //
-    FDODeviceExtension = 
(PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
-
-    //
-    // now build the urb
-    //
-    Urb = (PURB)AllocateItem(NonPagedPool, sizeof(URB));
-    if (!Urb)
-    {
-        //
-        // failed to allocate urb
-        //
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // now initialize the urb
-    //
-    Urb->UrbBulkOrInterruptTransfer.Hdr.Length = sizeof(URB);
-    Urb->UrbBulkOrInterruptTransfer.Hdr.Function = 
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
-    Urb->UrbBulkOrInterruptTransfer.PipeHandle = 
FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle;
-    Urb->UrbBulkOrInterruptTransfer.TransferBuffer = Data;
-    Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = DataLength;
-    Urb->UrbBulkOrInterruptTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN 
| USBD_SHORT_TRANSFER_OK;
-
-    //
-    // now send urb
-    //
-    Status = USBSTOR_SyncUrbRequest(FDODeviceExtension->LowerDeviceObject, 
Urb);
-
-    if (NT_SUCCESS(Status))
-    {
-        //
-        // copy csw status
-        //
-        RtlCopyMemory(OutCSW, Data, sizeof(CSW));
-    }
-
-    //
-    // free urb
-    //
-    FreeItem(Urb);
-
-    //
-    // done
-    //
-    return Status;
+    return STATUS_PENDING;
 }
 
 NTSTATUS
@@ -294,28 +522,28 @@
     IN PDEVICE_OBJECT DeviceObject)
 {
     UFI_INQUIRY_CMD Cmd;
-    CSW CSW;
     NTSTATUS Status;
+    KEVENT Event;
+    PPDO_DEVICE_EXTENSION PDODeviceExtension;
     PUFI_INQUIRY_RESPONSE Response;
-    PPDO_DEVICE_EXTENSION PDODeviceExtension;
-    PCBW OutControl;
+
+
+    //
+    // allocate inquiry response
+    //
+    Response = AllocateItem(NonPagedPool, PAGE_SIZE);
+    if (!Response)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
     //
     // get PDO device extension
     //
     PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    //
-    // allocate inquiry response
-    //
-    Response = (PUFI_INQUIRY_RESPONSE)AllocateItem(NonPagedPool, 
sizeof(UFI_INQUIRY_RESPONSE));
-    if (!Response)
-    {
-        //
-        // no memory
-        //
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
 
     //
     // initialize inquiry cmd
@@ -326,34 +554,19 @@
     Cmd.AllocationLength = sizeof(UFI_INQUIRY_RESPONSE);
 
     //
-    // now send inquiry cmd
-    //
-    Status = USBSTOR_SendCBW(DeviceObject, UFI_INQUIRY_CMD_LEN, (PUCHAR)&Cmd, 
sizeof(UFI_INQUIRY_RESPONSE), &OutControl);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to send CBW
-        //
-        DPRINT1("USBSTOR_SendInquiryCmd> USBSTOR_SendCBW failed with %x\n", 
Status);
-        FreeItem(Response);
-        ASSERT(FALSE);
-        return Status;
-    }
-
-    //
-    // now send inquiry response
-    //
-    Status = USBSTOR_SendData(DeviceObject, sizeof(UFI_INQUIRY_RESPONSE), 
Response);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to send CBW
-        //
-        DPRINT1("USBSTOR_SendInquiryCmd> USBSTOR_SendData failed with %x\n", 
Status);
-        FreeItem(Response);
-        ASSERT(FALSE);
-        return Status;
-    }
+    // initialize event
+    //
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    //
+    // now send the request
+    //
+    Status = USBSTOR_SendRequest(DeviceObject, NULL, &Event, 
UFI_INQUIRY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_INQUIRY_RESPONSE), 
(PUCHAR)Response);
+
+    //
+    // wait for the action to complete
+    //
+    KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
 
     DPRINT1("Response %p\n", Response);
     DPRINT1("DeviceType %x\n", Response->DeviceType);
@@ -371,6 +584,164 @@
     DPRINT1("Revision %c%c%c%c\n", Response->Revision[0], 
Response->Revision[1], Response->Revision[2], Response->Revision[3]);
 
     //
+    // store inquiry data
+    //
+    PDODeviceExtension->InquiryData = (PVOID)Response;
+
+    //
+    // done
+    //
+    return Status;
+}
+
+NTSTATUS
+USBSTOR_SendCapacityCmd(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    UFI_CAPACITY_CMD Cmd;
+    PUFI_CAPACITY_RESPONSE Response;
+    PPDO_DEVICE_EXTENSION PDODeviceExtension;
+
+    //
+    // get PDO device extension
+    //
+    PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    //
+    // allocate capacity response
+    //
+    Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, 
sizeof(UFI_CAPACITY_RESPONSE));
+    if (!Response)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // initialize capacity cmd
+    //
+    RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
+    Cmd.Code = SCSIOP_READ_CAPACITY;
+    Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
+
+    //
+    // send request, response will be freed in completion routine
+    //
+    return USBSTOR_SendRequest(DeviceObject, Irp, NULL, UFI_INQUIRY_CMD_LEN, 
(PUCHAR)&Cmd, sizeof(UFI_CAPACITY_RESPONSE), (PUCHAR)Response);
+}
+
+NTSTATUS
+USBSTOR_SendModeSenseCmd(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    UFI_SENSE_CMD Cmd;
+    NTSTATUS Status;
+    PVOID Response;
+    PPDO_DEVICE_EXTENSION PDODeviceExtension;
+    PCBW OutControl;
+    PCDB pCDB;
+    PUFI_MODE_PARAMETER_HEADER Header;
+
+    ASSERT(FALSE);
+    return STATUS_NOT_IMPLEMENTED;
+
+#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);
@@ -383,270 +754,6 @@
     DPRINT1("Status %x\n", CSW.Status);
 
     //
-    // free item
-    //
-    FreeItem(OutControl);
-
-    //
-    // store inquiry data
-    //
-    PDODeviceExtension->InquiryData = (PVOID)Response;
-
-    //
-    // FIXME: handle error
-    //
-    ASSERT(CSW.Status == 0);
-
-
-    //
-    // done
-    //
-    return Status;
-}
-
-NTSTATUS
-USBSTOR_SendCapacityCmd(
-    IN PDEVICE_OBJECT DeviceObject,
-    OUT PREAD_CAPACITY_DATA_EX CapacityDataEx,
-    OUT PREAD_CAPACITY_DATA CapacityData)
-{
-    UFI_CAPACITY_CMD Cmd;
-    CSW CSW;
-    NTSTATUS Status;
-    PUFI_CAPACITY_RESPONSE Response;
-    PPDO_DEVICE_EXTENSION PDODeviceExtension;
-    PCBW OutControl;
-
-    //
-    // get PDO device extension
-    //
-    PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    //
-    // allocate capacity response
-    //
-    Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, 
sizeof(UFI_CAPACITY_RESPONSE));
-    if (!Response)
-    {
-        //
-        // no memory
-        //
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // initialize capacity cmd
-    //
-    RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD));
-    Cmd.Code = SCSIOP_READ_CAPACITY;
-    Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
-
-    //
-    // now send capacity cmd
-    //
-    Status = USBSTOR_SendCBW(DeviceObject, UFI_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, 
sizeof(UFI_CAPACITY_RESPONSE), &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 inquiry response
-    //
-    Status = USBSTOR_SendData(DeviceObject, sizeof(UFI_CAPACITY_RESPONSE), 
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;
-    }
-
-    DPRINT1("LastLogicalBlockAddress %lu\n", 
NTOHL(Response->LastLogicalBlockAddress));
-    DPRINT1("BlockLength %lu\n", NTOHL(Response->BlockLength));
-    DPRINT1("Medium Length %lu\n", NTOHL(Response->BlockLength) * 
NTOHL(Response->LastLogicalBlockAddress));
-
-    //
-    // store response
-    //
-    if (CapacityDataEx)
-    {
-        CapacityDataEx->LogicalBlockAddress.QuadPart = 
Response->LastLogicalBlockAddress;
-        CapacityDataEx->BytesPerBlock = Response->BlockLength;
-    }
-    else
-    {
-        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
-    //
-    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);
-
-    //
-    // free item
-    //
-    FreeItem(OutControl);
-
-    //
-    // free response
-    //
-    FreeItem(Response);
-
-    //
-    // done
-    //
-    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;
-    PUFI_MODE_PARAMETER_HEADER Header;
-
-    //
-    // 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);
@@ -676,22 +783,31 @@
     // done
     //
     return Status;
+#endif
 }
 
 NTSTATUS
 USBSTOR_SendReadCmd(
     IN PDEVICE_OBJECT DeviceObject,
-    IN OUT PSCSI_REQUEST_BLOCK Request,
-    OUT PULONG TransferBufferLength)
+    IN PIRP Irp)
 {
     UFI_READ_CMD Cmd;
-    CSW CSW;
     NTSTATUS Status;
-    PVOID Response;
     PPDO_DEVICE_EXTENSION PDODeviceExtension;
-    PCBW OutControl;
     PCDB pCDB;
     ULONG BlockCount;
+    PIO_STACK_LOCATION IoStack;
+    PSCSI_REQUEST_BLOCK Request;
+
+    //
+    // get current stack location
+    //
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    //
+    // get request block
+    //
+    Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
 
     //
     // get SCSI command data block
@@ -704,18 +820,6 @@
     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);
@@ -726,7 +830,7 @@
     BlockCount = Request->DataTransferLength / PDODeviceExtension->BlockLength;
 
     //
-    // initialize read sense cmd
+    // initialize read cmd
     //
     RtlZeroMemory(&Cmd, sizeof(UFI_READ_CMD));
     Cmd.Code = SCSIOP_READ;
@@ -738,95 +842,40 @@
     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;
+    // send request
+    //
+    return USBSTOR_SendRequest(DeviceObject, Irp, NULL, UFI_READ_CMD_LEN, 
(PUCHAR)&Cmd, Request->DataTransferLength, (PUCHAR)Request->DataBuffer);
 }
 
 NTSTATUS
 USBSTOR_SendTestUnitCmd(
     IN PDEVICE_OBJECT DeviceObject,
-    IN OUT PSCSI_REQUEST_BLOCK Request)
+    IN OUT PIRP Irp)
 {
     UFI_TEST_UNIT_CMD Cmd;
-    CSW CSW;
-    NTSTATUS Status;
-    PVOID Response;
     PPDO_DEVICE_EXTENSION PDODeviceExtension;
-    PCBW OutControl;
-    PCDB pCDB;
-    ULONG BlockCount;
+    PIO_STACK_LOCATION IoStack;
+    PSCSI_REQUEST_BLOCK Request;
+
+    //
+    // get current stack location
+    //
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    //
+    // get request block
+    //
+    Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
+
+    //
+    // no transfer length
+    //
+    ASSERT(Request->DataTransferLength == 0);
+
+    //
+    // get PDO device extension
+    //
+    PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
     //
     // initialize test unit cmd
@@ -836,54 +885,7 @@
     Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN);
 
     //
-    // no data should be transferred
-    //
-    ASSERT(Request->DataTransferLength == 0);
-
-    //
-    // now send test unit cmd
-    //
-    Status = USBSTOR_SendCBW(DeviceObject, UFI_TEST_UNIT_CMD_LEN, 
(PUCHAR)&Cmd, 0, &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;
-    }
-
-    //
-    // 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);
-
-    //
-    // free item
-    //
-    FreeItem(OutControl);
-
-    //
-    // FIXME: read sense buffer
-    //
-
-    //
-    // done
-    //
-    return Status;
-}
+    // send the request
+    //
+    return USBSTOR_SendRequest(DeviceObject, Irp, NULL, UFI_TEST_UNIT_CMD_LEN, 
(PUCHAR)&Cmd, 0, NULL);
+}

Modified: branches/usb-bringup/drivers/usb/usbstor/usbstor.c
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor/usbstor.c?rev=51673&r1=51672&r2=51673&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/usbstor.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/usbstor.c [iso-8859-1] Wed May 11 
03:49:15 2011
@@ -165,11 +165,7 @@
     //
     // handle requests
     //
-    Status = USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
-
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return Status;
+    return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
 }
 
 NTSTATUS

Modified: branches/usb-bringup/drivers/usb/usbstor/usbstor.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor/usbstor.h?rev=51673&r1=51672&r2=51673&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/usbstor.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/usbstor.h [iso-8859-1] Wed May 11 
03:49:15 2011
@@ -250,6 +250,25 @@
 
 #define UFI_TEST_UNIT_CMD_LEN (6)
 
+typedef struct
+{
+    union
+    {
+        PCBW cbw;
+        PCSW csw;
+    };
+    URB Urb;
+    PIRP Irp;
+    ULONG TransferDataLength;
+    PUCHAR TransferData;
+    PFDO_DEVICE_EXTENSION FDODeviceExtension;
+    PPDO_DEVICE_EXTENSION PDODeviceExtension;
+    PMDL TransferBufferMDL;
+    PKEVENT Event;
+}IRP_CONTEXT, *PIRP_CONTEXT;
+
+
+
 //---------------------------------------------------------------------
 //
 // fdo.c routines
@@ -345,26 +364,22 @@
 NTSTATUS
 USBSTOR_SendCapacityCmd(
     IN PDEVICE_OBJECT DeviceObject,
-    OUT PREAD_CAPACITY_DATA_EX CapacityDataEx,
-    OUT PREAD_CAPACITY_DATA CapacityData);
+    IN PIRP Irp);
 
 NTSTATUS
 USBSTOR_SendModeSenseCmd(
     IN PDEVICE_OBJECT DeviceObject,
-    IN OUT PSCSI_REQUEST_BLOCK Request,
-    OUT PULONG TransferBufferLength);
+    IN PIRP Irp);
 
 NTSTATUS
 USBSTOR_SendReadCmd(
     IN PDEVICE_OBJECT DeviceObject,
-    IN OUT PSCSI_REQUEST_BLOCK Request,
-    OUT PULONG TransferBufferLength);
+    IN PIRP Irp);
 
 NTSTATUS
 USBSTOR_SendTestUnitCmd(
     IN PDEVICE_OBJECT DeviceObject,
-    IN OUT PSCSI_REQUEST_BLOCK Request);
-
+    IN PIRP Irp);
 
 //---------------------------------------------------------------------
 //


Reply via email to