2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/contrller.c
5 * PURPOSE: Implements the controller object
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
10 /* INCLUDES *****************************************************************/
13 #include <internal/debug.h>
15 /* GLOBALS *******************************************************************/
17 POBJECT_TYPE IoControllerObjectType
;
19 /* FUNCTIONS *****************************************************************/
24 * FUNCTION: Sets up a call to a driver-supplied ControllerControl routine
25 * as soon as the device controller, represented by the given controller
26 * object, is available to carry out an I/O operation for the target device,
27 * represented by the given device object.
29 * ControllerObject = Driver created controller object
30 * DeviceObject = Target device for the current irp
31 * ExecutionRoutine = Routine to be called when the device is available
32 * Context = Driver supplied context to be passed on to the above routine
36 IoAllocateController(PCONTROLLER_OBJECT ControllerObject
,
37 PDEVICE_OBJECT DeviceObject
,
38 PDRIVER_CONTROL ExecutionRoutine
,
41 IO_ALLOCATION_ACTION Result
;
43 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
45 /* Initialize the Wait Context Block */
46 DeviceObject
->Queue
.Wcb
.DeviceContext
= Context
;
47 DeviceObject
->Queue
.Wcb
.DeviceRoutine
= ExecutionRoutine
;
49 /* Insert the Device Queue */
50 if (!KeInsertDeviceQueue(&ControllerObject
->DeviceWaitQueue
,
51 &DeviceObject
->Queue
.Wcb
.WaitQueueEntry
));
53 Result
= ExecutionRoutine(DeviceObject
,
54 DeviceObject
->CurrentIrp
,
59 if (Result
== DeallocateObject
)
61 IoFreeController(ControllerObject
);
68 * FUNCTION: Allocates memory and initializes a controller object
70 * Size = Size (in bytes) to be allocated for the controller extension
71 * RETURNS: A pointer to the created object
75 IoCreateController(ULONG Size
)
78 PCONTROLLER_OBJECT Controller
;
79 OBJECT_ATTRIBUTES ObjectAttributes
;
82 ASSERT_IRQL(PASSIVE_LEVEL
);
84 /* Initialize an empty OBA */
85 InitializeObjectAttributes(&ObjectAttributes
, NULL
, 0, NULL
, NULL
);
87 /* Create the Object */
88 Status
= ObCreateObject(KernelMode
,
89 IoControllerObjectType
,
93 sizeof(CONTROLLER_OBJECT
) + Size
,
97 if (!NT_SUCCESS(Status
)) return NULL
;
100 Status
= ObInsertObject(Controller
,
102 FILE_READ_DATA
| FILE_WRITE_DATA
,
106 if (!NT_SUCCESS(Status
)) return NULL
;
108 /* Close the dummy handle */
111 /* Zero the Object and set its data */
112 RtlZeroMemory(Controller
, sizeof(CONTROLLER_OBJECT
) + Size
);
113 Controller
->Type
= IO_TYPE_CONTROLLER
;
114 Controller
->Size
= sizeof(CONTROLLER_OBJECT
) + Size
;
115 Controller
->ControllerExtension
= (Controller
+ 1);
117 /* Initialize its Queue */
118 KeInitializeDeviceQueue(&Controller
->DeviceWaitQueue
);
120 /* Return Controller */
127 * FUNCTION: Removes a given controller object from the system
129 * ControllerObject = Controller object to be released
133 IoDeleteController(PCONTROLLER_OBJECT ControllerObject
)
136 /* Just Dereference it */
137 ObDereferenceObject(ControllerObject
);
143 * FUNCTION: Releases a previously allocated controller object when a
144 * device has finished an I/O request
146 * ControllerObject = Controller object to be released
150 IoFreeController(PCONTROLLER_OBJECT ControllerObject
)
152 PKDEVICE_QUEUE_ENTRY QueueEntry
;
153 PDEVICE_OBJECT DeviceObject
;
154 IO_ALLOCATION_ACTION Result
;
156 /* Remove the Queue */
157 if ((QueueEntry
= KeRemoveDeviceQueue(&ControllerObject
->DeviceWaitQueue
)))
159 /* Get the Device Object */
160 DeviceObject
= CONTAINING_RECORD(QueueEntry
,
162 Queue
.Wcb
.WaitQueueEntry
);
163 /* Call the routine */
164 Result
= DeviceObject
->Queue
.Wcb
.DeviceRoutine(DeviceObject
,
165 DeviceObject
->CurrentIrp
,
167 DeviceObject
->Queue
.Wcb
.DeviceContext
);
168 /* Check the result */
169 if (Result
== DeallocateObject
)
172 IoFreeController(ControllerObject
);