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