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 <sys/fcntl.h>
#include <sys/namei.h>
#include <sys/module.h>
+#include <sys/syslog.h>
#include <dev/dkvar.h>
#include <miscfs/specfs/specdev.h> /* 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 <prop/proplib.h>
-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 <sys/mutex.h>
-#include <sys/device.h> /* for device_t */
#include <sys/rndsource.h>
+#include <dev/dkvar.h> /* 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;
};