summaryrefslogtreecommitdiff
path: root/sys/dev/acpi
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-12-17 17:57:20 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-12-17 17:57:20 +0000
commit50069fef668a82dc04444c38db36584f2a5c9e88 (patch)
tree5a533d53d43541bdf154a5a835ecfe472b488dd2 /sys/dev/acpi
parentdcc902adb92f89ac210751feb08b0688933664cf (diff)
Fix some issues with referencing named ACPI nodes from Packages.
These references need to be resolved at runtime rather than when they're parsed such that they pick up the right values for those nodes which can be changed when for example _INI methods run. The current approach is to replace these reference with a string that names the node in question. The problem with that is that packages can also contain normal strings. Which means that we need special code that depends on the context where the package is used. This diff takes a different approach by retaining a reference when parsing. Code that uses a package will need to resolve this reference but there is no ambiguiety anymore. ok patrick@
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r--sys/dev/acpi/acpi.c42
-rw-r--r--sys/dev/acpi/acpiprt.c10
-rw-r--r--sys/dev/acpi/acpipwrres.c6
-rw-r--r--sys/dev/acpi/acpitz.c6
-rw-r--r--sys/dev/acpi/atk0110.c8
-rw-r--r--sys/dev/acpi/dsdt.c51
6 files changed, 65 insertions, 58 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index 005add9063e..d7c68eee451 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.392 2020/12/05 16:14:30 kettenis Exp $ */
+/* $OpenBSD: acpi.c,v 1.393 2020/12/17 17:57:19 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -2989,21 +2989,24 @@ acpi_getprop(struct aml_node *node, const char *prop, void *buf, int buflen)
/* Check properties. */
for (i = 0; i < dsd.v_package[1]->length; i++) {
struct aml_value *res = dsd.v_package[1]->v_package[i];
+ struct aml_value *val;
int len;
if (res->type != AML_OBJTYPE_PACKAGE || res->length != 2 ||
res->v_package[0]->type != AML_OBJTYPE_STRING)
continue;
- len = res->v_package[1]->length;
- switch (res->v_package[1]->type) {
+ val = res->v_package[1];
+ if (val->type == AML_OBJTYPE_OBJREF)
+ val = val->v_objref.ref;
+
+ len = val->length;
+ switch (val->type) {
case AML_OBJTYPE_BUFFER:
- memcpy(buf, res->v_package[1]->v_buffer,
- min(len, buflen));
+ memcpy(buf, val->v_buffer, min(len, buflen));
return len;
case AML_OBJTYPE_STRING:
- memcpy(buf, res->v_package[1]->v_string,
- min(len, buflen));
+ memcpy(buf, val->v_string, min(len, buflen));
return len;
}
}
@@ -3040,14 +3043,22 @@ acpi_getpropint(struct aml_node *node, const char *prop, uint32_t defval)
/* Check properties. */
for (i = 0; i < dsd.v_package[1]->length; i++) {
struct aml_value *res = dsd.v_package[1]->v_package[i];
+ struct aml_value *val;
if (res->type != AML_OBJTYPE_PACKAGE || res->length != 2 ||
- res->v_package[0]->type != AML_OBJTYPE_STRING ||
- res->v_package[1]->type != AML_OBJTYPE_INTEGER)
+ res->v_package[0]->type != AML_OBJTYPE_STRING)
+ continue;
+
+ val = res->v_package[1];
+ if (val->type == AML_OBJTYPE_OBJREF)
+ val = val->v_objref.ref;
+
+ if (val->type != AML_OBJTYPE_INTEGER)
continue;
- if (strcmp(res->v_package[0]->v_string, prop) == 0)
- return res->v_package[1]->v_integer;
+ if (strcmp(res->v_package[0]->v_string, prop) == 0 &&
+ val->type == AML_OBJTYPE_INTEGER)
+ return val->v_integer;
}
return defval;
@@ -3139,7 +3150,7 @@ const char *acpi_isa_hids[] = {
void
acpi_attach_deps(struct acpi_softc *sc, struct aml_node *node)
{
- struct aml_value res;
+ struct aml_value res, *val;
struct aml_node *dep;
int i;
@@ -3150,9 +3161,12 @@ acpi_attach_deps(struct acpi_softc *sc, struct aml_node *node)
return;
for (i = 0; i < res.length; i++) {
- if (res.v_package[i]->type != AML_OBJTYPE_STRING)
+ val = res.v_package[i];
+ if (val->type == AML_OBJTYPE_OBJREF)
+ val = val->v_objref.ref;
+ if (val->type != AML_OBJTYPE_DEVICE)
continue;
- dep = aml_searchrel(node, res.v_package[i]->v_string);
+ dep = val->node;
if (dep == NULL || dep->attached)
continue;
dep = aml_searchname(dep, "_HID");
diff --git a/sys/dev/acpi/acpiprt.c b/sys/dev/acpi/acpiprt.c
index a83f540a80e..ea28993d051 100644
--- a/sys/dev/acpi/acpiprt.c
+++ b/sys/dev/acpi/acpiprt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpiprt.c,v 1.49 2020/04/11 11:01:18 kettenis Exp $ */
+/* $OpenBSD: acpiprt.c,v 1.50 2020/12/17 17:57:19 kettenis Exp $ */
/*
* Copyright (c) 2006 Mark Kettenis <kettenis@openbsd.org>
*
@@ -272,14 +272,6 @@ acpiprt_prt_add(struct acpiprt_softc *sc, struct aml_value *v)
}
pp = v->v_package[2];
- if (pp->type == AML_OBJTYPE_STRING) {
- node = aml_searchrel(sc->sc_devnode, pp->v_string);
- if (node == NULL) {
- printf("Invalid device\n");
- return;
- }
- pp = node->value;
- }
if (pp->type == AML_OBJTYPE_NAMEREF) {
node = aml_searchrel(sc->sc_devnode, pp->v_nameref);
if (node == NULL) {
diff --git a/sys/dev/acpi/acpipwrres.c b/sys/dev/acpi/acpipwrres.c
index 02ca268a541..4de7da1e871 100644
--- a/sys/dev/acpi/acpipwrres.c
+++ b/sys/dev/acpi/acpipwrres.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpipwrres.c,v 1.8 2020/04/06 00:01:08 pirofti Exp $ */
+/* $OpenBSD: acpipwrres.c,v 1.9 2020/12/17 17:57:19 kettenis Exp $ */
/*
* Copyright (c) 2013 Martin Pieuchot <mpi@openbsd.org>
@@ -291,10 +291,10 @@ acpipwrres_foundcons(struct aml_node *node, void *arg)
for (; i < res.length; i++) {
ref = res.v_package[i];
- if (ref->type == AML_OBJTYPE_STRING) {
+ if (ref->type == AML_OBJTYPE_NAMEREF) {
struct aml_node *pnode;
- pnode = aml_searchrel(&aml_root, ref->v_string);
+ pnode = aml_searchrel(&aml_root, ref->v_nameref);
if (pnode == NULL) {
DPRINTF(("%s: device %s not found\n",
DEVNAME(sc), ref->v_string));
diff --git a/sys/dev/acpi/acpitz.c b/sys/dev/acpi/acpitz.c
index 566187802c3..f364ac89006 100644
--- a/sys/dev/acpi/acpitz.c
+++ b/sys/dev/acpi/acpitz.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpitz.c,v 1.54 2018/06/29 17:39:18 kettenis Exp $ */
+/* $OpenBSD: acpitz.c,v 1.55 2020/12/17 17:57:19 kettenis Exp $ */
/*
* Copyright (c) 2006 Can Erkin Acar <canacar@openbsd.org>
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
@@ -304,9 +304,9 @@ acpitz_setfan(struct acpitz_softc *sc, int i, char *method)
}
for (y = 0; y < res1.length; y++) {
ref = res1.v_package[y];
- if (ref->type == AML_OBJTYPE_STRING) {
+ if (ref->type == AML_OBJTYPE_NAMEREF) {
node = aml_searchrel(sc->sc_devnode,
- ref->v_string);
+ ref->v_nameref);
if (node == NULL) {
printf("%s: %s[%d.%d] _PR0"
" not a valid device\n",
diff --git a/sys/dev/acpi/atk0110.c b/sys/dev/acpi/atk0110.c
index 209df77a57f..503d1e4a813 100644
--- a/sys/dev/acpi/atk0110.c
+++ b/sys/dev/acpi/atk0110.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atk0110.c,v 1.15 2018/06/29 17:39:18 kettenis Exp $ */
+/* $OpenBSD: atk0110.c,v 1.16 2020/12/17 17:57:19 kettenis Exp $ */
/*
* Copyright (c) 2009 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru>
@@ -230,12 +230,12 @@ aibs_attach_sif(struct aibs_softc *sc, enum sensor_type st)
}
for (i = 0, v++; i < n; i++, v++) {
- if(v[0]->type != AML_OBJTYPE_STRING) {
- printf("%s: %s: %i: not a string: %i type\n",
+ if(v[0]->type != AML_OBJTYPE_NAMEREF) {
+ printf("%s: %s: %i: not a nameref: %i type\n",
DEVNAME(sc), name, i, v[0]->type);
continue;
}
- aibs_add_sensor(sc, v[0]->v_string);
+ aibs_add_sensor(sc, v[0]->v_nameref);
}
aml_freevalue(&res);
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c
index 36c39deb63c..461c810a878 100644
--- a/sys/dev/acpi/dsdt.c
+++ b/sys/dev/acpi/dsdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.256 2020/09/27 16:46:15 kettenis Exp $ */
+/* $OpenBSD: dsdt.c,v 1.257 2020/12/17 17:57:19 kettenis Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
@@ -965,6 +965,7 @@ aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
lhs->v_mutex = rhs->v_mutex;
break;
case AML_OBJTYPE_POWERRSRC:
+ lhs->node = rhs->node;
lhs->v_powerrsrc = rhs->v_powerrsrc;
break;
case AML_OBJTYPE_METHOD:
@@ -980,6 +981,7 @@ aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
lhs->v_opregion = rhs->v_opregion;
break;
case AML_OBJTYPE_PROCESSOR:
+ lhs->node = rhs->node;
lhs->v_processor = rhs->v_processor;
break;
case AML_OBJTYPE_NAMEREF:
@@ -995,6 +997,8 @@ aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
aml_addref(lhs->v_objref.ref, "");
break;
case AML_OBJTYPE_DEVICE:
+ case AML_OBJTYPE_THERMZONE:
+ lhs->node = rhs->node;
break;
default:
printf("copyvalue: %x", rhs->type);
@@ -1035,10 +1039,8 @@ aml_freevalue(struct aml_value *val)
acpi_os_free(val->v_buffer);
break;
case AML_OBJTYPE_PACKAGE:
- for (idx = 0; idx < val->length; idx++) {
- aml_freevalue(val->v_package[idx]);
- acpi_os_free(val->v_package[idx]);
- }
+ for (idx = 0; idx < val->length; idx++)
+ aml_delref(&val->v_package[idx], "");
acpi_os_free(val->v_package);
break;
case AML_OBJTYPE_OBJREF:
@@ -1471,11 +1473,11 @@ struct aml_defval {
{ "_OSI", AML_OBJTYPE_METHOD, 1, aml_callosi },
/* Create default scopes */
- { "_GPE" },
- { "_PR_" },
- { "_SB_" },
- { "_TZ_" },
- { "_SI_" },
+ { "_GPE", AML_OBJTYPE_DEVICE },
+ { "_PR_", AML_OBJTYPE_DEVICE },
+ { "_SB_", AML_OBJTYPE_DEVICE },
+ { "_TZ_", AML_OBJTYPE_DEVICE },
+ { "_SI_", AML_OBJTYPE_DEVICE },
{ NULL }
};
@@ -3875,17 +3877,13 @@ aml_parse(struct aml_scope *scope, int ret_type, const char *stype)
case AMLOP_NAMECHAR:
/* opargs[0] = named object (node != NULL), or nameref */
my_ret = opargs[0];
- if (scope->type == AMLOP_PACKAGE) {
+ if (scope->type == AMLOP_PACKAGE && my_ret->node) {
/* Special case for package */
- if (my_ret->type == AML_OBJTYPE_NAMEREF)
- my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1,
- aml_getname(my_ret->v_nameref));
- else if (my_ret->node)
- my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1,
- aml_nodename(my_ret->node));
- break;
- }
- if (my_ret->type == AML_OBJTYPE_OBJREF) {
+ my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF,
+ AMLOP_NAMECHAR, 0);
+ my_ret->v_objref.ref = opargs[0];
+ aml_addref(my_ret, "package");
+ } else if (my_ret->type == AML_OBJTYPE_OBJREF) {
my_ret = my_ret->v_objref.ref;
aml_addref(my_ret, "de-alias");
}
@@ -4617,15 +4615,17 @@ acpi_getdevlist(struct acpi_devlist_head *list, struct aml_node *root,
struct aml_value *pkg, int off)
{
struct acpi_devlist *dl;
- struct aml_node *node;
+ struct aml_value *val;
int idx;
- for (idx=off; idx<pkg->length; idx++) {
- node = aml_searchname(root, pkg->v_package[idx]->v_string);
- if (node) {
+ for (idx = off; idx < pkg->length; idx++) {
+ val = pkg->v_package[idx];
+ if (val->type == AML_OBJTYPE_OBJREF)
+ val = val->v_objref.ref;
+ if (val->node) {
dl = acpi_os_malloc(sizeof(*dl));
if (dl) {
- dl->dev_node = node;
+ dl->dev_node = val->node;
TAILQ_INSERT_TAIL(list, dl, dev_link);
}
}
@@ -4642,4 +4642,5 @@ acpi_freedevlist(struct acpi_devlist_head *list)
acpi_os_free(dl);
}
}
+
#endif /* SMALL_KERNEL */