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 /*      $NetBSD: audio.c,v 1.215.2.4 2008/02/03 19:08:41 riz Exp $      */
    2 
    3 /*
    4  * Copyright (c) 1991-1993 Regents of the University of California.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by the Computer Systems
   18  *      Engineering Group at Lawrence Berkeley Laboratory.
   19  * 4. Neither the name of the University nor of the Laboratory may be used
   20  *    to endorse or promote products derived from this software without
   21  *    specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  */
   35 
   36 /*
   37  * This is a (partially) SunOS-compatible /dev/audio driver for NetBSD.
   38  *
   39  * This code tries to do something half-way sensible with
   40  * half-duplex hardware, such as with the SoundBlaster hardware.  With
   41  * half-duplex hardware allowing O_RDWR access doesn't really make
   42  * sense.  However, closing and opening the device to "turn around the
   43  * line" is relatively expensive and costs a card reset (which can
   44  * take some time, at least for the SoundBlaster hardware).  Instead
   45  * we allow O_RDWR access, and provide an ioctl to set the "mode",
   46  * i.e. playing or recording.
   47  *
   48  * If you write to a half-duplex device in record mode, the data is
   49  * tossed.  If you read from the device in play mode, you get silence
   50  * filled buffers at the rate at which samples are naturally
   51  * generated.
   52  *
   53  * If you try to set both play and record mode on a half-duplex
   54  * device, playing takes precedence.
   55  */
   56 
   57 /*
   58  * Todo:
   59  * - Add softaudio() isr processing for wakeup, poll, signals,
   60  *   and silence fill.
   61  */
   62 
   63 #include <sys/cdefs.h>
   64 __KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.215.2.4 2008/02/03 19:08:41 riz Exp $");
   65 
   66 #include "audio.h"
   67 #if NAUDIO > 0
   68 
   69 #include <sys/param.h>
   70 #include <sys/ioctl.h>
   71 #include <sys/fcntl.h>
   72 #include <sys/vnode.h>
   73 #include <sys/select.h>
   74 #include <sys/poll.h>
   75 #include <sys/malloc.h>
   76 #include <sys/proc.h>
   77 #include <sys/systm.h>
   78 #include <sys/syslog.h>
   79 #include <sys/kernel.h>
   80 #include <sys/signalvar.h>
   81 #include <sys/conf.h>
   82 #include <sys/audioio.h>
   83 #include <sys/device.h>
   84 
   85 #include <dev/audio_if.h>
   86 #include <dev/audiovar.h>
   87 
   88 #include <machine/endian.h>
   89 
   90 /* #define AUDIO_DEBUG  1 */
   91 #ifdef AUDIO_DEBUG
   92 #define DPRINTF(x)      if (audiodebug) printf x
   93 #define DPRINTFN(n,x)   if (audiodebug>(n)) printf x
   94 int     audiodebug = AUDIO_DEBUG;
   95 #else
   96 #define DPRINTF(x)
   97 #define DPRINTFN(n,x)
   98 #endif
   99 
  100 #define ROUNDSIZE(x)    x &= -16        /* round to nice boundary */
  101 #define SPECIFIED(x)    (x != ~0)
  102 #define SPECIFIED_CH(x) (x != (u_char)~0)
  103 
  104 int     audio_blk_ms = AUDIO_BLK_MS;
  105 
  106 int     audiosetinfo(struct audio_softc *, struct audio_info *);
  107 int     audiogetinfo(struct audio_softc *, struct audio_info *, int);
  108 
  109 int     audio_open(dev_t, struct audio_softc *, int, int, struct lwp *);
  110 int     audio_close(struct audio_softc *, int, int, struct lwp *);
  111 int     audio_read(struct audio_softc *, struct uio *, int);
  112 int     audio_write(struct audio_softc *, struct uio *, int);
  113 int     audio_ioctl(struct audio_softc *, u_long, caddr_t, int, struct lwp *);
  114 int     audio_poll(struct audio_softc *, int, struct lwp *);
  115 int     audio_kqfilter(struct audio_softc *, struct knote *);
  116 paddr_t audio_mmap(struct audio_softc *, off_t, int);
  117 
  118 int     mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *);
  119 int     mixer_close(struct audio_softc *, int, int, struct lwp *);
  120 int     mixer_ioctl(struct audio_softc *, u_long, caddr_t, int, struct lwp *);
  121 static  void mixer_remove(struct audio_softc *, struct lwp *);
  122 static  void mixer_signal(struct audio_softc *);
  123 
  124 void    audio_init_record(struct audio_softc *);
  125 void    audio_init_play(struct audio_softc *);
  126 int     audiostartr(struct audio_softc *);
  127 int     audiostartp(struct audio_softc *);
  128 void    audio_rint(void *);
  129 void    audio_pint(void *);
  130 int     audio_check_params(struct audio_params *);
  131 
  132 void    audio_calc_blksize(struct audio_softc *, int);
  133 void    audio_fill_silence(struct audio_params *, uint8_t *, int);
  134 int     audio_silence_copyout(struct audio_softc *, int, struct uio *);
  135 
  136 void    audio_init_ringbuffer(struct audio_softc *,
  137                               struct audio_ringbuffer *, int);
  138 int     audio_initbufs(struct audio_softc *);
  139 void    audio_calcwater(struct audio_softc *);
  140 static inline int audio_sleep_timo(int *, const char *, int);
  141 static inline int audio_sleep(int *, const char *);
  142 static inline void audio_wakeup(int *);
  143 int     audio_drain(struct audio_softc *);
  144 void    audio_clear(struct audio_softc *);
  145 static inline void audio_pint_silence
  146         (struct audio_softc *, struct audio_ringbuffer *, uint8_t *, int);
  147 
  148 int     audio_alloc_ring
  149         (struct audio_softc *, struct audio_ringbuffer *, int, size_t);
  150 void    audio_free_ring(struct audio_softc *, struct audio_ringbuffer *);
  151 static int audio_setup_pfilters(struct audio_softc *, const audio_params_t *,
  152                                 stream_filter_list_t *);
  153 static int audio_setup_rfilters(struct audio_softc *, const audio_params_t *,
  154                                 stream_filter_list_t *);
  155 static void audio_destruct_pfilters(struct audio_softc *);
  156 static void audio_destruct_rfilters(struct audio_softc *);
  157 static void audio_stream_dtor(audio_stream_t *);
  158 static int audio_stream_ctor(audio_stream_t *, const audio_params_t *, int);
  159 static void stream_filter_list_append
  160         (stream_filter_list_t *, stream_filter_factory_t,
  161          const audio_params_t *);
  162 static void stream_filter_list_prepend
  163         (stream_filter_list_t *, stream_filter_factory_t,
  164          const audio_params_t *);
  165 static void stream_filter_list_set
  166         (stream_filter_list_t *, int, stream_filter_factory_t,
  167          const audio_params_t *);
  168 int     audio_set_defaults(struct audio_softc *, u_int);
  169 
  170 int     audioprobe(struct device *, struct cfdata *, void *);
  171 void    audioattach(struct device *, struct device *, void *);
  172 int     audiodetach(struct device *, int);
  173 int     audioactivate(struct device *, enum devact);
  174 
  175 void    audio_powerhook(int, void *);
  176 
  177 struct portname {
  178         const char *name;
  179         int mask;
  180 };
  181 static const struct portname itable[] = {
  182         { AudioNmicrophone,     AUDIO_MICROPHONE },
  183         { AudioNline,           AUDIO_LINE_IN },
  184         { AudioNcd,             AUDIO_CD },
  185         { 0, 0 }
  186 };
  187 static const struct portname otable[] = {
  188         { AudioNspeaker,        AUDIO_SPEAKER },
  189         { AudioNheadphone,      AUDIO_HEADPHONE },
  190         { AudioNline,           AUDIO_LINE_OUT },
  191         { 0, 0 }
  192 };
  193 void    au_setup_ports(struct audio_softc *, struct au_mixer_ports *,
  194                         mixer_devinfo_t *, const struct portname *);
  195 int     au_set_gain(struct audio_softc *, struct au_mixer_ports *,
  196                         int, int);
  197 void    au_get_gain(struct audio_softc *, struct au_mixer_ports *,
  198                         u_int *, u_char *);
  199 int     au_set_port(struct audio_softc *, struct au_mixer_ports *,
  200                         u_int);
  201 int     au_get_port(struct audio_softc *, struct au_mixer_ports *);
  202 int     au_get_lr_value(struct audio_softc *, mixer_ctrl_t *,
  203                         int *, int *);
  204 int     au_set_lr_value(struct audio_softc *, mixer_ctrl_t *,
  205                         int, int);
  206 int     au_portof(struct audio_softc *, char *, int);
  207 
  208 typedef struct uio_fetcher {
  209         stream_fetcher_t base;
  210         struct uio *uio;
  211         int usedhigh;
  212         int last_used;
  213 } uio_fetcher_t;
  214 
  215 static void     uio_fetcher_ctor(uio_fetcher_t *, struct uio *, int);
  216 static int      uio_fetcher_fetch_to(stream_fetcher_t *,
  217                                      audio_stream_t *, int);
  218 static int      null_fetcher_fetch_to(stream_fetcher_t *,
  219                                       audio_stream_t *, int);
  220 
  221 dev_type_open(audioopen);
  222 dev_type_close(audioclose);
  223 dev_type_read(audioread);
  224 dev_type_write(audiowrite);
  225 dev_type_ioctl(audioioctl);
  226 dev_type_poll(audiopoll);
  227 dev_type_mmap(audiommap);
  228 dev_type_kqfilter(audiokqfilter);
  229 
  230 const struct cdevsw audio_cdevsw = {
  231         audioopen, audioclose, audioread, audiowrite, audioioctl,
  232         nostop, notty, audiopoll, audiommap, audiokqfilter, D_OTHER
  233 };
  234 
  235 /* The default audio mode: 8 kHz mono mu-law */
  236 const struct audio_params audio_default = {
  237         .sample_rate = 8000,
  238         .encoding = AUDIO_ENCODING_ULAW,
  239         .precision = 8,
  240         .validbits = 8,
  241         .channels = 1,
  242 };
  243 
  244 CFATTACH_DECL(audio, sizeof(struct audio_softc),
  245     audioprobe, audioattach, audiodetach, audioactivate);
  246 
  247 extern struct cfdriver audio_cd;
  248 
  249 int
  250 audioprobe(struct device *parent, struct cfdata *match,
  251     void *aux)
  252 {
  253         struct audio_attach_args *sa;
  254 
  255         sa = aux;
  256         DPRINTF(("audioprobe: type=%d sa=%p hw=%p\n",
  257                  sa->type, sa, sa->hwif));
  258         return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
  259 }
  260 
  261 void
  262 audioattach(struct device *parent, struct device *self, void *aux)
  263 {
  264         struct audio_softc *sc;
  265         struct audio_attach_args *sa;
  266         const struct audio_hw_if *hwp;
  267         void *hdlp;
  268         int error;
  269         mixer_devinfo_t mi;
  270         int iclass, mclass, oclass, rclass, props;
  271         int record_master_found, record_source_found;
  272 
  273         sc = (void *)self;
  274         sa = aux;
  275         hwp = sa->hwif;
  276         hdlp = sa->hdl;
  277 #ifdef DIAGNOSTIC
  278         if (hwp == 0 ||
  279             hwp->query_encoding == 0 ||
  280             hwp->set_params == 0 ||
  281             (hwp->start_output == 0 && hwp->trigger_output == 0) ||
  282             (hwp->start_input == 0 && hwp->trigger_input == 0) ||
  283             hwp->halt_output == 0 ||
  284             hwp->halt_input == 0 ||
  285             hwp->getdev == 0 ||
  286             hwp->set_port == 0 ||
  287             hwp->get_port == 0 ||
  288             hwp->query_devinfo == 0 ||
  289             hwp->get_props == 0) {
  290                 printf(": missing method\n");
  291                 sc->hw_if = 0;
  292                 return;
  293         }
  294 #endif
  295 
  296         props = hwp->get_props(hdlp);
  297 
  298         if (props & AUDIO_PROP_FULLDUPLEX)
  299                 printf(": full duplex");
  300         else
  301                 printf(": half duplex");
  302 
  303         if (props & AUDIO_PROP_MMAP)
  304                 printf(", mmap");
  305         if (props & AUDIO_PROP_INDEPENDENT)
  306                 printf(", independent");
  307 
  308         printf("\n");
  309 
  310         sc->hw_if = hwp;
  311         sc->hw_hdl = hdlp;
  312         sc->sc_dev = parent;
  313         sc->sc_opencnt = 0;
  314         sc->sc_writing = sc->sc_waitcomp = 0;
  315 
  316         error = audio_alloc_ring(sc, &sc->sc_pr, AUMODE_PLAY, AU_RING_SIZE);
  317         if (error) {
  318                 sc->hw_if = NULL;
  319                 printf("audio: could not allocate play buffer\n");
  320                 return;
  321         }
  322         error = audio_alloc_ring(sc, &sc->sc_rr, AUMODE_RECORD, AU_RING_SIZE);
  323         if (error) {
  324                 audio_free_ring(sc, &sc->sc_pr);
  325                 sc->hw_if = NULL;
  326                 printf("audio: could not allocate record buffer\n");
  327                 return;
  328         }
  329 
  330         if ((error = audio_set_defaults(sc, 0))) {
  331                 printf("audioattach: audio_set_defaults() failed\n");
  332                 sc->hw_if = NULL;
  333                 return;
  334         }
  335 
  336         iclass = mclass = oclass = rclass = -1;
  337         sc->sc_inports.index = -1;
  338         sc->sc_inports.master = -1;
  339         sc->sc_inports.nports = 0;
  340         sc->sc_inports.isenum = FALSE;
  341         sc->sc_inports.allports = 0;
  342         sc->sc_inports.isdual = FALSE;
  343         sc->sc_inports.mixerout = -1;
  344         sc->sc_inports.cur_port = -1;
  345         sc->sc_outports.index = -1;
  346         sc->sc_outports.master = -1;
  347         sc->sc_outports.nports = 0;
  348         sc->sc_outports.isenum = FALSE;
  349         sc->sc_outports.allports = 0;
  350         sc->sc_outports.isdual = FALSE;
  351         sc->sc_outports.mixerout = -1;
  352         sc->sc_outports.cur_port = -1;
  353         sc->sc_monitor_port = -1;
  354         /*
  355          * Read through the underlying driver's list, picking out the class
  356          * names from the mixer descriptions. We'll need them to decode the
  357          * mixer descriptions on the next pass through the loop.
  358          */
  359         for(mi.index = 0; ; mi.index++) {
  360                 if (hwp->query_devinfo(hdlp, &mi) != 0)
  361                         break;
  362                  /*
  363                   * The type of AUDIO_MIXER_CLASS merely introduces a class.
  364                   * All the other types describe an actual mixer.
  365                   */
  366                 if (mi.type == AUDIO_MIXER_CLASS) {
  367                         if (strcmp(mi.label.name, AudioCinputs) == 0)
  368                                 iclass = mi.mixer_class;
  369                         if (strcmp(mi.label.name, AudioCmonitor) == 0)
  370                                 mclass = mi.mixer_class;
  371                         if (strcmp(mi.label.name, AudioCoutputs) == 0)
  372                                 oclass = mi.mixer_class;
  373                         if (strcmp(mi.label.name, AudioCrecord) == 0)
  374                                 rclass = mi.mixer_class;
  375                 }
  376         }
  377         /*
  378          * This is where we assign each control in the "audio" model, to the
  379          * underlying "mixer" control.  We walk through the whole list once,
  380          * assigning likely candidates as we come across them.
  381          */
  382         record_master_found = 0;
  383         record_source_found = 0;
  384         for(mi.index = 0; ; mi.index++) {
  385                 if (hwp->query_devinfo(hdlp, &mi) != 0)
  386                         break;
  387                 if (mi.type == AUDIO_MIXER_CLASS)
  388                         continue;
  389                 if (mi.mixer_class == iclass) {
  390                         /*
  391                          * AudioCinputs is only a fallback, when we don't
  392                          * find what we're looking for in AudioCrecord, so
  393                          * check the flags before accepting one of these.
  394                          */
  395                         if (strcmp(mi.label.name, AudioNmaster) == 0
  396                             && record_master_found == 0)
  397                                 sc->sc_inports.master = mi.index;
  398                         if (strcmp(mi.label.name, AudioNsource) == 0
  399                             && record_source_found == 0) {
  400                                 if (mi.type == AUDIO_MIXER_ENUM) {
  401                                     int i;
  402                                     for(i = 0; i < mi.un.e.num_mem; i++)
  403                                         if (strcmp(mi.un.e.member[i].label.name,
  404                                                     AudioNmixerout) == 0)
  405                                                 sc->sc_inports.mixerout =
  406                                                     mi.un.e.member[i].ord;
  407                                 }
  408                                 au_setup_ports(sc, &sc->sc_inports, &mi,
  409                                     itable);
  410                         }
  411                 } else if (mi.mixer_class == mclass) {
  412                         if (strcmp(mi.label.name, AudioNmonitor) == 0)
  413                                 sc->sc_monitor_port = mi.index;
  414                 } else if (mi.mixer_class == oclass) {
  415                         if (strcmp(mi.label.name, AudioNmaster) == 0)
  416                                 sc->sc_outports.master = mi.index;
  417                         if (strcmp(mi.label.name, AudioNselect) == 0)
  418                                 au_setup_ports(sc, &sc->sc_outports, &mi,
  419                                     otable);
  420                 } else if (mi.mixer_class == rclass) {
  421                         /*
  422                          * These are the preferred mixers for the audio record
  423                          * controls, so set the flags here, but don't check.
  424                          */
  425                         if (strcmp(mi.label.name, AudioNmaster) == 0) {
  426                                 sc->sc_inports.master = mi.index;
  427                                 record_master_found = 1;
  428                         }
  429 #if 1   /* Deprecated. Use AudioNmaster. */
  430                         if (strcmp(mi.label.name, AudioNrecord) == 0) {
  431                                 sc->sc_inports.master = mi.index;
  432                                 record_master_found = 1;
  433                         }
  434                         if (strcmp(mi.label.name, AudioNvolume) == 0) {
  435                                 sc->sc_inports.master = mi.index;
  436                                 record_master_found = 1;
  437                         }
  438 #endif
  439                         if (strcmp(mi.label.name, AudioNsource) == 0) {
  440                                 if (mi.type == AUDIO_MIXER_ENUM) {
  441                                     int i;
  442                                     for(i = 0; i < mi.un.e.num_mem; i++)
  443                                         if (strcmp(mi.un.e.member[i].label.name,
  444                                                     AudioNmixerout) == 0)
  445                                                 sc->sc_inports.mixerout =
  446                                                     mi.un.e.member[i].ord;
  447                                 }
  448                                 au_setup_ports(sc, &sc->sc_inports, &mi,
  449                                     itable);
  450                                 record_source_found = 1;
  451                         }
  452                 }
  453         }
  454         DPRINTF(("audio_attach: inputs ports=0x%x, input master=%d, "
  455                  "output ports=0x%x, output master=%d\n",
  456                  sc->sc_inports.allports, sc->sc_inports.master,
  457                  sc->sc_outports.allports, sc->sc_outports.master));
  458 
  459         sc->sc_powerhook = powerhook_establish(sc->dev.dv_xname,
  460             audio_powerhook, sc);
  461         if (sc->sc_powerhook == NULL)
  462                 aprint_error("%s: can't establish powerhook\n",
  463                     sc->dev.dv_xname);
  464 }
  465 
  466 int
  467 audioactivate(struct device *self, enum devact act)
  468 {
  469         struct audio_softc *sc;
  470 
  471         sc = (struct audio_softc *)self;
  472         switch (act) {
  473         case DVACT_ACTIVATE:
  474                 return EOPNOTSUPP;
  475 
  476         case DVACT_DEACTIVATE:
  477                 sc->sc_dying = TRUE;
  478                 break;
  479         }
  480         return 0;
  481 }
  482 
  483 int
  484 audiodetach(struct device *self, int flags)
  485 {
  486         struct audio_softc *sc;
  487         int maj, mn;
  488         int s;
  489 
  490         sc = (struct audio_softc *)self;
  491         DPRINTF(("audio_detach: sc=%p flags=%d\n", sc, flags));
  492 
  493         sc->sc_dying = TRUE;
  494 
  495         wakeup(&sc->sc_wchan);
  496         wakeup(&sc->sc_rchan);
  497         s = splaudio();
  498         if (--sc->sc_refcnt >= 0) {
  499                 if (tsleep(&sc->sc_refcnt, PZERO, "auddet", hz * 120))
  500                         printf("audiodetach: %s didn't detach\n",
  501                                sc->dev.dv_xname);
  502         }
  503         splx(s);
  504 
  505         /* free resources */
  506         audio_free_ring(sc, &sc->sc_pr);
  507         audio_free_ring(sc, &sc->sc_rr);
  508         audio_destruct_pfilters(sc);
  509         audio_destruct_rfilters(sc);
  510 
  511         /* locate the major number */
  512         maj = cdevsw_lookup_major(&audio_cdevsw);
  513 
  514         /* Nuke the vnodes for any open instances (calls close). */
  515         mn = device_unit(self);
  516         vdevgone(maj, mn | SOUND_DEVICE,    mn | SOUND_DEVICE, VCHR);
  517         vdevgone(maj, mn | AUDIO_DEVICE,    mn | AUDIO_DEVICE, VCHR);
  518         vdevgone(maj, mn | AUDIOCTL_DEVICE, mn | AUDIOCTL_DEVICE, VCHR);
  519         vdevgone(maj, mn | MIXER_DEVICE,    mn | MIXER_DEVICE, VCHR);
  520 
  521         if (sc->sc_powerhook != NULL) {
  522                 powerhook_disestablish(sc->sc_powerhook);
  523                 sc->sc_powerhook = NULL;
  524         }
  525 
  526         return 0;
  527 }
  528 
  529 int
  530 au_portof(struct audio_softc *sc, char *name, int class)
  531 {
  532         mixer_devinfo_t mi;
  533 
  534         for(mi.index = 0;
  535             sc->hw_if->query_devinfo(sc->hw_hdl, &mi) == 0;
  536             mi.index++)
  537                 if (mi.mixer_class == class && strcmp(mi.label.name, name) == 0)
  538                         return mi.index;
  539         return -1;
  540 }
  541 
  542 void
  543 au_setup_ports(struct audio_softc *sc, struct au_mixer_ports *ports,
  544                mixer_devinfo_t *mi, const struct portname *tbl)
  545 {
  546         int i, j;
  547 
  548         ports->index = mi->index;
  549         if (mi->type == AUDIO_MIXER_ENUM) {
  550                 ports->isenum = TRUE;
  551                 for(i = 0; tbl[i].name; i++)
  552                     for(j = 0; j < mi->un.e.num_mem; j++)
  553                         if (strcmp(mi->un.e.member[j].label.name,
  554                                                             tbl[i].name) == 0) {
  555                                 ports->allports |= tbl[i].mask;
  556                                 ports->aumask[ports->nports] = tbl[i].mask;
  557                                 ports->misel[ports->nports] =
  558                                     mi->un.e.member[j].ord;
  559                                 ports->miport[ports->nports] =
  560                                     au_portof(sc, mi->un.e.member[j].label.name,
  561                                     mi->mixer_class);
  562                                 if (ports->mixerout != -1 &&
  563                                     ports->miport[ports->nports] != -1)
  564                                         ports->isdual = TRUE;
  565                                 ++ports->nports;
  566                         }
  567         } else if (mi->type == AUDIO_MIXER_SET) {
  568                 for(i = 0; tbl[i].name; i++)
  569                     for(j = 0; j < mi->un.s.num_mem; j++)
  570                         if (strcmp(mi->un.s.member[j].label.name,
  571                                                             tbl[i].name) == 0) {
  572                                 ports->allports |= tbl[i].mask;
  573                                 ports->aumask[ports->nports] = tbl[i].mask;
  574                                 ports->misel[ports->nports] =
  575                                     mi->un.s.member[j].mask;
  576                                 ports->miport[ports->nports] =
  577                                     au_portof(sc, mi->un.s.member[j].label.name,
  578                                     mi->mixer_class);
  579                                 ++ports->nports;
  580                         }
  581         }
  582 }
  583 
  584 /*
  585  * Called from hardware driver.  This is where the MI audio driver gets
  586  * probed/attached to the hardware driver.
  587  */
  588 struct device *
  589 audio_attach_mi(const struct audio_hw_if *ahwp, void *hdlp, struct device *dev)
  590 {
  591         struct audio_attach_args arg;
  592 
  593 #ifdef DIAGNOSTIC
  594         if (ahwp == NULL) {
  595                 aprint_error("audio_attach_mi: NULL\n");
  596                 return 0;
  597         }
  598 #endif
  599         arg.type = AUDIODEV_TYPE_AUDIO;
  600         arg.hwif = ahwp;
  601         arg.hdl = hdlp;
  602         return config_found(dev, &arg, audioprint);
  603 }
  604 
  605 #ifdef AUDIO_DEBUG
  606 void    audio_printsc(struct audio_softc *);
  607 void    audio_print_params(const char *, struct audio_params *);
  608 
  609 void
  610 audio_printsc(struct audio_softc *sc)
  611 {
  612         printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if);
  613         printf("open 0x%x mode 0x%x\n", sc->sc_open, sc->sc_mode);
  614         printf("rchan 0x%x wchan 0x%x ", sc->sc_rchan, sc->sc_wchan);
  615         printf("rring used 0x%x pring used=%d\n",
  616                audio_stream_get_used(&sc->sc_rr.s),
  617                audio_stream_get_used(&sc->sc_pr.s));
  618         printf("rbus 0x%x pbus 0x%x ", sc->sc_rbus, sc->sc_pbus);
  619         printf("blksize %d", sc->sc_pr.blksize);
  620         printf("hiwat %d lowat %d\n", sc->sc_pr.usedhigh, sc->sc_pr.usedlow);
  621 }
  622 
  623 void
  624 audio_print_params(const char *s, struct audio_params *p)
  625 {
  626         printf("%s enc=%u %uch %u/%ubit %uHz\n", s, p->encoding, p->channels,
  627                p->validbits, p->precision, p->sample_rate);
  628 }
  629 #endif
  630 
  631 int
  632 audio_alloc_ring(struct audio_softc *sc, struct audio_ringbuffer *r,
  633                  int direction, size_t bufsize)
  634 {
  635         const struct audio_hw_if *hw;
  636         void *hdl;
  637 
  638         hw = sc->hw_if;
  639         hdl = sc->hw_hdl;
  640         /*
  641          * Alloc DMA play and record buffers
  642          */
  643         if (bufsize < AUMINBUF)
  644                 bufsize = AUMINBUF;
  645         ROUNDSIZE(bufsize);
  646         if (hw->round_buffersize)
  647                 bufsize = hw->round_buffersize(hdl, direction, bufsize);
  648         if (hw->allocm)
  649                 r->s.start = hw->allocm(hdl, direction, bufsize,
  650                                         M_DEVBUF, M_WAITOK);
  651         else
  652                 r->s.start = malloc(bufsize, M_DEVBUF, M_WAITOK);
  653         if (r->s.start == 0)
  654                 return ENOMEM;
  655         r->s.bufsize = bufsize;
  656         return 0;
  657 }
  658 
  659 void
  660 audio_free_ring(struct audio_softc *sc, struct audio_ringbuffer *r)
  661 {
  662 
  663         if (sc->hw_if->freem)
  664                 sc->hw_if->freem(sc->hw_hdl, r->s.start, M_DEVBUF);
  665         else
  666                 free(r->s.start, M_DEVBUF);
  667         r->s.start = 0;
  668 }
  669 
  670 static int
  671 audio_setup_pfilters(struct audio_softc *sc, const audio_params_t *pp,
  672                      stream_filter_list_t *pfilters)
  673 {
  674         stream_filter_t *pf[AUDIO_MAX_FILTERS];
  675         audio_stream_t ps[AUDIO_MAX_FILTERS];
  676         const audio_params_t *from_param;
  677         audio_params_t *to_param;
  678         int i, n;
  679 
  680         while (sc->sc_writing) {
  681                 sc->sc_waitcomp = 1;
  682                 (void)tsleep(sc, 0, "audioch", 10*hz);
  683         }
  684 
  685         memset(pf, 0, sizeof(pf));
  686         memset(ps, 0, sizeof(ps));
  687         from_param = pp;
  688         for (i = 0; i < pfilters->req_size; i++) {
  689                 n = pfilters->req_size - i - 1;
  690                 to_param = &pfilters->filters[n].param;
  691                 audio_check_params(to_param);
  692                 pf[i] = pfilters->filters[n].factory(sc, from_param, to_param);
  693                 if (pf[i] == NULL)
  694                         break;
  695                 if (audio_stream_ctor(&ps[i], from_param, AU_RING_SIZE))
  696                         break;
  697                 if (i > 0)
  698                         pf[i]->set_fetcher(pf[i], &pf[i - 1]->base);
  699                 from_param = to_param;
  700         }
  701         if (i < pfilters->req_size) { /* failure */
  702                 DPRINTF(("%s: pfilters failure\n", __func__));
  703                 for (; i >= 0; i--) {
  704                         if (pf[i] != NULL)
  705                                 pf[i]->dtor(pf[i]);
  706                         audio_stream_dtor(&ps[i]);
  707                 }
  708                 sc->sc_waitcomp = 0;
  709                 return EINVAL;
  710         }
  711 
  712         audio_destruct_pfilters(sc);
  713         memcpy(sc->sc_pfilters, pf, sizeof(pf));
  714         memcpy(sc->sc_pstreams, ps, sizeof(ps));
  715         sc->sc_npfilters = pfilters->req_size;
  716         for (i = 0; i < pfilters->req_size; i++) {
  717                 pf[i]->set_inputbuffer(pf[i], &sc->sc_pstreams[i]);
  718         }
  719 
  720         /* hardware format and the buffer near to userland */
  721         if (pfilters->req_size <= 0) {
  722                 sc->sc_pr.s.param = *pp;
  723                 sc->sc_pustream = &sc->sc_pr.s;
  724         } else {
  725                 sc->sc_pr.s.param = pfilters->filters[0].param;
  726                 sc->sc_pustream = &sc->sc_pstreams[0];
  727         }
  728 #ifdef AUDIO_DEBUG
  729         printf("%s: HW-buffer=%p pustream=%p\n",
  730                __func__, &sc->sc_pr.s, sc->sc_pustream);
  731         for (i = 0; i < pfilters->req_size; i++) {
  732                 char num[100];
  733                 snprintf(num, 100, "[%d]", i);
  734                 audio_print_params(num, &sc->sc_pstreams[i].param);
  735         }
  736         audio_print_params("[HW]", &sc->sc_pr.s.param);
  737 #endif /* AUDIO_DEBUG */
  738 
  739         sc->sc_waitcomp = 0;
  740         return 0;
  741 }
  742 
  743 static int
  744 audio_setup_rfilters(struct audio_softc *sc, const audio_params_t *rp,
  745                      stream_filter_list_t *rfilters)
  746 {
  747         stream_filter_t *rf[AUDIO_MAX_FILTERS];
  748         audio_stream_t rs[AUDIO_MAX_FILTERS];
  749         const audio_params_t *to_param;
  750         audio_params_t *from_param;
  751         int i;
  752 
  753         memset(rf, 0, sizeof(rf));
  754         memset(rs, 0, sizeof(rs));
  755         for (i = 0; i < rfilters->req_size; i++) {
  756                 from_param = &rfilters->filters[i].param;
  757                 audio_check_params(from_param);
  758                 to_param = i + 1 < rfilters->req_size
  759                         ? &rfilters->filters[i + 1].param : rp;
  760                 rf[i] = rfilters->filters[i].factory(sc, from_param, to_param);
  761                 if (rf[i] == NULL)
  762                         break;
  763                 if (audio_stream_ctor(&rs[i], to_param, AU_RING_SIZE))
  764                         break;
  765                 if (i > 0) {
  766                         rf[i]->set_fetcher(rf[i], &rf[i - 1]->base);
  767                 } else {
  768                         /* rf[0] has no previous fetcher because
  769                          * the audio hardware fills data to the
  770                          * input buffer. */
  771                         rf[0]->set_inputbuffer(rf[0], &sc->sc_rr.s);
  772                 }
  773         }
  774         if (i < rfilters->req_size) { /* failure */
  775                 DPRINTF(("%s: rfilters failure\n", __func__));
  776                 for (; i >= 0; i--) {
  777                         if (rf[i] != NULL)
  778                                 rf[i]->dtor(rf[i]);
  779                         audio_stream_dtor(&rs[i]);
  780                 }
  781                 return EINVAL;
  782         }
  783 
  784         audio_destruct_rfilters(sc);
  785         memcpy(sc->sc_rfilters, rf, sizeof(rf));
  786         memcpy(sc->sc_rstreams, rs, sizeof(rs));
  787         sc->sc_nrfilters = rfilters->req_size;
  788         for (i = 1; i < rfilters->req_size; i++) {
  789                 rf[i]->set_inputbuffer(rf[i], &sc->sc_rstreams[i - 1]);
  790         }
  791 
  792         /* hardware format and the buffer near to userland */
  793         if (rfilters->req_size <= 0) {
  794                 sc->sc_rr.s.param = *rp;
  795                 sc->sc_rustream = &sc->sc_rr.s;
  796         } else {
  797                 sc->sc_rr.s.param = rfilters->filters[0].param;
  798                 sc->sc_rustream = &sc->sc_rstreams[rfilters->req_size - 1];
  799         }
  800 #ifdef AUDIO_DEBUG
  801         printf("%s: HW-buffer=%p pustream=%p\n",
  802                __func__, &sc->sc_rr.s, sc->sc_rustream);
  803         audio_print_params("[HW]", &sc->sc_rr.s.param);
  804         for (i = 0; i < rfilters->req_size; i++) {
  805                 char num[100];
  806                 snprintf(num, 100, "[%d]", i);
  807                 audio_print_params(num, &sc->sc_rstreams[i].param);
  808         }
  809 #endif /* AUDIO_DEBUG */
  810         return 0;
  811 }
  812 
  813 static void
  814 audio_destruct_pfilters(struct audio_softc *sc)
  815 {
  816         int i;
  817 
  818         for (i = 0; i < sc->sc_npfilters; i++) {
  819                 sc->sc_pfilters[i]->dtor(sc->sc_pfilters[i]);
  820                 sc->sc_pfilters[i] = NULL;
  821                 audio_stream_dtor(&sc->sc_pstreams[i]);
  822         }
  823         sc->sc_npfilters = 0;
  824 }
  825 
  826 static void
  827 audio_destruct_rfilters(struct audio_softc *sc)
  828 {
  829         int i;
  830 
  831         for (i = 0; i < sc->sc_nrfilters; i++) {
  832                 sc->sc_rfilters[i]->dtor(sc->sc_rfilters[i]);
  833                 sc->sc_rfilters[i] = NULL;
  834                 audio_stream_dtor(&sc->sc_rstreams[i]);
  835         }
  836         sc->sc_nrfilters = 0;
  837 }
  838 
  839 static void
  840 audio_stream_dtor(audio_stream_t *stream)
  841 {
  842 
  843         if (stream->start != NULL)
  844                 free(stream->start, M_DEVBUF);
  845         memset(stream, 0, sizeof(audio_stream_t));
  846 }
  847 
  848 static int
  849 audio_stream_ctor(audio_stream_t *stream, const audio_params_t *param, int size)
  850 {
  851         int frame_size;
  852 
  853         size = min(size, AU_RING_SIZE);
  854         stream->bufsize = size;
  855         stream->start = malloc(size, M_DEVBUF, M_WAITOK);
  856         if (stream->start == NULL)
  857                 return ENOMEM;
  858         frame_size = (param->precision + 7) / 8 * param->channels;
  859         size = (size / frame_size) * frame_size;
  860         stream->end = stream->start + size;
  861         stream->inp = stream->start;
  862         stream->outp = stream->start;
  863         stream->used = 0;
  864         stream->param = *param;
  865         stream->loop = FALSE;
  866         return 0;
  867 }
  868 
  869 static void
  870 stream_filter_list_append(stream_filter_list_t *list,
  871                           stream_filter_factory_t factory,
  872                           const audio_params_t *param)
  873 {
  874 
  875         if (list->req_size >= AUDIO_MAX_FILTERS) {
  876                 printf("%s: increase AUDIO_MAX_FILTERS in sys/dev/audio_if.h\n",
  877                        __func__);
  878                 return;
  879         }
  880         list->filters[list->req_size].factory = factory;
  881         list->filters[list->req_size].param = *param;
  882         list->req_size++;
  883 }
  884 
  885 static void
  886 stream_filter_list_set(stream_filter_list_t *list, int i,
  887                        stream_filter_factory_t factory,
  888                        const audio_params_t *param)
  889 {
  890 
  891         if (i < 0 || i >= AUDIO_MAX_FILTERS) {
  892                 printf("%s: invalid index: %d\n", __func__, i);
  893                 return;
  894         }
  895 
  896         list->filters[i].factory = factory;
  897         list->filters[i].param = *param;
  898         if (list->req_size <= i)
  899                 list->req_size = i + 1;
  900 }
  901 
  902 static void
  903 stream_filter_list_prepend(stream_filter_list_t *list,
  904                            stream_filter_factory_t factory,
  905                            const audio_params_t *param)
  906 {
  907 
  908         if (list->req_size >= AUDIO_MAX_FILTERS) {
  909                 printf("%s: increase AUDIO_MAX_FILTERS in sys/dev/audio_if.h\n",
  910                        __func__);
  911                 return;
  912         }
  913         memmove(&list->filters[1], &list->filters[0],
  914                 sizeof(struct stream_filter_req) * list->req_size);
  915         list->filters[0].factory = factory;
  916         list->filters[0].param = *param;
  917         list->req_size++;
  918 }
  919 
  920 int
  921 audioopen(dev_t dev, int flags, int ifmt, struct lwp *l)
  922 {
  923         struct audio_softc *sc;
  924         int error;
  925 
  926         sc = device_lookup(&audio_cd, AUDIOUNIT(dev));
  927         if (sc == NULL)
  928                 return ENXIO;
  929 
  930         if (sc->sc_dying)
  931                 return EIO;
  932 
  933         if (sc->hw_if->powerstate && sc->sc_opencnt <= 0)
  934                 sc->hw_if->powerstate(sc->hw_hdl, AUDIOPOWER_ON);
  935         sc->sc_opencnt++;
  936 
  937         sc->sc_refcnt++;
  938         switch (AUDIODEV(dev)) {
  939         case SOUND_DEVICE:
  940         case AUDIO_DEVICE:
  941                 error = audio_open(dev, sc, flags, ifmt, l);
  942                 break;
  943         case AUDIOCTL_DEVICE:
  944                 error = 0;
  945                 break;
  946         case MIXER_DEVICE:
  947                 error = mixer_open(dev, sc, flags, ifmt, l);
  948                 break;
  949         default:
  950                 error = ENXIO;
  951                 break;
  952         }
  953         if (--sc->sc_refcnt < 0)
  954                 wakeup(&sc->sc_refcnt);
  955         return error;
  956 }
  957 
  958 int
  959 audioclose(dev_t dev, int flags, int ifmt, struct lwp *l)
  960 {
  961         struct audio_softc *sc;
  962         int unit;
  963         int error;
  964 
  965         unit = AUDIOUNIT(dev);
  966         sc = audio_cd.cd_devs[unit];
  967         switch (AUDIODEV(dev)) {
  968         case SOUND_DEVICE:
  969         case AUDIO_DEVICE:
  970                 error = audio_close(sc, flags, ifmt, l);
  971                 break;
  972         case MIXER_DEVICE:
  973                 error = mixer_close(sc, flags, ifmt, l);
  974                 break;
  975         case AUDIOCTL_DEVICE:
  976                 error = 0;
  977                 break;
  978         default:
  979                 error = ENXIO;
  980                 break;
  981         }
  982 
  983         sc->sc_opencnt--;
  984         if (sc->hw_if->powerstate && sc->sc_opencnt <= 0)
  985                 sc->hw_if->powerstate(sc->hw_hdl, AUDIOPOWER_OFF);
  986 
  987         return error;
  988 }
  989 
  990 int
  991 audioread(dev_t dev, struct uio *uio, int ioflag)
  992 {
  993         struct audio_softc *sc;
  994         int error;
  995 
  996         sc = device_lookup(&audio_cd, AUDIOUNIT(dev));
  997         if (sc == NULL)
  998                 return ENXIO;
  999 
 1000         if (sc->sc_dying)
 1001                 return EIO;
 1002 
 1003         sc->sc_refcnt++;
 1004         switch (AUDIODEV(dev)) {
 1005         case SOUND_DEVICE:
 1006         case AUDIO_DEVICE:
 1007                 error = audio_read(sc, uio, ioflag);
 1008                 break;
 1009         case AUDIOCTL_DEVICE:
 1010         case MIXER_DEVICE:
 1011                 error = ENODEV;
 1012                 break;
 1013         default:
 1014                 error = ENXIO;
 1015                 break;
 1016         }
 1017         if (--sc->sc_refcnt < 0)
 1018                 wakeup(&sc->sc_refcnt);
 1019         return error;
 1020 }
 1021 
 1022 int
 1023 audiowrite(dev_t dev, struct uio *uio, int ioflag)
 1024 {
 1025         struct audio_softc *sc;
 1026         int error;
 1027 
 1028         sc = device_lookup(&audio_cd, AUDIOUNIT(dev));
 1029         if (sc == NULL)
 1030                 return ENXIO;
 1031 
 1032         if (sc->sc_dying)
 1033                 return EIO;
 1034 
 1035         sc->sc_refcnt++;
 1036         switch (AUDIODEV(dev)) {
 1037         case SOUND_DEVICE:
 1038         case AUDIO_DEVICE:
 1039                 error = audio_write(sc, uio, ioflag);
 1040                 break;
 1041         case AUDIOCTL_DEVICE:
 1042         case MIXER_DEVICE:
 1043                 error = ENODEV;
 1044                 break;
 1045         default:
 1046                 error = ENXIO;
 1047                 break;
 1048         }
 1049         if (--sc->sc_refcnt < 0)
 1050                 wakeup(&sc->sc_refcnt);
 1051         return error;
 1052 }
 1053 
 1054 int
 1055 audioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct lwp *l)
 1056 {
 1057         struct audio_softc *sc;
 1058         int error;
 1059 
 1060         sc = audio_cd.cd_devs[AUDIOUNIT(dev)];
 1061         if (sc->sc_dying)
 1062                 return EIO;
 1063 
 1064         sc->sc_refcnt++;
 1065         switch (AUDIODEV(dev)) {
 1066         case SOUND_DEVICE:
 1067         case AUDIO_DEVICE:
 1068         case AUDIOCTL_DEVICE:
 1069                 error = audio_ioctl(sc, cmd, addr, flag, l);
 1070                 break;
 1071         case MIXER_DEVICE:
 1072                 error = mixer_ioctl(sc, cmd, addr, flag, l);
 1073                 break;
 1074         default:
 1075                 error = ENXIO;
 1076                 break;
 1077         }
 1078         if (--sc->sc_refcnt < 0)
 1079                 wakeup(&sc->sc_refcnt);
 1080         return error;
 1081 }
 1082 
 1083 int
 1084 audiopoll(dev_t dev, int events, struct lwp *l)
 1085 {
 1086         struct audio_softc *sc;
 1087         int revents;
 1088 
 1089         sc = audio_cd.cd_devs[AUDIOUNIT(dev)];
 1090         if (sc->sc_dying)
 1091                 return POLLHUP;
 1092 
 1093         sc->sc_refcnt++;
 1094         switch (AUDIODEV(dev)) {
 1095         case SOUND_DEVICE:
 1096         case AUDIO_DEVICE:
 1097                 revents = audio_poll(sc, events, l);
 1098                 break;
 1099         case AUDIOCTL_DEVICE:
 1100         case MIXER_DEVICE:
 1101                 revents = 0;
 1102                 break;
 1103         default:
 1104                 revents = POLLERR;
 1105                 break;
 1106         }
 1107         if (--sc->sc_refcnt < 0)
 1108                 wakeup(&sc->sc_refcnt);
 1109         return revents;
 1110 }
 1111 
 1112 int
 1113 audiokqfilter(dev_t dev, struct knote *kn)
 1114 {
 1115         struct audio_softc *sc;
 1116         int rv;
 1117 
 1118         sc = audio_cd.cd_devs[AUDIOUNIT(dev)];
 1119         if (sc->sc_dying)
 1120                 return 1;
 1121 
 1122         sc->sc_refcnt++;
 1123         switch (AUDIODEV(dev)) {
 1124         case SOUND_DEVICE:
 1125         case AUDIO_DEVICE:
 1126                 rv = audio_kqfilter(sc, kn);
 1127                 break;
 1128         case AUDIOCTL_DEVICE:
 1129         case MIXER_DEVICE:
 1130                 rv = 1;
 1131                 break;
 1132         default:
 1133                 rv = 1;
 1134         }
 1135         if (--sc->sc_refcnt < 0)
 1136                 wakeup(&sc->sc_refcnt);
 1137         return rv;
 1138 }
 1139 
 1140 paddr_t
 1141 audiommap(dev_t dev, off_t off, int prot)
 1142 {
 1143         struct audio_softc *sc;
 1144         paddr_t error;
 1145 
 1146         sc = audio_cd.cd_devs[AUDIOUNIT(dev)];
 1147         if (sc->sc_dying)
 1148                 return -1;
 1149 
 1150         sc->sc_refcnt++;
 1151         switch (AUDIODEV(dev)) {
 1152         case SOUND_DEVICE:
 1153         case AUDIO_DEVICE:
 1154                 error = audio_mmap(sc, off, prot);
 1155                 break;
 1156         case AUDIOCTL_DEVICE:
 1157         case MIXER_DEVICE:
 1158                 error = -1;
 1159                 break;
 1160         default:
 1161                 error = -1;
 1162                 break;
 1163         }
 1164         if (--sc->sc_refcnt < 0)
 1165                 wakeup(&sc->sc_refcnt);
 1166         return error;
 1167 }
 1168 
 1169 /*
 1170  * Audio driver
 1171  */
 1172 void
 1173 audio_init_ringbuffer(struct audio_softc *sc, struct audio_ringbuffer *rp,
 1174                       int mode)
 1175 {
 1176         int nblks;
 1177         int blksize;
 1178 
 1179         blksize = rp->blksize;
 1180         if (blksize < AUMINBLK)
 1181                 blksize = AUMINBLK;
 1182         if (blksize > rp->s.bufsize / AUMINNOBLK)
 1183                 blksize = rp->s.bufsize / AUMINNOBLK;
 1184         ROUNDSIZE(blksize);
 1185         DPRINTF(("audio_init_ringbuffer: MI blksize=%d\n", blksize));
 1186         if (sc->hw_if->round_blocksize)
 1187                 blksize = sc->hw_if->round_blocksize(sc->hw_hdl, blksize,
 1188                                                      mode, &rp->s.param);
 1189         if (blksize <= 0)
 1190                 panic("audio_init_ringbuffer: blksize");
 1191         nblks = rp->s.bufsize / blksize;
 1192 
 1193         DPRINTF(("audio_init_ringbuffer: final blksize=%d\n", blksize));
 1194         rp->blksize = blksize;
 1195         rp->maxblks = nblks;
 1196         rp->s.end = rp->s.start + nblks * blksize;
 1197         rp->s.outp = rp->s.inp = rp->s.start;
 1198         rp->s.used = 0;
 1199         rp->stamp = 0;
 1200         rp->stamp_last = 0;
 1201         rp->fstamp = 0;
 1202         rp->drops = 0;
 1203         rp->pause = FALSE;
 1204         rp->copying = FALSE;
 1205         rp->needfill = FALSE;
 1206         rp->mmapped = FALSE;
 1207 }
 1208 
 1209 int
 1210 audio_initbufs(struct audio_softc *sc)
 1211 {
 1212         const struct audio_hw_if *hw;
 1213         int error;
 1214 
 1215         DPRINTF(("audio_initbufs: mode=0x%x\n", sc->sc_mode));
 1216         hw = sc->hw_if;
 1217         audio_init_ringbuffer(sc, &sc->sc_rr, AUMODE_RECORD);
 1218         if (hw->init_input && (sc->sc_mode & AUMODE_RECORD)) {
 1219                 error = hw->init_input(sc->hw_hdl, sc->sc_rr.s.start,
 1220                                        sc->sc_rr.s.end - sc->sc_rr.s.start);
 1221                 if (error)
 1222                         return error;
 1223         }
 1224 
 1225         audio_init_ringbuffer(sc, &sc->sc_pr, AUMODE_PLAY);
 1226         sc->sc_sil_count = 0;
 1227         if (hw->init_output && (sc->sc_mode & AUMODE_PLAY)) {
 1228                 error = hw->init_output(sc->hw_hdl, sc->sc_pr.s.start,
 1229                                         sc->sc_pr.s.end - sc->sc_pr.s.start);
 1230                 if (error)
 1231                         return error;
 1232         }
 1233 
 1234 #ifdef AUDIO_INTR_TIME
 1235 #define double u_long
 1236         sc->sc_pnintr = 0;
 1237         sc->sc_pblktime = (u_long)(
 1238             (double)sc->sc_pr.blksize * 100000 /
 1239             (double)(sc->sc_pparams.precision / NBBY *
 1240                      sc->sc_pparams.channels *
 1241                      sc->sc_pparams.sample_rate)) * 10;
 1242         DPRINTF(("audio: play blktime = %lu for %d\n",
 1243                  sc->sc_pblktime, sc->sc_pr.blksize));
 1244         sc->sc_rnintr = 0;
 1245         sc->sc_rblktime = (u_long)(
 1246             (double)sc->sc_rr.blksize * 100000 /
 1247             (double)(sc->sc_rparams.precision / NBBY *
 1248                      sc->sc_rparams.channels *
 1249                      sc->sc_rparams.sample_rate)) * 10;
 1250         DPRINTF(("audio: record blktime = %lu for %d\n",
 1251                  sc->sc_rblktime, sc->sc_rr.blksize));
 1252 #undef double
 1253 #endif
 1254 
 1255         return 0;
 1256 }
 1257 
 1258 void
 1259 audio_calcwater(struct audio_softc *sc)
 1260 {
 1261 
 1262         /* set high at 100% */
 1263         sc->sc_pr.usedhigh = sc->sc_pustream->end - sc->sc_pustream->start;
 1264         /* set low at 75% of usedhigh */
 1265         sc->sc_pr.usedlow = sc->sc_pr.usedhigh * 3 / 4;
 1266         if (sc->sc_pr.usedlow == sc->sc_pr.usedhigh)
 1267                 sc->sc_pr.usedlow -= sc->sc_pr.blksize;
 1268 
 1269         sc->sc_rr.usedhigh = sc->sc_rustream->end - sc->sc_rustream->start
 1270                 - sc->sc_rr.blksize;
 1271         sc->sc_rr.usedlow = 0;
 1272         DPRINTF(("%s: plow=%d phigh=%d rlow=%d rhigh=%d\n", __func__,
 1273                  sc->sc_pr.usedlow, sc->sc_pr.usedhigh,
 1274                  sc->sc_rr.usedlow, sc->sc_rr.usedhigh));
 1275 }
 1276 
 1277 static inline int
 1278 audio_sleep_timo(int *chan, const char *label, int timo)
 1279 {
 1280         int st;
 1281 
 1282         if (label == NULL)
 1283                 label = "audio";
 1284 
 1285         DPRINTFN(3, ("audio_sleep_timo: chan=%p, label=%s, timo=%d\n",
 1286                      chan, label, timo));
 1287         *chan = 1;
 1288         st = tsleep(chan, PWAIT | PCATCH, label, timo);
 1289         *chan = 0;
 1290 #ifdef AUDIO_DEBUG
 1291         if (st != 0 && st != EINTR)
 1292             DPRINTF(("audio_sleep: woke up st=%d\n", st));
 1293 #endif
 1294         return st;
 1295 }
 1296 
 1297 static inline int
 1298 audio_sleep(int *chan, const char *label)
 1299 {
 1300 
 1301         return audio_sleep_timo(chan, label, 0);
 1302 }
 1303 
 1304 /* call at splaudio() */
 1305 static inline void
 1306 audio_wakeup(int *chan)
 1307 {
 1308 
 1309         DPRINTFN(3, ("audio_wakeup: chan=%p, *chan=%d\n", chan, *chan));
 1310         if (*chan) {
 1311                 wakeup(chan);
 1312                 *chan = 0;
 1313         }
 1314 }
 1315 
 1316 int
 1317 audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
 1318     struct lwp *l)
 1319 {
 1320         int error;
 1321         u_int mode;
 1322         const struct audio_hw_if *hw;
 1323 
 1324         hw = sc->hw_if;
 1325         if (hw == NULL)
 1326                 return ENXIO;
 1327 
 1328         DPRINTF(("audio_open: flags=0x%x sc=%p hdl=%p\n",
 1329                  flags, sc, sc->hw_hdl));
 1330 
 1331         if (((flags & FREAD) && (sc->sc_open & AUOPEN_READ)) ||
 1332             ((flags & FWRITE) && (sc->sc_open & AUOPEN_WRITE)))
 1333                 return EBUSY;
 1334 
 1335         if (hw->open != NULL) {
 1336                 error = hw->open(sc->hw_hdl, flags);
 1337                 if (error)
 1338                         return error;
 1339         }
 1340 
 1341         sc->sc_async_audio = 0;
 1342         sc->sc_rchan = 0;
 1343         sc->sc_wchan = 0;
 1344         sc->sc_sil_count = 0;
 1345         sc->sc_rbus = FALSE;
 1346         sc->sc_pbus = FALSE;
 1347         sc->sc_eof = 0;
 1348         sc->sc_playdrop = 0;
 1349 
 1350         sc->sc_full_duplex = 
 1351                 (flags & (FWRITE|FREAD)) == (FWRITE|FREAD) &&
 1352                 (hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX);
 1353 
 1354         mode = 0;
 1355         if (flags & FREAD) {
 1356                 sc->sc_open |= AUOPEN_READ;
 1357                 mode |= AUMODE_RECORD;
 1358         }
 1359         if (flags & FWRITE) {
 1360                 sc->sc_open |= AUOPEN_WRITE;
 1361                 mode |= AUMODE_PLAY | AUMODE_PLAY_ALL;
 1362         }
 1363 
 1364         /*
 1365          * Multiplex device: /dev/audio (MU-Law) and /dev/sound (linear)
 1366          * The /dev/audio is always (re)set to 8-bit MU-Law mono
 1367          * For the other devices, you get what they were last set to.
 1368          */
 1369         if (ISDEVAUDIO(dev)) {
 1370                 error = audio_set_defaults(sc, mode);
 1371         } else {
 1372                 struct audio_info ai;
 1373 
 1374                 AUDIO_INITINFO(&ai);
 1375                 ai.mode = mode;
 1376                 error = audiosetinfo(sc, &ai);
 1377         }
 1378         if (error)
 1379                 goto bad;
 1380 
 1381 #ifdef DIAGNOSTIC
 1382         /*
 1383          * Sample rate and precision are supposed to be set to proper
 1384          * default values by the hardware driver, so that it may give
 1385          * us these values.
 1386          */
 1387         if (sc->sc_rparams.precision == 0 || sc->sc_pparams.precision == 0) {
 1388                 printf("audio_open: 0 precision\n");
 1389                 return EINVAL;
 1390         }
 1391 #endif
 1392 
 1393         /* audio_close() decreases sc_pr.usedlow, recalculate here */
 1394         audio_calcwater(sc);
 1395 
 1396         DPRINTF(("audio_open: done sc_mode = 0x%x\n", sc->sc_mode));
 1397 
 1398         return 0;
 1399 
 1400 bad:
 1401         if (hw->close != NULL)
 1402                 hw->close(sc->hw_hdl);
 1403         sc->sc_open = 0;
 1404         sc->sc_mode = 0;
 1405         sc->sc_full_duplex = 0;
 1406         return error;
 1407 }
 1408 
 1409 /*
 1410  * Must be called from task context.
 1411  */
 1412 void
 1413 audio_init_record(struct audio_softc *sc)
 1414 {
 1415         int s;
 1416 
 1417         s = splaudio();
 1418         if (sc->hw_if->speaker_ctl &&
 1419             (!sc->sc_full_duplex || (sc->sc_mode & AUMODE_PLAY) == 0))
 1420                 sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_OFF);
 1421         splx(s);
 1422 }
 1423 
 1424 /*
 1425  * Must be called from task context.
 1426  */
 1427 void
 1428 audio_init_play(struct audio_softc *sc)
 1429 {
 1430         int s;
 1431 
 1432         s = splaudio();
 1433         sc->sc_wstamp = sc->sc_pr.stamp;
 1434         if (sc->hw_if->speaker_ctl)
 1435                 sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_ON);
 1436         splx(s);
 1437 }
 1438 
 1439 int
 1440 audio_drain(struct audio_softc *sc)
 1441 {
 1442         struct audio_ringbuffer *cb;
 1443         int error, drops;
 1444         int s;
 1445         int i, used;
 1446 
 1447         DPRINTF(("audio_drain: enter busy=%d\n", sc->sc_pbus));
 1448         cb = &sc->sc_pr;
 1449         if (cb->mmapped)
 1450                 return 0;
 1451 
 1452         used = audio_stream_get_used(&sc->sc_pr.s);
 1453         s = splaudio();
 1454         for (i = 0; i < sc->sc_npfilters; i++)
 1455                 used += audio_stream_get_used(&sc->sc_pstreams[i]);
 1456         splx(s);
 1457         if (used <= 0)
 1458                 return 0;
 1459 
 1460         if (!sc->sc_pbus) {
 1461                 /* We've never started playing, probably because the
 1462                  * block was too short.  Pad it and start now.
 1463                  */
 1464                 int cc;
 1465                 uint8_t *inp = cb->s.inp;
 1466 
 1467                 cc = cb->blksize - (inp - cb->s.start) % cb->blksize;
 1468                 audio_fill_silence(&cb->s.param, inp, cc);
 1469                 s = splaudio();
 1470                 cb->s.inp = audio_stream_add_inp(&cb->s, inp, cc);
 1471                 error = audiostartp(sc);
 1472                 splx(s);
 1473                 if (error)
 1474                         return error;
 1475         }
 1476         /*
 1477          * Play until a silence block has been played, then we
 1478          * know all has been drained.
 1479          * XXX This should be done some other way to avoid
 1480          * playing silence.
 1481          */
 1482 #ifdef DIAGNOSTIC
 1483         if (cb->copying) {
 1484                 printf("audio_drain: copying in progress!?!\n");
 1485                 cb->copying = FALSE;
 1486         }
 1487 #endif
 1488         drops = cb->drops;
 1489         error = 0;
 1490         s = splaudio();
 1491         while (cb->drops == drops && !error) {
 1492                 DPRINTF(("audio_drain: used=%d, drops=%ld\n",
 1493                          audio_stream_get_used(&sc->sc_pr.s), cb->drops));
 1494                 /*
 1495                  * When the process is exiting, it ignores all signals and
 1496                  * we can't interrupt this sleep, so we set a timeout
 1497                  * just in case.
 1498                  */
 1499                 error = audio_sleep_timo(&sc->sc_wchan, "aud_dr", 30*hz);
 1500                 if (sc->sc_dying)
 1501                         error = EIO;
 1502         }
 1503         splx(s);
 1504         return error;
 1505 }
 1506 
 1507 /*
 1508  * Close an audio chip.
 1509  */
 1510 /* ARGSUSED */
 1511 int
 1512 audio_close(struct audio_softc *sc, int flags, int ifmt,
 1513     struct lwp *l)
 1514 {
 1515         const struct audio_hw_if *hw;
 1516         int s;
 1517 
 1518         DPRINTF(("audio_close: sc=%p\n", sc));
 1519         hw = sc->hw_if;
 1520         s = splaudio();
 1521         /* Stop recording. */
 1522         if ((flags & FREAD) && sc->sc_rbus) {
 1523                 /*
 1524                  * XXX Some drivers (e.g. SB) use the same routine
 1525                  * to halt input and output so don't halt input if
 1526                  * in full duplex mode.  These drivers should be fixed.
 1527                  */
 1528                 if (!sc->sc_full_duplex || hw->halt_input != hw->halt_output)
 1529                         hw->halt_input(sc->hw_hdl);
 1530                 sc->sc_rbus = FALSE;
 1531         }
 1532         /*
 1533          * Block until output drains, but allow ^C interrupt.
 1534          */
 1535         sc->sc_pr.usedlow = sc->sc_pr.blksize;  /* avoid excessive wakeups */
 1536         /*
 1537          * If there is pending output, let it drain (unless
 1538          * the output is paused).
 1539          */
 1540         if ((flags & FWRITE) && sc->sc_pbus) {
 1541                 if (!sc->sc_pr.pause && !audio_drain(sc) && hw->drain)
 1542                         (void)hw->drain(sc->hw_hdl);
 1543                 hw->halt_output(sc->hw_hdl);
 1544                 sc->sc_pbus = FALSE;
 1545         }
 1546 
 1547         if (hw->close != NULL)
 1548                 hw->close(sc->hw_hdl);
 1549 
 1550         sc->sc_open = 0;
 1551         sc->sc_mode = 0;
 1552         sc->sc_async_audio = 0;
 1553         sc->sc_full_duplex = 0;
 1554         splx(s);
 1555         DPRINTF(("audio_close: done\n"));
 1556 
 1557         return 0;
 1558 }
 1559 
 1560 int
 1561 audio_read(struct audio_softc *sc, struct uio *uio, int ioflag)
 1562 {
 1563         struct audio_ringbuffer *cb;
 1564         const uint8_t *outp;
 1565         uint8_t *inp;
 1566         int error, s, used, cc, n;
 1567 
 1568         cb = &sc->sc_rr;
 1569         if (cb->mmapped)
 1570                 return EINVAL;
 1571 
 1572         DPRINTFN(1,("audio_read: cc=%zu mode=%d\n",
 1573                     uio->uio_resid, sc->sc_mode));
 1574 
 1575         error = 0;
 1576         /*
 1577          * If hardware is half-duplex and currently playing, return
 1578          * silence blocks based on the number of blocks we have output.
 1579          */
 1580         if (!sc->sc_full_duplex && (sc->sc_mode & AUMODE_PLAY)) {
 1581                 while (uio->uio_resid > 0 && !error) {
 1582                         s = splaudio();
 1583                         for(;;) {
 1584                                 cc = sc->sc_pr.stamp - sc->sc_wstamp;
 1585                                 if (cc > 0)
 1586                                         break;
 1587                                 DPRINTF(("audio_read: stamp=%lu, wstamp=%lu\n",
 1588                                          sc->sc_pr.stamp, sc->sc_wstamp));
 1589                                 if (ioflag & IO_NDELAY) {
 1590                                         splx(s);
 1591                                         return EWOULDBLOCK;
 1592                                 }
 1593                                 error = audio_sleep(&sc->sc_rchan, "aud_hr");
 1594                                 if (sc->sc_dying)
 1595                                         error = EIO;
 1596                                 if (error) {
 1597                                         splx(s);
 1598                                         return error;
 1599                                 }
 1600                         }
 1601                         splx(s);
 1602 
 1603                         if (uio->uio_resid < cc)
 1604                                 cc = uio->uio_resid;
 1605                         DPRINTFN(1,("audio_read: reading in write mode, "
 1606                                     "cc=%d\n", cc));
 1607                         error = audio_silence_copyout(sc, cc, uio);
 1608                         sc->sc_wstamp += cc;
 1609                 }
 1610                 return error;
 1611         }
 1612 
 1613         while (uio->uio_resid > 0 && !error) {
 1614                 s = splaudio();
 1615                 while ((used = audio_stream_get_used(sc->sc_rustream)) <= 0) {
 1616                         if (!sc->sc_rbus) {
 1617                                 error = audiostartr(sc);
 1618                                 if (error) {
 1619                                         splx(s);
 1620                                         return error;
 1621                                 }
 1622                         }
 1623                         if (ioflag & IO_NDELAY) {
 1624                                 splx(s);
 1625                                 return EWOULDBLOCK;
 1626                         }
 1627                         DPRINTFN(2, ("audio_read: sleep used=%d\n", used));
 1628                         error = audio_sleep(&sc->sc_rchan, "aud_rd");
 1629                         if (sc->sc_dying)
 1630                                 error = EIO;
 1631                         if (error) {
 1632                                 splx(s);
 1633                                 return error;
 1634                         }
 1635                 }
 1636 
 1637                 outp = sc->sc_rustream->outp;
 1638                 inp = sc->sc_rustream->inp;
 1639                 cb->copying = TRUE;
 1640                 splx(s);
 1641 
 1642                 /*
 1643                  * cc is the amount of data in the sc_rustream excluding
 1644                  * wrapped data.  Note the tricky case of inp == outp, which
 1645                  * must mean the buffer is full, not empty, because used > 0.
 1646                  */
 1647                 cc = outp < inp ? inp - outp :sc->sc_rustream->end - outp;
 1648                 DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp, cc));
 1649 
 1650                 n = uio->uio_resid;
 1651                 error = uiomove(__UNCONST(outp), cc, uio);
 1652                 n -= uio->uio_resid; /* number of bytes actually moved */
 1653 
 1654                 s = splaudio();
 1655                 sc->sc_rustream->outp = audio_stream_add_outp
 1656                         (sc->sc_rustream, outp, n);
 1657                 cb->copying = FALSE;
 1658                 splx(s);
 1659         }
 1660         return error;
 1661 }
 1662 
 1663 void
 1664 audio_clear(struct audio_softc *sc)
 1665 {
 1666         int s;
 1667 
 1668         s = splaudio();
 1669         if (sc->sc_rbus) {
 1670                 audio_wakeup(&sc->sc_rchan);
 1671                 sc->hw_if->halt_input(sc->hw_hdl);
 1672                 sc->sc_rbus = FALSE;
 1673         }
 1674         if (sc->sc_pbus) {
 1675                 audio_wakeup(&sc->sc_wchan);
 1676                 sc->hw_if->halt_output(sc->hw_hdl);
 1677                 sc->sc_pbus = FALSE;
 1678         }
 1679         splx(s);
 1680 }
 1681 
 1682 void
 1683 audio_calc_blksize(struct audio_softc *sc, int mode)
 1684 {
 1685         const audio_params_t *parm;
 1686         struct audio_ringbuffer *rb;
 1687 
 1688         if (sc->sc_blkset)
 1689                 return;
 1690 
 1691         if (mode == AUMODE_PLAY) {
 1692                 rb = &sc->sc_pr;
 1693                 parm = &rb->s.param;
 1694         } else {
 1695                 rb = &sc->sc_rr;
 1696                 parm = &rb->s.param;
 1697         }
 1698 
 1699         rb->blksize = parm->sample_rate * audio_blk_ms / 1000 *
 1700              parm->channels * parm->precision / NBBY;
 1701 
 1702         DPRINTF(("audio_calc_blksize: %s blksize=%d\n",
 1703                  mode == AUMODE_PLAY ? "play" : "record", rb->blksize));
 1704 }
 1705 
 1706 void
 1707 audio_fill_silence(struct audio_params *params, uint8_t *p, int n)
 1708 {
 1709         uint8_t auzero0, auzero1;
 1710         int nfill;
 1711 
 1712         auzero1 = 0;            /* initialize to please gcc */
 1713         nfill = 1;
 1714         switch (params->encoding) {
 1715         case AUDIO_ENCODING_ULAW:
 1716                 auzero0 = 0x7f;
 1717                 break;
 1718         case AUDIO_ENCODING_ALAW:
 1719                 auzero0 = 0x55;
 1720                 break;
 1721         case AUDIO_ENCODING_MPEG_L1_STREAM:
 1722         case AUDIO_ENCODING_MPEG_L1_PACKETS:
 1723         case AUDIO_ENCODING_MPEG_L1_SYSTEM:
 1724         case AUDIO_ENCODING_MPEG_L2_STREAM:
 1725         case AUDIO_ENCODING_MPEG_L2_PACKETS:
 1726         case AUDIO_ENCODING_MPEG_L2_SYSTEM:
 1727         case AUDIO_ENCODING_ADPCM: /* is this right XXX */
 1728         case AUDIO_ENCODING_SLINEAR_LE:
 1729         case AUDIO_ENCODING_SLINEAR_BE:
 1730                 auzero0 = 0;/* fortunately this works for any number of bits */
 1731                 break;
 1732         case AUDIO_ENCODING_ULINEAR_LE:
 1733         case AUDIO_ENCODING_ULINEAR_BE:
 1734                 if (params->precision > 8) {
 1735                         nfill = (params->precision + NBBY - 1)/ NBBY;
 1736                         auzero0 = 0x80;
 1737                         auzero1 = 0;
 1738                 } else
 1739                         auzero0 = 0x80;
 1740                 break;
 1741         default:
 1742                 DPRINTF(("audio: bad encoding %d\n", params->encoding));
 1743                 auzero0 = 0;
 1744                 break;
 1745         }
 1746         if (nfill == 1) {
 1747                 while (--n >= 0)
 1748                         *p++ = auzero0; /* XXX memset */
 1749         } else /* nfill must no longer be 2 */ {
 1750                 if (params->encoding == AUDIO_ENCODING_ULINEAR_LE) {
 1751                         int k = nfill;
 1752                         while (--k > 0)
 1753                                 *p++ = auzero1;
 1754                         n -= nfill - 1;
 1755                 }
 1756                 while (n >= nfill) {
 1757                         int k = nfill;
 1758                         *p++ = auzero0;
 1759                         while (--k > 0)
 1760                                 *p++ = auzero1;
 1761 
 1762                         n -= nfill;
 1763                 }
 1764                 if (n-- > 0)    /* XXX must be 1 - DIAGNOSTIC check? */
 1765                         *p++ = auzero0;
 1766         }
 1767 }
 1768 
 1769 int
 1770 audio_silence_copyout(struct audio_softc *sc, int n, struct uio *uio)
 1771 {
 1772         uint8_t zerobuf[128];
 1773         int error;
 1774         int k;
 1775 
 1776         audio_fill_silence(&sc->sc_rparams, zerobuf, sizeof zerobuf);
 1777 
 1778         error = 0;
 1779         while (n > 0 && uio->uio_resid > 0 && !error) {
 1780                 k = min(n, min(uio->uio_resid, sizeof zerobuf));
 1781                 error = uiomove(zerobuf, k, uio);
 1782                 n -= k;
 1783         }
 1784         return error;
 1785 }
 1786 
 1787 static int
 1788 uio_fetcher_fetch_to(stream_fetcher_t *self, audio_stream_t *p,
 1789     int max_used)
 1790 {
 1791         uio_fetcher_t *this;
 1792         int size;
 1793         int stream_space;
 1794         int error;
 1795 
 1796         this = (uio_fetcher_t *)self;
 1797         this->last_used = audio_stream_get_used(p);
 1798         if (this->last_used >= this->usedhigh)
 1799                 return 0;
 1800         /*
 1801          * uio_fetcher ignores max_used and move the data as
 1802          * much as possible in order to return the correct value
 1803          * for audio_prinfo::seek and kfilters.
 1804          */
 1805         stream_space = audio_stream_get_space(p);
 1806         size = min(this->uio->uio_resid, stream_space);
 1807 
 1808         /* the first fragment of the space */
 1809         stream_space = p->end - p->inp;
 1810         if (stream_space >= size) {
 1811                 error = uiomove(p->inp, size, this->uio);
 1812                 if (error)
 1813                         return error;
 1814                 p->inp = audio_stream_add_inp(p, p->inp, size);
 1815         } else {
 1816                 error = uiomove(p->inp, stream_space, this->uio);
 1817                 if (error)
 1818                         return error;
 1819                 p->inp = audio_stream_add_inp(p, p->inp, stream_space);
 1820                 error = uiomove(p->start, size - stream_space, this->uio);
 1821                 if (error)
 1822                         return error;
 1823                 p->inp = audio_stream_add_inp(p, p->inp, size - stream_space);
 1824         }
 1825         this->last_used = audio_stream_get_used(p);
 1826         return 0;
 1827 }
 1828 
 1829 static int
 1830 null_fetcher_fetch_to(stream_fetcher_t *self,
 1831     audio_stream_t *p, int max_used)
 1832 {
 1833 
 1834         return 0;
 1835 }
 1836 
 1837 static void
 1838 uio_fetcher_ctor(uio_fetcher_t *this, struct uio *u, int h)
 1839 {
 1840 
 1841         this->base.fetch_to = uio_fetcher_fetch_to;
 1842         this->uio = u;
 1843         this->usedhigh = h;
 1844 }
 1845 
 1846 int
 1847 audio_write(struct audio_softc *sc, struct uio *uio, int ioflag)
 1848 {
 1849         uio_fetcher_t ufetcher;
 1850         audio_stream_t stream;
 1851         struct audio_ringbuffer *cb;
 1852         stream_fetcher_t *fetcher;
 1853         stream_filter_t *filter;
 1854         uint8_t *inp, *einp;
 1855         int saveerror, error, s, n, cc, used;
 1856 
 1857         DPRINTFN(2,("audio_write: sc=%p count=%zu used=%d(hi=%d)\n",
 1858                     sc, uio->uio_resid, audio_stream_get_used(sc->sc_pustream),
 1859                     sc->sc_pr.usedhigh));
 1860         cb = &sc->sc_pr;
 1861         if (cb->mmapped)
 1862                 return EINVAL;
 1863 
 1864         if (uio->uio_resid == 0) {
 1865                 sc->sc_eof++;
 1866                 return 0;
 1867         }
 1868 
 1869         /*
 1870          * If half-duplex and currently recording, throw away data.
 1871          */
 1872         if (!sc->sc_full_duplex &&
 1873             (sc->sc_mode & AUMODE_RECORD)) {
 1874                 uio->uio_offset += uio->uio_resid;
 1875                 uio->uio_resid = 0;
 1876                 DPRINTF(("audio_write: half-dpx read busy\n"));
 1877                 return 0;
 1878         }
 1879 
 1880         if (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) {
 1881                 n = min(sc->sc_playdrop, uio->uio_resid);
 1882                 DPRINTF(("audio_write: playdrop %d\n", n));
 1883                 uio->uio_offset += n;
 1884                 uio->uio_resid -= n;
 1885                 sc->sc_playdrop -= n;
 1886                 if (uio->uio_resid == 0)
 1887                         return 0;
 1888         }
 1889 
 1890         /**
 1891          * setup filter pipeline
 1892          */
 1893         uio_fetcher_ctor(&ufetcher, uio, cb->usedhigh);
 1894         if (sc->sc_npfilters > 0) {
 1895                 fetcher = &sc->sc_pfilters[sc->sc_npfilters - 1]->base;
 1896         } else {
 1897                 fetcher = &ufetcher.base;
 1898         }
 1899 
 1900         error = 0;
 1901         while (uio->uio_resid > 0 && !error) {
 1902                 s = splaudio();
 1903                 /* wait if the first buffer is occupied */
 1904                 while ((used = audio_stream_get_used(sc->sc_pustream))
 1905                     >= cb->usedhigh) {
 1906                         DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d "
 1907                                      "hiwat=%d\n", used,
 1908                                      cb->usedlow, cb->usedhigh));
 1909                         if (ioflag & IO_NDELAY) {
 1910                                 splx(s);
 1911                                 return EWOULDBLOCK;
 1912                         }
 1913                         error = audio_sleep(&sc->sc_wchan, "aud_wr");
 1914                         if (sc->sc_dying)
 1915                                 error = EIO;
 1916                         if (error) {
 1917                                 splx(s);
 1918                                 return error;
 1919                         }
 1920                 }
 1921                 inp = cb->s.inp;
 1922                 cb->copying = TRUE;
 1923                 stream = cb->s;
 1924                 used = stream.used;
 1925                 splx(s);
 1926 
 1927                 /*
 1928                  * write to the sc_pustream as much as possible
 1929                  *
 1930                  * work with a temporary audio_stream_t to narrow
 1931                  * splaudio() enclosure
 1932                  */
 1933 
 1934                 sc->sc_writing = 1;
 1935 
 1936                 if (sc->sc_npfilters > 0) {
 1937                         filter = sc->sc_pfilters[0];
 1938                         filter->set_fetcher(filter, &ufetcher.base);
 1939                         fetcher = &sc->sc_pfilters[sc->sc_npfilters - 1]->base;
 1940                         cc = cb->blksize * 2;
 1941                         error = fetcher->fetch_to(fetcher, &stream, cc);
 1942                         if (error != 0) {
 1943                                 fetcher = &ufetcher.base;
 1944                                 cc = sc->sc_pustream->end - sc->sc_pustream->start;
 1945                                 error = fetcher->fetch_to(fetcher, sc->sc_pustream, cc);
 1946                         }
 1947                 } else {
 1948                         fetcher = &ufetcher.base;
 1949                         cc = stream.end - stream.start;
 1950                         error = fetcher->fetch_to(fetcher, &stream, cc);
 1951                 }
 1952                 sc->sc_writing = 0;
 1953                 if (sc->sc_waitcomp)
 1954                         wakeup(sc);
 1955 
 1956                 s = splaudio();
 1957                 if (sc->sc_npfilters > 0) {
 1958                         cb->fstamp += ufetcher.last_used
 1959                             - audio_stream_get_used(sc->sc_pustream);
 1960                 }
 1961                 cb->s.used += stream.used - used;
 1962                 cb->s.inp = stream.inp;
 1963                 einp = cb->s.inp;
 1964 
 1965                 /*
 1966                  * This is a very suboptimal way of keeping track of
 1967                  * silence in the buffer, but it is simple.
 1968                  */
 1969                 sc->sc_sil_count = 0;
 1970 
 1971                 /*
 1972                  * If the interrupt routine wants the last block filled AND
 1973                  * the copy did not fill the last block completely it needs to
 1974                  * be padded.
 1975                  */
 1976                 if (cb->needfill && inp < einp &&
 1977                     (inp  - cb->s.start) / cb->blksize ==
 1978                     (einp - cb->s.start) / cb->blksize) {
 1979                         /* Figure out how many bytes to a block boundary. */
 1980                         cc = cb->blksize - (einp - cb->s.start) % cb->blksize;
 1981                         DPRINTF(("audio_write: partial fill %d\n", cc));
 1982                 } else
 1983                         cc = 0;
 1984                 cb->needfill = FALSE;
 1985                 cb->copying = FALSE;
 1986                 if (!sc->sc_pbus && !cb->pause) {
 1987                         saveerror = error;
 1988                         error = audiostartp(sc);
 1989                         if (saveerror != 0) {
 1990                                 /* Report the first error that occurred. */
 1991                                 error = saveerror;
 1992                         }
 1993                 }
 1994                 splx(s);
 1995                 if (cc != 0) {
 1996                         DPRINTFN(1, ("audio_write: fill %d\n", cc));
 1997                         audio_fill_silence(&cb->s.param, einp, cc);
 1998                 }
 1999         }
 2000 
 2001         return error;
 2002 }
 2003 
 2004 int
 2005 audio_ioctl(struct audio_softc *sc, u_long cmd, caddr_t addr, int flag,
 2006             struct lwp *l)
 2007 {
 2008         const struct audio_hw_if *hw;
 2009         struct audio_offset *ao;
 2010         u_long stamp;
 2011         int error, s, offs, fd;
 2012         boolean_t rbus, pbus;
 2013 
 2014         DPRINTF(("audio_ioctl(%lu,'%c',%lu)\n",
 2015                  IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff));
 2016         hw = sc->hw_if;
 2017         error = 0;
 2018         switch (cmd) {
 2019         case FIONBIO:
 2020                 /* All handled in the upper FS layer. */
 2021                 break;
 2022 
 2023         case FIONREAD:
 2024                 *(int *)addr = audio_stream_get_used(sc->sc_rustream);
 2025                 break;
 2026 
 2027         case FIOASYNC:
 2028                 if (*(int *)addr) {
 2029                         if (sc->sc_async_audio)
 2030                                 return EBUSY;
 2031                         sc->sc_async_audio = l->l_proc;
 2032                         DPRINTF(("audio_ioctl: FIOASYNC %p\n", l->l_proc));
 2033                 } else
 2034                         sc->sc_async_audio = 0;
 2035                 break;
 2036 
 2037         case AUDIO_FLUSH:
 2038                 DPRINTF(("AUDIO_FLUSH\n"));
 2039                 rbus = sc->sc_rbus;
 2040                 pbus = sc->sc_pbus;
 2041                 audio_clear(sc);
 2042                 s = splaudio();
 2043                 error = audio_initbufs(sc);
 2044                 if (error) {
 2045                         splx(s);
 2046                         return error;
 2047                 }
 2048                 if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_pbus && pbus)
 2049                         error = audiostartp(sc);
 2050                 if (!error &&
 2051                     (sc->sc_mode & AUMODE_RECORD) && !sc->sc_rbus && rbus)
 2052                         error = audiostartr(sc);
 2053                 splx(s);
 2054                 break;
 2055 
 2056         /*
 2057          * Number of read (write) samples dropped.  We don't know where or
 2058          * when they were dropped.
 2059          */
 2060         case AUDIO_RERROR:
 2061                 *(int *)addr = sc->sc_rr.drops;
 2062                 break;
 2063 
 2064         case AUDIO_PERROR:
 2065                 *(int *)addr = sc->sc_pr.drops;
 2066                 break;
 2067 
 2068         /*
 2069          * Offsets into buffer.
 2070          */
 2071         case AUDIO_GETIOFFS:
 2072                 ao = (struct audio_offset *)addr;
 2073                 s = splaudio();
 2074                 /* figure out where next DMA will start */
 2075                 stamp = sc->sc_rustream == &sc->sc_rr.s
 2076                         ? sc->sc_rr.stamp : sc->sc_rr.fstamp;
 2077                 offs = sc->sc_rustream->inp - sc->sc_rustream->start;
 2078                 splx(s);
 2079                 ao->samples = stamp;
 2080                 ao->deltablks =
 2081                   (stamp / sc->sc_rr.blksize) -
 2082                   (sc->sc_rr.stamp_last / sc->sc_rr.blksize);
 2083                 sc->sc_rr.stamp_last = stamp;
 2084                 ao->offset = offs;
 2085                 break;
 2086 
 2087         case AUDIO_GETOOFFS:
 2088                 ao = (struct audio_offset *)addr;
 2089                 s = splaudio();
 2090                 /* figure out where next DMA will start */
 2091                 stamp = sc->sc_pustream == &sc->sc_pr.s
 2092                         ? sc->sc_pr.stamp : sc->sc_pr.fstamp;
 2093                 offs = sc->sc_pustream->outp - sc->sc_pustream->start
 2094                         + sc->sc_pr.blksize;
 2095                 splx(s);
 2096                 ao->samples = stamp;
 2097                 ao->deltablks =
 2098                   (stamp / sc->sc_pr.blksize) -
 2099                   (sc->sc_pr.stamp_last / sc->sc_pr.blksize);
 2100                 sc->sc_pr.stamp_last = stamp;
 2101                 if (sc->sc_pustream->start + offs >= sc->sc_pustream->end)
 2102                         offs = 0;
 2103                 ao->offset = offs;
 2104                 break;
 2105 
 2106         /*
 2107          * How many bytes will elapse until mike hears the first
 2108          * sample of what we write next?
 2109          */
 2110         case AUDIO_WSEEK:
 2111                 *(u_long *)addr = audio_stream_get_used(sc->sc_pustream);
 2112                 break;
 2113 
 2114         case AUDIO_SETINFO:
 2115                 DPRINTF(("AUDIO_SETINFO mode=0x%x\n", sc->sc_mode));
 2116                 error = audiosetinfo(sc, (struct audio_info *)addr);
 2117                 break;
 2118 
 2119         case AUDIO_GETINFO:
 2120                 DPRINTF(("AUDIO_GETINFO\n"));
 2121                 error = audiogetinfo(sc, (struct audio_info *)addr, 0);
 2122                 break;
 2123 
 2124         case AUDIO_GETBUFINFO:
 2125                 DPRINTF(("AUDIO_GETBUFINFO\n"));
 2126                 error = audiogetinfo(sc, (struct audio_info *)addr, 1);
 2127                 break;
 2128 
 2129         case AUDIO_DRAIN:
 2130                 DPRINTF(("AUDIO_DRAIN\n"));
 2131                 error = audio_drain(sc);
 2132                 if (!error && hw->drain)
 2133                     error = hw->drain(sc->hw_hdl);
 2134                 break;
 2135 
 2136         case AUDIO_GETDEV:
 2137                 DPRINTF(("AUDIO_GETDEV\n"));
 2138                 error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr);
 2139                 break;
 2140 
 2141         case AUDIO_GETENC:
 2142                 DPRINTF(("AUDIO_GETENC\n"));
 2143                 error = hw->query_encoding(sc->hw_hdl,
 2144                     (struct audio_encoding *)addr);
 2145                 break;
 2146 
 2147         case AUDIO_GETFD:
 2148                 DPRINTF(("AUDIO_GETFD\n"));
 2149                 *(int *)addr = sc->sc_full_duplex;
 2150                 break;
 2151 
 2152         case AUDIO_SETFD:
 2153                 DPRINTF(("AUDIO_SETFD\n"));
 2154                 fd = *(int *)addr;
 2155                 if (hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX) {
 2156                         if (hw->setfd)
 2157                                 error = hw->setfd(sc->hw_hdl, fd);
 2158                         else
 2159                                 error = 0;
 2160                         if (!error)
 2161                                 sc->sc_full_duplex = fd;
 2162                 } else {
 2163                         if (fd)
 2164                                 error = ENOTTY;
 2165                         else
 2166                                 error = 0;
 2167                 }
 2168                 break;
 2169 
 2170         case AUDIO_GETPROPS:
 2171                 DPRINTF(("AUDIO_GETPROPS\n"));
 2172                 *(int *)addr = hw->get_props(sc->hw_hdl);
 2173                 break;
 2174 
 2175         default:
 2176                 if (hw->dev_ioctl) {
 2177                         error = hw->dev_ioctl(sc->hw_hdl, cmd, addr, flag, l);
 2178                 } else {
 2179                         DPRINTF(("audio_ioctl: unknown ioctl\n"));
 2180                         error = EINVAL;
 2181                 }
 2182                 break;
 2183         }
 2184         DPRINTF(("audio_ioctl(%lu,'%c',%lu) result %d\n",
 2185                  IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff, error));
 2186         return error;
 2187 }
 2188 
 2189 int
 2190 audio_poll(struct audio_softc *sc, int events, struct lwp *l)
 2191 {
 2192         int revents;
 2193         int s;
 2194         int used;
 2195 
 2196         DPRINTF(("audio_poll: events=0x%x mode=%d\n", events, sc->sc_mode));
 2197 
 2198         revents = 0;
 2199         s = splaudio();
 2200         if (events & (POLLIN | POLLRDNORM)) {
 2201                 used = audio_stream_get_used(sc->sc_rustream);
 2202                 /*
 2203                  * If half duplex and playing, audio_read() will generate
 2204                  * silence at the play rate; poll for silence being
 2205                  * available.  Otherwise, poll for recorded sound.
 2206                  */
 2207                 if ((!sc->sc_full_duplex && (sc->sc_mode & AUMODE_PLAY)) ?
 2208                     sc->sc_pr.stamp > sc->sc_wstamp :
 2209                     used > sc->sc_rr.usedlow)
 2210                         revents |= events & (POLLIN | POLLRDNORM);
 2211         }
 2212 
 2213         if (events & (POLLOUT | POLLWRNORM)) {
 2214                 used = audio_stream_get_used(sc->sc_pustream);
 2215                 /*
 2216                  * If half duplex and recording, audio_write() will throw
 2217                  * away play data, which means we are always ready to write.
 2218                  * Otherwise, poll for play buffer being below its low water
 2219                  * mark.
 2220                  */
 2221                 if ((!sc->sc_full_duplex && (sc->sc_mode & AUMODE_RECORD)) ||
 2222                     used <= sc->sc_pr.usedlow)
 2223                         revents |= events & (POLLOUT | POLLWRNORM);
 2224         }
 2225 
 2226         if (revents == 0) {
 2227                 if (events & (POLLIN | POLLRDNORM))
 2228                         selrecord(l, &sc->sc_rsel);
 2229 
 2230                 if (events & (POLLOUT | POLLWRNORM))
 2231                         selrecord(l, &sc->sc_wsel);
 2232         }
 2233 
 2234         splx(s);
 2235         return revents;
 2236 }
 2237 
 2238 static void
 2239 filt_audiordetach(struct knote *kn)
 2240 {
 2241         struct audio_softc *sc;
 2242         int s;
 2243 
 2244         sc = kn->kn_hook;
 2245         s = splaudio();
 2246         SLIST_REMOVE(&sc->sc_rsel.sel_klist, kn, knote, kn_selnext);
 2247         splx(s);
 2248 }
 2249 
 2250 static int
 2251 filt_audioread(struct knote *kn, long hint)
 2252 {
 2253         struct audio_softc *sc;
 2254         int s;
 2255 
 2256         sc = kn->kn_hook;
 2257         s = splaudio();
 2258         if (!sc->sc_full_duplex && (sc->sc_mode & AUMODE_PLAY))
 2259                 kn->kn_data = sc->sc_pr.stamp - sc->sc_wstamp;
 2260         else
 2261                 kn->kn_data = audio_stream_get_used(sc->sc_rustream)
 2262                         - sc->sc_rr.usedlow;
 2263         splx(s);
 2264 
 2265         return kn->kn_data > 0;
 2266 }
 2267 
 2268 static const struct filterops audioread_filtops =
 2269         { 1, NULL, filt_audiordetach, filt_audioread };
 2270 
 2271 static void
 2272 filt_audiowdetach(struct knote *kn)
 2273 {
 2274         struct audio_softc *sc;
 2275         int s;
 2276 
 2277         sc = kn->kn_hook;
 2278         s = splaudio();
 2279         SLIST_REMOVE(&sc->sc_wsel.sel_klist, kn, knote, kn_selnext);
 2280         splx(s);
 2281 }
 2282 
 2283 static int
 2284 filt_audiowrite(struct knote *kn, long hint)
 2285 {
 2286         struct audio_softc *sc;
 2287         audio_stream_t *stream;
 2288         int s;
 2289 
 2290         sc = kn->kn_hook;
 2291         s = splaudio();
 2292         stream = sc->sc_pustream;
 2293         kn->kn_data = (stream->end - stream->start)
 2294                 - audio_stream_get_used(stream);
 2295         splx(s);
 2296 
 2297         return kn->kn_data > 0;
 2298 }
 2299 
 2300 static const struct filterops audiowrite_filtops =
 2301         { 1, NULL, filt_audiowdetach, filt_audiowrite };
 2302 
 2303 int
 2304 audio_kqfilter(struct audio_softc *sc, struct knote *kn)
 2305 {
 2306         struct klist *klist;
 2307         int s;
 2308 
 2309         switch (kn->kn_filter) {
 2310         case EVFILT_READ:
 2311                 klist = &sc->sc_rsel.sel_klist;
 2312                 kn->kn_fop = &audioread_filtops;
 2313                 break;
 2314 
 2315         case EVFILT_WRITE:
 2316                 klist = &sc->sc_wsel.sel_klist;
 2317                 kn->kn_fop = &audiowrite_filtops;
 2318                 break;
 2319 
 2320         default:
 2321                 return 1;
 2322         }
 2323 
 2324         kn->kn_hook = sc;
 2325 
 2326         s = splaudio();
 2327         SLIST_INSERT_HEAD(klist, kn, kn_selnext);
 2328         splx(s);
 2329 
 2330         return 0;
 2331 }
 2332 
 2333 paddr_t
 2334 audio_mmap(struct audio_softc *sc, off_t off, int prot)
 2335 {
 2336         const struct audio_hw_if *hw;
 2337         struct audio_ringbuffer *cb;
 2338         int s;
 2339 
 2340         DPRINTF(("audio_mmap: off=%lld, prot=%d\n", (long long)off, prot));
 2341         hw = sc->hw_if;
 2342         if (!(hw->get_props(sc->hw_hdl) & AUDIO_PROP_MMAP) || !hw->mappage)
 2343                 return -1;
 2344 #if 0
 2345 /* XXX
 2346  * The idea here was to use the protection to determine if
 2347  * we are mapping the read or write buffer, but it fails.
 2348  * The VM system is broken in (at least) two ways.
 2349  * 1) If you map memory VM_PROT_WRITE you SIGSEGV
 2350  *    when writing to it, so VM_PROT_READ|VM_PROT_WRITE
 2351  *    has to be used for mmapping the play buffer.
 2352  * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE
 2353  *    audio_mmap will get called at some point with VM_PROT_READ
 2354  *    only.
 2355  * So, alas, we always map the play buffer for now.
 2356  */
 2357         if (prot == (VM_PROT_READ|VM_PROT_WRITE) ||
 2358             prot == VM_PROT_WRITE)
 2359                 cb = &sc->sc_pr;
 2360         else if (prot == VM_PROT_READ)
 2361                 cb = &sc->sc_rr;
 2362         else
 2363                 return -1;
 2364 #else
 2365         cb = &sc->sc_pr;
 2366 #endif
 2367 
 2368         if ((u_int)off >= cb->s.bufsize)
 2369                 return -1;
 2370         if (!cb->mmapped) {
 2371                 cb->mmapped = TRUE;
 2372                 if (cb == &sc->sc_pr) {
 2373                         audio_fill_silence(&cb->s.param, cb->s.start,
 2374                                            cb->s.bufsize);
 2375                         s = splaudio();
 2376                         sc->sc_pustream = &cb->s;
 2377                         if (!sc->sc_pbus)
 2378                                 (void)audiostartp(sc);
 2379                         splx(s);
 2380                 } else {
 2381                         s = splaudio();
 2382                         sc->sc_rustream = &cb->s;
 2383                         if (!sc->sc_rbus)
 2384                                 (void)audiostartr(sc);
 2385                         splx(s);
 2386                 }
 2387         }
 2388 
 2389         return hw->mappage(sc->hw_hdl, cb->s.start, off, prot);
 2390 }
 2391 
 2392 int
 2393 audiostartr(struct audio_softc *sc)
 2394 {
 2395         int error;
 2396 
 2397         DPRINTF(("audiostartr: start=%p used=%d(hi=%d) mmapped=%d\n",
 2398                  sc->sc_rr.s.start, audio_stream_get_used(&sc->sc_rr.s),
 2399                  sc->sc_rr.usedhigh, sc->sc_rr.mmapped));
 2400 
 2401         if (sc->hw_if->trigger_input)
 2402                 error = sc->hw_if->trigger_input(sc->hw_hdl, sc->sc_rr.s.start,
 2403                     sc->sc_rr.s.end, sc->sc_rr.blksize,
 2404                     audio_rint, (void *)sc, &sc->sc_rr.s.param);
 2405         else
 2406                 error = sc->hw_if->start_input(sc->hw_hdl, sc->sc_rr.s.start,
 2407                     sc->sc_rr.blksize, audio_rint, (void *)sc);
 2408         if (error) {
 2409                 DPRINTF(("audiostartr failed: %d\n", error));
 2410                 return error;
 2411         }
 2412         sc->sc_rbus = TRUE;
 2413         return 0;
 2414 }
 2415 
 2416 int
 2417 audiostartp(struct audio_softc *sc)
 2418 {
 2419         int error;
 2420         int used;
 2421 
 2422         used = audio_stream_get_used(&sc->sc_pr.s);
 2423         DPRINTF(("audiostartp: start=%p used=%d(hi=%d blk=%d) mmapped=%d\n",
 2424                  sc->sc_pr.s.start, used, sc->sc_pr.usedhigh,
 2425                  sc->sc_pr.blksize, sc->sc_pr.mmapped));
 2426 
 2427         if (!sc->sc_pr.mmapped && used < sc->sc_pr.blksize) {
 2428                 wakeup(&sc->sc_wchan);
 2429                 DPRINTF(("%s: wakeup and return\n", __func__));
 2430                 return 0;
 2431         }
 2432 
 2433         if (sc->hw_if->trigger_output) {
 2434                 DPRINTF(("%s: call trigger_output\n", __func__));
 2435                 error = sc->hw_if->trigger_output(sc->hw_hdl, sc->sc_pr.s.start,
 2436                     sc->sc_pr.s.end, sc->sc_pr.blksize,
 2437                     audio_pint, (void *)sc, &sc->sc_pr.s.param);
 2438         } else {
 2439                 DPRINTF(("%s: call start_output\n", __func__));
 2440                 error = sc->hw_if->start_output(sc->hw_hdl,
 2441                     __UNCONST(sc->sc_pr.s.outp), sc->sc_pr.blksize,
 2442                     audio_pint, (void *)sc);
 2443         }
 2444         if (error) {
 2445                 DPRINTF(("audiostartp failed: %d\n", error));
 2446                 return error;
 2447         }
 2448         sc->sc_pbus = TRUE;
 2449         return 0;
 2450 }
 2451 
 2452 /*
 2453  * When the play interrupt routine finds that the write isn't keeping
 2454  * the buffer filled it will insert silence in the buffer to make up
 2455  * for this.  The part of the buffer that is filled with silence
 2456  * is kept track of in a very approximate way: it starts at sc_sil_start
 2457  * and extends sc_sil_count bytes.  If there is already silence in
 2458  * the requested area nothing is done; so when the whole buffer is
 2459  * silent nothing happens.  When the writer starts again sc_sil_count
 2460  * is set to 0.
 2461  */
 2462 /* XXX
 2463  * Putting silence into the output buffer should not really be done
 2464  * at splaudio, but there is no softaudio level to do it at yet.
 2465  */
 2466 static inline void
 2467 audio_pint_silence(struct audio_softc *sc, struct audio_ringbuffer *cb,
 2468                    uint8_t *inp, int cc)
 2469 {
 2470         uint8_t *s, *e, *p, *q;
 2471 
 2472         if (sc->sc_sil_count > 0) {
 2473                 s = sc->sc_sil_start; /* start of silence */
 2474                 e = s + sc->sc_sil_count; /* end of sil., may be beyond end */
 2475                 p = inp;        /* adjusted pointer to area to fill */
 2476                 if (p < s)
 2477                         p += cb->s.end - cb->s.start;
 2478                 q = p + cc;
 2479                 /* Check if there is already silence. */
 2480                 if (!(s <= p && p <  e &&
 2481                       s <= q && q <= e)) {
 2482                         if (s <= p)
 2483                                 sc->sc_sil_count = max(sc->sc_sil_count, q-s);
 2484                         DPRINTFN(5,("audio_pint_silence: fill cc=%d inp=%p, "
 2485                                     "count=%d size=%d\n",
 2486                                     cc, inp, sc->sc_sil_count,
 2487                                     (int)(cb->s.end - cb->s.start)));
 2488                         audio_fill_silence(&cb->s.param, inp, cc);
 2489                 } else {
 2490                         DPRINTFN(5,("audio_pint_silence: already silent "
 2491                                     "cc=%d inp=%p\n", cc, inp));
 2492 
 2493                 }
 2494         } else {
 2495                 sc->sc_sil_start = inp;
 2496                 sc->sc_sil_count = cc;
 2497                 DPRINTFN(5, ("audio_pint_silence: start fill %p %d\n",
 2498                              inp, cc));
 2499                 audio_fill_silence(&cb->s.param, inp, cc);
 2500         }
 2501 }
 2502 
 2503 /*
 2504  * Called from HW driver module on completion of DMA output.
 2505  * Start output of new block, wrap in ring buffer if needed.
 2506  * If no more buffers to play, output zero instead.
 2507  * Do a wakeup if necessary.
 2508  */
 2509 void
 2510 audio_pint(void *v)
 2511 {
 2512         stream_fetcher_t null_fetcher;
 2513         struct audio_softc *sc;
 2514         const struct audio_hw_if *hw;
 2515         struct audio_ringbuffer *cb;
 2516         stream_fetcher_t *fetcher;
 2517         uint8_t *inp;
 2518         int cc, used;
 2519         int blksize;
 2520         int error;
 2521 
 2522         sc = v;
 2523         if (!sc->sc_open)
 2524                 return;         /* ignore interrupt if not open */
 2525 
 2526         hw = sc->hw_if;
 2527         cb = &sc->sc_pr;
 2528         blksize = cb->blksize;
 2529         cb->s.outp = audio_stream_add_outp(&cb->s, cb->s.outp, blksize);
 2530         cb->stamp += blksize;
 2531         if (cb->mmapped) {
 2532                 DPRINTFN(5, ("audio_pint: mmapped outp=%p cc=%d inp=%p\n",
 2533                              cb->s.outp, blksize, cb->s.inp));
 2534                 if (hw->trigger_output == NULL)
 2535                         (void)hw->start_output(sc->hw_hdl, __UNCONST(cb->s.outp),
 2536                             blksize, audio_pint, (void *)sc);
 2537                 return;
 2538         }
 2539 
 2540 #ifdef AUDIO_INTR_TIME
 2541         {
 2542                 struct timeval tv;
 2543                 u_long t;
 2544                 microtime(&tv);
 2545                 t = tv.tv_usec + 1000000 * tv.tv_sec;
 2546                 if (sc->sc_pnintr) {
 2547                         long lastdelta, totdelta;
 2548                         lastdelta = t - sc->sc_plastintr - sc->sc_pblktime;
 2549                         if (lastdelta > sc->sc_pblktime / 3) {
 2550                                 printf("audio: play interrupt(%d) off "
 2551                                        "relative by %ld us (%lu)\n",
 2552                                        sc->sc_pnintr, lastdelta,
 2553                                        sc->sc_pblktime);
 2554                         }
 2555                         totdelta = t - sc->sc_pfirstintr -
 2556                                 sc->sc_pblktime * sc->sc_pnintr;
 2557                         if (totdelta > sc->sc_pblktime) {
 2558                                 printf("audio: play interrupt(%d) off "
 2559                                        "absolute by %ld us (%lu) (LOST)\n",
 2560                                        sc->sc_pnintr, totdelta,
 2561                                        sc->sc_pblktime);
 2562                                 sc->sc_pnintr++; /* avoid repeated messages */
 2563                         }
 2564                 } else
 2565                         sc->sc_pfirstintr = t;
 2566                 sc->sc_plastintr = t;
 2567                 sc->sc_pnintr++;
 2568         }
 2569 #endif
 2570 
 2571         used = audio_stream_get_used(&cb->s);
 2572         /*
 2573          * "used <= cb->usedlow" should be "used < blksize" ideally.
 2574          * Some HW drivers such as uaudio(4) does not call audio_pint()
 2575          * at accurate timing.  If used < blksize, uaudio(4) already
 2576          * request transfer of garbage data.
 2577          */
 2578         if (used <= cb->usedlow && !cb->copying && sc->sc_npfilters > 0) {
 2579                 /* we might have data in filter pipeline */
 2580                 null_fetcher.fetch_to = null_fetcher_fetch_to;
 2581                 fetcher = &sc->sc_pfilters[sc->sc_npfilters - 1]->base;
 2582                 sc->sc_pfilters[0]->set_fetcher(sc->sc_pfilters[0],
 2583                                                 &null_fetcher);
 2584                 used = audio_stream_get_used(sc->sc_pustream);
 2585                 cc = cb->s.end - cb->s.start;
 2586                 if (blksize * 2 < cc)
 2587                         cc = blksize * 2;
 2588                 fetcher->fetch_to(fetcher, &cb->s, cc);
 2589                 cb->fstamp += used - audio_stream_get_used(sc->sc_pustream);
 2590                 used = audio_stream_get_used(&cb->s);
 2591         }
 2592         if (used < blksize) {
 2593                 /* we don't have a full block to use */
 2594                 if (cb->copying) {
 2595                         /* writer is in progress, don't disturb */
 2596                         cb->needfill = TRUE;
 2597                         DPRINTFN(1, ("audio_pint: copying in progress\n"));
 2598                 } else {
 2599                         inp = cb->s.inp;
 2600                         cc = blksize - (inp - cb->s.start) % blksize;
 2601                         if (cb->pause)
 2602                                 cb->pdrops += cc;
 2603                         else {
 2604                                 cb->drops += cc;
 2605                                 sc->sc_playdrop += cc;
 2606                         }
 2607                         audio_pint_silence(sc, cb, inp, cc);
 2608                         cb->s.inp = audio_stream_add_inp(&cb->s, inp, cc);
 2609 
 2610                         /* Clear next block so we keep ahead of the DMA. */
 2611                         used = audio_stream_get_used(&cb->s);
 2612                         if (used + cc < cb->s.end - cb->s.start)
 2613                                 audio_pint_silence(sc, cb, inp, blksize);
 2614                 }
 2615         }
 2616 
 2617         DPRINTFN(5, ("audio_pint: outp=%p cc=%d\n", cb->s.outp, blksize));
 2618         if (hw->trigger_output == NULL) {
 2619                 error = hw->start_output(sc->hw_hdl, __UNCONST(cb->s.outp),
 2620                     blksize, audio_pint, (void *)sc);
 2621                 if (error) {
 2622                         /* XXX does this really help? */
 2623                         DPRINTF(("audio_pint restart failed: %d\n", error));
 2624                         audio_clear(sc);
 2625                 }
 2626         }
 2627 
 2628         DPRINTFN(2, ("audio_pint: mode=%d pause=%d used=%d lowat=%d\n",
 2629                      sc->sc_mode, cb->pause,
 2630                      audio_stream_get_used(sc->sc_pustream), cb->usedlow));
 2631         if ((sc->sc_mode & AUMODE_PLAY) && !cb->pause) {
 2632                 if (audio_stream_get_used(sc->sc_pustream) <= cb->usedlow) {
 2633                         audio_wakeup(&sc->sc_wchan);
 2634                         selnotify(&sc->sc_wsel, 0);
 2635                         if (sc->sc_async_audio) {
 2636                                 DPRINTFN(3, ("audio_pint: sending SIGIO %p\n",
 2637                                              sc->sc_async_audio));
 2638                                 psignal(sc->sc_async_audio, SIGIO);
 2639                         }
 2640                 }
 2641         }
 2642 
 2643         /* Possible to return one or more "phantom blocks" now. */
 2644         if (!sc->sc_full_duplex && sc->sc_rchan) {
 2645                 audio_wakeup(&sc->sc_rchan);
 2646                 selnotify(&sc->sc_rsel, 0);
 2647                 if (sc->sc_async_audio)
 2648                         psignal(sc->sc_async_audio, SIGIO);
 2649         }
 2650 }
 2651 
 2652 /*
 2653  * Called from HW driver module on completion of DMA input.
 2654  * Mark it as input in the ring buffer (fiddle pointers).
 2655  * Do a wakeup if necessary.
 2656  */
 2657 void
 2658 audio_rint(void *v)
 2659 {
 2660         stream_fetcher_t null_fetcher;
 2661         struct audio_softc *sc;
 2662         const struct audio_hw_if *hw;
 2663         struct audio_ringbuffer *cb;
 2664         stream_fetcher_t *last_fetcher;
 2665         int cc;
 2666         int used;
 2667         int blksize;
 2668         int error;
 2669 
 2670         sc = v;
 2671         cb = &sc->sc_rr;
 2672         if (!sc->sc_open)
 2673                 return;         /* ignore interrupt if not open */
 2674 
 2675         hw = sc->hw_if;
 2676         blksize = cb->blksize;
 2677         cb->s.inp = audio_stream_add_inp(&cb->s, cb->s.inp, blksize);
 2678         cb->stamp += blksize;
 2679         if (cb->mmapped) {
 2680                 DPRINTFN(2, ("audio_rint: mmapped inp=%p cc=%d\n",
 2681                              cb->s.inp, blksize));
 2682                 if (hw->trigger_input == NULL)
 2683                         (void)hw->start_input(sc->hw_hdl, cb->s.inp, blksize,
 2684                             audio_rint, (void *)sc);
 2685                 return;
 2686         }
 2687 
 2688 #ifdef AUDIO_INTR_TIME
 2689         {
 2690                 struct timeval tv;
 2691                 u_long t;
 2692                 microtime(&tv);
 2693                 t = tv.tv_usec + 1000000 * tv.tv_sec;
 2694                 if (sc->sc_rnintr) {
 2695                         long lastdelta, totdelta;
 2696                         lastdelta = t - sc->sc_rlastintr - sc->sc_rblktime;
 2697                         if (lastdelta > sc->sc_rblktime / 5) {
 2698                                 printf("audio: record interrupt(%d) off "
 2699                                        "relative by %ld us (%lu)\n",
 2700                                        sc->sc_rnintr, lastdelta,
 2701                                        sc->sc_rblktime);
 2702                         }
 2703                         totdelta = t - sc->sc_rfirstintr -
 2704                                 sc->sc_rblktime * sc->sc_rnintr;
 2705                         if (totdelta > sc->sc_rblktime / 2) {
 2706                                 sc->sc_rnintr++;
 2707                                 printf("audio: record interrupt(%d) off "
 2708                                        "absolute by %ld us (%lu)\n",
 2709                                        sc->sc_rnintr, totdelta,
 2710                                        sc->sc_rblktime);
 2711                                 sc->sc_rnintr++; /* avoid repeated messages */
 2712                         }
 2713                 } else
 2714                         sc->sc_rfirstintr = t;
 2715                 sc->sc_rlastintr = t;
 2716                 sc->sc_rnintr++;
 2717         }
 2718 #endif
 2719 
 2720         if (!cb->pause && sc->sc_nrfilters > 0) {
 2721                 null_fetcher.fetch_to = null_fetcher_fetch_to;
 2722                 last_fetcher = &sc->sc_rfilters[sc->sc_nrfilters - 1]->base;
 2723                 sc->sc_rfilters[0]->set_fetcher(sc->sc_rfilters[0],
 2724                                                 &null_fetcher);
 2725                 used = audio_stream_get_used(sc->sc_rustream);
 2726                 cc = sc->sc_rustream->end - sc->sc_rustream->start;
 2727                 error = last_fetcher->fetch_to
 2728                         (last_fetcher, sc->sc_rustream, cc);
 2729                 cb->fstamp += audio_stream_get_used(sc->sc_rustream) - used;
 2730                 /* XXX what should do for error? */
 2731         }
 2732         used = audio_stream_get_used(&sc->sc_rr.s);
 2733         if (cb->pause) {
 2734                 DPRINTFN(1, ("audio_rint: pdrops %lu\n", cb->pdrops));
 2735                 cb->pdrops += blksize;
 2736                 cb->s.outp = audio_stream_add_outp(&cb->s, cb->s.outp, blksize);
 2737         } else if (used + blksize > cb->s.end - cb->s.start && !cb->copying) {
 2738                 DPRINTFN(1, ("audio_rint: drops %lu\n", cb->drops));
 2739                 cb->drops += blksize;
 2740                 cb->s.outp = audio_stream_add_outp(&cb->s, cb->s.outp, blksize);
 2741         }
 2742 
 2743         DPRINTFN(2, ("audio_rint: inp=%p cc=%d\n", cb->s.inp, blksize));
 2744         if (hw->trigger_input == NULL) {
 2745                 error = hw->start_input(sc->hw_hdl, cb->s.inp, blksize,
 2746                     audio_rint, (void *)sc);
 2747                 if (error) {
 2748                         /* XXX does this really help? */
 2749                         DPRINTF(("audio_rint: restart failed: %d\n", error));
 2750                         audio_clear(sc);
 2751                 }
 2752         }
 2753 
 2754         audio_wakeup(&sc->sc_rchan);
 2755         selnotify(&sc->sc_rsel, 0);
 2756         if (sc->sc_async_audio)
 2757                 psignal(sc->sc_async_audio, SIGIO);
 2758 }
 2759 
 2760 int
 2761 audio_check_params(struct audio_params *p)
 2762 {
 2763 
 2764         if (p->encoding == AUDIO_ENCODING_PCM16) {
 2765                 if (p->precision == 8)
 2766                         p->encoding = AUDIO_ENCODING_ULINEAR;
 2767                 else
 2768                         p->encoding = AUDIO_ENCODING_SLINEAR;
 2769         } else if (p->encoding == AUDIO_ENCODING_PCM8) {
 2770                 if (p->precision == 8)
 2771                         p->encoding = AUDIO_ENCODING_ULINEAR;
 2772                 else
 2773                         return EINVAL;
 2774         }
 2775 
 2776         if (p->encoding == AUDIO_ENCODING_SLINEAR)
 2777 #if BYTE_ORDER == LITTLE_ENDIAN
 2778                 p->encoding = AUDIO_ENCODING_SLINEAR_LE;
 2779 #else
 2780                 p->encoding = AUDIO_ENCODING_SLINEAR_BE;
 2781 #endif
 2782         if (p->encoding == AUDIO_ENCODING_ULINEAR)
 2783 #if BYTE_ORDER == LITTLE_ENDIAN
 2784                 p->encoding = AUDIO_ENCODING_ULINEAR_LE;
 2785 #else
 2786                 p->encoding = AUDIO_ENCODING_ULINEAR_BE;
 2787 #endif
 2788 
 2789         switch (p->encoding) {
 2790         case AUDIO_ENCODING_ULAW:
 2791         case AUDIO_ENCODING_ALAW:
 2792                 if (p->precision != 8)
 2793                         return EINVAL;
 2794                 break;
 2795         case AUDIO_ENCODING_ADPCM:
 2796                 if (p->precision != 4 && p->precision != 8)
 2797                         return EINVAL;
 2798                 break;
 2799         case AUDIO_ENCODING_SLINEAR_LE:
 2800         case AUDIO_ENCODING_SLINEAR_BE:
 2801         case AUDIO_ENCODING_ULINEAR_LE:
 2802         case AUDIO_ENCODING_ULINEAR_BE:
 2803                 /* XXX is: our zero-fill can handle any multiple of 8 */
 2804                 if (p->precision !=  8 && p->precision != 16 &&
 2805                     p->precision != 24 && p->precision != 32)
 2806                         return EINVAL;
 2807                 if (p->precision == 8 && p->encoding == AUDIO_ENCODING_SLINEAR_BE)
 2808                         p->encoding = AUDIO_ENCODING_SLINEAR_LE;
 2809                 if (p->precision == 8 && p->encoding == AUDIO_ENCODING_ULINEAR_BE)
 2810                         p->encoding = AUDIO_ENCODING_ULINEAR_LE;
 2811                 if (p->validbits > p->precision)
 2812                         return EINVAL;
 2813                 break;
 2814         case AUDIO_ENCODING_MPEG_L1_STREAM:
 2815         case AUDIO_ENCODING_MPEG_L1_PACKETS:
 2816         case AUDIO_ENCODING_MPEG_L1_SYSTEM:
 2817         case AUDIO_ENCODING_MPEG_L2_STREAM:
 2818         case AUDIO_ENCODING_MPEG_L2_PACKETS:
 2819         case AUDIO_ENCODING_MPEG_L2_SYSTEM:
 2820                 break;
 2821         default:
 2822                 return EINVAL;
 2823         }
 2824 
 2825         /* sanity check # of channels*/
 2826         if (p->channels < 1 || p->channels > AUDIO_MAX_CHANNELS)
 2827                 return EINVAL;
 2828 
 2829         return 0;
 2830 }
 2831 
 2832 int
 2833 audio_set_defaults(struct audio_softc *sc, u_int mode)
 2834 {
 2835         struct audio_info ai;
 2836 
 2837         /* default parameters */
 2838         sc->sc_rparams = audio_default;
 2839         sc->sc_pparams = audio_default;
 2840         sc->sc_blkset = FALSE;
 2841 
 2842         AUDIO_INITINFO(&ai);
 2843         ai.record.sample_rate = sc->sc_rparams.sample_rate;
 2844         ai.record.encoding    = sc->sc_rparams.encoding;
 2845         ai.record.channels    = sc->sc_rparams.channels;
 2846         ai.record.precision   = sc->sc_rparams.precision;
 2847         ai.play.sample_rate   = sc->sc_pparams.sample_rate;
 2848         ai.play.encoding      = sc->sc_pparams.encoding;
 2849         ai.play.channels      = sc->sc_pparams.channels;
 2850         ai.play.precision     = sc->sc_pparams.precision;
 2851         ai.mode               = mode;
 2852 
 2853         return audiosetinfo(sc, &ai);
 2854 }
 2855 
 2856 int
 2857 au_set_lr_value(struct  audio_softc *sc, mixer_ctrl_t *ct, int l, int r)
 2858 {
 2859 
 2860         ct->type = AUDIO_MIXER_VALUE;
 2861         ct->un.value.num_channels = 2;
 2862         ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
 2863         ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
 2864         if (sc->hw_if->set_port(sc->hw_hdl, ct) == 0)
 2865                 return 0;
 2866         ct->un.value.num_channels = 1;
 2867         ct->un.value.level[AUDIO_MIXER_LEVEL_MONO] = (l+r)/2;
 2868         return sc->hw_if->set_port(sc->hw_hdl, ct);
 2869 }
 2870 
 2871 int
 2872 au_set_gain(struct audio_softc *sc, struct au_mixer_ports *ports,
 2873             int gain, int balance)
 2874 {
 2875         mixer_ctrl_t ct;
 2876         int i, error;
 2877         int l, r;
 2878         u_int mask;
 2879         int nset;
 2880 
 2881         if (balance == AUDIO_MID_BALANCE) {
 2882                 l = r = gain;
 2883         } else if (balance < AUDIO_MID_BALANCE) {
 2884                 l = gain;
 2885                 r = (balance * gain) / AUDIO_MID_BALANCE;
 2886         } else {
 2887                 r = gain;
 2888                 l = ((AUDIO_RIGHT_BALANCE - balance) * gain)
 2889                     / AUDIO_MID_BALANCE;
 2890         }
 2891         DPRINTF(("au_set_gain: gain=%d balance=%d, l=%d r=%d\n",
 2892                  gain, balance, l, r));
 2893 
 2894         if (ports->index == -1) {
 2895         usemaster:
 2896                 if (ports->master == -1)
 2897                         return 0; /* just ignore it silently */
 2898                 ct.dev = ports->master;
 2899                 error = au_set_lr_value(sc, &ct, l, r);
 2900         } else {
 2901                 ct.dev = ports->index;
 2902                 if (ports->isenum) {
 2903                         ct.type = AUDIO_MIXER_ENUM;
 2904                         error = sc->hw_if->get_port(sc->hw_hdl, &ct);
 2905                         if (error)
 2906                                 return error;
 2907                         if (ports->isdual) {
 2908                                 if (ports->cur_port == -1)
 2909                                         ct.dev = ports->master;
 2910                                 else
 2911                                         ct.dev = ports->miport[ports->cur_port];
 2912                                 error = au_set_lr_value(sc, &ct, l, r);
 2913                         } else {
 2914                                 for(i = 0; i < ports->nports; i++)
 2915                                     if (ports->misel[i] == ct.un.ord) {
 2916                                             ct.dev = ports->miport[i];
 2917                                             if (ct.dev == -1 ||
 2918                                                 au_set_lr_value(sc, &ct, l, r))
 2919                                                     goto usemaster;
 2920                                             else
 2921                                                     break;
 2922                                     }
 2923                         }
 2924                 } else {
 2925                         ct.type = AUDIO_MIXER_SET;
 2926                         error = sc->hw_if->get_port(sc->hw_hdl, &ct);
 2927                         if (error)
 2928                                 return error;
 2929                         mask = ct.un.mask;
 2930                         nset = 0;
 2931                         for(i = 0; i < ports->nports; i++) {
 2932                                 if (ports->misel[i] & mask) {
 2933                                     ct.dev = ports->miport[i];
 2934                                     if (ct.dev != -1 &&
 2935                                         au_set_lr_value(sc, &ct, l, r) == 0)
 2936                                             nset++;
 2937                                 }
 2938                         }
 2939                         if (nset == 0)
 2940                                 goto usemaster;
 2941                 }
 2942         }
 2943         if (!error)
 2944                 mixer_signal(sc);
 2945         return error;
 2946 }
 2947 
 2948 int
 2949 au_get_lr_value(struct  audio_softc *sc, mixer_ctrl_t *ct, int *l, int *r)
 2950 {
 2951         int error;
 2952 
 2953         ct->un.value.num_channels = 2;
 2954         if (sc->hw_if->get_port(sc->hw_hdl, ct) == 0) {
 2955                 *l = ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
 2956                 *r = ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
 2957         } else {
 2958                 ct->un.value.num_channels = 1;
 2959                 error = sc->hw_if->get_port(sc->hw_hdl, ct);
 2960                 if (error)
 2961                         return error;
 2962                 *r = *l = ct->un.value.level[AUDIO_MIXER_LEVEL_MONO];
 2963         }
 2964         return 0;
 2965 }
 2966 
 2967 void
 2968 au_get_gain(struct audio_softc *sc, struct au_mixer_ports *ports,
 2969             u_int *pgain, u_char *pbalance)
 2970 {
 2971         mixer_ctrl_t ct;
 2972         int i, l, r, n;
 2973         int lgain, rgain;
 2974 
 2975         lgain = AUDIO_MAX_GAIN / 2;
 2976         rgain = AUDIO_MAX_GAIN / 2;
 2977         if (ports->index == -1) {
 2978         usemaster:
 2979                 if (ports->master == -1)
 2980                         goto bad;
 2981                 ct.dev = ports->master;
 2982                 ct.type = AUDIO_MIXER_VALUE;
 2983                 if (au_get_lr_value(sc, &ct, &lgain, &rgain))
 2984                         goto bad;
 2985         } else {
 2986                 ct.dev = ports->index;
 2987                 if (ports->isenum) {
 2988                         ct.type = AUDIO_MIXER_ENUM;
 2989                         if (sc->hw_if->get_port(sc->hw_hdl, &ct))
 2990                                 goto bad;
 2991                         ct.type = AUDIO_MIXER_VALUE;
 2992                         if (ports->isdual) {
 2993                                 if (ports->cur_port == -1)
 2994                                         ct.dev = ports->master;
 2995                                 else
 2996                                         ct.dev = ports->miport[ports->cur_port];
 2997                                 au_get_lr_value(sc, &ct, &lgain, &rgain);
 2998                         } else {
 2999                                 for(i = 0; i < ports->nports; i++)
 3000                                     if (ports->misel[i] == ct.un.ord) {
 3001                                             ct.dev = ports->miport[i];
 3002                                             if (ct.dev == -1 ||
 3003                                                 au_get_lr_value(sc, &ct,
 3004                                                                 &lgain, &rgain))
 3005                                                     goto usemaster;
 3006                                             else
 3007                                                     break;
 3008                                     }
 3009                         }
 3010                 } else {
 3011                         ct.type = AUDIO_MIXER_SET;
 3012                         if (sc->hw_if->get_port(sc->hw_hdl, &ct))
 3013                                 goto bad;
 3014                         ct.type = AUDIO_MIXER_VALUE;
 3015                         lgain = rgain = n = 0;
 3016                         for(i = 0; i < ports->nports; i++) {
 3017                                 if (ports->misel[i] & ct.un.mask) {
 3018                                         ct.dev = ports->miport[i];
 3019                                         if (ct.dev == -1 ||
 3020                                             au_get_lr_value(sc, &ct, &l, &r))
 3021                                                 goto usemaster;
 3022                                         else {
 3023                                                 lgain += l;
 3024                                                 rgain += r;
 3025                                                 n++;
 3026                                         }
 3027                                 }
 3028                         }
 3029                         if (n != 0) {
 3030                                 lgain /= n;
 3031                                 rgain /= n;
 3032                         }
 3033                 }
 3034         }
 3035 bad:
 3036         if (lgain == rgain) {   /* handles lgain==rgain==0 */
 3037                 *pgain = lgain;
 3038                 *pbalance = AUDIO_MID_BALANCE;
 3039         } else if (lgain < rgain) {
 3040                 *pgain = rgain;
 3041                 /* balance should be > AUDIO_MID_BALANCE */
 3042                 *pbalance = AUDIO_RIGHT_BALANCE -
 3043                         (AUDIO_MID_BALANCE * lgain) / rgain;
 3044         } else /* lgain > rgain */ {
 3045                 *pgain = lgain;
 3046                 /* balance should be < AUDIO_MID_BALANCE */
 3047                 *pbalance = (AUDIO_MID_BALANCE * rgain) / lgain;
 3048         }
 3049 }
 3050 
 3051 int
 3052 au_set_port(struct audio_softc *sc, struct au_mixer_ports *ports, u_int port)
 3053 {
 3054         mixer_ctrl_t ct;
 3055         int i, error, use_mixerout;
 3056 
 3057         use_mixerout = 1;
 3058         if (port == 0) {
 3059                 if (ports->allports == 0)
 3060                         return 0;               /* Allow this special case. */
 3061                 else if (ports->isdual) {
 3062                         if (ports->cur_port == -1) {
 3063                                 return 0;
 3064                         } else {
 3065                                 port = ports->aumask[ports->cur_port];
 3066                                 ports->cur_port = -1;
 3067                                 use_mixerout = 0;
 3068                         }
 3069                 }
 3070         }
 3071         if (ports->index == -1)
 3072                 return EINVAL;
 3073         ct.dev = ports->index;
 3074         if (ports->isenum) {
 3075                 if (port & (port-1))
 3076                         return EINVAL; /* Only one port allowed */
 3077                 ct.type = AUDIO_MIXER_ENUM;
 3078                 error = EINVAL;
 3079                 for(i = 0; i < ports->nports; i++)
 3080                         if (ports->aumask[i] == port) {
 3081                                 if (ports->isdual && use_mixerout) {
 3082                                         ct.un.ord = ports->mixerout;
 3083                                         ports->cur_port = i;
 3084                                 } else {
 3085                                         ct.un.ord = ports->misel[i];
 3086                                 }
 3087                                 error = sc->hw_if->set_port(sc->hw_hdl, &ct);
 3088                                 break;
 3089                         }
 3090         } else {
 3091                 ct.type = AUDIO_MIXER_SET;
 3092                 ct.un.mask = 0;
 3093                 for(i = 0; i < ports->nports; i++)
 3094                         if (ports->aumask[i] & port)
 3095                                 ct.un.mask |= ports->misel[i];
 3096                 if (port != 0 && ct.un.mask == 0)
 3097                         error = EINVAL;
 3098                 else
 3099                         error = sc->hw_if->set_port(sc->hw_hdl, &ct);
 3100         }
 3101         if (!error)
 3102                 mixer_signal(sc);
 3103         return error;
 3104 }
 3105 
 3106 int
 3107 au_get_port(struct audio_softc *sc, struct au_mixer_ports *ports)
 3108 {
 3109         mixer_ctrl_t ct;
 3110         int i, aumask;
 3111 
 3112         if (ports->index == -1)
 3113                 return 0;
 3114         ct.dev = ports->index;
 3115         ct.type = ports->isenum ? AUDIO_MIXER_ENUM : AUDIO_MIXER_SET;
 3116         if (sc->hw_if->get_port(sc->hw_hdl, &ct))
 3117                 return 0;
 3118         aumask = 0;
 3119         if (ports->isenum) {
 3120                 if (ports->isdual && ports->cur_port != -1) {
 3121                         if (ports->mixerout == ct.un.ord)
 3122                                 aumask = ports->aumask[ports->cur_port];
 3123                         else
 3124                                 ports->cur_port = -1;
 3125                 }
 3126                 if (aumask == 0)
 3127                         for(i = 0; i < ports->nports; i++)
 3128                                 if (ports->misel[i] == ct.un.ord)
 3129                                         aumask = ports->aumask[i];
 3130         } else {
 3131                 for(i = 0; i < ports->nports; i++)
 3132                         if (ct.un.mask & ports->misel[i])
 3133                                 aumask |= ports->aumask[i];
 3134         }
 3135         return aumask;
 3136 }
 3137 
 3138 int
 3139 audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
 3140 {
 3141         stream_filter_list_t pfilters, rfilters;
 3142         audio_params_t pp, rp;
 3143         struct audio_prinfo *r, *p;
 3144         const struct audio_hw_if *hw;
 3145         audio_stream_t *oldpus, *oldrus;
 3146         int s, setmode;
 3147         int error;
 3148         int np, nr;
 3149         unsigned int blks;
 3150         int oldpblksize, oldrblksize;
 3151         u_int gain;
 3152         boolean_t rbus, pbus;
 3153         boolean_t cleared, modechange, pausechange;
 3154         u_char balance;
 3155 
 3156         hw = sc->hw_if;
 3157         if (hw == NULL)         /* HW has not attached */
 3158                 return ENXIO;
 3159 
 3160         DPRINTF(("%s sc=%p ai=%p\n", __func__, sc, ai));
 3161         r = &ai->record;
 3162         p = &ai->play;
 3163         rbus = sc->sc_rbus;
 3164         pbus = sc->sc_pbus;
 3165         error = 0;
 3166         cleared = FALSE;
 3167         modechange = FALSE;
 3168         pausechange = FALSE;
 3169 
 3170         pp = sc->sc_pparams;    /* Temporary encoding storage in */
 3171         rp = sc->sc_rparams;    /* case setting the modes fails. */
 3172         nr = np = 0;
 3173 
 3174         if (SPECIFIED(p->sample_rate)) {
 3175                 pp.sample_rate = p->sample_rate;
 3176                 np++;
 3177         }
 3178         if (SPECIFIED(r->sample_rate)) {
 3179                 rp.sample_rate = r->sample_rate;
 3180                 nr++;
 3181         }
 3182         if (SPECIFIED(p->encoding)) {
 3183                 pp.encoding = p->encoding;
 3184                 np++;
 3185         }
 3186         if (SPECIFIED(r->encoding)) {
 3187                 rp.encoding = r->encoding;
 3188                 nr++;
 3189         }
 3190         if (SPECIFIED(p->precision)) {
 3191                 pp.precision = p->precision;
 3192                 /* we don't have API to specify validbits */
 3193                 pp.validbits = p->precision;
 3194                 np++;
 3195         }
 3196         if (SPECIFIED(r->precision)) {
 3197                 rp.precision = r->precision;
 3198                 /* we don't have API to specify validbits */
 3199                 rp.validbits = r->precision;
 3200                 nr++;
 3201         }
 3202         if (SPECIFIED(p->channels)) {
 3203                 pp.channels = p->channels;
 3204                 np++;
 3205         }
 3206         if (SPECIFIED(r->channels)) {
 3207                 rp.channels = r->channels;
 3208                 nr++;
 3209         }
 3210 #ifdef AUDIO_DEBUG
 3211         if (audiodebug && nr > 0)
 3212             audio_print_params("audiosetinfo() Setting record params:", &rp);
 3213         if (audiodebug && np > 0)
 3214             audio_print_params("audiosetinfo() Setting play params:", &pp);
 3215 #endif
 3216         if (nr > 0 && (error = audio_check_params(&rp)))
 3217                 return error;
 3218         if (np > 0 && (error = audio_check_params(&pp)))
 3219                 return error;
 3220 
 3221         oldpblksize = sc->sc_pr.blksize;
 3222         oldrblksize = sc->sc_rr.blksize;
 3223 
 3224         setmode = 0;
 3225         if (nr > 0) {
 3226                 if (!cleared) {
 3227                         audio_clear(sc);
 3228                         cleared = TRUE;
 3229                 }
 3230                 modechange = TRUE;
 3231                 setmode |= AUMODE_RECORD;
 3232         }
 3233         if (np > 0) {
 3234                 if (!cleared) {
 3235                         audio_clear(sc);
 3236                         cleared = TRUE;
 3237                 }
 3238                 modechange = TRUE;
 3239                 setmode |= AUMODE_PLAY;
 3240         }
 3241 
 3242         if (SPECIFIED(ai->mode)) {
 3243                 if (!cleared) {
 3244                         audio_clear(sc);
 3245                         cleared = TRUE;
 3246                 }
 3247                 modechange = TRUE;
 3248                 sc->sc_mode = ai->mode;
 3249                 if (sc->sc_mode & AUMODE_PLAY_ALL)
 3250                         sc->sc_mode |= AUMODE_PLAY;
 3251                 if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_full_duplex)
 3252                         /* Play takes precedence */
 3253                         sc->sc_mode &= ~AUMODE_RECORD;
 3254         }
 3255 
 3256         oldpus = sc->sc_pustream;
 3257         oldrus = sc->sc_rustream;
 3258         if (modechange) {
 3259                 int indep;
 3260 
 3261                 indep = hw->get_props(sc->hw_hdl) & AUDIO_PROP_INDEPENDENT;
 3262                 if (!indep) {
 3263                         if (setmode == AUMODE_RECORD)
 3264                                 pp = rp;
 3265                         else if (setmode == AUMODE_PLAY)
 3266                                 rp = pp;
 3267                 }
 3268                 memset(&pfilters, 0, sizeof(pfilters));
 3269                 memset(&rfilters, 0, sizeof(rfilters));
 3270                 pfilters.append = stream_filter_list_append;
 3271                 pfilters.prepend = stream_filter_list_prepend;
 3272                 pfilters.set = stream_filter_list_set;
 3273                 rfilters.append = stream_filter_list_append;
 3274                 rfilters.prepend = stream_filter_list_prepend;
 3275                 rfilters.set = stream_filter_list_set;
 3276                 /* Some device drivers change channels/sample_rate and change
 3277                  * no channels/sample_rate. */
 3278                 error = hw->set_params(sc->hw_hdl, setmode,
 3279                     sc->sc_mode & (AUMODE_PLAY | AUMODE_RECORD), &pp, &rp,
 3280                     &pfilters, &rfilters);
 3281                 if (error) {
 3282                         DPRINTF(("%s: hw->set_params() failed with %d\n",
 3283                                  __func__, error));
 3284                         goto cleanup;
 3285                 }
 3286 
 3287                 audio_check_params(&pp);
 3288                 audio_check_params(&rp);
 3289                 if (!indep) {
 3290                         /* XXX for !indep device, we have to use the same
 3291                          * parameters for the hardware, not userland */
 3292                         if (setmode == AUMODE_RECORD) {
 3293                                 pp = rp;
 3294                         } else if (setmode == AUMODE_PLAY) {
 3295                                 rp = pp;
 3296                         }
 3297                 }
 3298 
 3299                 if (sc->sc_pr.mmapped && pfilters.req_size > 0) {
 3300                         DPRINTF(("%s: mmapped, and filters are requested.\n",
 3301                                  __func__));
 3302                         error = EINVAL;
 3303                         goto cleanup;
 3304                 }
 3305 
 3306                 /* construct new filter chain */
 3307                 if (setmode & AUMODE_PLAY) {
 3308                         error = audio_setup_pfilters(sc, &pp, &pfilters);
 3309                         if (error)
 3310                                 goto cleanup;
 3311                 }
 3312                 if (setmode & AUMODE_RECORD) {
 3313                         error = audio_setup_rfilters(sc, &rp, &rfilters);
 3314                         if (error)
 3315                                 goto cleanup;
 3316                 }
 3317                 DPRINTF(("%s: filter setup is completed.\n", __func__));
 3318 
 3319                 /* userland formats */
 3320                 sc->sc_pparams = pp;
 3321                 sc->sc_rparams = rp;
 3322         }
 3323 
 3324         /* Play params can affect the record params, so recalculate blksize. */
 3325         if (nr > 0 || np > 0) {
 3326                 audio_calc_blksize(sc, AUMODE_RECORD);
 3327                 audio_calc_blksize(sc, AUMODE_PLAY);
 3328         }
 3329 #ifdef AUDIO_DEBUG
 3330         if (audiodebug > 1 && nr > 0)
 3331             audio_print_params("audiosetinfo() After setting record params:", &sc->sc_rparams);
 3332         if (audiodebug > 1 && np > 0)
 3333             audio_print_params("audiosetinfo() After setting play params:", &sc->sc_pparams);
 3334 #endif
 3335 
 3336         if (SPECIFIED(p->port)) {
 3337                 if (!cleared) {
 3338                         audio_clear(sc);
 3339                         cleared = TRUE;
 3340                 }
 3341                 error = au_set_port(sc, &sc->sc_outports, p->port);
 3342                 if (error)
 3343                         goto cleanup;
 3344         }
 3345         if (SPECIFIED(r->port)) {
 3346                 if (!cleared) {
 3347                         audio_clear(sc);
 3348                         cleared = TRUE;
 3349                 }
 3350                 error = au_set_port(sc, &sc->sc_inports, r->port);
 3351                 if (error)
 3352                         goto cleanup;
 3353         }
 3354         if (SPECIFIED(p->gain)) {
 3355                 au_get_gain(sc, &sc->sc_outports, &gain, &balance);
 3356                 error = au_set_gain(sc, &sc->sc_outports, p->gain, balance);
 3357                 if (error)
 3358                         goto cleanup;
 3359         }
 3360         if (SPECIFIED(r->gain)) {
 3361                 au_get_gain(sc, &sc->sc_inports, &gain, &balance);
 3362                 error = au_set_gain(sc, &sc->sc_inports, r->gain, balance);
 3363                 if (error)
 3364                         goto cleanup;
 3365         }
 3366 
 3367         if (SPECIFIED_CH(p->balance)) {
 3368                 au_get_gain(sc, &sc->sc_outports, &gain, &balance);
 3369                 error = au_set_gain(sc, &sc->sc_outports, gain, p->balance);
 3370                 if (error)
 3371                         goto cleanup;
 3372         }
 3373         if (SPECIFIED_CH(r->balance)) {
 3374                 au_get_gain(sc, &sc->sc_inports, &gain, &balance);
 3375                 error = au_set_gain(sc, &sc->sc_inports, gain, r->balance);
 3376                 if (error)
 3377                         goto cleanup;
 3378         }
 3379 
 3380         if (SPECIFIED(ai->monitor_gain) && sc->sc_monitor_port != -1) {
 3381                 mixer_ctrl_t ct;
 3382 
 3383                 ct.dev = sc->sc_monitor_port;
 3384                 ct.type = AUDIO_MIXER_VALUE;
 3385                 ct.un.value.num_channels = 1;
 3386                 ct.un.value.level[AUDIO_MIXER_LEVEL_MONO] = ai->monitor_gain;
 3387                 error = sc->hw_if->set_port(sc->hw_hdl, &ct);
 3388                 if (error)
 3389                         goto cleanup;
 3390         }
 3391 
 3392         if (SPECIFIED_CH(p->pause)) {
 3393                 sc->sc_pr.pause = p->pause;
 3394                 pbus = !p->pause;
 3395                 pausechange = TRUE;
 3396         }
 3397         if (SPECIFIED_CH(r->pause)) {
 3398                 sc->sc_rr.pause = r->pause;
 3399                 rbus = !r->pause;
 3400                 pausechange = TRUE;
 3401         }
 3402 
 3403         if (SPECIFIED(ai->blocksize)) {
 3404                 int pblksize, rblksize;
 3405 
 3406                 /* Block size specified explicitly. */
 3407                 if (ai->blocksize == 0) {
 3408                         if (!cleared) {
 3409                                 audio_clear(sc);
 3410                                 cleared = TRUE;
 3411                         }
 3412                         sc->sc_blkset = FALSE;
 3413                         audio_calc_blksize(sc, AUMODE_RECORD);
 3414                         audio_calc_blksize(sc, AUMODE_PLAY);
 3415                 } else {
 3416                         sc->sc_blkset = TRUE;
 3417                         /* check whether new blocksize changes actually */
 3418                         if (hw->round_blocksize == NULL) {
 3419                                 if (!cleared) {
 3420                                         audio_clear(sc);
 3421                                         cleared = TRUE;
 3422                                 }
 3423                                 sc->sc_pr.blksize = ai->blocksize;
 3424                                 sc->sc_rr.blksize = ai->blocksize;
 3425                         } else {
 3426                                 pblksize = hw->round_blocksize(sc->hw_hdl,
 3427                                     ai->blocksize, AUMODE_PLAY, &sc->sc_pr.s.param);
 3428                                 rblksize = hw->round_blocksize(sc->hw_hdl,
 3429                                     ai->blocksize, AUMODE_RECORD, &sc->sc_rr.s.param);
 3430                                 if (pblksize != sc->sc_pr.blksize ||
 3431                                     rblksize != sc->sc_rr.blksize) {
 3432                                         if (!cleared) {
 3433                                                 audio_clear(sc);
 3434                                                 cleared = TRUE;
 3435                                         }
 3436                                         sc->sc_pr.blksize = ai->blocksize;
 3437                                         sc->sc_rr.blksize = ai->blocksize;
 3438                                 }
 3439                         }
 3440                 }
 3441         }
 3442 
 3443         if (SPECIFIED(ai->mode)) {
 3444                 if (sc->sc_mode & AUMODE_PLAY)
 3445                         audio_init_play(sc);
 3446                 if (sc->sc_mode & AUMODE_RECORD)
 3447                         audio_init_record(sc);
 3448         }
 3449 
 3450         if (hw->commit_settings) {
 3451                 error = hw->commit_settings(sc->hw_hdl);
 3452                 if (error)
 3453                         goto cleanup;
 3454         }
 3455 
 3456 cleanup:
 3457         if (cleared || pausechange) {
 3458                 int init_error;
 3459 
 3460                 s = splaudio();
 3461                 init_error = audio_initbufs(sc);
 3462                 if (init_error) goto err;
 3463                 if (sc->sc_pr.blksize != oldpblksize ||
 3464                     sc->sc_rr.blksize != oldrblksize ||
 3465                     sc->sc_pustream != oldpus ||
 3466                     sc->sc_rustream != oldrus)
 3467                         audio_calcwater(sc);
 3468                 if ((sc->sc_mode & AUMODE_PLAY) &&
 3469                     pbus && !sc->sc_pbus)
 3470                         init_error = audiostartp(sc);
 3471                 if (!init_error &&
 3472                     (sc->sc_mode & AUMODE_RECORD) &&
 3473                     rbus && !sc->sc_rbus)
 3474                         init_error = audiostartr(sc);
 3475         err:
 3476                 splx(s);
 3477                 if (init_error)
 3478                         return init_error;
 3479         }
 3480 
 3481         /* Change water marks after initializing the buffers. */
 3482         if (SPECIFIED(ai->hiwat)) {
 3483                 blks = ai->hiwat;
 3484                 if (blks > sc->sc_pr.maxblks)
 3485                         blks = sc->sc_pr.maxblks;
 3486                 if (blks < 2)
 3487                         blks = 2;
 3488                 sc->sc_pr.usedhigh = blks * sc->sc_pr.blksize;
 3489         }
 3490         if (SPECIFIED(ai->lowat)) {
 3491                 blks = ai->lowat;
 3492                 if (blks > sc->sc_pr.maxblks - 1)
 3493                         blks = sc->sc_pr.maxblks - 1;
 3494                 sc->sc_pr.usedlow = blks * sc->sc_pr.blksize;
 3495         }
 3496         if (SPECIFIED(ai->hiwat) || SPECIFIED(ai->lowat)) {
 3497                 if (sc->sc_pr.usedlow > sc->sc_pr.usedhigh - sc->sc_pr.blksize)
 3498                         sc->sc_pr.usedlow =
 3499                                 sc->sc_pr.usedhigh - sc->sc_pr.blksize;
 3500         }
 3501 
 3502         return error;
 3503 }
 3504 
 3505 int
 3506 audiogetinfo(struct audio_softc *sc, struct audio_info *ai, int buf_only_mode)
 3507 {
 3508         struct audio_prinfo *r, *p;
 3509         const struct audio_hw_if *hw;
 3510 
 3511         r = &ai->record;
 3512         p = &ai->play;
 3513         hw = sc->hw_if;
 3514         if (hw == NULL)         /* HW has not attached */
 3515                 return ENXIO;
 3516 
 3517         p->sample_rate = sc->sc_pparams.sample_rate;
 3518         r->sample_rate = sc->sc_rparams.sample_rate;
 3519         p->channels = sc->sc_pparams.channels;
 3520         r->channels = sc->sc_rparams.channels;
 3521         p->precision = sc->sc_pparams.precision;
 3522         r->precision = sc->sc_rparams.precision;
 3523         p->encoding = sc->sc_pparams.encoding;
 3524         r->encoding = sc->sc_rparams.encoding;
 3525 
 3526         if (buf_only_mode) {
 3527                 r->port = 0;
 3528                 p->port = 0;
 3529 
 3530                 r->avail_ports = 0;
 3531                 p->avail_ports = 0;
 3532 
 3533                 r->gain = 0;
 3534                 r->balance = 0;
 3535 
 3536                 p->gain = 0;
 3537                 p->balance = 0;
 3538         } else {
 3539                 r->port = au_get_port(sc, &sc->sc_inports);
 3540                 p->port = au_get_port(sc, &sc->sc_outports);
 3541 
 3542                 r->avail_ports = sc->sc_inports.allports;
 3543                 p->avail_ports = sc->sc_outports.allports;
 3544 
 3545                 au_get_gain(sc, &sc->sc_inports,  &r->gain, &r->balance);
 3546                 au_get_gain(sc, &sc->sc_outports, &p->gain, &p->balance);
 3547         }
 3548 
 3549         if (sc->sc_monitor_port != -1 && buf_only_mode == 0) {
 3550                 mixer_ctrl_t ct;
 3551 
 3552                 ct.dev = sc->sc_monitor_port;
 3553                 ct.type = AUDIO_MIXER_VALUE;
 3554                 ct.un.value.num_channels = 1;
 3555                 if (sc->hw_if->get_port(sc->hw_hdl, &ct))
 3556                         ai->monitor_gain = 0;
 3557                 else
 3558                         ai->monitor_gain =
 3559                                 ct.un.value.level[AUDIO_MIXER_LEVEL_MONO];
 3560         } else
 3561                 ai->monitor_gain = 0;
 3562 
 3563         p->seek = audio_stream_get_used(sc->sc_pustream);
 3564         r->seek = audio_stream_get_used(sc->sc_rustream);
 3565 
 3566         /*
 3567          * XXX samples should be a value for userland data.
 3568          * But drops is a value for HW data.
 3569          */
 3570         p->samples = (sc->sc_pustream == &sc->sc_pr.s
 3571                       ? sc->sc_pr.stamp : sc->sc_pr.fstamp) - sc->sc_pr.drops;
 3572         r->samples = (sc->sc_rustream == &sc->sc_rr.s
 3573                       ? sc->sc_rr.stamp : sc->sc_rr.fstamp) - sc->sc_rr.drops;
 3574 
 3575         p->eof = sc->sc_eof;
 3576         r->eof = 0;
 3577 
 3578         p->pause = sc->sc_pr.pause;
 3579         r->pause = sc->sc_rr.pause;
 3580 
 3581         p->error = sc->sc_pr.drops != 0;
 3582         r->error = sc->sc_rr.drops != 0;
 3583 
 3584         p->waiting = r->waiting = 0;            /* open never hangs */
 3585 
 3586         p->open = (sc->sc_open & AUOPEN_WRITE) != 0;
 3587         r->open = (sc->sc_open & AUOPEN_READ) != 0;
 3588 
 3589         p->active = sc->sc_pbus;
 3590         r->active = sc->sc_rbus;
 3591 
 3592         p->buffer_size = sc->sc_pustream->bufsize;
 3593         r->buffer_size = sc->sc_rustream->bufsize;
 3594 
 3595         ai->blocksize = sc->sc_pr.blksize;
 3596         ai->hiwat = sc->sc_pr.usedhigh / sc->sc_pr.blksize;
 3597         ai->lowat = sc->sc_pr.usedlow / sc->sc_pr.blksize;
 3598         ai->mode = sc->sc_mode;
 3599 
 3600         return 0;
 3601 }
 3602 
 3603 /*
 3604  * Mixer driver
 3605  */
 3606 int
 3607 mixer_open(dev_t dev, struct audio_softc *sc, int flags,
 3608     int ifmt, struct lwp *l)
 3609 {
 3610         if (sc->hw_if == NULL)
 3611                 return  ENXIO;
 3612 
 3613         DPRINTF(("mixer_open: flags=0x%x sc=%p\n", flags, sc));
 3614 
 3615         return 0;
 3616 }
 3617 
 3618 /*
 3619  * Remove a process from those to be signalled on mixer activity.
 3620  */
 3621 static void
 3622 mixer_remove(struct audio_softc *sc, struct lwp *l)
 3623 {
 3624         struct mixer_asyncs **pm, *m;
 3625         struct proc *p;
 3626 
 3627         if (l == NULL)
 3628                 return;
 3629 
 3630         p = l->l_proc;
 3631 
 3632         for (pm = &sc->sc_async_mixer; *pm; pm = &(*pm)->next) {
 3633                 if ((*pm)->proc == p) {
 3634                         m = *pm;
 3635                         *pm = m->next;
 3636                         free(m, M_DEVBUF);
 3637                         return;
 3638                 }
 3639         }
 3640 }
 3641 
 3642 /*
 3643  * Signal all processes waiting for the mixer.
 3644  */
 3645 static void
 3646 mixer_signal(struct audio_softc *sc)
 3647 {
 3648         struct mixer_asyncs *m;
 3649 
 3650         for (m = sc->sc_async_mixer; m; m = m->next)
 3651                 psignal(m->proc, SIGIO);
 3652 }
 3653 
 3654 /*
 3655  * Close a mixer device
 3656  */
 3657 /* ARGSUSED */
 3658 int
 3659 mixer_close(struct audio_softc *sc, int flags, int ifmt,
 3660     struct lwp *l)
 3661 {
 3662 
 3663         DPRINTF(("mixer_close: sc %p\n", sc));
 3664         mixer_remove(sc, l);
 3665         return 0;
 3666 }
 3667 
 3668 int
 3669 mixer_ioctl(struct audio_softc *sc, u_long cmd, caddr_t addr, int flag,
 3670             struct lwp *l)
 3671 {
 3672         const struct audio_hw_if *hw;
 3673         int error;
 3674 
 3675         DPRINTF(("mixer_ioctl(%lu,'%c',%lu)\n",
 3676                  IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff));
 3677         hw = sc->hw_if;
 3678         error = EINVAL;
 3679         switch (cmd) {
 3680         case FIOASYNC:
 3681                 mixer_remove(sc, l);    /* remove old entry */
 3682                 if (*(int *)addr) {
 3683                         struct mixer_asyncs *ma;
 3684                         ma = malloc(sizeof (struct mixer_asyncs),
 3685                                     M_DEVBUF, M_WAITOK);
 3686                         ma->next = sc->sc_async_mixer;
 3687                         ma->proc = l->l_proc;
 3688                         sc->sc_async_mixer = ma;
 3689                 }
 3690                 error = 0;
 3691                 break;
 3692 
 3693         case AUDIO_GETDEV:
 3694                 DPRINTF(("AUDIO_GETDEV\n"));
 3695                 error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr);
 3696                 break;
 3697 
 3698         case AUDIO_MIXER_DEVINFO:
 3699                 DPRINTF(("AUDIO_MIXER_DEVINFO\n"));
 3700                 ((mixer_devinfo_t *)addr)->un.v.delta = 0; /* default */
 3701                 error = hw->query_devinfo(sc->hw_hdl, (mixer_devinfo_t *)addr);
 3702                 break;
 3703 
 3704         case AUDIO_MIXER_READ:
 3705                 DPRINTF(("AUDIO_MIXER_READ\n"));
 3706                 error = hw->get_port(sc->hw_hdl, (mixer_ctrl_t *)addr);
 3707                 break;
 3708 
 3709         case AUDIO_MIXER_WRITE:
 3710                 DPRINTF(("AUDIO_MIXER_WRITE\n"));
 3711                 error = hw->set_port(sc->hw_hdl, (mixer_ctrl_t *)addr);
 3712                 if (!error && hw->commit_settings)
 3713                         error = hw->commit_settings(sc->hw_hdl);
 3714                 if (!error)
 3715                         mixer_signal(sc);
 3716                 break;
 3717 
 3718         default:
 3719                 if (hw->dev_ioctl)
 3720                         error = hw->dev_ioctl(sc->hw_hdl, cmd, addr, flag, l);
 3721                 else
 3722                         error = EINVAL;
 3723                 break;
 3724         }
 3725         DPRINTF(("mixer_ioctl(%lu,'%c',%lu) result %d\n",
 3726                  IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff, error));
 3727         return error;
 3728 }
 3729 #endif /* NAUDIO > 0 */
 3730 
 3731 #include "midi.h"
 3732 
 3733 #if NAUDIO == 0 && (NMIDI > 0 || NMIDIBUS > 0)
 3734 #include <sys/param.h>
 3735 #include <sys/systm.h>
 3736 #include <sys/device.h>
 3737 #include <sys/audioio.h>
 3738 #include <dev/audio_if.h>
 3739 #endif
 3740 
 3741 #if NAUDIO > 0 || (NMIDI > 0 || NMIDIBUS > 0)
 3742 int
 3743 audioprint(void *aux, const char *pnp)
 3744 {
 3745         struct audio_attach_args *arg;
 3746         const char *type;
 3747 
 3748         if (pnp != NULL) {
 3749                 arg = aux;
 3750                 switch (arg->type) {
 3751                 case AUDIODEV_TYPE_AUDIO:
 3752                         type = "audio";
 3753                         break;
 3754                 case AUDIODEV_TYPE_MIDI:
 3755                         type = "midi";
 3756                         break;
 3757                 case AUDIODEV_TYPE_OPL:
 3758                         type = "opl";
 3759                         break;
 3760                 case AUDIODEV_TYPE_MPU:
 3761                         type = "mpu";
 3762                         break;
 3763                 default:
 3764                         panic("audioprint: unknown type %d", arg->type);
 3765                 }
 3766                 aprint_normal("%s at %s", type, pnp);
 3767         }
 3768         return UNCONF;
 3769 }
 3770 
 3771 #endif /* NAUDIO > 0 || (NMIDI > 0 || NMIDIBUS > 0) */
 3772 
 3773 #if NAUDIO > 0
 3774 void
 3775 audio_powerhook(int why, void *aux)
 3776 {
 3777         struct audio_softc *sc;
 3778         const struct audio_hw_if *hwp;
 3779 
 3780         sc = (struct audio_softc *)aux;
 3781         hwp = sc->hw_if;
 3782 
 3783         switch (why) {
 3784         case PWR_SOFTSUSPEND:
 3785                 if (sc->sc_pbus == TRUE)
 3786                         hwp->halt_output(sc->hw_hdl);
 3787                 if (sc->sc_rbus == TRUE)
 3788                         hwp->halt_input(sc->hw_hdl);
 3789                 break;
 3790         case PWR_SOFTRESUME:
 3791                 if (sc->sc_pbus == TRUE)
 3792                         audiostartp(sc);
 3793                 if (sc->sc_rbus == TRUE)
 3794                         audiostartr(sc);
 3795                 break;
 3796         }
 3797 
 3798         return;
 3799 }
 3800 #endif /* NAUDIO > 0 */

Cache object: 31bc4a4dc72e85fbb595bb0bd5d0deb6


[ 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.