Author: cgutman
Date: Tue Jan 24 04:39:09 2012
New Revision: 55138

URL: http://svn.reactos.org/svn/reactos?rev=55138&view=rev
Log:
[USBSTOR]
- Fix cancellation for IRPs that have already been dispatched for processing by 
IoStartNextPacket
- Don't complete IRPs with the IRP list lock held
- Clear the cancel routine before completing the IRP

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

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=55138&r1=55137&r2=55138&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 
24 04:39:09 2012
@@ -51,6 +51,45 @@
     ASSERT(FDODeviceExtension->Common.IsFDO);
 
     //
+    // this IRP isn't in our list here
+    //  
+
+    //
+    // now release the cancel lock
+    //
+    IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+    //
+    // set cancel status
+    //
+    Irp->IoStatus.Status = STATUS_CANCELLED;
+
+    //
+    // now cancel the irp
+    //
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}
+
+VOID
+NTAPI
+USBSTOR_Cancel(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp)
+{
+    PFDO_DEVICE_EXTENSION FDODeviceExtension;
+
+    //
+    // get FDO device extension
+    //
+    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    //
+    // sanity check
+    //
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    ASSERT(FDODeviceExtension->Common.IsFDO);
+
+    //
     // acquire irp list lock
     //
     KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
@@ -80,7 +119,6 @@
     //
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 }
-
 
 BOOLEAN
 USBSTOR_QueueAddIrp(
@@ -149,7 +187,14 @@
     //
     // now set the driver cancel routine
     //
-    OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo);
+    if (SrbProcessing)
+    {
+        OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_Cancel);
+    }
+    else
+    {
+        OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo);
+    }
 
     //
     // check if the irp has already been cancelled
@@ -159,7 +204,7 @@
         //
         // cancel irp
         //
-        USBSTOR_CancelIo(DeviceObject, Irp);
+        Irp->CancelRoutine(DeviceObject, Irp);
 
         //
         // irp was cancelled
@@ -241,6 +286,7 @@
     PIRP Irp;
     PIO_STACK_LOCATION IoStack;
     PSCSI_REQUEST_BLOCK Request;
+    KIRQL OldIrql;
 
     //
     // get FDO device extension
@@ -273,6 +319,13 @@
         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);
@@ -298,15 +351,20 @@
         Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
 
         //
+        // release lock
+        //
+        KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
+
+        //
         // complete request
         //
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    }
-
-    //
-    // release lock
-    //
-    KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
+        
+        //
+        // acquire lock
+        //
+        KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
+    }
 }
 
 VOID


Reply via email to