Reverted latest changes.
[reactos.git] / reactos / ntoskrnl / io / cntrller.c
1 /* $Id: cntrller.c,v 1.9 2002/09/08 10:23:24 chorns Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/pool.h>
16
17 #include <internal/debug.h>
18
19 /* GLOBALS *******************************************************************/
20
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')
24
25 /* TYPES ********************************************************************/
26
27 typedef struct
28 /*
29 * PURPOSE: A entry in the queue waiting for a controller object
30 */
31 {
32 KDEVICE_QUEUE_ENTRY Entry;
33 PDEVICE_OBJECT DeviceObject;
34 PDRIVER_CONTROL ExecutionRoutine;
35 PVOID Context;
36 } CONTROLLER_QUEUE_ENTRY, *PCONTROLLER_QUEUE_ENTRY;
37
38 /* FUNCTIONS *****************************************************************/
39
40 VOID
41 STDCALL
42 IoAllocateController(PCONTROLLER_OBJECT ControllerObject,
43 PDEVICE_OBJECT DeviceObject,
44 PDRIVER_CONTROL ExecutionRoutine,
45 PVOID Context)
46 /*
47 * FUNCTION: Sets up a call to a driver-supplied ControllerControl routine
48 * as soon as the device controller, represented by the given controller
49 * object, is available to carry out an I/O operation for the target device,
50 * represented by the given device object.
51 * ARGUMENTS:
52 * ControllerObject = Driver created controller object
53 * DeviceObject = Target device for the current irp
54 * ExecutionRoutine = Routine to be called when the device is available
55 * Context = Driver supplied context to be passed on to the above routine
56 * NOTE: Is the below implementation correct.
57 */
58 {
59 PCONTROLLER_QUEUE_ENTRY entry;
60 IO_ALLOCATION_ACTION Result;
61
62 assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
63
64 entry =
65 ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTROLLER_QUEUE_ENTRY),
66 TAG_CQE);
67 assert(entry!=NULL);
68
69 entry->DeviceObject = DeviceObject;
70 entry->ExecutionRoutine = ExecutionRoutine;
71 entry->Context = Context;
72
73 if (KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue,&entry->Entry))
74 {
75 return;
76 }
77 Result = ExecutionRoutine(DeviceObject,DeviceObject->CurrentIrp,
78 NULL,Context);
79 if (Result == DeallocateObject)
80 {
81 IoFreeController(ControllerObject);
82 }
83 ExFreePool(entry);
84 }
85
86 PCONTROLLER_OBJECT
87 STDCALL
88 IoCreateController(ULONG Size)
89 /*
90 * FUNCTION: Allocates memory and initializes a controller object
91 * ARGUMENTS:
92 * Size = Size (in bytes) to be allocated for the controller extension
93 * RETURNS: A pointer to the created object
94 */
95 {
96 PCONTROLLER_OBJECT controller;
97
98 assert_irql(PASSIVE_LEVEL);
99
100 controller =
101 ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTROLLER_OBJECT),
102 TAG_CONTROLLER);
103 if (controller==NULL)
104 {
105 return(NULL);
106 }
107
108 controller->ControllerExtension =
109 ExAllocatePoolWithTag(NonPagedPool, Size, TAG_CONTROLLER_EXTENSION);
110 if (controller->ControllerExtension==NULL)
111 {
112 ExFreePool(controller);
113 return(NULL);
114 }
115
116 KeInitializeDeviceQueue(&controller->DeviceWaitQueue);
117 return(controller);
118 }
119
120 VOID
121 STDCALL
122 IoDeleteController(PCONTROLLER_OBJECT ControllerObject)
123 /*
124 * FUNCTION: Removes a given controller object from the system
125 * ARGUMENTS:
126 * ControllerObject = Controller object to be released
127 */
128 {
129 assert_irql(PASSIVE_LEVEL);
130
131 ExFreePool(ControllerObject->ControllerExtension);
132 ExFreePool(ControllerObject);
133 }
134
135 VOID
136 STDCALL
137 IoFreeController(PCONTROLLER_OBJECT ControllerObject)
138 /*
139 * FUNCTION: Releases a previously allocated controller object when a
140 * device has finished an I/O request
141 * ARGUMENTS:
142 * ControllerObject = Controller object to be released
143 */
144 {
145 PKDEVICE_QUEUE_ENTRY QEntry;
146 CONTROLLER_QUEUE_ENTRY* Entry;
147 IO_ALLOCATION_ACTION Result;
148
149 do
150 {
151 QEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue);
152 Entry = CONTAINING_RECORD(QEntry,CONTROLLER_QUEUE_ENTRY,Entry);
153 if (QEntry==NULL)
154 {
155 return;
156 }
157 Result = Entry->ExecutionRoutine(Entry->DeviceObject,
158 Entry->DeviceObject->CurrentIrp,
159 NULL,
160 Entry->Context);
161 ExFreePool(Entry);
162 } while (Result == DeallocateObject);
163 }
164
165
166 /* EOF */