11 #pragma alloc_text (PAGE, Bus_PDO_PnP)
12 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceCaps)
13 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceId)
14 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceText)
15 #pragma alloc_text (PAGE, Bus_PDO_QueryResources)
16 #pragma alloc_text (PAGE, Bus_PDO_QueryResourceRequirements)
17 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceRelations)
18 #pragma alloc_text (PAGE, Bus_PDO_QueryBusInformation)
19 #pragma alloc_text (PAGE, Bus_GetDeviceCapabilities)
24 PDEVICE_OBJECT DeviceObject
,
26 PIO_STACK_LOCATION IrpStack
,
27 PPDO_DEVICE_DATA DeviceData
32 struct acpi_device
*device
= NULL
;
36 if (DeviceData
->AcpiHandle
)
37 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
40 // NB: Because we are a bus enumerator, we have no one to whom we could
41 // defer these irps. Therefore we do not pass them down but merely
45 switch (IrpStack
->MinorFunction
) {
47 case IRP_MN_START_DEVICE
:
49 // Here we do what ever initialization and ``turning on'' that is
50 // required to allow others to access this device.
51 // Power up the device.
53 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
54 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D0
)))
56 DPRINT1("Device %x failed to start!\n", DeviceData
->AcpiHandle
);
57 status
= STATUS_UNSUCCESSFUL
;
61 DeviceData
->InterfaceName
.Length
= 0;
62 status
= STATUS_SUCCESS
;
66 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
67 &GUID_DEVICE_SYS_BUTTON
,
69 &DeviceData
->InterfaceName
);
71 else if (device
->flags
.hardware_id
&&
72 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
))
74 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
75 &GUID_DEVICE_THERMAL_ZONE
,
77 &DeviceData
->InterfaceName
);
79 else if (device
->flags
.hardware_id
&&
80 strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
))
82 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
85 &DeviceData
->InterfaceName
);
87 else if (device
->flags
.hardware_id
&&
88 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))
90 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
91 &GUID_DEVICE_PROCESSOR
,
93 &DeviceData
->InterfaceName
);
96 /* Failure to register an interface is not a fatal failure so don't return a failure status */
97 if (NT_SUCCESS(status
) && DeviceData
->InterfaceName
.Length
!= 0)
98 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, TRUE
);
100 state
.DeviceState
= PowerDeviceD0
;
101 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
102 DeviceData
->Common
.DevicePowerState
= PowerDeviceD0
;
103 SET_NEW_PNP_STATE(DeviceData
->Common
, Started
);
104 status
= STATUS_SUCCESS
;
107 case IRP_MN_STOP_DEVICE
:
109 if (DeviceData
->InterfaceName
.Length
!= 0)
110 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, FALSE
);
113 // Here we shut down the device and give up and unmap any resources
114 // we acquired for the device.
116 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
117 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D3
)))
119 DPRINT1("Device %x failed to stop!\n", DeviceData
->AcpiHandle
);
120 status
= STATUS_UNSUCCESSFUL
;
124 state
.DeviceState
= PowerDeviceD3
;
125 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
126 DeviceData
->Common
.DevicePowerState
= PowerDeviceD3
;
127 SET_NEW_PNP_STATE(DeviceData
->Common
, Stopped
);
128 status
= STATUS_SUCCESS
;
132 case IRP_MN_QUERY_STOP_DEVICE
:
135 // No reason here why we can't stop the device.
136 // If there were a reason we should speak now, because answering success
137 // here may result in a stop device irp.
140 SET_NEW_PNP_STATE(DeviceData
->Common
, StopPending
);
141 status
= STATUS_SUCCESS
;
144 case IRP_MN_CANCEL_STOP_DEVICE
:
147 // The stop was canceled. Whatever state we set, or resources we put
148 // on hold in anticipation of the forthcoming STOP device IRP should be
149 // put back to normal. Someone, in the long list of concerned parties,
150 // has failed the stop device query.
154 // First check to see whether you have received cancel-stop
155 // without first receiving a query-stop. This could happen if someone
156 // above us fails a query-stop and passes down the subsequent
160 if (StopPending
== DeviceData
->Common
.DevicePnPState
)
163 // We did receive a query-stop, so restore.
165 RESTORE_PREVIOUS_PNP_STATE(DeviceData
->Common
);
167 status
= STATUS_SUCCESS
;// We must not fail this IRP.
170 case IRP_MN_REMOVE_DEVICE
:
172 // We handle REMOVE_DEVICE just like STOP_DEVICE. This is because
173 // the device is still physically present (or at least we don't know any better)
174 // so we have to retain the PDO after stopping and removing power from it.
176 if (DeviceData
->InterfaceName
.Length
!= 0)
177 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, FALSE
);
179 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
180 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D3
)))
182 DPRINT1("Device %x failed to enter D3!\n", DeviceData
->AcpiHandle
);
183 state
.DeviceState
= PowerDeviceD3
;
184 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
185 DeviceData
->Common
.DevicePowerState
= PowerDeviceD3
;
188 SET_NEW_PNP_STATE(DeviceData
->Common
, Stopped
);
189 status
= STATUS_SUCCESS
;
192 case IRP_MN_QUERY_REMOVE_DEVICE
:
193 SET_NEW_PNP_STATE(DeviceData
->Common
, RemovalPending
);
194 status
= STATUS_SUCCESS
;
197 case IRP_MN_CANCEL_REMOVE_DEVICE
:
198 if (RemovalPending
== DeviceData
->Common
.DevicePnPState
)
200 RESTORE_PREVIOUS_PNP_STATE(DeviceData
->Common
);
202 status
= STATUS_SUCCESS
;
205 case IRP_MN_QUERY_CAPABILITIES
:
208 // Return the capabilities of a device, such as whether the device
209 // can be locked or ejected..etc
212 status
= Bus_PDO_QueryDeviceCaps(DeviceData
, Irp
);
216 case IRP_MN_QUERY_ID
:
218 // Query the IDs of the device
219 status
= Bus_PDO_QueryDeviceId(DeviceData
, Irp
);
223 case IRP_MN_QUERY_DEVICE_RELATIONS
:
225 DPRINT("\tQueryDeviceRelation Type: %s\n",DbgDeviceRelationString(\
226 IrpStack
->Parameters
.QueryDeviceRelations
.Type
));
228 status
= Bus_PDO_QueryDeviceRelations(DeviceData
, Irp
);
232 case IRP_MN_QUERY_DEVICE_TEXT
:
234 status
= Bus_PDO_QueryDeviceText(DeviceData
, Irp
);
238 case IRP_MN_QUERY_RESOURCES
:
240 status
= Bus_PDO_QueryResources(DeviceData
, Irp
);
244 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
246 status
= Bus_PDO_QueryResourceRequirements(DeviceData
, Irp
);
250 case IRP_MN_QUERY_BUS_INFORMATION
:
252 status
= Bus_PDO_QueryBusInformation(DeviceData
, Irp
);
256 case IRP_MN_QUERY_INTERFACE
:
258 status
= Bus_PDO_QueryInterface(DeviceData
, Irp
);
263 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
266 // OPTIONAL for bus drivers.
267 // The PnP Manager sends this IRP to a device
268 // stack so filter and function drivers can adjust the
269 // resources required by the device, if appropriate.
274 //case IRP_MN_QUERY_PNP_DEVICE_STATE:
277 // OPTIONAL for bus drivers.
278 // The PnP Manager sends this IRP after the drivers for
279 // a device return success from the IRP_MN_START_DEVICE
280 // request. The PnP Manager also sends this IRP when a
281 // driver for the device calls IoInvalidateDeviceState.
286 //case IRP_MN_READ_CONFIG:
287 //case IRP_MN_WRITE_CONFIG:
290 // Bus drivers for buses with configuration space must handle
291 // this request for their child devices. Our devices don't
292 // have a config space.
297 //case IRP_MN_SET_LOCK:
304 // For PnP requests to the PDO that we do not understand we should
305 // return the IRP WITHOUT setting the status or information fields.
306 // These fields may have already been set by a filter (eg acpi).
307 status
= Irp
->IoStatus
.Status
;
312 Irp
->IoStatus
.Status
= status
;
313 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
319 Bus_PDO_QueryDeviceCaps(
320 PPDO_DEVICE_DATA DeviceData
,
324 PIO_STACK_LOCATION stack
;
325 PDEVICE_CAPABILITIES deviceCapabilities
;
326 struct acpi_device
*device
= NULL
;
331 if (DeviceData
->AcpiHandle
)
332 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
334 stack
= IoGetCurrentIrpStackLocation (Irp
);
339 deviceCapabilities
=stack
->Parameters
.DeviceCapabilities
.Capabilities
;
342 // Set the capabilities.
345 if (deviceCapabilities
->Version
!= 1 ||
346 deviceCapabilities
->Size
< sizeof(DEVICE_CAPABILITIES
))
348 return STATUS_UNSUCCESSFUL
;
351 deviceCapabilities
->D1Latency
= 0;
352 deviceCapabilities
->D2Latency
= 0;
353 deviceCapabilities
->D3Latency
= 0;
355 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
356 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD3
;
357 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD3
;
358 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
360 for (i
= 0; i
< ACPI_D_STATE_COUNT
&& device
; i
++)
362 if (!device
->power
.states
[i
].flags
.valid
)
368 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
372 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD1
;
373 deviceCapabilities
->D1Latency
= device
->power
.states
[i
].latency
;
377 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD2
;
378 deviceCapabilities
->D2Latency
= device
->power
.states
[i
].latency
;
382 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
383 deviceCapabilities
->D3Latency
= device
->power
.states
[i
].latency
;
388 // We can wake the system from D1
389 deviceCapabilities
->DeviceWake
= PowerDeviceD1
;
392 deviceCapabilities
->DeviceD1
=
393 (deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] == PowerDeviceD1
) ? TRUE
: FALSE
;
394 deviceCapabilities
->DeviceD2
=
395 (deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] == PowerDeviceD2
) ? TRUE
: FALSE
;
397 deviceCapabilities
->WakeFromD0
= FALSE
;
398 deviceCapabilities
->WakeFromD1
= TRUE
; //Yes we can
399 deviceCapabilities
->WakeFromD2
= FALSE
;
400 deviceCapabilities
->WakeFromD3
= FALSE
;
404 deviceCapabilities
->LockSupported
= device
->flags
.lockable
;
405 deviceCapabilities
->EjectSupported
= device
->flags
.ejectable
;
406 deviceCapabilities
->HardwareDisabled
= !device
->status
.enabled
&& !device
->status
.functional
;
407 deviceCapabilities
->Removable
= device
->flags
.removable
;
408 deviceCapabilities
->SurpriseRemovalOK
= device
->flags
.surprise_removal_ok
;
409 deviceCapabilities
->UniqueID
= device
->flags
.unique_id
;
410 deviceCapabilities
->NoDisplayInUI
= !device
->status
.show_in_ui
;
411 deviceCapabilities
->Address
= device
->pnp
.bus_address
;
415 (device
->flags
.hardware_id
&&
416 (strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
) ||
417 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
) ||
418 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))))
420 /* Allow ACPI to control the device if it is a lid button,
421 * a thermal zone, a processor, or a fixed feature button */
422 deviceCapabilities
->RawDeviceOK
= TRUE
;
425 deviceCapabilities
->SilentInstall
= FALSE
;
426 deviceCapabilities
->UINumber
= (ULONG
)-1;
428 return STATUS_SUCCESS
;
433 Bus_PDO_QueryDeviceId(
434 PPDO_DEVICE_DATA DeviceData
,
437 PIO_STACK_LOCATION stack
;
441 NTSTATUS status
= STATUS_SUCCESS
;
442 struct acpi_device
*Device
;
446 stack
= IoGetCurrentIrpStackLocation (Irp
);
448 switch (stack
->Parameters
.QueryId
.IdType
) {
450 case BusQueryDeviceID
:
452 /* This is a REG_SZ value */
454 if (DeviceData
->AcpiHandle
)
456 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
458 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
460 length
= wcslen(ProcessorIdString
);
461 wcscpy(temp
, ProcessorIdString
);
465 length
= swprintf(temp
,
467 Device
->pnp
.hardware_id
);
472 /* We know it's a fixed feature button because
473 * these are direct children of the ACPI root device
474 * and therefore have no handle
476 length
= swprintf(temp
,
477 L
"ACPI\\FixedButton");
480 temp
[length
++] = UNICODE_NULL
;
482 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
484 buffer
= ExAllocatePoolWithTag(PagedPool
, length
* sizeof(WCHAR
), 'IpcA');
487 status
= STATUS_INSUFFICIENT_RESOURCES
;
491 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
492 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
493 DPRINT("BusQueryDeviceID: %ls\n",buffer
);
496 case BusQueryInstanceID
:
498 /* This is a REG_SZ value */
500 /* See comment in BusQueryDeviceID case */
501 if(DeviceData
->AcpiHandle
)
503 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
505 if (Device
->flags
.unique_id
)
506 length
= swprintf(temp
,
508 Device
->pnp
.unique_id
);
510 /* FIXME: Generate unique id! */
511 length
= swprintf(temp
, L
"%ls", L
"0");
515 /* FIXME: Generate unique id! */
516 length
= swprintf(temp
, L
"%ls", L
"0");
519 temp
[length
++] = UNICODE_NULL
;
521 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
523 buffer
= ExAllocatePoolWithTag(PagedPool
, length
* sizeof(WCHAR
), 'IpcA');
525 status
= STATUS_INSUFFICIENT_RESOURCES
;
529 RtlCopyMemory (buffer
, temp
, length
* sizeof (WCHAR
));
530 DPRINT("BusQueryInstanceID: %ls\n",buffer
);
531 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
534 case BusQueryHardwareIDs
:
536 /* This is a REG_MULTI_SZ value */
538 status
= STATUS_NOT_SUPPORTED
;
540 /* See comment in BusQueryDeviceID case */
541 if (DeviceData
->AcpiHandle
)
543 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
545 if (!Device
->flags
.hardware_id
)
547 /* We don't have the ID to satisfy this request */
551 DPRINT("Device name: %s\n", Device
->pnp
.device_name
);
552 DPRINT("Hardware ID: %s\n", Device
->pnp
.hardware_id
);
554 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
556 length
= ProcessorHardwareIds
.Length
/ sizeof(WCHAR
);
557 src
= ProcessorHardwareIds
.Buffer
;
561 length
+= swprintf(&temp
[length
],
563 Device
->pnp
.hardware_id
);
564 temp
[length
++] = UNICODE_NULL
;
566 length
+= swprintf(&temp
[length
],
568 Device
->pnp
.hardware_id
);
569 temp
[length
++] = UNICODE_NULL
;
570 temp
[length
++] = UNICODE_NULL
;
576 length
+= swprintf(&temp
[length
],
577 L
"ACPI\\FixedButton");
578 temp
[length
++] = UNICODE_NULL
;
580 length
+= swprintf(&temp
[length
],
582 temp
[length
++] = UNICODE_NULL
;
583 temp
[length
++] = UNICODE_NULL
;
587 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
589 buffer
= ExAllocatePoolWithTag(PagedPool
, length
* sizeof(WCHAR
), 'IpcA');
592 status
= STATUS_INSUFFICIENT_RESOURCES
;
596 RtlCopyMemory (buffer
, src
, length
* sizeof(WCHAR
));
597 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
598 DPRINT("BusQueryHardwareIDs: %ls\n",buffer
);
599 status
= STATUS_SUCCESS
;
602 case BusQueryCompatibleIDs
:
604 /* This is a REG_MULTI_SZ value */
606 status
= STATUS_NOT_SUPPORTED
;
608 /* See comment in BusQueryDeviceID case */
609 if (DeviceData
->AcpiHandle
)
611 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
613 if (!Device
->flags
.hardware_id
)
615 /* We don't have the ID to satisfy this request */
619 DPRINT("Device name: %s\n", Device
->pnp
.device_name
);
620 DPRINT("Hardware ID: %s\n", Device
->pnp
.hardware_id
);
622 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
624 length
+= swprintf(&temp
[length
],
626 Device
->pnp
.hardware_id
);
627 temp
[length
++] = UNICODE_NULL
;
629 length
+= swprintf(&temp
[length
],
631 Device
->pnp
.hardware_id
);
632 temp
[length
++] = UNICODE_NULL
;
633 temp
[length
++] = UNICODE_NULL
;
635 else if (Device
->flags
.compatible_ids
)
637 for (i
= 0; i
< Device
->pnp
.cid_list
->Count
; i
++)
639 length
+= swprintf(&temp
[length
],
641 Device
->pnp
.cid_list
->Ids
[i
].String
);
642 temp
[length
++] = UNICODE_NULL
;
644 length
+= swprintf(&temp
[length
],
646 Device
->pnp
.cid_list
->Ids
[i
].String
);
647 temp
[length
++] = UNICODE_NULL
;
650 temp
[length
++] = UNICODE_NULL
;
654 /* No compatible IDs */
658 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
660 buffer
= ExAllocatePoolWithTag(PagedPool
, length
* sizeof(WCHAR
), 'IpcA');
663 status
= STATUS_INSUFFICIENT_RESOURCES
;
667 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
668 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
669 DPRINT("BusQueryCompatibleIDs: %ls\n",buffer
);
670 status
= STATUS_SUCCESS
;
675 status
= Irp
->IoStatus
.Status
;
681 Bus_PDO_QueryDeviceText(
682 PPDO_DEVICE_DATA DeviceData
,
686 PIO_STACK_LOCATION stack
;
687 NTSTATUS status
= Irp
->IoStatus
.Status
;
690 stack
= IoGetCurrentIrpStackLocation (Irp
);
692 switch (stack
->Parameters
.QueryDeviceText
.DeviceTextType
) {
694 case DeviceTextDescription
:
696 if (!Irp
->IoStatus
.Information
) {
697 if (wcsstr (DeviceData
->HardwareIDs
, L
"PNP000") != 0)
698 Temp
= L
"Programmable interrupt controller";
699 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP010") != 0)
700 Temp
= L
"System timer";
701 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP020") != 0)
702 Temp
= L
"DMA controller";
703 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP03") != 0)
705 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP040") != 0)
706 Temp
= L
"Parallel port";
707 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP05") != 0)
708 Temp
= L
"Serial port";
709 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP06") != 0)
710 Temp
= L
"Disk controller";
711 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP07") != 0)
712 Temp
= L
"Disk controller";
713 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP09") != 0)
714 Temp
= L
"Display adapter";
715 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A0") != 0)
716 Temp
= L
"Bus controller";
717 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0E0") != 0)
718 Temp
= L
"PCMCIA controller";
719 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0F") != 0)
720 Temp
= L
"Mouse device";
721 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP8") != 0)
722 Temp
= L
"Network adapter";
723 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPA0") != 0)
724 Temp
= L
"SCSI controller";
725 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPB0") != 0)
726 Temp
= L
"Multimedia device";
727 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPC00") != 0)
729 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0C") != 0)
730 Temp
= L
"Power Button";
731 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0E") != 0)
732 Temp
= L
"Sleep Button";
733 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0D") != 0)
734 Temp
= L
"Lid Switch";
735 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C09") != 0)
736 Temp
= L
"ACPI Embedded Controller";
737 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0B") != 0)
739 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
740 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
741 Temp
= L
"PCI Root Bridge";
742 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0A") != 0)
743 Temp
= L
"ACPI Battery";
744 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0F") != 0)
745 Temp
= L
"PCI Interrupt Link";
746 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI_PWR") != 0)
747 Temp
= L
"ACPI Power Resource";
748 else if (wcsstr(DeviceData
->HardwareIDs
, L
"Processor") != 0)
750 if (ProcessorNameString
!= NULL
)
751 Temp
= ProcessorNameString
;
755 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ThermalZone") != 0)
756 Temp
= L
"ACPI Thermal Zone";
757 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0002") != 0)
758 Temp
= L
"Smart Battery";
759 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0003") != 0)
760 Temp
= L
"AC Adapter";
761 /* Simply checking if AcpiHandle is NULL eliminates the need to check
762 * for the 4 different names that ACPI knows the fixed feature button as internally
764 else if (!DeviceData
->AcpiHandle
)
765 Temp
= L
"ACPI Fixed Feature Button";
767 Temp
= L
"Other ACPI device";
769 Buffer
= ExAllocatePoolWithTag(PagedPool
, (wcslen(Temp
) + 1) * sizeof(WCHAR
), 'IpcA');
772 status
= STATUS_INSUFFICIENT_RESOURCES
;
776 RtlCopyMemory (Buffer
, Temp
, (wcslen(Temp
) + 1) * sizeof(WCHAR
));
778 DPRINT("\tDeviceTextDescription :%ws\n", Buffer
);
780 Irp
->IoStatus
.Information
= (ULONG_PTR
) Buffer
;
781 status
= STATUS_SUCCESS
;
794 Bus_PDO_QueryResources(
795 PPDO_DEVICE_DATA DeviceData
,
798 ULONG NumberOfResources
= 0;
799 PCM_RESOURCE_LIST ResourceList
;
800 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor
;
801 ACPI_STATUS AcpiStatus
;
803 ACPI_RESOURCE
* resource
;
804 ULONG ResourceListSize
;
807 struct acpi_device
*device
;
809 if (!DeviceData
->AcpiHandle
)
811 return Irp
->IoStatus
.Status
;
814 /* A bus number resource is not included in the list of current resources
815 * for the root PCI bus so we manually query one here and if we find it
816 * we create a resource list and add a bus number descriptor to it */
817 if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
818 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
820 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
822 AcpiStatus
= acpi_evaluate_integer(DeviceData
->AcpiHandle
, "_BBN", NULL
, &BusNumber
);
823 if (AcpiStatus
!= AE_OK
)
826 if (device
->flags
.unique_id
)
828 /* FIXME: Try the unique ID */
834 DPRINT1("Failed to find a bus number\n");
839 DPRINT("Using _BBN for bus number\n");
842 DPRINT("Found PCI root hub: %d\n", BusNumber
);
844 ResourceListSize
= sizeof(CM_RESOURCE_LIST
);
845 ResourceList
= ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, 'RpcA');
847 return STATUS_INSUFFICIENT_RESOURCES
;
849 ResourceList
->Count
= 1;
850 ResourceList
->List
[0].InterfaceType
= Internal
;
851 ResourceList
->List
[0].BusNumber
= 0;
852 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
853 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
854 ResourceList
->List
[0].PartialResourceList
.Count
= 1;
855 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
857 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
858 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
859 ResourceDescriptor
->u
.BusNumber
.Start
= BusNumber
;
860 ResourceDescriptor
->u
.BusNumber
.Length
= 1;
862 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
863 return STATUS_SUCCESS
;
866 /* Get current resources */
868 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
869 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
872 return Irp
->IoStatus
.Status
;
875 Buffer
.Pointer
= ExAllocatePoolWithTag(PagedPool
, Buffer
.Length
, 'BpcA');
877 return STATUS_INSUFFICIENT_RESOURCES
;
879 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
880 if (!ACPI_SUCCESS(AcpiStatus
))
882 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
884 return STATUS_UNSUCCESSFUL
;
887 resource
= Buffer
.Pointer
;
888 /* Count number of resources */
889 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
891 switch (resource
->Type
)
893 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
895 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
896 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
898 NumberOfResources
+= irq_data
->InterruptCount
;
901 case ACPI_RESOURCE_TYPE_IRQ
:
903 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
904 NumberOfResources
+= irq_data
->InterruptCount
;
907 case ACPI_RESOURCE_TYPE_DMA
:
909 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
910 NumberOfResources
+= dma_data
->ChannelCount
;
913 case ACPI_RESOURCE_TYPE_ADDRESS16
:
914 case ACPI_RESOURCE_TYPE_ADDRESS32
:
915 case ACPI_RESOURCE_TYPE_ADDRESS64
:
916 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
918 ACPI_RESOURCE_ADDRESS
*addr_res
= (ACPI_RESOURCE_ADDRESS
*) &resource
->Data
;
919 if (addr_res
->ProducerConsumer
== ACPI_PRODUCER
)
924 case ACPI_RESOURCE_TYPE_MEMORY24
:
925 case ACPI_RESOURCE_TYPE_MEMORY32
:
926 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
927 case ACPI_RESOURCE_TYPE_FIXED_IO
:
928 case ACPI_RESOURCE_TYPE_IO
:
935 DPRINT1("Unknown resource type: %d\n", resource
->Type
);
939 resource
= ACPI_NEXT_RESOURCE(resource
);
942 /* Allocate memory */
943 ResourceListSize
= sizeof(CM_RESOURCE_LIST
) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
944 ResourceList
= ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, 'RpcA');
948 ExFreePoolWithTag(Buffer
.Pointer
, 'BpcA');
949 return STATUS_INSUFFICIENT_RESOURCES
;
951 ResourceList
->Count
= 1;
952 ResourceList
->List
[0].InterfaceType
= Internal
; /* FIXME */
953 ResourceList
->List
[0].BusNumber
= 0; /* We're the only ACPI bus device in the system */
954 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
955 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
956 ResourceList
->List
[0].PartialResourceList
.Count
= NumberOfResources
;
957 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
959 /* Fill resources list structure */
960 resource
= Buffer
.Pointer
;
961 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
963 switch (resource
->Type
)
965 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
967 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
968 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
970 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
972 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
974 ResourceDescriptor
->ShareDisposition
=
975 (irq_data
->Shareable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
976 ResourceDescriptor
->Flags
=
977 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
978 ResourceDescriptor
->u
.Interrupt
.Level
=
979 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
980 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
982 ResourceDescriptor
++;
986 case ACPI_RESOURCE_TYPE_IRQ
:
988 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
989 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
991 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
993 ResourceDescriptor
->ShareDisposition
=
994 (irq_data
->Shareable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
995 ResourceDescriptor
->Flags
=
996 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
997 ResourceDescriptor
->u
.Interrupt
.Level
=
998 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
999 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
1001 ResourceDescriptor
++;
1005 case ACPI_RESOURCE_TYPE_DMA
:
1007 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1008 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
1010 ResourceDescriptor
->Type
= CmResourceTypeDma
;
1011 ResourceDescriptor
->Flags
= 0;
1012 switch (dma_data
->Type
)
1014 case ACPI_TYPE_A
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
1015 case ACPI_TYPE_B
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
1016 case ACPI_TYPE_F
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
1018 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
1019 ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
1020 switch (dma_data
->Transfer
)
1022 case ACPI_TRANSFER_8
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
1023 case ACPI_TRANSFER_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
1024 case ACPI_TRANSFER_8_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
1026 ResourceDescriptor
->u
.Dma
.Channel
= dma_data
->Channels
[i
];
1028 ResourceDescriptor
++;
1032 case ACPI_RESOURCE_TYPE_IO
:
1034 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
1035 ResourceDescriptor
->Type
= CmResourceTypePort
;
1036 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1037 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1038 if (io_data
->IoDecode
== ACPI_DECODE_16
)
1039 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
1041 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
1042 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Minimum
;
1043 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1045 ResourceDescriptor
++;
1048 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1050 ACPI_RESOURCE_FIXED_IO
*io_data
= (ACPI_RESOURCE_FIXED_IO
*) &resource
->Data
;
1051 ResourceDescriptor
->Type
= CmResourceTypePort
;
1052 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1053 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1054 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Address
;
1055 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1057 ResourceDescriptor
++;
1060 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1062 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
1063 if (addr16_data
->ProducerConsumer
== ACPI_PRODUCER
)
1065 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1067 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1068 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1069 ResourceDescriptor
->Flags
= 0;
1070 ResourceDescriptor
->u
.BusNumber
.Start
= addr16_data
->Address
.Minimum
;
1071 ResourceDescriptor
->u
.BusNumber
.Length
= addr16_data
->Address
.AddressLength
;
1073 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1075 ResourceDescriptor
->Type
= CmResourceTypePort
;
1076 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1077 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1078 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1079 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1080 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr16_data
->Address
.Minimum
;
1081 ResourceDescriptor
->u
.Port
.Length
= addr16_data
->Address
.AddressLength
;
1085 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1086 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1087 ResourceDescriptor
->Flags
= 0;
1088 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1089 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1091 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1092 switch (addr16_data
->Info
.Mem
.Caching
)
1094 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1095 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1096 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1098 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr16_data
->Address
.Minimum
;
1099 ResourceDescriptor
->u
.Memory
.Length
= addr16_data
->Address
.AddressLength
;
1101 ResourceDescriptor
++;
1104 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1106 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
1107 if (addr32_data
->ProducerConsumer
== ACPI_PRODUCER
)
1109 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1111 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1112 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1113 ResourceDescriptor
->Flags
= 0;
1114 ResourceDescriptor
->u
.BusNumber
.Start
= addr32_data
->Address
.Minimum
;
1115 ResourceDescriptor
->u
.BusNumber
.Length
= addr32_data
->Address
.AddressLength
;
1117 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1119 ResourceDescriptor
->Type
= CmResourceTypePort
;
1120 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1121 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1122 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1123 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1124 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr32_data
->Address
.Minimum
;
1125 ResourceDescriptor
->u
.Port
.Length
= addr32_data
->Address
.AddressLength
;
1129 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1130 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1131 ResourceDescriptor
->Flags
= 0;
1132 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1133 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1135 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1136 switch (addr32_data
->Info
.Mem
.Caching
)
1138 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1139 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1140 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1142 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr32_data
->Address
.Minimum
;
1143 ResourceDescriptor
->u
.Memory
.Length
= addr32_data
->Address
.AddressLength
;
1145 ResourceDescriptor
++;
1148 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1150 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
1151 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1153 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1155 DPRINT1("64-bit bus address is not supported!\n");
1156 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1157 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1158 ResourceDescriptor
->Flags
= 0;
1159 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Address
.Minimum
;
1160 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->Address
.AddressLength
;
1162 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1164 ResourceDescriptor
->Type
= CmResourceTypePort
;
1165 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1166 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1167 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1168 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1169 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Address
.Minimum
;
1170 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->Address
.AddressLength
;
1174 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1175 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1176 ResourceDescriptor
->Flags
= 0;
1177 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1178 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1180 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1181 switch (addr64_data
->Info
.Mem
.Caching
)
1183 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1184 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1185 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1187 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Address
.Minimum
;
1188 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->Address
.AddressLength
;
1190 ResourceDescriptor
++;
1193 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1195 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
1196 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1198 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1200 DPRINT1("64-bit bus address is not supported!\n");
1201 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1202 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1203 ResourceDescriptor
->Flags
= 0;
1204 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Address
.Minimum
;
1205 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->Address
.AddressLength
;
1207 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1209 ResourceDescriptor
->Type
= CmResourceTypePort
;
1210 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1211 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1212 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1213 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1214 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Address
.Minimum
;
1215 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->Address
.AddressLength
;
1219 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1220 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1221 ResourceDescriptor
->Flags
= 0;
1222 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1223 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1225 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1226 switch (addr64_data
->Info
.Mem
.Caching
)
1228 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1229 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1230 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1232 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Address
.Minimum
;
1233 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->Address
.AddressLength
;
1235 ResourceDescriptor
++;
1238 case ACPI_RESOURCE_TYPE_MEMORY24
:
1240 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1241 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1242 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1243 ResourceDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1244 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1245 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1247 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1248 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem24_data
->Minimum
;
1249 ResourceDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1251 ResourceDescriptor
++;
1254 case ACPI_RESOURCE_TYPE_MEMORY32
:
1256 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1257 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1258 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1259 ResourceDescriptor
->Flags
= 0;
1260 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1261 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1263 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1264 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem32_data
->Minimum
;
1265 ResourceDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1267 ResourceDescriptor
++;
1270 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1272 ACPI_RESOURCE_FIXED_MEMORY32
*memfixed32_data
= (ACPI_RESOURCE_FIXED_MEMORY32
*) &resource
->Data
;
1273 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1274 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1275 ResourceDescriptor
->Flags
= 0;
1276 if (memfixed32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1277 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1279 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1280 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= memfixed32_data
->Address
;
1281 ResourceDescriptor
->u
.Memory
.Length
= memfixed32_data
->AddressLength
;
1283 ResourceDescriptor
++;
1291 resource
= ACPI_NEXT_RESOURCE(resource
);
1294 ExFreePoolWithTag(Buffer
.Pointer
, 'BpcA');
1295 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
1296 return STATUS_SUCCESS
;
1298 #endif /* UNIT_TEST */
1301 Bus_PDO_QueryResourceRequirements(
1302 PPDO_DEVICE_DATA DeviceData
,
1305 ULONG NumberOfResources
= 0;
1306 ACPI_STATUS AcpiStatus
;
1308 ACPI_RESOURCE
* resource
;
1309 ULONG i
, RequirementsListSize
;
1310 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
;
1311 PIO_RESOURCE_DESCRIPTOR RequirementDescriptor
;
1312 BOOLEAN CurrentRes
= FALSE
;
1313 BOOLEAN SeenStartDependent
;
1317 if (!DeviceData
->AcpiHandle
)
1319 return Irp
->IoStatus
.Status
;
1322 /* Handle the PCI root manually */
1323 if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
1324 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
1326 return Irp
->IoStatus
.Status
;
1329 /* Get current resources */
1334 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1336 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1337 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
1343 return Irp
->IoStatus
.Status
;
1349 Buffer
.Pointer
= ExAllocatePoolWithTag(PagedPool
, Buffer
.Length
, 'BpcA');
1350 if (!Buffer
.Pointer
)
1351 return STATUS_INSUFFICIENT_RESOURCES
;
1354 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1356 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1357 if (!ACPI_SUCCESS(AcpiStatus
))
1359 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
1361 return STATUS_UNSUCCESSFUL
;
1364 SeenStartDependent
= FALSE
;
1365 resource
= Buffer
.Pointer
;
1366 /* Count number of resources */
1367 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
&& resource
->Type
!= ACPI_RESOURCE_TYPE_END_DEPENDENT
)
1369 if (resource
->Type
== ACPI_RESOURCE_TYPE_START_DEPENDENT
)
1371 if (SeenStartDependent
)
1375 SeenStartDependent
= TRUE
;
1377 switch (resource
->Type
)
1379 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1381 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1382 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
1384 NumberOfResources
+= irq_data
->InterruptCount
;
1387 case ACPI_RESOURCE_TYPE_IRQ
:
1389 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1390 NumberOfResources
+= irq_data
->InterruptCount
;
1393 case ACPI_RESOURCE_TYPE_DMA
:
1395 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1396 NumberOfResources
+= dma_data
->ChannelCount
;
1399 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1400 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1401 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1402 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1404 ACPI_RESOURCE_ADDRESS
*res_addr
= (ACPI_RESOURCE_ADDRESS
*) &resource
->Data
;
1405 if (res_addr
->ProducerConsumer
== ACPI_PRODUCER
)
1407 NumberOfResources
++;
1410 case ACPI_RESOURCE_TYPE_MEMORY24
:
1411 case ACPI_RESOURCE_TYPE_MEMORY32
:
1412 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1413 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1414 case ACPI_RESOURCE_TYPE_IO
:
1416 NumberOfResources
++;
1424 resource
= ACPI_NEXT_RESOURCE(resource
);
1427 RequirementsListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
1428 RequirementsList
= ExAllocatePoolWithTag(PagedPool
, RequirementsListSize
, 'RpcA');
1430 if (!RequirementsList
)
1432 ExFreePoolWithTag(Buffer
.Pointer
, 'BpcA');
1433 return STATUS_INSUFFICIENT_RESOURCES
;
1435 RequirementsList
->ListSize
= RequirementsListSize
;
1436 RequirementsList
->InterfaceType
= Internal
;
1437 RequirementsList
->BusNumber
= 0;
1438 RequirementsList
->SlotNumber
= 0; /* Not used by WDM drivers */
1439 RequirementsList
->AlternativeLists
= 1;
1440 RequirementsList
->List
[0].Version
= 1;
1441 RequirementsList
->List
[0].Revision
= 1;
1442 RequirementsList
->List
[0].Count
= NumberOfResources
;
1443 RequirementDescriptor
= RequirementsList
->List
[0].Descriptors
;
1445 /* Fill resources list structure */
1446 SeenStartDependent
= FALSE
;
1447 resource
= Buffer
.Pointer
;
1448 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
&& resource
->Type
!= ACPI_RESOURCE_TYPE_END_DEPENDENT
)
1450 if (resource
->Type
== ACPI_RESOURCE_TYPE_START_DEPENDENT
)
1452 if (SeenStartDependent
)
1456 SeenStartDependent
= TRUE
;
1458 switch (resource
->Type
)
1460 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1462 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= &resource
->Data
.ExtendedIrq
;
1463 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
1465 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1467 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1468 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1469 RequirementDescriptor
->ShareDisposition
= (irq_data
->Shareable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1470 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1471 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1472 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1474 RequirementDescriptor
++;
1478 case ACPI_RESOURCE_TYPE_IRQ
:
1480 ACPI_RESOURCE_IRQ
*irq_data
= &resource
->Data
.Irq
;
1481 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1483 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1484 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1485 RequirementDescriptor
->ShareDisposition
= (irq_data
->Shareable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1486 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1487 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1488 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1490 RequirementDescriptor
++;
1494 case ACPI_RESOURCE_TYPE_DMA
:
1496 ACPI_RESOURCE_DMA
*dma_data
= &resource
->Data
.Dma
;
1497 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
1499 RequirementDescriptor
->Type
= CmResourceTypeDma
;
1500 RequirementDescriptor
->Flags
= 0;
1501 switch (dma_data
->Type
)
1503 case ACPI_TYPE_A
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
1504 case ACPI_TYPE_B
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
1505 case ACPI_TYPE_F
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
1507 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
1508 RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
1509 switch (dma_data
->Transfer
)
1511 case ACPI_TRANSFER_8
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
1512 case ACPI_TRANSFER_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
1513 case ACPI_TRANSFER_8_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
1516 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1517 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1518 RequirementDescriptor
->u
.Dma
.MinimumChannel
=
1519 RequirementDescriptor
->u
.Dma
.MaximumChannel
= dma_data
->Channels
[i
];
1520 RequirementDescriptor
++;
1524 case ACPI_RESOURCE_TYPE_IO
:
1526 ACPI_RESOURCE_IO
*io_data
= &resource
->Data
.Io
;
1527 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1528 if (io_data
->IoDecode
== ACPI_DECODE_16
)
1529 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
1531 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
1532 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1533 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1534 RequirementDescriptor
->Type
= CmResourceTypePort
;
1535 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1536 RequirementDescriptor
->u
.Port
.Alignment
= io_data
->Alignment
;
1537 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Minimum
;
1538 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Maximum
+ io_data
->AddressLength
- 1;
1540 RequirementDescriptor
++;
1543 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1545 ACPI_RESOURCE_FIXED_IO
*io_data
= &resource
->Data
.FixedIo
;
1546 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1547 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1548 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1549 RequirementDescriptor
->Type
= CmResourceTypePort
;
1550 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1551 RequirementDescriptor
->u
.Port
.Alignment
= 1;
1552 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Address
;
1553 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Address
+ io_data
->AddressLength
- 1;
1555 RequirementDescriptor
++;
1558 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1560 ACPI_RESOURCE_ADDRESS16
*addr16_data
= &resource
->Data
.Address16
;
1561 if (addr16_data
->ProducerConsumer
== ACPI_PRODUCER
)
1563 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1564 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1566 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1567 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1568 RequirementDescriptor
->Flags
= 0;
1569 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr16_data
->Address
.Minimum
;
1570 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr16_data
->Address
.Maximum
+ addr16_data
->Address
.AddressLength
- 1;
1571 RequirementDescriptor
->u
.BusNumber
.Length
= addr16_data
->Address
.AddressLength
;
1573 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1575 RequirementDescriptor
->Type
= CmResourceTypePort
;
1576 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1577 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1578 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1579 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1580 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr16_data
->Address
.Minimum
;
1581 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr16_data
->Address
.Maximum
+ addr16_data
->Address
.AddressLength
- 1;
1582 RequirementDescriptor
->u
.Port
.Length
= addr16_data
->Address
.AddressLength
;
1586 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1587 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1588 RequirementDescriptor
->Flags
= 0;
1589 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1590 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1592 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1593 switch (addr16_data
->Info
.Mem
.Caching
)
1595 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1596 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1597 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1599 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr16_data
->Address
.Minimum
;
1600 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr16_data
->Address
.Maximum
+ addr16_data
->Address
.AddressLength
- 1;
1601 RequirementDescriptor
->u
.Memory
.Length
= addr16_data
->Address
.AddressLength
;
1603 RequirementDescriptor
++;
1606 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1608 ACPI_RESOURCE_ADDRESS32
*addr32_data
= &resource
->Data
.Address32
;
1609 if (addr32_data
->ProducerConsumer
== ACPI_PRODUCER
)
1611 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1612 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1614 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1615 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1616 RequirementDescriptor
->Flags
= 0;
1617 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr32_data
->Address
.Minimum
;
1618 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr32_data
->Address
.Maximum
+ addr32_data
->Address
.AddressLength
- 1;
1619 RequirementDescriptor
->u
.BusNumber
.Length
= addr32_data
->Address
.AddressLength
;
1621 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1623 RequirementDescriptor
->Type
= CmResourceTypePort
;
1624 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1625 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1626 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1627 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1628 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr32_data
->Address
.Minimum
;
1629 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr32_data
->Address
.Maximum
+ addr32_data
->Address
.AddressLength
- 1;
1630 RequirementDescriptor
->u
.Port
.Length
= addr32_data
->Address
.AddressLength
;
1634 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1635 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1636 RequirementDescriptor
->Flags
= 0;
1637 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1638 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1640 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1641 switch (addr32_data
->Info
.Mem
.Caching
)
1643 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1644 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1645 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1647 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr32_data
->Address
.Minimum
;
1648 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr32_data
->Address
.Maximum
+ addr32_data
->Address
.AddressLength
- 1;
1649 RequirementDescriptor
->u
.Memory
.Length
= addr32_data
->Address
.AddressLength
;
1651 RequirementDescriptor
++;
1654 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1656 ACPI_RESOURCE_ADDRESS64
*addr64_data
= &resource
->Data
.Address64
;
1657 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1659 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1660 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1662 DPRINT1("64-bit bus address is not supported!\n");
1663 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1664 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1665 RequirementDescriptor
->Flags
= 0;
1666 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Address
.Minimum
;
1667 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1668 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->Address
.AddressLength
;
1670 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1672 RequirementDescriptor
->Type
= CmResourceTypePort
;
1673 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1674 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1675 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1676 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1677 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Address
.Minimum
;
1678 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1679 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->Address
.AddressLength
;
1683 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1684 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1685 RequirementDescriptor
->Flags
= 0;
1686 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1687 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1689 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1690 switch (addr64_data
->Info
.Mem
.Caching
)
1692 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1693 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1694 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1696 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Address
.Minimum
;
1697 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1698 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->Address
.AddressLength
;
1700 RequirementDescriptor
++;
1703 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1705 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= &resource
->Data
.ExtAddress64
;
1706 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1708 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1709 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1711 DPRINT1("64-bit bus address is not supported!\n");
1712 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1713 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1714 RequirementDescriptor
->Flags
= 0;
1715 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Address
.Minimum
;
1716 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1717 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->Address
.AddressLength
;
1719 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1721 RequirementDescriptor
->Type
= CmResourceTypePort
;
1722 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1723 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1724 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1725 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1726 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Address
.Minimum
;
1727 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1728 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->Address
.AddressLength
;
1732 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1733 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1734 RequirementDescriptor
->Flags
= 0;
1735 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1736 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1738 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1739 switch (addr64_data
->Info
.Mem
.Caching
)
1741 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1742 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1743 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1745 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Address
.Minimum
;
1746 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1747 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->Address
.AddressLength
;
1749 RequirementDescriptor
++;
1752 case ACPI_RESOURCE_TYPE_MEMORY24
:
1754 ACPI_RESOURCE_MEMORY24
*mem24_data
= &resource
->Data
.Memory24
;
1755 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1756 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1757 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1758 RequirementDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1759 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1760 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1762 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1763 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem24_data
->Minimum
;
1764 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem24_data
->Maximum
+ mem24_data
->AddressLength
- 1;
1765 RequirementDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1767 RequirementDescriptor
++;
1770 case ACPI_RESOURCE_TYPE_MEMORY32
:
1772 ACPI_RESOURCE_MEMORY32
*mem32_data
= &resource
->Data
.Memory32
;
1773 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1774 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1775 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1776 RequirementDescriptor
->Flags
= 0;
1777 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1778 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1780 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1781 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem32_data
->Minimum
;
1782 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem32_data
->Maximum
+ mem32_data
->AddressLength
- 1;
1783 RequirementDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1785 RequirementDescriptor
++;
1788 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1790 ACPI_RESOURCE_FIXED_MEMORY32
*fixedmem32_data
= &resource
->Data
.FixedMemory32
;
1791 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1792 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1793 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1794 RequirementDescriptor
->Flags
= 0;
1795 if (fixedmem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1796 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1798 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1799 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= fixedmem32_data
->Address
;
1800 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= fixedmem32_data
->Address
+ fixedmem32_data
->AddressLength
- 1;
1801 RequirementDescriptor
->u
.Memory
.Length
= fixedmem32_data
->AddressLength
;
1803 RequirementDescriptor
++;
1811 resource
= ACPI_NEXT_RESOURCE(resource
);
1813 ExFreePoolWithTag(Buffer
.Pointer
, 'BpcA');
1815 Irp
->IoStatus
.Information
= (ULONG_PTR
)RequirementsList
;
1817 return STATUS_SUCCESS
;
1822 Bus_PDO_QueryDeviceRelations(
1823 PPDO_DEVICE_DATA DeviceData
,
1827 Routine Description:
1829 The PnP Manager sends this IRP to gather information about
1830 devices with a relationship to the specified device.
1831 Bus drivers must handle this request for TargetDeviceRelation
1832 for their child devices (child PDOs).
1834 If a driver returns relations in response to this IRP,
1835 it allocates a DEVICE_RELATIONS structure from paged
1836 memory containing a count and the appropriate number of
1837 device object pointers. The PnP Manager frees the structure
1838 when it is no longer needed. If a driver replaces a
1839 DEVICE_RELATIONS structure allocated by another driver,
1840 it must free the previous structure.
1842 A driver must reference the PDO of any device that it
1843 reports in this IRP (ObReferenceObject). The PnP Manager
1844 removes the reference when appropriate.
1848 DeviceData - Pointer to the PDO's device extension.
1849 Irp - Pointer to the irp.
1858 PIO_STACK_LOCATION stack
;
1859 PDEVICE_RELATIONS deviceRelations
;
1864 stack
= IoGetCurrentIrpStackLocation (Irp
);
1866 switch (stack
->Parameters
.QueryDeviceRelations
.Type
) {
1868 case TargetDeviceRelation
:
1870 deviceRelations
= (PDEVICE_RELATIONS
) Irp
->IoStatus
.Information
;
1871 if (deviceRelations
) {
1873 // Only PDO can handle this request. Somebody above
1874 // is not playing by rule.
1876 ASSERTMSG("Someone above is handling TargetDeviceRelation\n", !deviceRelations
);
1879 deviceRelations
= ExAllocatePoolWithTag(PagedPool
,
1880 sizeof(DEVICE_RELATIONS
),
1882 if (!deviceRelations
) {
1883 status
= STATUS_INSUFFICIENT_RESOURCES
;
1888 // There is only one PDO pointer in the structure
1889 // for this relation type. The PnP Manager removes
1890 // the reference to the PDO when the driver or application
1891 // un-registers for notification on the device.
1894 deviceRelations
->Count
= 1;
1895 deviceRelations
->Objects
[0] = DeviceData
->Common
.Self
;
1896 ObReferenceObject(DeviceData
->Common
.Self
);
1898 status
= STATUS_SUCCESS
;
1899 Irp
->IoStatus
.Information
= (ULONG_PTR
) deviceRelations
;
1902 case BusRelations
: // Not handled by PDO
1903 case EjectionRelations
: // optional for PDO
1904 case RemovalRelations
: // // optional for PDO
1906 status
= Irp
->IoStatus
.Status
;
1913 Bus_PDO_QueryBusInformation(
1914 PPDO_DEVICE_DATA DeviceData
,
1918 Routine Description:
1920 The PnP Manager uses this IRP to request the type and
1921 instance number of a device's parent bus. Bus drivers
1922 should handle this request for their child devices (PDOs).
1926 DeviceData - Pointer to the PDO's device extension.
1927 Irp - Pointer to the irp.
1936 PPNP_BUS_INFORMATION busInfo
;
1940 busInfo
= ExAllocatePoolWithTag(PagedPool
,
1941 sizeof(PNP_BUS_INFORMATION
),
1944 if (busInfo
== NULL
) {
1945 return STATUS_INSUFFICIENT_RESOURCES
;
1948 busInfo
->BusTypeGuid
= GUID_ACPI_INTERFACE_STANDARD
;
1950 busInfo
->LegacyBusType
= InternalPowerBus
;
1952 busInfo
->BusNumber
= 0; //fixme
1954 Irp
->IoStatus
.Information
= (ULONG_PTR
)busInfo
;
1956 return STATUS_SUCCESS
;
1961 Bus_GetDeviceCapabilities(
1962 PDEVICE_OBJECT DeviceObject
,
1963 PDEVICE_CAPABILITIES DeviceCapabilities
1966 IO_STATUS_BLOCK ioStatus
;
1969 PDEVICE_OBJECT targetObject
;
1970 PIO_STACK_LOCATION irpStack
;
1976 // Initialize the capabilities that we will send down
1978 RtlZeroMemory( DeviceCapabilities
, sizeof(DEVICE_CAPABILITIES
) );
1979 DeviceCapabilities
->Size
= sizeof(DEVICE_CAPABILITIES
);
1980 DeviceCapabilities
->Version
= 1;
1981 DeviceCapabilities
->Address
= -1;
1982 DeviceCapabilities
->UINumber
= -1;
1985 // Initialize the event
1987 KeInitializeEvent( &pnpEvent
, NotificationEvent
, FALSE
);
1989 targetObject
= IoGetAttachedDeviceReference( DeviceObject
);
1994 pnpIrp
= IoBuildSynchronousFsdRequest(
2003 if (pnpIrp
== NULL
) {
2005 status
= STATUS_INSUFFICIENT_RESOURCES
;
2006 goto GetDeviceCapabilitiesExit
;
2011 // Pnp Irps all begin life as STATUS_NOT_SUPPORTED;
2013 pnpIrp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
2016 // Get the top of stack
2018 irpStack
= IoGetNextIrpStackLocation( pnpIrp
);
2021 // Set the top of stack
2023 RtlZeroMemory( irpStack
, sizeof(IO_STACK_LOCATION
) );
2024 irpStack
->MajorFunction
= IRP_MJ_PNP
;
2025 irpStack
->MinorFunction
= IRP_MN_QUERY_CAPABILITIES
;
2026 irpStack
->Parameters
.DeviceCapabilities
.Capabilities
= DeviceCapabilities
;
2031 status
= IoCallDriver( targetObject
, pnpIrp
);
2032 if (status
== STATUS_PENDING
) {
2035 // Block until the irp comes back.
2036 // Important thing to note here is when you allocate
2037 // the memory for an event in the stack you must do a
2038 // KernelMode wait instead of UserMode to prevent
2039 // the stack from getting paged out.
2042 KeWaitForSingleObject(
2049 status
= ioStatus
.Status
;
2053 GetDeviceCapabilitiesExit
:
2055 // Done with reference
2057 ObDereferenceObject( targetObject
);
2065 #endif /* UNIT_TEST */