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 <
[email protected]>
@@ -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