[USBSTOR] Do not try to retry a failed request
[reactos.git] / drivers / usb / usbstor / error.c
index 984a60b..571c89d 100644 (file)
@@ -1,12 +1,10 @@
 /*
  * PROJECT:     ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE:     GPL - See COPYING in the top level directory
- * FILE:        drivers/usb/usbstor/error.c
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
  * PURPOSE:     USB block storage device driver.
- * PROGRAMMERS:
- *              James Tabor
- *              Michael Martin (michael.martin@reactos.org)
- *              Johannes Anderwald (johannes.anderwald@reactos.org)
+ * COPYRIGHT:   2005-2006 James Tabor
+ *              2011-2012 Michael Martin (michael.martin@reactos.org)
+ *              2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
  */
 
 #include "usbstor.h"
@@ -14,6 +12,7 @@
 #define NDEBUG
 #include <debug.h>
 
+
 NTSTATUS
 USBSTOR_GetEndpointStatus(
     IN PDEVICE_OBJECT DeviceObject,
@@ -23,44 +22,25 @@ USBSTOR_GetEndpointStatus(
     PURB Urb;
     NTSTATUS Status;
 
-    //
-    // allocate urb
-    //
     DPRINT("Allocating URB\n");
     Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
     if (!Urb)
     {
-        //
-        // out of memory
-        //
         DPRINT1("OutofMemory!\n");
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    //
     // build status
-    //
-   UsbBuildGetStatusRequest(Urb, URB_FUNCTION_GET_STATUS_FROM_ENDPOINT, bEndpointAddress & 0x0F, Value, NULL, NULL);
+    UsbBuildGetStatusRequest(Urb, URB_FUNCTION_GET_STATUS_FROM_ENDPOINT, bEndpointAddress & 0x0F, Value, NULL, NULL);
 
-    //
     // send the request
-    //
     DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
     Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
 
-    //
-    // free urb
-    //
     FreeItem(Urb);
-
-    //
-    // done
-    //
     return Status;
 }
 
-
-
 NTSTATUS
 USBSTOR_ResetPipeWithHandle(
     IN PDEVICE_OBJECT DeviceObject,
@@ -69,156 +49,84 @@ USBSTOR_ResetPipeWithHandle(
     PURB Urb;
     NTSTATUS Status;
 
-    //
-    // allocate urb
-    //
     DPRINT("Allocating URB\n");
     Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
     if (!Urb)
     {
-        //
-        // out of memory
-        //
         DPRINT1("OutofMemory!\n");
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    //
-    // initialize the urb
-    //
     Urb->UrbPipeRequest.Hdr.Length = sizeof(struct _URB_PIPE_REQUEST);
     Urb->UrbPipeRequest.Hdr.Function = URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL;
     Urb->UrbPipeRequest.PipeHandle = PipeHandle;
 
-    //
     // send the request
-    //
     DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
     Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
 
-    //
-    // free urb
-    //
     FreeItem(Urb);
-
-    //
-    // done
-    //
     return Status;
 }
 
-
 NTSTATUS
 USBSTOR_HandleTransferError(
     PDEVICE_OBJECT DeviceObject,
     PIRP_CONTEXT Context)
 {
+    PPDO_DEVICE_EXTENSION PDODeviceExtension;
     NTSTATUS Status = STATUS_SUCCESS;
     PIO_STACK_LOCATION Stack;
     PSCSI_REQUEST_BLOCK Request;
     PCDB pCDB;
 
-    //
-    // sanity checks
-    //
     ASSERT(Context);
-    ASSERT(Context->PDODeviceExtension);
-    ASSERT(Context->PDODeviceExtension->Self);
     ASSERT(Context->Irp);
 
-    //
     // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
-    //
     Status = USBSTOR_ResetDevice(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension);
     if (NT_SUCCESS(Status))
     {
-        //
         // step 2 reset bulk in pipe section 5.3.4
-        //
         Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
         if (NT_SUCCESS(Status))
         {
-            //
             // finally reset bulk out pipe
-            //
             Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
         }
     }
 
-    //
-    // get next stack location
-    //
     Stack = IoGetCurrentIrpStackLocation(Context->Irp);
+    ASSERT(Stack->DeviceObject);
+    PDODeviceExtension = (PPDO_DEVICE_EXTENSION)Stack->DeviceObject->DeviceExtension;
 
-    //
-    // get request block
-    //
     Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
     ASSERT(Request);
 
-    //
     // obtain request type
-    //
     pCDB = (PCDB)Request->Cdb;
     ASSERT(pCDB);
 
-    if (Status != STATUS_SUCCESS || Context->RetryCount >= 1)
+    if (!NT_SUCCESS(Status))
     {
-        //
         // Complete the master IRP
-        //
         Context->Irp->IoStatus.Status = Status;
         Context->Irp->IoStatus.Information = 0;
-        USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
+        USBSTOR_QueueTerminateRequest(PDODeviceExtension->LowerDeviceObject, Context->Irp);
         IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
 
-        //
         // Start the next request
-        //
-        USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
+        USBSTOR_QueueNextRequest(PDODeviceExtension->LowerDeviceObject);
 
-        //
         // srb handling finished
-        //
         Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
 
-        //
         // clear timer srb
-        //
         Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
     }
-    else
-    {
-        DPRINT1("Retrying Count %lu %p\n", Context->RetryCount, Context->PDODeviceExtension->Self);
-
-        //
-        // re-schedule request
-        //
-        USBSTOR_HandleExecuteSCSI(Context->PDODeviceExtension->Self, Context->Irp, Context->RetryCount + 1);
-
-        //
-        // srb error handling finished
-        //
-        Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
 
-        //
-        // srb error handling finished
-        //
-        Context->FDODeviceExtension->TimerWorkQueueEnabled = TRUE;
-
-        //
-        // clear timer srb
-        //
-        Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
-    }
-
-    //
-    // cleanup irp context
-    //
-    FreeItem(Context->cbw);
     FreeItem(Context);
 
-
     DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status);
     return Status;
 }
@@ -231,16 +139,12 @@ USBSTOR_ResetHandlerWorkItemRoutine(
     NTSTATUS Status;
     PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
 
-    //
     // clear stall on BulkIn pipe
-    //
     Status = USBSTOR_ResetPipeWithHandle(WorkItemData->Context->FDODeviceExtension->LowerDeviceObject, WorkItemData->Context->FDODeviceExtension->InterfaceInformation->Pipes[WorkItemData->Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
     DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status);
 
-    //
     // now resend the csw as the stall got cleared
-    //
-    USBSTOR_SendCSW(WorkItemData->Context, WorkItemData->Irp);
+    USBSTOR_SendCSWRequest(WorkItemData->Context, WorkItemData->Irp);
 }
 
 VOID
@@ -252,23 +156,17 @@ ErrorHandlerWorkItemRoutine(
 
     if (WorkItemData->Context->ErrorIndex == 2)
     {
-        //
         // reset device
-        //
         USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context);
     }
     else
     {
-        //
         // clear stall
-        //
         USBSTOR_ResetHandlerWorkItemRoutine(WorkItemData);
     }
 
-    //
     // Free Work Item Data
-    //
-    ExFreePool(WorkItemData);
+    ExFreePoolWithTag(WorkItemData, USB_STOR_TAG);
 }
 
 VOID
@@ -280,56 +178,35 @@ USBSTOR_TimerWorkerRoutine(
     NTSTATUS Status;
     PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
 
-    //
-    // get device extension
-    //
     FDODeviceExtension = (PFDO_DEVICE_EXTENSION)WorkItemData->DeviceObject->DeviceExtension;
     ASSERT(FDODeviceExtension->Common.IsFDO);
 
-    //
     // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
-    //
     Status = USBSTOR_ResetDevice(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension);
     if (NT_SUCCESS(Status))
     {
-        //
         // step 2 reset bulk in pipe section 5.3.4
-        //
         Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle);
         if (NT_SUCCESS(Status))
         {
-            //
             // finally reset bulk out pipe
-            //
             Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
         }
     }
     DPRINT1("Status %x\n", Status);
 
-    //
     // clear timer srb
-    //
     FDODeviceExtension->LastTimerActiveSrb = NULL;
 
-    //
     // re-schedule request
-    //
     //USBSTOR_HandleExecuteSCSI(WorkItemData->Context->PDODeviceExtension->Self, WorkItemData->Context->Irp, Context->RetryCount + 1);
 
-
-
-    //
     // do not retry for the same packet again
-    //
     FDODeviceExtension->TimerWorkQueueEnabled = FALSE;
 
-    //
-    // Free Work Item Data
-    //
-    ExFreePool(WorkItemData);
+    ExFreePoolWithTag(WorkItemData, USB_STOR_TAG);
 }
 
-
 VOID
 NTAPI
 USBSTOR_TimerRoutine(
@@ -340,61 +217,44 @@ USBSTOR_TimerRoutine(
     BOOLEAN ResetDevice = FALSE;
     PERRORHANDLER_WORKITEM_DATA WorkItemData;
 
-    //
-    // get device extension
-    //
     FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
     DPRINT1("[USBSTOR] TimerRoutine entered\n");
     DPRINT1("[USBSTOR] ActiveSrb %p ResetInProgress %x LastTimerActiveSrb %p\n", FDODeviceExtension->ActiveSrb, FDODeviceExtension->ResetInProgress, FDODeviceExtension->LastTimerActiveSrb);
 
-    //
-    // acquire spinlock
-    //
     KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
 
-    //
     // is there an active srb and no global reset is in progress
-    //
     if (FDODeviceExtension->ActiveSrb && FDODeviceExtension->ResetInProgress == FALSE && FDODeviceExtension->TimerWorkQueueEnabled)
     {
         if (FDODeviceExtension->LastTimerActiveSrb != NULL && FDODeviceExtension->LastTimerActiveSrb == FDODeviceExtension->ActiveSrb)
         {
-            //
             // check if empty
-            //
             DPRINT1("[USBSTOR] ActiveSrb %p hang detected\n", FDODeviceExtension->ActiveSrb);
             ResetDevice = TRUE;
         }
         else
         {
-            //
             // update pointer
-            //
             FDODeviceExtension->LastTimerActiveSrb = FDODeviceExtension->ActiveSrb;
         }
     }
     else
     {
-        //
         // reset srb
-        //
         FDODeviceExtension->LastTimerActiveSrb = NULL;
     }
 
-    //
-    // release lock
-    //
     KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock);
 
 
     if (ResetDevice && FDODeviceExtension->TimerWorkQueueEnabled && FDODeviceExtension->SrbErrorHandlingActive == FALSE)
     {
-        WorkItemData = (PERRORHANDLER_WORKITEM_DATA)ExAllocatePool(NonPagedPool, sizeof(ERRORHANDLER_WORKITEM_DATA));
+        WorkItemData = ExAllocatePoolWithTag(NonPagedPool,
+                                             sizeof(ERRORHANDLER_WORKITEM_DATA),
+                                             USB_STOR_TAG);
         if (WorkItemData)
         {
-           //
            // Initialize and queue the work item to handle the error
-           //
            ExInitializeWorkItem(&WorkItemData->WorkQueueItem,
                                  USBSTOR_TimerWorkerRoutine,
                                  WorkItemData);