[USBSTOR]
[reactos.git] / drivers / usb / usbstor / scsi.c
index cc58623..5e80749 100644 (file)
@@ -181,18 +181,9 @@ USBSTOR_CSWCompletionRoutine(
             {
                 DPRINT1("Attempting Error Recovery\n");
                 //
-                // If a Read Capacity Request free TransferBuffer
+                // free the allocated irp
                 //
-                if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
-                {
-                    FreeItem(Context->TransferData);
-                }
-
-                //
-                // Clean up the rest
-                //
-                FreeItem(Context->cbw);
-                FreeItem(Context);
+                IoFreeIrp(Irp);
 
                 //
                 // Allocate Work Item Data
@@ -213,7 +204,6 @@ USBSTOR_CSWCompletionRoutine(
                                         ErrorHandlerWorkItemData);
     
                     ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject;
-                    ErrorHandlerWorkItemData->Irp = Irp;
                     ErrorHandlerWorkItemData->Context = Context;
                     DPRINT1("Queuing WorkItemROutine\n");
                     ExQueueWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, DelayedWorkQueue);
@@ -292,14 +282,14 @@ USBSTOR_CSWCompletionRoutine(
         Context->Irp->IoStatus.Information = Context->TransferDataLength;
 
         //
-        // complete request
+        // terminate current request
         //
-        IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
+        USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
 
         //
-        // terminate current request
+        // complete request
         //
-        USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, TRUE);
+        IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
 
         //
         // start next request
@@ -315,6 +305,10 @@ USBSTOR_CSWCompletionRoutine(
         KeSetEvent(Context->Event, 0, FALSE);
     }
 
+    //
+    // free our allocated irp
+    //
+    IoFreeIrp(Irp);
 
     //
     // free context
@@ -453,7 +447,7 @@ USBSTOR_CBWCompletionRoutine(
                                                NULL,
                                                Context->TransferBufferMDL,
                                                Context->TransferDataLength,
-                                               USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
+                                               ((Code == SCSIOP_WRITE) ? USBD_TRANSFER_DIRECTION_OUT : USBD_TRANSFER_DIRECTION_IN) | USBD_SHORT_TRANSFER_OK,
                                                NULL);
 
         //
@@ -576,7 +570,7 @@ USBSTOR_SendRequest(
     if (Context->TransferDataLength)
     {
         //
-        // check if the original request already does not have an mdl associated
+        // check if the original request already does have an mdl associated
         //
         if (OriginalRequest)
         {
@@ -589,13 +583,38 @@ USBSTOR_SendRequest(
                 if (CommandLength == UFI_READ_WRITE_CMD_LEN)
                 {
                     MdlVirtualAddress = MmGetMdlVirtualAddress(OriginalRequest->MdlAddress);
-                    ASSERT(MdlVirtualAddress == Context->TransferData);
+
+                    //
+                    // is there an offset
+                    //
+                    if (MdlVirtualAddress != Context->TransferData)
+                    {
+                        //
+                        // lets build an mdl
+                        //
+                        Context->TransferBufferMDL = IoAllocateMdl(Context->TransferData, MmGetMdlByteCount(OriginalRequest->MdlAddress), FALSE, FALSE, NULL);
+                        if (!Context->TransferBufferMDL)
+                        {
+                            //
+                            // failed to allocate MDL
+                            //
+                            return STATUS_INSUFFICIENT_RESOURCES;
+                        }
+
+                        //
+                        // now build the partial mdl
+                        //
+                        IoBuildPartialMdl(OriginalRequest->MdlAddress, Context->TransferBufferMDL, Context->TransferData, Context->TransferDataLength);
+                    }
                 }
 
-                //
-                // I/O paging request
-                //
-                Context->TransferBufferMDL = OriginalRequest->MdlAddress;
+                if (!Context->TransferBufferMDL)
+                {
+                    //
+                    // I/O paging request
+                    //
+                    Context->TransferBufferMDL = OriginalRequest->MdlAddress;
+                }
             }
             else
             {
@@ -820,6 +839,16 @@ USBSTOR_SendModeSenseCmd(
     PIO_STACK_LOCATION IoStack;
     PSCSI_REQUEST_BLOCK Request;
 
+    //
+    // get PDO device extension
+    //
+    PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    //
+    // sanity check
+    //
+    ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
+
     //
     // get current stack location
     //
@@ -834,23 +863,9 @@ USBSTOR_SendModeSenseCmd(
     Request->SrbStatus = SRB_STATUS_SUCCESS;
     Irp->IoStatus.Information = Request->DataTransferLength;
     Irp->IoStatus.Status = STATUS_SUCCESS;
+    USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-    //
-    // get PDO device extension
-    //
-    PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    //
-    // sanity check
-    //
-    ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
-
-    //
-    // terminate current request
-    //
-    USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, TRUE);
-
     //
     // start next request
     //
@@ -1185,13 +1200,9 @@ USBSTOR_HandleExecuteSCSI(
         Request->SrbStatus = SRB_STATUS_SUCCESS;
         Irp->IoStatus.Status = STATUS_SUCCESS;
         Irp->IoStatus.Information = Request->DataTransferLength;
+        USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Irp);
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-        //
-        // terminate current request
-        //
-        USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, TRUE);
-
         //
         // start next request
         //
@@ -1210,7 +1221,7 @@ USBSTOR_HandleExecuteSCSI(
     }
     else
     {
-        UNIMPLEMENTED;
+        DPRINT1("UNIMPLEMENTED Operation Code %x\n", pCDB->AsByte[0]);
         Request->SrbStatus = SRB_STATUS_ERROR;
         Status = STATUS_NOT_SUPPORTED;
         DbgBreakPoint();