Use free Windows DDK and compile with latest MinGW releases.
[reactos.git] / reactos / ntoskrnl / io / cntrller.c
1 /* $Id: cntrller.c,v 1.8 2002/09/07 15:12:52 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 <ntoskrnl.h>
15
16 #define NDEBUG
17 #include <internal/debug.h>
18
19
20 /* GLOBALS *******************************************************************/
21
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')
25
26 /* TYPES ********************************************************************/
27
28 typedef struct
29 /*
30 * PURPOSE: A entry in the queue waiting for a controller object
31 */
32 {
33 KDEVICE_QUEUE_ENTRY Entry;
34 PDEVICE_OBJECT DeviceObject;
35 PDRIVER_CONTROL ExecutionRoutine;
36 PVOID Context;
37 } CONTROLLER_QUEUE_ENTRY, *PCONTROLLER_QUEUE_ENTRY;
38
39 /* FUNCTIONS *****************************************************************/
40
41 VOID
42 STDCALL
43 IoAllocateController(PCONTROLLER_OBJECT ControllerObject,
44 PDEVICE_OBJECT DeviceObject,
45 PDRIVER_CONTROL ExecutionRoutine,
46 PVOID Context)
47 /*
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.
52 * ARGUMENTS:
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.
58 */
59 {
60 PCONTROLLER_QUEUE_ENTRY entry;
61 IO_ALLOCATION_ACTION Result;
62
63 assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
64
65 entry =
66 ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTROLLER_QUEUE_ENTRY),
67 TAG_CQE);
68 assert(entry!=NULL);
69
70 entry->DeviceObject = DeviceObject;
71 entry->ExecutionRoutine = ExecutionRoutine;
72 entry->Context = Context;
73
74 if (KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue,&entry->Entry))
75 {
76 return;
77 }
78 Result = ExecutionRoutine(DeviceObject,DeviceObject->CurrentIrp,
79 NULL,Context);
80 if (Result == DeallocateObject)
81 {
82 IoFreeController(ControllerObject);
83 }
84 ExFreePool(entry);
85 }
86
87 PCONTROLLER_OBJECT
88 STDCALL
89 IoCreateController(ULONG Size)
90 /*
91 * FUNCTION: Allocates memory and initializes a controller object
92 * ARGUMENTS:
93 * Size = Size (in bytes) to be allocated for the controller extension
94 * RETURNS: A pointer to the created object
95 */
96 {
97 PCONTROLLER_OBJECT controller;
98
99 assert_irql(PASSIVE_LEVEL);
100
101 controller =
102 ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTROLLER_OBJECT),
103 TAG_CONTROLLER);
104 if (controller==NULL)
105 {
106 return(NULL);
107 }
108
109 controller->ControllerExtension =
110 ExAllocatePoolWithTag(NonPagedPool, Size, TAG_CONTROLLER_EXTENSION);
111 if (controller->ControllerExtension==NULL)
112 {
113 ExFreePool(controller);
114 return(NULL);
115 }
116
117 KeInitializeDeviceQueue(&controller->DeviceWaitQueue);
118 return(controller);
119 }
120
121 VOID
122 STDCALL
123 IoDeleteController(PCONTROLLER_OBJECT ControllerObject)
124 /*
125 * FUNCTION: Removes a given controller object from the system
126 * ARGUMENTS:
127 * ControllerObject = Controller object to be released
128 */
129 {
130 assert_irql(PASSIVE_LEVEL);
131
132 ExFreePool(ControllerObject->ControllerExtension);
133 ExFreePool(ControllerObject);
134 }
135
136 VOID
137 STDCALL
138 IoFreeController(PCONTROLLER_OBJECT ControllerObject)
139 /*
140 * FUNCTION: Releases a previously allocated controller object when a
141 * device has finished an I/O request
142 * ARGUMENTS:
143 * ControllerObject = Controller object to be released
144 */
145 {
146 PKDEVICE_QUEUE_ENTRY QEntry;
147 CONTROLLER_QUEUE_ENTRY* Entry;
148 IO_ALLOCATION_ACTION Result;
149
150 do
151 {
152 QEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue);
153 Entry = CONTAINING_RECORD(QEntry,CONTROLLER_QUEUE_ENTRY,Entry);
154 if (QEntry==NULL)
155 {
156 return;
157 }
158 Result = Entry->ExecutionRoutine(Entry->DeviceObject,
159 Entry->DeviceObject->CurrentIrp,
160 NULL,
161 Entry->Context);
162 ExFreePool(Entry);
163 } while (Result == DeallocateObject);
164 }
165
166
167 /* EOF */