/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/usb/usbstor/queue.c
+ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: USB block storage device driver.
- * PROGRAMMERS:
- * James Tabor
- * Michael Martin (michael.martin@reactos.org)
- * Johannes Anderwald (johannes.anderwald@reactos.org)
+ * COPYRIGHT: 2005-2006 James Tabor
+ * 2011-2012 Michael Martin (michael.martin@reactos.org)
+ * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbstor.h"
+#define NDEBUG
+#include <debug.h>
+
+
VOID
USBSTOR_QueueInitialize(
PFDO_DEVICE_EXTENSION FDODeviceExtension)
{
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
-
- //
- // initialize queue lock
- //
KeInitializeSpinLock(&FDODeviceExtension->IrpListLock);
-
- //
- // initialize irp list head
- //
InitializeListHead(&FDODeviceExtension->IrpListHead);
-
- //
- // initialize event
- //
KeInitializeEvent(&FDODeviceExtension->NoPendingRequests, NotificationEvent, TRUE);
}
{
PFDO_DEVICE_EXTENSION FDODeviceExtension;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+ ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
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
- //
USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- //
- // start the next one
- //
USBSTOR_QueueNextRequest(DeviceObject);
}
{
PFDO_DEVICE_EXTENSION FDODeviceExtension;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+ ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire irp list lock
- //
KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
-
- //
- // remove the irp from the list
- //
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
-
- //
- // release irp list lock
- //
KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock);
- //
- // now release the cancel lock
- //
IoReleaseCancelSpinLock(Irp->CancelIrql);
-
- //
- // set cancel status
- //
Irp->IoStatus.Status = STATUS_CANCELLED;
- //
- // now cancel the irp
- //
USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- //
- // start the next one
- //
USBSTOR_QueueNextRequest(DeviceObject);
}
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // mark irp pending
- //
IoMarkIrpPending(Irp);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
- // check if there are irp pending
- //
SrbProcessing = FDODeviceExtension->IrpPendingCount != 0;
if (SrbProcessing)
{
- //
// add irp to queue
- //
InsertTailList(&FDODeviceExtension->IrpListHead, &Irp->Tail.Overlay.ListEntry);
}
- //
- // increment pending count
- //
FDODeviceExtension->IrpPendingCount++;
-
-
- //
- // clear the no requests pending event
- //
KeClearEvent(&FDODeviceExtension->NoPendingRequests);
- //
// check if queue is freezed
- //
IrpListFreeze = FDODeviceExtension->IrpListFreeze;
- //
- // release list lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
- //
// synchronize with cancellations by holding the cancel lock
- //
IoAcquireCancelSpinLock(&Irp->CancelIrql);
- //
- // now set the driver cancel routine
- //
if (SrbProcessing)
{
ASSERT(FDODeviceExtension->ActiveSrb != NULL);
OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo);
}
- //
// check if the irp has already been cancelled
- //
if (Irp->Cancel && OldDriverCancel == NULL)
{
- //
// cancel irp
- //
Irp->CancelRoutine(DeviceObject, Irp);
-
- //
- // irp was cancelled
- //
return FALSE;
}
- //
- // release the cancel lock
- //
IoReleaseCancelSpinLock(Irp->CancelIrql);
- //
// if list is freezed, dont start this packet
- //
DPRINT("IrpListFreeze: %lu IrpPendingCount %lu\n", IrpListFreeze, FDODeviceExtension->IrpPendingCount);
return (IrpListFreeze || SrbProcessing);
PLIST_ENTRY Entry;
PIRP Irp = NULL;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
- // check if list is empty
- //
if (!IsListEmpty(&FDODeviceExtension->IrpListHead))
{
- //
- // remove entry
- //
Entry = RemoveHeadList(&FDODeviceExtension->IrpListHead);
- //
// get offset to start of irp
- //
Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
}
- //
- // release list lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
- //
- // return result
- //
return Irp;
}
{
PFDO_DEVICE_EXTENSION FDODeviceExtension;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- //
- // perform the wait
- //
KeWaitForSingleObject(&FDODeviceExtension->NoPendingRequests,
Executive,
KernelMode,
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)FDODeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
- // decrement pending irp count
- //
FDODeviceExtension->IrpPendingCount--;
- //
// check if this was our current active SRB
- //
if (FDODeviceExtension->ActiveSrb == Request)
{
- //
// 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);
}
- //
- // release lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
-
}
VOID
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
- //
- // get pdo device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
// check first if there's already a request pending or the queue is frozen
- //
if (FDODeviceExtension->ActiveSrb != NULL ||
FDODeviceExtension->IrpListFreeze)
{
- //
// no work to do yet
- //
return;
}
- //
// remove first irp from list
- //
Irp = USBSTOR_RemoveIrp(DeviceObject);
- //
// is there an irp pending
- //
if (!Irp)
{
- //
// no work to do
- //
IoStartNextPacket(DeviceObject, TRUE);
return;
}
- //
- // get current stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get srb
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
-
- //
- // sanity check
- //
ASSERT(Request);
- //
- // set the active SRB
- //
FDODeviceExtension->ActiveSrb = Request;
- //
// start next packet
- //
IoStartPacket(DeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo);
-
- //
- // start next request
- //
IoStartNextPacket(DeviceObject, TRUE);
}
PIO_STACK_LOCATION IoStack;
PSCSI_REQUEST_BLOCK Request;
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
// clear freezed status
- //
FDODeviceExtension->IrpListFreeze = FALSE;
- //
- // release irp list lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
- //
// grab newest irp
- //
Irp = USBSTOR_RemoveIrp(DeviceObject);
- //
- // is there an irp
- //
if (!Irp)
{
- //
- // no irp
- //
return;
}
- //
- // get current irp stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- //
- // get srb
- //
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
- //
- // start new packet
- //
IoStartPacket(DeviceObject,
Irp,
&Request->QueueSortKey,
USBSTOR_CancelIo);
}
-
VOID
NTAPI
USBSTOR_StartIo(
PFDO_DEVICE_EXTENSION FDODeviceExtension;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
KIRQL OldLevel;
- NTSTATUS Status;
BOOLEAN ResetInProgress;
DPRINT("USBSTOR_StartIo\n");
- //
- // get FDO device extension
- //
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(FDODeviceExtension->Common.IsFDO);
- //
- // acquire cancel spinlock
- //
IoAcquireCancelSpinLock(&OldLevel);
- //
- // set cancel routine to zero
- //
IoSetCancelRoutine(Irp, NULL);
- //
// check if the irp has been cancelled
- //
if (Irp->Cancel)
{
- //
- // irp has been cancelled, release cancel spinlock
- //
IoReleaseCancelSpinLock(OldLevel);
- //
- // irp is cancelled
- //
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
- //
- // terminate request
- //
USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
-
- //
- // complete request
- //
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- //
- // queue next request
- //
USBSTOR_QueueNextRequest(DeviceObject);
-
- //
- // done
- //
return;
}
- //
- // release cancel spinlock
- //
IoReleaseCancelSpinLock(OldLevel);
- //
- // acquire lock
- //
KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
- //
- // check reset is in progress
- //
ResetInProgress = FDODeviceExtension->ResetInProgress;
ASSERT(ResetInProgress == FALSE);
- //
- // release lock
- //
KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
- //
- // get current irp stack location
- //
IoStack = IoGetCurrentIrpStackLocation(Irp);
- //
- // get pdo device extension
- //
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
-
- //
- // sanity check
- //
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
- //
- // is a reset in progress
- //
+ // TODO: this condition is always false
if (ResetInProgress)
{
- //
// hard reset is in progress
- //
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
USBSTOR_QueueTerminateRequest(DeviceObject, Irp);
return;
}
- //
- // execute scsi
- //
- Status = USBSTOR_HandleExecuteSCSI(IoStack->DeviceObject, Irp, 0);
+ USBSTOR_HandleExecuteSCSI(IoStack->DeviceObject, Irp);
- //
// FIXME: handle error
- //
}