Module Name:    src
Committed By:   mlelstv
Date:           Sun Jan  3 08:17:24 UTC 2016

Modified Files:
        src/sys/dev/raidframe: rf_engine.c rf_kintf.h rf_netbsdkintf.c
            rf_states.c

Log Message:
refactor driver to use common code in dksubr.


To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 src/sys/dev/raidframe/rf_engine.c
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/raidframe/rf_kintf.h
cvs rdiff -u -r1.334 -r1.335 src/sys/dev/raidframe/rf_netbsdkintf.c
cvs rdiff -u -r1.49 -r1.50 src/sys/dev/raidframe/rf_states.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/raidframe/rf_engine.c
diff -u src/sys/dev/raidframe/rf_engine.c:1.50 src/sys/dev/raidframe/rf_engine.c:1.51
--- src/sys/dev/raidframe/rf_engine.c:1.50	Sat Oct 18 08:33:28 2014
+++ src/sys/dev/raidframe/rf_engine.c	Sun Jan  3 08:17:24 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: rf_engine.c,v 1.50 2014/10/18 08:33:28 snj Exp $	*/
+/*	$NetBSD: rf_engine.c,v 1.51 2016/01/03 08:17:24 mlelstv Exp $	*/
 /*
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
@@ -55,7 +55,7 @@
  ****************************************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.50 2014/10/18 08:33:28 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.51 2016/01/03 08:17:24 mlelstv Exp $");
 
 #include <sys/errno.h>
 
@@ -843,7 +843,7 @@ DAGExecutionThread(RF_ThreadArg_t arg)
 
 /*
  * rf_RaidIOThread() -- When I/O to a component begins, raidstrategy()
- * puts the I/O on a buf_queue, and then signals raidPtr->iodone.  If
+ * puts the I/O on a buffer queue, and then signals raidPtr->iodone.  If
  * necessary, this function calls raidstart() to initiate the I/O.
  * When I/O to a component completes, KernelWakeupFunc() puts the
  * completed request onto raidPtr->iodone TAILQ.  This function looks

Index: src/sys/dev/raidframe/rf_kintf.h
diff -u src/sys/dev/raidframe/rf_kintf.h:1.23 src/sys/dev/raidframe/rf_kintf.h:1.24
--- src/sys/dev/raidframe/rf_kintf.h:1.23	Wed Aug  3 14:44:38 2011
+++ src/sys/dev/raidframe/rf_kintf.h	Sun Jan  3 08:17:24 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: rf_kintf.h,v 1.23 2011/08/03 14:44:38 oster Exp $	*/
+/*	$NetBSD: rf_kintf.h,v 1.24 2016/01/03 08:17:24 mlelstv Exp $	*/
 /*
  * rf_kintf.h
  *
@@ -42,6 +42,7 @@ int rf_reasonable_label(RF_ComponentLabe
 
 void    raidstart(RF_Raid_t * raidPtr);
 int     rf_DispatchKernelIO(RF_DiskQueue_t * queue, RF_DiskQueueData_t * req);
+void    raiddone(RF_Raid_t * raidPtr, struct buf * bp);
 
 int raidfetch_component_label(RF_Raid_t *, RF_RowCol_t);
 RF_ComponentLabel_t *raidget_component_label(RF_Raid_t *, RF_RowCol_t);
@@ -59,7 +60,6 @@ void raid_init_component_label(RF_Raid_t
 void rf_print_component_label(RF_ComponentLabel_t *);
 void rf_UnconfigureVnodes( RF_Raid_t * );
 void rf_close_component( RF_Raid_t *, struct vnode *, int);
-void rf_disk_unbusy(RF_RaidAccessDesc_t *);
 int rf_getdisksize(struct vnode *, RF_RaidDisk_t *);
 int rf_sync_component_caches(RF_Raid_t *raidPtr);
 #endif				/* _RF__RF_KINTF_H_ */

Index: src/sys/dev/raidframe/rf_netbsdkintf.c
diff -u src/sys/dev/raidframe/rf_netbsdkintf.c:1.334 src/sys/dev/raidframe/rf_netbsdkintf.c:1.335
--- src/sys/dev/raidframe/rf_netbsdkintf.c:1.334	Sat Jan  2 16:20:50 2016
+++ src/sys/dev/raidframe/rf_netbsdkintf.c	Sun Jan  3 08:17:24 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: rf_netbsdkintf.c,v 1.334 2016/01/02 16:20:50 mlelstv Exp $	*/
+/*	$NetBSD: rf_netbsdkintf.c,v 1.335 2016/01/03 08:17:24 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2008-2011 The NetBSD Foundation, Inc.
@@ -101,7 +101,7 @@
  ***********************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.334 2016/01/02 16:20:50 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.335 2016/01/03 08:17:24 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -181,6 +181,7 @@ static void InitBP(struct buf *, struct 
     void *, int, struct proc *);
 struct raid_softc;
 static void raidinit(struct raid_softc *);
+static int raiddoaccess(RF_Raid_t *raidPtr, struct buf *bp);
 
 static int raid_match(device_t, cfdata_t, void *);
 static void raid_attach(device_t, device_t, void *);
@@ -196,6 +197,9 @@ static int raidwrite_component_label(uns
 static int raidread_component_label(unsigned,
     dev_t, struct vnode *, RF_ComponentLabel_t *);
 
+static int raid_diskstart(device_t, struct buf *bp);
+static int raid_dumpblocks(device_t, void *, daddr_t, int);
+static int raid_lastclose(device_t);
 
 static dev_type_open(raidopen);
 static dev_type_close(raidclose);
@@ -233,12 +237,17 @@ const struct cdevsw raid_cdevsw = {
 };
 
 static struct dkdriver rf_dkdriver = {
+	.d_open = raidopen,
+	.d_close = raidclose,
 	.d_strategy = raidstrategy,
+	.d_diskstart = raid_diskstart,
+	.d_dumpblocks = raid_dumpblocks,
+	.d_lastclose = raid_lastclose,
 	.d_minphys = minphys
 };
 
 struct raid_softc {
-	device_t sc_dev;
+	struct dk_softc sc_dksc;
 	int	sc_unit;
 	int     sc_flags;	/* flags */
 	int     sc_cflags;	/* configuration flags */
@@ -246,8 +255,6 @@ struct raid_softc {
 	kcondvar_t sc_cv;	/* and the condvar */
 	uint64_t sc_size;	/* size of the raid device */
 	char    sc_xname[20];	/* XXX external name */
-	struct disk sc_dkdev;	/* generic disk device info */
-	struct bufq_state *buf_queue;	/* used for the device queue */
 	RF_Raid_t sc_r;
 	LIST_ENTRY(raid_softc) sc_link;
 };
