NetBSD-Bugs archive

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

Re: kern/39204



The following reply was made to PR kern/39204; it has been noted by GNATS.

From: Nat Sloss <nathanialsloss%yahoo.com.au@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: 
Subject: Re: kern/39204
Date: Mon, 14 May 2012 22:26:11 +1000

 Hi.
 
 Thank you for the guidelines.  I'm still learning.  I'm more of a hack than a 
 programmer though :)
 
 I hope this is better:
 
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pad/pad.c,v
 retrieving revision 1.19
 diff -u -r1.19 pad.c
 --- pad/pad.c   24 Nov 2011 01:54:08 -0000      1.19
 +++ pad/pad.c   14 May 2012 12:20:17 -0000
 @@ -374,11 +374,6 @@
                 intrarg = sc->sc_intrarg;
         }
 
 -       if (intr) {
 -               mutex_enter(&sc->sc_intr_lock);
 -               (*intr)(intrarg);
 -               mutex_exit(&sc->sc_intr_lock);
 -       }
         mutex_exit(&sc->sc_lock);
 
         return 
 err;===================================================================
 RCS file: /cvsroot/src/sys/dev/audio.c,v
 retrieving revision 1.261
 diff -u -r1.261 audio.c
 --- audio.c     30 Apr 2012 02:16:46 -0000      1.261
 +++ audio.c     14 May 2012 12:21:06 -0000
 @@ -401,6 +401,7 @@
         cv_init(&sc->sc_rchan, "audiord");
         cv_init(&sc->sc_wchan, "audiowr");
         cv_init(&sc->sc_lchan, "audiolk");
 +       cv_init(&sc->sc_dataready, "audiordy");
 
         if (hwp == 0 || hwp->get_locks == 0) {
                 printf(": missing method\n");
 @@ -760,6 +761,7 @@
         cv_destroy(&sc->sc_rchan);
         cv_destroy(&sc->sc_wchan);
         cv_destroy(&sc->sc_lchan);
 +       cv_destroy(&sc->sc_dataready);
 
         return 0;
  }
 @@ -2211,12 +2213,15 @@
                     sc, uio->uio_resid, 
 audio_stream_get_used(sc->sc_pustream),
                     sc->sc_pr.usedhigh));
         cb = &sc->sc_pr;
 -       if (cb->mmapped)
 -               return EINVAL;
 +       if (cb->mmapped) {
 +               error = EINVAL;
 +               goto audio_write_end;
 +       }
 
         if (uio->uio_resid == 0) {
                 sc->sc_eof++;
 -               return 0;
 +               error = 0;
 +               goto audio_write_end;
         }
 
  #ifdef AUDIO_PM_IDLE
 @@ -2232,7 +2237,8 @@
                 uio->uio_offset += uio->uio_resid;
                 uio->uio_resid = 0;
                 DPRINTF(("audio_write: half-dpx read busy\n"));
 -               return 0;
 +               error = 0;
 +               goto audio_write_end;
         }
 
         if (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) {
 @@ -2241,8 +2247,10 @@
                 uio->uio_offset += n;
                 uio->uio_resid -= n;
                 sc->sc_playdrop -= n;
 -               if (uio->uio_resid == 0)
 -                       return 0;
 +               if (uio->uio_resid == 0) {
 +                       error = 0;
 +                       goto audio_write_end;
 +               }
         }
 
         /**
 @@ -2265,13 +2273,15 @@
                                      "hiwat=%d\n", used,
                                      cb->usedlow, cb->usedhigh));
                         mutex_exit(sc->sc_intr_lock);
 -                       if (ioflag & IO_NDELAY)
 -                               return EWOULDBLOCK;
 +                       if (ioflag & IO_NDELAY) {
 +                               error = EWOULDBLOCK;
 +                               goto audio_write_end;
 +                       }
                         error = audio_waitio(sc, &sc->sc_wchan);
                         if (sc->sc_dying)
                                 error = EIO;
                         if (error)
 -                               return error;
 +                               goto audio_write_end;
                         mutex_enter(sc->sc_intr_lock);
                 }
                 inp = cb->s.inp;
 @@ -2298,6 +2308,7 @@
                         cc = stream.end - stream.start;
                         error = fetcher->fetch_to(sc, fetcher, &stream, cc);
                 }
 +
                 mutex_enter(sc->sc_intr_lock);
                 if (sc->sc_npfilters > 0) {
                         cb->fstamp += ufetcher.last_used
 @@ -2343,6 +2354,8 @@
         }
         mutex_exit(sc->sc_intr_lock);
 
 +audio_write_end:
 +       cv_broadcast(&sc->sc_dataready);
         return error;
  }
 
 @@ -2791,7 +2804,8 @@
         if (!audio_can_playback(sc))
                 return EINVAL;
 
 -       if (!sc->sc_pr.mmapped && used < sc->sc_pr.blksize) {
 +       if (!sc->sc_pr.mmapped && used < sc->sc_pr.blksize &&
 +           sc->hw_if->trigger_output != NULL) {
                 cv_broadcast(&sc->sc_wchan);
                 DPRINTF(("%s: wakeup and return\n", __func__));
                 return 0;
 @@ -2928,6 +2942,7 @@
         int cc, used;
         int blksize;
         int error;
 +       int i, timeout;
 
         sc = v;
 
 @@ -3042,8 +3057,28 @@
                      sc->sc_mode, cb->pause,
                      audio_stream_get_used(sc->sc_pustream), cb->usedlow));
         if ((sc->sc_mode & AUMODE_PLAY) && !cb->pause) {
 -               if (audio_stream_get_used(sc->sc_pustream) <= cb->usedlow)
 +               if ((used = audio_stream_get_used(sc->sc_pustream)) <= 
 cb->usedlow)
                         softint_schedule(sc->sc_sih_wr);
 +
 +               if (used < blksize && device_is_a(sc->sc_dev, "pad")) {
 +                       i = 0;
 +                       timeout = mstohz(5);
 +                       if (timeout == 0)
 +                               timeout = 1;
 +
 +                       mutex_exit(sc->sc_intr_lock);
 +                       while ((used = audio_stream_get_used(sc->sc_pustream))
 +                           < blksize && cb->usedlow > blksize) {
 +                               softint_schedule(sc->sc_sih_wr);
 +                               error = cv_timedwait_sig(&sc->sc_dataready, 
 sc->sc_lock, timeout);
 +                               i++;
 +                               if (error != 0 && error != EWOULDBLOCK)
 +                                       break;
 +                               if (i > 200)
 +                                       break;
 +                       }
 +                       mutex_enter(sc->sc_intr_lock);
 +               }
         }
 
         /* Possible to return one or more "phantom blocks" now. */
 
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/audiovar.h,v
 retrieving revision 1.46
 diff -u -r1.46 audiovar.h
 --- audiovar.h  23 Nov 2011 23:07:31 -0000      1.46
 +++ audiovar.h  14 May 2012 12:23:06 -0000
 @@ -147,6 +147,7 @@
         kcondvar_t      sc_rchan;
         kcondvar_t      sc_wchan;
         kcondvar_t      sc_lchan;
 +       kcondvar_t      sc_dataready;
         int             sc_dvlock;
         bool            sc_dying;
 
 I tested this with the scenarios mentioned before and it works even better 
 than my first attempt :)
 
 Note:  This patch is my own work which I submit under the NetBSD license.
 
 I hope this helps and thanks for the feedback.  May my future patches be even 
 better.
 
 Regards,
 
 Nat.
 


Home | Main Index | Thread Index | Old Index