summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Weingartner <weingart@cvs.openbsd.org>2007-09-13 03:43:23 +0000
committerTobias Weingartner <weingart@cvs.openbsd.org>2007-09-13 03:43:23 +0000
commit0e52d98879cbe68304cec52cb172d1c5f6eff44c (patch)
tree0cab7850706a78bb8e31369fb01b119f33e2e8a9
parent8637c5657aa77f6de4ed4699195d1fa39bfe2546 (diff)
Implement ACPI 6.5.1 spec tree walk for _STA and _INI.
Fixes mk's laptop. No regressions so far (thank you to the testers). ok gwk@, mk@, marco@
-rw-r--r--sys/dev/acpi/acpi.c76
-rw-r--r--sys/dev/acpi/acpidock.c8
-rw-r--r--sys/dev/acpi/dsdt.c13
-rw-r--r--sys/dev/acpi/dsdt.h4
4 files changed, 65 insertions, 36 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index fd39a1aaaa4..fd42c28326c 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.88 2007/04/17 16:07:45 mk Exp $ */
+/* $OpenBSD: acpi.c,v 1.89 2007/09/13 03:43:22 weingart Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -59,12 +59,13 @@ int acpi_print(void *, const char *);
void acpi_map_pmregs(struct acpi_softc *);
-void acpi_founddock(struct aml_node *, void *);
-void acpi_foundpss(struct aml_node *, void *);
-void acpi_foundhid(struct aml_node *, void *);
-void acpi_foundec(struct aml_node *, void *);
-void acpi_foundtmp(struct aml_node *, void *);
-void acpi_inidev(struct aml_node *, void *);
+int acpi_founddock(struct aml_node *, void *);
+int acpi_foundpss(struct aml_node *, void *);
+int acpi_foundhid(struct aml_node *, void *);
+int acpi_foundec(struct aml_node *, void *);
+int acpi_foundtmp(struct aml_node *, void *);
+int acpi_foundprt(struct aml_node *, void *);
+int acpi_inidev(struct aml_node *, void *);
int acpi_loadtables(struct acpi_softc *, struct acpi_rsdp *);
void acpi_load_table(paddr_t, size_t, acpi_qhead_t *);
@@ -74,8 +75,6 @@ void acpi_init_states(struct acpi_softc *);
void acpi_init_gpes(struct acpi_softc *);
void acpi_init_pm(struct acpi_softc *);
-void acpi_foundprt(struct aml_node *, void *);
-
void acpi_filtdetach(struct knote *);
int acpi_filtread(struct knote *, long);
@@ -250,30 +249,47 @@ acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address,
return (0);
}
-void
+int
acpi_inidev(struct aml_node *node, void *arg)
{
struct acpi_softc *sc = (struct acpi_softc *)arg;
struct aml_value res;
+ int st = 0;
+
+ /* Default value */
+ st = STA_PRESENT|STA_ENABLED;
+ st |= STA_SHOW_UI|STA_DEV_OK;
+ st |= STA_BATTERY;
/*
- * XXX per the ACPI spec 6.5.1 only run _INI when device is there
- * or when there is no _STA.
- * The tricky bit is that the parent can have a _STA that is disabled
- * and the children do not have a _STA. In that case the _INI will
- * execute! This needs to be fixed.
+ * Per the ACPI spec 6.5.1, only run _INI when device is there or
+ * when there is no _STA. We terminate the tree walk (with return 1)
+ * early if necessary.
*/
+ /* Evaluate _STA to decide _INI fate and walk fate */
memset(&res, 0, sizeof res);
- if (aml_evalname(sc, node, "_STA", 0, NULL, &res))
- res.v_integer = STA_PRESENT; /* no _STA, fake it */
+ if (! aml_evalname(sc, node, "_STA", 0, NULL, &res))
+ st = (int)aml_val2int(&res);
+ aml_freevalue(&res);
- if (res.v_integer & STA_PRESENT)
+ /* Evaluate _INI if we are present */
+ if (st & STA_PRESENT)
aml_evalnode(sc, node, 0, NULL, NULL);
- aml_freevalue(&res);
+
+ /* If we are functioning, we walk/search our children */
+ if(st & STA_DEV_OK)
+ return 0;
+
+ /* If we are not enabled, or not present, terminate search */
+ if (!(st & (STA_PRESENT|STA_ENABLED)))
+ return 1;
+
+ /* Default just continue search */
+ return 0;
}
-void
+int
acpi_foundprt(struct aml_node *node, void *arg)
{
struct acpi_softc *sc = (struct acpi_softc *)arg;
@@ -291,6 +307,8 @@ acpi_foundprt(struct aml_node *node, void *arg)
aaa.aaa_name = "acpiprt";
config_found(self, &aaa, acpi_print);
+
+ return 0;
}
int
@@ -1616,7 +1634,7 @@ acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval)
sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, offset, regval);
}
-void
+int
acpi_foundec(struct aml_node *node, void *arg)
{
struct acpi_softc *sc = (struct acpi_softc *)arg;
@@ -1626,7 +1644,7 @@ acpi_foundec(struct aml_node *node, void *arg)
struct acpi_attach_args aaa;
if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
- return;
+ return 0;
switch (res.type) {
case AML_OBJTYPE_STRING:
@@ -1641,7 +1659,7 @@ acpi_foundec(struct aml_node *node, void *arg)
}
if (strcmp(dev, ACPI_DEV_ECD))
- return;
+ return 0;
memset(&aaa, 0, sizeof(aaa));
aaa.aaa_iot = sc->sc_iot;
@@ -1651,9 +1669,11 @@ acpi_foundec(struct aml_node *node, void *arg)
aaa.aaa_name = "acpiec";
config_found(self, &aaa, acpi_print);
aml_freevalue(&res);
+
+ return 0;
}
-void
+int
acpi_foundhid(struct aml_node *node, void *arg)
{
struct acpi_softc *sc = (struct acpi_softc *)arg;
@@ -1664,7 +1684,7 @@ acpi_foundhid(struct aml_node *node, void *arg)
dnprintf(10, "found hid device: %s ", node->parent->name);
if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
- return;
+ return 0;
switch (res.type) {
case AML_OBJTYPE_STRING:
@@ -1697,9 +1717,11 @@ acpi_foundhid(struct aml_node *node, void *arg)
if (aaa.aaa_name)
config_found(self, &aaa, acpi_print);
aml_freevalue(&res);
+
+ return 0;
}
-void
+int
acpi_founddock(struct aml_node *node, void *arg)
{
struct acpi_softc *sc = (struct acpi_softc *)arg;
@@ -1717,5 +1739,7 @@ acpi_founddock(struct aml_node *node, void *arg)
aaa.aaa_name = "acpidock";
config_found(self, &aaa, acpi_print);
+
+ return 0;
}
#endif /* SMALL_KERNEL */
diff --git a/sys/dev/acpi/acpidock.c b/sys/dev/acpi/acpidock.c
index f22a97fa8f6..e92827c255b 100644
--- a/sys/dev/acpi/acpidock.c
+++ b/sys/dev/acpi/acpidock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidock.c,v 1.25 2007/04/23 19:29:03 mk Exp $ */
+/* $OpenBSD: acpidock.c,v 1.26 2007/09/13 03:43:22 weingart Exp $ */
/*
* Copyright (c) 2006,2007 Michael Knudsen <mk@openbsd.org>
*
@@ -52,7 +52,7 @@ int acpidock_eject(struct acpidock_softc *, struct aml_node *);
int acpidock_notify(struct aml_node *, int, void *);
int acpidock_status(struct acpidock_softc *);
-void acpidock_foundejd(struct aml_node *, void *);
+int acpidock_foundejd(struct aml_node *, void *);
int
acpidock_match(struct device *parent, void *match, void *aux)
@@ -266,7 +266,7 @@ acpidock_notify(struct aml_node *node, int notify_type, void *arg)
return (0);
}
-void
+int
acpidock_foundejd(struct aml_node *node, void *arg)
{
struct acpidock_softc *sc = (struct acpidock_softc *)arg;
@@ -292,4 +292,6 @@ acpidock_foundejd(struct aml_node *node, void *arg)
}
aml_freevalue(&res);
+
+ return 0;
}
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c
index 60378f0c74f..d3e1b34605c 100644
--- a/sys/dev/acpi/dsdt.c
+++ b/sys/dev/acpi/dsdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.88 2007/09/08 21:19:52 gwk Exp $ */
+/* $OpenBSD: dsdt.c,v 1.89 2007/09/13 03:43:22 weingart Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -2123,21 +2123,24 @@ aml_walkroot(void)
int
aml_find_node(struct aml_node *node, const char *name,
- void (*cbproc)(struct aml_node *, void *arg), void *arg)
+ int (*cbproc)(struct aml_node *, void *arg), void *arg)
{
const char *nn;
+ int st = 0;
while (node) {
if ((nn = node->name) != NULL) {
if (*nn == AMLOP_ROOTCHAR) nn++;
while (*nn == AMLOP_PARENTPREFIX) nn++;
if (!strcmp(name, nn))
- cbproc(node, arg);
+ st = cbproc(node, arg);
}
- aml_find_node(node->child, name, cbproc, arg);
+ /* Only recurse if cbproc() wants us to */
+ if (!st)
+ aml_find_node(node->child, name, cbproc, arg);
node = node->sibling;
}
- return (0);
+ return st;
}
/*
diff --git a/sys/dev/acpi/dsdt.h b/sys/dev/acpi/dsdt.h
index ed04b482cfe..fc7832d9149 100644
--- a/sys/dev/acpi/dsdt.h
+++ b/sys/dev/acpi/dsdt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.h,v 1.28 2007/04/11 02:51:11 jordan Exp $ */
+/* $OpenBSD: dsdt.h,v 1.29 2007/09/13 03:43:22 weingart Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -64,7 +64,7 @@ void aml_walkroot(void);
void aml_walktree(struct aml_node *);
int aml_find_node(struct aml_node *, const char *,
- void (*)(struct aml_node *, void *), void *);
+ int (*)(struct aml_node *, void *), void *);
int acpi_parse_aml(struct acpi_softc *, u_int8_t *,
u_int32_t);
int aml_eval_object(struct acpi_softc *, struct aml_node *,