summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2009-03-21 13:16:22 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2009-03-21 13:16:22 +0000
commit3ddaccc07fb0cfffb23e8fde0d30df6fcdcd7133 (patch)
tree19397b128a8233d49a105bc8c4a9047c56fbda74 /sys
parent58daf95a97d8d2a1361926265eaef1beb656ed2d (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.c131
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