Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/fdt When attaching child devices, consider the best ...



details:   https://anonhg.NetBSD.org/src/rev/74ddbbba3155
branches:  trunk
changeset: 323768:74ddbbba3155
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sat Jun 30 13:44:50 2018 +0000

description:
When attaching child devices, consider the best match for all passes
instead of just the current pass. Fixes an issue where a driver with a
lower match number and early pass number will attach instead of a better
match on a later pass.

diffstat:

 sys/dev/fdt/fdtbus.c |  41 +++++++++++++++++++++++++++++++++++++++--
 1 files changed, 39 insertions(+), 2 deletions(-)

diffs (69 lines):

diff -r a1dfc8415861 -r 74ddbbba3155 sys/dev/fdt/fdtbus.c
--- a/sys/dev/fdt/fdtbus.c      Sat Jun 30 12:42:42 2018 +0000
+++ b/sys/dev/fdt/fdtbus.c      Sat Jun 30 13:44:50 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdtbus.c,v 1.19 2018/06/20 19:11:01 thorpej Exp $ */
+/* $NetBSD: fdtbus.c,v 1.20 2018/06/30 13:44:50 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.19 2018/06/20 19:11:01 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.20 2018/06/30 13:44:50 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -228,6 +228,34 @@
        return config_stdsubmatch(parent, cf, locs, aux);
 }
 
+static cfdata_t
+fdt_scan_best(struct fdt_softc *sc, struct fdt_node *node)
+{
+       struct fdt_attach_args faa;
+       cfdata_t cf, best_cf;
+       int match, best_match;
+
+       best_cf = NULL;
+       best_match = 0;
+
+       for (int pass = 0; pass <= FDTCF_PASS_DEFAULT; pass++) {
+               const int locs[FDTCF_NLOCS] = {
+                       [FDTCF_PASS] = pass
+               };
+               fdt_init_attach_args(sc, node, true, &faa);
+               cf = config_search_loc(fdt_scan_submatch, node->n_bus, "fdt", locs, &faa);
+               if (cf == NULL)
+                       continue;
+               match = config_match(node->n_bus, cf, &faa);
+               if (match > best_match) {
+                       best_match = match;
+                       best_cf = cf;
+               }
+       }
+
+       return best_cf;
+}
+
 static void
 fdt_scan(struct fdt_softc *sc, int pass)
 {
@@ -245,6 +273,15 @@
                fdt_init_attach_args(sc, node, quiet, &faa);
 
                /*
+                * Make sure we don't attach before a better match in a later pass.
+                */
+               cfdata_t cf_best = fdt_scan_best(sc, node);
+               cfdata_t cf_pass =
+                   config_search_loc(fdt_scan_submatch, node->n_bus, "fdt", locs, &faa);
+               if (cf_best != cf_pass)
+                       continue;
+
+               /*
                 * Attach the device.
                 */
                node->n_dev = config_found_sm_loc(node->n_bus, "fdt", locs,



Home | Main Index | Thread Index | Old Index