Index: sys/disk.h =================================================================== RCS file: /cvsroot/src/sys/sys/disk.h,v retrieving revision 1.63 diff -u -r1.63 disk.h --- sys/disk.h 31 Dec 2014 20:13:41 -0000 1.63 +++ sys/disk.h 26 Apr 2015 20:31:27 -0000 @@ -470,18 +470,18 @@ struct cpu_disklabel *dk_cpulabel; }; +#ifdef _KERNEL struct dkdriver { void (*d_strategy)(struct buf *); void (*d_minphys)(struct buf *); -#ifdef notyet - int (*d_open)(dev_t, int, int, struct proc *); - int (*d_close)(dev_t, int, int, struct proc *); - int (*d_ioctl)(dev_t, u_long, void *, int, struct proc *); - int (*d_dump)(dev_t); - void (*d_start)(struct buf *, daddr_t); - int (*d_mklabel)(struct disk *); -#endif + int (*d_open)(dev_t, int, int, struct lwp *); + int (*d_close)(dev_t, int, int, struct lwp *); + void (*d_diskstart)(device_t); + void (*d_iosize)(device_t, int *); + int (*d_dumpblocks)(device_t, void *, daddr_t, int); + int (*d_lastclose)(device_t); }; +#endif /* states */ #define DK_CLOSED 0 /* drive is closed */ Index: dev/dksubr.c =================================================================== RCS file: /cvsroot/src/sys/dev/dksubr.c,v retrieving revision 1.58 diff -u -r1.58 dksubr.c --- dev/dksubr.c 31 Dec 2014 19:52:05 -0000 1.58 +++ dev/dksubr.c 26 Apr 2015 20:31:28 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include /* for v_rdev */ @@ -71,20 +72,35 @@ #define DKLABELDEV(dev) \ (MAKEDISKDEV(major((dev)), DISKUNIT((dev)), RAW_PART)) -static void dk_makedisklabel(struct dk_intf *, struct dk_softc *); +static void dk_makedisklabel(struct dk_softc *); void -dk_sc_init(struct dk_softc *dksc, const char *xname) +dk_init(struct dk_softc *dksc, device_t dev, int dtype) { memset(dksc, 0x0, sizeof(*dksc)); - strncpy(dksc->sc_xname, xname, DK_XNAME_SIZE); + dksc->sc_dtype = dtype; + dksc->sc_dev = dev; + + strncpy(dksc->sc_xname, device_xname(dev), DK_XNAME_SIZE); dksc->sc_dkdev.dk_name = dksc->sc_xname; } +void +dk_attach(struct dk_softc *dksc) +{ + dksc->sc_flags |= DKF_INITED | DKF_WARNLABEL | DKF_LABELSANITY; +} + +void +dk_detach(struct dk_softc *dksc) +{ + dksc->sc_flags &= ~DKF_INITED; +} + /* ARGSUSED */ int -dk_open(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, +dk_open(struct dk_softc *dksc, dev_t dev, int flags, int fmt, struct lwp *l) { struct disklabel *lp = dksc->sc_dkdev.dk_label; @@ -94,7 +110,7 @@ struct disk *dk = &dksc->sc_dkdev; DPRINTF_FOLLOW(("dk_open(%s, %p, 0x%"PRIx64", 0x%x)\n", - di->di_dkname, dksc, dev, flags)); + dksc->sc_xname, dksc, dev, flags)); mutex_enter(&dk->dk_openlock); part = DISKPART(dev); @@ -115,17 +131,17 @@ * update the in-core disklabel. */ if ((dksc->sc_flags & DKF_INITED)) { - if (dk->dk_openmask == 0) { - dk_getdisklabel(di, dksc, dev); + if ((dksc->sc_flags & DKF_VLABEL) == 0) { + dksc->sc_flags |= DKF_VLABEL; + dk_getdisklabel(dksc, dev); } - /* XXX re-discover wedges? */ } /* Fail if we can't find the partition. */ - if ((part != RAW_PART) && - (((dksc->sc_flags & DKF_INITED) == 0) || - ((part >= lp->d_npartitions) || - (lp->d_partitions[part].p_fstype == FS_UNUSED)))) { + if (part != RAW_PART && + ((dksc->sc_flags & DKF_VLABEL) == 0 || + part >= lp->d_npartitions || + lp->d_partitions[part].p_fstype == FS_UNUSED)) { ret = ENXIO; goto done; } @@ -149,15 +165,16 @@ /* ARGSUSED */ int -dk_close(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, +dk_close(struct dk_softc *dksc, dev_t dev, int flags, int fmt, struct lwp *l) { + const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver; int part = DISKPART(dev); int pmask = 1 << part; struct disk *dk = &dksc->sc_dkdev; DPRINTF_FOLLOW(("dk_close(%s, %p, 0x%"PRIx64", 0x%x)\n", - di->di_dkname, dksc, dev, flags)); + dksc->sc_xname, dksc, dev, flags)); mutex_enter(&dk->dk_openlock); @@ -171,13 +188,22 @@ } dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask; + if (dk->dk_openmask == 0) { + if (dkd->d_lastclose != NULL) + (*dkd->d_lastclose)(dksc->sc_dev); + } + + if ((dksc->sc_flags & DKF_KLABEL) == 0) + dksc->sc_flags &= ~DKF_VLABEL; + mutex_exit(&dk->dk_openlock); return 0; } void -dk_strategy(struct dk_intf *di, struct dk_softc *dksc, struct buf *bp) +dk_strategy(struct dk_softc *dksc, struct buf *bp) { + const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver; int s, part; int wlabel; daddr_t blkno; @@ -187,7 +213,7 @@ unsigned secsize; DPRINTF_FOLLOW(("dk_strategy(%s, %p, %p)\n", - di->di_dkname, dksc, bp)); + dksc->sc_xname, dksc, bp)); if (!(dksc->sc_flags & DKF_INITED)) { DPRINTF_FOLLOW(("dk_strategy: not inited\n")); @@ -245,14 +271,33 @@ */ s = splbio(); bufq_put(dksc->sc_bufq, bp); - di->di_diskstart(dksc); + dkd->d_diskstart(dksc->sc_dev); splx(s); return; } +void +dk_done(struct dk_softc *dksc, struct buf *bp) +{ + struct disk *dk = &dksc->sc_dkdev; + + if (bp->b_error != 0) { + diskerr(bp, dksc->sc_xname, "error", LOG_PRINTF, 0, + dk->dk_label); + printf("\n"); + } + + disk_unbusy(dk, bp->b_bcount - bp->b_resid, (bp->b_flags & B_READ)); +#ifdef notyet + rnd_add_uint(&dksc->sc_rnd_source, bp->b_rawblkno); +#endif + biodone(bp); +} + int -dk_size(struct dk_intf *di, struct dk_softc *dksc, dev_t dev) +dk_size(struct dk_softc *dksc, dev_t dev) { + const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver; struct disklabel *lp; int is_open; int part; @@ -264,7 +309,7 @@ part = DISKPART(dev); is_open = dksc->sc_dkdev.dk_openmask & (1 << part); - if (!is_open && di->di_open(dev, 0, S_IFBLK, curlwp)) + if (!is_open && dkd->d_open(dev, 0, S_IFBLK, curlwp)) return -1; lp = dksc->sc_dkdev.dk_label; @@ -274,16 +319,17 @@ size = lp->d_partitions[part].p_size * (lp->d_secsize / DEV_BSIZE); - if (!is_open && di->di_close(dev, 0, S_IFBLK, curlwp)) + if (!is_open && dkd->d_close(dev, 0, S_IFBLK, curlwp)) return 1; return size; } int -dk_ioctl(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, +dk_ioctl(struct dk_softc *dksc, dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { + const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver; struct disklabel *lp; struct disk *dk = &dksc->sc_dkdev; #ifdef __HAVE_OLD_DISKLABEL @@ -292,7 +338,7 @@ int error; DPRINTF_FOLLOW(("dk_ioctl(%s, %p, 0x%"PRIx64", 0x%lx)\n", - di->di_dkname, dksc, dev, cmd)); + dksc->sc_xname, dksc, dev, cmd)); /* ensure that the pseudo disk is open for writes for these commands */ switch (cmd) { @@ -315,6 +361,7 @@ case DIOCSDINFO: case DIOCWDINFO: case DIOCGPART: + case DIOCKLABEL: case DIOCWLABEL: case DIOCGDEFLABEL: case DIOCAWEDGE: @@ -366,7 +413,7 @@ #endif ) error = writedisklabel(DKLABELDEV(dev), - di->di_strategy, dksc->sc_dkdev.dk_label, + dkd->d_strategy, dksc->sc_dkdev.dk_label, dksc->sc_dkdev.dk_cpulabel); } @@ -374,6 +421,15 @@ mutex_exit(&dk->dk_openlock); break; + case DIOCKLABEL: + if ((flag & FWRITE) == 0) + return (EBADF); + if (*(int *)data != 0) + dksc->sc_flags |= DKF_KLABEL; + else + dksc->sc_flags &= ~DKF_KLABEL; + break; + case DIOCWLABEL: if (*(int *)data != 0) dksc->sc_flags |= DKF_WLABEL; @@ -382,12 +438,12 @@ break; case DIOCGDEFLABEL: - dk_getdefaultlabel(di, dksc, (struct disklabel *)data); + dk_getdefaultlabel(dksc, (struct disklabel *)data); break; #ifdef __HAVE_OLD_DISKLABEL case ODIOCGDEFLABEL: - dk_getdefaultlabel(di, dksc, &newlabel); + dk_getdefaultlabel(dksc, &newlabel); if (newlabel.d_npartitions > OLDMAXPARTITIONS) return ENOTTY; memcpy(data, &newlabel, sizeof (struct olddisklabel)); @@ -449,7 +505,6 @@ * This requires substantially more framework than {s,w}ddump, and hence * is probably much more fragile. * - * XXX: we currently do not implement this. */ #define DKF_READYFORDUMP (DKF_INITED|DKF_TAKEDUMP) @@ -458,9 +513,14 @@ /* ARGSUSED */ int -dk_dump(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, - daddr_t blkno, void *va, size_t size) +dk_dump(struct dk_softc *dksc, dev_t dev, + daddr_t blkno, void *vav, size_t size) { + const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver; + char *va = vav; + struct disklabel *lp; + int part, towrt, nsects, sectoff, maxblkcnt, nblk; + int maxxfer, rv = 0; /* * ensure that we consider this device to be safe for dumping, @@ -474,17 +534,53 @@ return EFAULT; dk_dumping = 1; - /* XXX: unimplemented */ + if (dkd->d_dumpblocks == NULL) + return ENXIO; + + /* device specific max transfer size */ + maxxfer = MAXPHYS; + if (dkd->d_iosize != NULL) + (*dkd->d_iosize)(dksc->sc_dev, &maxxfer); + + /* Convert to disk sectors. Request must be a multiple of size. */ + part = DISKPART(dev); + lp = dksc->sc_dkdev.dk_label; + if ((size % lp->d_secsize) != 0) + return (EFAULT); + towrt = size / lp->d_secsize; + blkno = dbtob(blkno) / lp->d_secsize; /* blkno in secsize units */ + + nsects = lp->d_partitions[part].p_size; + sectoff = lp->d_partitions[part].p_offset; + + /* Check transfer bounds against partition size. */ + if ((blkno < 0) || ((blkno + towrt) > nsects)) + return (EINVAL); + + /* Offset block number to start of partition. */ + blkno += sectoff; + + /* Start dumping and return when done. */ + maxblkcnt = howmany(maxxfer, lp->d_secsize); + while (towrt > 0) { + nblk = min(maxblkcnt, towrt); + + if ((rv = (*dkd->d_dumpblocks)(dksc->sc_dev, va, blkno, nblk)) != 0) + return (rv); + + towrt -= nblk; + blkno += nblk; + va += nblk * lp->d_secsize; + } dk_dumping = 0; - /* XXX: actually for now, we are going to leave this alone */ - return ENXIO; + return 0; } /* ARGSUSED */ void -dk_getdefaultlabel(struct dk_intf *di, struct dk_softc *dksc, +dk_getdefaultlabel(struct dk_softc *dksc, struct disklabel *lp) { struct disk_geom *dg = &dksc->sc_dkdev.dk_geom; @@ -501,8 +597,8 @@ lp->d_ncylinders = dg->dg_ncylinders; lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors; - strncpy(lp->d_typename, di->di_dkname, sizeof(lp->d_typename)); - lp->d_type = di->di_dtype; + strncpy(lp->d_typename, dksc->sc_xname, sizeof(lp->d_typename)); + lp->d_type = dksc->sc_dtype; strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname)); lp->d_rpm = 3600; lp->d_interleave = 1; @@ -520,21 +616,22 @@ /* ARGSUSED */ void -dk_getdisklabel(struct dk_intf *di, struct dk_softc *dksc, dev_t dev) +dk_getdisklabel(struct dk_softc *dksc, dev_t dev) { + const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver; struct disklabel *lp = dksc->sc_dkdev.dk_label; struct cpu_disklabel *clp = dksc->sc_dkdev.dk_cpulabel; - struct disk_geom *dg = &dksc->sc_dkdev.dk_geom; + struct disk_geom *dg = &dksc->sc_dkdev.dk_geom; struct partition *pp; int i; const char *errstring; memset(clp, 0x0, sizeof(*clp)); - dk_getdefaultlabel(di, dksc, lp); - errstring = readdisklabel(DKLABELDEV(dev), di->di_strategy, + dk_getdefaultlabel(dksc, lp); + errstring = readdisklabel(DKLABELDEV(dev), dkd->d_strategy, dksc->sc_dkdev.dk_label, dksc->sc_dkdev.dk_cpulabel); if (errstring) { - dk_makedisklabel(di, dksc); + dk_makedisklabel(dksc); if (dksc->sc_flags & DKF_WARNLABEL) printf("%s: %s\n", dksc->sc_xname, errstring); return; @@ -549,7 +646,7 @@ lp->d_secperunit > dg->dg_secperunit) printf("WARNING: %s: total sector size in disklabel (%ju) " "!= the size of %s (%ju)\n", dksc->sc_xname, - (uintmax_t)lp->d_secperunit, di->di_dkname, + (uintmax_t)lp->d_secperunit, dksc->sc_xname, (uintmax_t)dg->dg_secperunit); for (i=0; i < lp->d_npartitions; i++) { @@ -557,14 +654,14 @@ if (pp->p_offset + pp->p_size > dg->dg_secperunit) printf("WARNING: %s: end of partition `%c' exceeds " "the size of %s (%ju)\n", dksc->sc_xname, - 'a' + i, di->di_dkname, + 'a' + i, dksc->sc_xname, (uintmax_t)dg->dg_secperunit); } } /* ARGSUSED */ static void -dk_makedisklabel(struct dk_intf *di, struct dk_softc *dksc) +dk_makedisklabel(struct dk_softc *dksc) { struct disklabel *lp = dksc->sc_dkdev.dk_label; Index: dev/dkvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/dkvar.h,v retrieving revision 1.19 diff -u -r1.19 dkvar.h --- dev/dkvar.h 25 May 2014 19:23:49 -0000 1.19 +++ dev/dkvar.h 26 Apr 2015 20:31:28 -0000 @@ -31,7 +31,6 @@ struct pathbuf; /* from namei.h */ - /* literally this is not a softc, but is intended to be included in * the pseudo-disk's softc and passed to calls in dksubr.c. It * should include the common elements of the pseudo-disk's softc. @@ -46,6 +45,7 @@ char sc_xname[DK_XNAME_SIZE]; /* external name */ struct disk sc_dkdev; /* generic disk info */ struct bufq_state *sc_bufq; /* buffer queue */ + int sc_dtype; /* disk type */ }; /* sc_flags: @@ -59,23 +59,13 @@ #define DKF_WARNLABEL 0x00080000 /* warn if disklabel not present */ #define DKF_LABELSANITY 0x00100000 /* warn if disklabel not sane */ #define DKF_TAKEDUMP 0x00200000 /* allow dumping */ +#define DKF_KLABEL 0x00400000 /* keep label on close */ +#define DKF_VLABEL 0x00800000 /* label is valid */ /* Mask of flags that dksubr.c understands, other flags are fair game */ #define DK_FLAGMASK 0xffff0000 -/* - * This defines the interface to the routines in dksubr.c. This - * should be a single static structure per pseudo-disk driver. - * We only define the functions that we currently need. - */ -struct dk_intf { - int di_dtype; /* disk type */ - const char *di_dkname; /* disk type name */ - int (*di_open)(dev_t, int, int, struct lwp *); - int (*di_close)(dev_t, int, int, struct lwp *); - void (*di_strategy)(struct buf *); - void (*di_diskstart)(struct dk_softc *); -}; +#define DK_ATTACHED(_dksc) ((_dksc)->sc_flags & DKF_INITED) #define DK_BUSY(_dksc, _pmask) \ (((_dksc)->sc_dkdev.dk_openmask & ~(_pmask)) || \ @@ -86,20 +76,22 @@ * Functions that are exported to the pseudo disk implementations: */ -void dk_sc_init(struct dk_softc *, const char *); +void dk_init(struct dk_softc *, device_t, int); +void dk_attach(struct dk_softc *); +void dk_detach(struct dk_softc *); -int dk_open(struct dk_intf *, struct dk_softc *, dev_t, +int dk_open(struct dk_softc *, dev_t, int, int, struct lwp *); -int dk_close(struct dk_intf *, struct dk_softc *, dev_t, +int dk_close(struct dk_softc *, dev_t, int, int, struct lwp *); -void dk_strategy(struct dk_intf *, struct dk_softc *, struct buf *); -int dk_size(struct dk_intf *, struct dk_softc *, dev_t); -int dk_ioctl(struct dk_intf *, struct dk_softc *, dev_t, +void dk_strategy(struct dk_softc *, struct buf *); +void dk_done(struct dk_softc *, struct buf *); +int dk_size(struct dk_softc *, dev_t); +int dk_ioctl(struct dk_softc *, dev_t, u_long, void *, int, struct lwp *); -int dk_dump(struct dk_intf *, struct dk_softc *, dev_t, +int dk_dump(struct dk_softc *, dev_t, daddr_t, void *, size_t); -void dk_getdisklabel(struct dk_intf *, struct dk_softc *, dev_t); -void dk_getdefaultlabel(struct dk_intf *, struct dk_softc *, - struct disklabel *); +void dk_getdisklabel(struct dk_softc *, dev_t); +void dk_getdefaultlabel(struct dk_softc *, struct disklabel *); int dk_lookup(struct pathbuf *, struct lwp *, struct vnode **); Index: dev/ld.c =================================================================== RCS file: /cvsroot/src/sys/dev/ld.c,v retrieving revision 1.82 diff -u -r1.82 ld.c --- dev/ld.c 13 Apr 2015 16:33:23 -0000 1.82 +++ dev/ld.c 26 Apr 2015 20:31:28 -0000 @@ -60,15 +60,16 @@ #include -static void ldgetdefaultlabel(struct ld_softc *, struct disklabel *); -static void ldgetdisklabel(struct ld_softc *); static void ldminphys(struct buf *bp); static bool ld_suspend(device_t, const pmf_qual_t *); static bool ld_shutdown(device_t, int); -static void ldstart(struct ld_softc *, struct buf *); +static void ld_start(device_t); +static void ld_iosize(device_t, int *); +static int ld_dumpblocks(device_t, void *, daddr_t, int); +static void ld_fake_geometry(struct ld_softc *); static void ld_set_geometry(struct ld_softc *); static void ld_config_interrupts (device_t); -static int ldlastclose(device_t); +static int ld_lastclose(device_t); extern struct cfdriver ld_cd; @@ -107,72 +108,59 @@ .d_flag = D_DISK }; -static struct dkdriver lddkdriver = { ldstrategy, ldminphys }; +static struct dkdriver lddkdriver = { + .d_open = ldopen, + .d_close = ldclose, + .d_strategy = ldstrategy, + .d_iosize = ld_iosize, + .d_minphys = ldminphys, + .d_diskstart = ld_start, + .d_dumpblocks = ld_dumpblocks, + .d_lastclose = ld_lastclose +}; void ldattach(struct ld_softc *sc) { - char tbuf[9]; + device_t self = sc->sc_dv; + struct dk_softc *dksc = &sc->sc_dksc; mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM); if ((sc->sc_flags & LDF_ENABLED) == 0) { - aprint_normal_dev(sc->sc_dv, "disabled\n"); return; } - /* Initialise and attach the disk structure. */ - disk_init(&sc->sc_dk, device_xname(sc->sc_dv), &lddkdriver); - disk_attach(&sc->sc_dk); + /* Initialise dk and disk structure. */ + dk_init(dksc, self, DKTYPE_LD); + disk_init(&dksc->sc_dkdev, dksc->sc_xname, &lddkdriver); + + /* Attach the device into the rnd source list. */ + rnd_attach_source(&sc->sc_rnd_source, dksc->sc_xname, + RND_TYPE_DISK, RND_FLAG_DEFAULT); if (sc->sc_maxxfer > MAXPHYS) sc->sc_maxxfer = MAXPHYS; /* Build synthetic geometry if necessary. */ if (sc->sc_nheads == 0 || sc->sc_nsectors == 0 || - sc->sc_ncylinders == 0) { - uint64_t ncyl; - - if (sc->sc_secperunit <= 528 * 2048) /* 528MB */ - sc->sc_nheads = 16; - else if (sc->sc_secperunit <= 1024 * 2048) /* 1GB */ - sc->sc_nheads = 32; - else if (sc->sc_secperunit <= 21504 * 2048) /* 21GB */ - sc->sc_nheads = 64; - else if (sc->sc_secperunit <= 43008 * 2048) /* 42GB */ - sc->sc_nheads = 128; - else - sc->sc_nheads = 255; + sc->sc_ncylinders == 0) + ld_fake_geometry(sc); - sc->sc_nsectors = 63; - sc->sc_ncylinders = INT_MAX; - ncyl = sc->sc_secperunit / - (sc->sc_nheads * sc->sc_nsectors); - if (ncyl < INT_MAX) - sc->sc_ncylinders = (int)ncyl; - } - - format_bytes(tbuf, sizeof(tbuf), sc->sc_secperunit * - sc->sc_secsize); - aprint_normal_dev(sc->sc_dv, "%s, %d cyl, %d head, %d sec, " - "%d bytes/sect x %"PRIu64" sectors\n", - tbuf, sc->sc_ncylinders, sc->sc_nheads, - sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit); sc->sc_disksize512 = sc->sc_secperunit * sc->sc_secsize / DEV_BSIZE; + /* Attach dk and disk subsystems */ + dk_attach(dksc); + disk_attach(&dksc->sc_dkdev); ld_set_geometry(sc); - /* Attach the device into the rnd source list. */ - rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dv), - RND_TYPE_DISK, RND_FLAG_DEFAULT); + bufq_alloc(&dksc->sc_bufq, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK); /* Register with PMF */ - if (!pmf_device_register1(sc->sc_dv, ld_suspend, NULL, ld_shutdown)) - aprint_error_dev(sc->sc_dv, + if (!pmf_device_register1(dksc->sc_dev, ld_suspend, NULL, ld_shutdown)) + aprint_error_dev(dksc->sc_dev, "couldn't establish power handler\n"); - bufq_alloc(&sc->sc_bufq, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK); - /* Discover wedges on this disk. */ config_interrupts(sc->sc_dv, ld_config_interrupts); } @@ -192,19 +180,22 @@ int ldbegindetach(struct ld_softc *sc, int flags) { + struct dk_softc *dksc = &sc->sc_dksc; int s, rv = 0; if ((sc->sc_flags & LDF_ENABLED) == 0) return (0); - rv = disk_begindetach(&sc->sc_dk, ldlastclose, sc->sc_dv, flags); + rv = disk_begindetach(&dksc->sc_dkdev, ld_lastclose, dksc->sc_dev, flags); if (rv != 0) return rv; s = splbio(); sc->sc_maxqueuecnt = 0; - sc->sc_flags |= LDF_DETACH; + + dk_detach(dksc); + while (sc->sc_queuecnt > 0) { sc->sc_flags |= LDF_DRAIN; rv = tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 0); @@ -219,6 +210,7 @@ void ldenddetach(struct ld_softc *sc) { + struct dk_softc *dksc = &sc->sc_dksc; int s, bmaj, cmaj, i, mn; if ((sc->sc_flags & LDF_ENABLED) == 0) @@ -227,7 +219,7 @@ /* Wait for commands queued with the hardware to complete. */ if (sc->sc_queuecnt != 0) if (tsleep(&sc->sc_queuecnt, PRIBIO, "lddtch", 30 * hz)) - printf("%s: not drained\n", device_xname(sc->sc_dv)); + printf("%s: not drained\n", dksc->sc_xname); /* Locate the major numbers. */ bmaj = bdevsw_lookup_major(&ld_bdevsw); @@ -235,30 +227,30 @@ /* Kill off any queued buffers. */ s = splbio(); - bufq_drain(sc->sc_bufq); + bufq_drain(dksc->sc_bufq); splx(s); - bufq_free(sc->sc_bufq); + bufq_free(dksc->sc_bufq); /* Nuke the vnodes for any open instances. */ for (i = 0; i < MAXPARTITIONS; i++) { - mn = DISKMINOR(device_unit(sc->sc_dv), i); + mn = DISKMINOR(device_unit(dksc->sc_dev), i); vdevgone(bmaj, mn, mn, VBLK); vdevgone(cmaj, mn, mn, VCHR); } /* Delete all of our wedges. */ - dkwedge_delall(&sc->sc_dk); + dkwedge_delall(&dksc->sc_dkdev); /* Detach from the disk list. */ - disk_detach(&sc->sc_dk); - disk_destroy(&sc->sc_dk); + disk_detach(&dksc->sc_dkdev); + disk_destroy(&dksc->sc_dkdev); /* Unhook the entropy source. */ rnd_detach_source(&sc->sc_rnd_source); /* Deregister with PMF */ - pmf_device_deregister(sc->sc_dv); + pmf_device_deregister(dksc->sc_dev); /* * XXX We can't really flush the cache here, beceause the @@ -269,7 +261,7 @@ /* Flush the device's cache. */ if (sc->sc_flush != NULL) if ((*sc->sc_flush)(sc, 0) != 0) - aprint_error_dev(sc->sc_dv, "unable to flush cache\n"); + aprint_error_dev(dksc->sc_dev, "unable to flush cache\n"); #endif mutex_destroy(&sc->sc_mutex); } @@ -286,9 +278,10 @@ ld_shutdown(device_t dev, int flags) { struct ld_softc *sc = device_private(dev); + struct dk_softc *dksc = &sc->sc_dksc; if (sc->sc_flush != NULL && (*sc->sc_flush)(sc, LDFL_POLL) != 0) { - printf("%s: unable to flush cache\n", device_xname(dev)); + printf("%s: unable to flush cache\n", dksc->sc_xname); return false; } @@ -300,90 +293,41 @@ ldopen(dev_t dev, int flags, int fmt, struct lwp *l) { struct ld_softc *sc; - int error, unit, part; + struct dk_softc *dksc; + int unit; unit = DISKUNIT(dev); if ((sc = device_lookup_private(&ld_cd, unit)) == NULL) return (ENXIO); - if ((sc->sc_flags & LDF_ENABLED) == 0) - return (ENODEV); - part = DISKPART(dev); - - mutex_enter(&sc->sc_dk.dk_openlock); - - if (sc->sc_dk.dk_openmask == 0) { - /* Load the partition info if not already loaded. */ - if ((sc->sc_flags & LDF_VLABEL) == 0) - ldgetdisklabel(sc); - } - - /* Check that the partition exists. */ - if (part != RAW_PART && (part >= sc->sc_dk.dk_label->d_npartitions || - sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) { - error = ENXIO; - goto bad1; - } - - /* Ensure only one open at a time. */ - switch (fmt) { - case S_IFCHR: - sc->sc_dk.dk_copenmask |= (1 << part); - break; - case S_IFBLK: - sc->sc_dk.dk_bopenmask |= (1 << part); - break; - } - sc->sc_dk.dk_openmask = - sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask; + dksc = &sc->sc_dksc; - error = 0; - bad1: - mutex_exit(&sc->sc_dk.dk_openlock); - return (error); + return dk_open(dksc, dev, flags, fmt, l); } static int -ldlastclose(device_t self) +ld_lastclose(device_t self) { struct ld_softc *sc = device_private(self); - + if (sc->sc_flush != NULL && (*sc->sc_flush)(sc, 0) != 0) aprint_error_dev(self, "unable to flush cache\n"); - if ((sc->sc_flags & LDF_KLABEL) == 0) - sc->sc_flags &= ~LDF_VLABEL; - + return 0; -} +} /* ARGSUSED */ static int ldclose(dev_t dev, int flags, int fmt, struct lwp *l) { struct ld_softc *sc; - int part, unit; + struct dk_softc *dksc; + int unit; unit = DISKUNIT(dev); - part = DISKPART(dev); sc = device_lookup_private(&ld_cd, unit); + dksc = &sc->sc_dksc; - mutex_enter(&sc->sc_dk.dk_openlock); - - switch (fmt) { - case S_IFCHR: - sc->sc_dk.dk_copenmask &= ~(1 << part); - break; - case S_IFBLK: - sc->sc_dk.dk_bopenmask &= ~(1 << part); - break; - } - sc->sc_dk.dk_openmask = - sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask; - - if (sc->sc_dk.dk_openmask == 0) - ldlastclose(sc->sc_dv); - - mutex_exit(&sc->sc_dk.dk_openlock); - return (0); + return dk_close(dksc, dev, flags, fmt, l); } /* ARGSUSED */ @@ -407,89 +351,24 @@ ldioctl(dev_t dev, u_long cmd, void *addr, int32_t flag, struct lwp *l) { struct ld_softc *sc; + struct dk_softc *dksc; int unit, error; -#ifdef __HAVE_OLD_DISKLABEL - struct disklabel newlabel; -#endif - struct disklabel *lp; unit = DISKUNIT(dev); sc = device_lookup_private(&ld_cd, unit); + dksc = &sc->sc_dksc; - error = disk_ioctl(&sc->sc_dk, dev, cmd, addr, flag, l); + error = disk_ioctl(&dksc->sc_dkdev, dev, cmd, addr, flag, l); if (error != EPASSTHROUGH) return (error); - error = 0; - switch (cmd) { - case DIOCWDINFO: - case DIOCSDINFO: -#ifdef __HAVE_OLD_DISKLABEL - case ODIOCWDINFO: - case ODIOCSDINFO: - - if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) { - memset(&newlabel, 0, sizeof newlabel); - memcpy(&newlabel, addr, sizeof (struct olddisklabel)); - lp = &newlabel; - } else -#endif - lp = (struct disklabel *)addr; - - if ((flag & FWRITE) == 0) - return (EBADF); - - mutex_enter(&sc->sc_dk.dk_openlock); - sc->sc_flags |= LDF_LABELLING; - - error = setdisklabel(sc->sc_dk.dk_label, - lp, /*sc->sc_dk.dk_openmask : */0, - sc->sc_dk.dk_cpulabel); - if (error == 0 && (cmd == DIOCWDINFO -#ifdef __HAVE_OLD_DISKLABEL - || cmd == ODIOCWDINFO -#endif - )) - error = writedisklabel( - MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART), - ldstrategy, sc->sc_dk.dk_label, - sc->sc_dk.dk_cpulabel); - - sc->sc_flags &= ~LDF_LABELLING; - mutex_exit(&sc->sc_dk.dk_openlock); - break; - - case DIOCKLABEL: - if ((flag & FWRITE) == 0) - return (EBADF); - if (*(int *)addr) - sc->sc_flags |= LDF_KLABEL; - else - sc->sc_flags &= ~LDF_KLABEL; - break; - - case DIOCWLABEL: - if ((flag & FWRITE) == 0) - return (EBADF); - if (*(int *)addr) - sc->sc_flags |= LDF_WLABEL; - else - sc->sc_flags &= ~LDF_WLABEL; - break; - - case DIOCGDEFLABEL: - ldgetdefaultlabel(sc, (struct disklabel *)addr); - break; + error = dk_ioctl(dksc, dev, cmd, addr, flag, l); + if (error != EPASSTHROUGH) + return (error); -#ifdef __HAVE_OLD_DISKLABEL - case ODIOCGDEFLABEL: - ldgetdefaultlabel(sc, &newlabel); - if (newlabel.d_npartitions > OLDMAXPARTITIONS) - return ENOTTY; - memcpy(addr, &newlabel, sizeof (struct olddisklabel)); - break; -#endif + error = 0; + switch (cmd) { case DIOCCACHESYNC: /* * XXX Do we really need to care about having a writable @@ -502,45 +381,6 @@ else error = 0; /* XXX Error out instead? */ break; - - case DIOCGSTRATEGY: - { - struct disk_strategy *dks = (void *)addr; - - mutex_enter(&sc->sc_mutex); - strlcpy(dks->dks_name, bufq_getstrategyname(sc->sc_bufq), - sizeof(dks->dks_name)); - mutex_exit(&sc->sc_mutex); - dks->dks_paramlen = 0; - - return 0; - } - case DIOCSSTRATEGY: - { - struct disk_strategy *dks = (void *)addr; - struct bufq_state *new_bufq, *old_bufq; - - if ((flag & FWRITE) == 0) - return EPERM; - - if (dks->dks_param != NULL) - return EINVAL; - - dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */ - error = bufq_alloc(&new_bufq, dks->dks_name, - BUFQ_EXACT|BUFQ_SORT_RAWBLOCK); - if (error) - return error; - - mutex_enter(&sc->sc_mutex); - old_bufq = sc->sc_bufq; - bufq_move(new_bufq, old_bufq); - sc->sc_bufq = new_bufq; - mutex_exit(&sc->sc_mutex); - bufq_free(old_bufq); - - return 0; - } default: error = ENOTTY; break; @@ -553,89 +393,32 @@ ldstrategy(struct buf *bp) { struct ld_softc *sc; - struct disklabel *lp; - daddr_t blkno; - int s, part; - - sc = device_lookup_private(&ld_cd, DISKUNIT(bp->b_dev)); - part = DISKPART(bp->b_dev); - - if ((sc->sc_flags & LDF_DETACH) != 0) { - bp->b_error = EIO; - goto done; - } - - lp = sc->sc_dk.dk_label; - - /* - * The transfer must be a whole number of blocks and the offset must - * not be negative. - */ - if ((bp->b_bcount % lp->d_secsize) != 0 || bp->b_blkno < 0) { - bp->b_error = EINVAL; - goto done; - } - - /* If it's a null transfer, return immediately. */ - if (bp->b_bcount == 0) - goto done; - - /* - * Do bounds checking and adjust the transfer. If error, process. - * If past the end of partition, just return. - */ - if (part == RAW_PART) { - if (bounds_check_with_mediasize(bp, DEV_BSIZE, - sc->sc_disksize512) <= 0) - goto done; - } else { - if (bounds_check_with_label(&sc->sc_dk, bp, - (sc->sc_flags & (LDF_WLABEL | LDF_LABELLING)) != 0) <= 0) - goto done; - } - - /* - * Convert the block number to absolute and put it in terms - * of the device's logical block size. - */ - if (lp->d_secsize == DEV_BSIZE) - blkno = bp->b_blkno; - else if (lp->d_secsize > DEV_BSIZE) - blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE); - else - blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize); - - if (part != RAW_PART) - blkno += lp->d_partitions[part].p_offset; - - bp->b_rawblkno = blkno; + struct dk_softc *dksc; + int unit; - s = splbio(); - ldstart(sc, bp); - splx(s); - return; + unit = DISKUNIT(bp->b_dev); + sc = device_lookup_private(&ld_cd, unit); + dksc = &sc->sc_dksc; - done: - bp->b_resid = bp->b_bcount; - biodone(bp); + return dk_strategy(dksc, bp); } static void -ldstart(struct ld_softc *sc, struct buf *bp) +ld_start(device_t dev) { + struct ld_softc *sc = device_private(dev); + struct dk_softc *dksc = &sc->sc_dksc; + struct buf *bp; int error; mutex_enter(&sc->sc_mutex); - if (bp != NULL) - bufq_put(sc->sc_bufq, bp); - while (sc->sc_queuecnt < sc->sc_maxqueuecnt) { /* See if there is work to do. */ - if ((bp = bufq_peek(sc->sc_bufq)) == NULL) + if ((bp = bufq_peek(dksc->sc_bufq)) == NULL) break; - disk_busy(&sc->sc_dk); + disk_busy(&dksc->sc_dkdev); sc->sc_queuecnt++; if (__predict_true((error = (*sc->sc_start)(sc, bp)) == 0)) { @@ -643,9 +426,9 @@ * The back-end is running the job; remove it from * the queue. */ - (void) bufq_get(sc->sc_bufq); + (void) bufq_get(dksc->sc_bufq); } else { - disk_unbusy(&sc->sc_dk, 0, (bp->b_flags & B_READ)); + disk_unbusy(&dksc->sc_dkdev, 0, (bp->b_flags & B_READ)); sc->sc_queuecnt--; if (error == EAGAIN) { /* @@ -658,7 +441,7 @@ */ break; } else { - (void) bufq_get(sc->sc_bufq); + (void) bufq_get(dksc->sc_bufq); bp->b_error = error; bp->b_resid = bp->b_bcount; mutex_exit(&sc->sc_mutex); @@ -674,16 +457,9 @@ void lddone(struct ld_softc *sc, struct buf *bp) { + struct dk_softc *dksc = &sc->sc_dksc; - if (bp->b_error != 0) { - diskerr(bp, "ld", "error", LOG_PRINTF, 0, sc->sc_dk.dk_label); - printf("\n"); - } - - disk_unbusy(&sc->sc_dk, bp->b_bcount - bp->b_resid, - (bp->b_flags & B_READ)); - rnd_add_uint32(&sc->sc_rnd_source, bp->b_rawblkno); - biodone(bp); + dk_done(dksc, bp); mutex_enter(&sc->sc_mutex); if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) { @@ -692,7 +468,7 @@ wakeup(&sc->sc_queuecnt); } mutex_exit(&sc->sc_mutex); - ldstart(sc, NULL); + ld_start(dksc->sc_dev); } else mutex_exit(&sc->sc_mutex); } @@ -701,143 +477,50 @@ ldsize(dev_t dev) { struct ld_softc *sc; - int part, unit, omask, size; + struct dk_softc *dksc; + int unit; unit = DISKUNIT(dev); if ((sc = device_lookup_private(&ld_cd, unit)) == NULL) return (ENODEV); + dksc = &sc->sc_dksc; + if ((sc->sc_flags & LDF_ENABLED) == 0) return (ENODEV); - part = DISKPART(dev); - - omask = sc->sc_dk.dk_openmask & (1 << part); - - if (omask == 0 && ldopen(dev, 0, S_IFBLK, NULL) != 0) - return (-1); - else if (sc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP) - size = -1; - else - size = sc->sc_dk.dk_label->d_partitions[part].p_size * - (sc->sc_dk.dk_label->d_secsize / DEV_BSIZE); - if (omask == 0 && ldclose(dev, 0, S_IFBLK, NULL) != 0) - return (-1); - - return (size); -} - -/* - * Load the label information from the specified device. - */ -static void -ldgetdisklabel(struct ld_softc *sc) -{ - const char *errstring; - - ldgetdefaultlabel(sc, sc->sc_dk.dk_label); - - /* Call the generic disklabel extraction routine. */ - errstring = readdisklabel(MAKEDISKDEV(0, device_unit(sc->sc_dv), - RAW_PART), ldstrategy, sc->sc_dk.dk_label, sc->sc_dk.dk_cpulabel); - if (errstring != NULL) - printf("%s: %s\n", device_xname(sc->sc_dv), errstring); - - /* In-core label now valid. */ - sc->sc_flags |= LDF_VLABEL; -} -/* - * Construct a ficticious label. - */ -static void -ldgetdefaultlabel(struct ld_softc *sc, struct disklabel *lp) -{ - - memset(lp, 0, sizeof(struct disklabel)); - - lp->d_secsize = sc->sc_secsize; - lp->d_ntracks = sc->sc_nheads; - lp->d_nsectors = sc->sc_nsectors; - lp->d_ncylinders = sc->sc_ncylinders; - lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors; - lp->d_type = DKTYPE_LD; - strlcpy(lp->d_typename, "unknown", sizeof(lp->d_typename)); - strlcpy(lp->d_packname, "fictitious", sizeof(lp->d_packname)); - if (sc->sc_secperunit > UINT32_MAX) - lp->d_secperunit = UINT32_MAX; - else - lp->d_secperunit = sc->sc_secperunit; - lp->d_rpm = 7200; - lp->d_interleave = 1; - lp->d_flags = 0; - - lp->d_partitions[RAW_PART].p_offset = 0; - lp->d_partitions[RAW_PART].p_size = lp->d_secperunit; - lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; - lp->d_npartitions = RAW_PART + 1; - - lp->d_magic = DISKMAGIC; - lp->d_magic2 = DISKMAGIC; - lp->d_checksum = dkcksum(lp); + return dk_size(dksc, dev); } /* * Take a dump. */ static int -lddump(dev_t dev, daddr_t blkno, void *vav, size_t size) +lddump(dev_t dev, daddr_t blkno, void *va, size_t size) { - char *va = vav; struct ld_softc *sc; - struct disklabel *lp; - int unit, part, nsects, sectoff, towrt, nblk, maxblkcnt, rv; - static int dumping; + struct dk_softc *dksc; + int unit; unit = DISKUNIT(dev); if ((sc = device_lookup_private(&ld_cd, unit)) == NULL) return (ENXIO); + dksc = &sc->sc_dksc; + if ((sc->sc_flags & LDF_ENABLED) == 0) return (ENODEV); + + return dk_dump(dksc, dev, blkno, va, size); +} + +static int +ld_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk) +{ + struct ld_softc *sc = device_private(dev); + if (sc->sc_dump == NULL) return (ENXIO); - /* Check if recursive dump; if so, punt. */ - if (dumping) - return (EFAULT); - dumping = 1; - - /* Convert to disk sectors. Request must be a multiple of size. */ - part = DISKPART(dev); - lp = sc->sc_dk.dk_label; - if ((size % lp->d_secsize) != 0) - return (EFAULT); - towrt = size / lp->d_secsize; - blkno = dbtob(blkno) / lp->d_secsize; /* blkno in DEV_BSIZE units */ - - nsects = lp->d_partitions[part].p_size; - sectoff = lp->d_partitions[part].p_offset; - - /* Check transfer bounds against partition size. */ - if ((blkno < 0) || ((blkno + towrt) > nsects)) - return (EINVAL); - - /* Offset block number to start of partition. */ - blkno += sectoff; - - /* Start dumping and return when done. */ - maxblkcnt = sc->sc_maxxfer / sc->sc_secsize - 1; - while (towrt > 0) { - nblk = min(maxblkcnt, towrt); - - if ((rv = (*sc->sc_dump)(sc, va, blkno, nblk)) != 0) - return (rv); - - towrt -= nblk; - blkno += nblk; - va += nblk * sc->sc_secsize; - } - - dumping = 0; - return (0); + return (*sc->sc_dump)(sc, va, blkno, nblk); } /* @@ -846,34 +529,78 @@ static void ldminphys(struct buf *bp) { + int unit; struct ld_softc *sc; - sc = device_lookup_private(&ld_cd, DISKUNIT(bp->b_dev)); + unit = DISKUNIT(bp->b_dev); + sc = device_lookup_private(&ld_cd, unit); - if (bp->b_bcount > sc->sc_maxxfer) - bp->b_bcount = sc->sc_maxxfer; + ld_iosize(sc->sc_dv, &bp->b_bcount); minphys(bp); } static void -ld_set_geometry(struct ld_softc *ld) +ld_iosize(device_t d, int *countp) { - struct disk_geom *dg = &ld->sc_dk.dk_geom; + struct ld_softc *sc = device_private(d); - memset(dg, 0, sizeof(*dg)); + if (*countp > sc->sc_maxxfer) + *countp = sc->sc_maxxfer; +} + +static void +ld_fake_geometry(struct ld_softc *sc) +{ + uint64_t ncyl; + + if (sc->sc_secperunit <= 528 * 2048) /* 528MB */ + sc->sc_nheads = 16; + else if (sc->sc_secperunit <= 1024 * 2048) /* 1GB */ + sc->sc_nheads = 32; + else if (sc->sc_secperunit <= 21504 * 2048) /* 21GB */ + sc->sc_nheads = 64; + else if (sc->sc_secperunit <= 43008 * 2048) /* 42GB */ + sc->sc_nheads = 128; + else + sc->sc_nheads = 255; + + sc->sc_nsectors = 63; + sc->sc_ncylinders = INT_MAX; + ncyl = sc->sc_secperunit / + (sc->sc_nheads * sc->sc_nsectors); + if (ncyl < INT_MAX) + sc->sc_ncylinders = (int)ncyl; +} + +static void +ld_set_geometry(struct ld_softc *sc) +{ + struct dk_softc *dksc = &sc->sc_dksc; + struct disk_geom *dg = &dksc->sc_dkdev.dk_geom; + char tbuf[9]; + + format_bytes(tbuf, sizeof(tbuf), sc->sc_secperunit * + sc->sc_secsize); + aprint_normal_dev(dksc->sc_dev, "%s, %d cyl, %d head, %d sec, " + "%d bytes/sect x %"PRIu64" sectors\n", + tbuf, sc->sc_ncylinders, sc->sc_nheads, + sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit); - dg->dg_secperunit = ld->sc_secperunit; - dg->dg_secsize = ld->sc_secsize; - dg->dg_nsectors = ld->sc_nsectors; - dg->dg_ntracks = ld->sc_nheads; - dg->dg_ncylinders = ld->sc_ncylinders; + memset(dg, 0, sizeof(*dg)); + dg->dg_secperunit = sc->sc_secperunit; + dg->dg_secsize = sc->sc_secsize; + dg->dg_nsectors = sc->sc_nsectors; + dg->dg_ntracks = sc->sc_nheads; + dg->dg_ncylinders = sc->sc_ncylinders; - disk_set_info(ld->sc_dv, &ld->sc_dk, NULL); + disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL); } static void ld_config_interrupts(device_t d) { struct ld_softc *sc = device_private(d); - dkwedge_discover(&sc->sc_dk); + struct dk_softc *dksc = &sc->sc_dksc; + + dkwedge_discover(&dksc->sc_dkdev); } Index: dev/ldvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ldvar.h,v retrieving revision 1.22 diff -u -r1.22 ldvar.h --- dev/ldvar.h 13 Apr 2015 16:33:23 -0000 1.22 +++ dev/ldvar.h 26 Apr 2015 20:31:28 -0000 @@ -33,15 +33,15 @@ #define _DEV_LDVAR_H_ #include -#include /* for device_t */ #include +#include /* for dk_softc */ + struct ld_softc { - device_t sc_dv; - struct disk sc_dk; - struct bufq_state *sc_bufq; + struct dk_softc sc_dksc; kmutex_t sc_mutex; krndsource_t sc_rnd_source; + int sc_queuecnt; /* current h/w queue depth */ int sc_ncylinders; /* # cylinders */ int sc_nheads; /* # heads */ @@ -51,7 +51,8 @@ /* * The following are filled by hardware specific attachment code. */ - int sc_flags; /* control flags */ + device_t sc_dv; + int sc_flags; /* control flags */ uint64_t sc_secperunit; /* # sectors in total */ int sc_secsize; /* sector size in bytes */ int sc_maxxfer; /* max xfer size in bytes */ @@ -64,12 +65,7 @@ /* sc_flags */ #define LDF_ENABLED 0x001 /* device enabled */ -#define LDF_WLABEL 0x008 /* label is writable */ -#define LDF_LABELLING 0x010 /* writing label */ #define LDF_DRAIN 0x020 /* maxqueuecnt has changed; drain */ -#define LDF_DETACH 0x040 /* detach pending */ -#define LDF_KLABEL 0x080 /* keep label on close */ -#define LDF_VLABEL 0x100 /* label is valid */ /* sc_flush() flags */ #define LDFL_POLL 0x001 /* poll for completion */ Index: dev/cgd.c =================================================================== RCS file: /cvsroot/src/sys/dev/cgd.c,v retrieving revision 1.97 diff -u -r1.97 cgd.c --- dev/cgd.c 25 Apr 2015 13:06:11 -0000 1.97 +++ dev/cgd.c 26 Apr 2015 20:31:28 -0000 @@ -104,7 +104,7 @@ /* Internal Functions */ -static void cgdstart(struct dk_softc *); +static void cgd_start(device_t); static void cgdiodone(struct buf *); static int cgd_ioctl_set(struct cgd_softc *, void *, struct lwp *); @@ -115,21 +115,15 @@ static void cgd_cipher(struct cgd_softc *, void *, void *, size_t, daddr_t, size_t, int); -/* Pseudo-disk Interface */ - -static struct dk_intf the_dkintf = { - DKTYPE_CGD, - "cgd", - cgdopen, - cgdclose, - cgdstrategy, - cgdstart, -}; -static struct dk_intf *di = &the_dkintf; - static struct dkdriver cgddkdriver = { - .d_strategy = cgdstrategy, - .d_minphys = minphys, + .d_minphys = minphys, + .d_open = cgdopen, + .d_close = cgdclose, + .d_strategy = cgdstrategy, + .d_iosize = NULL, + .d_diskstart = cgd_start, + .d_dumpblocks = NULL, + .d_lastclose = NULL }; CFATTACH_DECL3_NEW(cgd, sizeof(struct cgd_softc), @@ -205,11 +199,10 @@ struct cgd_softc *sc = device_private(self); mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO); - dk_sc_init(&sc->sc_dksc, device_xname(self)); - sc->sc_dksc.sc_dev = self; + dk_init(&sc->sc_dksc, self, DKTYPE_CGD); disk_init(&sc->sc_dksc.sc_dkdev, sc->sc_dksc.sc_xname, &cgddkdriver); - if (!pmf_device_register(self, NULL, NULL)) + if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "unable to register power management hooks\n"); } @@ -225,7 +218,7 @@ if (DK_BUSY(dksc, pmask)) return EBUSY; - if ((dksc->sc_flags & DKF_INITED) != 0 && + if (DK_ATTACHED(dksc) && (ret = cgd_ioctl_clr(sc, curlwp)) != 0) return ret; @@ -281,7 +274,7 @@ DPRINTF_FOLLOW(("cgdopen(0x%"PRIx64", %d)\n", dev, flags)); GETCGD_SOFTC(cs, dev); - return dk_open(di, &cs->sc_dksc, dev, flags, fmt, l); + return dk_open(&cs->sc_dksc, dev, flags, fmt, l); } static int @@ -294,10 +287,10 @@ DPRINTF_FOLLOW(("cgdclose(0x%"PRIx64", %d)\n", dev, flags)); GETCGD_SOFTC(cs, dev); dksc = &cs->sc_dksc; - if ((error = dk_close(di, dksc, dev, flags, fmt, l)) != 0) + if ((error = dk_close(dksc, dev, flags, fmt, l)) != 0) return error; - if ((dksc->sc_flags & DKF_INITED) == 0) { + if (!DK_ATTACHED(dksc)) { if ((error = cgd_destroy(cs->sc_dksc.sc_dev)) != 0) { aprint_error_dev(dksc->sc_dev, "unable to detach instance\n"); @@ -330,7 +323,7 @@ } /* XXXrcd: Should we test for (cs != NULL)? */ - dk_strategy(di, &cs->sc_dksc, bp); + dk_strategy(&cs->sc_dksc, bp); return; } @@ -342,7 +335,7 @@ DPRINTF_FOLLOW(("cgdsize(0x%"PRIx64")\n", dev)); if (!cs) return -1; - return dk_size(di, &cs->sc_dksc, dev); + return dk_size(&cs->sc_dksc, dev); } /* @@ -387,9 +380,10 @@ } static void -cgdstart(struct dk_softc *dksc) +cgd_start(device_t dev) { - struct cgd_softc *cs = (struct cgd_softc *)dksc; + struct cgd_softc *cs = device_private(dev); + struct dk_softc *dksc = &cs->sc_dksc; struct buf *bp, *nbp; #ifdef DIAGNOSTIC struct buf *qbp; @@ -401,7 +395,7 @@ while ((bp = bufq_peek(dksc->sc_bufq)) != NULL) { - DPRINTF_FOLLOW(("cgdstart(%p, %p)\n", dksc, bp)); + DPRINTF_FOLLOW(("cgd_start(%p, %p)\n", dksc, bp)); disk_busy(&dksc->sc_dkdev); bn = bp->b_rawblkno; @@ -506,7 +500,7 @@ disk_unbusy(&dksc->sc_dkdev, obp->b_bcount - obp->b_resid, (obp->b_flags & B_READ)); biodone(obp); - cgdstart(dksc); + cgd_start(dksc->sc_dev); splx(s); } @@ -521,7 +515,7 @@ (unsigned long long)dev, uio, flags)); GETCGD_SOFTC(cs, dev); dksc = &cs->sc_dksc; - if ((dksc->sc_flags & DKF_INITED) == 0) + if (!DK_ATTACHED(dksc)) return ENXIO; return physio(cgdstrategy, NULL, dev, B_READ, minphys, uio); } @@ -536,7 +530,7 @@ DPRINTF_FOLLOW(("cgdwrite(0x%"PRIx64", %p, %d)\n", dev, uio, flags)); GETCGD_SOFTC(cs, dev); dksc = &cs->sc_dksc; - if ((dksc->sc_flags & DKF_INITED) == 0) + if (!DK_ATTACHED(dksc)) return ENXIO; return physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio); } @@ -568,7 +562,7 @@ switch (cmd) { case CGDIOCSET: - if (dksc->sc_flags & DKF_INITED) + if (DK_ATTACHED(dksc)) return EBUSY; return cgd_ioctl_set(cs, data, l); case CGDIOCCLR: @@ -588,7 +582,7 @@ */ return VOP_IOCTL(cs->sc_tvn, cmd, data, flag, l->l_cred); default: - return dk_ioctl(di, dksc, dev, cmd, data, flag, l); + return dk_ioctl(dksc, dev, cmd, data, flag, l); case CGDIOCGET: KASSERT(0); return EINVAL; @@ -603,7 +597,7 @@ DPRINTF_FOLLOW(("cgddump(0x%"PRIx64", %" PRId64 ", %p, %lu)\n", dev, blkno, va, (unsigned long)size)); GETCGD_SOFTC(cs, dev); - return dk_dump(di, &cs->sc_dksc, dev, blkno, va, size); + return dk_dump(&cs->sc_dksc, dev, blkno, va, size); } /* @@ -717,15 +711,14 @@ cs->sc_data = malloc(MAXPHYS, M_DEVBUF, M_WAITOK); cs->sc_data_used = 0; - dksc->sc_flags |= DKF_INITED; - - disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL); - /* Attach the disk. */ + dk_attach(dksc); disk_attach(&dksc->sc_dkdev); + disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL); + /* Try and read the disklabel. */ - dk_getdisklabel(di, dksc, 0 /* XXX ? (cause of PR 41704) */); + dk_getdisklabel(dksc, 0 /* XXX ? (cause of PR 41704) */); /* Discover wedges on this disk. */ dkwedge_discover(&dksc->sc_dkdev); @@ -745,7 +738,7 @@ int s; struct dk_softc *dksc = &cs->sc_dksc; - if ((dksc->sc_flags & DKF_INITED) == 0) + if (!DK_ATTACHED(dksc)) return ENXIO; /* Delete all of our wedges. */ @@ -762,7 +755,7 @@ free(cs->sc_tpath, M_DEVBUF); free(cs->sc_data, M_DEVBUF); cs->sc_data_used = 0; - dksc->sc_flags &= ~DKF_INITED; + dk_detach(dksc); disk_detach(&dksc->sc_dkdev); return 0; @@ -789,7 +782,7 @@ return EINVAL; /* XXX: should this be ENXIO? */ cs = device_lookup_private(&cgd_cd, unit); - if (cs == NULL || (dksc->sc_flags & DKF_INITED) == 0) { + if (cs == NULL || !DK_ATTACHED(dksc)) { cgu->cgu_dev = 0; cgu->cgu_alg[0] = '\0'; cgu->cgu_blocksize = 0; Index: arch/xen/xen/xbd_xenbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/xbd_xenbus.c,v retrieving revision 1.70 diff -u -r1.70 xbd_xenbus.c --- arch/xen/xen/xbd_xenbus.c 13 Apr 2015 21:18:40 -0000 1.70 +++ arch/xen/xen/xbd_xenbus.c 26 Apr 2015 20:31:28 -0000 @@ -168,7 +168,7 @@ static bool xbd_xenbus_resume(device_t, const pmf_qual_t *); static int xbd_handler(void *); -static void xbdstart(struct dk_softc *); +static void xbdstart(device_t); static void xbd_backend_changed(void *, XenbusState); static void xbd_connect(struct xbd_xenbus_softc *); @@ -218,19 +218,12 @@ extern struct cfdriver xbd_cd; -/* Pseudo-disk Interface */ -static struct dk_intf dkintf_esdi = { - DKTYPE_ESDI, - "Xen Virtual ESDI", - xbdopen, - xbdclose, - xbdstrategy, - xbdstart, -}, *di = &dkintf_esdi; - static struct dkdriver xbddkdriver = { .d_strategy = xbdstrategy, .d_minphys = xbdminphys, + .d_open = xbdopen, + .d_close = xbdclose, + .d_diskstart = xbdstart, }; static int @@ -265,8 +258,8 @@ config_pending_incr(self); aprint_normal(": Xen Virtual Block Device Interface\n"); - dk_sc_init(&sc->sc_dksc, device_xname(self)); - sc->sc_dksc.sc_dev = self; + dk_init(&sc->sc_dksc, self, DKTYPE_ESDI); + disk_init(&sc->sc_dksc.sc_dkdev, device_xname(self), &xbddkdriver); #ifdef XBD_DEBUG printf("path: %s\n", xa->xa_xbusd->xbusd_path); @@ -293,7 +286,6 @@ sc->sc_xbusd = xa->xa_xbusd; sc->sc_xbusd->xbusd_otherend_changed = xbd_backend_changed; - disk_init(&sc->sc_dksc.sc_dkdev, device_xname(self), &xbddkdriver); /* initialize free requests list */ SLIST_INIT(&sc->sc_xbdreq_head); for (i = 0; i < XBD_RING_SIZE; i++) { @@ -380,6 +372,7 @@ /* detach disk */ disk_detach(&sc->sc_dksc.sc_dkdev); disk_destroy(&sc->sc_dksc.sc_dkdev); + dk_detach(&sc->sc_dksc); /* Unhook the entropy source. */ rnd_detach_source(&sc->sc_rnd_source); } @@ -580,13 +573,13 @@ dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors; bufq_alloc(&sc->sc_dksc.sc_bufq, "fcfs", 0); - sc->sc_dksc.sc_flags |= DKF_INITED; + dk_attach(&sc->sc_dksc); disk_attach(&sc->sc_dksc.sc_dkdev); sc->sc_backend_status = BLKIF_STATE_CONNECTED; /* try to read the disklabel */ - dk_getdisklabel(di, &sc->sc_dksc, 0 /* XXX ? */); + dk_getdisklabel(&sc->sc_dksc, 0 /* XXX ? */); format_bytes(buf, sizeof(buf), sc->sc_sectors * sc->sc_secsize); aprint_verbose_dev(sc->sc_dksc.sc_dev, "%s, %d bytes/sect x %" PRIu64 " sectors\n", @@ -727,7 +720,7 @@ if (sc->sc_xbdreq_wait) wakeup(&sc->sc_xbdreq_wait); else - xbdstart(&sc->sc_dksc); + xbdstart(sc->sc_dksc.sc_dev); return 1; } @@ -752,7 +745,7 @@ return EROFS; DPRINTF(("xbdopen(0x%04x, %d)\n", dev, flags)); - return dk_open(di, &sc->sc_dksc, dev, flags, fmt, l); + return dk_open(&sc->sc_dksc, dev, flags, fmt, l); } int @@ -763,7 +756,7 @@ sc = device_lookup_private(&xbd_cd, DISKUNIT(dev)); DPRINTF(("xbdclose(%d, %d)\n", dev, flags)); - return dk_close(di, &sc->sc_dksc, dev, flags, fmt, l); + return dk_close(&sc->sc_dksc, dev, flags, fmt, l); } void @@ -788,7 +781,7 @@ return; } - dk_strategy(di, &sc->sc_dksc, bp); + dk_strategy(&sc->sc_dksc, bp); return; } @@ -802,7 +795,7 @@ sc = device_lookup_private(&xbd_cd, DISKUNIT(dev)); if (sc == NULL || sc->sc_shutdown != BLKIF_SHUTDOWN_RUN) return -1; - return dk_size(di, &sc->sc_dksc, dev); + return dk_size(&sc->sc_dksc, dev); } int @@ -812,7 +805,7 @@ device_lookup_private(&xbd_cd, DISKUNIT(dev)); struct dk_softc *dksc = &sc->sc_dksc; - if ((dksc->sc_flags & DKF_INITED) == 0) + if (!DK_ATTACHED(dksc)) return ENXIO; return physio(xbdstrategy, NULL, dev, B_READ, xbdminphys, uio); } @@ -824,7 +817,7 @@ device_lookup_private(&xbd_cd, DISKUNIT(dev)); struct dk_softc *dksc = &sc->sc_dksc; - if ((dksc->sc_flags & DKF_INITED) == 0) + if (!DK_ATTACHED(dksc)) return ENXIO; if (__predict_false(sc->sc_info & VDISK_READONLY)) return EROFS; @@ -904,7 +897,7 @@ break; default: - error = dk_ioctl(di, dksc, dev, cmd, data, flag, l); + error = dk_ioctl(dksc, dev, cmd, data, flag, l); break; } @@ -922,13 +915,14 @@ DPRINTF(("xbddump(%d, %" PRId64 ", %p, %lu)\n", dev, blkno, va, (unsigned long)size)); - return dk_dump(di, &sc->sc_dksc, dev, blkno, va, size); + return dk_dump(&sc->sc_dksc, dev, blkno, va, size); } static void -xbdstart(struct dk_softc *dksc) +xbdstart(device_t self) { - struct xbd_xenbus_softc *sc = (struct xbd_xenbus_softc *)dksc; + struct xbd_xenbus_softc *sc = device_private(self); + struct dk_softc *dksc = &sc->sc_dksc; struct buf *bp; #ifdef DIAGNOSTIC struct buf *qbp; Index: arch/xen/include/xbdvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/xen/include/xbdvar.h,v retrieving revision 1.16 diff -u -r1.16 xbdvar.h --- arch/xen/include/xbdvar.h 14 Apr 2015 20:32:35 -0000 1.16 +++ arch/xen/include/xbdvar.h 26 Apr 2015 20:31:28 -0000 @@ -36,7 +36,6 @@ device_t sc_dev; /* base device glue */ struct dk_softc sc_dksc; /* generic disk interface */ unsigned long sc_xd_device; /* cookie identifying device */ - struct dk_intf *sc_di; /* pseudo-disk interface */ int sc_shutdown; /* about to be removed */ krndsource_t sc_rnd_source; }; @@ -44,7 +43,6 @@ struct xbd_attach_args { const char *xa_device; vdisk_t *xa_xd; - struct dk_intf *xa_dkintf; struct sysctlnode *xa_diskcookies; };