Author: cgutman
Date: Tue Jan 31 15:33:32 2012
New Revision: 55350

URL: http://svn.reactos.org/svn/reactos?rev=55350&view=rev
Log:
[USBSTOR]
- Fix handling of SRB_FUNCTION_FLUSH and SRB_FUNCTION_SHUTDOWN to prevent data 
loss

Modified:
    branches/usb-bringup-trunk/drivers/usb/usbstor/disk.c
    branches/usb-bringup-trunk/drivers/usb/usbstor/queue.c
    branches/usb-bringup-trunk/drivers/usb/usbstor/usbstor.h

Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/disk.c
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbstor/disk.c?rev=55350&r1=55349&r2=55350&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbstor/disk.c [iso-8859-1] 
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbstor/disk.c [iso-8859-1] Tue Jan 
31 15:33:32 2012
@@ -175,9 +175,9 @@
             DPRINT1("SRB_FUNCTION_FLUSH / SRB_FUNCTION_FLUSH_QUEUE / 
SRB_FUNCTION_SHUTDOWN\n");
 
             //
-            // flush all requests
-            //
-            USBSTOR_QueueFlushIrps(PDODeviceExtension->LowerDeviceObject);
+            // wait for pending requests to finish
+            //
+            
USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject);
 
             //
             // set status success

Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/queue.c
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbstor/queue.c?rev=55350&r1=55349&r2=55350&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbstor/queue.c [iso-8859-1] 
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbstor/queue.c [iso-8859-1] Tue Jan 
31 15:33:32 2012
@@ -176,12 +176,18 @@
         // add irp to queue
         //
         InsertTailList(&FDODeviceExtension->IrpListHead, 
&Irp->Tail.Overlay.ListEntry);
-   }
-
-   //
-   // increment pending count
-   //
-   FDODeviceExtension->IrpPendingCount++;
+    }
+
+    //
+    // increment pending count
+    //
+    FDODeviceExtension->IrpPendingCount++;
+
+
+    //
+    // clear the no requests pending event
+    //
+    KeClearEvent(&FDODeviceExtension->NoPendingRequests);
 
     //
     // check if queue is freezed
@@ -296,105 +302,24 @@
 }
 
 VOID
-USBSTOR_QueueFlushIrps(
+USBSTOR_QueueWaitForPendingRequests(
     IN PDEVICE_OBJECT DeviceObject)
 {
-    KIRQL OldLevel;
-    PFDO_DEVICE_EXTENSION FDODeviceExtension;
-    PLIST_ENTRY Entry;
-    PIRP Irp;
-    PIO_STACK_LOCATION IoStack;
-    PSCSI_REQUEST_BLOCK Request;
-    KIRQL OldIrql;
-
-    //
-    // get FDO device extension
-    //
-    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    //
-    // sanity check
-    //
-    ASSERT(FDODeviceExtension->Common.IsFDO);
-
-    //
-    // acquire lock
-    //
-    KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
-
-    //
-    // complete all irps with status cancelled
-    // 
-    while(!IsListEmpty(&FDODeviceExtension->IrpListHead))
-    {
-        //
-        // remove irp
-        //
-        Entry = RemoveHeadList(&FDODeviceExtension->IrpListHead);
-
-        //
-        // get start of irp structure
-        //
-        Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
-
-        //
-        // remove the cancellation routine
-        //
-        IoAcquireCancelSpinLock(&OldIrql);
-        (void)IoSetCancelRoutine(Irp, NULL);
-        IoReleaseCancelSpinLock(OldIrql);
-
-        //
-        // get current stack location
-        //
-        IoStack = IoGetCurrentIrpStackLocation(Irp);
-
-        //
-        // get request block
-        //
-        Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
-
-        //
-        // sanity check
-        //
-        ASSERT(Request);
-
-        //
-        // set srb status to flushed
-        //
-        Request->SrbStatus = SRB_STATUS_REQUEST_FLUSHED;
-
-        //
-        // set unsuccessful status
-        //
-        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-
-        //
-        // release lock
-        //
-        KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
-
-        //
-        // complete request
-        //
-        USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        
-        //
-        // start next one
-        //
-        USBSTOR_QueueNextRequest(DeviceObject);
-
-        //
-        // acquire lock
-        //
-        KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
-    }
-
-    //
-    // release lock
-    //
-    KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
+    PFDO_DEVICE_EXTENSION FDODeviceExtension;
+
+    //
+    // get FDO device extension
+    //
+    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    //
+    // perform the wait
+    //
+    KeWaitForSingleObject(&FDODeviceExtension->NoPendingRequests,
+                          Executive,
+                          KernelMode,
+                          FALSE,
+                          NULL);
 }
 
 VOID
@@ -436,6 +361,15 @@
         // indicate processing is completed
         //
         FDODeviceExtension->ActiveSrb = NULL;
+    }
+
+    //
+    // Set the event if nothing else is pending
+    //
+    if (FDODeviceExtension->IrpPendingCount == 0 &&
+        FDODeviceExtension->ActiveSrb == NULL)
+    {
+        KeSetEvent(&FDODeviceExtension->NoPendingRequests, IO_NO_INCREMENT, 
FALSE);
     }
 
     //

Modified: branches/usb-bringup-trunk/drivers/usb/usbstor/usbstor.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbstor/usbstor.h?rev=55350&r1=55349&r2=55350&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbstor/usbstor.h [iso-8859-1] 
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbstor/usbstor.h [iso-8859-1] Tue 
Jan 31 15:33:32 2012
@@ -67,6 +67,7 @@
     BOOLEAN ResetInProgress;                                                   
          // if hard reset is in progress
     ULONG IrpPendingCount;                                                     
          // count of irp pending
     PSCSI_REQUEST_BLOCK ActiveSrb;                                             
          // stores the current active SRB
+    KEVENT NoPendingRequests;                                                  
          // set if no pending or in progress requests
 }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
 
 typedef struct
@@ -405,7 +406,7 @@
     PIRP Irp);
 
 VOID
-USBSTOR_QueueFlushIrps(
+USBSTOR_QueueWaitForPendingRequests(
     IN PDEVICE_OBJECT DeviceObject);
 
 VOID


Reply via email to