- Make ACPI use PCH. Cuts down compile time to 9 seconds on gcc.
[reactos.git] / reactos / drivers / bus / acpi / ospm / pdo.c
1 /* $Id$
2 *
3 * PROJECT: ReactOS ACPI bus driver
4 * FILE: acpi/ospm/pdo.c
5 * PURPOSE: Child device object dispatch routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * UPDATE HISTORY:
8 * 08-08-2001 CSH Created
9 */
10 #include <acpi.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /*** PRIVATE *****************************************************************/
16
17 static NTSTATUS
18 AcpiDuplicateUnicodeString(
19 PUNICODE_STRING Destination,
20 PUNICODE_STRING Source,
21 POOL_TYPE PoolType)
22 {
23 if (Source == NULL)
24 {
25 RtlInitUnicodeString(Destination, NULL);
26 return STATUS_SUCCESS;
27 }
28
29 Destination->Buffer = ExAllocatePool(PoolType, Source->MaximumLength);
30 if (Destination->Buffer == NULL)
31 {
32 return STATUS_INSUFFICIENT_RESOURCES;
33 }
34
35 Destination->MaximumLength = Source->MaximumLength;
36 Destination->Length = Source->Length;
37 RtlCopyMemory(Destination->Buffer, Source->Buffer, Source->MaximumLength);
38
39 return STATUS_SUCCESS;
40 }
41
42
43 static NTSTATUS
44 PdoQueryDeviceText(
45 IN PDEVICE_OBJECT DeviceObject,
46 IN PIRP Irp,
47 PIO_STACK_LOCATION IrpSp)
48 {
49 PPDO_DEVICE_EXTENSION DeviceExtension;
50 PWSTR Buffer;
51 NTSTATUS Status;
52
53 DPRINT("Called\n");
54
55 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
56
57 Status = STATUS_SUCCESS;
58
59 switch (IrpSp->Parameters.QueryDeviceText.DeviceTextType)
60 {
61 case DeviceTextDescription:
62 DPRINT("DeviceTextDescription\n");
63 Buffer = (PWSTR)ExAllocatePool(PagedPool, DeviceExtension->DeviceDescription.Length + sizeof(UNICODE_NULL));
64 if (Buffer == NULL)
65 Status = STATUS_INSUFFICIENT_RESOURCES;
66 else
67 {
68 RtlCopyMemory(Buffer, DeviceExtension->DeviceDescription.Buffer, DeviceExtension->DeviceDescription.Length);
69 Buffer[DeviceExtension->DeviceDescription.Length / sizeof(WCHAR)] = UNICODE_NULL;
70 Irp->IoStatus.Information = (ULONG_PTR)Buffer;
71 }
72 break;
73
74 default:
75 Irp->IoStatus.Information = 0;
76 Status = STATUS_INVALID_PARAMETER;
77 }
78
79 return Status;
80 }
81
82
83 static NTSTATUS
84 PdoQueryId(
85 IN PDEVICE_OBJECT DeviceObject,
86 IN PIRP Irp,
87 PIO_STACK_LOCATION IrpSp)
88 {
89 PPDO_DEVICE_EXTENSION DeviceExtension;
90 UNICODE_STRING String;
91 NTSTATUS Status;
92
93 DPRINT("Called\n");
94
95 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
96
97 RtlInitUnicodeString(&String, NULL);
98
99 // Irp->IoStatus.Information = 0;
100
101 switch (IrpSp->Parameters.QueryId.IdType)
102 {
103 case BusQueryDeviceID:
104 DPRINT("BusQueryDeviceID\n");
105 Status = AcpiDuplicateUnicodeString(&String,
106 &DeviceExtension->DeviceID,
107 PagedPool);
108 DPRINT("DeviceID: %S\n", String.Buffer);
109 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
110 break;
111
112 case BusQueryHardwareIDs:
113 DPRINT("BusQueryHardwareIDs\n");
114 Status = AcpiDuplicateUnicodeString(&String,
115 &DeviceExtension->HardwareIDs,
116 PagedPool);
117 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
118 break;
119
120 case BusQueryCompatibleIDs:
121 DPRINT("BusQueryCompatibleIDs\n");
122 Status = STATUS_NOT_IMPLEMENTED;
123 break;
124
125 case BusQueryInstanceID:
126 DPRINT("BusQueryInstanceID\n");
127 Status = AcpiDuplicateUnicodeString(&String,
128 &DeviceExtension->InstanceID,
129 PagedPool);
130 DPRINT("InstanceID: %S\n", String.Buffer);
131 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
132 break;
133
134 case BusQueryDeviceSerialNumber:
135 DPRINT("BusQueryDeviceSerialNumber\n");
136 Status = STATUS_NOT_IMPLEMENTED;
137 break;
138
139 default:
140 DPRINT("Unknown id type: %lx\n", IrpSp->Parameters.QueryId.IdType);
141 Status = STATUS_NOT_IMPLEMENTED;
142 }
143
144 return Status;
145 }
146
147
148 static NTSTATUS
149 PdoQueryResourceRequirements(
150 IN PDEVICE_OBJECT DeviceObject,
151 IN PIRP Irp,
152 PIO_STACK_LOCATION IrpSp)
153 {
154 PPDO_DEVICE_EXTENSION DeviceExtension;
155 PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
156
157 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
158
159 if (DeviceExtension->ResourceRequirementsListSize == 0)
160 {
161 return Irp->IoStatus.Status;
162 }
163
164 ResourceRequirementsList = ExAllocatePool(PagedPool, DeviceExtension->ResourceRequirementsListSize);
165 if (!ResourceRequirementsList)
166 {
167 Irp->IoStatus.Information = 0;
168 return STATUS_INSUFFICIENT_RESOURCES;
169 }
170
171 RtlCopyMemory(ResourceRequirementsList, DeviceExtension->ResourceRequirementsList, DeviceExtension->ResourceRequirementsListSize);
172 Irp->IoStatus.Information = (ULONG_PTR)ResourceRequirementsList;
173 return STATUS_SUCCESS;
174 }
175
176
177 static NTSTATUS
178 PdoQueryResources(
179 IN PDEVICE_OBJECT DeviceObject,
180 IN PIRP Irp,
181 PIO_STACK_LOCATION IrpSp)
182 {
183 PPDO_DEVICE_EXTENSION DeviceExtension;
184 PCM_RESOURCE_LIST ResourceList;
185
186 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
187
188 if (DeviceExtension->ResourceListSize == 0)
189 {
190 return Irp->IoStatus.Status;
191 }
192
193 ResourceList = ExAllocatePool(PagedPool, DeviceExtension->ResourceListSize);
194 if (!ResourceList)
195 {
196 Irp->IoStatus.Information = 0;
197 return STATUS_INSUFFICIENT_RESOURCES;
198 }
199
200 RtlCopyMemory(ResourceList, DeviceExtension->ResourceList, DeviceExtension->ResourceListSize);
201 Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
202 return STATUS_SUCCESS;
203 }
204
205
206 static NTSTATUS
207 PdoSetPower(
208 IN PDEVICE_OBJECT DeviceObject,
209 IN PIRP Irp,
210 PIO_STACK_LOCATION IrpSp)
211 {
212 PPDO_DEVICE_EXTENSION DeviceExtension;
213 NTSTATUS Status;
214
215 DPRINT("Called\n");
216
217 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
218
219 if (IrpSp->Parameters.Power.Type == DevicePowerState) {
220 Status = STATUS_SUCCESS;
221 switch (IrpSp->Parameters.Power.State.SystemState) {
222 default:
223 Status = STATUS_UNSUCCESSFUL;
224 }
225 } else {
226 Status = STATUS_UNSUCCESSFUL;
227 }
228
229 return Status;
230 }
231
232
233 /*** PUBLIC ******************************************************************/
234
235 NTSTATUS
236 STDCALL
237 PdoPnpControl(
238 PDEVICE_OBJECT DeviceObject,
239 PIRP Irp)
240 /*
241 * FUNCTION: Handle Plug and Play IRPs for the child device
242 * ARGUMENTS:
243 * DeviceObject = Pointer to physical device object of the child device
244 * Irp = Pointer to IRP that should be handled
245 * RETURNS:
246 * Status
247 */
248 {
249 PIO_STACK_LOCATION IrpSp;
250 NTSTATUS Status;
251
252 DPRINT("Called\n");
253
254 Status = Irp->IoStatus.Status;
255
256 IrpSp = IoGetCurrentIrpStackLocation(Irp);
257
258 switch (IrpSp->MinorFunction) {
259 case IRP_MN_CANCEL_REMOVE_DEVICE:
260 break;
261
262 case IRP_MN_CANCEL_STOP_DEVICE:
263 break;
264
265 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
266 break;
267
268 case IRP_MN_EJECT:
269 break;
270
271 case IRP_MN_QUERY_BUS_INFORMATION:
272 break;
273
274 case IRP_MN_QUERY_CAPABILITIES:
275 break;
276
277 case IRP_MN_QUERY_DEVICE_RELATIONS:
278 /* FIXME: Possibly handle for RemovalRelations */
279 break;
280
281 case IRP_MN_QUERY_DEVICE_TEXT:
282 Status = PdoQueryDeviceText(DeviceObject, Irp, IrpSp);
283 break;
284
285 case IRP_MN_QUERY_ID:
286 Status = PdoQueryId(DeviceObject,
287 Irp,
288 IrpSp);
289 break;
290
291 case IRP_MN_QUERY_PNP_DEVICE_STATE:
292 break;
293
294 case IRP_MN_QUERY_REMOVE_DEVICE:
295 break;
296
297 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
298 Status = PdoQueryResourceRequirements(DeviceObject,
299 Irp,
300 IrpSp);
301 break;
302
303 case IRP_MN_QUERY_RESOURCES:
304 Status = PdoQueryResources(DeviceObject,
305 Irp,
306 IrpSp);
307 break;
308
309 case IRP_MN_QUERY_STOP_DEVICE:
310 break;
311
312 case IRP_MN_REMOVE_DEVICE:
313 break;
314
315 case IRP_MN_SET_LOCK:
316 break;
317
318 case IRP_MN_START_DEVICE:
319 Status = STATUS_SUCCESS;
320 break;
321
322 case IRP_MN_STOP_DEVICE:
323 break;
324
325 case IRP_MN_SURPRISE_REMOVAL:
326 break;
327
328 default:
329 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
330 break;
331 }
332
333 if (Status != STATUS_PENDING) {
334 Irp->IoStatus.Status = Status;
335 IoCompleteRequest(Irp, IO_NO_INCREMENT);
336 }
337
338 DPRINT("Leaving. Status 0x%X\n", Status);
339
340 return Status;
341 }
342
343 NTSTATUS
344 STDCALL
345 PdoPowerControl(
346 PDEVICE_OBJECT DeviceObject,
347 PIRP Irp)
348 /*
349 * FUNCTION: Handle power management IRPs for the child device
350 * ARGUMENTS:
351 * DeviceObject = Pointer to physical device object of the child device
352 * Irp = Pointer to IRP that should be handled
353 * RETURNS:
354 * Status
355 */
356 {
357 PIO_STACK_LOCATION IrpSp;
358 NTSTATUS Status;
359
360 DPRINT("Called\n");
361
362 IrpSp = IoGetCurrentIrpStackLocation(Irp);
363
364 switch (IrpSp->MinorFunction) {
365 case IRP_MN_SET_POWER:
366 Status = PdoSetPower(DeviceObject, Irp, IrpSp);
367 break;
368
369 default:
370 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
371 Status = STATUS_NOT_IMPLEMENTED;
372 break;
373 }
374
375 if (Status != STATUS_PENDING) {
376 Irp->IoStatus.Status = Status;
377 IoCompleteRequest(Irp, IO_NO_INCREMENT);
378 }
379
380 DPRINT("Leaving. Status 0x%X\n", Status);
381
382 return Status;
383 }
384
385 /* EOF */