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