mirror of
https://github.com/reactos/reactos.git
synced 2024-07-03 19:24:20 +00:00
[USBSTOR]
- Fix handling of SRB_FUNCTION_FLUSH and SRB_FUNCTION_SHUTDOWN to prevent data loss svn path=/branches/usb-bringup-trunk/; revision=55350
This commit is contained in:
parent
47e18d8e47
commit
823a29d5e3
|
@ -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
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue