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