1 /* $Id: queue.c,v 1.11 2002/09/07 15:12:53 chorns Exp $
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 ******************************************************************/
15 #include <internal/debug.h>
18 /* FUNCTIONS *****************************************************************/
22 IoStartNextPacketByKey(PDEVICE_OBJECT DeviceObject
,
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
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
35 PKDEVICE_QUEUE_ENTRY entry
;
38 entry
= KeRemoveByKeyDeviceQueue(&DeviceObject
->DeviceQueue
,
43 Irp
= CONTAINING_RECORD(entry
,
45 Tail
.Overlay
.DeviceQueueEntry
);
46 DeviceObject
->CurrentIrp
= Irp
;
47 DPRINT("Next irp is %x\n", Irp
);
48 ((PDRIVER_STARTIO
)DeviceObject
->DriverObject
->DriverStartIo
)(DeviceObject
, Irp
);
52 DPRINT("No next irp\n");
53 DeviceObject
->CurrentIrp
= NULL
;
59 IoStartNextPacket(PDEVICE_OBJECT DeviceObject
, BOOLEAN Cancelable
)
61 * FUNCTION: Removes the next packet from the device's queue and calls
62 * the driver's StartIO
64 * DeviceObject = Device
65 * Cancelable = True if irps in the queue can be canceled
68 PKDEVICE_QUEUE_ENTRY entry
;
71 DPRINT("IoStartNextPacket(DeviceObject %x, Cancelable %d)\n",
72 DeviceObject
,Cancelable
);
74 entry
= KeRemoveDeviceQueue(&DeviceObject
->DeviceQueue
);
78 Irp
= CONTAINING_RECORD(entry
,IRP
,Tail
.Overlay
.DeviceQueueEntry
);
79 DeviceObject
->CurrentIrp
= Irp
;
80 ((PDRIVER_STARTIO
)DeviceObject
->DriverObject
->DriverStartIo
)(DeviceObject
,Irp
);
84 DeviceObject
->CurrentIrp
= NULL
;
90 IoStartPacket(PDEVICE_OBJECT DeviceObject
,
91 PIRP Irp
, PULONG Key
, PDRIVER_CANCEL CancelFunction
)
93 * FUNCTION: Either call the device's StartIO routine with the packet or,
94 * if the device is busy, queue it.
96 * DeviceObject = Device to start the packet on
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
106 DPRINT("IoStartPacket(Irp %x)\n", Irp
);
108 ASSERT_IRQL(DISPATCH_LEVEL
);
110 IoAcquireCancelSpinLock(&oldirql
);
112 if (CancelFunction
!= NULL
)
114 Irp
->CancelRoutine
= CancelFunction
;
119 stat
= KeInsertByKeyDeviceQueue(&DeviceObject
->DeviceQueue
,
120 &Irp
->Tail
.Overlay
.DeviceQueueEntry
,
125 stat
= KeInsertDeviceQueue(&DeviceObject
->DeviceQueue
,
126 &Irp
->Tail
.Overlay
.DeviceQueueEntry
);
129 IoReleaseCancelSpinLock(oldirql
);
133 DeviceObject
->CurrentIrp
= Irp
;
134 ((PDRIVER_STARTIO
)DeviceObject
->DriverObject
->DriverStartIo
)(DeviceObject
,Irp
);