The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/audio.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: audio.c,v 1.205 2022/11/08 17:53:01 kn Exp $  */
    2 /*
    3  * Copyright (c) 2015 Alexandre Ratchov <alex@caoua.org>
    4  *
    5  * Permission to use, copy, modify, and distribute this software for any
    6  * purpose with or without fee is hereby granted, provided that the above
    7  * copyright notice and this permission notice appear in all copies.
    8  *
    9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16  */
   17 #include <sys/param.h>
   18 #include <sys/fcntl.h>
   19 #include <sys/systm.h>
   20 #include <sys/ioctl.h>
   21 #include <sys/conf.h>
   22 #include <sys/kernel.h>
   23 #include <sys/event.h>
   24 #include <sys/mutex.h>
   25 #include <sys/task.h>
   26 #include <sys/vnode.h>
   27 #include <sys/malloc.h>
   28 #include <sys/device.h>
   29 #include <sys/audioio.h>
   30 #include <dev/audio_if.h>
   31 #include <dev/mulaw.h>
   32 #include "audio.h"
   33 #include "wskbd.h"
   34 
   35 #ifdef AUDIO_DEBUG
   36 #define DPRINTF(...)                            \
   37         do {                                    \
   38                 if (audio_debug)                \
   39                         printf(__VA_ARGS__);    \
   40         } while(0)
   41 #define DPRINTFN(n, ...)                        \
   42         do {                                    \
   43                 if (audio_debug > (n))          \
   44                         printf(__VA_ARGS__);    \
   45         } while(0)
   46 #else
   47 #define DPRINTF(...) do {} while(0)
   48 #define DPRINTFN(n, ...) do {} while(0)
   49 #endif
   50 
   51 #define IPL_SOFTAUDIO           IPL_SOFTNET
   52 
   53 #define DEVNAME(sc)             ((sc)->dev.dv_xname)
   54 #define AUDIO_UNIT(n)           (minor(n) & 0x0f)
   55 #define AUDIO_DEV(n)            (minor(n) & 0xf0)
   56 #define AUDIO_DEV_AUDIO         0       /* minor of /dev/audio0 */
   57 #define AUDIO_DEV_AUDIOCTL      0xc0    /* minor of /dev/audioctl */
   58 #define AUDIO_BUFSZ             65536   /* buffer size in bytes */
   59 
   60 /*
   61  * mixer entries added by the audio(4) layer
   62  */
   63 #define MIXER_RECORD                    0       /* record class */
   64 #define MIXER_RECORD_ENABLE             1       /* record.enable control */
   65 #define  MIXER_RECORD_ENABLE_OFF        0       /* record.enable=off value */
   66 #define  MIXER_RECORD_ENABLE_ON         1       /* record.enable=on value */
   67 #define  MIXER_RECORD_ENABLE_SYSCTL     2       /* record.enable=sysctl val */
   68 
   69 /*
   70  * dma buffer
   71  */
   72 struct audio_buf {
   73         unsigned char *data;            /* DMA memory block */
   74         size_t datalen;                 /* size of DMA memory block */
   75         size_t len;                     /* size of DMA FIFO */
   76         size_t start;                   /* first byte used in the FIFO */
   77         size_t used;                    /* bytes used in the FIFO */
   78         size_t blksz;                   /* DMA block size */
   79         unsigned int nblks;             /* number of blocks */
   80         struct klist klist;             /* list of knotes */
   81         unsigned int pos;               /* bytes transferred */
   82         unsigned int xrun;              /* bytes lost by xruns */
   83         int blocking;                   /* read/write blocking */
   84 };
   85 
   86 #if NWSKBD > 0
   87 struct wskbd_vol
   88 {
   89         int val;                        /* index of the value control */
   90         int mute;                       /* index of the mute control */
   91         int step;                       /* increment/decrement step */
   92         int nch;                        /* channels in the value control */
   93         int val_pending;                /* pending change of val */
   94         int mute_pending;               /* pending change of mute */
   95 #define WSKBD_MUTE_TOGGLE       1
   96 #define WSKBD_MUTE_DISABLE      2
   97 #define WSKBD_MUTE_ENABLE       3
   98 };
   99 
  100 int wskbd_set_mixervolume_unit(int, long, long);
  101 #endif
  102 
  103 /*
  104  * event indicating that a control was changed
  105  */
  106 struct mixer_ev {
  107         struct mixer_ev *next;
  108         int pending;
  109 };
  110 
  111 /*
  112  * device structure
  113  */
  114 struct audio_softc {
  115         struct device dev;
  116         const struct audio_hw_if *ops;  /* driver funcs */
  117         void *cookie;                   /* wskbd cookie */
  118         void *arg;                      /* first arg to driver funcs */
  119         int mode;                       /* bitmask of AUMODE_* */
  120         int quiesce;                    /* device suspended */
  121         struct audio_buf play, rec;
  122         unsigned int sw_enc;            /* user exposed AUDIO_ENCODING_* */
  123         unsigned int hw_enc;            /* hardware AUDIO_ENCODING_* */
  124         unsigned int bits;              /* bits per sample */
  125         unsigned int bps;               /* bytes-per-sample */
  126         unsigned int msb;               /* sample are MSB aligned */
  127         unsigned int rate;              /* rate in Hz */
  128         unsigned int round;             /* block size in frames */
  129         unsigned int pchan, rchan;      /* number of channels */
  130         unsigned char silence[4];       /* a sample of silence */
  131         int pause;                      /* not trying to start DMA */
  132         int active;                     /* DMA in process */
  133         int offs;                       /* offset between play & rec dir */
  134         void (*conv_enc)(unsigned char *, int); /* encode to native */
  135         void (*conv_dec)(unsigned char *, int); /* decode to user */
  136         struct mixer_ctrl *mix_ents;    /* mixer state for suspend/resume */
  137         int mix_nent;                   /* size of mixer state */
  138         int mix_isopen;                 /* mixer open for reading */
  139         int mix_blocking;               /* read() blocking */
  140         struct klist mix_klist;         /* list of knotes */
  141         struct mixer_ev *mix_evbuf;     /* per mixer-control event */
  142         struct mixer_ev *mix_pending;   /* list of changed controls */
  143 #if NWSKBD > 0
  144         struct wskbd_vol spkr, mic;
  145         struct task wskbd_task;
  146 #endif
  147         int record_enable;              /* mixer record.enable value */
  148 };
  149 
  150 int audio_match(struct device *, void *, void *);
  151 void audio_attach(struct device *, struct device *, void *);
  152 int audio_activate(struct device *, int);
  153 int audio_detach(struct device *, int);
  154 void audio_pintr(void *);
  155 void audio_rintr(void *);
  156 void audio_buf_wakeup(struct audio_buf *);
  157 void audio_mixer_wakeup(struct audio_softc *);
  158 #if NWSKBD > 0
  159 void wskbd_mixer_init(struct audio_softc *);
  160 void wskbd_mixer_cb(void *);
  161 #endif
  162 
  163 const struct cfattach audio_ca = {
  164         sizeof(struct audio_softc), audio_match, audio_attach,
  165         audio_detach, audio_activate
  166 };
  167 
  168 struct cfdriver audio_cd = {
  169         NULL, "audio", DV_DULL
  170 };
  171 
  172 void filt_audioctlrdetach(struct knote *);
  173 int filt_audioctlread(struct knote *, long);
  174 int filt_audiomodify(struct kevent *, struct knote *);
  175 int filt_audioprocess(struct knote *, struct kevent *);
  176 
  177 const struct filterops audioctlread_filtops = {
  178         .f_flags        = FILTEROP_ISFD | FILTEROP_MPSAFE,
  179         .f_attach       = NULL,
  180         .f_detach       = filt_audioctlrdetach,
  181         .f_event        = filt_audioctlread,
  182         .f_modify       = filt_audiomodify,
  183         .f_process      = filt_audioprocess,
  184 };
  185 
  186 void filt_audiowdetach(struct knote *);
  187 int filt_audiowrite(struct knote *, long);
  188 
  189 const struct filterops audiowrite_filtops = {
  190         .f_flags        = FILTEROP_ISFD | FILTEROP_MPSAFE,
  191         .f_attach       = NULL,
  192         .f_detach       = filt_audiowdetach,
  193         .f_event        = filt_audiowrite,
  194         .f_modify       = filt_audiomodify,
  195         .f_process      = filt_audioprocess,
  196 };
  197 
  198 void filt_audiordetach(struct knote *);
  199 int filt_audioread(struct knote *, long);
  200 
  201 const struct filterops audioread_filtops = {
  202         .f_flags        = FILTEROP_ISFD | FILTEROP_MPSAFE,
  203         .f_attach       = NULL,
  204         .f_detach       = filt_audiordetach,
  205         .f_event        = filt_audioread,
  206         .f_modify       = filt_audiomodify,
  207         .f_process      = filt_audioprocess,
  208 };
  209 
  210 /*
  211  * This mutex protects data structures (including registers on the
  212  * sound-card) that are manipulated by both the interrupt handler and
  213  * syscall code-paths.
  214  *
  215  * Note that driver methods may sleep (e.g. in malloc); consequently the
  216  * audio layer calls them with the mutex unlocked. Driver methods are
  217  * responsible for locking the mutex when they manipulate data used by
  218  * the interrupt handler and interrupts may occur.
  219  *
  220  * Similarly, the driver is responsible for locking the mutex in its
  221  * interrupt handler and to call the audio layer call-backs (i.e.
  222  * audio_{p,r}int()) with the mutex locked.
  223  */
  224 struct mutex audio_lock = MUTEX_INITIALIZER(IPL_AUDIO);
  225 
  226 /*
  227  * Global flag to control if audio recording is enabled when the
  228  * mixerctl setting is record.enable=sysctl
  229  */
  230 int audio_record_enable = 0;
  231 
  232 #ifdef AUDIO_DEBUG
  233 /*
  234  * 0 - nothing, as if AUDIO_DEBUG isn't defined
  235  * 1 - initialisations & setup
  236  * 2 - blocks & interrupts
  237  */
  238 int audio_debug = 1;
  239 #endif
  240 
  241 unsigned int
  242 audio_gcd(unsigned int a, unsigned int b)
  243 {
  244         unsigned int r;
  245 
  246         while (b > 0) {
  247                 r = a % b;
  248                 a = b;
  249                 b = r;
  250         }
  251         return a;
  252 }
  253 
  254 /*
  255  * Calculate the least block size (in frames) such that both the
  256  * corresponding play and/or record block sizes (in bytes) are multiple
  257  * of the given number of bytes.
  258  */
  259 int
  260 audio_blksz_bytes(int mode,
  261         struct audio_params *p, struct audio_params *r, int bytes)
  262 {
  263         unsigned int np, nr;
  264 
  265         if (mode & AUMODE_PLAY) {
  266                 np = bytes / audio_gcd(p->bps * p->channels, bytes);
  267                 if (!(mode & AUMODE_RECORD))
  268                         nr = np;
  269         }
  270         if (mode & AUMODE_RECORD) {
  271                 nr = bytes / audio_gcd(r->bps * r->channels, bytes);
  272                 if (!(mode & AUMODE_PLAY))
  273                         np = nr;
  274         }
  275 
  276         return nr * np / audio_gcd(nr, np);
  277 }
  278 
  279 void
  280 audio_mixer_wakeup(struct audio_softc *sc)
  281 {
  282         MUTEX_ASSERT_LOCKED(&audio_lock);
  283 
  284         if (sc->mix_blocking) {
  285                 wakeup(&sc->mix_blocking);
  286                 sc->mix_blocking = 0;
  287         }
  288         KNOTE(&sc->mix_klist, 0);
  289 }
  290 
  291 void
  292 audio_buf_wakeup(struct audio_buf *buf)
  293 {
  294         MUTEX_ASSERT_LOCKED(&audio_lock);
  295 
  296         if (buf->blocking) {
  297                 wakeup(&buf->blocking);
  298                 buf->blocking = 0;
  299         }
  300         KNOTE(&buf->klist, 0);
  301 }
  302 
  303 int
  304 audio_buf_init(struct audio_softc *sc, struct audio_buf *buf, int dir)
  305 {
  306         klist_init_mutex(&buf->klist, &audio_lock);
  307         if (sc->ops->round_buffersize) {
  308                 buf->datalen = sc->ops->round_buffersize(sc->arg,
  309                     dir, AUDIO_BUFSZ);
  310         } else
  311                 buf->datalen = AUDIO_BUFSZ;
  312         if (sc->ops->allocm) {
  313                 buf->data = sc->ops->allocm(sc->arg, dir, buf->datalen,
  314                     M_DEVBUF, M_WAITOK);
  315         } else
  316                 buf->data = malloc(buf->datalen, M_DEVBUF, M_WAITOK);
  317         if (buf->data == NULL) {
  318                 klist_free(&buf->klist);
  319                 return ENOMEM;
  320         }
  321         return 0;
  322 }
  323 
  324 void
  325 audio_buf_done(struct audio_softc *sc, struct audio_buf *buf)
  326 {
  327         if (sc->ops->freem)
  328                 sc->ops->freem(sc->arg, buf->data, M_DEVBUF);
  329         else
  330                 free(buf->data, M_DEVBUF, buf->datalen);
  331         klist_free(&buf->klist);
  332 }
  333 
  334 /*
  335  * return the reader pointer and the number of bytes available
  336  */
  337 unsigned char *
  338 audio_buf_rgetblk(struct audio_buf *buf, size_t *rsize)
  339 {
  340         size_t count;
  341 
  342         count = buf->len - buf->start;
  343         if (count > buf->used)
  344                 count = buf->used;
  345         *rsize = count;
  346         return buf->data + buf->start;
  347 }
  348 
  349 /*
  350  * discard "count" bytes at the start position.
  351  */
  352 void
  353 audio_buf_rdiscard(struct audio_buf *buf, size_t count)
  354 {
  355 #ifdef AUDIO_DEBUG
  356         if (count > buf->used) {
  357                 panic("audio_buf_rdiscard: bad count = %zu, "
  358                     "start = %zu, used = %zu", count, buf->start, buf->used);
  359         }
  360 #endif
  361         buf->used -= count;
  362         buf->start += count;
  363         if (buf->start >= buf->len)
  364                 buf->start -= buf->len;
  365 }
  366 
  367 /*
  368  * advance the writer pointer by "count" bytes
  369  */
  370 void
  371 audio_buf_wcommit(struct audio_buf *buf, size_t count)
  372 {
  373 #ifdef AUDIO_DEBUG
  374         if (count > (buf->len - buf->used)) {
  375                 panic("audio_buf_wcommit: bad count = %zu, "
  376                     "start = %zu, used = %zu", count, buf->start, buf->used);
  377         }
  378 #endif
  379         buf->used += count;
  380 }
  381 
  382 /*
  383  * get writer pointer and the number of bytes writable
  384  */
  385 unsigned char *
  386 audio_buf_wgetblk(struct audio_buf *buf, size_t *rsize)
  387 {
  388         size_t end, avail, count;
  389 
  390         end = buf->start + buf->used;
  391         if (end >= buf->len)
  392                 end -= buf->len;
  393         avail = buf->len - buf->used;
  394         count = buf->len - end;
  395         if (count > avail)
  396                 count = avail;
  397         *rsize = count;
  398         return buf->data + end;
  399 }
  400 
  401 void
  402 audio_calc_sil(struct audio_softc *sc)
  403 {
  404         unsigned char *q;
  405         unsigned int s, i;
  406         int d, e;
  407 
  408         e = sc->sw_enc;
  409 #ifdef AUDIO_DEBUG
  410         switch (e) {
  411         case AUDIO_ENCODING_SLINEAR_LE:
  412         case AUDIO_ENCODING_ULINEAR_LE:
  413         case AUDIO_ENCODING_SLINEAR_BE:
  414         case AUDIO_ENCODING_ULINEAR_BE:
  415                 break;
  416         default:
  417                 printf("%s: unhandled play encoding %d\n", DEVNAME(sc), e);
  418                 memset(sc->silence, 0, sc->bps);
  419                 return;
  420         }
  421 #endif
  422         if (e == AUDIO_ENCODING_SLINEAR_BE || e == AUDIO_ENCODING_ULINEAR_BE) {
  423                 d = -1;
  424                 q = sc->silence + sc->bps - 1;
  425         } else {
  426                 d = 1;
  427                 q = sc->silence;
  428         }
  429         if (e == AUDIO_ENCODING_SLINEAR_LE || e == AUDIO_ENCODING_SLINEAR_BE) {
  430                 s = 0;
  431         } else {
  432                 s = 0x80000000;
  433                 if (sc->msb)
  434                         s >>= 32 - 8 * sc->bps;
  435                 else
  436                         s >>= 32 - sc->bits;
  437         }
  438         for (i = 0; i < sc->bps; i++) {
  439                 *q = s;
  440                 q += d;
  441                 s >>= 8;
  442         }
  443         if (sc->conv_enc)
  444                 sc->conv_enc(sc->silence, sc->bps);
  445 }
  446 
  447 void
  448 audio_fill_sil(struct audio_softc *sc, unsigned char *ptr, size_t count)
  449 {
  450         unsigned char *q, *p;
  451         size_t i, j;
  452 
  453         q = ptr;
  454         for (j = count / sc->bps; j > 0; j--) {
  455                 p = sc->silence;
  456                 for (i = sc->bps; i > 0; i--)
  457                         *q++ = *p++;
  458         }
  459 }
  460 
  461 void
  462 audio_clear(struct audio_softc *sc)
  463 {
  464         if (sc->mode & AUMODE_PLAY) {
  465                 sc->play.used = sc->play.start = 0;
  466                 sc->play.pos = sc->play.xrun = 0;
  467                 audio_fill_sil(sc, sc->play.data, sc->play.len);
  468         }
  469         if (sc->mode & AUMODE_RECORD) {
  470                 sc->rec.used = sc->rec.start = 0;
  471                 sc->rec.pos = sc->rec.xrun = 0;
  472                 audio_fill_sil(sc, sc->rec.data, sc->rec.len);
  473         }
  474 }
  475 
  476 /*
  477  * called whenever a block is consumed by the driver
  478  */
  479 void
  480 audio_pintr(void *addr)
  481 {
  482         struct audio_softc *sc = addr;
  483         unsigned char *ptr;
  484         size_t count;
  485         int error, nblk, todo;
  486 
  487         MUTEX_ASSERT_LOCKED(&audio_lock);
  488         if (!(sc->mode & AUMODE_PLAY) || !sc->active) {
  489                 printf("%s: play interrupt but not playing\n", DEVNAME(sc));
  490                 return;
  491         }
  492         if (sc->quiesce) {
  493                 DPRINTF("%s: quiesced, skipping play intr\n", DEVNAME(sc));
  494                 return;
  495         }
  496 
  497         /*
  498          * check if record pointer wrapped, see explanation
  499          * in audio_rintr()
  500          */
  501         if ((sc->mode & AUMODE_RECORD) && sc->ops->underrun == NULL) {
  502                 sc->offs--;
  503                 nblk = sc->rec.len / sc->rec.blksz;
  504                 todo = -sc->offs;
  505                 if (todo >= nblk) {
  506                         todo -= todo % nblk;
  507                         DPRINTFN(1, "%s: rec ptr wrapped, moving %d blocks\n",
  508                             DEVNAME(sc), todo);
  509                         while (todo-- > 0)
  510                                 audio_rintr(sc);
  511                 }
  512         }
  513 
  514         sc->play.pos += sc->play.blksz;
  515         if (!sc->ops->underrun) {
  516                 audio_fill_sil(sc, sc->play.data + sc->play.start,
  517                     sc->play.blksz);
  518         }
  519         audio_buf_rdiscard(&sc->play, sc->play.blksz);
  520         if (sc->play.used < sc->play.blksz) {
  521                 DPRINTFN(1, "%s: play underrun\n", DEVNAME(sc));
  522                 sc->play.xrun += sc->play.blksz;
  523                 audio_buf_wcommit(&sc->play, sc->play.blksz);
  524                 if (sc->ops->underrun)
  525                         sc->ops->underrun(sc->arg);
  526         }
  527 
  528         DPRINTFN(1, "%s: play intr, used -> %zu, start -> %zu\n",
  529             DEVNAME(sc), sc->play.used, sc->play.start);
  530 
  531         if (!sc->ops->trigger_output) {
  532                 ptr = audio_buf_rgetblk(&sc->play, &count);
  533                 error = sc->ops->start_output(sc->arg,
  534                     ptr, sc->play.blksz, audio_pintr, sc);
  535                 if (error) {
  536                         printf("%s: play restart failed: %d\n",
  537                             DEVNAME(sc), error);
  538                 }
  539         }
  540 
  541         if (sc->play.used < sc->play.len) {
  542                 DPRINTFN(1, "%s: play wakeup, chan = %d\n",
  543                     DEVNAME(sc), sc->play.blocking);
  544                 audio_buf_wakeup(&sc->play);
  545         }
  546 }
  547 
  548 /*
  549  * called whenever a block is produced by the driver
  550  */
  551 void
  552 audio_rintr(void *addr)
  553 {
  554         struct audio_softc *sc = addr;
  555         unsigned char *ptr;
  556         size_t count;
  557         int error, nblk, todo;
  558 
  559         MUTEX_ASSERT_LOCKED(&audio_lock);
  560         if (!(sc->mode & AUMODE_RECORD) || !sc->active) {
  561                 printf("%s: rec interrupt but not recording\n", DEVNAME(sc));
  562                 return;
  563         }
  564         if (sc->quiesce) {
  565                 DPRINTF("%s: quiesced, skipping rec intr\n", DEVNAME(sc));
  566                 return;
  567         }
  568 
  569         /*
  570          * Interrupts may be masked by other sub-systems during 320ms
  571          * and more. During such a delay the hardware doesn't stop
  572          * playing and the play buffer pointers may wrap, this can't be
  573          * detected and corrected by low level drivers. This makes the
  574          * record stream ahead of the play stream; this is detected as a
  575          * hardware anomaly by userland and cause programs to misbehave.
  576          *
  577          * We fix this by advancing play position by an integer count of
  578          * full buffers, so it reaches the record position.
  579          */
  580         if ((sc->mode & AUMODE_PLAY) && sc->ops->underrun == NULL) {
  581                 sc->offs++;
  582                 nblk = sc->play.len / sc->play.blksz;
  583                 todo = sc->offs;
  584                 if (todo >= nblk) {
  585                         todo -= todo % nblk;
  586                         DPRINTFN(1, "%s: play ptr wrapped, moving %d blocks\n",
  587                             DEVNAME(sc), todo);
  588                         while (todo-- > 0)
  589                                 audio_pintr(sc);
  590                 }
  591         }
  592 
  593         sc->rec.pos += sc->rec.blksz;
  594         if ((sc->record_enable == MIXER_RECORD_ENABLE_SYSCTL &&
  595             !audio_record_enable) ||
  596             sc->record_enable == MIXER_RECORD_ENABLE_OFF) {
  597                 ptr = audio_buf_wgetblk(&sc->rec, &count);
  598                 audio_fill_sil(sc, ptr, sc->rec.blksz);
  599         }
  600         audio_buf_wcommit(&sc->rec, sc->rec.blksz);
  601         if (sc->rec.used > sc->rec.len - sc->rec.blksz) {
  602                 DPRINTFN(1, "%s: rec overrun\n", DEVNAME(sc));
  603                 sc->rec.xrun += sc->rec.blksz;
  604                 audio_buf_rdiscard(&sc->rec, sc->rec.blksz);
  605         }
  606         DPRINTFN(1, "%s: rec intr, used -> %zu\n", DEVNAME(sc), sc->rec.used);
  607 
  608         if (!sc->ops->trigger_input) {
  609                 ptr = audio_buf_wgetblk(&sc->rec, &count);
  610                 error = sc->ops->start_input(sc->arg,
  611                     ptr, sc->rec.blksz, audio_rintr, sc);
  612                 if (error) {
  613                         printf("%s: rec restart failed: %d\n",
  614                             DEVNAME(sc), error);
  615                 }
  616         }
  617 
  618         if (sc->rec.used > 0) {
  619                 DPRINTFN(1, "%s: rec wakeup, chan = %d\n",
  620                     DEVNAME(sc), sc->rec.blocking);
  621                 audio_buf_wakeup(&sc->rec);
  622         }
  623 }
  624 
  625 int
  626 audio_start_do(struct audio_softc *sc)
  627 {
  628         int error;
  629         struct audio_params p;
  630         unsigned char *ptr;
  631         size_t count;
  632 
  633         DPRINTF("%s: starting\n", DEVNAME(sc));
  634 
  635         error = 0;
  636         sc->offs = 0;
  637         if (sc->mode & AUMODE_PLAY) {
  638                 if (sc->ops->trigger_output) {
  639                         p.encoding = sc->hw_enc;
  640                         p.precision = sc->bits;
  641                         p.bps = sc->bps;
  642                         p.msb = sc->msb;
  643                         p.sample_rate = sc->rate;
  644                         p.channels = sc->pchan;
  645                         error = sc->ops->trigger_output(sc->arg,
  646                             sc->play.data,
  647                             sc->play.data + sc->play.len,
  648                             sc->play.blksz,
  649                             audio_pintr, sc, &p);
  650                 } else {
  651                         mtx_enter(&audio_lock);
  652                         ptr = audio_buf_rgetblk(&sc->play, &count);
  653                         error = sc->ops->start_output(sc->arg,
  654                             ptr, sc->play.blksz, audio_pintr, sc);
  655                         mtx_leave(&audio_lock);
  656                 }
  657                 if (error)
  658                         printf("%s: failed to start playback\n", DEVNAME(sc));
  659         }
  660         if (sc->mode & AUMODE_RECORD) {
  661                 if (sc->ops->trigger_input) {
  662                         p.encoding = sc->hw_enc;
  663                         p.precision = sc->bits;
  664                         p.bps = sc->bps;
  665                         p.msb = sc->msb;
  666                         p.sample_rate = sc->rate;
  667                         p.channels = sc->rchan;
  668                         error = sc->ops->trigger_input(sc->arg,
  669                             sc->rec.data,
  670                             sc->rec.data + sc->rec.len,
  671                             sc->rec.blksz,
  672                             audio_rintr, sc, &p);
  673                 } else {
  674                         mtx_enter(&audio_lock);
  675                         ptr = audio_buf_wgetblk(&sc->rec, &count);
  676                         error = sc->ops->start_input(sc->arg,
  677                             ptr, sc->rec.blksz, audio_rintr, sc);
  678                         mtx_leave(&audio_lock);
  679                 }
  680                 if (error)
  681                         printf("%s: failed to start recording\n", DEVNAME(sc));
  682         }
  683         return error;
  684 }
  685 
  686 int
  687 audio_stop_do(struct audio_softc *sc)
  688 {
  689         if (sc->mode & AUMODE_PLAY)
  690                 sc->ops->halt_output(sc->arg);
  691         if (sc->mode & AUMODE_RECORD)
  692                 sc->ops->halt_input(sc->arg);
  693         DPRINTF("%s: stopped\n", DEVNAME(sc));
  694         return 0;
  695 }
  696 
  697 int
  698 audio_start(struct audio_softc *sc)
  699 {
  700         sc->active = 1;
  701         sc->play.xrun = sc->play.pos = sc->rec.xrun = sc->rec.pos = 0;
  702         return audio_start_do(sc);
  703 }
  704 
  705 int
  706 audio_stop(struct audio_softc *sc)
  707 {
  708         int error;
  709 
  710         error = audio_stop_do(sc);
  711         if (error)
  712                 return error;
  713         audio_clear(sc);
  714         sc->active = 0;
  715         return 0;
  716 }
  717 
  718 int
  719 audio_canstart(struct audio_softc *sc)
  720 {
  721         if (sc->active || sc->pause)
  722                 return 0;
  723         if ((sc->mode & AUMODE_RECORD) && sc->rec.used != 0)
  724                 return 0;
  725         if ((sc->mode & AUMODE_PLAY) && sc->play.used != sc->play.len)
  726                 return 0;
  727         return 1;
  728 }
  729 
  730 int
  731 audio_setpar_blksz(struct audio_softc *sc,
  732     struct audio_params *p, struct audio_params *r)
  733 {
  734         unsigned int nr, np, max, min, mult;
  735         unsigned int blk_mult, blk_max;
  736 
  737         if (sc->ops->set_blksz) {
  738                 /*
  739                  * Don't allow block size of exceed half the buffer size
  740                  */
  741                 if (sc->mode & AUMODE_PLAY) {
  742                         max = sc->play.datalen / 2 / (sc->pchan * sc->bps);
  743                         if (sc->round > max)
  744                                 sc->round = max;
  745                 }
  746                 if (sc->mode & AUMODE_RECORD) {
  747                         max = sc->rec.datalen / 2 / (sc->rchan * sc->bps);
  748                         if (sc->round > max)
  749                                 sc->round = max;
  750                 }
  751 
  752                 sc->round = sc->ops->set_blksz(sc->arg, sc->mode,
  753                     p, r, sc->round);
  754 
  755                 DPRINTF("%s: block size set to: %u\n", DEVNAME(sc), sc->round);
  756                 return 0;
  757         }
  758 
  759         /*
  760          * get least multiplier of the number of frames per block
  761          */
  762         if (sc->ops->round_blocksize) {
  763                 blk_mult = sc->ops->round_blocksize(sc->arg, 1);
  764                 if (blk_mult == 0) {
  765                         printf("%s: 0x%x: bad block size multiplier\n",
  766                             DEVNAME(sc), blk_mult);
  767                         return ENODEV;
  768                 }
  769         } else
  770                 blk_mult = 1;
  771         DPRINTF("%s: hw block size multiplier: %u\n", DEVNAME(sc), blk_mult);
  772         if (sc->mode & AUMODE_PLAY) {
  773                 np = blk_mult / audio_gcd(sc->pchan * sc->bps, blk_mult);
  774                 if (!(sc->mode & AUMODE_RECORD))
  775                         nr = np;
  776                 DPRINTF("%s: play number of frames multiplier: %u\n",
  777                     DEVNAME(sc), np);
  778         }
  779         if (sc->mode & AUMODE_RECORD) {
  780                 nr = blk_mult / audio_gcd(sc->rchan * sc->bps, blk_mult);
  781                 if (!(sc->mode & AUMODE_PLAY))
  782                         np = nr;
  783                 DPRINTF("%s: record number of frames multiplier: %u\n",
  784                     DEVNAME(sc), nr);
  785         }
  786         mult = nr * np / audio_gcd(nr, np);
  787         DPRINTF("%s: least common number of frames multiplier: %u\n",
  788             DEVNAME(sc), mult);
  789 
  790         /*
  791          * get minimum and maximum frames per block
  792          */
  793         if (sc->ops->round_blocksize)
  794                 blk_max = sc->ops->round_blocksize(sc->arg, AUDIO_BUFSZ);
  795         else
  796                 blk_max = AUDIO_BUFSZ;
  797         if ((sc->mode & AUMODE_PLAY) && blk_max > sc->play.datalen / 2)
  798                 blk_max = sc->play.datalen / 2;
  799         if ((sc->mode & AUMODE_RECORD) && blk_max > sc->rec.datalen / 2)
  800                 blk_max = sc->rec.datalen / 2;
  801         if (sc->mode & AUMODE_PLAY) {
  802                 np = blk_max / (sc->pchan * sc->bps);
  803                 if (!(sc->mode & AUMODE_RECORD))
  804                         nr = np;
  805         }
  806         if (sc->mode & AUMODE_RECORD) {
  807                 nr = blk_max / (sc->rchan * sc->bps);
  808                 if (!(sc->mode & AUMODE_PLAY))
  809                         np = nr;
  810         }
  811         max = np < nr ? np : nr;
  812         max -= max % mult;
  813         min = sc->rate / 1000 + mult - 1;
  814         min -= min % mult;
  815         DPRINTF("%s: frame number range: %u..%u\n", DEVNAME(sc), min, max);
  816         if (max < min) {
  817                 printf("%s: %u: bad max frame number\n", DEVNAME(sc), max);
  818                 return EIO;
  819         }
  820 
  821         /*
  822          * adjust the frame per block to match our constraints
  823          */
  824         sc->round += mult / 2;
  825         sc->round -= sc->round % mult;
  826         if (sc->round > max)
  827                 sc->round = max;
  828         else if (sc->round < min)
  829                 sc->round = min;
  830 
  831         return 0;
  832 }
  833 
  834 int
  835 audio_setpar_nblks(struct audio_softc *sc,
  836     struct audio_params *p, struct audio_params *r)
  837 {
  838         unsigned int max;
  839 
  840         /*
  841          * set buffer size (number of blocks)
  842          */
  843         if (sc->mode & AUMODE_PLAY) {
  844                 max = sc->play.datalen / (sc->round * sc->pchan * sc->bps);
  845                 if (sc->play.nblks > max)
  846                         sc->play.nblks = max;
  847                 else if (sc->play.nblks < 2)
  848                         sc->play.nblks = 2;
  849                 if (sc->ops->set_nblks) {
  850                         sc->play.nblks = sc->ops->set_nblks(sc->arg, sc->mode,
  851                             p, sc->round, sc->play.nblks);
  852                         DPRINTF("%s: play nblks -> %u\n", DEVNAME(sc),
  853                             sc->play.nblks);
  854                 }
  855         }
  856         if (sc->mode & AUMODE_RECORD) {
  857                 /*
  858                  * for recording, buffer size is not the latency (it's
  859                  * exactly one block), so let's get the maximum buffer
  860                  * size of maximum reliability during xruns
  861                  */
  862                 max = sc->rec.datalen / (sc->round * sc->rchan * sc->bps);
  863                 if (sc->ops->set_nblks) {
  864                         max = sc->ops->set_nblks(sc->arg, sc->mode,
  865                             r, sc->round, max);
  866                         DPRINTF("%s: rec nblks -> %u\n", DEVNAME(sc), max);
  867                 }
  868                 sc->rec.nblks = max;
  869         }
  870         return 0;
  871 }
  872 
  873 int
  874 audio_setpar(struct audio_softc *sc)
  875 {
  876         struct audio_params p, r;
  877         int error;
  878 
  879         DPRINTF("%s: setpar: req enc=%d bits=%d, bps=%d, msb=%d "
  880             "rate=%d, pchan=%d, rchan=%d, round=%u, nblks=%d\n",
  881             DEVNAME(sc), sc->sw_enc, sc->bits, sc->bps, sc->msb,
  882             sc->rate, sc->pchan, sc->rchan, sc->round, sc->play.nblks);
  883 
  884         /*
  885          * check if requested parameters are in the allowed ranges
  886          */
  887         if (sc->mode & AUMODE_PLAY) {
  888                 if (sc->pchan < 1)
  889                         sc->pchan = 1;
  890                 else if (sc->pchan > 64)
  891                         sc->pchan = 64;
  892         }
  893         if (sc->mode & AUMODE_RECORD) {
  894                 if (sc->rchan < 1)
  895                         sc->rchan = 1;
  896                 else if (sc->rchan > 64)
  897                         sc->rchan = 64;
  898         }
  899         switch (sc->sw_enc) {
  900         case AUDIO_ENCODING_ULAW:
  901         case AUDIO_ENCODING_ALAW:
  902         case AUDIO_ENCODING_SLINEAR_LE:
  903         case AUDIO_ENCODING_SLINEAR_BE:
  904         case AUDIO_ENCODING_ULINEAR_LE:
  905         case AUDIO_ENCODING_ULINEAR_BE:
  906                 break;
  907         default:
  908                 sc->sw_enc = AUDIO_ENCODING_SLINEAR_LE;
  909         }
  910         if (sc->bits < 8)
  911                 sc->bits = 8;
  912         else if (sc->bits > 32)
  913                 sc->bits = 32;
  914         if (sc->bps < 1)
  915                 sc->bps = 1;
  916         else if (sc->bps > 4)
  917                 sc->bps = 4;
  918         if (sc->rate < 4000)
  919                 sc->rate = 4000;
  920         else if (sc->rate > 192000)
  921                 sc->rate = 192000;
  922 
  923         /*
  924          * copy into struct audio_params, required by drivers
  925          */
  926         p.encoding = r.encoding = sc->sw_enc;
  927         p.precision = r.precision = sc->bits;
  928         p.bps = r.bps = sc->bps;
  929         p.msb = r.msb = sc->msb;
  930         p.sample_rate = r.sample_rate = sc->rate;
  931         p.channels = sc->pchan;
  932         r.channels = sc->rchan;
  933 
  934         /*
  935          * set parameters
  936          */
  937         error = sc->ops->set_params(sc->arg, sc->mode, sc->mode, &p, &r);
  938         if (error)
  939                 return error;
  940         if (sc->mode == (AUMODE_PLAY | AUMODE_RECORD)) {
  941                 if (p.encoding != r.encoding ||
  942                     p.precision != r.precision ||
  943                     p.bps != r.bps ||
  944                     p.msb != r.msb ||
  945                     p.sample_rate != r.sample_rate) {
  946                         printf("%s: different play and record parameters "
  947                             "returned by hardware\n", DEVNAME(sc));
  948                         return ENODEV;
  949                 }
  950         }
  951         if (sc->mode & AUMODE_PLAY) {
  952                 sc->hw_enc = p.encoding;
  953                 sc->bits = p.precision;
  954                 sc->bps = p.bps;
  955                 sc->msb = p.msb;
  956                 sc->rate = p.sample_rate;
  957                 sc->pchan = p.channels;
  958         }
  959         if (sc->mode & AUMODE_RECORD) {
  960                 sc->hw_enc = r.encoding;
  961                 sc->bits = r.precision;
  962                 sc->bps = r.bps;
  963                 sc->msb = r.msb;
  964                 sc->rate = r.sample_rate;
  965                 sc->rchan = r.channels;
  966         }
  967         if (sc->rate == 0 || sc->bps == 0 || sc->bits == 0) {
  968                 printf("%s: invalid parameters returned by hardware\n",
  969                     DEVNAME(sc));
  970                 return ENODEV;
  971         }
  972         if (sc->ops->commit_settings) {
  973                 error = sc->ops->commit_settings(sc->arg);
  974                 if (error)
  975                         return error;
  976         }
  977 
  978         /*
  979          * conversion from/to exotic/dead encoding, for drivers not supporting
  980          * linear
  981          */
  982         switch (sc->hw_enc) {
  983         case AUDIO_ENCODING_SLINEAR_LE:
  984         case AUDIO_ENCODING_SLINEAR_BE:
  985         case AUDIO_ENCODING_ULINEAR_LE:
  986         case AUDIO_ENCODING_ULINEAR_BE:
  987                 sc->sw_enc = sc->hw_enc;
  988                 sc->conv_dec = sc->conv_enc = NULL;
  989                 break;
  990         case AUDIO_ENCODING_ULAW:
  991 #if BYTE_ORDER == LITTLE_ENDIAN
  992                 sc->sw_enc = AUDIO_ENCODING_SLINEAR_LE;
  993 #else
  994                 sc->sw_enc = AUDIO_ENCODING_SLINEAR_BE;
  995 #endif
  996                 if (sc->bits == 8) {
  997                         sc->conv_enc = slinear8_to_mulaw;
  998                         sc->conv_dec = mulaw_to_slinear8;
  999                 } else if (sc->bits == 24) {
 1000                         sc->conv_enc = slinear24_to_mulaw24;
 1001                         sc->conv_dec = mulaw24_to_slinear24;
 1002                 } else {
 1003                         sc->sw_enc = sc->hw_enc;
 1004                         sc->conv_dec = sc->conv_enc = NULL;
 1005                 }
 1006                 break;
 1007         default:
 1008                 printf("%s: setpar: enc = %d, bits = %d: emulation skipped\n",
 1009                     DEVNAME(sc), sc->hw_enc, sc->bits);
 1010                 sc->sw_enc = sc->hw_enc;
 1011                 sc->conv_dec = sc->conv_enc = NULL;
 1012         }
 1013         audio_calc_sil(sc);
 1014 
 1015         error = audio_setpar_blksz(sc, &p, &r);
 1016         if (error)
 1017                 return error;
 1018 
 1019         error = audio_setpar_nblks(sc, &p, &r);
 1020         if (error)
 1021                 return error;
 1022 
 1023         /*
 1024          * set buffer
 1025          */
 1026         if (sc->mode & AUMODE_PLAY) {
 1027                 sc->play.blksz = sc->round * sc->pchan * sc->bps;
 1028                 sc->play.len = sc->play.nblks * sc->play.blksz;
 1029         }
 1030         if (sc->mode & AUMODE_RECORD) {
 1031                 sc->rec.blksz = sc->round * sc->rchan * sc->bps;
 1032                 sc->rec.len = sc->rec.nblks * sc->rec.blksz;
 1033         }
 1034 
 1035         DPRINTF("%s: setpar: new enc=%d bits=%d, bps=%d, msb=%d "
 1036             "rate=%d, pchan=%d, rchan=%d, round=%u, nblks=%d\n",
 1037             DEVNAME(sc), sc->sw_enc, sc->bits, sc->bps, sc->msb,
 1038             sc->rate, sc->pchan, sc->rchan, sc->round, sc->play.nblks);
 1039         return 0;
 1040 }
 1041 
 1042 int
 1043 audio_ioc_start(struct audio_softc *sc)
 1044 {
 1045         if (!sc->pause) {
 1046                 DPRINTF("%s: can't start: already started\n", DEVNAME(sc));
 1047                 return EBUSY;
 1048         }
 1049         if ((sc->mode & AUMODE_PLAY) && sc->play.used != sc->play.len) {
 1050                 DPRINTF("%s: play buffer not ready\n", DEVNAME(sc));
 1051                 return EBUSY;
 1052         }
 1053         if ((sc->mode & AUMODE_RECORD) && sc->rec.used != 0) {
 1054                 DPRINTF("%s: record buffer not ready\n", DEVNAME(sc));
 1055                 return EBUSY;
 1056         }
 1057         sc->pause = 0;
 1058         return audio_start(sc);
 1059 }
 1060 
 1061 int
 1062 audio_ioc_stop(struct audio_softc *sc)
 1063 {
 1064         if (sc->pause) {
 1065                 DPRINTF("%s: can't stop: not started\n", DEVNAME(sc));
 1066                 return EBUSY;
 1067         }
 1068         sc->pause = 1;
 1069         if (sc->active)
 1070                 return audio_stop(sc);
 1071         return 0;
 1072 }
 1073 
 1074 int
 1075 audio_ioc_getpar(struct audio_softc *sc, struct audio_swpar *p)
 1076 {
 1077         p->rate = sc->rate;
 1078         p->sig = sc->sw_enc == AUDIO_ENCODING_SLINEAR_LE ||
 1079             sc->sw_enc == AUDIO_ENCODING_SLINEAR_BE;
 1080         p->le = sc->sw_enc == AUDIO_ENCODING_SLINEAR_LE ||
 1081             sc->sw_enc == AUDIO_ENCODING_ULINEAR_LE;
 1082         p->bits = sc->bits;
 1083         p->bps = sc->bps;
 1084         p->msb = sc->msb;
 1085         p->pchan = sc->pchan;
 1086         p->rchan = sc->rchan;
 1087         p->nblks = sc->play.nblks;
 1088         p->round = sc->round;
 1089         return 0;
 1090 }
 1091 
 1092 int
 1093 audio_ioc_setpar(struct audio_softc *sc, struct audio_swpar *p)
 1094 {
 1095         int error, le, sig;
 1096 
 1097         if (sc->active) {
 1098                 DPRINTF("%s: can't change params during dma\n",
 1099                     DEVNAME(sc));
 1100                 return EBUSY;
 1101         }
 1102 
 1103         /*
 1104          * copy desired parameters into the softc structure
 1105          */
 1106         if (p->sig != ~0U || p->le != ~0U || p->bits != ~0U) {
 1107                 sig = 1;
 1108                 le = (BYTE_ORDER == LITTLE_ENDIAN);
 1109                 sc->bits = 16;
 1110                 sc->bps = 2;
 1111                 sc->msb = 1;
 1112                 if (p->sig != ~0U)
 1113                         sig = p->sig;
 1114                 if (p->le != ~0U)
 1115                         le = p->le;
 1116                 if (p->bits != ~0U) {
 1117                         sc->bits = p->bits;
 1118                         sc->bps = sc->bits <= 8 ?
 1119                             1 : (sc->bits <= 16 ? 2 : 4);
 1120                         if (p->bps != ~0U)
 1121                                 sc->bps = p->bps;
 1122                         if (p->msb != ~0U)
 1123                                 sc->msb = p->msb ? 1 : 0;
 1124                 }
 1125                 sc->sw_enc = (sig) ?
 1126                     (le ? AUDIO_ENCODING_SLINEAR_LE :
 1127                         AUDIO_ENCODING_SLINEAR_BE) :
 1128                     (le ? AUDIO_ENCODING_ULINEAR_LE :
 1129                         AUDIO_ENCODING_ULINEAR_BE);
 1130         }
 1131         if (p->rate != ~0)
 1132                 sc->rate = p->rate;
 1133         if (p->pchan != ~0)
 1134                 sc->pchan = p->pchan;
 1135         if (p->rchan != ~0)
 1136                 sc->rchan = p->rchan;
 1137         if (p->round != ~0)
 1138                 sc->round = p->round;
 1139         if (p->nblks != ~0)
 1140                 sc->play.nblks = p->nblks;
 1141 
 1142         /*
 1143          * if the device is not opened for playback or recording don't
 1144          * touch the hardware yet (ex. if this is /dev/audioctlN)
 1145          */
 1146         if (sc->mode == 0)
 1147                 return 0;
 1148 
 1149         /*
 1150          * negotiate parameters with the hardware
 1151          */
 1152         error = audio_setpar(sc);
 1153         if (error)
 1154                 return error;
 1155         audio_clear(sc);
 1156         if ((sc->mode & AUMODE_PLAY) && sc->ops->init_output) {
 1157                 error = sc->ops->init_output(sc->arg,
 1158                     sc->play.data, sc->play.len);
 1159                 if (error)
 1160                         return error;
 1161         }
 1162         if ((sc->mode & AUMODE_RECORD) && sc->ops->init_input) {
 1163                 error = sc->ops->init_input(sc->arg,
 1164                     sc->rec.data, sc->rec.len);
 1165                 if (error)
 1166                         return error;
 1167         }
 1168         return 0;
 1169 }
 1170 
 1171 int
 1172 audio_ioc_getstatus(struct audio_softc *sc, struct audio_status *p)
 1173 {
 1174         p->mode = sc->mode;
 1175         p->pause = sc->pause;
 1176         p->active = sc->active;
 1177         return 0;
 1178 }
 1179 
 1180 int
 1181 audio_match(struct device *parent, void *match, void *aux)
 1182 {
 1183         struct audio_attach_args *sa = aux;
 1184 
 1185         return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
 1186 }
 1187 
 1188 void
 1189 audio_attach(struct device *parent, struct device *self, void *aux)
 1190 {
 1191         struct audio_softc *sc = (void *)self;
 1192         struct audio_attach_args *sa = aux;
 1193         const struct audio_hw_if *ops = sa->hwif;
 1194         struct mixer_devinfo *mi;
 1195         struct mixer_ctrl *ent;
 1196         void *arg = sa->hdl;
 1197         int error;
 1198 
 1199         printf("\n");
 1200 
 1201 #ifdef DIAGNOSTIC
 1202         if (ops == 0 ||
 1203             ops->open == 0 ||
 1204             ops->close == 0 ||
 1205             ops->set_params == 0 ||
 1206             (ops->start_output == 0 && ops->trigger_output == 0) ||
 1207             (ops->start_input == 0 && ops->trigger_input == 0) ||
 1208             ops->halt_output == 0 ||
 1209             ops->halt_input == 0 ||
 1210             ops->set_port == 0 ||
 1211             ops->get_port == 0 ||
 1212             ops->query_devinfo == 0) {
 1213                 printf("%s: missing method\n", DEVNAME(sc));
 1214                 sc->ops = 0;
 1215                 return;
 1216         }
 1217 #endif
 1218         sc->ops = ops;
 1219         sc->cookie = sa->cookie;
 1220         sc->arg = arg;
 1221 
 1222 #if NWSKBD > 0
 1223         wskbd_mixer_init(sc);
 1224 #endif /* NWSKBD > 0 */
 1225 
 1226         error = audio_buf_init(sc, &sc->play, AUMODE_PLAY);
 1227         if (error) {
 1228                 sc->ops = 0;
 1229                 printf("%s: could not allocate play buffer\n", DEVNAME(sc));
 1230                 return;
 1231         }
 1232         error = audio_buf_init(sc, &sc->rec, AUMODE_RECORD);
 1233         if (error) {
 1234                 audio_buf_done(sc, &sc->play);
 1235                 sc->ops = 0;
 1236                 printf("%s: could not allocate record buffer\n", DEVNAME(sc));
 1237                 return;
 1238         }
 1239 
 1240         klist_init_mutex(&sc->mix_klist, &audio_lock);
 1241 
 1242         /* set defaults */
 1243 #if BYTE_ORDER == LITTLE_ENDIAN
 1244         sc->sw_enc = AUDIO_ENCODING_SLINEAR_LE;
 1245 #else
 1246         sc->sw_enc = AUDIO_ENCODING_SLINEAR_BE;
 1247 #endif
 1248         sc->bits = 16;
 1249         sc->bps = 2;
 1250         sc->msb = 1;
 1251         sc->rate = 48000;
 1252         sc->pchan = 2;
 1253         sc->rchan = 2;
 1254         sc->round = 960;
 1255         sc->play.nblks = 2;
 1256         sc->play.pos = sc->play.xrun = sc->rec.pos = sc->rec.xrun = 0;
 1257         sc->record_enable = MIXER_RECORD_ENABLE_SYSCTL;
 1258 
 1259         /*
 1260          * allocate an array of mixer_ctrl structures to save the
 1261          * mixer state and prefill them.
 1262          */
 1263 
 1264         mi = malloc(sizeof(struct mixer_devinfo), M_TEMP, M_WAITOK);
 1265 
 1266         mi->index = 0;
 1267         while (1) {
 1268                 if (sc->ops->query_devinfo(sc->arg, mi) != 0)
 1269                         break;
 1270                 mi->index++;
 1271         }
 1272         sc->mix_nent = mi->index;
 1273         sc->mix_ents = mallocarray(sc->mix_nent,
 1274             sizeof(struct mixer_ctrl), M_DEVBUF, M_WAITOK);
 1275         sc->mix_evbuf = mallocarray(sc->mix_nent,
 1276             sizeof(struct mixer_ev), M_DEVBUF, M_WAITOK | M_ZERO);
 1277 
 1278         ent = sc->mix_ents;
 1279         mi->index = 0;
 1280         while (1) {
 1281                 if (sc->ops->query_devinfo(sc->arg, mi) != 0)
 1282                         break;
 1283                 switch (mi->type) {
 1284                 case AUDIO_MIXER_VALUE:
 1285                         ent->un.value.num_channels = mi->un.v.num_channels;
 1286                         /* FALLTHROUGH */
 1287                 case AUDIO_MIXER_SET:
 1288                 case AUDIO_MIXER_ENUM:
 1289                         ent->dev = mi->index;
 1290                         ent->type = mi->type;
 1291                 }
 1292                 mi->index++;
 1293                 ent++;
 1294         }
 1295 
 1296         free(mi, M_TEMP, sizeof(struct mixer_devinfo));
 1297 }
 1298 
 1299 int
 1300 audio_activate(struct device *self, int act)
 1301 {
 1302         struct audio_softc *sc = (struct audio_softc *)self;
 1303         int i;
 1304 
 1305         switch (act) {
 1306         case DVACT_QUIESCE:
 1307                 /*
 1308                  * good drivers run play and rec handlers in a single
 1309                  * interrupt. Grab the lock to ensure we expose the same
 1310                  * sc->quiesce value to both play and rec handlers
 1311                  */
 1312                 mtx_enter(&audio_lock);
 1313                 sc->quiesce = 1;
 1314                 mtx_leave(&audio_lock);
 1315 
 1316                 /*
 1317                  * once sc->quiesce is set, interrupts may occur, but
 1318                  * counters are not advanced and consequently processes
 1319                  * keep sleeping.
 1320                  *
 1321                  * XXX: ensure read/write/ioctl don't start/stop
 1322                  * DMA at the same time, this needs a "ready" condvar
 1323                  */
 1324                 if (sc->mode != 0 && sc->active)
 1325                         audio_stop_do(sc);
 1326 
 1327                 /*
 1328                  * save mixer state
 1329                  */
 1330                 for (i = 0; i != sc->mix_nent; i++)
 1331                         sc->ops->get_port(sc->arg, sc->mix_ents + i);
 1332 
 1333                 DPRINTF("%s: quiesce: active = %d\n", DEVNAME(sc), sc->active);
 1334                 break;
 1335         case DVACT_WAKEUP:
 1336                 DPRINTF("%s: wakeup: active = %d\n", DEVNAME(sc), sc->active);
 1337 
 1338                 /*
 1339                  * restore mixer state
 1340                  */
 1341                 for (i = 0; i != sc->mix_nent; i++)
 1342                         sc->ops->set_port(sc->arg, sc->mix_ents + i);
 1343 
 1344                 /*
 1345                  * keep buffer usage the same, but set start pointer to
 1346                  * the beginning of the buffer.
 1347                  *
 1348                  * No need to grab the audio_lock as DMA is stopped and
 1349                  * this is the only thread running (caller ensures this)
 1350                  */
 1351                 sc->quiesce = 0;
 1352                 wakeup(&sc->quiesce);
 1353 
 1354                 if (sc->mode != 0) {
 1355                         if (audio_setpar(sc) != 0)
 1356                                 break;
 1357                         if (sc->mode & AUMODE_PLAY) {
 1358                                 sc->play.start = 0;
 1359                                 audio_fill_sil(sc, sc->play.data, sc->play.len);
 1360                         }
 1361                         if (sc->mode & AUMODE_RECORD) {
 1362                                 sc->rec.start = sc->rec.len - sc->rec.used;
 1363                                 audio_fill_sil(sc, sc->rec.data, sc->rec.len);
 1364                         }
 1365                         if (sc->active)
 1366                                 audio_start_do(sc);
 1367                 }
 1368                 break;
 1369         }
 1370         return 0;
 1371 }
 1372 
 1373 int
 1374 audio_detach(struct device *self, int flags)
 1375 {
 1376         struct audio_softc *sc = (struct audio_softc *)self;
 1377         int maj, mn;
 1378 
 1379         DPRINTF("%s: audio_detach: flags = %d\n", DEVNAME(sc), flags);
 1380 
 1381         wakeup(&sc->quiesce);
 1382 
 1383         /* locate the major number */
 1384         for (maj = 0; maj < nchrdev; maj++)
 1385                 if (cdevsw[maj].d_open == audioopen)
 1386                         break;
 1387         /*
 1388          * Nuke the vnodes for any open instances, calls close but as
 1389          * close uses device_lookup, it returns EXIO and does nothing
 1390          */
 1391         mn = self->dv_unit;
 1392         vdevgone(maj, mn | AUDIO_DEV_AUDIO, mn | AUDIO_DEV_AUDIO, VCHR);
 1393         vdevgone(maj, mn | AUDIO_DEV_AUDIOCTL, mn | AUDIO_DEV_AUDIOCTL, VCHR);
 1394 
 1395         /*
 1396          * The close() method did nothing, quickly halt DMA (normally
 1397          * parent is already gone, and code below is no-op), and wake-up
 1398          * user-land blocked in read/write/ioctl, which return EIO.
 1399          */
 1400         if (sc->mode != 0) {
 1401                 if (sc->active) {
 1402                         wakeup(&sc->play.blocking);
 1403                         wakeup(&sc->rec.blocking);
 1404                         audio_stop(sc);
 1405                 }
 1406                 sc->ops->close(sc->arg);
 1407                 sc->mode = 0;
 1408         }
 1409         if (sc->mix_isopen)
 1410                 wakeup(&sc->mix_blocking);
 1411         klist_invalidate(&sc->play.klist);
 1412         klist_invalidate(&sc->rec.klist);
 1413         klist_invalidate(&sc->mix_klist);
 1414 
 1415         /* free resources */
 1416         klist_free(&sc->mix_klist);
 1417         free(sc->mix_evbuf, M_DEVBUF, sc->mix_nent * sizeof(struct mixer_ev));
 1418         free(sc->mix_ents, M_DEVBUF, sc->mix_nent * sizeof(struct mixer_ctrl));
 1419         audio_buf_done(sc, &sc->play);
 1420         audio_buf_done(sc, &sc->rec);
 1421         return 0;
 1422 }
 1423 
 1424 int
 1425 audio_submatch(struct device *parent, void *match, void *aux)
 1426 {
 1427         struct cfdata *cf = match;
 1428 
 1429         return (cf->cf_driver == &audio_cd);
 1430 }
 1431 
 1432 struct device *
 1433 audio_attach_mi(const struct audio_hw_if *ops, void *arg, void *cookie,
 1434     struct device *dev)
 1435 {
 1436         struct audio_attach_args aa;
 1437 
 1438         aa.type = AUDIODEV_TYPE_AUDIO;
 1439         aa.hwif = ops;
 1440         aa.hdl = arg;
 1441         aa.cookie = cookie;
 1442 
 1443         /*
 1444          * attach this driver to the caller (hardware driver), this
 1445          * checks the kernel config and possibly calls audio_attach()
 1446          */
 1447         return config_found_sm(dev, &aa, audioprint, audio_submatch);
 1448 }
 1449 
 1450 int
 1451 audioprint(void *aux, const char *pnp)
 1452 {
 1453         struct audio_attach_args *arg = aux;
 1454         const char *type;
 1455 
 1456         if (pnp != NULL) {
 1457                 switch (arg->type) {
 1458                 case AUDIODEV_TYPE_AUDIO:
 1459                         type = "audio";
 1460                         break;
 1461                 case AUDIODEV_TYPE_OPL:
 1462                         type = "opl";
 1463                         break;
 1464                 case AUDIODEV_TYPE_MPU:
 1465                         type = "mpu";
 1466                         break;
 1467                 default:
 1468                         panic("audioprint: unknown type %d", arg->type);
 1469                 }
 1470                 printf("%s at %s", type, pnp);
 1471         }
 1472         return UNCONF;
 1473 }
 1474 
 1475 int
 1476 audio_open(struct audio_softc *sc, int flags)
 1477 {
 1478         int error;
 1479 
 1480         if (sc->mode)
 1481                 return EBUSY;
 1482         error = sc->ops->open(sc->arg, flags);
 1483         if (error)
 1484                 return error;
 1485         sc->active = 0;
 1486         sc->pause = 1;
 1487         sc->rec.blocking = 0;
 1488         sc->play.blocking = 0;
 1489         sc->mode = 0;
 1490         if (flags & FWRITE)
 1491                 sc->mode |= AUMODE_PLAY;
 1492         if (flags & FREAD)
 1493                 sc->mode |= AUMODE_RECORD;
 1494 
 1495         error = audio_setpar(sc);
 1496         if (error)
 1497                 goto bad;
 1498         audio_clear(sc);
 1499 
 1500         /*
 1501          * allow read(2)/write(2) to automatically start DMA, without
 1502          * the need for ioctl(), to make /dev/audio usable in scripts
 1503          */
 1504         sc->pause = 0;
 1505         return 0;
 1506 bad:
 1507         sc->ops->close(sc->arg);
 1508         sc->mode = 0;
 1509         return error;
 1510 }
 1511 
 1512 int
 1513 audio_drain(struct audio_softc *sc)
 1514 {
 1515         int error, xrun;
 1516         unsigned char *ptr;
 1517         size_t count, bpf;
 1518 
 1519         DPRINTF("%s: drain: mode = %d, pause = %d, active = %d, used = %zu\n",
 1520             DEVNAME(sc), sc->mode, sc->pause, sc->active, sc->play.used);
 1521         if (!(sc->mode & AUMODE_PLAY) || sc->pause)
 1522                 return 0;
 1523 
 1524         /* discard partial samples, required by audio_fill_sil() */
 1525         mtx_enter(&audio_lock);
 1526         bpf = sc->pchan * sc->bps;
 1527         sc->play.used -= sc->play.used % bpf;
 1528         if (sc->play.used == 0) {
 1529                 mtx_leave(&audio_lock);
 1530                 return 0;
 1531         }
 1532 
 1533         if (!sc->active) {
 1534                 /*
 1535                  * dma not started yet because buffer was not full
 1536                  * enough to start automatically. Pad it and start now.
 1537                  */
 1538                 for (;;) {
 1539                         ptr = audio_buf_wgetblk(&sc->play, &count);
 1540                         if (count == 0)
 1541                                 break;
 1542                         audio_fill_sil(sc, ptr, count);
 1543                         audio_buf_wcommit(&sc->play, count);
 1544                 }
 1545                 mtx_leave(&audio_lock);
 1546                 error = audio_start(sc);
 1547                 if (error)
 1548                         return error;
 1549                 mtx_enter(&audio_lock);
 1550         }
 1551 
 1552         xrun = sc->play.xrun;
 1553         while (sc->play.xrun == xrun) {
 1554                 DPRINTF("%s: drain: used = %zu, xrun = %d\n",
 1555                     DEVNAME(sc), sc->play.used, sc->play.xrun);
 1556 
 1557                 /*
 1558                  * set a 5 second timeout, in case interrupts don't
 1559                  * work, useful only for debugging drivers
 1560                  */
 1561                 sc->play.blocking = 1;
 1562                 error = msleep_nsec(&sc->play.blocking, &audio_lock,
 1563                     PWAIT | PCATCH, "au_dr", SEC_TO_NSEC(5));
 1564                 if (!(sc->dev.dv_flags & DVF_ACTIVE))
 1565                         error = EIO;
 1566                 if (error) {
 1567                         DPRINTF("%s: drain, err = %d\n", DEVNAME(sc), error);
 1568                         break;
 1569                 }
 1570         }
 1571         mtx_leave(&audio_lock);
 1572         return error;
 1573 }
 1574 
 1575 int
 1576 audio_close(struct audio_softc *sc)
 1577 {
 1578         audio_drain(sc);
 1579         if (sc->active)
 1580                 audio_stop(sc);
 1581         sc->ops->close(sc->arg);
 1582         sc->mode = 0;
 1583         DPRINTF("%s: close: done\n", DEVNAME(sc));
 1584         return 0;
 1585 }
 1586 
 1587 int
 1588 audio_read(struct audio_softc *sc, struct uio *uio, int ioflag)
 1589 {
 1590         unsigned char *ptr;
 1591         size_t count;
 1592         int error;
 1593 
 1594         DPRINTFN(1, "%s: read: resid = %zd\n", DEVNAME(sc), uio->uio_resid);
 1595 
 1596         /* block if quiesced */
 1597         while (sc->quiesce)
 1598                 tsleep_nsec(&sc->quiesce, 0, "au_qrd", INFSLP);
 1599 
 1600         /* start automatically if audio_ioc_start() was never called */
 1601         if (audio_canstart(sc)) {
 1602                 error = audio_start(sc);
 1603                 if (error)
 1604                         return error;
 1605         }
 1606 
 1607         mtx_enter(&audio_lock);
 1608 
 1609         /* if there is no data then sleep */
 1610         while (sc->rec.used == 0) {
 1611                 if (ioflag & IO_NDELAY) {
 1612                         mtx_leave(&audio_lock);
 1613                         return EWOULDBLOCK;
 1614                 }
 1615                 DPRINTFN(1, "%s: read sleep\n", DEVNAME(sc));
 1616                 sc->rec.blocking = 1;
 1617                 error = msleep_nsec(&sc->rec.blocking,
 1618                     &audio_lock, PWAIT | PCATCH, "au_rd", INFSLP);
 1619                 if (!(sc->dev.dv_flags & DVF_ACTIVE))
 1620                         error = EIO;
 1621                 if (error) {
 1622                         DPRINTF("%s: read woke up error = %d\n",
 1623                             DEVNAME(sc), error);
 1624                         mtx_leave(&audio_lock);
 1625                         return error;
 1626                 }
 1627         }
 1628 
 1629         /* at this stage, there is data to transfer */
 1630         while (uio->uio_resid > 0 && sc->rec.used > 0) {
 1631                 ptr = audio_buf_rgetblk(&sc->rec, &count);
 1632                 if (count > uio->uio_resid)
 1633                         count = uio->uio_resid;
 1634                 mtx_leave(&audio_lock);
 1635                 DPRINTFN(1, "%s: read: start = %zu, count = %zu\n",
 1636                     DEVNAME(sc), ptr - sc->rec.data, count);
 1637                 if (sc->conv_dec)
 1638                         sc->conv_dec(ptr, count);
 1639                 error = uiomove(ptr, count, uio);
 1640                 if (error)
 1641                         return error;
 1642                 mtx_enter(&audio_lock);
 1643                 audio_buf_rdiscard(&sc->rec, count);
 1644         }
 1645         mtx_leave(&audio_lock);
 1646         return 0;
 1647 }
 1648 
 1649 int
 1650 audio_write(struct audio_softc *sc, struct uio *uio, int ioflag)
 1651 {
 1652         unsigned char *ptr;
 1653         size_t count;
 1654         int error;
 1655 
 1656         DPRINTFN(1, "%s: write: resid = %zd\n",  DEVNAME(sc), uio->uio_resid);
 1657 
 1658         /* block if quiesced */
 1659         while (sc->quiesce)
 1660                 tsleep_nsec(&sc->quiesce, 0, "au_qwr", INFSLP);
 1661 
 1662         /*
 1663          * if IO_NDELAY flag is set then check if there is enough room
 1664          * in the buffer to store at least one byte. If not then don't
 1665          * start the write process.
 1666          */
 1667         mtx_enter(&audio_lock);
 1668         if (uio->uio_resid > 0 && (ioflag & IO_NDELAY)) {
 1669                 if (sc->play.used == sc->play.len) {
 1670                         mtx_leave(&audio_lock);
 1671                         return EWOULDBLOCK;
 1672                 }
 1673         }
 1674 
 1675         while (uio->uio_resid > 0) {
 1676                 while (1) {
 1677                         ptr = audio_buf_wgetblk(&sc->play, &count);
 1678                         if (count > 0)
 1679                                 break;
 1680                         if (ioflag & IO_NDELAY) {
 1681                                 /*
 1682                                  * At this stage at least one byte is already
 1683                                  * moved so we do not return EWOULDBLOCK
 1684                                  */
 1685                                 mtx_leave(&audio_lock);
 1686                                 return 0;
 1687                         }
 1688                         DPRINTFN(1, "%s: write sleep\n", DEVNAME(sc));
 1689                         sc->play.blocking = 1;
 1690                         error = msleep_nsec(&sc->play.blocking,
 1691                             &audio_lock, PWAIT | PCATCH, "au_wr", INFSLP);
 1692                         if (!(sc->dev.dv_flags & DVF_ACTIVE))
 1693                                 error = EIO;
 1694                         if (error) {
 1695                                 DPRINTF("%s: write woke up error = %d\n",
 1696                                     DEVNAME(sc), error);
 1697                                 mtx_leave(&audio_lock);
 1698                                 return error;
 1699                         }
 1700                 }
 1701                 if (count > uio->uio_resid)
 1702                         count = uio->uio_resid;
 1703                 mtx_leave(&audio_lock);
 1704                 error = uiomove(ptr, count, uio);
 1705                 if (error)
 1706                         return 0;
 1707                 if (sc->conv_enc) {
 1708                         sc->conv_enc(ptr, count);
 1709                         DPRINTFN(1, "audio_write: converted count = %zu\n",
 1710                             count);
 1711                 }
 1712                 if (sc->ops->copy_output)
 1713                         sc->ops->copy_output(sc->arg, count);
 1714 
 1715                 mtx_enter(&audio_lock);
 1716                 audio_buf_wcommit(&sc->play, count);
 1717 
 1718                 /* start automatically if audio_ioc_start() was never called */
 1719                 if (audio_canstart(sc)) {
 1720                         mtx_leave(&audio_lock);
 1721                         error = audio_start(sc);
 1722                         if (error)
 1723                                 return error;
 1724                         mtx_enter(&audio_lock);
 1725                 }
 1726         }
 1727         mtx_leave(&audio_lock);
 1728         return 0;
 1729 }
 1730 
 1731 int
 1732 audio_getdev(struct audio_softc *sc, struct audio_device *adev)
 1733 {
 1734         memset(adev, 0, sizeof(struct audio_device));
 1735         if (sc->dev.dv_parent == NULL)
 1736                 return EIO;
 1737         strlcpy(adev->name, sc->dev.dv_parent->dv_xname, MAX_AUDIO_DEV_LEN);
 1738         return 0;
 1739 }
 1740 
 1741 int
 1742 audio_ioctl(struct audio_softc *sc, unsigned long cmd, void *addr)
 1743 {
 1744         struct audio_pos *ap;
 1745         int error = 0;
 1746 
 1747         /* block if quiesced */
 1748         while (sc->quiesce)
 1749                 tsleep_nsec(&sc->quiesce, 0, "au_qio", INFSLP);
 1750 
 1751         switch (cmd) {
 1752         case FIONBIO:
 1753                 /* All handled in the upper FS layer. */
 1754                 break;
 1755         case AUDIO_GETPOS:
 1756                 mtx_enter(&audio_lock);
 1757                 ap = (struct audio_pos *)addr;
 1758                 ap->play_pos = sc->play.pos;
 1759                 ap->play_xrun = sc->play.xrun;
 1760                 ap->rec_pos = sc->rec.pos;
 1761                 ap->rec_xrun = sc->rec.xrun;
 1762                 mtx_leave(&audio_lock);
 1763                 break;
 1764         case AUDIO_START:
 1765                 return audio_ioc_start(sc);
 1766         case AUDIO_STOP:
 1767                 return audio_ioc_stop(sc);
 1768         case AUDIO_SETPAR:
 1769                 error = audio_ioc_setpar(sc, (struct audio_swpar *)addr);
 1770                 break;
 1771         case AUDIO_GETPAR:
 1772                 error = audio_ioc_getpar(sc, (struct audio_swpar *)addr);
 1773                 break;
 1774         case AUDIO_GETSTATUS:
 1775                 error = audio_ioc_getstatus(sc, (struct audio_status *)addr);
 1776                 break;
 1777         case AUDIO_GETDEV:
 1778                 error = audio_getdev(sc, (struct audio_device *)addr);
 1779                 break;
 1780         default:
 1781                 DPRINTF("%s: unknown ioctl 0x%lx\n", DEVNAME(sc), cmd);
 1782                 error = ENOTTY;
 1783                 break;
 1784         }
 1785         return error;
 1786 }
 1787 
 1788 void
 1789 audio_event(struct audio_softc *sc, int addr)
 1790 {
 1791         struct mixer_ev *e;
 1792 
 1793         mtx_enter(&audio_lock);
 1794         if (sc->mix_isopen) {
 1795                 e = sc->mix_evbuf + addr;
 1796                 if (!e->pending) {
 1797                         e->pending = 1;
 1798                         e->next = sc->mix_pending;
 1799                         sc->mix_pending = e;
 1800                 }
 1801                 audio_mixer_wakeup(sc);
 1802         }
 1803         mtx_leave(&audio_lock);
 1804 }
 1805 
 1806 int
 1807 audio_mixer_devinfo(struct audio_softc *sc, struct mixer_devinfo *devinfo)
 1808 {
 1809         if (devinfo->index < sc->mix_nent)
 1810                 return sc->ops->query_devinfo(sc->arg, devinfo);        
 1811 
 1812         devinfo->next = -1;
 1813         devinfo->prev = -1;
 1814         switch (devinfo->index - sc->mix_nent) {
 1815         case MIXER_RECORD:
 1816                 strlcpy(devinfo->label.name, AudioCrecord, MAX_AUDIO_DEV_LEN);
 1817                 devinfo->type = AUDIO_MIXER_CLASS;
 1818                 devinfo->mixer_class = -1;
 1819                 break;
 1820         case MIXER_RECORD_ENABLE:
 1821                 strlcpy(devinfo->label.name, "enable", MAX_AUDIO_DEV_LEN);
 1822                 devinfo->type = AUDIO_MIXER_ENUM;
 1823                 devinfo->mixer_class = MIXER_RECORD + sc->mix_nent;
 1824                 devinfo->un.e.num_mem = 3;
 1825                 devinfo->un.e.member[0].ord = MIXER_RECORD_ENABLE_OFF;
 1826                 strlcpy(devinfo->un.e.member[0].label.name, "off",
 1827                     MAX_AUDIO_DEV_LEN);
 1828                 devinfo->un.e.member[1].ord = MIXER_RECORD_ENABLE_ON;
 1829                 strlcpy(devinfo->un.e.member[1].label.name, "on",
 1830                     MAX_AUDIO_DEV_LEN);
 1831                 devinfo->un.e.member[2].ord = MIXER_RECORD_ENABLE_SYSCTL;
 1832                 strlcpy(devinfo->un.e.member[2].label.name, "sysctl",
 1833                     MAX_AUDIO_DEV_LEN);
 1834                 break;
 1835         default:
 1836                 return EINVAL;
 1837         }
 1838 
 1839         return 0;
 1840 }
 1841 
 1842 int
 1843 audio_mixer_get(struct audio_softc *sc, struct mixer_ctrl *c)
 1844 {
 1845         if (c->dev < sc->mix_nent)
 1846                 return sc->ops->get_port(sc->arg, c);
 1847 
 1848         switch (c->dev - sc->mix_nent) {
 1849         case MIXER_RECORD:
 1850                 return EBADF;
 1851         case MIXER_RECORD_ENABLE:
 1852                 c->un.ord = sc->record_enable;
 1853                 break;
 1854         default:
 1855                 return EINVAL;
 1856         }
 1857 
 1858         return 0;
 1859 }
 1860 
 1861 int
 1862 audio_mixer_set(struct audio_softc *sc, struct mixer_ctrl *c, struct proc *p)
 1863 {
 1864         int error;
 1865 
 1866         if (c->dev < sc->mix_nent) {
 1867                 error = sc->ops->set_port(sc->arg, c);
 1868                 if (error)
 1869                         return error;
 1870                 if (sc->ops->commit_settings)
 1871                         return sc->ops->commit_settings(sc->arg);
 1872                 audio_event(sc, c->dev);
 1873                 return 0;
 1874         }
 1875 
 1876         switch (c->dev - sc->mix_nent) {
 1877         case MIXER_RECORD:
 1878                 return EBADF;
 1879         case MIXER_RECORD_ENABLE:
 1880                 switch (c->un.ord) {
 1881                 case MIXER_RECORD_ENABLE_OFF:
 1882                 case MIXER_RECORD_ENABLE_ON:
 1883                 case MIXER_RECORD_ENABLE_SYSCTL:
 1884                         break;
 1885                 default:
 1886                         return EINVAL;
 1887                 }
 1888                 if (suser(p) == 0)
 1889                         sc->record_enable = c->un.ord;
 1890                 break;
 1891         default:
 1892                 return EINVAL;
 1893         }
 1894 
 1895         return 0;
 1896 }
 1897 
 1898 int
 1899 audio_ioctl_mixer(struct audio_softc *sc, unsigned long cmd, void *addr,
 1900         struct proc *p)
 1901 {
 1902         /* block if quiesced */
 1903         while (sc->quiesce)
 1904                 tsleep_nsec(&sc->quiesce, 0, "mix_qio", INFSLP);
 1905 
 1906         switch (cmd) {
 1907         case FIONBIO:
 1908                 /* All handled in the upper FS layer. */
 1909                 break;
 1910         case AUDIO_MIXER_DEVINFO:
 1911                 return audio_mixer_devinfo(sc, addr);
 1912         case AUDIO_MIXER_READ:
 1913                 return audio_mixer_get(sc, addr);
 1914         case AUDIO_MIXER_WRITE:
 1915                 return audio_mixer_set(sc, addr, p);
 1916         default:
 1917                 return ENOTTY;
 1918         }
 1919         return 0;
 1920 }
 1921 
 1922 int
 1923 audio_mixer_read(struct audio_softc *sc, struct uio *uio, int ioflag)
 1924 {       
 1925         struct mixer_ev *e;
 1926         int data;
 1927         int error;
 1928 
 1929         DPRINTF("%s: mixer read: resid = %zd\n", DEVNAME(sc), uio->uio_resid);
 1930 
 1931         /* block if quiesced */
 1932         while (sc->quiesce)
 1933                 tsleep_nsec(&sc->quiesce, 0, "mix_qrd", INFSLP);
 1934 
 1935         mtx_enter(&audio_lock);
 1936 
 1937         /* if there are no events then sleep */
 1938         while (!sc->mix_pending) {
 1939                 if (ioflag & IO_NDELAY) {
 1940                         mtx_leave(&audio_lock);
 1941                         return EWOULDBLOCK;
 1942                 }
 1943                 DPRINTF("%s: mixer read sleep\n", DEVNAME(sc));
 1944                 sc->mix_blocking = 1;
 1945                 error = msleep_nsec(&sc->mix_blocking,
 1946                     &audio_lock, PWAIT | PCATCH, "mix_rd", INFSLP);
 1947                 if (!(sc->dev.dv_flags & DVF_ACTIVE))
 1948                         error = EIO;
 1949                 if (error) {
 1950                         DPRINTF("%s: mixer read woke up error = %d\n",
 1951                             DEVNAME(sc), error);
 1952                         mtx_leave(&audio_lock);
 1953                         return error;
 1954                 }
 1955         }
 1956 
 1957         /* at this stage, there is an event to transfer */
 1958         while (uio->uio_resid >= sizeof(int) && sc->mix_pending) {
 1959                 e = sc->mix_pending;
 1960                 sc->mix_pending = e->next;
 1961                 e->pending = 0;
 1962                 data = e - sc->mix_evbuf;
 1963                 mtx_leave(&audio_lock);
 1964                 DPRINTF("%s: mixer read: %u\n", DEVNAME(sc), data);
 1965                 error = uiomove(&data, sizeof(int), uio);
 1966                 if (error)
 1967                         return error;
 1968                 mtx_enter(&audio_lock);
 1969         }
 1970 
 1971         mtx_leave(&audio_lock);
 1972         return 0;
 1973 }
 1974 
 1975 int
 1976 audio_mixer_open(struct audio_softc *sc, int flags)
 1977 {
 1978         DPRINTF("%s: flags = 0x%x\n", __func__, flags);
 1979 
 1980         if (flags & FREAD) {
 1981                 if (sc->mix_isopen)
 1982                         return EBUSY;
 1983                 sc->mix_isopen = 1;
 1984         }
 1985         return 0;
 1986 }
 1987 
 1988 int
 1989 audio_mixer_close(struct audio_softc *sc, int flags)
 1990 {
 1991         int i;
 1992 
 1993         DPRINTF("%s: flags = 0x%x\n", __func__, flags);
 1994 
 1995         if (flags & FREAD) {
 1996                 sc->mix_isopen = 0;
 1997 
 1998                 mtx_enter(&audio_lock);
 1999                 sc->mix_pending = NULL;
 2000                 for (i = 0; i < sc->mix_nent; i++)
 2001                         sc->mix_evbuf[i].pending = 0;
 2002                 mtx_leave(&audio_lock);
 2003         }
 2004         return 0;
 2005 }
 2006 
 2007 int
 2008 audioopen(dev_t dev, int flags, int mode, struct proc *p)
 2009 {
 2010         struct audio_softc *sc;
 2011         int error;
 2012 
 2013         sc = (struct audio_softc *)device_lookup(&audio_cd, AUDIO_UNIT(dev));
 2014         if (sc == NULL)
 2015                 return ENXIO;
 2016         if (sc->ops == NULL)
 2017                 error = ENXIO;
 2018         else {
 2019                 switch (AUDIO_DEV(dev)) {
 2020                 case AUDIO_DEV_AUDIO:
 2021                         error = audio_open(sc, flags);
 2022                         break;
 2023                 case AUDIO_DEV_AUDIOCTL:
 2024                         error = audio_mixer_open(sc, flags);
 2025                         break;
 2026                 default:
 2027                         error = ENXIO;
 2028                 }
 2029         }
 2030         device_unref(&sc->dev);
 2031         return error;
 2032 }
 2033 
 2034 int
 2035 audioclose(dev_t dev, int flags, int ifmt, struct proc *p)
 2036 {
 2037         struct audio_softc *sc;
 2038         int error;
 2039 
 2040         sc = (struct audio_softc *)device_lookup(&audio_cd, AUDIO_UNIT(dev));
 2041         if (sc == NULL)
 2042                 return ENXIO;
 2043         switch (AUDIO_DEV(dev)) {
 2044         case AUDIO_DEV_AUDIO:
 2045                 error = audio_close(sc);
 2046                 break;
 2047         case AUDIO_DEV_AUDIOCTL:
 2048                 error = audio_mixer_close(sc, flags);
 2049                 break;
 2050         default:
 2051                 error = ENXIO;
 2052         }
 2053         device_unref(&sc->dev);
 2054         return error;
 2055 }
 2056 
 2057 int
 2058 audioread(dev_t dev, struct uio *uio, int ioflag)
 2059 {
 2060         struct audio_softc *sc;
 2061         int error;
 2062 
 2063         sc = (struct audio_softc *)device_lookup(&audio_cd, AUDIO_UNIT(dev));
 2064         if (sc == NULL)
 2065                 return ENXIO;
 2066         switch (AUDIO_DEV(dev)) {
 2067         case AUDIO_DEV_AUDIO:
 2068                 error = audio_read(sc, uio, ioflag);
 2069                 break;
 2070         case AUDIO_DEV_AUDIOCTL:
 2071                 error = audio_mixer_read(sc, uio, ioflag);
 2072                 break;
 2073         default:
 2074                 error = ENXIO;
 2075         }
 2076         device_unref(&sc->dev);
 2077         return error;
 2078 }
 2079 
 2080 int
 2081 audiowrite(dev_t dev, struct uio *uio, int ioflag)
 2082 {
 2083         struct audio_softc *sc;
 2084         int error;
 2085 
 2086         sc = (struct audio_softc *)device_lookup(&audio_cd, AUDIO_UNIT(dev));
 2087         if (sc == NULL)
 2088                 return ENXIO;
 2089         switch (AUDIO_DEV(dev)) {
 2090         case AUDIO_DEV_AUDIO:
 2091                 error = audio_write(sc, uio, ioflag);
 2092                 break;
 2093         case AUDIO_DEV_AUDIOCTL:
 2094                 error = ENODEV;
 2095                 break;
 2096         default:
 2097                 error = ENXIO;
 2098         }
 2099         device_unref(&sc->dev);
 2100         return error;
 2101 }
 2102 
 2103 int
 2104 audioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
 2105 {
 2106         struct audio_softc *sc;
 2107         int error;
 2108 
 2109         sc = (struct audio_softc *)device_lookup(&audio_cd, AUDIO_UNIT(dev));
 2110         if (sc == NULL)
 2111                 return ENXIO;
 2112         switch (AUDIO_DEV(dev)) {
 2113         case AUDIO_DEV_AUDIO:
 2114                 error = audio_ioctl(sc, cmd, addr);
 2115                 break;
 2116         case AUDIO_DEV_AUDIOCTL:
 2117                 if (cmd == AUDIO_SETPAR && sc->mode != 0) {
 2118                         error = EBUSY;
 2119                         break;
 2120                 }
 2121                 if (cmd == AUDIO_START || cmd == AUDIO_STOP) {
 2122                         error = ENXIO;
 2123                         break;
 2124                 }
 2125                 if (cmd == AUDIO_MIXER_DEVINFO ||
 2126                     cmd == AUDIO_MIXER_READ ||
 2127                     cmd == AUDIO_MIXER_WRITE)
 2128                         error = audio_ioctl_mixer(sc, cmd, addr, p);
 2129                 else
 2130                         error = audio_ioctl(sc, cmd, addr);
 2131                 break;
 2132         default:
 2133                 error = ENXIO;
 2134         }
 2135         device_unref(&sc->dev);
 2136         return error;
 2137 }
 2138 
 2139 int
 2140 audiokqfilter(dev_t dev, struct knote *kn)
 2141 {
 2142         struct audio_softc *sc;
 2143         struct klist      *klist;
 2144         int error;
 2145 
 2146         sc = (struct audio_softc *)device_lookup(&audio_cd, AUDIO_UNIT(dev));
 2147         if (sc == NULL)
 2148                 return ENXIO;
 2149         error = 0;
 2150         switch (AUDIO_DEV(dev)) {
 2151         case AUDIO_DEV_AUDIO:
 2152                 switch (kn->kn_filter) {
 2153                 case EVFILT_READ:
 2154                         klist = &sc->rec.klist;
 2155                         kn->kn_fop = &audioread_filtops;
 2156                         break;
 2157                 case EVFILT_WRITE:
 2158                         klist = &sc->play.klist;
 2159                         kn->kn_fop = &audiowrite_filtops;
 2160                         break;
 2161                 default:
 2162                         error = EINVAL;
 2163                         goto done;
 2164                 }
 2165                 break;
 2166         case AUDIO_DEV_AUDIOCTL:
 2167                 switch (kn->kn_filter) {
 2168                 case EVFILT_READ:
 2169                         klist = &sc->mix_klist;
 2170                         kn->kn_fop = &audioctlread_filtops;
 2171                         break;
 2172                 default:
 2173                         error = EINVAL;
 2174                         goto done;
 2175                 }
 2176                 break;
 2177         }
 2178         kn->kn_hook = sc;
 2179 
 2180         klist_insert(klist, kn);
 2181 done:
 2182         device_unref(&sc->dev);
 2183         return error;
 2184 }
 2185 
 2186 void
 2187 filt_audiordetach(struct knote *kn)
 2188 {
 2189         struct audio_softc *sc = kn->kn_hook;
 2190 
 2191         klist_remove(&sc->rec.klist, kn);
 2192 }
 2193 
 2194 int
 2195 filt_audioread(struct knote *kn, long hint)
 2196 {
 2197         struct audio_softc *sc = kn->kn_hook;
 2198 
 2199         MUTEX_ASSERT_LOCKED(&audio_lock);
 2200 
 2201         return (sc->mode & AUMODE_RECORD) && (sc->rec.used > 0);
 2202 }
 2203 
 2204 void
 2205 filt_audiowdetach(struct knote *kn)
 2206 {
 2207         struct audio_softc *sc = kn->kn_hook;
 2208 
 2209         klist_remove(&sc->play.klist, kn);
 2210 }
 2211 
 2212 int
 2213 filt_audiowrite(struct knote *kn, long hint)
 2214 {
 2215         struct audio_softc *sc = kn->kn_hook;
 2216 
 2217         MUTEX_ASSERT_LOCKED(&audio_lock);
 2218 
 2219         return (sc->mode & AUMODE_PLAY) && (sc->play.used < sc->play.len);
 2220 }
 2221 
 2222 void
 2223 filt_audioctlrdetach(struct knote *kn)
 2224 {
 2225         struct audio_softc *sc = kn->kn_hook;
 2226 
 2227         klist_remove(&sc->mix_klist, kn);
 2228 }
 2229 
 2230 int
 2231 filt_audioctlread(struct knote *kn, long hint)
 2232 {
 2233         struct audio_softc *sc = kn->kn_hook;
 2234 
 2235         MUTEX_ASSERT_LOCKED(&audio_lock);
 2236 
 2237         return (sc->mix_isopen && sc->mix_pending);
 2238 }
 2239 
 2240 int
 2241 filt_audiomodify(struct kevent *kev, struct knote *kn)
 2242 {
 2243         int active;
 2244 
 2245         mtx_enter(&audio_lock);
 2246         active = knote_modify(kev, kn);
 2247         mtx_leave(&audio_lock);
 2248 
 2249         return active;
 2250 }
 2251 
 2252 int
 2253 filt_audioprocess(struct knote *kn, struct kevent *kev)
 2254 {
 2255         int active;
 2256 
 2257         mtx_enter(&audio_lock);
 2258         active = knote_process(kn, kev);
 2259         mtx_leave(&audio_lock);
 2260 
 2261         return active;
 2262 }
 2263 
 2264 #if NWSKBD > 0
 2265 int
 2266 wskbd_initmute(struct audio_softc *sc, struct mixer_devinfo *vol)
 2267 {
 2268         struct mixer_devinfo *mi;
 2269         int index = -1;
 2270 
 2271         mi = malloc(sizeof(struct mixer_devinfo), M_TEMP, M_WAITOK);
 2272 
 2273         for (mi->index = vol->next; mi->index != -1; mi->index = mi->next) {
 2274                 if (sc->ops->query_devinfo(sc->arg, mi) != 0)
 2275                         break;
 2276                 if (strcmp(mi->label.name, AudioNmute) == 0) {
 2277                         index = mi->index;
 2278                         break;
 2279                 }
 2280         }
 2281 
 2282         free(mi, M_TEMP, sizeof(struct mixer_devinfo));
 2283         return index;
 2284 }
 2285 
 2286 int
 2287 wskbd_initvol(struct audio_softc *sc, struct wskbd_vol *vol, char *cn, char *dn)
 2288 {
 2289         struct mixer_devinfo *dev, *cls;
 2290 
 2291         vol->val = vol->mute = -1;
 2292         dev = malloc(sizeof(struct mixer_devinfo), M_TEMP, M_WAITOK);
 2293         cls = malloc(sizeof(struct mixer_devinfo), M_TEMP, M_WAITOK);
 2294 
 2295         for (dev->index = 0; ; dev->index++) {
 2296                 if (sc->ops->query_devinfo(sc->arg, dev) != 0)
 2297                         break;
 2298                 if (dev->type != AUDIO_MIXER_VALUE)
 2299                         continue;
 2300                 cls->index = dev->mixer_class;
 2301                 if (sc->ops->query_devinfo(sc->arg, cls) != 0)
 2302                         continue;
 2303                 if (strcmp(cls->label.name, cn) == 0 &&
 2304                     strcmp(dev->label.name, dn) == 0) {
 2305                         vol->val = dev->index;
 2306                         vol->nch = dev->un.v.num_channels;
 2307                         vol->step = dev->un.v.delta > 8 ? dev->un.v.delta : 8;
 2308                         vol->mute = wskbd_initmute(sc, dev);
 2309                         vol->val_pending = vol->mute_pending = 0;
 2310                         DPRINTF("%s: wskbd using %s.%s%s\n", DEVNAME(sc),
 2311                             cn, dn, vol->mute >= 0 ? ", mute control" : "");
 2312                         break;
 2313                 }
 2314         }
 2315 
 2316         free(cls, M_TEMP, sizeof(struct mixer_devinfo));
 2317         free(dev, M_TEMP, sizeof(struct mixer_devinfo));
 2318         return (vol->val != -1);
 2319 }
 2320 
 2321 void
 2322 wskbd_mixer_init(struct audio_softc *sc)
 2323 {
 2324         static struct {
 2325                 char *cn, *dn;
 2326         } spkr_names[] = {
 2327                 {AudioCoutputs, AudioNmaster},
 2328                 {AudioCinputs,  AudioNdac},
 2329                 {AudioCoutputs, AudioNdac},
 2330                 {AudioCoutputs, AudioNoutput}
 2331         }, mic_names[] = {
 2332                 {AudioCrecord, AudioNrecord},
 2333                 {AudioCrecord, AudioNvolume},
 2334                 {AudioCinputs, AudioNrecord},
 2335                 {AudioCinputs, AudioNvolume},
 2336                 {AudioCinputs, AudioNinput}
 2337         };
 2338         int i;
 2339 
 2340         for (i = 0; i < sizeof(spkr_names) / sizeof(spkr_names[0]); i++) {
 2341                 if (wskbd_initvol(sc, &sc->spkr,
 2342                         spkr_names[i].cn, spkr_names[i].dn))
 2343                         break;
 2344         }
 2345         for (i = 0; i < sizeof(mic_names) / sizeof(mic_names[0]); i++) {
 2346                 if (wskbd_initvol(sc, &sc->mic,
 2347                         mic_names[i].cn, mic_names[i].dn))
 2348                         break;
 2349         }
 2350         task_set(&sc->wskbd_task, wskbd_mixer_cb, sc);
 2351 }
 2352 
 2353 void
 2354 wskbd_mixer_update(struct audio_softc *sc, struct wskbd_vol *vol)
 2355 {
 2356         struct mixer_ctrl ctrl;
 2357         int val_pending, mute_pending, i, gain, error, s;
 2358 
 2359         s = spltty();
 2360         val_pending = vol->val_pending;
 2361         vol->val_pending = 0;
 2362         mute_pending = vol->mute_pending;
 2363         vol->mute_pending = 0;
 2364         splx(s);
 2365 
 2366         if (sc->ops == NULL)
 2367                 return;
 2368         if (vol->mute >= 0 && mute_pending) {
 2369                 ctrl.dev = vol->mute;
 2370                 ctrl.type = AUDIO_MIXER_ENUM;
 2371                 error = sc->ops->get_port(sc->arg, &ctrl);
 2372                 if (error) {
 2373                         DPRINTF("%s: get mute err = %d\n", DEVNAME(sc), error);
 2374                         return;
 2375                 }
 2376                 switch (mute_pending) {
 2377                 case WSKBD_MUTE_TOGGLE:
 2378                         ctrl.un.ord = !ctrl.un.ord;
 2379                         break;
 2380                 case WSKBD_MUTE_DISABLE:
 2381                         ctrl.un.ord = 0;
 2382                         break;
 2383                 case WSKBD_MUTE_ENABLE:
 2384                         ctrl.un.ord = 1;
 2385                         break;
 2386                 }
 2387                 DPRINTFN(1, "%s: wskbd mute setting to %d\n",
 2388                     DEVNAME(sc), ctrl.un.ord);
 2389                 error = sc->ops->set_port(sc->arg, &ctrl);
 2390                 if (error) {
 2391                         DPRINTF("%s: set mute err = %d\n", DEVNAME(sc), error);
 2392                         return;
 2393                 }
 2394                 audio_event(sc, vol->mute);
 2395         }
 2396         if (vol->val >= 0 && val_pending) {
 2397                 ctrl.dev = vol->val;
 2398                 ctrl.type = AUDIO_MIXER_VALUE;
 2399                 ctrl.un.value.num_channels = vol->nch;
 2400                 error = sc->ops->get_port(sc->arg, &ctrl);
 2401                 if (error) {
 2402                         DPRINTF("%s: get mute err = %d\n", DEVNAME(sc), error);
 2403                         return;
 2404                 }
 2405                 for (i = 0; i < vol->nch; i++) {
 2406                         gain = ctrl.un.value.level[i] + vol->step * val_pending;
 2407                         if (gain > AUDIO_MAX_GAIN)
 2408                                 gain = AUDIO_MAX_GAIN;
 2409                         else if (gain < AUDIO_MIN_GAIN)
 2410                                 gain = AUDIO_MIN_GAIN;
 2411                         ctrl.un.value.level[i] = gain;
 2412                         DPRINTFN(1, "%s: wskbd level %d set to %d\n",
 2413                             DEVNAME(sc), i, gain);
 2414                 }
 2415                 error = sc->ops->set_port(sc->arg, &ctrl);
 2416                 if (error) {
 2417                         DPRINTF("%s: set vol err = %d\n", DEVNAME(sc), error);
 2418                         return;
 2419                 }
 2420                 audio_event(sc, vol->val);
 2421         }
 2422 }
 2423 
 2424 void
 2425 wskbd_mixer_cb(void *arg)
 2426 {
 2427         struct audio_softc *sc = arg;
 2428 
 2429         wskbd_mixer_update(sc, &sc->spkr);
 2430         wskbd_mixer_update(sc, &sc->mic);
 2431         device_unref(&sc->dev);
 2432 }
 2433 
 2434 int
 2435 wskbd_set_mixermute(long mute, long out)
 2436 {
 2437         struct audio_softc *sc;
 2438         struct wskbd_vol *vol;
 2439 
 2440         sc = (struct audio_softc *)device_lookup(&audio_cd, 0);
 2441         if (sc == NULL)
 2442                 return ENODEV;
 2443         vol = out ? &sc->spkr : &sc->mic;
 2444         vol->mute_pending = mute ? WSKBD_MUTE_ENABLE : WSKBD_MUTE_DISABLE;
 2445         if (!task_add(systq, &sc->wskbd_task))
 2446                 device_unref(&sc->dev);
 2447         return 0;
 2448 }
 2449 
 2450 /*
 2451  * Adjust the volume of the audio device associated with the given cookie.
 2452  * Otherwise, fallback to audio0.
 2453  */
 2454 int
 2455 wskbd_set_mixervolume_dev(void *cookie, long dir, long out)
 2456 {
 2457         int unit = 0;
 2458         int i;
 2459 
 2460         for (i = 0; i < audio_cd.cd_ndevs; i++) {
 2461                 struct audio_softc *sc;
 2462 
 2463                 sc = (struct audio_softc *)device_lookup(&audio_cd, i);
 2464                 if (sc == NULL)
 2465                         continue;
 2466                 if (sc->cookie != cookie) {
 2467                         device_unref(&sc->dev);
 2468                         continue;
 2469                 }
 2470 
 2471                 device_unref(&sc->dev);
 2472                 unit = i;
 2473                 break;
 2474         }
 2475 
 2476         return wskbd_set_mixervolume_unit(unit, dir, out);
 2477 }
 2478 
 2479 int
 2480 wskbd_set_mixervolume(long dir, long out)
 2481 {
 2482         return wskbd_set_mixervolume_unit(0, dir, out);
 2483 }
 2484 
 2485 int
 2486 wskbd_set_mixervolume_unit(int unit, long dir, long out)
 2487 {
 2488         struct audio_softc *sc;
 2489         struct wskbd_vol *vol;
 2490 
 2491         sc = (struct audio_softc *)device_lookup(&audio_cd, unit);
 2492         if (sc == NULL)
 2493                 return ENODEV;
 2494         vol = out ? &sc->spkr : &sc->mic;
 2495         if (dir == 0)
 2496                 vol->mute_pending ^= WSKBD_MUTE_TOGGLE;
 2497         else
 2498                 vol->val_pending += dir;
 2499         if (!task_add(systq, &sc->wskbd_task))
 2500                 device_unref(&sc->dev);
 2501         return 0;
 2502 }
 2503 #endif /* NWSKBD > 0 */

Cache object: a3e10e0e7c435f27947d8c7ed6eabcad


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.