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 @@ -148,7 +148,7 @@ */ #include -__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 #include #include +#include +#include #include #include #include @@ -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 #include #include +#include +#include #include #include #include #include #include +#include #include #include -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