Initial revision
[reactos.git] / reactos / ntoskrnl / io / queue.c
1 /*
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)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <windows.h>
12 #include <ddk/ntddk.h>
13 #include <internal/kernel.h>
14 #include <internal/debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 VOID IoStartNextPacketByKey(PDEVICE_OBJECT DeviceObject,
19 BOOLEAN Cancelable,
20 ULONG Key)
21 /*
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
25 * ARGUMENTS:
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
29 */
30 {
31 PKDEVICE_QUEUE_ENTRY entry;
32 PIRP Irp;
33 KIRQL oldirql;
34
35 entry = KeRemoveByKeyDeviceQueue(&DeviceObject->DeviceQueue,Key);
36
37 if (entry!=NULL)
38 {
39 Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
40 DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
41 }
42 }
43
44 VOID IoStartNextPacket(PDEVICE_OBJECT DeviceObject, BOOLEAN Cancelable)
45 /*
46 * FUNCTION: Removes the next packet from the device's queue and calls
47 * the driver's StartIO
48 * ARGUMENTS:
49 * DeviceObject = Device
50 * Cancelable = True if irps in the queue can be canceled
51 */
52 {
53 PKDEVICE_QUEUE_ENTRY entry;
54 PIRP Irp;
55 KIRQL oldirql;
56
57 entry = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
58
59 if (entry!=NULL)
60 {
61 Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
62 DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
63 }
64
65 }
66
67 VOID IoStartPacket(PDEVICE_OBJECT DeviceObject,
68 PIRP Irp, PULONG Key, PDRIVER_CANCEL CancelFunction)
69 /*
70 * FUNCTION: Either call the device's StartIO routine with the packet or,
71 * if the device is busy, queue it.
72 * ARGUMENTS:
73 * DeviceObject = Device to start the packet on
74 * Irp = Irp to queue
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
78 */
79 {
80 BOOLEAN stat;
81 KIRQL oldirql;
82
83 ASSERT_IRQL(DISPATCH_LEVEL);
84
85 IoAcquireCancelSpinLock(&oldirql);
86
87 if (CancelFunction != NULL)
88 {
89 Irp->CancelRoutine = CancelFunction;
90 }
91
92 if (Key!=0)
93 {
94 stat = KeInsertByKeyDeviceQueue(&DeviceObject->DeviceQueue,
95 &Irp->Tail.Overlay.DeviceQueueEntry,
96 *Key);
97 }
98 else
99 {
100 stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
101 &Irp->Tail.Overlay.DeviceQueueEntry);
102 }
103
104 IoReleaseCancelSpinLock(oldirql);
105
106 if (!stat)
107 {
108 DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
109 }
110 }
111
112