diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2009-03-21 13:16:22 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2009-03-21 13:16:22 +0000 |
commit | 3ddaccc07fb0cfffb23e8fde0d30df6fcdcd7133 (patch) | |
tree | 19397b128a8233d49a105bc8c4a9047c56fbda74 /sys | |
parent | 58daf95a97d8d2a1361926265eaef1beb656ed2d (diff) |
don't call uiomove(9) at IPL_AUDIO, slightly simplify the code
help from and ok jakemsr
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/audio.c | 131 |
1 files changed, 46 insertions, 85 deletions
diff --git a/sys/dev/audio.c b/sys/dev/audio.c index 9a0b48a09b1..0ffdad02623 100644 --- a/sys/dev/audio.c +++ b/sys/dev/audio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: audio.c,v 1.102 2009/03/16 19:45:09 ratchov Exp $ */ +/* $OpenBSD: audio.c,v 1.103 2009/03/21 13:16:21 ratchov Exp $ */ /* $NetBSD: audio.c,v 1.119 1999/11/09 16:50:47 augustss Exp $ */ /* @@ -1225,7 +1225,7 @@ audio_read(dev_t dev, struct uio *uio, int ioflag) struct audio_softc *sc = audio_cd.cd_devs[unit]; struct audio_ringbuffer *cb = &sc->sc_rr; u_char *outp; - int error, s, used, cc, n; + int error, s, cc, n, resid; if (cb->mmapped) return EINVAL; @@ -1271,7 +1271,7 @@ audio_read(dev_t dev, struct uio *uio, int ioflag) } return (error); } - while (uio->uio_resid > 0 && !error) { + while (uio->uio_resid > 0) { s = splaudio(); while (cb->used <= 0) { if (!sc->sc_rbus && !sc->sc_rr.pause) { @@ -1294,30 +1294,28 @@ audio_read(dev_t dev, struct uio *uio, int ioflag) return error; } } - used = cb->used; + resid = uio->uio_resid * sc->sc_rparams.factor; outp = cb->outp; - cc = used - cb->usedlow; /* maximum to read */ + cc = cb->used - cb->usedlow; /* maximum to read */ n = cb->end - outp; - if (n < cc) - cc = n; /* don't read beyond end of buffer */ - /* and no more than we want */ - if (uio->uio_resid < cc / sc->sc_rparams.factor) - cc = uio->uio_resid * sc->sc_rparams.factor; - if (cb->blksize < cc) - cc = cb->blksize; /* splx() quickly */ + if (cc > n) + cc = n; /* don't read beyond end of buffer */ + + if (cc > resid) + cc = resid; /* and no more than we want */ + cb->used -= cc; + cb->outp += cc; + if (cb->outp >= cb->end) + cb->outp = cb->start; + splx(s); + DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp, cc)); if (sc->sc_rparams.sw_code) sc->sc_rparams.sw_code(sc->hw_hdl, outp, cc); - DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp, cc)); error = uiomove(outp, cc / sc->sc_rparams.factor, uio); - used -= cc; - outp += cc; - if (outp >= cb->end) - outp = cb->start; - cb->outp = outp; - cb->used = used; - splx(s); + if (error) + return error; } - return (error); + return 0; } void @@ -1462,7 +1460,7 @@ audio_write(dev_t dev, struct uio *uio, int ioflag) struct audio_softc *sc = audio_cd.cd_devs[unit]; struct audio_ringbuffer *cb = &sc->sc_pr; u_char *inp; - int saveerror, error, s, n, cc, used; + int error, s, n, cc, resid, avail; DPRINTFN(2, ("audio_write: sc=%p(unit=%d) count=%d used=%d(hi=%d)\n", sc, unit, uio->uio_resid, sc->sc_pr.used, sc->sc_pr.usedhigh)); @@ -1501,12 +1499,18 @@ audio_write(dev_t dev, struct uio *uio, int ioflag) sc->sc_pparams.precision, sc->sc_pparams.channels, sc->sc_pparams.sw_code, sc->sc_pparams.factor)); - error = 0; - while (uio->uio_resid > 0 && !error) { + while (uio->uio_resid > 0) { s = splaudio(); while (cb->used >= cb->usedhigh) { DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d hiwat=%d\n", cb->used, cb->usedlow, cb->usedhigh)); + if (!sc->sc_pbus && !cb->pause) { + error = audiostartp(sc); + if (error) { + splx(s); + return error; + } + } if (ioflag & IO_NDELAY) { splx(s); return (EWOULDBLOCK); @@ -1519,79 +1523,36 @@ audio_write(dev_t dev, struct uio *uio, int ioflag) return error; } } - used = cb->used; + resid = uio->uio_resid * sc->sc_pparams.factor; + avail = cb->end - cb->inp; inp = cb->inp; - cc = cb->usedhigh - used; /* maximum to write */ - n = cb->end - inp; - if (sc->sc_pparams.factor != 1) { - /* Compensate for software coding expansion factor. */ - n /= sc->sc_pparams.factor; - cc /= sc->sc_pparams.factor; - } - if (n < cc) - cc = n; /* don't write beyond end of buffer */ - if (uio->uio_resid < cc) - cc = uio->uio_resid; /* and no more than we have */ - if (cb->blksize < cc) - cc = cb->blksize; /* splx() quickly */ - -#ifdef DIAGNOSTIC + cc = cb->usedhigh - cb->used; + if (cc > resid) + cc = resid; + if (cc > avail) + cc = avail; + cb->inp += cc; + if (cb->inp >= cb->end) + cb->inp = cb->start; + cb->used += cc; /* - * This should never happen since the block size and and - * block pointers are always nicely aligned. + * This is a very suboptimal way of keeping track of + * silence in the buffer, but it is simple. */ - if (cc == 0) { - printf("audio_write: cc == 0, swcode=%p, factor=%d\n", - sc->sc_pparams.sw_code, sc->sc_pparams.factor); - splx(s); - return EINVAL; - } -#endif + sc->sc_sil_count = 0; + splx(s); + cc /= sc->sc_pparams.factor; DPRINTFN(1, ("audio_write: uiomove cc=%d inp=%p, left=%d\n", cc, inp, uio->uio_resid)); - n = uio->uio_resid; error = uiomove(inp, cc, uio); - cc = n - uio->uio_resid; /* number of bytes actually moved */ -#ifdef AUDIO_DEBUG if (error) - printf("audio_write:(1) uiomove failed %d; cc=%d inp=%p\n", - error, cc, inp); -#endif - /* - * Continue even if uiomove() failed because we may have - * gotten a partial block. - */ - + return 0; if (sc->sc_pparams.sw_code) { sc->sc_pparams.sw_code(sc->hw_hdl, inp, cc); - /* Adjust count after the expansion. */ - cc *= sc->sc_pparams.factor; DPRINTFN(1, ("audio_write: expanded cc=%d\n", cc)); } - - inp = cb->inp + cc; - if (inp >= cb->end) - inp = cb->start; - cb->inp = inp; - cb->used += cc; - - /* - * This is a very suboptimal way of keeping track of - * silence in the buffer, but it is simple. - */ - sc->sc_sil_count = 0; - - if (!sc->sc_pbus && !cb->pause) { - saveerror = error; - error = audiostartp(sc); - if (saveerror != 0) { - /* Report the first error that occurred. */ - error = saveerror; - } - } - splx(s); } - return (error); + return 0; } int |