1 /* $Id: cntrller.c,v 1.8 2002/09/07 15:12:52 chorns Exp $
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 *****************************************************************/
17 #include <internal/debug.h>
20 /* GLOBALS *******************************************************************/
22 #define TAG_CQE TAG('C', 'Q', 'E', ' ')
23 #define TAG_CONTROLLER TAG('C', 'N', 'T', 'R')
24 #define TAG_CONTROLLER_EXTENSION TAG('C', 'E', 'X', 'T')
26 /* TYPES ********************************************************************/
30 * PURPOSE: A entry in the queue waiting for a controller object
33 KDEVICE_QUEUE_ENTRY Entry
;
34 PDEVICE_OBJECT DeviceObject
;
35 PDRIVER_CONTROL ExecutionRoutine
;
37 } CONTROLLER_QUEUE_ENTRY
, *PCONTROLLER_QUEUE_ENTRY
;
39 /* FUNCTIONS *****************************************************************/
43 IoAllocateController(PCONTROLLER_OBJECT ControllerObject
,
44 PDEVICE_OBJECT DeviceObject
,
45 PDRIVER_CONTROL ExecutionRoutine
,
48 * FUNCTION: Sets up a call to a driver-supplied ControllerControl routine
49 * as soon as the device controller, represented by the given controller
50 * object, is available to carry out an I/O operation for the target device,
51 * represented by the given device object.
53 * ControllerObject = Driver created controller object
54 * DeviceObject = Target device for the current irp
55 * ExecutionRoutine = Routine to be called when the device is available
56 * Context = Driver supplied context to be passed on to the above routine
57 * NOTE: Is the below implementation correct.
60 PCONTROLLER_QUEUE_ENTRY entry
;
61 IO_ALLOCATION_ACTION Result
;
63 assert(KeGetCurrentIrql() == DISPATCH_LEVEL
);
66 ExAllocatePoolWithTag(NonPagedPool
, sizeof(CONTROLLER_QUEUE_ENTRY
),
70 entry
->DeviceObject
= DeviceObject
;
71 entry
->ExecutionRoutine
= ExecutionRoutine
;
72 entry
->Context
= Context
;
74 if (KeInsertDeviceQueue(&ControllerObject
->DeviceWaitQueue
,&entry
->Entry
))
78 Result
= ExecutionRoutine(DeviceObject
,DeviceObject
->CurrentIrp
,
80 if (Result
== DeallocateObject
)
82 IoFreeController(ControllerObject
);
89 IoCreateController(ULONG Size
)
91 * FUNCTION: Allocates memory and initializes a controller object
93 * Size = Size (in bytes) to be allocated for the controller extension
94 * RETURNS: A pointer to the created object
97 PCONTROLLER_OBJECT controller
;
99 assert_irql(PASSIVE_LEVEL
);
102 ExAllocatePoolWithTag(NonPagedPool
, sizeof(CONTROLLER_OBJECT
),
104 if (controller
==NULL
)
109 controller
->ControllerExtension
=
110 ExAllocatePoolWithTag(NonPagedPool
, Size
, TAG_CONTROLLER_EXTENSION
);
111 if (controller
->ControllerExtension
==NULL
)
113 ExFreePool(controller
);
117 KeInitializeDeviceQueue(&controller
->DeviceWaitQueue
);
123 IoDeleteController(PCONTROLLER_OBJECT ControllerObject
)
125 * FUNCTION: Removes a given controller object from the system
127 * ControllerObject = Controller object to be released
130 assert_irql(PASSIVE_LEVEL
);
132 ExFreePool(ControllerObject
->ControllerExtension
);
133 ExFreePool(ControllerObject
);
138 IoFreeController(PCONTROLLER_OBJECT ControllerObject
)
140 * FUNCTION: Releases a previously allocated controller object when a
141 * device has finished an I/O request
143 * ControllerObject = Controller object to be released
146 PKDEVICE_QUEUE_ENTRY QEntry
;
147 CONTROLLER_QUEUE_ENTRY
* Entry
;
148 IO_ALLOCATION_ACTION Result
;
152 QEntry
= KeRemoveDeviceQueue(&ControllerObject
->DeviceWaitQueue
);
153 Entry
= CONTAINING_RECORD(QEntry
,CONTROLLER_QUEUE_ENTRY
,Entry
);
158 Result
= Entry
->ExecutionRoutine(Entry
->DeviceObject
,
159 Entry
->DeviceObject
->CurrentIrp
,
163 } while (Result
== DeallocateObject
);