summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-05-08 10:09:26 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-05-08 10:09:26 +0000
commit466b594238d8c02209610e93543379e8e52f6e2a (patch)
tree374be7af5af2b88c13b3dce00b54a3a08bad98dc /sys
parentacd3d1aec379a4d88910956c2783aede779bd3a6 (diff)
Make sure devices listed by a device's _DEP method are attached before
we attach the device itself. The _DEP methode, introduced in ACPI 5.0, is a hint that the device in question depends on OpRegion support from the devices listed by _DEP, so we have to order them the proper way. To prevent us from attaching those devices again when we encounter them later walking down the device tree, keep track of our attempts to attach a device driver to them using aflag in the aml_node structure. ok guenther@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi/acpi.c36
-rw-r--r--sys/dev/acpi/amltypes.h4
2 files changed, 37 insertions, 3 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index 736012413db..4828c0c6f47 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.310 2016/04/25 15:43:30 pirofti Exp $ */
+/* $OpenBSD: acpi.c,v 1.311 2016/05/08 10:09:25 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -2772,6 +2772,33 @@ const char *acpi_skip_hids[] = {
NULL
};
+void
+acpi_attach_deps(struct acpi_softc *sc, struct aml_node *node)
+{
+ struct aml_value res;
+ struct aml_node *dep;
+ int i;
+
+ if (aml_evalname(sc, node, "_DEP", 0, NULL, &res))
+ return;
+
+ if (res.type != AML_OBJTYPE_PACKAGE)
+ return;
+
+ for (i = 0; i < res.length; i++) {
+ if (res.v_package[i]->type != AML_OBJTYPE_STRING)
+ continue;
+ dep = aml_searchrel(node, res.v_package[i]->v_string);
+ if (dep == NULL || dep->attached)
+ continue;
+ dep = aml_searchname(dep, "_HID");
+ if (dep)
+ acpi_foundhid(dep, sc);
+ }
+
+ aml_freevalue(&res);
+}
+
int
acpi_foundhid(struct aml_node *node, void *arg)
{
@@ -2794,6 +2821,8 @@ acpi_foundhid(struct aml_node *node, void *arg)
if ((sta & STA_PRESENT) == 0)
return (0);
+ acpi_attach_deps(sc, node->parent);
+
memset(&aaa, 0, sizeof(aaa));
aaa.aaa_iot = sc->sc_iot;
aaa.aaa_memt = sc->sc_memt;
@@ -2814,7 +2843,10 @@ acpi_foundhid(struct aml_node *node, void *arg)
}
#endif
- config_found(self, &aaa, acpi_print);
+ if (!node->parent->attached) {
+ config_found(self, &aaa, acpi_print);
+ node->parent->attached = 1;
+ }
return (0);
}
diff --git a/sys/dev/acpi/amltypes.h b/sys/dev/acpi/amltypes.h
index 825b7671943..1f9bbedfa14 100644
--- a/sys/dev/acpi/amltypes.h
+++ b/sys/dev/acpi/amltypes.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amltypes.h,v 1.43 2016/04/02 00:34:47 jsg Exp $ */
+/* $OpenBSD: amltypes.h,v 1.44 2016/05/08 10:09:25 kettenis Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -376,6 +376,8 @@ struct aml_node {
SIMPLEQ_HEAD(,aml_node) son;
SIMPLEQ_ENTRY(aml_node) sib;
+ int attached;
+
char name[5];
u_int16_t opcode;
u_int8_t *start;