Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pad Pace I/O timing to match the audio interface.



details:   https://anonhg.NetBSD.org/src/rev/06fb14ba6ea8
branches:  trunk
changeset: 373218:06fb14ba6ea8
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Tue Jan 24 08:17:11 2023 +0000

description:
Pace I/O timing to match the audio interface.
Enable interrupts while copying buffers.

diffstat:

 sys/dev/pad/pad.c    |  64 ++++++++++++++++++++++++++++++++++++++-------------
 sys/dev/pad/padvar.h |   4 ++-
 2 files changed, 50 insertions(+), 18 deletions(-)

diffs (171 lines):

diff -r 252f8223fea5 -r 06fb14ba6ea8 sys/dev/pad/pad.c
--- a/sys/dev/pad/pad.c Tue Jan 24 08:09:37 2023 +0000
+++ b/sys/dev/pad/pad.c Tue Jan 24 08:17:11 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pad.c,v 1.78 2022/03/31 19:30:16 pgoyette Exp $ */
+/* $NetBSD: pad.c,v 1.79 2023/01/24 08:17:11 mlelstv Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.78 2022/03/31 19:30:16 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.79 2023/01/24 08:17:11 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -148,7 +148,7 @@
 extern void    padattach(int);
 
 static int     pad_add_block(struct pad_softc *, uint8_t *, int);
-static int     pad_get_block(struct pad_softc *, pad_block_t *, int);
+static int     pad_get_block(struct pad_softc *, pad_block_t *, int, int);
 
 static dev_type_open(pad_open);
 
@@ -280,7 +280,7 @@
 static int
 pad_add_block(struct pad_softc *sc, uint8_t *blk, int blksize)
 {
-       int l;
+       int foff, flen, tlen;
 
        KASSERT(blksize >= 0);
        KASSERT(mutex_owned(&sc->sc_intr_lock));
@@ -289,18 +289,27 @@
            sc->sc_buflen > PAD_BUFSIZE - (unsigned)blksize)
                return ENOBUFS;
 
-       if (sc->sc_wpos + blksize <= PAD_BUFSIZE)
-               memcpy(sc->sc_audiobuf + sc->sc_wpos, blk, blksize);
-       else {
-               l = PAD_BUFSIZE - sc->sc_wpos;
-               memcpy(sc->sc_audiobuf + sc->sc_wpos, blk, l);
-               memcpy(sc->sc_audiobuf, blk + l, blksize - l);
+       foff = sc->sc_wpos;
+       if (sc->sc_wpos + blksize <= PAD_BUFSIZE) {
+               flen = blksize;
+               tlen = 0;
+       } else {
+               flen = PAD_BUFSIZE - sc->sc_wpos;
+               tlen = blksize - flen;
        }
 
-       sc->sc_wpos += blksize;
+       sc->sc_wpos = foff + blksize;
        if (sc->sc_wpos >= PAD_BUFSIZE)
                sc->sc_wpos -= PAD_BUFSIZE;
 
+       /*
+        * release interrupt lock for bulk copy to audio buffer
+        */
+       mutex_exit(&sc->sc_intr_lock);
+       memcpy(sc->sc_audiobuf + foff, blk, flen);
+       memcpy(sc->sc_audiobuf, blk + flen, tlen);
+       mutex_enter(&sc->sc_intr_lock);
+
        sc->sc_buflen += blksize;
        cv_broadcast(&sc->sc_condvar);
 
@@ -308,13 +317,16 @@
 }
 
 static int
-pad_get_block(struct pad_softc *sc, pad_block_t *pb, int maxblksize)
+pad_get_block(struct pad_softc *sc, pad_block_t *pb, int maxblksize, int dowait)
 {
        int l, blksize, error;
 
        KASSERT(maxblksize > 0);
        KASSERT(mutex_owned(&sc->sc_intr_lock));
 
+       if (sc->sc_buflen == 0 && !dowait)
+               return EAGAIN;
+
        while (sc->sc_buflen == 0) {
                DPRINTF("%s: wait\n", __func__);
                error = cv_wait_sig(&sc->sc_condvar, &sc->sc_intr_lock);
@@ -500,14 +512,20 @@
     int ioflag)
 {
        pad_block_t pb;
-       int err;
+       int err, first;
 
        err = 0;
+       first = 1;
        DPRINTF("%s: resid=%zu\n", __func__, uio->uio_resid);
        while (uio->uio_resid > 0) {
                mutex_enter(&sc->sc_intr_lock);
-               err = pad_get_block(sc, &pb, MIN(uio->uio_resid, INT_MAX));
+               err = pad_get_block(sc, &pb, MIN(uio->uio_resid, INT_MAX), first);
                mutex_exit(&sc->sc_intr_lock);
+               first = 0;
+               if (err == EAGAIN) {
+                       err = 0;
+                       break;
+               }
                if (err)
                        break;
 
@@ -557,7 +575,8 @@
 {
        struct pad_softc *sc = opaque;
        int err;
-       int ms;
+       u_int framesize;
+       int ticks;
 
        KASSERT(mutex_owned(&sc->sc_intr_lock));
 
@@ -566,10 +585,20 @@
 
        DPRINTF("%s: blksize=%d\n", __func__, blksize);
        err = pad_add_block(sc, block, blksize);
+       if (err) {
+               DPRINTF("%s: failed: %d\n", __func__, err);
+               /* "Silently" drop overflows, but keep pace */
+               err = 0;
+       }
 
-       ms = blksize * 1000 / PADCHAN / (PADPREC / NBBY) / PADFREQ;
+       framesize = PADCHAN * (PADPREC / NBBY) * PADFREQ;
+
+       sc->sc_resid += blksize;
+       ticks = mstohz(sc->sc_resid * 1000 / framesize);
+       sc->sc_resid -= hztoms(ticks) * framesize / 1000;
+
        DPRINTF("%s: callout ms=%d\n", __func__, ms);
-       callout_schedule(&sc->sc_pcallout, mstohz(ms));
+       callout_schedule(&sc->sc_pcallout, ticks);
 
        return err;
 }
@@ -587,6 +616,7 @@
        sc->sc_intr = NULL;
        sc->sc_intrarg = NULL;
        sc->sc_buflen = 0;
+       sc->sc_resid = 0;
        sc->sc_rpos = sc->sc_wpos = 0;
 
        return 0;
diff -r 252f8223fea5 -r 06fb14ba6ea8 sys/dev/pad/padvar.h
--- a/sys/dev/pad/padvar.h      Tue Jan 24 08:09:37 2023 +0000
+++ b/sys/dev/pad/padvar.h      Tue Jan 24 08:17:11 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: padvar.h,v 1.16 2021/06/14 18:44:45 riastradh Exp $ */
+/* $NetBSD: padvar.h,v 1.17 2023/01/24 08:17:11 mlelstv Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -57,6 +57,8 @@
        u_int           sc_wpos;
 
        uint8_t         sc_swvol;
+
+       u_int           sc_resid;
 };
 
 #endif /* !_SYS_DEV_PAD_PADVAR_H */



Home | Main Index | Thread Index | Old Index