9 #include <acpi_drivers.h>
18 #pragma alloc_text (PAGE, Bus_PDO_PnP)
19 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceCaps)
20 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceId)
21 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceText)
22 #pragma alloc_text (PAGE, Bus_PDO_QueryResources)
23 #pragma alloc_text (PAGE, Bus_PDO_QueryResourceRequirements)
24 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceRelations)
25 #pragma alloc_text (PAGE, Bus_PDO_QueryBusInformation)
26 #pragma alloc_text (PAGE, Bus_GetDeviceCapabilities)
31 PDEVICE_OBJECT DeviceObject
,
33 PIO_STACK_LOCATION IrpStack
,
34 PPDO_DEVICE_DATA DeviceData
39 struct acpi_device
*device
= NULL
;
43 if (DeviceData
->AcpiHandle
)
44 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
47 // NB: Because we are a bus enumerator, we have no one to whom we could
48 // defer these irps. Therefore we do not pass them down but merely
52 switch (IrpStack
->MinorFunction
) {
54 case IRP_MN_START_DEVICE
:
56 // Here we do what ever initialization and ``turning on'' that is
57 // required to allow others to access this device.
58 // Power up the device.
60 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
61 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D0
)))
63 DPRINT1("Device %x failed to start!\n", DeviceData
->AcpiHandle
);
64 status
= STATUS_UNSUCCESSFUL
;
68 DeviceData
->InterfaceName
.Length
= 0;
69 status
= STATUS_SUCCESS
;
73 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
74 &GUID_DEVICE_SYS_BUTTON
,
76 &DeviceData
->InterfaceName
);
78 else if (device
->flags
.hardware_id
&&
79 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
))
81 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
82 &GUID_DEVICE_THERMAL_ZONE
,
84 &DeviceData
->InterfaceName
);
86 else if (device
->flags
.hardware_id
&&
87 strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
))
89 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
92 &DeviceData
->InterfaceName
);
94 else if (device
->flags
.hardware_id
&&
95 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))
97 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
98 &GUID_DEVICE_PROCESSOR
,
100 &DeviceData
->InterfaceName
);
103 /* Failure to register an interface is not a fatal failure so don't return a failure status */
104 if (NT_SUCCESS(status
) && DeviceData
->InterfaceName
.Length
!= 0)
105 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, TRUE
);
107 state
.DeviceState
= PowerDeviceD0
;
108 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
109 DeviceData
->Common
.DevicePowerState
= PowerDeviceD0
;
110 SET_NEW_PNP_STATE(DeviceData
->Common
, Started
);
111 status
= STATUS_SUCCESS
;
114 case IRP_MN_STOP_DEVICE
:
116 if (DeviceData
->InterfaceName
.Length
!= 0)
117 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, FALSE
);
120 // Here we shut down the device and give up and unmap any resources
121 // we acquired for the device.
123 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
124 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D3
)))
126 DPRINT1("Device %x failed to stop!\n", DeviceData
->AcpiHandle
);
127 status
= STATUS_UNSUCCESSFUL
;
131 state
.DeviceState
= PowerDeviceD3
;
132 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
133 DeviceData
->Common
.DevicePowerState
= PowerDeviceD3
;
134 SET_NEW_PNP_STATE(DeviceData
->Common
, Stopped
);
135 status
= STATUS_SUCCESS
;
139 case IRP_MN_QUERY_STOP_DEVICE
:
142 // No reason here why we can't stop the device.
143 // If there were a reason we should speak now, because answering success
144 // here may result in a stop device irp.
147 SET_NEW_PNP_STATE(DeviceData
->Common
, StopPending
);
148 status
= STATUS_SUCCESS
;
151 case IRP_MN_CANCEL_STOP_DEVICE
:
154 // The stop was canceled. Whatever state we set, or resources we put
155 // on hold in anticipation of the forthcoming STOP device IRP should be
156 // put back to normal. Someone, in the long list of concerned parties,
157 // has failed the stop device query.
161 // First check to see whether you have received cancel-stop
162 // without first receiving a query-stop. This could happen if someone
163 // above us fails a query-stop and passes down the subsequent
167 if (StopPending
== DeviceData
->Common
.DevicePnPState
)
170 // We did receive a query-stop, so restore.
172 RESTORE_PREVIOUS_PNP_STATE(DeviceData
->Common
);
174 status
= STATUS_SUCCESS
;// We must not fail this IRP.
176 case IRP_MN_QUERY_CAPABILITIES
:
179 // Return the capabilities of a device, such as whether the device
180 // can be locked or ejected..etc
183 status
= Bus_PDO_QueryDeviceCaps(DeviceData
, Irp
);
187 case IRP_MN_QUERY_ID
:
189 // Query the IDs of the device
190 status
= Bus_PDO_QueryDeviceId(DeviceData
, Irp
);
194 case IRP_MN_QUERY_DEVICE_RELATIONS
:
196 DPRINT("\tQueryDeviceRelation Type: %s\n",DbgDeviceRelationString(\
197 IrpStack
->Parameters
.QueryDeviceRelations
.Type
));
199 status
= Bus_PDO_QueryDeviceRelations(DeviceData
, Irp
);
203 case IRP_MN_QUERY_DEVICE_TEXT
:
205 status
= Bus_PDO_QueryDeviceText(DeviceData
, Irp
);
209 case IRP_MN_QUERY_RESOURCES
:
211 status
= Bus_PDO_QueryResources(DeviceData
, Irp
);
215 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
217 status
= Bus_PDO_QueryResourceRequirements(DeviceData
, Irp
);
221 case IRP_MN_QUERY_BUS_INFORMATION
:
223 status
= Bus_PDO_QueryBusInformation(DeviceData
, Irp
);
227 case IRP_MN_QUERY_INTERFACE
:
229 status
= Bus_PDO_QueryInterface(DeviceData
, Irp
);
234 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
237 // OPTIONAL for bus drivers.
238 // The PnP Manager sends this IRP to a device
239 // stack so filter and function drivers can adjust the
240 // resources required by the device, if appropriate.
245 //case IRP_MN_QUERY_PNP_DEVICE_STATE:
248 // OPTIONAL for bus drivers.
249 // The PnP Manager sends this IRP after the drivers for
250 // a device return success from the IRP_MN_START_DEVICE
251 // request. The PnP Manager also sends this IRP when a
252 // driver for the device calls IoInvalidateDeviceState.
257 //case IRP_MN_READ_CONFIG:
258 //case IRP_MN_WRITE_CONFIG:
261 // Bus drivers for buses with configuration space must handle
262 // this request for their child devices. Our devices don't
263 // have a config space.
268 //case IRP_MN_SET_LOCK:
275 // For PnP requests to the PDO that we do not understand we should
276 // return the IRP WITHOUT setting the status or information fields.
277 // These fields may have already been set by a filter (eg acpi).
278 status
= Irp
->IoStatus
.Status
;
283 Irp
->IoStatus
.Status
= status
;
284 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
290 Bus_PDO_QueryDeviceCaps(
291 PPDO_DEVICE_DATA DeviceData
,
295 PIO_STACK_LOCATION stack
;
296 PDEVICE_CAPABILITIES deviceCapabilities
;
297 struct acpi_device
*device
= NULL
;
302 if (DeviceData
->AcpiHandle
)
303 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
305 stack
= IoGetCurrentIrpStackLocation (Irp
);
310 deviceCapabilities
=stack
->Parameters
.DeviceCapabilities
.Capabilities
;
313 // Set the capabilities.
316 if (deviceCapabilities
->Version
!= 1 ||
317 deviceCapabilities
->Size
< sizeof(DEVICE_CAPABILITIES
))
319 return STATUS_UNSUCCESSFUL
;
322 deviceCapabilities
->D1Latency
= 0;
323 deviceCapabilities
->D2Latency
= 0;
324 deviceCapabilities
->D3Latency
= 0;
326 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
327 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD3
;
328 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD3
;
329 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
331 for (i
= 0; i
< ACPI_D_STATE_COUNT
&& device
; i
++)
333 if (!device
->power
.states
[i
].flags
.valid
)
339 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
343 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD1
;
344 deviceCapabilities
->D1Latency
= device
->power
.states
[i
].latency
;
348 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD2
;
349 deviceCapabilities
->D2Latency
= device
->power
.states
[i
].latency
;
353 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
354 deviceCapabilities
->D3Latency
= device
->power
.states
[i
].latency
;
359 // We can wake the system from D1
360 deviceCapabilities
->DeviceWake
= PowerDeviceD1
;
363 deviceCapabilities
->DeviceD1
=
364 (deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] == PowerDeviceD1
) ? TRUE
: FALSE
;
365 deviceCapabilities
->DeviceD2
=
366 (deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] == PowerDeviceD2
) ? TRUE
: FALSE
;
368 deviceCapabilities
->WakeFromD0
= FALSE
;
369 deviceCapabilities
->WakeFromD1
= TRUE
; //Yes we can
370 deviceCapabilities
->WakeFromD2
= FALSE
;
371 deviceCapabilities
->WakeFromD3
= FALSE
;
375 deviceCapabilities
->LockSupported
= device
->flags
.lockable
;
376 deviceCapabilities
->EjectSupported
= device
->flags
.ejectable
;
377 deviceCapabilities
->HardwareDisabled
= !device
->status
.enabled
&& !device
->status
.functional
;
378 deviceCapabilities
->Removable
= device
->flags
.removable
;
379 deviceCapabilities
->SurpriseRemovalOK
= device
->flags
.suprise_removal_ok
;
380 deviceCapabilities
->UniqueID
= device
->flags
.unique_id
;
381 deviceCapabilities
->NoDisplayInUI
= !device
->status
.show_in_ui
;
382 deviceCapabilities
->Address
= device
->pnp
.bus_address
;
386 (device
->flags
.hardware_id
&&
387 (strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
) ||
388 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
) ||
389 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))))
391 /* Allow ACPI to control the device if it is a lid button,
392 * a thermal zone, a processor, or a fixed feature button */
393 deviceCapabilities
->RawDeviceOK
= TRUE
;
396 deviceCapabilities
->SilentInstall
= FALSE
;
397 deviceCapabilities
->UINumber
= (ULONG
)-1;
399 return STATUS_SUCCESS
;
404 Bus_PDO_QueryDeviceId(
405 PPDO_DEVICE_DATA DeviceData
,
408 PIO_STACK_LOCATION stack
;
412 NTSTATUS status
= STATUS_SUCCESS
;
413 struct acpi_device
*Device
;
417 stack
= IoGetCurrentIrpStackLocation (Irp
);
419 switch (stack
->Parameters
.QueryId
.IdType
) {
421 case BusQueryDeviceID
:
423 /* This is a REG_SZ value */
425 if (DeviceData
->AcpiHandle
)
427 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
429 length
= swprintf(temp
,
431 Device
->pnp
.hardware_id
);
435 /* We know it's a fixed feature button because
436 * these are direct children of the ACPI root device
437 * and therefore have no handle
439 length
= swprintf(temp
,
440 L
"ACPI\\FixedButton");
443 temp
[length
++] = UNICODE_NULL
;
445 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
447 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
450 status
= STATUS_INSUFFICIENT_RESOURCES
;
454 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
455 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
456 DPRINT("BusQueryDeviceID: %ls\n",buffer
);
459 case BusQueryInstanceID
:
461 /* This is a REG_SZ value */
463 /* See comment in BusQueryDeviceID case */
464 if(DeviceData
->AcpiHandle
)
466 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
468 if (Device
->flags
.unique_id
)
469 length
= swprintf(temp
,
471 Device
->pnp
.unique_id
);
473 /* FIXME: Generate unique id! */
474 length
= swprintf(temp
, L
"%ls", L
"0000");
478 /* FIXME: Generate unique id! */
479 length
= swprintf(temp
, L
"%ls", L
"0000");
482 temp
[length
++] = UNICODE_NULL
;
484 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
486 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof (WCHAR
), 'IPCA');
488 status
= STATUS_INSUFFICIENT_RESOURCES
;
492 RtlCopyMemory (buffer
, temp
, length
* sizeof (WCHAR
));
493 DPRINT("BusQueryInstanceID: %ls\n",buffer
);
494 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
497 case BusQueryHardwareIDs
:
499 /* This is a REG_MULTI_SZ value */
502 /* See comment in BusQueryDeviceID case */
503 if (DeviceData
->AcpiHandle
)
505 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
507 DPRINT1("Device name: %s\n", Device
->pnp
.device_name
);
508 DPRINT1("Hardware ID: %s\n", Device
->pnp
.hardware_id
);
510 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
512 length
= ProcessorHardwareIds
.Length
/ sizeof(WCHAR
);
513 src
= ProcessorHardwareIds
.Buffer
;
517 length
+= swprintf(&temp
[length
],
519 Device
->pnp
.hardware_id
);
520 temp
[length
++] = UNICODE_NULL
;
522 length
+= swprintf(&temp
[length
],
524 Device
->pnp
.hardware_id
);
525 temp
[length
++] = UNICODE_NULL
;
526 temp
[length
++] = UNICODE_NULL
;
532 length
+= swprintf(&temp
[length
],
533 L
"ACPI\\FixedButton");
534 temp
[length
++] = UNICODE_NULL
;
536 length
+= swprintf(&temp
[length
],
538 temp
[length
++] = UNICODE_NULL
;
539 temp
[length
++] = UNICODE_NULL
;
543 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
545 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
548 status
= STATUS_INSUFFICIENT_RESOURCES
;
552 RtlCopyMemory (buffer
, src
, length
* sizeof(WCHAR
));
553 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
554 DPRINT("BusQueryHardwareIDs: %ls\n",buffer
);
557 case BusQueryCompatibleIDs
:
559 /* This is a REG_MULTI_SZ value */
561 status
= STATUS_NOT_SUPPORTED
;
563 /* See comment in BusQueryDeviceID case */
564 if (DeviceData
->AcpiHandle
)
566 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
568 if (strcmp(Device
->pnp
.hardware_id
, "Processor") == 0)
570 DPRINT("Device name: %s\n", Device
->pnp
.device_name
);
571 DPRINT("Hardware ID: %s\n", Device
->pnp
.hardware_id
);
573 length
+= swprintf(&temp
[length
],
575 Device
->pnp
.hardware_id
);
576 temp
[length
++] = UNICODE_NULL
;
578 length
+= swprintf(&temp
[length
],
580 Device
->pnp
.hardware_id
);
581 temp
[length
++] = UNICODE_NULL
;
582 temp
[length
++] = UNICODE_NULL
;
584 NT_ASSERT(length
* sizeof(WCHAR
) <= sizeof(temp
));
586 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
589 status
= STATUS_INSUFFICIENT_RESOURCES
;
593 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
594 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
595 DPRINT("BusQueryHardwareIDs: %ls\n",buffer
);
596 status
= STATUS_SUCCESS
;
602 status
= Irp
->IoStatus
.Status
;
608 Bus_PDO_QueryDeviceText(
609 PPDO_DEVICE_DATA DeviceData
,
613 PIO_STACK_LOCATION stack
;
614 NTSTATUS status
= Irp
->IoStatus
.Status
;
617 stack
= IoGetCurrentIrpStackLocation (Irp
);
619 switch (stack
->Parameters
.QueryDeviceText
.DeviceTextType
) {
621 case DeviceTextDescription
:
623 if (!Irp
->IoStatus
.Information
) {
624 if (wcsstr (DeviceData
->HardwareIDs
, L
"PNP000") != 0)
625 Temp
= L
"Programmable interrupt controller";
626 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP010") != 0)
627 Temp
= L
"System timer";
628 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP020") != 0)
629 Temp
= L
"DMA controller";
630 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP03") != 0)
632 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP040") != 0)
633 Temp
= L
"Parallel port";
634 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP05") != 0)
635 Temp
= L
"Serial port";
636 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP06") != 0)
637 Temp
= L
"Disk controller";
638 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP07") != 0)
639 Temp
= L
"Disk controller";
640 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP09") != 0)
641 Temp
= L
"Display adapter";
642 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A0") != 0)
643 Temp
= L
"Bus controller";
644 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0E0") != 0)
645 Temp
= L
"PCMCIA controller";
646 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0F") != 0)
647 Temp
= L
"Mouse device";
648 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP8") != 0)
649 Temp
= L
"Network adapter";
650 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPA0") != 0)
651 Temp
= L
"SCSI controller";
652 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPB0") != 0)
653 Temp
= L
"Multimedia device";
654 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPC00") != 0)
656 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0C") != 0)
657 Temp
= L
"Power Button";
658 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0E") != 0)
659 Temp
= L
"Sleep Button";
660 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0D") != 0)
661 Temp
= L
"Lid Switch";
662 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C09") != 0)
663 Temp
= L
"ACPI Embedded Controller";
664 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0B") != 0)
666 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
667 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0 )
668 Temp
= L
"PCI Root Bridge";
669 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0A") != 0)
670 Temp
= L
"ACPI Battery";
671 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0F") != 0)
672 Temp
= L
"PCI Interrupt Link";
673 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI_PWR") != 0)
674 Temp
= L
"ACPI Power Resource";
675 else if (wcsstr(DeviceData
->HardwareIDs
, L
"Processor") != 0)
677 if (ProcessorNameString
!= NULL
)
678 Temp
= ProcessorNameString
;
682 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ThermalZone") != 0)
683 Temp
= L
"ACPI Thermal Zone";
684 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0002") != 0)
685 Temp
= L
"Smart Battery";
686 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0003") != 0)
687 Temp
= L
"AC Adapter";
688 /* Simply checking if AcpiHandle is NULL eliminates the need to check
689 * for the 4 different names that ACPI knows the fixed feature button as internally
691 else if (!DeviceData
->AcpiHandle
)
692 Temp
= L
"ACPI Fixed Feature Button";
694 Temp
= L
"Other ACPI device";
696 Buffer
= ExAllocatePoolWithTag (PagedPool
, (wcslen(Temp
) + 1) * sizeof(WCHAR
), 'IPCA');
699 status
= STATUS_INSUFFICIENT_RESOURCES
;
703 RtlCopyMemory (Buffer
, Temp
, (wcslen(Temp
) + 1) * sizeof(WCHAR
));
705 DPRINT("\tDeviceTextDescription :%ws\n", Buffer
);
707 Irp
->IoStatus
.Information
= (ULONG_PTR
) Buffer
;
708 status
= STATUS_SUCCESS
;
721 Bus_PDO_QueryResources(
722 PPDO_DEVICE_DATA DeviceData
,
725 ULONG NumberOfResources
= 0;
726 PCM_RESOURCE_LIST ResourceList
;
727 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor
;
728 ACPI_STATUS AcpiStatus
;
730 ACPI_RESOURCE
* resource
;
731 ULONG ResourceListSize
;
734 struct acpi_device
*device
;
736 if (!DeviceData
->AcpiHandle
)
738 return Irp
->IoStatus
.Status
;
741 /* A bus number resource is not included in the list of current resources
742 * for the root PCI bus so we manually query one here and if we find it
743 * we create a resource list and add a bus number descriptor to it */
744 if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
745 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
747 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
749 AcpiStatus
= acpi_evaluate_integer(DeviceData
->AcpiHandle
, "_BBN", NULL
, &BusNumber
);
750 if (AcpiStatus
!= AE_OK
)
753 if (device
->flags
.unique_id
)
755 /* FIXME: Try the unique ID */
761 DPRINT1("Failed to find a bus number\n");
766 DPRINT1("Using _BBN for bus number\n");
769 DPRINT1("Found PCI root hub: %d\n", BusNumber
);
771 ResourceListSize
= sizeof(CM_RESOURCE_LIST
);
772 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, 'IPCA');
774 return STATUS_INSUFFICIENT_RESOURCES
;
776 ResourceList
->Count
= 1;
777 ResourceList
->List
[0].InterfaceType
= Internal
;
778 ResourceList
->List
[0].BusNumber
= 0;
779 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
780 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
781 ResourceList
->List
[0].PartialResourceList
.Count
= 1;
782 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
784 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
785 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
786 ResourceDescriptor
->u
.BusNumber
.Start
= BusNumber
;
787 ResourceDescriptor
->u
.BusNumber
.Length
= 1;
789 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
790 return STATUS_SUCCESS
;
793 /* Get current resources */
795 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
796 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
799 return Irp
->IoStatus
.Status
;
802 Buffer
.Pointer
= ExAllocatePoolWithTag(PagedPool
, Buffer
.Length
, 'IPCA');
804 return STATUS_INSUFFICIENT_RESOURCES
;
806 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
807 if (!ACPI_SUCCESS(AcpiStatus
))
809 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
811 return STATUS_UNSUCCESSFUL
;
814 resource
= Buffer
.Pointer
;
815 /* Count number of resources */
816 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
818 switch (resource
->Type
)
820 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
822 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
823 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
825 NumberOfResources
+= irq_data
->InterruptCount
;
828 case ACPI_RESOURCE_TYPE_IRQ
:
830 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
831 NumberOfResources
+= irq_data
->InterruptCount
;
834 case ACPI_RESOURCE_TYPE_DMA
:
836 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
837 NumberOfResources
+= dma_data
->ChannelCount
;
840 case ACPI_RESOURCE_TYPE_ADDRESS16
:
841 case ACPI_RESOURCE_TYPE_ADDRESS32
:
842 case ACPI_RESOURCE_TYPE_ADDRESS64
:
843 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
845 ACPI_RESOURCE_ADDRESS
*addr_res
= (ACPI_RESOURCE_ADDRESS
*) &resource
->Data
;
846 if (addr_res
->ProducerConsumer
== ACPI_PRODUCER
)
851 case ACPI_RESOURCE_TYPE_MEMORY24
:
852 case ACPI_RESOURCE_TYPE_MEMORY32
:
853 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
854 case ACPI_RESOURCE_TYPE_FIXED_IO
:
855 case ACPI_RESOURCE_TYPE_IO
:
862 DPRINT1("Unknown resource type: %d\n", resource
->Type
);
866 resource
= ACPI_NEXT_RESOURCE(resource
);
869 /* Allocate memory */
870 ResourceListSize
= sizeof(CM_RESOURCE_LIST
) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
871 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePoolWithTag(PagedPool
, ResourceListSize
, 'IPCA');
875 ExFreePoolWithTag(Buffer
.Pointer
, 'IPCA');
876 return STATUS_INSUFFICIENT_RESOURCES
;
878 ResourceList
->Count
= 1;
879 ResourceList
->List
[0].InterfaceType
= Internal
; /* FIXME */
880 ResourceList
->List
[0].BusNumber
= 0; /* We're the only ACPI bus device in the system */
881 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
882 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
883 ResourceList
->List
[0].PartialResourceList
.Count
= NumberOfResources
;
884 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
886 /* Fill resources list structure */
887 resource
= Buffer
.Pointer
;
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 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
899 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
901 ResourceDescriptor
->ShareDisposition
=
902 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
903 ResourceDescriptor
->Flags
=
904 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
905 ResourceDescriptor
->u
.Interrupt
.Level
=
906 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
907 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
909 ResourceDescriptor
++;
913 case ACPI_RESOURCE_TYPE_IRQ
:
915 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
916 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
918 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
920 ResourceDescriptor
->ShareDisposition
=
921 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
922 ResourceDescriptor
->Flags
=
923 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
924 ResourceDescriptor
->u
.Interrupt
.Level
=
925 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
926 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
928 ResourceDescriptor
++;
932 case ACPI_RESOURCE_TYPE_DMA
:
934 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
935 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
937 ResourceDescriptor
->Type
= CmResourceTypeDma
;
938 ResourceDescriptor
->Flags
= 0;
939 switch (dma_data
->Type
)
941 case ACPI_TYPE_A
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
942 case ACPI_TYPE_B
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
943 case ACPI_TYPE_F
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
945 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
946 ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
947 switch (dma_data
->Transfer
)
949 case ACPI_TRANSFER_8
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
950 case ACPI_TRANSFER_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
951 case ACPI_TRANSFER_8_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
953 ResourceDescriptor
->u
.Dma
.Channel
= dma_data
->Channels
[i
];
955 ResourceDescriptor
++;
959 case ACPI_RESOURCE_TYPE_IO
:
961 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
962 ResourceDescriptor
->Type
= CmResourceTypePort
;
963 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
964 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
965 if (io_data
->IoDecode
== ACPI_DECODE_16
)
966 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
968 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
969 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Minimum
;
970 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
972 ResourceDescriptor
++;
975 case ACPI_RESOURCE_TYPE_FIXED_IO
:
977 ACPI_RESOURCE_FIXED_IO
*io_data
= (ACPI_RESOURCE_FIXED_IO
*) &resource
->Data
;
978 ResourceDescriptor
->Type
= CmResourceTypePort
;
979 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
980 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
981 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Address
;
982 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
984 ResourceDescriptor
++;
987 case ACPI_RESOURCE_TYPE_ADDRESS16
:
989 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
990 if (addr16_data
->ProducerConsumer
== ACPI_PRODUCER
)
992 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
994 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
995 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
996 ResourceDescriptor
->Flags
= 0;
997 ResourceDescriptor
->u
.BusNumber
.Start
= addr16_data
->Minimum
;
998 ResourceDescriptor
->u
.BusNumber
.Length
= addr16_data
->AddressLength
;
1000 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1002 ResourceDescriptor
->Type
= CmResourceTypePort
;
1003 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1004 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1005 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1006 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1007 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr16_data
->Minimum
;
1008 ResourceDescriptor
->u
.Port
.Length
= addr16_data
->AddressLength
;
1012 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1013 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1014 ResourceDescriptor
->Flags
= 0;
1015 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1016 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1018 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1019 switch (addr16_data
->Info
.Mem
.Caching
)
1021 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1022 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1023 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1025 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr16_data
->Minimum
;
1026 ResourceDescriptor
->u
.Memory
.Length
= addr16_data
->AddressLength
;
1028 ResourceDescriptor
++;
1031 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1033 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
1034 if (addr32_data
->ProducerConsumer
== ACPI_PRODUCER
)
1036 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1038 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1039 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1040 ResourceDescriptor
->Flags
= 0;
1041 ResourceDescriptor
->u
.BusNumber
.Start
= addr32_data
->Minimum
;
1042 ResourceDescriptor
->u
.BusNumber
.Length
= addr32_data
->AddressLength
;
1044 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1046 ResourceDescriptor
->Type
= CmResourceTypePort
;
1047 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1048 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1049 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1050 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1051 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr32_data
->Minimum
;
1052 ResourceDescriptor
->u
.Port
.Length
= addr32_data
->AddressLength
;
1056 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1057 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1058 ResourceDescriptor
->Flags
= 0;
1059 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1060 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1062 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1063 switch (addr32_data
->Info
.Mem
.Caching
)
1065 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1066 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1067 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1069 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr32_data
->Minimum
;
1070 ResourceDescriptor
->u
.Memory
.Length
= addr32_data
->AddressLength
;
1072 ResourceDescriptor
++;
1075 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1077 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
1078 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1080 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1082 DPRINT1("64-bit bus address is not supported!\n");
1083 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1084 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1085 ResourceDescriptor
->Flags
= 0;
1086 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Minimum
;
1087 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1089 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1091 ResourceDescriptor
->Type
= CmResourceTypePort
;
1092 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1093 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1094 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1095 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1096 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Minimum
;
1097 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1101 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1102 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1103 ResourceDescriptor
->Flags
= 0;
1104 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1105 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1107 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1108 switch (addr64_data
->Info
.Mem
.Caching
)
1110 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1111 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1112 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1114 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Minimum
;
1115 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1117 ResourceDescriptor
++;
1120 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1122 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
1123 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1125 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1127 DPRINT1("64-bit bus address is not supported!\n");
1128 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1129 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1130 ResourceDescriptor
->Flags
= 0;
1131 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Minimum
;
1132 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1134 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1136 ResourceDescriptor
->Type
= CmResourceTypePort
;
1137 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1138 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1139 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1140 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1141 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Minimum
;
1142 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1146 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1147 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1148 ResourceDescriptor
->Flags
= 0;
1149 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1150 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1152 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1153 switch (addr64_data
->Info
.Mem
.Caching
)
1155 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1156 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1157 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1159 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Minimum
;
1160 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1162 ResourceDescriptor
++;
1165 case ACPI_RESOURCE_TYPE_MEMORY24
:
1167 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1168 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1169 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1170 ResourceDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1171 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1172 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1174 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1175 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem24_data
->Minimum
;
1176 ResourceDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1178 ResourceDescriptor
++;
1181 case ACPI_RESOURCE_TYPE_MEMORY32
:
1183 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1184 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1185 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1186 ResourceDescriptor
->Flags
= 0;
1187 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1188 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1190 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1191 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem32_data
->Minimum
;
1192 ResourceDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1194 ResourceDescriptor
++;
1197 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1199 ACPI_RESOURCE_FIXED_MEMORY32
*memfixed32_data
= (ACPI_RESOURCE_FIXED_MEMORY32
*) &resource
->Data
;
1200 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1201 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1202 ResourceDescriptor
->Flags
= 0;
1203 if (memfixed32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1204 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1206 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1207 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= memfixed32_data
->Address
;
1208 ResourceDescriptor
->u
.Memory
.Length
= memfixed32_data
->AddressLength
;
1210 ResourceDescriptor
++;
1218 resource
= ACPI_NEXT_RESOURCE(resource
);
1221 ExFreePoolWithTag(Buffer
.Pointer
, 'IPCA');
1222 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
1223 return STATUS_SUCCESS
;
1227 Bus_PDO_QueryResourceRequirements(
1228 PPDO_DEVICE_DATA DeviceData
,
1231 ULONG NumberOfResources
= 0;
1232 ACPI_STATUS AcpiStatus
;
1234 ACPI_RESOURCE
* resource
;
1235 ULONG i
, RequirementsListSize
;
1236 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
;
1237 PIO_RESOURCE_DESCRIPTOR RequirementDescriptor
;
1238 BOOLEAN CurrentRes
= FALSE
;
1242 if (!DeviceData
->AcpiHandle
)
1244 return Irp
->IoStatus
.Status
;
1247 /* Handle the PCI root manually */
1248 if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0 ||
1249 wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A08") != 0)
1251 return Irp
->IoStatus
.Status
;
1254 /* Get current resources */
1259 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1261 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1262 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
1268 return Irp
->IoStatus
.Status
;
1274 Buffer
.Pointer
= ExAllocatePoolWithTag(PagedPool
, Buffer
.Length
, 'IPCA');
1275 if (!Buffer
.Pointer
)
1276 return STATUS_INSUFFICIENT_RESOURCES
;
1279 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1281 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1282 if (!ACPI_SUCCESS(AcpiStatus
))
1284 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
1286 return STATUS_UNSUCCESSFUL
;
1289 resource
= Buffer
.Pointer
;
1290 /* Count number of resources */
1291 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
1293 switch (resource
->Type
)
1295 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1297 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1298 if (irq_data
->ProducerConsumer
== ACPI_PRODUCER
)
1300 NumberOfResources
+= irq_data
->InterruptCount
;
1303 case ACPI_RESOURCE_TYPE_IRQ
:
1305 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1306 NumberOfResources
+= irq_data
->InterruptCount
;
1309 case ACPI_RESOURCE_TYPE_DMA
:
1311 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1312 NumberOfResources
+= dma_data
->ChannelCount
;
1315 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1316 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1317 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1318 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1320 ACPI_RESOURCE_ADDRESS
*res_addr
= (ACPI_RESOURCE_ADDRESS
*) &resource
->Data
;
1321 if (res_addr
->ProducerConsumer
== ACPI_PRODUCER
)
1323 NumberOfResources
++;
1326 case ACPI_RESOURCE_TYPE_MEMORY24
:
1327 case ACPI_RESOURCE_TYPE_MEMORY32
:
1328 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1329 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1330 case ACPI_RESOURCE_TYPE_IO
:
1332 NumberOfResources
++;
1340 resource
= ACPI_NEXT_RESOURCE(resource
);
1343 RequirementsListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
1344 RequirementsList
= (PIO_RESOURCE_REQUIREMENTS_LIST
)ExAllocatePoolWithTag(PagedPool
, RequirementsListSize
, 'IPCA');
1346 if (!RequirementsList
)
1348 ExFreePoolWithTag(Buffer
.Pointer
, 'IPCA');
1349 return STATUS_INSUFFICIENT_RESOURCES
;
1351 RequirementsList
->ListSize
= RequirementsListSize
;
1352 RequirementsList
->InterfaceType
= Internal
;
1353 RequirementsList
->BusNumber
= 0;
1354 RequirementsList
->SlotNumber
= 0; /* Not used by WDM drivers */
1355 RequirementsList
->AlternativeLists
= 1;
1356 RequirementsList
->List
[0].Version
= 1;
1357 RequirementsList
->List
[0].Revision
= 1;
1358 RequirementsList
->List
[0].Count
= NumberOfResources
;
1359 RequirementDescriptor
= RequirementsList
->List
[0].Descriptors
;
1361 /* Fill resources list structure */
1362 resource
= Buffer
.Pointer
;
1363 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
&& resource
->Type
!= ACPI_RESOURCE_TYPE_END_DEPENDENT
)
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 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1374 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1375 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1376 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1377 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1378 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1379 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1381 RequirementDescriptor
++;
1385 case ACPI_RESOURCE_TYPE_IRQ
:
1387 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1388 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1390 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1391 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1392 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1393 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1394 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1395 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1397 RequirementDescriptor
++;
1401 case ACPI_RESOURCE_TYPE_DMA
:
1403 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1404 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
1406 RequirementDescriptor
->Type
= CmResourceTypeDma
;
1407 RequirementDescriptor
->Flags
= 0;
1408 switch (dma_data
->Type
)
1410 case ACPI_TYPE_A
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
1411 case ACPI_TYPE_B
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
1412 case ACPI_TYPE_F
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
1414 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
1415 RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
1416 switch (dma_data
->Transfer
)
1418 case ACPI_TRANSFER_8
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
1419 case ACPI_TRANSFER_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
1420 case ACPI_TRANSFER_8_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
1423 RequirementDescriptor
->Option
= (i
== 0) ? IO_RESOURCE_PREFERRED
: IO_RESOURCE_ALTERNATIVE
;
1424 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1425 RequirementDescriptor
->u
.Dma
.MinimumChannel
=
1426 RequirementDescriptor
->u
.Dma
.MaximumChannel
= dma_data
->Channels
[i
];
1427 RequirementDescriptor
++;
1431 case ACPI_RESOURCE_TYPE_IO
:
1433 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
1434 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1435 if (io_data
->IoDecode
== ACPI_DECODE_16
)
1436 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
1438 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
1439 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1440 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1441 RequirementDescriptor
->Type
= CmResourceTypePort
;
1442 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1443 RequirementDescriptor
->u
.Port
.Alignment
= io_data
->Alignment
;
1444 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Minimum
;
1445 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Maximum
+ io_data
->AddressLength
- 1;
1447 RequirementDescriptor
++;
1450 case ACPI_RESOURCE_TYPE_FIXED_IO
:
1452 ACPI_RESOURCE_FIXED_IO
*io_data
= (ACPI_RESOURCE_FIXED_IO
*) &resource
->Data
;
1453 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1454 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1455 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1456 RequirementDescriptor
->Type
= CmResourceTypePort
;
1457 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1458 RequirementDescriptor
->u
.Port
.Alignment
= 1;
1459 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Address
;
1460 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Address
+ io_data
->AddressLength
- 1;
1462 RequirementDescriptor
++;
1465 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1467 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
1468 if (addr16_data
->ProducerConsumer
== ACPI_PRODUCER
)
1470 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1471 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1473 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1474 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1475 RequirementDescriptor
->Flags
= 0;
1476 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr16_data
->Minimum
;
1477 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr16_data
->Maximum
+ addr16_data
->AddressLength
- 1;
1478 RequirementDescriptor
->u
.BusNumber
.Length
= addr16_data
->AddressLength
;
1480 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1482 RequirementDescriptor
->Type
= CmResourceTypePort
;
1483 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1484 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1485 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1486 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1487 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr16_data
->Minimum
;
1488 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr16_data
->Maximum
+ addr16_data
->AddressLength
- 1;
1489 RequirementDescriptor
->u
.Port
.Length
= addr16_data
->AddressLength
;
1493 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1494 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1495 RequirementDescriptor
->Flags
= 0;
1496 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1497 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1499 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1500 switch (addr16_data
->Info
.Mem
.Caching
)
1502 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1503 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1504 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1506 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr16_data
->Minimum
;
1507 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr16_data
->Maximum
+ addr16_data
->AddressLength
- 1;
1508 RequirementDescriptor
->u
.Memory
.Length
= addr16_data
->AddressLength
;
1510 RequirementDescriptor
++;
1513 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1515 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
1516 if (addr32_data
->ProducerConsumer
== ACPI_PRODUCER
)
1518 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1519 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1521 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1522 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1523 RequirementDescriptor
->Flags
= 0;
1524 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr32_data
->Minimum
;
1525 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr32_data
->Maximum
+ addr32_data
->AddressLength
- 1;
1526 RequirementDescriptor
->u
.BusNumber
.Length
= addr32_data
->AddressLength
;
1528 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1530 RequirementDescriptor
->Type
= CmResourceTypePort
;
1531 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1532 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1533 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1534 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1535 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr32_data
->Minimum
;
1536 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr32_data
->Maximum
+ addr32_data
->AddressLength
- 1;
1537 RequirementDescriptor
->u
.Port
.Length
= addr32_data
->AddressLength
;
1541 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1542 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1543 RequirementDescriptor
->Flags
= 0;
1544 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1545 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1547 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1548 switch (addr32_data
->Info
.Mem
.Caching
)
1550 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1551 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1552 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1554 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr32_data
->Minimum
;
1555 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr32_data
->Maximum
+ addr32_data
->AddressLength
- 1;
1556 RequirementDescriptor
->u
.Memory
.Length
= addr32_data
->AddressLength
;
1558 RequirementDescriptor
++;
1561 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1563 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
1564 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1566 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1567 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1569 DPRINT1("64-bit bus address is not supported!\n");
1570 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1571 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1572 RequirementDescriptor
->Flags
= 0;
1573 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Minimum
;
1574 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1575 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1577 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1579 RequirementDescriptor
->Type
= CmResourceTypePort
;
1580 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1581 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1582 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1583 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1584 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1585 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1586 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1590 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1591 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1592 RequirementDescriptor
->Flags
= 0;
1593 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1594 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1596 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1597 switch (addr64_data
->Info
.Mem
.Caching
)
1599 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1600 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1601 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1603 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1604 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1605 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1607 RequirementDescriptor
++;
1610 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1612 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
1613 if (addr64_data
->ProducerConsumer
== ACPI_PRODUCER
)
1615 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1616 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1618 DPRINT1("64-bit bus address is not supported!\n");
1619 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1620 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1621 RequirementDescriptor
->Flags
= 0;
1622 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Minimum
;
1623 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1624 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1626 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1628 RequirementDescriptor
->Type
= CmResourceTypePort
;
1629 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1630 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1631 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1632 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1633 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1634 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1635 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1639 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1640 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1641 RequirementDescriptor
->Flags
= 0;
1642 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1643 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1645 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1646 switch (addr64_data
->Info
.Mem
.Caching
)
1648 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1649 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1650 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1652 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1653 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
+ addr64_data
->AddressLength
- 1;
1654 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1656 RequirementDescriptor
++;
1659 case ACPI_RESOURCE_TYPE_MEMORY24
:
1661 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1662 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1663 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1664 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1665 RequirementDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1666 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1667 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1669 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1670 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem24_data
->Minimum
;
1671 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem24_data
->Maximum
+ mem24_data
->AddressLength
- 1;
1672 RequirementDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1674 RequirementDescriptor
++;
1677 case ACPI_RESOURCE_TYPE_MEMORY32
:
1679 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1680 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1681 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1682 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1683 RequirementDescriptor
->Flags
= 0;
1684 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1685 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1687 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1688 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem32_data
->Minimum
;
1689 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem32_data
->Maximum
+ mem32_data
->AddressLength
- 1;
1690 RequirementDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1692 RequirementDescriptor
++;
1695 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1697 ACPI_RESOURCE_FIXED_MEMORY32
*fixedmem32_data
= (ACPI_RESOURCE_FIXED_MEMORY32
*) &resource
->Data
;
1698 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1699 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1700 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1701 RequirementDescriptor
->Flags
= 0;
1702 if (fixedmem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1703 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1705 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1706 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= fixedmem32_data
->Address
;
1707 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= fixedmem32_data
->Address
+ fixedmem32_data
->AddressLength
- 1;
1708 RequirementDescriptor
->u
.Memory
.Length
= fixedmem32_data
->AddressLength
;
1710 RequirementDescriptor
++;
1718 resource
= ACPI_NEXT_RESOURCE(resource
);
1720 ExFreePoolWithTag(Buffer
.Pointer
, 'IPCA');
1722 Irp
->IoStatus
.Information
= (ULONG_PTR
)RequirementsList
;
1724 return STATUS_SUCCESS
;
1728 Bus_PDO_QueryDeviceRelations(
1729 PPDO_DEVICE_DATA DeviceData
,
1733 Routine Description:
1735 The PnP Manager sends this IRP to gather information about
1736 devices with a relationship to the specified device.
1737 Bus drivers must handle this request for TargetDeviceRelation
1738 for their child devices (child PDOs).
1740 If a driver returns relations in response to this IRP,
1741 it allocates a DEVICE_RELATIONS structure from paged
1742 memory containing a count and the appropriate number of
1743 device object pointers. The PnP Manager frees the structure
1744 when it is no longer needed. If a driver replaces a
1745 DEVICE_RELATIONS structure allocated by another driver,
1746 it must free the previous structure.
1748 A driver must reference the PDO of any device that it
1749 reports in this IRP (ObReferenceObject). The PnP Manager
1750 removes the reference when appropriate.
1754 DeviceData - Pointer to the PDO's device extension.
1755 Irp - Pointer to the irp.
1764 PIO_STACK_LOCATION stack
;
1765 PDEVICE_RELATIONS deviceRelations
;
1770 stack
= IoGetCurrentIrpStackLocation (Irp
);
1772 switch (stack
->Parameters
.QueryDeviceRelations
.Type
) {
1774 case TargetDeviceRelation
:
1776 deviceRelations
= (PDEVICE_RELATIONS
) Irp
->IoStatus
.Information
;
1777 if (deviceRelations
) {
1779 // Only PDO can handle this request. Somebody above
1780 // is not playing by rule.
1782 ASSERTMSG("Someone above is handling TargetDeviceRelation", !deviceRelations
);
1785 deviceRelations
= (PDEVICE_RELATIONS
)
1786 ExAllocatePoolWithTag (PagedPool
,
1787 sizeof(DEVICE_RELATIONS
),
1789 if (!deviceRelations
) {
1790 status
= STATUS_INSUFFICIENT_RESOURCES
;
1795 // There is only one PDO pointer in the structure
1796 // for this relation type. The PnP Manager removes
1797 // the reference to the PDO when the driver or application
1798 // un-registers for notification on the device.
1801 deviceRelations
->Count
= 1;
1802 deviceRelations
->Objects
[0] = DeviceData
->Common
.Self
;
1803 ObReferenceObject(DeviceData
->Common
.Self
);
1805 status
= STATUS_SUCCESS
;
1806 Irp
->IoStatus
.Information
= (ULONG_PTR
) deviceRelations
;
1809 case BusRelations
: // Not handled by PDO
1810 case EjectionRelations
: // optional for PDO
1811 case RemovalRelations
: // // optional for PDO
1813 status
= Irp
->IoStatus
.Status
;
1820 Bus_PDO_QueryBusInformation(
1821 PPDO_DEVICE_DATA DeviceData
,
1825 Routine Description:
1827 The PnP Manager uses this IRP to request the type and
1828 instance number of a device's parent bus. Bus drivers
1829 should handle this request for their child devices (PDOs).
1833 DeviceData - Pointer to the PDO's device extension.
1834 Irp - Pointer to the irp.
1843 PPNP_BUS_INFORMATION busInfo
;
1847 busInfo
= ExAllocatePoolWithTag (PagedPool
, sizeof(PNP_BUS_INFORMATION
),
1850 if (busInfo
== NULL
) {
1851 return STATUS_INSUFFICIENT_RESOURCES
;
1854 busInfo
->BusTypeGuid
= GUID_ACPI_INTERFACE_STANDARD
;
1856 busInfo
->LegacyBusType
= InternalPowerBus
;
1858 busInfo
->BusNumber
= 0; //fixme
1860 Irp
->IoStatus
.Information
= (ULONG_PTR
)busInfo
;
1862 return STATUS_SUCCESS
;
1867 Bus_GetDeviceCapabilities(
1868 PDEVICE_OBJECT DeviceObject
,
1869 PDEVICE_CAPABILITIES DeviceCapabilities
1872 IO_STATUS_BLOCK ioStatus
;
1875 PDEVICE_OBJECT targetObject
;
1876 PIO_STACK_LOCATION irpStack
;
1882 // Initialize the capabilities that we will send down
1884 RtlZeroMemory( DeviceCapabilities
, sizeof(DEVICE_CAPABILITIES
) );
1885 DeviceCapabilities
->Size
= sizeof(DEVICE_CAPABILITIES
);
1886 DeviceCapabilities
->Version
= 1;
1887 DeviceCapabilities
->Address
= -1;
1888 DeviceCapabilities
->UINumber
= -1;
1891 // Initialize the event
1893 KeInitializeEvent( &pnpEvent
, NotificationEvent
, FALSE
);
1895 targetObject
= IoGetAttachedDeviceReference( DeviceObject
);
1900 pnpIrp
= IoBuildSynchronousFsdRequest(
1909 if (pnpIrp
== NULL
) {
1911 status
= STATUS_INSUFFICIENT_RESOURCES
;
1912 goto GetDeviceCapabilitiesExit
;
1917 // Pnp Irps all begin life as STATUS_NOT_SUPPORTED;
1919 pnpIrp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
1922 // Get the top of stack
1924 irpStack
= IoGetNextIrpStackLocation( pnpIrp
);
1927 // Set the top of stack
1929 RtlZeroMemory( irpStack
, sizeof(IO_STACK_LOCATION
) );
1930 irpStack
->MajorFunction
= IRP_MJ_PNP
;
1931 irpStack
->MinorFunction
= IRP_MN_QUERY_CAPABILITIES
;
1932 irpStack
->Parameters
.DeviceCapabilities
.Capabilities
= DeviceCapabilities
;
1937 status
= IoCallDriver( targetObject
, pnpIrp
);
1938 if (status
== STATUS_PENDING
) {
1941 // Block until the irp comes back.
1942 // Important thing to note here is when you allocate
1943 // the memory for an event in the stack you must do a
1944 // KernelMode wait instead of UserMode to prevent
1945 // the stack from getting paged out.
1948 KeWaitForSingleObject(
1955 status
= ioStatus
.Status
;
1959 GetDeviceCapabilitiesExit
:
1961 // Done with reference
1963 ObDereferenceObject( targetObject
);