mirror of
https://github.com/reactos/reactos.git
synced 2024-05-31 17:51:49 +00:00
126768af64
svn path=/trunk/; revision=527
125 lines
3.3 KiB
C
125 lines
3.3 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* FILE: ntoskrnl/io/queue.c
|
|
* PURPOSE: Implement device queueing
|
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <ddk/ntddk.h>
|
|
|
|
#define NDEBUG
|
|
#include <internal/debug.h>
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
VOID IoStartNextPacketByKey(PDEVICE_OBJECT DeviceObject,
|
|
BOOLEAN Cancelable,
|
|
ULONG Key)
|
|
/*
|
|
* FUNCTION: Dequeues the next packet from the given device object's
|
|
* associated device queue according to a specified sort-key value and calls
|
|
* the drivers StartIo routine with that IRP
|
|
* ARGUMENTS:
|
|
* DeviceObject = Device object for which the irp is to dequeued
|
|
* Cancelable = True if IRPs in the key can be canceled
|
|
* Key = Sort key specifing which entry to remove from the queue
|
|
*/
|
|
{
|
|
PKDEVICE_QUEUE_ENTRY entry;
|
|
PIRP Irp;
|
|
|
|
entry = KeRemoveByKeyDeviceQueue(&DeviceObject->DeviceQueue,Key);
|
|
|
|
if (entry!=NULL)
|
|
{
|
|
Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
|
|
DeviceObject->CurrentIrp = Irp;
|
|
DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
|
|
}
|
|
else
|
|
{
|
|
DeviceObject->CurrentIrp = NULL;
|
|
}
|
|
}
|
|
|
|
VOID IoStartNextPacket(PDEVICE_OBJECT DeviceObject, BOOLEAN Cancelable)
|
|
/*
|
|
* FUNCTION: Removes the next packet from the device's queue and calls
|
|
* the driver's StartIO
|
|
* ARGUMENTS:
|
|
* DeviceObject = Device
|
|
* Cancelable = True if irps in the queue can be canceled
|
|
*/
|
|
{
|
|
PKDEVICE_QUEUE_ENTRY entry;
|
|
PIRP Irp;
|
|
|
|
DPRINT("IoStartNextPacket(DeviceObject %x, Cancelable %d)\n",
|
|
DeviceObject,Cancelable);
|
|
|
|
entry = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
|
|
|
|
if (entry!=NULL)
|
|
{
|
|
Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
|
|
DeviceObject->CurrentIrp = Irp;
|
|
DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
|
|
}
|
|
else
|
|
{
|
|
DeviceObject->CurrentIrp = NULL;
|
|
}
|
|
}
|
|
|
|
VOID IoStartPacket(PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp, PULONG Key, PDRIVER_CANCEL CancelFunction)
|
|
/*
|
|
* FUNCTION: Either call the device's StartIO routine with the packet or,
|
|
* if the device is busy, queue it.
|
|
* ARGUMENTS:
|
|
* DeviceObject = Device to start the packet on
|
|
* Irp = Irp to queue
|
|
* Key = Where to insert the irp
|
|
* If zero then insert in the tail of the queue
|
|
* CancelFunction = Optional function to cancel the irqp
|
|
*/
|
|
{
|
|
BOOLEAN stat;
|
|
KIRQL oldirql;
|
|
|
|
ASSERT_IRQL(DISPATCH_LEVEL);
|
|
|
|
IoAcquireCancelSpinLock(&oldirql);
|
|
|
|
if (CancelFunction != NULL)
|
|
{
|
|
Irp->CancelRoutine = CancelFunction;
|
|
}
|
|
|
|
if (Key!=0)
|
|
{
|
|
stat = KeInsertByKeyDeviceQueue(&DeviceObject->DeviceQueue,
|
|
&Irp->Tail.Overlay.DeviceQueueEntry,
|
|
*Key);
|
|
}
|
|
else
|
|
{
|
|
stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
|
|
&Irp->Tail.Overlay.DeviceQueueEntry);
|
|
}
|
|
|
|
IoReleaseCancelSpinLock(oldirql);
|
|
|
|
if (!stat)
|
|
{
|
|
DeviceObject->CurrentIrp = Irp;
|
|
DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
|
|
}
|
|
}
|
|
|
|
|