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);

Reply via email to