10 #pragma alloc_text (PAGE, Bus_PDO_PnP)
11 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceCaps)
12 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceId)
13 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceText)
14 #pragma alloc_text (PAGE, Bus_PDO_QueryResources)
15 #pragma alloc_text (PAGE, Bus_PDO_QueryResourceRequirements)
16 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceRelations)
17 #pragma alloc_text (PAGE, Bus_PDO_QueryBusInformation)
18 #pragma alloc_text (PAGE, Bus_GetDeviceCapabilities)
23 PDEVICE_OBJECT DeviceObject
,
25 PIO_STACK_LOCATION IrpStack
,
26 PPDO_DEVICE_DATA DeviceData
31 struct acpi_device
*device
= NULL
;
35 if (DeviceData
->AcpiHandle
)
36 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
39 // NB: Because we are a bus enumerator, we have no one to whom we could
40 // defer these irps. Therefore we do not pass them down but merely
44 switch (IrpStack
->MinorFunction
) {
46 case IRP_MN_START_DEVICE
:
48 // Here we do what ever initialization and ``turning on'' that is
49 // required to allow others to access this device.
50 // Power up the device.
52 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
53 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D0
)))
55 DPRINT1("Device %x failed to start!\n", DeviceData
->AcpiHandle
);
56 status
= STATUS_UNSUCCESSFUL
;
60 DeviceData
->InterfaceName
.Length
= 0;
61 status
= STATUS_SUCCESS
;
65 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
66 &GUID_DEVICE_SYS_BUTTON
,
68 &DeviceData
->InterfaceName
);
70 else if (device
->flags
.hardware_id
&&
71 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
))
73 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
74 &GUID_DEVICE_THERMAL_ZONE
,
76 &DeviceData
->InterfaceName
);
78 else if (device
->flags
.hardware_id
&&
79 strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
))
81 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
84 &DeviceData
->InterfaceName
);
86 else if (device
->flags
.hardware_id
&&
87 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))
89 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
90 &GUID_DEVICE_PROCESSOR
,
92 &DeviceData
->InterfaceName
);
95 /* Failure to register an interface is not a fatal failure so don't return a failure status */
96 if (NT_SUCCESS(status
) && DeviceData
->InterfaceName
.Length
!= 0)
97 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, TRUE
);
99 state
.DeviceState
= PowerDeviceD0
;
100 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
101 DeviceData
->Common
.DevicePowerState
= PowerDeviceD0
;
102 SET_NEW_PNP_STATE(DeviceData
->Common
, Started
);
103 status
= STATUS_SUCCESS
;
106 case IRP_MN_STOP_DEVICE
:
108 if (DeviceData
->InterfaceName
.Length
!= 0)
109 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, FALSE
);
112 // Here we shut down the device and give up and unmap any resources
113 // we acquired for the device.
115 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
116 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D3
)))
118 DPRINT1("Device %x failed to stop!\n", DeviceData
->AcpiHandle
);
119 status
= STATUS_UNSUCCESSFUL
;
123 state
.DeviceState
= PowerDeviceD3
;
124 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
125 DeviceData
->Common
.DevicePowerState
= PowerDeviceD3
;
126 SET_NEW_PNP_STATE(DeviceData
->Common
, Stopped
);
127 status
= STATUS_SUCCESS
;
131 case IRP_MN_QUERY_STOP_DEVICE
:
134 // No reason here why we can't stop the device.
135 // If there were a reason we should speak now, because answering success
136 // here may result in a stop device irp.
139 SET_NEW_PNP_STATE(DeviceData
->Common
, StopPending
);
140 status
= STATUS_SUCCESS
;
143 case IRP_MN_CANCEL_STOP_DEVICE
:
146 // The stop was canceled. Whatever state we set, or resources we put
147 // on hold in anticipation of the forthcoming STOP device IRP should be
148 // put back to normal. Someone, in the long list of concerned parties,
149 // has failed the stop device query.
153 // First check to see whether you have received cancel-stop
154 // without first receiving a query-stop. This could happen if someone
155 // above us fails a query-stop and passes down the subsequent
159 if (StopPending
== DeviceData
->Common
.DevicePnPState
)
162 // We did receive a query-stop, so restore.
164 RESTORE_PREVIOUS_PNP_STATE(DeviceData
->Common
);
166 status
= STATUS_SUCCESS
;// We must not fail this IRP.
169 case IRP_MN_REMOVE_DEVICE
:
171 // We handle REMOVE_DEVICE just like STOP_DEVICE. This is because
172 // the device is still physically present (or at least we don't know any better)
173 // so we have to retain the PDO after stopping and removing power from it.
175 if (DeviceData
->InterfaceName
.Length
!= 0)
176 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, FALSE
);
178 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
179 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D3
)))
181 DPRINT1("Device %x failed to enter D3!\n", DeviceData
->AcpiHandle
);
182 state
.DeviceState
= PowerDeviceD3
;
183 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
184 DeviceData
->Common
.DevicePowerState
= PowerDeviceD3
;
187 SET_NEW_PNP_STATE(DeviceData
->Common
, Stopped
);
188 status
= STATUS_SUCCESS
;
191 case IRP_MN_QUERY_REMOVE_DEVICE
:
192 SET_NEW_PNP_STATE(DeviceData
->Common
, RemovalPending
);
193 status
= STATUS_SUCCESS
;
196 case IRP_MN_CANCEL_REMOVE_DEVICE
:
197 if (RemovalPending
== DeviceData
->Common
.DevicePnPState
)
199 RESTORE_PREVIOUS_PNP_STATE(DeviceData
->Common
);
201 status
= STATUS_SUCCESS
;
204 case IRP_MN_QUERY_CAPABILITIES
:
207 // Return the capabilities of a device, such as whether the device
208 // can be locked or ejected..etc
211 status
= Bus_PDO_QueryDeviceCaps(DeviceData
, Irp
);
215 case IRP_MN_QUERY_ID
:
217 // Query the IDs of the device
218 status
= Bus_PDO_QueryDeviceId(DeviceData
, Irp
);
222 case IRP_MN_QUERY_DEVICE_RELATIONS
:
224 DPRINT("\tQueryDeviceRelation Type: %s\n",DbgDeviceRelationString(\
225 IrpStack
->Parameters
.QueryDeviceRelations
.Type
));
227 status
= Bus_PDO_QueryDeviceRelations(DeviceData
, Irp
);
231 case IRP_MN_QUERY_DEVICE_TEXT
:
233 status
= Bus_PDO_QueryDeviceText(DeviceData
, Irp
);
237 case IRP_MN_QUERY_RESOURCES
:
239 status
= Bus_PDO_QueryResources(DeviceData
, Irp
);
243 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
245 status
= Bus_PDO_QueryResourceRequirements(DeviceData
, Irp
);
249 case IRP_MN_QUERY_BUS_INFORMATION
:
251 status
= Bus_PDO_QueryBusInformation(DeviceData
, Irp
);
255 case IRP_MN_QUERY_INTERFACE
:
257 status
= Bus_PDO_QueryInterface(DeviceData
, Irp
);
262 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
265 // OPTIONAL for bus drivers.
266 // The PnP Manager sends this IRP to a device
267 // stack so filter and function drivers can adjust the
268 // resources required by the device, if appropriate.
273 //case IRP_MN_QUERY_PNP_DEVICE_STATE:
276 // OPTIONAL for bus drivers.
277 // The PnP Manager sends this IRP after the drivers for
278 // a device return success from the IRP_MN_START_DEVICE
279 // request. The PnP Manager also sends this IRP when a
280 // driver for the device calls IoInvalidateDeviceState.
285 //case IRP_MN_READ_CONFIG:
286 //case IRP_MN_WRITE_CONFIG:
289 // Bus drivers for buses with configuration space must handle
290 // this request for their child devices. Our devices don't
291 // have a config space.
296 //case IRP_MN_SET_LOCK:
303 // For PnP requests to the PDO that we do not understand we should
304 // return the IRP WITHOUT setting the status or information fields.
305 // These fields may have already been set by a filter (eg acpi).
306 status
= Irp
->IoStatus
.Status
;
311 Irp
->IoStatus
.Status
= status
;
312 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
318 Bus_PDO_QueryDeviceCaps(
319 PPDO_DEVICE_DATA DeviceData
,
323 PIO_STACK_LOCATION stack
;
324 PDEVICE_CAPABILITIES deviceCapabilities
;
325 struct acpi_device
*device
= NULL
;
330 if (DeviceData
->AcpiHandle
)
331 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
333 stack
= IoGetCurrentIrpStackLocation (Irp
);
338 deviceCapabilities
=stack
->Parameters
.DeviceCapabilities
.Capabilities
;
341 // Set the capabilities.
344 if (deviceCapabilities
->Version
!= 1 ||
345 deviceCapabilities
->Size
< sizeof(DEVICE_CAPABILITIES
))
347 return STATUS_UNSUCCESSFUL
;
350 deviceCapabilities
->D1Latency
= 0;
351 deviceCapabilities
->D2Latency
= 0;
352 deviceCapabilities
->D3Latency
= 0;
354 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
355 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD3
;
356 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD3
;
357 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
359 for (i
= 0; i
< ACPI_D_STATE_COUNT
&& device
; i
++)
361 if (!device
->power
.states
[i
].flags
.valid
)
367 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
371 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD1
;
372 deviceCapabilities
->D1Latency
= device
->power
.states
[i
].latency
;
376 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD2
;
377 deviceCapabilities
->D2Latency
= device
->power
.states
[i
].latency
;
381 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
382 deviceCapabilities
->D3Latency
= device
->power
.states
[i
].latency
;
387 // We can wake the system from D1
388 deviceCapabilities
->DeviceWake
= PowerDeviceD1
;
391 deviceCapabilities
->DeviceD1
=
392 (deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] == PowerDeviceD1
) ? TRUE
: FALSE
;
393 deviceCapabilities
->DeviceD2
=
394 (deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] == PowerDeviceD2
) ? TRUE
: FALSE
;
396 deviceCapabilities
->WakeFromD0
= FALSE
;
397 deviceCapabilities
->WakeFromD1
= TRUE
; //Yes we can
398 deviceCapabilities
->WakeFromD2
= FALSE
;
399 deviceCapabilities
->WakeFromD3
= FALSE
;
403 deviceCapabilities
->LockSupported
= device
->flags
.lockable
;
404 deviceCapabilities
->EjectSupported
= device
->flags
.ejectable
;
405 deviceCapabilities
->HardwareDisabled
= !device
->status
.enabled
&& !device
->status
.functional
;
406 deviceCapabilities
->Removable
= device
->flags
.removable
;
407 deviceCapabilities
->SurpriseRemovalOK
= device
->flags
.surprise_removal_ok
;
408 deviceCapabilities
->UniqueID
= device
->flags
.unique_id
;
409 deviceCapabilities
->NoDisplayInUI
= !device
->status
.show_in_ui
;
410 deviceCapabilities
->Address
= device
->pnp
.bus_address
;
414 (device
->flags
.hardware_id
&&
415 (strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
) ||
416 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
) ||
417 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))))
419 /* Allow ACPI to control the device if it is a lid button,
420 * a thermal zone, a processor, or a fixed feature button */
421 deviceCapabilities
->RawDeviceOK
= TRUE
;
424 deviceCapabilities
->SilentInstall
= FALSE
;
425 deviceCapabilities
->UINumber
= (ULONG
)-1;
427 return STATUS_SUCCESS
;
432 Bus_PDO_QueryDeviceId(
433 PPDO_DEVICE_DATA DeviceData
,
436 PIO_STACK_LOCATION stack
;
440 NTSTATUS status
= STATUS_SUCCESS
;
441 struct acpi_device
*Device
;
445 stack
= IoGetCurrentIrpStackLocation (Irp
);
447 switch (stack
->Parameters
.QueryId
.IdType
) {
449 case BusQueryDeviceID
:
451 /* This is a REG_SZ value */
453 if (DeviceData
->AcpiHandle
)
455 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
457 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
459 length
= wcslen(ProcessorIdString
);
460 wcscpy(temp
, ProcessorIdString
);
464 length
= swprintf(temp
,
466 Device
->pnp
.hardware_id
);
471 /* We know it's a fixed feature button because
472 * these are direct children of the ACPI root device
473 * and therefore have no handle
475 length
= swprintf(temp
,
476 L
"ACPI\\FixedButton");
479 temp
[length
++] = UNICODE_NULL
;
481 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
483 buffer
= ExAllocatePoolWithTag(PagedPool
, length
* sizeof(WCHAR
), 'IpcA');
486 status
= STATUS_INSUFFICIENT_RESOURCES
;
490 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
491 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
492 DPRINT("BusQueryDeviceID: %ls\n",buffer
);
495 case BusQueryInstanceID
:
497 /* This is a REG_SZ value */
499 /* See comment in BusQueryDeviceID case */
500 if(DeviceData
->AcpiHandle
)
502 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
504 if (Device
->flags
.unique_id
)
505 length
= swprintf(temp
,
507 Device
->pnp
.unique_id
);
509 /* FIXME: Generate unique id! */
510 length
= swprintf(temp
, L
"%ls", L
"0000");
514 /* FIXME: Generate unique id! */
515 length
= swprintf(temp
, L
"%ls", L
"0000");
518 temp
[length
++] = UNICODE_NULL
;
520 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
522 buffer
= ExAllocatePoolWithTag(PagedPool
, length
* sizeof(WCHAR
), 'IpcA');
524 status
= STATUS_INSUFFICIENT_RESOURCES
;
528 RtlCopyMemory (buffer
, temp
, length
* sizeof (WCHAR
));
529 DPRINT("BusQueryInstanceID: %ls\n",buffer
);
530 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
533 case BusQueryHardwareIDs
:
535 /* This is a REG_MULTI_SZ value */
537 status
= STATUS_NOT_SUPPORTED
;
539 /* See comment in BusQueryDeviceID case */
540 if (DeviceData
->AcpiHandle
)
542 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
544 if (!Device
->flags
.hardware_id
)
546 /* We don't have the ID to satisfy this request */
550 DPRINT("Device name: %s\n", Device
->pnp
.device_name
);
551 DPRINT("Hardware ID: %s\n", Device
->pnp
.hardware_id
);
553 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
555 length
= ProcessorHardwareIds
.Length
/ sizeof(WCHAR
);
556 src
= ProcessorHardwareIds
.Buffer
;
560 length
+= swprintf(&temp
[length
],
562 Device
->pnp
.hardware_id
);
563 temp
[length
++] = UNICODE_NULL
;
565 length
+= swprintf(&temp
[length
],
567 Device
->pnp
.hardware_id
);
568 temp
[length
++] = UNICODE_NULL
;
569 temp
[length
++] = UNICODE_NULL
;
575 length
+= swprintf(&temp
[length
],
576 L
"ACPI\\FixedButton");
577 temp
[length
++] = UNICODE_NULL
;
579 length
+= swprintf(&temp
[length
],
581 temp
[length
++] = UNICODE_NULL
;
582 temp
[length
++] = UNICODE_NULL
;
586 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
588 buffer
= ExAllocatePoolWithTag(PagedPool
, length
* sizeof(WCHAR
), 'IpcA');
591 status
= STATUS_INSUFFICIENT_RESOURCES
;
595 RtlCopyMemory (buffer
, src
, length
* sizeof(WCHAR
));
596 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
597 DPRINT("BusQueryHardwareIDs: %ls\n",buffer
);
598 status
= STATUS_SUCCESS
;
601 case BusQueryCompatibleIDs
:
603 /* This is a REG_MULTI_SZ value */
605 status
= STATUS_NOT_SUPPORTED
;
607 /* See comment in BusQueryDeviceID case */
608 if (DeviceData
->AcpiHandle
)
610 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
612 if (!Device
->flags
.hardware_id
)
614 /* We don't have the ID to satisfy this request */
618 DPRINT("Device name: %s\n", Device
->pnp
.device_name
);
619 DPRINT("Hardware ID: %s\n", Device
->pnp
.hardware_id
);
621 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
623 length
+= swprintf(&temp
[length
],
625 Device
->pnp
.hardware_id
);
626 temp
[length
++] = UNICODE_NULL
;
628 length
+= swprintf(&temp
[length
],
630 Device
->pnp
.hardware_id
);
631 temp
[length
++] = UNICODE_NULL
;
632 temp
[length
++] = UNICODE_NULL
;
634 else if (Device
->flags
.compatible_ids
)
636 for (i
= 0; i
< Device
->pnp
.cid_list
->Count
; i
++)
638 length
+= swprintf(&temp
[length
],
640 Device
->pnp
.cid_list
->Ids
[i
].String
);
641 temp
[length
++] = UNICODE_NULL
;
643 length
+= swprintf(&temp
[length
],
645 Device
->pnp
.cid_list
->Ids
[i
].String
);
646 temp
[length
++] = UNICODE_NULL
;
649 temp
[length
++] = UNICODE_NULL
;
653 /* No compatible IDs */
657 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
659 buffer
= ExAllocatePoolWithTag(PagedPool
, length
* sizeof(WCHAR
), 'IpcA');
662 status
= STATUS_INSUFFICIENT_RESOURCES
;
666 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
667 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
668 DPRINT("BusQueryCompatibleIDs: %ls\n",buffer
);
669 status
= STATUS_SUCCESS
;
674 status
= Irp
->IoStatus
.Status
;
680 Bus_PDO_QueryDeviceText(
681 PPDO_DEVICE_DATA DeviceData
,
685 PIO_STACK_LOCATION stack
;
686 NTSTATUS status
= Irp
->IoStatus
.Status
;
689 stack
= IoGetCurrentIrpStackLocation (Irp
);
691 switch (stack
->Parameters
.QueryDeviceText
.DeviceTextType
) {
693 case DeviceTextDescription
:
695 if (!Irp
->IoStatus
.Information
) {
696 if (wcsstr (DeviceData
->HardwareIDs
, L
"PNP000") != 0)
697 Temp
= L
"Programmable interrupt controller";
698 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP010") != 0)
699 Temp
= L
"System timer";
700 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP020") != 0)
701 Temp
= L
"DMA controller";
702 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP03") != 0)
704 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP040") != 0)
705 Temp
= L
"Parallel port";
706 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP05") != 0)
707 Temp
= L
"Serial port";
708 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP06") != 0)
709 Temp
= L
"Disk controller";
710 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP07") != 0)
711 Temp
= L
"Disk controller";
712 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP09") != 0)
713 Temp
= L
"Display adapter";
714 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A0") != 0)
715 Temp
= L
"Bus controller";
716 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0E0") != 0)
717 Temp
= L
"PCMCIA controller";
718 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0F") != 0)
719 Temp
= L
"Mouse device";
720 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP8") != 0)
721 Temp
= L
"Network adapter";
722 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPA0") != 0)
723 Temp
= L
"SCSI controller";
724 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPB0") != 0)
725 Temp
= L
"Multimedia device";
726 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPC00") != 0)
728 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0C") != 0)
729 Temp
= L
"Power Button";
730 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0E") != 0)
731 Temp
= L
"Sleep Button";
732 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0D") != 0)
733 Temp
= L
"Lid Switch";
734 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C09") != 0)
735 Temp
= L
"ACPI Embedded Controller";
736 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0B") != 0)
738 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
739 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
740 Temp
= L
"PCI Root Bridge";
741 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0A") != 0)
742 Temp
= L
"ACPI Battery";
743 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0F") != 0)
744 Temp
= L
"PCI Interrupt Link";
745 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI_PWR") != 0)
746 Temp
= L
"ACPI Power Resource";
747 else if (wcsstr(DeviceData
->HardwareIDs
, L
"Processor") != 0)
749 if (ProcessorNameString
!= NULL
)
750 Temp
= ProcessorNameString
;
754 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ThermalZone") != 0)
755 Temp
= L
"ACPI Thermal Zone";
756 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0002") != 0)
757 Temp
= L
"Smart Battery";
758 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0003") != 0)
759 Temp
= L
"AC Adapter";
760 /* Simply checking if AcpiHandle is NULL eliminates the need to check
761 * for the 4 different names that ACPI knows the fixed feature button as internally
763 else if (!DeviceData
->AcpiHandle
)
764 Temp
= L
"ACPI Fixed Feature Button";
766 Temp
= L
"Other ACPI device";
768 Buffer
= ExAllocatePoolWithTag(PagedPool
, (wcslen(Temp
) + 1) * sizeof(WCHAR
), 'IpcA');
771 status
= STATUS_INSUFFICIENT_RESOURCES
;
775 RtlCopyMemory (Buffer
, Temp
, (wcslen(Temp
) + 1) * sizeof(WCHAR
));
777 DPRINT("\tDeviceTextDescription :%ws\n", Buffer
);
779 Irp
->IoStatus
.Information
= (ULONG_PTR
) Buffer
;
780 status
= STATUS_SUCCESS
;
793 Bus_PDO_QueryResources(
794 PPDO_DEVICE_DATA DeviceData
,
797 ULONG NumberOfResources
= 0;
798 PCM_RESOURCE_LIST ResourceList
;
799 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor
;
800 ACPI_STATUS AcpiStatus
;
802 ACPI_RESOURCE
* resource
;
803 ULONG ResourceListSize
;
806 struct acpi_device
*device
;
808 if (!DeviceData
->AcpiHandle
)
810 return Irp
->IoStatus
.Status
;
813 /* A bus number resource is not included in the list of current resources
814 * for the root PCI bus so we manually query one here and if we find it
815 * we create a resource list and add a bus number descriptor to it */
816 if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
817 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
819 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
821 AcpiStatus
= acpi_evaluate_integer(DeviceData
->AcpiHandle
, "_BBN", NULL
, &BusNumber
);
822 if (AcpiStatus
!= AE_OK
)
825 if (device
->flags
.unique_id
)
827 /* FIXME: Try the unique ID */
833 DPRINT1("Failed to find a bus number\n");
838 DPRINT("Using _BBN for bus number\n");
841 DPRINT("Found PCI root hub: %d\n", BusNumber
);
843 ResourceListSize
= sizeof(CM_RESOURCE_LIST
);
844 ResourceList
= ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, 'RpcA');
846 return STATUS_INSUFFICIENT_RESOURCES
;
848 ResourceList
->Count
= 1;
849 ResourceList
->List
[0].InterfaceType
= Internal
;
850 ResourceList
->List
[0].BusNumber
= 0;
851 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
852 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
853 ResourceList
->List
[0].PartialResourceList
.Count
= 1;
854 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
856 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
857 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
858 ResourceDescriptor
->u
.BusNumber
.Start
= BusNumber
;
859 ResourceDescriptor
->u
.BusNumber
.Length
= 1;
861 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
862 return STATUS_SUCCESS
;
865 /* Get current resources */
867 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
868 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
871 return Irp
->IoStatus
.Status
;
874 Buffer
.Pointer
= ExAllocatePoolWithTag(PagedPool
, Buffer
.Length
, 'BpcA');
876 return STATUS_INSUFFICIENT_RESOURCES
;
878 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
879 if (!ACPI_SUCCESS(AcpiStatus
))
881 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
883 return STATUS_UNSUCCESSFUL
;
886 resource
= Buffer
.Pointer
;
887 /* Count number of resources */
888 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
890 switch (resource
->Type
)
892 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
894 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
895 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
897 NumberOfResources
+= irq_data
->InterruptCount
;
900 case ACPI_RESOURCE_TYPE_IRQ
:
902 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
903 NumberOfResources
+= irq_data
->InterruptCount
;
906 case ACPI_RESOURCE_TYPE_DMA
:
908 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
909 NumberOfResources
+= dma_data
->ChannelCount
;
912 case ACPI_RESOURCE_TYPE_ADDRESS16
:
913 case ACPI_RESOURCE_TYPE_ADDRESS32
:
914 case ACPI_RESOURCE_TYPE_ADDRESS64
:
915 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
917 ACPI_RESOURCE_ADDRESS
*addr_res
= (ACPI_RESOURCE_ADDRESS
*) &resource
->Data
;
918 if (addr_res
->ProducerConsumer
== ACPI_PRODUCER
)
923 case ACPI_RESOURCE_TYPE_MEMORY24
:
924 case ACPI_RESOURCE_TYPE_MEMORY32
:
925 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
926 case ACPI_RESOURCE_TYPE_FIXED_IO
:
927 case ACPI_RESOURCE_TYPE_IO
:
934 DPRINT1("Unknown resource type: %d\n", resource
->Type
);
938 resource
= ACPI_NEXT_RESOURCE(resource
);
941 /* Allocate memory */
942 ResourceListSize
= sizeof(CM_RESOURCE_LIST
) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
943 ResourceList
= ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, 'RpcA');
947 ExFreePoolWithTag(Buffer
.Pointer
, 'BpcA');
948 return STATUS_INSUFFICIENT_RESOURCES
;
950 ResourceList
->Count
= 1;
951 ResourceList
->List
[0].InterfaceType
= Internal
; /* FIXME */
952 ResourceList
->List
[0].BusNumber
= 0; /* We're the only ACPI bus device in the system */
953 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
954 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
955 ResourceList
->List
[0].PartialResourceList
.Count
= NumberOfResources
;
956 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
958 /* Fill resources list structure */
959 resource
= Buffer
.Pointer
;
960 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
962 switch (resource
->Type
)
964 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
966 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
967 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
969 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
971 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
973 ResourceDescriptor
->ShareDisposition
=
974 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
975 ResourceDescriptor
->Flags
=
976 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
977 ResourceDescriptor
->u
.Interrupt
.Level
=
978 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
979 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
981 ResourceDescriptor
++;
985 case ACPI_RESOURCE_TYPE_IRQ
:
987 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
988 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
990 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
992 ResourceDescriptor
->ShareDisposition
=
993 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
994 ResourceDescriptor
->Flags
=
995 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
996 ResourceDescriptor
->u
.Interrupt
.Level
=
997 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
998 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
1000 ResourceDescriptor
++;
1004 case ACPI_RESOURCE_TYPE_DMA
:
1006 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1007 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
1009 ResourceDescriptor
->Type
= CmResourceTypeDma
;
1010 ResourceDescriptor
->Flags
= 0;
1011 switch (dma_data
->Type
)
1013 case ACPI_TYPE_A
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
1014 case ACPI_TYPE_B
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
1015 case ACPI_TYPE_F
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
1017 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
1018 ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
1019 switch (dma_data
->Transfer
)
1021 case ACPI_TRANSFER_8
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
1022 case ACPI_TRANSFER_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
1023 case ACPI_TRANSFER_8_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
1025 ResourceDescriptor
->u
.Dma
.Channel
= dma_data
->Channels
[i
];
1027 ResourceDescriptor
++;
1031 case ACPI_RESOURCE_TYPE_IO
:
1033 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
1034 ResourceDescriptor
->Type
= CmResourceTypePort
;
1035 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1036 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1037 if (io_data
->IoDecode
== ACPI_DECODE_16
)
1038 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
1040 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
1041 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Minimum
;
1042 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1044 ResourceDescriptor
++;
1047 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1049 ACPI_RESOURCE_FIXED_IO
*io_data
= (ACPI_RESOURCE_FIXED_IO
*) &resource
->Data
;
1050 ResourceDescriptor
->Type
= CmResourceTypePort
;
1051 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1052 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1053 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Address
;
1054 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1056 ResourceDescriptor
++;
1059 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1061 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
1062 if (addr16_data
->ProducerConsumer
== ACPI_PRODUCER
)
1064 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1066 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1067 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1068 ResourceDescriptor
->Flags
= 0;
1069 ResourceDescriptor
->u
.BusNumber
.Start
= addr16_data
->Address
.Minimum
;
1070 ResourceDescriptor
->u
.BusNumber
.Length
= addr16_data
->Address
.AddressLength
;
1072 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1074 ResourceDescriptor
->Type
= CmResourceTypePort
;
1075 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1076 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1077 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1078 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1079 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr16_data
->Address
.Minimum
;
1080 ResourceDescriptor
->u
.Port
.Length
= addr16_data
->Address
.AddressLength
;
1084 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1085 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1086 ResourceDescriptor
->Flags
= 0;
1087 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1088 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1090 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1091 switch (addr16_data
->Info
.Mem
.Caching
)
1093 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1094 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1095 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1097 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr16_data
->Address
.Minimum
;
1098 ResourceDescriptor
->u
.Memory
.Length
= addr16_data
->Address
.AddressLength
;
1100 ResourceDescriptor
++;
1103 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1105 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
1106 if (addr32_data
->ProducerConsumer
== ACPI_PRODUCER
)
1108 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1110 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1111 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1112 ResourceDescriptor
->Flags
= 0;
1113 ResourceDescriptor
->u
.BusNumber
.Start
= addr32_data
->Address
.Minimum
;
1114 ResourceDescriptor
->u
.BusNumber
.Length
= addr32_data
->Address
.AddressLength
;
1116 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1118 ResourceDescriptor
->Type
= CmResourceTypePort
;
1119 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1120 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1121 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1122 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1123 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr32_data
->Address
.Minimum
;
1124 ResourceDescriptor
->u
.Port
.Length
= addr32_data
->Address
.AddressLength
;
1128 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1129 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1130 ResourceDescriptor
->Flags
= 0;
1131 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1132 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1134 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1135 switch (addr32_data
->Info
.Mem
.Caching
)
1137 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1138 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1139 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1141 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr32_data
->Address
.Minimum
;
1142 ResourceDescriptor
->u
.Memory
.Length
= addr32_data
->Address
.AddressLength
;
1144 ResourceDescriptor
++;
1147 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1149 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
1150 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1152 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1154 DPRINT1("64-bit bus address is not supported!\n");
1155 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1156 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1157 ResourceDescriptor
->Flags
= 0;
1158 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Address
.Minimum
;
1159 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->Address
.AddressLength
;
1161 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1163 ResourceDescriptor
->Type
= CmResourceTypePort
;
1164 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1165 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1166 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1167 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1168 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Address
.Minimum
;
1169 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->Address
.AddressLength
;
1173 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1174 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1175 ResourceDescriptor
->Flags
= 0;
1176 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1177 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1179 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1180 switch (addr64_data
->Info
.Mem
.Caching
)
1182 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1183 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1184 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1186 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Address
.Minimum
;
1187 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->Address
.AddressLength
;
1189 ResourceDescriptor
++;
1192 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1194 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
1195 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1197 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1199 DPRINT1("64-bit bus address is not supported!\n");
1200 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1201 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1202 ResourceDescriptor
->Flags
= 0;
1203 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Address
.Minimum
;
1204 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->Address
.AddressLength
;
1206 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1208 ResourceDescriptor
->Type
= CmResourceTypePort
;
1209 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1210 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1211 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1212 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1213 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Address
.Minimum
;
1214 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->Address
.AddressLength
;
1218 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1219 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1220 ResourceDescriptor
->Flags
= 0;
1221 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1222 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1224 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1225 switch (addr64_data
->Info
.Mem
.Caching
)
1227 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1228 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1229 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1231 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Address
.Minimum
;
1232 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->Address
.AddressLength
;
1234 ResourceDescriptor
++;
1237 case ACPI_RESOURCE_TYPE_MEMORY24
:
1239 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1240 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1241 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1242 ResourceDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1243 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1244 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1246 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1247 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem24_data
->Minimum
;
1248 ResourceDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1250 ResourceDescriptor
++;
1253 case ACPI_RESOURCE_TYPE_MEMORY32
:
1255 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1256 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1257 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1258 ResourceDescriptor
->Flags
= 0;
1259 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1260 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1262 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1263 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem32_data
->Minimum
;
1264 ResourceDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1266 ResourceDescriptor
++;
1269 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1271 ACPI_RESOURCE_FIXED_MEMORY32
*memfixed32_data
= (ACPI_RESOURCE_FIXED_MEMORY32
*) &resource
->Data
;
1272 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1273 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1274 ResourceDescriptor
->Flags
= 0;
1275 if (memfixed32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1276 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1278 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1279 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= memfixed32_data
->Address
;
1280 ResourceDescriptor
->u
.Memory
.Length
= memfixed32_data
->AddressLength
;
1282 ResourceDescriptor
++;
1290 resource
= ACPI_NEXT_RESOURCE(resource
);
1293 ExFreePoolWithTag(Buffer
.Pointer
, 'BpcA');
1294 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
1295 return STATUS_SUCCESS
;
1299 Bus_PDO_QueryResourceRequirements(
1300 PPDO_DEVICE_DATA DeviceData
,
1303 ULONG NumberOfResources
= 0;
1304 ACPI_STATUS AcpiStatus
;
1306 ACPI_RESOURCE
* resource
;
1307 ULONG i
, RequirementsListSize
;
1308 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
;
1309 PIO_RESOURCE_DESCRIPTOR RequirementDescriptor
;
1310 BOOLEAN CurrentRes
= FALSE
;
1314 if (!DeviceData
->AcpiHandle
)
1316 return Irp
->IoStatus
.Status
;
1319 /* Handle the PCI root manually */
1320 if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
1321 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
1323 return Irp
->IoStatus
.Status
;
1326 /* Get current resources */
1331 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1333 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1334 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
1340 return Irp
->IoStatus
.Status
;
1346 Buffer
.Pointer
= ExAllocatePoolWithTag(PagedPool
, Buffer
.Length
, 'BpcA');
1347 if (!Buffer
.Pointer
)
1348 return STATUS_INSUFFICIENT_RESOURCES
;
1351 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1353 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1354 if (!ACPI_SUCCESS(AcpiStatus
))
1356 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
1358 return STATUS_UNSUCCESSFUL
;
1361 resource
= Buffer
.Pointer
;
1362 /* Count number of resources */
1363 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
1365 switch (resource
->Type
)
1367 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1369 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1370 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
1372 NumberOfResources
+= irq_data
->InterruptCount
;
1375 case ACPI_RESOURCE_TYPE_IRQ
:
1377 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1378 NumberOfResources
+= irq_data
->InterruptCount
;
1381 case ACPI_RESOURCE_TYPE_DMA
:
1383 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1384 NumberOfResources
+= dma_data
->ChannelCount
;
1387 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1388 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1389 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1390 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1392 ACPI_RESOURCE_ADDRESS
*res_addr
= (ACPI_RESOURCE_ADDRESS
*) &resource
->Data
;
1393 if (res_addr
->ProducerConsumer
== ACPI_PRODUCER
)
1395 NumberOfResources
++;
1398 case ACPI_RESOURCE_TYPE_MEMORY24
:
1399 case ACPI_RESOURCE_TYPE_MEMORY32
:
1400 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1401 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1402 case ACPI_RESOURCE_TYPE_IO
:
1404 NumberOfResources
++;
1412 resource
= ACPI_NEXT_RESOURCE(resource
);
1415 RequirementsListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
1416 RequirementsList
= ExAllocatePoolWithTag(PagedPool
, RequirementsListSize
, 'RpcA');
1418 if (!RequirementsList
)
1420 ExFreePoolWithTag(Buffer
.Pointer
, 'BpcA');
1421 return STATUS_INSUFFICIENT_RESOURCES
;
1423 RequirementsList
->ListSize
= RequirementsListSize
;
1424 RequirementsList
->InterfaceType
= Internal
;
1425 RequirementsList
->BusNumber
= 0;
1426 RequirementsList
->SlotNumber
= 0; /* Not used by WDM drivers */
1427 RequirementsList
->AlternativeLists
= 1;
1428 RequirementsList
->List
[0].Version
= 1;
1429 RequirementsList
->List
[0].Revision
= 1;
1430 RequirementsList
->List
[0].Count
= NumberOfResources
;
1431 RequirementDescriptor
= RequirementsList
->List
[0].Descriptors
;
1433 /* Fill resources list structure */
1434 resource
= Buffer
.Pointer
;
1435 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
&& resource
->Type
!= ACPI_RESOURCE_TYPE_END_DEPENDENT
)
1437 switch (resource
->Type
)
1439 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1441 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1442 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
1444 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1446 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1447 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1448 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1449 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1450 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1451 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1453 RequirementDescriptor
++;
1457 case ACPI_RESOURCE_TYPE_IRQ
:
1459 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1460 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1462 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1463 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1464 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1465 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1466 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1467 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1469 RequirementDescriptor
++;
1473 case ACPI_RESOURCE_TYPE_DMA
:
1475 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1476 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
1478 RequirementDescriptor
->Type
= CmResourceTypeDma
;
1479 RequirementDescriptor
->Flags
= 0;
1480 switch (dma_data
->Type
)
1482 case ACPI_TYPE_A
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
1483 case ACPI_TYPE_B
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
1484 case ACPI_TYPE_F
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
1486 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
1487 RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
1488 switch (dma_data
->Transfer
)
1490 case ACPI_TRANSFER_8
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
1491 case ACPI_TRANSFER_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
1492 case ACPI_TRANSFER_8_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
1495 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1496 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1497 RequirementDescriptor
->u
.Dma
.MinimumChannel
=
1498 RequirementDescriptor
->u
.Dma
.MaximumChannel
= dma_data
->Channels
[i
];
1499 RequirementDescriptor
++;
1503 case ACPI_RESOURCE_TYPE_IO
:
1505 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
1506 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1507 if (io_data
->IoDecode
== ACPI_DECODE_16
)
1508 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
1510 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
1511 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1512 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1513 RequirementDescriptor
->Type
= CmResourceTypePort
;
1514 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1515 RequirementDescriptor
->u
.Port
.Alignment
= io_data
->Alignment
;
1516 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Minimum
;
1517 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Maximum
+ io_data
->AddressLength
- 1;
1519 RequirementDescriptor
++;
1522 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1524 ACPI_RESOURCE_FIXED_IO
*io_data
= (ACPI_RESOURCE_FIXED_IO
*) &resource
->Data
;
1525 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1526 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1527 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1528 RequirementDescriptor
->Type
= CmResourceTypePort
;
1529 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1530 RequirementDescriptor
->u
.Port
.Alignment
= 1;
1531 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Address
;
1532 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Address
+ io_data
->AddressLength
- 1;
1534 RequirementDescriptor
++;
1537 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1539 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
1540 if (addr16_data
->ProducerConsumer
== ACPI_PRODUCER
)
1542 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1543 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1545 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1546 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1547 RequirementDescriptor
->Flags
= 0;
1548 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr16_data
->Address
.Minimum
;
1549 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr16_data
->Address
.Maximum
+ addr16_data
->Address
.AddressLength
- 1;
1550 RequirementDescriptor
->u
.BusNumber
.Length
= addr16_data
->Address
.AddressLength
;
1552 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1554 RequirementDescriptor
->Type
= CmResourceTypePort
;
1555 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1556 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1557 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1558 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1559 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr16_data
->Address
.Minimum
;
1560 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr16_data
->Address
.Maximum
+ addr16_data
->Address
.AddressLength
- 1;
1561 RequirementDescriptor
->u
.Port
.Length
= addr16_data
->Address
.AddressLength
;
1565 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1566 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1567 RequirementDescriptor
->Flags
= 0;
1568 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1569 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1571 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1572 switch (addr16_data
->Info
.Mem
.Caching
)
1574 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1575 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1576 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1578 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr16_data
->Address
.Minimum
;
1579 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr16_data
->Address
.Maximum
+ addr16_data
->Address
.AddressLength
- 1;
1580 RequirementDescriptor
->u
.Memory
.Length
= addr16_data
->Address
.AddressLength
;
1582 RequirementDescriptor
++;
1585 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1587 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
1588 if (addr32_data
->ProducerConsumer
== ACPI_PRODUCER
)
1590 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1591 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1593 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1594 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1595 RequirementDescriptor
->Flags
= 0;
1596 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr32_data
->Address
.Minimum
;
1597 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr32_data
->Address
.Maximum
+ addr32_data
->Address
.AddressLength
- 1;
1598 RequirementDescriptor
->u
.BusNumber
.Length
= addr32_data
->Address
.AddressLength
;
1600 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1602 RequirementDescriptor
->Type
= CmResourceTypePort
;
1603 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1604 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1605 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1606 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1607 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr32_data
->Address
.Minimum
;
1608 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr32_data
->Address
.Maximum
+ addr32_data
->Address
.AddressLength
- 1;
1609 RequirementDescriptor
->u
.Port
.Length
= addr32_data
->Address
.AddressLength
;
1613 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1614 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1615 RequirementDescriptor
->Flags
= 0;
1616 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1617 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1619 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1620 switch (addr32_data
->Info
.Mem
.Caching
)
1622 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1623 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1624 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1626 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr32_data
->Address
.Minimum
;
1627 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr32_data
->Address
.Maximum
+ addr32_data
->Address
.AddressLength
- 1;
1628 RequirementDescriptor
->u
.Memory
.Length
= addr32_data
->Address
.AddressLength
;
1630 RequirementDescriptor
++;
1633 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1635 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
1636 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1638 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1639 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1641 DPRINT1("64-bit bus address is not supported!\n");
1642 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1643 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1644 RequirementDescriptor
->Flags
= 0;
1645 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Address
.Minimum
;
1646 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1647 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->Address
.AddressLength
;
1649 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1651 RequirementDescriptor
->Type
= CmResourceTypePort
;
1652 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1653 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1654 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1655 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1656 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Address
.Minimum
;
1657 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1658 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->Address
.AddressLength
;
1662 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1663 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1664 RequirementDescriptor
->Flags
= 0;
1665 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1666 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1668 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1669 switch (addr64_data
->Info
.Mem
.Caching
)
1671 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1672 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1673 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1675 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Address
.Minimum
;
1676 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1677 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->Address
.AddressLength
;
1679 RequirementDescriptor
++;
1682 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1684 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
1685 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1687 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1688 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1690 DPRINT1("64-bit bus address is not supported!\n");
1691 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1692 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1693 RequirementDescriptor
->Flags
= 0;
1694 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Address
.Minimum
;
1695 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1696 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->Address
.AddressLength
;
1698 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1700 RequirementDescriptor
->Type
= CmResourceTypePort
;
1701 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1702 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1703 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1704 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1705 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Address
.Minimum
;
1706 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1707 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->Address
.AddressLength
;
1711 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1712 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1713 RequirementDescriptor
->Flags
= 0;
1714 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1715 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1717 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1718 switch (addr64_data
->Info
.Mem
.Caching
)
1720 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1721 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1722 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1724 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Address
.Minimum
;
1725 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Address
.Maximum
+ addr64_data
->Address
.AddressLength
- 1;
1726 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->Address
.AddressLength
;
1728 RequirementDescriptor
++;
1731 case ACPI_RESOURCE_TYPE_MEMORY24
:
1733 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1734 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1735 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1736 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1737 RequirementDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1738 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1739 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1741 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1742 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem24_data
->Minimum
;
1743 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem24_data
->Maximum
+ mem24_data
->AddressLength
- 1;
1744 RequirementDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1746 RequirementDescriptor
++;
1749 case ACPI_RESOURCE_TYPE_MEMORY32
:
1751 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1752 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1753 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1754 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1755 RequirementDescriptor
->Flags
= 0;
1756 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1757 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1759 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1760 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem32_data
->Minimum
;
1761 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem32_data
->Maximum
+ mem32_data
->AddressLength
- 1;
1762 RequirementDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1764 RequirementDescriptor
++;
1767 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1769 ACPI_RESOURCE_FIXED_MEMORY32
*fixedmem32_data
= (ACPI_RESOURCE_FIXED_MEMORY32
*) &resource
->Data
;
1770 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1771 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1772 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1773 RequirementDescriptor
->Flags
= 0;
1774 if (fixedmem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1775 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1777 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1778 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= fixedmem32_data
->Address
;
1779 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= fixedmem32_data
->Address
+ fixedmem32_data
->AddressLength
- 1;
1780 RequirementDescriptor
->u
.Memory
.Length
= fixedmem32_data
->AddressLength
;
1782 RequirementDescriptor
++;
1790 resource
= ACPI_NEXT_RESOURCE(resource
);
1792 ExFreePoolWithTag(Buffer
.Pointer
, 'BpcA');
1794 Irp
->IoStatus
.Information
= (ULONG_PTR
)RequirementsList
;
1796 return STATUS_SUCCESS
;
1800 Bus_PDO_QueryDeviceRelations(
1801 PPDO_DEVICE_DATA DeviceData
,
1805 Routine Description:
1807 The PnP Manager sends this IRP to gather information about
1808 devices with a relationship to the specified device.
1809 Bus drivers must handle this request for TargetDeviceRelation
1810 for their child devices (child PDOs).
1812 If a driver returns relations in response to this IRP,
1813 it allocates a DEVICE_RELATIONS structure from paged
1814 memory containing a count and the appropriate number of
1815 device object pointers. The PnP Manager frees the structure
1816 when it is no longer needed. If a driver replaces a
1817 DEVICE_RELATIONS structure allocated by another driver,
1818 it must free the previous structure.
1820 A driver must reference the PDO of any device that it
1821 reports in this IRP (ObReferenceObject). The PnP Manager
1822 removes the reference when appropriate.
1826 DeviceData - Pointer to the PDO's device extension.
1827 Irp - Pointer to the irp.
1836 PIO_STACK_LOCATION stack
;
1837 PDEVICE_RELATIONS deviceRelations
;
1842 stack
= IoGetCurrentIrpStackLocation (Irp
);
1844 switch (stack
->Parameters
.QueryDeviceRelations
.Type
) {
1846 case TargetDeviceRelation
:
1848 deviceRelations
= (PDEVICE_RELATIONS
) Irp
->IoStatus
.Information
;
1849 if (deviceRelations
) {
1851 // Only PDO can handle this request. Somebody above
1852 // is not playing by rule.
1854 ASSERTMSG("Someone above is handling TargetDeviceRelation", !deviceRelations
);
1857 deviceRelations
= ExAllocatePoolWithTag(PagedPool
,
1858 sizeof(DEVICE_RELATIONS
),
1860 if (!deviceRelations
) {
1861 status
= STATUS_INSUFFICIENT_RESOURCES
;
1866 // There is only one PDO pointer in the structure
1867 // for this relation type. The PnP Manager removes
1868 // the reference to the PDO when the driver or application
1869 // un-registers for notification on the device.
1872 deviceRelations
->Count
= 1;
1873 deviceRelations
->Objects
[0] = DeviceData
->Common
.Self
;
1874 ObReferenceObject(DeviceData
->Common
.Self
);
1876 status
= STATUS_SUCCESS
;
1877 Irp
->IoStatus
.Information
= (ULONG_PTR
) deviceRelations
;
1880 case BusRelations
: // Not handled by PDO
1881 case EjectionRelations
: // optional for PDO
1882 case RemovalRelations
: // // optional for PDO
1884 status
= Irp
->IoStatus
.Status
;
1891 Bus_PDO_QueryBusInformation(
1892 PPDO_DEVICE_DATA DeviceData
,
1896 Routine Description:
1898 The PnP Manager uses this IRP to request the type and
1899 instance number of a device's parent bus. Bus drivers
1900 should handle this request for their child devices (PDOs).
1904 DeviceData - Pointer to the PDO's device extension.
1905 Irp - Pointer to the irp.
1914 PPNP_BUS_INFORMATION busInfo
;
1918 busInfo
= ExAllocatePoolWithTag(PagedPool
,
1919 sizeof(PNP_BUS_INFORMATION
),
1922 if (busInfo
== NULL
) {
1923 return STATUS_INSUFFICIENT_RESOURCES
;
1926 busInfo
->BusTypeGuid
= GUID_ACPI_INTERFACE_STANDARD
;
1928 busInfo
->LegacyBusType
= InternalPowerBus
;
1930 busInfo
->BusNumber
= 0; //fixme
1932 Irp
->IoStatus
.Information
= (ULONG_PTR
)busInfo
;
1934 return STATUS_SUCCESS
;
1939 Bus_GetDeviceCapabilities(
1940 PDEVICE_OBJECT DeviceObject
,
1941 PDEVICE_CAPABILITIES DeviceCapabilities
1944 IO_STATUS_BLOCK ioStatus
;
1947 PDEVICE_OBJECT targetObject
;
1948 PIO_STACK_LOCATION irpStack
;
1954 // Initialize the capabilities that we will send down
1956 RtlZeroMemory( DeviceCapabilities
, sizeof(DEVICE_CAPABILITIES
) );
1957 DeviceCapabilities
->Size
= sizeof(DEVICE_CAPABILITIES
);
1958 DeviceCapabilities
->Version
= 1;
1959 DeviceCapabilities
->Address
= -1;
1960 DeviceCapabilities
->UINumber
= -1;
1963 // Initialize the event
1965 KeInitializeEvent( &pnpEvent
, NotificationEvent
, FALSE
);
1967 targetObject
= IoGetAttachedDeviceReference( DeviceObject
);
1972 pnpIrp
= IoBuildSynchronousFsdRequest(
1981 if (pnpIrp
== NULL
) {
1983 status
= STATUS_INSUFFICIENT_RESOURCES
;
1984 goto GetDeviceCapabilitiesExit
;
1989 // Pnp Irps all begin life as STATUS_NOT_SUPPORTED;
1991 pnpIrp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
1994 // Get the top of stack
1996 irpStack
= IoGetNextIrpStackLocation( pnpIrp
);
1999 // Set the top of stack
2001 RtlZeroMemory( irpStack
, sizeof(IO_STACK_LOCATION
) );
2002 irpStack
->MajorFunction
= IRP_MJ_PNP
;
2003 irpStack
->MinorFunction
= IRP_MN_QUERY_CAPABILITIES
;
2004 irpStack
->Parameters
.DeviceCapabilities
.Capabilities
= DeviceCapabilities
;
2009 status
= IoCallDriver( targetObject
, pnpIrp
);
2010 if (status
== STATUS_PENDING
) {
2013 // Block until the irp comes back.
2014 // Important thing to note here is when you allocate
2015 // the memory for an event in the stack you must do a
2016 // KernelMode wait instead of UserMode to prevent
2017 // the stack from getting paged out.
2020 KeWaitForSingleObject(
2027 status
= ioStatus
.Status
;
2031 GetDeviceCapabilitiesExit
:
2033 // Done with reference
2035 ObDereferenceObject( targetObject
);