[USBSTOR]
authorCameron Gutman <aicommander@gmail.com>
Tue, 24 Jan 2012 04:39:09 +0000 (04:39 +0000)
committerCameron Gutman <aicommander@gmail.com>
Tue, 24 Jan 2012 04:39:09 +0000 (04:39 +0000)
- 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

svn path=/branches/usb-bringup-trunk/; revision=55138

drivers/usb/usbstor/queue.c

index 11e87ab..9d42e9f 100644 (file)
@@ -50,6 +50,45 @@ USBSTOR_CancelIo(
     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
     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
     //
@@ -81,7 +120,6 @@ USBSTOR_CancelIo(
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 }
 
-
 BOOLEAN
 USBSTOR_QueueAddIrp(
     IN PDEVICE_OBJECT DeviceObject,
@@ -149,7 +187,14 @@ USBSTOR_QueueAddIrp(
     //
     // 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 @@ USBSTOR_QueueAddIrp(
         //
         // cancel irp
         //
-        USBSTOR_CancelIo(DeviceObject, Irp);
+        Irp->CancelRoutine(DeviceObject, Irp);
 
         //
         // irp was cancelled
@@ -241,6 +286,7 @@ USBSTOR_QueueFlushIrps(
     PIRP Irp;
     PIO_STACK_LOCATION IoStack;
     PSCSI_REQUEST_BLOCK Request;
+    KIRQL OldIrql;
 
     //
     // get FDO device extension
@@ -272,6 +318,13 @@ USBSTOR_QueueFlushIrps(
         //
         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
         //
@@ -297,16 +350,21 @@ USBSTOR_QueueFlushIrps(
         //
         Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
 
+        //
+        // release lock
+        //
+        KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
+
         //
         // complete request
         //
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        
+        //
+        // acquire lock
+        //
+        KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
     }
-
-    //
-    // release lock
-    //
-    KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
 }
 
 VOID