Source-Changes-HG archive

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

[src/trunk]: src Overhaul the way cfattach structures are looked up. The cfd...



details:   https://anonhg.NetBSD.org/src/rev/c41dfef8f667
branches:  trunk
changeset: 537633:c41dfef8f667
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Fri Oct 04 01:50:53 2002 +0000

description:
Overhaul the way cfattach structures are looked up.  The cfdata entry
now carries the name of the attachment (e.g. "tlp_pci" or "audio"),
and cfattach structures are registered at boot time on a per-driver
basis.  The cfdriver and cfattach pointers are cached in the device
structure when attached.

diffstat:

 sys/arch/amiga/amiga/autoconf.c |   14 ++-
 sys/arch/atari/atari/autoconf.c |   12 +-
 sys/arch/x68k/x68k/autoconf.c   |   12 +-
 sys/kern/subr_autoconf.c        |  169 +++++++++++++++++++++++++++++++++------
 sys/kern/subr_userconf.c        |    8 +-
 sys/sys/device.h                |   30 +++++-
 usr.sbin/config/mkioconf.c      |   64 +++++++++++++-
 7 files changed, 251 insertions(+), 58 deletions(-)

diffs (truncated from 630 to 300 lines):

diff -r 31900689c631 -r c41dfef8f667 sys/arch/amiga/amiga/autoconf.c
--- a/sys/arch/amiga/amiga/autoconf.c   Fri Oct 04 00:50:15 2002 +0000
+++ b/sys/arch/amiga/amiga/autoconf.c   Fri Oct 04 01:50:53 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: autoconf.c,v 1.85 2002/10/02 04:55:47 thorpej Exp $    */
+/*     $NetBSD: autoconf.c,v 1.86 2002/10/04 01:50:54 thorpej Exp $    */
 
 /*
  * Copyright (c) 1994 Christian E. Hopps
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.85 2002/10/02 04:55:47 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.86 2002/10/04 01:50:54 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -166,6 +166,7 @@
 {
        struct device temp;
        struct cfdata *cf;
+       const struct cfattach *ca;
 
        if (amiga_realconfig)
                return(config_found(pdp, auxp, pfn) != NULL);
@@ -175,9 +176,12 @@
 
        pdp->dv_cfdata = pcfp;
        if ((cf = config_search((cfmatch_t)NULL, pdp, auxp)) != NULL) {
-               cf->cf_attach->ca_attach(pdp, NULL, auxp);
-               pdp->dv_cfdata = NULL;
-               return(1);
+               ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
+               if (ca != NULL) {
+                       (*ca->ca_attach)(pdp, NULL, auxp);
+                       pdp->dv_cfdata = NULL;
+                       return(1);
+               }
        }
        pdp->dv_cfdata = NULL;
        return(0);
diff -r 31900689c631 -r c41dfef8f667 sys/arch/atari/atari/autoconf.c
--- a/sys/arch/atari/atari/autoconf.c   Fri Oct 04 00:50:15 2002 +0000
+++ b/sys/arch/atari/atari/autoconf.c   Fri Oct 04 01:50:53 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: autoconf.c,v 1.40 2002/10/02 05:04:24 thorpej Exp $    */
+/*     $NetBSD: autoconf.c,v 1.41 2002/10/04 01:50:55 thorpej Exp $    */
 
 /*
  * Copyright (c) 1995 Leo Weppelman
@@ -98,6 +98,7 @@
 {
        struct device temp;
        struct cfdata *cf;
+       const struct cfattach *ca;
        extern int      atari_realconfig;
 
        if (atari_realconfig)
@@ -108,9 +109,12 @@
 
        pdp->dv_cfdata = pcfp;
        if ((cf = config_search((cfmatch_t)NULL, pdp, auxp)) != NULL) {
-               cf->cf_attach->ca_attach(pdp, NULL, auxp);
-               pdp->dv_cfdata = NULL;
-               return(1);
+               ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
+               if (ca != NULL) {
+                       (*ca->ca_attach)(pdp, NULL, auxp);
+                       pdp->dv_cfdata = NULL;
+                       return(1);
+               }
        }
        pdp->dv_cfdata = NULL;
        return(0);
diff -r 31900689c631 -r c41dfef8f667 sys/arch/x68k/x68k/autoconf.c
--- a/sys/arch/x68k/x68k/autoconf.c     Fri Oct 04 00:50:15 2002 +0000
+++ b/sys/arch/x68k/x68k/autoconf.c     Fri Oct 04 01:50:53 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: autoconf.c,v 1.33 2002/10/02 16:02:44 thorpej Exp $    */
+/*     $NetBSD: autoconf.c,v 1.34 2002/10/04 01:50:55 thorpej Exp $    */
 
 /*
  * Copyright (c) 1995 Leo Weppelman
@@ -117,6 +117,7 @@
 {
        struct device temp;
        struct cfdata *cf;
+       const struct cfattach *ca;
 
        if (x68k_realconfig)
                return(config_found(pdp, auxp, pfn) != NULL);
@@ -126,9 +127,12 @@
 
        pdp->dv_cfdata = pcfp;
        if ((cf = config_search((cfmatch_t)NULL, pdp, auxp)) != NULL) {
-               cf->cf_attach->ca_attach(pdp, NULL, auxp);
-               pdp->dv_cfdata = NULL;
-               return(1);
+               ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
+               if (ca != NULL) {
+                       (*ca->ca_attach)(pdp, NULL, auxp);
+                       pdp->dv_cfdata = NULL;
+                       return(1);
+               }
        }
        pdp->dv_cfdata = NULL;
        return(0);
diff -r 31900689c631 -r c41dfef8f667 sys/kern/subr_autoconf.c
--- a/sys/kern/subr_autoconf.c  Fri Oct 04 00:50:15 2002 +0000
+++ b/sys/kern/subr_autoconf.c  Fri Oct 04 01:50:53 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_autoconf.c,v 1.75 2002/10/01 18:11:58 thorpej Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.76 2002/10/04 01:50:53 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.75 2002/10/01 18:11:58 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.76 2002/10/04 01:50:53 thorpej Exp $");
 
 #include "opt_ddb.h"
 
@@ -119,6 +119,11 @@
 extern struct cfdriver * const cfdriver_list_initial[];
 
 /*
+ * Initial list of cfattach's.
+ */
+extern const struct cfattachinit cfattachinit[];
+
+/*
  * List of cfdata tables.  We always have one such list -- the one
  * built statically when the kernel was configured.
  */
