3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/cntrller.c
6 * PURPOSE: Implements the controller object
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/pool.h>
17 #include <internal/debug.h>
19 /* GLOBALS *******************************************************************/
21 #define TAG_CQE TAG('C', 'Q', 'E', ' ')
22 #define TAG_CONTROLLER TAG('C', 'N', 'T', 'R')
23 #define TAG_CONTROLLER_EXTENSION TAG('C', 'E', 'X', 'T')
25 /* TYPES ********************************************************************/
29 * PURPOSE: A entry in the queue waiting for a controller object
32 KDEVICE_QUEUE_ENTRY Entry;
33 PDEVICE_OBJECT DeviceObject;
34 PDRIVER_CONTROL ExecutionRoutine;
36 } CONTROLLER_QUEUE_ENTRY, *PCONTROLLER_QUEUE_ENTRY;
38 /* FUNCTIONS *****************************************************************/
45 IoAllocateController(PCONTROLLER_OBJECT ControllerObject,
46 PDEVICE_OBJECT DeviceObject,
47 PDRIVER_CONTROL ExecutionRoutine,
50 * FUNCTION: Sets up a call to a driver-supplied ControllerControl routine
51 * as soon as the device controller, represented by the given controller
52 * object, is available to carry out an I/O operation for the target device,
53 * represented by the given device object.
55 * ControllerObject = Driver created controller object
56 * DeviceObject = Target device for the current irp
57 * ExecutionRoutine = Routine to be called when the device is available
58 * Context = Driver supplied context to be passed on to the above routine
59 * NOTE: Is the below implementation correct.
62 PCONTROLLER_QUEUE_ENTRY entry;
63 IO_ALLOCATION_ACTION Result;
65 assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
68 ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTROLLER_QUEUE_ENTRY),
72 entry->DeviceObject = DeviceObject;
73 entry->ExecutionRoutine = ExecutionRoutine;
74 entry->Context = Context;
76 if (KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue,&entry->Entry))
80 Result = ExecutionRoutine(DeviceObject,DeviceObject->CurrentIrp,
82 if (Result == DeallocateObject)
84 IoFreeController(ControllerObject);
94 IoCreateController(ULONG Size)
96 * FUNCTION: Allocates memory and initializes a controller object
98 * Size = Size (in bytes) to be allocated for the controller extension
99 * RETURNS: A pointer to the created object
102 PCONTROLLER_OBJECT controller;
104 assert_irql(PASSIVE_LEVEL);
107 ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTROLLER_OBJECT),
109 if (controller==NULL)
114 controller->ControllerExtension =
115 ExAllocatePoolWithTag(NonPagedPool, Size, TAG_CONTROLLER_EXTENSION);
116 if (controller->ControllerExtension==NULL)
118 ExFreePool(controller);
122 KeInitializeDeviceQueue(&controller->DeviceWaitQueue);
131 IoDeleteController(PCONTROLLER_OBJECT ControllerObject)
133 * FUNCTION: Removes a given controller object from the system
135 * ControllerObject = Controller object to be released
138 assert_irql(PASSIVE_LEVEL);
140 ExFreePool(ControllerObject->ControllerExtension);
141 ExFreePool(ControllerObject);
149 IoFreeController(PCONTROLLER_OBJECT ControllerObject)
151 * FUNCTION: Releases a previously allocated controller object when a
152 * device has finished an I/O request
154 * ControllerObject = Controller object to be released
157 PKDEVICE_QUEUE_ENTRY QEntry;
158 CONTROLLER_QUEUE_ENTRY* Entry;
159 IO_ALLOCATION_ACTION Result;
163 QEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue);
164 Entry = CONTAINING_RECORD(QEntry,CONTROLLER_QUEUE_ENTRY,Entry);
169 Result = Entry->ExecutionRoutine(Entry->DeviceObject,
170 Entry->DeviceObject->CurrentIrp,
174 } while (Result == DeallocateObject);