Use free Windows DDK and compile with latest MinGW releases.
[reactos.git] / reactos / ntoskrnl / io / queue.c
1 /* $Id: queue.c,v 1.11 2002/09/07 15:12:53 chorns Exp $
2 *
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)
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ntoskrnl.h>
13
14 #define NDEBUG
15 #include <internal/debug.h>
16
17
18 /* FUNCTIONS *****************************************************************/
19
20 VOID
21 STDCALL
22 IoStartNextPacketByKey(PDEVICE_OBJECT DeviceObject,
23 BOOLEAN Cancelable,
24 ULONG Key)
25 /*
26 * FUNCTION: Dequeues the next packet from the given device object's
27 * associated device queue according to a specified sort-key value and calls
28 * the drivers StartIo routine with that IRP
29 * ARGUMENTS:
30 * DeviceObject = Device object for which the irp is to dequeued
31 * Cancelable = True if IRPs in the key can be canceled
32 * Key = Sort key specifing which entry to remove from the queue
33 */
34 {
35 PKDEVICE_QUEUE_ENTRY entry;
36 PIRP Irp;
37
38 entry = KeRemoveByKeyDeviceQueue(&DeviceObject->DeviceQueue,
39 Key);
40
41 if (entry != NULL)
42 {
43 Irp = CONTAINING_RECORD(entry,
44 IRP,
45 Tail.Overlay.DeviceQueueEntry);
46 DeviceObject->CurrentIrp = Irp;
47 DPRINT("Next irp is %x\n", Irp);
48 ((PDRIVER_STARTIO)DeviceObject->DriverObject->DriverStartIo)(DeviceObject, Irp);
49 }
50 else
51 {
52 DPRINT("No next irp\n");
53 DeviceObject->CurrentIrp = NULL;
54 }
55 }
56
57 VOID
58 STDCALL
59 IoStartNextPacket(PDEVICE_OBJECT DeviceObject, BOOLEAN Cancelable)
60 /*
61 * FUNCTION: Removes the next packet from the device's queue and calls
62 * the driver's StartIO
63 * ARGUMENTS:
64 * DeviceObject = Device
65 * Cancelable = True if irps in the queue can be canceled
66 */
67 {
68 PKDEVICE_QUEUE_ENTRY entry;
69 PIRP Irp;
70
71 DPRINT("IoStartNextPacket(DeviceObject %x, Cancelable %d)\n",
72 DeviceObject,Cancelable);
73
74 entry = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
75
76 if (entry!=NULL)
77 {
78 Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
79 DeviceObject->CurrentIrp = Irp;
80 ((PDRIVER_STARTIO)DeviceObject->DriverObject->DriverStartIo)(DeviceObject,Irp);
81 }
82 else
83 {
84 DeviceObject->CurrentIrp = NULL;
85 }
86 }
87
88 VOID
89 STDCALL
90 IoStartPacket(PDEVICE_OBJECT DeviceObject,
91 PIRP Irp, PULONG Key, PDRIVER_CANCEL CancelFunction)
92 /*
93 * FUNCTION: Either call the device's StartIO routine with the packet or,
94 * if the device is busy, queue it.
95 * ARGUMENTS:
96 * DeviceObject = Device to start the packet on
97 * Irp = Irp to queue
98 * Key = Where to insert the irp
99 * If zero then insert in the tail of the queue
100 * CancelFunction = Optional function to cancel the irqp
101 */
102 {
103 BOOLEAN stat;
104 KIRQL oldirql;
105
106 DPRINT("IoStartPacket(Irp %x)\n", Irp);
107
108 ASSERT_IRQL(DISPATCH_LEVEL);
109
110 IoAcquireCancelSpinLock(&oldirql);
111
112 if (CancelFunction != NULL)
113 {
114 Irp->CancelRoutine = CancelFunction;
115 }
116
117 if (Key!=0)
118 {
119 stat = KeInsertByKeyDeviceQueue(&DeviceObject->DeviceQueue,
120 &Irp->Tail.Overlay.DeviceQueueEntry,
121 *Key);
122 }
123 else
124 {
125 stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
126 &Irp->Tail.Overlay.DeviceQueueEntry);
127 }
128
129 IoReleaseCancelSpinLock(oldirql);
130
131 if (!stat)
132 {
133 DeviceObject->CurrentIrp = Irp;
134 ((PDRIVER_STARTIO)DeviceObject->DriverObject->DriverStartIo)(DeviceObject,Irp);
135 }
136 }
137
138
139 /* EOF */