Index: src/sys/dev/audio.c
===================================================================
RCS file: /cvsroot/src/sys/dev/audio.c,v
retrieving revision 1.288
diff -u -r1.288 audio.c
--- src/sys/dev/audio.c	28 Dec 2016 02:44:59 -0000	1.288
+++ src/sys/dev/audio.c	28 Dec 2016 02:50:48 -0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.288 2016/12/28 02:44:59 nat Exp $	*/
+/*	$NetBSD: audio.c,v 1.287 2016/12/25 22:44:24 nat Exp $	*/
 
 /*-
  * Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au>
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.288 2016/12/28 02:44:59 nat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.287 2016/12/25 22:44:24 nat Exp $");
 
 #include "audio.h"
 #if NAUDIO > 0
@@ -157,6 +157,8 @@
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
 #include <sys/vnode.h>
 #include <sys/select.h>
 #include <sys/poll.h>
@@ -206,19 +208,20 @@
 int	audiosetinfo(struct audio_softc *, struct audio_info *, bool, int);
 int	audiogetinfo(struct audio_softc *, struct audio_info *, int, int);
 
-int	audio_open(dev_t, struct audio_softc *, int, int, struct lwp *);
-int	audio_close(struct audio_softc *, int, int, struct lwp *, int);
-int	audio_read(struct audio_softc *, struct uio *, int);
-int	audio_write(struct audio_softc *, struct uio *, int);
-int	audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int,
-		    struct lwp *);
-int	audio_poll(struct audio_softc *, int, struct lwp *);
+int	audio_open(dev_t, struct audio_softc *, int, int, struct lwp *,
+		   struct file **);
+int	audio_close(struct audio_softc *, int, int);
+int	audio_read(struct audio_softc *, struct uio *, int, int);
+int	audio_write(struct audio_softc *, struct uio *, int, int);
+int	audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int, int);
+int	audio_poll(struct audio_softc *, int, int);
 int	audio_kqfilter(struct audio_softc *, struct knote *);
 paddr_t	audio_mmap(struct audio_softc *, off_t, int);
 
-int	mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *);
-int	mixer_close(struct audio_softc *, int, int, struct lwp *);
-int	mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *);
+int	mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *,
+		   struct file **);
+int	mixer_close(struct audio_softc *, int, int);
+int	mixer_ioctl(struct audio_softc *, u_long, void *, int);
 static	void mixer_remove(struct audio_softc *);
 static	void mixer_signal(struct audio_softc *);
 
@@ -321,6 +324,15 @@
 static void	audio_exit(struct audio_softc *);
 static int	audio_waitio(struct audio_softc *, kcondvar_t *);
 
+int audioclose(struct file *);
+int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int);
+int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int);
+int audioioctl(struct file *, u_long, void *);
+int audiopoll(struct file *, int);
+int audiokqfilter(struct file *, struct knote *);
+
+int audiobellopen(dev_t, int, int, struct lwp *, struct file **);
+
 #define AUDIO_OUTPUT_CLASS 0
 #define AUDIO_INPUT_CLASS 1
 
@@ -380,29 +392,34 @@
 				      audio_stream_t *, int);
 
 dev_type_open(audioopen);
-dev_type_close(audioclose);
-dev_type_read(audioread);
-dev_type_write(audiowrite);
-dev_type_ioctl(audioioctl);
-dev_type_poll(audiopoll);
 dev_type_mmap(audiommap);
-dev_type_kqfilter(audiokqfilter);
 
 const struct cdevsw audio_cdevsw = {
 	.d_open = audioopen,
-	.d_close = audioclose,
-	.d_read = audioread,
-	.d_write = audiowrite,
-	.d_ioctl = audioioctl,
+	.d_close = noclose,
+	.d_read = noread,
+	.d_write = nowrite,
+	.d_ioctl = noioctl,
 	.d_stop = nostop,
 	.d_tty = notty,
-	.d_poll = audiopoll,
+	.d_poll = nopoll,
 	.d_mmap = audiommap,
-	.d_kqfilter = audiokqfilter,
+	.d_kqfilter = nokqfilter,
 	.d_discard = nodiscard,
 	.d_flag = D_MCLOSE | D_MPSAFE
 };
 
+const struct fileops audio_fileops = {
+	.fo_read = audioread,
+	.fo_write = audiowrite,
+	.fo_ioctl = audioioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = audiopoll,
+	.fo_close = audioclose,
+	.fo_kqfilter = audiokqfilter,
+	.fo_restart = fnullop_restart
+};
+
 /* The default audio mode: 8 kHz mono mu-law */
 const struct audio_params audio_default = {
 	.sample_rate = 8000,
@@ -923,7 +940,8 @@
 
 	/* free resources */
 	for (n = 0; n < VAUDIOCHANS; n++) {
-		if (n != 0 && sc->sc_audiopid[n].pid == -1)
+		if (n != 0 && (sc->sc_audiopid[n].pid == -1 ||
+		    sc->sc_audiopid[n].pid == -2))
 			continue;
 		audio_free_ring(sc, &sc->sc_vchan[n]->sc_mpr);
 		audio_free_ring(sc, &sc->sc_vchan[n]->sc_mrr);
@@ -931,7 +949,8 @@
 	audio_free_ring(sc, &sc->sc_pr);
 	audio_free_ring(sc, &sc->sc_rr);
 	for (n = 0; n < VAUDIOCHANS; n++) {
-		if (n != 0 && sc->sc_audiopid[n].pid == -1)
+		if (n != 0 && (sc->sc_audiopid[n].pid == -1 ||
+		    sc->sc_audiopid[n].pid == -2))
 			continue;
 		for (i = 0; i < sc->sc_vchan[n]->sc_npfilters; i++) {
 			sc->sc_vchan[n]->sc_pfilters[i]->dtor
@@ -1089,15 +1108,7 @@
 void
 audio_printsc(struct audio_softc *sc)
 {
-	int n;
-
-	for (n = 1; n < VAUDIOCHANS; n++) {
-		if (sc->sc_audiopid[n].pid == curproc->p_pid)
-			break;
-	}
-
-	if (n == VAUDIOCHANS)
-		return;
+	int n = 0;
 
 	printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if);
 	printf("open 0x%x mode 0x%x\n", sc->sc_vchan[n]->sc_open,
@@ -1474,9 +1485,37 @@
 }
 
 int
+audiobellopen(dev_t dev, int flags, int ifmt, struct lwp *l, struct file **fp)
+{
+	struct audio_softc *sc;
+	int error;
+
+	if ((error = audio_enter(dev, RW_WRITER, &sc)) != 0)
+		return error;
+	device_active(sc->dev, DVA_SYSTEM);
+	switch (AUDIODEV(dev)) {
+	case SOUND_DEVICE:
+	case AUDIO_DEVICE:
+	case AUDIOCTL_DEVICE:
+		error = audio_open(dev, sc, flags, ifmt, l, fp);
+		break;
+	case MIXER_DEVICE:
+		error = mixer_open(dev, sc, flags, ifmt, l, fp);
+		break;
+	default:
+		error = ENXIO;
+		break;
+	}
+	audio_exit(sc);
+
+	return error;
+}
+
+int
 audioopen(dev_t dev, int flags, int ifmt, struct lwp *l)
 {
 	struct audio_softc *sc;
+	struct file *fp;
 	int error;
 
 	if ((error = audio_enter(dev, RW_WRITER, &sc)) != 0)
@@ -1486,10 +1525,10 @@
 	case SOUND_DEVICE:
 	case AUDIO_DEVICE:
 	case AUDIOCTL_DEVICE:
-		error = audio_open(dev, sc, flags, ifmt, l);
+		error = audio_open(dev, sc, flags, ifmt, l, &fp);
 		break;
 	case MIXER_DEVICE:
-		error = mixer_open(dev, sc, flags, ifmt, l);
+		error = mixer_open(dev, sc, flags, ifmt, l, &fp);
 		break;
 	default:
 		error = ENXIO;
@@ -1501,30 +1540,29 @@
 }
 
 int
-audioclose(dev_t dev, int flags, int ifmt, struct lwp *l)
+audioclose(struct file *fp)
 {
 	struct audio_softc *sc;
 	int error, n;
+	dev_t dev;
+
+	dev = fp->f_audioctx->dev;
 
 	if ((error = audio_enter(dev, RW_WRITER, &sc)) != 0)
 		return error;
+	for (n = 1; n < VAUDIOCHANS; n++) {
+		if (fp->f_audioctx == &sc->sc_audiopid[n])
+			break;
+	}
 	device_active(sc->dev, DVA_SYSTEM);
 	switch (AUDIODEV(dev)) {
 	case SOUND_DEVICE:
 	case AUDIO_DEVICE:
 	case AUDIOCTL_DEVICE:
-		for (n = 1; n < VAUDIOCHANS; n++) {
-			if (sc->sc_audiopid[n].pid == curproc->p_pid)
-				break;
-		}
-		if (n == VAUDIOCHANS) {
-			error = EIO;
-			break;	
-		}
-		error = audio_close(sc, flags, ifmt, l, n);
+		error = audio_close(sc, fp->f_flag, n);
 		break;
 	case MIXER_DEVICE:
-		error = mixer_close(sc, flags, ifmt, l);
+		error = mixer_close(sc, fp->f_flag, n);
 		break;
 	default:
 		error = ENXIO;
@@ -1536,17 +1574,25 @@
 }
 
 int
-audioread(dev_t dev, struct uio *uio, int ioflag)
+audioread(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
+	  int ioflag)
 {
 	struct audio_softc *sc;
-	int error;
+	int error, n;
+	dev_t dev;
+
+	dev = fp->f_audioctx->dev;
 
 	if ((error = audio_enter(dev, RW_READER, &sc)) != 0)
 		return error;
+	for (n = 1; n < VAUDIOCHANS; n++) {
+		if (fp->f_audioctx == &sc->sc_audiopid[n])
+			break;
+	}
 	switch (AUDIODEV(dev)) {
 	case SOUND_DEVICE:
 	case AUDIO_DEVICE:
-		error = audio_read(sc, uio, ioflag);
+		error = audio_read(sc, uio, ioflag, n);
 		break;
 	case AUDIOCTL_DEVICE:
 	case MIXER_DEVICE:
@@ -1562,17 +1608,26 @@
 }
 
 int
-audiowrite(dev_t dev, struct uio *uio, int ioflag)
+audiowrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
+	   int ioflag)
 {
 	struct audio_softc *sc;
-	int error;
+	int error, n;
+	dev_t dev;
+
+	dev = fp->f_audioctx->dev;
 
 	if ((error = audio_enter(dev, RW_READER, &sc)) != 0)
 		return error;
+
+	for (n = 1; n < VAUDIOCHANS; n++) {
+		if (fp->f_audioctx == &sc->sc_audiopid[n])
+			break;
+	}
 	switch (AUDIODEV(dev)) {
 	case SOUND_DEVICE:
 	case AUDIO_DEVICE:
-		error = audio_write(sc, uio, ioflag);
+		error = audio_write(sc, uio, ioflag, n);
 		break;
 	case AUDIOCTL_DEVICE:
 	case MIXER_DEVICE:
@@ -1588,11 +1643,14 @@
 }
 
 int
-audioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
+audioioctl(struct file *fp, u_long cmd, void *addr)
 {
 	struct audio_softc *sc;
-	int error;
+	int error, n;
 	krw_t rw;
+	dev_t dev;
+
+	dev = fp->f_audioctx->dev;
 
 	/* Figure out which lock type we need. */
 	switch (cmd) {
@@ -1609,18 +1667,23 @@
 
 	if ((error = audio_enter(dev, rw, &sc)) != 0)
 		return error;
+
+	for (n = 1; n < VAUDIOCHANS; n++) {
+		if (fp->f_audioctx == &sc->sc_audiopid[n])
+			break;
+	}
 	switch (AUDIODEV(dev)) {
 	case SOUND_DEVICE:
 	case AUDIO_DEVICE:
 	case AUDIOCTL_DEVICE:
 		device_active(sc->dev, DVA_SYSTEM);
 		if (IOCGROUP(cmd) == IOCGROUP(AUDIO_MIXER_READ))
-			error = mixer_ioctl(sc, cmd, addr, flag, l);
+			error = mixer_ioctl(sc, cmd, addr, fp->f_flag);
 		else
-			error = audio_ioctl(dev, sc, cmd, addr, flag, l);
+			error = audio_ioctl(dev, sc, cmd, addr, fp->f_flag, n);
 		break;
 	case MIXER_DEVICE:
-		error = mixer_ioctl(sc, cmd, addr, flag, l);
+		error = mixer_ioctl(sc, cmd, addr, fp->f_flag);
 		break;
 	default:
 		error = ENXIO;
@@ -1632,10 +1695,13 @@
 }
 
 int
-audiopoll(dev_t dev, int events, struct lwp *l)
+audiopoll(struct file *fp, int events)
 {
 	struct audio_softc *sc;
-	int revents;
+	int n, revents;
+	dev_t dev;
+
+	dev = fp->f_audioctx->dev;
 
 	/* Don't bother with device level lock here. */
 	sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev));
@@ -1646,10 +1712,14 @@
 		mutex_exit(sc->sc_lock);
 		return EIO;
 	}
+	for (n = 1; n < VAUDIOCHANS; n++) {
+		if (fp->f_audioctx == &sc->sc_audiopid[n])
+			break;
+	}
 	switch (AUDIODEV(dev)) {
 	case SOUND_DEVICE:
 	case AUDIO_DEVICE:
-		revents = audio_poll(sc, events, l);
+		revents = audio_poll(sc, events, n);
 		break;
 	case AUDIOCTL_DEVICE:
 	case MIXER_DEVICE:
@@ -1665,10 +1735,13 @@
 }
 
 int
-audiokqfilter(dev_t dev, struct knote *kn)
+audiokqfilter(struct file *fp, struct knote *kn)
 {
 	struct audio_softc *sc;
 	int rv;
+	dev_t dev;
+
+	dev = fp->f_audioctx->dev;
 
 	/* Don't bother with device level lock here. */
 	sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev));
@@ -1702,6 +1775,8 @@
 	struct audio_softc *sc;
 	paddr_t error;
 
+	return -1;
+
 	/*
 	 * Acquire a reader lock.  audio_mmap() will drop sc_lock
 	 * in order to allow the device's mmap routine to sleep.
@@ -1861,8 +1936,10 @@
 
 int
 audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
-    struct lwp *l)
+    struct lwp *l, struct file **nfp)
 {
+	struct file *fp;
+	int fd;
 	int error, i, n;
 	u_int mode;
 	const struct audio_hw_if *hw;
@@ -1874,13 +1951,6 @@
 		return ENXIO;
 
 	for (n = 1; n < VAUDIOCHANS; n++) {
-		if (sc->sc_audiopid[n].pid == curproc->p_pid)
-			break;
-	}
-	if (n < VAUDIOCHANS)
-		return ENXIO;
-
-	for (n = 1; n < VAUDIOCHANS; n++) {
 		if (sc->sc_audiopid[n].pid == -1)
 			break;
 	}
@@ -1891,6 +1961,10 @@
 	if (hw == NULL)
 		return ENXIO;
 
+	error = fd_allocfile(&fp, &fd);
+	if (error)
+		return error;
+
 	sc->sc_vchan[n] = kmem_zalloc(sizeof(struct virtual_channel), KM_SLEEP);
 	vc = sc->sc_vchan[n];
 
@@ -2014,7 +2088,12 @@
 	sc->sc_nmixer_states += 2;
 	mutex_exit(sc->sc_intr_lock);
 
-	return 0;
+	sc->sc_audiopid[n].dev = dev;
+	error = fd_clone(fp, fd, flags, &audio_fileops, &sc->sc_audiopid[n]);
+	KASSERT(error == EMOVEFD);
+
+	*nfp = fp;
+	return error;
 
 bad:
 	for (i = 0; i < vc->sc_npfilters; i++) {
@@ -2168,8 +2247,7 @@
  */
 /* ARGSUSED */
 int
-audio_close(struct audio_softc *sc, int flags, int ifmt,
-    struct lwp *l, int n)
+audio_close(struct audio_softc *sc, int flags, int n)
 {
 	struct virtual_channel *vc;
 	const struct audio_hw_if *hw;
@@ -2260,20 +2338,16 @@
 }
 
 int
-audio_read(struct audio_softc *sc, struct uio *uio, int ioflag)
+audio_read(struct audio_softc *sc, struct uio *uio, int ioflag, int m)
 {
 	struct audio_ringbuffer *cb;
 	struct virtual_channel *vc;
 	const uint8_t *outp;
 	uint8_t *inp;
-	int error, used, cc, n, m;
+	int error, used, cc, n;
 
 	KASSERT(mutex_owned(sc->sc_lock));
 
-	for (m = 1; m < VAUDIOCHANS; m++) {
-		if (sc->sc_audiopid[m].pid == curproc->p_pid)
-			break;
-	}
 	if (m == VAUDIOCHANS)
 		return EINVAL;
 
@@ -2590,7 +2664,7 @@
 }
 
 int
-audio_write(struct audio_softc *sc, struct uio *uio, int ioflag)
+audio_write(struct audio_softc *sc, struct uio *uio, int ioflag, int n)
 {
 	uio_fetcher_t ufetcher;
 	audio_stream_t stream;
@@ -2599,14 +2673,10 @@
 	stream_fetcher_t *fetcher;
 	stream_filter_t *filter;
 	uint8_t *inp, *einp;
-	int saveerror, error, n, m, cc, used;
+	int saveerror, error, m, cc, used;
 
 	KASSERT(mutex_owned(sc->sc_lock));
 
-	for (n = 1; n < VAUDIOCHANS; n++) {
-		if (sc->sc_audiopid[n].pid == curproc->p_pid)
-			break;
-	}
 	if (n == VAUDIOCHANS)
 		return EINVAL;
 
@@ -2757,20 +2827,16 @@
 
 int
 audio_ioctl(dev_t dev, struct audio_softc *sc, u_long cmd, void *addr, int flag,
-	    struct lwp *l)
+	    int n)
 {
 	const struct audio_hw_if *hw;
 	struct virtual_channel *vc;
 	struct audio_offset *ao;
 	u_long stamp;
-	int error, offs, fd, m, n;
+	int error, offs, fd, m;
 	bool rbus, pbus;
 
 	KASSERT(mutex_owned(sc->sc_lock));
-	for (n = 1; n < VAUDIOCHANS; n++) {
-		if (sc->sc_audiopid[n].pid == curproc->p_pid)
-			break;
-	}
 	m = n;
 	for (n = 1; n < VAUDIOCHANS; n++) {
 		if (sc->sc_despid[m].pid >= 0 && sc->sc_audiopid[n].pid ==
@@ -2960,7 +3026,8 @@
 
 	default:
 		if (hw->dev_ioctl) {
-			error = hw->dev_ioctl(sc->hw_hdl, cmd, addr, flag, l);
+			error = hw->dev_ioctl(sc->hw_hdl, cmd, addr, flag,
+			    curlwp);
 		} else {
 			DPRINTF(("audio_ioctl: unknown ioctl\n"));
 			error = EINVAL;
@@ -2973,17 +3040,13 @@
 }
 
 int
-audio_poll(struct audio_softc *sc, int events, struct lwp *l)
+audio_poll(struct audio_softc *sc, int events, int n)
 {
 	struct virtual_channel *vc;
 	int revents;
-	int used, n;
+	int used;
 
 	KASSERT(mutex_owned(sc->sc_lock));
-	for (n = 1; n < VAUDIOCHANS; n++) {
-		if (sc->sc_audiopid[n].pid == curproc->p_pid)
-			break;
-	}
 	if (n == VAUDIOCHANS)
 		return ENXIO;
 	vc = sc->sc_vchan[n];
@@ -3022,10 +3085,10 @@
 
 	if (revents == 0) {
 		if (events & (POLLIN | POLLRDNORM))
-			selrecord(l, &sc->sc_rsel);
+			selrecord(curlwp, &sc->sc_rsel);
 
 		if (events & (POLLOUT | POLLWRNORM))
-			selrecord(l, &sc->sc_wsel);
+			selrecord(curlwp, &sc->sc_wsel);
 	}
 
 	return revents;
@@ -3047,17 +3110,10 @@
 {
 	struct audio_softc *sc;
 	struct virtual_channel *vc;
-	int n;
 
 	sc = kn->kn_hook;
-	for (n = 1; n < VAUDIOCHANS; n++) {
-		if (sc->sc_audiopid[n].pid == curproc->p_pid)
-			break;
-	}
-	if (n == VAUDIOCHANS)
-		return ENXIO;
 
-	vc = sc->sc_vchan[n];
+	vc = sc->sc_vchan[0];
 	mutex_enter(sc->sc_intr_lock);
 	if (!vc->sc_full_duplex && (vc->sc_mode & AUMODE_PLAY))
 		kn->kn_data = vc->sc_mpr.stamp - vc->sc_wstamp;
@@ -3088,18 +3144,11 @@
 {
 	struct audio_softc *sc;
 	audio_stream_t *stream;
-	int n;
 
 	sc = kn->kn_hook;
 	mutex_enter(sc->sc_intr_lock);
-	for (n = 1; n < VAUDIOCHANS; n++) {
-		if (sc->sc_audiopid[n].pid == curproc->p_pid)
-			break;
-	}
-	if (n == VAUDIOCHANS)
-		return ENXIO;
 
-	stream = sc->sc_vchan[n]->sc_pustream;
+	stream = sc->sc_vchan[0]->sc_pustream;
 	kn->kn_data = (stream->end - stream->start)
 		- audio_stream_get_used(stream);
 	mutex_exit(sc->sc_intr_lock);
@@ -3431,6 +3480,8 @@
 		if (sc->sc_audiopid[n].pid == -1)
 			continue;
 		i--;
+		if (sc->sc_audiopid[n].pid == -2)
+			continue;
 		vc = sc->sc_vchan[n];
 		if (!vc->sc_open)
 			continue;
@@ -3623,6 +3674,9 @@
 		if (sc->sc_audiopid[n].pid == -1)
 			continue;
 		i--;
+		if (sc->sc_audiopid[n].pid == -2)
+			continue;
+
 		vc = sc->sc_vchan[n];
 		if (!(vc->sc_open & AUOPEN_READ))
 			continue;
@@ -4685,8 +4739,10 @@
  */
 int
 mixer_open(dev_t dev, struct audio_softc *sc, int flags,
-    int ifmt, struct lwp *l)
+    int ifmt, struct lwp *l, struct file **nfp)
 {
+	struct file *fp;
+	int error, fd, n;
 
 	KASSERT(mutex_owned(sc->sc_lock));
 
@@ -4695,7 +4751,25 @@
 
 	DPRINTF(("mixer_open: flags=0x%x sc=%p\n", flags, sc));
 
-	return 0;
+	for (n = 1; n < VAUDIOCHANS; n++) {
+		if (sc->sc_audiopid[n].pid == -1)
+			break;
+	}
+	if (n == VAUDIOCHANS)
+		return ENOMEM;
+
+	error = fd_allocfile(&fp, &fd);
+	if (error)
+		return error;
+
+	sc->sc_audiopid[n].pid = -2;
+
+	sc->sc_audiopid[n].dev = dev;
+	error = fd_clone(fp, fd, flags, &audio_fileops, &sc->sc_audiopid[n]);
+	KASSERT(error == EMOVEFD);
+
+	*nfp = fp;
+	return error;
 }
 
 /*
@@ -4742,21 +4816,22 @@
  */
 /* ARGSUSED */
 int
-mixer_close(struct audio_softc *sc, int flags, int ifmt, struct lwp *l)
+mixer_close(struct audio_softc *sc, int flags, int n)
 {
 
 	KASSERT(mutex_owned(sc->sc_lock));
 	if (sc->hw_if == NULL)
 		return ENXIO;
 
+	sc->sc_audiopid[n].pid = -1;
+
 	DPRINTF(("mixer_close: sc %p\n", sc));
 	mixer_remove(sc);
 	return 0;
 }
 
 int
-mixer_ioctl(struct audio_softc *sc, u_long cmd, void *addr, int flag,
-	    struct lwp *l)
+mixer_ioctl(struct audio_softc *sc, u_long cmd, void *addr, int flag)
 {
 	const struct audio_hw_if *hw;
 	struct mixer_asyncs *ma;
@@ -4829,9 +4904,10 @@
 		break;
 
 	default:
-		if (hw->dev_ioctl)
-			error = hw->dev_ioctl(sc->hw_hdl, cmd, addr, flag, l);
-		else
+		if (hw->dev_ioctl) {
+			error = hw->dev_ioctl(sc->hw_hdl, cmd, addr, flag,
+			    curlwp);
+		} else
 			error = EINVAL;
 		break;
 	}
@@ -4993,7 +5069,7 @@
 	mutex_enter(sc->sc_lock);
 	audio_mixer_capture(sc);
 	for (n = 1; n < VAUDIOCHANS; n++) {
-		if (sc->sc_audiopid[n].pid == -1)
+		if (sc->sc_audiopid[n].pid == -1 || sc->sc_audiopid[n].pid == -2)
 			continue;
 
 		vc = sc->sc_vchan[n];
@@ -5032,7 +5108,7 @@
 
 	audio_mixer_restore(sc);
 	for (n = 1; n < VAUDIOCHANS; n++) {
-		if (sc->sc_audiopid[n].pid == -1)
+		if (sc->sc_audiopid[n].pid == -1 || sc->sc_audiopid[n].pid == -2)
 			continue;
 		vc = sc->sc_vchan[n];
 
Index: src/sys/dev/audiobell.c
===================================================================
RCS file: /cvsroot/src/sys/dev/audiobell.c,v
retrieving revision 1.12
diff -u -r1.12 audiobell.c
--- src/sys/dev/audiobell.c	13 Dec 2016 20:18:32 -0000	1.12
+++ src/sys/dev/audiobell.c	28 Dec 2016 02:50:48 -0000
@@ -38,19 +38,22 @@
 #include <sys/conf.h>
 #include <sys/device.h>
 #include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
 #include <sys/ioctl.h>
 #include <sys/malloc.h>
 #include <sys/null.h>
 #include <sys/systm.h>
 #include <sys/uio.h>
+#include <sys/unistd.h>
 
 #include <dev/audio_if.h>
 #include <dev/audiobellvar.h>
 
-extern dev_type_open(audioopen);
-extern dev_type_ioctl(audioioctl);
-extern dev_type_write(audiowrite);
-extern dev_type_close(audioclose);
+extern int audiobellopen(dev_t, int, int, struct lwp *, struct file **);
+extern int audioclose(struct file *);
+extern int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int);
+extern int audioioctl(struct file *, u_long, void *);
 
 /* Convert a %age volume to an amount to add to u-law values */
 /* XXX Probably highly inaccurate -- should be regenerated */
@@ -143,18 +146,23 @@
 	struct audio_info ai;
 	struct uio auio;
 	struct iovec aiov;
+	struct file *fp;
 	int size, len, offset;
+
+	fp = NULL;
 	dev_t audio = AUDIO_DEVICE | device_unit((device_t)v);
 
 	/* The audio system isn't built for polling. */
 	if (poll) return;
 
 	/* If not configured, we can't beep. */
-	if (audioopen(audio, FWRITE, 0, NULL) != 0)
+	if (audiobellopen(audio, FWRITE, 0, NULL, &fp) != EMOVEFD || fp == NULL)
 		return;
 
-	if (audioioctl(audio, AUDIO_GETINFO, &ai, 0, NULL) != 0)
+	if (audioioctl(fp, AUDIO_GETINFO, &ai) != 0) {
+		audioclose(fp);
 		return;
+	}
 
 	buf = NULL;
 
@@ -179,11 +187,11 @@
 		auio.uio_rw = UIO_WRITE;
 		UIO_SETUP_SYSSPACE(&auio);
 
-		audiowrite(audio, &auio, 0);
+		audiowrite(fp, NULL, &auio, NULL, 0);
 		len -= size;
 		offset += size;
 	}
 out:
 	if (buf != NULL) free(buf, M_TEMP);
-	audioclose(audio, FWRITE, 0, NULL);
+	audioclose(fp);
 }
Index: src/sys/sys/audioio.h
===================================================================
RCS file: /cvsroot/src/sys/sys/audioio.h,v
retrieving revision 1.35
diff -u -r1.35 audioio.h
--- src/sys/sys/audioio.h	8 Dec 2016 10:28:44 -0000	1.35
+++ src/sys/sys/audioio.h	28 Dec 2016 02:50:48 -0000
@@ -144,6 +144,7 @@
 } audio_encoding_t;
 
 struct audio_pid {
+	dev_t	dev;
 	pid_t	pid;			/* for audio device belonging to pid */
 	lwpid_t	lwpid;			/* unused */
 };
Index: src/sys/sys/file.h
===================================================================
RCS file: /cvsroot/src/sys/sys/file.h,v
retrieving revision 1.79
diff -u -r1.79 file.h
--- src/sys/sys/file.h	30 May 2015 20:09:47 -0000	1.79
+++ src/sys/sys/file.h	28 Dec 2016 02:50:48 -0000
@@ -103,6 +103,7 @@
 	struct kqueue *fd_kq;		// DTYPE_KQUEUE
 	void *fd_data;			// DTYPE_MISC
 	struct rnd_ctx *fd_rndctx;	// DTYPE_MISC (rnd)
+	struct audio_pid *fd_audioctx;	// DTYPE_MISC (audio)
 	int fd_devunit;			// DTYPE_MISC (tap)
 	struct bpf_d *fd_bpf;		// DTYPE_MISC (bpf)
 	struct fcrypt *fd_fcrypt;	// DTYPE_CRYPTO is not used
@@ -144,6 +145,7 @@
 #define f_ksem		f_undata.fd_ks
 
 #define f_rndctx	f_undata.fd_rndctx
+#define f_audioctx	f_undata.fd_audioctx
 #define f_devunit	f_undata.fd_devunit
 #define f_bpf		f_undata.fd_bpf
 #define f_fcrypt	f_undata.fd_fcrypt
