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