1 #ifndef UNIT_TEST 2 #include "precomp.h" 3 4 #include <initguid.h> 5 #include <poclass.h> 6 7 #define NDEBUG 8 #include <debug.h> 9 10 #ifdef ALLOC_PRAGMA 11 #pragma alloc_text (PAGE, Bus_PDO_PnP) 12 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceCaps) 13 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceId) 14 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceText) 15 #pragma alloc_text (PAGE, Bus_PDO_QueryResources) 16 #pragma alloc_text (PAGE, Bus_PDO_QueryResourceRequirements) 17 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceRelations) 18 #pragma alloc_text (PAGE, Bus_PDO_QueryBusInformation) 19 #pragma alloc_text (PAGE, Bus_GetDeviceCapabilities) 20 #endif 21 22 NTSTATUS 23 Bus_PDO_PnP ( 24 PDEVICE_OBJECT DeviceObject, 25 PIRP Irp, 26 PIO_STACK_LOCATION IrpStack, 27 PPDO_DEVICE_DATA DeviceData 28 ) 29 { 30 NTSTATUS status; 31 POWER_STATE state; 32 struct acpi_device *device = NULL; 33 34 PAGED_CODE (); 35 36 if (DeviceData->AcpiHandle) 37 acpi_bus_get_device(DeviceData->AcpiHandle, &device); 38 39 // 40 // NB: Because we are a bus enumerator, we have no one to whom we could 41 // defer these irps. Therefore we do not pass them down but merely 42 // return them. 43 // 44 45 switch (IrpStack->MinorFunction) { 46 47 case IRP_MN_START_DEVICE: 48 // 49 // Here we do what ever initialization and ``turning on'' that is 50 // required to allow others to access this device. 51 // Power up the device. 52 // 53 if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) && 54 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D0))) 55 { 56 DPRINT1("Device %x failed to start!\n", DeviceData->AcpiHandle); 57 status = STATUS_UNSUCCESSFUL; 58 break; 59 } 60 61 DeviceData->InterfaceName.Length = 0; 62 status = STATUS_SUCCESS; 63 64 if (!device) 65 { 66 status = IoRegisterDeviceInterface(DeviceData->Common.Self, 67 &GUID_DEVICE_SYS_BUTTON, 68 NULL, 69 &DeviceData->InterfaceName); 70 } 71 else if (device->flags.hardware_id && 72 strstr(device->pnp.hardware_id, ACPI_THERMAL_HID)) 73 { 74 status = IoRegisterDeviceInterface(DeviceData->Common.Self, 75 &GUID_DEVICE_THERMAL_ZONE, 76 NULL, 77 &DeviceData->InterfaceName); 78 } 79 else if (device->flags.hardware_id && 80 strstr(device->pnp.hardware_id, ACPI_FAN_HID)) 81 { 82 status = IoRegisterDeviceInterface(DeviceData->Common.Self, 83 &GUID_DEVICE_FAN, 84 NULL, 85 &DeviceData->InterfaceName); 86 } 87 else if (device->flags.hardware_id && 88 strstr(device->pnp.hardware_id, ACPI_BUTTON_HID_LID)) 89 { 90 status = IoRegisterDeviceInterface(DeviceData->Common.Self, 91 &GUID_DEVICE_LID, 92 NULL, 93 &DeviceData->InterfaceName); 94 } 95 else if (device->flags.hardware_id && 96 strstr(device->pnp.hardware_id, ACPI_PROCESSOR_HID)) 97 { 98 status = IoRegisterDeviceInterface(DeviceData->Common.Self, 99 &GUID_DEVICE_PROCESSOR, 100 NULL, 101 &DeviceData->InterfaceName); 102 } 103 104 /* Failure to register an interface is not a fatal failure so don't return a failure status */ 105 if (NT_SUCCESS(status) && DeviceData->InterfaceName.Length != 0) 106 IoSetDeviceInterfaceState(&DeviceData->InterfaceName, TRUE); 107 108 state.DeviceState = PowerDeviceD0; 109 PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state); 110 DeviceData->Common.DevicePowerState = PowerDeviceD0; 111 SET_NEW_PNP_STATE(DeviceData->Common, Started); 112 status = STATUS_SUCCESS; 113 break; 114 115 case IRP_MN_STOP_DEVICE: 116 117 if (DeviceData->InterfaceName.Length != 0) 118 IoSetDeviceInterfaceState(&DeviceData->InterfaceName, FALSE); 119 120 // 121 // Here we shut down the device and give up and unmap any resources 122 // we acquired for the device. 123 // 124 if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) && 125 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D3))) 126 { 127 DPRINT1("Device %x failed to stop!\n", DeviceData->AcpiHandle); 128 status = STATUS_UNSUCCESSFUL; 129 break; 130 } 131 132 state.DeviceState = PowerDeviceD3; 133 PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state); 134 DeviceData->Common.DevicePowerState = PowerDeviceD3; 135 SET_NEW_PNP_STATE(DeviceData->Common, Stopped); 136 status = STATUS_SUCCESS; 137 break; 138 139 140 case IRP_MN_QUERY_STOP_DEVICE: 141 142 // 143 // No reason here why we can't stop the device. 144 // If there were a reason we should speak now, because answering success 145 // here may result in a stop device irp. 146 // 147 148 SET_NEW_PNP_STATE(DeviceData->Common, StopPending); 149 status = STATUS_SUCCESS; 150 break; 151 152 case IRP_MN_CANCEL_STOP_DEVICE: 153 154 // 155 // The stop was canceled. Whatever state we set, or resources we put 156 // on hold in anticipation of the forthcoming STOP device IRP should be 157 // put back to normal. Someone, in the long list of concerned parties, 158 // has failed the stop device query. 159 // 160 161 // 162 // First check to see whether you have received cancel-stop 163 // without first receiving a query-stop. This could happen if someone 164 // above us fails a query-stop and passes down the subsequent 165 // cancel-stop. 166 // 167 168 if (StopPending == DeviceData->Common.DevicePnPState) 169 { 170 // 171 // We did receive a query-stop, so restore. 172 // 173 RESTORE_PREVIOUS_PNP_STATE(DeviceData->Common); 174 } 175 status = STATUS_SUCCESS;// We must not fail this IRP. 176 break; 177 178 case IRP_MN_REMOVE_DEVICE: 179 // 180 // We handle REMOVE_DEVICE just like STOP_DEVICE. This is because 181 // the device is still physically present (or at least we don't know any better) 182 // so we have to retain the PDO after stopping and removing power from it. 183 // 184 if (DeviceData->InterfaceName.Length != 0) 185 IoSetDeviceInterfaceState(&DeviceData->InterfaceName, FALSE); 186 187 if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) && 188 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D3))) 189 { 190 DPRINT1("Device %x failed to enter D3!\n", DeviceData->AcpiHandle); 191 state.DeviceState = PowerDeviceD3; 192 PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state); 193 DeviceData->Common.DevicePowerState = PowerDeviceD3; 194 } 195 196 SET_NEW_PNP_STATE(DeviceData->Common, Stopped); 197 status = STATUS_SUCCESS; 198 break; 199 200 case IRP_MN_QUERY_REMOVE_DEVICE: 201 SET_NEW_PNP_STATE(DeviceData->Common, RemovalPending); 202 status = STATUS_SUCCESS; 203 break; 204 205 case IRP_MN_CANCEL_REMOVE_DEVICE: 206 if (RemovalPending == DeviceData->Common.DevicePnPState) 207 { 208 RESTORE_PREVIOUS_PNP_STATE(DeviceData->Common); 209 } 210 status = STATUS_SUCCESS; 211 break; 212 213 case IRP_MN_QUERY_CAPABILITIES: 214 215 // 216 // Return the capabilities of a device, such as whether the device 217 // can be locked or ejected..etc 218 // 219 220 status = Bus_PDO_QueryDeviceCaps(DeviceData, Irp); 221 222 break; 223 224 case IRP_MN_QUERY_ID: 225 226 // Query the IDs of the device 227 status = Bus_PDO_QueryDeviceId(DeviceData, Irp); 228 229 break; 230 231 case IRP_MN_QUERY_DEVICE_RELATIONS: 232 233 DPRINT("\tQueryDeviceRelation Type: %s\n",DbgDeviceRelationString(\ 234 IrpStack->Parameters.QueryDeviceRelations.Type)); 235 236 status = Bus_PDO_QueryDeviceRelations(DeviceData, Irp); 237 238 break; 239 240 case IRP_MN_QUERY_DEVICE_TEXT: 241 242 status = Bus_PDO_QueryDeviceText(DeviceData, Irp); 243 244 break; 245 246 case IRP_MN_QUERY_RESOURCES: 247 248 status = Bus_PDO_QueryResources(DeviceData, Irp); 249 250 break; 251 252 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 253 254 status = Bus_PDO_QueryResourceRequirements(DeviceData, Irp); 255 256 break; 257 258 case IRP_MN_QUERY_BUS_INFORMATION: 259 260 status = Bus_PDO_QueryBusInformation(DeviceData, Irp); 261 262 break; 263 264 case IRP_MN_QUERY_INTERFACE: 265 266 status = Bus_PDO_QueryInterface(DeviceData, Irp); 267 268 break; 269 270 271 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: 272 273 // 274 // OPTIONAL for bus drivers. 275 // The PnP Manager sends this IRP to a device 276 // stack so filter and function drivers can adjust the 277 // resources required by the device, if appropriate. 278 // 279 280 //break; 281 282 //case IRP_MN_QUERY_PNP_DEVICE_STATE: 283 284 // 285 // OPTIONAL for bus drivers. 286 // The PnP Manager sends this IRP after the drivers for 287 // a device return success from the IRP_MN_START_DEVICE 288 // request. The PnP Manager also sends this IRP when a 289 // driver for the device calls IoInvalidateDeviceState. 290 // 291 292 // break; 293 294 //case IRP_MN_READ_CONFIG: 295 //case IRP_MN_WRITE_CONFIG: 296 297 // 298 // Bus drivers for buses with configuration space must handle 299 // this request for their child devices. Our devices don't 300 // have a config space. 301 // 302 303 // break; 304 305 //case IRP_MN_SET_LOCK: 306 307 // break; 308 309 default: 310 311 // 312 // For PnP requests to the PDO that we do not understand we should 313 // return the IRP WITHOUT setting the status or information fields. 314 // These fields may have already been set by a filter (eg acpi). 315 status = Irp->IoStatus.Status; 316 317 break; 318 } 319 320 Irp->IoStatus.Status = status; 321 IoCompleteRequest (Irp, IO_NO_INCREMENT); 322 323 return status; 324 } 325 326 NTSTATUS 327 Bus_PDO_QueryDeviceCaps( 328 PPDO_DEVICE_DATA DeviceData, 329 PIRP Irp ) 330 { 331 332 PIO_STACK_LOCATION stack; 333 PDEVICE_CAPABILITIES deviceCapabilities; 334 struct acpi_device *device = NULL; 335 ULONG i; 336 337 PAGED_CODE (); 338 339 if (DeviceData->AcpiHandle) 340 acpi_bus_get_device(DeviceData->AcpiHandle, &device); 341 342 stack = IoGetCurrentIrpStackLocation (Irp); 343 344 // 345 // Get the packet. 346 // 347 deviceCapabilities=stack->Parameters.DeviceCapabilities.Capabilities; 348 349 // 350 // Set the capabilities. 351 // 352 353 if (deviceCapabilities->Version != 1 || 354 deviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES)) 355 { 356 return STATUS_UNSUCCESSFUL; 357 } 358 359 deviceCapabilities->D1Latency = 0; 360 deviceCapabilities->D2Latency = 0; 361 deviceCapabilities->D3Latency = 0; 362 363 deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0; 364 deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD3; 365 deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3; 366 deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3; 367 368 for (i = 0; i < ACPI_D_STATE_COUNT && device; i++) 369 { 370 if (!device->power.states[i].flags.valid) 371 continue; 372 373 switch (i) 374 { 375 case ACPI_STATE_D0: 376 deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0; 377 break; 378 379 case ACPI_STATE_D1: 380 deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1; 381 deviceCapabilities->D1Latency = device->power.states[i].latency; 382 break; 383 384 case ACPI_STATE_D2: 385 deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD2; 386 deviceCapabilities->D2Latency = device->power.states[i].latency; 387 break; 388 389 case ACPI_STATE_D3: 390 deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3; 391 deviceCapabilities->D3Latency = device->power.states[i].latency; 392 break; 393 } 394 } 395 396 // We can wake the system from D1 397 deviceCapabilities->DeviceWake = PowerDeviceD1; 398 399 400 deviceCapabilities->DeviceD1 = 401 (deviceCapabilities->DeviceState[PowerSystemSleeping1] == PowerDeviceD1) ? TRUE : FALSE; 402 deviceCapabilities->DeviceD2 = 403 (deviceCapabilities->DeviceState[PowerSystemSleeping2] == PowerDeviceD2) ? TRUE : FALSE; 404 405 deviceCapabilities->WakeFromD0 = FALSE; 406 deviceCapabilities->WakeFromD1 = TRUE; //Yes we can 407 deviceCapabilities->WakeFromD2 = FALSE; 408 deviceCapabilities->WakeFromD3 = FALSE; 409 410 if (device) 411 { 412 deviceCapabilities->LockSupported = device->flags.lockable; 413 deviceCapabilities->EjectSupported = device->flags.ejectable; 414 deviceCapabilities->HardwareDisabled = !device->status.enabled && !device->status.functional; 415 deviceCapabilities->Removable = device->flags.removable; 416 deviceCapabilities->SurpriseRemovalOK = device->flags.surprise_removal_ok; 417 deviceCapabilities->UniqueID = device->flags.unique_id; 418 deviceCapabilities->NoDisplayInUI = !device->status.show_in_ui; 419 deviceCapabilities->Address = device->pnp.bus_address; 420 } 421 422 if (!device || 423 (device->flags.hardware_id && 424 (strstr(device->pnp.hardware_id, ACPI_BUTTON_HID_LID) || 425 strstr(device->pnp.hardware_id, ACPI_THERMAL_HID) || 426 strstr(device->pnp.hardware_id, ACPI_PROCESSOR_HID)))) 427 { 428 /* Allow ACPI to control the device if it is a lid button, 429 * a thermal zone, a processor, or a fixed feature button */ 430 deviceCapabilities->RawDeviceOK = TRUE; 431 } 432 433 deviceCapabilities->SilentInstall = FALSE; 434 deviceCapabilities->UINumber = (ULONG)-1; 435 436 return STATUS_SUCCESS; 437 438 } 439 440 NTSTATUS 441 Bus_PDO_QueryDeviceId( 442 PPDO_DEVICE_DATA DeviceData, 443 PIRP Irp ) 444 { 445 PIO_STACK_LOCATION stack; 446 PWCHAR buffer, src; 447 WCHAR temp[256]; 448 ULONG length, i; 449 NTSTATUS status = STATUS_SUCCESS; 450 struct acpi_device *Device; 451 452 PAGED_CODE (); 453 454 stack = IoGetCurrentIrpStackLocation (Irp); 455 456 switch (stack->Parameters.QueryId.IdType) { 457 458 case BusQueryDeviceID: 459 460 /* This is a REG_SZ value */ 461 462 if (DeviceData->AcpiHandle) 463 { 464 acpi_bus_get_device(DeviceData->AcpiHandle, &Device); 465 466 if (strcmp(Device->pnp.hardware_id, "Processor") == 0) 467 { 468 length = wcslen(ProcessorIdString); 469 wcscpy(temp, ProcessorIdString); 470 } 471 else 472 { 473 length = swprintf(temp, 474 L"ACPI\\%hs", 475 Device->pnp.hardware_id); 476 } 477 } 478 else 479 { 480 /* We know it's a fixed feature button because 481 * these are direct children of the ACPI root device 482 * and therefore have no handle 483 */ 484 length = swprintf(temp, 485 L"ACPI\\FixedButton"); 486 } 487 488 temp[length++] = UNICODE_NULL; 489 490 NT_ASSERT(length * sizeof(WCHAR) <= sizeof(temp)); 491 492 buffer = ExAllocatePoolWithTag(PagedPool, length * sizeof(WCHAR), 'IpcA'); 493 494 if (!buffer) { 495 status = STATUS_INSUFFICIENT_RESOURCES; 496 break; 497 } 498 499 RtlCopyMemory (buffer, temp, length * sizeof(WCHAR)); 500 Irp->IoStatus.Information = (ULONG_PTR) buffer; 501 DPRINT("BusQueryDeviceID: %ls\n",buffer); 502 break; 503 504 case BusQueryInstanceID: 505 506 /* This is a REG_SZ value */ 507 508 /* See comment in BusQueryDeviceID case */ 509 if(DeviceData->AcpiHandle) 510 { 511 acpi_bus_get_device(DeviceData->AcpiHandle, &Device); 512 513 if (Device->flags.unique_id) 514 length = swprintf(temp, 515 L"%hs", 516 Device->pnp.unique_id); 517 else 518 /* FIXME: Generate unique id! */ 519 length = swprintf(temp, L"%ls", L"0"); 520 } 521 else 522 { 523 /* FIXME: Generate unique id! */ 524 length = swprintf(temp, L"%ls", L"0"); 525 } 526 527 temp[length++] = UNICODE_NULL; 528 529 NT_ASSERT(length * sizeof(WCHAR) <= sizeof(temp)); 530 531 buffer = ExAllocatePoolWithTag(PagedPool, length * sizeof(WCHAR), 'IpcA'); 532 if (!buffer) { 533 status = STATUS_INSUFFICIENT_RESOURCES; 534 break; 535 } 536 537 RtlCopyMemory (buffer, temp, length * sizeof (WCHAR)); 538 DPRINT("BusQueryInstanceID: %ls\n",buffer); 539 Irp->IoStatus.Information = (ULONG_PTR) buffer; 540 break; 541 542 case BusQueryHardwareIDs: 543 544 /* This is a REG_MULTI_SZ value */ 545 length = 0; 546 status = STATUS_NOT_SUPPORTED; 547 548 /* See comment in BusQueryDeviceID case */ 549 if (DeviceData->AcpiHandle) 550 { 551 acpi_bus_get_device(DeviceData->AcpiHandle, &Device); 552 553 if (!Device->flags.hardware_id) 554 { 555 /* We don't have the ID to satisfy this request */ 556 break; 557 } 558 559 DPRINT("Device name: %s\n", Device->pnp.device_name); 560 DPRINT("Hardware ID: %s\n", Device->pnp.hardware_id); 561 562 if (strcmp(Device->pnp.hardware_id, "Processor") == 0) 563 { 564 length = ProcessorHardwareIds.Length / sizeof(WCHAR); 565 src = ProcessorHardwareIds.Buffer; 566 } 567 else 568 { 569 length += swprintf(&temp[length], 570 L"ACPI\\%hs", 571 Device->pnp.hardware_id); 572 temp[length++] = UNICODE_NULL; 573 574 length += swprintf(&temp[length], 575 L"*%hs", 576 Device->pnp.hardware_id); 577 temp[length++] = UNICODE_NULL; 578 temp[length++] = UNICODE_NULL; 579 src = temp; 580 } 581 } 582 else 583 { 584 length += swprintf(&temp[length], 585 L"ACPI\\FixedButton"); 586 temp[length++] = UNICODE_NULL; 587 588 length += swprintf(&temp[length], 589 L"*FixedButton"); 590 temp[length++] = UNICODE_NULL; 591 temp[length++] = UNICODE_NULL; 592 src = temp; 593 } 594 595 NT_ASSERT(length * sizeof(WCHAR) <= sizeof(temp)); 596 597 buffer = ExAllocatePoolWithTag(PagedPool, length * sizeof(WCHAR), 'IpcA'); 598 599 if (!buffer) { 600 status = STATUS_INSUFFICIENT_RESOURCES; 601 break; 602 } 603 604 RtlCopyMemory (buffer, src, length * sizeof(WCHAR)); 605 Irp->IoStatus.Information = (ULONG_PTR) buffer; 606 DPRINT("BusQueryHardwareIDs: %ls\n",buffer); 607 status = STATUS_SUCCESS; 608 break; 609 610 case BusQueryCompatibleIDs: 611 612 /* This is a REG_MULTI_SZ value */ 613 length = 0; 614 status = STATUS_NOT_SUPPORTED; 615 616 /* See comment in BusQueryDeviceID case */ 617 if (DeviceData->AcpiHandle) 618 { 619 acpi_bus_get_device(DeviceData->AcpiHandle, &Device); 620 621 if (!Device->flags.hardware_id) 622 { 623 /* We don't have the ID to satisfy this request */ 624 break; 625 } 626 627 DPRINT("Device name: %s\n", Device->pnp.device_name); 628 DPRINT("Hardware ID: %s\n", Device->pnp.hardware_id); 629 630 if (strcmp(Device->pnp.hardware_id, "Processor") == 0) 631 { 632 length += swprintf(&temp[length], 633 L"ACPI\\%hs", 634 Device->pnp.hardware_id); 635 temp[length++] = UNICODE_NULL; 636 637 length += swprintf(&temp[length], 638 L"*%hs", 639 Device->pnp.hardware_id); 640 temp[length++] = UNICODE_NULL; 641 temp[length++] = UNICODE_NULL; 642 } 643 else if (Device->flags.compatible_ids) 644 { 645 for (i = 0; i < Device->pnp.cid_list->Count; i++) 646 { 647 length += swprintf(&temp[length], 648 L"ACPI\\%hs", 649 Device->pnp.cid_list->Ids[i].String); 650 temp[length++] = UNICODE_NULL; 651 652 length += swprintf(&temp[length], 653 L"*%hs", 654 Device->pnp.cid_list->Ids[i].String); 655 temp[length++] = UNICODE_NULL; 656 } 657 658 temp[length++] = UNICODE_NULL; 659 } 660 else 661 { 662 /* No compatible IDs */ 663 break; 664 } 665 666 NT_ASSERT(length * sizeof(WCHAR) <= sizeof(temp)); 667 668 buffer = ExAllocatePoolWithTag(PagedPool, length * sizeof(WCHAR), 'IpcA'); 669 if (!buffer) 670 { 671 status = STATUS_INSUFFICIENT_RESOURCES; 672 break; 673 } 674 675 RtlCopyMemory (buffer, temp, length * sizeof(WCHAR)); 676 Irp->IoStatus.Information = (ULONG_PTR) buffer; 677 DPRINT("BusQueryCompatibleIDs: %ls\n",buffer); 678 status = STATUS_SUCCESS; 679 } 680 break; 681 682 default: 683 status = Irp->IoStatus.Status; 684 } 685 return status; 686 } 687 688 NTSTATUS 689 Bus_PDO_QueryDeviceText( 690 PPDO_DEVICE_DATA DeviceData, 691 PIRP Irp ) 692 { 693 PWCHAR Buffer, Temp; 694 PIO_STACK_LOCATION stack; 695 NTSTATUS status = Irp->IoStatus.Status; 696 PAGED_CODE (); 697 698 stack = IoGetCurrentIrpStackLocation (Irp); 699 700 switch (stack->Parameters.QueryDeviceText.DeviceTextType) { 701 702 case DeviceTextDescription: 703 704 if (!Irp->IoStatus.Information) { 705 if (wcsstr (DeviceData->HardwareIDs, L"PNP000") != 0) 706 Temp = L"Programmable interrupt controller"; 707 else if (wcsstr(DeviceData->HardwareIDs, L"PNP010") != 0) 708 Temp = L"System timer"; 709 else if (wcsstr(DeviceData->HardwareIDs, L"PNP020") != 0) 710 Temp = L"DMA controller"; 711 else if (wcsstr(DeviceData->HardwareIDs, L"PNP03") != 0) 712 Temp = L"Keyboard"; 713 else if (wcsstr(DeviceData->HardwareIDs, L"PNP040") != 0) 714 Temp = L"Parallel port"; 715 else if (wcsstr(DeviceData->HardwareIDs, L"PNP05") != 0) 716 Temp = L"Serial port"; 717 else if (wcsstr(DeviceData->HardwareIDs, L"PNP06") != 0) 718 Temp = L"Disk controller"; 719 else if (wcsstr(DeviceData->HardwareIDs, L"PNP07") != 0) 720 Temp = L"Disk controller"; 721 else if (wcsstr(DeviceData->HardwareIDs, L"PNP09") != 0) 722 Temp = L"Display adapter"; 723 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0A0") != 0) 724 Temp = L"Bus controller"; 725 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0E0") != 0) 726 Temp = L"PCMCIA controller"; 727 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0F") != 0) 728 Temp = L"Mouse device"; 729 else if (wcsstr(DeviceData->HardwareIDs, L"PNP8") != 0) 730 Temp = L"Network adapter"; 731 else if (wcsstr(DeviceData->HardwareIDs, L"PNPA0") != 0) 732 Temp = L"SCSI controller"; 733 else if (wcsstr(DeviceData->HardwareIDs, L"PNPB0") != 0) 734 Temp = L"Multimedia device"; 735 else if (wcsstr(DeviceData->HardwareIDs, L"PNPC00") != 0) 736 Temp = L"Modem"; 737 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0C") != 0) 738 Temp = L"Power Button"; 739 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0E") != 0) 740 Temp = L"Sleep Button"; 741 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0D") != 0) 742 Temp = L"Lid Switch"; 743 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C09") != 0) 744 Temp = L"ACPI Embedded Controller"; 745 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0B") != 0) 746 Temp = L"ACPI Fan"; 747 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 || 748 wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0) 749 Temp = L"PCI Root Bridge"; 750 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0A") != 0) 751 Temp = L"ACPI Battery"; 752 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0F") != 0) 753 Temp = L"PCI Interrupt Link"; 754 else if (wcsstr(DeviceData->HardwareIDs, L"ACPI_PWR") != 0) 755 Temp = L"ACPI Power Resource"; 756 else if (wcsstr(DeviceData->HardwareIDs, L"Processor") != 0) 757 { 758 if (ProcessorNameString != NULL) 759 Temp = ProcessorNameString; 760 else 761 Temp = L"Processor"; 762 } 763 else if (wcsstr(DeviceData->HardwareIDs, L"ThermalZone") != 0) 764 Temp = L"ACPI Thermal Zone"; 765 else if (wcsstr(DeviceData->HardwareIDs, L"ACPI0002") != 0) 766 Temp = L"Smart Battery"; 767 else if (wcsstr(DeviceData->HardwareIDs, L"ACPI0003") != 0) 768 Temp = L"AC Adapter"; 769 /* Simply checking if AcpiHandle is NULL eliminates the need to check 770 * for the 4 different names that ACPI knows the fixed feature button as internally 771 */ 772 else if (!DeviceData->AcpiHandle) 773 Temp = L"ACPI Fixed Feature Button"; 774 else 775 Temp = L"Other ACPI device"; 776 777 Buffer = ExAllocatePoolWithTag(PagedPool, (wcslen(Temp) + 1) * sizeof(WCHAR), 'IpcA'); 778 779 if (!Buffer) { 780 status = STATUS_INSUFFICIENT_RESOURCES; 781 break; 782 } 783 784 RtlCopyMemory (Buffer, Temp, (wcslen(Temp) + 1) * sizeof(WCHAR)); 785 786 DPRINT("\tDeviceTextDescription :%ws\n", Buffer); 787 788 Irp->IoStatus.Information = (ULONG_PTR) Buffer; 789 status = STATUS_SUCCESS; 790 } 791 break; 792 793 default: 794 break; 795 } 796 797 return status; 798 799 } 800 801 NTSTATUS 802 Bus_PDO_QueryResources( 803 PPDO_DEVICE_DATA DeviceData, 804 PIRP Irp ) 805 { 806 ULONG NumberOfResources = 0; 807 PCM_RESOURCE_LIST ResourceList; 808 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; 809 ACPI_STATUS AcpiStatus; 810 ACPI_BUFFER Buffer; 811 ACPI_RESOURCE* resource; 812 ULONG ResourceListSize; 813 ULONG i; 814 ULONGLONG BusNumber; 815 struct acpi_device *device; 816 817 if (!DeviceData->AcpiHandle) 818 { 819 return Irp->IoStatus.Status; 820 } 821 822 /* A bus number resource is not included in the list of current resources 823 * for the root PCI bus so we manually query one here and if we find it 824 * we create a resource list and add a bus number descriptor to it */ 825 if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 || 826 wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0) 827 { 828 acpi_bus_get_device(DeviceData->AcpiHandle, &device); 829 830 AcpiStatus = acpi_evaluate_integer(DeviceData->AcpiHandle, "_BBN", NULL, &BusNumber); 831 if (AcpiStatus != AE_OK) 832 { 833 #if 0 834 if (device->flags.unique_id) 835 { 836 /* FIXME: Try the unique ID */ 837 } 838 else 839 #endif 840 { 841 BusNumber = 0; 842 DPRINT1("Failed to find a bus number\n"); 843 } 844 } 845 else 846 { 847 DPRINT("Using _BBN for bus number\n"); 848 } 849 850 DPRINT("Found PCI root hub: %d\n", BusNumber); 851 852 ResourceListSize = sizeof(CM_RESOURCE_LIST); 853 ResourceList = ExAllocatePoolWithTag(PagedPool, ResourceListSize, 'RpcA'); 854 if (!ResourceList) 855 return STATUS_INSUFFICIENT_RESOURCES; 856 857 ResourceList->Count = 1; 858 ResourceList->List[0].InterfaceType = Internal; 859 ResourceList->List[0].BusNumber = 0; 860 ResourceList->List[0].PartialResourceList.Version = 1; 861 ResourceList->List[0].PartialResourceList.Revision = 1; 862 ResourceList->List[0].PartialResourceList.Count = 1; 863 ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; 864 865 ResourceDescriptor->Type = CmResourceTypeBusNumber; 866 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 867 ResourceDescriptor->u.BusNumber.Start = BusNumber; 868 ResourceDescriptor->u.BusNumber.Length = 1; 869 870 Irp->IoStatus.Information = (ULONG_PTR)ResourceList; 871 return STATUS_SUCCESS; 872 } 873 874 /* Get current resources */ 875 Buffer.Length = 0; 876 AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); 877 if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) || 878 Buffer.Length == 0) 879 { 880 return Irp->IoStatus.Status; 881 } 882 883 Buffer.Pointer = ExAllocatePoolWithTag(PagedPool, Buffer.Length, 'BpcA'); 884 if (!Buffer.Pointer) 885 return STATUS_INSUFFICIENT_RESOURCES; 886 887 AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); 888 if (!ACPI_SUCCESS(AcpiStatus)) 889 { 890 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus); 891 ASSERT(FALSE); 892 return STATUS_UNSUCCESSFUL; 893 } 894 895 resource= Buffer.Pointer; 896 /* Count number of resources */ 897 while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG) 898 { 899 switch (resource->Type) 900 { 901 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 902 { 903 ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data; 904 if (irq_data->ProducerConsumer == ACPI_PRODUCER) 905 break; 906 NumberOfResources += irq_data->InterruptCount; 907 break; 908 } 909 case ACPI_RESOURCE_TYPE_IRQ: 910 { 911 ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data; 912 NumberOfResources += irq_data->InterruptCount; 913 break; 914 } 915 case ACPI_RESOURCE_TYPE_DMA: 916 { 917 ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data; 918 NumberOfResources += dma_data->ChannelCount; 919 break; 920 } 921 case ACPI_RESOURCE_TYPE_ADDRESS16: 922 case ACPI_RESOURCE_TYPE_ADDRESS32: 923 case ACPI_RESOURCE_TYPE_ADDRESS64: 924 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 925 { 926 ACPI_RESOURCE_ADDRESS *addr_res = (ACPI_RESOURCE_ADDRESS*) &resource->Data; 927 if (addr_res->ProducerConsumer == ACPI_PRODUCER) 928 break; 929 NumberOfResources++; 930 break; 931 } 932 case ACPI_RESOURCE_TYPE_MEMORY24: 933 case ACPI_RESOURCE_TYPE_MEMORY32: 934 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 935 case ACPI_RESOURCE_TYPE_FIXED_IO: 936 case ACPI_RESOURCE_TYPE_IO: 937 { 938 NumberOfResources++; 939 break; 940 } 941 default: 942 { 943 DPRINT1("Unknown resource type: %d\n", resource->Type); 944 break; 945 } 946 } 947 resource = ACPI_NEXT_RESOURCE(resource); 948 } 949 950 /* Allocate memory */ 951 ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1); 952 ResourceList = ExAllocatePoolWithTag(PagedPool, ResourceListSize, 'RpcA'); 953 954 if (!ResourceList) 955 { 956 ExFreePoolWithTag(Buffer.Pointer, 'BpcA'); 957 return STATUS_INSUFFICIENT_RESOURCES; 958 } 959 ResourceList->Count = 1; 960 ResourceList->List[0].InterfaceType = Internal; /* FIXME */ 961 ResourceList->List[0].BusNumber = 0; /* We're the only ACPI bus device in the system */ 962 ResourceList->List[0].PartialResourceList.Version = 1; 963 ResourceList->List[0].PartialResourceList.Revision = 1; 964 ResourceList->List[0].PartialResourceList.Count = NumberOfResources; 965 ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; 966 967 /* Fill resources list structure */ 968 resource = Buffer.Pointer; 969 while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG) 970 { 971 switch (resource->Type) 972 { 973 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 974 { 975 ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data; 976 if (irq_data->ProducerConsumer == ACPI_PRODUCER) 977 break; 978 for (i = 0; i < irq_data->InterruptCount; i++) 979 { 980 ResourceDescriptor->Type = CmResourceTypeInterrupt; 981 982 ResourceDescriptor->ShareDisposition = 983 (irq_data->Shareable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); 984 ResourceDescriptor->Flags = 985 (irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); 986 ResourceDescriptor->u.Interrupt.Level = 987 ResourceDescriptor->u.Interrupt.Vector = irq_data->Interrupts[i]; 988 ResourceDescriptor->u.Interrupt.Affinity = (KAFFINITY)(-1); 989 990 ResourceDescriptor++; 991 } 992 break; 993 } 994 case ACPI_RESOURCE_TYPE_IRQ: 995 { 996 ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data; 997 for (i = 0; i < irq_data->InterruptCount; i++) 998 { 999 ResourceDescriptor->Type = CmResourceTypeInterrupt; 1000 1001 ResourceDescriptor->ShareDisposition = 1002 (irq_data->Shareable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); 1003 ResourceDescriptor->Flags = 1004 (irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); 1005 ResourceDescriptor->u.Interrupt.Level = 1006 ResourceDescriptor->u.Interrupt.Vector = irq_data->Interrupts[i]; 1007 ResourceDescriptor->u.Interrupt.Affinity = (KAFFINITY)(-1); 1008 1009 ResourceDescriptor++; 1010 } 1011 break; 1012 } 1013 case ACPI_RESOURCE_TYPE_DMA: 1014 { 1015 ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data; 1016 for (i = 0; i < dma_data->ChannelCount; i++) 1017 { 1018 ResourceDescriptor->Type = CmResourceTypeDma; 1019 ResourceDescriptor->Flags = 0; 1020 switch (dma_data->Type) 1021 { 1022 case ACPI_TYPE_A: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break; 1023 case ACPI_TYPE_B: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break; 1024 case ACPI_TYPE_F: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break; 1025 } 1026 if (dma_data->BusMaster == ACPI_BUS_MASTER) 1027 ResourceDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER; 1028 switch (dma_data->Transfer) 1029 { 1030 case ACPI_TRANSFER_8: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8; break; 1031 case ACPI_TRANSFER_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_16; break; 1032 case ACPI_TRANSFER_8_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break; 1033 } 1034 ResourceDescriptor->u.Dma.Channel = dma_data->Channels[i]; 1035 1036 ResourceDescriptor++; 1037 } 1038 break; 1039 } 1040 case ACPI_RESOURCE_TYPE_IO: 1041 { 1042 ACPI_RESOURCE_IO *io_data = (ACPI_RESOURCE_IO*) &resource->Data; 1043 ResourceDescriptor->Type = CmResourceTypePort; 1044 ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 1045 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 1046 if (io_data->IoDecode == ACPI_DECODE_16) 1047 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE; 1048 else 1049 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE; 1050 ResourceDescriptor->u.Port.Start.QuadPart = io_data->Minimum; 1051 ResourceDescriptor->u.Port.Length = io_data->AddressLength; 1052 1053 ResourceDescriptor++; 1054 break; 1055 } 1056 case ACPI_RESOURCE_TYPE_FIXED_IO: 1057 { 1058 ACPI_RESOURCE_FIXED_IO *io_data = (ACPI_RESOURCE_FIXED_IO*) &resource->Data; 1059 ResourceDescriptor->Type = CmResourceTypePort; 1060 ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 1061 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 1062 ResourceDescriptor->u.Port.Start.QuadPart = io_data->Address; 1063 ResourceDescriptor->u.Port.Length = io_data->AddressLength; 1064 1065 ResourceDescriptor++; 1066 break; 1067 } 1068 case ACPI_RESOURCE_TYPE_ADDRESS16: 1069 { 1070 ACPI_RESOURCE_ADDRESS16 *addr16_data = (ACPI_RESOURCE_ADDRESS16*) &resource->Data; 1071 if (addr16_data->ProducerConsumer == ACPI_PRODUCER) 1072 break; 1073 if (addr16_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 1074 { 1075 ResourceDescriptor->Type = CmResourceTypeBusNumber; 1076 ResourceDescriptor->ShareDisposition = CmResourceShareShared; 1077 ResourceDescriptor->Flags = 0; 1078 ResourceDescriptor->u.BusNumber.Start = addr16_data->Address.Minimum; 1079 ResourceDescriptor->u.BusNumber.Length = addr16_data->Address.AddressLength; 1080 } 1081 else if (addr16_data->ResourceType == ACPI_IO_RANGE) 1082 { 1083 ResourceDescriptor->Type = CmResourceTypePort; 1084 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1085 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 1086 if (addr16_data->Decode == ACPI_POS_DECODE) 1087 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 1088 ResourceDescriptor->u.Port.Start.QuadPart = addr16_data->Address.Minimum; 1089 ResourceDescriptor->u.Port.Length = addr16_data->Address.AddressLength; 1090 } 1091 else 1092 { 1093 ResourceDescriptor->Type = CmResourceTypeMemory; 1094 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1095 ResourceDescriptor->Flags = 0; 1096 if (addr16_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 1097 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1098 else 1099 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1100 switch (addr16_data->Info.Mem.Caching) 1101 { 1102 case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 1103 case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 1104 case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 1105 } 1106 ResourceDescriptor->u.Memory.Start.QuadPart = addr16_data->Address.Minimum; 1107 ResourceDescriptor->u.Memory.Length = addr16_data->Address.AddressLength; 1108 } 1109 ResourceDescriptor++; 1110 break; 1111 } 1112 case ACPI_RESOURCE_TYPE_ADDRESS32: 1113 { 1114 ACPI_RESOURCE_ADDRESS32 *addr32_data = (ACPI_RESOURCE_ADDRESS32*) &resource->Data; 1115 if (addr32_data->ProducerConsumer == ACPI_PRODUCER) 1116 break; 1117 if (addr32_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 1118 { 1119 ResourceDescriptor->Type = CmResourceTypeBusNumber; 1120 ResourceDescriptor->ShareDisposition = CmResourceShareShared; 1121 ResourceDescriptor->Flags = 0; 1122 ResourceDescriptor->u.BusNumber.Start = addr32_data->Address.Minimum; 1123 ResourceDescriptor->u.BusNumber.Length = addr32_data->Address.AddressLength; 1124 } 1125 else if (addr32_data->ResourceType == ACPI_IO_RANGE) 1126 { 1127 ResourceDescriptor->Type = CmResourceTypePort; 1128 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1129 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 1130 if (addr32_data->Decode == ACPI_POS_DECODE) 1131 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 1132 ResourceDescriptor->u.Port.Start.QuadPart = addr32_data->Address.Minimum; 1133 ResourceDescriptor->u.Port.Length = addr32_data->Address.AddressLength; 1134 } 1135 else 1136 { 1137 ResourceDescriptor->Type = CmResourceTypeMemory; 1138 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1139 ResourceDescriptor->Flags = 0; 1140 if (addr32_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 1141 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1142 else 1143 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1144 switch (addr32_data->Info.Mem.Caching) 1145 { 1146 case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 1147 case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 1148 case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 1149 } 1150 ResourceDescriptor->u.Memory.Start.QuadPart = addr32_data->Address.Minimum; 1151 ResourceDescriptor->u.Memory.Length = addr32_data->Address.AddressLength; 1152 } 1153 ResourceDescriptor++; 1154 break; 1155 } 1156 case ACPI_RESOURCE_TYPE_ADDRESS64: 1157 { 1158 ACPI_RESOURCE_ADDRESS64 *addr64_data = (ACPI_RESOURCE_ADDRESS64*) &resource->Data; 1159 if (addr64_data->ProducerConsumer == ACPI_PRODUCER) 1160 break; 1161 if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 1162 { 1163 DPRINT1("64-bit bus address is not supported!\n"); 1164 ResourceDescriptor->Type = CmResourceTypeBusNumber; 1165 ResourceDescriptor->ShareDisposition = CmResourceShareShared; 1166 ResourceDescriptor->Flags = 0; 1167 ResourceDescriptor->u.BusNumber.Start = (ULONG)addr64_data->Address.Minimum; 1168 ResourceDescriptor->u.BusNumber.Length = addr64_data->Address.AddressLength; 1169 } 1170 else if (addr64_data->ResourceType == ACPI_IO_RANGE) 1171 { 1172 ResourceDescriptor->Type = CmResourceTypePort; 1173 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1174 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 1175 if (addr64_data->Decode == ACPI_POS_DECODE) 1176 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 1177 ResourceDescriptor->u.Port.Start.QuadPart = addr64_data->Address.Minimum; 1178 ResourceDescriptor->u.Port.Length = addr64_data->Address.AddressLength; 1179 } 1180 else 1181 { 1182 ResourceDescriptor->Type = CmResourceTypeMemory; 1183 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1184 ResourceDescriptor->Flags = 0; 1185 if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 1186 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1187 else 1188 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1189 switch (addr64_data->Info.Mem.Caching) 1190 { 1191 case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 1192 case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 1193 case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 1194 } 1195 ResourceDescriptor->u.Memory.Start.QuadPart = addr64_data->Address.Minimum; 1196 ResourceDescriptor->u.Memory.Length = addr64_data->Address.AddressLength; 1197 } 1198 ResourceDescriptor++; 1199 break; 1200 } 1201 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 1202 { 1203 ACPI_RESOURCE_EXTENDED_ADDRESS64 *addr64_data = (ACPI_RESOURCE_EXTENDED_ADDRESS64*) &resource->Data; 1204 if (addr64_data->ProducerConsumer == ACPI_PRODUCER) 1205 break; 1206 if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 1207 { 1208 DPRINT1("64-bit bus address is not supported!\n"); 1209 ResourceDescriptor->Type = CmResourceTypeBusNumber; 1210 ResourceDescriptor->ShareDisposition = CmResourceShareShared; 1211 ResourceDescriptor->Flags = 0; 1212 ResourceDescriptor->u.BusNumber.Start = (ULONG)addr64_data->Address.Minimum; 1213 ResourceDescriptor->u.BusNumber.Length = addr64_data->Address.AddressLength; 1214 } 1215 else if (addr64_data->ResourceType == ACPI_IO_RANGE) 1216 { 1217 ResourceDescriptor->Type = CmResourceTypePort; 1218 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1219 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 1220 if (addr64_data->Decode == ACPI_POS_DECODE) 1221 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 1222 ResourceDescriptor->u.Port.Start.QuadPart = addr64_data->Address.Minimum; 1223 ResourceDescriptor->u.Port.Length = addr64_data->Address.AddressLength; 1224 } 1225 else 1226 { 1227 ResourceDescriptor->Type = CmResourceTypeMemory; 1228 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1229 ResourceDescriptor->Flags = 0; 1230 if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 1231 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1232 else 1233 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1234 switch (addr64_data->Info.Mem.Caching) 1235 { 1236 case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 1237 case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 1238 case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 1239 } 1240 ResourceDescriptor->u.Memory.Start.QuadPart = addr64_data->Address.Minimum; 1241 ResourceDescriptor->u.Memory.Length = addr64_data->Address.AddressLength; 1242 } 1243 ResourceDescriptor++; 1244 break; 1245 } 1246 case ACPI_RESOURCE_TYPE_MEMORY24: 1247 { 1248 ACPI_RESOURCE_MEMORY24 *mem24_data = (ACPI_RESOURCE_MEMORY24*) &resource->Data; 1249 ResourceDescriptor->Type = CmResourceTypeMemory; 1250 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1251 ResourceDescriptor->Flags = CM_RESOURCE_MEMORY_24; 1252 if (mem24_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 1253 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1254 else 1255 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1256 ResourceDescriptor->u.Memory.Start.QuadPart = mem24_data->Minimum; 1257 ResourceDescriptor->u.Memory.Length = mem24_data->AddressLength; 1258 1259 ResourceDescriptor++; 1260 break; 1261 } 1262 case ACPI_RESOURCE_TYPE_MEMORY32: 1263 { 1264 ACPI_RESOURCE_MEMORY32 *mem32_data = (ACPI_RESOURCE_MEMORY32*) &resource->Data; 1265 ResourceDescriptor->Type = CmResourceTypeMemory; 1266 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1267 ResourceDescriptor->Flags = 0; 1268 if (mem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 1269 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1270 else 1271 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1272 ResourceDescriptor->u.Memory.Start.QuadPart = mem32_data->Minimum; 1273 ResourceDescriptor->u.Memory.Length = mem32_data->AddressLength; 1274 1275 ResourceDescriptor++; 1276 break; 1277 } 1278 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 1279 { 1280 ACPI_RESOURCE_FIXED_MEMORY32 *memfixed32_data = (ACPI_RESOURCE_FIXED_MEMORY32*) &resource->Data; 1281 ResourceDescriptor->Type = CmResourceTypeMemory; 1282 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1283 ResourceDescriptor->Flags = 0; 1284 if (memfixed32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 1285 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1286 else 1287 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1288 ResourceDescriptor->u.Memory.Start.QuadPart = memfixed32_data->Address; 1289 ResourceDescriptor->u.Memory.Length = memfixed32_data->AddressLength; 1290 1291 ResourceDescriptor++; 1292 break; 1293 } 1294 default: 1295 { 1296 break; 1297 } 1298 } 1299 resource = ACPI_NEXT_RESOURCE(resource); 1300 } 1301 1302 ExFreePoolWithTag(Buffer.Pointer, 'BpcA'); 1303 Irp->IoStatus.Information = (ULONG_PTR)ResourceList; 1304 return STATUS_SUCCESS; 1305 } 1306 #endif /* UNIT_TEST */ 1307 1308 NTSTATUS 1309 Bus_PDO_QueryResourceRequirements( 1310 PPDO_DEVICE_DATA DeviceData, 1311 PIRP Irp ) 1312 { 1313 ULONG NumberOfResources = 0; 1314 ACPI_STATUS AcpiStatus; 1315 ACPI_BUFFER Buffer; 1316 ACPI_RESOURCE* resource; 1317 ULONG i, RequirementsListSize; 1318 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; 1319 PIO_RESOURCE_DESCRIPTOR RequirementDescriptor; 1320 BOOLEAN CurrentRes = FALSE; 1321 BOOLEAN SeenStartDependent; 1322 1323 PAGED_CODE (); 1324 1325 if (!DeviceData->AcpiHandle) 1326 { 1327 return Irp->IoStatus.Status; 1328 } 1329 1330 /* Handle the PCI root manually */ 1331 if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 || 1332 wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0) 1333 { 1334 return Irp->IoStatus.Status; 1335 } 1336 1337 /* Get current resources */ 1338 while (TRUE) 1339 { 1340 Buffer.Length = 0; 1341 if (CurrentRes) 1342 AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); 1343 else 1344 AcpiStatus = AcpiGetPossibleResources(DeviceData->AcpiHandle, &Buffer); 1345 if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) || 1346 Buffer.Length == 0) 1347 { 1348 if (!CurrentRes) 1349 CurrentRes = TRUE; 1350 else 1351 return Irp->IoStatus.Status; 1352 } 1353 else 1354 break; 1355 } 1356 1357 Buffer.Pointer = ExAllocatePoolWithTag(PagedPool, Buffer.Length, 'BpcA'); 1358 if (!Buffer.Pointer) 1359 return STATUS_INSUFFICIENT_RESOURCES; 1360 1361 if (CurrentRes) 1362 AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); 1363 else 1364 AcpiStatus = AcpiGetPossibleResources(DeviceData->AcpiHandle, &Buffer); 1365 if (!ACPI_SUCCESS(AcpiStatus)) 1366 { 1367 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus); 1368 ASSERT(FALSE); 1369 return STATUS_UNSUCCESSFUL; 1370 } 1371 1372 SeenStartDependent = FALSE; 1373 resource = Buffer.Pointer; 1374 /* Count number of resources */ 1375 while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG && resource->Type != ACPI_RESOURCE_TYPE_END_DEPENDENT) 1376 { 1377 if (resource->Type == ACPI_RESOURCE_TYPE_START_DEPENDENT) 1378 { 1379 if (SeenStartDependent) 1380 { 1381 break; 1382 } 1383 SeenStartDependent = TRUE; 1384 } 1385 switch (resource->Type) 1386 { 1387 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 1388 { 1389 ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data; 1390 if (irq_data->ProducerConsumer == ACPI_PRODUCER) 1391 break; 1392 NumberOfResources += irq_data->InterruptCount; 1393 break; 1394 } 1395 case ACPI_RESOURCE_TYPE_IRQ: 1396 { 1397 ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data; 1398 NumberOfResources += irq_data->InterruptCount; 1399 break; 1400 } 1401 case ACPI_RESOURCE_TYPE_DMA: 1402 { 1403 ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data; 1404 NumberOfResources += dma_data->ChannelCount; 1405 break; 1406 } 1407 case ACPI_RESOURCE_TYPE_ADDRESS16: 1408 case ACPI_RESOURCE_TYPE_ADDRESS32: 1409 case ACPI_RESOURCE_TYPE_ADDRESS64: 1410 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 1411 { 1412 ACPI_RESOURCE_ADDRESS *res_addr = (ACPI_RESOURCE_ADDRESS*) &resource->Data; 1413 if (res_addr->ProducerConsumer == ACPI_PRODUCER) 1414 break; 1415 NumberOfResources++; 1416 break; 1417 } 1418 case ACPI_RESOURCE_TYPE_MEMORY24: 1419 case ACPI_RESOURCE_TYPE_MEMORY32: 1420 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 1421 case ACPI_RESOURCE_TYPE_FIXED_IO: 1422 case ACPI_RESOURCE_TYPE_IO: 1423 { 1424 NumberOfResources++; 1425 break; 1426 } 1427 default: 1428 { 1429 break; 1430 } 1431 } 1432 resource = ACPI_NEXT_RESOURCE(resource); 1433 } 1434 1435 RequirementsListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) + sizeof(IO_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1); 1436 RequirementsList = ExAllocatePoolWithTag(PagedPool, RequirementsListSize, 'RpcA'); 1437 1438 if (!RequirementsList) 1439 { 1440 ExFreePoolWithTag(Buffer.Pointer, 'BpcA'); 1441 return STATUS_INSUFFICIENT_RESOURCES; 1442 } 1443 RequirementsList->ListSize = RequirementsListSize; 1444 RequirementsList->InterfaceType = Internal; 1445 RequirementsList->BusNumber = 0; 1446 RequirementsList->SlotNumber = 0; /* Not used by WDM drivers */ 1447 RequirementsList->AlternativeLists = 1; 1448 RequirementsList->List[0].Version = 1; 1449 RequirementsList->List[0].Revision = 1; 1450 RequirementsList->List[0].Count = NumberOfResources; 1451 RequirementDescriptor = RequirementsList->List[0].Descriptors; 1452 1453 /* Fill resources list structure */ 1454 SeenStartDependent = FALSE; 1455 resource = Buffer.Pointer; 1456 while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG && resource->Type != ACPI_RESOURCE_TYPE_END_DEPENDENT) 1457 { 1458 if (resource->Type == ACPI_RESOURCE_TYPE_START_DEPENDENT) 1459 { 1460 if (SeenStartDependent) 1461 { 1462 break; 1463 } 1464 SeenStartDependent = TRUE; 1465 } 1466 switch (resource->Type) 1467 { 1468 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 1469 { 1470 ACPI_RESOURCE_EXTENDED_IRQ *irq_data = &resource->Data.ExtendedIrq; 1471 if (irq_data->ProducerConsumer == ACPI_PRODUCER) 1472 break; 1473 for (i = 0; i < irq_data->InterruptCount; i++) 1474 { 1475 RequirementDescriptor->Option = (i == 0) ? IO_RESOURCE_PREFERRED : IO_RESOURCE_ALTERNATIVE; 1476 RequirementDescriptor->Type = CmResourceTypeInterrupt; 1477 RequirementDescriptor->ShareDisposition = (irq_data->Shareable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); 1478 RequirementDescriptor->Flags =(irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); 1479 RequirementDescriptor->u.Interrupt.MinimumVector = 1480 RequirementDescriptor->u.Interrupt.MaximumVector = irq_data->Interrupts[i]; 1481 1482 RequirementDescriptor++; 1483 } 1484 break; 1485 } 1486 case ACPI_RESOURCE_TYPE_IRQ: 1487 { 1488 ACPI_RESOURCE_IRQ *irq_data = &resource->Data.Irq; 1489 for (i = 0; i < irq_data->InterruptCount; i++) 1490 { 1491 RequirementDescriptor->Option = (i == 0) ? IO_RESOURCE_PREFERRED : IO_RESOURCE_ALTERNATIVE; 1492 RequirementDescriptor->Type = CmResourceTypeInterrupt; 1493 RequirementDescriptor->ShareDisposition = (irq_data->Shareable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); 1494 RequirementDescriptor->Flags =(irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); 1495 RequirementDescriptor->u.Interrupt.MinimumVector = 1496 RequirementDescriptor->u.Interrupt.MaximumVector = irq_data->Interrupts[i]; 1497 1498 RequirementDescriptor++; 1499 } 1500 break; 1501 } 1502 case ACPI_RESOURCE_TYPE_DMA: 1503 { 1504 ACPI_RESOURCE_DMA *dma_data = &resource->Data.Dma; 1505 for (i = 0; i < dma_data->ChannelCount; i++) 1506 { 1507 RequirementDescriptor->Type = CmResourceTypeDma; 1508 RequirementDescriptor->Flags = 0; 1509 switch (dma_data->Type) 1510 { 1511 case ACPI_TYPE_A: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break; 1512 case ACPI_TYPE_B: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break; 1513 case ACPI_TYPE_F: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break; 1514 } 1515 if (dma_data->BusMaster == ACPI_BUS_MASTER) 1516 RequirementDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER; 1517 switch (dma_data->Transfer) 1518 { 1519 case ACPI_TRANSFER_8: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8; break; 1520 case ACPI_TRANSFER_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_16; break; 1521 case ACPI_TRANSFER_8_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break; 1522 } 1523 1524 RequirementDescriptor->Option = (i == 0) ? IO_RESOURCE_PREFERRED : IO_RESOURCE_ALTERNATIVE; 1525 RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 1526 RequirementDescriptor->u.Dma.MinimumChannel = 1527 RequirementDescriptor->u.Dma.MaximumChannel = dma_data->Channels[i]; 1528 RequirementDescriptor++; 1529 } 1530 break; 1531 } 1532 case ACPI_RESOURCE_TYPE_IO: 1533 { 1534 ACPI_RESOURCE_IO *io_data = &resource->Data.Io; 1535 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 1536 if (io_data->IoDecode == ACPI_DECODE_16) 1537 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE; 1538 else 1539 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE; 1540 RequirementDescriptor->u.Port.Length = io_data->AddressLength; 1541 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 1542 RequirementDescriptor->Type = CmResourceTypePort; 1543 RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 1544 RequirementDescriptor->u.Port.Alignment = io_data->Alignment; 1545 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = io_data->Minimum; 1546 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = io_data->Maximum + io_data->AddressLength - 1; 1547 1548 RequirementDescriptor++; 1549 break; 1550 } 1551 case ACPI_RESOURCE_TYPE_FIXED_IO: 1552 { 1553 ACPI_RESOURCE_FIXED_IO *io_data = &resource->Data.FixedIo; 1554 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 1555 RequirementDescriptor->u.Port.Length = io_data->AddressLength; 1556 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 1557 RequirementDescriptor->Type = CmResourceTypePort; 1558 RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 1559 RequirementDescriptor->u.Port.Alignment = 1; 1560 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = io_data->Address; 1561 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = io_data->Address + io_data->AddressLength - 1; 1562 1563 RequirementDescriptor++; 1564 break; 1565 } 1566 case ACPI_RESOURCE_TYPE_ADDRESS16: 1567 { 1568 ACPI_RESOURCE_ADDRESS16 *addr16_data = &resource->Data.Address16; 1569 if (addr16_data->ProducerConsumer == ACPI_PRODUCER) 1570 break; 1571 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 1572 if (addr16_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 1573 { 1574 RequirementDescriptor->Type = CmResourceTypeBusNumber; 1575 RequirementDescriptor->ShareDisposition = CmResourceShareShared; 1576 RequirementDescriptor->Flags = 0; 1577 RequirementDescriptor->u.BusNumber.MinBusNumber = addr16_data->Address.Minimum; 1578 RequirementDescriptor->u.BusNumber.MaxBusNumber = addr16_data->Address.Maximum + addr16_data->Address.AddressLength - 1; 1579 RequirementDescriptor->u.BusNumber.Length = addr16_data->Address.AddressLength; 1580 } 1581 else if (addr16_data->ResourceType == ACPI_IO_RANGE) 1582 { 1583 RequirementDescriptor->Type = CmResourceTypePort; 1584 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1585 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 1586 if (addr16_data->Decode == ACPI_POS_DECODE) 1587 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 1588 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr16_data->Address.Minimum; 1589 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr16_data->Address.Maximum + addr16_data->Address.AddressLength - 1; 1590 RequirementDescriptor->u.Port.Length = addr16_data->Address.AddressLength; 1591 } 1592 else 1593 { 1594 RequirementDescriptor->Type = CmResourceTypeMemory; 1595 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1596 RequirementDescriptor->Flags = 0; 1597 if (addr16_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 1598 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1599 else 1600 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1601 switch (addr16_data->Info.Mem.Caching) 1602 { 1603 case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 1604 case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 1605 case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 1606 } 1607 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr16_data->Address.Minimum; 1608 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr16_data->Address.Maximum + addr16_data->Address.AddressLength - 1; 1609 RequirementDescriptor->u.Memory.Length = addr16_data->Address.AddressLength; 1610 } 1611 RequirementDescriptor++; 1612 break; 1613 } 1614 case ACPI_RESOURCE_TYPE_ADDRESS32: 1615 { 1616 ACPI_RESOURCE_ADDRESS32 *addr32_data = &resource->Data.Address32; 1617 if (addr32_data->ProducerConsumer == ACPI_PRODUCER) 1618 break; 1619 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 1620 if (addr32_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 1621 { 1622 RequirementDescriptor->Type = CmResourceTypeBusNumber; 1623 RequirementDescriptor->ShareDisposition = CmResourceShareShared; 1624 RequirementDescriptor->Flags = 0; 1625 RequirementDescriptor->u.BusNumber.MinBusNumber = addr32_data->Address.Minimum; 1626 RequirementDescriptor->u.BusNumber.MaxBusNumber = addr32_data->Address.Maximum + addr32_data->Address.AddressLength - 1; 1627 RequirementDescriptor->u.BusNumber.Length = addr32_data->Address.AddressLength; 1628 } 1629 else if (addr32_data->ResourceType == ACPI_IO_RANGE) 1630 { 1631 RequirementDescriptor->Type = CmResourceTypePort; 1632 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1633 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 1634 if (addr32_data->Decode == ACPI_POS_DECODE) 1635 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 1636 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr32_data->Address.Minimum; 1637 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr32_data->Address.Maximum + addr32_data->Address.AddressLength - 1; 1638 RequirementDescriptor->u.Port.Length = addr32_data->Address.AddressLength; 1639 } 1640 else 1641 { 1642 RequirementDescriptor->Type = CmResourceTypeMemory; 1643 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1644 RequirementDescriptor->Flags = 0; 1645 if (addr32_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 1646 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1647 else 1648 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1649 switch (addr32_data->Info.Mem.Caching) 1650 { 1651 case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 1652 case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 1653 case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 1654 } 1655 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr32_data->Address.Minimum; 1656 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr32_data->Address.Maximum + addr32_data->Address.AddressLength - 1; 1657 RequirementDescriptor->u.Memory.Length = addr32_data->Address.AddressLength; 1658 } 1659 RequirementDescriptor++; 1660 break; 1661 } 1662 case ACPI_RESOURCE_TYPE_ADDRESS64: 1663 { 1664 ACPI_RESOURCE_ADDRESS64 *addr64_data = &resource->Data.Address64; 1665 if (addr64_data->ProducerConsumer == ACPI_PRODUCER) 1666 break; 1667 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 1668 if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 1669 { 1670 DPRINT1("64-bit bus address is not supported!\n"); 1671 RequirementDescriptor->Type = CmResourceTypeBusNumber; 1672 RequirementDescriptor->ShareDisposition = CmResourceShareShared; 1673 RequirementDescriptor->Flags = 0; 1674 RequirementDescriptor->u.BusNumber.MinBusNumber = (ULONG)addr64_data->Address.Minimum; 1675 RequirementDescriptor->u.BusNumber.MaxBusNumber = (ULONG)addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1; 1676 RequirementDescriptor->u.BusNumber.Length = addr64_data->Address.AddressLength; 1677 } 1678 else if (addr64_data->ResourceType == ACPI_IO_RANGE) 1679 { 1680 RequirementDescriptor->Type = CmResourceTypePort; 1681 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1682 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 1683 if (addr64_data->Decode == ACPI_POS_DECODE) 1684 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 1685 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr64_data->Address.Minimum; 1686 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1; 1687 RequirementDescriptor->u.Port.Length = addr64_data->Address.AddressLength; 1688 } 1689 else 1690 { 1691 RequirementDescriptor->Type = CmResourceTypeMemory; 1692 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1693 RequirementDescriptor->Flags = 0; 1694 if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 1695 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1696 else 1697 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1698 switch (addr64_data->Info.Mem.Caching) 1699 { 1700 case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 1701 case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 1702 case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 1703 } 1704 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr64_data->Address.Minimum; 1705 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1; 1706 RequirementDescriptor->u.Memory.Length = addr64_data->Address.AddressLength; 1707 } 1708 RequirementDescriptor++; 1709 break; 1710 } 1711 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 1712 { 1713 ACPI_RESOURCE_EXTENDED_ADDRESS64 *addr64_data = &resource->Data.ExtAddress64; 1714 if (addr64_data->ProducerConsumer == ACPI_PRODUCER) 1715 break; 1716 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 1717 if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 1718 { 1719 DPRINT1("64-bit bus address is not supported!\n"); 1720 RequirementDescriptor->Type = CmResourceTypeBusNumber; 1721 RequirementDescriptor->ShareDisposition = CmResourceShareShared; 1722 RequirementDescriptor->Flags = 0; 1723 RequirementDescriptor->u.BusNumber.MinBusNumber = (ULONG)addr64_data->Address.Minimum; 1724 RequirementDescriptor->u.BusNumber.MaxBusNumber = (ULONG)addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1; 1725 RequirementDescriptor->u.BusNumber.Length = addr64_data->Address.AddressLength; 1726 } 1727 else if (addr64_data->ResourceType == ACPI_IO_RANGE) 1728 { 1729 RequirementDescriptor->Type = CmResourceTypePort; 1730 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1731 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 1732 if (addr64_data->Decode == ACPI_POS_DECODE) 1733 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 1734 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr64_data->Address.Minimum; 1735 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1; 1736 RequirementDescriptor->u.Port.Length = addr64_data->Address.AddressLength; 1737 } 1738 else 1739 { 1740 RequirementDescriptor->Type = CmResourceTypeMemory; 1741 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1742 RequirementDescriptor->Flags = 0; 1743 if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 1744 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1745 else 1746 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1747 switch (addr64_data->Info.Mem.Caching) 1748 { 1749 case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 1750 case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 1751 case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 1752 } 1753 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr64_data->Address.Minimum; 1754 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1; 1755 RequirementDescriptor->u.Memory.Length = addr64_data->Address.AddressLength; 1756 } 1757 RequirementDescriptor++; 1758 break; 1759 } 1760 case ACPI_RESOURCE_TYPE_MEMORY24: 1761 { 1762 ACPI_RESOURCE_MEMORY24 *mem24_data = &resource->Data.Memory24; 1763 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 1764 RequirementDescriptor->Type = CmResourceTypeMemory; 1765 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1766 RequirementDescriptor->Flags = CM_RESOURCE_MEMORY_24; 1767 if (mem24_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 1768 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1769 else 1770 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1771 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = mem24_data->Minimum; 1772 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = mem24_data->Maximum + mem24_data->AddressLength - 1; 1773 RequirementDescriptor->u.Memory.Length = mem24_data->AddressLength; 1774 1775 RequirementDescriptor++; 1776 break; 1777 } 1778 case ACPI_RESOURCE_TYPE_MEMORY32: 1779 { 1780 ACPI_RESOURCE_MEMORY32 *mem32_data = &resource->Data.Memory32; 1781 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 1782 RequirementDescriptor->Type = CmResourceTypeMemory; 1783 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1784 RequirementDescriptor->Flags = 0; 1785 if (mem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 1786 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1787 else 1788 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1789 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = mem32_data->Minimum; 1790 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = mem32_data->Maximum + mem32_data->AddressLength - 1; 1791 RequirementDescriptor->u.Memory.Length = mem32_data->AddressLength; 1792 1793 RequirementDescriptor++; 1794 break; 1795 } 1796 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 1797 { 1798 ACPI_RESOURCE_FIXED_MEMORY32 *fixedmem32_data = &resource->Data.FixedMemory32; 1799 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 1800 RequirementDescriptor->Type = CmResourceTypeMemory; 1801 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 1802 RequirementDescriptor->Flags = 0; 1803 if (fixedmem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 1804 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 1805 else 1806 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 1807 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = fixedmem32_data->Address; 1808 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = fixedmem32_data->Address + fixedmem32_data->AddressLength - 1; 1809 RequirementDescriptor->u.Memory.Length = fixedmem32_data->AddressLength; 1810 1811 RequirementDescriptor++; 1812 break; 1813 } 1814 default: 1815 { 1816 break; 1817 } 1818 } 1819 resource = ACPI_NEXT_RESOURCE(resource); 1820 } 1821 ExFreePoolWithTag(Buffer.Pointer, 'BpcA'); 1822 1823 Irp->IoStatus.Information = (ULONG_PTR)RequirementsList; 1824 1825 return STATUS_SUCCESS; 1826 } 1827 1828 #ifndef UNIT_TEST 1829 NTSTATUS 1830 Bus_PDO_QueryDeviceRelations( 1831 PPDO_DEVICE_DATA DeviceData, 1832 PIRP Irp ) 1833 /*++ 1834 1835 Routine Description: 1836 1837 The PnP Manager sends this IRP to gather information about 1838 devices with a relationship to the specified device. 1839 Bus drivers must handle this request for TargetDeviceRelation 1840 for their child devices (child PDOs). 1841 1842 If a driver returns relations in response to this IRP, 1843 it allocates a DEVICE_RELATIONS structure from paged 1844 memory containing a count and the appropriate number of 1845 device object pointers. The PnP Manager frees the structure 1846 when it is no longer needed. If a driver replaces a 1847 DEVICE_RELATIONS structure allocated by another driver, 1848 it must free the previous structure. 1849 1850 A driver must reference the PDO of any device that it 1851 reports in this IRP (ObReferenceObject). The PnP Manager 1852 removes the reference when appropriate. 1853 1854 Arguments: 1855 1856 DeviceData - Pointer to the PDO's device extension. 1857 Irp - Pointer to the irp. 1858 1859 Return Value: 1860 1861 NT STATUS 1862 1863 --*/ 1864 { 1865 1866 PIO_STACK_LOCATION stack; 1867 PDEVICE_RELATIONS deviceRelations; 1868 NTSTATUS status; 1869 1870 PAGED_CODE (); 1871 1872 stack = IoGetCurrentIrpStackLocation (Irp); 1873 1874 switch (stack->Parameters.QueryDeviceRelations.Type) { 1875 1876 case TargetDeviceRelation: 1877 1878 deviceRelations = (PDEVICE_RELATIONS) Irp->IoStatus.Information; 1879 if (deviceRelations) { 1880 // 1881 // Only PDO can handle this request. Somebody above 1882 // is not playing by rule. 1883 // 1884 ASSERTMSG("Someone above is handling TargetDeviceRelation\n", !deviceRelations); 1885 } 1886 1887 deviceRelations = ExAllocatePoolWithTag(PagedPool, 1888 sizeof(DEVICE_RELATIONS), 1889 'IpcA'); 1890 if (!deviceRelations) { 1891 status = STATUS_INSUFFICIENT_RESOURCES; 1892 break; 1893 } 1894 1895 // 1896 // There is only one PDO pointer in the structure 1897 // for this relation type. The PnP Manager removes 1898 // the reference to the PDO when the driver or application 1899 // un-registers for notification on the device. 1900 // 1901 1902 deviceRelations->Count = 1; 1903 deviceRelations->Objects[0] = DeviceData->Common.Self; 1904 ObReferenceObject(DeviceData->Common.Self); 1905 1906 status = STATUS_SUCCESS; 1907 Irp->IoStatus.Information = (ULONG_PTR) deviceRelations; 1908 break; 1909 1910 case BusRelations: // Not handled by PDO 1911 case EjectionRelations: // optional for PDO 1912 case RemovalRelations: // // optional for PDO 1913 default: 1914 status = Irp->IoStatus.Status; 1915 } 1916 1917 return status; 1918 } 1919 1920 NTSTATUS 1921 Bus_PDO_QueryBusInformation( 1922 PPDO_DEVICE_DATA DeviceData, 1923 PIRP Irp ) 1924 /*++ 1925 1926 Routine Description: 1927 1928 The PnP Manager uses this IRP to request the type and 1929 instance number of a device's parent bus. Bus drivers 1930 should handle this request for their child devices (PDOs). 1931 1932 Arguments: 1933 1934 DeviceData - Pointer to the PDO's device extension. 1935 Irp - Pointer to the irp. 1936 1937 Return Value: 1938 1939 NT STATUS 1940 1941 --*/ 1942 { 1943 1944 PPNP_BUS_INFORMATION busInfo; 1945 1946 PAGED_CODE (); 1947 1948 busInfo = ExAllocatePoolWithTag(PagedPool, 1949 sizeof(PNP_BUS_INFORMATION), 1950 'IpcA'); 1951 1952 if (busInfo == NULL) { 1953 return STATUS_INSUFFICIENT_RESOURCES; 1954 } 1955 1956 busInfo->BusTypeGuid = GUID_ACPI_INTERFACE_STANDARD; 1957 1958 busInfo->LegacyBusType = InternalPowerBus; 1959 1960 busInfo->BusNumber = 0; //fixme 1961 1962 Irp->IoStatus.Information = (ULONG_PTR)busInfo; 1963 1964 return STATUS_SUCCESS; 1965 } 1966 1967 1968 NTSTATUS 1969 Bus_GetDeviceCapabilities( 1970 PDEVICE_OBJECT DeviceObject, 1971 PDEVICE_CAPABILITIES DeviceCapabilities 1972 ) 1973 { 1974 IO_STATUS_BLOCK ioStatus; 1975 KEVENT pnpEvent; 1976 NTSTATUS status; 1977 PDEVICE_OBJECT targetObject; 1978 PIO_STACK_LOCATION irpStack; 1979 PIRP pnpIrp; 1980 1981 PAGED_CODE(); 1982 1983 // 1984 // Initialize the capabilities that we will send down 1985 // 1986 RtlZeroMemory( DeviceCapabilities, sizeof(DEVICE_CAPABILITIES) ); 1987 DeviceCapabilities->Size = sizeof(DEVICE_CAPABILITIES); 1988 DeviceCapabilities->Version = 1; 1989 DeviceCapabilities->Address = -1; 1990 DeviceCapabilities->UINumber = -1; 1991 1992 // 1993 // Initialize the event 1994 // 1995 KeInitializeEvent( &pnpEvent, NotificationEvent, FALSE ); 1996 1997 targetObject = IoGetAttachedDeviceReference( DeviceObject ); 1998 1999 // 2000 // Build an Irp 2001 // 2002 pnpIrp = IoBuildSynchronousFsdRequest( 2003 IRP_MJ_PNP, 2004 targetObject, 2005 NULL, 2006 0, 2007 NULL, 2008 &pnpEvent, 2009 &ioStatus 2010 ); 2011 if (pnpIrp == NULL) { 2012 2013 status = STATUS_INSUFFICIENT_RESOURCES; 2014 goto GetDeviceCapabilitiesExit; 2015 2016 } 2017 2018 // 2019 // Pnp Irps all begin life as STATUS_NOT_SUPPORTED; 2020 // 2021 pnpIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; 2022 2023 // 2024 // Get the top of stack 2025 // 2026 irpStack = IoGetNextIrpStackLocation( pnpIrp ); 2027 2028 // 2029 // Set the top of stack 2030 // 2031 RtlZeroMemory( irpStack, sizeof(IO_STACK_LOCATION ) ); 2032 irpStack->MajorFunction = IRP_MJ_PNP; 2033 irpStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES; 2034 irpStack->Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities; 2035 2036 // 2037 // Call the driver 2038 // 2039 status = IoCallDriver( targetObject, pnpIrp ); 2040 if (status == STATUS_PENDING) { 2041 2042 // 2043 // Block until the irp comes back. 2044 // Important thing to note here is when you allocate 2045 // the memory for an event in the stack you must do a 2046 // KernelMode wait instead of UserMode to prevent 2047 // the stack from getting paged out. 2048 // 2049 2050 KeWaitForSingleObject( 2051 &pnpEvent, 2052 Executive, 2053 KernelMode, 2054 FALSE, 2055 NULL 2056 ); 2057 status = ioStatus.Status; 2058 2059 } 2060 2061 GetDeviceCapabilitiesExit: 2062 // 2063 // Done with reference 2064 // 2065 ObDereferenceObject( targetObject ); 2066 2067 // 2068 // Done 2069 // 2070 return status; 2071 2072 } 2073 #endif /* UNIT_TEST */ 2074