Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbuspdo.c
Go to the documentation of this file.
00001 #include <ntddk.h> 00002 00003 #include <acpi.h> 00004 #include <acpisys.h> 00005 #include <wdmguid.h> 00006 #include <stdio.h> 00007 00008 #include <acpi_bus.h> 00009 #include <acpi_drivers.h> 00010 00011 #include <initguid.h> 00012 #include <poclass.h> 00013 00014 #define NDEBUG 00015 #include <debug.h> 00016 00017 #ifdef ALLOC_PRAGMA 00018 #pragma alloc_text (PAGE, Bus_PDO_PnP) 00019 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceCaps) 00020 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceId) 00021 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceText) 00022 #pragma alloc_text (PAGE, Bus_PDO_QueryResources) 00023 #pragma alloc_text (PAGE, Bus_PDO_QueryResourceRequirements) 00024 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceRelations) 00025 #pragma alloc_text (PAGE, Bus_PDO_QueryBusInformation) 00026 #pragma alloc_text (PAGE, Bus_GetDeviceCapabilities) 00027 #endif 00028 00029 NTSTATUS 00030 Bus_PDO_PnP ( 00031 PDEVICE_OBJECT DeviceObject, 00032 PIRP Irp, 00033 PIO_STACK_LOCATION IrpStack, 00034 PPDO_DEVICE_DATA DeviceData 00035 ) 00036 { 00037 NTSTATUS status; 00038 POWER_STATE state; 00039 struct acpi_device *device = NULL; 00040 00041 PAGED_CODE (); 00042 00043 if (DeviceData->AcpiHandle) 00044 acpi_bus_get_device(DeviceData->AcpiHandle, &device); 00045 00046 // 00047 // NB: Because we are a bus enumerator, we have no one to whom we could 00048 // defer these irps. Therefore we do not pass them down but merely 00049 // return them. 00050 // 00051 00052 switch (IrpStack->MinorFunction) { 00053 00054 case IRP_MN_START_DEVICE: 00055 // 00056 // Here we do what ever initialization and ``turning on'' that is 00057 // required to allow others to access this device. 00058 // Power up the device. 00059 // 00060 if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) && 00061 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D0))) 00062 { 00063 DPRINT1("Device %x failed to start!\n", DeviceData->AcpiHandle); 00064 status = STATUS_UNSUCCESSFUL; 00065 break; 00066 } 00067 00068 DeviceData->InterfaceName.Length = 0; 00069 status = STATUS_SUCCESS; 00070 00071 if (!device) 00072 { 00073 status = IoRegisterDeviceInterface(DeviceData->Common.Self, 00074 &GUID_DEVICE_SYS_BUTTON, 00075 NULL, 00076 &DeviceData->InterfaceName); 00077 } 00078 else if (device->flags.hardware_id && 00079 strstr(device->pnp.hardware_id, ACPI_THERMAL_HID)) 00080 { 00081 status = IoRegisterDeviceInterface(DeviceData->Common.Self, 00082 &GUID_DEVICE_THERMAL_ZONE, 00083 NULL, 00084 &DeviceData->InterfaceName); 00085 } 00086 else if (device->flags.hardware_id && 00087 strstr(device->pnp.hardware_id, ACPI_BUTTON_HID_LID)) 00088 { 00089 status = IoRegisterDeviceInterface(DeviceData->Common.Self, 00090 &GUID_DEVICE_LID, 00091 NULL, 00092 &DeviceData->InterfaceName); 00093 } 00094 else if (device->flags.hardware_id && 00095 strstr(device->pnp.hardware_id, ACPI_PROCESSOR_HID)) 00096 { 00097 status = IoRegisterDeviceInterface(DeviceData->Common.Self, 00098 &GUID_DEVICE_PROCESSOR, 00099 NULL, 00100 &DeviceData->InterfaceName); 00101 } 00102 00103 /* Failure to register an interface is not a fatal failure so don't return a failure status */ 00104 if (NT_SUCCESS(status) && DeviceData->InterfaceName.Length != 0) 00105 IoSetDeviceInterfaceState(&DeviceData->InterfaceName, TRUE); 00106 00107 state.DeviceState = PowerDeviceD0; 00108 PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state); 00109 DeviceData->Common.DevicePowerState = PowerDeviceD0; 00110 SET_NEW_PNP_STATE(DeviceData->Common, Started); 00111 status = STATUS_SUCCESS; 00112 break; 00113 00114 case IRP_MN_STOP_DEVICE: 00115 00116 if (DeviceData->InterfaceName.Length != 0) 00117 IoSetDeviceInterfaceState(&DeviceData->InterfaceName, FALSE); 00118 00119 // 00120 // Here we shut down the device and give up and unmap any resources 00121 // we acquired for the device. 00122 // 00123 if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) && 00124 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D3))) 00125 { 00126 DPRINT1("Device %x failed to stop!\n", DeviceData->AcpiHandle); 00127 status = STATUS_UNSUCCESSFUL; 00128 break; 00129 } 00130 00131 state.DeviceState = PowerDeviceD3; 00132 PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state); 00133 DeviceData->Common.DevicePowerState = PowerDeviceD3; 00134 SET_NEW_PNP_STATE(DeviceData->Common, Stopped); 00135 status = STATUS_SUCCESS; 00136 break; 00137 00138 00139 case IRP_MN_QUERY_STOP_DEVICE: 00140 00141 // 00142 // No reason here why we can't stop the device. 00143 // If there were a reason we should speak now, because answering success 00144 // here may result in a stop device irp. 00145 // 00146 00147 SET_NEW_PNP_STATE(DeviceData->Common, StopPending); 00148 status = STATUS_SUCCESS; 00149 break; 00150 00151 case IRP_MN_CANCEL_STOP_DEVICE: 00152 00153 // 00154 // The stop was canceled. Whatever state we set, or resources we put 00155 // on hold in anticipation of the forthcoming STOP device IRP should be 00156 // put back to normal. Someone, in the long list of concerned parties, 00157 // has failed the stop device query. 00158 // 00159 00160 // 00161 // First check to see whether you have received cancel-stop 00162 // without first receiving a query-stop. This could happen if someone 00163 // above us fails a query-stop and passes down the subsequent 00164 // cancel-stop. 00165 // 00166 00167 if (StopPending == DeviceData->Common.DevicePnPState) 00168 { 00169 // 00170 // We did receive a query-stop, so restore. 00171 // 00172 RESTORE_PREVIOUS_PNP_STATE(DeviceData->Common); 00173 } 00174 status = STATUS_SUCCESS;// We must not fail this IRP. 00175 break; 00176 case IRP_MN_QUERY_CAPABILITIES: 00177 00178 // 00179 // Return the capabilities of a device, such as whether the device 00180 // can be locked or ejected..etc 00181 // 00182 00183 status = Bus_PDO_QueryDeviceCaps(DeviceData, Irp); 00184 00185 break; 00186 00187 case IRP_MN_QUERY_ID: 00188 00189 // Query the IDs of the device 00190 status = Bus_PDO_QueryDeviceId(DeviceData, Irp); 00191 00192 break; 00193 00194 case IRP_MN_QUERY_DEVICE_RELATIONS: 00195 00196 DPRINT("\tQueryDeviceRelation Type: %s\n",DbgDeviceRelationString(\ 00197 IrpStack->Parameters.QueryDeviceRelations.Type)); 00198 00199 status = Bus_PDO_QueryDeviceRelations(DeviceData, Irp); 00200 00201 break; 00202 00203 case IRP_MN_QUERY_DEVICE_TEXT: 00204 00205 status = Bus_PDO_QueryDeviceText(DeviceData, Irp); 00206 00207 break; 00208 00209 case IRP_MN_QUERY_RESOURCES: 00210 00211 status = Bus_PDO_QueryResources(DeviceData, Irp); 00212 00213 break; 00214 00215 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 00216 00217 status = Bus_PDO_QueryResourceRequirements(DeviceData, Irp); 00218 00219 break; 00220 00221 case IRP_MN_QUERY_BUS_INFORMATION: 00222 00223 status = Bus_PDO_QueryBusInformation(DeviceData, Irp); 00224 00225 break; 00226 00227 case IRP_MN_QUERY_INTERFACE: 00228 00229 status = Bus_PDO_QueryInterface(DeviceData, Irp); 00230 00231 break; 00232 00233 00234 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: 00235 00236 // 00237 // OPTIONAL for bus drivers. 00238 // The PnP Manager sends this IRP to a device 00239 // stack so filter and function drivers can adjust the 00240 // resources required by the device, if appropriate. 00241 // 00242 00243 //break; 00244 00245 //case IRP_MN_QUERY_PNP_DEVICE_STATE: 00246 00247 // 00248 // OPTIONAL for bus drivers. 00249 // The PnP Manager sends this IRP after the drivers for 00250 // a device return success from the IRP_MN_START_DEVICE 00251 // request. The PnP Manager also sends this IRP when a 00252 // driver for the device calls IoInvalidateDeviceState. 00253 // 00254 00255 // break; 00256 00257 //case IRP_MN_READ_CONFIG: 00258 //case IRP_MN_WRITE_CONFIG: 00259 00260 // 00261 // Bus drivers for buses with configuration space must handle 00262 // this request for their child devices. Our devices don't 00263 // have a config space. 00264 // 00265 00266 // break; 00267 00268 //case IRP_MN_SET_LOCK: 00269 00270 // break; 00271 00272 default: 00273 00274 // 00275 // For PnP requests to the PDO that we do not understand we should 00276 // return the IRP WITHOUT setting the status or information fields. 00277 // These fields may have already been set by a filter (eg acpi). 00278 status = Irp->IoStatus.Status; 00279 00280 break; 00281 } 00282 00283 Irp->IoStatus.Status = status; 00284 IoCompleteRequest (Irp, IO_NO_INCREMENT); 00285 00286 return status; 00287 } 00288 00289 NTSTATUS 00290 Bus_PDO_QueryDeviceCaps( 00291 PPDO_DEVICE_DATA DeviceData, 00292 PIRP Irp ) 00293 { 00294 00295 PIO_STACK_LOCATION stack; 00296 PDEVICE_CAPABILITIES deviceCapabilities; 00297 struct acpi_device *device = NULL; 00298 ULONG i; 00299 00300 PAGED_CODE (); 00301 00302 if (DeviceData->AcpiHandle) 00303 acpi_bus_get_device(DeviceData->AcpiHandle, &device); 00304 00305 stack = IoGetCurrentIrpStackLocation (Irp); 00306 00307 // 00308 // Get the packet. 00309 // 00310 deviceCapabilities=stack->Parameters.DeviceCapabilities.Capabilities; 00311 00312 // 00313 // Set the capabilities. 00314 // 00315 00316 if (deviceCapabilities->Version != 1 || 00317 deviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES)) 00318 { 00319 return STATUS_UNSUCCESSFUL; 00320 } 00321 00322 deviceCapabilities->D1Latency = 0; 00323 deviceCapabilities->D2Latency = 0; 00324 deviceCapabilities->D3Latency = 0; 00325 00326 deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0; 00327 deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD3; 00328 deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3; 00329 deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3; 00330 00331 for (i = 0; i < ACPI_D_STATE_COUNT && device; i++) 00332 { 00333 if (!device->power.states[i].flags.valid) 00334 continue; 00335 00336 switch (i) 00337 { 00338 case ACPI_STATE_D0: 00339 deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0; 00340 break; 00341 00342 case ACPI_STATE_D1: 00343 deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1; 00344 deviceCapabilities->D1Latency = device->power.states[i].latency; 00345 break; 00346 00347 case ACPI_STATE_D2: 00348 deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD2; 00349 deviceCapabilities->D2Latency = device->power.states[i].latency; 00350 break; 00351 00352 case ACPI_STATE_D3: 00353 deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3; 00354 deviceCapabilities->D3Latency = device->power.states[i].latency; 00355 break; 00356 } 00357 } 00358 00359 // We can wake the system from D1 00360 deviceCapabilities->DeviceWake = PowerDeviceD1; 00361 00362 00363 deviceCapabilities->DeviceD1 = 00364 (deviceCapabilities->DeviceState[PowerSystemSleeping1] == PowerDeviceD1) ? TRUE : FALSE; 00365 deviceCapabilities->DeviceD2 = 00366 (deviceCapabilities->DeviceState[PowerSystemSleeping2] == PowerDeviceD2) ? TRUE : FALSE; 00367 00368 deviceCapabilities->WakeFromD0 = FALSE; 00369 deviceCapabilities->WakeFromD1 = TRUE; //Yes we can 00370 deviceCapabilities->WakeFromD2 = FALSE; 00371 deviceCapabilities->WakeFromD3 = FALSE; 00372 00373 if (device) 00374 { 00375 deviceCapabilities->LockSupported = device->flags.lockable; 00376 deviceCapabilities->EjectSupported = device->flags.ejectable; 00377 deviceCapabilities->HardwareDisabled = !device->status.enabled && !device->status.functional; 00378 deviceCapabilities->Removable = device->flags.removable; 00379 deviceCapabilities->SurpriseRemovalOK = device->flags.suprise_removal_ok; 00380 deviceCapabilities->UniqueID = device->flags.unique_id; 00381 deviceCapabilities->NoDisplayInUI = !device->status.show_in_ui; 00382 deviceCapabilities->Address = device->pnp.bus_address; 00383 } 00384 00385 if (!device || 00386 (device->flags.hardware_id && 00387 (strstr(device->pnp.hardware_id, ACPI_BUTTON_HID_LID) || 00388 strstr(device->pnp.hardware_id, ACPI_THERMAL_HID) || 00389 strstr(device->pnp.hardware_id, ACPI_PROCESSOR_HID)))) 00390 { 00391 /* Allow ACPI to control the device if it is a lid button, 00392 * a thermal zone, a processor, or a fixed feature button */ 00393 deviceCapabilities->RawDeviceOK = TRUE; 00394 } 00395 00396 deviceCapabilities->SilentInstall = FALSE; 00397 deviceCapabilities->UINumber = (ULONG)-1; 00398 00399 return STATUS_SUCCESS; 00400 00401 } 00402 00403 NTSTATUS 00404 Bus_PDO_QueryDeviceId( 00405 PPDO_DEVICE_DATA DeviceData, 00406 PIRP Irp ) 00407 { 00408 PIO_STACK_LOCATION stack; 00409 PWCHAR buffer; 00410 WCHAR temp[256]; 00411 ULONG length; 00412 NTSTATUS status = STATUS_SUCCESS; 00413 struct acpi_device *Device; 00414 00415 PAGED_CODE (); 00416 00417 stack = IoGetCurrentIrpStackLocation (Irp); 00418 00419 switch (stack->Parameters.QueryId.IdType) { 00420 00421 case BusQueryDeviceID: 00422 if (DeviceData->AcpiHandle) 00423 { 00424 acpi_bus_get_device(DeviceData->AcpiHandle, &Device); 00425 00426 length = swprintf(temp, 00427 L"ACPI\\%hs", 00428 Device->pnp.hardware_id); 00429 } 00430 else 00431 { 00432 /* We know it's a fixed feature button because 00433 * these are direct children of the ACPI root device 00434 * and therefore have no handle 00435 */ 00436 length = swprintf(temp, 00437 L"ACPI\\FixedButton"); 00438 } 00439 00440 temp[++length] = UNICODE_NULL; 00441 00442 buffer = ExAllocatePoolWithTag (PagedPool, length * sizeof(WCHAR), 'IPCA'); 00443 00444 if (!buffer) { 00445 status = STATUS_INSUFFICIENT_RESOURCES; 00446 break; 00447 } 00448 00449 RtlCopyMemory (buffer, temp, length * sizeof(WCHAR)); 00450 Irp->IoStatus.Information = (ULONG_PTR) buffer; 00451 DPRINT("BusQueryDeviceID: %ls\n",buffer); 00452 break; 00453 00454 case BusQueryInstanceID: 00455 /* See comment in BusQueryDeviceID case */ 00456 if(DeviceData->AcpiHandle) 00457 { 00458 acpi_bus_get_device(DeviceData->AcpiHandle, &Device); 00459 00460 if (Device->flags.unique_id) 00461 length = swprintf(temp, 00462 L"%hs", 00463 Device->pnp.unique_id); 00464 else 00465 /* FIXME: Generate unique id! */ 00466 length = swprintf(temp, L"%ls", L"0000"); 00467 } 00468 else 00469 /* FIXME: Generate unique id! */ 00470 length = swprintf(temp, L"%ls", L"0000"); 00471 00472 temp[++length] = UNICODE_NULL; 00473 00474 buffer = ExAllocatePoolWithTag (PagedPool, length * sizeof (WCHAR), 'IPCA'); 00475 if (!buffer) { 00476 status = STATUS_INSUFFICIENT_RESOURCES; 00477 break; 00478 } 00479 00480 RtlCopyMemory (buffer, temp, length * sizeof (WCHAR)); 00481 DPRINT("BusQueryInstanceID: %ls\n",buffer); 00482 Irp->IoStatus.Information = (ULONG_PTR) buffer; 00483 break; 00484 00485 case BusQueryHardwareIDs: 00486 length = 0; 00487 00488 /* See comment in BusQueryDeviceID case */ 00489 if (DeviceData->AcpiHandle) 00490 { 00491 acpi_bus_get_device(DeviceData->AcpiHandle, &Device); 00492 00493 length += swprintf(&temp[length], 00494 L"ACPI\\%hs", 00495 Device->pnp.hardware_id); 00496 length++; 00497 00498 length += swprintf(&temp[length], 00499 L"*%hs", 00500 Device->pnp.hardware_id); 00501 length++; 00502 } 00503 else 00504 { 00505 length += swprintf(&temp[length], 00506 L"ACPI\\FixedButton"); 00507 length++; 00508 00509 length += swprintf(&temp[length], 00510 L"*FixedButton"); 00511 length++; 00512 } 00513 00514 temp[length] = UNICODE_NULL; 00515 00516 length++; 00517 00518 temp[length] = UNICODE_NULL; 00519 00520 buffer = ExAllocatePoolWithTag (PagedPool, length * sizeof(WCHAR), 'IPCA'); 00521 00522 if (!buffer) { 00523 status = STATUS_INSUFFICIENT_RESOURCES; 00524 break; 00525 } 00526 00527 RtlCopyMemory (buffer, temp, length * sizeof(WCHAR)); 00528 Irp->IoStatus.Information = (ULONG_PTR) buffer; 00529 DPRINT("BusQueryHardwareIDs: %ls\n",buffer); 00530 break; 00531 00532 default: 00533 status = Irp->IoStatus.Status; 00534 } 00535 return status; 00536 } 00537 00538 NTSTATUS 00539 Bus_PDO_QueryDeviceText( 00540 PPDO_DEVICE_DATA DeviceData, 00541 PIRP Irp ) 00542 { 00543 PWCHAR Buffer, Temp; 00544 PIO_STACK_LOCATION stack; 00545 NTSTATUS status = Irp->IoStatus.Status; 00546 PAGED_CODE (); 00547 00548 stack = IoGetCurrentIrpStackLocation (Irp); 00549 00550 switch (stack->Parameters.QueryDeviceText.DeviceTextType) { 00551 00552 case DeviceTextDescription: 00553 00554 if (!Irp->IoStatus.Information) { 00555 if (wcsstr (DeviceData->HardwareIDs, L"PNP000") != 0) 00556 Temp = L"Programmable interrupt controller"; 00557 else if (wcsstr(DeviceData->HardwareIDs, L"PNP010") != 0) 00558 Temp = L"System timer"; 00559 else if (wcsstr(DeviceData->HardwareIDs, L"PNP020") != 0) 00560 Temp = L"DMA controller"; 00561 else if (wcsstr(DeviceData->HardwareIDs, L"PNP03") != 0) 00562 Temp = L"Keyboard"; 00563 else if (wcsstr(DeviceData->HardwareIDs, L"PNP040") != 0) 00564 Temp = L"Parallel port"; 00565 else if (wcsstr(DeviceData->HardwareIDs, L"PNP05") != 0) 00566 Temp = L"Serial port"; 00567 else if (wcsstr(DeviceData->HardwareIDs, L"PNP06") != 0) 00568 Temp = L"Disk controller"; 00569 else if (wcsstr(DeviceData->HardwareIDs, L"PNP07") != 0) 00570 Temp = L"Disk controller"; 00571 else if (wcsstr(DeviceData->HardwareIDs, L"PNP09") != 0) 00572 Temp = L"Display adapter"; 00573 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0A0") != 0) 00574 Temp = L"Bus controller"; 00575 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0E0") != 0) 00576 Temp = L"PCMCIA controller"; 00577 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0F") != 0) 00578 Temp = L"Mouse device"; 00579 else if (wcsstr(DeviceData->HardwareIDs, L"PNP8") != 0) 00580 Temp = L"Network adapter"; 00581 else if (wcsstr(DeviceData->HardwareIDs, L"PNPA0") != 0) 00582 Temp = L"SCSI controller"; 00583 else if (wcsstr(DeviceData->HardwareIDs, L"PNPB0") != 0) 00584 Temp = L"Multimedia device"; 00585 else if (wcsstr(DeviceData->HardwareIDs, L"PNPC00") != 0) 00586 Temp = L"Modem"; 00587 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0C") != 0) 00588 Temp = L"Power Button"; 00589 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0E") != 0) 00590 Temp = L"Sleep Button"; 00591 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0D") != 0) 00592 Temp = L"Lid Switch"; 00593 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C09") != 0) 00594 Temp = L"ACPI Embedded Controller"; 00595 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0B") != 0) 00596 Temp = L"ACPI Fan"; 00597 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 || 00598 wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0 ) 00599 Temp = L"PCI Root Bridge"; 00600 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0A") != 0) 00601 Temp = L"ACPI Battery"; 00602 else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0F") != 0) 00603 Temp = L"PCI Interrupt Link"; 00604 else if (wcsstr(DeviceData->HardwareIDs, L"ACPI_PWR") != 0) 00605 Temp = L"ACPI Power Resource"; 00606 else if (wcsstr(DeviceData->HardwareIDs, L"Processor") != 0) 00607 Temp = L"Processor"; 00608 else if (wcsstr(DeviceData->HardwareIDs, L"ThermalZone") != 0) 00609 Temp = L"ACPI Thermal Zone"; 00610 else if (wcsstr(DeviceData->HardwareIDs, L"ACPI0002") != 0) 00611 Temp = L"Smart Battery"; 00612 else if (wcsstr(DeviceData->HardwareIDs, L"ACPI0003") != 0) 00613 Temp = L"AC Adapter"; 00614 /* Simply checking if AcpiHandle is NULL eliminates the need to check 00615 * for the 4 different names that ACPI knows the fixed feature button as internally 00616 */ 00617 else if (!DeviceData->AcpiHandle) 00618 Temp = L"ACPI Fixed Feature Button"; 00619 else 00620 Temp = L"Other ACPI device"; 00621 00622 Buffer = ExAllocatePoolWithTag (PagedPool, (wcslen(Temp) + 1) * sizeof(WCHAR), 'IPCA'); 00623 00624 if (!Buffer) { 00625 status = STATUS_INSUFFICIENT_RESOURCES; 00626 break; 00627 } 00628 00629 RtlCopyMemory (Buffer, Temp, (wcslen(Temp) + 1) * sizeof(WCHAR)); 00630 00631 DPRINT("\tDeviceTextDescription :%ws\n", Buffer); 00632 00633 Irp->IoStatus.Information = (ULONG_PTR) Buffer; 00634 status = STATUS_SUCCESS; 00635 } 00636 break; 00637 00638 default: 00639 break; 00640 } 00641 00642 return status; 00643 00644 } 00645 00646 NTSTATUS 00647 Bus_PDO_QueryResources( 00648 PPDO_DEVICE_DATA DeviceData, 00649 PIRP Irp ) 00650 { 00651 ULONG NumberOfResources = 0; 00652 PCM_RESOURCE_LIST ResourceList; 00653 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; 00654 ACPI_STATUS AcpiStatus; 00655 ACPI_BUFFER Buffer; 00656 ACPI_RESOURCE* resource; 00657 ULONG ResourceListSize; 00658 ULONG i; 00659 ULONGLONG BusNumber; 00660 struct acpi_device *device; 00661 00662 if (!DeviceData->AcpiHandle) 00663 { 00664 return Irp->IoStatus.Status; 00665 } 00666 00667 /* A bus number resource is not included in the list of current resources 00668 * for the root PCI bus so we manually query one here and if we find it 00669 * we create a resource list and add a bus number descriptor to it */ 00670 if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 || 00671 wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0) 00672 { 00673 acpi_bus_get_device(DeviceData->AcpiHandle, &device); 00674 00675 AcpiStatus = acpi_evaluate_integer(DeviceData->AcpiHandle, "_BBN", NULL, &BusNumber); 00676 if (AcpiStatus != AE_OK) 00677 { 00678 #if 0 00679 if (device->flags.unique_id) 00680 { 00681 /* FIXME: Try the unique ID */ 00682 } 00683 else 00684 #endif 00685 { 00686 BusNumber = 0; 00687 DPRINT1("Failed to find a bus number\n"); 00688 } 00689 } 00690 else 00691 { 00692 DPRINT1("Using _BBN for bus number\n"); 00693 } 00694 00695 DPRINT1("Found PCI root hub: %d\n", BusNumber); 00696 00697 ResourceListSize = sizeof(CM_RESOURCE_LIST); 00698 ResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, 'IPCA'); 00699 if (!ResourceList) 00700 return STATUS_INSUFFICIENT_RESOURCES; 00701 00702 ResourceList->Count = 1; 00703 ResourceList->List[0].InterfaceType = Internal; 00704 ResourceList->List[0].BusNumber = 0; 00705 ResourceList->List[0].PartialResourceList.Version = 1; 00706 ResourceList->List[0].PartialResourceList.Revision = 1; 00707 ResourceList->List[0].PartialResourceList.Count = 1; 00708 ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; 00709 00710 ResourceDescriptor->Type = CmResourceTypeBusNumber; 00711 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 00712 ResourceDescriptor->u.BusNumber.Start = BusNumber; 00713 ResourceDescriptor->u.BusNumber.Length = 1; 00714 00715 Irp->IoStatus.Information = (ULONG_PTR)ResourceList; 00716 return STATUS_SUCCESS; 00717 } 00718 00719 /* Get current resources */ 00720 Buffer.Length = 0; 00721 AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); 00722 if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) || 00723 Buffer.Length == 0) 00724 { 00725 return Irp->IoStatus.Status; 00726 } 00727 00728 Buffer.Pointer = ExAllocatePoolWithTag(PagedPool, Buffer.Length, 'IPCA'); 00729 if (!Buffer.Pointer) 00730 return STATUS_INSUFFICIENT_RESOURCES; 00731 00732 AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); 00733 if (!ACPI_SUCCESS(AcpiStatus)) 00734 { 00735 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus); 00736 ASSERT(FALSE); 00737 return STATUS_UNSUCCESSFUL; 00738 } 00739 00740 resource= Buffer.Pointer; 00741 /* Count number of resources */ 00742 while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG) 00743 { 00744 switch (resource->Type) 00745 { 00746 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 00747 { 00748 ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data; 00749 if (irq_data->ProducerConsumer == ACPI_PRODUCER) 00750 break; 00751 NumberOfResources += irq_data->InterruptCount; 00752 break; 00753 } 00754 case ACPI_RESOURCE_TYPE_IRQ: 00755 { 00756 ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data; 00757 NumberOfResources += irq_data->InterruptCount; 00758 break; 00759 } 00760 case ACPI_RESOURCE_TYPE_DMA: 00761 { 00762 ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data; 00763 NumberOfResources += dma_data->ChannelCount; 00764 break; 00765 } 00766 case ACPI_RESOURCE_TYPE_ADDRESS16: 00767 case ACPI_RESOURCE_TYPE_ADDRESS32: 00768 case ACPI_RESOURCE_TYPE_ADDRESS64: 00769 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 00770 { 00771 ACPI_RESOURCE_ADDRESS *addr_res = (ACPI_RESOURCE_ADDRESS*) &resource->Data; 00772 if (addr_res->ProducerConsumer == ACPI_PRODUCER) 00773 break; 00774 NumberOfResources++; 00775 break; 00776 } 00777 case ACPI_RESOURCE_TYPE_MEMORY24: 00778 case ACPI_RESOURCE_TYPE_MEMORY32: 00779 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 00780 case ACPI_RESOURCE_TYPE_FIXED_IO: 00781 case ACPI_RESOURCE_TYPE_IO: 00782 { 00783 NumberOfResources++; 00784 break; 00785 } 00786 default: 00787 { 00788 DPRINT1("Unknown resource type: %d\n", resource->Type); 00789 break; 00790 } 00791 } 00792 resource = ACPI_NEXT_RESOURCE(resource); 00793 } 00794 00795 /* Allocate memory */ 00796 ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1); 00797 ResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, 'IPCA'); 00798 00799 if (!ResourceList) 00800 { 00801 ExFreePoolWithTag(Buffer.Pointer, 'IPCA'); 00802 return STATUS_INSUFFICIENT_RESOURCES; 00803 } 00804 ResourceList->Count = 1; 00805 ResourceList->List[0].InterfaceType = Internal; /* FIXME */ 00806 ResourceList->List[0].BusNumber = 0; /* We're the only ACPI bus device in the system */ 00807 ResourceList->List[0].PartialResourceList.Version = 1; 00808 ResourceList->List[0].PartialResourceList.Revision = 1; 00809 ResourceList->List[0].PartialResourceList.Count = NumberOfResources; 00810 ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; 00811 00812 /* Fill resources list structure */ 00813 resource = Buffer.Pointer; 00814 while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG) 00815 { 00816 switch (resource->Type) 00817 { 00818 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 00819 { 00820 ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data; 00821 if (irq_data->ProducerConsumer == ACPI_PRODUCER) 00822 break; 00823 for (i = 0; i < irq_data->InterruptCount; i++) 00824 { 00825 ResourceDescriptor->Type = CmResourceTypeInterrupt; 00826 00827 ResourceDescriptor->ShareDisposition = 00828 (irq_data->Sharable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); 00829 ResourceDescriptor->Flags = 00830 (irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); 00831 ResourceDescriptor->u.Interrupt.Level = 00832 ResourceDescriptor->u.Interrupt.Vector = irq_data->Interrupts[i]; 00833 ResourceDescriptor->u.Interrupt.Affinity = (KAFFINITY)(-1); 00834 00835 ResourceDescriptor++; 00836 } 00837 break; 00838 } 00839 case ACPI_RESOURCE_TYPE_IRQ: 00840 { 00841 ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data; 00842 for (i = 0; i < irq_data->InterruptCount; i++) 00843 { 00844 ResourceDescriptor->Type = CmResourceTypeInterrupt; 00845 00846 ResourceDescriptor->ShareDisposition = 00847 (irq_data->Sharable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); 00848 ResourceDescriptor->Flags = 00849 (irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); 00850 ResourceDescriptor->u.Interrupt.Level = 00851 ResourceDescriptor->u.Interrupt.Vector = irq_data->Interrupts[i]; 00852 ResourceDescriptor->u.Interrupt.Affinity = (KAFFINITY)(-1); 00853 00854 ResourceDescriptor++; 00855 } 00856 break; 00857 } 00858 case ACPI_RESOURCE_TYPE_DMA: 00859 { 00860 ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data; 00861 for (i = 0; i < dma_data->ChannelCount; i++) 00862 { 00863 ResourceDescriptor->Type = CmResourceTypeDma; 00864 ResourceDescriptor->Flags = 0; 00865 switch (dma_data->Type) 00866 { 00867 case ACPI_TYPE_A: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break; 00868 case ACPI_TYPE_B: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break; 00869 case ACPI_TYPE_F: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break; 00870 } 00871 if (dma_data->BusMaster == ACPI_BUS_MASTER) 00872 ResourceDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER; 00873 switch (dma_data->Transfer) 00874 { 00875 case ACPI_TRANSFER_8: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8; break; 00876 case ACPI_TRANSFER_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_16; break; 00877 case ACPI_TRANSFER_8_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break; 00878 } 00879 ResourceDescriptor->u.Dma.Channel = dma_data->Channels[i]; 00880 00881 ResourceDescriptor++; 00882 } 00883 break; 00884 } 00885 case ACPI_RESOURCE_TYPE_IO: 00886 { 00887 ACPI_RESOURCE_IO *io_data = (ACPI_RESOURCE_IO*) &resource->Data; 00888 ResourceDescriptor->Type = CmResourceTypePort; 00889 ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 00890 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 00891 if (io_data->IoDecode == ACPI_DECODE_16) 00892 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE; 00893 else 00894 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE; 00895 ResourceDescriptor->u.Port.Start.QuadPart = io_data->Minimum; 00896 ResourceDescriptor->u.Port.Length = io_data->AddressLength; 00897 00898 ResourceDescriptor++; 00899 break; 00900 } 00901 case ACPI_RESOURCE_TYPE_FIXED_IO: 00902 { 00903 ACPI_RESOURCE_FIXED_IO *io_data = (ACPI_RESOURCE_FIXED_IO*) &resource->Data; 00904 ResourceDescriptor->Type = CmResourceTypePort; 00905 ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 00906 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 00907 ResourceDescriptor->u.Port.Start.QuadPart = io_data->Address; 00908 ResourceDescriptor->u.Port.Length = io_data->AddressLength; 00909 00910 ResourceDescriptor++; 00911 break; 00912 } 00913 case ACPI_RESOURCE_TYPE_ADDRESS16: 00914 { 00915 ACPI_RESOURCE_ADDRESS16 *addr16_data = (ACPI_RESOURCE_ADDRESS16*) &resource->Data; 00916 if (addr16_data->ProducerConsumer == ACPI_PRODUCER) 00917 break; 00918 if (addr16_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 00919 { 00920 ResourceDescriptor->Type = CmResourceTypeBusNumber; 00921 ResourceDescriptor->ShareDisposition = CmResourceShareShared; 00922 ResourceDescriptor->Flags = 0; 00923 ResourceDescriptor->u.BusNumber.Start = addr16_data->Minimum; 00924 ResourceDescriptor->u.BusNumber.Length = addr16_data->AddressLength; 00925 } 00926 else if (addr16_data->ResourceType == ACPI_IO_RANGE) 00927 { 00928 ResourceDescriptor->Type = CmResourceTypePort; 00929 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 00930 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 00931 if (addr16_data->Decode == ACPI_POS_DECODE) 00932 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 00933 ResourceDescriptor->u.Port.Start.QuadPart = addr16_data->Minimum; 00934 ResourceDescriptor->u.Port.Length = addr16_data->AddressLength; 00935 } 00936 else 00937 { 00938 ResourceDescriptor->Type = CmResourceTypeMemory; 00939 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 00940 ResourceDescriptor->Flags = 0; 00941 if (addr16_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 00942 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 00943 else 00944 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 00945 switch (addr16_data->Info.Mem.Caching) 00946 { 00947 case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 00948 case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 00949 case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 00950 } 00951 ResourceDescriptor->u.Memory.Start.QuadPart = addr16_data->Minimum; 00952 ResourceDescriptor->u.Memory.Length = addr16_data->AddressLength; 00953 } 00954 ResourceDescriptor++; 00955 break; 00956 } 00957 case ACPI_RESOURCE_TYPE_ADDRESS32: 00958 { 00959 ACPI_RESOURCE_ADDRESS32 *addr32_data = (ACPI_RESOURCE_ADDRESS32*) &resource->Data; 00960 if (addr32_data->ProducerConsumer == ACPI_PRODUCER) 00961 break; 00962 if (addr32_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 00963 { 00964 ResourceDescriptor->Type = CmResourceTypeBusNumber; 00965 ResourceDescriptor->ShareDisposition = CmResourceShareShared; 00966 ResourceDescriptor->Flags = 0; 00967 ResourceDescriptor->u.BusNumber.Start = addr32_data->Minimum; 00968 ResourceDescriptor->u.BusNumber.Length = addr32_data->AddressLength; 00969 } 00970 else if (addr32_data->ResourceType == ACPI_IO_RANGE) 00971 { 00972 ResourceDescriptor->Type = CmResourceTypePort; 00973 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 00974 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 00975 if (addr32_data->Decode == ACPI_POS_DECODE) 00976 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 00977 ResourceDescriptor->u.Port.Start.QuadPart = addr32_data->Minimum; 00978 ResourceDescriptor->u.Port.Length = addr32_data->AddressLength; 00979 } 00980 else 00981 { 00982 ResourceDescriptor->Type = CmResourceTypeMemory; 00983 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 00984 ResourceDescriptor->Flags = 0; 00985 if (addr32_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 00986 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 00987 else 00988 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 00989 switch (addr32_data->Info.Mem.Caching) 00990 { 00991 case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 00992 case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 00993 case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 00994 } 00995 ResourceDescriptor->u.Memory.Start.QuadPart = addr32_data->Minimum; 00996 ResourceDescriptor->u.Memory.Length = addr32_data->AddressLength; 00997 } 00998 ResourceDescriptor++; 00999 break; 01000 } 01001 case ACPI_RESOURCE_TYPE_ADDRESS64: 01002 { 01003 ACPI_RESOURCE_ADDRESS64 *addr64_data = (ACPI_RESOURCE_ADDRESS64*) &resource->Data; 01004 if (addr64_data->ProducerConsumer == ACPI_PRODUCER) 01005 break; 01006 if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 01007 { 01008 DPRINT1("64-bit bus address is not supported!\n"); 01009 ResourceDescriptor->Type = CmResourceTypeBusNumber; 01010 ResourceDescriptor->ShareDisposition = CmResourceShareShared; 01011 ResourceDescriptor->Flags = 0; 01012 ResourceDescriptor->u.BusNumber.Start = (ULONG)addr64_data->Minimum; 01013 ResourceDescriptor->u.BusNumber.Length = addr64_data->AddressLength; 01014 } 01015 else if (addr64_data->ResourceType == ACPI_IO_RANGE) 01016 { 01017 ResourceDescriptor->Type = CmResourceTypePort; 01018 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01019 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 01020 if (addr64_data->Decode == ACPI_POS_DECODE) 01021 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 01022 ResourceDescriptor->u.Port.Start.QuadPart = addr64_data->Minimum; 01023 ResourceDescriptor->u.Port.Length = addr64_data->AddressLength; 01024 } 01025 else 01026 { 01027 ResourceDescriptor->Type = CmResourceTypeMemory; 01028 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01029 ResourceDescriptor->Flags = 0; 01030 if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 01031 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01032 else 01033 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01034 switch (addr64_data->Info.Mem.Caching) 01035 { 01036 case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 01037 case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 01038 case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 01039 } 01040 ResourceDescriptor->u.Memory.Start.QuadPart = addr64_data->Minimum; 01041 ResourceDescriptor->u.Memory.Length = addr64_data->AddressLength; 01042 } 01043 ResourceDescriptor++; 01044 break; 01045 } 01046 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 01047 { 01048 ACPI_RESOURCE_EXTENDED_ADDRESS64 *addr64_data = (ACPI_RESOURCE_EXTENDED_ADDRESS64*) &resource->Data; 01049 if (addr64_data->ProducerConsumer == ACPI_PRODUCER) 01050 break; 01051 if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 01052 { 01053 DPRINT1("64-bit bus address is not supported!\n"); 01054 ResourceDescriptor->Type = CmResourceTypeBusNumber; 01055 ResourceDescriptor->ShareDisposition = CmResourceShareShared; 01056 ResourceDescriptor->Flags = 0; 01057 ResourceDescriptor->u.BusNumber.Start = (ULONG)addr64_data->Minimum; 01058 ResourceDescriptor->u.BusNumber.Length = addr64_data->AddressLength; 01059 } 01060 else if (addr64_data->ResourceType == ACPI_IO_RANGE) 01061 { 01062 ResourceDescriptor->Type = CmResourceTypePort; 01063 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01064 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO; 01065 if (addr64_data->Decode == ACPI_POS_DECODE) 01066 ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 01067 ResourceDescriptor->u.Port.Start.QuadPart = addr64_data->Minimum; 01068 ResourceDescriptor->u.Port.Length = addr64_data->AddressLength; 01069 } 01070 else 01071 { 01072 ResourceDescriptor->Type = CmResourceTypeMemory; 01073 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01074 ResourceDescriptor->Flags = 0; 01075 if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 01076 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01077 else 01078 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01079 switch (addr64_data->Info.Mem.Caching) 01080 { 01081 case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 01082 case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 01083 case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 01084 } 01085 ResourceDescriptor->u.Memory.Start.QuadPart = addr64_data->Minimum; 01086 ResourceDescriptor->u.Memory.Length = addr64_data->AddressLength; 01087 } 01088 ResourceDescriptor++; 01089 break; 01090 } 01091 case ACPI_RESOURCE_TYPE_MEMORY24: 01092 { 01093 ACPI_RESOURCE_MEMORY24 *mem24_data = (ACPI_RESOURCE_MEMORY24*) &resource->Data; 01094 ResourceDescriptor->Type = CmResourceTypeMemory; 01095 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01096 ResourceDescriptor->Flags = CM_RESOURCE_MEMORY_24; 01097 if (mem24_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 01098 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01099 else 01100 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01101 ResourceDescriptor->u.Memory.Start.QuadPart = mem24_data->Minimum; 01102 ResourceDescriptor->u.Memory.Length = mem24_data->AddressLength; 01103 01104 ResourceDescriptor++; 01105 break; 01106 } 01107 case ACPI_RESOURCE_TYPE_MEMORY32: 01108 { 01109 ACPI_RESOURCE_MEMORY32 *mem32_data = (ACPI_RESOURCE_MEMORY32*) &resource->Data; 01110 ResourceDescriptor->Type = CmResourceTypeMemory; 01111 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01112 ResourceDescriptor->Flags = 0; 01113 if (mem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 01114 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01115 else 01116 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01117 ResourceDescriptor->u.Memory.Start.QuadPart = mem32_data->Minimum; 01118 ResourceDescriptor->u.Memory.Length = mem32_data->AddressLength; 01119 01120 ResourceDescriptor++; 01121 break; 01122 } 01123 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 01124 { 01125 ACPI_RESOURCE_FIXED_MEMORY32 *memfixed32_data = (ACPI_RESOURCE_FIXED_MEMORY32*) &resource->Data; 01126 ResourceDescriptor->Type = CmResourceTypeMemory; 01127 ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01128 ResourceDescriptor->Flags = 0; 01129 if (memfixed32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 01130 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01131 else 01132 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01133 ResourceDescriptor->u.Memory.Start.QuadPart = memfixed32_data->Address; 01134 ResourceDescriptor->u.Memory.Length = memfixed32_data->AddressLength; 01135 01136 ResourceDescriptor++; 01137 break; 01138 } 01139 default: 01140 { 01141 break; 01142 } 01143 } 01144 resource = ACPI_NEXT_RESOURCE(resource); 01145 } 01146 01147 ExFreePoolWithTag(Buffer.Pointer, 'IPCA'); 01148 Irp->IoStatus.Information = (ULONG_PTR)ResourceList; 01149 return STATUS_SUCCESS; 01150 } 01151 01152 NTSTATUS 01153 Bus_PDO_QueryResourceRequirements( 01154 PPDO_DEVICE_DATA DeviceData, 01155 PIRP Irp ) 01156 { 01157 ULONG NumberOfResources = 0; 01158 ACPI_STATUS AcpiStatus; 01159 ACPI_BUFFER Buffer; 01160 ACPI_RESOURCE* resource; 01161 ULONG i, RequirementsListSize; 01162 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; 01163 PIO_RESOURCE_DESCRIPTOR RequirementDescriptor; 01164 BOOLEAN CurrentRes = FALSE; 01165 01166 PAGED_CODE (); 01167 01168 if (!DeviceData->AcpiHandle) 01169 { 01170 return Irp->IoStatus.Status; 01171 } 01172 01173 /* Handle the PCI root manually */ 01174 if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 || 01175 wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0) 01176 { 01177 return Irp->IoStatus.Status; 01178 } 01179 01180 /* Get current resources */ 01181 while (TRUE) 01182 { 01183 Buffer.Length = 0; 01184 if (CurrentRes) 01185 AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); 01186 else 01187 AcpiStatus = AcpiGetPossibleResources(DeviceData->AcpiHandle, &Buffer); 01188 if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) || 01189 Buffer.Length == 0) 01190 { 01191 if (!CurrentRes) 01192 CurrentRes = TRUE; 01193 else 01194 return Irp->IoStatus.Status; 01195 } 01196 else 01197 break; 01198 } 01199 01200 Buffer.Pointer = ExAllocatePoolWithTag(PagedPool, Buffer.Length, 'IPCA'); 01201 if (!Buffer.Pointer) 01202 return STATUS_INSUFFICIENT_RESOURCES; 01203 01204 if (CurrentRes) 01205 AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer); 01206 else 01207 AcpiStatus = AcpiGetPossibleResources(DeviceData->AcpiHandle, &Buffer); 01208 if (!ACPI_SUCCESS(AcpiStatus)) 01209 { 01210 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus); 01211 ASSERT(FALSE); 01212 return STATUS_UNSUCCESSFUL; 01213 } 01214 01215 resource= Buffer.Pointer; 01216 /* Count number of resources */ 01217 while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG) 01218 { 01219 switch (resource->Type) 01220 { 01221 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 01222 { 01223 ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data; 01224 if (irq_data->ProducerConsumer == ACPI_PRODUCER) 01225 break; 01226 NumberOfResources += irq_data->InterruptCount; 01227 break; 01228 } 01229 case ACPI_RESOURCE_TYPE_IRQ: 01230 { 01231 ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data; 01232 NumberOfResources += irq_data->InterruptCount; 01233 break; 01234 } 01235 case ACPI_RESOURCE_TYPE_DMA: 01236 { 01237 ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data; 01238 NumberOfResources += dma_data->ChannelCount; 01239 break; 01240 } 01241 case ACPI_RESOURCE_TYPE_ADDRESS16: 01242 case ACPI_RESOURCE_TYPE_ADDRESS32: 01243 case ACPI_RESOURCE_TYPE_ADDRESS64: 01244 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 01245 { 01246 ACPI_RESOURCE_ADDRESS *res_addr = (ACPI_RESOURCE_ADDRESS*) &resource->Data; 01247 if (res_addr->ProducerConsumer == ACPI_PRODUCER) 01248 break; 01249 NumberOfResources++; 01250 break; 01251 } 01252 case ACPI_RESOURCE_TYPE_MEMORY24: 01253 case ACPI_RESOURCE_TYPE_MEMORY32: 01254 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 01255 case ACPI_RESOURCE_TYPE_FIXED_IO: 01256 case ACPI_RESOURCE_TYPE_IO: 01257 { 01258 NumberOfResources++; 01259 break; 01260 } 01261 default: 01262 { 01263 break; 01264 } 01265 } 01266 resource = ACPI_NEXT_RESOURCE(resource); 01267 } 01268 01269 RequirementsListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) + sizeof(IO_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1); 01270 RequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST)ExAllocatePoolWithTag(PagedPool, RequirementsListSize, 'IPCA'); 01271 01272 if (!RequirementsList) 01273 { 01274 ExFreePoolWithTag(Buffer.Pointer, 'IPCA'); 01275 return STATUS_INSUFFICIENT_RESOURCES; 01276 } 01277 RequirementsList->ListSize = RequirementsListSize; 01278 RequirementsList->InterfaceType = Internal; 01279 RequirementsList->BusNumber = 0; 01280 RequirementsList->SlotNumber = 0; /* Not used by WDM drivers */ 01281 RequirementsList->AlternativeLists = 1; 01282 RequirementsList->List[0].Version = 1; 01283 RequirementsList->List[0].Revision = 1; 01284 RequirementsList->List[0].Count = NumberOfResources; 01285 RequirementDescriptor = RequirementsList->List[0].Descriptors; 01286 01287 /* Fill resources list structure */ 01288 resource = Buffer.Pointer; 01289 while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG && resource->Type != ACPI_RESOURCE_TYPE_END_DEPENDENT) 01290 { 01291 switch (resource->Type) 01292 { 01293 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 01294 { 01295 ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data; 01296 if (irq_data->ProducerConsumer == ACPI_PRODUCER) 01297 break; 01298 for (i = 0; i < irq_data->InterruptCount; i++) 01299 { 01300 RequirementDescriptor->Option = (i == 0) ? IO_RESOURCE_PREFERRED : IO_RESOURCE_ALTERNATIVE; 01301 RequirementDescriptor->Type = CmResourceTypeInterrupt; 01302 RequirementDescriptor->ShareDisposition = (irq_data->Sharable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); 01303 RequirementDescriptor->Flags =(irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); 01304 RequirementDescriptor->u.Interrupt.MinimumVector = 01305 RequirementDescriptor->u.Interrupt.MaximumVector = irq_data->Interrupts[i]; 01306 01307 RequirementDescriptor++; 01308 } 01309 break; 01310 } 01311 case ACPI_RESOURCE_TYPE_IRQ: 01312 { 01313 ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data; 01314 for (i = 0; i < irq_data->InterruptCount; i++) 01315 { 01316 RequirementDescriptor->Option = (i == 0) ? IO_RESOURCE_PREFERRED : IO_RESOURCE_ALTERNATIVE; 01317 RequirementDescriptor->Type = CmResourceTypeInterrupt; 01318 RequirementDescriptor->ShareDisposition = (irq_data->Sharable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive); 01319 RequirementDescriptor->Flags =(irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED); 01320 RequirementDescriptor->u.Interrupt.MinimumVector = 01321 RequirementDescriptor->u.Interrupt.MaximumVector = irq_data->Interrupts[i]; 01322 01323 RequirementDescriptor++; 01324 } 01325 break; 01326 } 01327 case ACPI_RESOURCE_TYPE_DMA: 01328 { 01329 ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data; 01330 for (i = 0; i < dma_data->ChannelCount; i++) 01331 { 01332 RequirementDescriptor->Type = CmResourceTypeDma; 01333 RequirementDescriptor->Flags = 0; 01334 switch (dma_data->Type) 01335 { 01336 case ACPI_TYPE_A: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break; 01337 case ACPI_TYPE_B: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break; 01338 case ACPI_TYPE_F: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break; 01339 } 01340 if (dma_data->BusMaster == ACPI_BUS_MASTER) 01341 RequirementDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER; 01342 switch (dma_data->Transfer) 01343 { 01344 case ACPI_TRANSFER_8: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8; break; 01345 case ACPI_TRANSFER_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_16; break; 01346 case ACPI_TRANSFER_8_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break; 01347 } 01348 01349 RequirementDescriptor->Option = (i == 0) ? IO_RESOURCE_PREFERRED : IO_RESOURCE_ALTERNATIVE; 01350 RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 01351 RequirementDescriptor->u.Dma.MinimumChannel = 01352 RequirementDescriptor->u.Dma.MaximumChannel = dma_data->Channels[i]; 01353 RequirementDescriptor++; 01354 } 01355 break; 01356 } 01357 case ACPI_RESOURCE_TYPE_IO: 01358 { 01359 ACPI_RESOURCE_IO *io_data = (ACPI_RESOURCE_IO*) &resource->Data; 01360 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 01361 if (io_data->IoDecode == ACPI_DECODE_16) 01362 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE; 01363 else 01364 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE; 01365 RequirementDescriptor->u.Port.Length = io_data->AddressLength; 01366 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 01367 RequirementDescriptor->Type = CmResourceTypePort; 01368 RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 01369 RequirementDescriptor->u.Port.Alignment = io_data->Alignment; 01370 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = io_data->Minimum; 01371 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = io_data->Maximum + io_data->AddressLength - 1; 01372 01373 RequirementDescriptor++; 01374 break; 01375 } 01376 case ACPI_RESOURCE_TYPE_FIXED_IO: 01377 { 01378 ACPI_RESOURCE_FIXED_IO *io_data = (ACPI_RESOURCE_FIXED_IO*) &resource->Data; 01379 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 01380 RequirementDescriptor->u.Port.Length = io_data->AddressLength; 01381 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 01382 RequirementDescriptor->Type = CmResourceTypePort; 01383 RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive; 01384 RequirementDescriptor->u.Port.Alignment = 1; 01385 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = io_data->Address; 01386 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = io_data->Address + io_data->AddressLength - 1; 01387 01388 RequirementDescriptor++; 01389 break; 01390 } 01391 case ACPI_RESOURCE_TYPE_ADDRESS16: 01392 { 01393 ACPI_RESOURCE_ADDRESS16 *addr16_data = (ACPI_RESOURCE_ADDRESS16*) &resource->Data; 01394 if (addr16_data->ProducerConsumer == ACPI_PRODUCER) 01395 break; 01396 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 01397 if (addr16_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 01398 { 01399 RequirementDescriptor->Type = CmResourceTypeBusNumber; 01400 RequirementDescriptor->ShareDisposition = CmResourceShareShared; 01401 RequirementDescriptor->Flags = 0; 01402 RequirementDescriptor->u.BusNumber.MinBusNumber = addr16_data->Minimum; 01403 RequirementDescriptor->u.BusNumber.MaxBusNumber = addr16_data->Maximum + addr16_data->AddressLength - 1; 01404 RequirementDescriptor->u.BusNumber.Length = addr16_data->AddressLength; 01405 } 01406 else if (addr16_data->ResourceType == ACPI_IO_RANGE) 01407 { 01408 RequirementDescriptor->Type = CmResourceTypePort; 01409 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01410 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 01411 if (addr16_data->Decode == ACPI_POS_DECODE) 01412 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 01413 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr16_data->Minimum; 01414 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr16_data->Maximum + addr16_data->AddressLength - 1; 01415 RequirementDescriptor->u.Port.Length = addr16_data->AddressLength; 01416 } 01417 else 01418 { 01419 RequirementDescriptor->Type = CmResourceTypeMemory; 01420 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01421 RequirementDescriptor->Flags = 0; 01422 if (addr16_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 01423 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01424 else 01425 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01426 switch (addr16_data->Info.Mem.Caching) 01427 { 01428 case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 01429 case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 01430 case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 01431 } 01432 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr16_data->Minimum; 01433 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr16_data->Maximum + addr16_data->AddressLength - 1; 01434 RequirementDescriptor->u.Memory.Length = addr16_data->AddressLength; 01435 } 01436 RequirementDescriptor++; 01437 break; 01438 } 01439 case ACPI_RESOURCE_TYPE_ADDRESS32: 01440 { 01441 ACPI_RESOURCE_ADDRESS32 *addr32_data = (ACPI_RESOURCE_ADDRESS32*) &resource->Data; 01442 if (addr32_data->ProducerConsumer == ACPI_PRODUCER) 01443 break; 01444 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 01445 if (addr32_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 01446 { 01447 RequirementDescriptor->Type = CmResourceTypeBusNumber; 01448 RequirementDescriptor->ShareDisposition = CmResourceShareShared; 01449 RequirementDescriptor->Flags = 0; 01450 RequirementDescriptor->u.BusNumber.MinBusNumber = addr32_data->Minimum; 01451 RequirementDescriptor->u.BusNumber.MaxBusNumber = addr32_data->Maximum + addr32_data->AddressLength - 1; 01452 RequirementDescriptor->u.BusNumber.Length = addr32_data->AddressLength; 01453 } 01454 else if (addr32_data->ResourceType == ACPI_IO_RANGE) 01455 { 01456 RequirementDescriptor->Type = CmResourceTypePort; 01457 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01458 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 01459 if (addr32_data->Decode == ACPI_POS_DECODE) 01460 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 01461 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr32_data->Minimum; 01462 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr32_data->Maximum + addr32_data->AddressLength - 1; 01463 RequirementDescriptor->u.Port.Length = addr32_data->AddressLength; 01464 } 01465 else 01466 { 01467 RequirementDescriptor->Type = CmResourceTypeMemory; 01468 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01469 RequirementDescriptor->Flags = 0; 01470 if (addr32_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 01471 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01472 else 01473 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01474 switch (addr32_data->Info.Mem.Caching) 01475 { 01476 case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 01477 case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 01478 case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 01479 } 01480 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr32_data->Minimum; 01481 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr32_data->Maximum + addr32_data->AddressLength - 1; 01482 RequirementDescriptor->u.Memory.Length = addr32_data->AddressLength; 01483 } 01484 RequirementDescriptor++; 01485 break; 01486 } 01487 case ACPI_RESOURCE_TYPE_ADDRESS64: 01488 { 01489 ACPI_RESOURCE_ADDRESS64 *addr64_data = (ACPI_RESOURCE_ADDRESS64*) &resource->Data; 01490 if (addr64_data->ProducerConsumer == ACPI_PRODUCER) 01491 break; 01492 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 01493 if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 01494 { 01495 DPRINT1("64-bit bus address is not supported!\n"); 01496 RequirementDescriptor->Type = CmResourceTypeBusNumber; 01497 RequirementDescriptor->ShareDisposition = CmResourceShareShared; 01498 RequirementDescriptor->Flags = 0; 01499 RequirementDescriptor->u.BusNumber.MinBusNumber = (ULONG)addr64_data->Minimum; 01500 RequirementDescriptor->u.BusNumber.MaxBusNumber = (ULONG)addr64_data->Maximum + addr64_data->AddressLength - 1; 01501 RequirementDescriptor->u.BusNumber.Length = addr64_data->AddressLength; 01502 } 01503 else if (addr64_data->ResourceType == ACPI_IO_RANGE) 01504 { 01505 RequirementDescriptor->Type = CmResourceTypePort; 01506 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01507 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 01508 if (addr64_data->Decode == ACPI_POS_DECODE) 01509 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 01510 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr64_data->Minimum; 01511 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr64_data->Maximum + addr64_data->AddressLength - 1; 01512 RequirementDescriptor->u.Port.Length = addr64_data->AddressLength; 01513 } 01514 else 01515 { 01516 RequirementDescriptor->Type = CmResourceTypeMemory; 01517 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01518 RequirementDescriptor->Flags = 0; 01519 if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 01520 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01521 else 01522 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01523 switch (addr64_data->Info.Mem.Caching) 01524 { 01525 case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 01526 case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 01527 case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 01528 } 01529 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr64_data->Minimum; 01530 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr64_data->Maximum + addr64_data->AddressLength - 1; 01531 RequirementDescriptor->u.Memory.Length = addr64_data->AddressLength; 01532 } 01533 RequirementDescriptor++; 01534 break; 01535 } 01536 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 01537 { 01538 ACPI_RESOURCE_EXTENDED_ADDRESS64 *addr64_data = (ACPI_RESOURCE_EXTENDED_ADDRESS64*) &resource->Data; 01539 if (addr64_data->ProducerConsumer == ACPI_PRODUCER) 01540 break; 01541 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 01542 if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE) 01543 { 01544 DPRINT1("64-bit bus address is not supported!\n"); 01545 RequirementDescriptor->Type = CmResourceTypeBusNumber; 01546 RequirementDescriptor->ShareDisposition = CmResourceShareShared; 01547 RequirementDescriptor->Flags = 0; 01548 RequirementDescriptor->u.BusNumber.MinBusNumber = (ULONG)addr64_data->Minimum; 01549 RequirementDescriptor->u.BusNumber.MaxBusNumber = (ULONG)addr64_data->Maximum + addr64_data->AddressLength - 1; 01550 RequirementDescriptor->u.BusNumber.Length = addr64_data->AddressLength; 01551 } 01552 else if (addr64_data->ResourceType == ACPI_IO_RANGE) 01553 { 01554 RequirementDescriptor->Type = CmResourceTypePort; 01555 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01556 RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO; 01557 if (addr64_data->Decode == ACPI_POS_DECODE) 01558 RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE; 01559 RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr64_data->Minimum; 01560 RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr64_data->Maximum + addr64_data->AddressLength - 1; 01561 RequirementDescriptor->u.Port.Length = addr64_data->AddressLength; 01562 } 01563 else 01564 { 01565 RequirementDescriptor->Type = CmResourceTypeMemory; 01566 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01567 RequirementDescriptor->Flags = 0; 01568 if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY) 01569 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01570 else 01571 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01572 switch (addr64_data->Info.Mem.Caching) 01573 { 01574 case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break; 01575 case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break; 01576 case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break; 01577 } 01578 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr64_data->Minimum; 01579 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr64_data->Maximum + addr64_data->AddressLength - 1; 01580 RequirementDescriptor->u.Memory.Length = addr64_data->AddressLength; 01581 } 01582 RequirementDescriptor++; 01583 break; 01584 } 01585 case ACPI_RESOURCE_TYPE_MEMORY24: 01586 { 01587 ACPI_RESOURCE_MEMORY24 *mem24_data = (ACPI_RESOURCE_MEMORY24*) &resource->Data; 01588 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 01589 RequirementDescriptor->Type = CmResourceTypeMemory; 01590 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01591 RequirementDescriptor->Flags = CM_RESOURCE_MEMORY_24; 01592 if (mem24_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 01593 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01594 else 01595 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01596 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = mem24_data->Minimum; 01597 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = mem24_data->Maximum + mem24_data->AddressLength - 1; 01598 RequirementDescriptor->u.Memory.Length = mem24_data->AddressLength; 01599 01600 RequirementDescriptor++; 01601 break; 01602 } 01603 case ACPI_RESOURCE_TYPE_MEMORY32: 01604 { 01605 ACPI_RESOURCE_MEMORY32 *mem32_data = (ACPI_RESOURCE_MEMORY32*) &resource->Data; 01606 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 01607 RequirementDescriptor->Type = CmResourceTypeMemory; 01608 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01609 RequirementDescriptor->Flags = 0; 01610 if (mem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 01611 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01612 else 01613 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01614 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = mem32_data->Minimum; 01615 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = mem32_data->Maximum + mem32_data->AddressLength - 1; 01616 RequirementDescriptor->u.Memory.Length = mem32_data->AddressLength; 01617 01618 RequirementDescriptor++; 01619 break; 01620 } 01621 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 01622 { 01623 ACPI_RESOURCE_FIXED_MEMORY32 *fixedmem32_data = (ACPI_RESOURCE_FIXED_MEMORY32*) &resource->Data; 01624 RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED; 01625 RequirementDescriptor->Type = CmResourceTypeMemory; 01626 RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; 01627 RequirementDescriptor->Flags = 0; 01628 if (fixedmem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY) 01629 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; 01630 else 01631 RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; 01632 RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = fixedmem32_data->Address; 01633 RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = fixedmem32_data->Address + fixedmem32_data->AddressLength - 1; 01634 RequirementDescriptor->u.Memory.Length = fixedmem32_data->AddressLength; 01635 01636 RequirementDescriptor++; 01637 break; 01638 } 01639 default: 01640 { 01641 break; 01642 } 01643 } 01644 resource = ACPI_NEXT_RESOURCE(resource); 01645 } 01646 ExFreePoolWithTag(Buffer.Pointer, 'IPCA'); 01647 01648 Irp->IoStatus.Information = (ULONG_PTR)RequirementsList; 01649 01650 return STATUS_SUCCESS; 01651 } 01652 01653 NTSTATUS 01654 Bus_PDO_QueryDeviceRelations( 01655 PPDO_DEVICE_DATA DeviceData, 01656 PIRP Irp ) 01657 /*++ 01658 01659 Routine Description: 01660 01661 The PnP Manager sends this IRP to gather information about 01662 devices with a relationship to the specified device. 01663 Bus drivers must handle this request for TargetDeviceRelation 01664 for their child devices (child PDOs). 01665 01666 If a driver returns relations in response to this IRP, 01667 it allocates a DEVICE_RELATIONS structure from paged 01668 memory containing a count and the appropriate number of 01669 device object pointers. The PnP Manager frees the structure 01670 when it is no longer needed. If a driver replaces a 01671 DEVICE_RELATIONS structure allocated by another driver, 01672 it must free the previous structure. 01673 01674 A driver must reference the PDO of any device that it 01675 reports in this IRP (ObReferenceObject). The PnP Manager 01676 removes the reference when appropriate. 01677 01678 Arguments: 01679 01680 DeviceData - Pointer to the PDO's device extension. 01681 Irp - Pointer to the irp. 01682 01683 Return Value: 01684 01685 NT STATUS 01686 01687 --*/ 01688 { 01689 01690 PIO_STACK_LOCATION stack; 01691 PDEVICE_RELATIONS deviceRelations; 01692 NTSTATUS status; 01693 01694 PAGED_CODE (); 01695 01696 stack = IoGetCurrentIrpStackLocation (Irp); 01697 01698 switch (stack->Parameters.QueryDeviceRelations.Type) { 01699 01700 case TargetDeviceRelation: 01701 01702 deviceRelations = (PDEVICE_RELATIONS) Irp->IoStatus.Information; 01703 if (deviceRelations) { 01704 // 01705 // Only PDO can handle this request. Somebody above 01706 // is not playing by rule. 01707 // 01708 ASSERTMSG("Someone above is handling TargetDeviceRelation", !deviceRelations); 01709 } 01710 01711 deviceRelations = (PDEVICE_RELATIONS) 01712 ExAllocatePoolWithTag (PagedPool, 01713 sizeof(DEVICE_RELATIONS), 01714 'IPCA'); 01715 if (!deviceRelations) { 01716 status = STATUS_INSUFFICIENT_RESOURCES; 01717 break; 01718 } 01719 01720 // 01721 // There is only one PDO pointer in the structure 01722 // for this relation type. The PnP Manager removes 01723 // the reference to the PDO when the driver or application 01724 // un-registers for notification on the device. 01725 // 01726 01727 deviceRelations->Count = 1; 01728 deviceRelations->Objects[0] = DeviceData->Common.Self; 01729 ObReferenceObject(DeviceData->Common.Self); 01730 01731 status = STATUS_SUCCESS; 01732 Irp->IoStatus.Information = (ULONG_PTR) deviceRelations; 01733 break; 01734 01735 case BusRelations: // Not handled by PDO 01736 case EjectionRelations: // optional for PDO 01737 case RemovalRelations: // // optional for PDO 01738 default: 01739 status = Irp->IoStatus.Status; 01740 } 01741 01742 return status; 01743 } 01744 01745 NTSTATUS 01746 Bus_PDO_QueryBusInformation( 01747 PPDO_DEVICE_DATA DeviceData, 01748 PIRP Irp ) 01749 /*++ 01750 01751 Routine Description: 01752 01753 The PnP Manager uses this IRP to request the type and 01754 instance number of a device's parent bus. Bus drivers 01755 should handle this request for their child devices (PDOs). 01756 01757 Arguments: 01758 01759 DeviceData - Pointer to the PDO's device extension. 01760 Irp - Pointer to the irp. 01761 01762 Return Value: 01763 01764 NT STATUS 01765 01766 --*/ 01767 { 01768 01769 PPNP_BUS_INFORMATION busInfo; 01770 01771 PAGED_CODE (); 01772 01773 busInfo = ExAllocatePoolWithTag (PagedPool, sizeof(PNP_BUS_INFORMATION), 01774 'IPCA'); 01775 01776 if (busInfo == NULL) { 01777 return STATUS_INSUFFICIENT_RESOURCES; 01778 } 01779 01780 busInfo->BusTypeGuid = GUID_ACPI_INTERFACE_STANDARD; 01781 01782 busInfo->LegacyBusType = InternalPowerBus; 01783 01784 busInfo->BusNumber = 0; //fixme 01785 01786 Irp->IoStatus.Information = (ULONG_PTR)busInfo; 01787 01788 return STATUS_SUCCESS; 01789 } 01790 01791 01792 NTSTATUS 01793 Bus_GetDeviceCapabilities( 01794 PDEVICE_OBJECT DeviceObject, 01795 PDEVICE_CAPABILITIES DeviceCapabilities 01796 ) 01797 { 01798 IO_STATUS_BLOCK ioStatus; 01799 KEVENT pnpEvent; 01800 NTSTATUS status; 01801 PDEVICE_OBJECT targetObject; 01802 PIO_STACK_LOCATION irpStack; 01803 PIRP pnpIrp; 01804 01805 PAGED_CODE(); 01806 01807 // 01808 // Initialize the capabilities that we will send down 01809 // 01810 RtlZeroMemory( DeviceCapabilities, sizeof(DEVICE_CAPABILITIES) ); 01811 DeviceCapabilities->Size = sizeof(DEVICE_CAPABILITIES); 01812 DeviceCapabilities->Version = 1; 01813 DeviceCapabilities->Address = -1; 01814 DeviceCapabilities->UINumber = -1; 01815 01816 // 01817 // Initialize the event 01818 // 01819 KeInitializeEvent( &pnpEvent, NotificationEvent, FALSE ); 01820 01821 targetObject = IoGetAttachedDeviceReference( DeviceObject ); 01822 01823 // 01824 // Build an Irp 01825 // 01826 pnpIrp = IoBuildSynchronousFsdRequest( 01827 IRP_MJ_PNP, 01828 targetObject, 01829 NULL, 01830 0, 01831 NULL, 01832 &pnpEvent, 01833 &ioStatus 01834 ); 01835 if (pnpIrp == NULL) { 01836 01837 status = STATUS_INSUFFICIENT_RESOURCES; 01838 goto GetDeviceCapabilitiesExit; 01839 01840 } 01841 01842 // 01843 // Pnp Irps all begin life as STATUS_NOT_SUPPORTED; 01844 // 01845 pnpIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; 01846 01847 // 01848 // Get the top of stack 01849 // 01850 irpStack = IoGetNextIrpStackLocation( pnpIrp ); 01851 01852 // 01853 // Set the top of stack 01854 // 01855 RtlZeroMemory( irpStack, sizeof(IO_STACK_LOCATION ) ); 01856 irpStack->MajorFunction = IRP_MJ_PNP; 01857 irpStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES; 01858 irpStack->Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities; 01859 01860 // 01861 // Call the driver 01862 // 01863 status = IoCallDriver( targetObject, pnpIrp ); 01864 if (status == STATUS_PENDING) { 01865 01866 // 01867 // Block until the irp comes back. 01868 // Important thing to note here is when you allocate 01869 // the memory for an event in the stack you must do a 01870 // KernelMode wait instead of UserMode to prevent 01871 // the stack from getting paged out. 01872 // 01873 01874 KeWaitForSingleObject( 01875 &pnpEvent, 01876 Executive, 01877 KernelMode, 01878 FALSE, 01879 NULL 01880 ); 01881 status = ioStatus.Status; 01882 01883 } 01884 01885 GetDeviceCapabilitiesExit: 01886 // 01887 // Done with reference 01888 // 01889 ObDereferenceObject( targetObject ); 01890 01891 // 01892 // Done 01893 // 01894 return status; 01895 01896 } 01897 01898 Generated on Sun May 27 2012 04:27:25 for ReactOS by
1.7.6.1
|