aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/acpica/acpi.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2014-01-28 20:53:33 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2014-01-28 20:53:33 +0000
commit7e3343bfcf0884acc5b3741a55f7e37b57c89a98 (patch)
tree3a521aef52a0172fcab67bcda4012b7b07562bd5 /sys/dev/acpica/acpi.c
parent6f3caa6d8159eeef8831510bee51ad81e798583d (diff)
downloadsrc-7e3343bfcf0884acc5b3741a55f7e37b57c89a98.tar.gz
src-7e3343bfcf0884acc5b3741a55f7e37b57c89a98.zip
Some BIOSes incorrectly use standard memory resource ranges to list
the memory ranges that they decode for downstream devices rather than creating ResourceProducer range resource entries. The result is that we allocate the full range to the PCI root bridge device causing allocations in child devices to all fail. As a workaround, ignore any standard memory resources on a PCI root bridge device. It is normal for a PCI root bridge to allocate an I/O resource for the I/O ports used for PCI config access, but I have not seen any PCI root bridges that legitimately allocate a memory resource. Reviewed by: jkim MFC after: 1 week
Notes
Notes: svn path=/head/; revision=261243
Diffstat (limited to 'sys/dev/acpica/acpi.c')
-rw-r--r--sys/dev/acpica/acpi.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index d17245eb419b..dee0c468238f 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -1190,12 +1190,28 @@ acpi_set_resource(device_t dev, device_t child, int type, int rid,
struct acpi_softc *sc = device_get_softc(dev);
struct acpi_device *ad = device_get_ivars(child);
struct resource_list *rl = &ad->ad_rl;
+ ACPI_DEVICE_INFO *devinfo;
u_long end;
/* Ignore IRQ resources for PCI link devices. */
if (type == SYS_RES_IRQ && ACPI_ID_PROBE(dev, child, pcilink_ids) != NULL)
return (0);
+ /*
+ * Ignore memory resources for PCI root bridges. Some BIOSes
+ * incorrectly enumerate the memory ranges they decode as plain
+ * memory resources instead of as a ResourceProducer range.
+ */
+ if (type == SYS_RES_MEMORY) {
+ if (ACPI_SUCCESS(AcpiGetObjectInfo(ad->ad_handle, &devinfo))) {
+ if ((devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0) {
+ AcpiOsFree(devinfo);
+ return (0);
+ }
+ AcpiOsFree(devinfo);
+ }
+ }
+
/* If the resource is already allocated, fail. */
if (resource_list_busy(rl, type, rid))
return (EBUSY);