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/us... ============================================================================== --- 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/us... ============================================================================== --- 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/us... ============================================================================== --- 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