3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/queue.c
6 * PURPOSE: Implement device queueing
7 * PROGRAMMER: David Welch (welch@mcmail.com)
10 /* INCLUDES ******************************************************************/
12 #include <ddk/ntddk.h>
15 #include <internal/debug.h>
17 /* FUNCTIONS *****************************************************************/
21 IoStartNextPacketByKey(PDEVICE_OBJECT DeviceObject,
25 * FUNCTION: Dequeues the next packet from the given device object's
26 * associated device queue according to a specified sort-key value and calls
27 * the drivers StartIo routine with that IRP
29 * DeviceObject = Device object for which the irp is to dequeued
30 * Cancelable = True if IRPs in the key can be canceled
31 * Key = Sort key specifing which entry to remove from the queue
34 PKDEVICE_QUEUE_ENTRY entry;
37 entry = KeRemoveByKeyDeviceQueue(&DeviceObject->DeviceQueue,
42 Irp = CONTAINING_RECORD(entry,
44 Tail.Overlay.DeviceQueueEntry);
45 DeviceObject->CurrentIrp = Irp;
46 DPRINT("Next irp is %x\n", Irp);
47 DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
51 DPRINT("No next irp\n");
52 DeviceObject->CurrentIrp = NULL;
58 IoStartNextPacket(PDEVICE_OBJECT DeviceObject, BOOLEAN Cancelable)
60 * FUNCTION: Removes the next packet from the device's queue and calls
61 * the driver's StartIO
63 * DeviceObject = Device
64 * Cancelable = True if irps in the queue can be canceled
67 PKDEVICE_QUEUE_ENTRY entry;
70 DPRINT("IoStartNextPacket(DeviceObject %x, Cancelable %d)\n",
71 DeviceObject,Cancelable);
73 entry = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
77 Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
78 DeviceObject->CurrentIrp = Irp;
79 DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
83 DeviceObject->CurrentIrp = NULL;
89 IoStartPacket(PDEVICE_OBJECT DeviceObject,
90 PIRP Irp, PULONG Key, PDRIVER_CANCEL CancelFunction)
92 * FUNCTION: Either call the device's StartIO routine with the packet or,
93 * if the device is busy, queue it.
95 * DeviceObject = Device to start the packet on
97 * Key = Where to insert the irp
98 * If zero then insert in the tail of the queue
99 * CancelFunction = Optional function to cancel the irqp
105 DPRINT("IoStartPacket(Irp %x)\n", Irp);
107 ASSERT_IRQL(DISPATCH_LEVEL);
109 IoAcquireCancelSpinLock(&oldirql);
111 if (CancelFunction != NULL)
113 Irp->CancelRoutine = CancelFunction;
118 stat = KeInsertByKeyDeviceQueue(&DeviceObject->DeviceQueue,
119 &Irp->Tail.Overlay.DeviceQueueEntry,
124 stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
125 &Irp->Tail.Overlay.DeviceQueueEntry);
128 IoReleaseCancelSpinLock(oldirql);
132 DeviceObject->CurrentIrp = Irp;
133 DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);