This function is really weird. It looks for nodes with a specific name, and calls a callback function if a match is found. But it doesn't just look at the children of the passed node, it also looks atthe passed node itself and all of its children. That is really unexpected, and jcs@ fell into that trap. The result is that the dwiic(4) code actually tries to attach all i2c devices to all i2c controllers ;).
I looked at all the use cases, and AFAIK the intention always is to just look at the children of the passed node. This diff makes it so. ok? Index: dsdt.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v retrieving revision 1.218 diff -u -p -r1.218 dsdt.c --- dsdt.c 20 Aug 2015 20:50:10 -0000 1.218 +++ dsdt.c 12 Jan 2016 21:01:48 -0000 @@ -1249,26 +1249,26 @@ aml_walknodes(struct aml_node *node, int nodecb(node, arg); } -int +void aml_find_node(struct aml_node *node, const char *name, int (*cbproc)(struct aml_node *, void *arg), void *arg) { + struct aml_node *child; const char *nn; - int st = 0; - while (node) { - if ((nn = node->name) != NULL) { + SIMPLEQ_FOREACH(child, &node->son, sib) { + nn = child->name; + if ((nn = child->name) != NULL) { if (*nn == AMLOP_ROOTCHAR) nn++; while (*nn == AMLOP_PARENTPREFIX) nn++; - if (!strcmp(name, nn)) - st = cbproc(node, arg); + if (strcmp(name, nn) == 0) { + /* Only recurse if cbproc() wants us to */ + if (cbproc(child, arg) == 0) + continue; + } } - /* Only recurse if cbproc() wants us to */ - if (!st) - aml_find_node(SIMPLEQ_FIRST(&node->son), name, cbproc, arg); - node = SIMPLEQ_NEXT(node, sib); + aml_find_node(child, name, cbproc, arg); } - return st; } /* Index: dsdt.h =================================================================== RCS file: /cvs/src/sys/dev/acpi/dsdt.h,v retrieving revision 1.65 diff -u -p -r1.65 dsdt.h --- dsdt.h 9 Jan 2016 10:50:43 -0000 1.65 +++ dsdt.h 12 Jan 2016 21:01:48 -0000 @@ -53,7 +53,7 @@ void aml_showvalue(struct aml_value *, void aml_walkroot(void); void aml_walktree(struct aml_node *); -int aml_find_node(struct aml_node *, const char *, +void aml_find_node(struct aml_node *, const char *, int (*)(struct aml_node *, void *), void *); int acpi_parse_aml(struct acpi_softc *, u_int8_t *, u_int32_t);