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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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