1 /* 2 * PROJECT: ReactOS HAL 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * FILE: hal/halx86/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 return STATUS_NOT_SUPPORTED; 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 TAG_HAL); 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 ObReferenceObject(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 TAG_HAL); 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 ObReferenceObject(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 TAG_HAL); 380 if (!ResourceList ) 381 { 382 /* Fail, no memory */ 383 Status = STATUS_INSUFFICIENT_RESOURCES; 384 ExFreePoolWithTag(RequirementsList, TAG_HAL); 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, TAG_HAL); 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 SIZE_T 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 TAG_HAL); 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 SIZE_T 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 TAG_HAL); 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 UNIMPLEMENTED_DBGBREAK("HAL: PnP Driver WMI!\n"); 817 return STATUS_SUCCESS; 818 } 819 820 NTSTATUS 821 NTAPI 822 HalpDispatchPower(IN PDEVICE_OBJECT DeviceObject, 823 IN PIRP Irp) 824 { 825 PFDO_EXTENSION FdoExtension; 826 827 DPRINT("HAL: PnP Driver Power!\n"); 828 FdoExtension = DeviceObject->DeviceExtension; 829 if (FdoExtension->ExtensionType == FdoExtensionType) 830 { 831 PoStartNextPowerIrp(Irp); 832 IoSkipCurrentIrpStackLocation(Irp); 833 return PoCallDriver(FdoExtension->AttachedDeviceObject, Irp); 834 } 835 else 836 { 837 PoStartNextPowerIrp(Irp); 838 Irp->IoStatus.Status = STATUS_SUCCESS; 839 IoCompleteRequest(Irp, IO_NO_INCREMENT); 840 return STATUS_SUCCESS; 841 } 842 } 843 844 NTSTATUS 845 NTAPI 846 HalpDriverEntry(IN PDRIVER_OBJECT DriverObject, 847 IN PUNICODE_STRING RegistryPath) 848 { 849 NTSTATUS Status; 850 PDEVICE_OBJECT TargetDevice = NULL; 851 852 DPRINT("HAL: PnP Driver ENTRY!\n"); 853 854 /* This is us */ 855 HalpDriverObject = DriverObject; 856 857 /* Set up add device */ 858 DriverObject->DriverExtension->AddDevice = HalpAddDevice; 859 860 /* Set up the callouts */ 861 DriverObject->MajorFunction[IRP_MJ_PNP] = HalpDispatchPnp; 862 DriverObject->MajorFunction[IRP_MJ_POWER] = HalpDispatchPower; 863 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HalpDispatchWmi; 864 865 /* Create the PDO */ 866 Status = IoCreateDevice(DriverObject, 867 0, 868 NULL, 869 FILE_DEVICE_CONTROLLER, 870 0, 871 FALSE, 872 &TargetDevice); 873 if (!NT_SUCCESS(Status)) 874 return Status; 875 876 TargetDevice->Flags &= ~DO_DEVICE_INITIALIZING; 877 878 /* Set up the device stack */ 879 Status = HalpAddDevice(DriverObject, TargetDevice); 880 if (!NT_SUCCESS(Status)) 881 { 882 IoDeleteDevice(TargetDevice); 883 return Status; 884 } 885 886 /* Tell the PnP manager about us */ 887 Status = IoReportDetectedDevice(DriverObject, 888 InterfaceTypeUndefined, 889 -1, 890 -1, 891 NULL, 892 NULL, 893 FALSE, 894 &TargetDevice); 895 896 /* Return to kernel */ 897 return Status; 898 } 899 900 NTSTATUS 901 NTAPI 902 HaliInitPnpDriver(VOID) 903 { 904 NTSTATUS Status; 905 UNICODE_STRING DriverString; 906 PAGED_CODE(); 907 908 /* Create the driver */ 909 RtlInitUnicodeString(&DriverString, L"\\Driver\\ACPI_HAL"); 910 Status = IoCreateDriver(&DriverString, HalpDriverEntry); 911 912 /* Return status */ 913 return Status; 914 } 915 916 /* EOF */ 917