Module Name:    src
Committed By:   pgoyette
Date:           Wed Jul 27 01:13:50 UTC 2016

Modified Files:
        src/sys/dev [pgoyette-localcount]: fss.c ld.c md.c

Log Message:
Update a few more drivers for localcount(9)


To generate a diff of this commit:
cvs rdiff -u -r1.93.2.3 -r1.93.2.4 src/sys/dev/fss.c
cvs rdiff -u -r1.94.2.3 -r1.94.2.4 src/sys/dev/ld.c
cvs rdiff -u -r1.76.2.3 -r1.76.2.4 src/sys/dev/md.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/fss.c
diff -u src/sys/dev/fss.c:1.93.2.3 src/sys/dev/fss.c:1.93.2.4
--- src/sys/dev/fss.c:1.93.2.3	Tue Jul 26 05:54:39 2016
+++ src/sys/dev/fss.c	Wed Jul 27 01:13:50 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: fss.c,v 1.93.2.3 2016/07/26 05:54:39 pgoyette Exp $	*/
+/*	$NetBSD: fss.c,v 1.93.2.4 2016/07/27 01:13:50 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.93.2.3 2016/07/26 05:54:39 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.93.2.4 2016/07/27 01:13:50 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -172,6 +172,10 @@ fss_attach(device_t parent, device_t sel
 		vfs_hooks_attach(&fss_vfs_hooks);
 }
 
+/*
+ * Caller must hold a reference to the device's localcount.  The
+ * reference is released upon successful exit.
+ */
 static int
 fss_detach(device_t self, int flags)
 {
@@ -193,12 +197,14 @@ fss_detach(device_t self, int flags)
 	disk_destroy(sc->sc_dkdev);
 	free(sc->sc_dkdev, M_DEVBUF);
 
+	device_release(self);
 	return 0;
 }
 
 int
 fss_open(dev_t dev, int flags, int mode, struct lwp *l)
 {
+	device_t self;
 	int mflag;
 	cfdata_t cf;
 	struct fss_softc *sc;
@@ -207,15 +213,23 @@ fss_open(dev_t dev, int flags, int mode,
 
 	mutex_enter(&fss_device_lock);
 
-	sc = device_lookup_private(&fss_cd, minor(dev));
+	self = device_lookup_acquire(&fss_cd, minor(dev));
+	if (self == NULL)
+		sc = NULL;
+	else
+		sc = device_private(self);
+
 	if (sc == NULL) {
 		cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
 		cf->cf_name = fss_cd.cd_name;
 		cf->cf_atname = fss_cd.cd_name;
 		cf->cf_unit = minor(dev);
 		cf->cf_fstate = FSTATE_STAR;
-		sc = device_private(config_attach_pseudo(cf));
+		self = config_attach_pseudo(cf));
+		device_acquire(self);
+		sc = device_private(self);
 		if (sc == NULL) {
+			device_release(self);
 			mutex_exit(&fss_device_lock);
 			return ENOMEM;
 		}
@@ -228,15 +242,17 @@ fss_open(dev_t dev, int flags, int mode,
 	mutex_exit(&sc->sc_slock);
 	mutex_exit(&fss_device_lock);
 
+	device_release(sc);
 	return 0;
 }
 
 int
 fss_close(dev_t dev, int flags, int mode, struct lwp *l)
 {
+	device_t self = device_lookup_acquire(&fss_cd, minor(dev));
 	int mflag, error;
 	cfdata_t cf;
-	struct fss_softc *sc = device_lookup_private(&fss_cd, minor(dev));
+	struct fss_softc *sc = device_private(self);
 
 	mflag = (mode == S_IFCHR ? FSS_CDEV_OPEN : FSS_BDEV_OPEN);
 	error = 0;
@@ -248,6 +264,7 @@ restart:
 		sc->sc_flags &= ~mflag;
 		mutex_exit(&sc->sc_slock);
 		mutex_exit(&fss_device_lock);
+		device_release(self);
 		return 0;
 	}
 	if ((sc->sc_flags & FSS_ACTIVE) != 0 &&
@@ -260,6 +277,7 @@ restart:
 	if ((sc->sc_flags & FSS_ACTIVE) != 0) {
 		mutex_exit(&sc->sc_slock);
 		mutex_exit(&fss_device_lock);
+		device_release(self);
 		return error;
 	}
 
@@ -272,14 +290,16 @@ restart:
 		free(cf, M_DEVBUF);
 	mutex_exit(&fss_device_lock);
 
+	/* device_release() was called by fss_detach() from config_detach() */
 	return error;
 }
 
 void
 fss_strategy(struct buf *bp)
 {
+	device_t self = device_lookup_acquire(&fss_cd, minor(bp->b_dev));;
 	const bool write = ((bp->b_flags & B_READ) != B_READ);
-	struct fss_softc *sc = device_lookup_private(&fss_cd, minor(bp->b_dev));
+	struct fss_softc *sc = device_private(self);
 
 	mutex_enter(&sc->sc_slock);
 
@@ -290,6 +310,7 @@ fss_strategy(struct buf *bp)
 		bp->b_error = (write ? EROFS : ENXIO);
 		bp->b_resid = bp->b_bcount;
 		biodone(bp);
+		device_release(self);
 		return;
 	}
 
@@ -298,6 +319,7 @@ fss_strategy(struct buf *bp)
 	cv_signal(&sc->sc_work_cv);
 
 	mutex_exit(&sc->sc_slock);
+	device_release(self);
 }
 
 int
@@ -315,8 +337,9 @@ fss_write(dev_t dev, struct uio *uio, in
 int
 fss_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
 {
+	device_t self = device_lookup_acquire(&fss_cd, minor(dev));
 	int error;
-	struct fss_softc *sc = device_lookup_private(&fss_cd, minor(dev));
+	struct fss_softc *sc = device_private(self);
 	struct fss_set _fss;
 	struct fss_set *fss = (struct fss_set *)data;
 	struct fss_set50 *fss50 = (struct fss_set50 *)data;
@@ -430,6 +453,7 @@ fss_ioctl(dev_t dev, u_long cmd, void *d
 		break;
 	}
 
+	device_release(self);
 	return error;
 }
 
@@ -570,18 +594,22 @@ fss_softc_free(struct fss_softc *sc)
 static void
 fss_unmount_hook(struct mount *mp)
 {
+	device_t self;
 	int i;
 	struct fss_softc *sc;
 
 	mutex_enter(&fss_device_lock);
 	for (i = 0; i < fss_cd.cd_ndevs; i++) {
-		if ((sc = device_lookup_private(&fss_cd, i)) == NULL)
+		self = device_lookup_acquire(&fss_cd, i);
+		if (self == NULL)
 			continue;
+		sc = device_private(self);
 		mutex_enter(&sc->sc_slock);
 		if ((sc->sc_flags & FSS_ACTIVE) != 0 &&
 		    sc->sc_mount == mp)
 			fss_error(sc, "forced unmount");
 		mutex_exit(&sc->sc_slock);
+		device_release(self);
 	}
 	mutex_exit(&fss_device_lock);
 }

Index: src/sys/dev/ld.c
diff -u src/sys/dev/ld.c:1.94.2.3 src/sys/dev/ld.c:1.94.2.4
--- src/sys/dev/ld.c:1.94.2.3	Tue Jul 26 05:54:39 2016
+++ src/sys/dev/ld.c	Wed Jul 27 01:13:50 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ld.c,v 1.94.2.3 2016/07/26 05:54:39 pgoyette Exp $	*/
+/*	$NetBSD: ld.c,v 1.94.2.4 2016/07/27 01:13:50 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.94.2.3 2016/07/26 05:54:39 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.94.2.4 2016/07/27 01:13:50 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -290,16 +290,22 @@ ld_shutdown(device_t dev, int flags)
 static int
 ldopen(dev_t dev, int flags, int fmt, struct lwp *l)
 {
+	device_t self;
 	struct ld_softc *sc;
 	struct dk_softc *dksc;
 	int unit;
+	int error;
 
 	unit = DISKUNIT(dev);
-	if ((sc = device_lookup_private(&ld_cd, unit)) == NULL)
-		return (ENXIO);
+	self = device_lookup_acquire(&ld_cd, unit);
+	if (self == NULL)
+		return ENXIO;
+	sc = device_private(self);
 	dksc = &sc->sc_dksc;
 
-	return dk_open(dksc, dev, flags, fmt, l);
+	error = dk_open(dksc, dev, flags, fmt, l);
+	device_release(self);
+	return error;
 }
 
 static int
@@ -317,15 +323,22 @@ ld_lastclose(device_t self)
 static int
 ldclose(dev_t dev, int flags, int fmt, struct lwp *l)
 {
+	device_t self;
 	struct ld_softc *sc;
 	struct dk_softc *dksc;
 	int unit;
+	int error;
 
 	unit = DISKUNIT(dev);
-	sc = device_lookup_private(&ld_cd, unit);
+	self = device_lookup_acquire(&ld_cd, unit);
+	if (self == NULL)
+		return ENXIO;
+	sc = device_private(self);
 	dksc = &sc->sc_dksc;
 
-	return dk_close(dksc, dev, flags, fmt, l);
+	error = dk_close(dksc, dev, flags, fmt, l);
+	device_release(self);
+	return error;
 }
 
 /* ARGSUSED */
@@ -348,17 +361,23 @@ ldwrite(dev_t dev, struct uio *uio, int 
 static int
 ldioctl(dev_t dev, u_long cmd, void *addr, int32_t flag, struct lwp *l)
 {
+	device_t self;
 	struct ld_softc *sc;
 	struct dk_softc *dksc;
 	int unit, error;
 
 	unit = DISKUNIT(dev);
-	sc = device_lookup_private(&ld_cd, unit);
+	self = device_lookup_acquire(&ld_cd, unit);
+	if (self == NULL)
+		return ENXIO;
+	sc = device_private(self);
 	dksc = &sc->sc_dksc;
 
 	error = dk_ioctl(dksc, dev, cmd, addr, flag, l);
-	if (error != EPASSTHROUGH)
+	if (error != EPASSTHROUGH) {
+		device_release(self);
 		return (error);
+	}
 
 	error = 0;
 
@@ -380,31 +399,41 @@ ldioctl(dev_t dev, u_long cmd, void *add
 		break;
 	}
 
+	device_release(self);
 	return (error);
 }
 
 static void
 ldstrategy(struct buf *bp)
 {
+	device_t self;
 	struct ld_softc *sc;
 	struct dk_softc *dksc;
 	int unit;
 
 	unit = DISKUNIT(bp->b_dev);
-	sc = device_lookup_private(&ld_cd, unit);
+	self = device_lookup_acquire(&ld_cd, unit);
+	if (self == NULL)
+		return;
+	sc = device_private(self);
 	dksc = &sc->sc_dksc;
 
 	dk_strategy(dksc, bp);
+	device_release(self);
 }
 
 static int
 ld_diskstart(device_t dev, struct buf *bp)
 {
-	struct ld_softc *sc = device_private(dev);
+	struct ld_softc *sc;
 	int error;
 
-	if (sc->sc_queuecnt >= sc->sc_maxqueuecnt)
+	device_acquire(dev);
+	sc = device_private(dev);
+	if (sc->sc_queuecnt >= sc->sc_maxqueuecnt) {
+		device_release(dev);
 		return EAGAIN;
+	}
 
 	mutex_enter(&sc->sc_mutex);
 
@@ -418,6 +447,7 @@ ld_diskstart(device_t dev, struct buf *b
 
 	mutex_exit(&sc->sc_mutex);
 
+	device_release(dev);
 	return error;
 }
 
@@ -443,19 +473,26 @@ lddone(struct ld_softc *sc, struct buf *
 static int
 ldsize(dev_t dev)
 {
+	device_t self;
 	struct ld_softc *sc;
 	struct dk_softc *dksc;
 	int unit;
+	int error;
 
 	unit = DISKUNIT(dev);
-	if ((sc = device_lookup_private(&ld_cd, unit)) == NULL)
-		return (ENODEV);
+	self = device_lookup_acquire(&ld_cd, unit);
+	if (self == NULL)
+		return ENODEV;
+	sc = device_private(self);
 	dksc = &sc->sc_dksc;
 
 	if ((sc->sc_flags & LDF_ENABLED) == 0)
-		return (ENODEV);
+		error = (ENODEV);
+	else
+		error = dk_size(dksc, dev);
 
-	return dk_size(dksc, dev);
+	device_release(self);
+	return error;
 }
 
 /*
@@ -464,30 +501,43 @@ ldsize(dev_t dev)
 static int
 lddump(dev_t dev, daddr_t blkno, void *va, size_t size)
 {
+	device_t self;
 	struct ld_softc *sc;
 	struct dk_softc *dksc;
 	int unit;
+	int error;
 
 	unit = DISKUNIT(dev);
-	if ((sc = device_lookup_private(&ld_cd, unit)) == NULL)
-		return (ENXIO);
+	self = device_lookup_acquire(&ld_cd, unit);
+	if (self == NULL)
+		return ENXIO;
+	sc = device_private(self);
 	dksc = &sc->sc_dksc;
 
 	if ((sc->sc_flags & LDF_ENABLED) == 0)
-		return (ENODEV);
+		error = (ENODEV);
+	else
+		error = dk_dump(dksc, dev, blkno, va, size);
 
-	return dk_dump(dksc, dev, blkno, va, size);
+	device_release(self);
+	return error;
 }
 
 static int
 ld_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
 {
-	struct ld_softc *sc = device_private(dev);
+	struct ld_softc *sc;
+	int error;
 
+	device_acquire(dev);
+	sc = device_private(dev);
 	if (sc->sc_dump == NULL)
-		return (ENODEV);
+		error = ENODEV;
+	else
+		error = (*sc->sc_dump)(sc, va, blkno, nblk);
 
-	return (*sc->sc_dump)(sc, va, blkno, nblk);
+	device_release(dev);
+	return error;
 }
 
 /*
@@ -496,23 +546,33 @@ ld_dumpblocks(device_t dev, void *va, da
 static void
 ldminphys(struct buf *bp)
 {
+	device_t self;
 	int unit;
 	struct ld_softc *sc;
 
 	unit = DISKUNIT(bp->b_dev);
-	sc = device_lookup_private(&ld_cd, unit);
+	self = device_lookup_acquire(&ld_cd, unit);
+	if (self == NULL)
+		return;
+	sc = device_private(self);
 
 	ld_iosize(sc->sc_dv, &bp->b_bcount);
 	minphys(bp);
+	device_release(self);
 }
 
 static void
 ld_iosize(device_t d, int *countp)
 {
-	struct ld_softc *sc = device_private(d);
+	struct ld_softc *sc;
+
+	device_acquire(d);
+	sc = device_private(d);
 
 	if (*countp > sc->sc_maxxfer)
 		*countp = sc->sc_maxxfer;
+
+	device_release(d);
 }
 
 static void
@@ -566,21 +626,29 @@ ld_set_geometry(struct ld_softc *sc)
 static void
 ld_config_interrupts(device_t d)
 {
-	struct ld_softc *sc = device_private(d);
+	struct ld_softc *sc;
 	struct dk_softc *dksc = &sc->sc_dksc;
 
+	device_acquire(d);
+	sc = device_private(d);
 	dkwedge_discover(&dksc->sc_dkdev);
+	device_release(d);
 }
 
 static int
 ld_discard(device_t dev, off_t pos, off_t len)
 {
-	struct ld_softc *sc = device_private(dev);
+	struct ld_softc *sc;
+	int error;
 
+	device_acquire(dev);
+	sc = device_private(dev);
 	if (sc->sc_discard == NULL)
-		return (ENODEV);
-
-	return (*sc->sc_discard)(sc, pos, len);
+		error = (ENODEV);
+	else
+		error = (*sc->sc_discard)(sc, pos, len);
+	device_release(dev);
+	return error;
 }
 
 static int
@@ -589,10 +657,16 @@ lddiscard(dev_t dev, off_t pos, off_t le
 	struct ld_softc *sc;
 	struct dk_softc *dksc;
 	int unit;
+	int error;
 
 	unit = DISKUNIT(dev);
-	sc = device_lookup_private(&ld_cd, unit);
+	self = device_lookup_acquire(&ld_cd, unit);
+	if (self == NULL)
+		return ENXIO;
+	sc = device_private(self);
 	dksc = &sc->sc_dksc;
 
-	return dk_discard(dksc, dev, pos, len);
+	error = dk_discard(dksc, dev, pos, len);
+	device_release(self);
+	return error;
 }

Index: src/sys/dev/md.c
diff -u src/sys/dev/md.c:1.76.2.3 src/sys/dev/md.c:1.76.2.4
--- src/sys/dev/md.c:1.76.2.3	Tue Jul 26 05:54:39 2016
+++ src/sys/dev/md.c	Wed Jul 27 01:13:50 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: md.c,v 1.76.2.3 2016/07/26 05:54:39 pgoyette Exp $	*/
+/*	$NetBSD: md.c,v 1.76.2.4 2016/07/27 01:13:50 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 1995 Gordon W. Ross, Leo Weppelman.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: md.c,v 1.76.2.3 2016/07/26 05:54:39 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: md.c,v 1.76.2.4 2016/07/27 01:13:50 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_md.h"
@@ -195,6 +195,10 @@ md_attach(device_t parent, device_t self
 		aprint_error_dev(self, "couldn't establish power handler\n");
 }
 
+/*
+ * Caller must hold a reference to the device's localcount.  The reference
+ * is released if detach is successful.
+ */
 static int
 md_detach(device_t self, int flags)
 {
@@ -212,6 +216,7 @@ md_detach(device_t self, int flags)
 	if (rc != 0)
 		return rc;
 
+	device_release(self);
 	pmf_device_deregister(self);
 	disk_detach(&sc->sc_dkdev);
 	disk_destroy(&sc->sc_dkdev);
@@ -238,12 +243,14 @@ static int	md_ioctl_kalloc(struct md_sof
 static int
 mdsize(dev_t dev)
 {
+	device_t self;
 	struct md_softc *sc;
 	int res;
 
-	sc = device_lookup_private(&md_cd, MD_UNIT(dev));
-	if (sc == NULL)
+	self = device_lookup_acquire(&md_cd, MD_UNIT(dev));
+	if (self == NULL)
 		return 0;
+	sc = device_private(self);
 
 	mutex_enter(&sc->sc_lock);
 	if (sc->sc_type == MD_UNCONFIGURED)
@@ -252,12 +259,14 @@ mdsize(dev_t dev)
 		res = sc->sc_size >> DEV_BSHIFT;
 	mutex_exit(&sc->sc_lock);
 
+	device_release(self);
 	return res;
 }
 
 static int
 mdopen(dev_t dev, int flag, int fmt, struct lwp *l)
 {
+	device_t self;
 	int unit;
 	int part = DISKPART(dev);
 	int pmask = 1 << part;
@@ -270,8 +279,9 @@ mdopen(dev_t dev, int flag, int fmt, str
 
 	mutex_enter(&md_device_lock);
 	unit = MD_UNIT(dev);
-	sc = device_lookup_private(&md_cd, unit);
-	if (sc == NULL) {
+	sc = NULL;
+	self = device_lookup_acquire(&md_cd, unit);
+	if (self == NULL) {
 		if (part != RAW_PART) {
 			mutex_exit(&md_device_lock);
 			return ENXIO;
@@ -281,12 +291,19 @@ mdopen(dev_t dev, int flag, int fmt, str
 		cf->cf_atname = md_cd.cd_name;
 		cf->cf_unit = unit;
 		cf->cf_fstate = FSTATE_STAR;
-		sc = device_private(config_attach_pseudo(cf));
+		self = config_attach_pseudo(cf));
+		if (self != NULL) {
+			device_acquire(self);
+			sc = device_private(self);
+		}
 		if (sc == NULL) {
 			mutex_exit(&md_device_lock);
+			device_release(self);
 			return ENOMEM;
 		}
 	}
+	else
+		sc = device_private(self);
 
 	dk = &sc->sc_dkdev;
 
@@ -311,6 +328,7 @@ mdopen(dev_t dev, int flag, int fmt, str
 	 */
 	if (sc->sc_type == MD_UNCONFIGURED) {
 		mutex_exit(&md_device_lock);
+		device_release(self);
 		return ENXIO;
 	}
 
@@ -331,12 +349,14 @@ ok:
 
 	mutex_exit(&dk->dk_openlock);
 	mutex_exit(&md_device_lock);
+	device_release(self);
 	return 0;
 }
 
 static int
 mdclose(dev_t dev, int flag, int fmt, struct lwp *l)
 {
+	device_t self;
 	int part = DISKPART(dev);
 	int pmask = 1 << part;
 	int error;
@@ -344,9 +364,10 @@ mdclose(dev_t dev, int flag, int fmt, st
 	struct md_softc *sc;
 	struct disk *dk;
 
-	sc = device_lookup_private(&md_cd, MD_UNIT(dev));
-	if (sc == NULL)
+	self = device_lookup_acquire(&md_cd, MD_UNIT(dev));
+	if (self == NULL)
 		return ENXIO;
+	sc = device_private(self);
 
 	dk = &sc->sc_dkdev;
 
@@ -363,6 +384,7 @@ mdclose(dev_t dev, int flag, int fmt, st
 	dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
 	if (dk->dk_openmask != 0) {
 		mutex_exit(&dk->dk_openlock);
+		device_release(self);
 		return 0;
 	}
 
@@ -374,33 +396,53 @@ mdclose(dev_t dev, int flag, int fmt, st
 	if (! error)
 		free(cf, M_DEVBUF);
 	mutex_exit(&md_device_lock);
+	device_release(self);
 	return error;
 }
 
 static int
 mdread(dev_t dev, struct uio *uio, int flags)
 {
+	device_t self;
 	struct md_softc *sc;
+	int error;
 
-	sc = device_lookup_private(&md_cd, MD_UNIT(dev));
+	self = device_lookup_acquire(&md_cd, MD_UNIT(dev));
+	if (self == NULL)
+		return ENXIO;
 
-	if (sc == NULL || sc->sc_type == MD_UNCONFIGURED)
+	sc = device_private(self);
+	if (sc == NULL || sc->sc_type == MD_UNCONFIGURED) {
+		device_release(self);
 		return ENXIO;
+	}
 
-	return (physio(mdstrategy, NULL, dev, B_READ, minphys, uio));
+	error = (physio(mdstrategy, NULL, dev, B_READ, minphys, uio));
+	device_release(self);
+	return error;
 }
 
 static int
 mdwrite(dev_t dev, struct uio *uio, int flags)
 {
+	device_t self;
 	struct md_softc *sc;
+	int error;
 
-	sc = device_lookup_private(&md_cd, MD_UNIT(dev));
+	self = device_lookup_acquire(&md_cd, MD_UNIT(dev));
+	if (self == NULL)
+		return ENXIO;
 
-	if (sc == NULL || sc->sc_type == MD_UNCONFIGURED)
+	sc = device_private(self);
+	if (sc == NULL || sc->sc_type == MD_UNCONFIGURED) {
+		device_release(self);
 		return ENXIO;
+	}
+
+	error = (physio(mdstrategy, NULL, dev, B_WRITE, minphys, uio));
 
-	return (physio(mdstrategy, NULL, dev, B_WRITE, minphys, uio));
+	device_release(self);
+	return error;
 }
 
 /*
@@ -410,19 +452,24 @@ mdwrite(dev_t dev, struct uio *uio, int 
 static void
 mdstrategy(struct buf *bp)
 {
+	device_t self;
 	struct md_softc	*sc;
 	void *	addr;
 	size_t off, xfer;
 	bool is_read;
 
-	sc = device_lookup_private(&md_cd, MD_UNIT(bp->b_dev));
-
-	mutex_enter(&sc->sc_lock);
+	self = device_lookup_acquire(&md_cd, MD_UNIT(bp->b_dev));
+	if (self == NULL) {
+		bp->b_error = ENXIO;
+		goto done;
+	}
 
+	sc = device_private(self);
 	if (sc == NULL || sc->sc_type == MD_UNCONFIGURED) {
 		bp->b_error = ENXIO;
 		goto done;
 	}
+	mutex_enter(&sc->sc_lock);
 
 	switch (sc->sc_type) {
 #if MEMORY_DISK_SERVER
@@ -433,6 +480,7 @@ mdstrategy(struct buf *bp)
 		mutex_exit(&sc->sc_lock);
 		/* see md_server_loop() */
 		/* no biodone in this case */
+		device_release(self);
 		return;
 #endif	/* MEMORY_DISK_SERVER */
 
@@ -471,23 +519,28 @@ mdstrategy(struct buf *bp)
 	mutex_exit(&sc->sc_lock);
 
 	biodone(bp);
+	device_release(self);
 }
 
 static int
 mdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
 {
+	device_t self;
 	struct md_softc *sc;
 	struct md_conf *umd;
 	int error;
 
-	if ((sc = device_lookup_private(&md_cd, MD_UNIT(dev))) == NULL)
+	self = device_lookup_private(&md_cd, MD_UNIT(dev));
+	if (self == NULL)
 		return ENXIO;
 
+	sc = device_private(self);
 	mutex_enter(&sc->sc_lock);
 	if (sc->sc_type != MD_UNCONFIGURED) {
 		error = disk_ioctl(&sc->sc_dkdev, dev, cmd, data, flag, l); 
 		if (error != EPASSTHROUGH) {
 			mutex_exit(&sc->sc_lock);
+			device_release(self);
 			return 0;
 		}
 	}
@@ -495,6 +548,7 @@ mdioctl(dev_t dev, u_long cmd, void *dat
 	/* If this is not the raw partition, punt! */
 	if (DISKPART(dev) != RAW_PART) {
 		mutex_exit(&sc->sc_lock);
+		device_release(self);
 		return ENOTTY;
 	}
 
@@ -525,6 +579,7 @@ mdioctl(dev_t dev, u_long cmd, void *dat
 		break;
 	}
 	mutex_exit(&sc->sc_lock);
+	device_release(self);
 	return error;
 }
 

Reply via email to