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.
168 case IRP_MN_QUERY_CAPABILITIES
:
171 // Return the capabilities of a device, such as whether the device
172 // can be locked or ejected..etc
175 status
= Bus_PDO_QueryDeviceCaps(DeviceData
, Irp
);
179 case IRP_MN_QUERY_ID
:
181 // Query the IDs of the device
182 status
= Bus_PDO_QueryDeviceId(DeviceData
, Irp
);
186 case IRP_MN_QUERY_DEVICE_RELATIONS
:
188 DPRINT("\tQueryDeviceRelation Type: %s\n",DbgDeviceRelationString(\
189 IrpStack
->Parameters
.QueryDeviceRelations
.Type
));
191 status
= Bus_PDO_QueryDeviceRelations(DeviceData
, Irp
);
195 case IRP_MN_QUERY_DEVICE_TEXT
:
197 status
= Bus_PDO_QueryDeviceText(DeviceData
, Irp
);
201 case IRP_MN_QUERY_RESOURCES
:
203 status
= Bus_PDO_QueryResources(DeviceData
, Irp
);
207 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
209 status
= Bus_PDO_QueryResourceRequirements(DeviceData
, Irp
);
213 case IRP_MN_QUERY_BUS_INFORMATION
:
215 status
= Bus_PDO_QueryBusInformation(DeviceData
, Irp
);
219 case IRP_MN_QUERY_INTERFACE
:
221 status
= Bus_PDO_QueryInterface(DeviceData
, Irp
);
226 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
229 // OPTIONAL for bus drivers.
230 // The PnP Manager sends this IRP to a device
231 // stack so filter and function drivers can adjust the
232 // resources required by the device, if appropriate.
237 //case IRP_MN_QUERY_PNP_DEVICE_STATE:
240 // OPTIONAL for bus drivers.
241 // The PnP Manager sends this IRP after the drivers for
242 // a device return success from the IRP_MN_START_DEVICE
243 // request. The PnP Manager also sends this IRP when a
244 // driver for the device calls IoInvalidateDeviceState.
249 //case IRP_MN_READ_CONFIG:
250 //case IRP_MN_WRITE_CONFIG:
253 // Bus drivers for buses with configuration space must handle
254 // this request for their child devices. Our devices don't
255 // have a config space.
260 //case IRP_MN_SET_LOCK:
267 // For PnP requests to the PDO that we do not understand we should
268 // return the IRP WITHOUT setting the status or information fields.
269 // These fields may have already been set by a filter (eg acpi).
270 status
= Irp
->IoStatus
.Status
;
275 Irp
->IoStatus
.Status
= status
;
276 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
282 Bus_PDO_QueryDeviceCaps(
283 PPDO_DEVICE_DATA DeviceData
,
287 PIO_STACK_LOCATION stack
;
288 PDEVICE_CAPABILITIES deviceCapabilities
;
289 struct acpi_device
*device
= NULL
;
294 if (DeviceData
->AcpiHandle
)
295 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
297 stack
= IoGetCurrentIrpStackLocation (Irp
);
302 deviceCapabilities
=stack
->Parameters
.DeviceCapabilities
.Capabilities
;
305 // Set the capabilities.
308 if (deviceCapabilities
->Version
!= 1 ||
309 deviceCapabilities
->Size
< sizeof(DEVICE_CAPABILITIES
))
311 return STATUS_UNSUCCESSFUL
;
314 deviceCapabilities
->D1Latency
= 0;
315 deviceCapabilities
->D2Latency
= 0;
316 deviceCapabilities
->D3Latency
= 0;
318 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
319 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD3
;
320 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD3
;
321 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
323 for (i
= 0; i
< ACPI_D_STATE_COUNT
&& device
; i
++)
325 if (!device
->power
.states
[i
].flags
.valid
)
331 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
335 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD1
;
336 deviceCapabilities
->D1Latency
= device
->power
.states
[i
].latency
;
340 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD2
;
341 deviceCapabilities
->D2Latency
= device
->power
.states
[i
].latency
;
345 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
346 deviceCapabilities
->D3Latency
= device
->power
.states
[i
].latency
;
351 // We can wake the system from D1
352 deviceCapabilities
->DeviceWake
= PowerDeviceD1
;
355 deviceCapabilities
->DeviceD1
=
356 (deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] == PowerDeviceD1
) ? TRUE
: FALSE
;
357 deviceCapabilities
->DeviceD2
=
358 (deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] == PowerDeviceD2
) ? TRUE
: FALSE
;
360 deviceCapabilities
->WakeFromD0
= FALSE
;
361 deviceCapabilities
->WakeFromD1
= TRUE
; //Yes we can
362 deviceCapabilities
->WakeFromD2
= FALSE
;
363 deviceCapabilities
->WakeFromD3
= FALSE
;
367 deviceCapabilities
->LockSupported
= device
->flags
.lockable
;
368 deviceCapabilities
->EjectSupported
= device
->flags
.ejectable
;
369 deviceCapabilities
->HardwareDisabled
= !device
->status
.enabled
&& !device
->status
.functional
;
370 deviceCapabilities
->Removable
= device
->flags
.removable
;
371 deviceCapabilities
->SurpriseRemovalOK
= device
->flags
.suprise_removal_ok
;
372 deviceCapabilities
->UniqueID
= device
->flags
.unique_id
;
373 deviceCapabilities
->NoDisplayInUI
= !device
->status
.show_in_ui
;
374 deviceCapabilities
->Address
= device
->pnp
.bus_address
;
378 (device
->flags
.hardware_id
&&
379 (strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
) ||
380 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
) ||
381 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))))
383 /* Allow ACPI to control the device if it is a lid button,
384 * a thermal zone, a processor, or a fixed feature button */
385 deviceCapabilities
->RawDeviceOK
= TRUE
;
388 deviceCapabilities
->SilentInstall
= FALSE
;
389 deviceCapabilities
->UINumber
= (ULONG
)-1;
391 return STATUS_SUCCESS
;
396 Bus_PDO_QueryDeviceId(
397 PPDO_DEVICE_DATA DeviceData
,
400 PIO_STACK_LOCATION stack
;
404 NTSTATUS status
= STATUS_SUCCESS
;
405 struct acpi_device
*Device
;
409 stack
= IoGetCurrentIrpStackLocation (Irp
);
411 switch (stack
->Parameters
.QueryId
.IdType
) {
413 case BusQueryDeviceID
:
415 /* This is a REG_SZ value */
417 if (DeviceData
->AcpiHandle
)
419 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
421 length
= swprintf(temp
,
423 Device
->pnp
.hardware_id
);
427 /* We know it's a fixed feature button because
428 * these are direct children of the ACPI root device
429 * and therefore have no handle
431 length
= swprintf(temp
,
432 L
"ACPI\\FixedButton");
435 temp
[length
++] = UNICODE_NULL
;
437 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
439 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
442 status
= STATUS_INSUFFICIENT_RESOURCES
;
446 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
447 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
448 DPRINT("BusQueryDeviceID: %ls\n",buffer
);
451 case BusQueryInstanceID
:
453 /* This is a REG_SZ value */
455 /* See comment in BusQueryDeviceID case */
456 if(DeviceData
->AcpiHandle
)
458 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
460 if (Device
->flags
.unique_id
)
461 length
= swprintf(temp
,
463 Device
->pnp
.unique_id
);
465 /* FIXME: Generate unique id! */
466 length
= swprintf(temp
, L
"%ls", L
"0000");
470 /* FIXME: Generate unique id! */
471 length
= swprintf(temp
, L
"%ls", L
"0000");
474 temp
[length
++] = UNICODE_NULL
;
476 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
478 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof (WCHAR
), 'IPCA');
480 status
= STATUS_INSUFFICIENT_RESOURCES
;
484 RtlCopyMemory (buffer
, temp
, length
* sizeof (WCHAR
));
485 DPRINT("BusQueryInstanceID: %ls\n",buffer
);
486 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
489 case BusQueryHardwareIDs
:
491 /* This is a REG_MULTI_SZ value */
493 status
= STATUS_NOT_SUPPORTED
;
495 /* See comment in BusQueryDeviceID case */
496 if (DeviceData
->AcpiHandle
)
498 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
500 if (!Device
->flags
.hardware_id
)
502 /* We don't have the ID to satisfy this request */
506 DPRINT("Device name: %s\n", Device
->pnp
.device_name
);
507 DPRINT("Hardware ID: %s\n", Device
->pnp
.hardware_id
);
509 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
511 length
= ProcessorHardwareIds
.Length
/ sizeof(WCHAR
);
512 src
= ProcessorHardwareIds
.Buffer
;
516 length
+= swprintf(&temp
[length
],
518 Device
->pnp
.hardware_id
);
519 temp
[length
++] = UNICODE_NULL
;
521 length
+= swprintf(&temp
[length
],
523 Device
->pnp
.hardware_id
);
524 temp
[length
++] = UNICODE_NULL
;
525 temp
[length
++] = UNICODE_NULL
;
531 length
+= swprintf(&temp
[length
],
532 L
"ACPI\\FixedButton");
533 temp
[length
++] = UNICODE_NULL
;
535 length
+= swprintf(&temp
[length
],
537 temp
[length
++] = UNICODE_NULL
;
538 temp
[length
++] = UNICODE_NULL
;
542 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
544 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
547 status
= STATUS_INSUFFICIENT_RESOURCES
;
551 RtlCopyMemory (buffer
, src
, length
* sizeof(WCHAR
));
552 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
553 DPRINT("BusQueryHardwareIDs: %ls\n",buffer
);
556 case BusQueryCompatibleIDs
:
558 /* This is a REG_MULTI_SZ value */
560 status
= STATUS_NOT_SUPPORTED
;
562 /* See comment in BusQueryDeviceID case */
563 if (DeviceData
->AcpiHandle
)
565 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
567 if (!Device
->flags
.hardware_id
)
569 /* We don't have the ID to satisfy this request */
573 DPRINT("Device name: %s\n", Device
->pnp
.device_name
);
574 DPRINT("Hardware ID: %s\n", Device
->pnp
.hardware_id
);
576 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
578 length
+= swprintf(&temp
[length
],
580 Device
->pnp
.hardware_id
);
581 temp
[length
++] = UNICODE_NULL
;
583 length
+= swprintf(&temp
[length
],
585 Device
->pnp
.hardware_id
);
586 temp
[length
++] = UNICODE_NULL
;
587 temp
[length
++] = UNICODE_NULL
;
589 else if (Device
->flags
.compatible_ids
)
591 for (i
= 0; i
< Device
->pnp
.cid_list
->Count
; i
++)
593 length
+= swprintf(&temp
[length
],
595 Device
->pnp
.cid_list
->Ids
[i
].String
);
596 temp
[length
++] = UNICODE_NULL
;
598 length
+= swprintf(&temp
[length
],
600 Device
->pnp
.cid_list
->Ids
[i
].String
);
601 temp
[length
++] = UNICODE_NULL
;
604 temp
[length
++] = UNICODE_NULL
;
608 /* No compatible IDs */
612 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
614 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
617 status
= STATUS_INSUFFICIENT_RESOURCES
;
621 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
622 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
623 DPRINT("BusQueryCompatibleIDs: %ls\n",buffer
);
624 status
= STATUS_SUCCESS
;
629 status
= Irp
->IoStatus
.Status
;
635 Bus_PDO_QueryDeviceText(
636 PPDO_DEVICE_DATA DeviceData
,
640 PIO_STACK_LOCATION stack
;
641 NTSTATUS status
= Irp
->IoStatus
.Status
;
644 stack
= IoGetCurrentIrpStackLocation (Irp
);
646 switch (stack
->Parameters
.QueryDeviceText
.DeviceTextType
) {
648 case DeviceTextDescription
:
650 if (!Irp
->IoStatus
.Information
) {
651 if (wcsstr (DeviceData
->HardwareIDs
, L
"PNP000") != 0)
652 Temp
= L
"Programmable interrupt controller";
653 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP010") != 0)
654 Temp
= L
"System timer";
655 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP020") != 0)
656 Temp
= L
"DMA controller";
657 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP03") != 0)
659 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP040") != 0)
660 Temp
= L
"Parallel port";
661 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP05") != 0)
662 Temp
= L
"Serial port";
663 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP06") != 0)
664 Temp
= L
"Disk controller";
665 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP07") != 0)
666 Temp
= L
"Disk controller";
667 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP09") != 0)
668 Temp
= L
"Display adapter";
669 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A0") != 0)
670 Temp
= L
"Bus controller";
671 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0E0") != 0)
672 Temp
= L
"PCMCIA controller";
673 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0F") != 0)
674 Temp
= L
"Mouse device";
675 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP8") != 0)
676 Temp
= L
"Network adapter";
677 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPA0") != 0)
678 Temp
= L
"SCSI controller";
679 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPB0") != 0)
680 Temp
= L
"Multimedia device";
681 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPC00") != 0)
683 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0C") != 0)
684 Temp
= L
"Power Button";
685 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0E") != 0)
686 Temp
= L
"Sleep Button";
687 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0D") != 0)
688 Temp
= L
"Lid Switch";
689 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C09") != 0)
690 Temp
= L
"ACPI Embedded Controller";
691 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0B") != 0)
693 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
694 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0 )
695 Temp
= L
"PCI Root Bridge";
696 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0A") != 0)
697 Temp
= L
"ACPI Battery";
698 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0F") != 0)
699 Temp
= L
"PCI Interrupt Link";
700 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI_PWR") != 0)
701 Temp
= L
"ACPI Power Resource";
702 else if (wcsstr(DeviceData
->HardwareIDs
, L
"Processor") != 0)
704 if (ProcessorNameString
!= NULL
)
705 Temp
= ProcessorNameString
;
709 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ThermalZone") != 0)
710 Temp
= L
"ACPI Thermal Zone";
711 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0002") != 0)
712 Temp
= L
"Smart Battery";
713 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0003") != 0)
714 Temp
= L
"AC Adapter";
715 /* Simply checking if AcpiHandle is NULL eliminates the need to check
716 * for the 4 different names that ACPI knows the fixed feature button as internally
718 else if (!DeviceData
->AcpiHandle
)
719 Temp
= L
"ACPI Fixed Feature Button";
721 Temp
= L
"Other ACPI device";
723 Buffer
= ExAllocatePoolWithTag (PagedPool
, (wcslen(Temp
) + 1) * sizeof(WCHAR
), 'IPCA');
726 status
= STATUS_INSUFFICIENT_RESOURCES
;
730 RtlCopyMemory (Buffer
, Temp
, (wcslen(Temp
) + 1) * sizeof(WCHAR
));
732 DPRINT("\tDeviceTextDescription :%ws\n", Buffer
);
734 Irp
->IoStatus
.Information
= (ULONG_PTR
) Buffer
;
735 status
= STATUS_SUCCESS
;
748 Bus_PDO_QueryResources(
749 PPDO_DEVICE_DATA DeviceData
,
752 ULONG NumberOfResources
= 0;
753 PCM_RESOURCE_LIST ResourceList
;
754 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor
;
755 ACPI_STATUS AcpiStatus
;
757 ACPI_RESOURCE
* resource
;
758 ULONG ResourceListSize
;
761 struct acpi_device
*device
;
763 if (!DeviceData
->AcpiHandle
)
765 return Irp
->IoStatus
.Status
;
768 /* A bus number resource is not included in the list of current resources
769 * for the root PCI bus so we manually query one here and if we find it
770 * we create a resource list and add a bus number descriptor to it */
771 if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
772 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
774 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
776 AcpiStatus
= acpi_evaluate_integer(DeviceData
->AcpiHandle
, "_BBN", NULL
, &BusNumber
);
777 if (AcpiStatus
!= AE_OK
)
780 if (device
->flags
.unique_id
)
782 /* FIXME: Try the unique ID */
788 DPRINT1("Failed to find a bus number\n");
793 DPRINT("Using _BBN for bus number\n");
796 DPRINT("Found PCI root hub: %d\n", BusNumber
);
798 ResourceListSize
= sizeof(CM_RESOURCE_LIST
);
799 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, 'IPCA');
801 return STATUS_INSUFFICIENT_RESOURCES
;
803 ResourceList
->Count
= 1;
804 ResourceList
->List
[0].InterfaceType
= Internal
;
805 ResourceList
->List
[0].BusNumber
= 0;
806 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
807 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
808 ResourceList
->List
[0].PartialResourceList
.Count
= 1;
809 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
811 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
812 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
813 ResourceDescriptor
->u
.BusNumber
.Start
= BusNumber
;
814 ResourceDescriptor
->u
.BusNumber
.Length
= 1;
816 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
817 return STATUS_SUCCESS
;
820 /* Get current resources */
822 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
823 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
826 return Irp
->IoStatus
.Status
;
829 Buffer
.Pointer
= ExAllocatePoolWithTag(PagedPool
, Buffer
.Length
, 'IPCA');
831 return STATUS_INSUFFICIENT_RESOURCES
;
833 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
834 if (!ACPI_SUCCESS(AcpiStatus
))
836 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
838 return STATUS_UNSUCCESSFUL
;
841 resource
= Buffer
.Pointer
;
842 /* Count number of resources */
843 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
845 switch (resource
->Type
)
847 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
849 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
850 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
852 NumberOfResources
+= irq_data
->InterruptCount
;
855 case ACPI_RESOURCE_TYPE_IRQ
:
857 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
858 NumberOfResources
+= irq_data
->InterruptCount
;
861 case ACPI_RESOURCE_TYPE_DMA
:
863 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
864 NumberOfResources
+= dma_data
->ChannelCount
;
867 case ACPI_RESOURCE_TYPE_ADDRESS16
:
868 case ACPI_RESOURCE_TYPE_ADDRESS32
:
869 case ACPI_RESOURCE_TYPE_ADDRESS64
:
870 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
872 ACPI_RESOURCE_ADDRESS
*addr_res
= (ACPI_RESOURCE_ADDRESS
*) &resource
->Data
;
873 if (addr_res
->ProducerConsumer
== ACPI_PRODUCER
)
878 case ACPI_RESOURCE_TYPE_MEMORY24
:
879 case ACPI_RESOURCE_TYPE_MEMORY32
:
880 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
881 case ACPI_RESOURCE_TYPE_FIXED_IO
:
882 case ACPI_RESOURCE_TYPE_IO
:
889 DPRINT1("Unknown resource type: %d\n", resource
->Type
);
893 resource
= ACPI_NEXT_RESOURCE(resource
);
896 /* Allocate memory */
897 ResourceListSize
= sizeof(CM_RESOURCE_LIST
) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
898 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, 'IPCA');
902 ExFreePoolWithTag(Buffer
.Pointer
, 'IPCA');
903 return STATUS_INSUFFICIENT_RESOURCES
;
905 ResourceList
->Count
= 1;
906 ResourceList
->List
[0].InterfaceType
= Internal
; /* FIXME */
907 ResourceList
->List
[0].BusNumber
= 0; /* We're the only ACPI bus device in the system */
908 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
909 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
910 ResourceList
->List
[0].PartialResourceList
.Count
= NumberOfResources
;
911 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
913 /* Fill resources list structure */
914 resource
= Buffer
.Pointer
;
915 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
917 switch (resource
->Type
)
919 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
921 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
922 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
924 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
926 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
928 ResourceDescriptor
->ShareDisposition
=
929 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
930 ResourceDescriptor
->Flags
=
931 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
932 ResourceDescriptor
->u
.Interrupt
.Level
=
933 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
934 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
936 ResourceDescriptor
++;
940 case ACPI_RESOURCE_TYPE_IRQ
:
942 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
943 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
945 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
947 ResourceDescriptor
->ShareDisposition
=
948 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
949 ResourceDescriptor
->Flags
=
950 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
951 ResourceDescriptor
->u
.Interrupt
.Level
=
952 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
953 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
955 ResourceDescriptor
++;
959 case ACPI_RESOURCE_TYPE_DMA
:
961 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
962 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
964 ResourceDescriptor
->Type
= CmResourceTypeDma
;
965 ResourceDescriptor
->Flags
= 0;
966 switch (dma_data
->Type
)
968 case ACPI_TYPE_A
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
969 case ACPI_TYPE_B
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
970 case ACPI_TYPE_F
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
972 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
973 ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
974 switch (dma_data
->Transfer
)
976 case ACPI_TRANSFER_8
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
977 case ACPI_TRANSFER_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
978 case ACPI_TRANSFER_8_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
980 ResourceDescriptor
->u
.Dma
.Channel
= dma_data
->Channels
[i
];
982 ResourceDescriptor
++;
986 case ACPI_RESOURCE_TYPE_IO
:
988 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
989 ResourceDescriptor
->Type
= CmResourceTypePort
;
990 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
991 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
992 if (io_data
->IoDecode
== ACPI_DECODE_16
)
993 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
995 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
996 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Minimum
;
997 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
999 ResourceDescriptor
++;
1002 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1004 ACPI_RESOURCE_FIXED_IO
*io_data
= (ACPI_RESOURCE_FIXED_IO
*) &resource
->Data
;
1005 ResourceDescriptor
->Type
= CmResourceTypePort
;
1006 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1007 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1008 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Address
;
1009 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1011 ResourceDescriptor
++;
1014 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1016 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
1017 if (addr16_data
->ProducerConsumer
== ACPI_PRODUCER
)
1019 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1021 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1022 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1023 ResourceDescriptor
->Flags
= 0;
1024 ResourceDescriptor
->u
.BusNumber
.Start
= addr16_data
->Minimum
;
1025 ResourceDescriptor
->u
.BusNumber
.Length
= addr16_data
->AddressLength
;
1027 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1029 ResourceDescriptor
->Type
= CmResourceTypePort
;
1030 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1031 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1032 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1033 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1034 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr16_data
->Minimum
;
1035 ResourceDescriptor
->u
.Port
.Length
= addr16_data
->AddressLength
;
1039 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1040 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1041 ResourceDescriptor
->Flags
= 0;
1042 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1043 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1045 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1046 switch (addr16_data
->Info
.Mem
.Caching
)
1048 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1049 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1050 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1052 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr16_data
->Minimum
;
1053 ResourceDescriptor
->u
.Memory
.Length
= addr16_data
->AddressLength
;
1055 ResourceDescriptor
++;
1058 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1060 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
1061 if (addr32_data
->ProducerConsumer
== ACPI_PRODUCER
)
1063 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1065 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1066 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1067 ResourceDescriptor
->Flags
= 0;
1068 ResourceDescriptor
->u
.BusNumber
.Start
= addr32_data
->Minimum
;
1069 ResourceDescriptor
->u
.BusNumber
.Length
= addr32_data
->AddressLength
;
1071 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1073 ResourceDescriptor
->Type
= CmResourceTypePort
;
1074 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1075 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1076 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1077 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1078 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr32_data
->Minimum
;
1079 ResourceDescriptor
->u
.Port
.Length
= addr32_data
->AddressLength
;
1083 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1084 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1085 ResourceDescriptor
->Flags
= 0;
1086 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1087 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1089 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1090 switch (addr32_data
->Info
.Mem
.Caching
)
1092 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1093 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1094 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1096 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr32_data
->Minimum
;
1097 ResourceDescriptor
->u
.Memory
.Length
= addr32_data
->AddressLength
;
1099 ResourceDescriptor
++;
1102 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1104 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
1105 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1107 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1109 DPRINT1("64-bit bus address is not supported!\n");
1110 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1111 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1112 ResourceDescriptor
->Flags
= 0;
1113 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Minimum
;
1114 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1116 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1118 ResourceDescriptor
->Type
= CmResourceTypePort
;
1119 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1120 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1121 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1122 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1123 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Minimum
;
1124 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1128 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1129 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1130 ResourceDescriptor
->Flags
= 0;
1131 if (addr64_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 (addr64_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
= addr64_data
->Minimum
;
1142 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1144 ResourceDescriptor
++;
1147 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1149 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_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
->Minimum
;
1159 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->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
->Minimum
;
1169 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->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
->Minimum
;
1187 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1189 ResourceDescriptor
++;
1192 case ACPI_RESOURCE_TYPE_MEMORY24
:
1194 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1195 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1196 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1197 ResourceDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1198 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1199 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1201 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1202 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem24_data
->Minimum
;
1203 ResourceDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1205 ResourceDescriptor
++;
1208 case ACPI_RESOURCE_TYPE_MEMORY32
:
1210 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1211 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1212 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1213 ResourceDescriptor
->Flags
= 0;
1214 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1215 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1217 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1218 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem32_data
->Minimum
;
1219 ResourceDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1221 ResourceDescriptor
++;
1224 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1226 ACPI_RESOURCE_FIXED_MEMORY32
*memfixed32_data
= (ACPI_RESOURCE_FIXED_MEMORY32
*) &resource
->Data
;
1227 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1228 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1229 ResourceDescriptor
->Flags
= 0;
1230 if (memfixed32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1231 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1233 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1234 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= memfixed32_data
->Address
;
1235 ResourceDescriptor
->u
.Memory
.Length
= memfixed32_data
->AddressLength
;
1237 ResourceDescriptor
++;
1245 resource
= ACPI_NEXT_RESOURCE(resource
);
1248 ExFreePoolWithTag(Buffer
.Pointer
, 'IPCA');
1249 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
1250 return STATUS_SUCCESS
;
1254 Bus_PDO_QueryResourceRequirements(
1255 PPDO_DEVICE_DATA DeviceData
,
1258 ULONG NumberOfResources
= 0;
1259 ACPI_STATUS AcpiStatus
;
1261 ACPI_RESOURCE
* resource
;
1262 ULONG i
, RequirementsListSize
;
1263 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
;
1264 PIO_RESOURCE_DESCRIPTOR RequirementDescriptor
;
1265 BOOLEAN CurrentRes
= FALSE
;
1269 if (!DeviceData
->AcpiHandle
)
1271 return Irp
->IoStatus
.Status
;
1274 /* Handle the PCI root manually */
1275 if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
1276 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
1278 return Irp
->IoStatus
.Status
;
1281 /* Get current resources */
1286 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1288 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1289 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
1295 return Irp
->IoStatus
.Status
;
1301 Buffer
.Pointer
= ExAllocatePoolWithTag(PagedPool
, Buffer
.Length
, 'IPCA');
1302 if (!Buffer
.Pointer
)
1303 return STATUS_INSUFFICIENT_RESOURCES
;
1306 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1308 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1309 if (!ACPI_SUCCESS(AcpiStatus
))
1311 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
1313 return STATUS_UNSUCCESSFUL
;
1316 resource
= Buffer
.Pointer
;
1317 /* Count number of resources */
1318 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
1320 switch (resource
->Type
)
1322 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1324 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1325 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
1327 NumberOfResources
+= irq_data
->InterruptCount
;
1330 case ACPI_RESOURCE_TYPE_IRQ
:
1332 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1333 NumberOfResources
+= irq_data
->InterruptCount
;
1336 case ACPI_RESOURCE_TYPE_DMA
:
1338 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1339 NumberOfResources
+= dma_data
->ChannelCount
;
1342 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1343 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1344 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1345 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1347 ACPI_RESOURCE_ADDRESS
*res_addr
= (ACPI_RESOURCE_ADDRESS
*) &resource
->Data
;
1348 if (res_addr
->ProducerConsumer
== ACPI_PRODUCER
)
1350 NumberOfResources
++;
1353 case ACPI_RESOURCE_TYPE_MEMORY24
:
1354 case ACPI_RESOURCE_TYPE_MEMORY32
:
1355 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1356 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1357 case ACPI_RESOURCE_TYPE_IO
:
1359 NumberOfResources
++;
1367 resource
= ACPI_NEXT_RESOURCE(resource
);
1370 RequirementsListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
1371 RequirementsList
= (PIO_RESOURCE_REQUIREMENTS_LIST
)ExAllocatePoolWithTag(PagedPool
, RequirementsListSize
, 'IPCA');
1373 if (!RequirementsList
)
1375 ExFreePoolWithTag(Buffer
.Pointer
, 'IPCA');
1376 return STATUS_INSUFFICIENT_RESOURCES
;
1378 RequirementsList
->ListSize
= RequirementsListSize
;
1379 RequirementsList
->InterfaceType
= Internal
;
1380 RequirementsList
->BusNumber
= 0;
1381 RequirementsList
->SlotNumber
= 0; /* Not used by WDM drivers */
1382 RequirementsList
->AlternativeLists
= 1;
1383 RequirementsList
->List
[0].Version
= 1;
1384 RequirementsList
->List
[0].Revision
= 1;
1385 RequirementsList
->List
[0].Count
= NumberOfResources
;
1386 RequirementDescriptor
= RequirementsList
->List
[0].Descriptors
;
1388 /* Fill resources list structure */
1389 resource
= Buffer
.Pointer
;
1390 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
&& resource
->Type
!= ACPI_RESOURCE_TYPE_END_DEPENDENT
)
1392 switch (resource
->Type
)
1394 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1396 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1397 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
1399 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1401 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1402 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1403 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1404 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1405 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1406 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1408 RequirementDescriptor
++;
1412 case ACPI_RESOURCE_TYPE_IRQ
:
1414 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1415 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1417 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1418 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1419 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1420 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1421 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1422 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1424 RequirementDescriptor
++;
1428 case ACPI_RESOURCE_TYPE_DMA
:
1430 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1431 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
1433 RequirementDescriptor
->Type
= CmResourceTypeDma
;
1434 RequirementDescriptor
->Flags
= 0;
1435 switch (dma_data
->Type
)
1437 case ACPI_TYPE_A
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
1438 case ACPI_TYPE_B
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
1439 case ACPI_TYPE_F
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
1441 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
1442 RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
1443 switch (dma_data
->Transfer
)
1445 case ACPI_TRANSFER_8
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
1446 case ACPI_TRANSFER_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
1447 case ACPI_TRANSFER_8_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
1450 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1451 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1452 RequirementDescriptor
->u
.Dma
.MinimumChannel
=
1453 RequirementDescriptor
->u
.Dma
.MaximumChannel
= dma_data
->Channels
[i
];
1454 RequirementDescriptor
++;
1458 case ACPI_RESOURCE_TYPE_IO
:
1460 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
1461 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1462 if (io_data
->IoDecode
== ACPI_DECODE_16
)
1463 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
1465 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
1466 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1467 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1468 RequirementDescriptor
->Type
= CmResourceTypePort
;
1469 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1470 RequirementDescriptor
->u
.Port
.Alignment
= io_data
->Alignment
;
1471 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Minimum
;
1472 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Maximum
+ io_data
->AddressLength
- 1;
1474 RequirementDescriptor
++;
1477 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1479 ACPI_RESOURCE_FIXED_IO
*io_data
= (ACPI_RESOURCE_FIXED_IO
*) &resource
->Data
;
1480 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1481 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1482 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1483 RequirementDescriptor
->Type
= CmResourceTypePort
;
1484 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1485 RequirementDescriptor
->u
.Port
.Alignment
= 1;
1486 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Address
;
1487 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Address
+ io_data
->AddressLength
- 1;
1489 RequirementDescriptor
++;
1492 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1494 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
1495 if (addr16_data
->ProducerConsumer
== ACPI_PRODUCER
)
1497 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1498 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1500 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1501 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1502 RequirementDescriptor
->Flags
= 0;
1503 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr16_data
->Minimum
;
1504 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr16_data
->Maximum
+ addr16_data
->AddressLength
- 1;
1505 RequirementDescriptor
->u
.BusNumber
.Length
= addr16_data
->AddressLength
;
1507 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1509 RequirementDescriptor
->Type
= CmResourceTypePort
;
1510 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1511 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1512 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1513 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1514 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr16_data
->Minimum
;
1515 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr16_data
->Maximum
+ addr16_data
->AddressLength
- 1;
1516 RequirementDescriptor
->u
.Port
.Length
= addr16_data
->AddressLength
;
1520 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1521 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1522 RequirementDescriptor
->Flags
= 0;
1523 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1524 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1526 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1527 switch (addr16_data
->Info
.Mem
.Caching
)
1529 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1530 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1531 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1533 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr16_data
->Minimum
;
1534 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr16_data
->Maximum
+ addr16_data
->AddressLength
- 1;
1535 RequirementDescriptor
->u
.Memory
.Length
= addr16_data
->AddressLength
;
1537 RequirementDescriptor
++;
1540 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1542 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
1543 if (addr32_data
->ProducerConsumer
== ACPI_PRODUCER
)
1545 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1546 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1548 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1549 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1550 RequirementDescriptor
->Flags
= 0;
1551 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr32_data
->Minimum
;
1552 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr32_data
->Maximum
+ addr32_data
->AddressLength
- 1;
1553 RequirementDescriptor
->u
.BusNumber
.Length
= addr32_data
->AddressLength
;
1555 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1557 RequirementDescriptor
->Type
= CmResourceTypePort
;
1558 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1559 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1560 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1561 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1562 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr32_data
->Minimum
;
1563 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr32_data
->Maximum
+ addr32_data
->AddressLength
- 1;
1564 RequirementDescriptor
->u
.Port
.Length
= addr32_data
->AddressLength
;
1568 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1569 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1570 RequirementDescriptor
->Flags
= 0;
1571 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1572 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1574 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1575 switch (addr32_data
->Info
.Mem
.Caching
)
1577 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1578 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1579 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1581 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr32_data
->Minimum
;
1582 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr32_data
->Maximum
+ addr32_data
->AddressLength
- 1;
1583 RequirementDescriptor
->u
.Memory
.Length
= addr32_data
->AddressLength
;
1585 RequirementDescriptor
++;
1588 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1590 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
1591 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1593 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1594 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1596 DPRINT1("64-bit bus address is not supported!\n");
1597 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1598 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1599 RequirementDescriptor
->Flags
= 0;
1600 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Minimum
;
1601 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1602 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1604 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1606 RequirementDescriptor
->Type
= CmResourceTypePort
;
1607 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1608 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1609 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1610 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1611 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1612 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1613 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1617 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1618 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1619 RequirementDescriptor
->Flags
= 0;
1620 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1621 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1623 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1624 switch (addr64_data
->Info
.Mem
.Caching
)
1626 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1627 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1628 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1630 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1631 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1632 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1634 RequirementDescriptor
++;
1637 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1639 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
1640 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1642 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1643 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1645 DPRINT1("64-bit bus address is not supported!\n");
1646 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1647 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1648 RequirementDescriptor
->Flags
= 0;
1649 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Minimum
;
1650 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1651 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1653 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1655 RequirementDescriptor
->Type
= CmResourceTypePort
;
1656 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1657 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1658 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1659 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1660 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1661 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1662 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1666 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1667 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1668 RequirementDescriptor
->Flags
= 0;
1669 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1670 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1672 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1673 switch (addr64_data
->Info
.Mem
.Caching
)
1675 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1676 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1677 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1679 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1680 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1681 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1683 RequirementDescriptor
++;
1686 case ACPI_RESOURCE_TYPE_MEMORY24
:
1688 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1689 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1690 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1691 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1692 RequirementDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1693 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1694 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1696 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1697 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem24_data
->Minimum
;
1698 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem24_data
->Maximum
+ mem24_data
->AddressLength
- 1;
1699 RequirementDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1701 RequirementDescriptor
++;
1704 case ACPI_RESOURCE_TYPE_MEMORY32
:
1706 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1707 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1708 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1709 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1710 RequirementDescriptor
->Flags
= 0;
1711 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1712 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1714 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1715 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem32_data
->Minimum
;
1716 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem32_data
->Maximum
+ mem32_data
->AddressLength
- 1;
1717 RequirementDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1719 RequirementDescriptor
++;
1722 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1724 ACPI_RESOURCE_FIXED_MEMORY32
*fixedmem32_data
= (ACPI_RESOURCE_FIXED_MEMORY32
*) &resource
->Data
;
1725 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1726 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1727 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1728 RequirementDescriptor
->Flags
= 0;
1729 if (fixedmem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1730 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1732 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1733 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= fixedmem32_data
->Address
;
1734 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= fixedmem32_data
->Address
+ fixedmem32_data
->AddressLength
- 1;
1735 RequirementDescriptor
->u
.Memory
.Length
= fixedmem32_data
->AddressLength
;
1737 RequirementDescriptor
++;
1745 resource
= ACPI_NEXT_RESOURCE(resource
);
1747 ExFreePoolWithTag(Buffer
.Pointer
, 'IPCA');
1749 Irp
->IoStatus
.Information
= (ULONG_PTR
)RequirementsList
;
1751 return STATUS_SUCCESS
;
1755 Bus_PDO_QueryDeviceRelations(
1756 PPDO_DEVICE_DATA DeviceData
,
1760 Routine Description:
1762 The PnP Manager sends this IRP to gather information about
1763 devices with a relationship to the specified device.
1764 Bus drivers must handle this request for TargetDeviceRelation
1765 for their child devices (child PDOs).
1767 If a driver returns relations in response to this IRP,
1768 it allocates a DEVICE_RELATIONS structure from paged
1769 memory containing a count and the appropriate number of
1770 device object pointers. The PnP Manager frees the structure
1771 when it is no longer needed. If a driver replaces a
1772 DEVICE_RELATIONS structure allocated by another driver,
1773 it must free the previous structure.
1775 A driver must reference the PDO of any device that it
1776 reports in this IRP (ObReferenceObject). The PnP Manager
1777 removes the reference when appropriate.
1781 DeviceData - Pointer to the PDO's device extension.
1782 Irp - Pointer to the irp.
1791 PIO_STACK_LOCATION stack
;
1792 PDEVICE_RELATIONS deviceRelations
;
1797 stack
= IoGetCurrentIrpStackLocation (Irp
);
1799 switch (stack
->Parameters
.QueryDeviceRelations
.Type
) {
1801 case TargetDeviceRelation
:
1803 deviceRelations
= (PDEVICE_RELATIONS
) Irp
->IoStatus
.Information
;
1804 if (deviceRelations
) {
1806 // Only PDO can handle this request. Somebody above
1807 // is not playing by rule.
1809 ASSERTMSG("Someone above is handling TargetDeviceRelation", !deviceRelations
);
1812 deviceRelations
= (PDEVICE_RELATIONS
)
1813 ExAllocatePoolWithTag (PagedPool
,
1814 sizeof(DEVICE_RELATIONS
),
1816 if (!deviceRelations
) {
1817 status
= STATUS_INSUFFICIENT_RESOURCES
;
1822 // There is only one PDO pointer in the structure
1823 // for this relation type. The PnP Manager removes
1824 // the reference to the PDO when the driver or application
1825 // un-registers for notification on the device.
1828 deviceRelations
->Count
= 1;
1829 deviceRelations
->Objects
[0] = DeviceData
->Common
.Self
;
1830 ObReferenceObject(DeviceData
->Common
.Self
);
1832 status
= STATUS_SUCCESS
;
1833 Irp
->IoStatus
.Information
= (ULONG_PTR
) deviceRelations
;
1836 case BusRelations
: // Not handled by PDO
1837 case EjectionRelations
: // optional for PDO
1838 case RemovalRelations
: // // optional for PDO
1840 status
= Irp
->IoStatus
.Status
;
1847 Bus_PDO_QueryBusInformation(
1848 PPDO_DEVICE_DATA DeviceData
,
1852 Routine Description:
1854 The PnP Manager uses this IRP to request the type and
1855 instance number of a device's parent bus. Bus drivers
1856 should handle this request for their child devices (PDOs).
1860 DeviceData - Pointer to the PDO's device extension.
1861 Irp - Pointer to the irp.
1870 PPNP_BUS_INFORMATION busInfo
;
1874 busInfo
= ExAllocatePoolWithTag (PagedPool
, sizeof(PNP_BUS_INFORMATION
),
1877 if (busInfo
== NULL
) {
1878 return STATUS_INSUFFICIENT_RESOURCES
;
1881 busInfo
->BusTypeGuid
= GUID_ACPI_INTERFACE_STANDARD
;
1883 busInfo
->LegacyBusType
= InternalPowerBus
;
1885 busInfo
->BusNumber
= 0; //fixme
1887 Irp
->IoStatus
.Information
= (ULONG_PTR
)busInfo
;
1889 return STATUS_SUCCESS
;
1894 Bus_GetDeviceCapabilities(
1895 PDEVICE_OBJECT DeviceObject
,
1896 PDEVICE_CAPABILITIES DeviceCapabilities
1899 IO_STATUS_BLOCK ioStatus
;
1902 PDEVICE_OBJECT targetObject
;
1903 PIO_STACK_LOCATION irpStack
;
1909 // Initialize the capabilities that we will send down
1911 RtlZeroMemory( DeviceCapabilities
, sizeof(DEVICE_CAPABILITIES
) );
1912 DeviceCapabilities
->Size
= sizeof(DEVICE_CAPABILITIES
);
1913 DeviceCapabilities
->Version
= 1;
1914 DeviceCapabilities
->Address
= -1;
1915 DeviceCapabilities
->UINumber
= -1;
1918 // Initialize the event
1920 KeInitializeEvent( &pnpEvent
, NotificationEvent
, FALSE
);
1922 targetObject
= IoGetAttachedDeviceReference( DeviceObject
);
1927 pnpIrp
= IoBuildSynchronousFsdRequest(
1936 if (pnpIrp
== NULL
) {
1938 status
= STATUS_INSUFFICIENT_RESOURCES
;
1939 goto GetDeviceCapabilitiesExit
;
1944 // Pnp Irps all begin life as STATUS_NOT_SUPPORTED;
1946 pnpIrp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
1949 // Get the top of stack
1951 irpStack
= IoGetNextIrpStackLocation( pnpIrp
);
1954 // Set the top of stack
1956 RtlZeroMemory( irpStack
, sizeof(IO_STACK_LOCATION
) );
1957 irpStack
->MajorFunction
= IRP_MJ_PNP
;
1958 irpStack
->MinorFunction
= IRP_MN_QUERY_CAPABILITIES
;
1959 irpStack
->Parameters
.DeviceCapabilities
.Capabilities
= DeviceCapabilities
;
1964 status
= IoCallDriver( targetObject
, pnpIrp
);
1965 if (status
== STATUS_PENDING
) {
1968 // Block until the irp comes back.
1969 // Important thing to note here is when you allocate
1970 // the memory for an event in the stack you must do a
1971 // KernelMode wait instead of UserMode to prevent
1972 // the stack from getting paged out.
1975 KeWaitForSingleObject(
1982 status
= ioStatus
.Status
;
1986 GetDeviceCapabilitiesExit
:
1988 // Done with reference
1990 ObDereferenceObject( targetObject
);