@@ -182,16 +187,29 @@
 void
 config_init(void)
 {
-       int i;
+       const struct cfattachinit *cfai;
+       int i, j;
 
        if (config_initialized)
                return;
 
        /* allcfdrivers is statically initialized. */
-       for (i = 0; cfdriver_list_initial[i] != NULL; i++)
+       for (i = 0; cfdriver_list_initial[i] != NULL; i++) {
                if (config_cfdriver_attach(cfdriver_list_initial[i]) != 0)
                        panic("configure: duplicate `%s' drivers",
                            cfdriver_list_initial[i]->cd_name);
+       }
+
+       for (cfai = &cfattachinit[0]; cfai->cfai_name != NULL; cfai++) {
+               for (j = 0; cfai->cfai_list[j] != NULL; j++) {
+                       if (config_cfattach_attach(cfai->cfai_name,
+                                                  cfai->cfai_list[j]) != 0)
+                               panic("configure: duplicate `%s' attachment "
+                                   "of `%s' driver",
+                                   cfai->cfai_list[j]->ca_name,
+                                   cfai->cfai_name);
+               }
+       }
 
        TAILQ_INIT(&allcftables);
        initcftable.ct_cfdata = cfdata;
@@ -257,6 +275,7 @@
                        return (EEXIST);
        }
 
+       LIST_INIT(&cd->cd_attach);
        LIST_INSERT_HEAD(&allcfdrivers, cd, cd_list);
 
        return (0);
@@ -276,6 +295,10 @@
                        return (EBUSY);
        }
 
+       /* ...and no attachments loaded. */
+       if (LIST_EMPTY(&cd->cd_attach) == 0)
+               return (EBUSY);
+
        LIST_REMOVE(cd, cd_list);
 
        KASSERT(cd->cd_devs == NULL);
@@ -291,21 +314,6 @@
 {
        struct cfdriver *cd;
 
-       /*
-        * It is sometimes necessary to use the autoconfiguration
-        * framework quite early (e.g. to initialize the console).
-        * We support this by noticing an empty cfdriver list and
-        * searching the initial static list instead.
-        */
-       if (LIST_EMPTY(&allcfdrivers)) {
-               int i;
-
-               for (i = 0; cfdriver_list_initial[i] != NULL; i++) {
-                       if (STREQ(cfdriver_list_initial[i]->cd_name, name))
-                               return (cfdriver_list_initial[i]);
-               }
-       }
-
        LIST_FOREACH(cd, &allcfdrivers, cd_list) {
                if (STREQ(cd->cd_name, name))
                        return (cd);
@@ -315,6 +323,88 @@
 }
 
 /*
+ * Add a cfattach to the specified driver.
+ */
+int
+config_cfattach_attach(const char *driver, struct cfattach *ca)
+{
+       struct cfattach *lca;
+       struct cfdriver *cd;
+
+       cd = config_cfdriver_lookup(driver);
+       if (cd == NULL)
+               return (ESRCH);
+
+       /* Make sure this attachment isn't already on this driver. */
+       LIST_FOREACH(lca, &cd->cd_attach, ca_list) {
+               if (STREQ(lca->ca_name, ca->ca_name))
+                       return (EEXIST);
+       }
+
+       LIST_INSERT_HEAD(&cd->cd_attach, ca, ca_list);
+
+       return (0);
+}
+
+/*
+ * Remove a cfattach from the specified driver.
+ */
+int
+config_cfattach_detach(const char *driver, struct cfattach *ca)
+{
+       struct cfdriver *cd;
+       struct device *dev;
+       int i;
+
+       cd = config_cfdriver_lookup(driver);
+       if (cd == NULL)
+               return (ESRCH);
+
+       /* Make sure there are no active instances. */
+       for (i = 0; i < cd->cd_ndevs; i++) {
+               if ((dev = cd->cd_devs[i]) == NULL)
+                       continue;
+               if (STREQ(dev->dv_cfdata->cf_atname, ca->ca_name))
+                       return (EBUSY);
+       }
+
+       LIST_REMOVE(ca, ca_list);
+
+       return (0);
+}
+
+/*
+ * Look up a cfattach by name.
+ */
+static struct cfattach *
+config_cfattach_lookup_cd(struct cfdriver *cd, const char *atname)
+{
+       struct cfattach *ca;
+
+       LIST_FOREACH(ca, &cd->cd_attach, ca_list) {
+               if (STREQ(ca->ca_name, atname))
+                       return (ca);
+       }
+
+       return (NULL);
+}
+
+/*
+ * Look up a cfattach by driver/attachment name.
+ */
+struct cfattach *
+config_cfattach_lookup(const char *name, const char *atname)
+{
+       struct cfdriver *cd;
+
+       cd = config_cfdriver_lookup(name);
+       if (cd == NULL)
+               return (NULL);
+
+       return (config_cfattach_lookup_cd(cd, atname));
+}
+
+/*
  * Apply the matching function and choose the best.  This is used
  * a few times and we want to keep the code small.
  */



Home | Main Index | Thread Index | Old Index