diff options
author | Tobias Weingartner <weingart@cvs.openbsd.org> | 2007-09-13 03:43:23 +0000 |
---|---|---|
committer | Tobias Weingartner <weingart@cvs.openbsd.org> | 2007-09-13 03:43:23 +0000 |
commit | 0e52d98879cbe68304cec52cb172d1c5f6eff44c (patch) | |
tree | 0cab7850706a78bb8e31369fb01b119f33e2e8a9 | |
parent | 8637c5657aa77f6de4ed4699195d1fa39bfe2546 (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.c | 76 | ||||
-rw-r--r-- | sys/dev/acpi/acpidock.c | 8 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.c | 13 | ||||
-rw-r--r-- | sys/dev/acpi/dsdt.h | 4 |
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 *, |