tech-kern archive

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

Re: maj, min from device name



On Sun, Aug 30, 2009 at 08:51:01PM +0200, Jan Danielsson wrote:
> Hello,
> 
>    How does one convert a device string (for instance "cgd0a", "cgd1d")
> to/from a dev_t?
> 
>    For wd*, finddevice() (found in sys/kern/kern_subr.c) can be used --
> but it appears that cgd* aren't listed in alldevs, so it returns NULL.

I think that you're right, cgd(4) does not appear in alldevs.  It
should.  I wrote this patch for -current.  It compiles, but I haven't
tested it.  Can you give it a try and let me know?

Dave

-- 
David Young             OJC Technologies
dyoung%ojctech.com@localhost      Urbana, IL * (217) 278-3933
Index: cgd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/cgd.c,v
retrieving revision 1.58
diff -p -u -u -p -r1.58 cgd.c
--- cgd.c       5 Jun 2009 19:21:02 -0000       1.58
+++ cgd.c       30 Aug 2009 19:04:32 -0000
@@ -75,13 +75,19 @@ const struct cdevsw cgd_cdevsw = {
        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 *,
@@ -104,6 +110,10 @@ static struct dkdriver cgddkdriver = {
        .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)
@@ -139,7 +149,6 @@ static void hexprint(const char *, void 
 
 /* Global variables */
 
-struct cgd_softc *cgd_softc;
 int    numcgd = 0;
 
 /* Utility Functions */
@@ -147,52 +156,87 @@ int       numcgd = 0;
 #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);
+       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);
+
+       sc->sc_dev = 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);
+       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 = (void *)malloc(num * sizeof(*cgd_softc), M_DEVBUF, 
M_NOWAIT);
-       if (!cgd_softc) {
-               printf("WARNING: unable to malloc(9) memory for crypt disks\n");
-               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
@@ -208,11 +252,24 @@ cgdopen(dev_t dev, int flags, int fmt, s
 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
@@ -452,15 +509,11 @@ cgdioctl(dev_t dev, u_long cmd, void *da
                        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:
@@ -612,9 +665,15 @@ bail:
 
 /* 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);
@@ -632,6 +691,7 @@ cgd_ioctl_clr(struct cgd_softc *cs, void
        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: cgdvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/cgdvar.h,v
retrieving revision 1.12
diff -p -u -u -p -r1.12 cgdvar.h
--- cgdvar.h    12 Sep 2008 16:51:55 -0000      1.12
+++ cgdvar.h    30 Aug 2009 19:04:32 -0000
@@ -69,6 +69,7 @@ struct cryptdata {
 };
 
 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