Source-Changes-HG archive

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

[src/trunk]: src/sys/dev - no limit on the number of ccd devices.



details:   https://anonhg.NetBSD.org/src/rev/d36a3d7f4847
branches:  trunk
changeset: 786372:d36a3d7f4847
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Apr 27 17:13:32 2013 +0000

description:
- no limit on the number of ccd devices.
- provide sysctl for getting information.

diffstat:

 sys/dev/ccd.c    |  320 +++++++++++++++++++++++++++++++++++++++++++++---------
 sys/dev/ccdvar.h |   16 ++-
 2 files changed, 278 insertions(+), 58 deletions(-)

diffs (truncated from 476 to 300 lines):

diff -r 0afd6b249c90 -r d36a3d7f4847 sys/dev/ccd.c
--- a/sys/dev/ccd.c     Sat Apr 27 17:12:36 2013 +0000
+++ b/sys/dev/ccd.c     Sat Apr 27 17:13:32 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ccd.c,v 1.143 2011/11/13 23:02:46 christos Exp $       */
+/*     $NetBSD: ccd.c,v 1.144 2013/04/27 17:13:32 christos Exp $       */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 1999, 2007, 2009 The NetBSD Foundation, Inc.
@@ -88,7 +88,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ccd.c,v 1.143 2011/11/13 23:02:46 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ccd.c,v 1.144 2013/04/27 17:13:32 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -114,6 +114,7 @@
 #include <sys/kauth.h>
 #include <sys/kthread.h>
 #include <sys/bufq.h>
+#include <sys/sysctl.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -205,10 +206,70 @@
 static void printiinfo(struct ccdiinfo *);
 #endif
 
-/* Publically visible for the benefit of libkvm and ccdconfig(8). */
-struct ccd_softc       *ccd_softc;
-const int              ccd_softc_elemsize = sizeof(struct ccd_softc);
-int                    numccd = 0;
+static LIST_HEAD(, ccd_softc) ccds = LIST_HEAD_INITIALIZER(ccds);
+static kmutex_t ccd_lock;
+
+static struct ccd_softc *
+ccdcreate(int unit) {
+       struct ccd_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
+       if (sc == NULL) {
+#ifdef DIAGNOSTIC
+               printf("%s: out of memory\n", __func__);
+#endif
+               return NULL;
+       }
+       /* Initialize per-softc structures. */
+       snprintf(sc->sc_xname, sizeof(sc->sc_xname), "ccd%d", unit);
+       mutex_init(&sc->sc_dvlock, MUTEX_DEFAULT, IPL_NONE);
+       sc->sc_iolock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
+       cv_init(&sc->sc_stop, "ccdstop");
+       cv_init(&sc->sc_push, "ccdthr");
+       disk_init(&sc->sc_dkdev, sc->sc_xname, NULL); /* XXX */
+       return sc;
+}
+
+static void
+ccddestroy(struct ccd_softc *sc) {
+       mutex_obj_free(sc->sc_iolock);
+       mutex_destroy(&sc->sc_dvlock);
+       cv_destroy(&sc->sc_stop);
+       cv_destroy(&sc->sc_push);
+       disk_destroy(&sc->sc_dkdev);
+       kmem_free(sc, sizeof(*sc));
+}
+
+static struct ccd_softc *
+ccdget(int unit) {
+       struct ccd_softc *sc;
+       if (unit < 0) {
+#ifdef DIAGNOSTIC
+               panic("%s: unit %d!", __func__, unit);
+#endif
+               return NULL;
+       }
+       mutex_enter(&ccd_lock);
+       LIST_FOREACH(sc, &ccds, sc_link) {
+               if (sc->sc_unit == unit) {
+                       mutex_exit(&ccd_lock);
+                       return sc;
+               }
+       }
+       mutex_exit(&ccd_lock);
+       if ((sc = ccdcreate(unit)) == NULL)
+               return NULL;
+       mutex_enter(&ccd_lock);
+       LIST_INSERT_HEAD(&ccds, sc, sc_link);
+       mutex_exit(&ccd_lock);
+       return sc;
+}
+
+static void 
+ccdput(struct ccd_softc *sc) {
+       mutex_enter(&ccd_lock);
+       LIST_REMOVE(sc, sc_link);
+       mutex_exit(&ccd_lock);
+       ccddestroy(sc);
+}
 
 /*
  * Called by main() during pseudo-device attachment.  All we need
@@ -217,37 +278,11 @@
 void
 ccdattach(int num)
 {
-       struct ccd_softc *cs;
-       int i;
-
-       if (num <= 0) {
-#ifdef DIAGNOSTIC
-               panic("ccdattach: count <= 0");
-#endif
-               return;
-       }
-
-       ccd_softc = kmem_zalloc(num * ccd_softc_elemsize, KM_SLEEP);
-       if (ccd_softc == NULL) {
-               printf("WARNING: no memory for concatenated disks\n");
-               return;
-       }
-       numccd = num;
+       mutex_init(&ccd_lock, MUTEX_DEFAULT, IPL_NONE);
 
        /* Initialize the component buffer pool. */
        ccd_cache = pool_cache_init(sizeof(struct ccdbuf), 0,
            0, 0, "ccdbuf", NULL, IPL_BIO, NULL, NULL, NULL);
-
-       /* Initialize per-softc structures. */
-       for (i = 0; i < num; i++) {
-               cs = &ccd_softc[i];
-               snprintf(cs->sc_xname, sizeof(cs->sc_xname), "ccd%d", i);
-               mutex_init(&cs->sc_dvlock, MUTEX_DEFAULT, IPL_NONE);
-               cs->sc_iolock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
-               cv_init(&cs->sc_stop, "ccdstop");
-               cv_init(&cs->sc_push, "ccdthr");
-               disk_init(&cs->sc_dkdev, cs->sc_xname, NULL); /* XXX */
-       }
 }
 
 static int
