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