3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/queue.c
6 * PURPOSE: Implement device queueing
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES ******************************************************************/
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
);
140 IoReleaseCancelSpinLock(DISPATCH_LEVEL
);
141 DeviceObject
->CurrentIrp
= Irp
;
142 DeviceObject
->DriverObject
->DriverStartIo(DeviceObject
,Irp
);
143 if (oldirql
< DISPATCH_LEVEL
)
145 KeLowerIrql(oldirql
);
150 IoReleaseCancelSpinLock(oldirql
);