[HALACPI]
[reactos.git] / hal / halx86 / acpi / halpnpdd.c
1 /*
2 * PROJECT: ReactOS HAL
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: hal/halx86/generic/acpi/halpnpdd.c
5 * PURPOSE: HAL Plug and Play Device Driver
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <hal.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 typedef enum _EXTENSION_TYPE
16 {
17 PdoExtensionType = 0xC0,
18 FdoExtensionType
19 } EXTENSION_TYPE;
20
21 typedef enum _PDO_TYPE
22 {
23 AcpiPdo = 0x80,
24 WdPdo
25 } PDO_TYPE;
26
27 typedef struct _FDO_EXTENSION
28 {
29 EXTENSION_TYPE ExtensionType;
30 struct _PDO_EXTENSION* ChildPdoList;
31 PDEVICE_OBJECT PhysicalDeviceObject;
32 PDEVICE_OBJECT FunctionalDeviceObject;
33 PDEVICE_OBJECT AttachedDeviceObject;
34 } FDO_EXTENSION, *PFDO_EXTENSION;
35
36 typedef struct _PDO_EXTENSION
37 {
38 EXTENSION_TYPE ExtensionType;
39 struct _PDO_EXTENSION* Next;
40 PDEVICE_OBJECT PhysicalDeviceObject;
41 PFDO_EXTENSION ParentFdoExtension;
42 PDO_TYPE PdoType;
43 PDESCRIPTION_HEADER WdTable;
44 LONG InterfaceReferenceCount;
45 } PDO_EXTENSION, *PPDO_EXTENSION;
46
47 /* GLOBALS ********************************************************************/
48
49 PDRIVER_OBJECT HalpDriverObject;
50
51 /* PRIVATE FUNCTIONS **********************************************************/
52
53 VOID
54 NTAPI
55 HalpReportDetectedDevices(IN PDRIVER_OBJECT DriverObject,
56 IN PVOID Context,
57 IN ULONG Count)
58 {
59 PFDO_EXTENSION FdoExtension = Context;
60
61 /* Invalidate device relations since we added a new device */
62 IoInvalidateDeviceRelations(FdoExtension->PhysicalDeviceObject, BusRelations);
63 }
64
65 NTSTATUS
66 NTAPI
67 HalpAddDevice(IN PDRIVER_OBJECT DriverObject,
68 IN PDEVICE_OBJECT TargetDevice)
69 {
70 NTSTATUS Status;
71 PFDO_EXTENSION FdoExtension;
72 PPDO_EXTENSION PdoExtension;
73 PDEVICE_OBJECT DeviceObject, AttachedDevice;
74 PDEVICE_OBJECT PdoDeviceObject;
75 PDESCRIPTION_HEADER Wdrt;
76
77 DPRINT("HAL: PnP Driver ADD!\n");
78
79 /* Create the FDO */
80 Status = IoCreateDevice(DriverObject,
81 sizeof(FDO_EXTENSION),
82 NULL,
83 FILE_DEVICE_BUS_EXTENDER,
84 0,
85 FALSE,
86 &DeviceObject);
87 if (!NT_SUCCESS(Status))
88 {
89 /* Should not happen */
90 DbgBreakPoint();
91 return Status;
92 }
93
94 /* Setup the FDO extension */
95 FdoExtension = DeviceObject->DeviceExtension;
96 FdoExtension->ExtensionType = FdoExtensionType;
97 FdoExtension->PhysicalDeviceObject = TargetDevice;
98 FdoExtension->FunctionalDeviceObject = DeviceObject;
99 FdoExtension->ChildPdoList = NULL;
100
101 /* FDO is done initializing */
102 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
103
104 /* Attach to the physical device object (the bus) */
105 AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject, TargetDevice);
106 if (!AttachedDevice)
107 {
108 /* Failed, undo everything */
109 IoDeleteDevice(DeviceObject);
110 return STATUS_NO_SUCH_DEVICE;
111 }
112
113 /* Save the attachment */
114 FdoExtension->AttachedDeviceObject = AttachedDevice;
115
116 /* Create the PDO */
117 Status = IoCreateDevice(DriverObject,
118 sizeof(PDO_EXTENSION),
119 NULL,
120 FILE_DEVICE_BUS_EXTENDER,
121 FILE_AUTOGENERATED_DEVICE_NAME,
122 FALSE,
123 &PdoDeviceObject);
124 if (!NT_SUCCESS(Status))
125 {
126 /* Fail */
127 DPRINT1("HAL: Could not create ACPI device object status=0x%08x\n", Status);
128 return Status;
129 }
130
131 /* Setup the PDO device extension */
132 PdoExtension = PdoDeviceObject->DeviceExtension;
133 PdoExtension->ExtensionType = PdoExtensionType;
134 PdoExtension->PhysicalDeviceObject = PdoDeviceObject;
135 PdoExtension->ParentFdoExtension = FdoExtension;
136 PdoExtension->PdoType = AcpiPdo;
137
138 /* Add the PDO to the head of the list */
139 PdoExtension->Next = FdoExtension->ChildPdoList;
140 FdoExtension->ChildPdoList = PdoExtension;
141
142 /* Initialization is finished */
143 PdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
144
145 /* Find the ACPI watchdog table */
146 Wdrt = HalAcpiGetTable(0, 'TRDW');
147 if (Wdrt)
148 {
149 /* FIXME: TODO */
150 DPRINT1("You have an ACPI Watchdog. That's great! You should be proud ;-)\n");
151 }
152
153 /* Register for reinitialization to report devices later */
154 IoRegisterBootDriverReinitialization(DriverObject,
155 HalpReportDetectedDevices,
156 FdoExtension);
157
158 /* Return status */
159 DPRINT("Device added %lx\n", Status);
160 return Status;
161 }
162
163 NTSTATUS
164 NTAPI
165 HalpQueryInterface(IN PDEVICE_OBJECT DeviceObject,
166 IN CONST GUID* InterfaceType,
167 IN USHORT Version,
168 IN PVOID InterfaceSpecificData,
169 IN ULONG InterfaceBufferSize,
170 IN PINTERFACE Interface,
171 OUT PULONG Length)
172 {
173 UNIMPLEMENTED;
174 while (TRUE);
175 return STATUS_NO_SUCH_DEVICE;
176 }
177
178 NTSTATUS
179 NTAPI
180 HalpQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
181 IN DEVICE_RELATION_TYPE RelationType,
182 OUT PDEVICE_RELATIONS* DeviceRelations)
183 {
184 EXTENSION_TYPE ExtensionType;
185 PPDO_EXTENSION PdoExtension;
186 PFDO_EXTENSION FdoExtension;
187 PDEVICE_RELATIONS PdoRelations, FdoRelations;
188 PDEVICE_OBJECT* ObjectEntry;
189 ULONG i = 0, PdoCount = 0;
190
191 /* Get FDO device extension and PDO count */
192 FdoExtension = DeviceObject->DeviceExtension;
193 ExtensionType = FdoExtension->ExtensionType;
194
195 /* What do they want? */
196 if (RelationType == BusRelations)
197 {
198 /* This better be an FDO */
199 if (ExtensionType == FdoExtensionType)
200 {
201 /* Count how many PDOs we have */
202 PdoExtension = FdoExtension->ChildPdoList;
203 while (PdoExtension)
204 {
205 /* Next one */
206 PdoExtension = PdoExtension->Next;
207 PdoCount++;
208 }
209
210 /* Add the PDOs that already exist in the device relations */
211 if (*DeviceRelations)
212 {
213 PdoCount += (*DeviceRelations)->Count;
214 }
215
216 /* Allocate our structure */
217 FdoRelations = ExAllocatePoolWithTag(PagedPool,
218 FIELD_OFFSET(DEVICE_RELATIONS,
219 Objects) +
220 sizeof(PDEVICE_OBJECT) * PdoCount,
221 ' laH');
222 if (!FdoRelations) return STATUS_INSUFFICIENT_RESOURCES;
223
224 /* Save our count */
225 FdoRelations->Count = PdoCount;
226
227 /* Query existing relations */
228 ObjectEntry = FdoRelations->Objects;
229 if (*DeviceRelations)
230 {
231 /* Check if there were any */
232 if ((*DeviceRelations)->Count)
233 {
234 /* Loop them all */
235 do
236 {
237 /* Copy into our structure */
238 *ObjectEntry++ = (*DeviceRelations)->Objects[i];
239 }
240 while (++i < (*DeviceRelations)->Count);
241 }
242
243 /* Free existing structure */
244 ExFreePool(*DeviceRelations);
245 }
246
247 /* Now check if we have a PDO list */
248 PdoExtension = FdoExtension->ChildPdoList;
249 if (PdoExtension)
250 {
251 /* Loop the PDOs */
252 do
253 {
254 /* Save our own PDO and reference it */
255 *ObjectEntry++ = PdoExtension->PhysicalDeviceObject;
256 ObfReferenceObject(PdoExtension->PhysicalDeviceObject);
257
258 /* Go to our next PDO */
259 PdoExtension = PdoExtension->Next;
260 }
261 while (PdoExtension);
262 }
263
264 /* Return the new structure */
265 *DeviceRelations = FdoRelations;
266 return STATUS_SUCCESS;
267 }
268 }
269 else
270 {
271 /* The only other thing we support is a target relation for the PDO */
272 if ((RelationType == TargetDeviceRelation) &&
273 (ExtensionType == PdoExtensionType))
274 {
275 /* Only one entry */
276 PdoRelations = ExAllocatePoolWithTag(PagedPool,
277 sizeof(DEVICE_RELATIONS),
278 ' laH');
279 if (!PdoRelations) return STATUS_INSUFFICIENT_RESOURCES;
280
281 /* Fill it out and reference us */
282 PdoRelations->Count = 1;
283 PdoRelations->Objects[0] = DeviceObject;
284 ObfReferenceObject(DeviceObject);
285
286 /* Return it */
287 *DeviceRelations = PdoRelations;
288 return STATUS_SUCCESS;
289 }
290 }
291
292 /* We don't support anything else */
293 return STATUS_NOT_SUPPORTED;
294 }
295
296 NTSTATUS
297 NTAPI
298 HalpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject,
299 OUT PDEVICE_CAPABILITIES Capabilities)
300 {
301 //PPDO_EXTENSION PdoExtension;
302 NTSTATUS Status;
303 PAGED_CODE();
304
305 /* Get the extension and check for valid version */
306 //PdoExtension = DeviceObject->DeviceExtension;
307 ASSERT(Capabilities->Version == 1);
308 if (Capabilities->Version == 1)
309 {
310 /* Can't lock or eject us */
311 Capabilities->LockSupported = FALSE;
312 Capabilities->EjectSupported = FALSE;
313
314 /* Can't remove or dock us */
315 Capabilities->Removable = FALSE;
316 Capabilities->DockDevice = FALSE;
317
318 /* Can't access us raw */
319 Capabilities->RawDeviceOK = FALSE;
320
321 /* We have a unique ID, and don't bother the user */
322 Capabilities->UniqueID = TRUE;
323 Capabilities->SilentInstall = TRUE;
324
325 /* Fill out the adress */
326 Capabilities->Address = InterfaceTypeUndefined;
327 Capabilities->UINumber = InterfaceTypeUndefined;
328
329 /* Fill out latencies */
330 Capabilities->D1Latency = 0;
331 Capabilities->D2Latency = 0;
332 Capabilities->D3Latency = 0;
333
334 /* Fill out supported device states */
335 Capabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
336 Capabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
337 Capabilities->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
338 Capabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
339
340 /* Done */
341 Status = STATUS_SUCCESS;
342 }
343 else
344 {
345 /* Fail */
346 Status = STATUS_NOT_SUPPORTED;
347 }
348
349 /* Return status */
350 return Status;
351 }
352
353 NTSTATUS
354 NTAPI
355 HalpQueryResources(IN PDEVICE_OBJECT DeviceObject,
356 OUT PCM_RESOURCE_LIST *Resources)
357 {
358 PPDO_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
359 NTSTATUS Status;
360 PCM_RESOURCE_LIST ResourceList;
361 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
362 PIO_RESOURCE_DESCRIPTOR Descriptor;
363 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDesc;
364 ULONG i;
365 PAGED_CODE();
366
367 /* Only the ACPI PDO has requirements */
368 if (DeviceExtension->PdoType == AcpiPdo)
369 {
370 /* Query ACPI requirements */
371 Status = HalpQueryAcpiResourceRequirements(&RequirementsList);
372 if (!NT_SUCCESS(Status)) return Status;
373
374 ASSERT(RequirementsList->AlternativeLists == 1);
375
376 /* Allocate the resourcel ist */
377 ResourceList = ExAllocatePoolWithTag(PagedPool,
378 sizeof(CM_RESOURCE_LIST),
379 ' laH');
380 if (!ResourceList )
381 {
382 /* Fail, no memory */
383 Status = STATUS_INSUFFICIENT_RESOURCES;
384 ExFreePoolWithTag(RequirementsList, ' laH');
385 return Status;
386 }
387
388 /* Initialize it */
389 RtlZeroMemory(ResourceList, sizeof(CM_RESOURCE_LIST));
390 ResourceList->Count = 1;
391
392 /* Setup the list fields */
393 ResourceList->List[0].BusNumber = -1;
394 ResourceList->List[0].InterfaceType = PNPBus;
395 ResourceList->List[0].PartialResourceList.Version = 1;
396 ResourceList->List[0].PartialResourceList.Revision = 1;
397 ResourceList->List[0].PartialResourceList.Count = 0;
398
399 /* Setup the first descriptor */
400 PartialDesc = ResourceList->List[0].PartialResourceList.PartialDescriptors;
401
402 /* Find the requirement descriptor for the SCI */
403 for (i = 0; i < RequirementsList->List[0].Count; i++)
404 {
405 /* Get this descriptor */
406 Descriptor = &RequirementsList->List[0].Descriptors[i];
407 if (Descriptor->Type == CmResourceTypeInterrupt)
408 {
409 /* Copy requirements descriptor into resource descriptor */
410 PartialDesc->Type = CmResourceTypeInterrupt;
411 PartialDesc->ShareDisposition = Descriptor->ShareDisposition;
412 PartialDesc->Flags = Descriptor->Flags;
413 ASSERT(Descriptor->u.Interrupt.MinimumVector ==
414 Descriptor->u.Interrupt.MaximumVector);
415 PartialDesc->u.Interrupt.Vector = Descriptor->u.Interrupt.MinimumVector;
416 PartialDesc->u.Interrupt.Level = Descriptor->u.Interrupt.MinimumVector;
417 PartialDesc->u.Interrupt.Affinity = 0xFFFFFFFF;
418
419 ResourceList->List[0].PartialResourceList.Count++;
420
421 break;
422 }
423 }
424
425 /* Return resources and success */
426 *Resources = ResourceList;
427
428 ExFreePoolWithTag(RequirementsList, ' laH');
429
430 return STATUS_SUCCESS;
431 }
432 else if (DeviceExtension->PdoType == WdPdo)
433 {
434 /* Watchdog doesn't */
435 return STATUS_NOT_SUPPORTED;
436 }
437 else
438 {
439 /* This shouldn't happen */
440 return STATUS_UNSUCCESSFUL;
441 }
442 }
443
444 NTSTATUS
445 NTAPI
446 HalpQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject,
447 OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements)
448 {
449 PPDO_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
450 PAGED_CODE();
451
452 /* Only the ACPI PDO has requirements */
453 if (DeviceExtension->PdoType == AcpiPdo)
454 {
455 /* Query ACPI requirements */
456 return HalpQueryAcpiResourceRequirements(Requirements);
457 }
458 else if (DeviceExtension->PdoType == WdPdo)
459 {
460 /* Watchdog doesn't */
461 return STATUS_NOT_SUPPORTED;
462 }
463 else
464 {
465 /* This shouldn't happen */
466 return STATUS_UNSUCCESSFUL;
467 }
468 }
469
470 NTSTATUS
471 NTAPI
472 HalpQueryIdPdo(IN PDEVICE_OBJECT DeviceObject,
473 IN BUS_QUERY_ID_TYPE IdType,
474 OUT PUSHORT *BusQueryId)
475 {
476 PPDO_EXTENSION PdoExtension;
477 PDO_TYPE PdoType;
478 PWCHAR CurrentId;
479 WCHAR Id[100];
480 NTSTATUS Status;
481 ULONG Length = 0;
482 PWCHAR Buffer;
483
484 /* Get the PDO type */
485 PdoExtension = DeviceObject->DeviceExtension;
486 PdoType = PdoExtension->PdoType;
487
488 /* What kind of ID is being requested? */
489 DPRINT("ID: %d\n", IdType);
490 switch (IdType)
491 {
492 case BusQueryDeviceID:
493 case BusQueryHardwareIDs:
494
495 /* What kind of PDO is this? */
496 if (PdoType == AcpiPdo)
497 {
498 /* ACPI ID */
499 CurrentId = L"ACPI_HAL\\PNP0C08";
500 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
501 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
502
503 CurrentId = L"*PNP0C08";
504 RtlCopyMemory(&Id[wcslen(Id) + 1], CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
505 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
506 }
507 else if (PdoType == WdPdo)
508 {
509 /* WatchDog ID */
510 CurrentId = L"ACPI_HAL\\PNP0C18";
511 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
512 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
513
514 CurrentId = L"*PNP0C18";
515 RtlCopyMemory(&Id[wcslen(Id) + 1], CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
516 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
517 }
518 else
519 {
520 /* Unknown */
521 return STATUS_NOT_SUPPORTED;
522 }
523 break;
524
525 case BusQueryInstanceID:
526
527 /* Instance ID */
528 CurrentId = L"0";
529 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
530 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
531 break;
532
533 case BusQueryCompatibleIDs:
534 default:
535
536 /* We don't support anything else */
537 return STATUS_NOT_SUPPORTED;
538 }
539
540
541 /* Allocate the buffer */
542 Buffer = ExAllocatePoolWithTag(PagedPool,
543 Length + sizeof(UNICODE_NULL),
544 ' laH');
545 if (Buffer)
546 {
547 /* Copy the string and null-terminate it */
548 RtlCopyMemory(Buffer, Id, Length);
549 Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
550
551 /* Return string */
552 *BusQueryId = Buffer;
553 Status = STATUS_SUCCESS;
554 DPRINT("Returning: %S\n", *BusQueryId);
555 }
556 else
557 {
558 /* Fail */
559 Status = STATUS_INSUFFICIENT_RESOURCES;
560 }
561
562 /* Return status */
563 return Status;
564 }
565
566 NTSTATUS
567 NTAPI
568 HalpQueryIdFdo(IN PDEVICE_OBJECT DeviceObject,
569 IN BUS_QUERY_ID_TYPE IdType,
570 OUT PUSHORT *BusQueryId)
571 {
572 NTSTATUS Status;
573 ULONG Length;
574 PWCHAR Id;
575 PWCHAR Buffer;
576
577 /* What kind of ID is being requested? */
578 DPRINT("ID: %d\n", IdType);
579 switch (IdType)
580 {
581 case BusQueryDeviceID:
582 /* HACK */
583 Id = L"Root\\ACPI_HAL";
584 break;
585
586 case BusQueryHardwareIDs:
587
588 /* This is our hardware ID */
589 Id = HalHardwareIdString;
590 break;
591
592 case BusQueryInstanceID:
593
594 /* And our instance ID */
595 Id = L"0";
596 break;
597
598 default:
599
600 /* We don't support anything else */
601 return STATUS_NOT_SUPPORTED;
602 }
603
604 /* Calculate the length */
605 Length = (wcslen(Id) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
606
607 /* Allocate the buffer */
608 Buffer = ExAllocatePoolWithTag(PagedPool,
609 Length + sizeof(UNICODE_NULL),
610 ' laH');
611 if (Buffer)
612 {
613 /* Copy the string and null-terminate it */
614 RtlCopyMemory(Buffer, Id, Length);
615 Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
616
617 /* Return string */
618 *BusQueryId = Buffer;
619 Status = STATUS_SUCCESS;
620 DPRINT("Returning: %S\n", *BusQueryId);
621 }
622 else
623 {
624 /* Fail */
625 Status = STATUS_INSUFFICIENT_RESOURCES;
626 }
627
628 /* Return status */
629 return Status;
630 }
631
632 NTSTATUS
633 NTAPI
634 HalpDispatchPnp(IN PDEVICE_OBJECT DeviceObject,
635 IN PIRP Irp)
636 {
637 PIO_STACK_LOCATION IoStackLocation;
638 //PPDO_EXTENSION PdoExtension;
639 PFDO_EXTENSION FdoExtension;
640 NTSTATUS Status;
641 UCHAR Minor;
642
643 /* Get the device extension and stack location */
644 FdoExtension = DeviceObject->DeviceExtension;
645 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
646 Minor = IoStackLocation->MinorFunction;
647
648 /* FDO? */
649 if (FdoExtension->ExtensionType == FdoExtensionType)
650 {
651 /* Query the IRP type */
652 switch (Minor)
653 {
654 case IRP_MN_QUERY_DEVICE_RELATIONS:
655
656 /* Call the worker */
657 DPRINT("Querying device relations for FDO\n");
658 Status = HalpQueryDeviceRelations(DeviceObject,
659 IoStackLocation->Parameters.QueryDeviceRelations.Type,
660 (PVOID)&Irp->IoStatus.Information);
661 break;
662
663 case IRP_MN_QUERY_INTERFACE:
664
665 /* Call the worker */
666 DPRINT("Querying interface for FDO\n");
667 Status = HalpQueryInterface(DeviceObject,
668 IoStackLocation->Parameters.QueryInterface.InterfaceType,
669 IoStackLocation->Parameters.QueryInterface.Size,
670 IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData,
671 IoStackLocation->Parameters.QueryInterface.Version,
672 IoStackLocation->Parameters.QueryInterface.Interface,
673 (PVOID)&Irp->IoStatus.Information);
674 break;
675
676
677 case IRP_MN_QUERY_ID:
678
679 /* Call the worker */
680 DPRINT("Querying ID for FDO\n");
681 Status = HalpQueryIdFdo(DeviceObject,
682 IoStackLocation->Parameters.QueryId.IdType,
683 (PVOID)&Irp->IoStatus.Information);
684 break;
685
686 case IRP_MN_QUERY_CAPABILITIES:
687
688 /* Call the worker */
689 DPRINT("Querying the capabilities for the FDO\n");
690 Status = HalpQueryCapabilities(DeviceObject,
691 IoStackLocation->Parameters.DeviceCapabilities.Capabilities);
692 break;
693
694 default:
695
696 DPRINT("Other IRP: %lx\n", Minor);
697 Status = Irp->IoStatus.Status;
698 break;
699 }
700
701 /* Nowhere for the IRP to go since we also own the PDO */
702 Irp->IoStatus.Status = Status;
703 IoCompleteRequest(Irp, IO_NO_INCREMENT);
704 return Status;
705 }
706 else
707 {
708 /* This is a PDO instead */
709 ASSERT(FdoExtension->ExtensionType == PdoExtensionType);
710 //PdoExtension = (PPDO_EXTENSION)FdoExtension;
711 /* Query the IRP type */
712 Status = STATUS_SUCCESS;
713 switch (Minor)
714 {
715 case IRP_MN_START_DEVICE:
716
717 /* We only care about a PCI PDO */
718 DPRINT1("Start device received\n");
719 /* Complete the IRP normally */
720 break;
721
722 case IRP_MN_REMOVE_DEVICE:
723
724 /* Check if this is a PCI device */
725 DPRINT1("Remove device received\n");
726
727 /* We're done */
728 Status = STATUS_SUCCESS;
729 break;
730
731 case IRP_MN_SURPRISE_REMOVAL:
732
733 /* Inherit whatever status we had */
734 DPRINT1("Surprise removal IRP\n");
735 Status = Irp->IoStatus.Status;
736 break;
737
738 case IRP_MN_QUERY_DEVICE_RELATIONS:
739
740 /* Query the device relations */
741 DPRINT("Querying PDO relations\n");
742 Status = HalpQueryDeviceRelations(DeviceObject,
743 IoStackLocation->Parameters.QueryDeviceRelations.Type,
744 (PVOID)&Irp->IoStatus.Information);
745 break;
746
747 case IRP_MN_QUERY_INTERFACE:
748
749 /* Call the worker */
750 DPRINT("Querying interface for PDO\n");
751 Status = HalpQueryInterface(DeviceObject,
752 IoStackLocation->Parameters.QueryInterface.InterfaceType,
753 IoStackLocation->Parameters.QueryInterface.Size,
754 IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData,
755 IoStackLocation->Parameters.QueryInterface.Version,
756 IoStackLocation->Parameters.QueryInterface.Interface,
757 (PVOID)&Irp->IoStatus.Information);
758 break;
759
760 case IRP_MN_QUERY_CAPABILITIES:
761
762 /* Call the worker */
763 DPRINT("Querying the capabilities for the PDO\n");
764 Status = HalpQueryCapabilities(DeviceObject,
765 IoStackLocation->Parameters.DeviceCapabilities.Capabilities);
766 break;
767
768 case IRP_MN_QUERY_RESOURCES:
769
770 /* Call the worker */
771 DPRINT("Querying the resources for the PDO\n");
772 Status = HalpQueryResources(DeviceObject, (PVOID)&Irp->IoStatus.Information);
773 break;
774
775 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
776
777 /* Call the worker */
778 DPRINT("Querying the resource requirements for the PDO\n");
779 Status = HalpQueryResourceRequirements(DeviceObject,
780 (PVOID)&Irp->IoStatus.Information);
781 break;
782
783 case IRP_MN_QUERY_ID:
784
785 /* Call the worker */
786 DPRINT("Query the ID for the PDO\n");
787 Status = HalpQueryIdPdo(DeviceObject,
788 IoStackLocation->Parameters.QueryId.IdType,
789 (PVOID)&Irp->IoStatus.Information);
790 break;
791
792 default:
793
794 /* We don't handle anything else, so inherit the old state */
795 DPRINT("Illegal IRP: %lx\n", Minor);
796 Status = Irp->IoStatus.Status;
797 break;
798 }
799
800 /* If it's not supported, inherit the old status */
801 if (Status == STATUS_NOT_SUPPORTED) Status = Irp->IoStatus.Status;
802
803 /* Complete the IRP */
804 DPRINT("IRP completed with status: %lx\n", Status);
805 Irp->IoStatus.Status = Status;
806 IoCompleteRequest(Irp, IO_NO_INCREMENT);
807 return Status;
808 }
809 }
810
811 NTSTATUS
812 NTAPI
813 HalpDispatchWmi(IN PDEVICE_OBJECT DeviceObject,
814 IN PIRP Irp)
815 {
816 DPRINT1("HAL: PnP Driver WMI!\n");
817 while (TRUE);
818 return STATUS_SUCCESS;
819 }
820
821 NTSTATUS
822 NTAPI
823 HalpDispatchPower(IN PDEVICE_OBJECT DeviceObject,
824 IN PIRP Irp)
825 {
826 DPRINT1("HAL: PnP Driver Power!\n");
827 return STATUS_SUCCESS;
828 }
829
830 NTSTATUS
831 NTAPI
832 HalpDriverEntry(IN PDRIVER_OBJECT DriverObject,
833 IN PUNICODE_STRING RegistryPath)
834 {
835 NTSTATUS Status;
836 PDEVICE_OBJECT TargetDevice = NULL;
837
838 DPRINT("HAL: PnP Driver ENTRY!\n");
839
840 /* This is us */
841 HalpDriverObject = DriverObject;
842
843 /* Set up add device */
844 DriverObject->DriverExtension->AddDevice = HalpAddDevice;
845
846 /* Set up the callouts */
847 DriverObject->MajorFunction[IRP_MJ_PNP] = HalpDispatchPnp;
848 DriverObject->MajorFunction[IRP_MJ_POWER] = HalpDispatchPower;
849 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HalpDispatchWmi;
850
851 /* Create the PDO */
852 Status = IoCreateDevice(DriverObject,
853 0,
854 NULL,
855 FILE_DEVICE_CONTROLLER,
856 0,
857 FALSE,
858 &TargetDevice);
859 if (!NT_SUCCESS(Status))
860 return Status;
861
862 TargetDevice->Flags &= ~DO_DEVICE_INITIALIZING;
863
864 /* Set up the device stack */
865 Status = HalpAddDevice(DriverObject, TargetDevice);
866 if (!NT_SUCCESS(Status))
867 {
868 IoDeleteDevice(TargetDevice);
869 return Status;
870 }
871
872 /* Tell the PnP manager about us */
873 Status = IoReportDetectedDevice(DriverObject,
874 InterfaceTypeUndefined,
875 -1,
876 -1,
877 NULL,
878 NULL,
879 FALSE,
880 &TargetDevice);
881
882 /* Return to kernel */
883 return Status;
884 }
885
886 NTSTATUS
887 NTAPI
888 HaliInitPnpDriver(VOID)
889 {
890 NTSTATUS Status;
891 UNICODE_STRING DriverString;
892 PAGED_CODE();
893
894 /* Create the driver */
895 RtlInitUnicodeString(&DriverString, L"\\Driver\\ACPI_HAL");
896 Status = IoCreateDriver(&DriverString, HalpDriverEntry);
897
898 /* Return status */
899 return Status;
900 }
901
902 /* EOF */