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