2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/queue.c
5 * PURPOSE: Implement device queueing
6 * PROGRAMMER: David Welch (welch@mcmail.com)
9 /* INCLUDES ******************************************************************/
12 #include <ddk/ntddk.h>
13 #include <internal/kernel.h>
14 #include <internal/debug.h>
16 /* FUNCTIONS *****************************************************************/
18 VOID
IoStartNextPacketByKey(PDEVICE_OBJECT DeviceObject
,
22 * FUNCTION: Dequeues the next packet from the given device object's
23 * associated device queue according to a specified sort-key value and calls
24 * the drivers StartIo routine with that IRP
26 * DeviceObject = Device object for which the irp is to dequeued
27 * Cancelable = True if IRPs in the key can be canceled
28 * Key = Sort key specifing which entry to remove from the queue
31 PKDEVICE_QUEUE_ENTRY entry
;
35 entry
= KeRemoveByKeyDeviceQueue(&DeviceObject
->DeviceQueue
,Key
);
39 Irp
= CONTAINING_RECORD(entry
,IRP
,Tail
.Overlay
.DeviceQueueEntry
);
40 DeviceObject
->DriverObject
->DriverStartIo(DeviceObject
,Irp
);
44 VOID
IoStartNextPacket(PDEVICE_OBJECT DeviceObject
, BOOLEAN Cancelable
)
46 * FUNCTION: Removes the next packet from the device's queue and calls
47 * the driver's StartIO
49 * DeviceObject = Device
50 * Cancelable = True if irps in the queue can be canceled
53 PKDEVICE_QUEUE_ENTRY entry
;
57 entry
= KeRemoveDeviceQueue(&DeviceObject
->DeviceQueue
);
61 Irp
= CONTAINING_RECORD(entry
,IRP
,Tail
.Overlay
.DeviceQueueEntry
);
62 DeviceObject
->DriverObject
->DriverStartIo(DeviceObject
,Irp
);
67 VOID
IoStartPacket(PDEVICE_OBJECT DeviceObject
,
68 PIRP Irp
, PULONG Key
, PDRIVER_CANCEL CancelFunction
)
70 * FUNCTION: Either call the device's StartIO routine with the packet or,
71 * if the device is busy, queue it.
73 * DeviceObject = Device to start the packet on
75 * Key = Where to insert the irp
76 * If zero then insert in the tail of the queue
77 * CancelFunction = Optional function to cancel the irqp
83 ASSERT_IRQL(DISPATCH_LEVEL
);
85 IoAcquireCancelSpinLock(&oldirql
);
87 if (CancelFunction
!= NULL
)
89 Irp
->CancelRoutine
= CancelFunction
;
94 stat
= KeInsertByKeyDeviceQueue(&DeviceObject
->DeviceQueue
,
95 &Irp
->Tail
.Overlay
.DeviceQueueEntry
,
100 stat
= KeInsertDeviceQueue(&DeviceObject
->DeviceQueue
,
101 &Irp
->Tail
.Overlay
.DeviceQueueEntry
);
104 IoReleaseCancelSpinLock(oldirql
);
108 DeviceObject
->DriverObject
->DriverStartIo(DeviceObject
,Irp
);