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