@@ -545,9 +580,8 @@
        if (ccddebug & CCDB_FOLLOW)
                printf("ccdopen(0x%"PRIx64", 0x%x)\n", dev, flags);
 #endif
-       if (unit >= numccd)
-               return (ENXIO);
-       cs = &ccd_softc[unit];
+       if ((cs = ccdget(unit)) == NULL)
+               return ENXIO;
 
        mutex_enter(&cs->sc_dvlock);
 
@@ -607,9 +641,8 @@
                printf("ccdclose(0x%"PRIx64", 0x%x)\n", dev, flags);
 #endif
 
-       if (unit >= numccd)
-               return (ENXIO);
-       cs = &ccd_softc[unit];
+       if ((cs = ccdget(unit)) == NULL)
+               return ENXIO;
 
        mutex_enter(&cs->sc_dvlock);
 
@@ -690,7 +723,9 @@
 ccdstrategy(struct buf *bp)
 {
        int unit = ccdunit(bp->b_dev);
-       struct ccd_softc *cs = &ccd_softc[unit];
+       struct ccd_softc *cs;
+       if ((cs = ccdget(unit)) == NULL)
+               return;
 
        /* Must be open or reading label. */
        KASSERT(cs->sc_dkdev.dk_openmask != 0 ||
@@ -975,9 +1010,8 @@
        if (ccddebug & CCDB_FOLLOW)
                printf("ccdread(0x%"PRIx64", %p)\n", dev, uio);
 #endif
-       if (unit >= numccd)
-               return (ENXIO);
-       cs = &ccd_softc[unit];
+       if ((cs = ccdget(unit)) == NULL)
+               return 0;
 
        /* Unlocked advisory check, ccdstrategy check is synchronous. */
        if ((cs->sc_flags & CCDF_INITED) == 0)
@@ -997,9 +1031,8 @@
        if (ccddebug & CCDB_FOLLOW)
                printf("ccdwrite(0x%"PRIx64", %p)\n", dev, uio);
 #endif
-       if (unit >= numccd)
-               return (ENXIO);
-       cs = &ccd_softc[unit];
+       if ((cs = ccdget(unit)) == NULL)
+               return ENOENT;
 
        /* Unlocked advisory check, ccdstrategy check is synchronous. */
        if ((cs->sc_flags & CCDF_INITED) == 0)
@@ -1024,9 +1057,8 @@
        struct disklabel newlabel;
 #endif
 
-       if (unit >= numccd)
-               return (ENXIO);
-       cs = &ccd_softc[unit];
+       if ((cs = ccdget(unit)) == NULL)
+               return ENOENT;
        uc = kauth_cred_get();
 
        /* Must be open for writes for these commands... */
@@ -1238,6 +1270,7 @@
                /* Detatch the disk. */
                disk_detach(&cs->sc_dkdev);
                bufq_free(cs->sc_bufq);
+               ccdput(cs);
                break;
 
        case DIOCGDINFO:
@@ -1359,9 +1392,8 @@
        int part, unit, omask, size;
 
        unit = ccdunit(dev);
-       if (unit >= numccd)
-               return (-1);
-       cs = &ccd_softc[unit];
+       if ((cs = ccdget(unit)) == NULL)
+               return -1;
 
        if ((cs->sc_flags & CCDF_INITED) == 0)
                return (-1);
@@ -1424,11 +1456,15 @@
 ccdgetdisklabel(dev_t dev)
 {
        int unit = ccdunit(dev);
-       struct ccd_softc *cs = &ccd_softc[unit];
+       struct ccd_softc *cs;
        const char *errstring;
-       struct disklabel *lp = cs->sc_dkdev.dk_label;
-       struct cpu_disklabel *clp = cs->sc_dkdev.dk_cpulabel;
+       struct disklabel *lp;
+       struct cpu_disklabel *clp;
 
+       if ((cs = ccdget(unit)) == NULL)
+               return;
+       lp = cs->sc_dkdev.dk_label;
+       clp = cs->sc_dkdev.dk_cpulabel;
        KASSERT(mutex_owned(&cs->sc_dvlock));
 
        memset(clp, 0, sizeof(*clp));
@@ -1553,3 +1589,177 @@
 
        return error;
 }
+
+static int
+ccd_units_sysctl(SYSCTLFN_ARGS)
+{
+       struct sysctlnode node;
+       struct ccd_softc *sc;
+       int error, i, nccd, *units;
+       size_t size;
+
+       nccd = 0;
+       mutex_enter(&ccd_lock);
+       LIST_FOREACH(sc, &ccds, sc_link)
+               nccd++;
+       mutex_exit(&ccd_lock);
+
+       if (nccd != 0) {
+               size = nccd * sizeof(*units);
+               units = kmem_zalloc(size, KM_SLEEP);
+               if (units == NULL)
+                       return ENOMEM;
+
+               i = 0;
+               mutex_enter(&ccd_lock);
+               LIST_FOREACH(sc, &ccds, sc_link) {
+                       if (i >= nccd)
+                               break;
+                       units[i] = sc->sc_unit;
+               }
+               mutex_exit(&ccd_lock);
+       } else {
+               units = NULL;
+               size = 0;
+       }
+
+       node = *rnode;
+       node.sysctl_data = units;
+       node.sysctl_size = size;
+
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (units)
+               kmem_free(units, size);
+       return error;
+}
+
+static int
+ccd_info_sysctl(SYSCTLFN_ARGS)



Home | Main Index | Thread Index | Old Index