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