diff --git a/drivers/usb/usbstor/disk.c b/drivers/usb/usbstor/disk.c index 6e4fa0d55d9..b9c1a42905e 100644 --- a/drivers/usb/usbstor/disk.c +++ b/drivers/usb/usbstor/disk.c @@ -175,9 +175,9 @@ USBSTOR_HandleInternalDeviceControl( DPRINT1("SRB_FUNCTION_FLUSH / SRB_FUNCTION_FLUSH_QUEUE / SRB_FUNCTION_SHUTDOWN\n"); // - // flush all requests + // wait for pending requests to finish // - USBSTOR_QueueFlushIrps(PDODeviceExtension->LowerDeviceObject); + USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject); // // set status success diff --git a/drivers/usb/usbstor/queue.c b/drivers/usb/usbstor/queue.c index 63fa53447e6..f31b62bb204 100644 --- a/drivers/usb/usbstor/queue.c +++ b/drivers/usb/usbstor/queue.c @@ -176,12 +176,18 @@ USBSTOR_QueueAddIrp( // 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,16 +302,10 @@ USBSTOR_RemoveIrp( } 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 @@ -313,88 +313,13 @@ USBSTOR_QueueFlushIrps( FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // - // sanity check + // perform the wait // - 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); + KeWaitForSingleObject(&FDODeviceExtension->NoPendingRequests, + Executive, + KernelMode, + FALSE, + NULL); } VOID @@ -438,6 +363,15 @@ USBSTOR_QueueTerminateRequest( 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); + } + // // release lock // diff --git a/drivers/usb/usbstor/usbstor.h b/drivers/usb/usbstor/usbstor.h index e265067acac..7c0e0d4e84e 100644 --- a/drivers/usb/usbstor/usbstor.h +++ b/drivers/usb/usbstor/usbstor.h @@ -67,6 +67,7 @@ typedef struct 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 @@ USBSTOR_StartIo( PIRP Irp); VOID -USBSTOR_QueueFlushIrps( +USBSTOR_QueueWaitForPendingRequests( IN PDEVICE_OBJECT DeviceObject); VOID