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