ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

buspdo.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.