Source-Changes-HG archive

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

[src/trunk]: src/sys Add support for multiple cfdata tables to the internals ...



details:   https://anonhg.NetBSD.org/src/rev/91768b309d9b
branches:  trunk
changeset: 536895:91768b309d9b
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Mon Sep 23 23:16:06 2002 +0000

description:
Add support for multiple cfdata tables to the internals of the
autoconfiguration machinery, derived from PR #2112.

More work is left to do, including revamping how matches against
a candidate parent are done.

diffstat:

 sys/kern/subr_autoconf.c |  85 +++++++++++++++++++++++++++++++----------------
 sys/sys/device.h         |  15 +++++++-
 2 files changed, 69 insertions(+), 31 deletions(-)

diffs (210 lines):

diff -r 2b59b34790b6 -r 91768b309d9b sys/kern/subr_autoconf.c
--- a/sys/kern/subr_autoconf.c  Mon Sep 23 21:35:42 2002 +0000
+++ b/sys/kern/subr_autoconf.c  Mon Sep 23 23:16:06 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_autoconf.c,v 1.64 2002/07/10 19:04:09 drochner Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.65 2002/09/23 23:16:06 thorpej Exp $ */
 
 /*
  * Copyright (c) 1996, 2000 Christopher G. Demetriou
@@ -81,7 +81,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.64 2002/07/10 19:04:09 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.65 2002/09/23 23:16:06 thorpej Exp $");
 
 #include "opt_ddb.h"
 
@@ -111,6 +111,13 @@
 extern struct cfdata cfdata[];
 extern short cfroots[];
 
+/*
+ * List of cfdata tables.  We always have one such list -- the one
+ * built statically when the kernel was configured.
+ */
+struct cftablelist allcftables;
+static struct cftable initcftable;
+
 #define        ROOT ((struct device *)NULL)
 
 struct matchinfo {
@@ -153,6 +160,11 @@
 configure(void)
 {
 
+       TAILQ_INIT(&allcftables);
+
+       initcftable.ct_cfdata = cfdata;
+       TAILQ_INSERT_TAIL(&allcftables, &initcftable, ct_list);
+
        TAILQ_INIT(&deferred_config_queue);
        TAILQ_INIT(&interrupt_config_queue);
        TAILQ_INIT(&alldevs); 
@@ -223,6 +235,7 @@
 struct cfdata *
 config_search(cfmatch_t fn, struct device *parent, void *aux)
 {
+       struct cftable *ct;
        struct cfdata *cf;
        short *p;
        struct matchinfo m;
@@ -232,19 +245,23 @@
        m.aux = aux;
        m.match = NULL;
        m.pri = 0;
-       for (cf = cfdata; cf->cf_driver; cf++) {
-               /*
-                * Skip cf if no longer eligible, otherwise scan through
-                * parents for one matching `parent', and try match function.
-                */
-               if (cf->cf_fstate == FSTATE_FOUND)
-                       continue;
-               if (cf->cf_fstate == FSTATE_DNOTFOUND ||
-                   cf->cf_fstate == FSTATE_DSTAR)
-                       continue;
-               for (p = cf->cf_parents; *p >= 0; p++)
-                       if (parent->dv_cfdata == &cfdata[*p])
-                               mapply(&m, cf);
+
+       TAILQ_FOREACH(ct, &allcftables, ct_list) {
+               for (cf = ct->ct_cfdata; cf->cf_driver; cf++) {
+                       /*
+                        * Skip cf if no longer eligible, otherwise scan
+                        * through parents for one matching `parent', and
+                        * try match function.
+                        */
+                       if (cf->cf_fstate == FSTATE_FOUND)
+                               continue;
+                       if (cf->cf_fstate == FSTATE_DNOTFOUND ||
+                           cf->cf_fstate == FSTATE_DSTAR)
+                               continue;
+                       for (p = cf->cf_parents; *p >= 0; p++)
+                               if (parent->dv_cfdata == &(ct->ct_cfdata)[*p])
+                                       mapply(&m, cf);
+               }
        }
        return (m.match);
 }
@@ -252,6 +269,8 @@
 /*
  * Find the given root device.
  * This is much like config_search, but there is no parent.
+ * Don't bother with multiple cfdata tables; the root node
+ * must always be in the initial table.
  */
 struct cfdata *
 config_rootsearch(cfmatch_t fn, const char *rootname, void *aux)
@@ -373,6 +392,7 @@
        cfprint_t print)
 {
        struct device *dev;
+       struct cftable *ct;
        struct cfdriver *cd;
        struct cfattach *ca;
        size_t lname, lunit;
@@ -448,15 +468,19 @@
 #ifdef __BROKEN_CONFIG_UNIT_USAGE
        /* bump the unit number on all starred cfdata for this device. */
 #endif /* __BROKEN_CONFIG_UNIT_USAGE */
-       for (cf = cfdata; cf->cf_driver; cf++)
-               if (cf->cf_driver == cd && cf->cf_unit == dev->dv_unit) {
-                       if (cf->cf_fstate == FSTATE_NOTFOUND)
-                               cf->cf_fstate = FSTATE_FOUND;
+       TAILQ_FOREACH(ct, &allcftables, ct_list) {
+               for (cf = ct->ct_cfdata; cf->cf_driver; cf++) {
+                       if (cf->cf_driver == cd &&
+                           cf->cf_unit == dev->dv_unit) {
+                               if (cf->cf_fstate == FSTATE_NOTFOUND)
+                                       cf->cf_fstate = FSTATE_FOUND;
 #ifdef __BROKEN_CONFIG_UNIT_USAGE
-                       if (cf->cf_fstate == FSTATE_STAR)
-                               cf->cf_unit++;
+                               if (cf->cf_fstate == FSTATE_STAR)
+                                       cf->cf_unit++;
 #endif /* __BROKEN_CONFIG_UNIT_USAGE */
+                       }
                }
+       }
 #ifdef __HAVE_DEVICE_REGISTER
        device_register(dev, aux);
 #endif
@@ -477,6 +501,7 @@
 int
 config_detach(struct device *dev, int flags)
 {
+       struct cftable *ct;
        struct cfdata *cf;
        struct cfattach *ca;
        struct cfdriver *cd;
@@ -551,16 +576,18 @@
         * being detached had the last assigned unit number.
         */
 #endif /* __BROKEN_CONFIG_UNIT_USAGE */
-       for (cf = cfdata; cf->cf_driver; cf++) {
-               if (cf->cf_driver == cd) {
-                       if (cf->cf_fstate == FSTATE_FOUND &&
-                           cf->cf_unit == dev->dv_unit)
-                               cf->cf_fstate = FSTATE_NOTFOUND;
+       TAILQ_FOREACH(ct, &allcftables, ct_list) {
+               for (cf = ct->ct_cfdata; cf->cf_driver; cf++) {
+                       if (cf->cf_driver == cd) {
+                               if (cf->cf_fstate == FSTATE_FOUND &&
+                                   cf->cf_unit == dev->dv_unit)
+                                       cf->cf_fstate = FSTATE_NOTFOUND;
 #ifdef __BROKEN_CONFIG_UNIT_USAGE
-                       if (cf->cf_fstate == FSTATE_STAR &&
-                           cf->cf_unit == dev->dv_unit + 1)
-                               cf->cf_unit--;
+                               if (cf->cf_fstate == FSTATE_STAR &&
+                                   cf->cf_unit == dev->dv_unit + 1)
+                                       cf->cf_unit--;
 #endif /* __BROKEN_CONFIG_UNIT_USAGE */
+                       }
                }
        }
 
diff -r 2b59b34790b6 -r 91768b309d9b sys/sys/device.h
--- a/sys/sys/device.h  Mon Sep 23 21:35:42 2002 +0000
+++ b/sys/sys/device.h  Mon Sep 23 23:16:06 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: device.h,v 1.49 2002/02/15 11:18:26 simonb Exp $ */
+/* $NetBSD: device.h,v 1.50 2002/09/23 23:16:07 thorpej Exp $ */
 
 /*
  * Copyright (c) 1996, 2000 Christopher G. Demetriou
@@ -180,6 +180,16 @@
 #define FSTATE_DSTAR           3       /* has not been found, and disabled */
 #define FSTATE_DNOTFOUND       4       /* duplicate, and disabled */
 
+/*
+ * Multiple configuration data tables may be maintained.  This structure
+ * provides the linkage.
+ */
+struct cftable {
+       struct cfdata *ct_cfdata;       /* pointer to cfdata table */
+       TAILQ_ENTRY(cftable) ct_list;   /* list linkage */
+};
+TAILQ_HEAD(cftablelist, cftable);
+
 typedef int (*cfmatch_t)(struct device *, struct cfdata *, void *);
 
 /*
@@ -211,7 +221,7 @@
 
 struct cfdriver {
        void    **cd_devs;              /* devices found */
-       char    *cd_name;               /* device name */
+       const char *cd_name;            /* device name */
        enum    devclass cd_class;      /* device classification */
        int     cd_ndevs;               /* size of cd_devs array */
 };
@@ -239,6 +249,7 @@
 
 extern struct devicelist alldevs;      /* list of all devices */
 extern struct evcntlist allevents;     /* list of all event counters */
+extern struct cftablelist allcftables; /* list of all cfdata tables */
 extern struct device *booted_device;   /* the device we booted from */
 
 extern __volatile int config_pending;  /* semaphore for mountroot */



Home | Main Index | Thread Index | Old Index