[BACK]Return to pad.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pad

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/pad/pad.c between version 1.22.2.1 and 1.22.2.2

version 1.22.2.1, 2015/09/22 12:05:59 version 1.22.2.2, 2016/03/19 11:30:10
Line 43  __KERNEL_RCSID(0, "$NetBSD$");
Line 43  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/vnode.h>  #include <sys/vnode.h>
 #include <sys/module.h>  #include <sys/module.h>
 #include <sys/atomic.h>  #include <sys/atomic.h>
   #include <sys/time.h>
   
 #include <dev/audio_if.h>  #include <dev/audio_if.h>
 #include <dev/audiovar.h>  #include <dev/audiovar.h>
Line 316  pad_open(dev_t dev, int flags, int fmt, 
Line 317  pad_open(dev_t dev, int flags, int fmt, 
         if (atomic_swap_uint(&sc->sc_open, 1) != 0) {          if (atomic_swap_uint(&sc->sc_open, 1) != 0) {
                 return EBUSY;                  return EBUSY;
         }          }
   
           getmicrotime(&sc->sc_last);
           sc->sc_bytes_count = 0;
   
         return 0;          return 0;
 }  }
Line 335  pad_close(dev_t dev, int flags, int fmt,
Line 339  pad_close(dev_t dev, int flags, int fmt,
         return 0;          return 0;
 }  }
   
   #define PAD_BYTES_PER_SEC (44100 * sizeof(int16_t) * 2)
   #define TIMENEXTREAD    (20 * 1000)
   #define BYTESTOSLEEP (PAD_BYTES_PER_SEC / (1000000 / TIMENEXTREAD))
   
 int  int
 pad_read(dev_t dev, struct uio *uio, int flags)  pad_read(dev_t dev, struct uio *uio, int flags)
 {  {
           struct timeval now;
           uint64_t nowusec, lastusec;
         pad_softc_t *sc;          pad_softc_t *sc;
         pad_block_t pb;          pad_block_t pb;
         void (*intr)(void *);          void (*intr)(void *);
         void *intrarg;          void *intrarg;
         int err;          int err, wait_ticks;
   
         sc = device_lookup_private(&pad_cd, PADUNIT(dev));          sc = device_lookup_private(&pad_cd, PADUNIT(dev));
         if (sc == NULL)          if (sc == NULL)
Line 354  pad_read(dev_t dev, struct uio *uio, int
Line 364  pad_read(dev_t dev, struct uio *uio, int
         intr = sc->sc_intr;          intr = sc->sc_intr;
         intrarg = sc->sc_intrarg;          intrarg = sc->sc_intrarg;
   
         kpreempt_disable();  
         while (uio->uio_resid > 0 && !err) {          while (uio->uio_resid > 0 && !err) {
                   getmicrotime(&now);
                   nowusec = (now.tv_sec * 1000000) + now.tv_usec;
                   lastusec = (sc->sc_last.tv_sec * 1000000) +
                        sc->sc_last.tv_usec;
                   if (lastusec + TIMENEXTREAD > nowusec &&
                        sc->sc_bytes_count >= BYTESTOSLEEP) {
                           wait_ticks = (hz * ((lastusec + TIMENEXTREAD) -
                                nowusec)) / 1000000;
                           if (wait_ticks > 0) {
                                   kpause("padwait", TRUE, wait_ticks,
                                        &sc->sc_lock);
                           }
   
                           sc->sc_bytes_count -= BYTESTOSLEEP;
                           getmicrotime(&sc->sc_last);
                   } else if (sc->sc_bytes_count >= BYTESTOSLEEP) {
                           sc->sc_bytes_count -= BYTESTOSLEEP;
                           getmicrotime(&sc->sc_last);
                   } else if (lastusec + TIMENEXTREAD <= nowusec)
                           getmicrotime(&sc->sc_last);
   
                 err = pad_get_block(sc, &pb, min(uio->uio_resid, PAD_BLKSIZE));                  err = pad_get_block(sc, &pb, min(uio->uio_resid, PAD_BLKSIZE));
                 if (!err) {                  if (!err) {
                           sc->sc_bytes_count += pb.pb_len;
   
                         mutex_exit(&sc->sc_lock);                          mutex_exit(&sc->sc_lock);
                         err = uiomove(pb.pb_ptr, pb.pb_len, uio);                          err = uiomove(pb.pb_ptr, pb.pb_len, uio);
                         mutex_enter(&sc->sc_lock);                          mutex_enter(&sc->sc_lock);
Line 366  pad_read(dev_t dev, struct uio *uio, int
Line 398  pad_read(dev_t dev, struct uio *uio, int
   
                 if (intr) {                  if (intr) {
                         mutex_enter(&sc->sc_intr_lock);                          mutex_enter(&sc->sc_intr_lock);
                           kpreempt_disable();
                         (*intr)(intrarg);                          (*intr)(intrarg);
                           kpreempt_enable();
                         mutex_exit(&sc->sc_intr_lock);                          mutex_exit(&sc->sc_intr_lock);
                         intr = sc->sc_intr;                          intr = sc->sc_intr;
                         intrarg = sc->sc_intrarg;                          intrarg = sc->sc_intrarg;
Line 374  pad_read(dev_t dev, struct uio *uio, int
Line 408  pad_read(dev_t dev, struct uio *uio, int
                         continue;                          continue;
                 }                  }
                 err = cv_wait_sig(&sc->sc_condvar, &sc->sc_lock);                  err = cv_wait_sig(&sc->sc_condvar, &sc->sc_lock);
                 if (err != 0) {                  if (err != 0)
                         mutex_exit(&sc->sc_lock);                          break;
                         kpreempt_enable();  
                         return err;  
                 }  
                 intr = sc->sc_intr;                  intr = sc->sc_intr;
                 intrarg = sc->sc_intrarg;                  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);          mutex_exit(&sc->sc_lock);
         kpreempt_enable();  
   
         return err;          return err;
 }  }

Legend:
Removed from v.1.22.2.1  
changed lines
  Added in v.1.22.2.2

CVSweb <webmaster@jp.NetBSD.org>