tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
pseudoify cgd
Hello,
The attached diff is essentially a diff by David Young, which I
tweaked slightly (it wouldn't apply entirely against a more current
source tree).
The motivation for this was because I needed access to the cgd
device's device_t.
Does it look ok?
--
Kind regards,
Jan Danielsson
? arch/i386/conf/QEMUBASE
? arch/i386/conf/QEMUDBG
? dev/.cgd.c.swp
Index: dev/cgd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/cgd.c,v
retrieving revision 1.64
diff -u -r1.64 cgd.c
--- dev/cgd.c 10 Nov 2009 20:39:36 -0000 1.64
+++ dev/cgd.c 31 Dec 2009 22:04:24 -0000
@@ -76,13 +76,19 @@
nostop, notty, nopoll, nommap, nokqfilter, D_DISK
};
+static int cgd_match(device_t, cfdata_t, void *);
+static void cgd_attach(device_t, device_t, void *);
+static int cgd_detach(device_t, int);
+static struct cgd_softc *cgd_spawn(int);
+static int cgd_destroy(device_t);
+
/* Internal Functions */
static int cgdstart(struct dk_softc *, struct buf *);
static void cgdiodone(struct buf *);
static int cgd_ioctl_set(struct cgd_softc *, void *, struct lwp *);
-static int cgd_ioctl_clr(struct cgd_softc *, void *, struct lwp *);
+static int cgd_ioctl_clr(struct cgd_softc *, struct lwp *);
static int cgdinit(struct cgd_softc *, const char *, struct vnode *,
struct lwp *);
static void cgd_cipher(struct cgd_softc *, void *, void *,
@@ -105,6 +111,10 @@
.d_minphys = minphys,
};
+CFATTACH_DECL3_NEW(cgd, sizeof(struct cgd_softc),
+ cgd_match, cgd_attach, cgd_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
+extern struct cfdriver cgd_cd;
+
/* DIAGNOSTIC and DEBUG definitions */
#if defined(CGDDEBUG) && !defined(DEBUG)
@@ -140,7 +150,6 @@
/* Global variables */
-struct cgd_softc *cgd_softc;
int numcgd = 0;
/* Utility Functions */
@@ -148,53 +157,88 @@
#define CGDUNIT(x) DISKUNIT(x)
#define GETCGD_SOFTC(_cs, x) if (!((_cs) = getcgd_softc(x))) return ENXIO
+/* The code */
+
static struct cgd_softc *
getcgd_softc(dev_t dev)
{
int unit = CGDUNIT(dev);
+ struct cgd_softc *sc;
DPRINTF_FOLLOW(("getcgd_softc(0x%"PRIx64"): unit = %d\n", dev, unit));
- if (unit >= numcgd)
+ if (numcgd > 0 && unit >= numcgd)
return NULL;
- return &cgd_softc[unit];
+
+ sc = device_lookup_private(&cgd_cd, unit);
+ if (sc == NULL)
+ sc = cgd_spawn(unit);
+ return sc;
}
-/* The code */
+static int
+cgd_match(device_t self, cfdata_t cfdata, void *aux)
+{
+
+ return 1;
+}
static void
-cgdsoftc_init(struct cgd_softc *cs, int num)
+cgd_attach(device_t parent, device_t self, void *aux)
{
- char sbuf[DK_XNAME_SIZE];
+ struct cgd_softc *sc = device_private(self);
- memset(cs, 0x0, sizeof(*cs));
- snprintf(sbuf, DK_XNAME_SIZE, "cgd%d", num);
- simple_lock_init(&cs->sc_slock);
- dk_sc_init(&cs->sc_dksc, cs, sbuf);
- disk_init(&cs->sc_dksc.sc_dkdev, cs->sc_dksc.sc_xname, &cgddkdriver);
+ sc->sc_dev = self;
+ simple_lock_init(&sc->sc_slock);
+ dk_sc_init(&sc->sc_dksc, sc, device_xname(sc->sc_dev));
+ disk_init(&sc->sc_dksc.sc_dkdev, sc->sc_dksc.sc_xname, &cgddkdriver);
+}
+
+
+static int
+cgd_detach(device_t self, int flags)
+{
+ return 0;
}
void
cgdattach(int num)
{
- int i;
+ int error;
- DPRINTF_FOLLOW(("cgdattach(%d)\n", num));
- if (num <= 0) {
- DIAGPANIC(("cgdattach: count <= 0"));
- return;
- }
+ numcgd = num;
- cgd_softc = malloc(num * sizeof(*cgd_softc), M_DEVBUF, M_NOWAIT);
- if (!cgd_softc) {
- DPRINTF_FOLLOW(("WARNING: unable to malloc(9) memory for %d "
- "crypt disks\n", num));
- DIAGPANIC(("cgdattach: cannot malloc(9) enough memory"));
- return;
- }
+ error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
+ if (error != 0)
+ aprint_error("%s: unable to register cfattach\n",
+ cgd_cd.cd_name);
+}
- numcgd = num;
- for (i = 0; i < num; i++)
- cgdsoftc_init(&cgd_softc[i], i);
+static struct cgd_softc *
+cgd_spawn(int unit)
+{
+ cfdata_t cf;
+
+ cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
+ cf->cf_name = cgd_cd.cd_name;
+ cf->cf_atname = cgd_cd.cd_name;
+ cf->cf_unit = unit;
+ cf->cf_fstate = FSTATE_STAR;
+
+ return device_private(config_attach_pseudo(cf));
+}
+
+static int
+cgd_destroy(device_t dev)
+{
+ int error;
+ cfdata_t cf;
+
+ cf = device_cfdata(dev);
+ error = config_detach(dev, DETACH_QUIET);
+ if (error)
+ return error;
+ free(cf, M_DEVBUF);
+ return 0;
}
static int
@@ -210,11 +254,24 @@
static int
cgdclose(dev_t dev, int flags, int fmt, struct lwp *l)
{
+ int error;
struct cgd_softc *cs;
+ struct dk_softc *dksc;
DPRINTF_FOLLOW(("cgdclose(0x%"PRIx64", %d)\n", dev, flags));
GETCGD_SOFTC(cs, dev);
- return dk_close(di, &cs->sc_dksc, dev, flags, fmt, l);
+ dksc = &cs->sc_dksc;
+ if ((error = dk_close(di, dksc, dev, flags, fmt, l)) != 0)
+ return error;
+
+ if ((dksc->sc_flags & DKF_INITED) == 0) {
+ if ((error = cgd_destroy(cs->sc_dev)) != 0) {
+ aprint_error_dev(cs->sc_dev,
+ "unable to detach instance\n");
+ return error;
+ }
+ }
+ return 0;
}
static void
@@ -455,15 +512,11 @@
ret = cgd_ioctl_set(cs, data, l);
break;
case CGDIOCCLR:
- if (!(dksc->sc_flags & DKF_INITED)) {
- ret = ENXIO;
- break;
- }
- if (DK_BUSY(&cs->sc_dksc, pmask)) {
+
+ if (DK_BUSY(&cs->sc_dksc, pmask))
ret = EBUSY;
- break;
- }
- ret = cgd_ioctl_clr(cs, data, l);
+ else
+ ret = cgd_ioctl_clr(cs, l);
break;
case DIOCCACHESYNC:
@@ -605,7 +658,7 @@
disk_attach(&cs->sc_dksc.sc_dkdev);
/* Try and read the disklabel. */
- dk_getdisklabel(di, &cs->sc_dksc, 0 /* XXX ? */);
+ dk_getdisklabel(di, &cs->sc_dksc, 0 /* XXX ? (cause of PR 41704) */);
/* Discover wedges on this disk. */
dkwedge_discover(&cs->sc_dksc.sc_dkdev);
@@ -620,9 +673,15 @@
/* ARGSUSED */
static int
-cgd_ioctl_clr(struct cgd_softc *cs, void *data, struct lwp *l)
+cgd_ioctl_clr(struct cgd_softc *cs, struct lwp *l)
{
int s;
+ struct dk_softc *dksc;
+
+ dksc = &cs->sc_dksc;
+
+ if ((dksc->sc_flags & DKF_INITED) == 0)
+ return ENXIO;
/* Delete all of our wedges. */
dkwedge_delall(&cs->sc_dksc.sc_dkdev);
@@ -640,6 +699,7 @@
cs->sc_data_used = 0;
cs->sc_dksc.sc_flags &= ~DKF_INITED;
disk_detach(&cs->sc_dksc.sc_dkdev);
+ disk_destroy(&cs->sc_dksc.sc_dkdev);
return 0;
}
Index: dev/cgdvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/cgdvar.h,v
retrieving revision 1.13
diff -u -r1.13 cgdvar.h
--- dev/cgdvar.h 10 Nov 2009 20:05:50 -0000 1.13
+++ dev/cgdvar.h 31 Dec 2009 22:04:24 -0000
@@ -69,6 +69,7 @@
};
struct cgd_softc {
+ device_t sc_dev;
struct dk_softc sc_dksc; /* generic disk interface */
struct cryptinfo *sc_crypt; /* the alg/key/etc */
struct vnode *sc_tvn; /* target device's vnode */
Home |
Main Index |
Thread Index |
Old Index