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