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