@@ -256,10 +263,12 @@ struct raid_softc {
 #define RAIDF_WLABEL	0x02	/* label area is writable */
 #define RAIDF_LABELLING	0x04	/* unit is currently being labelled */
 #define RAIDF_SHUTDOWN	0x08	/* unit is being shutdown */
+#define RAIDF_DETACH  	0x10	/* detach after final close */
 #define RAIDF_WANTED	0x40	/* someone is waiting to obtain a lock */
 #define RAIDF_LOCKED	0x80	/* unit is locked */
 
 #define	raidunit(x)	DISKUNIT(x)
+#define	raidsoftc(dev)	(((struct raid_softc *)device_private(dev))->sc_r.softc)
 
 extern struct cfdriver raid_cd;
 CFATTACH_DECL3_NEW(raid, sizeof(struct raid_softc),
@@ -292,11 +301,6 @@ CFATTACH_DECL3_NEW(raid, sizeof(struct r
 
 /* declared here, and made public, for the benefit of KVM stuff.. */
 
-static void raidgetdefaultlabel(RF_Raid_t *, struct raid_softc *,
-				     struct disklabel *);
-static void raidgetdisklabel(dev_t);
-static void raidmakedisklabel(struct raid_softc *);
-
 static int raidlock(struct raid_softc *);
 static void raidunlock(struct raid_softc *);
 
@@ -352,7 +356,6 @@ raidcreate(int unit) {
 		return NULL;
 	}
 	sc->sc_unit = unit;
-	bufq_alloc(&sc->buf_queue, "fcfs", BUFQ_SORT_RAWBLOCK);
 	cv_init(&sc->sc_cv, "raidunit");
 	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
 	return sc;
@@ -362,7 +365,6 @@ static void
 raiddestroy(struct raid_softc *sc) {
 	cv_destroy(&sc->sc_cv);
 	mutex_destroy(&sc->sc_mutex);
-	bufq_free(sc->buf_queue);
 	kmem_free(sc, sizeof(*sc));
 }
 
@@ -480,6 +482,7 @@ rf_buildroothack(RF_ConfigSet_t *config_
 	RF_ConfigSet_t *next_cset;
 	int num_root;
 	struct raid_softc *sc, *rsc;
+	struct dk_softc *dksc;
 
 	sc = rsc = NULL;
 	num_root = 0;
@@ -510,6 +513,7 @@ rf_buildroothack(RF_ConfigSet_t *config_
 		rf_cleanup_config_set(cset);
 		cset = next_cset;
 	}
+	dksc = &rsc->sc_dksc;
 
 	/* if the user has specified what the root device should be
 	   then we don't touch booted_device or boothowto... */
@@ -532,14 +536,14 @@ rf_buildroothack(RF_ConfigSet_t *config_
 	 */
 	if (num_root == 1) {
 		device_t candidate_root;
-		if (rsc->sc_dkdev.dk_nwedges != 0) {
+		if (dksc->sc_dkdev.dk_nwedges != 0) {
 			char cname[sizeof(cset->ac->devname)];
 			/* XXX: assume 'a' */
 			snprintf(cname, sizeof(cname), "%s%c",
-			    device_xname(rsc->sc_dev), 'a');
+			    device_xname(dksc->sc_dev), 'a');
 			candidate_root = dkwedge_find_by_wname(cname);
 		} else
-			candidate_root = rsc->sc_dev;
+			candidate_root = dksc->sc_dev;
 		if (booted_device == NULL ||
 		    rsc->sc_r.root_partition == 1 ||
 		    rf_containsboot(&rsc->sc_r, booted_device)) {
@@ -570,12 +574,13 @@ rf_buildroothack(RF_ConfigSet_t *config_
 			if (rf_containsboot(r, booted_device)) {
 				num_root++;
 				rsc = sc;
+				dksc = &rsc->sc_dksc;
 			}
 		}
 		mutex_exit(&raid_lock);
 
 		if (num_root == 1) {
-			booted_device = rsc->sc_dev;
+			booted_device = dksc->sc_dev;
 			booted_partition = 0;	/* XXX assume 'a' */
 		} else {
 			/* we can't guess.. require the user to answer... */
@@ -588,55 +593,49 @@ static int
 raidsize(dev_t dev)
 {
 	struct raid_softc *rs;
-	struct disklabel *lp;
-	int     part, unit, omask, size;
+	struct dk_softc *dksc;
+	unsigned int unit;
 
 	unit = raidunit(dev);
 	if ((rs = raidget(unit, false)) == NULL)
-		return -1;
-	if ((rs->sc_flags & RAIDF_INITED) == 0)
-		return (-1);
+		return ENXIO;
+	dksc = &rs->sc_dksc;
 
-	part = DISKPART(dev);
-	omask = rs->sc_dkdev.dk_openmask & (1 << part);
-	lp = rs->sc_dkdev.dk_label;
+	if ((rs->sc_flags & RAIDF_INITED) == 0)
+		return (ENODEV);
 
-	if (omask == 0 && raidopen(dev, 0, S_IFBLK, curlwp))
-		return (-1);
+	return dk_size(dksc, dev);
+}
 
-	if (lp->d_partitions[part].p_fstype != FS_SWAP)
-		size = -1;
-	else
-		size = lp->d_partitions[part].p_size *
-		    (lp->d_secsize / DEV_BSIZE);
+static int
+raiddump(dev_t dev, daddr_t blkno, void *va, size_t size)
+{
+	unsigned int unit;
+	struct raid_softc *rs;
+	struct dk_softc *dksc;
 
-	if (omask == 0 && raidclose(dev, 0, S_IFBLK, curlwp))
-		return (-1);
+	unit = raidunit(dev);
+	if ((rs = raidget(unit, false)) == NULL)
+		return ENXIO;
+	dksc = &rs->sc_dksc;
 
-	return (size);
+	if ((rs->sc_flags & RAIDF_INITED) == 0)
+		return ENODEV;
 
+	return dk_dump(dksc, dev, blkno, va, size);
 }
 
 static int
-raiddump(dev_t dev, daddr_t blkno, void *va, size_t size)
+raid_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
 {
-	int     unit = raidunit(dev);
-	struct raid_softc *rs;
+	struct raid_softc *rs = raidsoftc(dev);
 	const struct bdevsw *bdev;
-	struct disklabel *lp;
 	RF_Raid_t *raidPtr;
-	daddr_t offset;
-	int     part, c, sparecol, j, scol, dumpto;
+	int     c, sparecol, j, scol, dumpto;
 	int     error = 0;
 
-	if ((rs = raidget(unit, false)) == NULL)
-		return ENXIO;
-
 	raidPtr = &rs->sc_r;
 
-	if ((rs->sc_flags & RAIDF_INITED) == 0)
-		return ENXIO;
-
 	/* we only support dumping to RAID 1 sets */
 	if (raidPtr->Layout.numDataCol != 1 || 
 	    raidPtr->Layout.numParityCol != 1)
@@ -645,23 +644,6 @@ raiddump(dev_t dev, daddr_t blkno, void 
 	if ((error = raidlock(rs)) != 0)
 		return error;
 
-	if (size % DEV_BSIZE != 0) {
-		error = EINVAL;
-		goto out;
-	}
-
-	if (blkno + size / DEV_BSIZE > rs->sc_size) {
-		printf("%s: blkno (%" PRIu64 ") + size / DEV_BSIZE (%zu) > "
-		    "sc->sc_size (%" PRIu64 ")\n", __func__, blkno,
-		    size / DEV_BSIZE, rs->sc_size);
-		error = EINVAL;
-		goto out;
-	}
-
-	part = DISKPART(dev);
-	lp = rs->sc_dkdev.dk_label;
-	offset = lp->d_partitions[part].p_offset + RF_PROTECTED_SECTORS;
-
 	/* figure out what device is alive.. */
 
 	/* 
@@ -736,16 +718,8 @@ raiddump(dev_t dev, daddr_t blkno, void 
 
 	bdev = bdevsw_lookup(raidPtr->Disks[dumpto].dev);
 
-	/* 
-	   Note that blkno is relative to this particular partition.
-	   By adding the offset of this partition in the RAID
-	   set, and also adding RF_PROTECTED_SECTORS, we get a
-	   value that is relative to the partition used for the
-	   underlying component.
-	*/
-	   
 	error = (*bdev->d_dump)(raidPtr->Disks[dumpto].dev, 
-				blkno + offset, va, size);
+				blkno, va, nblk);
 	
 out:
 	raidunlock(rs);
@@ -760,9 +734,9 @@ raidopen(dev_t dev, int flags, int fmt,
 {
 	int     unit = raidunit(dev);
 	struct raid_softc *rs;
-	struct disklabel *lp;
-	int     part, pmask;
+	struct dk_softc *dksc;
 	int     error = 0;
+	int     part, pmask;
 
 	if ((rs = raidget(unit, true)) == NULL)
 		return ENXIO;
@@ -774,47 +748,12 @@ raidopen(dev_t dev, int flags, int fmt,
 		goto bad;
 	}
 
-	lp = rs->sc_dkdev.dk_label;
+	dksc = &rs->sc_dksc;
 
 	part = DISKPART(dev);
-
-	/*
-	 * If there are wedges, and this is not RAW_PART, then we
-	 * need to fail.
-	 */
-	if (rs->sc_dkdev.dk_nwedges != 0 && part != RAW_PART) {
-		error = EBUSY;
-		goto bad;
-	}
 	pmask = (1 << part);
 
-	if ((rs->sc_flags & RAIDF_INITED) &&
-	    (rs->sc_dkdev.dk_nwedges == 0) &&
-	    (rs->sc_dkdev.dk_openmask == 0))
-		raidgetdisklabel(dev);
-
-	/* make sure that this partition exists */
-
-	if (part != RAW_PART) {
-		if (((rs->sc_flags & RAIDF_INITED) == 0) ||
-		    ((part >= lp->d_npartitions) ||
-			(lp->d_partitions[part].p_fstype == FS_UNUSED))) {
-			error = ENXIO;
-			goto bad;
-		}
-	}
-	/* Prevent this unit from being unconfigured while open. */
-	switch (fmt) {
-	case S_IFCHR:
-		rs->sc_dkdev.dk_copenmask |= pmask;
-		break;
-
-	case S_IFBLK:
-		rs->sc_dkdev.dk_bopenmask |= pmask;
-		break;
-	}
-
-	if ((rs->sc_dkdev.dk_openmask == 0) &&
+	if (!DK_BUSY(dksc, pmask) &&
 	    ((rs->sc_flags & RAIDF_INITED) != 0)) {
 		/* First one... mark things as dirty... Note that we *MUST*
 		 have done a configure before this.  I DO NOT WANT TO BE
@@ -827,9 +766,8 @@ raidopen(dev_t dev, int flags, int fmt,
 		rf_markalldirty(&rs->sc_r);
 	}
 
-
-	rs->sc_dkdev.dk_openmask =
-	    rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
+	if ((rs->sc_flags & RAIDF_INITED) != 0)
+		error = dk_open(dksc, dev, flags, fmt, l);
 
 bad:
 	raidunlock(rs);
@@ -839,141 +777,144 @@ bad:
 
 }
 
+static int
+raid_lastclose(device_t self)
+{
+	struct raid_softc *rs = raidsoftc(self);
+
+	/* Last one... device is not unconfigured yet.
+	   Device shutdown has taken care of setting the
+	   clean bits if RAIDF_INITED is not set
+	   mark things as clean... */
+
+	rf_update_component_labels(&rs->sc_r,
+	    RF_FINAL_COMPONENT_UPDATE);
+
+	/* pass to unlocked code */
+	if ((rs->sc_flags & RAIDF_SHUTDOWN) != 0)
+		rs->sc_flags |= RAIDF_DETACH;
+
+	return 0;
+}
+
 /* ARGSUSED */
 static int
 raidclose(dev_t dev, int flags, int fmt, struct lwp *l)
 {
 	int     unit = raidunit(dev);
 	struct raid_softc *rs;
-	int     error = 0;
-	int     part;
+	struct dk_softc *dksc;
+	cfdata_t cf;
+	int     error = 0, do_detach = 0, do_put = 0;
 
 	if ((rs = raidget(unit, false)) == NULL)
 		return ENXIO;
+	dksc = &rs->sc_dksc;
 
 	if ((error = raidlock(rs)) != 0)
 		return (error);
 
-	part = DISKPART(dev);
-
-	/* ...that much closer to allowing unconfiguration... */
-	switch (fmt) {
-	case S_IFCHR:
-		rs->sc_dkdev.dk_copenmask &= ~(1 << part);
-		break;
-
-	case S_IFBLK:
-		rs->sc_dkdev.dk_bopenmask &= ~(1 << part);
-		break;
-	}
-	rs->sc_dkdev.dk_openmask =
-	    rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
+	if ((rs->sc_flags & RAIDF_INITED) != 0) {
+		error = dk_close(dksc, dev, flags, fmt, l);
+		if ((rs->sc_flags & RAIDF_DETACH) != 0)
+			do_detach = 1;
+	} else if ((rs->sc_flags & RAIDF_SHUTDOWN) != 0)
+		do_put = 1;
 
-	if ((rs->sc_dkdev.dk_openmask == 0) &&
-	    ((rs->sc_flags & RAIDF_INITED) != 0)) {
-		/* Last one... device is not unconfigured yet.
-		   Device shutdown has taken care of setting the
-		   clean bits if RAIDF_INITED is not set
-		   mark things as clean... */
+	raidunlock(rs);
 
-		rf_update_component_labels(&rs->sc_r,
-						 RF_FINAL_COMPONENT_UPDATE);
+	if (do_detach) {
+		/* free the pseudo device attach bits */
+		cf = device_cfdata(dksc->sc_dev);
+		error = config_detach(dksc->sc_dev, 0);
+		if (error == 0) 
+			free(cf, M_RAIDFRAME);
+	} else if (do_put) {
+		raidput(rs);
 	}
-	if ((rs->sc_dkdev.dk_openmask == 0) &&
-	    ((rs->sc_flags & RAIDF_SHUTDOWN) != 0)) {
-		/*
-		 * Detach this raid unit
-		 */
-		cfdata_t cf = NULL;
-		int retcode = 0;
 
-		if (rs->sc_dev != NULL) {
-			cf = device_cfdata(rs->sc_dev);
+	return (error);
 
-			raidunlock(rs);
-			retcode = config_detach(rs->sc_dev, 0);
-			if (retcode == 0)
-				/* free the pseudo device attach bits */
-				free(cf, M_RAIDFRAME);
-		} else {
-			raidput(rs);
-		}
-		return retcode;
-	}
+}
 
-	raidunlock(rs);
-	return (0);
+static void
+raid_wakeup(RF_Raid_t *raidPtr)
+{
+	rf_lock_mutex2(raidPtr->iodone_lock);
+	rf_signal_cond2(raidPtr->iodone_cv);
+	rf_unlock_mutex2(raidPtr->iodone_lock);
 }
 
 static void
 raidstrategy(struct buf *bp)
 {
-	unsigned int unit = raidunit(bp->b_dev);
-	RF_Raid_t *raidPtr;
-	int     wlabel;
+	unsigned int unit;
 	struct raid_softc *rs;
+	struct dk_softc *dksc;
+	RF_Raid_t *raidPtr;
 
+	unit = raidunit(bp->b_dev);
 	if ((rs = raidget(unit, false)) == NULL) {
 		bp->b_error = ENXIO;
-		goto done;
+		goto fail;
 	}
 	if ((rs->sc_flags & RAIDF_INITED) == 0) {
 		bp->b_error = ENXIO;
-		goto done;
+		goto fail;
 	}
+	dksc = &rs->sc_dksc;
 	raidPtr = &rs->sc_r;
-	if (!raidPtr->valid) {
-		bp->b_error = ENODEV;
-		goto done;
-	}
-	if (bp->b_bcount == 0) {
-		db1_printf(("b_bcount is zero..\n"));
+
+	/* Queue IO only */
+	if (dk_strategy_defer(dksc, bp))
 		goto done;
-	}
 
-	/*
-	 * Do bounds checking and adjust transfer.  If there's an
-	 * error, the bounds check will flag that for us.
-	 */
+	/* schedule the IO to happen at the next convenient time */
+	raid_wakeup(raidPtr);
 
-	wlabel = rs->sc_flags & (RAIDF_WLABEL | RAIDF_LABELLING);
-	if (DISKPART(bp->b_dev) == RAW_PART) {
-		uint64_t size; /* device size in DEV_BSIZE unit */
-
-		if (raidPtr->logBytesPerSector > DEV_BSHIFT) {
-			size = raidPtr->totalSectors <<
-			    (raidPtr->logBytesPerSector - DEV_BSHIFT);
-		} else {
-			size = raidPtr->totalSectors >>
-			    (DEV_BSHIFT - raidPtr->logBytesPerSector);
-		}
-		if (bounds_check_with_mediasize(bp, DEV_BSIZE, size) <= 0) {
-			goto done;
-		}
-	} else {
-		if (bounds_check_with_label(&rs->sc_dkdev, bp, wlabel) <= 0) {
-			db1_printf(("Bounds check failed!!:%d %d\n",
-				(int) bp->b_blkno, (int) wlabel));
-			goto done;
-		}
-	}
+done:
+	return;
 
-	rf_lock_mutex2(raidPtr->iodone_lock);
+fail:
+	bp->b_resid = bp->b_bcount;
+	biodone(bp);
+}
 
+static int
+raid_diskstart(device_t dev, struct buf *bp)
+{
+	struct raid_softc *rs = raidsoftc(dev);
+	RF_Raid_t *raidPtr;
+
+	raidPtr = &rs->sc_r;
+	if (!raidPtr->valid) {
+		db1_printf(("raid is not valid..\n"));
+		return ENODEV;
+	}
+
+	/* XXX */
 	bp->b_resid = 0;
 
-	/* stuff it onto our queue */
-	bufq_put(rs->buf_queue, bp);
+	return raiddoaccess(raidPtr, bp);
+}
 
-	/* scheduled the IO to happen at the next convenient time */
-	rf_signal_cond2(raidPtr->iodone_cv);
-	rf_unlock_mutex2(raidPtr->iodone_lock);
+void
+raiddone(RF_Raid_t *raidPtr, struct buf *bp)
+{
+	struct raid_softc *rs;
+	struct dk_softc *dksc;
 
-	return;
+	rs = raidPtr->softc;
+	dksc = &rs->sc_dksc;
 
-done:
-	bp->b_resid = bp->b_bcount;
-	biodone(bp);
+	dk_done(dksc, bp);
+
+	rf_lock_mutex2(raidPtr->mutex);
+	raidPtr->openings++;
+	rf_unlock_mutex2(raidPtr->mutex);
+
+	/* schedule more IO */
+	raid_wakeup(raidPtr);
 }
 
 /* ARGSUSED */
@@ -1013,16 +954,13 @@ raidwrite(dev_t dev, struct uio *uio, in
 static int
 raid_detach_unlocked(struct raid_softc *rs)
 {
-	int error;
+	struct dk_softc *dksc = &rs->sc_dksc;
 	RF_Raid_t *raidPtr;
+	int error;
 
 	raidPtr = &rs->sc_r;
 
-	/*
-	 * If somebody has a partition mounted, we shouldn't
-	 * shutdown.
-	 */
-	if (rs->sc_dkdev.dk_openmask != 0)
+	if (DK_BUSY(dksc, 0))
 		return EBUSY;
 
 	if ((rs->sc_flags & RAIDF_INITED) == 0)
@@ -1033,13 +971,18 @@ raid_detach_unlocked(struct raid_softc *
 	if ((error = rf_Shutdown(raidPtr)) != 0)
 		return error;
 
-	/* Detach the disk. */
-	dkwedge_delall(&rs->sc_dkdev);
-	disk_detach(&rs->sc_dkdev);
-	disk_destroy(&rs->sc_dkdev);
-
 	rs->sc_flags &= ~RAIDF_INITED;
 
+	/* Kill off any queued buffers */
+	dk_drain(dksc);
+	bufq_free(dksc->sc_bufq);
+
+	/* Detach the disk. */
+	dkwedge_delall(&dksc->sc_dkdev);
+	disk_detach(&dksc->sc_dkdev);
+	disk_destroy(&dksc->sc_dkdev);
+	dk_detach(dksc);
+
 	return 0;
 }
 
@@ -1048,8 +991,9 @@ raidioctl(dev_t dev, u_long cmd, void *d
 {
 	int     unit = raidunit(dev);
 	int     error = 0;
-	int     part, pmask, s;
+	int     part, pmask;
 	struct raid_softc *rs;
+	struct dk_softc *dksc;
 	RF_Config_t *k_cfg, *u_cfg;
 	RF_Raid_t *raidPtr;
 	RF_RaidDisk_t *diskPtr;
@@ -1067,62 +1011,17 @@ raidioctl(dev_t dev, u_long cmd, void *d
 	RF_SingleComponent_t component;
 	RF_ProgressInfo_t progressInfo, **progressInfoPtr;
 	int i, j, d;
-#ifdef __HAVE_OLD_DISKLABEL
-	struct disklabel newlabel;
-#endif
 
 	if ((rs = raidget(unit, false)) == NULL)
 		return ENXIO;
+	dksc = &rs->sc_dksc;
 	raidPtr = &rs->sc_r;
 
 	db1_printf(("raidioctl: %d %d %d %lu\n", (int) dev,
 		(int) DISKPART(dev), (int) unit, cmd));
 
-	/* Must be open for writes for these commands... */
-	switch (cmd) {
-#ifdef DIOCGSECTORSIZE
-	case DIOCGSECTORSIZE:
-		*(u_int *)data = raidPtr->bytesPerSector;
-		return 0;
-	case DIOCGMEDIASIZE:
-		*(off_t *)data =
-		    (off_t)raidPtr->totalSectors * raidPtr->bytesPerSector;
-		return 0;
-#endif
-	case DIOCSDINFO:
-	case DIOCWDINFO:
-#ifdef __HAVE_OLD_DISKLABEL
-	case ODIOCWDINFO:
-	case ODIOCSDINFO:
-#endif
-	case DIOCWLABEL:
-	case DIOCAWEDGE:
-	case DIOCDWEDGE:
-	case DIOCMWEDGES:
-	case DIOCSSTRATEGY:
-		if ((flag & FWRITE) == 0)
-			return (EBADF);
-	}
-
 	/* Must be initialized for these... */
 	switch (cmd) {
-	case DIOCGDINFO:
-	case DIOCSDINFO:
-	case DIOCWDINFO:
-#ifdef __HAVE_OLD_DISKLABEL
-	case ODIOCGDINFO:
-	case ODIOCWDINFO:
-	case ODIOCSDINFO:
-	case ODIOCGDEFLABEL:
-#endif
-	case DIOCGPARTINFO:
-	case DIOCWLABEL:
-	case DIOCGDEFLABEL:
-	case DIOCAWEDGE:
-	case DIOCDWEDGE:
-	case DIOCLWEDGES:
-	case DIOCMWEDGES:
-	case DIOCCACHESYNC:
 	case RAIDFRAME_REWRITEPARITY:
 	case RAIDFRAME_GET_INFO:
 	case RAIDFRAME_RESET_ACCTOTALS:
@@ -1152,8 +1051,6 @@ raidioctl(dev_t dev, u_long cmd, void *d
 	case RAIDFRAME_PARITYMAP_GET_DISABLE:
 	case RAIDFRAME_PARITYMAP_SET_DISABLE:
 	case RAIDFRAME_PARITYMAP_SET_PARAMS:
-	case DIOCGSTRATEGY:
-	case DIOCSSTRATEGY:
 		if ((rs->sc_flags & RAIDF_INITED) == 0)
 			return (ENXIO);
 	}
@@ -1249,6 +1146,7 @@ raidioctl(dev_t dev, u_long cmd, void *d
 			raidPtr->openings = RAIDOUTSTANDING;
 
 			raidinit(rs);
+			raid_wakeup(raidPtr);
 			rf_markalldirty(raidPtr);
 		}
 		/* free the buffers.  No return code here. */
@@ -1275,11 +1173,10 @@ raidioctl(dev_t dev, u_long cmd, void *d
 		if ((error = raidlock(rs)) != 0)
 			return (error);
 
-		if ((rs->sc_dkdev.dk_openmask & ~pmask) ||
-		    ((rs->sc_dkdev.dk_bopenmask & pmask) &&
-			(rs->sc_dkdev.dk_copenmask & pmask)))
+		if (DK_BUSY(dksc, pmask))
 			retcode = EBUSY;
 		else {
+			/* detach and free on close */
 			rs->sc_flags |= RAIDF_SHUTDOWN;
 			retcode = 0;
 		}
@@ -1832,115 +1729,14 @@ raidioctl(dev_t dev, u_long cmd, void *d
 	 * Add support for "regular" device ioctls here.
 	 */
 	
-	error = disk_ioctl(&rs->sc_dkdev, dev, cmd, data, flag, l); 
+	error = dk_ioctl(dksc, dev, cmd, data, flag, l);
 	if (error != EPASSTHROUGH)
 		return (error);
 
 	switch (cmd) {
-	case DIOCWDINFO:
-	case DIOCSDINFO:
-#ifdef __HAVE_OLD_DISKLABEL
-	case ODIOCWDINFO:
-	case ODIOCSDINFO:
-#endif
-	{
-		struct disklabel *lp;
-#ifdef __HAVE_OLD_DISKLABEL
-		if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
-			memset(&newlabel, 0, sizeof newlabel);
-			memcpy(&newlabel, data, sizeof (struct olddisklabel));
-			lp = &newlabel;
-		} else
-#endif
-		lp = (struct disklabel *)data;
-
-		if ((error = raidlock(rs)) != 0)
-			return (error);
-
-		rs->sc_flags |= RAIDF_LABELLING;
-
-		error = setdisklabel(rs->sc_dkdev.dk_label,
-		    lp, 0, rs->sc_dkdev.dk_cpulabel);
-		if (error == 0) {
-			if (cmd == DIOCWDINFO
-#ifdef __HAVE_OLD_DISKLABEL
-			    || cmd == ODIOCWDINFO
-#endif
-			   )
-				error = writedisklabel(RAIDLABELDEV(dev),
-				    raidstrategy, rs->sc_dkdev.dk_label,
-				    rs->sc_dkdev.dk_cpulabel);
-		}
-		rs->sc_flags &= ~RAIDF_LABELLING;
-
-		raidunlock(rs);
-
-		if (error)
-			return (error);
-		break;
-	}
-
-	case DIOCWLABEL:
-		if (*(int *) data != 0)
-			rs->sc_flags |= RAIDF_WLABEL;
-		else
-			rs->sc_flags &= ~RAIDF_WLABEL;
-		break;
-
-	case DIOCGDEFLABEL:
-		raidgetdefaultlabel(raidPtr, rs, (struct disklabel *) data);
-		break;
-
-#ifdef __HAVE_OLD_DISKLABEL
-	case ODIOCGDEFLABEL:
-		raidgetdefaultlabel(raidPtr, rs, &newlabel);
-		if (newlabel.d_npartitions > OLDMAXPARTITIONS)
-			return ENOTTY;
-		memcpy(data, &newlabel, sizeof (struct olddisklabel));
-		break;
-#endif
-
 	case DIOCCACHESYNC:
 		return rf_sync_component_caches(raidPtr);
 
-	case DIOCGSTRATEGY:
-	    {
-		struct disk_strategy *dks = (void *)data;
-
-		s = splbio();
-		strlcpy(dks->dks_name, bufq_getstrategyname(rs->buf_queue),
-		    sizeof(dks->dks_name));
-		splx(s);
-		dks->dks_paramlen = 0;
-
-		return 0;
-	    }
-	
-	case DIOCSSTRATEGY:
-	    {
-		struct disk_strategy *dks = (void *)data;
-		struct bufq_state *new;
-		struct bufq_state *old;
-
-		if (dks->dks_param != NULL) {
-			return EINVAL;
-		}
-		dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */
-		error = bufq_alloc(&new, dks->dks_name,
-		    BUFQ_EXACT|BUFQ_SORT_RAWBLOCK);
-		if (error) {
-			return error;
-		}
-		s = splbio();
-		old = rs->buf_queue;
-		bufq_move(new, old);
-		rs->buf_queue = new;
-		splx(s);
-		bufq_free(old);
-
-		return 0;
-	    }
-
 	default:
 		retcode = ENOTTY;
 	}
@@ -1957,17 +1753,15 @@ static void
 raidinit(struct raid_softc *rs)
 {
 	cfdata_t cf;
-	int     unit;
+	unsigned int unit;
+	struct dk_softc *dksc = &rs->sc_dksc;
 	RF_Raid_t *raidPtr = &rs->sc_r;
+	device_t dev;
 
 	unit = raidPtr->raidid;
 
-
-	/* XXX should check return code first... */
-	rs->sc_flags |= RAIDF_INITED;
-
 	/* XXX doesn't check bounds. */
-	snprintf(rs->sc_xname, sizeof(rs->sc_xname), "raid%d", unit);
+	snprintf(rs->sc_xname, sizeof(rs->sc_xname), "raid%u", unit);
 
 	/* attach the pseudo device */
 	cf = malloc(sizeof(*cf), M_RAIDFRAME, M_WAITOK);
@@ -1976,33 +1770,41 @@ raidinit(struct raid_softc *rs)
 	cf->cf_unit = unit;
 	cf->cf_fstate = FSTATE_STAR;
 
-	rs->sc_dev = config_attach_pseudo(cf);
-
-	if (rs->sc_dev == NULL) {
+	dev = config_attach_pseudo(cf);
+	if (dev == NULL) {
 		printf("raid%d: config_attach_pseudo failed\n",
 		    raidPtr->raidid);
-		rs->sc_flags &= ~RAIDF_INITED;
 		free(cf, M_RAIDFRAME);
 		return;
 	}
 
+	/* provide a backpointer to the real softc */
+	raidsoftc(dev) = rs;
+
 	/* disk_attach actually creates space for the CPU disklabel, among
 	 * other things, so it's critical to call this *BEFORE* we try putzing
 	 * with disklabels. */
-
-	disk_init(&rs->sc_dkdev, rs->sc_xname, &rf_dkdriver);
-	disk_attach(&rs->sc_dkdev);
+	dk_init(dksc, dev, DKTYPE_RAID);
+	disk_init(&dksc->sc_dkdev, rs->sc_xname, &rf_dkdriver);
 
 	/* XXX There may be a weird interaction here between this, and
 	 * protectedSectors, as used in RAIDframe.  */
 
 	rs->sc_size = raidPtr->totalSectors;
 
+	/* Attach dk and disk subsystems */
+	dk_attach(dksc);
+	disk_attach(&dksc->sc_dkdev);
 	rf_set_geometry(rs, raidPtr);
 
-	dkwedge_discover(&rs->sc_dkdev);
+	bufq_alloc(&dksc->sc_bufq, "fcfs", BUFQ_SORT_RAWBLOCK);
+
+	/* mark unit as usuable */
+	rs->sc_flags |= RAIDF_INITED;
 
+	dkwedge_discover(&dksc->sc_dkdev);
 }
+
 #if (RF_INCLUDE_PARITY_DECLUSTERING_DS > 0)
 /* wake up the daemon & tell it to get us a spare table
  * XXX
@@ -2049,16 +1851,11 @@ rf_GetSpareTableFromDaemon(RF_SparetWait
 void
 raidstart(RF_Raid_t *raidPtr)
 {
-	RF_SectorCount_t num_blocks, pb, sum;
-	RF_RaidAddr_t raid_addr;
-	struct partition *pp;
-	daddr_t blocknum;
 	struct raid_softc *rs;
-	int     do_async;
-	struct buf *bp;
-	int rc;
+	struct dk_softc *dksc;
 
 	rs = raidPtr->softc;
+	dksc = &rs->sc_dksc;
 	/* quick check to see if anything has died recently */
 	rf_lock_mutex2(raidPtr->mutex);
 	if (raidPtr->numNewFailures > 0) {
@@ -2068,104 +1865,88 @@ raidstart(RF_Raid_t *raidPtr)
 		rf_lock_mutex2(raidPtr->mutex);
 		raidPtr->numNewFailures--;
 	}
+	rf_unlock_mutex2(raidPtr->mutex);
 
-	/* Check to see if we're at the limit... */
-	while (raidPtr->openings > 0) {
-		rf_unlock_mutex2(raidPtr->mutex);
-
-		/* get the next item, if any, from the queue */
-		if ((bp = bufq_get(rs->buf_queue)) == NULL) {
-			/* nothing more to do */
-			return;
-		}
-
-		/* Ok, for the bp we have here, bp->b_blkno is relative to the
-		 * partition.. Need to make it absolute to the underlying
-		 * device.. */
-
-		blocknum = bp->b_blkno << DEV_BSHIFT >> raidPtr->logBytesPerSector;
-		if (DISKPART(bp->b_dev) != RAW_PART) {
-			pp = &rs->sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)];
-			blocknum += pp->p_offset;
-		}
-
-		db1_printf(("Blocks: %d, %d\n", (int) bp->b_blkno,
-			    (int) blocknum));
-
-		db1_printf(("bp->b_bcount = %d\n", (int) bp->b_bcount));
-		db1_printf(("bp->b_resid = %d\n", (int) bp->b_resid));
-
-		/* *THIS* is where we adjust what block we're going to...
-		 * but DO NOT TOUCH bp->b_blkno!!! */
-		raid_addr = blocknum;
-
-		num_blocks = bp->b_bcount >> raidPtr->logBytesPerSector;
-		pb = (bp->b_bcount & raidPtr->sectorMask) ? 1 : 0;
-		sum = raid_addr + num_blocks + pb;
-		if (1 || rf_debugKernelAccess) {
-			db1_printf(("raid_addr=%d sum=%d num_blocks=%d(+%d) (%d)\n",
-				    (int) raid_addr, (int) sum, (int) num_blocks,
-				    (int) pb, (int) bp->b_resid));
-		}
-		if ((sum > raidPtr->totalSectors) || (sum < raid_addr)
-		    || (sum < num_blocks) || (sum < pb)) {
-			bp->b_error = ENOSPC;
-			bp->b_resid = bp->b_bcount;
-			biodone(bp);
-			rf_lock_mutex2(raidPtr->mutex);
-			continue;
-		}
-		/*
-		 * XXX rf_DoAccess() should do this, not just DoAccessKernel()
-		 */
-
-		if (bp->b_bcount & raidPtr->sectorMask) {
-			bp->b_error = EINVAL;
-			bp->b_resid = bp->b_bcount;
-			biodone(bp);
-			rf_lock_mutex2(raidPtr->mutex);
-			continue;
+	if ((rs->sc_flags & RAIDF_INITED) == 0) {
+		printf("raid%d: raidstart not ready\n", raidPtr->raidid);
+		return;
+	}
 
-		}
-		db1_printf(("Calling DoAccess..\n"));
+	dk_start(dksc, NULL);
+}
 
+static int
+raiddoaccess(RF_Raid_t *raidPtr, struct buf *bp)
+{
+	RF_SectorCount_t num_blocks, pb, sum;
+	RF_RaidAddr_t raid_addr;
+	daddr_t blocknum;
+	int     do_async;
+	int rc;
 
-		rf_lock_mutex2(raidPtr->mutex);
-		raidPtr->openings--;
+	rf_lock_mutex2(raidPtr->mutex);
+	if (raidPtr->openings == 0) {
 		rf_unlock_mutex2(raidPtr->mutex);
+		return EAGAIN;
+	}
+	rf_unlock_mutex2(raidPtr->mutex);
 
-		/*
-		 * Everything is async.
-		 */
-		do_async = 1;
+	blocknum = bp->b_rawblkno;
 
-		disk_busy(&rs->sc_dkdev);
+	db1_printf(("Blocks: %d, %d\n", (int) bp->b_blkno,
+		    (int) blocknum));
 
-		/* XXX we're still at splbio() here... do we *really*
-		   need to be? */
+	db1_printf(("bp->b_bcount = %d\n", (int) bp->b_bcount));
+	db1_printf(("bp->b_resid = %d\n", (int) bp->b_resid));
 
-		/* don't ever condition on bp->b_flags & B_WRITE.
-		 * always condition on B_READ instead */
-
-		rc = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
-				 RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
-				 do_async, raid_addr, num_blocks,
-				 bp->b_data, bp, RF_DAG_NONBLOCKING_IO);
-
-		if (rc) {
-			bp->b_error = rc;
-			bp->b_resid = bp->b_bcount;
-			biodone(bp);
-			/* continue loop */
-		}
+	/* *THIS* is where we adjust what block we're going to...
+	 * but DO NOT TOUCH bp->b_blkno!!! */
+	raid_addr = blocknum;
+
+	num_blocks = bp->b_bcount >> raidPtr->logBytesPerSector;
+	pb = (bp->b_bcount & raidPtr->sectorMask) ? 1 : 0;
+	sum = raid_addr + num_blocks + pb;
+	if (1 || rf_debugKernelAccess) {
+		db1_printf(("raid_addr=%d sum=%d num_blocks=%d(+%d) (%d)\n",
+			    (int) raid_addr, (int) sum, (int) num_blocks,
+			    (int) pb, (int) bp->b_resid));
+	}
+	if ((sum > raidPtr->totalSectors) || (sum < raid_addr)
+	    || (sum < num_blocks) || (sum < pb)) {
+		rc = ENOSPC;
+		goto done;
+	}
+	/*
+	 * XXX rf_DoAccess() should do this, not just DoAccessKernel()
+	 */
 
-		rf_lock_mutex2(raidPtr->mutex);
+	if (bp->b_bcount & raidPtr->sectorMask) {
+		rc = ENOSPC;
+		goto done;
 	}
+	db1_printf(("Calling DoAccess..\n"));
+
+
+	rf_lock_mutex2(raidPtr->mutex);
+	raidPtr->openings--;
 	rf_unlock_mutex2(raidPtr->mutex);
-}
 
+	/*
+	 * Everything is async.
+	 */
+	do_async = 1;
 
+	/* don't ever condition on bp->b_flags & B_WRITE.
+	 * always condition on B_READ instead */
 
+	rc = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
+			 RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
+			 do_async, raid_addr, num_blocks,
+			 bp->b_data, bp, RF_DAG_NONBLOCKING_IO);
+
+done:
+	return rc;
+}
 
 /* invoke an I/O from kernel mode.  Disk queue should be locked upon entry */
 
@@ -2341,128 +2122,6 @@ InitBP(struct buf *bp, struct vnode *b_v
 	bp->b_private = cbArg;
 }
 
-static void
-raidgetdefaultlabel(RF_Raid_t *raidPtr, struct raid_softc *rs,
-		    struct disklabel *lp)
-{
-	memset(lp, 0, sizeof(*lp));
-
-	/* fabricate a label... */
-	if (raidPtr->totalSectors > UINT32_MAX)
-		lp->d_secperunit = UINT32_MAX;
-	else
-		lp->d_secperunit = raidPtr->totalSectors;
-	lp->d_secsize = raidPtr->bytesPerSector;
-	lp->d_nsectors = raidPtr->Layout.dataSectorsPerStripe;
-	lp->d_ntracks = 4 * raidPtr->numCol;
-	lp->d_ncylinders = raidPtr->totalSectors /
-		(lp->d_nsectors * lp->d_ntracks);
-	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
-
-	strncpy(lp->d_typename, "raid", sizeof(lp->d_typename));
-	lp->d_type = DKTYPE_RAID;
-	strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
-	lp->d_rpm = 3600;
-	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(rs->sc_dkdev.dk_label);
-
-}
-/*
- * Read the disklabel from the raid device.  If one is not present, fake one
- * up.
- */
-static void
-raidgetdisklabel(dev_t dev)
-{
-	int     unit = raidunit(dev);
-	struct raid_softc *rs;
-	const char   *errstring;
-	struct disklabel *lp;
-	struct cpu_disklabel *clp;
-	RF_Raid_t *raidPtr;
-
-	if ((rs = raidget(unit, false)) == NULL)
-		return;
-
-	lp = rs->sc_dkdev.dk_label;
-	clp = rs->sc_dkdev.dk_cpulabel;
-
-	db1_printf(("Getting the disklabel...\n"));
-
-	memset(clp, 0, sizeof(*clp));
-
-	raidPtr = &rs->sc_r;
-
-	raidgetdefaultlabel(raidPtr, rs, lp);
-
-	/*
-	 * Call the generic disklabel extraction routine.
-	 */
-	errstring = readdisklabel(RAIDLABELDEV(dev), raidstrategy,
-	    rs->sc_dkdev.dk_label, rs->sc_dkdev.dk_cpulabel);
-	if (errstring)
-		raidmakedisklabel(rs);
-	else {
-		int     i;
-		struct partition *pp;
-
-		/*
-		 * Sanity check whether the found disklabel is valid.
-		 *
-		 * This is necessary since total size of the raid device
-		 * may vary when an interleave is changed even though exactly
-		 * same components are used, and old disklabel may used
-		 * if that is found.
-		 */
-		if (lp->d_secperunit < UINT32_MAX ?
-		    lp->d_secperunit != rs->sc_size :
-		    lp->d_secperunit > rs->sc_size)
-			printf("raid%d: WARNING: %s: "
-			    "total sector size in disklabel (%ju) != "
-			    "the size of raid (%ju)\n", unit, rs->sc_xname,
-			    (uintmax_t)lp->d_secperunit,
-			    (uintmax_t)rs->sc_size);
-		for (i = 0; i < lp->d_npartitions; i++) {
-			pp = &lp->d_partitions[i];
-			if (pp->p_offset + pp->p_size > rs->sc_size)
-				printf("raid%d: WARNING: %s: end of partition `%c' "
-				       "exceeds the size of raid (%ju)\n",
-				       unit, rs->sc_xname, 'a' + i,
-				       (uintmax_t)rs->sc_size);
-		}
-	}
-
-}
-/*
- * Take care of things one might want to take care of in the event
- * that a disklabel isn't present.
- */
-static void
-raidmakedisklabel(struct raid_softc *rs)
-{
-	struct disklabel *lp = rs->sc_dkdev.dk_label;
-	db1_printf(("Making a label..\n"));
-
-	/*
-	 * For historical reasons, if there's no disklabel present
-	 * the raw partition must be marked FS_BSDFFS.
-	 */
-
-	lp->d_partitions[RAW_PART].p_fstype = FS_BSDFFS;
-
-	strncpy(lp->d_packname, "default label", sizeof(lp->d_packname));
-
-	lp->d_checksum = dkcksum(lp);
-}
 /*
  * Wait interruptibly for an exclusive lock.
  *
@@ -2475,16 +2134,18 @@ raidlock(struct raid_softc *rs)
 {
 	int     error;
 
+	error = 0;
 	mutex_enter(&rs->sc_mutex);
 	while ((rs->sc_flags & RAIDF_LOCKED) != 0) {
 		rs->sc_flags |= RAIDF_WANTED;
 		error = cv_wait_sig(&rs->sc_cv, &rs->sc_mutex);
 		if (error != 0)
-			return (error);
+			goto done;
 	}
 	rs->sc_flags |= RAIDF_LOCKED;
+done:
 	mutex_exit(&rs->sc_mutex);
-	return (0);
+	return (error);
 }
 /*
  * Unlock and wake up any waiters.
@@ -3089,171 +2750,186 @@ rf_find_raid_components(void)
 	RF_AutoConfig_t *ac_list;
 	uint64_t numsecs;
 	unsigned secsize;
+	int dowedges;
 
 	/* initialize the AutoConfig list */
 	ac_list = NULL;
 
-	/* we begin by trolling through *all* the devices on the system */
+	/*
+	 * we begin by trolling through *all* the devices on the system *twice*
+	 * first we scan for wedges, second for other devices. This avoids
+	 * using a raw partition instead of a wedge that covers the whole disk
+	 */
 
-	for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
-	     dv = deviter_next(&di)) {
+	for (dowedges=1; dowedges>=0; --dowedges) {
+		for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
+		     dv = deviter_next(&di)) {
 
-		/* we are only interested in disks... */
-		if (device_class(dv) != DV_DISK)
-			continue;
-
-		/* we don't care about floppies... */
-		if (device_is_a(dv, "fd")) {
-			continue;
-		}
+			/* we are only interested in disks... */
+			if (device_class(dv) != DV_DISK)
+				continue;
 
-		/* we don't care about CD's... */
-		if (device_is_a(dv, "cd")) {
-			continue;
-		}
+			/* we don't care about floppies... */
+			if (device_is_a(dv, "fd")) {
+				continue;
+			}
 
-		/* we don't care about md's... */
-		if (device_is_a(dv, "md")) {
-			continue;
-		}
+			/* we don't care about CD's... */
+			if (device_is_a(dv, "cd")) {
+				continue;
+			}
 
-		/* hdfd is the Atari/Hades floppy driver */
-		if (device_is_a(dv, "hdfd")) {
-			continue;
-		}
+			/* we don't care about md's... */
+			if (device_is_a(dv, "md")) {
+				continue;
+			}
 
-		/* fdisa is the Atari/Milan floppy driver */
-		if (device_is_a(dv, "fdisa")) {
-			continue;
-		}
+			/* hdfd is the Atari/Hades floppy driver */
+			if (device_is_a(dv, "hdfd")) {
+				continue;
+			}
 
-		/* need to find the device_name_to_block_device_major stuff */
-		bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
+			/* fdisa is the Atari/Milan floppy driver */
+			if (device_is_a(dv, "fdisa")) {
+				continue;
+			}
 
-		rf_part_found = 0; /*No raid partition as yet*/
+			/* are we in the wedges pass ? */
+			wedge = device_is_a(dv, "dk");
+			if (wedge != dowedges) {
+				continue;
+			}
 
-		/* get a vnode for the raw partition of this disk */
+			/* need to find the device_name_to_block_device_major stuff */
+			bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
 
-		wedge = device_is_a(dv, "dk");
-		bminor = minor(device_unit(dv));
-		dev = wedge ? makedev(bmajor, bminor) :
-		    MAKEDISKDEV(bmajor, bminor, RAW_PART);
-		if (bdevvp(dev, &vp))
-			panic("RAID can't alloc vnode");
+			rf_part_found = 0; /*No raid partition as yet*/
 
-		error = VOP_OPEN(vp, FREAD | FSILENT, NOCRED);
+			/* get a vnode for the raw partition of this disk */
+			bminor = minor(device_unit(dv));
+			dev = wedge ? makedev(bmajor, bminor) :
+			    MAKEDISKDEV(bmajor, bminor, RAW_PART);
+			if (bdevvp(dev, &vp))
+				panic("RAID can't alloc vnode");
 
-		if (error) {
-			/* "Who cares."  Continue looking
-			   for something that exists*/
-			vput(vp);
-			continue;
-		}
+			error = VOP_OPEN(vp, FREAD | FSILENT, NOCRED);
 
-		error = getdisksize(vp, &numsecs, &secsize);
-		if (error) {
-			vput(vp);
-			continue;
-		}
-		if (wedge) {
-			struct dkwedge_info dkw;
-			error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD,
-			    NOCRED);
 			if (error) {
-				printf("RAIDframe: can't get wedge info for "
-				    "dev %s (%d)\n", device_xname(dv), error);
-				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-				VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
+				/* "Who cares."  Continue looking
+				   for something that exists*/
 				vput(vp);
 				continue;
 			}
 
-			if (strcmp(dkw.dkw_ptype, DKW_PTYPE_RAIDFRAME) != 0) {
+			error = getdisksize(vp, &numsecs, &secsize);
+			if (error) {
+				printf("RAIDframe: can't get disk size for "
+				    "dev %s (%d)\n", device_xname(dv), error);
 				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 				VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
 				vput(vp);
 				continue;
 			}
-				
-			ac_list = rf_get_component(ac_list, dev, vp,
-			    device_xname(dv), dkw.dkw_size, numsecs, secsize);
-			rf_part_found = 1; /*There is a raid component on this disk*/
-			continue;
-		}
-
-		/* Ok, the disk exists.  Go get the disklabel. */
-		error = VOP_IOCTL(vp, DIOCGDINFO, &label, FREAD, NOCRED);
-		if (error) {
-			/*
-			 * XXX can't happen - open() would
-			 * have errored out (or faked up one)
-			 */
-			if (error != ENOTTY)
-				printf("RAIDframe: can't get label for dev "
-				    "%s (%d)\n", device_xname(dv), error);
-		}
+			if (wedge) {
+				struct dkwedge_info dkw;
+				error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD,
+				    NOCRED);
+				if (error) {
+					printf("RAIDframe: can't get wedge info for "
+					    "dev %s (%d)\n", device_xname(dv), error);
+					vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+					VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
+					vput(vp);
+					continue;
+				}
 
-		/* don't need this any more.  We'll allocate it again
-		   a little later if we really do... */
-		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-		VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
-		vput(vp);
+				if (strcmp(dkw.dkw_ptype, DKW_PTYPE_RAIDFRAME) != 0) {
+					vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+					VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
+					vput(vp);
+					continue;
+				}
+					
+				ac_list = rf_get_component(ac_list, dev, vp,
+				    device_xname(dv), dkw.dkw_size, numsecs, secsize);
+				rf_part_found = 1; /*There is a raid component on this disk*/
+				continue;
+			}
 
-		if (error)
-			continue;
+			/* Ok, the disk exists.  Go get the disklabel. */
+			error = VOP_IOCTL(vp, DIOCGDINFO, &label, FREAD, NOCRED);
+			if (error) {
+				/*
+				 * XXX can't happen - open() would
+				 * have errored out (or faked up one)
+				 */
+				if (error != ENOTTY)
+					printf("RAIDframe: can't get label for dev "
+					    "%s (%d)\n", device_xname(dv), error);
+			}
 
-		rf_part_found = 0; /*No raid partitions yet*/
-		for (i = 0; i < label.d_npartitions; i++) {
-			char cname[sizeof(ac_list->devname)];
+			/* don't need this any more.  We'll allocate it again
+			   a little later if we really do... */
+			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+			VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
+			vput(vp);
 
-			/* We only support partitions marked as RAID */
-			if (label.d_partitions[i].p_fstype != FS_RAID)
+			if (error)
 				continue;
 
-			dev = MAKEDISKDEV(bmajor, device_unit(dv), i);
-			if (bdevvp(dev, &vp))
-				panic("RAID can't alloc vnode");
-
-			error = VOP_OPEN(vp, FREAD, NOCRED);
-			if (error) {
-				/* Whatever... */
-				vput(vp);
-				continue;
-			}
-			snprintf(cname, sizeof(cname), "%s%c",
-			    device_xname(dv), 'a' + i);
-			ac_list = rf_get_component(ac_list, dev, vp, cname,
-				label.d_partitions[i].p_size, numsecs, secsize);
+			rf_part_found = 0; /*No raid partitions yet*/
+			for (i = 0; i < label.d_npartitions; i++) {
+				char cname[sizeof(ac_list->devname)];
+
+				/* We only support partitions marked as RAID */
+				if (label.d_partitions[i].p_fstype != FS_RAID)
+					continue;
+
+				dev = MAKEDISKDEV(bmajor, device_unit(dv), i);
+				if (bdevvp(dev, &vp))
+					panic("RAID can't alloc vnode");
+
+				error = VOP_OPEN(vp, FREAD, NOCRED);
+				if (error) {
+					/* Whatever... */
+					vput(vp);
+					continue;
+				}
+				snprintf(cname, sizeof(cname), "%s%c",
+				    device_xname(dv), 'a' + i);
+				ac_list = rf_get_component(ac_list, dev, vp, cname,
+					label.d_partitions[i].p_size, numsecs, secsize);
 				rf_part_found = 1; /*There is at least one raid partition on this disk*/
-		}
-
-		/*
-		 *If there is no raid component on this disk, either in a
-		 *disklabel or inside a wedge, check the raw partition as well,
-		 *as it is possible to configure raid components on raw disk
-		 *devices.
-		 */
+			}
 
-		if (!rf_part_found) {
-			char cname[sizeof(ac_list->devname)];
+			/*
+			 *If there is no raid component on this disk, either in a
+			 *disklabel or inside a wedge, check the raw partition as well,
+			 *as it is possible to configure raid components on raw disk
+			 *devices.
+			 */
 
-			dev = MAKEDISKDEV(bmajor, device_unit(dv), RAW_PART);
-			if (bdevvp(dev, &vp))
-				panic("RAID can't alloc vnode");
+			if (!rf_part_found) {
+				char cname[sizeof(ac_list->devname)];
 
-			error = VOP_OPEN(vp, FREAD, NOCRED);
-			if (error) {
-				/* Whatever... */
-				vput(vp);
-				continue;
+				dev = MAKEDISKDEV(bmajor, device_unit(dv), RAW_PART);
+				if (bdevvp(dev, &vp))
+					panic("RAID can't alloc vnode");
+
+				error = VOP_OPEN(vp, FREAD, NOCRED);
+				if (error) {
+					/* Whatever... */
+					vput(vp);
+					continue;
+				}
+				snprintf(cname, sizeof(cname), "%s%c",
+				    device_xname(dv), 'a' + RAW_PART);
+				ac_list = rf_get_component(ac_list, dev, vp, cname,
+					label.d_partitions[RAW_PART].p_size, numsecs, secsize);
 			}
-			snprintf(cname, sizeof(cname), "%s%c",
-			    device_xname(dv), 'a' + RAW_PART);
-			ac_list = rf_get_component(ac_list, dev, vp, cname,
-				label.d_partitions[RAW_PART].p_size, numsecs, secsize);
 		}
+		deviter_release(&di);
 	}
-	deviter_release(&di);
 	return ac_list;
 }
 
@@ -3681,7 +3357,7 @@ rf_release_all_vps(RF_ConfigSet_t *cset)
 		/* Close the vp, and give it back */
 		if (ac->vp) {
 			vn_lock(ac->vp, LK_EXCLUSIVE | LK_RETRY);
-			VOP_CLOSE(ac->vp, FREAD, NOCRED);
+			VOP_CLOSE(ac->vp, FREAD | FWRITE, NOCRED);
 			vput(ac->vp);
 			ac->vp = NULL;
 		}
@@ -3829,18 +3505,6 @@ rf_auto_config_set(RF_ConfigSet_t *cset)
 }
 
 void
-rf_disk_unbusy(RF_RaidAccessDesc_t *desc)
-{
-	struct buf *bp;
-	struct raid_softc *rs;
-
-	bp = (struct buf *)desc->bp;
-	rs = desc->raidPtr->softc;
-	disk_unbusy(&rs->sc_dkdev, (bp->b_bcount - bp->b_resid),
-	    (bp->b_flags & B_READ));
-}
-
-void
 rf_pool_init(struct pool *p, size_t size, const char *w_chan,
 	     size_t xmin, size_t xmax)
 {
@@ -3851,21 +3515,28 @@ rf_pool_init(struct pool *p, size_t size
 }
 
 /*
- * rf_buf_queue_check(RF_Raid_t raidPtr) -- looks into the buf_queue to see
- * if there is IO pending and if that IO could possibly be done for a
- * given RAID set.  Returns 0 if IO is waiting and can be done, 1
+ * rf_buf_queue_check(RF_Raid_t raidPtr) -- looks into the buffer queue
+ * to see if there is IO pending and if that IO could possibly be done
+ * for a given RAID set.  Returns 0 if IO is waiting and can be done, 1
  * otherwise.
  *
  */
-
 int
 rf_buf_queue_check(RF_Raid_t *raidPtr)
 {
-	struct raid_softc *rs = raidPtr->softc;
-	if ((bufq_peek(rs->buf_queue) != NULL) && raidPtr->openings > 0) {
+	struct raid_softc *rs;
+	struct dk_softc *dksc;
+
+	rs = raidPtr->softc;
+	dksc = &rs->sc_dksc;
+
+	if ((rs->sc_flags & RAIDF_INITED) == 0)
+		return 1;
+
+	if (dk_strategy_pending(dksc) && raidPtr->openings > 0) {
 		/* there is work to do */
 		return 0;
-	} 
+	}
 	/* default is nothing to do */
 	return 1;
 }
@@ -3896,7 +3567,6 @@ raid_match(device_t self, cfdata_t cfdat
 static void
 raid_attach(device_t parent, device_t self, void *aux)
 {
-
 }
 
 
@@ -3904,7 +3574,7 @@ static int
 raid_detach(device_t self, int flags)
 {
 	int error;
-	struct raid_softc *rs = raidget(device_unit(self), false);
+	struct raid_softc *rs = raidsoftc(self);
 
 	if (rs == NULL)
 		return ENXIO;
@@ -3930,7 +3600,8 @@ raid_detach(device_t self, int flags)
 static void
 rf_set_geometry(struct raid_softc *rs, RF_Raid_t *raidPtr)
 {
-	struct disk_geom *dg = &rs->sc_dkdev.dk_geom;
+	struct dk_softc *dksc = &rs->sc_dksc;
+	struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
 
 	memset(dg, 0, sizeof(*dg));
 
@@ -3939,7 +3610,7 @@ rf_set_geometry(struct raid_softc *rs, R
 	dg->dg_nsectors = raidPtr->Layout.dataSectorsPerStripe;
 	dg->dg_ntracks = 4 * raidPtr->numCol;
 
-	disk_set_info(rs->sc_dev, &rs->sc_dkdev, NULL);
+	disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
 }
 
 /* 
@@ -4110,12 +3781,14 @@ raid_modcmd_fini(void)
 
 	error = config_cfattach_detach(raid_cd.cd_name, &raid_ca);
 	if (error != 0) {
+		aprint_error("%s: cannot detach cfattach\n",__func__);
 		mutex_exit(&raid_lock);
 		return error;
 	}
 #ifdef _MODULE
 	error = config_cfdriver_detach(&raid_cd);
 	if (error != 0) {
+		aprint_error("%s: cannot detach cfdriver\n",__func__);
 		config_cfattach_attach(raid_cd.cd_name, &raid_ca);
 		mutex_exit(&raid_lock);
 		return error;
@@ -4123,6 +3796,7 @@ raid_modcmd_fini(void)
 #endif
 	error = devsw_detach(&raid_bdevsw, &raid_cdevsw);
 	if (error != 0) {
+		aprint_error("%s: cannot detach devsw\n",__func__);
 #ifdef _MODULE
 		config_cfdriver_attach(&raid_cd);
 #endif

Index: src/sys/dev/raidframe/rf_states.c
diff -u src/sys/dev/raidframe/rf_states.c:1.49 src/sys/dev/raidframe/rf_states.c:1.50
--- src/sys/dev/raidframe/rf_states.c:1.49	Wed May 11 18:13:12 2011
+++ src/sys/dev/raidframe/rf_states.c	Sun Jan  3 08:17:24 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: rf_states.c,v 1.49 2011/05/11 18:13:12 mrg Exp $	*/
+/*	$NetBSD: rf_states.c,v 1.50 2016/01/03 08:17:24 mlelstv Exp $	*/
 /*
  * Copyright (c) 1995 Carnegie-Mellon University.
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.49 2011/05/11 18:13:12 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.50 2016/01/03 08:17:24 mlelstv Exp $");
 
 #include <sys/errno.h>
 
@@ -222,24 +222,6 @@ rf_State_LastState(RF_RaidAccessDesc_t *
 	KASSERT(desc->async_flag);
 
 	/*
-	 * That's all the IO for this one... unbusy the 'disk'.
-	 */
-
-	rf_disk_unbusy(desc);
-
-	/*
-	 * Wakeup any requests waiting to go.
-	 */
-
-	rf_lock_mutex2(desc->raidPtr->mutex);
-	desc->raidPtr->openings++;
-	rf_unlock_mutex2(desc->raidPtr->mutex);
-
-	rf_lock_mutex2(desc->raidPtr->iodone_lock);
-	rf_signal_cond2(desc->raidPtr->iodone_cv);
-	rf_unlock_mutex2(desc->raidPtr->iodone_lock);
-
-	/*
 	 * The parity_map hook has to go here, because the iodone
 	 * callback goes straight into the kintf layer.
 	 */
@@ -248,8 +230,8 @@ rf_State_LastState(RF_RaidAccessDesc_t *
 		rf_paritymap_end(desc->raidPtr->parity_map, 
 		    desc->raidAddress, desc->numBlocks);
 
-	/* printf("Calling biodone on 0x%x\n",desc->bp); */
-	biodone(desc->bp);	/* access came through ioctl */
+	/* printf("Calling raiddone on 0x%x\n",desc->bp); */
+	raiddone(desc->raidPtr, desc->bp); /* access came through ioctl */
 
 	if (callbackFunc)
 		callbackFunc(callbackArg);

Reply via email to