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 *****************************************************************/
24 IoStartNextPacketByKey(PDEVICE_OBJECT DeviceObject,
28 * FUNCTION: Dequeues the next packet from the given device object's
29 * associated device queue according to a specified sort-key value and calls
30 * the drivers StartIo routine with that IRP
32 * DeviceObject = Device object for which the irp is to dequeued
33 * Cancelable = True if IRPs in the key can be canceled
34 * Key = Sort key specifing which entry to remove from the queue
37 PKDEVICE_QUEUE_ENTRY entry;
40 entry = KeRemoveByKeyDeviceQueue(&DeviceObject->DeviceQueue,
45 Irp = CONTAINING_RECORD(entry,
47 Tail.Overlay.DeviceQueueEntry);
48 DeviceObject->CurrentIrp = Irp;
49 DPRINT("Next irp is %x\n", Irp);
50 DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
54 DPRINT("No next irp\n");
55 DeviceObject->CurrentIrp = NULL;
64 IoStartNextPacket(PDEVICE_OBJECT DeviceObject, BOOLEAN Cancelable)
66 * FUNCTION: Removes the next packet from the device's queue and calls
67 * the driver's StartIO
69 * DeviceObject = Device
70 * Cancelable = True if irps in the queue can be canceled
73 PKDEVICE_QUEUE_ENTRY entry;
76 DPRINT("IoStartNextPacket(DeviceObject %x, Cancelable %d)\n",
77 DeviceObject,Cancelable);
79 entry = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
83 Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
84 DeviceObject->CurrentIrp = Irp;
85 DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
89 DeviceObject->CurrentIrp = NULL;
98 IoStartPacket(PDEVICE_OBJECT DeviceObject,
99 PIRP Irp, PULONG Key, PDRIVER_CANCEL CancelFunction)
101 * FUNCTION: Either call the device's StartIO routine with the packet or,
102 * if the device is busy, queue it.
104 * DeviceObject = Device to start the packet on
106 * Key = Where to insert the irp
107 * If zero then insert in the tail of the queue
108 * CancelFunction = Optional function to cancel the irqp
114 DPRINT("IoStartPacket(Irp %x)\n", Irp);
116 ASSERT_IRQL(DISPATCH_LEVEL);
118 IoAcquireCancelSpinLock(&oldirql);
120 if (CancelFunction != NULL)
122 Irp->CancelRoutine = CancelFunction;
127 stat = KeInsertByKeyDeviceQueue(&DeviceObject->DeviceQueue,
128 &Irp->Tail.Overlay.DeviceQueueEntry,
133 stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
134 &Irp->Tail.Overlay.DeviceQueueEntry);
137 IoReleaseCancelSpinLock(oldirql);
141 DeviceObject->CurrentIrp = Irp;
142 DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);