summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2006-05-07 03:28:10 +0000
committernjl <njl@FreeBSD.org>2006-05-07 03:28:10 +0000
commit6389d78b01474b1118cdad8a56bd5ce67c96a711 (patch)
tree863b9c14326ace98b78df611f1ff24adb92045a2 /sys/dev/acpica
parent79b0d24eca099a2505c578785f4a464500d23449 (diff)
downloadFreeBSD-src-6389d78b01474b1118cdad8a56bd5ce67c96a711.zip
FreeBSD-src-6389d78b01474b1118cdad8a56bd5ce67c96a711.tar.gz
Don't attach special devices in the order they appear in the AML tree.
If the embedded controller exists before the sysresource devices, for example, it will be attached first. Instead, let the normal device order function work as we first desired. [1] There still remained a problem where we couldn't allocate resources in acpi0 that were passed up by the sysresource pseudo-devices. These devices had to probe/attach first to give their resources to acpi, then acpi would allocate them before probing/attaching other devices. To work around this, we attach them from acpi_sysres_alloc(). A better approach would be to implement multi-pass probe/attach in newbus but that's a much bigger task. Suggested by: jhb [1] Hardware from: Centaur Technologies MFC after: 1 week
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r--sys/dev/acpica/acpi.c42
-rw-r--r--sys/dev/acpica/acpi_resource.c2
2 files changed, 26 insertions, 18 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 72956b9..c6ef01b 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -475,6 +475,10 @@ acpi_attach(device_t dev)
/*
* Call the ECDT probe function to provide EC functionality before
* the namespace has been evaluated.
+ *
+ * XXX This happens before the sysresource devices have been probed and
+ * attached so its resources come from nexus0. In practice, this isn't
+ * a problem but should be addressed eventually.
*/
acpi_ec_ecdt_probe(dev);
@@ -903,6 +907,21 @@ acpi_sysres_alloc(device_t dev)
struct resource_list *rl;
struct resource_list_entry *rle;
struct rman *rm;
+ char *sysres_ids[] = { "PNP0C01", "PNP0C02", NULL };
+ device_t *children;
+ int child_count, i;
+
+ /*
+ * Probe/attach any sysresource devices. This would be unnecessary if we
+ * had multi-pass probe/attach.
+ */
+ if (device_get_children(dev, &children, &child_count) != 0)
+ return (ENXIO);
+ for (i = 0; i < child_count; i++) {
+ if (ACPI_ID_PROBE(dev, children[i], sysres_ids) != NULL)
+ device_probe_and_attach(children[i]);
+ }
+ free(children, M_TEMP);
rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
STAILQ_FOREACH(rle, rl, link) {
@@ -1489,26 +1508,19 @@ acpi_probe_children(device_t bus)
static int
acpi_probe_order(ACPI_HANDLE handle, int *order)
{
- int ret;
/*
* 1. I/O port and memory system resource holders
* 2. Embedded controllers (to handle early accesses)
* 3. PCI Link Devices
*/
- ret = 0;
- if (acpi_MatchHid(handle, "PNP0C01") || acpi_MatchHid(handle, "PNP0C02")) {
+ if (acpi_MatchHid(handle, "PNP0C01") || acpi_MatchHid(handle, "PNP0C02"))
*order = 1;
- ret = 1;
- } else if (acpi_MatchHid(handle, "PNP0C09")) {
+ else if (acpi_MatchHid(handle, "PNP0C09"))
*order = 2;
- ret = 1;
- } else if (acpi_MatchHid(handle, "PNP0C0F")) {
+ else if (acpi_MatchHid(handle, "PNP0C0F"))
*order = 3;
- ret = 1;
- }
-
- return (ret);
+ return (0);
}
/*
@@ -1521,7 +1533,7 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
ACPI_OBJECT_TYPE type;
ACPI_HANDLE h;
device_t bus, child;
- int order, probe_now;
+ int order;
char *handle_str, **search;
static char *scopes[] = {"\\_PR_", "\\_TZ_", "\\_SI_", "\\_SB_", NULL};
@@ -1561,7 +1573,7 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
*/
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n", handle_str));
order = (level + 1) * 10;
- probe_now = acpi_probe_order(handle, &order);
+ acpi_probe_order(handle, &order);
child = BUS_ADD_CHILD(bus, order, NULL, -1);
if (child == NULL)
break;
@@ -1602,10 +1614,6 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
* device not to have any resources.
*/
acpi_parse_resources(child, handle, &acpi_res_parse_set, NULL);
-
- /* If order was overridden, probe/attach now rather than later. */
- if (probe_now)
- device_probe_and_attach(child);
break;
}
}
diff --git a/sys/dev/acpica/acpi_resource.c b/sys/dev/acpica/acpi_resource.c
index cde23e2..5785db6 100644
--- a/sys/dev/acpica/acpi_resource.c
+++ b/sys/dev/acpica/acpi_resource.c
@@ -688,7 +688,7 @@ acpi_sysres_probe(device_t dev)
device_set_desc(dev, "System Resource");
device_quiet(dev);
- return (-100);
+ return (BUS_PROBE_DEFAULT);
}
static int
OpenPOWER on IntegriCloud