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

Annotation of src/sys/dev/audio/audio.c, Revision 1.79

1.79    ! isaki       1: /*     $NetBSD: audio.c,v 1.78 2020/08/23 04:20:01 isaki Exp $ */
1.2       isaki       2:
                      3: /*-
                      4:  * Copyright (c) 2008 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Andrew Doran.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: /*
                     33:  * Copyright (c) 1991-1993 Regents of the University of California.
                     34:  * All rights reserved.
                     35:  *
                     36:  * Redistribution and use in source and binary forms, with or without
                     37:  * modification, are permitted provided that the following conditions
                     38:  * are met:
                     39:  * 1. Redistributions of source code must retain the above copyright
                     40:  *    notice, this list of conditions and the following disclaimer.
                     41:  * 2. Redistributions in binary form must reproduce the above copyright
                     42:  *    notice, this list of conditions and the following disclaimer in the
                     43:  *    documentation and/or other materials provided with the distribution.
                     44:  * 3. All advertising materials mentioning features or use of this software
                     45:  *    must display the following acknowledgement:
                     46:  *     This product includes software developed by the Computer Systems
                     47:  *     Engineering Group at Lawrence Berkeley Laboratory.
                     48:  * 4. Neither the name of the University nor of the Laboratory may be used
                     49:  *    to endorse or promote products derived from this software without
                     50:  *    specific prior written permission.
                     51:  *
                     52:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     53:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     54:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     55:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     56:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     57:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     58:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     59:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     60:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     61:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     62:  * SUCH DAMAGE.
                     63:  */
                     64:
                     65: /*
                     66:  * Locking: there are three locks per device.
                     67:  *
                     68:  * - sc_lock, provided by the underlying driver.  This is an adaptive lock,
                     69:  *   returned in the second parameter to hw_if->get_locks().  It is known
                     70:  *   as the "thread lock".
                     71:  *
                     72:  *   It serializes access to state in all places except the
                     73:  *   driver's interrupt service routine.  This lock is taken from process
                     74:  *   context (example: access to /dev/audio).  It is also taken from soft
                     75:  *   interrupt handlers in this module, primarily to serialize delivery of
                     76:  *   wakeups.  This lock may be used/provided by modules external to the
                     77:  *   audio subsystem, so take care not to introduce a lock order problem.
                     78:  *   LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD.
                     79:  *
                     80:  * - sc_intr_lock, provided by the underlying driver.  This may be either a
                     81:  *   spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or
                     82:  *   IPL_SOFT*), returned in the first parameter to hw_if->get_locks().  It
                     83:  *   is known as the "interrupt lock".
                     84:  *
                     85:  *   It provides atomic access to the device's hardware state, and to audio
                     86:  *   channel data that may be accessed by the hardware driver's ISR.
                     87:  *   In all places outside the ISR, sc_lock must be held before taking
                     88:  *   sc_intr_lock.  This is to ensure that groups of hardware operations are
                     89:  *   made atomically.  SLEEPS CANNOT OCCUR WITH THIS LOCK HELD.
                     90:  *
                     91:  * - sc_exlock, private to this module.  This is a variable protected by
                     92:  *   sc_lock.  It is known as the "critical section".
                     93:  *   Some operations release sc_lock in order to allocate memory, to wait
                     94:  *   for in-flight I/O to complete, to copy to/from user context, etc.
                     95:  *   sc_exlock provides a critical section even under the circumstance.
                     96:  *   "+" in following list indicates the interfaces which necessary to be
                     97:  *   protected by sc_exlock.
                     98:  *
                     99:  * List of hardware interface methods, and which locks are held when each
                    100:  * is called by this module:
                    101:  *
                    102:  *     METHOD                  INTR    THREAD  NOTES
                    103:  *     ----------------------- ------- ------- -------------------------
                    104:  *     open                    x       x +
                    105:  *     close                   x       x +
                    106:  *     query_format            -       x
                    107:  *     set_format              -       x
                    108:  *     round_blocksize         -       x
                    109:  *     commit_settings         -       x
                    110:  *     init_output             x       x
                    111:  *     init_input              x       x
                    112:  *     start_output            x       x +
                    113:  *     start_input             x       x +
                    114:  *     halt_output             x       x +
                    115:  *     halt_input              x       x +
                    116:  *     speaker_ctl             x       x
                    117:  *     getdev                  -       x
                    118:  *     set_port                -       x +
                    119:  *     get_port                -       x +
                    120:  *     query_devinfo           -       x
1.64      isaki     121:  *     allocm                  -       - +
                    122:  *     freem                   -       - +
1.2       isaki     123:  *     round_buffersize        -       x
1.52      isaki     124:  *     get_props               -       -       Called at attach time
1.2       isaki     125:  *     trigger_output          x       x +
                    126:  *     trigger_input           x       x +
                    127:  *     dev_ioctl               -       x
                    128:  *     get_locks               -       -       Called at attach time
                    129:  *
1.9       isaki     130:  * In addition, there is an additional lock.
1.2       isaki     131:  *
                    132:  * - track->lock.  This is an atomic variable and is similar to the
                    133:  *   "interrupt lock".  This is one for each track.  If any thread context
                    134:  *   (and software interrupt context) and hardware interrupt context who
                    135:  *   want to access some variables on this track, they must acquire this
                    136:  *   lock before.  It protects track's consistency between hardware
                    137:  *   interrupt context and others.
                    138:  */
                    139:
                    140: #include <sys/cdefs.h>
1.79    ! isaki     141: __KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.78 2020/08/23 04:20:01 isaki Exp $");
1.2       isaki     142:
                    143: #ifdef _KERNEL_OPT
                    144: #include "audio.h"
                    145: #include "midi.h"
                    146: #endif
                    147:
                    148: #if NAUDIO > 0
                    149:
                    150: #include <sys/types.h>
                    151: #include <sys/param.h>
                    152: #include <sys/atomic.h>
                    153: #include <sys/audioio.h>
                    154: #include <sys/conf.h>
                    155: #include <sys/cpu.h>
                    156: #include <sys/device.h>
                    157: #include <sys/fcntl.h>
                    158: #include <sys/file.h>
                    159: #include <sys/filedesc.h>
                    160: #include <sys/intr.h>
                    161: #include <sys/ioctl.h>
                    162: #include <sys/kauth.h>
                    163: #include <sys/kernel.h>
                    164: #include <sys/kmem.h>
                    165: #include <sys/malloc.h>
                    166: #include <sys/mman.h>
                    167: #include <sys/module.h>
                    168: #include <sys/poll.h>
                    169: #include <sys/proc.h>
                    170: #include <sys/queue.h>
                    171: #include <sys/select.h>
                    172: #include <sys/signalvar.h>
                    173: #include <sys/stat.h>
                    174: #include <sys/sysctl.h>
                    175: #include <sys/systm.h>
                    176: #include <sys/syslog.h>
                    177: #include <sys/vnode.h>
                    178:
                    179: #include <dev/audio/audio_if.h>
                    180: #include <dev/audio/audiovar.h>
                    181: #include <dev/audio/audiodef.h>
                    182: #include <dev/audio/linear.h>
                    183: #include <dev/audio/mulaw.h>
                    184:
                    185: #include <machine/endian.h>
                    186:
1.53      chs       187: #include <uvm/uvm_extern.h>
1.2       isaki     188:
                    189: #include "ioconf.h"
                    190:
                    191: /*
                    192:  * 0: No debug logs
                    193:  * 1: action changes like open/close/set_format...
                    194:  * 2: + normal operations like read/write/ioctl...
                    195:  * 3: + TRACEs except interrupt
                    196:  * 4: + TRACEs including interrupt
                    197:  */
                    198: //#define AUDIO_DEBUG 1
                    199:
                    200: #if defined(AUDIO_DEBUG)
                    201:
                    202: int audiodebug = AUDIO_DEBUG;
                    203: static void audio_vtrace(struct audio_softc *sc, const char *, const char *,
                    204:        const char *, va_list);
                    205: static void audio_trace(struct audio_softc *sc, const char *, const char *, ...)
                    206:        __printflike(3, 4);
                    207: static void audio_tracet(const char *, audio_track_t *, const char *, ...)
                    208:        __printflike(3, 4);
                    209: static void audio_tracef(const char *, audio_file_t *, const char *, ...)
                    210:        __printflike(3, 4);
                    211:
                    212: /* XXX sloppy memory logger */
                    213: static void audio_mlog_init(void);
                    214: static void audio_mlog_free(void);
                    215: static void audio_mlog_softintr(void *);
                    216: extern void audio_mlog_flush(void);
                    217: extern void audio_mlog_printf(const char *, ...);
                    218:
                    219: static int mlog_refs;          /* reference counter */
                    220: static char *mlog_buf[2];      /* double buffer */
                    221: static int mlog_buflen;                /* buffer length */
                    222: static int mlog_used;          /* used length */
                    223: static int mlog_full;          /* number of dropped lines by buffer full */
                    224: static int mlog_drop;          /* number of dropped lines by busy */
                    225: static volatile uint32_t mlog_inuse;   /* in-use */
                    226: static int mlog_wpage;         /* active page */
                    227: static void *mlog_sih;         /* softint handle */
                    228:
                    229: static void
                    230: audio_mlog_init(void)
                    231: {
                    232:        mlog_refs++;
                    233:        if (mlog_refs > 1)
                    234:                return;
                    235:        mlog_buflen = 4096;
                    236:        mlog_buf[0] = kmem_zalloc(mlog_buflen, KM_SLEEP);
                    237:        mlog_buf[1] = kmem_zalloc(mlog_buflen, KM_SLEEP);
                    238:        mlog_used = 0;
                    239:        mlog_full = 0;
                    240:        mlog_drop = 0;
                    241:        mlog_inuse = 0;
                    242:        mlog_wpage = 0;
                    243:        mlog_sih = softint_establish(SOFTINT_SERIAL, audio_mlog_softintr, NULL);
                    244:        if (mlog_sih == NULL)
                    245:                printf("%s: softint_establish failed\n", __func__);
                    246: }
                    247:
                    248: static void
                    249: audio_mlog_free(void)
                    250: {
                    251:        mlog_refs--;
                    252:        if (mlog_refs > 0)
                    253:                return;
                    254:
                    255:        audio_mlog_flush();
                    256:        if (mlog_sih)
                    257:                softint_disestablish(mlog_sih);
                    258:        kmem_free(mlog_buf[0], mlog_buflen);
                    259:        kmem_free(mlog_buf[1], mlog_buflen);
                    260: }
                    261:
                    262: /*
                    263:  * Flush memory buffer.
                    264:  * It must not be called from hardware interrupt context.
                    265:  */
                    266: void
                    267: audio_mlog_flush(void)
                    268: {
                    269:        if (mlog_refs == 0)
                    270:                return;
                    271:
                    272:        /* Nothing to do if already in use ? */
                    273:        if (atomic_swap_32(&mlog_inuse, 1) == 1)
                    274:                return;
                    275:
                    276:        int rpage = mlog_wpage;
                    277:        mlog_wpage ^= 1;
                    278:        mlog_buf[mlog_wpage][0] = '\0';
                    279:        mlog_used = 0;
                    280:
                    281:        atomic_swap_32(&mlog_inuse, 0);
                    282:
                    283:        if (mlog_buf[rpage][0] != '\0') {
                    284:                printf("%s", mlog_buf[rpage]);
                    285:                if (mlog_drop > 0)
                    286:                        printf("mlog_drop %d\n", mlog_drop);
                    287:                if (mlog_full > 0)
                    288:                        printf("mlog_full %d\n", mlog_full);
                    289:        }
                    290:        mlog_full = 0;
                    291:        mlog_drop = 0;
                    292: }
                    293:
                    294: static void
                    295: audio_mlog_softintr(void *cookie)
                    296: {
                    297:        audio_mlog_flush();
                    298: }
                    299:
                    300: void
                    301: audio_mlog_printf(const char *fmt, ...)
                    302: {
                    303:        int len;
                    304:        va_list ap;
                    305:
                    306:        if (atomic_swap_32(&mlog_inuse, 1) == 1) {
                    307:                /* already inuse */
                    308:                mlog_drop++;
                    309:                return;
                    310:        }
                    311:
                    312:        va_start(ap, fmt);
                    313:        len = vsnprintf(
                    314:            mlog_buf[mlog_wpage] + mlog_used,
                    315:            mlog_buflen - mlog_used,
                    316:            fmt, ap);
                    317:        va_end(ap);
                    318:
                    319:        mlog_used += len;
                    320:        if (mlog_buflen - mlog_used <= 1) {
                    321:                mlog_full++;
                    322:        }
                    323:
                    324:        atomic_swap_32(&mlog_inuse, 0);
                    325:
                    326:        if (mlog_sih)
                    327:                softint_schedule(mlog_sih);
                    328: }
                    329:
                    330: /* trace functions */
                    331: static void
                    332: audio_vtrace(struct audio_softc *sc, const char *funcname, const char *header,
                    333:        const char *fmt, va_list ap)
                    334: {
                    335:        char buf[256];
                    336:        int n;
                    337:
                    338:        n = 0;
                    339:        buf[0] = '\0';
                    340:        n += snprintf(buf + n, sizeof(buf) - n, "%s@%d %s",
                    341:            funcname, device_unit(sc->sc_dev), header);
                    342:        n += vsnprintf(buf + n, sizeof(buf) - n, fmt, ap);
                    343:
                    344:        if (cpu_intr_p()) {
                    345:                audio_mlog_printf("%s\n", buf);
                    346:        } else {
                    347:                audio_mlog_flush();
                    348:                printf("%s\n", buf);
                    349:        }
                    350: }
                    351:
                    352: static void
                    353: audio_trace(struct audio_softc *sc, const char *funcname, const char *fmt, ...)
                    354: {
                    355:        va_list ap;
                    356:
                    357:        va_start(ap, fmt);
                    358:        audio_vtrace(sc, funcname, "", fmt, ap);
                    359:        va_end(ap);
                    360: }
                    361:
                    362: static void
                    363: audio_tracet(const char *funcname, audio_track_t *track, const char *fmt, ...)
                    364: {
                    365:        char hdr[16];
                    366:        va_list ap;
                    367:
                    368:        snprintf(hdr, sizeof(hdr), "#%d ", track->id);
                    369:        va_start(ap, fmt);
                    370:        audio_vtrace(track->mixer->sc, funcname, hdr, fmt, ap);
                    371:        va_end(ap);
                    372: }
                    373:
                    374: static void
                    375: audio_tracef(const char *funcname, audio_file_t *file, const char *fmt, ...)
                    376: {
                    377:        char hdr[32];
                    378:        char phdr[16], rhdr[16];
                    379:        va_list ap;
                    380:
                    381:        phdr[0] = '\0';
                    382:        rhdr[0] = '\0';
                    383:        if (file->ptrack)
                    384:                snprintf(phdr, sizeof(phdr), "#%d", file->ptrack->id);
                    385:        if (file->rtrack)
                    386:                snprintf(rhdr, sizeof(rhdr), "#%d", file->rtrack->id);
                    387:        snprintf(hdr, sizeof(hdr), "{%s,%s} ", phdr, rhdr);
                    388:
                    389:        va_start(ap, fmt);
                    390:        audio_vtrace(file->sc, funcname, hdr, fmt, ap);
                    391:        va_end(ap);
                    392: }
                    393:
                    394: #define DPRINTF(n, fmt...)     do {    \
                    395:        if (audiodebug >= (n)) {        \
                    396:                audio_mlog_flush();     \
                    397:                printf(fmt);            \
                    398:        }                               \
                    399: } while (0)
                    400: #define TRACE(n, fmt...)       do { \
                    401:        if (audiodebug >= (n)) audio_trace(sc, __func__, fmt); \
                    402: } while (0)
                    403: #define TRACET(n, t, fmt...)   do { \
                    404:        if (audiodebug >= (n)) audio_tracet(__func__, t, fmt); \
                    405: } while (0)
                    406: #define TRACEF(n, f, fmt...)   do { \
                    407:        if (audiodebug >= (n)) audio_tracef(__func__, f, fmt); \
                    408: } while (0)
                    409:
                    410: struct audio_track_debugbuf {
                    411:        char usrbuf[32];
                    412:        char codec[32];
                    413:        char chvol[32];
                    414:        char chmix[32];
                    415:        char freq[32];
                    416:        char outbuf[32];
                    417: };
                    418:
                    419: static void
                    420: audio_track_bufstat(audio_track_t *track, struct audio_track_debugbuf *buf)
                    421: {
                    422:
                    423:        memset(buf, 0, sizeof(*buf));
                    424:
                    425:        snprintf(buf->outbuf, sizeof(buf->outbuf), " out=%d/%d/%d",
                    426:            track->outbuf.head, track->outbuf.used, track->outbuf.capacity);
                    427:        if (track->freq.filter)
                    428:                snprintf(buf->freq, sizeof(buf->freq), " f=%d/%d/%d",
                    429:                    track->freq.srcbuf.head,
                    430:                    track->freq.srcbuf.used,
                    431:                    track->freq.srcbuf.capacity);
                    432:        if (track->chmix.filter)
                    433:                snprintf(buf->chmix, sizeof(buf->chmix), " m=%d",
                    434:                    track->chmix.srcbuf.used);
                    435:        if (track->chvol.filter)
                    436:                snprintf(buf->chvol, sizeof(buf->chvol), " v=%d",
                    437:                    track->chvol.srcbuf.used);
                    438:        if (track->codec.filter)
                    439:                snprintf(buf->codec, sizeof(buf->codec), " e=%d",
                    440:                    track->codec.srcbuf.used);
                    441:        snprintf(buf->usrbuf, sizeof(buf->usrbuf), " usr=%d/%d/H%d",
                    442:            track->usrbuf.head, track->usrbuf.used, track->usrbuf_usedhigh);
                    443: }
                    444: #else
                    445: #define DPRINTF(n, fmt...)     do { } while (0)
                    446: #define TRACE(n, fmt, ...)     do { } while (0)
                    447: #define TRACET(n, t, fmt, ...) do { } while (0)
                    448: #define TRACEF(n, f, fmt, ...) do { } while (0)
                    449: #endif
                    450:
                    451: #define SPECIFIED(x)   ((x) != ~0)
                    452: #define SPECIFIED_CH(x)        ((x) != (u_char)~0)
                    453:
1.68      isaki     454: /*
                    455:  * Default hardware blocksize in msec.
                    456:  *
1.69      isaki     457:  * We use 10 msec for most modern platforms.  This period is good enough to
                    458:  * play audio and video synchronizely.
1.68      isaki     459:  * In contrast, for very old platforms, this is usually too short and too
                    460:  * severe.  Also such platforms usually can not play video confortably, so
1.69      isaki     461:  * it's not so important to make the blocksize shorter.  If the platform
                    462:  * defines its own value as __AUDIO_BLK_MS in its <machine/param.h>, it
                    463:  * uses this instead.
                    464:  *
1.68      isaki     465:  * In either case, you can overwrite AUDIO_BLK_MS by your kernel
                    466:  * configuration file if you wish.
1.69      isaki     467:  */
1.68      isaki     468: #if !defined(AUDIO_BLK_MS)
1.69      isaki     469: # if defined(__AUDIO_BLK_MS)
                    470: #  define AUDIO_BLK_MS __AUDIO_BLK_MS
1.68      isaki     471: # else
1.69      isaki     472: #  define AUDIO_BLK_MS (10)
1.68      isaki     473: # endif
                    474: #endif
                    475:
1.2       isaki     476: /* Device timeout in msec */
                    477: #define AUDIO_TIMEOUT  (3000)
                    478:
                    479: /* #define AUDIO_PM_IDLE */
                    480: #ifdef AUDIO_PM_IDLE
                    481: int audio_idle_timeout = 30;
                    482: #endif
                    483:
1.41      isaki     484: /* Number of elements of async mixer's pid */
                    485: #define AM_CAPACITY    (4)
                    486:
1.2       isaki     487: struct portname {
                    488:        const char *name;
                    489:        int mask;
                    490: };
                    491:
                    492: static int audiomatch(device_t, cfdata_t, void *);
                    493: static void audioattach(device_t, device_t, void *);
                    494: static int audiodetach(device_t, int);
                    495: static int audioactivate(device_t, enum devact);
                    496: static void audiochilddet(device_t, device_t);
                    497: static int audiorescan(device_t, const char *, const int *);
                    498:
                    499: static int audio_modcmd(modcmd_t, void *);
                    500:
                    501: #ifdef AUDIO_PM_IDLE
                    502: static void audio_idle(void *);
                    503: static void audio_activity(device_t, devactive_t);
                    504: #endif
                    505:
                    506: static bool audio_suspend(device_t dv, const pmf_qual_t *);
                    507: static bool audio_resume(device_t dv, const pmf_qual_t *);
                    508: static void audio_volume_down(device_t);
                    509: static void audio_volume_up(device_t);
                    510: static void audio_volume_toggle(device_t);
                    511:
                    512: static void audio_mixer_capture(struct audio_softc *);
                    513: static void audio_mixer_restore(struct audio_softc *);
                    514:
                    515: static void audio_softintr_rd(void *);
                    516: static void audio_softintr_wr(void *);
                    517:
1.63      isaki     518: static int audio_exlock_mutex_enter(struct audio_softc *);
                    519: static void audio_exlock_mutex_exit(struct audio_softc *);
                    520: static int audio_exlock_enter(struct audio_softc *);
                    521: static void audio_exlock_exit(struct audio_softc *);
1.56      isaki     522: static struct audio_softc *audio_file_enter(audio_file_t *, struct psref *);
                    523: static void audio_file_exit(struct audio_softc *, struct psref *);
1.2       isaki     524: static int audio_track_waitio(struct audio_softc *, audio_track_t *);
                    525:
                    526: static int audioclose(struct file *);
                    527: static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int);
                    528: static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int);
                    529: static int audioioctl(struct file *, u_long, void *);
                    530: static int audiopoll(struct file *, int);
                    531: static int audiokqfilter(struct file *, struct knote *);
                    532: static int audiommap(struct file *, off_t *, size_t, int, int *, int *,
                    533:        struct uvm_object **, int *);
                    534: static int audiostat(struct file *, struct stat *);
                    535:
                    536: static void filt_audiowrite_detach(struct knote *);
                    537: static int  filt_audiowrite_event(struct knote *, long);
                    538: static void filt_audioread_detach(struct knote *);
                    539: static int  filt_audioread_event(struct knote *, long);
                    540:
                    541: static int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *,
1.21      isaki     542:        audio_file_t **);
1.2       isaki     543: static int audio_close(struct audio_softc *, audio_file_t *);
1.56      isaki     544: static int audio_unlink(struct audio_softc *, audio_file_t *);
1.2       isaki     545: static int audio_read(struct audio_softc *, struct uio *, int, audio_file_t *);
                    546: static int audio_write(struct audio_softc *, struct uio *, int, audio_file_t *);
                    547: static void audio_file_clear(struct audio_softc *, audio_file_t *);
                    548: static int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int,
                    549:        struct lwp *, audio_file_t *);
                    550: static int audio_poll(struct audio_softc *, int, struct lwp *, audio_file_t *);
                    551: static int audio_kqfilter(struct audio_softc *, audio_file_t *, struct knote *);
                    552: static int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *,
                    553:        struct uvm_object **, int *, audio_file_t *);
                    554:
                    555: static int audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *);
                    556:
                    557: static void audio_pintr(void *);
                    558: static void audio_rintr(void *);
                    559:
                    560: static int audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *);
                    561:
                    562: static __inline int audio_track_readablebytes(const audio_track_t *);
                    563: static int audio_file_setinfo(struct audio_softc *, audio_file_t *,
                    564:        const struct audio_info *);
1.62      isaki     565: static int audio_track_setinfo_check(audio_track_t *,
                    566:        audio_format2_t *, const struct audio_prinfo *);
1.2       isaki     567: static void audio_track_setinfo_water(audio_track_t *,
                    568:        const struct audio_info *);
                    569: static int audio_hw_setinfo(struct audio_softc *, const struct audio_info *,
                    570:        struct audio_info *);
                    571: static int audio_hw_set_format(struct audio_softc *, int,
1.45      isaki     572:        const audio_format2_t *, const audio_format2_t *,
1.2       isaki     573:        audio_filter_reg_t *, audio_filter_reg_t *);
                    574: static int audiogetinfo(struct audio_softc *, struct audio_info *, int,
                    575:        audio_file_t *);
                    576: static bool audio_can_playback(struct audio_softc *);
                    577: static bool audio_can_capture(struct audio_softc *);
                    578: static int audio_check_params(audio_format2_t *);
                    579: static int audio_mixers_init(struct audio_softc *sc, int,
                    580:        const audio_format2_t *, const audio_format2_t *,
                    581:        const audio_filter_reg_t *, const audio_filter_reg_t *);
                    582: static int audio_select_freq(const struct audio_format *);
1.55      isaki     583: static int audio_hw_probe(struct audio_softc *, audio_format2_t *, int);
1.2       isaki     584: static int audio_hw_validate_format(struct audio_softc *, int,
                    585:        const audio_format2_t *);
                    586: static int audio_mixers_set_format(struct audio_softc *,
                    587:        const struct audio_info *);
                    588: static void audio_mixers_get_format(struct audio_softc *, struct audio_info *);
                    589: static int audio_sysctl_blk_ms(SYSCTLFN_PROTO);
                    590: static int audio_sysctl_multiuser(SYSCTLFN_PROTO);
                    591: #if defined(AUDIO_DEBUG)
                    592: static int audio_sysctl_debug(SYSCTLFN_PROTO);
                    593: static void audio_format2_tostr(char *, size_t, const audio_format2_t *);
                    594: static void audio_print_format2(const char *, const audio_format2_t *) __unused;
                    595: #endif
                    596:
                    597: static void *audio_realloc(void *, size_t);
                    598: static int audio_realloc_usrbuf(audio_track_t *, int);
                    599: static void audio_free_usrbuf(audio_track_t *);
                    600:
                    601: static audio_track_t *audio_track_create(struct audio_softc *,
                    602:        audio_trackmixer_t *);
                    603: static void audio_track_destroy(audio_track_t *);
                    604: static audio_filter_t audio_track_get_codec(audio_track_t *,
                    605:        const audio_format2_t *, const audio_format2_t *);
                    606: static int audio_track_set_format(audio_track_t *, audio_format2_t *);
                    607: static void audio_track_play(audio_track_t *);
                    608: static int audio_track_drain(struct audio_softc *, audio_track_t *);
                    609: static void audio_track_record(audio_track_t *);
                    610: static void audio_track_clear(struct audio_softc *, audio_track_t *);
                    611:
                    612: static int audio_mixer_init(struct audio_softc *, int,
                    613:        const audio_format2_t *, const audio_filter_reg_t *);
                    614: static void audio_mixer_destroy(struct audio_softc *, audio_trackmixer_t *);
                    615: static void audio_pmixer_start(struct audio_softc *, bool);
                    616: static void audio_pmixer_process(struct audio_softc *);
1.23      isaki     617: static void audio_pmixer_agc(audio_trackmixer_t *, int);
1.2       isaki     618: static int  audio_pmixer_mix_track(audio_trackmixer_t *, audio_track_t *, int);
                    619: static void audio_pmixer_output(struct audio_softc *);
                    620: static int  audio_pmixer_halt(struct audio_softc *);
                    621: static void audio_rmixer_start(struct audio_softc *);
                    622: static void audio_rmixer_process(struct audio_softc *);
                    623: static void audio_rmixer_input(struct audio_softc *);
                    624: static int  audio_rmixer_halt(struct audio_softc *);
                    625:
                    626: static void mixer_init(struct audio_softc *);
                    627: static int mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *);
                    628: static int mixer_close(struct audio_softc *, audio_file_t *);
                    629: static int mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *);
1.41      isaki     630: static void mixer_async_add(struct audio_softc *, pid_t);
                    631: static void mixer_async_remove(struct audio_softc *, pid_t);
1.2       isaki     632: static void mixer_signal(struct audio_softc *);
                    633:
                    634: static int au_portof(struct audio_softc *, char *, int);
                    635:
                    636: static void au_setup_ports(struct audio_softc *, struct au_mixer_ports *,
                    637:        mixer_devinfo_t *, const struct portname *);
                    638: static int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, int, int);
                    639: static int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, int *, int *);
                    640: static int au_set_gain(struct audio_softc *, struct au_mixer_ports *, int, int);
                    641: static void au_get_gain(struct audio_softc *, struct au_mixer_ports *,
                    642:        u_int *, u_char *);
                    643: static int au_set_port(struct audio_softc *, struct au_mixer_ports *, u_int);
                    644: static int au_get_port(struct audio_softc *, struct au_mixer_ports *);
                    645: static int au_set_monitor_gain(struct audio_softc *, int);
                    646: static int au_get_monitor_gain(struct audio_softc *);
                    647: static int audio_get_port(struct audio_softc *, mixer_ctrl_t *);
                    648: static int audio_set_port(struct audio_softc *, mixer_ctrl_t *);
                    649:
                    650: static __inline struct audio_params
                    651: format2_to_params(const audio_format2_t *f2)
                    652: {
                    653:        audio_params_t p;
                    654:
                    655:        /* validbits/precision <-> precision/stride */
                    656:        p.sample_rate = f2->sample_rate;
                    657:        p.channels    = f2->channels;
                    658:        p.encoding    = f2->encoding;
                    659:        p.validbits   = f2->precision;
                    660:        p.precision   = f2->stride;
                    661:        return p;
                    662: }
                    663:
                    664: static __inline audio_format2_t
                    665: params_to_format2(const struct audio_params *p)
                    666: {
                    667:        audio_format2_t f2;
                    668:
                    669:        /* precision/stride <-> validbits/precision */
                    670:        f2.sample_rate = p->sample_rate;
                    671:        f2.channels    = p->channels;
                    672:        f2.encoding    = p->encoding;
                    673:        f2.precision   = p->validbits;
                    674:        f2.stride      = p->precision;
                    675:        return f2;
                    676: }
                    677:
                    678: /* Return true if this track is a playback track. */
                    679: static __inline bool
                    680: audio_track_is_playback(const audio_track_t *track)
                    681: {
                    682:
                    683:        return ((track->mode & AUMODE_PLAY) != 0);
                    684: }
                    685:
                    686: /* Return true if this track is a recording track. */
                    687: static __inline bool
                    688: audio_track_is_record(const audio_track_t *track)
                    689: {
                    690:
                    691:        return ((track->mode & AUMODE_RECORD) != 0);
                    692: }
                    693:
                    694: #if 0 /* XXX Not used yet */
                    695: /*
                    696:  * Convert 0..255 volume used in userland to internal presentation 0..256.
                    697:  */
                    698: static __inline u_int
                    699: audio_volume_to_inner(u_int v)
                    700: {
                    701:
                    702:        return v < 127 ? v : v + 1;
                    703: }
                    704:
                    705: /*
                    706:  * Convert 0..256 internal presentation to 0..255 volume used in userland.
                    707:  */
                    708: static __inline u_int
                    709: audio_volume_to_outer(u_int v)
                    710: {
                    711:
                    712:        return v < 127 ? v : v - 1;
                    713: }
                    714: #endif /* 0 */
                    715:
                    716: static dev_type_open(audioopen);
                    717: /* XXXMRG use more dev_type_xxx */
                    718:
                    719: const struct cdevsw audio_cdevsw = {
                    720:        .d_open = audioopen,
                    721:        .d_close = noclose,
                    722:        .d_read = noread,
                    723:        .d_write = nowrite,
                    724:        .d_ioctl = noioctl,
                    725:        .d_stop = nostop,
                    726:        .d_tty = notty,
                    727:        .d_poll = nopoll,
                    728:        .d_mmap = nommap,
                    729:        .d_kqfilter = nokqfilter,
                    730:        .d_discard = nodiscard,
                    731:        .d_flag = D_OTHER | D_MPSAFE
                    732: };
                    733:
                    734: const struct fileops audio_fileops = {
                    735:        .fo_name = "audio",
                    736:        .fo_read = audioread,
                    737:        .fo_write = audiowrite,
                    738:        .fo_ioctl = audioioctl,
                    739:        .fo_fcntl = fnullop_fcntl,
                    740:        .fo_stat = audiostat,
                    741:        .fo_poll = audiopoll,
                    742:        .fo_close = audioclose,
                    743:        .fo_mmap = audiommap,
                    744:        .fo_kqfilter = audiokqfilter,
                    745:        .fo_restart = fnullop_restart
                    746: };
                    747:
                    748: /* The default audio mode: 8 kHz mono mu-law */
                    749: static const struct audio_params audio_default = {
                    750:        .sample_rate = 8000,
                    751:        .encoding = AUDIO_ENCODING_ULAW,
                    752:        .precision = 8,
                    753:        .validbits = 8,
                    754:        .channels = 1,
                    755: };
                    756:
                    757: static const char *encoding_names[] = {
                    758:        "none",
                    759:        AudioEmulaw,
                    760:        AudioEalaw,
                    761:        "pcm16",
                    762:        "pcm8",
                    763:        AudioEadpcm,
                    764:        AudioEslinear_le,
                    765:        AudioEslinear_be,
                    766:        AudioEulinear_le,
                    767:        AudioEulinear_be,
                    768:        AudioEslinear,
                    769:        AudioEulinear,
                    770:        AudioEmpeg_l1_stream,
                    771:        AudioEmpeg_l1_packets,
                    772:        AudioEmpeg_l1_system,
                    773:        AudioEmpeg_l2_stream,
                    774:        AudioEmpeg_l2_packets,
                    775:        AudioEmpeg_l2_system,
                    776:        AudioEac3,
                    777: };
                    778:
                    779: /*
                    780:  * Returns encoding name corresponding to AUDIO_ENCODING_*.
                    781:  * Note that it may return a local buffer because it is mainly for debugging.
                    782:  */
                    783: const char *
                    784: audio_encoding_name(int encoding)
                    785: {
                    786:        static char buf[16];
                    787:
                    788:        if (0 <= encoding && encoding < __arraycount(encoding_names)) {
                    789:                return encoding_names[encoding];
                    790:        } else {
                    791:                snprintf(buf, sizeof(buf), "enc=%d", encoding);
                    792:                return buf;
                    793:        }
                    794: }
                    795:
                    796: /*
                    797:  * Supported encodings used by AUDIO_GETENC.
                    798:  * index and flags are set by code.
                    799:  * XXX is there any needs for SLINEAR_OE:>=16/ULINEAR_OE:>=16 ?
                    800:  */
                    801: static const audio_encoding_t audio_encodings[] = {
                    802:        { 0, AudioEmulaw,       AUDIO_ENCODING_ULAW,            8,  0 },
                    803:        { 0, AudioEalaw,        AUDIO_ENCODING_ALAW,            8,  0 },
                    804:        { 0, AudioEslinear,     AUDIO_ENCODING_SLINEAR,         8,  0 },
                    805:        { 0, AudioEulinear,     AUDIO_ENCODING_ULINEAR,         8,  0 },
                    806:        { 0, AudioEslinear_le,  AUDIO_ENCODING_SLINEAR_LE,      16, 0 },
                    807:        { 0, AudioEulinear_le,  AUDIO_ENCODING_ULINEAR_LE,      16, 0 },
                    808:        { 0, AudioEslinear_be,  AUDIO_ENCODING_SLINEAR_BE,      16, 0 },
                    809:        { 0, AudioEulinear_be,  AUDIO_ENCODING_ULINEAR_BE,      16, 0 },
                    810: #if defined(AUDIO_SUPPORT_LINEAR24)
                    811:        { 0, AudioEslinear_le,  AUDIO_ENCODING_SLINEAR_LE,      24, 0 },
                    812:        { 0, AudioEulinear_le,  AUDIO_ENCODING_ULINEAR_LE,      24, 0 },
                    813:        { 0, AudioEslinear_be,  AUDIO_ENCODING_SLINEAR_BE,      24, 0 },
                    814:        { 0, AudioEulinear_be,  AUDIO_ENCODING_ULINEAR_BE,      24, 0 },
                    815: #endif
                    816:        { 0, AudioEslinear_le,  AUDIO_ENCODING_SLINEAR_LE,      32, 0 },
                    817:        { 0, AudioEulinear_le,  AUDIO_ENCODING_ULINEAR_LE,      32, 0 },
                    818:        { 0, AudioEslinear_be,  AUDIO_ENCODING_SLINEAR_BE,      32, 0 },
                    819:        { 0, AudioEulinear_be,  AUDIO_ENCODING_ULINEAR_BE,      32, 0 },
                    820: };
                    821:
                    822: static const struct portname itable[] = {
                    823:        { AudioNmicrophone,     AUDIO_MICROPHONE },
                    824:        { AudioNline,           AUDIO_LINE_IN },
                    825:        { AudioNcd,             AUDIO_CD },
                    826:        { 0, 0 }
                    827: };
                    828: static const struct portname otable[] = {
                    829:        { AudioNspeaker,        AUDIO_SPEAKER },
                    830:        { AudioNheadphone,      AUDIO_HEADPHONE },
                    831:        { AudioNline,           AUDIO_LINE_OUT },
                    832:        { 0, 0 }
                    833: };
                    834:
1.56      isaki     835: static struct psref_class *audio_psref_class __read_mostly;
                    836:
1.2       isaki     837: CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc),
                    838:     audiomatch, audioattach, audiodetach, audioactivate, audiorescan,
                    839:     audiochilddet, DVF_DETACH_SHUTDOWN);
                    840:
                    841: static int
                    842: audiomatch(device_t parent, cfdata_t match, void *aux)
                    843: {
                    844:        struct audio_attach_args *sa;
                    845:
                    846:        sa = aux;
                    847:        DPRINTF(1, "%s: type=%d sa=%p hw=%p\n",
                    848:             __func__, sa->type, sa, sa->hwif);
                    849:        return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
                    850: }
                    851:
                    852: static void
                    853: audioattach(device_t parent, device_t self, void *aux)
                    854: {
                    855:        struct audio_softc *sc;
                    856:        struct audio_attach_args *sa;
                    857:        const struct audio_hw_if *hw_if;
                    858:        audio_format2_t phwfmt;
                    859:        audio_format2_t rhwfmt;
                    860:        audio_filter_reg_t pfil;
                    861:        audio_filter_reg_t rfil;
                    862:        const struct sysctlnode *node;
                    863:        void *hdlp;
1.13      isaki     864:        bool has_playback;
                    865:        bool has_capture;
                    866:        bool has_indep;
                    867:        bool has_fulldup;
1.2       isaki     868:        int mode;
                    869:        int error;
                    870:
                    871:        sc = device_private(self);
                    872:        sc->sc_dev = self;
                    873:        sa = (struct audio_attach_args *)aux;
                    874:        hw_if = sa->hwif;
                    875:        hdlp = sa->hdl;
                    876:
1.54      isaki     877:        if (hw_if == NULL) {
1.2       isaki     878:                panic("audioattach: missing hw_if method");
                    879:        }
1.54      isaki     880:        if (hw_if->get_locks == NULL || hw_if->get_props == NULL) {
                    881:                aprint_error(": missing mandatory method\n");
                    882:                return;
                    883:        }
1.2       isaki     884:
                    885:        hw_if->get_locks(hdlp, &sc->sc_intr_lock, &sc->sc_lock);
1.54      isaki     886:        sc->sc_props = hw_if->get_props(hdlp);
                    887:
                    888:        has_playback = (sc->sc_props & AUDIO_PROP_PLAYBACK);
                    889:        has_capture  = (sc->sc_props & AUDIO_PROP_CAPTURE);
                    890:        has_indep    = (sc->sc_props & AUDIO_PROP_INDEPENDENT);
                    891:        has_fulldup  = (sc->sc_props & AUDIO_PROP_FULLDUPLEX);
1.2       isaki     892:
                    893: #ifdef DIAGNOSTIC
                    894:        if (hw_if->query_format == NULL ||
                    895:            hw_if->set_format == NULL ||
                    896:            hw_if->getdev == NULL ||
                    897:            hw_if->set_port == NULL ||
                    898:            hw_if->get_port == NULL ||
1.54      isaki     899:            hw_if->query_devinfo == NULL) {
                    900:                aprint_error(": missing mandatory method\n");
1.2       isaki     901:                return;
                    902:        }
1.54      isaki     903:        if (has_playback) {
1.76      isaki     904:                if ((hw_if->start_output == NULL &&
                    905:                     hw_if->trigger_output == NULL) ||
1.54      isaki     906:                    hw_if->halt_output == NULL) {
                    907:                        aprint_error(": missing playback method\n");
                    908:                }
                    909:        }
                    910:        if (has_capture) {
1.76      isaki     911:                if ((hw_if->start_input == NULL &&
                    912:                     hw_if->trigger_input == NULL) ||
1.54      isaki     913:                    hw_if->halt_input == NULL) {
                    914:                        aprint_error(": missing capture method\n");
                    915:                }
                    916:        }
1.2       isaki     917: #endif
                    918:
                    919:        sc->hw_if = hw_if;
                    920:        sc->hw_hdl = hdlp;
                    921:        sc->hw_dev = parent;
                    922:
1.63      isaki     923:        sc->sc_exlock = 1;
1.2       isaki     924:        sc->sc_blk_ms = AUDIO_BLK_MS;
                    925:        SLIST_INIT(&sc->sc_files);
                    926:        cv_init(&sc->sc_exlockcv, "audiolk");
1.41      isaki     927:        sc->sc_am_capacity = 0;
                    928:        sc->sc_am_used = 0;
                    929:        sc->sc_am = NULL;
1.2       isaki     930:
1.14      isaki     931:        /* MMAP is now supported by upper layer.  */
                    932:        sc->sc_props |= AUDIO_PROP_MMAP;
                    933:
1.13      isaki     934:        KASSERT(has_playback || has_capture);
                    935:        /* Unidirectional device must have neither FULLDUP nor INDEPENDENT. */
                    936:        if (!has_playback || !has_capture) {
                    937:                KASSERT(!has_indep);
                    938:                KASSERT(!has_fulldup);
                    939:        }
1.2       isaki     940:
                    941:        mode = 0;
1.13      isaki     942:        if (has_playback) {
                    943:                aprint_normal(": playback");
1.2       isaki     944:                mode |= AUMODE_PLAY;
                    945:        }
1.13      isaki     946:        if (has_capture) {
                    947:                aprint_normal("%c capture", has_playback ? ',' : ':');
1.2       isaki     948:                mode |= AUMODE_RECORD;
                    949:        }
1.13      isaki     950:        if (has_playback && has_capture) {
                    951:                if (has_fulldup)
                    952:                        aprint_normal(", full duplex");
                    953:                else
                    954:                        aprint_normal(", half duplex");
                    955:
                    956:                if (has_indep)
                    957:                        aprint_normal(", independent");
                    958:        }
1.2       isaki     959:
                    960:        aprint_naive("\n");
                    961:        aprint_normal("\n");
                    962:
                    963:        /* probe hw params */
                    964:        memset(&phwfmt, 0, sizeof(phwfmt));
                    965:        memset(&rhwfmt, 0, sizeof(rhwfmt));
                    966:        memset(&pfil, 0, sizeof(pfil));
                    967:        memset(&rfil, 0, sizeof(rfil));
1.55      isaki     968:        if (has_indep) {
                    969:                int perror, rerror;
                    970:
                    971:                /* On independent devices, probe separately. */
                    972:                perror = audio_hw_probe(sc, &phwfmt, AUMODE_PLAY);
                    973:                rerror = audio_hw_probe(sc, &rhwfmt, AUMODE_RECORD);
                    974:                if (perror && rerror) {
                    975:                        aprint_error_dev(self, "audio_hw_probe failed, "
                    976:                            "perror = %d, rerror = %d\n", perror, rerror);
                    977:                        goto bad;
                    978:                }
                    979:                if (perror) {
                    980:                        mode &= ~AUMODE_PLAY;
                    981:                        aprint_error_dev(self, "audio_hw_probe failed with "
                    982:                            "%d, playback disabled\n", perror);
                    983:                }
                    984:                if (rerror) {
                    985:                        mode &= ~AUMODE_RECORD;
                    986:                        aprint_error_dev(self, "audio_hw_probe failed with "
                    987:                            "%d, capture disabled\n", rerror);
                    988:                }
                    989:        } else {
                    990:                /*
                    991:                 * On non independent devices or uni-directional devices,
                    992:                 * probe once (simultaneously).
                    993:                 */
                    994:                audio_format2_t *fmt = has_playback ? &phwfmt : &rhwfmt;
                    995:                error = audio_hw_probe(sc, fmt, mode);
                    996:                if (error) {
                    997:                        aprint_error_dev(self, "audio_hw_probe failed, "
                    998:                            "error = %d\n", error);
                    999:                        goto bad;
                   1000:                }
                   1001:                if (has_playback && has_capture)
                   1002:                        rhwfmt = phwfmt;
1.2       isaki    1003:        }
1.55      isaki    1004:
1.2       isaki    1005:        /* Init hardware. */
                   1006:        /* hw_probe() also validates [pr]hwfmt.  */
                   1007:        error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
                   1008:        if (error) {
1.4       nakayama 1009:                aprint_error_dev(self, "audio_hw_set_format failed, "
                   1010:                    "error = %d\n", error);
1.2       isaki    1011:                goto bad;
                   1012:        }
                   1013:
                   1014:        /*
                   1015:         * Init track mixers.  If at least one direction is available on
                   1016:         * attach time, we assume a success.
                   1017:         */
                   1018:        error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
1.4       nakayama 1019:        if (sc->sc_pmixer == NULL && sc->sc_rmixer == NULL) {
                   1020:                aprint_error_dev(self, "audio_mixers_init failed, "
                   1021:                    "error = %d\n", error);
1.2       isaki    1022:                goto bad;
1.4       nakayama 1023:        }
1.2       isaki    1024:
1.56      isaki    1025:        sc->sc_psz = pserialize_create();
                   1026:        psref_target_init(&sc->sc_psref, audio_psref_class);
                   1027:
1.2       isaki    1028:        selinit(&sc->sc_wsel);
                   1029:        selinit(&sc->sc_rsel);
                   1030:
                   1031:        /* Initial parameter of /dev/sound */
                   1032:        sc->sc_sound_pparams = params_to_format2(&audio_default);
                   1033:        sc->sc_sound_rparams = params_to_format2(&audio_default);
                   1034:        sc->sc_sound_ppause = false;
                   1035:        sc->sc_sound_rpause = false;
                   1036:
                   1037:        /* XXX TODO: consider about sc_ai */
                   1038:
                   1039:        mixer_init(sc);
                   1040:        TRACE(2, "inputs ports=0x%x, input master=%d, "
                   1041:            "output ports=0x%x, output master=%d",
                   1042:            sc->sc_inports.allports, sc->sc_inports.master,
                   1043:            sc->sc_outports.allports, sc->sc_outports.master);
                   1044:
                   1045:        sysctl_createv(&sc->sc_log, 0, NULL, &node,
                   1046:            0,
                   1047:            CTLTYPE_NODE, device_xname(sc->sc_dev),
                   1048:            SYSCTL_DESCR("audio test"),
                   1049:            NULL, 0,
                   1050:            NULL, 0,
                   1051:            CTL_HW,
                   1052:            CTL_CREATE, CTL_EOL);
                   1053:
                   1054:        if (node != NULL) {
                   1055:                sysctl_createv(&sc->sc_log, 0, NULL, NULL,
                   1056:                    CTLFLAG_READWRITE,
                   1057:                    CTLTYPE_INT, "blk_ms",
                   1058:                    SYSCTL_DESCR("blocksize in msec"),
                   1059:                    audio_sysctl_blk_ms, 0, (void *)sc, 0,
                   1060:                    CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
                   1061:
                   1062:                sysctl_createv(&sc->sc_log, 0, NULL, NULL,
                   1063:                    CTLFLAG_READWRITE,
                   1064:                    CTLTYPE_BOOL, "multiuser",
                   1065:                    SYSCTL_DESCR("allow multiple user access"),
                   1066:                    audio_sysctl_multiuser, 0, (void *)sc, 0,
                   1067:                    CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
                   1068:
                   1069: #if defined(AUDIO_DEBUG)
                   1070:                sysctl_createv(&sc->sc_log, 0, NULL, NULL,
                   1071:                    CTLFLAG_READWRITE,
                   1072:                    CTLTYPE_INT, "debug",
                   1073:                    SYSCTL_DESCR("debug level (0..4)"),
                   1074:                    audio_sysctl_debug, 0, (void *)sc, 0,
                   1075:                    CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
                   1076: #endif
                   1077:        }
                   1078:
                   1079: #ifdef AUDIO_PM_IDLE
                   1080:        callout_init(&sc->sc_idle_counter, 0);
                   1081:        callout_setfunc(&sc->sc_idle_counter, audio_idle, self);
                   1082: #endif
                   1083:
                   1084:        if (!pmf_device_register(self, audio_suspend, audio_resume))
                   1085:                aprint_error_dev(self, "couldn't establish power handler\n");
                   1086: #ifdef AUDIO_PM_IDLE
                   1087:        if (!device_active_register(self, audio_activity))
                   1088:                aprint_error_dev(self, "couldn't register activity handler\n");
                   1089: #endif
                   1090:
                   1091:        if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN,
                   1092:            audio_volume_down, true))
                   1093:                aprint_error_dev(self, "couldn't add volume down handler\n");
                   1094:        if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP,
                   1095:            audio_volume_up, true))
                   1096:                aprint_error_dev(self, "couldn't add volume up handler\n");
                   1097:        if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE,
                   1098:            audio_volume_toggle, true))
                   1099:                aprint_error_dev(self, "couldn't add volume toggle handler\n");
                   1100:
                   1101: #ifdef AUDIO_PM_IDLE
                   1102:        callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz);
                   1103: #endif
                   1104:
                   1105: #if defined(AUDIO_DEBUG)
                   1106:        audio_mlog_init();
                   1107: #endif
                   1108:
                   1109:        audiorescan(self, "audio", NULL);
1.63      isaki    1110:        sc->sc_exlock = 0;
1.2       isaki    1111:        return;
                   1112:
                   1113: bad:
                   1114:        /* Clearing hw_if means that device is attached but disabled. */
                   1115:        sc->hw_if = NULL;
1.63      isaki    1116:        sc->sc_exlock = 0;
1.2       isaki    1117:        aprint_error_dev(sc->sc_dev, "disabled\n");
                   1118:        return;
                   1119: }
                   1120:
                   1121: /*
                   1122:  * Initialize hardware mixer.
                   1123:  * This function is called from audioattach().
                   1124:  */
                   1125: static void
                   1126: mixer_init(struct audio_softc *sc)
                   1127: {
                   1128:        mixer_devinfo_t mi;
                   1129:        int iclass, mclass, oclass, rclass;
                   1130:        int record_master_found, record_source_found;
                   1131:
                   1132:        iclass = mclass = oclass = rclass = -1;
                   1133:        sc->sc_inports.index = -1;
                   1134:        sc->sc_inports.master = -1;
                   1135:        sc->sc_inports.nports = 0;
                   1136:        sc->sc_inports.isenum = false;
                   1137:        sc->sc_inports.allports = 0;
                   1138:        sc->sc_inports.isdual = false;
                   1139:        sc->sc_inports.mixerout = -1;
                   1140:        sc->sc_inports.cur_port = -1;
                   1141:        sc->sc_outports.index = -1;
                   1142:        sc->sc_outports.master = -1;
                   1143:        sc->sc_outports.nports = 0;
                   1144:        sc->sc_outports.isenum = false;
                   1145:        sc->sc_outports.allports = 0;
                   1146:        sc->sc_outports.isdual = false;
                   1147:        sc->sc_outports.mixerout = -1;
                   1148:        sc->sc_outports.cur_port = -1;
                   1149:        sc->sc_monitor_port = -1;
                   1150:        /*
                   1151:         * Read through the underlying driver's list, picking out the class
                   1152:         * names from the mixer descriptions. We'll need them to decode the
                   1153:         * mixer descriptions on the next pass through the loop.
                   1154:         */
                   1155:        mutex_enter(sc->sc_lock);
                   1156:        for(mi.index = 0; ; mi.index++) {
                   1157:                if (audio_query_devinfo(sc, &mi) != 0)
                   1158:                        break;
                   1159:                 /*
                   1160:                  * The type of AUDIO_MIXER_CLASS merely introduces a class.
                   1161:                  * All the other types describe an actual mixer.
                   1162:                  */
                   1163:                if (mi.type == AUDIO_MIXER_CLASS) {
                   1164:                        if (strcmp(mi.label.name, AudioCinputs) == 0)
                   1165:                                iclass = mi.mixer_class;
                   1166:                        if (strcmp(mi.label.name, AudioCmonitor) == 0)
                   1167:                                mclass = mi.mixer_class;
                   1168:                        if (strcmp(mi.label.name, AudioCoutputs) == 0)
                   1169:                                oclass = mi.mixer_class;
                   1170:                        if (strcmp(mi.label.name, AudioCrecord) == 0)
                   1171:                                rclass = mi.mixer_class;
                   1172:                }
                   1173:        }
                   1174:        mutex_exit(sc->sc_lock);
                   1175:
                   1176:        /* Allocate save area.  Ensure non-zero allocation. */
                   1177:        sc->sc_nmixer_states = mi.index;
                   1178:        sc->sc_mixer_state = kmem_zalloc(sizeof(mixer_ctrl_t) *
                   1179:            (sc->sc_nmixer_states + 1), KM_SLEEP);
                   1180:
                   1181:        /*
                   1182:         * This is where we assign each control in the "audio" model, to the
                   1183:         * underlying "mixer" control.  We walk through the whole list once,
                   1184:         * assigning likely candidates as we come across them.
                   1185:         */
                   1186:        record_master_found = 0;
                   1187:        record_source_found = 0;
                   1188:        mutex_enter(sc->sc_lock);
                   1189:        for(mi.index = 0; ; mi.index++) {
                   1190:                if (audio_query_devinfo(sc, &mi) != 0)
                   1191:                        break;
                   1192:                KASSERT(mi.index < sc->sc_nmixer_states);
                   1193:                if (mi.type == AUDIO_MIXER_CLASS)
                   1194:                        continue;
                   1195:                if (mi.mixer_class == iclass) {
                   1196:                        /*
                   1197:                         * AudioCinputs is only a fallback, when we don't
                   1198:                         * find what we're looking for in AudioCrecord, so
                   1199:                         * check the flags before accepting one of these.
                   1200:                         */
                   1201:                        if (strcmp(mi.label.name, AudioNmaster) == 0
                   1202:                            && record_master_found == 0)
                   1203:                                sc->sc_inports.master = mi.index;
                   1204:                        if (strcmp(mi.label.name, AudioNsource) == 0
                   1205:                            && record_source_found == 0) {
                   1206:                                if (mi.type == AUDIO_MIXER_ENUM) {
                   1207:                                    int i;
                   1208:                                    for(i = 0; i < mi.un.e.num_mem; i++)
                   1209:                                        if (strcmp(mi.un.e.member[i].label.name,
                   1210:                                                    AudioNmixerout) == 0)
                   1211:                                                sc->sc_inports.mixerout =
                   1212:                                                    mi.un.e.member[i].ord;
                   1213:                                }
                   1214:                                au_setup_ports(sc, &sc->sc_inports, &mi,
                   1215:                                    itable);
                   1216:                        }
                   1217:                        if (strcmp(mi.label.name, AudioNdac) == 0 &&
                   1218:                            sc->sc_outports.master == -1)
                   1219:                                sc->sc_outports.master = mi.index;
                   1220:                } else if (mi.mixer_class == mclass) {
                   1221:                        if (strcmp(mi.label.name, AudioNmonitor) == 0)
                   1222:                                sc->sc_monitor_port = mi.index;
                   1223:                } else if (mi.mixer_class == oclass) {
                   1224:                        if (strcmp(mi.label.name, AudioNmaster) == 0)
                   1225:                                sc->sc_outports.master = mi.index;
                   1226:                        if (strcmp(mi.label.name, AudioNselect) == 0)
                   1227:                                au_setup_ports(sc, &sc->sc_outports, &mi,
                   1228:                                    otable);
                   1229:                } else if (mi.mixer_class == rclass) {
                   1230:                        /*
                   1231:                         * These are the preferred mixers for the audio record
                   1232:                         * controls, so set the flags here, but don't check.
                   1233:                         */
                   1234:                        if (strcmp(mi.label.name, AudioNmaster) == 0) {
                   1235:                                sc->sc_inports.master = mi.index;
                   1236:                                record_master_found = 1;
                   1237:                        }
                   1238: #if 1  /* Deprecated. Use AudioNmaster. */
                   1239:                        if (strcmp(mi.label.name, AudioNrecord) == 0) {
                   1240:                                sc->sc_inports.master = mi.index;
                   1241:                                record_master_found = 1;
                   1242:                        }
                   1243:                        if (strcmp(mi.label.name, AudioNvolume) == 0) {
                   1244:                                sc->sc_inports.master = mi.index;
                   1245:                                record_master_found = 1;
                   1246:                        }
                   1247: #endif
                   1248:                        if (strcmp(mi.label.name, AudioNsource) == 0) {
                   1249:                                if (mi.type == AUDIO_MIXER_ENUM) {
                   1250:                                    int i;
                   1251:                                    for(i = 0; i < mi.un.e.num_mem; i++)
                   1252:                                        if (strcmp(mi.un.e.member[i].label.name,
                   1253:                                                    AudioNmixerout) == 0)
                   1254:                                                sc->sc_inports.mixerout =
                   1255:                                                    mi.un.e.member[i].ord;
                   1256:                                }
                   1257:                                au_setup_ports(sc, &sc->sc_inports, &mi,
                   1258:                                    itable);
                   1259:                                record_source_found = 1;
                   1260:                        }
                   1261:                }
                   1262:        }
                   1263:        mutex_exit(sc->sc_lock);
                   1264: }
                   1265:
                   1266: static int
                   1267: audioactivate(device_t self, enum devact act)
                   1268: {
                   1269:        struct audio_softc *sc = device_private(self);
                   1270:
                   1271:        switch (act) {
                   1272:        case DVACT_DEACTIVATE:
                   1273:                mutex_enter(sc->sc_lock);
                   1274:                sc->sc_dying = true;
                   1275:                cv_broadcast(&sc->sc_exlockcv);
                   1276:                mutex_exit(sc->sc_lock);
                   1277:                return 0;
                   1278:        default:
                   1279:                return EOPNOTSUPP;
                   1280:        }
                   1281: }
                   1282:
                   1283: static int
                   1284: audiodetach(device_t self, int flags)
                   1285: {
                   1286:        struct audio_softc *sc;
1.56      isaki    1287:        struct audio_file *file;
1.2       isaki    1288:        int error;
                   1289:
                   1290:        sc = device_private(self);
                   1291:        TRACE(2, "flags=%d", flags);
                   1292:
                   1293:        /* device is not initialized */
                   1294:        if (sc->hw_if == NULL)
                   1295:                return 0;
                   1296:
                   1297:        /* Start draining existing accessors of the device. */
                   1298:        error = config_detach_children(self, flags);
                   1299:        if (error)
                   1300:                return error;
                   1301:
1.56      isaki    1302:        /* delete sysctl nodes */
                   1303:        sysctl_teardown(&sc->sc_log);
                   1304:
1.2       isaki    1305:        mutex_enter(sc->sc_lock);
                   1306:        sc->sc_dying = true;
                   1307:        cv_broadcast(&sc->sc_exlockcv);
                   1308:        if (sc->sc_pmixer)
                   1309:                cv_broadcast(&sc->sc_pmixer->outcv);
                   1310:        if (sc->sc_rmixer)
                   1311:                cv_broadcast(&sc->sc_rmixer->outcv);
1.56      isaki    1312:
                   1313:        /* Prevent new users */
                   1314:        SLIST_FOREACH(file, &sc->sc_files, entry) {
                   1315:                atomic_store_relaxed(&file->dying, true);
                   1316:        }
                   1317:
                   1318:        /*
                   1319:         * Wait for existing users to drain.
                   1320:         * - pserialize_perform waits for all pserialize_read sections on
                   1321:         *   all CPUs; after this, no more new psref_acquire can happen.
                   1322:         * - psref_target_destroy waits for all extant acquired psrefs to
                   1323:         *   be psref_released.
                   1324:         */
                   1325:        pserialize_perform(sc->sc_psz);
1.2       isaki    1326:        mutex_exit(sc->sc_lock);
1.56      isaki    1327:        psref_target_destroy(&sc->sc_psref, audio_psref_class);
1.2       isaki    1328:
1.56      isaki    1329:        /*
                   1330:         * We are now guaranteed that there are no calls to audio fileops
                   1331:         * that hold sc, and any new calls with files that were for sc will
                   1332:         * fail.  Thus, we now have exclusive access to the softc.
                   1333:         */
1.63      isaki    1334:        sc->sc_exlock = 1;
1.2       isaki    1335:
                   1336:        /*
1.56      isaki    1337:         * Nuke all open instances.
                   1338:         * Here, we no longer need any locks to traverse sc_files.
1.2       isaki    1339:         */
1.56      isaki    1340:        while ((file = SLIST_FIRST(&sc->sc_files)) != NULL) {
                   1341:                audio_unlink(sc, file);
                   1342:        }
1.2       isaki    1343:
                   1344:        pmf_event_deregister(self, PMFE_AUDIO_VOLUME_DOWN,
                   1345:            audio_volume_down, true);
                   1346:        pmf_event_deregister(self, PMFE_AUDIO_VOLUME_UP,
                   1347:            audio_volume_up, true);
                   1348:        pmf_event_deregister(self, PMFE_AUDIO_VOLUME_TOGGLE,
                   1349:            audio_volume_toggle, true);
                   1350:
                   1351: #ifdef AUDIO_PM_IDLE
                   1352:        callout_halt(&sc->sc_idle_counter, sc->sc_lock);
                   1353:
                   1354:        device_active_deregister(self, audio_activity);
                   1355: #endif
                   1356:
                   1357:        pmf_device_deregister(self);
                   1358:
                   1359:        /* Free resources */
                   1360:        if (sc->sc_pmixer) {
                   1361:                audio_mixer_destroy(sc, sc->sc_pmixer);
                   1362:                kmem_free(sc->sc_pmixer, sizeof(*sc->sc_pmixer));
                   1363:        }
                   1364:        if (sc->sc_rmixer) {
                   1365:                audio_mixer_destroy(sc, sc->sc_rmixer);
                   1366:                kmem_free(sc->sc_rmixer, sizeof(*sc->sc_rmixer));
                   1367:        }
1.41      isaki    1368:        if (sc->sc_am)
                   1369:                kern_free(sc->sc_am);
1.2       isaki    1370:
                   1371:        seldestroy(&sc->sc_wsel);
                   1372:        seldestroy(&sc->sc_rsel);
                   1373:
                   1374: #ifdef AUDIO_PM_IDLE
                   1375:        callout_destroy(&sc->sc_idle_counter);
                   1376: #endif
                   1377:
                   1378:        cv_destroy(&sc->sc_exlockcv);
                   1379:
                   1380: #if defined(AUDIO_DEBUG)
                   1381:        audio_mlog_free();
                   1382: #endif
                   1383:
                   1384:        return 0;
                   1385: }
                   1386:
                   1387: static void
                   1388: audiochilddet(device_t self, device_t child)
                   1389: {
                   1390:
                   1391:        /* we hold no child references, so do nothing */
                   1392: }
                   1393:
                   1394: static int
                   1395: audiosearch(device_t parent, cfdata_t cf, const int *locs, void *aux)
                   1396: {
                   1397:
                   1398:        if (config_match(parent, cf, aux))
                   1399:                config_attach_loc(parent, cf, locs, aux, NULL);
                   1400:
                   1401:        return 0;
                   1402: }
                   1403:
                   1404: static int
                   1405: audiorescan(device_t self, const char *ifattr, const int *flags)
                   1406: {
                   1407:        struct audio_softc *sc = device_private(self);
                   1408:
                   1409:        if (!ifattr_match(ifattr, "audio"))
                   1410:                return 0;
                   1411:
                   1412:        config_search_loc(audiosearch, sc->sc_dev, "audio", NULL, NULL);
                   1413:
                   1414:        return 0;
                   1415: }
                   1416:
                   1417: /*
                   1418:  * Called from hardware driver.  This is where the MI audio driver gets
                   1419:  * probed/attached to the hardware driver.
                   1420:  */
                   1421: device_t
                   1422: audio_attach_mi(const struct audio_hw_if *ahwp, void *hdlp, device_t dev)
                   1423: {
                   1424:        struct audio_attach_args arg;
                   1425:
                   1426: #ifdef DIAGNOSTIC
                   1427:        if (ahwp == NULL) {
                   1428:                aprint_error("audio_attach_mi: NULL\n");
                   1429:                return 0;
                   1430:        }
                   1431: #endif
                   1432:        arg.type = AUDIODEV_TYPE_AUDIO;
                   1433:        arg.hwif = ahwp;
                   1434:        arg.hdl = hdlp;
                   1435:        return config_found(dev, &arg, audioprint);
                   1436: }
                   1437:
                   1438: /*
1.63      isaki    1439:  * Enter critical section and also keep sc_lock.
                   1440:  * If successful, returns 0 with sc_lock held.  Otherwise returns errno.
1.42      isaki    1441:  * Must be called without sc_lock held.
1.2       isaki    1442:  */
                   1443: static int
1.63      isaki    1444: audio_exlock_mutex_enter(struct audio_softc *sc)
1.2       isaki    1445: {
                   1446:        int error;
                   1447:
                   1448:        mutex_enter(sc->sc_lock);
                   1449:        if (sc->sc_dying) {
                   1450:                mutex_exit(sc->sc_lock);
                   1451:                return EIO;
                   1452:        }
                   1453:
                   1454:        while (__predict_false(sc->sc_exlock != 0)) {
                   1455:                error = cv_wait_sig(&sc->sc_exlockcv, sc->sc_lock);
                   1456:                if (sc->sc_dying)
                   1457:                        error = EIO;
                   1458:                if (error) {
                   1459:                        mutex_exit(sc->sc_lock);
                   1460:                        return error;
                   1461:                }
                   1462:        }
                   1463:
                   1464:        /* Acquire */
                   1465:        sc->sc_exlock = 1;
                   1466:        return 0;
                   1467: }
                   1468:
                   1469: /*
1.63      isaki    1470:  * Exit critical section and exit sc_lock.
1.2       isaki    1471:  * Must be called with sc_lock held.
                   1472:  */
                   1473: static void
1.63      isaki    1474: audio_exlock_mutex_exit(struct audio_softc *sc)
1.2       isaki    1475: {
                   1476:
                   1477:        KASSERT(mutex_owned(sc->sc_lock));
                   1478:
                   1479:        sc->sc_exlock = 0;
                   1480:        cv_broadcast(&sc->sc_exlockcv);
                   1481:        mutex_exit(sc->sc_lock);
                   1482: }
                   1483:
                   1484: /*
1.63      isaki    1485:  * Enter critical section.
                   1486:  * If successful, it returns 0.  Otherwise returns errno.
                   1487:  * Must be called without sc_lock held.
                   1488:  * This function returns without sc_lock held.
                   1489:  */
                   1490: static int
                   1491: audio_exlock_enter(struct audio_softc *sc)
                   1492: {
                   1493:        int error;
                   1494:
                   1495:        error = audio_exlock_mutex_enter(sc);
                   1496:        if (error)
                   1497:                return error;
                   1498:        mutex_exit(sc->sc_lock);
                   1499:        return 0;
                   1500: }
                   1501:
                   1502: /*
                   1503:  * Exit critical section.
                   1504:  * Must be called without sc_lock held.
                   1505:  */
                   1506: static void
                   1507: audio_exlock_exit(struct audio_softc *sc)
                   1508: {
                   1509:
                   1510:        mutex_enter(sc->sc_lock);
                   1511:        audio_exlock_mutex_exit(sc);
                   1512: }
                   1513:
                   1514: /*
1.56      isaki    1515:  * Acquire sc from file, and increment the psref count.
                   1516:  * If successful, returns sc.  Otherwise returns NULL.
                   1517:  */
                   1518: struct audio_softc *
                   1519: audio_file_enter(audio_file_t *file, struct psref *refp)
                   1520: {
                   1521:        int s;
                   1522:        bool dying;
                   1523:
                   1524:        /* psref(9) forbids to migrate CPUs */
                   1525:        curlwp_bind();
                   1526:
                   1527:        /* Block audiodetach while we acquire a reference */
                   1528:        s = pserialize_read_enter();
                   1529:
                   1530:        /* If close or audiodetach already ran, tough -- no more audio */
                   1531:        dying = atomic_load_relaxed(&file->dying);
                   1532:        if (dying) {
                   1533:                pserialize_read_exit(s);
                   1534:                return NULL;
                   1535:        }
                   1536:
                   1537:        /* Acquire a reference */
                   1538:        psref_acquire(refp, &file->sc->sc_psref, audio_psref_class);
                   1539:
                   1540:        /* Now sc won't go away until we drop the reference count */
                   1541:        pserialize_read_exit(s);
                   1542:
                   1543:        return file->sc;
                   1544: }
                   1545:
                   1546: /*
                   1547:  * Decrement the psref count.
                   1548:  */
                   1549: void
                   1550: audio_file_exit(struct audio_softc *sc, struct psref *refp)
                   1551: {
                   1552:
                   1553:        psref_release(refp, &sc->sc_psref, audio_psref_class);
                   1554: }
                   1555:
                   1556: /*
1.2       isaki    1557:  * Wait for I/O to complete, releasing sc_lock.
                   1558:  * Must be called with sc_lock held.
                   1559:  */
                   1560: static int
                   1561: audio_track_waitio(struct audio_softc *sc, audio_track_t *track)
                   1562: {
                   1563:        int error;
                   1564:
                   1565:        KASSERT(track);
                   1566:        KASSERT(mutex_owned(sc->sc_lock));
                   1567:
                   1568:        /* Wait for pending I/O to complete. */
                   1569:        error = cv_timedwait_sig(&track->mixer->outcv, sc->sc_lock,
                   1570:            mstohz(AUDIO_TIMEOUT));
1.75      isaki    1571:        if (sc->sc_suspending) {
                   1572:                /* If it's about to suspend, ignore timeout error. */
                   1573:                if (error == EWOULDBLOCK) {
                   1574:                        TRACET(2, track, "timeout (suspending)");
                   1575:                        return 0;
                   1576:                }
                   1577:        }
1.2       isaki    1578:        if (sc->sc_dying) {
                   1579:                error = EIO;
                   1580:        }
                   1581:        if (error) {
                   1582:                TRACET(2, track, "cv_timedwait_sig failed %d", error);
                   1583:                if (error == EWOULDBLOCK)
                   1584:                        device_printf(sc->sc_dev, "device timeout\n");
                   1585:        } else {
                   1586:                TRACET(3, track, "wakeup");
                   1587:        }
                   1588:        return error;
                   1589: }
                   1590:
                   1591: /*
                   1592:  * Try to acquire track lock.
                   1593:  * It doesn't block if the track lock is already aquired.
                   1594:  * Returns true if the track lock was acquired, or false if the track
                   1595:  * lock was already acquired.
                   1596:  */
                   1597: static __inline bool
                   1598: audio_track_lock_tryenter(audio_track_t *track)
                   1599: {
                   1600:        return (atomic_cas_uint(&track->lock, 0, 1) == 0);
                   1601: }
                   1602:
                   1603: /*
                   1604:  * Acquire track lock.
                   1605:  */
                   1606: static __inline void
                   1607: audio_track_lock_enter(audio_track_t *track)
                   1608: {
                   1609:        /* Don't sleep here. */
                   1610:        while (audio_track_lock_tryenter(track) == false)
                   1611:                ;
                   1612: }
                   1613:
                   1614: /*
                   1615:  * Release track lock.
                   1616:  */
                   1617: static __inline void
                   1618: audio_track_lock_exit(audio_track_t *track)
                   1619: {
                   1620:        atomic_swap_uint(&track->lock, 0);
                   1621: }
                   1622:
                   1623:
                   1624: static int
                   1625: audioopen(dev_t dev, int flags, int ifmt, struct lwp *l)
                   1626: {
                   1627:        struct audio_softc *sc;
                   1628:        int error;
                   1629:
                   1630:        /* Find the device */
                   1631:        sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev));
                   1632:        if (sc == NULL || sc->hw_if == NULL)
                   1633:                return ENXIO;
                   1634:
1.63      isaki    1635:        error = audio_exlock_enter(sc);
1.2       isaki    1636:        if (error)
                   1637:                return error;
                   1638:
                   1639:        device_active(sc->sc_dev, DVA_SYSTEM);
                   1640:        switch (AUDIODEV(dev)) {
                   1641:        case SOUND_DEVICE:
                   1642:        case AUDIO_DEVICE:
                   1643:                error = audio_open(dev, sc, flags, ifmt, l, NULL);
                   1644:                break;
                   1645:        case AUDIOCTL_DEVICE:
                   1646:                error = audioctl_open(dev, sc, flags, ifmt, l);
                   1647:                break;
                   1648:        case MIXER_DEVICE:
                   1649:                error = mixer_open(dev, sc, flags, ifmt, l);
                   1650:                break;
                   1651:        default:
                   1652:                error = ENXIO;
                   1653:                break;
                   1654:        }
1.63      isaki    1655:        audio_exlock_exit(sc);
1.2       isaki    1656:
                   1657:        return error;
                   1658: }
                   1659:
                   1660: static int
                   1661: audioclose(struct file *fp)
                   1662: {
                   1663:        struct audio_softc *sc;
1.56      isaki    1664:        struct psref sc_ref;
1.2       isaki    1665:        audio_file_t *file;
                   1666:        int error;
                   1667:        dev_t dev;
                   1668:
                   1669:        KASSERT(fp->f_audioctx);
                   1670:        file = fp->f_audioctx;
                   1671:        dev = file->dev;
1.56      isaki    1672:        error = 0;
                   1673:
                   1674:        /*
                   1675:         * audioclose() must
                   1676:         * - unplug track from the trackmixer (and unplug anything from softc),
                   1677:         *   if sc exists.
                   1678:         * - free all memory objects, regardless of sc.
                   1679:         */
1.2       isaki    1680:
1.56      isaki    1681:        sc = audio_file_enter(file, &sc_ref);
                   1682:        if (sc) {
                   1683:                switch (AUDIODEV(dev)) {
                   1684:                case SOUND_DEVICE:
                   1685:                case AUDIO_DEVICE:
                   1686:                        error = audio_close(sc, file);
                   1687:                        break;
                   1688:                case AUDIOCTL_DEVICE:
                   1689:                        error = 0;
                   1690:                        break;
                   1691:                case MIXER_DEVICE:
                   1692:                        error = mixer_close(sc, file);
                   1693:                        break;
                   1694:                default:
                   1695:                        error = ENXIO;
                   1696:                        break;
                   1697:                }
1.2       isaki    1698:
1.56      isaki    1699:                audio_file_exit(sc, &sc_ref);
1.2       isaki    1700:        }
1.56      isaki    1701:
                   1702:        /* Free memory objects anyway */
                   1703:        TRACEF(2, file, "free memory");
                   1704:        if (file->ptrack)
                   1705:                audio_track_destroy(file->ptrack);
                   1706:        if (file->rtrack)
                   1707:                audio_track_destroy(file->rtrack);
                   1708:        kmem_free(file, sizeof(*file));
1.39      isaki    1709:        fp->f_audioctx = NULL;
1.2       isaki    1710:
                   1711:        return error;
                   1712: }
                   1713:
                   1714: static int
                   1715: audioread(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
                   1716:        int ioflag)
                   1717: {
                   1718:        struct audio_softc *sc;
1.56      isaki    1719:        struct psref sc_ref;
1.2       isaki    1720:        audio_file_t *file;
                   1721:        int error;
                   1722:        dev_t dev;
                   1723:
                   1724:        KASSERT(fp->f_audioctx);
                   1725:        file = fp->f_audioctx;
                   1726:        dev = file->dev;
                   1727:
1.56      isaki    1728:        sc = audio_file_enter(file, &sc_ref);
                   1729:        if (sc == NULL)
                   1730:                return EIO;
                   1731:
1.2       isaki    1732:        if (fp->f_flag & O_NONBLOCK)
                   1733:                ioflag |= IO_NDELAY;
                   1734:
                   1735:        switch (AUDIODEV(dev)) {
                   1736:        case SOUND_DEVICE:
                   1737:        case AUDIO_DEVICE:
                   1738:                error = audio_read(sc, uio, ioflag, file);
                   1739:                break;
                   1740:        case AUDIOCTL_DEVICE:
                   1741:        case MIXER_DEVICE:
                   1742:                error = ENODEV;
                   1743:                break;
                   1744:        default:
                   1745:                error = ENXIO;
                   1746:                break;
                   1747:        }
                   1748:
1.56      isaki    1749:        audio_file_exit(sc, &sc_ref);
1.2       isaki    1750:        return error;
                   1751: }
                   1752:
                   1753: static int
                   1754: audiowrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
                   1755:        int ioflag)
                   1756: {
                   1757:        struct audio_softc *sc;
1.56      isaki    1758:        struct psref sc_ref;
1.2       isaki    1759:        audio_file_t *file;
                   1760:        int error;
                   1761:        dev_t dev;
                   1762:
                   1763:        KASSERT(fp->f_audioctx);
                   1764:        file = fp->f_audioctx;
                   1765:        dev = file->dev;
                   1766:
1.56      isaki    1767:        sc = audio_file_enter(file, &sc_ref);
                   1768:        if (sc == NULL)
                   1769:                return EIO;
                   1770:
1.2       isaki    1771:        if (fp->f_flag & O_NONBLOCK)
                   1772:                ioflag |= IO_NDELAY;
                   1773:
                   1774:        switch (AUDIODEV(dev)) {
                   1775:        case SOUND_DEVICE:
                   1776:        case AUDIO_DEVICE:
                   1777:                error = audio_write(sc, uio, ioflag, file);
                   1778:                break;
                   1779:        case AUDIOCTL_DEVICE:
                   1780:        case MIXER_DEVICE:
                   1781:                error = ENODEV;
                   1782:                break;
                   1783:        default:
                   1784:                error = ENXIO;
                   1785:                break;
                   1786:        }
                   1787:
1.56      isaki    1788:        audio_file_exit(sc, &sc_ref);
1.2       isaki    1789:        return error;
                   1790: }
                   1791:
                   1792: static int
                   1793: audioioctl(struct file *fp, u_long cmd, void *addr)
                   1794: {
                   1795:        struct audio_softc *sc;
1.56      isaki    1796:        struct psref sc_ref;
1.2       isaki    1797:        audio_file_t *file;
                   1798:        struct lwp *l = curlwp;
                   1799:        int error;
                   1800:        dev_t dev;
                   1801:
                   1802:        KASSERT(fp->f_audioctx);
                   1803:        file = fp->f_audioctx;
                   1804:        dev = file->dev;
                   1805:
1.56      isaki    1806:        sc = audio_file_enter(file, &sc_ref);
                   1807:        if (sc == NULL)
                   1808:                return EIO;
                   1809:
1.2       isaki    1810:        switch (AUDIODEV(dev)) {
                   1811:        case SOUND_DEVICE:
                   1812:        case AUDIO_DEVICE:
                   1813:        case AUDIOCTL_DEVICE:
                   1814:                mutex_enter(sc->sc_lock);
                   1815:                device_active(sc->sc_dev, DVA_SYSTEM);
                   1816:                mutex_exit(sc->sc_lock);
                   1817:                if (IOCGROUP(cmd) == IOCGROUP(AUDIO_MIXER_READ))
                   1818:                        error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l);
                   1819:                else
                   1820:                        error = audio_ioctl(dev, sc, cmd, addr, fp->f_flag, l,
                   1821:                            file);
                   1822:                break;
                   1823:        case MIXER_DEVICE:
                   1824:                error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l);
                   1825:                break;
                   1826:        default:
                   1827:                error = ENXIO;
                   1828:                break;
                   1829:        }
                   1830:
1.56      isaki    1831:        audio_file_exit(sc, &sc_ref);
1.2       isaki    1832:        return error;
                   1833: }
                   1834:
                   1835: static int
                   1836: audiostat(struct file *fp, struct stat *st)
                   1837: {
1.56      isaki    1838:        struct audio_softc *sc;
                   1839:        struct psref sc_ref;
1.2       isaki    1840:        audio_file_t *file;
                   1841:
                   1842:        KASSERT(fp->f_audioctx);
                   1843:        file = fp->f_audioctx;
                   1844:
1.56      isaki    1845:        sc = audio_file_enter(file, &sc_ref);
                   1846:        if (sc == NULL)
                   1847:                return EIO;
                   1848:
1.2       isaki    1849:        memset(st, 0, sizeof(*st));
                   1850:
                   1851:        st->st_dev = file->dev;
                   1852:        st->st_uid = kauth_cred_geteuid(fp->f_cred);
                   1853:        st->st_gid = kauth_cred_getegid(fp->f_cred);
                   1854:        st->st_mode = S_IFCHR;
1.56      isaki    1855:
                   1856:        audio_file_exit(sc, &sc_ref);
1.2       isaki    1857:        return 0;
                   1858: }
                   1859:
                   1860: static int
                   1861: audiopoll(struct file *fp, int events)
                   1862: {
                   1863:        struct audio_softc *sc;
1.56      isaki    1864:        struct psref sc_ref;
1.2       isaki    1865:        audio_file_t *file;
                   1866:        struct lwp *l = curlwp;
                   1867:        int revents;
                   1868:        dev_t dev;
                   1869:
                   1870:        KASSERT(fp->f_audioctx);
                   1871:        file = fp->f_audioctx;
                   1872:        dev = file->dev;
                   1873:
1.56      isaki    1874:        sc = audio_file_enter(file, &sc_ref);
                   1875:        if (sc == NULL)
                   1876:                return EIO;
                   1877:
1.2       isaki    1878:        switch (AUDIODEV(dev)) {
                   1879:        case SOUND_DEVICE:
                   1880:        case AUDIO_DEVICE:
                   1881:                revents = audio_poll(sc, events, l, file);
                   1882:                break;
                   1883:        case AUDIOCTL_DEVICE:
                   1884:        case MIXER_DEVICE:
                   1885:                revents = 0;
                   1886:                break;
                   1887:        default:
                   1888:                revents = POLLERR;
                   1889:                break;
                   1890:        }
                   1891:
1.56      isaki    1892:        audio_file_exit(sc, &sc_ref);
1.2       isaki    1893:        return revents;
                   1894: }
                   1895:
                   1896: static int
                   1897: audiokqfilter(struct file *fp, struct knote *kn)
                   1898: {
                   1899:        struct audio_softc *sc;
1.56      isaki    1900:        struct psref sc_ref;
1.2       isaki    1901:        audio_file_t *file;
                   1902:        dev_t dev;
                   1903:        int error;
                   1904:
                   1905:        KASSERT(fp->f_audioctx);
                   1906:        file = fp->f_audioctx;
                   1907:        dev = file->dev;
                   1908:
1.56      isaki    1909:        sc = audio_file_enter(file, &sc_ref);
                   1910:        if (sc == NULL)
                   1911:                return EIO;
                   1912:
1.2       isaki    1913:        switch (AUDIODEV(dev)) {
                   1914:        case SOUND_DEVICE:
                   1915:        case AUDIO_DEVICE:
                   1916:                error = audio_kqfilter(sc, file, kn);
                   1917:                break;
                   1918:        case AUDIOCTL_DEVICE:
                   1919:        case MIXER_DEVICE:
                   1920:                error = ENODEV;
                   1921:                break;
                   1922:        default:
                   1923:                error = ENXIO;
                   1924:                break;
                   1925:        }
                   1926:
1.56      isaki    1927:        audio_file_exit(sc, &sc_ref);
1.2       isaki    1928:        return error;
                   1929: }
                   1930:
                   1931: static int
                   1932: audiommap(struct file *fp, off_t *offp, size_t len, int prot, int *flagsp,
                   1933:        int *advicep, struct uvm_object **uobjp, int *maxprotp)
                   1934: {
                   1935:        struct audio_softc *sc;
1.56      isaki    1936:        struct psref sc_ref;
1.2       isaki    1937:        audio_file_t *file;
                   1938:        dev_t dev;
                   1939:        int error;
                   1940:
                   1941:        KASSERT(fp->f_audioctx);
                   1942:        file = fp->f_audioctx;
                   1943:        dev = file->dev;
                   1944:
1.56      isaki    1945:        sc = audio_file_enter(file, &sc_ref);
                   1946:        if (sc == NULL)
                   1947:                return EIO;
                   1948:
1.2       isaki    1949:        mutex_enter(sc->sc_lock);
                   1950:        device_active(sc->sc_dev, DVA_SYSTEM); /* XXXJDM */
                   1951:        mutex_exit(sc->sc_lock);
                   1952:
                   1953:        switch (AUDIODEV(dev)) {
                   1954:        case SOUND_DEVICE:
                   1955:        case AUDIO_DEVICE:
                   1956:                error = audio_mmap(sc, offp, len, prot, flagsp, advicep,
                   1957:                    uobjp, maxprotp, file);
                   1958:                break;
                   1959:        case AUDIOCTL_DEVICE:
                   1960:        case MIXER_DEVICE:
                   1961:        default:
                   1962:                error = ENOTSUP;
                   1963:                break;
                   1964:        }
                   1965:
1.56      isaki    1966:        audio_file_exit(sc, &sc_ref);
1.2       isaki    1967:        return error;
                   1968: }
                   1969:
                   1970:
                   1971: /* Exported interfaces for audiobell. */
                   1972:
                   1973: /*
                   1974:  * Open for audiobell.
1.21      isaki    1975:  * It stores allocated file to *filep.
1.2       isaki    1976:  * If successful returns 0, otherwise errno.
                   1977:  */
                   1978: int
1.21      isaki    1979: audiobellopen(dev_t dev, audio_file_t **filep)
1.2       isaki    1980: {
                   1981:        struct audio_softc *sc;
                   1982:        int error;
                   1983:
                   1984:        /* Find the device */
                   1985:        sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev));
                   1986:        if (sc == NULL || sc->hw_if == NULL)
                   1987:                return ENXIO;
                   1988:
1.63      isaki    1989:        error = audio_exlock_enter(sc);
1.2       isaki    1990:        if (error)
                   1991:                return error;
                   1992:
                   1993:        device_active(sc->sc_dev, DVA_SYSTEM);
1.21      isaki    1994:        error = audio_open(dev, sc, FWRITE, 0, curlwp, filep);
1.2       isaki    1995:
1.63      isaki    1996:        audio_exlock_exit(sc);
1.2       isaki    1997:        return error;
                   1998: }
                   1999:
                   2000: /* Close for audiobell */
                   2001: int
                   2002: audiobellclose(audio_file_t *file)
                   2003: {
                   2004:        struct audio_softc *sc;
1.56      isaki    2005:        struct psref sc_ref;
1.2       isaki    2006:        int error;
                   2007:
1.56      isaki    2008:        sc = audio_file_enter(file, &sc_ref);
                   2009:        if (sc == NULL)
                   2010:                return EIO;
1.2       isaki    2011:
                   2012:        error = audio_close(sc, file);
                   2013:
1.56      isaki    2014:        audio_file_exit(sc, &sc_ref);
1.57      isaki    2015:
                   2016:        KASSERT(file->ptrack);
                   2017:        audio_track_destroy(file->ptrack);
                   2018:        KASSERT(file->rtrack == NULL);
                   2019:        kmem_free(file, sizeof(*file));
1.2       isaki    2020:        return error;
                   2021: }
                   2022:
1.21      isaki    2023: /* Set sample rate for audiobell */
                   2024: int
                   2025: audiobellsetrate(audio_file_t *file, u_int sample_rate)
                   2026: {
                   2027:        struct audio_softc *sc;
1.56      isaki    2028:        struct psref sc_ref;
1.21      isaki    2029:        struct audio_info ai;
                   2030:        int error;
                   2031:
1.56      isaki    2032:        sc = audio_file_enter(file, &sc_ref);
                   2033:        if (sc == NULL)
                   2034:                return EIO;
1.21      isaki    2035:
                   2036:        AUDIO_INITINFO(&ai);
                   2037:        ai.play.sample_rate = sample_rate;
                   2038:
1.63      isaki    2039:        error = audio_exlock_enter(sc);
1.21      isaki    2040:        if (error)
1.56      isaki    2041:                goto done;
1.21      isaki    2042:        error = audio_file_setinfo(sc, file, &ai);
1.63      isaki    2043:        audio_exlock_exit(sc);
1.21      isaki    2044:
1.56      isaki    2045: done:
                   2046:        audio_file_exit(sc, &sc_ref);
1.21      isaki    2047:        return error;
                   2048: }
                   2049:
1.2       isaki    2050: /* Playback for audiobell */
                   2051: int
                   2052: audiobellwrite(audio_file_t *file, struct uio *uio)
                   2053: {
                   2054:        struct audio_softc *sc;
1.56      isaki    2055:        struct psref sc_ref;
1.2       isaki    2056:        int error;
                   2057:
1.56      isaki    2058:        sc = audio_file_enter(file, &sc_ref);
                   2059:        if (sc == NULL)
                   2060:                return EIO;
                   2061:
1.2       isaki    2062:        error = audio_write(sc, uio, 0, file);
1.56      isaki    2063:
                   2064:        audio_file_exit(sc, &sc_ref);
1.2       isaki    2065:        return error;
                   2066: }
                   2067:
                   2068:
                   2069: /*
                   2070:  * Audio driver
                   2071:  */
1.63      isaki    2072:
                   2073: /*
                   2074:  * Must be called with sc_exlock held and without sc_lock held.
                   2075:  */
1.2       isaki    2076: int
                   2077: audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
1.21      isaki    2078:        struct lwp *l, audio_file_t **bellfile)
1.2       isaki    2079: {
                   2080:        struct audio_info ai;
                   2081:        struct file *fp;
                   2082:        audio_file_t *af;
                   2083:        audio_ring_t *hwbuf;
                   2084:        bool fullduplex;
                   2085:        int fd;
                   2086:        int error;
                   2087:
                   2088:        KASSERT(sc->sc_exlock);
                   2089:
1.22      isaki    2090:        TRACE(1, "%sdev=%s flags=0x%x po=%d ro=%d",
1.2       isaki    2091:            (audiodebug >= 3) ? "start " : "",
1.22      isaki    2092:            ISDEVSOUND(dev) ? "sound" : "audio",
1.2       isaki    2093:            flags, sc->sc_popens, sc->sc_ropens);
                   2094:
                   2095:        af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP);
                   2096:        af->sc = sc;
                   2097:        af->dev = dev;
                   2098:        if ((flags & FWRITE) != 0 && audio_can_playback(sc))
                   2099:                af->mode |= AUMODE_PLAY | AUMODE_PLAY_ALL;
                   2100:        if ((flags & FREAD) != 0 && audio_can_capture(sc))
                   2101:                af->mode |= AUMODE_RECORD;
                   2102:        if (af->mode == 0) {
                   2103:                error = ENXIO;
                   2104:                goto bad1;
                   2105:        }
                   2106:
1.14      isaki    2107:        fullduplex = (sc->sc_props & AUDIO_PROP_FULLDUPLEX);
1.2       isaki    2108:
                   2109:        /*
                   2110:         * On half duplex hardware,
                   2111:         * 1. if mode is (PLAY | REC), let mode PLAY.
                   2112:         * 2. if mode is PLAY, let mode PLAY if no rec tracks, otherwise error.
                   2113:         * 3. if mode is REC, let mode REC if no play tracks, otherwise error.
                   2114:         */
                   2115:        if (fullduplex == false) {
                   2116:                if ((af->mode & AUMODE_PLAY)) {
                   2117:                        if (sc->sc_ropens != 0) {
                   2118:                                TRACE(1, "record track already exists");
                   2119:                                error = ENODEV;
                   2120:                                goto bad1;
                   2121:                        }
                   2122:                        /* Play takes precedence */
                   2123:                        af->mode &= ~AUMODE_RECORD;
                   2124:                }
                   2125:                if ((af->mode & AUMODE_RECORD)) {
                   2126:                        if (sc->sc_popens != 0) {
                   2127:                                TRACE(1, "play track already exists");
                   2128:                                error = ENODEV;
                   2129:                                goto bad1;
                   2130:                        }
                   2131:                }
                   2132:        }
                   2133:
                   2134:        /* Create tracks */
                   2135:        if ((af->mode & AUMODE_PLAY))
                   2136:                af->ptrack = audio_track_create(sc, sc->sc_pmixer);
                   2137:        if ((af->mode & AUMODE_RECORD))
                   2138:                af->rtrack = audio_track_create(sc, sc->sc_rmixer);
                   2139:
                   2140:        /* Set parameters */
                   2141:        AUDIO_INITINFO(&ai);
1.21      isaki    2142:        if (bellfile) {
                   2143:                /* If audiobell, only sample_rate will be set later. */
                   2144:                ai.play.sample_rate   = audio_default.sample_rate;
                   2145:                ai.play.encoding      = AUDIO_ENCODING_SLINEAR_NE;
                   2146:                ai.play.channels      = 1;
                   2147:                ai.play.precision     = 16;
1.58      isaki    2148:                ai.play.pause         = 0;
1.2       isaki    2149:        } else if (ISDEVAUDIO(dev)) {
                   2150:                /* If /dev/audio, initialize everytime. */
                   2151:                ai.play.sample_rate   = audio_default.sample_rate;
                   2152:                ai.play.encoding      = audio_default.encoding;
                   2153:                ai.play.channels      = audio_default.channels;
                   2154:                ai.play.precision     = audio_default.precision;
1.58      isaki    2155:                ai.play.pause         = 0;
1.2       isaki    2156:                ai.record.sample_rate = audio_default.sample_rate;
                   2157:                ai.record.encoding    = audio_default.encoding;
                   2158:                ai.record.channels    = audio_default.channels;
                   2159:                ai.record.precision   = audio_default.precision;
1.58      isaki    2160:                ai.record.pause       = 0;
1.2       isaki    2161:        } else {
                   2162:                /* If /dev/sound, take over the previous parameters. */
                   2163:                ai.play.sample_rate   = sc->sc_sound_pparams.sample_rate;
                   2164:                ai.play.encoding      = sc->sc_sound_pparams.encoding;
                   2165:                ai.play.channels      = sc->sc_sound_pparams.channels;
                   2166:                ai.play.precision     = sc->sc_sound_pparams.precision;
                   2167:                ai.play.pause         = sc->sc_sound_ppause;
                   2168:                ai.record.sample_rate = sc->sc_sound_rparams.sample_rate;
                   2169:                ai.record.encoding    = sc->sc_sound_rparams.encoding;
                   2170:                ai.record.channels    = sc->sc_sound_rparams.channels;
                   2171:                ai.record.precision   = sc->sc_sound_rparams.precision;
                   2172:                ai.record.pause       = sc->sc_sound_rpause;
                   2173:        }
                   2174:        error = audio_file_setinfo(sc, af, &ai);
                   2175:        if (error)
                   2176:                goto bad2;
                   2177:
                   2178:        if (sc->sc_popens + sc->sc_ropens == 0) {
                   2179:                /* First open */
                   2180:
                   2181:                sc->sc_cred = kauth_cred_get();
                   2182:                kauth_cred_hold(sc->sc_cred);
                   2183:
                   2184:                if (sc->hw_if->open) {
                   2185:                        int hwflags;
                   2186:
                   2187:                        /*
                   2188:                         * Call hw_if->open() only at first open of
                   2189:                         * combination of playback and recording.
                   2190:                         * On full duplex hardware, the flags passed to
                   2191:                         * hw_if->open() is always (FREAD | FWRITE)
                   2192:                         * regardless of this open()'s flags.
                   2193:                         * see also dev/isa/aria.c
                   2194:                         * On half duplex hardware, the flags passed to
                   2195:                         * hw_if->open() is either FREAD or FWRITE.
                   2196:                         * see also arch/evbarm/mini2440/audio_mini2440.c
                   2197:                         */
                   2198:                        if (fullduplex) {
                   2199:                                hwflags = FREAD | FWRITE;
                   2200:                        } else {
                   2201:                                /* Construct hwflags from af->mode. */
                   2202:                                hwflags = 0;
                   2203:                                if ((af->mode & AUMODE_PLAY) != 0)
                   2204:                                        hwflags |= FWRITE;
                   2205:                                if ((af->mode & AUMODE_RECORD) != 0)
                   2206:                                        hwflags |= FREAD;
                   2207:                        }
                   2208:
1.63      isaki    2209:                        mutex_enter(sc->sc_lock);
1.2       isaki    2210:                        mutex_enter(sc->sc_intr_lock);
                   2211:                        error = sc->hw_if->open(sc->hw_hdl, hwflags);
                   2212:                        mutex_exit(sc->sc_intr_lock);
1.63      isaki    2213:                        mutex_exit(sc->sc_lock);
1.2       isaki    2214:                        if (error)
                   2215:                                goto bad2;
                   2216:                }
                   2217:
                   2218:                /*
                   2219:                 * Set speaker mode when a half duplex.
                   2220:                 * XXX I'm not sure this is correct.
                   2221:                 */
                   2222:                if (1/*XXX*/) {
                   2223:                        if (sc->hw_if->speaker_ctl) {
                   2224:                                int on;
                   2225:                                if (af->ptrack) {
                   2226:                                        on = 1;
                   2227:                                } else {
                   2228:                                        on = 0;
                   2229:                                }
1.63      isaki    2230:                                mutex_enter(sc->sc_lock);
1.2       isaki    2231:                                mutex_enter(sc->sc_intr_lock);
                   2232:                                error = sc->hw_if->speaker_ctl(sc->hw_hdl, on);
                   2233:                                mutex_exit(sc->sc_intr_lock);
1.63      isaki    2234:                                mutex_exit(sc->sc_lock);
1.2       isaki    2235:                                if (error)
                   2236:                                        goto bad3;
                   2237:                        }
                   2238:                }
                   2239:        } else if (sc->sc_multiuser == false) {
                   2240:                uid_t euid = kauth_cred_geteuid(kauth_cred_get());
                   2241:                if (euid != 0 && euid != kauth_cred_geteuid(sc->sc_cred)) {
                   2242:                        error = EPERM;
                   2243:                        goto bad2;
                   2244:                }
                   2245:        }
                   2246:
                   2247:        /* Call init_output if this is the first playback open. */
                   2248:        if (af->ptrack && sc->sc_popens == 0) {
                   2249:                if (sc->hw_if->init_output) {
                   2250:                        hwbuf = &sc->sc_pmixer->hwbuf;
1.63      isaki    2251:                        mutex_enter(sc->sc_lock);
1.2       isaki    2252:                        mutex_enter(sc->sc_intr_lock);
                   2253:                        error = sc->hw_if->init_output(sc->hw_hdl,
                   2254:                            hwbuf->mem,
                   2255:                            hwbuf->capacity *
                   2256:                            hwbuf->fmt.channels * hwbuf->fmt.stride / NBBY);
                   2257:                        mutex_exit(sc->sc_intr_lock);
1.63      isaki    2258:                        mutex_exit(sc->sc_lock);
1.2       isaki    2259:                        if (error)
                   2260:                                goto bad3;
                   2261:                }
                   2262:        }
1.65      isaki    2263:        /*
                   2264:         * Call init_input and start rmixer, if this is the first recording
                   2265:         * open.  See pause consideration notes.
                   2266:         */
1.2       isaki    2267:        if (af->rtrack && sc->sc_ropens == 0) {
                   2268:                if (sc->hw_if->init_input) {
                   2269:                        hwbuf = &sc->sc_rmixer->hwbuf;
1.63      isaki    2270:                        mutex_enter(sc->sc_lock);
1.2       isaki    2271:                        mutex_enter(sc->sc_intr_lock);
                   2272:                        error = sc->hw_if->init_input(sc->hw_hdl,
                   2273:                            hwbuf->mem,
                   2274:                            hwbuf->capacity *
                   2275:                            hwbuf->fmt.channels * hwbuf->fmt.stride / NBBY);
                   2276:                        mutex_exit(sc->sc_intr_lock);
1.63      isaki    2277:                        mutex_exit(sc->sc_lock);
1.2       isaki    2278:                        if (error)
                   2279:                                goto bad3;
                   2280:                }
1.65      isaki    2281:
                   2282:                mutex_enter(sc->sc_lock);
                   2283:                audio_rmixer_start(sc);
                   2284:                mutex_exit(sc->sc_lock);
1.2       isaki    2285:        }
                   2286:
1.21      isaki    2287:        if (bellfile == NULL) {
1.2       isaki    2288:                error = fd_allocfile(&fp, &fd);
                   2289:                if (error)
                   2290:                        goto bad3;
                   2291:        }
                   2292:
                   2293:        /*
                   2294:         * Count up finally.
                   2295:         * Don't fail from here.
                   2296:         */
1.63      isaki    2297:        mutex_enter(sc->sc_lock);
1.2       isaki    2298:        if (af->ptrack)
                   2299:                sc->sc_popens++;
                   2300:        if (af->rtrack)
                   2301:                sc->sc_ropens++;
                   2302:        mutex_enter(sc->sc_intr_lock);
                   2303:        SLIST_INSERT_HEAD(&sc->sc_files, af, entry);
                   2304:        mutex_exit(sc->sc_intr_lock);
1.63      isaki    2305:        mutex_exit(sc->sc_lock);
1.2       isaki    2306:
1.21      isaki    2307:        if (bellfile) {
                   2308:                *bellfile = af;
1.2       isaki    2309:        } else {
                   2310:                error = fd_clone(fp, fd, flags, &audio_fileops, af);
1.47      isaki    2311:                KASSERTMSG(error == EMOVEFD, "error=%d", error);
1.2       isaki    2312:        }
                   2313:
                   2314:        TRACEF(3, af, "done");
                   2315:        return error;
                   2316:
                   2317:        /*
                   2318:         * Since track here is not yet linked to sc_files,
                   2319:         * you can call track_destroy() without sc_intr_lock.
                   2320:         */
                   2321: bad3:
                   2322:        if (sc->sc_popens + sc->sc_ropens == 0) {
                   2323:                if (sc->hw_if->close) {
1.63      isaki    2324:                        mutex_enter(sc->sc_lock);
1.2       isaki    2325:                        mutex_enter(sc->sc_intr_lock);
                   2326:                        sc->hw_if->close(sc->hw_hdl);
                   2327:                        mutex_exit(sc->sc_intr_lock);
1.63      isaki    2328:                        mutex_exit(sc->sc_lock);
1.2       isaki    2329:                }
                   2330:        }
                   2331: bad2:
                   2332:        if (af->rtrack) {
                   2333:                audio_track_destroy(af->rtrack);
                   2334:                af->rtrack = NULL;
                   2335:        }
                   2336:        if (af->ptrack) {
                   2337:                audio_track_destroy(af->ptrack);
                   2338:                af->ptrack = NULL;
                   2339:        }
                   2340: bad1:
                   2341:        kmem_free(af, sizeof(*af));
                   2342:        return error;
                   2343: }
                   2344:
1.9       isaki    2345: /*
1.42      isaki    2346:  * Must be called without sc_lock nor sc_exlock held.
1.9       isaki    2347:  */
1.2       isaki    2348: int
                   2349: audio_close(struct audio_softc *sc, audio_file_t *file)
                   2350: {
1.56      isaki    2351:
                   2352:        /* Protect entering new fileops to this file */
                   2353:        atomic_store_relaxed(&file->dying, true);
                   2354:
                   2355:        /*
                   2356:         * Drain first.
1.63      isaki    2357:         * It must be done before unlinking(acquiring exlock).
1.56      isaki    2358:         */
                   2359:        if (file->ptrack) {
                   2360:                mutex_enter(sc->sc_lock);
                   2361:                audio_track_drain(sc, file->ptrack);
                   2362:                mutex_exit(sc->sc_lock);
                   2363:        }
                   2364:
                   2365:        return audio_unlink(sc, file);
                   2366: }
                   2367:
                   2368: /*
                   2369:  * Unlink this file, but not freeing memory here.
                   2370:  * Must be called without sc_lock nor sc_exlock held.
                   2371:  */
                   2372: int
                   2373: audio_unlink(struct audio_softc *sc, audio_file_t *file)
                   2374: {
1.2       isaki    2375:        int error;
                   2376:
1.63      isaki    2377:        mutex_enter(sc->sc_lock);
                   2378:
1.2       isaki    2379:        TRACEF(1, file, "%spid=%d.%d po=%d ro=%d",
                   2380:            (audiodebug >= 3) ? "start " : "",
                   2381:            (int)curproc->p_pid, (int)curlwp->l_lid,
                   2382:            sc->sc_popens, sc->sc_ropens);
                   2383:        KASSERTMSG(sc->sc_popens + sc->sc_ropens > 0,
                   2384:            "sc->sc_popens=%d, sc->sc_ropens=%d",
                   2385:            sc->sc_popens, sc->sc_ropens);
                   2386:
                   2387:        /*
1.63      isaki    2388:         * Acquire exlock to protect counters.
                   2389:         * Does not use audio_exlock_enter() due to sc_dying.
1.2       isaki    2390:         */
1.56      isaki    2391:        while (__predict_false(sc->sc_exlock != 0)) {
                   2392:                error = cv_timedwait_sig(&sc->sc_exlockcv, sc->sc_lock,
                   2393:                    mstohz(AUDIO_TIMEOUT));
                   2394:                /* XXX what should I do on error? */
                   2395:                if (error == EWOULDBLOCK) {
                   2396:                        mutex_exit(sc->sc_lock);
                   2397:                        device_printf(sc->sc_dev,
                   2398:                            "%s: cv_timedwait_sig failed %d", __func__, error);
                   2399:                        return error;
                   2400:                }
1.2       isaki    2401:        }
1.56      isaki    2402:        sc->sc_exlock = 1;
1.2       isaki    2403:
1.56      isaki    2404:        device_active(sc->sc_dev, DVA_SYSTEM);
                   2405:
                   2406:        mutex_enter(sc->sc_intr_lock);
                   2407:        SLIST_REMOVE(&sc->sc_files, file, audio_file, entry);
                   2408:        mutex_exit(sc->sc_intr_lock);
1.2       isaki    2409:
                   2410:        if (file->ptrack) {
1.56      isaki    2411:                TRACET(3, file->ptrack, "dropframes=%" PRIu64,
                   2412:                    file->ptrack->dropframes);
                   2413:
                   2414:                KASSERT(sc->sc_popens > 0);
                   2415:                sc->sc_popens--;
                   2416:
1.2       isaki    2417:                /* Call hw halt_output if this is the last playback track. */
1.56      isaki    2418:                if (sc->sc_popens == 0 && sc->sc_pbusy) {
1.2       isaki    2419:                        error = audio_pmixer_halt(sc);
                   2420:                        if (error) {
                   2421:                                device_printf(sc->sc_dev,
1.56      isaki    2422:                                    "halt_output failed with %d (ignored)\n",
                   2423:                                    error);
1.2       isaki    2424:                        }
                   2425:                }
                   2426:
1.20      isaki    2427:                /* Restore mixing volume if all tracks are gone. */
                   2428:                if (sc->sc_popens == 0) {
1.56      isaki    2429:                        /* intr_lock is not necessary, but just manners. */
1.20      isaki    2430:                        mutex_enter(sc->sc_intr_lock);
                   2431:                        sc->sc_pmixer->volume = 256;
1.23      isaki    2432:                        sc->sc_pmixer->voltimer = 0;
1.20      isaki    2433:                        mutex_exit(sc->sc_intr_lock);
                   2434:                }
1.2       isaki    2435:        }
                   2436:        if (file->rtrack) {
1.56      isaki    2437:                TRACET(3, file->rtrack, "dropframes=%" PRIu64,
                   2438:                    file->rtrack->dropframes);
                   2439:
                   2440:                KASSERT(sc->sc_ropens > 0);
                   2441:                sc->sc_ropens--;
                   2442:
1.2       isaki    2443:                /* Call hw halt_input if this is the last recording track. */
1.56      isaki    2444:                if (sc->sc_ropens == 0 && sc->sc_rbusy) {
1.2       isaki    2445:                        error = audio_rmixer_halt(sc);
                   2446:                        if (error) {
                   2447:                                device_printf(sc->sc_dev,
1.56      isaki    2448:                                    "halt_input failed with %d (ignored)\n",
                   2449:                                    error);
1.2       isaki    2450:                        }
                   2451:                }
                   2452:
                   2453:        }
                   2454:
                   2455:        /* Call hw close if this is the last track. */
                   2456:        if (sc->sc_popens + sc->sc_ropens == 0) {
                   2457:                if (sc->hw_if->close) {
                   2458:                        TRACE(2, "hw_if close");
                   2459:                        mutex_enter(sc->sc_intr_lock);
                   2460:                        sc->hw_if->close(sc->hw_hdl);
                   2461:                        mutex_exit(sc->sc_intr_lock);
                   2462:                }
1.63      isaki    2463:        }
1.2       isaki    2464:
1.63      isaki    2465:        mutex_exit(sc->sc_lock);
                   2466:        if (sc->sc_popens + sc->sc_ropens == 0)
1.2       isaki    2467:                kauth_cred_free(sc->sc_cred);
                   2468:
                   2469:        TRACE(3, "done");
1.63      isaki    2470:        audio_exlock_exit(sc);
1.39      isaki    2471:
1.2       isaki    2472:        return 0;
                   2473: }
                   2474:
1.42      isaki    2475: /*
                   2476:  * Must be called without sc_lock nor sc_exlock held.
                   2477:  */
1.2       isaki    2478: int
                   2479: audio_read(struct audio_softc *sc, struct uio *uio, int ioflag,
                   2480:        audio_file_t *file)
                   2481: {
                   2482:        audio_track_t *track;
                   2483:        audio_ring_t *usrbuf;
                   2484:        audio_ring_t *input;
                   2485:        int error;
                   2486:
1.24      isaki    2487:        /*
                   2488:         * On half-duplex hardware, O_RDWR is treated as O_WRONLY.
                   2489:         * However read() system call itself can be called because it's
                   2490:         * opened with O_RDWR.  So in this case, deny this read().
                   2491:         */
1.2       isaki    2492:        track = file->rtrack;
1.24      isaki    2493:        if (track == NULL) {
                   2494:                return EBADF;
                   2495:        }
1.2       isaki    2496:
                   2497:        /* I think it's better than EINVAL. */
                   2498:        if (track->mmapped)
                   2499:                return EPERM;
                   2500:
1.78      isaki    2501:        TRACET(2, track, "resid=%zd ioflag=0x%x", uio->uio_resid, ioflag);
1.24      isaki    2502:
1.65      isaki    2503: #ifdef AUDIO_PM_IDLE
1.63      isaki    2504:        error = audio_exlock_mutex_enter(sc);
                   2505:        if (error)
                   2506:                return error;
                   2507:
1.2       isaki    2508:        if (device_is_active(&sc->sc_dev) || sc->sc_idle)
                   2509:                device_active(&sc->sc_dev, DVA_SYSTEM);
                   2510:
1.65      isaki    2511:        /* In recording, unlike playback, read() never operates rmixer. */
                   2512:
1.63      isaki    2513:        audio_exlock_mutex_exit(sc);
1.65      isaki    2514: #endif
1.2       isaki    2515:
1.63      isaki    2516:        usrbuf = &track->usrbuf;
                   2517:        input = track->input;
1.2       isaki    2518:        error = 0;
1.63      isaki    2519:
1.2       isaki    2520:        while (uio->uio_resid > 0 && error == 0) {
                   2521:                int bytes;
                   2522:
                   2523:                TRACET(3, track,
                   2524:                    "while resid=%zd input=%d/%d/%d usrbuf=%d/%d/H%d",
                   2525:                    uio->uio_resid,
                   2526:                    input->head, input->used, input->capacity,
                   2527:                    usrbuf->head, usrbuf->used, track->usrbuf_usedhigh);
                   2528:
                   2529:                /* Wait when buffers are empty. */
                   2530:                mutex_enter(sc->sc_lock);
                   2531:                for (;;) {
                   2532:                        bool empty;
                   2533:                        audio_track_lock_enter(track);
                   2534:                        empty = (input->used == 0 && usrbuf->used == 0);
                   2535:                        audio_track_lock_exit(track);
                   2536:                        if (!empty)
                   2537:                                break;
                   2538:
                   2539:                        if ((ioflag & IO_NDELAY)) {
                   2540:                                mutex_exit(sc->sc_lock);
                   2541:                                return EWOULDBLOCK;
                   2542:                        }
                   2543:
                   2544:                        TRACET(3, track, "sleep");
                   2545:                        error = audio_track_waitio(sc, track);
                   2546:                        if (error) {
                   2547:                                mutex_exit(sc->sc_lock);
                   2548:                                return error;
                   2549:                        }
                   2550:                }
                   2551:                mutex_exit(sc->sc_lock);
                   2552:
                   2553:                audio_track_lock_enter(track);
                   2554:                audio_track_record(track);
                   2555:
                   2556:                /* uiomove from usrbuf as much as possible. */
                   2557:                bytes = uimin(usrbuf->used, uio->uio_resid);
                   2558:                while (bytes > 0) {
                   2559:                        int head = usrbuf->head;
                   2560:                        int len = uimin(bytes, usrbuf->capacity - head);
                   2561:                        error = uiomove((uint8_t *)usrbuf->mem + head, len,
                   2562:                            uio);
                   2563:                        if (error) {
1.9       isaki    2564:                                audio_track_lock_exit(track);
1.2       isaki    2565:                                device_printf(sc->sc_dev,
                   2566:                                    "uiomove(len=%d) failed with %d\n",
                   2567:                                    len, error);
                   2568:                                goto abort;
                   2569:                        }
                   2570:                        auring_take(usrbuf, len);
                   2571:                        track->useriobytes += len;
                   2572:                        TRACET(3, track, "uiomove(len=%d) usrbuf=%d/%d/C%d",
                   2573:                            len,
                   2574:                            usrbuf->head, usrbuf->used, usrbuf->capacity);
                   2575:                        bytes -= len;
                   2576:                }
1.9       isaki    2577:
                   2578:                audio_track_lock_exit(track);
1.2       isaki    2579:        }
                   2580:
                   2581: abort:
                   2582:        return error;
                   2583: }
                   2584:
                   2585:
                   2586: /*
                   2587:  * Clear file's playback and/or record track buffer immediately.
                   2588:  */
                   2589: static void
                   2590: audio_file_clear(struct audio_softc *sc, audio_file_t *file)
                   2591: {
                   2592:
                   2593:        if (file->ptrack)
                   2594:                audio_track_clear(sc, file->ptrack);
                   2595:        if (file->rtrack)
                   2596:                audio_track_clear(sc, file->rtrack);
                   2597: }
                   2598:
1.42      isaki    2599: /*
                   2600:  * Must be called without sc_lock nor sc_exlock held.
                   2601:  */
1.2       isaki    2602: int
                   2603: audio_write(struct audio_softc *sc, struct uio *uio, int ioflag,
                   2604:        audio_file_t *file)
                   2605: {
                   2606:        audio_track_t *track;
                   2607:        audio_ring_t *usrbuf;
                   2608:        audio_ring_t *outbuf;
                   2609:        int error;
                   2610:
                   2611:        track = file->ptrack;
                   2612:        KASSERT(track);
                   2613:
                   2614:        /* I think it's better than EINVAL. */
                   2615:        if (track->mmapped)
                   2616:                return EPERM;
                   2617:
1.25      isaki    2618:        TRACET(2, track, "%sresid=%zd pid=%d.%d ioflag=0x%x",
                   2619:            audiodebug >= 3 ? "begin " : "",
                   2620:            uio->uio_resid, (int)curproc->p_pid, (int)curlwp->l_lid, ioflag);
                   2621:
1.2       isaki    2622:        if (uio->uio_resid == 0) {
                   2623:                track->eofcounter++;
                   2624:                return 0;
                   2625:        }
                   2626:
1.63      isaki    2627:        error = audio_exlock_mutex_enter(sc);
                   2628:        if (error)
                   2629:                return error;
                   2630:
1.2       isaki    2631: #ifdef AUDIO_PM_IDLE
                   2632:        if (device_is_active(&sc->sc_dev) || sc->sc_idle)
                   2633:                device_active(&sc->sc_dev, DVA_SYSTEM);
                   2634: #endif
                   2635:
                   2636:        /*
                   2637:         * The first write starts pmixer.
                   2638:         */
                   2639:        if (sc->sc_pbusy == false)
                   2640:                audio_pmixer_start(sc, false);
1.63      isaki    2641:        audio_exlock_mutex_exit(sc);
1.2       isaki    2642:
1.63      isaki    2643:        usrbuf = &track->usrbuf;
                   2644:        outbuf = &track->outbuf;
1.2       isaki    2645:        track->pstate = AUDIO_STATE_RUNNING;
                   2646:        error = 0;
1.63      isaki    2647:
1.2       isaki    2648:        while (uio->uio_resid > 0 && error == 0) {
                   2649:                int bytes;
                   2650:
                   2651:                TRACET(3, track, "while resid=%zd usrbuf=%d/%d/H%d",
                   2652:                    uio->uio_resid,
                   2653:                    usrbuf->head, usrbuf->used, track->usrbuf_usedhigh);
                   2654:
                   2655:                /* Wait when buffers are full. */
                   2656:                mutex_enter(sc->sc_lock);
                   2657:                for (;;) {
                   2658:                        bool full;
                   2659:                        audio_track_lock_enter(track);
                   2660:                        full = (usrbuf->used >= track->usrbuf_usedhigh &&
                   2661:                            outbuf->used >= outbuf->capacity);
                   2662:                        audio_track_lock_exit(track);
                   2663:                        if (!full)
                   2664:                                break;
                   2665:
                   2666:                        if ((ioflag & IO_NDELAY)) {
                   2667:                                error = EWOULDBLOCK;
                   2668:                                mutex_exit(sc->sc_lock);
                   2669:                                goto abort;
                   2670:                        }
                   2671:
                   2672:                        TRACET(3, track, "sleep usrbuf=%d/H%d",
                   2673:                            usrbuf->used, track->usrbuf_usedhigh);
                   2674:                        error = audio_track_waitio(sc, track);
                   2675:                        if (error) {
                   2676:                                mutex_exit(sc->sc_lock);
                   2677:                                goto abort;
                   2678:                        }
                   2679:                }
                   2680:                mutex_exit(sc->sc_lock);
                   2681:
1.9       isaki    2682:                audio_track_lock_enter(track);
                   2683:
1.2       isaki    2684:                /* uiomove to usrbuf as much as possible. */
                   2685:                bytes = uimin(track->usrbuf_usedhigh - usrbuf->used,
                   2686:                    uio->uio_resid);
                   2687:                while (bytes > 0) {
                   2688:                        int tail = auring_tail(usrbuf);
                   2689:                        int len = uimin(bytes, usrbuf->capacity - tail);
                   2690:                        error = uiomove((uint8_t *)usrbuf->mem + tail, len,
                   2691:                            uio);
                   2692:                        if (error) {
1.9       isaki    2693:                                audio_track_lock_exit(track);
1.2       isaki    2694:                                device_printf(sc->sc_dev,
                   2695:                                    "uiomove(len=%d) failed with %d\n",
                   2696:                                    len, error);
                   2697:                                goto abort;
                   2698:                        }
                   2699:                        auring_push(usrbuf, len);
                   2700:                        track->useriobytes += len;
                   2701:                        TRACET(3, track, "uiomove(len=%d) usrbuf=%d/%d/C%d",
                   2702:                            len,
                   2703:                            usrbuf->head, usrbuf->used, usrbuf->capacity);
                   2704:                        bytes -= len;
                   2705:                }
                   2706:
                   2707:                /* Convert them as much as possible. */
                   2708:                while (usrbuf->used >= track->usrbuf_blksize &&
                   2709:                    outbuf->used < outbuf->capacity) {
                   2710:                        audio_track_play(track);
                   2711:                }
1.9       isaki    2712:
1.2       isaki    2713:                audio_track_lock_exit(track);
                   2714:        }
                   2715:
                   2716: abort:
                   2717:        TRACET(3, track, "done error=%d", error);
                   2718:        return error;
                   2719: }
                   2720:
1.42      isaki    2721: /*
                   2722:  * Must be called without sc_lock nor sc_exlock held.
                   2723:  */
1.2       isaki    2724: int
                   2725: audio_ioctl(dev_t dev, struct audio_softc *sc, u_long cmd, void *addr, int flag,
                   2726:        struct lwp *l, audio_file_t *file)
                   2727: {
                   2728:        struct audio_offset *ao;
                   2729:        struct audio_info ai;
                   2730:        audio_track_t *track;
                   2731:        audio_encoding_t *ae;
                   2732:        audio_format_query_t *query;
                   2733:        u_int stamp;
                   2734:        u_int offs;
                   2735:        int fd;
                   2736:        int index;
                   2737:        int error;
                   2738:
                   2739: #if defined(AUDIO_DEBUG)
                   2740:        const char *ioctlnames[] = {
                   2741:                " AUDIO_GETINFO",       /* 21 */
                   2742:                " AUDIO_SETINFO",       /* 22 */
                   2743:                " AUDIO_DRAIN",         /* 23 */
                   2744:                " AUDIO_FLUSH",         /* 24 */
                   2745:                " AUDIO_WSEEK",         /* 25 */
                   2746:                " AUDIO_RERROR",        /* 26 */
                   2747:                " AUDIO_GETDEV",        /* 27 */
                   2748:                " AUDIO_GETENC",        /* 28 */
                   2749:                " AUDIO_GETFD",         /* 29 */
                   2750:                " AUDIO_SETFD",         /* 30 */
                   2751:                " AUDIO_PERROR",        /* 31 */
                   2752:                " AUDIO_GETIOFFS",      /* 32 */
                   2753:                " AUDIO_GETOOFFS",      /* 33 */
                   2754:                " AUDIO_GETPROPS",      /* 34 */
                   2755:                " AUDIO_GETBUFINFO",    /* 35 */
                   2756:                " AUDIO_SETCHAN",       /* 36 */
                   2757:                " AUDIO_GETCHAN",       /* 37 */
                   2758:                " AUDIO_QUERYFORMAT",   /* 38 */
                   2759:                " AUDIO_GETFORMAT",     /* 39 */
                   2760:                " AUDIO_SETFORMAT",     /* 40 */
                   2761:        };
                   2762:        int nameidx = (cmd & 0xff);
                   2763:        const char *ioctlname = "";
                   2764:        if (21 <= nameidx && nameidx <= 21 + __arraycount(ioctlnames))
                   2765:                ioctlname = ioctlnames[nameidx - 21];
                   2766:        TRACEF(2, file, "(%lu,'%c',%lu)%s pid=%d.%d",
                   2767:            IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff, ioctlname,
                   2768:            (int)curproc->p_pid, (int)l->l_lid);
                   2769: #endif
                   2770:
                   2771:        error = 0;
                   2772:        switch (cmd) {
                   2773:        case FIONBIO:
                   2774:                /* All handled in the upper FS layer. */
                   2775:                break;
                   2776:
                   2777:        case FIONREAD:
                   2778:                /* Get the number of bytes that can be read. */
                   2779:                if (file->rtrack) {
                   2780:                        *(int *)addr = audio_track_readablebytes(file->rtrack);
                   2781:                } else {
                   2782:                        *(int *)addr = 0;
                   2783:                }
                   2784:                break;
                   2785:
                   2786:        case FIOASYNC:
                   2787:                /* Set/Clear ASYNC I/O. */
                   2788:                if (*(int *)addr) {
                   2789:                        file->async_audio = curproc->p_pid;
                   2790:                        TRACEF(2, file, "FIOASYNC pid %d", file->async_audio);
                   2791:                } else {
                   2792:                        file->async_audio = 0;
                   2793:                        TRACEF(2, file, "FIOASYNC off");
                   2794:                }
                   2795:                break;
                   2796:
                   2797:        case AUDIO_FLUSH:
                   2798:                /* XXX TODO: clear errors and restart? */
                   2799:                audio_file_clear(sc, file);
                   2800:                break;
                   2801:
                   2802:        case AUDIO_RERROR:
                   2803:                /*
                   2804:                 * Number of read bytes dropped.  We don't know where
                   2805:                 * or when they were dropped (including conversion stage).
                   2806:                 * Therefore, the number of accurate bytes or samples is
                   2807:                 * also unknown.
                   2808:                 */
                   2809:                track = file->rtrack;
                   2810:                if (track) {
                   2811:                        *(int *)addr = frametobyte(&track->usrbuf.fmt,
                   2812:                            track->dropframes);
                   2813:                }
                   2814:                break;
                   2815:
                   2816:        case AUDIO_PERROR:
                   2817:                /*
                   2818:                 * Number of write bytes dropped.  We don't know where
                   2819:                 * or when they were dropped (including conversion stage).
                   2820:                 * Therefore, the number of accurate bytes or samples is
                   2821:                 * also unknown.
                   2822:                 */
                   2823:                track = file->ptrack;
                   2824:                if (track) {
                   2825:                        *(int *)addr = frametobyte(&track->usrbuf.fmt,
                   2826:                            track->dropframes);
                   2827:                }
                   2828:                break;
                   2829:
                   2830:        case AUDIO_GETIOFFS:
                   2831:                /* XXX TODO */
                   2832:                ao = (struct audio_offset *)addr;
                   2833:                ao->samples = 0;
                   2834:                ao->deltablks = 0;
                   2835:                ao->offset = 0;
                   2836:                break;
                   2837:
                   2838:        case AUDIO_GETOOFFS:
                   2839:                ao = (struct audio_offset *)addr;
                   2840:                track = file->ptrack;
                   2841:                if (track == NULL) {
                   2842:                        ao->samples = 0;
                   2843:                        ao->deltablks = 0;
                   2844:                        ao->offset = 0;
                   2845:                        break;
                   2846:                }
                   2847:                mutex_enter(sc->sc_lock);
                   2848:                mutex_enter(sc->sc_intr_lock);
                   2849:                /* figure out where next DMA will start */
                   2850:                stamp = track->usrbuf_stamp;
                   2851:                offs = track->usrbuf.head;
                   2852:                mutex_exit(sc->sc_intr_lock);
                   2853:                mutex_exit(sc->sc_lock);
                   2854:
                   2855:                ao->samples = stamp;
                   2856:                ao->deltablks = (stamp / track->usrbuf_blksize) -
                   2857:                    (track->usrbuf_stamp_last / track->usrbuf_blksize);
                   2858:                track->usrbuf_stamp_last = stamp;
                   2859:                offs = rounddown(offs, track->usrbuf_blksize)
                   2860:                    + track->usrbuf_blksize;
                   2861:                if (offs >= track->usrbuf.capacity)
                   2862:                        offs -= track->usrbuf.capacity;
                   2863:                ao->offset = offs;
                   2864:
                   2865:                TRACET(3, track, "GETOOFFS: samples=%u deltablks=%u offset=%u",
                   2866:                    ao->samples, ao->deltablks, ao->offset);
                   2867:                break;
                   2868:
                   2869:        case AUDIO_WSEEK:
                   2870:                /* XXX return value does not include outbuf one. */
                   2871:                if (file->ptrack)
                   2872:                        *(u_long *)addr = file->ptrack->usrbuf.used;
                   2873:                break;
                   2874:
                   2875:        case AUDIO_SETINFO:
1.63      isaki    2876:                error = audio_exlock_enter(sc);
1.2       isaki    2877:                if (error)
                   2878:                        break;
                   2879:                error = audio_file_setinfo(sc, file, (struct audio_info *)addr);
                   2880:                if (error) {
1.63      isaki    2881:                        audio_exlock_exit(sc);
1.2       isaki    2882:                        break;
                   2883:                }
                   2884:                /* XXX TODO: update last_ai if /dev/sound ? */
                   2885:                if (ISDEVSOUND(dev))
                   2886:                        error = audiogetinfo(sc, &sc->sc_ai, 0, file);
1.63      isaki    2887:                audio_exlock_exit(sc);
1.2       isaki    2888:                break;
                   2889:
                   2890:        case AUDIO_GETINFO:
1.63      isaki    2891:                error = audio_exlock_enter(sc);
1.2       isaki    2892:                if (error)
                   2893:                        break;
                   2894:                error = audiogetinfo(sc, (struct audio_info *)addr, 1, file);
1.63      isaki    2895:                audio_exlock_exit(sc);
1.2       isaki    2896:                break;
                   2897:
                   2898:        case AUDIO_GETBUFINFO:
1.63      isaki    2899:                error = audio_exlock_enter(sc);
                   2900:                if (error)
                   2901:                        break;
1.2       isaki    2902:                error = audiogetinfo(sc, (struct audio_info *)addr, 0, file);
1.63      isaki    2903:                audio_exlock_exit(sc);
1.2       isaki    2904:                break;
                   2905:
                   2906:        case AUDIO_DRAIN:
                   2907:                if (file->ptrack) {
                   2908:                        mutex_enter(sc->sc_lock);
                   2909:                        error = audio_track_drain(sc, file->ptrack);
                   2910:                        mutex_exit(sc->sc_lock);
                   2911:                }
                   2912:                break;
                   2913:
                   2914:        case AUDIO_GETDEV:
                   2915:                mutex_enter(sc->sc_lock);
                   2916:                error = sc->hw_if->getdev(sc->hw_hdl, (audio_device_t *)addr);
                   2917:                mutex_exit(sc->sc_lock);
                   2918:                break;
                   2919:
                   2920:        case AUDIO_GETENC:
                   2921:                ae = (audio_encoding_t *)addr;
                   2922:                index = ae->index;
                   2923:                if (index < 0 || index >= __arraycount(audio_encodings)) {
                   2924:                        error = EINVAL;
                   2925:                        break;
                   2926:                }
                   2927:                *ae = audio_encodings[index];
                   2928:                ae->index = index;
                   2929:                /*
                   2930:                 * EMULATED always.
                   2931:                 * EMULATED flag at that time used to mean that it could
                   2932:                 * not be passed directly to the hardware as-is.  But
                   2933:                 * currently, all formats including hardware native is not
                   2934:                 * passed directly to the hardware.  So I set EMULATED
                   2935:                 * flag for all formats.
                   2936:                 */
                   2937:                ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
                   2938:                break;
                   2939:
                   2940:        case AUDIO_GETFD:
                   2941:                /*
                   2942:                 * Returns the current setting of full duplex mode.
                   2943:                 * If HW has full duplex mode and there are two mixers,
                   2944:                 * it is full duplex.  Otherwise half duplex.
                   2945:                 */
1.63      isaki    2946:                error = audio_exlock_enter(sc);
                   2947:                if (error)
                   2948:                        break;
1.14      isaki    2949:                fd = (sc->sc_props & AUDIO_PROP_FULLDUPLEX)
1.2       isaki    2950:                    && (sc->sc_pmixer && sc->sc_rmixer);
1.63      isaki    2951:                audio_exlock_exit(sc);
1.2       isaki    2952:                *(int *)addr = fd;
                   2953:                break;
                   2954:
                   2955:        case AUDIO_GETPROPS:
1.14      isaki    2956:                *(int *)addr = sc->sc_props;
1.2       isaki    2957:                break;
                   2958:
                   2959:        case AUDIO_QUERYFORMAT:
                   2960:                query = (audio_format_query_t *)addr;
1.48      isaki    2961:                mutex_enter(sc->sc_lock);
                   2962:                error = sc->hw_if->query_format(sc->hw_hdl, query);
                   2963:                mutex_exit(sc->sc_lock);
1.79    ! isaki    2964:                /* Hide internal information */
1.48      isaki    2965:                query->fmt.driver_data = NULL;
1.2       isaki    2966:                break;
                   2967:
                   2968:        case AUDIO_GETFORMAT:
1.63      isaki    2969:                error = audio_exlock_enter(sc);
                   2970:                if (error)
                   2971:                        break;
1.2       isaki    2972:                audio_mixers_get_format(sc, (struct audio_info *)addr);
1.63      isaki    2973:                audio_exlock_exit(sc);
1.2       isaki    2974:                break;
                   2975:
                   2976:        case AUDIO_SETFORMAT:
1.63      isaki    2977:                error = audio_exlock_enter(sc);
1.2       isaki    2978:                audio_mixers_get_format(sc, &ai);
                   2979:                error = audio_mixers_set_format(sc, (struct audio_info *)addr);
                   2980:                if (error) {
                   2981:                        /* Rollback */
                   2982:                        audio_mixers_set_format(sc, &ai);
                   2983:                }
1.63      isaki    2984:                audio_exlock_exit(sc);
1.2       isaki    2985:                break;
                   2986:
                   2987:        case AUDIO_SETFD:
                   2988:        case AUDIO_SETCHAN:
                   2989:        case AUDIO_GETCHAN:
                   2990:                /* Obsoleted */
                   2991:                break;
                   2992:
                   2993:        default:
                   2994:                if (sc->hw_if->dev_ioctl) {
1.63      isaki    2995:                        mutex_enter(sc->sc_lock);
1.2       isaki    2996:                        error = sc->hw_if->dev_ioctl(sc->hw_hdl,
                   2997:                            cmd, addr, flag, l);
1.63      isaki    2998:                        mutex_exit(sc->sc_lock);
1.2       isaki    2999:                } else {
                   3000:                        TRACEF(2, file, "unknown ioctl");
                   3001:                        error = EINVAL;
                   3002:                }
                   3003:                break;
                   3004:        }
                   3005:        TRACEF(2, file, "(%lu,'%c',%lu)%s result %d",
                   3006:            IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff, ioctlname,
                   3007:            error);
                   3008:        return error;
                   3009: }
                   3010:
                   3011: /*
                   3012:  * Returns the number of bytes that can be read on recording buffer.
                   3013:  */
                   3014: static __inline int
                   3015: audio_track_readablebytes(const audio_track_t *track)
                   3016: {
                   3017:        int bytes;
                   3018:
                   3019:        KASSERT(track);
                   3020:        KASSERT(track->mode == AUMODE_RECORD);
                   3021:
                   3022:        /*
                   3023:         * Although usrbuf is primarily readable data, recorded data
                   3024:         * also stays in track->input until reading.  So it is necessary
                   3025:         * to add it.  track->input is in frame, usrbuf is in byte.
                   3026:         */
                   3027:        bytes = track->usrbuf.used +
                   3028:            track->input->used * frametobyte(&track->usrbuf.fmt, 1);
                   3029:        return bytes;
                   3030: }
                   3031:
1.42      isaki    3032: /*
                   3033:  * Must be called without sc_lock nor sc_exlock held.
                   3034:  */
1.2       isaki    3035: int
                   3036: audio_poll(struct audio_softc *sc, int events, struct lwp *l,
                   3037:        audio_file_t *file)
                   3038: {
                   3039:        audio_track_t *track;
                   3040:        int revents;
                   3041:        bool in_is_valid;
                   3042:        bool out_is_valid;
                   3043:
                   3044: #if defined(AUDIO_DEBUG)
                   3045: #define POLLEV_BITMAP "\177\020" \
                   3046:            "b\10WRBAND\0" \
                   3047:            "b\7RDBAND\0" "b\6RDNORM\0" "b\5NVAL\0" "b\4HUP\0" \
                   3048:            "b\3ERR\0" "b\2OUT\0" "b\1PRI\0" "b\0IN\0"
                   3049:        char evbuf[64];
                   3050:        snprintb(evbuf, sizeof(evbuf), POLLEV_BITMAP, events);
                   3051:        TRACEF(2, file, "pid=%d.%d events=%s",
                   3052:            (int)curproc->p_pid, (int)l->l_lid, evbuf);
                   3053: #endif
                   3054:
                   3055:        revents = 0;
                   3056:        in_is_valid = false;
                   3057:        out_is_valid = false;
                   3058:        if (events & (POLLIN | POLLRDNORM)) {
                   3059:                track = file->rtrack;
                   3060:                if (track) {
                   3061:                        int used;
                   3062:                        in_is_valid = true;
                   3063:                        used = audio_track_readablebytes(track);
                   3064:                        if (used > 0)
                   3065:                                revents |= events & (POLLIN | POLLRDNORM);
                   3066:                }
                   3067:        }
                   3068:        if (events & (POLLOUT | POLLWRNORM)) {
                   3069:                track = file->ptrack;
                   3070:                if (track) {
                   3071:                        out_is_valid = true;
                   3072:                        if (track->usrbuf.used <= track->usrbuf_usedlow)
                   3073:                                revents |= events & (POLLOUT | POLLWRNORM);
                   3074:                }
                   3075:        }
                   3076:
                   3077:        if (revents == 0) {
                   3078:                mutex_enter(sc->sc_lock);
                   3079:                if (in_is_valid) {
                   3080:                        TRACEF(3, file, "selrecord rsel");
                   3081:                        selrecord(l, &sc->sc_rsel);
                   3082:                }
                   3083:                if (out_is_valid) {
                   3084:                        TRACEF(3, file, "selrecord wsel");
                   3085:                        selrecord(l, &sc->sc_wsel);
                   3086:                }
                   3087:                mutex_exit(sc->sc_lock);
                   3088:        }
                   3089:
                   3090: #if defined(AUDIO_DEBUG)
                   3091:        snprintb(evbuf, sizeof(evbuf), POLLEV_BITMAP, revents);
                   3092:        TRACEF(2, file, "revents=%s", evbuf);
                   3093: #endif
                   3094:        return revents;
                   3095: }
                   3096:
                   3097: static const struct filterops audioread_filtops = {
                   3098:        .f_isfd = 1,
                   3099:        .f_attach = NULL,
                   3100:        .f_detach = filt_audioread_detach,
                   3101:        .f_event = filt_audioread_event,
                   3102: };
                   3103:
                   3104: static void
                   3105: filt_audioread_detach(struct knote *kn)
                   3106: {
                   3107:        struct audio_softc *sc;
                   3108:        audio_file_t *file;
                   3109:
                   3110:        file = kn->kn_hook;
                   3111:        sc = file->sc;
                   3112:        TRACEF(3, file, "");
                   3113:
                   3114:        mutex_enter(sc->sc_lock);
                   3115:        SLIST_REMOVE(&sc->sc_rsel.sel_klist, kn, knote, kn_selnext);
                   3116:        mutex_exit(sc->sc_lock);
                   3117: }
                   3118:
                   3119: static int
                   3120: filt_audioread_event(struct knote *kn, long hint)
                   3121: {
                   3122:        audio_file_t *file;
                   3123:        audio_track_t *track;
                   3124:
                   3125:        file = kn->kn_hook;
                   3126:        track = file->rtrack;
                   3127:
                   3128:        /*
                   3129:         * kn_data must contain the number of bytes can be read.
                   3130:         * The return value indicates whether the event occurs or not.
                   3131:         */
                   3132:
                   3133:        if (track == NULL) {
                   3134:                /* can not read with this descriptor. */
                   3135:                kn->kn_data = 0;
                   3136:                return 0;
                   3137:        }
                   3138:
                   3139:        kn->kn_data = audio_track_readablebytes(track);
                   3140:        TRACEF(3, file, "data=%" PRId64, kn->kn_data);
                   3141:        return kn->kn_data > 0;
                   3142: }
                   3143:
                   3144: static const struct filterops audiowrite_filtops = {
                   3145:        .f_isfd = 1,
                   3146:        .f_attach = NULL,
                   3147:        .f_detach = filt_audiowrite_detach,
                   3148:        .f_event = filt_audiowrite_event,
                   3149: };
                   3150:
                   3151: static void
                   3152: filt_audiowrite_detach(struct knote *kn)
                   3153: {
                   3154:        struct audio_softc *sc;
                   3155:        audio_file_t *file;
                   3156:
                   3157:        file = kn->kn_hook;
                   3158:        sc = file->sc;
                   3159:        TRACEF(3, file, "");
                   3160:
                   3161:        mutex_enter(sc->sc_lock);
                   3162:        SLIST_REMOVE(&sc->sc_wsel.sel_klist, kn, knote, kn_selnext);
                   3163:        mutex_exit(sc->sc_lock);
                   3164: }
                   3165:
                   3166: static int
                   3167: filt_audiowrite_event(struct knote *kn, long hint)
                   3168: {
                   3169:        audio_file_t *file;
                   3170:        audio_track_t *track;
                   3171:
                   3172:        file = kn->kn_hook;
                   3173:        track = file->ptrack;
                   3174:
                   3175:        /*
                   3176:         * kn_data must contain the number of bytes can be write.
                   3177:         * The return value indicates whether the event occurs or not.
                   3178:         */
                   3179:
                   3180:        if (track == NULL) {
                   3181:                /* can not write with this descriptor. */
                   3182:                kn->kn_data = 0;
                   3183:                return 0;
                   3184:        }
                   3185:
                   3186:        kn->kn_data = track->usrbuf_usedhigh - track->usrbuf.used;
                   3187:        TRACEF(3, file, "data=%" PRId64, kn->kn_data);
                   3188:        return (track->usrbuf.used < track->usrbuf_usedlow);
                   3189: }
                   3190:
1.42      isaki    3191: /*
                   3192:  * Must be called without sc_lock nor sc_exlock held.
                   3193:  */
1.2       isaki    3194: int
                   3195: audio_kqfilter(struct audio_softc *sc, audio_file_t *file, struct knote *kn)
                   3196: {
                   3197:        struct klist *klist;
                   3198:
                   3199:        TRACEF(3, file, "kn=%p kn_filter=%x", kn, (int)kn->kn_filter);
                   3200:
1.63      isaki    3201:        mutex_enter(sc->sc_lock);
1.2       isaki    3202:        switch (kn->kn_filter) {
                   3203:        case EVFILT_READ:
                   3204:                klist = &sc->sc_rsel.sel_klist;
                   3205:                kn->kn_fop = &audioread_filtops;
                   3206:                break;
                   3207:
                   3208:        case EVFILT_WRITE:
                   3209:                klist = &sc->sc_wsel.sel_klist;
                   3210:                kn->kn_fop = &audiowrite_filtops;
                   3211:                break;
                   3212:
                   3213:        default:
1.63      isaki    3214:                mutex_exit(sc->sc_lock);
1.2       isaki    3215:                return EINVAL;
                   3216:        }
                   3217:
                   3218:        kn->kn_hook = file;
                   3219:
                   3220:        SLIST_INSERT_HEAD(klist, kn, kn_selnext);
                   3221:        mutex_exit(sc->sc_lock);
                   3222:
                   3223:        return 0;
                   3224: }
                   3225:
1.42      isaki    3226: /*
                   3227:  * Must be called without sc_lock nor sc_exlock held.
                   3228:  */
1.2       isaki    3229: int
                   3230: audio_mmap(struct audio_softc *sc, off_t *offp, size_t len, int prot,
                   3231:        int *flagsp, int *advicep, struct uvm_object **uobjp, int *maxprotp,
                   3232:        audio_file_t *file)
                   3233: {
                   3234:        audio_track_t *track;
                   3235:        vsize_t vsize;
                   3236:        int error;
                   3237:
                   3238:        TRACEF(2, file, "off=%lld, prot=%d", (long long)(*offp), prot);
                   3239:
                   3240:        if (*offp < 0)
                   3241:                return EINVAL;
                   3242:
                   3243: #if 0
                   3244:        /* XXX
                   3245:         * The idea here was to use the protection to determine if
                   3246:         * we are mapping the read or write buffer, but it fails.
                   3247:         * The VM system is broken in (at least) two ways.
                   3248:         * 1) If you map memory VM_PROT_WRITE you SIGSEGV
                   3249:         *    when writing to it, so VM_PROT_READ|VM_PROT_WRITE
                   3250:         *    has to be used for mmapping the play buffer.
                   3251:         * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE
                   3252:         *    audio_mmap will get called at some point with VM_PROT_READ
                   3253:         *    only.
                   3254:         * So, alas, we always map the play buffer for now.
                   3255:         */
                   3256:        if (prot == (VM_PROT_READ|VM_PROT_WRITE) ||
                   3257:            prot == VM_PROT_WRITE)
                   3258:                track = file->ptrack;
                   3259:        else if (prot == VM_PROT_READ)
                   3260:                track = file->rtrack;
                   3261:        else
                   3262:                return EINVAL;
                   3263: #else
                   3264:        track = file->ptrack;
                   3265: #endif
                   3266:        if (track == NULL)
                   3267:                return EACCES;
                   3268:
                   3269:        vsize = roundup2(MAX(track->usrbuf.capacity, PAGE_SIZE), PAGE_SIZE);
                   3270:        if (len > vsize)
                   3271:                return EOVERFLOW;
                   3272:        if (*offp > (uint)(vsize - len))
                   3273:                return EOVERFLOW;
                   3274:
                   3275:        /* XXX TODO: what happens when mmap twice. */
                   3276:        if (!track->mmapped) {
                   3277:                track->mmapped = true;
                   3278:
                   3279:                if (!track->is_pause) {
1.63      isaki    3280:                        error = audio_exlock_mutex_enter(sc);
1.2       isaki    3281:                        if (error)
                   3282:                                return error;
                   3283:                        if (sc->sc_pbusy == false)
                   3284:                                audio_pmixer_start(sc, true);
1.63      isaki    3285:                        audio_exlock_mutex_exit(sc);
1.2       isaki    3286:                }
                   3287:                /* XXX mmapping record buffer is not supported */
                   3288:        }
                   3289:
                   3290:        /* get ringbuffer */
                   3291:        *uobjp = track->uobj;
                   3292:
                   3293:        /* Acquire a reference for the mmap.  munmap will release. */
                   3294:        uao_reference(*uobjp);
                   3295:        *maxprotp = prot;
                   3296:        *advicep = UVM_ADV_RANDOM;
                   3297:        *flagsp = MAP_SHARED;
                   3298:        return 0;
                   3299: }
                   3300:
                   3301: /*
                   3302:  * /dev/audioctl has to be able to open at any time without interference
                   3303:  * with any /dev/audio or /dev/sound.
1.63      isaki    3304:  * Must be called with sc_exlock held and without sc_lock held.
1.2       isaki    3305:  */
                   3306: static int
                   3307: audioctl_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
                   3308:        struct lwp *l)
                   3309: {
                   3310:        struct file *fp;
                   3311:        audio_file_t *af;
                   3312:        int fd;
                   3313:        int error;
                   3314:
                   3315:        KASSERT(sc->sc_exlock);
                   3316:
                   3317:        TRACE(1, "");
                   3318:
                   3319:        error = fd_allocfile(&fp, &fd);
                   3320:        if (error)
                   3321:                return error;
                   3322:
                   3323:        af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP);
                   3324:        af->sc = sc;
                   3325:        af->dev = dev;
                   3326:
                   3327:        /* Not necessary to insert sc_files. */
                   3328:
                   3329:        error = fd_clone(fp, fd, flags, &audio_fileops, af);
1.47      isaki    3330:        KASSERTMSG(error == EMOVEFD, "error=%d", error);
1.2       isaki    3331:
                   3332:        return error;
                   3333: }
                   3334:
                   3335: /*
                   3336:  * Free 'mem' if available, and initialize the pointer.
                   3337:  * For this reason, this is implemented as macro.
                   3338:  */
                   3339: #define audio_free(mem)        do {    \
                   3340:        if (mem != NULL) {      \
                   3341:                kern_free(mem); \
                   3342:                mem = NULL;     \
                   3343:        }       \
                   3344: } while (0)
                   3345:
                   3346: /*
1.35      isaki    3347:  * (Re)allocate 'memblock' with specified 'bytes'.
                   3348:  * bytes must not be 0.
                   3349:  * This function never returns NULL.
                   3350:  */
                   3351: static void *
                   3352: audio_realloc(void *memblock, size_t bytes)
                   3353: {
                   3354:
                   3355:        KASSERT(bytes != 0);
                   3356:        audio_free(memblock);
                   3357:        return kern_malloc(bytes, M_WAITOK);
                   3358: }
                   3359:
                   3360: /*
1.2       isaki    3361:  * (Re)allocate usrbuf with 'newbufsize' bytes.
                   3362:  * Use this function for usrbuf because only usrbuf can be mmapped.
                   3363:  * If successful, it updates track->usrbuf.mem, track->usrbuf.capacity and
                   3364:  * returns 0.  Otherwise, it clears track->usrbuf.mem, track->usrbuf.capacity
                   3365:  * and returns errno.
                   3366:  * It must be called before updating usrbuf.capacity.
                   3367:  */
                   3368: static int
                   3369: audio_realloc_usrbuf(audio_track_t *track, int newbufsize)
                   3370: {
                   3371:        struct audio_softc *sc;
                   3372:        vaddr_t vstart;
                   3373:        vsize_t oldvsize;
                   3374:        vsize_t newvsize;
                   3375:        int error;
                   3376:
                   3377:        KASSERT(newbufsize > 0);
                   3378:        sc = track->mixer->sc;
                   3379:
                   3380:        /* Get a nonzero multiple of PAGE_SIZE */
                   3381:        newvsize = roundup2(MAX(newbufsize, PAGE_SIZE), PAGE_SIZE);
                   3382:
                   3383:        if (track->usrbuf.mem != NULL) {
                   3384:                oldvsize = roundup2(MAX(track->usrbuf.capacity, PAGE_SIZE),
                   3385:                    PAGE_SIZE);
                   3386:                if (oldvsize == newvsize) {
                   3387:                        track->usrbuf.capacity = newbufsize;
                   3388:                        return 0;
                   3389:                }
                   3390:                vstart = (vaddr_t)track->usrbuf.mem;
                   3391:                uvm_unmap(kernel_map, vstart, vstart + oldvsize);
                   3392:                /* uvm_unmap also detach uobj */
                   3393:                track->uobj = NULL;             /* paranoia */
                   3394:                track->usrbuf.mem = NULL;
                   3395:        }
                   3396:
                   3397:        /* Create a uvm anonymous object */
                   3398:        track->uobj = uao_create(newvsize, 0);
                   3399:
                   3400:        /* Map it into the kernel virtual address space */
                   3401:        vstart = 0;
                   3402:        error = uvm_map(kernel_map, &vstart, newvsize, track->uobj, 0, 0,
                   3403:            UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_NONE,
                   3404:            UVM_ADV_RANDOM, 0));
                   3405:        if (error) {
                   3406:                device_printf(sc->sc_dev, "uvm_map failed with %d\n", error);
                   3407:                uao_detach(track->uobj);        /* release reference */
                   3408:                goto abort;
                   3409:        }
                   3410:
                   3411:        error = uvm_map_pageable(kernel_map, vstart, vstart + newvsize,
                   3412:            false, 0);
                   3413:        if (error) {
                   3414:                device_printf(sc->sc_dev, "uvm_map_pageable failed with %d\n",
                   3415:                    error);
                   3416:                uvm_unmap(kernel_map, vstart, vstart + newvsize);
                   3417:                /* uvm_unmap also detach uobj */
                   3418:                goto abort;
                   3419:        }
                   3420:
                   3421:        track->usrbuf.mem = (void *)vstart;
                   3422:        track->usrbuf.capacity = newbufsize;
                   3423:        memset(track->usrbuf.mem, 0, newvsize);
                   3424:        return 0;
                   3425:
                   3426:        /* failure */
                   3427: abort:
                   3428:        track->uobj = NULL;             /* paranoia */
                   3429:        track->usrbuf.mem = NULL;
                   3430:        track->usrbuf.capacity = 0;
                   3431:        return error;
                   3432: }
                   3433:
                   3434: /*
                   3435:  * Free usrbuf (if available).
                   3436:  */
                   3437: static void
                   3438: audio_free_usrbuf(audio_track_t *track)
                   3439: {
                   3440:        vaddr_t vstart;
                   3441:        vsize_t vsize;
                   3442:
                   3443:        vstart = (vaddr_t)track->usrbuf.mem;
                   3444:        vsize = roundup2(MAX(track->usrbuf.capacity, PAGE_SIZE), PAGE_SIZE);
                   3445:        if (track->usrbuf.mem != NULL) {
                   3446:                /*
                   3447:                 * Unmap the kernel mapping.  uvm_unmap releases the
                   3448:                 * reference to the uvm object, and this should be the
                   3449:                 * last virtual mapping of the uvm object, so no need
                   3450:                 * to explicitly release (`detach') the object.
                   3451:                 */
                   3452:                uvm_unmap(kernel_map, vstart, vstart + vsize);
                   3453:
                   3454:                track->uobj = NULL;
                   3455:                track->usrbuf.mem = NULL;
                   3456:                track->usrbuf.capacity = 0;
                   3457:        }
                   3458: }
                   3459:
                   3460: /*
                   3461:  * This filter changes the volume for each channel.
                   3462:  * arg->context points track->ch_volume[].
                   3463:  */
                   3464: static void
                   3465: audio_track_chvol(audio_filter_arg_t *arg)
                   3466: {
                   3467:        int16_t *ch_volume;
                   3468:        const aint_t *s;
                   3469:        aint_t *d;
                   3470:        u_int i;
                   3471:        u_int ch;
                   3472:        u_int channels;
                   3473:
                   3474:        DIAGNOSTIC_filter_arg(arg);
1.47      isaki    3475:        KASSERTMSG(arg->srcfmt->channels == arg->dstfmt->channels,
                   3476:            "arg->srcfmt->channels=%d, arg->dstfmt->channels=%d",
                   3477:            arg->srcfmt->channels, arg->dstfmt->channels);
1.2       isaki    3478:        KASSERT(arg->context != NULL);
1.47      isaki    3479:        KASSERTMSG(arg->srcfmt->channels <= AUDIO_MAX_CHANNELS,
                   3480:            "arg->srcfmt->channels=%d", arg->srcfmt->channels);
1.2       isaki    3481:
                   3482:        s = arg->src;
                   3483:        d = arg->dst;
                   3484:        ch_volume = arg->context;
                   3485:
                   3486:        channels = arg->srcfmt->channels;
                   3487:        for (i = 0; i < arg->count; i++) {
                   3488:                for (ch = 0; ch < channels; ch++) {
                   3489:                        aint2_t val;
                   3490:                        val = *s++;
1.16      isaki    3491:                        val = AUDIO_SCALEDOWN(val * ch_volume[ch], 8);
1.2       isaki    3492:                        *d++ = (aint_t)val;
                   3493:                }
                   3494:        }
                   3495: }
                   3496:
                   3497: /*
                   3498:  * This filter performs conversion from stereo (or more channels) to mono.
                   3499:  */
                   3500: static void
                   3501: audio_track_chmix_mixLR(audio_filter_arg_t *arg)
                   3502: {
                   3503:        const aint_t *s;
                   3504:        aint_t *d;
                   3505:        u_int i;
                   3506:
                   3507:        DIAGNOSTIC_filter_arg(arg);
                   3508:
                   3509:        s = arg->src;
                   3510:        d = arg->dst;
                   3511:
                   3512:        for (i = 0; i < arg->count; i++) {
1.16      isaki    3513:                *d++ = AUDIO_SCALEDOWN(s[0], 1) + AUDIO_SCALEDOWN(s[1], 1);
1.2       isaki    3514:                s += arg->srcfmt->channels;
                   3515:        }
                   3516: }
                   3517:
                   3518: /*
                   3519:  * This filter performs conversion from mono to stereo (or more channels).
                   3520:  */
                   3521: static void
                   3522: audio_track_chmix_dupLR(audio_filter_arg_t *arg)
                   3523: {
                   3524:        const aint_t *s;
                   3525:        aint_t *d;
                   3526:        u_int i;
                   3527:        u_int ch;
                   3528:        u_int dstchannels;
                   3529:
                   3530:        DIAGNOSTIC_filter_arg(arg);
                   3531:
                   3532:        s = arg->src;
                   3533:        d = arg->dst;
                   3534:        dstchannels = arg->dstfmt->channels;
                   3535:
                   3536:        for (i = 0; i < arg->count; i++) {
                   3537:                d[0] = s[0];
                   3538:                d[1] = s[0];
                   3539:                s++;
                   3540:                d += dstchannels;
                   3541:        }
                   3542:        if (dstchannels > 2) {
                   3543:                d = arg->dst;
                   3544:                for (i = 0; i < arg->count; i++) {
                   3545:                        for (ch = 2; ch < dstchannels; ch++) {
                   3546:                                d[ch] = 0;
                   3547:                        }
                   3548:                        d += dstchannels;
                   3549:                }
                   3550:        }
                   3551: }
                   3552:
                   3553: /*
                   3554:  * This filter shrinks M channels into N channels.
                   3555:  * Extra channels are discarded.
                   3556:  */
                   3557: static void
                   3558: audio_track_chmix_shrink(audio_filter_arg_t *arg)
                   3559: {
                   3560:        const aint_t *s;
                   3561:        aint_t *d;
                   3562:        u_int i;
                   3563:        u_int ch;
                   3564:
                   3565:        DIAGNOSTIC_filter_arg(arg);
                   3566:
                   3567:        s = arg->src;
                   3568:        d = arg->dst;
                   3569:
                   3570:        for (i = 0; i < arg->count; i++) {
                   3571:                for (ch = 0; ch < arg->dstfmt->channels; ch++) {
                   3572:                        *d++ = s[ch];
                   3573:                }
                   3574:                s += arg->srcfmt->channels;
                   3575:        }
                   3576: }
                   3577:
                   3578: /*
                   3579:  * This filter expands M channels into N channels.
                   3580:  * Silence is inserted for missing channels.
                   3581:  */
                   3582: static void
                   3583: audio_track_chmix_expand(audio_filter_arg_t *arg)
                   3584: {
                   3585:        const aint_t *s;
                   3586:        aint_t *d;
                   3587:        u_int i;
                   3588:        u_int ch;
                   3589:        u_int srcchannels;
                   3590:        u_int dstchannels;
                   3591:
                   3592:        DIAGNOSTIC_filter_arg(arg);
                   3593:
                   3594:        s = arg->src;
                   3595:        d = arg->dst;
                   3596:
                   3597:        srcchannels = arg->srcfmt->channels;
                   3598:        dstchannels = arg->dstfmt->channels;
                   3599:        for (i = 0; i < arg->count; i++) {
                   3600:                for (ch = 0; ch < srcchannels; ch++) {
                   3601:                        *d++ = *s++;
                   3602:                }
                   3603:                for (; ch < dstchannels; ch++) {
                   3604:                        *d++ = 0;
                   3605:                }
                   3606:        }
                   3607: }
                   3608:
                   3609: /*
                   3610:  * This filter performs frequency conversion (up sampling).
                   3611:  * It uses linear interpolation.
                   3612:  */
                   3613: static void
                   3614: audio_track_freq_up(audio_filter_arg_t *arg)
                   3615: {
                   3616:        audio_track_t *track;
                   3617:        audio_ring_t *src;
                   3618:        audio_ring_t *dst;
                   3619:        const aint_t *s;
                   3620:        aint_t *d;
                   3621:        aint_t prev[AUDIO_MAX_CHANNELS];
                   3622:        aint_t curr[AUDIO_MAX_CHANNELS];
                   3623:        aint_t grad[AUDIO_MAX_CHANNELS];
                   3624:        u_int i;
                   3625:        u_int t;
                   3626:        u_int step;
                   3627:        u_int channels;
                   3628:        u_int ch;
                   3629:        int srcused;
                   3630:
                   3631:        track = arg->context;
                   3632:        KASSERT(track);
                   3633:        src = &track->freq.srcbuf;
                   3634:        dst = track->freq.dst;
                   3635:        DIAGNOSTIC_ring(dst);
                   3636:        DIAGNOSTIC_ring(src);
                   3637:        KASSERT(src->used > 0);
1.47      isaki    3638:        KASSERTMSG(src->fmt.channels == dst->fmt.channels,
                   3639:            "src->fmt.channels=%d dst->fmt.channels=%d",
                   3640:            src->fmt.channels, dst->fmt.channels);
                   3641:        KASSERTMSG(src->head % track->mixer->frames_per_block == 0,
                   3642:            "src->head=%d track->mixer->frames_per_block=%d",
                   3643:            src->head, track->mixer->frames_per_block);
1.2       isaki    3644:
                   3645:        s = arg->src;
                   3646:        d = arg->dst;
                   3647:
                   3648:        /*
                   3649:         * In order to faciliate interpolation for each block, slide (delay)
                   3650:         * input by one sample.  As a result, strictly speaking, the output
                   3651:         * phase is delayed by 1/dstfreq.  However, I believe there is no
                   3652:         * observable impact.
                   3653:         *
                   3654:         * Example)
                   3655:         * srcfreq:dstfreq = 1:3
                   3656:         *
                   3657:         *  A - -
                   3658:         *  |
                   3659:         *  |
                   3660:         *  |     B - -
                   3661:         *  +-----+-----> input timeframe
                   3662:         *  0     1
                   3663:         *
                   3664:         *  0     1
                   3665:         *  +-----+-----> input timeframe
                   3666:         *  |     A
                   3667:         *  |   x   x
                   3668:         *  | x       x
                   3669:         *  x          (B)
                   3670:         *  +-+-+-+-+-+-> output timeframe
                   3671:         *  0 1 2 3 4 5
                   3672:         */
                   3673:
                   3674:        /* Last samples in previous block */
                   3675:        channels = src->fmt.channels;
                   3676:        for (ch = 0; ch < channels; ch++) {
                   3677:                prev[ch] = track->freq_prev[ch];
                   3678:                curr[ch] = track->freq_curr[ch];
                   3679:                grad[ch] = curr[ch] - prev[ch];
                   3680:        }
                   3681:
                   3682:        step = track->freq_step;
                   3683:        t = track->freq_current;
                   3684: //#define FREQ_DEBUG
                   3685: #if defined(FREQ_DEBUG)
                   3686: #define PRINTF(fmt...) printf(fmt)
                   3687: #else
                   3688: #define PRINTF(fmt...) do { } while (0)
                   3689: #endif
                   3690:        srcused = src->used;
                   3691:        PRINTF("upstart step=%d leap=%d", step, track->freq_leap);
                   3692:        PRINTF(" srcused=%d arg->count=%u", src->used, arg->count);
                   3693:        PRINTF(" prev=%d curr=%d grad=%d", prev[0], curr[0], grad[0]);
                   3694:        PRINTF(" t=%d\n", t);
                   3695:
                   3696:        for (i = 0; i < arg->count; i++) {
                   3697:                PRINTF("i=%d t=%5d", i, t);
                   3698:                if (t >= 65536) {
                   3699:                        for (ch = 0; ch < channels; ch++) {
                   3700:                                prev[ch] = curr[ch];
                   3701:                                curr[ch] = *s++;
                   3702:                                grad[ch] = curr[ch] - prev[ch];
                   3703:                        }
                   3704:                        PRINTF(" prev=%d s[%d]=%d",
                   3705:                            prev[0], src->used - srcused, curr[0]);
                   3706:
                   3707:                        /* Update */
                   3708:                        t -= 65536;
                   3709:                        srcused--;
                   3710:                        if (srcused < 0) {
                   3711:                                PRINTF(" break\n");
                   3712:                                break;
                   3713:                        }
                   3714:                }
                   3715:
                   3716:                for (ch = 0; ch < channels; ch++) {
                   3717:                        *d++ = prev[ch] + (aint2_t)grad[ch] * t / 65536;
                   3718: #if defined(FREQ_DEBUG)
                   3719:                        if (ch == 0)
                   3720:                                printf(" t=%5d *d=%d", t, d[-1]);
                   3721: #endif
                   3722:                }
                   3723:                t += step;
                   3724:
                   3725:                PRINTF("\n");
                   3726:        }
                   3727:        PRINTF("end prev=%d curr=%d\n", prev[0], curr[0]);
                   3728:
                   3729:        auring_take(src, src->used);
                   3730:        auring_push(dst, i);
                   3731:
                   3732:        /* Adjust */
                   3733:        t += track->freq_leap;
                   3734:
                   3735:        track->freq_current = t;
                   3736:        for (ch = 0; ch < channels; ch++) {
                   3737:                track->freq_prev[ch] = prev[ch];
                   3738:                track->freq_curr[ch] = curr[ch];
                   3739:        }
                   3740: }
                   3741:
                   3742: /*
                   3743:  * This filter performs frequency conversion (down sampling).
                   3744:  * It uses simple thinning.
                   3745:  */
                   3746: static void
                   3747: audio_track_freq_down(audio_filter_arg_t *arg)
                   3748: {
                   3749:        audio_track_t *track;
                   3750:        audio_ring_t *src;
                   3751:        audio_ring_t *dst;
                   3752:        const aint_t *s0;
                   3753:        aint_t *d;
                   3754:        u_int i;
                   3755:        u_int t;
                   3756:        u_int step;
                   3757:        u_int ch;
                   3758:        u_int channels;
                   3759:
                   3760:        track = arg->context;
                   3761:        KASSERT(track);
                   3762:        src = &track->freq.srcbuf;
                   3763:        dst = track->freq.dst;
                   3764:
                   3765:        DIAGNOSTIC_ring(dst);
                   3766:        DIAGNOSTIC_ring(src);
                   3767:        KASSERT(src->used > 0);
1.47      isaki    3768:        KASSERTMSG(src->fmt.channels == dst->fmt.channels,
                   3769:            "src->fmt.channels=%d dst->fmt.channels=%d",
                   3770:            src->fmt.channels, dst->fmt.channels);
1.2       isaki    3771:        KASSERTMSG(src->head % track->mixer->frames_per_block == 0,
1.47      isaki    3772:            "src->head=%d track->mixer->frames_per_block=%d",
1.2       isaki    3773:            src->head, track->mixer->frames_per_block);
                   3774:
                   3775:        s0 = arg->src;
                   3776:        d = arg->dst;
                   3777:        t = track->freq_current;
                   3778:        step = track->freq_step;
                   3779:        channels = dst->fmt.channels;
                   3780:        PRINTF("downstart step=%d leap=%d", step, track->freq_leap);
                   3781:        PRINTF(" srcused=%d arg->count=%u", src->used, arg->count);
                   3782:        PRINTF(" t=%d\n", t);
                   3783:
                   3784:        for (i = 0; i < arg->count && t / 65536 < src->used; i++) {
                   3785:                const aint_t *s;
                   3786:                PRINTF("i=%4d t=%10d", i, t);
                   3787:                s = s0 + (t / 65536) * channels;
                   3788:                PRINTF(" s=%5ld", (s - s0) / channels);
                   3789:                for (ch = 0; ch < channels; ch++) {
                   3790:                        if (ch == 0) PRINTF(" *s=%d", s[ch]);
                   3791:                        *d++ = s[ch];
                   3792:                }
                   3793:                PRINTF("\n");
                   3794:                t += step;
                   3795:        }
                   3796:        t += track->freq_leap;
                   3797:        PRINTF("end t=%d\n", t);
                   3798:        auring_take(src, src->used);
                   3799:        auring_push(dst, i);
                   3800:        track->freq_current = t % 65536;
                   3801: }
                   3802:
                   3803: /*
                   3804:  * Creates track and returns it.
1.63      isaki    3805:  * Must be called without sc_lock held.
1.2       isaki    3806:  */
                   3807: audio_track_t *
                   3808: audio_track_create(struct audio_softc *sc, audio_trackmixer_t *mixer)
                   3809: {
                   3810:        audio_track_t *track;
                   3811:        static int newid = 0;
                   3812:
                   3813:        track = kmem_zalloc(sizeof(*track), KM_SLEEP);
                   3814:
                   3815:        track->id = newid++;
                   3816:        track->mixer = mixer;
                   3817:        track->mode = mixer->mode;
                   3818:
                   3819:        /* Do TRACE after id is assigned. */
                   3820:        TRACET(3, track, "for %s",
                   3821:            mixer->mode == AUMODE_PLAY ? "playback" : "recording");
                   3822:
                   3823: #if defined(AUDIO_SUPPORT_TRACK_VOLUME)
                   3824:        track->volume = 256;
                   3825: #endif
                   3826:        for (int i = 0; i < AUDIO_MAX_CHANNELS; i++) {
                   3827:                track->ch_volume[i] = 256;
                   3828:        }
                   3829:
                   3830:        return track;
                   3831: }
                   3832:
                   3833: /*
                   3834:  * Release all resources of the track and track itself.
                   3835:  * track must not be NULL.  Don't specify the track within the file
                   3836:  * structure linked from sc->sc_files.
                   3837:  */
                   3838: static void
                   3839: audio_track_destroy(audio_track_t *track)
                   3840: {
                   3841:
                   3842:        KASSERT(track);
                   3843:
                   3844:        audio_free_usrbuf(track);
                   3845:        audio_free(track->codec.srcbuf.mem);
                   3846:        audio_free(track->chvol.srcbuf.mem);
                   3847:        audio_free(track->chmix.srcbuf.mem);
                   3848:        audio_free(track->freq.srcbuf.mem);
                   3849:        audio_free(track->outbuf.mem);
                   3850:
                   3851:        kmem_free(track, sizeof(*track));
                   3852: }
                   3853:
                   3854: /*
                   3855:  * It returns encoding conversion filter according to src and dst format.
                   3856:  * If it is not a convertible pair, it returns NULL.  Either src or dst
                   3857:  * must be internal format.
                   3858:  */
                   3859: static audio_filter_t
                   3860: audio_track_get_codec(audio_track_t *track, const audio_format2_t *src,
                   3861:        const audio_format2_t *dst)
                   3862: {
                   3863:
                   3864:        if (audio_format2_is_internal(src)) {
                   3865:                if (dst->encoding == AUDIO_ENCODING_ULAW) {
                   3866:                        return audio_internal_to_mulaw;
                   3867:                } else if (dst->encoding == AUDIO_ENCODING_ALAW) {
                   3868:                        return audio_internal_to_alaw;
                   3869:                } else if (audio_format2_is_linear(dst)) {
                   3870:                        switch (dst->stride) {
                   3871:                        case 8:
                   3872:                                return audio_internal_to_linear8;
                   3873:                        case 16:
                   3874:                                return audio_internal_to_linear16;
                   3875: #if defined(AUDIO_SUPPORT_LINEAR24)
                   3876:                        case 24:
                   3877:                                return audio_internal_to_linear24;
                   3878: #endif
                   3879:                        case 32:
                   3880:                                return audio_internal_to_linear32;
                   3881:                        default:
                   3882:                                TRACET(1, track, "unsupported %s stride %d",
                   3883:                                    "dst", dst->stride);
                   3884:                                goto abort;
                   3885:                        }
                   3886:                }
                   3887:        } else if (audio_format2_is_internal(dst)) {
                   3888:                if (src->encoding == AUDIO_ENCODING_ULAW) {
                   3889:                        return audio_mulaw_to_internal;
                   3890:                } else if (src->encoding == AUDIO_ENCODING_ALAW) {
                   3891:                        return audio_alaw_to_internal;
                   3892:                } else if (audio_format2_is_linear(src)) {
                   3893:                        switch (src->stride) {
                   3894:                        case 8:
                   3895:                                return audio_linear8_to_internal;
                   3896:                        case 16:
                   3897:                                return audio_linear16_to_internal;
                   3898: #if defined(AUDIO_SUPPORT_LINEAR24)
                   3899:                        case 24:
                   3900:                                return audio_linear24_to_internal;
                   3901: #endif
                   3902:                        case 32:
                   3903:                                return audio_linear32_to_internal;
                   3904:                        default:
                   3905:                                TRACET(1, track, "unsupported %s stride %d",
                   3906:                                    "src", src->stride);
                   3907:                                goto abort;
                   3908:                        }
                   3909:                }
                   3910:        }
                   3911:
                   3912:        TRACET(1, track, "unsupported encoding");
                   3913: abort:
                   3914: #if defined(AUDIO_DEBUG)
                   3915:        if (audiodebug >= 2) {
                   3916:                char buf[100];
                   3917:                audio_format2_tostr(buf, sizeof(buf), src);
                   3918:                TRACET(2, track, "src %s", buf);
                   3919:                audio_format2_tostr(buf, sizeof(buf), dst);
                   3920:                TRACET(2, track, "dst %s", buf);
                   3921:        }
                   3922: #endif
                   3923:        return NULL;
                   3924: }
                   3925:
                   3926: /*
                   3927:  * Initialize the codec stage of this track as necessary.
                   3928:  * If successful, it initializes the codec stage as necessary, stores updated
                   3929:  * last_dst in *last_dstp in any case, and returns 0.
                   3930:  * Otherwise, it returns errno without modifying *last_dstp.
                   3931:  */
                   3932: static int
                   3933: audio_track_init_codec(audio_track_t *track, audio_ring_t **last_dstp)
                   3934: {
                   3935:        audio_ring_t *last_dst;
                   3936:        audio_ring_t *srcbuf;
                   3937:        audio_format2_t *srcfmt;
                   3938:        audio_format2_t *dstfmt;
                   3939:        audio_filter_arg_t *arg;
                   3940:        u_int len;
                   3941:        int error;
                   3942:
                   3943:        KASSERT(track);
                   3944:
                   3945:        last_dst = *last_dstp;
                   3946:        dstfmt = &last_dst->fmt;
                   3947:        srcfmt = &track->inputfmt;
                   3948:        srcbuf = &track->codec.srcbuf;
                   3949:        error = 0;
                   3950:
                   3951:        if (srcfmt->encoding != dstfmt->encoding
                   3952:         || srcfmt->precision != dstfmt->precision
                   3953:         || srcfmt->stride != dstfmt->stride) {
                   3954:                track->codec.dst = last_dst;
                   3955:
                   3956:                srcbuf->fmt = *dstfmt;
                   3957:                srcbuf->fmt.encoding = srcfmt->encoding;
                   3958:                srcbuf->fmt.precision = srcfmt->precision;
                   3959:                srcbuf->fmt.stride = srcfmt->stride;
                   3960:
                   3961:                track->codec.filter = audio_track_get_codec(track,
                   3962:                    &srcbuf->fmt, dstfmt);
                   3963:                if (track->codec.filter == NULL) {
                   3964:                        error = EINVAL;
                   3965:                        goto abort;
                   3966:                }
                   3967:
                   3968:                srcbuf->head = 0;
                   3969:                srcbuf->used = 0;
                   3970:                srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
                   3971:                len = auring_bytelen(srcbuf);
                   3972:                srcbuf->mem = audio_realloc(srcbuf->mem, len);
                   3973:
                   3974:                arg = &track->codec.arg;
                   3975:                arg->srcfmt = &srcbuf->fmt;
                   3976:                arg->dstfmt = dstfmt;
                   3977:                arg->context = NULL;
                   3978:
                   3979:                *last_dstp = srcbuf;
                   3980:                return 0;
                   3981:        }
                   3982:
                   3983: abort:
                   3984:        track->codec.filter = NULL;
                   3985:        audio_free(srcbuf->mem);
                   3986:        return error;
                   3987: }
                   3988:
                   3989: /*
                   3990:  * Initialize the chvol stage of this track as necessary.
                   3991:  * If successful, it initializes the chvol stage as necessary, stores updated
                   3992:  * last_dst in *last_dstp in any case, and returns 0.
                   3993:  * Otherwise, it returns errno without modifying *last_dstp.
                   3994:  */
                   3995: static int
                   3996: audio_track_init_chvol(audio_track_t *track, audio_ring_t **last_dstp)
                   3997: {
                   3998:        audio_ring_t *last_dst;
                   3999:        audio_ring_t *srcbuf;
                   4000:        audio_format2_t *srcfmt;
                   4001:        audio_format2_t *dstfmt;
                   4002:        audio_filter_arg_t *arg;
                   4003:        u_int len;
                   4004:        int error;
                   4005:
                   4006:        KASSERT(track);
                   4007:
                   4008:        last_dst = *last_dstp;
                   4009:        dstfmt = &last_dst->fmt;
                   4010:        srcfmt = &track->inputfmt;
                   4011:        srcbuf = &track->chvol.srcbuf;
                   4012:        error = 0;
                   4013:
                   4014:        /* Check whether channel volume conversion is necessary. */
                   4015:        bool use_chvol = false;
                   4016:        for (int ch = 0; ch < srcfmt->channels; ch++) {
                   4017:                if (track->ch_volume[ch] != 256) {
                   4018:                        use_chvol = true;
                   4019:                        break;
                   4020:                }
                   4021:        }
                   4022:
                   4023:        if (use_chvol == true) {
                   4024:                track->chvol.dst = last_dst;
                   4025:                track->chvol.filter = audio_track_chvol;
                   4026:
                   4027:                srcbuf->fmt = *dstfmt;
                   4028:                /* no format conversion occurs */
                   4029:
                   4030:                srcbuf->head = 0;
                   4031:                srcbuf->used = 0;
                   4032:                srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
                   4033:                len = auring_bytelen(srcbuf);
                   4034:                srcbuf->mem = audio_realloc(srcbuf->mem, len);
                   4035:
                   4036:                arg = &track->chvol.arg;
                   4037:                arg->srcfmt = &srcbuf->fmt;
                   4038:                arg->dstfmt = dstfmt;
                   4039:                arg->context = track->ch_volume;
                   4040:
                   4041:                *last_dstp = srcbuf;
                   4042:                return 0;
                   4043:        }
                   4044:
                   4045:        track->chvol.filter = NULL;
                   4046:        audio_free(srcbuf->mem);
                   4047:        return error;
                   4048: }
                   4049:
                   4050: /*
                   4051:  * Initialize the chmix stage of this track as necessary.
                   4052:  * If successful, it initializes the chmix stage as necessary, stores updated
                   4053:  * last_dst in *last_dstp in any case, and returns 0.
                   4054:  * Otherwise, it returns errno without modifying *last_dstp.
                   4055:  */
                   4056: static int
                   4057: audio_track_init_chmix(audio_track_t *track, audio_ring_t **last_dstp)
                   4058: {
                   4059:        audio_ring_t *last_dst;
                   4060:        audio_ring_t *srcbuf;
                   4061:        audio_format2_t *srcfmt;
                   4062:        audio_format2_t *dstfmt;
                   4063:        audio_filter_arg_t *arg;
                   4064:        u_int srcch;
                   4065:        u_int dstch;
                   4066:        u_int len;
                   4067:        int error;
                   4068:
                   4069:        KASSERT(track);
                   4070:
                   4071:        last_dst = *last_dstp;
                   4072:        dstfmt = &last_dst->fmt;
                   4073:        srcfmt = &track->inputfmt;
                   4074:        srcbuf = &track->chmix.srcbuf;
                   4075:        error = 0;
                   4076:
                   4077:        srcch = srcfmt->channels;
                   4078:        dstch = dstfmt->channels;
                   4079:        if (srcch != dstch) {
                   4080:                track->chmix.dst = last_dst;
                   4081:
                   4082:                if (srcch >= 2 && dstch == 1) {
                   4083:                        track->chmix.filter = audio_track_chmix_mixLR;
                   4084:                } else if (srcch == 1 && dstch >= 2) {
                   4085:                        track->chmix.filter = audio_track_chmix_dupLR;
                   4086:                } else if (srcch > dstch) {
                   4087:                        track->chmix.filter = audio_track_chmix_shrink;
                   4088:                } else {
                   4089:                        track->chmix.filter = audio_track_chmix_expand;
                   4090:                }
                   4091:
                   4092:                srcbuf->fmt = *dstfmt;
                   4093:                srcbuf->fmt.channels = srcch;
                   4094:
                   4095:                srcbuf->head = 0;
                   4096:                srcbuf->used = 0;
                   4097:                /* XXX The buffer size should be able to calculate. */
                   4098:                srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
                   4099:                len = auring_bytelen(srcbuf);
                   4100:                srcbuf->mem = audio_realloc(srcbuf->mem, len);
                   4101:
                   4102:                arg = &track->chmix.arg;
                   4103:                arg->srcfmt = &srcbuf->fmt;
                   4104:                arg->dstfmt = dstfmt;
                   4105:                arg->context = NULL;
                   4106:
                   4107:                *last_dstp = srcbuf;
                   4108:                return 0;
                   4109:        }
                   4110:
                   4111:        track->chmix.filter = NULL;
                   4112:        audio_free(srcbuf->mem);
                   4113:        return error;
                   4114: }
                   4115:
                   4116: /*
                   4117:  * Initialize the freq stage of this track as necessary.
                   4118:  * If successful, it initializes the freq stage as necessary, stores updated
                   4119:  * last_dst in *last_dstp in any case, and returns 0.
                   4120:  * Otherwise, it returns errno without modifying *last_dstp.
                   4121:  */
                   4122: static int
                   4123: audio_track_init_freq(audio_track_t *track, audio_ring_t **last_dstp)
                   4124: {
                   4125:        audio_ring_t *last_dst;
                   4126:        audio_ring_t *srcbuf;
                   4127:        audio_format2_t *srcfmt;
                   4128:        audio_format2_t *dstfmt;
                   4129:        audio_filter_arg_t *arg;
                   4130:        uint32_t srcfreq;
                   4131:        uint32_t dstfreq;
                   4132:        u_int dst_capacity;
                   4133:        u_int mod;
                   4134:        u_int len;
                   4135:        int error;
                   4136:
                   4137:        KASSERT(track);
                   4138:
                   4139:        last_dst = *last_dstp;
                   4140:        dstfmt = &last_dst->fmt;
                   4141:        srcfmt = &track->inputfmt;
                   4142:        srcbuf = &track->freq.srcbuf;
                   4143:        error = 0;
                   4144:
                   4145:        srcfreq = srcfmt->sample_rate;
                   4146:        dstfreq = dstfmt->sample_rate;
                   4147:        if (srcfreq != dstfreq) {
                   4148:                track->freq.dst = last_dst;
                   4149:
                   4150:                memset(track->freq_prev, 0, sizeof(track->freq_prev));
                   4151:                memset(track->freq_curr, 0, sizeof(track->freq_curr));
                   4152:
                   4153:                /* freq_step is the ratio of src/dst when let dst 65536. */
                   4154:                track->freq_step = (uint64_t)srcfreq * 65536 / dstfreq;
                   4155:
                   4156:                dst_capacity = frame_per_block(track->mixer, dstfmt);
                   4157:                mod = (uint64_t)srcfreq * 65536 % dstfreq;
                   4158:                track->freq_leap = (mod * dst_capacity + dstfreq / 2) / dstfreq;
                   4159:
                   4160:                if (track->freq_step < 65536) {
                   4161:                        track->freq.filter = audio_track_freq_up;
                   4162:                        /* In order to carry at the first time. */
                   4163:                        track->freq_current = 65536;
                   4164:                } else {
                   4165:                        track->freq.filter = audio_track_freq_down;
                   4166:                        track->freq_current = 0;
                   4167:                }
                   4168:
                   4169:                srcbuf->fmt = *dstfmt;
                   4170:                srcbuf->fmt.sample_rate = srcfreq;
                   4171:
                   4172:                srcbuf->head = 0;
                   4173:                srcbuf->used = 0;
                   4174:                srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
                   4175:                len = auring_bytelen(srcbuf);
                   4176:                srcbuf->mem = audio_realloc(srcbuf->mem, len);
                   4177:
                   4178:                arg = &track->freq.arg;
                   4179:                arg->srcfmt = &srcbuf->fmt;
                   4180:                arg->dstfmt = dstfmt;/*&last_dst->fmt;*/
                   4181:                arg->context = track;
                   4182:
                   4183:                *last_dstp = srcbuf;
                   4184:                return 0;
                   4185:        }
                   4186:
                   4187:        track->freq.filter = NULL;
                   4188:        audio_free(srcbuf->mem);
                   4189:        return error;
                   4190: }
                   4191:
                   4192: /*
                   4193:  * When playing back: (e.g. if codec and freq stage are valid)
                   4194:  *
                   4195:  *               write
                   4196:  *                | uiomove
                   4197:  *                v
                   4198:  *  usrbuf      [...............]  byte ring buffer (mmap-able)
                   4199:  *                | memcpy
                   4200:  *                v
                   4201:  *  codec.srcbuf[....]             1 block (ring) buffer   <-- stage input
                   4202:  *       .dst ----+
                   4203:  *                | convert
                   4204:  *                v
                   4205:  *  freq.srcbuf [....]             1 block (ring) buffer
                   4206:  *      .dst  ----+
                   4207:  *                | convert
                   4208:  *                v
                   4209:  *  outbuf      [...............]  NBLKOUT blocks ring buffer
                   4210:  *
                   4211:  *
                   4212:  * When recording:
                   4213:  *
                   4214:  *  freq.srcbuf [...............]  NBLKOUT blocks ring buffer <-- stage input
                   4215:  *      .dst  ----+
                   4216:  *                | convert
                   4217:  *                v
                   4218:  *  codec.srcbuf[.....]            1 block (ring) buffer
                   4219:  *       .dst ----+
                   4220:  *                | convert
                   4221:  *                v
                   4222:  *  outbuf      [.....]            1 block (ring) buffer
                   4223:  *                | memcpy
                   4224:  *                v
                   4225:  *  usrbuf      [...............]  byte ring buffer (mmap-able *)
                   4226:  *                | uiomove
                   4227:  *                v
                   4228:  *               read
                   4229:  *
                   4230:  *    *: usrbuf for recording is also mmap-able due to symmetry with
                   4231:  *       playback buffer, but for now mmap will never happen for recording.
                   4232:  */
                   4233:
                   4234: /*
                   4235:  * Set the userland format of this track.
1.77      isaki    4236:  * usrfmt argument should have been previously verified by
                   4237:  * audio_track_setinfo_check().
                   4238:  * This function may release and reallocate all internal conversion buffers.
1.2       isaki    4239:  * It returns 0 if successful.  Otherwise it returns errno with clearing all
                   4240:  * internal buffers.
                   4241:  * It must be called without sc_intr_lock since uvm_* routines require non
                   4242:  * intr_lock state.
                   4243:  * It must be called with track lock held since it may release and reallocate
                   4244:  * outbuf.
                   4245:  */
                   4246: static int
                   4247: audio_track_set_format(audio_track_t *track, audio_format2_t *usrfmt)
                   4248: {
                   4249:        struct audio_softc *sc;
                   4250:        u_int newbufsize;
                   4251:        u_int oldblksize;
                   4252:        u_int len;
                   4253:        int error;
                   4254:
                   4255:        KASSERT(track);
                   4256:        sc = track->mixer->sc;
                   4257:
                   4258:        /* usrbuf is the closest buffer to the userland. */
                   4259:        track->usrbuf.fmt = *usrfmt;
                   4260:
                   4261:        /*
                   4262:         * For references, one block size (in 40msec) is:
                   4263:         *  320 bytes    = 204 blocks/64KB for mulaw/8kHz/1ch
                   4264:         *  7680 bytes   = 8 blocks/64KB for s16/48kHz/2ch
                   4265:         *  30720 bytes  = 90 KB/3blocks for s16/48kHz/8ch
                   4266:         *  61440 bytes  = 180 KB/3blocks for s16/96kHz/8ch
                   4267:         *  245760 bytes = 720 KB/3blocks for s32/192kHz/8ch
                   4268:         *
                   4269:         * For example,
                   4270:         * 1) If usrbuf_blksize = 7056 (s16/44.1k/2ch) and PAGE_SIZE = 8192,
                   4271:         *     newbufsize = rounddown(65536 / 7056) = 63504
                   4272:         *     newvsize = roundup2(63504, PAGE_SIZE) = 65536
                   4273:         *    Therefore it maps 8 * 8K pages and usrbuf->capacity = 63504.
                   4274:         *
                   4275:         * 2) If usrbuf_blksize = 7680 (s16/48k/2ch) and PAGE_SIZE = 4096,
                   4276:         *     newbufsize = rounddown(65536 / 7680) = 61440
                   4277:         *     newvsize = roundup2(61440, PAGE_SIZE) = 61440 (= 15 pages)
                   4278:         *    Therefore it maps 15 * 4K pages and usrbuf->capacity = 61440.
                   4279:         */
                   4280:        oldblksize = track->usrbuf_blksize;
                   4281:        track->usrbuf_blksize = frametobyte(&track->usrbuf.fmt,
                   4282:            frame_per_block(track->mixer, &track->usrbuf.fmt));
                   4283:        track->usrbuf.head = 0;
                   4284:        track->usrbuf.used = 0;
                   4285:        newbufsize = MAX(track->usrbuf_blksize * AUMINNOBLK, 65536);
                   4286:        newbufsize = rounddown(newbufsize, track->usrbuf_blksize);
                   4287:        error = audio_realloc_usrbuf(track, newbufsize);
                   4288:        if (error) {
                   4289:                device_printf(sc->sc_dev, "malloc usrbuf(%d) failed\n",
                   4290:                    newbufsize);
                   4291:                goto error;
                   4292:        }
                   4293:
                   4294:        /* Recalc water mark. */
                   4295:        if (track->usrbuf_blksize != oldblksize) {
                   4296:                if (audio_track_is_playback(track)) {
                   4297:                        /* Set high at 100%, low at 75%.  */
                   4298:                        track->usrbuf_usedhigh = track->usrbuf.capacity;
                   4299:                        track->usrbuf_usedlow = track->usrbuf.capacity * 3 / 4;
                   4300:                } else {
                   4301:                        /* Set high at 100% minus 1block(?), low at 0% */
                   4302:                        track->usrbuf_usedhigh = track->usrbuf.capacity -
                   4303:                            track->usrbuf_blksize;
                   4304:                        track->usrbuf_usedlow = 0;
                   4305:                }
                   4306:        }
                   4307:
                   4308:        /* Stage buffer */
                   4309:        audio_ring_t *last_dst = &track->outbuf;
                   4310:        if (audio_track_is_playback(track)) {
                   4311:                /* On playback, initialize from the mixer side in order. */
                   4312:                track->inputfmt = *usrfmt;
                   4313:                track->outbuf.fmt =  track->mixer->track_fmt;
                   4314:
                   4315:                if ((error = audio_track_init_freq(track, &last_dst)) != 0)
                   4316:                        goto error;
                   4317:                if ((error = audio_track_init_chmix(track, &last_dst)) != 0)
                   4318:                        goto error;
                   4319:                if ((error = audio_track_init_chvol(track, &last_dst)) != 0)
                   4320:                        goto error;
                   4321:                if ((error = audio_track_init_codec(track, &last_dst)) != 0)
                   4322:                        goto error;
                   4323:        } else {
                   4324:                /* On recording, initialize from userland side in order. */
                   4325:                track->inputfmt = track->mixer->track_fmt;
                   4326:                track->outbuf.fmt = *usrfmt;
                   4327:
                   4328:                if ((error = audio_track_init_codec(track, &last_dst)) != 0)
                   4329:                        goto error;
                   4330:                if ((error = audio_track_init_chvol(track, &last_dst)) != 0)
                   4331:                        goto error;
                   4332:                if ((error = audio_track_init_chmix(track, &last_dst)) != 0)
                   4333:                        goto error;
                   4334:                if ((error = audio_track_init_freq(track, &last_dst)) != 0)
                   4335:                        goto error;
                   4336:        }
                   4337: #if 0
                   4338:        /* debug */
                   4339:        if (track->freq.filter) {
                   4340:                audio_print_format2("freq src", &track->freq.srcbuf.fmt);
                   4341:                audio_print_format2("freq dst", &track->freq.dst->fmt);
                   4342:        }
                   4343:        if (track->chmix.filter) {
                   4344:                audio_print_format2("chmix src", &track->chmix.srcbuf.fmt);
                   4345:                audio_print_format2("chmix dst", &track->chmix.dst->fmt);
                   4346:        }
                   4347:        if (track->chvol.filter) {
                   4348:                audio_print_format2("chvol src", &track->chvol.srcbuf.fmt);
                   4349:                audio_print_format2("chvol dst", &track->chvol.dst->fmt);
                   4350:        }
                   4351:        if (track->codec.filter) {
                   4352:                audio_print_format2("codec src", &track->codec.srcbuf.fmt);
                   4353:                audio_print_format2("codec dst", &track->codec.dst->fmt);
                   4354:        }
                   4355: #endif
                   4356:
                   4357:        /* Stage input buffer */
                   4358:        track->input = last_dst;
                   4359:
                   4360:        /*
                   4361:         * On the recording track, make the first stage a ring buffer.
                   4362:         * XXX is there a better way?
                   4363:         */
                   4364:        if (audio_track_is_record(track)) {
                   4365:                track->input->capacity = NBLKOUT *
                   4366:                    frame_per_block(track->mixer, &track->input->fmt);
                   4367:                len = auring_bytelen(track->input);
                   4368:                track->input->mem = audio_realloc(track->input->mem, len);
                   4369:        }
                   4370:
                   4371:        /*
                   4372:         * Output buffer.
                   4373:         * On the playback track, its capacity is NBLKOUT blocks.
                   4374:         * On the recording track, its capacity is 1 block.
                   4375:         */
                   4376:        track->outbuf.head = 0;
                   4377:        track->outbuf.used = 0;
                   4378:        track->outbuf.capacity = frame_per_block(track->mixer,
                   4379:            &track->outbuf.fmt);
                   4380:        if (audio_track_is_playback(track))
                   4381:                track->outbuf.capacity *= NBLKOUT;
                   4382:        len = auring_bytelen(&track->outbuf);
                   4383:        track->outbuf.mem = audio_realloc(track->outbuf.mem, len);
                   4384:        if (track->outbuf.mem == NULL) {
                   4385:                device_printf(sc->sc_dev, "malloc outbuf(%d) failed\n", len);
                   4386:                error = ENOMEM;
                   4387:                goto error;
                   4388:        }
                   4389:
                   4390: #if defined(AUDIO_DEBUG)
                   4391:        if (audiodebug >= 3) {
                   4392:                struct audio_track_debugbuf m;
                   4393:
                   4394:                memset(&m, 0, sizeof(m));
                   4395:                snprintf(m.outbuf, sizeof(m.outbuf), " out=%d",
                   4396:                    track->outbuf.capacity * frametobyte(&track->outbuf.fmt,1));
                   4397:                if (track->freq.filter)
                   4398:                        snprintf(m.freq, sizeof(m.freq), " freq=%d",
                   4399:                            track->freq.srcbuf.capacity *
                   4400:                            frametobyte(&track->freq.srcbuf.fmt, 1));
                   4401:                if (track->chmix.filter)
                   4402:                        snprintf(m.chmix, sizeof(m.chmix), " chmix=%d",
                   4403:                            track->chmix.srcbuf.capacity *
                   4404:                            frametobyte(&track->chmix.srcbuf.fmt, 1));
                   4405:                if (track->chvol.filter)
                   4406:                        snprintf(m.chvol, sizeof(m.chvol), " chvol=%d",
                   4407:                            track->chvol.srcbuf.capacity *
                   4408:                            frametobyte(&track->chvol.srcbuf.fmt, 1));
                   4409:                if (track->codec.filter)
                   4410:                        snprintf(m.codec, sizeof(m.codec), " codec=%d",
                   4411:                            track->codec.srcbuf.capacity *
                   4412:                            frametobyte(&track->codec.srcbuf.fmt, 1));
                   4413:                snprintf(m.usrbuf, sizeof(m.usrbuf),
                   4414:                    " usr=%d", track->usrbuf.capacity);
                   4415:
                   4416:                if (audio_track_is_playback(track)) {
                   4417:                        TRACET(0, track, "bufsize%s%s%s%s%s%s",
                   4418:                            m.outbuf, m.freq, m.chmix,
                   4419:                            m.chvol, m.codec, m.usrbuf);
                   4420:                } else {
                   4421:                        TRACET(0, track, "bufsize%s%s%s%s%s%s",
                   4422:                            m.freq, m.chmix, m.chvol,
                   4423:                            m.codec, m.outbuf, m.usrbuf);
                   4424:                }
                   4425:        }
                   4426: #endif
                   4427:        return 0;
                   4428:
                   4429: error:
                   4430:        audio_free_usrbuf(track);
                   4431:        audio_free(track->codec.srcbuf.mem);
                   4432:        audio_free(track->chvol.srcbuf.mem);
                   4433:        audio_free(track->chmix.srcbuf.mem);
                   4434:        audio_free(track->freq.srcbuf.mem);
                   4435:        audio_free(track->outbuf.mem);
                   4436:        return error;
                   4437: }
                   4438:
                   4439: /*
                   4440:  * Fill silence frames (as the internal format) up to 1 block
                   4441:  * if the ring is not empty and less than 1 block.
                   4442:  * It returns the number of appended frames.
                   4443:  */
                   4444: static int
                   4445: audio_append_silence(audio_track_t *track, audio_ring_t *ring)
                   4446: {
                   4447:        int fpb;
                   4448:        int n;
                   4449:
                   4450:        KASSERT(track);
                   4451:        KASSERT(audio_format2_is_internal(&ring->fmt));
                   4452:
                   4453:        /* XXX is n correct? */
                   4454:        /* XXX memset uses frametobyte()? */
                   4455:
                   4456:        if (ring->used == 0)
                   4457:                return 0;
                   4458:
                   4459:        fpb = frame_per_block(track->mixer, &ring->fmt);
                   4460:        if (ring->used >= fpb)
                   4461:                return 0;
                   4462:
                   4463:        n = (ring->capacity - ring->used) % fpb;
                   4464:
1.47      isaki    4465:        KASSERTMSG(auring_get_contig_free(ring) >= n,
                   4466:            "auring_get_contig_free(ring)=%d n=%d",
                   4467:            auring_get_contig_free(ring), n);
1.2       isaki    4468:
                   4469:        memset(auring_tailptr_aint(ring), 0,
                   4470:            n * ring->fmt.channels * sizeof(aint_t));
                   4471:        auring_push(ring, n);
                   4472:        return n;
                   4473: }
                   4474:
                   4475: /*
                   4476:  * Execute the conversion stage.
                   4477:  * It prepares arg from this stage and executes stage->filter.
                   4478:  * It must be called only if stage->filter is not NULL.
                   4479:  *
                   4480:  * For stages other than frequency conversion, the function increments
                   4481:  * src and dst counters here.  For frequency conversion stage, on the
                   4482:  * other hand, the function does not touch src and dst counters and
                   4483:  * filter side has to increment them.
                   4484:  */
                   4485: static void
                   4486: audio_apply_stage(audio_track_t *track, audio_stage_t *stage, bool isfreq)
                   4487: {
                   4488:        audio_filter_arg_t *arg;
                   4489:        int srccount;
                   4490:        int dstcount;
                   4491:        int count;
                   4492:
                   4493:        KASSERT(track);
                   4494:        KASSERT(stage->filter);
                   4495:
                   4496:        srccount = auring_get_contig_used(&stage->srcbuf);
                   4497:        dstcount = auring_get_contig_free(stage->dst);
                   4498:
                   4499:        if (isfreq) {
1.47      isaki    4500:                KASSERTMSG(srccount > 0, "freq but srccount=%d", srccount);
1.2       isaki    4501:                count = uimin(dstcount, track->mixer->frames_per_block);
                   4502:        } else {
                   4503:                count = uimin(srccount, dstcount);
                   4504:        }
                   4505:
                   4506:        if (count > 0) {
                   4507:                arg = &stage->arg;
                   4508:                arg->src = auring_headptr(&stage->srcbuf);
                   4509:                arg->dst = auring_tailptr(stage->dst);
                   4510:                arg->count = count;
                   4511:
                   4512:                stage->filter(arg);
                   4513:
                   4514:                if (!isfreq) {
                   4515:                        auring_take(&stage->srcbuf, count);
                   4516:                        auring_push(stage->dst, count);
                   4517:                }
                   4518:        }
                   4519: }
                   4520:
                   4521: /*
                   4522:  * Produce output buffer for playback from user input buffer.
                   4523:  * It must be called only if usrbuf is not empty and outbuf is
                   4524:  * available at least one free block.
                   4525:  */
                   4526: static void
                   4527: audio_track_play(audio_track_t *track)
                   4528: {
                   4529:        audio_ring_t *usrbuf;
                   4530:        audio_ring_t *input;
                   4531:        int count;
                   4532:        int framesize;
                   4533:        int bytes;
                   4534:
                   4535:        KASSERT(track);
                   4536:        KASSERT(track->lock);
                   4537:        TRACET(4, track, "start pstate=%d", track->pstate);
                   4538:
                   4539:        /* At this point usrbuf must not be empty. */
                   4540:        KASSERT(track->usrbuf.used > 0);
                   4541:        /* Also, outbuf must be available at least one block. */
                   4542:        count = auring_get_contig_free(&track->outbuf);
                   4543:        KASSERTMSG(count >= frame_per_block(track->mixer, &track->outbuf.fmt),
                   4544:            "count=%d fpb=%d",
                   4545:            count, frame_per_block(track->mixer, &track->outbuf.fmt));
                   4546:
                   4547:        /* XXX TODO: is this necessary for now? */
                   4548:        int track_count_0 = track->outbuf.used;
                   4549:
                   4550:        usrbuf = &track->usrbuf;
                   4551:        input = track->input;
                   4552:
                   4553:        /*
                   4554:         * framesize is always 1 byte or more since all formats supported as
                   4555:         * usrfmt(=input) have 8bit or more stride.
                   4556:         */
                   4557:        framesize = frametobyte(&input->fmt, 1);
                   4558:        KASSERT(framesize >= 1);
                   4559:
                   4560:        /* The next stage of usrbuf (=input) must be available. */
                   4561:        KASSERT(auring_get_contig_free(input) > 0);
                   4562:
                   4563:        /*
                   4564:         * Copy usrbuf up to 1block to input buffer.
                   4565:         * count is the number of frames to copy from usrbuf.
                   4566:         * bytes is the number of bytes to copy from usrbuf.  However it is
                   4567:         * not copied less than one frame.
                   4568:         */
                   4569:        count = uimin(usrbuf->used, track->usrbuf_blksize) / framesize;
                   4570:        bytes = count * framesize;
                   4571:
                   4572:        track->usrbuf_stamp += bytes;
                   4573:
                   4574:        if (usrbuf->head + bytes < usrbuf->capacity) {
                   4575:                memcpy((uint8_t *)input->mem + auring_tail(input) * framesize,
                   4576:                    (uint8_t *)usrbuf->mem + usrbuf->head,
                   4577:                    bytes);
                   4578:                auring_push(input, count);
                   4579:                auring_take(usrbuf, bytes);
                   4580:        } else {
                   4581:                int bytes1;
                   4582:                int bytes2;
                   4583:
                   4584:                bytes1 = auring_get_contig_used(usrbuf);
1.47      isaki    4585:                KASSERTMSG(bytes1 % framesize == 0,
                   4586:                    "bytes1=%d framesize=%d", bytes1, framesize);
1.2       isaki    4587:                memcpy((uint8_t *)input->mem + auring_tail(input) * framesize,
                   4588:                    (uint8_t *)usrbuf->mem + usrbuf->head,
                   4589:                    bytes1);
                   4590:                auring_push(input, bytes1 / framesize);
                   4591:                auring_take(usrbuf, bytes1);
                   4592:
                   4593:                bytes2 = bytes - bytes1;
                   4594:                memcpy((uint8_t *)input->mem + auring_tail(input) * framesize,
                   4595:                    (uint8_t *)usrbuf->mem + usrbuf->head,
                   4596:                    bytes2);
                   4597:                auring_push(input, bytes2 / framesize);
                   4598:                auring_take(usrbuf, bytes2);
                   4599:        }
                   4600:
                   4601:        /* Encoding conversion */
                   4602:        if (track->codec.filter)
                   4603:                audio_apply_stage(track, &track->codec, false);
                   4604:
                   4605:        /* Channel volume */
                   4606:        if (track->chvol.filter)
                   4607:                audio_apply_stage(track, &track->chvol, false);
                   4608:
                   4609:        /* Channel mix */
                   4610:        if (track->chmix.filter)
                   4611:                audio_apply_stage(track, &track->chmix, false);
                   4612:
                   4613:        /* Frequency conversion */
                   4614:        /*
                   4615:         * Since the frequency conversion needs correction for each block,
                   4616:         * it rounds up to 1 block.
                   4617:         */
                   4618:        if (track->freq.filter) {
                   4619:                int n;
                   4620:                n = audio_append_silence(track, &track->freq.srcbuf);
                   4621:                if (n > 0) {
                   4622:                        TRACET(4, track,
                   4623:                            "freq.srcbuf add silence %d -> %d/%d/%d",
                   4624:                            n,
                   4625:                            track->freq.srcbuf.head,
                   4626:                            track->freq.srcbuf.used,
                   4627:                            track->freq.srcbuf.capacity);
                   4628:                }
                   4629:                if (track->freq.srcbuf.used > 0) {
                   4630:                        audio_apply_stage(track, &track->freq, true);
                   4631:                }
                   4632:        }
                   4633:
1.18      isaki    4634:        if (bytes < track->usrbuf_blksize) {
1.2       isaki    4635:                /*
                   4636:                 * Clear all conversion buffer pointer if the conversion was
                   4637:                 * not exactly one block.  These conversion stage buffers are
                   4638:                 * certainly circular buffers because of symmetry with the
                   4639:                 * previous and next stage buffer.  However, since they are
                   4640:                 * treated as simple contiguous buffers in operation, so head
                   4641:                 * always should point 0.  This may happen during drain-age.
                   4642:                 */
                   4643:                TRACET(4, track, "reset stage");
                   4644:                if (track->codec.filter) {
                   4645:                        KASSERT(track->codec.srcbuf.used == 0);
                   4646:                        track->codec.srcbuf.head = 0;
                   4647:                }
                   4648:                if (track->chvol.filter) {
                   4649:                        KASSERT(track->chvol.srcbuf.used == 0);
                   4650:                        track->chvol.srcbuf.head = 0;
                   4651:                }
                   4652:                if (track->chmix.filter) {
                   4653:                        KASSERT(track->chmix.srcbuf.used == 0);
                   4654:                        track->chmix.srcbuf.head = 0;
                   4655:                }
                   4656:                if (track->freq.filter) {
                   4657:                        KASSERT(track->freq.srcbuf.used == 0);
                   4658:                        track->freq.srcbuf.head = 0;
                   4659:                }
                   4660:        }
                   4661:
                   4662:        if (track->input == &track->outbuf) {
                   4663:                track->outputcounter = track->inputcounter;
                   4664:        } else {
                   4665:                track->outputcounter += track->outbuf.used - track_count_0;
                   4666:        }
                   4667:
                   4668: #if defined(AUDIO_DEBUG)
                   4669:        if (audiodebug >= 3) {
                   4670:                struct audio_track_debugbuf m;
                   4671:                audio_track_bufstat(track, &m);
                   4672:                TRACET(0, track, "end%s%s%s%s%s%s",
                   4673:                    m.outbuf, m.freq, m.chvol, m.chmix, m.codec, m.usrbuf);
                   4674:        }
                   4675: #endif
                   4676: }
                   4677:
                   4678: /*
                   4679:  * Produce user output buffer for recording from input buffer.
                   4680:  */
                   4681: static void
                   4682: audio_track_record(audio_track_t *track)
                   4683: {
                   4684:        audio_ring_t *outbuf;
                   4685:        audio_ring_t *usrbuf;
                   4686:        int count;
                   4687:        int bytes;
                   4688:        int framesize;
                   4689:
                   4690:        KASSERT(track);
                   4691:        KASSERT(track->lock);
                   4692:
                   4693:        /* Number of frames to process */
                   4694:        count = auring_get_contig_used(track->input);
                   4695:        count = uimin(count, track->mixer->frames_per_block);
                   4696:        if (count == 0) {
                   4697:                TRACET(4, track, "count == 0");
                   4698:                return;
                   4699:        }
                   4700:
                   4701:        /* Frequency conversion */
                   4702:        if (track->freq.filter) {
                   4703:                if (track->freq.srcbuf.used > 0) {
                   4704:                        audio_apply_stage(track, &track->freq, true);
                   4705:                        /* XXX should input of freq be from beginning of buf? */
                   4706:                }
                   4707:        }
                   4708:
                   4709:        /* Channel mix */
                   4710:        if (track->chmix.filter)
                   4711:                audio_apply_stage(track, &track->chmix, false);
                   4712:
                   4713:        /* Channel volume */
                   4714:        if (track->chvol.filter)
                   4715:                audio_apply_stage(track, &track->chvol, false);
                   4716:
                   4717:        /* Encoding conversion */
                   4718:        if (track->codec.filter)
                   4719:                audio_apply_stage(track, &track->codec, false);
                   4720:
                   4721:        /* Copy outbuf to usrbuf */
                   4722:        outbuf = &track->outbuf;
                   4723:        usrbuf = &track->usrbuf;
                   4724:        /*
                   4725:         * framesize is always 1 byte or more since all formats supported
                   4726:         * as usrfmt(=output) have 8bit or more stride.
                   4727:         */
                   4728:        framesize = frametobyte(&outbuf->fmt, 1);
                   4729:        KASSERT(framesize >= 1);
                   4730:        /*
                   4731:         * count is the number of frames to copy to usrbuf.
                   4732:         * bytes is the number of bytes to copy to usrbuf.
                   4733:         */
                   4734:        count = outbuf->used;
                   4735:        count = uimin(count,
                   4736:            (track->usrbuf_usedhigh - usrbuf->used) / framesize);
                   4737:        bytes = count * framesize;
                   4738:        if (auring_tail(usrbuf) + bytes < usrbuf->capacity) {
                   4739:                memcpy((uint8_t *)usrbuf->mem + auring_tail(usrbuf),
                   4740:                    (uint8_t *)outbuf->mem + outbuf->head * framesize,
                   4741:                    bytes);
                   4742:                auring_push(usrbuf, bytes);
                   4743:                auring_take(outbuf, count);
                   4744:        } else {
                   4745:                int bytes1;
                   4746:                int bytes2;
                   4747:
1.33      isaki    4748:                bytes1 = auring_get_contig_free(usrbuf);
1.47      isaki    4749:                KASSERTMSG(bytes1 % framesize == 0,
                   4750:                    "bytes1=%d framesize=%d", bytes1, framesize);
1.2       isaki    4751:                memcpy((uint8_t *)usrbuf->mem + auring_tail(usrbuf),
                   4752:                    (uint8_t *)outbuf->mem + outbuf->head * framesize,
                   4753:                    bytes1);
                   4754:                auring_push(usrbuf, bytes1);
                   4755:                auring_take(outbuf, bytes1 / framesize);
                   4756:
                   4757:                bytes2 = bytes - bytes1;
                   4758:                memcpy((uint8_t *)usrbuf->mem + auring_tail(usrbuf),
                   4759:                    (uint8_t *)outbuf->mem + outbuf->head * framesize,
                   4760:                    bytes2);
                   4761:                auring_push(usrbuf, bytes2);
                   4762:                auring_take(outbuf, bytes2 / framesize);
                   4763:        }
                   4764:
                   4765:        /* XXX TODO: any counters here? */
                   4766:
                   4767: #if defined(AUDIO_DEBUG)
                   4768:        if (audiodebug >= 3) {
                   4769:                struct audio_track_debugbuf m;
                   4770:                audio_track_bufstat(track, &m);
                   4771:                TRACET(0, track, "end%s%s%s%s%s%s",
                   4772:                    m.freq, m.chvol, m.chmix, m.codec, m.outbuf, m.usrbuf);
                   4773:        }
                   4774: #endif
                   4775: }
                   4776:
                   4777: /*
1.79    ! isaki    4778:  * Calculate blktime [msec] from mixer(.hwbuf.fmt).
1.63      isaki    4779:  * Must be called with sc_exlock held.
1.2       isaki    4780:  */
                   4781: static u_int
                   4782: audio_mixer_calc_blktime(struct audio_softc *sc, audio_trackmixer_t *mixer)
                   4783: {
                   4784:        audio_format2_t *fmt;
                   4785:        u_int blktime;
                   4786:        u_int frames_per_block;
                   4787:
1.63      isaki    4788:        KASSERT(sc->sc_exlock);
1.2       isaki    4789:
                   4790:        fmt = &mixer->hwbuf.fmt;
                   4791:        blktime = sc->sc_blk_ms;
                   4792:
                   4793:        /*
                   4794:         * If stride is not multiples of 8, special treatment is necessary.
                   4795:         * For now, it is only x68k's vs(4), 4 bit/sample ADPCM.
                   4796:         */
                   4797:        if (fmt->stride == 4) {
                   4798:                frames_per_block = fmt->sample_rate * blktime / 1000;
                   4799:                if ((frames_per_block & 1) != 0)
                   4800:                        blktime *= 2;
                   4801:        }
                   4802: #ifdef DIAGNOSTIC
                   4803:        else if (fmt->stride % NBBY != 0) {
                   4804:                panic("unsupported HW stride %d", fmt->stride);
                   4805:        }
                   4806: #endif
                   4807:
                   4808:        return blktime;
                   4809: }
                   4810:
                   4811: /*
                   4812:  * Initialize the mixer corresponding to the mode.
                   4813:  * Set AUMODE_PLAY to the 'mode' for playback or AUMODE_RECORD for recording.
                   4814:  * sc->sc_[pr]mixer (corresponding to the 'mode') must be zero-filled.
1.36      msaitoh  4815:  * This function returns 0 on successful.  Otherwise returns errno.
1.63      isaki    4816:  * Must be called with sc_exlock held and without sc_lock held.
1.2       isaki    4817:  */
                   4818: static int
                   4819: audio_mixer_init(struct audio_softc *sc, int mode,
                   4820:        const audio_format2_t *hwfmt, const audio_filter_reg_t *reg)
                   4821: {
                   4822:        char codecbuf[64];
1.67      isaki    4823:        char blkdmsbuf[8];
1.2       isaki    4824:        audio_trackmixer_t *mixer;
                   4825:        void (*softint_handler)(void *);
                   4826:        int len;
                   4827:        int blksize;
                   4828:        int capacity;
                   4829:        size_t bufsize;
                   4830:        int hwblks;
                   4831:        int blkms;
1.67      isaki    4832:        int blkdms;
1.2       isaki    4833:        int error;
                   4834:
                   4835:        KASSERT(hwfmt != NULL);
                   4836:        KASSERT(reg != NULL);
1.63      isaki    4837:        KASSERT(sc->sc_exlock);
1.2       isaki    4838:
                   4839:        error = 0;
                   4840:        if (mode == AUMODE_PLAY)
                   4841:                mixer = sc->sc_pmixer;
                   4842:        else
                   4843:                mixer = sc->sc_rmixer;
                   4844:
                   4845:        mixer->sc = sc;
                   4846:        mixer->mode = mode;
                   4847:
                   4848:        mixer->hwbuf.fmt = *hwfmt;
                   4849:        mixer->volume = 256;
                   4850:        mixer->blktime_d = 1000;
                   4851:        mixer->blktime_n = audio_mixer_calc_blktime(sc, mixer);
                   4852:        sc->sc_blk_ms = mixer->blktime_n;
                   4853:        hwblks = NBLKHW;
                   4854:
                   4855:        mixer->frames_per_block = frame_per_block(mixer, &mixer->hwbuf.fmt);
                   4856:        blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block);
                   4857:        if (sc->hw_if->round_blocksize) {
                   4858:                int rounded;
                   4859:                audio_params_t p = format2_to_params(&mixer->hwbuf.fmt);
1.63      isaki    4860:                mutex_enter(sc->sc_lock);
1.2       isaki    4861:                rounded = sc->hw_if->round_blocksize(sc->hw_hdl, blksize,
                   4862:                    mode, &p);
1.63      isaki    4863:                mutex_exit(sc->sc_lock);
1.31      isaki    4864:                TRACE(1, "round_blocksize %d -> %d", blksize, rounded);
1.2       isaki    4865:                if (rounded != blksize) {
                   4866:                        if ((rounded * NBBY) % (mixer->hwbuf.fmt.stride *
                   4867:                            mixer->hwbuf.fmt.channels) != 0) {
                   4868:                                device_printf(sc->sc_dev,
1.61      isaki    4869:                                    "round_blocksize must return blocksize "
                   4870:                                    "divisible by framesize: "
                   4871:                                    "blksize=%d rounded=%d "
                   4872:                                    "stride=%ubit channels=%u\n",
                   4873:                                    blksize, rounded,
                   4874:                                    mixer->hwbuf.fmt.stride,
                   4875:                                    mixer->hwbuf.fmt.channels);
1.2       isaki    4876:                                return EINVAL;
                   4877:                        }
                   4878:                        /* Recalculation */
                   4879:                        blksize = rounded;
                   4880:                        mixer->frames_per_block = blksize * NBBY /
                   4881:                            (mixer->hwbuf.fmt.stride *
                   4882:                             mixer->hwbuf.fmt.channels);
                   4883:                }
                   4884:        }
                   4885:        mixer->blktime_n = mixer->frames_per_block;
                   4886:        mixer->blktime_d = mixer->hwbuf.fmt.sample_rate;
                   4887:
                   4888:        capacity = mixer->frames_per_block * hwblks;
                   4889:        bufsize = frametobyte(&mixer->hwbuf.fmt, capacity);
                   4890:        if (sc->hw_if->round_buffersize) {
                   4891:                size_t rounded;
1.63      isaki    4892:                mutex_enter(sc->sc_lock);
1.2       isaki    4893:                rounded = sc->hw_if->round_buffersize(sc->hw_hdl, mode,
                   4894:                    bufsize);
1.63      isaki    4895:                mutex_exit(sc->sc_lock);
1.31      isaki    4896:                TRACE(1, "round_buffersize %zd -> %zd", bufsize, rounded);
1.2       isaki    4897:                if (rounded < bufsize) {
                   4898:                        /* buffersize needs NBLKHW blocks at least. */
                   4899:                        device_printf(sc->sc_dev,
                   4900:                            "buffersize too small: buffersize=%zd blksize=%d\n",
                   4901:                            rounded, blksize);
                   4902:                        return EINVAL;
                   4903:                }
                   4904:                if (rounded % blksize != 0) {
                   4905:                        /* buffersize/blksize constraint mismatch? */
                   4906:                        device_printf(sc->sc_dev,
                   4907:                            "buffersize must be multiple of blksize: "
                   4908:                            "buffersize=%zu blksize=%d\n",
                   4909:                            rounded, blksize);
                   4910:                        return EINVAL;
                   4911:                }
                   4912:                if (rounded != bufsize) {
1.79    ! isaki    4913:                        /* Recalculation */
1.2       isaki    4914:                        bufsize = rounded;
                   4915:                        hwblks = bufsize / blksize;
                   4916:                        capacity = mixer->frames_per_block * hwblks;
                   4917:                }
                   4918:        }
1.31      isaki    4919:        TRACE(1, "buffersize for %s = %zu",
1.2       isaki    4920:            (mode == AUMODE_PLAY) ? "playback" : "recording",
                   4921:            bufsize);
                   4922:        mixer->hwbuf.capacity = capacity;
                   4923:
                   4924:        if (sc->hw_if->allocm) {
1.64      isaki    4925:                /* sc_lock is not necessary for allocm */
1.2       isaki    4926:                mixer->hwbuf.mem = sc->hw_if->allocm(sc->hw_hdl, mode, bufsize);
                   4927:                if (mixer->hwbuf.mem == NULL) {
                   4928:                        device_printf(sc->sc_dev, "%s: allocm(%zu) failed\n",
                   4929:                            __func__, bufsize);
                   4930:                        return ENOMEM;
                   4931:                }
                   4932:        } else {
1.28      isaki    4933:                mixer->hwbuf.mem = kmem_alloc(bufsize, KM_SLEEP);
1.2       isaki    4934:        }
                   4935:
                   4936:        /* From here, audio_mixer_destroy is necessary to exit. */
                   4937:        if (mode == AUMODE_PLAY) {
                   4938:                cv_init(&mixer->outcv, "audiowr");
                   4939:        } else {
                   4940:                cv_init(&mixer->outcv, "audiord");
                   4941:        }
                   4942:
                   4943:        if (mode == AUMODE_PLAY) {
                   4944:                softint_handler = audio_softintr_wr;
                   4945:        } else {
                   4946:                softint_handler = audio_softintr_rd;
                   4947:        }
                   4948:        mixer->sih = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE,
                   4949:            softint_handler, sc);
                   4950:        if (mixer->sih == NULL) {
                   4951:                device_printf(sc->sc_dev, "softint_establish failed\n");
                   4952:                goto abort;
                   4953:        }
                   4954:
                   4955:        mixer->track_fmt.encoding = AUDIO_ENCODING_SLINEAR_NE;
                   4956:        mixer->track_fmt.precision = AUDIO_INTERNAL_BITS;
                   4957:        mixer->track_fmt.stride = AUDIO_INTERNAL_BITS;
                   4958:        mixer->track_fmt.channels = mixer->hwbuf.fmt.channels;
                   4959:        mixer->track_fmt.sample_rate = mixer->hwbuf.fmt.sample_rate;
                   4960:
                   4961:        if (mixer->hwbuf.fmt.encoding == AUDIO_ENCODING_SLINEAR_OE &&
                   4962:            mixer->hwbuf.fmt.precision == AUDIO_INTERNAL_BITS) {
                   4963:                mixer->swap_endian = true;
                   4964:                TRACE(1, "swap_endian");
                   4965:        }
                   4966:
                   4967:        if (mode == AUMODE_PLAY) {
                   4968:                /* Mixing buffer */
                   4969:                mixer->mixfmt = mixer->track_fmt;
                   4970:                mixer->mixfmt.precision *= 2;
                   4971:                mixer->mixfmt.stride *= 2;
                   4972:                /* XXX TODO: use some macros? */
                   4973:                len = mixer->frames_per_block * mixer->mixfmt.channels *
                   4974:                    mixer->mixfmt.stride / NBBY;
                   4975:                mixer->mixsample = audio_realloc(mixer->mixsample, len);
                   4976:        } else {
                   4977:                /* No mixing buffer for recording */
                   4978:        }
                   4979:
                   4980:        if (reg->codec) {
                   4981:                mixer->codec = reg->codec;
                   4982:                mixer->codecarg.context = reg->context;
                   4983:                if (mode == AUMODE_PLAY) {
                   4984:                        mixer->codecarg.srcfmt = &mixer->track_fmt;
                   4985:                        mixer->codecarg.dstfmt = &mixer->hwbuf.fmt;
                   4986:                } else {
                   4987:                        mixer->codecarg.srcfmt = &mixer->hwbuf.fmt;
                   4988:                        mixer->codecarg.dstfmt = &mixer->track_fmt;
                   4989:                }
                   4990:                mixer->codecbuf.fmt = mixer->track_fmt;
                   4991:                mixer->codecbuf.capacity = mixer->frames_per_block;
                   4992:                len = auring_bytelen(&mixer->codecbuf);
                   4993:                mixer->codecbuf.mem = audio_realloc(mixer->codecbuf.mem, len);
                   4994:                if (mixer->codecbuf.mem == NULL) {
                   4995:                        device_printf(sc->sc_dev,
                   4996:                            "%s: malloc codecbuf(%d) failed\n",
                   4997:                            __func__, len);
                   4998:                        error = ENOMEM;
                   4999:                        goto abort;
                   5000:                }
                   5001:        }
                   5002:
                   5003:        /* Succeeded so display it. */
                   5004:        codecbuf[0] = '\0';
                   5005:        if (mixer->codec || mixer->swap_endian) {
                   5006:                snprintf(codecbuf, sizeof(codecbuf), " %s %s:%d",
                   5007:                    (mode == AUMODE_PLAY) ? "->" : "<-",
                   5008:                    audio_encoding_name(mixer->hwbuf.fmt.encoding),
                   5009:                    mixer->hwbuf.fmt.precision);
                   5010:        }
                   5011:        blkms = mixer->blktime_n * 1000 / mixer->blktime_d;
1.67      isaki    5012:        blkdms = (mixer->blktime_n * 10000 / mixer->blktime_d) % 10;
                   5013:        blkdmsbuf[0] = '\0';
                   5014:        if (blkdms != 0) {
                   5015:                snprintf(blkdmsbuf, sizeof(blkdmsbuf), ".%1d", blkdms);
                   5016:        }
                   5017:        aprint_normal_dev(sc->sc_dev,
                   5018:            "%s:%d%s %dch %dHz, blk %d bytes (%d%sms) for %s\n",
1.2       isaki    5019:            audio_encoding_name(mixer->track_fmt.encoding),
                   5020:            mixer->track_fmt.precision,
                   5021:            codecbuf,
                   5022:            mixer->track_fmt.channels,
                   5023:            mixer->track_fmt.sample_rate,
1.67      isaki    5024:            blksize,
                   5025:            blkms, blkdmsbuf,
1.2       isaki    5026:            (mode == AUMODE_PLAY) ? "playback" : "recording");
                   5027:
                   5028:        return 0;
                   5029:
                   5030: abort:
                   5031:        audio_mixer_destroy(sc, mixer);
                   5032:        return error;
                   5033: }
                   5034:
                   5035: /*
                   5036:  * Releases all resources of 'mixer'.
                   5037:  * Note that it does not release the memory area of 'mixer' itself.
1.63      isaki    5038:  * Must be called with sc_exlock held and without sc_lock held.
1.2       isaki    5039:  */
                   5040: static void
                   5041: audio_mixer_destroy(struct audio_softc *sc, audio_trackmixer_t *mixer)
                   5042: {
1.27      isaki    5043:        int bufsize;
1.2       isaki    5044:
1.63      isaki    5045:        KASSERT(sc->sc_exlock == 1);
1.2       isaki    5046:
1.27      isaki    5047:        bufsize = frametobyte(&mixer->hwbuf.fmt, mixer->hwbuf.capacity);
1.2       isaki    5048:
                   5049:        if (mixer->hwbuf.mem != NULL) {
                   5050:                if (sc->hw_if->freem) {
1.64      isaki    5051:                        /* sc_lock is not necessary for freem */
1.27      isaki    5052:                        sc->hw_if->freem(sc->hw_hdl, mixer->hwbuf.mem, bufsize);
1.2       isaki    5053:                } else {
1.28      isaki    5054:                        kmem_free(mixer->hwbuf.mem, bufsize);
1.2       isaki    5055:                }
                   5056:                mixer->hwbuf.mem = NULL;
                   5057:        }
                   5058:
                   5059:        audio_free(mixer->codecbuf.mem);
                   5060:        audio_free(mixer->mixsample);
                   5061:
                   5062:        cv_destroy(&mixer->outcv);
                   5063:
                   5064:        if (mixer->sih) {
                   5065:                softint_disestablish(mixer->sih);
                   5066:                mixer->sih = NULL;
                   5067:        }
                   5068: }
                   5069:
                   5070: /*
                   5071:  * Starts playback mixer.
                   5072:  * Must be called only if sc_pbusy is false.
1.50      isaki    5073:  * Must be called with sc_lock && sc_exlock held.
1.2       isaki    5074:  * Must not be called from the interrupt context.
                   5075:  */
                   5076: static void
                   5077: audio_pmixer_start(struct audio_softc *sc, bool force)
                   5078: {
                   5079:        audio_trackmixer_t *mixer;
                   5080:        int minimum;
                   5081:
                   5082:        KASSERT(mutex_owned(sc->sc_lock));
1.50      isaki    5083:        KASSERT(sc->sc_exlock);
1.2       isaki    5084:        KASSERT(sc->sc_pbusy == false);
                   5085:
                   5086:        mutex_enter(sc->sc_intr_lock);
                   5087:
                   5088:        mixer = sc->sc_pmixer;
                   5089:        TRACE(2, "%smixseq=%d hwseq=%d hwbuf=%d/%d/%d%s",
                   5090:            (audiodebug >= 3) ? "begin " : "",
                   5091:            (int)mixer->mixseq, (int)mixer->hwseq,
                   5092:            mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity,
                   5093:            force ? " force" : "");
                   5094:
                   5095:        /* Need two blocks to start normally. */
                   5096:        minimum = (force) ? 1 : 2;
                   5097:        while (mixer->hwbuf.used < mixer->frames_per_block * minimum) {
                   5098:                audio_pmixer_process(sc);
                   5099:        }
                   5100:
                   5101:        /* Start output */
                   5102:        audio_pmixer_output(sc);
                   5103:        sc->sc_pbusy = true;
                   5104:
                   5105:        TRACE(3, "end   mixseq=%d hwseq=%d hwbuf=%d/%d/%d",
                   5106:            (int)mixer->mixseq, (int)mixer->hwseq,
                   5107:            mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
                   5108:
                   5109:        mutex_exit(sc->sc_intr_lock);
                   5110: }
                   5111:
                   5112: /*
                   5113:  * When playing back with MD filter:
                   5114:  *
                   5115:  *           track track ...
                   5116:  *               v v
                   5117:  *                +  mix (with aint2_t)
                   5118:  *                |  master volume (with aint2_t)
                   5119:  *                v
                   5120:  *    mixsample [::::]                  wide-int 1 block (ring) buffer
                   5121:  *                |
                   5122:  *                |  convert aint2_t -> aint_t
                   5123:  *                v
                   5124:  *    codecbuf  [....]                  1 block (ring) buffer
                   5125:  *                |
                   5126:  *                |  convert to hw format
                   5127:  *                v
                   5128:  *    hwbuf     [............]          NBLKHW blocks ring buffer
                   5129:  *
                   5130:  * When playing back without MD filter:
                   5131:  *
                   5132:  *    mixsample [::::]                  wide-int 1 block (ring) buffer
                   5133:  *                |
                   5134:  *                |  convert aint2_t -> aint_t
                   5135:  *                |  (with byte swap if necessary)
                   5136:  *                v
                   5137:  *    hwbuf     [............]          NBLKHW blocks ring buffer
                   5138:  *
                   5139:  * mixsample: slinear_NE, wide internal precision, HW ch, HW freq.
                   5140:  * codecbuf:  slinear_NE, internal precision,      HW ch, HW freq.
                   5141:  * hwbuf:     HW encoding, HW precision,           HW ch, HW freq.
                   5142:  */
                   5143:
                   5144: /*
                   5145:  * Performs track mixing and converts it to hwbuf.
                   5146:  * Note that this function doesn't transfer hwbuf to hardware.
                   5147:  * Must be called with sc_intr_lock held.
                   5148:  */
                   5149: static void
                   5150: audio_pmixer_process(struct audio_softc *sc)
                   5151: {
                   5152:        audio_trackmixer_t *mixer;
                   5153:        audio_file_t *f;
                   5154:        int frame_count;
                   5155:        int sample_count;
                   5156:        int mixed;
                   5157:        int i;
                   5158:        aint2_t *m;
                   5159:        aint_t *h;
                   5160:
                   5161:        mixer = sc->sc_pmixer;
                   5162:
                   5163:        frame_count = mixer->frames_per_block;
1.47      isaki    5164:        KASSERTMSG(auring_get_contig_free(&mixer->hwbuf) >= frame_count,
                   5165:            "auring_get_contig_free()=%d frame_count=%d",
                   5166:            auring_get_contig_free(&mixer->hwbuf), frame_count);
1.2       isaki    5167:        sample_count = frame_count * mixer->mixfmt.channels;
                   5168:
                   5169:        mixer->mixseq++;
                   5170:
                   5171:        /* Mix all tracks */
                   5172:        mixed = 0;
                   5173:        SLIST_FOREACH(f, &sc->sc_files, entry) {
                   5174:                audio_track_t *track = f->ptrack;
                   5175:
                   5176:                if (track == NULL)
                   5177:                        continue;
                   5178:
                   5179:                if (track->is_pause) {
                   5180:                        TRACET(4, track, "skip; paused");
                   5181:                        continue;
                   5182:                }
                   5183:
                   5184:                /* Skip if the track is used by process context. */
                   5185:                if (audio_track_lock_tryenter(track) == false) {
                   5186:                        TRACET(4, track, "skip; in use");
                   5187:                        continue;
                   5188:                }
                   5189:
                   5190:                /* Emulate mmap'ped track */
                   5191:                if (track->mmapped) {
                   5192:                        auring_push(&track->usrbuf, track->usrbuf_blksize);
                   5193:                        TRACET(4, track, "mmap; usr=%d/%d/C%d",
                   5194:                            track->usrbuf.head,
                   5195:                            track->usrbuf.used,
                   5196:                            track->usrbuf.capacity);
                   5197:                }
                   5198:
                   5199:                if (track->outbuf.used < mixer->frames_per_block &&
                   5200:                    track->usrbuf.used > 0) {
                   5201:                        TRACET(4, track, "process");
                   5202:                        audio_track_play(track);
                   5203:                }
                   5204:
                   5205:                if (track->outbuf.used > 0) {
                   5206:                        mixed = audio_pmixer_mix_track(mixer, track, mixed);
                   5207:                } else {
                   5208:                        TRACET(4, track, "skip; empty");
                   5209:                }
                   5210:
                   5211:                audio_track_lock_exit(track);
                   5212:        }
                   5213:
                   5214:        if (mixed == 0) {
                   5215:                /* Silence */
                   5216:                memset(mixer->mixsample, 0,
                   5217:                    frametobyte(&mixer->mixfmt, frame_count));
                   5218:        } else {
1.23      isaki    5219:                if (mixed > 1) {
                   5220:                        /* If there are multiple tracks, do auto gain control */
                   5221:                        audio_pmixer_agc(mixer, sample_count);
1.2       isaki    5222:                }
                   5223:
1.23      isaki    5224:                /* Apply master volume */
                   5225:                if (mixer->volume < 256) {
1.2       isaki    5226:                        m = mixer->mixsample;
                   5227:                        for (i = 0; i < sample_count; i++) {
1.23      isaki    5228:                                *m = AUDIO_SCALEDOWN(*m * mixer->volume, 8);
1.2       isaki    5229:                                m++;
                   5230:                        }
1.23      isaki    5231:
                   5232:                        /*
                   5233:                         * Recover the volume gradually at the pace of
                   5234:                         * several times per second.  If it's too fast, you
                   5235:                         * can recognize that the volume changes up and down
                   5236:                         * quickly and it's not so comfortable.
                   5237:                         */
                   5238:                        mixer->voltimer += mixer->blktime_n;
                   5239:                        if (mixer->voltimer * 4 >= mixer->blktime_d) {
                   5240:                                mixer->volume++;
                   5241:                                mixer->voltimer = 0;
                   5242: #if defined(AUDIO_DEBUG_AGC)
                   5243:                                TRACE(1, "volume recover: %d", mixer->volume);
                   5244: #endif
                   5245:                        }
1.2       isaki    5246:                }
                   5247:        }
                   5248:
                   5249:        /*
                   5250:         * The rest is the hardware part.
                   5251:         */
                   5252:
                   5253:        if (mixer->codec) {
                   5254:                h = auring_tailptr_aint(&mixer->codecbuf);
                   5255:        } else {
                   5256:                h = auring_tailptr_aint(&mixer->hwbuf);
                   5257:        }
                   5258:
                   5259:        m = mixer->mixsample;
                   5260:        if (mixer->swap_endian) {
                   5261:                for (i = 0; i < sample_count; i++) {
                   5262:                        *h++ = bswap16(*m++);
                   5263:                }
                   5264:        } else {
                   5265:                for (i = 0; i < sample_count; i++) {
                   5266:                        *h++ = *m++;
                   5267:                }
                   5268:        }
                   5269:
                   5270:        /* Hardware driver's codec */
                   5271:        if (mixer->codec) {
                   5272:                auring_push(&mixer->codecbuf, frame_count);
                   5273:                mixer->codecarg.src = auring_headptr(&mixer->codecbuf);
                   5274:                mixer->codecarg.dst = auring_tailptr(&mixer->hwbuf);
                   5275:                mixer->codecarg.count = frame_count;
                   5276:                mixer->codec(&mixer->codecarg);
                   5277:                auring_take(&mixer->codecbuf, mixer->codecarg.count);
                   5278:        }
                   5279:
                   5280:        auring_push(&mixer->hwbuf, frame_count);
                   5281:
                   5282:        TRACE(4, "done mixseq=%d hwbuf=%d/%d/%d%s",
                   5283:            (int)mixer->mixseq,
                   5284:            mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity,
                   5285:            (mixed == 0) ? " silent" : "");
                   5286: }
                   5287:
                   5288: /*
1.23      isaki    5289:  * Do auto gain control.
                   5290:  * Must be called sc_intr_lock held.
                   5291:  */
                   5292: static void
                   5293: audio_pmixer_agc(audio_trackmixer_t *mixer, int sample_count)
                   5294: {
                   5295:        struct audio_softc *sc __unused;
                   5296:        aint2_t val;
                   5297:        aint2_t maxval;
                   5298:        aint2_t minval;
                   5299:        aint2_t over_plus;
                   5300:        aint2_t over_minus;
                   5301:        aint2_t *m;
                   5302:        int newvol;
                   5303:        int i;
                   5304:
                   5305:        sc = mixer->sc;
                   5306:
                   5307:        /* Overflow detection */
                   5308:        maxval = AINT_T_MAX;
                   5309:        minval = AINT_T_MIN;
                   5310:        m = mixer->mixsample;
                   5311:        for (i = 0; i < sample_count; i++) {
                   5312:                val = *m++;
                   5313:                if (val > maxval)
                   5314:                        maxval = val;
                   5315:                else if (val < minval)
                   5316:                        minval = val;
                   5317:        }
                   5318:
                   5319:        /* Absolute value of overflowed amount */
                   5320:        over_plus = maxval - AINT_T_MAX;
                   5321:        over_minus = AINT_T_MIN - minval;
                   5322:
                   5323:        if (over_plus > 0 || over_minus > 0) {
                   5324:                if (over_plus > over_minus) {
                   5325:                        newvol = (int)((aint2_t)AINT_T_MAX * 256 / maxval);
                   5326:                } else {
                   5327:                        newvol = (int)((aint2_t)AINT_T_MIN * 256 / minval);
                   5328:                }
                   5329:
                   5330:                /*
                   5331:                 * Change the volume only if new one is smaller.
                   5332:                 * Reset the timer even if the volume isn't changed.
                   5333:                 */
                   5334:                if (newvol <= mixer->volume) {
                   5335:                        mixer->volume = newvol;
                   5336:                        mixer->voltimer = 0;
                   5337: #if defined(AUDIO_DEBUG_AGC)
                   5338:                        TRACE(1, "auto volume adjust: %d", mixer->volume);
                   5339: #endif
                   5340:                }
                   5341:        }
                   5342: }
                   5343:
                   5344: /*
1.2       isaki    5345:  * Mix one track.
                   5346:  * 'mixed' specifies the number of tracks mixed so far.
                   5347:  * It returns the number of tracks mixed.  In other words, it returns
                   5348:  * mixed + 1 if this track is mixed.
                   5349:  */
                   5350: static int
                   5351: audio_pmixer_mix_track(audio_trackmixer_t *mixer, audio_track_t *track,
                   5352:        int mixed)
                   5353: {
                   5354:        int count;
                   5355:        int sample_count;
                   5356:        int remain;
                   5357:        int i;
                   5358:        const aint_t *s;
                   5359:        aint2_t *d;
                   5360:
                   5361:        /* XXX TODO: Is this necessary for now? */
                   5362:        if (mixer->mixseq < track->seq)
                   5363:                return mixed;
                   5364:
                   5365:        count = auring_get_contig_used(&track->outbuf);
                   5366:        count = uimin(count, mixer->frames_per_block);
                   5367:
                   5368:        s = auring_headptr_aint(&track->outbuf);
                   5369:        d = mixer->mixsample;
                   5370:
                   5371:        /*
                   5372:         * Apply track volume with double-sized integer and perform
                   5373:         * additive synthesis.
                   5374:         *
                   5375:         * XXX If you limit the track volume to 1.0 or less (<= 256),
                   5376:         *     it would be better to do this in the track conversion stage
                   5377:         *     rather than here.  However, if you accept the volume to
                   5378:         *     be greater than 1.0 (> 256), it's better to do it here.
                   5379:         *     Because the operation here is done by double-sized integer.
                   5380:         */
                   5381:        sample_count = count * mixer->mixfmt.channels;
                   5382:        if (mixed == 0) {
                   5383:                /* If this is the first track, assignment can be used. */
                   5384: #if defined(AUDIO_SUPPORT_TRACK_VOLUME)
                   5385:                if (track->volume != 256) {
                   5386:                        for (i = 0; i < sample_count; i++) {
1.16      isaki    5387:                                aint2_t v;
                   5388:                                v = *s++;
                   5389:                                *d++ = AUDIO_SCALEDOWN(v * track->volume, 8)
1.2       isaki    5390:                        }
                   5391:                } else
                   5392: #endif
                   5393:                {
                   5394:                        for (i = 0; i < sample_count; i++) {
                   5395:                                *d++ = ((aint2_t)*s++);
                   5396:                        }
                   5397:                }
1.17      isaki    5398:                /* Fill silence if the first track is not filled. */
                   5399:                for (; i < mixer->frames_per_block * mixer->mixfmt.channels; i++)
                   5400:                        *d++ = 0;
1.2       isaki    5401:        } else {
                   5402:                /* If this is the second or later, add it. */
                   5403: #if defined(AUDIO_SUPPORT_TRACK_VOLUME)
                   5404:                if (track->volume != 256) {
                   5405:                        for (i = 0; i < sample_count; i++) {
1.16      isaki    5406:                                aint2_t v;
                   5407:                                v = *s++;
                   5408:                                *d++ += AUDIO_SCALEDOWN(v * track->volume, 8);
1.2       isaki    5409:                        }
                   5410:                } else
                   5411: #endif
                   5412:                {
                   5413:                        for (i = 0; i < sample_count; i++) {
                   5414:                                *d++ += ((aint2_t)*s++);
                   5415:                        }
                   5416:                }
                   5417:        }
                   5418:
                   5419:        auring_take(&track->outbuf, count);
                   5420:        /*
                   5421:         * The counters have to align block even if outbuf is less than
                   5422:         * one block. XXX Is this still necessary?
                   5423:         */
                   5424:        remain = mixer->frames_per_block - count;
                   5425:        if (__predict_false(remain != 0)) {
                   5426:                auring_push(&track->outbuf, remain);
                   5427:                auring_take(&track->outbuf, remain);
                   5428:        }
                   5429:
                   5430:        /*
                   5431:         * Update track sequence.
                   5432:         * mixseq has previous value yet at this point.
                   5433:         */
                   5434:        track->seq = mixer->mixseq + 1;
                   5435:
                   5436:        return mixed + 1;
                   5437: }
                   5438:
                   5439: /*
                   5440:  * Output one block from hwbuf to HW.
                   5441:  * Must be called with sc_intr_lock held.
                   5442:  */
                   5443: static void
                   5444: audio_pmixer_output(struct audio_softc *sc)
                   5445: {
                   5446:        audio_trackmixer_t *mixer;
                   5447:        audio_params_t params;
                   5448:        void *start;
                   5449:        void *end;
                   5450:        int blksize;
                   5451:        int error;
                   5452:
                   5453:        mixer = sc->sc_pmixer;
                   5454:        TRACE(4, "pbusy=%d hwbuf=%d/%d/%d",
                   5455:            sc->sc_pbusy,
                   5456:            mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
1.47      isaki    5457:        KASSERTMSG(mixer->hwbuf.used >= mixer->frames_per_block,
                   5458:            "mixer->hwbuf.used=%d mixer->frames_per_block=%d",
                   5459:            mixer->hwbuf.used, mixer->frames_per_block);
1.2       isaki    5460:
                   5461:        blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block);
                   5462:
                   5463:        if (sc->hw_if->trigger_output) {
                   5464:                /* trigger (at once) */
                   5465:                if (!sc->sc_pbusy) {
                   5466:                        start = mixer->hwbuf.mem;
                   5467:                        end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf);
                   5468:                        params = format2_to_params(&mixer->hwbuf.fmt);
                   5469:
                   5470:                        error = sc->hw_if->trigger_output(sc->hw_hdl,
                   5471:                            start, end, blksize, audio_pintr, sc, &params);
                   5472:                        if (error) {
                   5473:                                device_printf(sc->sc_dev,
1.15      isaki    5474:                                    "trigger_output failed with %d\n", error);
1.2       isaki    5475:                                return;
                   5476:                        }
                   5477:                }
                   5478:        } else {
                   5479:                /* start (everytime) */
                   5480:                start = auring_headptr(&mixer->hwbuf);
                   5481:
                   5482:                error = sc->hw_if->start_output(sc->hw_hdl,
                   5483:                    start, blksize, audio_pintr, sc);
                   5484:                if (error) {
                   5485:                        device_printf(sc->sc_dev,
1.15      isaki    5486:                            "start_output failed with %d\n", error);
1.2       isaki    5487:                        return;
                   5488:                }
                   5489:        }
                   5490: }
                   5491:
                   5492: /*
                   5493:  * This is an interrupt handler for playback.
                   5494:  * It is called with sc_intr_lock held.
                   5495:  *
                   5496:  * It is usually called from hardware interrupt.  However, note that
                   5497:  * for some drivers (e.g. uaudio) it is called from software interrupt.
                   5498:  */
                   5499: static void
                   5500: audio_pintr(void *arg)
                   5501: {
                   5502:        struct audio_softc *sc;
                   5503:        audio_trackmixer_t *mixer;
                   5504:
                   5505:        sc = arg;
                   5506:        KASSERT(mutex_owned(sc->sc_intr_lock));
                   5507:
                   5508:        if (sc->sc_dying)
                   5509:                return;
1.49      isaki    5510:        if (sc->sc_pbusy == false) {
1.2       isaki    5511: #if defined(DIAGNOSTIC)
1.66      isaki    5512:                device_printf(sc->sc_dev,
                   5513:                    "DIAGNOSTIC: %s raised stray interrupt\n",
                   5514:                    device_xname(sc->hw_dev));
1.49      isaki    5515: #endif
1.2       isaki    5516:                return;
                   5517:        }
                   5518:
                   5519:        mixer = sc->sc_pmixer;
                   5520:        mixer->hw_complete_counter += mixer->frames_per_block;
                   5521:        mixer->hwseq++;
                   5522:
                   5523:        auring_take(&mixer->hwbuf, mixer->frames_per_block);
                   5524:
                   5525:        TRACE(4,
                   5526:            "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d",
                   5527:            mixer->hwseq, mixer->hw_complete_counter,
                   5528:            mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
                   5529:
                   5530: #if defined(AUDIO_HW_SINGLE_BUFFER)
                   5531:        /*
                   5532:         * Create a new block here and output it immediately.
                   5533:         * It makes a latency lower but needs machine power.
                   5534:         */
                   5535:        audio_pmixer_process(sc);
                   5536:        audio_pmixer_output(sc);
                   5537: #else
                   5538:        /*
                   5539:         * It is called when block N output is done.
                   5540:         * Output immediately block N+1 created by the last interrupt.
                   5541:         * And then create block N+2 for the next interrupt.
                   5542:         * This method makes playback robust even on slower machines.
                   5543:         * Instead the latency is increased by one block.
                   5544:         */
                   5545:
                   5546:        /* At first, output ready block. */
                   5547:        if (mixer->hwbuf.used >= mixer->frames_per_block) {
                   5548:                audio_pmixer_output(sc);
                   5549:        }
                   5550:
                   5551:        bool later = false;
                   5552:
                   5553:        if (mixer->hwbuf.used < mixer->frames_per_block) {
                   5554:                later = true;
                   5555:        }
                   5556:
                   5557:        /* Then, process next block. */
                   5558:        audio_pmixer_process(sc);
                   5559:
                   5560:        if (later) {
                   5561:                audio_pmixer_output(sc);
                   5562:        }
                   5563: #endif
                   5564:
                   5565:        /*
                   5566:         * When this interrupt is the real hardware interrupt, disabling
                   5567:         * preemption here is not necessary.  But some drivers (e.g. uaudio)
                   5568:         * emulate it by software interrupt, so kpreempt_disable is necessary.
                   5569:         */
                   5570:        kpreempt_disable();
                   5571:        softint_schedule(mixer->sih);
                   5572:        kpreempt_enable();
                   5573: }
                   5574:
                   5575: /*
                   5576:  * Starts record mixer.
                   5577:  * Must be called only if sc_rbusy is false.
1.50      isaki    5578:  * Must be called with sc_lock && sc_exlock held.
1.2       isaki    5579:  * Must not be called from the interrupt context.
                   5580:  */
                   5581: static void
                   5582: audio_rmixer_start(struct audio_softc *sc)
                   5583: {
                   5584:
                   5585:        KASSERT(mutex_owned(sc->sc_lock));
1.50      isaki    5586:        KASSERT(sc->sc_exlock);
1.2       isaki    5587:        KASSERT(sc->sc_rbusy == false);
                   5588:
                   5589:        mutex_enter(sc->sc_intr_lock);
                   5590:
                   5591:        TRACE(2, "%s", (audiodebug >= 3) ? "begin" : "");
                   5592:        audio_rmixer_input(sc);
                   5593:        sc->sc_rbusy = true;
                   5594:        TRACE(3, "end");
                   5595:
                   5596:        mutex_exit(sc->sc_intr_lock);
                   5597: }
                   5598:
                   5599: /*
                   5600:  * When recording with MD filter:
                   5601:  *
                   5602:  *    hwbuf     [............]          NBLKHW blocks ring buffer
                   5603:  *                |
                   5604:  *                | convert from hw format
                   5605:  *                v
                   5606:  *    codecbuf  [....]                  1 block (ring) buffer
                   5607:  *               |  |
                   5608:  *               v  v
                   5609:  *            track track ...
                   5610:  *
                   5611:  * When recording without MD filter:
                   5612:  *
                   5613:  *    hwbuf     [............]          NBLKHW blocks ring buffer
                   5614:  *               |  |
                   5615:  *               v  v
                   5616:  *            track track ...
                   5617:  *
                   5618:  * hwbuf:     HW encoding, HW precision, HW ch, HW freq.
                   5619:  * codecbuf:  slinear_NE, internal precision, HW ch, HW freq.
                   5620:  */
                   5621:
                   5622: /*
                   5623:  * Distribute a recorded block to all recording tracks.
                   5624:  */
                   5625: static void
                   5626: audio_rmixer_process(struct audio_softc *sc)
                   5627: {
                   5628:        audio_trackmixer_t *mixer;
                   5629:        audio_ring_t *mixersrc;
                   5630:        audio_file_t *f;
                   5631:        aint_t *p;
                   5632:        int count;
                   5633:        int bytes;
                   5634:        int i;
                   5635:
                   5636:        mixer = sc->sc_rmixer;
                   5637:
                   5638:        /*
                   5639:         * count is the number of frames to be retrieved this time.
                   5640:         * count should be one block.
                   5641:         */
                   5642:        count = auring_get_contig_used(&mixer->hwbuf);
                   5643:        count = uimin(count, mixer->frames_per_block);
                   5644:        if (count <= 0) {
                   5645:                TRACE(4, "count %d: too short", count);
                   5646:                return;
                   5647:        }
                   5648:        bytes = frametobyte(&mixer->track_fmt, count);
                   5649:
                   5650:        /* Hardware driver's codec */
                   5651:        if (mixer->codec) {
                   5652:                mixer->codecarg.src = auring_headptr(&mixer->hwbuf);
                   5653:                mixer->codecarg.dst = auring_tailptr(&mixer->codecbuf);
                   5654:                mixer->codecarg.count = count;
                   5655:                mixer->codec(&mixer->codecarg);
                   5656:                auring_take(&mixer->hwbuf, mixer->codecarg.count);
                   5657:                auring_push(&mixer->codecbuf, mixer->codecarg.count);
                   5658:                mixersrc = &mixer->codecbuf;
                   5659:        } else {
                   5660:                mixersrc = &mixer->hwbuf;
                   5661:        }
                   5662:
                   5663:        if (mixer->swap_endian) {
                   5664:                /* inplace conversion */
                   5665:                p = auring_headptr_aint(mixersrc);
                   5666:                for (i = 0; i < count * mixer->track_fmt.channels; i++, p++) {
                   5667:                        *p = bswap16(*p);
                   5668:                }
                   5669:        }
                   5670:
                   5671:        /* Distribute to all tracks. */
                   5672:        SLIST_FOREACH(f, &sc->sc_files, entry) {
                   5673:                audio_track_t *track = f->rtrack;
                   5674:                audio_ring_t *input;
                   5675:
                   5676:                if (track == NULL)
                   5677:                        continue;
                   5678:
                   5679:                if (track->is_pause) {
                   5680:                        TRACET(4, track, "skip; paused");
                   5681:                        continue;
                   5682:                }
                   5683:
                   5684:                if (audio_track_lock_tryenter(track) == false) {
                   5685:                        TRACET(4, track, "skip; in use");
                   5686:                        continue;
                   5687:                }
                   5688:
                   5689:                /* If the track buffer is full, discard the oldest one? */
                   5690:                input = track->input;
                   5691:                if (input->capacity - input->used < mixer->frames_per_block) {
                   5692:                        int drops = mixer->frames_per_block -
                   5693:                            (input->capacity - input->used);
                   5694:                        track->dropframes += drops;
                   5695:                        TRACET(4, track, "drop %d frames: inp=%d/%d/%d",
                   5696:                            drops,
                   5697:                            input->head, input->used, input->capacity);
                   5698:                        auring_take(input, drops);
                   5699:                }
1.47      isaki    5700:                KASSERTMSG(input->used % mixer->frames_per_block == 0,
                   5701:                    "input->used=%d mixer->frames_per_block=%d",
                   5702:                    input->used, mixer->frames_per_block);
1.2       isaki    5703:
                   5704:                memcpy(auring_tailptr_aint(input),
                   5705:                    auring_headptr_aint(mixersrc),
                   5706:                    bytes);
                   5707:                auring_push(input, count);
                   5708:
                   5709:                /* XXX sequence counter? */
                   5710:
                   5711:                audio_track_lock_exit(track);
                   5712:        }
                   5713:
                   5714:        auring_take(mixersrc, count);
                   5715: }
                   5716:
                   5717: /*
                   5718:  * Input one block from HW to hwbuf.
                   5719:  * Must be called with sc_intr_lock held.
                   5720:  */
                   5721: static void
                   5722: audio_rmixer_input(struct audio_softc *sc)
                   5723: {
                   5724:        audio_trackmixer_t *mixer;
                   5725:        audio_params_t params;
                   5726:        void *start;
                   5727:        void *end;
                   5728:        int blksize;
                   5729:        int error;
                   5730:
                   5731:        mixer = sc->sc_rmixer;
                   5732:        blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block);
                   5733:
                   5734:        if (sc->hw_if->trigger_input) {
                   5735:                /* trigger (at once) */
                   5736:                if (!sc->sc_rbusy) {
                   5737:                        start = mixer->hwbuf.mem;
                   5738:                        end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf);
                   5739:                        params = format2_to_params(&mixer->hwbuf.fmt);
                   5740:
                   5741:                        error = sc->hw_if->trigger_input(sc->hw_hdl,
                   5742:                            start, end, blksize, audio_rintr, sc, &params);
                   5743:                        if (error) {
                   5744:                                device_printf(sc->sc_dev,
1.15      isaki    5745:                                    "trigger_input failed with %d\n", error);
1.2       isaki    5746:                                return;
                   5747:                        }
                   5748:                }
                   5749:        } else {
                   5750:                /* start (everytime) */
                   5751:                start = auring_tailptr(&mixer->hwbuf);
                   5752:
                   5753:                error = sc->hw_if->start_input(sc->hw_hdl,
                   5754:                    start, blksize, audio_rintr, sc);
                   5755:                if (error) {
                   5756:                        device_printf(sc->sc_dev,
1.15      isaki    5757:                            "start_input failed with %d\n", error);
1.2       isaki    5758:                        return;
                   5759:                }
                   5760:        }
                   5761: }
                   5762:
                   5763: /*
                   5764:  * This is an interrupt handler for recording.
                   5765:  * It is called with sc_intr_lock.
                   5766:  *
                   5767:  * It is usually called from hardware interrupt.  However, note that
                   5768:  * for some drivers (e.g. uaudio) it is called from software interrupt.
                   5769:  */
                   5770: static void
                   5771: audio_rintr(void *arg)
                   5772: {
                   5773:        struct audio_softc *sc;
                   5774:        audio_trackmixer_t *mixer;
                   5775:
                   5776:        sc = arg;
                   5777:        KASSERT(mutex_owned(sc->sc_intr_lock));
                   5778:
                   5779:        if (sc->sc_dying)
                   5780:                return;
1.49      isaki    5781:        if (sc->sc_rbusy == false) {
1.2       isaki    5782: #if defined(DIAGNOSTIC)
1.66      isaki    5783:                device_printf(sc->sc_dev,
                   5784:                    "DIAGNOSTIC: %s raised stray interrupt\n",
                   5785:                    device_xname(sc->hw_dev));
1.49      isaki    5786: #endif
1.2       isaki    5787:                return;
                   5788:        }
                   5789:
                   5790:        mixer = sc->sc_rmixer;
                   5791:        mixer->hw_complete_counter += mixer->frames_per_block;
                   5792:        mixer->hwseq++;
                   5793:
                   5794:        auring_push(&mixer->hwbuf, mixer->frames_per_block);
                   5795:
                   5796:        TRACE(4,
                   5797:            "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d",
                   5798:            mixer->hwseq, mixer->hw_complete_counter,
                   5799:            mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
                   5800:
                   5801:        /* Distrubute recorded block */
                   5802:        audio_rmixer_process(sc);
                   5803:
                   5804:        /* Request next block */
                   5805:        audio_rmixer_input(sc);
                   5806:
                   5807:        /*
                   5808:         * When this interrupt is the real hardware interrupt, disabling
                   5809:         * preemption here is not necessary.  But some drivers (e.g. uaudio)
                   5810:         * emulate it by software interrupt, so kpreempt_disable is necessary.
                   5811:         */
                   5812:        kpreempt_disable();
                   5813:        softint_schedule(mixer->sih);
                   5814:        kpreempt_enable();
                   5815: }
                   5816:
                   5817: /*
                   5818:  * Halts playback mixer.
                   5819:  * This function also clears related parameters, so call this function
                   5820:  * instead of calling halt_output directly.
                   5821:  * Must be called only if sc_pbusy is true.
                   5822:  * Must be called with sc_lock && sc_exlock held.
                   5823:  */
                   5824: static int
                   5825: audio_pmixer_halt(struct audio_softc *sc)
                   5826: {
                   5827:        int error;
                   5828:
                   5829:        TRACE(2, "");
                   5830:        KASSERT(mutex_owned(sc->sc_lock));
                   5831:        KASSERT(sc->sc_exlock);
                   5832:
                   5833:        mutex_enter(sc->sc_intr_lock);
                   5834:        error = sc->hw_if->halt_output(sc->hw_hdl);
                   5835:
                   5836:        /* Halts anyway even if some error has occurred. */
                   5837:        sc->sc_pbusy = false;
                   5838:        sc->sc_pmixer->hwbuf.head = 0;
                   5839:        sc->sc_pmixer->hwbuf.used = 0;
                   5840:        sc->sc_pmixer->mixseq = 0;
                   5841:        sc->sc_pmixer->hwseq = 0;
1.51      isaki    5842:        mutex_exit(sc->sc_intr_lock);
1.2       isaki    5843:
                   5844:        return error;
                   5845: }
                   5846:
                   5847: /*
                   5848:  * Halts recording mixer.
                   5849:  * This function also clears related parameters, so call this function
                   5850:  * instead of calling halt_input directly.
                   5851:  * Must be called only if sc_rbusy is true.
                   5852:  * Must be called with sc_lock && sc_exlock held.
                   5853:  */
                   5854: static int
                   5855: audio_rmixer_halt(struct audio_softc *sc)
                   5856: {
                   5857:        int error;
                   5858:
                   5859:        TRACE(2, "");
                   5860:        KASSERT(mutex_owned(sc->sc_lock));
                   5861:        KASSERT(sc->sc_exlock);
                   5862:
                   5863:        mutex_enter(sc->sc_intr_lock);
                   5864:        error = sc->hw_if->halt_input(sc->hw_hdl);
                   5865:
                   5866:        /* Halts anyway even if some error has occurred. */
                   5867:        sc->sc_rbusy = false;
                   5868:        sc->sc_rmixer->hwbuf.head = 0;
                   5869:        sc->sc_rmixer->hwbuf.used = 0;
                   5870:        sc->sc_rmixer->mixseq = 0;
                   5871:        sc->sc_rmixer->hwseq = 0;
1.51      isaki    5872:        mutex_exit(sc->sc_intr_lock);
1.2       isaki    5873:
                   5874:        return error;
                   5875: }
                   5876:
                   5877: /*
                   5878:  * Flush this track.
                   5879:  * Halts all operations, clears all buffers, reset error counters.
                   5880:  * XXX I'm not sure...
                   5881:  */
                   5882: static void
                   5883: audio_track_clear(struct audio_softc *sc, audio_track_t *track)
                   5884: {
                   5885:
                   5886:        KASSERT(track);
                   5887:        TRACET(3, track, "clear");
                   5888:
                   5889:        audio_track_lock_enter(track);
                   5890:
                   5891:        track->usrbuf.used = 0;
                   5892:        /* Clear all internal parameters. */
                   5893:        if (track->codec.filter) {
                   5894:                track->codec.srcbuf.used = 0;
                   5895:                track->codec.srcbuf.head = 0;
                   5896:        }
                   5897:        if (track->chvol.filter) {
                   5898:                track->chvol.srcbuf.used = 0;
                   5899:                track->chvol.srcbuf.head = 0;
                   5900:        }
                   5901:        if (track->chmix.filter) {
                   5902:                track->chmix.srcbuf.used = 0;
                   5903:                track->chmix.srcbuf.head = 0;
                   5904:        }
                   5905:        if (track->freq.filter) {
                   5906:                track->freq.srcbuf.used = 0;
                   5907:                track->freq.srcbuf.head = 0;
                   5908:                if (track->freq_step < 65536)
                   5909:                        track->freq_current = 65536;
                   5910:                else
                   5911:                        track->freq_current = 0;
                   5912:                memset(track->freq_prev, 0, sizeof(track->freq_prev));
                   5913:                memset(track->freq_curr, 0, sizeof(track->freq_curr));
                   5914:        }
                   5915:        /* Clear buffer, then operation halts naturally. */
                   5916:        track->outbuf.used = 0;
                   5917:
                   5918:        /* Clear counters. */
                   5919:        track->dropframes = 0;
                   5920:
                   5921:        audio_track_lock_exit(track);
                   5922: }
                   5923:
                   5924: /*
                   5925:  * Drain the track.
                   5926:  * track must be present and for playback.
                   5927:  * If successful, it returns 0.  Otherwise returns errno.
                   5928:  * Must be called with sc_lock held.
                   5929:  */
                   5930: static int
                   5931: audio_track_drain(struct audio_softc *sc, audio_track_t *track)
                   5932: {
                   5933:        audio_trackmixer_t *mixer;
                   5934:        int done;
                   5935:        int error;
                   5936:
                   5937:        KASSERT(track);
                   5938:        TRACET(3, track, "start");
                   5939:        mixer = track->mixer;
                   5940:        KASSERT(mutex_owned(sc->sc_lock));
                   5941:
                   5942:        /* Ignore them if pause. */
                   5943:        if (track->is_pause) {
                   5944:                TRACET(3, track, "pause -> clear");
                   5945:                track->pstate = AUDIO_STATE_CLEAR;
                   5946:        }
                   5947:        /* Terminate early here if there is no data in the track. */
                   5948:        if (track->pstate == AUDIO_STATE_CLEAR) {
                   5949:                TRACET(3, track, "no need to drain");
                   5950:                return 0;
                   5951:        }
                   5952:        track->pstate = AUDIO_STATE_DRAINING;
                   5953:
                   5954:        for (;;) {
1.10      isaki    5955:                /* I want to display it before condition evaluation. */
1.2       isaki    5956:                TRACET(3, track, "pid=%d.%d trkseq=%d hwseq=%d out=%d/%d/%d",
                   5957:                    (int)curproc->p_pid, (int)curlwp->l_lid,
                   5958:                    (int)track->seq, (int)mixer->hwseq,
                   5959:                    track->outbuf.head, track->outbuf.used,
                   5960:                    track->outbuf.capacity);
                   5961:
                   5962:                /* Condition to terminate */
                   5963:                audio_track_lock_enter(track);
                   5964:                done = (track->usrbuf.used < frametobyte(&track->inputfmt, 1) &&
                   5965:                    track->outbuf.used == 0 &&
                   5966:                    track->seq <= mixer->hwseq);
                   5967:                audio_track_lock_exit(track);
                   5968:                if (done)
                   5969:                        break;
                   5970:
                   5971:                TRACET(3, track, "sleep");
                   5972:                error = audio_track_waitio(sc, track);
                   5973:                if (error)
                   5974:                        return error;
                   5975:
                   5976:                /* XXX call audio_track_play here ? */
                   5977:        }
                   5978:
                   5979:        track->pstate = AUDIO_STATE_CLEAR;
                   5980:        TRACET(3, track, "done trk_inp=%d trk_out=%d",
                   5981:                (int)track->inputcounter, (int)track->outputcounter);
                   5982:        return 0;
                   5983: }
                   5984:
                   5985: /*
1.30      isaki    5986:  * Send signal to process.
                   5987:  * This is intended to be called only from audio_softintr_{rd,wr}.
1.63      isaki    5988:  * Must be called without sc_intr_lock held.
1.30      isaki    5989:  */
                   5990: static inline void
                   5991: audio_psignal(struct audio_softc *sc, pid_t pid, int signum)
                   5992: {
                   5993:        proc_t *p;
                   5994:
                   5995:        KASSERT(pid != 0);
                   5996:
                   5997:        /*
                   5998:         * psignal() must be called without spin lock held.
                   5999:         */
                   6000:
1.70      ad       6001:        mutex_enter(&proc_lock);
1.30      isaki    6002:        p = proc_find(pid);
                   6003:        if (p)
                   6004:                psignal(p, signum);
1.70      ad       6005:        mutex_exit(&proc_lock);
1.30      isaki    6006: }
                   6007:
                   6008: /*
1.2       isaki    6009:  * This is software interrupt handler for record.
                   6010:  * It is called from recording hardware interrupt everytime.
                   6011:  * It does:
                   6012:  * - Deliver SIGIO for all async processes.
                   6013:  * - Notify to audio_read() that data has arrived.
                   6014:  * - selnotify() for select/poll-ing processes.
                   6015:  */
                   6016: /*
                   6017:  * XXX If a process issues FIOASYNC between hardware interrupt and
                   6018:  *     software interrupt, (stray) SIGIO will be sent to the process
                   6019:  *     despite the fact that it has not receive recorded data yet.
                   6020:  */
                   6021: static void
                   6022: audio_softintr_rd(void *cookie)
                   6023: {
                   6024:        struct audio_softc *sc = cookie;
                   6025:        audio_file_t *f;
                   6026:        pid_t pid;
                   6027:
                   6028:        mutex_enter(sc->sc_lock);
                   6029:
                   6030:        SLIST_FOREACH(f, &sc->sc_files, entry) {
                   6031:                audio_track_t *track = f->rtrack;
                   6032:
                   6033:                if (track == NULL)
                   6034:                        continue;
                   6035:
                   6036:                TRACET(4, track, "broadcast; inp=%d/%d/%d",
                   6037:                    track->input->head,
                   6038:                    track->input->used,
                   6039:                    track->input->capacity);
                   6040:
                   6041:                pid = f->async_audio;
                   6042:                if (pid != 0) {
                   6043:                        TRACEF(4, f, "sending SIGIO %d", pid);
1.30      isaki    6044:                        audio_psignal(sc, pid, SIGIO);
1.2       isaki    6045:                }
                   6046:        }
                   6047:
                   6048:        /* Notify that data has arrived. */
                   6049:        selnotify(&sc->sc_rsel, 0, NOTE_SUBMIT);
                   6050:        KNOTE(&sc->sc_rsel.sel_klist, 0);
                   6051:        cv_broadcast(&sc->sc_rmixer->outcv);
                   6052:
                   6053:        mutex_exit(sc->sc_lock);
                   6054: }
                   6055:
                   6056: /*
                   6057:  * This is software interrupt handler for playback.
                   6058:  * It is called from playback hardware interrupt everytime.
                   6059:  * It does:
                   6060:  * - Deliver SIGIO for all async and writable (used < lowat) processes.
                   6061:  * - Notify to audio_write() that outbuf block available.
                   6062:  * - selnotify() for select/poll-ing processes if there are any writable
                   6063:  *   (used < lowat) processes.  Checking each descriptor will be done by
                   6064:  *   filt_audiowrite_event().
                   6065:  */
                   6066: static void
                   6067: audio_softintr_wr(void *cookie)
                   6068: {
                   6069:        struct audio_softc *sc = cookie;
                   6070:        audio_file_t *f;
                   6071:        bool found;
                   6072:        pid_t pid;
                   6073:
                   6074:        TRACE(4, "called");
                   6075:        found = false;
                   6076:
                   6077:        mutex_enter(sc->sc_lock);
                   6078:
                   6079:        SLIST_FOREACH(f, &sc->sc_files, entry) {
                   6080:                audio_track_t *track = f->ptrack;
                   6081:
                   6082:                if (track == NULL)
                   6083:                        continue;
                   6084:
1.78      isaki    6085:                TRACET(4, track, "broadcast; trkseq=%d out=%d/%d/%d",
1.2       isaki    6086:                    (int)track->seq,
                   6087:                    track->outbuf.head,
                   6088:                    track->outbuf.used,
                   6089:                    track->outbuf.capacity);
                   6090:
                   6091:                /*
                   6092:                 * Send a signal if the process is async mode and
                   6093:                 * used is lower than lowat.
                   6094:                 */
                   6095:                if (track->usrbuf.used <= track->usrbuf_usedlow &&
                   6096:                    !track->is_pause) {
1.30      isaki    6097:                        /* For selnotify */
1.2       isaki    6098:                        found = true;
1.30      isaki    6099:                        /* For SIGIO */
1.2       isaki    6100:                        pid = f->async_audio;
                   6101:                        if (pid != 0) {
                   6102:                                TRACEF(4, f, "sending SIGIO %d", pid);
1.30      isaki    6103:                                audio_psignal(sc, pid, SIGIO);
1.2       isaki    6104:                        }
                   6105:                }
                   6106:        }
                   6107:
                   6108:        /*
                   6109:         * Notify for select/poll when someone become writable.
                   6110:         * It needs sc_lock (and not sc_intr_lock).
                   6111:         */
                   6112:        if (found) {
                   6113:                TRACE(4, "selnotify");
                   6114:                selnotify(&sc->sc_wsel, 0, NOTE_SUBMIT);
                   6115:                KNOTE(&sc->sc_wsel.sel_klist, 0);
                   6116:        }
                   6117:
                   6118:        /* Notify to audio_write() that outbuf available. */
                   6119:        cv_broadcast(&sc->sc_pmixer->outcv);
                   6120:
                   6121:        mutex_exit(sc->sc_lock);
                   6122: }
                   6123:
                   6124: /*
                   6125:  * Check (and convert) the format *p came from userland.
                   6126:  * If successful, it writes back the converted format to *p if necessary
                   6127:  * and returns 0.  Otherwise returns errno (*p may change even this case).
                   6128:  */
                   6129: static int
                   6130: audio_check_params(audio_format2_t *p)
                   6131: {
                   6132:
1.72      nia      6133:        /*
                   6134:         * Convert obsolete AUDIO_ENCODING_PCM encodings.
1.76      isaki    6135:         *
1.72      nia      6136:         * AUDIO_ENCODING_PCM16 == AUDIO_ENCODING_LINEAR
                   6137:         * So, it's always signed, as in SunOS.
                   6138:         *
                   6139:         * AUDIO_ENCODING_PCM8 == AUDIO_ENCODING_LINEAR8
                   6140:         * So, it's always unsigned, as in SunOS.
                   6141:         */
1.2       isaki    6142:        if (p->encoding == AUDIO_ENCODING_PCM16) {
1.72      nia      6143:                p->encoding = AUDIO_ENCODING_SLINEAR;
1.2       isaki    6144:        } else if (p->encoding == AUDIO_ENCODING_PCM8) {
                   6145:                if (p->precision == 8)
                   6146:                        p->encoding = AUDIO_ENCODING_ULINEAR;
                   6147:                else
                   6148:                        return EINVAL;
                   6149:        }
                   6150:
                   6151:        /*
                   6152:         * Convert obsoleted AUDIO_ENCODING_[SU]LINEAR without endianness
                   6153:         * suffix.
                   6154:         */
                   6155:        if (p->encoding == AUDIO_ENCODING_SLINEAR)
                   6156:                p->encoding = AUDIO_ENCODING_SLINEAR_NE;
                   6157:        if (p->encoding == AUDIO_ENCODING_ULINEAR)
                   6158:                p->encoding = AUDIO_ENCODING_ULINEAR_NE;
                   6159:
                   6160:        switch (p->encoding) {
                   6161:        case AUDIO_ENCODING_ULAW:
                   6162:        case AUDIO_ENCODING_ALAW:
                   6163:                if (p->precision != 8)
                   6164:                        return EINVAL;
                   6165:                break;
                   6166:        case AUDIO_ENCODING_ADPCM:
                   6167:                if (p->precision != 4 && p->precision != 8)
                   6168:                        return EINVAL;
                   6169:                break;
                   6170:        case AUDIO_ENCODING_SLINEAR_LE:
                   6171:        case AUDIO_ENCODING_SLINEAR_BE:
                   6172:        case AUDIO_ENCODING_ULINEAR_LE:
                   6173:        case AUDIO_ENCODING_ULINEAR_BE:
                   6174:                if (p->precision !=  8 && p->precision != 16 &&
                   6175:                    p->precision != 24 && p->precision != 32)
                   6176:                        return EINVAL;
                   6177:
                   6178:                /* 8bit format does not have endianness. */
                   6179:                if (p->precision == 8) {
                   6180:                        if (p->encoding == AUDIO_ENCODING_SLINEAR_OE)
                   6181:                                p->encoding = AUDIO_ENCODING_SLINEAR_NE;
                   6182:                        if (p->encoding == AUDIO_ENCODING_ULINEAR_OE)
                   6183:                                p->encoding = AUDIO_ENCODING_ULINEAR_NE;
                   6184:                }
                   6185:
                   6186:                if (p->precision > p->stride)
                   6187:                        return EINVAL;
                   6188:                break;
                   6189:        case AUDIO_ENCODING_MPEG_L1_STREAM:
                   6190:        case AUDIO_ENCODING_MPEG_L1_PACKETS:
                   6191:        case AUDIO_ENCODING_MPEG_L1_SYSTEM:
                   6192:        case AUDIO_ENCODING_MPEG_L2_STREAM:
                   6193:        case AUDIO_ENCODING_MPEG_L2_PACKETS:
                   6194:        case AUDIO_ENCODING_MPEG_L2_SYSTEM:
                   6195:        case AUDIO_ENCODING_AC3:
                   6196:                break;
                   6197:        default:
                   6198:                return EINVAL;
                   6199:        }
                   6200:
                   6201:        /* sanity check # of channels*/
                   6202:        if (p->channels < 1 || p->channels > AUDIO_MAX_CHANNELS)
                   6203:                return EINVAL;
                   6204:
                   6205:        return 0;
                   6206: }
                   6207:
                   6208: /*
                   6209:  * Initialize playback and record mixers.
1.32      msaitoh  6210:  * mode (AUMODE_{PLAY,RECORD}) indicates the mixer to be initialized.
1.2       isaki    6211:  * phwfmt and rhwfmt indicate the hardware format.  pfil and rfil indicate
                   6212:  * the filter registration information.  These four must not be NULL.
                   6213:  * If successful returns 0.  Otherwise returns errno.
1.63      isaki    6214:  * Must be called with sc_exlock held and without sc_lock held.
1.2       isaki    6215:  * Must not be called if there are any tracks.
                   6216:  * Caller should check that the initialization succeed by whether
                   6217:  * sc_[pr]mixer is not NULL.
                   6218:  */
                   6219: static int
                   6220: audio_mixers_init(struct audio_softc *sc, int mode,
                   6221:        const audio_format2_t *phwfmt, const audio_format2_t *rhwfmt,
                   6222:        const audio_filter_reg_t *pfil, const audio_filter_reg_t *rfil)
                   6223: {
                   6224:        int error;
                   6225:
                   6226:        KASSERT(phwfmt != NULL);
                   6227:        KASSERT(rhwfmt != NULL);
                   6228:        KASSERT(pfil != NULL);
                   6229:        KASSERT(rfil != NULL);
1.63      isaki    6230:        KASSERT(sc->sc_exlock);
1.2       isaki    6231:
                   6232:        if ((mode & AUMODE_PLAY)) {
1.26      isaki    6233:                if (sc->sc_pmixer == NULL) {
                   6234:                        sc->sc_pmixer = kmem_zalloc(sizeof(*sc->sc_pmixer),
                   6235:                            KM_SLEEP);
                   6236:                } else {
                   6237:                        /* destroy() doesn't free memory. */
1.2       isaki    6238:                        audio_mixer_destroy(sc, sc->sc_pmixer);
1.26      isaki    6239:                        memset(sc->sc_pmixer, 0, sizeof(*sc->sc_pmixer));
1.2       isaki    6240:                }
                   6241:                error = audio_mixer_init(sc, AUMODE_PLAY, phwfmt, pfil);
                   6242:                if (error) {
1.46      isaki    6243:                        device_printf(sc->sc_dev,
                   6244:                            "configuring playback mode failed with %d\n",
                   6245:                            error);
1.2       isaki    6246:                        kmem_free(sc->sc_pmixer, sizeof(*sc->sc_pmixer));
                   6247:                        sc->sc_pmixer = NULL;
                   6248:                        return error;
                   6249:                }
                   6250:        }
                   6251:        if ((mode & AUMODE_RECORD)) {
1.26      isaki    6252:                if (sc->sc_rmixer == NULL) {
                   6253:                        sc->sc_rmixer = kmem_zalloc(sizeof(*sc->sc_rmixer),
                   6254:                            KM_SLEEP);
                   6255:                } else {
                   6256:                        /* destroy() doesn't free memory. */
1.2       isaki    6257:                        audio_mixer_destroy(sc, sc->sc_rmixer);
1.26      isaki    6258:                        memset(sc->sc_rmixer, 0, sizeof(*sc->sc_rmixer));
1.2       isaki    6259:                }
                   6260:                error = audio_mixer_init(sc, AUMODE_RECORD, rhwfmt, rfil);
                   6261:                if (error) {
1.46      isaki    6262:                        device_printf(sc->sc_dev,
                   6263:                            "configuring record mode failed with %d\n",
                   6264:                            error);
1.2       isaki    6265:                        kmem_free(sc->sc_rmixer, sizeof(*sc->sc_rmixer));
                   6266:                        sc->sc_rmixer = NULL;
                   6267:                        return error;
                   6268:                }
                   6269:        }
                   6270:
                   6271:        return 0;
                   6272: }
                   6273:
                   6274: /*
                   6275:  * Select a frequency.
                   6276:  * Prioritize 48kHz and 44.1kHz.  Otherwise choose the highest one.
                   6277:  * XXX Better algorithm?
                   6278:  */
                   6279: static int
                   6280: audio_select_freq(const struct audio_format *fmt)
                   6281: {
                   6282:        int freq;
                   6283:        int high;
                   6284:        int low;
                   6285:        int j;
                   6286:
                   6287:        if (fmt->frequency_type == 0) {
                   6288:                low = fmt->frequency[0];
                   6289:                high = fmt->frequency[1];
                   6290:                freq = 48000;
                   6291:                if (low <= freq && freq <= high) {
                   6292:                        return freq;
                   6293:                }
                   6294:                freq = 44100;
                   6295:                if (low <= freq && freq <= high) {
                   6296:                        return freq;
                   6297:                }
                   6298:                return high;
                   6299:        } else {
                   6300:                for (j = 0; j < fmt->frequency_type; j++) {
                   6301:                        if (fmt->frequency[j] == 48000) {
                   6302:                                return fmt->frequency[j];
                   6303:                        }
                   6304:                }
                   6305:                high = 0;
                   6306:                for (j = 0; j < fmt->frequency_type; j++) {
                   6307:                        if (fmt->frequency[j] == 44100) {
                   6308:                                return fmt->frequency[j];
                   6309:                        }
                   6310:                        if (fmt->frequency[j] > high) {
                   6311:                                high = fmt->frequency[j];
                   6312:                        }
                   6313:                }
                   6314:                return high;
                   6315:        }
                   6316: }
                   6317:
                   6318: /*
                   6319:  * Choose the most preferred hardware format.
                   6320:  * If successful, it will store the chosen format into *cand and return 0.
                   6321:  * Otherwise, return errno.
1.55      isaki    6322:  * Must be called without sc_lock held.
1.2       isaki    6323:  */
                   6324: static int
1.55      isaki    6325: audio_hw_probe(struct audio_softc *sc, audio_format2_t *cand, int mode)
1.2       isaki    6326: {
                   6327:        audio_format_query_t query;
                   6328:        int cand_score;
                   6329:        int score;
                   6330:        int i;
                   6331:        int error;
                   6332:
                   6333:        /*
                   6334:         * Score each formats and choose the highest one.
                   6335:         *
                   6336:         *                 +---- priority(0-3)
                   6337:         *                 |+--- encoding/precision
                   6338:         *                 ||+-- channels
                   6339:         * score = 0x000000PEC
                   6340:         */
                   6341:
                   6342:        cand_score = 0;
                   6343:        for (i = 0; ; i++) {
                   6344:                memset(&query, 0, sizeof(query));
                   6345:                query.index = i;
                   6346:
1.55      isaki    6347:                mutex_enter(sc->sc_lock);
1.2       isaki    6348:                error = sc->hw_if->query_format(sc->hw_hdl, &query);
1.55      isaki    6349:                mutex_exit(sc->sc_lock);
1.2       isaki    6350:                if (error == EINVAL)
                   6351:                        break;
                   6352:                if (error)
                   6353:                        return error;
                   6354:
                   6355: #if defined(AUDIO_DEBUG)
                   6356:                DPRINTF(1, "fmt[%d] %c%c pri=%d %s,%d/%dbit,%dch,", i,
                   6357:                    (query.fmt.mode & AUMODE_PLAY)   ? 'P' : '-',
                   6358:                    (query.fmt.mode & AUMODE_RECORD) ? 'R' : '-',
                   6359:                    query.fmt.priority,
                   6360:                    audio_encoding_name(query.fmt.encoding),
                   6361:                    query.fmt.validbits,
                   6362:                    query.fmt.precision,
                   6363:                    query.fmt.channels);
                   6364:                if (query.fmt.frequency_type == 0) {
                   6365:                        DPRINTF(1, "{%d-%d",
                   6366:                            query.fmt.frequency[0], query.fmt.frequency[1]);
                   6367:                } else {
                   6368:                        int j;
                   6369:                        for (j = 0; j < query.fmt.frequency_type; j++) {
                   6370:                                DPRINTF(1, "%c%d",
                   6371:                                    (j == 0) ? '{' : ',',
                   6372:                                    query.fmt.frequency[j]);
                   6373:                        }
                   6374:                }
                   6375:                DPRINTF(1, "}\n");
                   6376: #endif
                   6377:
                   6378:                if ((query.fmt.mode & mode) == 0) {
                   6379:                        DPRINTF(1, "fmt[%d] skip; mode not match %d\n", i,
                   6380:                            mode);
                   6381:                        continue;
                   6382:                }
                   6383:
                   6384:                if (query.fmt.priority < 0) {
                   6385:                        DPRINTF(1, "fmt[%d] skip; unsupported encoding\n", i);
                   6386:                        continue;
                   6387:                }
                   6388:
                   6389:                /* Score */
                   6390:                score = (query.fmt.priority & 3) * 0x100;
                   6391:                if (query.fmt.encoding == AUDIO_ENCODING_SLINEAR_NE &&
                   6392:                    query.fmt.validbits == AUDIO_INTERNAL_BITS &&
                   6393:                    query.fmt.precision == AUDIO_INTERNAL_BITS) {
                   6394:                        score += 0x20;
                   6395:                } else if (query.fmt.encoding == AUDIO_ENCODING_SLINEAR_OE &&
                   6396:                    query.fmt.validbits == AUDIO_INTERNAL_BITS &&
                   6397:                    query.fmt.precision == AUDIO_INTERNAL_BITS) {
                   6398:                        score += 0x10;
                   6399:                }
                   6400:                score += query.fmt.channels;
                   6401:
                   6402:                if (score < cand_score) {
                   6403:                        DPRINTF(1, "fmt[%d] skip; score 0x%x < 0x%x\n", i,
                   6404:                            score, cand_score);
                   6405:                        continue;
                   6406:                }
                   6407:
                   6408:                /* Update candidate */
                   6409:                cand_score = score;
                   6410:                cand->encoding    = query.fmt.encoding;
                   6411:                cand->precision   = query.fmt.validbits;
                   6412:                cand->stride      = query.fmt.precision;
                   6413:                cand->channels    = query.fmt.channels;
                   6414:                cand->sample_rate = audio_select_freq(&query.fmt);
                   6415:                DPRINTF(1, "fmt[%d] candidate (score=0x%x)"
                   6416:                    " pri=%d %s,%d/%d,%dch,%dHz\n", i,
                   6417:                    cand_score, query.fmt.priority,
                   6418:                    audio_encoding_name(query.fmt.encoding),
                   6419:                    cand->precision, cand->stride,
                   6420:                    cand->channels, cand->sample_rate);
                   6421:        }
                   6422:
                   6423:        if (cand_score == 0) {
                   6424:                DPRINTF(1, "%s no fmt\n", __func__);
                   6425:                return ENXIO;
                   6426:        }
                   6427:        DPRINTF(1, "%s selected: %s,%d/%d,%dch,%dHz\n", __func__,
                   6428:            audio_encoding_name(cand->encoding),
                   6429:            cand->precision, cand->stride, cand->channels, cand->sample_rate);
                   6430:        return 0;
                   6431: }
                   6432:
                   6433: /*
                   6434:  * Validate fmt with query_format.
                   6435:  * If fmt is included in the result of query_format, returns 0.
                   6436:  * Otherwise returns EINVAL.
1.63      isaki    6437:  * Must be called without sc_lock held.
1.76      isaki    6438:  */
1.2       isaki    6439: static int
                   6440: audio_hw_validate_format(struct audio_softc *sc, int mode,
                   6441:        const audio_format2_t *fmt)
                   6442: {
                   6443:        audio_format_query_t query;
                   6444:        struct audio_format *q;
                   6445:        int index;
                   6446:        int error;
                   6447:        int j;
                   6448:
                   6449:        for (index = 0; ; index++) {
                   6450:                query.index = index;
1.63      isaki    6451:                mutex_enter(sc->sc_lock);
1.2       isaki    6452:                error = sc->hw_if->query_format(sc->hw_hdl, &query);
1.63      isaki    6453:                mutex_exit(sc->sc_lock);
1.2       isaki    6454:                if (error == EINVAL)
                   6455:                        break;
                   6456:                if (error)
                   6457:                        return error;
                   6458:
                   6459:                q = &query.fmt;
                   6460:                /*
                   6461:                 * Note that fmt is audio_format2_t (precision/stride) but
                   6462:                 * q is audio_format_t (validbits/precision).
                   6463:                 */
                   6464:                if ((q->mode & mode) == 0) {
                   6465:                        continue;
                   6466:                }
                   6467:                if (fmt->encoding != q->encoding) {
                   6468:                        continue;
                   6469:                }
                   6470:                if (fmt->precision != q->validbits) {
                   6471:                        continue;
                   6472:                }
                   6473:                if (fmt->stride != q->precision) {
                   6474:                        continue;
                   6475:                }
                   6476:                if (fmt->channels != q->channels) {
                   6477:                        continue;
                   6478:                }
                   6479:                if (q->frequency_type == 0) {
                   6480:                        if (fmt->sample_rate < q->frequency[0] ||
                   6481:                            fmt->sample_rate > q->frequency[1]) {
                   6482:                                continue;
                   6483:                        }
                   6484:                } else {
                   6485:                        for (j = 0; j < q->frequency_type; j++) {
                   6486:                                if (fmt->sample_rate == q->frequency[j])
                   6487:                                        break;
                   6488:                        }
                   6489:                        if (j == query.fmt.frequency_type) {
                   6490:                                continue;
                   6491:                        }
                   6492:                }
                   6493:
                   6494:                /* Matched. */
                   6495:                return 0;
                   6496:        }
                   6497:
                   6498:        return EINVAL;
                   6499: }
                   6500:
                   6501: /*
                   6502:  * Set track mixer's format depending on ai->mode.
                   6503:  * If AUMODE_PLAY is set in ai->mode, it set up the playback mixer
1.44      isaki    6504:  * with ai.play.*.
1.2       isaki    6505:  * If AUMODE_RECORD is set in ai->mode, it set up the recording mixer
1.44      isaki    6506:  * with ai.record.*.
1.2       isaki    6507:  * All other fields in ai are ignored.
                   6508:  * If successful returns 0.  Otherwise returns errno.
                   6509:  * This function does not roll back even if it fails.
1.63      isaki    6510:  * Must be called with sc_exlock held and without sc_lock held.
1.2       isaki    6511:  */
                   6512: static int
                   6513: audio_mixers_set_format(struct audio_softc *sc, const struct audio_info *ai)
                   6514: {
                   6515:        audio_format2_t phwfmt;
                   6516:        audio_format2_t rhwfmt;
                   6517:        audio_filter_reg_t pfil;
                   6518:        audio_filter_reg_t rfil;
                   6519:        int mode;
                   6520:        int error;
                   6521:
1.63      isaki    6522:        KASSERT(sc->sc_exlock);
1.2       isaki    6523:
                   6524:        /*
                   6525:         * Even when setting either one of playback and recording,
                   6526:         * both must be halted.
                   6527:         */
                   6528:        if (sc->sc_popens + sc->sc_ropens > 0)
                   6529:                return EBUSY;
                   6530:
                   6531:        if (!SPECIFIED(ai->mode) || ai->mode == 0)
                   6532:                return ENOTTY;
                   6533:
                   6534:        mode = ai->mode;
                   6535:        if ((mode & AUMODE_PLAY)) {
                   6536:                phwfmt.encoding    = ai->play.encoding;
                   6537:                phwfmt.precision   = ai->play.precision;
                   6538:                phwfmt.stride      = ai->play.precision;
                   6539:                phwfmt.channels    = ai->play.channels;
                   6540:                phwfmt.sample_rate = ai->play.sample_rate;
                   6541:        }
                   6542:        if ((mode & AUMODE_RECORD)) {
                   6543:                rhwfmt.encoding    = ai->record.encoding;
                   6544:                rhwfmt.precision   = ai->record.precision;
                   6545:                rhwfmt.stride      = ai->record.precision;
                   6546:                rhwfmt.channels    = ai->record.channels;
                   6547:                rhwfmt.sample_rate = ai->record.sample_rate;
                   6548:        }
                   6549:
                   6550:        /* On non-independent devices, use the same format for both. */
1.14      isaki    6551:        if ((sc->sc_props & AUDIO_PROP_INDEPENDENT) == 0) {
1.2       isaki    6552:                if (mode == AUMODE_RECORD) {
                   6553:                        phwfmt = rhwfmt;
                   6554:                } else {
                   6555:                        rhwfmt = phwfmt;
                   6556:                }
                   6557:                mode = AUMODE_PLAY | AUMODE_RECORD;
                   6558:        }
                   6559:
                   6560:        /* Then, unset the direction not exist on the hardware. */
1.14      isaki    6561:        if ((sc->sc_props & AUDIO_PROP_PLAYBACK) == 0)
1.2       isaki    6562:                mode &= ~AUMODE_PLAY;
1.14      isaki    6563:        if ((sc->sc_props & AUDIO_PROP_CAPTURE) == 0)
1.2       isaki    6564:                mode &= ~AUMODE_RECORD;
                   6565:
                   6566:        /* debug */
                   6567:        if ((mode & AUMODE_PLAY)) {
                   6568:                TRACE(1, "play=%s/%d/%d/%dch/%dHz",
                   6569:                    audio_encoding_name(phwfmt.encoding),
                   6570:                    phwfmt.precision,
                   6571:                    phwfmt.stride,
                   6572:                    phwfmt.channels,
                   6573:                    phwfmt.sample_rate);
                   6574:        }
                   6575:        if ((mode & AUMODE_RECORD)) {
                   6576:                TRACE(1, "rec =%s/%d/%d/%dch/%dHz",
                   6577:                    audio_encoding_name(rhwfmt.encoding),
                   6578:                    rhwfmt.precision,
                   6579:                    rhwfmt.stride,
                   6580:                    rhwfmt.channels,
                   6581:                    rhwfmt.sample_rate);
                   6582:        }
                   6583:
                   6584:        /* Check the format */
                   6585:        if ((mode & AUMODE_PLAY)) {
                   6586:                if (audio_hw_validate_format(sc, AUMODE_PLAY, &phwfmt)) {
                   6587:                        TRACE(1, "invalid format");
                   6588:                        return EINVAL;
                   6589:                }
                   6590:        }
                   6591:        if ((mode & AUMODE_RECORD)) {
                   6592:                if (audio_hw_validate_format(sc, AUMODE_RECORD, &rhwfmt)) {
                   6593:                        TRACE(1, "invalid format");
                   6594:                        return EINVAL;
                   6595:                }
                   6596:        }
                   6597:
                   6598:        /* Configure the mixers. */
                   6599:        memset(&pfil, 0, sizeof(pfil));
                   6600:        memset(&rfil, 0, sizeof(rfil));
                   6601:        error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
                   6602:        if (error)
                   6603:                return error;
                   6604:
                   6605:        error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
                   6606:        if (error)
                   6607:                return error;
                   6608:
1.59      isaki    6609:        /*
                   6610:         * Reinitialize the sticky parameters for /dev/sound.
                   6611:         * If the number of the hardware channels becomes less than the number
                   6612:         * of channels that sticky parameters remember, subsequent /dev/sound
                   6613:         * open will fail.  To prevent this, reinitialize the sticky
                   6614:         * parameters whenever the hardware format is changed.
                   6615:         */
                   6616:        sc->sc_sound_pparams = params_to_format2(&audio_default);
                   6617:        sc->sc_sound_rparams = params_to_format2(&audio_default);
                   6618:        sc->sc_sound_ppause = false;
                   6619:        sc->sc_sound_rpause = false;
                   6620:
1.2       isaki    6621:        return 0;
                   6622: }
                   6623:
                   6624: /*
                   6625:  * Store current mixers format into *ai.
1.63      isaki    6626:  * Must be called with sc_exlock held.
1.2       isaki    6627:  */
                   6628: static void
                   6629: audio_mixers_get_format(struct audio_softc *sc, struct audio_info *ai)
                   6630: {
1.63      isaki    6631:
                   6632:        KASSERT(sc->sc_exlock);
                   6633:
1.2       isaki    6634:        /*
                   6635:         * There is no stride information in audio_info but it doesn't matter.
                   6636:         * trackmixer always treats stride and precision as the same.
                   6637:         */
                   6638:        AUDIO_INITINFO(ai);
                   6639:        ai->mode = 0;
                   6640:        if (sc->sc_pmixer) {
                   6641:                audio_format2_t *fmt = &sc->sc_pmixer->track_fmt;
                   6642:                ai->play.encoding    = fmt->encoding;
                   6643:                ai->play.precision   = fmt->precision;
                   6644:                ai->play.channels    = fmt->channels;
                   6645:                ai->play.sample_rate = fmt->sample_rate;
                   6646:                ai->mode |= AUMODE_PLAY;
                   6647:        }
                   6648:        if (sc->sc_rmixer) {
                   6649:                audio_format2_t *fmt = &sc->sc_rmixer->track_fmt;
                   6650:                ai->record.encoding    = fmt->encoding;
                   6651:                ai->record.precision   = fmt->precision;
                   6652:                ai->record.channels    = fmt->channels;
                   6653:                ai->record.sample_rate = fmt->sample_rate;
                   6654:                ai->mode |= AUMODE_RECORD;
                   6655:        }
                   6656: }
                   6657:
                   6658: /*
                   6659:  * audio_info details:
                   6660:  *
                   6661:  * ai.{play,record}.sample_rate                (R/W)
                   6662:  * ai.{play,record}.encoding           (R/W)
                   6663:  * ai.{play,record}.precision          (R/W)
                   6664:  * ai.{play,record}.channels           (R/W)
                   6665:  *     These specify the playback or recording format.
                   6666:  *     Ignore members within an inactive track.
                   6667:  *
                   6668:  * ai.mode                             (R/W)
                   6669:  *     It specifies the playback or recording mode, AUMODE_*.
                   6670:  *     Currently, a mode change operation by ai.mode after opening is
                   6671:  *     prohibited.  In addition, AUMODE_PLAY_ALL no longer makes sense.
                   6672:  *     However, it's possible to get or to set for backward compatibility.
                   6673:  *
                   6674:  * ai.{hiwat,lowat}                    (R/W)
                   6675:  *     These specify the high water mark and low water mark for playback
                   6676:  *     track.  The unit is block.
                   6677:  *
                   6678:  * ai.{play,record}.gain               (R/W)
                   6679:  *     It specifies the HW mixer volume in 0-255.
                   6680:  *     It is historical reason that the gain is connected to HW mixer.
                   6681:  *
                   6682:  * ai.{play,record}.balance            (R/W)
                   6683:  *     It specifies the left-right balance of HW mixer in 0-64.
                   6684:  *     32 means the center.
                   6685:  *     It is historical reason that the balance is connected to HW mixer.
                   6686:  *
                   6687:  * ai.{play,record}.port               (R/W)
                   6688:  *     It specifies the input/output port of HW mixer.
                   6689:  *
                   6690:  * ai.monitor_gain                     (R/W)
                   6691:  *     It specifies the recording monitor gain(?) of HW mixer.
                   6692:  *
                   6693:  * ai.{play,record}.pause              (R/W)
                   6694:  *     Non-zero means the track is paused.
                   6695:  *
                   6696:  * ai.play.seek                                (R/-)
                   6697:  *     It indicates the number of bytes written but not processed.
                   6698:  * ai.record.seek                      (R/-)
                   6699:  *     It indicates the number of bytes to be able to read.
                   6700:  *
                   6701:  * ai.{play,record}.avail_ports                (R/-)
                   6702:  *     Mixer info.
                   6703:  *
                   6704:  * ai.{play,record}.buffer_size                (R/-)
                   6705:  *     It indicates the buffer size in bytes.  Internally it means usrbuf.
                   6706:  *
                   6707:  * ai.{play,record}.samples            (R/-)
                   6708:  *     It indicates the total number of bytes played or recorded.
                   6709:  *
                   6710:  * ai.{play,record}.eof                        (R/-)
                   6711:  *     It indicates the number of times reached EOF(?).
                   6712:  *
                   6713:  * ai.{play,record}.error              (R/-)
                   6714:  *     Non-zero indicates overflow/underflow has occured.
                   6715:  *
                   6716:  * ai.{play,record}.waiting            (R/-)
                   6717:  *     Non-zero indicates that other process waits to open.
                   6718:  *     It will never happen anymore.
                   6719:  *
                   6720:  * ai.{play,record}.open               (R/-)
                   6721:  *     Non-zero indicates the direction is opened by this process(?).
                   6722:  *     XXX Is this better to indicate that "the device is opened by
                   6723:  *     at least one process"?
                   6724:  *
                   6725:  * ai.{play,record}.active             (R/-)
                   6726:  *     Non-zero indicates that I/O is currently active.
                   6727:  *
                   6728:  * ai.blocksize                                (R/-)
                   6729:  *     It indicates the block size in bytes.
                   6730:  *     XXX The blocksize of playback and recording may be different.
                   6731:  */
                   6732:
                   6733: /*
                   6734:  * Pause consideration:
                   6735:  *
1.65      isaki    6736:  * Pausing/unpausing never affect [pr]mixer.  This single rule makes
                   6737:  * operation simple.  Note that playback and recording are asymmetric.
                   6738:  *
                   6739:  * For playback,
                   6740:  *  1. Any playback open doesn't start pmixer regardless of initial pause
                   6741:  *     state of this track.
                   6742:  *  2. The first write access among playback tracks only starts pmixer
                   6743:  *     regardless of this track's pause state.
                   6744:  *  3. Even a pause of the last playback track doesn't stop pmixer.
                   6745:  *  4. The last close of all playback tracks only stops pmixer.
                   6746:  *
                   6747:  * For recording,
                   6748:  *  1. The first recording open only starts rmixer regardless of initial
                   6749:  *     pause state of this track.
                   6750:  *  2. Even a pause of the last track doesn't stop rmixer.
                   6751:  *  3. The last close of all recording tracks only stops rmixer.
1.2       isaki    6752:  */
                   6753:
                   6754: /*
                   6755:  * Set both track's parameters within a file depending on ai.
                   6756:  * Update sc_sound_[pr]* if set.
1.63      isaki    6757:  * Must be called with sc_exlock held and without sc_lock held.
1.2       isaki    6758:  */
                   6759: static int
                   6760: audio_file_setinfo(struct audio_softc *sc, audio_file_t *file,
                   6761:        const struct audio_info *ai)
                   6762: {
                   6763:        const struct audio_prinfo *pi;
                   6764:        const struct audio_prinfo *ri;
                   6765:        audio_track_t *ptrack;
                   6766:        audio_track_t *rtrack;
                   6767:        audio_format2_t pfmt;
                   6768:        audio_format2_t rfmt;
                   6769:        int pchanges;
                   6770:        int rchanges;
                   6771:        int mode;
                   6772:        struct audio_info saved_ai;
                   6773:        audio_format2_t saved_pfmt;
                   6774:        audio_format2_t saved_rfmt;
                   6775:        int error;
                   6776:
                   6777:        KASSERT(sc->sc_exlock);
                   6778:
                   6779:        pi = &ai->play;
                   6780:        ri = &ai->record;
                   6781:        pchanges = 0;
                   6782:        rchanges = 0;
                   6783:
                   6784:        ptrack = file->ptrack;
                   6785:        rtrack = file->rtrack;
                   6786:
                   6787: #if defined(AUDIO_DEBUG)
                   6788:        if (audiodebug >= 2) {
                   6789:                char buf[256];
                   6790:                char p[64];
                   6791:                int buflen;
                   6792:                int plen;
                   6793: #define SPRINTF(var, fmt...) do {      \
                   6794:        var##len += snprintf(var + var##len, sizeof(var) - var##len, fmt); \
                   6795: } while (0)
                   6796:
                   6797:                buflen = 0;
                   6798:                plen = 0;
                   6799:                if (SPECIFIED(pi->encoding))
                   6800:                        SPRINTF(p, "/%s", audio_encoding_name(pi->encoding));
                   6801:                if (SPECIFIED(pi->precision))
                   6802:                        SPRINTF(p, "/%dbit", pi->precision);
                   6803:                if (SPECIFIED(pi->channels))
                   6804:                        SPRINTF(p, "/%dch", pi->channels);
                   6805:                if (SPECIFIED(pi->sample_rate))
                   6806:                        SPRINTF(p, "/%dHz", pi->sample_rate);
                   6807:                if (plen > 0)
                   6808:                        SPRINTF(buf, ",play.param=%s", p + 1);
                   6809:
                   6810:                plen = 0;
                   6811:                if (SPECIFIED(ri->encoding))
                   6812:                        SPRINTF(p, "/%s", audio_encoding_name(ri->encoding));
                   6813:                if (SPECIFIED(ri->precision))
                   6814:                        SPRINTF(p, "/%dbit", ri->precision);
                   6815:                if (SPECIFIED(ri->channels))
                   6816:                        SPRINTF(p, "/%dch", ri->channels);
                   6817:                if (SPECIFIED(ri->sample_rate))
                   6818:                        SPRINTF(p, "/%dHz", ri->sample_rate);
                   6819:                if (plen > 0)
                   6820:                        SPRINTF(buf, ",record.param=%s", p + 1);
                   6821:
                   6822:                if (SPECIFIED(ai->mode))
                   6823:                        SPRINTF(buf, ",mode=%d", ai->mode);
                   6824:                if (SPECIFIED(ai->hiwat))
                   6825:                        SPRINTF(buf, ",hiwat=%d", ai->hiwat);
                   6826:                if (SPECIFIED(ai->lowat))
                   6827:                        SPRINTF(buf, ",lowat=%d", ai->lowat);
                   6828:                if (SPECIFIED(ai->play.gain))
                   6829:                        SPRINTF(buf, ",play.gain=%d", ai->play.gain);
                   6830:                if (SPECIFIED(ai->record.gain))
                   6831:                        SPRINTF(buf, ",record.gain=%d", ai->record.gain);
                   6832:                if (SPECIFIED_CH(ai->play.balance))
                   6833:                        SPRINTF(buf, ",play.balance=%d", ai->play.balance);
                   6834:                if (SPECIFIED_CH(ai->record.balance))
                   6835:                        SPRINTF(buf, ",record.balance=%d", ai->record.balance);
                   6836:                if (SPECIFIED(ai->play.port))
                   6837:                        SPRINTF(buf, ",play.port=%d", ai->play.port);
                   6838:                if (SPECIFIED(ai->record.port))
                   6839:                        SPRINTF(buf, ",record.port=%d", ai->record.port);
                   6840:                if (SPECIFIED(ai->monitor_gain))
                   6841:                        SPRINTF(buf, ",monitor_gain=%d", ai->monitor_gain);
                   6842:                if (SPECIFIED_CH(ai->play.pause))
                   6843:                        SPRINTF(buf, ",play.pause=%d", ai->play.pause);
                   6844:                if (SPECIFIED_CH(ai->record.pause))
                   6845:                        SPRINTF(buf, ",record.pause=%d", ai->record.pause);
                   6846:
                   6847:                if (buflen > 0)
                   6848:                        TRACE(2, "specified %s", buf + 1);
                   6849:        }
                   6850: #endif
                   6851:
                   6852:        AUDIO_INITINFO(&saved_ai);
                   6853:        /* XXX shut up gcc */
                   6854:        memset(&saved_pfmt, 0, sizeof(saved_pfmt));
                   6855:        memset(&saved_rfmt, 0, sizeof(saved_rfmt));
                   6856:
1.62      isaki    6857:        /*
                   6858:         * Set default value and save current parameters.
                   6859:         * For backward compatibility, use sticky parameters for nonexistent
                   6860:         * track.
                   6861:         */
1.2       isaki    6862:        if (ptrack) {
                   6863:                pfmt = ptrack->usrbuf.fmt;
                   6864:                saved_pfmt = ptrack->usrbuf.fmt;
                   6865:                saved_ai.play.pause = ptrack->is_pause;
1.62      isaki    6866:        } else {
                   6867:                pfmt = sc->sc_sound_pparams;
1.2       isaki    6868:        }
                   6869:        if (rtrack) {
                   6870:                rfmt = rtrack->usrbuf.fmt;
                   6871:                saved_rfmt = rtrack->usrbuf.fmt;
                   6872:                saved_ai.record.pause = rtrack->is_pause;
1.62      isaki    6873:        } else {
                   6874:                rfmt = sc->sc_sound_rparams;
1.2       isaki    6875:        }
                   6876:        saved_ai.mode = file->mode;
                   6877:
1.62      isaki    6878:        /*
                   6879:         * Overwrite if specified.
                   6880:         */
1.2       isaki    6881:        mode = file->mode;
                   6882:        if (SPECIFIED(ai->mode)) {
                   6883:                /*
                   6884:                 * Setting ai->mode no longer does anything because it's
                   6885:                 * prohibited to change playback/recording mode after open
                   6886:                 * and AUMODE_PLAY_ALL is obsoleted.  However, it still
                   6887:                 * keeps the state of AUMODE_PLAY_ALL itself for backward
                   6888:                 * compatibility.
                   6889:                 * In the internal, only file->mode has the state of
                   6890:                 * AUMODE_PLAY_ALL flag and track->mode in both track does
                   6891:                 * not have.
                   6892:                 */
                   6893:                if ((file->mode & AUMODE_PLAY)) {
                   6894:                        mode = (file->mode & (AUMODE_PLAY | AUMODE_RECORD))
                   6895:                            | (ai->mode & AUMODE_PLAY_ALL);
                   6896:                }
                   6897:        }
                   6898:
1.62      isaki    6899:        pchanges = audio_track_setinfo_check(ptrack, &pfmt, pi);
                   6900:        if (pchanges == -1) {
1.8       isaki    6901: #if defined(AUDIO_DEBUG)
1.62      isaki    6902:                TRACEF(1, file, "check play.params failed: "
                   6903:                    "%s %ubit %uch %uHz",
                   6904:                    audio_encoding_name(pi->encoding),
                   6905:                    pi->precision,
                   6906:                    pi->channels,
                   6907:                    pi->sample_rate);
1.8       isaki    6908: #endif
1.62      isaki    6909:                return EINVAL;
1.2       isaki    6910:        }
1.62      isaki    6911:
                   6912:        rchanges = audio_track_setinfo_check(rtrack, &rfmt, ri);
                   6913:        if (rchanges == -1) {
1.8       isaki    6914: #if defined(AUDIO_DEBUG)
1.62      isaki    6915:                TRACEF(1, file, "check record.params failed: "
                   6916:                    "%s %ubit %uch %uHz",
                   6917:                    audio_encoding_name(ri->encoding),
                   6918:                    ri->precision,
                   6919:                    ri->channels,
                   6920:                    ri->sample_rate);
1.8       isaki    6921: #endif
1.62      isaki    6922:                return EINVAL;
                   6923:        }
                   6924:
                   6925:        if (SPECIFIED(ai->mode)) {
                   6926:                pchanges = 1;
                   6927:                rchanges = 1;
1.2       isaki    6928:        }
                   6929:
                   6930:        /*
                   6931:         * Even when setting either one of playback and recording,
                   6932:         * both track must be halted.
                   6933:         */
                   6934:        if (pchanges || rchanges) {
                   6935:                audio_file_clear(sc, file);
                   6936: #if defined(AUDIO_DEBUG)
1.62      isaki    6937:                char nbuf[16];
1.2       isaki    6938:                char fmtbuf[64];
                   6939:                if (pchanges) {
1.62      isaki    6940:                        if (ptrack) {
                   6941:                                snprintf(nbuf, sizeof(nbuf), "%d", ptrack->id);
                   6942:                        } else {
                   6943:                                snprintf(nbuf, sizeof(nbuf), "-");
                   6944:                        }
1.2       isaki    6945:                        audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &pfmt);
1.62      isaki    6946:                        DPRINTF(1, "audio track#%s play mode: %s\n",
                   6947:                            nbuf, fmtbuf);
1.2       isaki    6948:                }
                   6949:                if (rchanges) {
1.62      isaki    6950:                        if (rtrack) {
                   6951:                                snprintf(nbuf, sizeof(nbuf), "%d", rtrack->id);
                   6952:                        } else {
                   6953:                                snprintf(nbuf, sizeof(nbuf), "-");
                   6954:                        }
1.2       isaki    6955:                        audio_format2_tostr(fmtbuf, sizeof(fmtbuf), &rfmt);
1.62      isaki    6956:                        DPRINTF(1, "audio track#%s rec  mode: %s\n",
                   6957:                            nbuf, fmtbuf);
1.2       isaki    6958:                }
                   6959: #endif
                   6960:        }
                   6961:
                   6962:        /* Set mixer parameters */
1.63      isaki    6963:        mutex_enter(sc->sc_lock);
1.2       isaki    6964:        error = audio_hw_setinfo(sc, ai, &saved_ai);
1.63      isaki    6965:        mutex_exit(sc->sc_lock);
1.2       isaki    6966:        if (error)
                   6967:                goto abort1;
                   6968:
1.62      isaki    6969:        /*
                   6970:         * Set to track and update sticky parameters.
                   6971:         */
1.2       isaki    6972:        error = 0;
                   6973:        file->mode = mode;
1.62      isaki    6974:
                   6975:        if (SPECIFIED_CH(pi->pause)) {
                   6976:                if (ptrack)
1.2       isaki    6977:                        ptrack->is_pause = pi->pause;
1.62      isaki    6978:                sc->sc_sound_ppause = pi->pause;
                   6979:        }
                   6980:        if (pchanges) {
                   6981:                if (ptrack) {
1.2       isaki    6982:                        audio_track_lock_enter(ptrack);
                   6983:                        error = audio_track_set_format(ptrack, &pfmt);
                   6984:                        audio_track_lock_exit(ptrack);
                   6985:                        if (error) {
                   6986:                                TRACET(1, ptrack, "set play.params failed");
                   6987:                                goto abort2;
                   6988:                        }
                   6989:                }
1.62      isaki    6990:                sc->sc_sound_pparams = pfmt;
                   6991:        }
                   6992:        /* Change water marks after initializing the buffers. */
                   6993:        if (SPECIFIED(ai->hiwat) || SPECIFIED(ai->lowat)) {
                   6994:                if (ptrack)
1.2       isaki    6995:                        audio_track_setinfo_water(ptrack, ai);
                   6996:        }
1.62      isaki    6997:
                   6998:        if (SPECIFIED_CH(ri->pause)) {
                   6999:                if (rtrack)
1.2       isaki    7000:                        rtrack->is_pause = ri->pause;
1.62      isaki    7001:                sc->sc_sound_rpause = ri->pause;
                   7002:        }
                   7003:        if (rchanges) {
                   7004:                if (rtrack) {
1.2       isaki    7005:                        audio_track_lock_enter(rtrack);
                   7006:                        error = audio_track_set_format(rtrack, &rfmt);
                   7007:                        audio_track_lock_exit(rtrack);
                   7008:                        if (error) {
                   7009:                                TRACET(1, rtrack, "set record.params failed");
                   7010:                                goto abort3;
                   7011:                        }
                   7012:                }
1.62      isaki    7013:                sc->sc_sound_rparams = rfmt;
1.2       isaki    7014:        }
                   7015:
                   7016:        return 0;
                   7017:
                   7018:        /* Rollback */
                   7019: abort3:
                   7020:        if (error != ENOMEM) {
                   7021:                rtrack->is_pause = saved_ai.record.pause;
                   7022:                audio_track_lock_enter(rtrack);
                   7023:                audio_track_set_format(rtrack, &saved_rfmt);
                   7024:                audio_track_lock_exit(rtrack);
                   7025:        }
1.62      isaki    7026:        sc->sc_sound_rpause = saved_ai.record.pause;
                   7027:        sc->sc_sound_rparams = saved_rfmt;
1.2       isaki    7028: abort2:
                   7029:        if (ptrack && error != ENOMEM) {
                   7030:                ptrack->is_pause = saved_ai.play.pause;
                   7031:                audio_track_lock_enter(ptrack);
                   7032:                audio_track_set_format(ptrack, &saved_pfmt);
                   7033:                audio_track_lock_exit(ptrack);
                   7034:        }
1.62      isaki    7035:        sc->sc_sound_ppause = saved_ai.play.pause;
                   7036:        sc->sc_sound_pparams = saved_pfmt;
1.2       isaki    7037:        file->mode = saved_ai.mode;
                   7038: abort1:
1.63      isaki    7039:        mutex_enter(sc->sc_lock);
1.2       isaki    7040:        audio_hw_setinfo(sc, &saved_ai, NULL);
1.63      isaki    7041:        mutex_exit(sc->sc_lock);
1.2       isaki    7042:
                   7043:        return error;
                   7044: }
                   7045:
                   7046: /*
                   7047:  * Write SPECIFIED() parameters within info back to fmt.
1.62      isaki    7048:  * Note that track can be NULL here.
1.2       isaki    7049:  * Return value of 1 indicates that fmt is modified.
                   7050:  * Return value of 0 indicates that fmt is not modified.
                   7051:  * Return value of -1 indicates that error EINVAL has occurred.
                   7052:  */
                   7053: static int
1.62      isaki    7054: audio_track_setinfo_check(audio_track_t *track,
                   7055:        audio_format2_t *fmt, const struct audio_prinfo *info)
1.2       isaki    7056: {
1.62      isaki    7057:        const audio_format2_t *hwfmt;
1.2       isaki    7058:        int changes;
                   7059:
                   7060:        changes = 0;
                   7061:        if (SPECIFIED(info->sample_rate)) {
                   7062:                if (info->sample_rate < AUDIO_MIN_FREQUENCY)
                   7063:                        return -1;
                   7064:                if (info->sample_rate > AUDIO_MAX_FREQUENCY)
                   7065:                        return -1;
                   7066:                fmt->sample_rate = info->sample_rate;
                   7067:                changes = 1;
                   7068:        }
                   7069:        if (SPECIFIED(info->encoding)) {
                   7070:                fmt->encoding = info->encoding;
                   7071:                changes = 1;
                   7072:        }
                   7073:        if (SPECIFIED(info->precision)) {
                   7074:                fmt->precision = info->precision;
                   7075:                /* we don't have API to specify stride */
                   7076:                fmt->stride = info->precision;
                   7077:                changes = 1;
                   7078:        }
                   7079:        if (SPECIFIED(info->channels)) {
1.43      isaki    7080:                /*
                   7081:                 * We can convert between monaural and stereo each other.
                   7082:                 * We can reduce than the number of channels that the hardware
                   7083:                 * supports.
                   7084:                 */
1.62      isaki    7085:                if (info->channels > 2) {
                   7086:                        if (track) {
                   7087:                                hwfmt = &track->mixer->hwbuf.fmt;
                   7088:                                if (info->channels > hwfmt->channels)
                   7089:                                        return -1;
                   7090:                        } else {
                   7091:                                /*
                   7092:                                 * This should never happen.
                   7093:                                 * If track == NULL, channels should be <= 2.
                   7094:                                 */
                   7095:                                return -1;
                   7096:                        }
                   7097:                }
1.2       isaki    7098:                fmt->channels = info->channels;
                   7099:                changes = 1;
                   7100:        }
                   7101:
                   7102:        if (changes) {
1.8       isaki    7103:                if (audio_check_params(fmt) != 0)
1.2       isaki    7104:                        return -1;
                   7105:        }
                   7106:
                   7107:        return changes;
                   7108: }
                   7109:
                   7110: /*
                   7111:  * Change water marks for playback track if specfied.
                   7112:  */
                   7113: static void
                   7114: audio_track_setinfo_water(audio_track_t *track, const struct audio_info *ai)
                   7115: {
                   7116:        u_int blks;
                   7117:        u_int maxblks;
                   7118:        u_int blksize;
                   7119:
                   7120:        KASSERT(audio_track_is_playback(track));
                   7121:
                   7122:        blksize = track->usrbuf_blksize;
                   7123:        maxblks = track->usrbuf.capacity / blksize;
                   7124:
                   7125:        if (SPECIFIED(ai->hiwat)) {
                   7126:                blks = ai->hiwat;
                   7127:                if (blks > maxblks)
                   7128:                        blks = maxblks;
                   7129:                if (blks < 2)
                   7130:                        blks = 2;
                   7131:                track->usrbuf_usedhigh = blks * blksize;
                   7132:        }
                   7133:        if (SPECIFIED(ai->lowat)) {
                   7134:                blks = ai->lowat;
                   7135:                if (blks > maxblks - 1)
                   7136:                        blks = maxblks - 1;
                   7137:                track->usrbuf_usedlow = blks * blksize;
                   7138:        }
                   7139:        if (SPECIFIED(ai->hiwat) || SPECIFIED(ai->lowat)) {
                   7140:                if (track->usrbuf_usedlow > track->usrbuf_usedhigh - blksize) {
                   7141:                        track->usrbuf_usedlow = track->usrbuf_usedhigh -
                   7142:                            blksize;
                   7143:                }
                   7144:        }
                   7145: }
                   7146:
                   7147: /*
1.44      isaki    7148:  * Set hardware part of *newai.
1.2       isaki    7149:  * The parameters handled here are *.port, *.gain, *.balance and monitor_gain.
                   7150:  * If oldai is specified, previous parameters are stored.
                   7151:  * This function itself does not roll back if error occurred.
1.63      isaki    7152:  * Must be called with sc_lock && sc_exlock held.
1.2       isaki    7153:  */
                   7154: static int
                   7155: audio_hw_setinfo(struct audio_softc *sc, const struct audio_info *newai,
                   7156:        struct audio_info *oldai)
                   7157: {
                   7158:        const struct audio_prinfo *newpi;
                   7159:        const struct audio_prinfo *newri;
                   7160:        struct audio_prinfo *oldpi;
                   7161:        struct audio_prinfo *oldri;
                   7162:        u_int pgain;
                   7163:        u_int rgain;
                   7164:        u_char pbalance;
                   7165:        u_char rbalance;
                   7166:        int error;
                   7167:
                   7168:        KASSERT(mutex_owned(sc->sc_lock));
                   7169:        KASSERT(sc->sc_exlock);
                   7170:
                   7171:        /* XXX shut up gcc */
                   7172:        oldpi = NULL;
                   7173:        oldri = NULL;
                   7174:
                   7175:        newpi = &newai->play;
                   7176:        newri = &newai->record;
                   7177:        if (oldai) {
                   7178:                oldpi = &oldai->play;
                   7179:                oldri = &oldai->record;
                   7180:        }
                   7181:        error = 0;
                   7182:
                   7183:        /*
                   7184:         * It looks like unnecessary to halt HW mixers to set HW mixers.
                   7185:         * mixer_ioctl(MIXER_WRITE) also doesn't halt.
                   7186:         */
                   7187:
                   7188:        if (SPECIFIED(newpi->port)) {
                   7189:                if (oldai)
                   7190:                        oldpi->port = au_get_port(sc, &sc->sc_outports);
                   7191:                error = au_set_port(sc, &sc->sc_outports, newpi->port);
                   7192:                if (error) {
                   7193:                        device_printf(sc->sc_dev,
                   7194:                            "setting play.port=%d failed with %d\n",
                   7195:                            newpi->port, error);
                   7196:                        goto abort;
                   7197:                }
                   7198:        }
                   7199:        if (SPECIFIED(newri->port)) {
                   7200:                if (oldai)
                   7201:                        oldri->port = au_get_port(sc, &sc->sc_inports);
                   7202:                error = au_set_port(sc, &sc->sc_inports, newri->port);
                   7203:                if (error) {
                   7204:                        device_printf(sc->sc_dev,
                   7205:                            "setting record.port=%d failed with %d\n",
                   7206:                            newri->port, error);
                   7207:                        goto abort;
                   7208:                }
                   7209:        }
                   7210:
                   7211:        /* Backup play.{gain,balance} */
                   7212:        if (SPECIFIED(newpi->gain) || SPECIFIED_CH(newpi->balance)) {
                   7213:                au_get_gain(sc, &sc->sc_outports, &pgain, &pbalance);
                   7214:                if (oldai) {
                   7215:                        oldpi->gain = pgain;
                   7216:                        oldpi->balance = pbalance;
                   7217:                }
                   7218:        }
                   7219:        /* Backup record.{gain,balance} */
                   7220:        if (SPECIFIED(newri->gain) || SPECIFIED_CH(newri->balance)) {
                   7221:                au_get_gain(sc, &sc->sc_inports, &rgain, &rbalance);
                   7222:                if (oldai) {
                   7223:                        oldri->gain = rgain;
                   7224:                        oldri->balance = rbalance;
                   7225:                }
                   7226:        }
                   7227:        if (SPECIFIED(newpi->gain)) {
                   7228:                error = au_set_gain(sc, &sc->sc_outports,
                   7229:                    newpi->gain, pbalance);
                   7230:                if (error) {
                   7231:                        device_printf(sc->sc_dev,
                   7232:                            "setting play.gain=%d failed with %d\n",
                   7233:                            newpi->gain, error);
                   7234:                        goto abort;
                   7235:                }
                   7236:        }
                   7237:        if (SPECIFIED(newri->gain)) {
                   7238:                error = au_set_gain(sc, &sc->sc_inports,
                   7239:                    newri->gain, rbalance);
                   7240:                if (error) {
                   7241:                        device_printf(sc->sc_dev,
                   7242:                            "setting record.gain=%d failed with %d\n",
                   7243:                            newri->gain, error);
                   7244:                        goto abort;
                   7245:                }
                   7246:        }
                   7247:        if (SPECIFIED_CH(newpi->balance)) {
                   7248:                error = au_set_gain(sc, &sc->sc_outports,
                   7249:                    pgain, newpi->balance);
                   7250:                if (error) {
                   7251:                        device_printf(sc->sc_dev,
                   7252:                            "setting play.balance=%d failed with %d\n",
                   7253:                            newpi->balance, error);
                   7254:                        goto abort;
                   7255:                }
                   7256:        }
                   7257:        if (SPECIFIED_CH(newri->balance)) {
                   7258:                error = au_set_gain(sc, &sc->sc_inports,
                   7259:                    rgain, newri->balance);
                   7260:                if (error) {
                   7261:                        device_printf(sc->sc_dev,
                   7262:                            "setting record.balance=%d failed with %d\n",
                   7263:                            newri->balance, error);
                   7264:                        goto abort;
                   7265:                }
                   7266:        }
                   7267:
                   7268:        if (SPECIFIED(newai->monitor_gain) && sc->sc_monitor_port != -1) {
                   7269:                if (oldai)
                   7270:                        oldai->monitor_gain = au_get_monitor_gain(sc);
                   7271:                error = au_set_monitor_gain(sc, newai->monitor_gain);
                   7272:                if (error) {
                   7273:                        device_printf(sc->sc_dev,
                   7274:                            "setting monitor_gain=%d failed with %d\n",
                   7275:                            newai->monitor_gain, error);
                   7276:                        goto abort;
                   7277:                }
                   7278:        }
                   7279:
                   7280:        /* XXX TODO */
                   7281:        /* sc->sc_ai = *ai; */
                   7282:
                   7283:        error = 0;
                   7284: abort:
                   7285:        return error;
                   7286: }
                   7287:
                   7288: /*
                   7289:  * Setup the hardware with mixer format phwfmt, rhwfmt.
                   7290:  * The arguments have following restrictions:
                   7291:  * - setmode is the direction you want to set, AUMODE_PLAY or AUMODE_RECORD,
                   7292:  *   or both.
                   7293:  * - phwfmt and rhwfmt must not be NULL regardless of setmode.
                   7294:  * - On non-independent devices, phwfmt and rhwfmt must have the same
                   7295:  *   parameters.
                   7296:  * - pfil and rfil must be zero-filled.
                   7297:  * If successful,
                   7298:  * - pfil, rfil will be filled with filter information specified by the
1.77      isaki    7299:  *   hardware driver if necessary.
1.2       isaki    7300:  * and then returns 0.  Otherwise returns errno.
1.63      isaki    7301:  * Must be called without sc_lock held.
1.2       isaki    7302:  */
                   7303: static int
                   7304: audio_hw_set_format(struct audio_softc *sc, int setmode,
1.45      isaki    7305:        const audio_format2_t *phwfmt, const audio_format2_t *rhwfmt,
1.2       isaki    7306:        audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
                   7307: {
                   7308:        audio_params_t pp, rp;
                   7309:        int error;
                   7310:
                   7311:        KASSERT(phwfmt != NULL);
                   7312:        KASSERT(rhwfmt != NULL);
                   7313:
                   7314:        pp = format2_to_params(phwfmt);
                   7315:        rp = format2_to_params(rhwfmt);
                   7316:
1.63      isaki    7317:        mutex_enter(sc->sc_lock);
1.2       isaki    7318:        error = sc->hw_if->set_format(sc->hw_hdl, setmode,
                   7319:            &pp, &rp, pfil, rfil);
                   7320:        if (error) {
1.63      isaki    7321:                mutex_exit(sc->sc_lock);
1.2       isaki    7322:                device_printf(sc->sc_dev,
                   7323:                    "set_format failed with %d\n", error);
                   7324:                return error;
                   7325:        }
                   7326:
                   7327:        if (sc->hw_if->commit_settings) {
                   7328:                error = sc->hw_if->commit_settings(sc->hw_hdl);
                   7329:                if (error) {
1.63      isaki    7330:                        mutex_exit(sc->sc_lock);
1.2       isaki    7331:                        device_printf(sc->sc_dev,
                   7332:                            "commit_settings failed with %d\n", error);
                   7333:                        return error;
                   7334:                }
                   7335:        }
1.63      isaki    7336:        mutex_exit(sc->sc_lock);
1.2       isaki    7337:
                   7338:        return 0;
                   7339: }
                   7340:
                   7341: /*
                   7342:  * Fill audio_info structure.  If need_mixerinfo is true, it will also
                   7343:  * fill the hardware mixer information.
1.63      isaki    7344:  * Must be called with sc_exlock held and without sc_lock held.
1.2       isaki    7345:  */
                   7346: static int
                   7347: audiogetinfo(struct audio_softc *sc, struct audio_info *ai, int need_mixerinfo,
                   7348:        audio_file_t *file)
                   7349: {
                   7350:        struct audio_prinfo *ri, *pi;
                   7351:        audio_track_t *track;
                   7352:        audio_track_t *ptrack;
                   7353:        audio_track_t *rtrack;
                   7354:        int gain;
                   7355:
1.63      isaki    7356:        KASSERT(sc->sc_exlock);
1.2       isaki    7357:
                   7358:        ri = &ai->record;
                   7359:        pi = &ai->play;
                   7360:        ptrack = file->ptrack;
                   7361:        rtrack = file->rtrack;
                   7362:
                   7363:        memset(ai, 0, sizeof(*ai));
                   7364:
                   7365:        if (ptrack) {
                   7366:                pi->sample_rate = ptrack->usrbuf.fmt.sample_rate;
                   7367:                pi->channels    = ptrack->usrbuf.fmt.channels;
                   7368:                pi->precision   = ptrack->usrbuf.fmt.precision;
                   7369:                pi->encoding    = ptrack->usrbuf.fmt.encoding;
1.62      isaki    7370:                pi->pause       = ptrack->is_pause;
1.2       isaki    7371:        } else {
1.62      isaki    7372:                /* Use sticky parameters if the track is not available. */
                   7373:                pi->sample_rate = sc->sc_sound_pparams.sample_rate;
                   7374:                pi->channels    = sc->sc_sound_pparams.channels;
                   7375:                pi->precision   = sc->sc_sound_pparams.precision;
                   7376:                pi->encoding    = sc->sc_sound_pparams.encoding;
                   7377:                pi->pause       = sc->sc_sound_ppause;
1.2       isaki    7378:        }
                   7379:        if (rtrack) {
                   7380:                ri->sample_rate = rtrack->usrbuf.fmt.sample_rate;
                   7381:                ri->channels    = rtrack->usrbuf.fmt.channels;
                   7382:                ri->precision   = rtrack->usrbuf.fmt.precision;
                   7383:                ri->encoding    = rtrack->usrbuf.fmt.encoding;
1.62      isaki    7384:                ri->pause       = rtrack->is_pause;
1.2       isaki    7385:        } else {
1.62      isaki    7386:                /* Use sticky parameters if the track is not available. */
                   7387:                ri->sample_rate = sc->sc_sound_rparams.sample_rate;
                   7388:                ri->channels    = sc->sc_sound_rparams.channels;
                   7389:                ri->precision   = sc->sc_sound_rparams.precision;
                   7390:                ri->encoding    = sc->sc_sound_rparams.encoding;
                   7391:                ri->pause       = sc->sc_sound_rpause;
1.2       isaki    7392:        }
                   7393:
                   7394:        if (ptrack) {
                   7395:                pi->seek = ptrack->usrbuf.used;
                   7396:                pi->samples = ptrack->usrbuf_stamp;
                   7397:                pi->eof = ptrack->eofcounter;
                   7398:                pi->error = (ptrack->dropframes != 0) ? 1 : 0;
                   7399:                pi->open = 1;
                   7400:                pi->buffer_size = ptrack->usrbuf.capacity;
                   7401:        }
1.62      isaki    7402:        pi->waiting = 0;                /* open never hangs */
                   7403:        pi->active = sc->sc_pbusy;
                   7404:
1.2       isaki    7405:        if (rtrack) {
                   7406:                ri->seek = rtrack->usrbuf.used;
                   7407:                ri->samples = rtrack->usrbuf_stamp;
                   7408:                ri->eof = 0;
                   7409:                ri->error = (rtrack->dropframes != 0) ? 1 : 0;
                   7410:                ri->open = 1;
                   7411:                ri->buffer_size = rtrack->usrbuf.capacity;
                   7412:        }
1.62      isaki    7413:        ri->waiting = 0;                /* open never hangs */
                   7414:        ri->active = sc->sc_rbusy;
1.2       isaki    7415:
                   7416:        /*
                   7417:         * XXX There may be different number of channels between playback
                   7418:         *     and recording, so that blocksize also may be different.
                   7419:         *     But struct audio_info has an united blocksize...
                   7420:         *     Here, I use play info precedencely if ptrack is available,
                   7421:         *     otherwise record info.
                   7422:         *
                   7423:         * XXX hiwat/lowat is a playback-only parameter.  What should I
                   7424:         *     return for a record-only descriptor?
                   7425:         */
1.3       maya     7426:        track = ptrack ? ptrack : rtrack;
1.2       isaki    7427:        if (track) {
                   7428:                ai->blocksize = track->usrbuf_blksize;
                   7429:                ai->hiwat = track->usrbuf_usedhigh / track->usrbuf_blksize;
                   7430:                ai->lowat = track->usrbuf_usedlow / track->usrbuf_blksize;
                   7431:        }
                   7432:        ai->mode = file->mode;
                   7433:
1.62      isaki    7434:        /*
                   7435:         * For backward compatibility, we have to pad these five fields
                   7436:         * a fake non-zero value even if there are no tracks.
                   7437:         */
                   7438:        if (ptrack == NULL)
                   7439:                pi->buffer_size = 65536;
                   7440:        if (rtrack == NULL)
                   7441:                ri->buffer_size = 65536;
                   7442:        if (ptrack == NULL && rtrack == NULL) {
                   7443:                ai->blocksize = 2048;
                   7444:                ai->hiwat = ai->play.buffer_size / ai->blocksize;
                   7445:                ai->lowat = ai->hiwat * 3 / 4;
                   7446:        }
                   7447:
1.2       isaki    7448:        if (need_mixerinfo) {
1.63      isaki    7449:                mutex_enter(sc->sc_lock);
1.2       isaki    7450:
                   7451:                pi->port = au_get_port(sc, &sc->sc_outports);
                   7452:                ri->port = au_get_port(sc, &sc->sc_inports);
                   7453:
                   7454:                pi->avail_ports = sc->sc_outports.allports;
                   7455:                ri->avail_ports = sc->sc_inports.allports;
                   7456:
                   7457:                au_get_gain(sc, &sc->sc_outports, &pi->gain, &pi->balance);
                   7458:                au_get_gain(sc, &sc->sc_inports, &ri->gain, &ri->balance);
                   7459:
                   7460:                if (sc->sc_monitor_port != -1) {
                   7461:                        gain = au_get_monitor_gain(sc);
                   7462:                        if (gain != -1)
                   7463:                                ai->monitor_gain = gain;
                   7464:                }
1.63      isaki    7465:                mutex_exit(sc->sc_lock);
1.2       isaki    7466:        }
                   7467:
                   7468:        return 0;
                   7469: }
                   7470:
                   7471: /*
                   7472:  * Return true if playback is configured.
                   7473:  * This function can be used after audioattach.
                   7474:  */
                   7475: static bool
                   7476: audio_can_playback(struct audio_softc *sc)
                   7477: {
                   7478:
                   7479:        return (sc->sc_pmixer != NULL);
                   7480: }
                   7481:
                   7482: /*
                   7483:  * Return true if recording is configured.
                   7484:  * This function can be used after audioattach.
                   7485:  */
                   7486: static bool
                   7487: audio_can_capture(struct audio_softc *sc)
                   7488: {
                   7489:
                   7490:        return (sc->sc_rmixer != NULL);
                   7491: }
                   7492:
                   7493: /*
                   7494:  * Get the afp->index'th item from the valid one of format[].
                   7495:  * If found, stores it to afp->fmt and returns 0.  Otherwise return EINVAL.
                   7496:  *
                   7497:  * This is common routines for query_format.
                   7498:  * If your hardware driver has struct audio_format[], the simplest case
                   7499:  * you can write your query_format interface as follows:
                   7500:  *
                   7501:  * struct audio_format foo_format[] = { ... };
                   7502:  *
                   7503:  * int
                   7504:  * foo_query_format(void *hdl, audio_format_query_t *afp)
                   7505:  * {
                   7506:  *   return audio_query_format(foo_format, __arraycount(foo_format), afp);
                   7507:  * }
                   7508:  */
                   7509: int
                   7510: audio_query_format(const struct audio_format *format, int nformats,
                   7511:        audio_format_query_t *afp)
                   7512: {
                   7513:        const struct audio_format *f;
                   7514:        int idx;
                   7515:        int i;
                   7516:
                   7517:        idx = 0;
                   7518:        for (i = 0; i < nformats; i++) {
                   7519:                f = &format[i];
                   7520:                if (!AUFMT_IS_VALID(f))
                   7521:                        continue;
                   7522:                if (afp->index == idx) {
                   7523:                        afp->fmt = *f;
                   7524:                        return 0;
                   7525:                }
                   7526:                idx++;
                   7527:        }
                   7528:        return EINVAL;
                   7529: }
                   7530:
                   7531: /*
                   7532:  * This function is provided for the hardware driver's set_format() to
                   7533:  * find index matches with 'param' from array of audio_format_t 'formats'.
                   7534:  * 'mode' is either of AUMODE_PLAY or AUMODE_RECORD.
                   7535:  * It returns the matched index and never fails.  Because param passed to
                   7536:  * set_format() is selected from query_format().
                   7537:  * This function will be an alternative to auconv_set_converter() to
                   7538:  * find index.
                   7539:  */
                   7540: int
                   7541: audio_indexof_format(const struct audio_format *formats, int nformats,
                   7542:        int mode, const audio_params_t *param)
                   7543: {
                   7544:        const struct audio_format *f;
                   7545:        int index;
                   7546:        int j;
                   7547:
                   7548:        for (index = 0; index < nformats; index++) {
                   7549:                f = &formats[index];
                   7550:
                   7551:                if (!AUFMT_IS_VALID(f))
                   7552:                        continue;
                   7553:                if ((f->mode & mode) == 0)
                   7554:                        continue;
                   7555:                if (f->encoding != param->encoding)
                   7556:                        continue;
                   7557:                if (f->validbits != param->precision)
                   7558:                        continue;
                   7559:                if (f->channels != param->channels)
                   7560:                        continue;
                   7561:
                   7562:                if (f->frequency_type == 0) {
                   7563:                        if (param->sample_rate < f->frequency[0] ||
                   7564:                            param->sample_rate > f->frequency[1])
                   7565:                                continue;
                   7566:                } else {
                   7567:                        for (j = 0; j < f->frequency_type; j++) {
                   7568:                                if (param->sample_rate == f->frequency[j])
                   7569:                                        break;
                   7570:                        }
                   7571:                        if (j == f->frequency_type)
                   7572:                                continue;
                   7573:                }
                   7574:
                   7575:                /* Then, matched */
                   7576:                return index;
                   7577:        }
                   7578:
                   7579:        /* Not matched.  This should not be happened. */
                   7580:        panic("%s: cannot find matched format\n", __func__);
                   7581: }
                   7582:
                   7583: /*
                   7584:  * Get or set hardware blocksize in msec.
                   7585:  * XXX It's for debug.
                   7586:  */
                   7587: static int
                   7588: audio_sysctl_blk_ms(SYSCTLFN_ARGS)
                   7589: {
                   7590:        struct sysctlnode node;
                   7591:        struct audio_softc *sc;
                   7592:        audio_format2_t phwfmt;
                   7593:        audio_format2_t rhwfmt;
                   7594:        audio_filter_reg_t pfil;
                   7595:        audio_filter_reg_t rfil;
                   7596:        int t;
                   7597:        int old_blk_ms;
                   7598:        int mode;
                   7599:        int error;
                   7600:
                   7601:        node = *rnode;
                   7602:        sc = node.sysctl_data;
                   7603:
1.63      isaki    7604:        error = audio_exlock_enter(sc);
                   7605:        if (error)
                   7606:                return error;
1.2       isaki    7607:
                   7608:        old_blk_ms = sc->sc_blk_ms;
                   7609:        t = old_blk_ms;
                   7610:        node.sysctl_data = &t;
                   7611:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   7612:        if (error || newp == NULL)
                   7613:                goto abort;
                   7614:
                   7615:        if (t < 0) {
                   7616:                error = EINVAL;
                   7617:                goto abort;
                   7618:        }
                   7619:
                   7620:        if (sc->sc_popens + sc->sc_ropens > 0) {
                   7621:                error = EBUSY;
                   7622:                goto abort;
                   7623:        }
                   7624:        sc->sc_blk_ms = t;
                   7625:        mode = 0;
                   7626:        if (sc->sc_pmixer) {
                   7627:                mode |= AUMODE_PLAY;
                   7628:                phwfmt = sc->sc_pmixer->hwbuf.fmt;
                   7629:        }
                   7630:        if (sc->sc_rmixer) {
                   7631:                mode |= AUMODE_RECORD;
                   7632:                rhwfmt = sc->sc_rmixer->hwbuf.fmt;
                   7633:        }
                   7634:
                   7635:        /* re-init hardware */
                   7636:        memset(&pfil, 0, sizeof(pfil));
                   7637:        memset(&rfil, 0, sizeof(rfil));
                   7638:        error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
                   7639:        if (error) {
                   7640:                goto abort;
                   7641:        }
                   7642:
                   7643:        /* re-init track mixer */
                   7644:        error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
                   7645:        if (error) {
                   7646:                /* Rollback */
                   7647:                sc->sc_blk_ms = old_blk_ms;
                   7648:                audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
                   7649:                goto abort;
                   7650:        }
                   7651:        error = 0;
                   7652: abort:
1.63      isaki    7653:        audio_exlock_exit(sc);
1.2       isaki    7654:        return error;
                   7655: }
                   7656:
                   7657: /*
                   7658:  * Get or set multiuser mode.
                   7659:  */
                   7660: static int
                   7661: audio_sysctl_multiuser(SYSCTLFN_ARGS)
                   7662: {
                   7663:        struct sysctlnode node;
                   7664:        struct audio_softc *sc;
1.6       nakayama 7665:        bool t;
                   7666:        int error;
1.2       isaki    7667:
                   7668:        node = *rnode;
                   7669:        sc = node.sysctl_data;
                   7670:
1.63      isaki    7671:        error = audio_exlock_enter(sc);
                   7672:        if (error)
                   7673:                return error;
1.2       isaki    7674:
                   7675:        t = sc->sc_multiuser;
                   7676:        node.sysctl_data = &t;
                   7677:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   7678:        if (error || newp == NULL)
                   7679:                goto abort;
                   7680:
                   7681:        sc->sc_multiuser = t;
                   7682:        error = 0;
                   7683: abort:
1.63      isaki    7684:        audio_exlock_exit(sc);
1.2       isaki    7685:        return error;
                   7686: }
                   7687:
                   7688: #if defined(AUDIO_DEBUG)
                   7689: /*
                   7690:  * Get or set debug verbose level. (0..4)
                   7691:  * XXX It's for debug.
                   7692:  * XXX It is not separated per device.
                   7693:  */
                   7694: static int
                   7695: audio_sysctl_debug(SYSCTLFN_ARGS)
                   7696: {
                   7697:        struct sysctlnode node;
                   7698:        int t;
                   7699:        int error;
                   7700:
                   7701:        node = *rnode;
                   7702:        t = audiodebug;
                   7703:        node.sysctl_data = &t;
                   7704:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   7705:        if (error || newp == NULL)
                   7706:                return error;
                   7707:
                   7708:        if (t < 0 || t > 4)
                   7709:                return EINVAL;
                   7710:        audiodebug = t;
                   7711:        printf("audio: audiodebug = %d\n", audiodebug);
                   7712:        return 0;
                   7713: }
                   7714: #endif /* AUDIO_DEBUG */
                   7715:
                   7716: #ifdef AUDIO_PM_IDLE
                   7717: static void
                   7718: audio_idle(void *arg)
                   7719: {
                   7720:        device_t dv = arg;
                   7721:        struct audio_softc *sc = device_private(dv);
                   7722:
                   7723: #ifdef PNP_DEBUG
                   7724:        extern int pnp_debug_idle;
                   7725:        if (pnp_debug_idle)
                   7726:                printf("%s: idle handler called\n", device_xname(dv));
                   7727: #endif
                   7728:
                   7729:        sc->sc_idle = true;
                   7730:
                   7731:        /* XXX joerg Make pmf_device_suspend handle children? */
                   7732:        if (!pmf_device_suspend(dv, PMF_Q_SELF))
                   7733:                return;
                   7734:
                   7735:        if (!pmf_device_suspend(sc->hw_dev, PMF_Q_SELF))
                   7736:                pmf_device_resume(dv, PMF_Q_SELF);
                   7737: }
                   7738:
                   7739: static void
                   7740: audio_activity(device_t dv, devactive_t type)
                   7741: {
                   7742:        struct audio_softc *sc = device_private(dv);
                   7743:
                   7744:        if (type != DVA_SYSTEM)
                   7745:                return;
                   7746:
                   7747:        callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz);
                   7748:
                   7749:        sc->sc_idle = false;
                   7750:        if (!device_is_active(dv)) {
                   7751:                /* XXX joerg How to deal with a failing resume... */
                   7752:                pmf_device_resume(sc->hw_dev, PMF_Q_SELF);
                   7753:                pmf_device_resume(dv, PMF_Q_SELF);
                   7754:        }
                   7755: }
                   7756: #endif
                   7757:
                   7758: static bool
                   7759: audio_suspend(device_t dv, const pmf_qual_t *qual)
                   7760: {
                   7761:        struct audio_softc *sc = device_private(dv);
                   7762:        int error;
                   7763:
1.63      isaki    7764:        error = audio_exlock_mutex_enter(sc);
1.2       isaki    7765:        if (error)
                   7766:                return error;
1.75      isaki    7767:        sc->sc_suspending = true;
1.2       isaki    7768:        audio_mixer_capture(sc);
                   7769:
                   7770:        if (sc->sc_pbusy) {
                   7771:                audio_pmixer_halt(sc);
1.75      isaki    7772:                /* Reuse this as need-to-restart flag while suspending */
                   7773:                sc->sc_pbusy = true;
1.2       isaki    7774:        }
                   7775:        if (sc->sc_rbusy) {
                   7776:                audio_rmixer_halt(sc);
1.75      isaki    7777:                /* Reuse this as need-to-restart flag while suspending */
                   7778:                sc->sc_rbusy = true;
1.2       isaki    7779:        }
                   7780:
                   7781: #ifdef AUDIO_PM_IDLE
                   7782:        callout_halt(&sc->sc_idle_counter, sc->sc_lock);
                   7783: #endif
1.63      isaki    7784:        audio_exlock_mutex_exit(sc);
1.2       isaki    7785:
                   7786:        return true;
                   7787: }
                   7788:
                   7789: static bool
                   7790: audio_resume(device_t dv, const pmf_qual_t *qual)
                   7791: {
                   7792:        struct audio_softc *sc = device_private(dv);
                   7793:        struct audio_info ai;
                   7794:        int error;
                   7795:
1.63      isaki    7796:        error = audio_exlock_mutex_enter(sc);
1.2       isaki    7797:        if (error)
                   7798:                return error;
                   7799:
1.75      isaki    7800:        sc->sc_suspending = false;
1.2       isaki    7801:        audio_mixer_restore(sc);
                   7802:        /* XXX ? */
                   7803:        AUDIO_INITINFO(&ai);
                   7804:        audio_hw_setinfo(sc, &ai, NULL);
                   7805:
1.75      isaki    7806:        /*
                   7807:         * During from suspend to resume here, sc_[pr]busy is used as
                   7808:         * need-to-restart flag temporarily.  After this point,
                   7809:         * sc_[pr]busy is returned to its original usage (busy flag).
                   7810:         * And note that sc_[pr]busy must be false to call [pr]mixer_start().
                   7811:         */
                   7812:        if (sc->sc_pbusy) {
                   7813:                /* pmixer_start() requires pbusy is false */
                   7814:                sc->sc_pbusy = false;
1.2       isaki    7815:                audio_pmixer_start(sc, true);
1.75      isaki    7816:        }
                   7817:        if (sc->sc_rbusy) {
                   7818:                /* rmixer_start() requires rbusy is false */
                   7819:                sc->sc_rbusy = false;
1.2       isaki    7820:                audio_rmixer_start(sc);
1.75      isaki    7821:        }
1.2       isaki    7822:
1.63      isaki    7823:        audio_exlock_mutex_exit(sc);
1.2       isaki    7824:
                   7825:        return true;
                   7826: }
                   7827:
1.8       isaki    7828: #if defined(AUDIO_DEBUG)
1.2       isaki    7829: static void
                   7830: audio_format2_tostr(char *buf, size_t bufsize, const audio_format2_t *fmt)
                   7831: {
                   7832:        int n;
                   7833:
                   7834:        n = 0;
                   7835:        n += snprintf(buf + n, bufsize - n, "%s",
                   7836:            audio_encoding_name(fmt->encoding));
                   7837:        if (fmt->precision == fmt->stride) {
                   7838:                n += snprintf(buf + n, bufsize - n, " %dbit", fmt->precision);
                   7839:        } else {
                   7840:                n += snprintf(buf + n, bufsize - n, " %d/%dbit",
                   7841:                        fmt->precision, fmt->stride);
                   7842:        }
                   7843:
                   7844:        snprintf(buf + n, bufsize - n, " %uch %uHz",
                   7845:            fmt->channels, fmt->sample_rate);
                   7846: }
                   7847: #endif
                   7848:
                   7849: #if defined(AUDIO_DEBUG)
                   7850: static void
                   7851: audio_print_format2(const char *s, const audio_format2_t *fmt)
                   7852: {
                   7853:        char fmtstr[64];
                   7854:
                   7855:        audio_format2_tostr(fmtstr, sizeof(fmtstr), fmt);
                   7856:        printf("%s %s\n", s, fmtstr);
                   7857: }
                   7858: #endif
                   7859:
                   7860: #ifdef DIAGNOSTIC
                   7861: void
1.47      isaki    7862: audio_diagnostic_format2(const char *where, const audio_format2_t *fmt)
1.2       isaki    7863: {
                   7864:
1.47      isaki    7865:        KASSERTMSG(fmt, "called from %s", where);
1.2       isaki    7866:
                   7867:        /* XXX MSM6258 vs(4) only has 4bit stride format. */
                   7868:        if (fmt->encoding == AUDIO_ENCODING_ADPCM) {
                   7869:                KASSERTMSG(fmt->stride == 4 || fmt->stride == 8,
1.47      isaki    7870:                    "called from %s: fmt->stride=%d", where, fmt->stride);
1.2       isaki    7871:        } else {
                   7872:                KASSERTMSG(fmt->stride % NBBY == 0,
1.47      isaki    7873:                    "called from %s: fmt->stride=%d", where, fmt->stride);
1.2       isaki    7874:        }
                   7875:        KASSERTMSG(fmt->precision <= fmt->stride,
1.47      isaki    7876:            "called from %s: fmt->precision=%d fmt->stride=%d",
                   7877:            where, fmt->precision, fmt->stride);
1.2       isaki    7878:        KASSERTMSG(1 <= fmt->channels && fmt->channels <= AUDIO_MAX_CHANNELS,
1.47      isaki    7879:            "called from %s: fmt->channels=%d", where, fmt->channels);
1.2       isaki    7880:
                   7881:        /* XXX No check for encodings? */
                   7882: }
                   7883:
                   7884: void
1.47      isaki    7885: audio_diagnostic_filter_arg(const char *where, const audio_filter_arg_t *arg)
1.2       isaki    7886: {
                   7887:
                   7888:        KASSERT(arg != NULL);
                   7889:        KASSERT(arg->src != NULL);
                   7890:        KASSERT(arg->dst != NULL);
1.47      isaki    7891:        audio_diagnostic_format2(where, arg->srcfmt);
                   7892:        audio_diagnostic_format2(where, arg->dstfmt);
                   7893:        KASSERT(arg->count > 0);
1.2       isaki    7894: }
                   7895:
                   7896: void
1.47      isaki    7897: audio_diagnostic_ring(const char *where, const audio_ring_t *ring)
1.2       isaki    7898: {
                   7899:
1.47      isaki    7900:        KASSERTMSG(ring, "called from %s", where);
                   7901:        audio_diagnostic_format2(where, &ring->fmt);
1.2       isaki    7902:        KASSERTMSG(0 <= ring->capacity && ring->capacity < INT_MAX / 2,
1.47      isaki    7903:            "called from %s: ring->capacity=%d", where, ring->capacity);
1.2       isaki    7904:        KASSERTMSG(0 <= ring->used && ring->used <= ring->capacity,
1.47      isaki    7905:            "called from %s: ring->used=%d ring->capacity=%d",
                   7906:            where, ring->used, ring->capacity);
1.2       isaki    7907:        if (ring->capacity == 0) {
                   7908:                KASSERTMSG(ring->mem == NULL,
1.47      isaki    7909:                    "called from %s: capacity == 0 but mem != NULL", where);
1.2       isaki    7910:        } else {
                   7911:                KASSERTMSG(ring->mem != NULL,
1.47      isaki    7912:                    "called from %s: capacity != 0 but mem == NULL", where);
1.2       isaki    7913:                KASSERTMSG(0 <= ring->head && ring->head < ring->capacity,
1.47      isaki    7914:                    "called from %s: ring->head=%d ring->capacity=%d",
                   7915:                    where, ring->head, ring->capacity);
1.2       isaki    7916:        }
                   7917: }
                   7918: #endif /* DIAGNOSTIC */
                   7919:
                   7920:
                   7921: /*
                   7922:  * Mixer driver
                   7923:  */
1.63      isaki    7924:
                   7925: /*
                   7926:  * Must be called without sc_lock held.
                   7927:  */
1.2       isaki    7928: int
                   7929: mixer_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
                   7930:        struct lwp *l)
                   7931: {
                   7932:        struct file *fp;
                   7933:        audio_file_t *af;
                   7934:        int error, fd;
                   7935:
                   7936:        TRACE(1, "flags=0x%x", flags);
                   7937:
                   7938:        error = fd_allocfile(&fp, &fd);
                   7939:        if (error)
                   7940:                return error;
                   7941:
                   7942:        af = kmem_zalloc(sizeof(*af), KM_SLEEP);
                   7943:        af->sc = sc;
                   7944:        af->dev = dev;
                   7945:
                   7946:        error = fd_clone(fp, fd, flags, &audio_fileops, af);
                   7947:        KASSERT(error == EMOVEFD);
                   7948:
                   7949:        return error;
                   7950: }
                   7951:
                   7952: /*
1.41      isaki    7953:  * Add a process to those to be signalled on mixer activity.
                   7954:  * If the process has already been added, do nothing.
1.63      isaki    7955:  * Must be called with sc_exlock held and without sc_lock held.
1.41      isaki    7956:  */
                   7957: static void
                   7958: mixer_async_add(struct audio_softc *sc, pid_t pid)
                   7959: {
                   7960:        int i;
                   7961:
1.63      isaki    7962:        KASSERT(sc->sc_exlock);
1.41      isaki    7963:
                   7964:        /* If already exists, returns without doing anything. */
                   7965:        for (i = 0; i < sc->sc_am_used; i++) {
                   7966:                if (sc->sc_am[i] == pid)
                   7967:                        return;
                   7968:        }
                   7969:
                   7970:        /* Extend array if necessary. */
                   7971:        if (sc->sc_am_used >= sc->sc_am_capacity) {
                   7972:                sc->sc_am_capacity += AM_CAPACITY;
                   7973:                sc->sc_am = kern_realloc(sc->sc_am,
                   7974:                    sc->sc_am_capacity * sizeof(pid_t), M_WAITOK);
                   7975:                TRACE(2, "realloc am_capacity=%d", sc->sc_am_capacity);
                   7976:        }
                   7977:
                   7978:        TRACE(2, "am[%d]=%d", sc->sc_am_used, (int)pid);
                   7979:        sc->sc_am[sc->sc_am_used++] = pid;
                   7980: }
                   7981:
                   7982: /*
1.2       isaki    7983:  * Remove a process from those to be signalled on mixer activity.
1.41      isaki    7984:  * If the process has not been added, do nothing.
1.63      isaki    7985:  * Must be called with sc_exlock held and without sc_lock held.
1.2       isaki    7986:  */
                   7987: static void
1.41      isaki    7988: mixer_async_remove(struct audio_softc *sc, pid_t pid)
1.2       isaki    7989: {
1.41      isaki    7990:        int i;
1.2       isaki    7991:
1.63      isaki    7992:        KASSERT(sc->sc_exlock);
1.2       isaki    7993:
1.41      isaki    7994:        for (i = 0; i < sc->sc_am_used; i++) {
                   7995:                if (sc->sc_am[i] == pid) {
                   7996:                        sc->sc_am[i] = sc->sc_am[--sc->sc_am_used];
                   7997:                        TRACE(2, "am[%d](%d) removed, used=%d",
                   7998:                            i, (int)pid, sc->sc_am_used);
                   7999:
                   8000:                        /* Empty array if no longer necessary. */
                   8001:                        if (sc->sc_am_used == 0) {
                   8002:                                kern_free(sc->sc_am);
                   8003:                                sc->sc_am = NULL;
                   8004:                                sc->sc_am_capacity = 0;
                   8005:                                TRACE(2, "released");
                   8006:                        }
1.2       isaki    8007:                        return;
                   8008:                }
                   8009:        }
                   8010: }
                   8011:
                   8012: /*
                   8013:  * Signal all processes waiting for the mixer.
1.63      isaki    8014:  * Must be called with sc_exlock held.
1.2       isaki    8015:  */
                   8016: static void
                   8017: mixer_signal(struct audio_softc *sc)
                   8018: {
                   8019:        proc_t *p;
1.41      isaki    8020:        int i;
                   8021:
1.63      isaki    8022:        KASSERT(sc->sc_exlock);
1.2       isaki    8023:
1.41      isaki    8024:        for (i = 0; i < sc->sc_am_used; i++) {
1.70      ad       8025:                mutex_enter(&proc_lock);
1.41      isaki    8026:                p = proc_find(sc->sc_am[i]);
                   8027:                if (p)
1.2       isaki    8028:                        psignal(p, SIGIO);
1.70      ad       8029:                mutex_exit(&proc_lock);
1.2       isaki    8030:        }
                   8031: }
                   8032:
                   8033: /*
                   8034:  * Close a mixer device
                   8035:  */
                   8036: int
                   8037: mixer_close(struct audio_softc *sc, audio_file_t *file)
                   8038: {
1.63      isaki    8039:        int error;
1.2       isaki    8040:
1.63      isaki    8041:        error = audio_exlock_enter(sc);
                   8042:        if (error)
                   8043:                return error;
1.2       isaki    8044:        TRACE(1, "");
1.41      isaki    8045:        mixer_async_remove(sc, curproc->p_pid);
1.63      isaki    8046:        audio_exlock_exit(sc);
1.2       isaki    8047:
                   8048:        return 0;
                   8049: }
                   8050:
1.42      isaki    8051: /*
                   8052:  * Must be called without sc_lock nor sc_exlock held.
                   8053:  */
1.2       isaki    8054: int
                   8055: mixer_ioctl(struct audio_softc *sc, u_long cmd, void *addr, int flag,
                   8056:        struct lwp *l)
                   8057: {
                   8058:        mixer_devinfo_t *mi;
                   8059:        mixer_ctrl_t *mc;
                   8060:        int error;
                   8061:
                   8062:        TRACE(2, "(%lu,'%c',%lu)",
                   8063:            IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd & 0xff);
                   8064:        error = EINVAL;
                   8065:
                   8066:        /* we can return cached values if we are sleeping */
                   8067:        if (cmd != AUDIO_MIXER_READ) {
                   8068:                mutex_enter(sc->sc_lock);
                   8069:                device_active(sc->sc_dev, DVA_SYSTEM);
                   8070:                mutex_exit(sc->sc_lock);
                   8071:        }
                   8072:
                   8073:        switch (cmd) {
                   8074:        case FIOASYNC:
1.63      isaki    8075:                error = audio_exlock_enter(sc);
                   8076:                if (error)
                   8077:                        break;
1.2       isaki    8078:                if (*(int *)addr) {
1.41      isaki    8079:                        mixer_async_add(sc, curproc->p_pid);
1.2       isaki    8080:                } else {
1.41      isaki    8081:                        mixer_async_remove(sc, curproc->p_pid);
1.2       isaki    8082:                }
1.63      isaki    8083:                audio_exlock_exit(sc);
1.2       isaki    8084:                break;
                   8085:
                   8086:        case AUDIO_GETDEV:
                   8087:                TRACE(2, "AUDIO_GETDEV");
1.63      isaki    8088:                mutex_enter(sc->sc_lock);
1.2       isaki    8089:                error = sc->hw_if->getdev(sc->hw_hdl, (audio_device_t *)addr);
1.63      isaki    8090:                mutex_exit(sc->sc_lock);
1.2       isaki    8091:                break;
                   8092:
                   8093:        case AUDIO_MIXER_DEVINFO:
                   8094:                TRACE(2, "AUDIO_MIXER_DEVINFO");
                   8095:                mi = (mixer_devinfo_t *)addr;
                   8096:
                   8097:                mi->un.v.delta = 0; /* default */
                   8098:                mutex_enter(sc->sc_lock);
                   8099:                error = audio_query_devinfo(sc, mi);
                   8100:                mutex_exit(sc->sc_lock);
                   8101:                break;
                   8102:
                   8103:        case AUDIO_MIXER_READ:
                   8104:                TRACE(2, "AUDIO_MIXER_READ");
                   8105:                mc = (mixer_ctrl_t *)addr;
                   8106:
1.63      isaki    8107:                error = audio_exlock_mutex_enter(sc);
1.2       isaki    8108:                if (error)
                   8109:                        break;
                   8110:                if (device_is_active(sc->hw_dev))
                   8111:                        error = audio_get_port(sc, mc);
                   8112:                else if (mc->dev < 0 || mc->dev >= sc->sc_nmixer_states)
                   8113:                        error = ENXIO;
                   8114:                else {
                   8115:                        int dev = mc->dev;
                   8116:                        memcpy(mc, &sc->sc_mixer_state[dev],
                   8117:                            sizeof(mixer_ctrl_t));
                   8118:                        error = 0;
                   8119:                }
1.63      isaki    8120:                audio_exlock_mutex_exit(sc);
1.2       isaki    8121:                break;
                   8122:
                   8123:        case AUDIO_MIXER_WRITE:
                   8124:                TRACE(2, "AUDIO_MIXER_WRITE");
1.63      isaki    8125:                error = audio_exlock_mutex_enter(sc);
1.2       isaki    8126:                if (error)
                   8127:                        break;
                   8128:                error = audio_set_port(sc, (mixer_ctrl_t *)addr);
                   8129:                if (error) {
1.63      isaki    8130:                        audio_exlock_mutex_exit(sc);
1.2       isaki    8131:                        break;
                   8132:                }
                   8133:
                   8134:                if (sc->hw_if->commit_settings) {
                   8135:                        error = sc->hw_if->commit_settings(sc->hw_hdl);
                   8136:                        if (error) {
1.63      isaki    8137:                                audio_exlock_mutex_exit(sc);
1.2       isaki    8138:                                break;
                   8139:                        }
                   8140:                }
1.63      isaki    8141:                mutex_exit(sc->sc_lock);
1.2       isaki    8142:                mixer_signal(sc);
1.63      isaki    8143:                audio_exlock_exit(sc);
1.2       isaki    8144:                break;
                   8145:
                   8146:        default:
                   8147:                if (sc->hw_if->dev_ioctl) {
1.63      isaki    8148:                        mutex_enter(sc->sc_lock);
1.2       isaki    8149:                        error = sc->hw_if->dev_ioctl(sc->hw_hdl,
                   8150:                            cmd, addr, flag, l);
1.63      isaki    8151:                        mutex_exit(sc->sc_lock);
1.2       isaki    8152:                } else
                   8153:                        error = EINVAL;
                   8154:                break;
                   8155:        }
                   8156:        TRACE(2, "(%lu,'%c',%lu) result %d",
                   8157:            IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd & 0xff, error);
                   8158:        return error;
                   8159: }
                   8160:
                   8161: /*
                   8162:  * Must be called with sc_lock held.
                   8163:  */
                   8164: int
                   8165: au_portof(struct audio_softc *sc, char *name, int class)
                   8166: {
                   8167:        mixer_devinfo_t mi;
                   8168:
                   8169:        KASSERT(mutex_owned(sc->sc_lock));
                   8170:
                   8171:        for (mi.index = 0; audio_query_devinfo(sc, &mi) == 0; mi.index++) {
                   8172:                if (mi.mixer_class == class && strcmp(mi.label.name, name) == 0)
                   8173:                        return mi.index;
                   8174:        }
                   8175:        return -1;
                   8176: }
                   8177:
                   8178: /*
                   8179:  * Must be called with sc_lock held.
                   8180:  */
                   8181: void
                   8182: au_setup_ports(struct audio_softc *sc, struct au_mixer_ports *ports,
                   8183:        mixer_devinfo_t *mi, const struct portname *tbl)
                   8184: {
                   8185:        int i, j;
                   8186:
                   8187:        KASSERT(mutex_owned(sc->sc_lock));
                   8188:
                   8189:        ports->index = mi->index;
                   8190:        if (mi->type == AUDIO_MIXER_ENUM) {
                   8191:                ports->isenum = true;
                   8192:                for(i = 0; tbl[i].name; i++)
                   8193:                    for(j = 0; j < mi->un.e.num_mem; j++)
                   8194:                        if (strcmp(mi->un.e.member[j].label.name,
                   8195:                                                    tbl[i].name) == 0) {
                   8196:                                ports->allports |= tbl[i].mask;
                   8197:                                ports->aumask[ports->nports] = tbl[i].mask;
                   8198:                                ports->misel[ports->nports] =
                   8199:                                    mi->un.e.member[j].ord;
                   8200:                                ports->miport[ports->nports] =
                   8201:                                    au_portof(sc, mi->un.e.member[j].label.name,
                   8202:                                    mi->mixer_class);
                   8203:                                if (ports->mixerout != -1 &&
                   8204:                                    ports->miport[ports->nports] != -1)
                   8205:                                        ports->isdual = true;
                   8206:                                ++ports->nports;
                   8207:                        }
                   8208:        } else if (mi->type == AUDIO_MIXER_SET) {
                   8209:                for(i = 0; tbl[i].name; i++)
                   8210:                    for(j = 0; j < mi->un.s.num_mem; j++)
                   8211:                        if (strcmp(mi->un.s.member[j].label.name,
                   8212:                                                tbl[i].name) == 0) {
                   8213:                                ports->allports |= tbl[i].mask;
                   8214:                                ports->aumask[ports->nports] = tbl[i].mask;
                   8215:                                ports->misel[ports->nports] =
                   8216:                                    mi->un.s.member[j].mask;
                   8217:                                ports->miport[ports->nports] =
                   8218:                                    au_portof(sc, mi->un.s.member[j].label.name,
                   8219:                                    mi->mixer_class);
                   8220:                                ++ports->nports;
                   8221:                        }
                   8222:        }
                   8223: }
                   8224:
                   8225: /*
                   8226:  * Must be called with sc_lock && sc_exlock held.
                   8227:  */
                   8228: int
                   8229: au_set_lr_value(struct audio_softc *sc, mixer_ctrl_t *ct, int l, int r)
                   8230: {
                   8231:
                   8232:        KASSERT(mutex_owned(sc->sc_lock));
                   8233:        KASSERT(sc->sc_exlock);
                   8234:
                   8235:        ct->type = AUDIO_MIXER_VALUE;
                   8236:        ct->un.value.num_channels = 2;
                   8237:        ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
                   8238:        ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
                   8239:        if (audio_set_port(sc, ct) == 0)
                   8240:                return 0;
                   8241:        ct->un.value.num_channels = 1;
                   8242:        ct->un.value.level[AUDIO_MIXER_LEVEL_MONO] = (l+r)/2;
                   8243:        return audio_set_port(sc, ct);
                   8244: }
                   8245:
                   8246: /*
                   8247:  * Must be called with sc_lock && sc_exlock held.
                   8248:  */
                   8249: int
                   8250: au_get_lr_value(struct audio_softc *sc, mixer_ctrl_t *ct, int *l, int *r)
                   8251: {
                   8252:        int error;
                   8253:
                   8254:        KASSERT(mutex_owned(sc->sc_lock));
                   8255:        KASSERT(sc->sc_exlock);
                   8256:
                   8257:        ct->un.value.num_channels = 2;
                   8258:        if (audio_get_port(sc, ct) == 0) {
                   8259:                *l = ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
                   8260:                *r = ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
                   8261:        } else {
                   8262:                ct->un.value.num_channels = 1;
                   8263:                error = audio_get_port(sc, ct);
                   8264:                if (error)
                   8265:                        return error;
                   8266:                *r = *l = ct->un.value.level[AUDIO_MIXER_LEVEL_MONO];
                   8267:        }
                   8268:        return 0;
                   8269: }
                   8270:
                   8271: /*
                   8272:  * Must be called with sc_lock && sc_exlock held.
                   8273:  */
                   8274: int
                   8275: au_set_gain(struct audio_softc *sc, struct au_mixer_ports *ports,
                   8276:        int gain, int balance)
                   8277: {
                   8278:        mixer_ctrl_t ct;
                   8279:        int i, error;
                   8280:        int l, r;
                   8281:        u_int mask;
                   8282:        int nset;
                   8283:
                   8284:        KASSERT(mutex_owned(sc->sc_lock));
                   8285:        KASSERT(sc->sc_exlock);
                   8286:
                   8287:        if (balance == AUDIO_MID_BALANCE) {
                   8288:                l = r = gain;
                   8289:        } else if (balance < AUDIO_MID_BALANCE) {
                   8290:                l = gain;
                   8291:                r = (balance * gain) / AUDIO_MID_BALANCE;
                   8292:        } else {
                   8293:                r = gain;
                   8294:                l = ((AUDIO_RIGHT_BALANCE - balance) * gain)
                   8295:                    / AUDIO_MID_BALANCE;
                   8296:        }
                   8297:        TRACE(2, "gain=%d balance=%d, l=%d r=%d", gain, balance, l, r);
                   8298:
                   8299:        if (ports->index == -1) {
                   8300:        usemaster:
                   8301:                if (ports->master == -1)
                   8302:                        return 0; /* just ignore it silently */
                   8303:                ct.dev = ports->master;
                   8304:                error = au_set_lr_value(sc, &ct, l, r);
                   8305:        } else {
                   8306:                ct.dev = ports->index;
                   8307:                if (ports->isenum) {
                   8308:                        ct.type = AUDIO_MIXER_ENUM;
                   8309:                        error = audio_get_port(sc, &ct);
                   8310:                        if (error)
                   8311:                                return error;
                   8312:                        if (ports->isdual) {
                   8313:                                if (ports->cur_port == -1)
                   8314:                                        ct.dev = ports->master;
                   8315:                                else
                   8316:                                        ct.dev = ports->miport[ports->cur_port];
                   8317:                                error = au_set_lr_value(sc, &ct, l, r);
                   8318:                        } else {
                   8319:                                for(i = 0; i < ports->nports; i++)
                   8320:                                    if (ports->misel[i] == ct.un.ord) {
                   8321:                                            ct.dev = ports->miport[i];
                   8322:                                            if (ct.dev == -1 ||
                   8323:                                                au_set_lr_value(sc, &ct, l, r))
                   8324:                                                    goto usemaster;
                   8325:                                            else
                   8326:                                                    break;
                   8327:                                    }
                   8328:                        }
                   8329:                } else {
                   8330:                        ct.type = AUDIO_MIXER_SET;
                   8331:                        error = audio_get_port(sc, &ct);
                   8332:                        if (error)
                   8333:                                return error;
                   8334:                        mask = ct.un.mask;
                   8335:                        nset = 0;
                   8336:                        for(i = 0; i < ports->nports; i++) {
                   8337:                                if (ports->misel[i] & mask) {
                   8338:                                    ct.dev = ports->miport[i];
                   8339:                                    if (ct.dev != -1 &&
                   8340:                                        au_set_lr_value(sc, &ct, l, r) == 0)
                   8341:                                            nset++;
                   8342:                                }
                   8343:                        }
                   8344:                        if (nset == 0)
                   8345:                                goto usemaster;
                   8346:                }
                   8347:        }
                   8348:        if (!error)
                   8349:                mixer_signal(sc);
                   8350:        return error;
                   8351: }
                   8352:
                   8353: /*
                   8354:  * Must be called with sc_lock && sc_exlock held.
                   8355:  */
                   8356: void
                   8357: au_get_gain(struct audio_softc *sc, struct au_mixer_ports *ports,
                   8358:        u_int *pgain, u_char *pbalance)
                   8359: {
                   8360:        mixer_ctrl_t ct;
                   8361:        int i, l, r, n;
                   8362:        int lgain, rgain;
                   8363:
                   8364:        KASSERT(mutex_owned(sc->sc_lock));
                   8365:        KASSERT(sc->sc_exlock);
                   8366:
                   8367:        lgain = AUDIO_MAX_GAIN / 2;
                   8368:        rgain = AUDIO_MAX_GAIN / 2;
                   8369:        if (ports->index == -1) {
                   8370:        usemaster:
                   8371:                if (ports->master == -1)
                   8372:                        goto bad;
                   8373:                ct.dev = ports->master;
                   8374:                ct.type = AUDIO_MIXER_VALUE;
                   8375:                if (au_get_lr_value(sc, &ct, &lgain, &rgain))
                   8376:                        goto bad;
                   8377:        } else {
                   8378:                ct.dev = ports->index;
                   8379:                if (ports->isenum) {
                   8380:                        ct.type = AUDIO_MIXER_ENUM;
                   8381:                        if (audio_get_port(sc, &ct))
                   8382:                                goto bad;
                   8383:                        ct.type = AUDIO_MIXER_VALUE;
                   8384:                        if (ports->isdual) {
                   8385:                                if (ports->cur_port == -1)
                   8386:                                        ct.dev = ports->master;
                   8387:                                else
                   8388:                                        ct.dev = ports->miport[ports->cur_port];
                   8389:                                au_get_lr_value(sc, &ct, &lgain, &rgain);
                   8390:                        } else {
                   8391:                                for(i = 0; i < ports->nports; i++)
                   8392:                                    if (ports->misel[i] == ct.un.ord) {
                   8393:                                            ct.dev = ports->miport[i];
                   8394:                                            if (ct.dev == -1 ||
                   8395:                                                au_get_lr_value(sc, &ct,
                   8396:                                                                &lgain, &rgain))
                   8397:                                                    goto usemaster;
                   8398:                                            else
                   8399:                                                    break;
                   8400:                                    }
                   8401:                        }
                   8402:                } else {
                   8403:                        ct.type = AUDIO_MIXER_SET;
                   8404:                        if (audio_get_port(sc, &ct))
                   8405:                                goto bad;
                   8406:                        ct.type = AUDIO_MIXER_VALUE;
                   8407:                        lgain = rgain = n = 0;
                   8408:                        for(i = 0; i < ports->nports; i++) {
                   8409:                                if (ports->misel[i] & ct.un.mask) {
                   8410:                                        ct.dev = ports->miport[i];
                   8411:                                        if (ct.dev == -1 ||
                   8412:                                            au_get_lr_value(sc, &ct, &l, &r))
                   8413:                                                goto usemaster;
                   8414:                                        else {
                   8415:                                                lgain += l;
                   8416:                                                rgain += r;
                   8417:                                                n++;
                   8418:                                        }
                   8419:                                }
                   8420:                        }
                   8421:                        if (n != 0) {
                   8422:                                lgain /= n;
                   8423:                                rgain /= n;
                   8424:                        }
                   8425:                }
                   8426:        }
                   8427: bad:
                   8428:        if (lgain == rgain) {   /* handles lgain==rgain==0 */
                   8429:                *pgain = lgain;
                   8430:                *pbalance = AUDIO_MID_BALANCE;
                   8431:        } else if (lgain < rgain) {
                   8432:                *pgain = rgain;
                   8433:                /* balance should be > AUDIO_MID_BALANCE */
                   8434:                *pbalance = AUDIO_RIGHT_BALANCE -
                   8435:                        (AUDIO_MID_BALANCE * lgain) / rgain;
                   8436:        } else /* lgain > rgain */ {
                   8437:                *pgain = lgain;
                   8438:                /* balance should be < AUDIO_MID_BALANCE */
                   8439:                *pbalance = (AUDIO_MID_BALANCE * rgain) / lgain;
                   8440:        }
                   8441: }
                   8442:
                   8443: /*
                   8444:  * Must be called with sc_lock && sc_exlock held.
                   8445:  */
                   8446: int
                   8447: au_set_port(struct audio_softc *sc, struct au_mixer_ports *ports, u_int port)
                   8448: {
                   8449:        mixer_ctrl_t ct;
                   8450:        int i, error, use_mixerout;
                   8451:
                   8452:        KASSERT(mutex_owned(sc->sc_lock));
                   8453:        KASSERT(sc->sc_exlock);
                   8454:
                   8455:        use_mixerout = 1;
                   8456:        if (port == 0) {
                   8457:                if (ports->allports == 0)
                   8458:                        return 0;               /* Allow this special case. */
                   8459:                else if (ports->isdual) {
                   8460:                        if (ports->cur_port == -1) {
                   8461:                                return 0;
                   8462:                        } else {
                   8463:                                port = ports->aumask[ports->cur_port];
                   8464:                                ports->cur_port = -1;
                   8465:                                use_mixerout = 0;
                   8466:                        }
                   8467:                }
                   8468:        }
                   8469:        if (ports->index == -1)
                   8470:                return EINVAL;
                   8471:        ct.dev = ports->index;
                   8472:        if (ports->isenum) {
                   8473:                if (port & (port-1))
                   8474:                        return EINVAL; /* Only one port allowed */
                   8475:                ct.type = AUDIO_MIXER_ENUM;
                   8476:                error = EINVAL;
                   8477:                for(i = 0; i < ports->nports; i++)
                   8478:                        if (ports->aumask[i] == port) {
                   8479:                                if (ports->isdual && use_mixerout) {
                   8480:                                        ct.un.ord = ports->mixerout;
                   8481:                                        ports->cur_port = i;
                   8482:                                } else {
                   8483:                                        ct.un.ord = ports->misel[i];
                   8484:                                }
                   8485:                                error = audio_set_port(sc, &ct);
                   8486:                                break;
                   8487:                        }
                   8488:        } else {
                   8489:                ct.type = AUDIO_MIXER_SET;
                   8490:                ct.un.mask = 0;
                   8491:                for(i = 0; i < ports->nports; i++)
                   8492:                        if (ports->aumask[i] & port)
                   8493:                                ct.un.mask |= ports->misel[i];
                   8494:                if (port != 0 && ct.un.mask == 0)
                   8495:                        error = EINVAL;
                   8496:                else
                   8497:                        error = audio_set_port(sc, &ct);
                   8498:        }
                   8499:        if (!error)
                   8500:                mixer_signal(sc);
                   8501:        return error;
                   8502: }
                   8503:
                   8504: /*
                   8505:  * Must be called with sc_lock && sc_exlock held.
                   8506:  */
                   8507: int
                   8508: au_get_port(struct audio_softc *sc, struct au_mixer_ports *ports)
                   8509: {
                   8510:        mixer_ctrl_t ct;
                   8511:        int i, aumask;
                   8512:
                   8513:        KASSERT(mutex_owned(sc->sc_lock));
                   8514:        KASSERT(sc->sc_exlock);
                   8515:
                   8516:        if (ports->index == -1)
                   8517:                return 0;
                   8518:        ct.dev = ports->index;
                   8519:        ct.type = ports->isenum ? AUDIO_MIXER_ENUM : AUDIO_MIXER_SET;
                   8520:        if (audio_get_port(sc, &ct))
                   8521:                return 0;
                   8522:        aumask = 0;
                   8523:        if (ports->isenum) {
                   8524:                if (ports->isdual && ports->cur_port != -1) {
                   8525:                        if (ports->mixerout == ct.un.ord)
                   8526:                                aumask = ports->aumask[ports->cur_port];
                   8527:                        else
                   8528:                                ports->cur_port = -1;
                   8529:                }
                   8530:                if (aumask == 0)
                   8531:                        for(i = 0; i < ports->nports; i++)
                   8532:                                if (ports->misel[i] == ct.un.ord)
                   8533:                                        aumask = ports->aumask[i];
                   8534:        } else {
                   8535:                for(i = 0; i < ports->nports; i++)
                   8536:                        if (ct.un.mask & ports->misel[i])
                   8537:                                aumask |= ports->aumask[i];
                   8538:        }
                   8539:        return aumask;
                   8540: }
                   8541:
                   8542: /*
                   8543:  * It returns 0 if success, otherwise errno.
                   8544:  * Must be called only if sc->sc_monitor_port != -1.
                   8545:  * Must be called with sc_lock && sc_exlock held.
                   8546:  */
                   8547: static int
                   8548: au_set_monitor_gain(struct audio_softc *sc, int monitor_gain)
                   8549: {
                   8550:        mixer_ctrl_t ct;
                   8551:
                   8552:        KASSERT(mutex_owned(sc->sc_lock));
                   8553:        KASSERT(sc->sc_exlock);
                   8554:
                   8555:        ct.dev = sc->sc_monitor_port;
                   8556:        ct.type = AUDIO_MIXER_VALUE;
                   8557:        ct.un.value.num_channels = 1;
                   8558:        ct.un.value.level[AUDIO_MIXER_LEVEL_MONO] = monitor_gain;
                   8559:        return audio_set_port(sc, &ct);
                   8560: }
                   8561:
                   8562: /*
                   8563:  * It returns monitor gain if success, otherwise -1.
                   8564:  * Must be called only if sc->sc_monitor_port != -1.
                   8565:  * Must be called with sc_lock && sc_exlock held.
                   8566:  */
                   8567: static int
                   8568: au_get_monitor_gain(struct audio_softc *sc)
                   8569: {
                   8570:        mixer_ctrl_t ct;
                   8571:
                   8572:        KASSERT(mutex_owned(sc->sc_lock));
                   8573:        KASSERT(sc->sc_exlock);
                   8574:
                   8575:        ct.dev = sc->sc_monitor_port;
                   8576:        ct.type = AUDIO_MIXER_VALUE;
                   8577:        ct.un.value.num_channels = 1;
                   8578:        if (audio_get_port(sc, &ct))
                   8579:                return -1;
                   8580:        return ct.un.value.level[AUDIO_MIXER_LEVEL_MONO];
                   8581: }
                   8582:
                   8583: /*
                   8584:  * Must be called with sc_lock && sc_exlock held.
                   8585:  */
                   8586: static int
                   8587: audio_set_port(struct audio_softc *sc, mixer_ctrl_t *mc)
                   8588: {
                   8589:
                   8590:        KASSERT(mutex_owned(sc->sc_lock));
                   8591:        KASSERT(sc->sc_exlock);
                   8592:
                   8593:        return sc->hw_if->set_port(sc->hw_hdl, mc);
                   8594: }
                   8595:
                   8596: /*
                   8597:  * Must be called with sc_lock && sc_exlock held.
                   8598:  */
                   8599: static int
                   8600: audio_get_port(struct audio_softc *sc, mixer_ctrl_t *mc)
                   8601: {
                   8602:
                   8603:        KASSERT(mutex_owned(sc->sc_lock));
                   8604:        KASSERT(sc->sc_exlock);
                   8605:
                   8606:        return sc->hw_if->get_port(sc->hw_hdl, mc);
                   8607: }
                   8608:
                   8609: /*
                   8610:  * Must be called with sc_lock && sc_exlock held.
                   8611:  */
                   8612: static void
                   8613: audio_mixer_capture(struct audio_softc *sc)
                   8614: {
                   8615:        mixer_devinfo_t mi;
                   8616:        mixer_ctrl_t *mc;
                   8617:
                   8618:        KASSERT(mutex_owned(sc->sc_lock));
                   8619:        KASSERT(sc->sc_exlock);
                   8620:
                   8621:        for (mi.index = 0;; mi.index++) {
                   8622:                if (audio_query_devinfo(sc, &mi) != 0)
                   8623:                        break;
                   8624:                KASSERT(mi.index < sc->sc_nmixer_states);
                   8625:                if (mi.type == AUDIO_MIXER_CLASS)
                   8626:                        continue;
                   8627:                mc = &sc->sc_mixer_state[mi.index];
                   8628:                mc->dev = mi.index;
                   8629:                mc->type = mi.type;
                   8630:                mc->un.value.num_channels = mi.un.v.num_channels;
                   8631:                (void)audio_get_port(sc, mc);
                   8632:        }
                   8633:
                   8634:        return;
                   8635: }
                   8636:
                   8637: /*
                   8638:  * Must be called with sc_lock && sc_exlock held.
                   8639:  */
                   8640: static void
                   8641: audio_mixer_restore(struct audio_softc *sc)
                   8642: {
                   8643:        mixer_devinfo_t mi;
                   8644:        mixer_ctrl_t *mc;
                   8645:
                   8646:        KASSERT(mutex_owned(sc->sc_lock));
                   8647:        KASSERT(sc->sc_exlock);
                   8648:
                   8649:        for (mi.index = 0; ; mi.index++) {
                   8650:                if (audio_query_devinfo(sc, &mi) != 0)
                   8651:                        break;
                   8652:                if (mi.type == AUDIO_MIXER_CLASS)
                   8653:                        continue;
                   8654:                mc = &sc->sc_mixer_state[mi.index];
                   8655:                (void)audio_set_port(sc, mc);
                   8656:        }
                   8657:        if (sc->hw_if->commit_settings)
                   8658:                sc->hw_if->commit_settings(sc->hw_hdl);
                   8659:
                   8660:        return;
                   8661: }
                   8662:
                   8663: static void
                   8664: audio_volume_down(device_t dv)
                   8665: {
                   8666:        struct audio_softc *sc = device_private(dv);
                   8667:        mixer_devinfo_t mi;
                   8668:        int newgain;
                   8669:        u_int gain;
                   8670:        u_char balance;
                   8671:
1.63      isaki    8672:        if (audio_exlock_mutex_enter(sc) != 0)
1.2       isaki    8673:                return;
                   8674:        if (sc->sc_outports.index == -1 && sc->sc_outports.master != -1) {
                   8675:                mi.index = sc->sc_outports.master;
                   8676:                mi.un.v.delta = 0;
                   8677:                if (audio_query_devinfo(sc, &mi) == 0) {
                   8678:                        au_get_gain(sc, &sc->sc_outports, &gain, &balance);
                   8679:                        newgain = gain - mi.un.v.delta;
                   8680:                        if (newgain < AUDIO_MIN_GAIN)
                   8681:                                newgain = AUDIO_MIN_GAIN;
                   8682:                        au_set_gain(sc, &sc->sc_outports, newgain, balance);
                   8683:                }
                   8684:        }
1.63      isaki    8685:        audio_exlock_mutex_exit(sc);
1.2       isaki    8686: }
                   8687:
                   8688: static void
                   8689: audio_volume_up(device_t dv)
                   8690: {
                   8691:        struct audio_softc *sc = device_private(dv);
                   8692:        mixer_devinfo_t mi;
                   8693:        u_int gain, newgain;
                   8694:        u_char balance;
                   8695:
1.63      isaki    8696:        if (audio_exlock_mutex_enter(sc) != 0)
1.2       isaki    8697:                return;
                   8698:        if (sc->sc_outports.index == -1 && sc->sc_outports.master != -1) {
                   8699:                mi.index = sc->sc_outports.master;
                   8700:                mi.un.v.delta = 0;
                   8701:                if (audio_query_devinfo(sc, &mi) == 0) {
                   8702:                        au_get_gain(sc, &sc->sc_outports, &gain, &balance);
                   8703:                        newgain = gain + mi.un.v.delta;
                   8704:                        if (newgain > AUDIO_MAX_GAIN)
                   8705:                                newgain = AUDIO_MAX_GAIN;
                   8706:                        au_set_gain(sc, &sc->sc_outports, newgain, balance);
                   8707:                }
                   8708:        }
1.63      isaki    8709:        audio_exlock_mutex_exit(sc);
1.2       isaki    8710: }
                   8711:
                   8712: static void
                   8713: audio_volume_toggle(device_t dv)
                   8714: {
                   8715:        struct audio_softc *sc = device_private(dv);
                   8716:        u_int gain, newgain;
                   8717:        u_char balance;
                   8718:
1.63      isaki    8719:        if (audio_exlock_mutex_enter(sc) != 0)
1.2       isaki    8720:                return;
                   8721:        au_get_gain(sc, &sc->sc_outports, &gain, &balance);
                   8722:        if (gain != 0) {
                   8723:                sc->sc_lastgain = gain;
                   8724:                newgain = 0;
                   8725:        } else
                   8726:                newgain = sc->sc_lastgain;
                   8727:        au_set_gain(sc, &sc->sc_outports, newgain, balance);
1.63      isaki    8728:        audio_exlock_mutex_exit(sc);
1.2       isaki    8729: }
                   8730:
1.63      isaki    8731: /*
                   8732:  * Must be called with sc_lock held.
                   8733:  */
1.2       isaki    8734: static int
                   8735: audio_query_devinfo(struct audio_softc *sc, mixer_devinfo_t *di)
                   8736: {
                   8737:
                   8738:        KASSERT(mutex_owned(sc->sc_lock));
                   8739:
                   8740:        return sc->hw_if->query_devinfo(sc->hw_hdl, di);
                   8741: }
                   8742:
                   8743: #endif /* NAUDIO > 0 */
                   8744:
                   8745: #if NAUDIO == 0 && (NMIDI > 0 || NMIDIBUS > 0)
                   8746: #include <sys/param.h>
                   8747: #include <sys/systm.h>
                   8748: #include <sys/device.h>
                   8749: #include <sys/audioio.h>
                   8750: #include <dev/audio/audio_if.h>
                   8751: #endif
                   8752:
                   8753: #if NAUDIO > 0 || (NMIDI > 0 || NMIDIBUS > 0)
                   8754: int
                   8755: audioprint(void *aux, const char *pnp)
                   8756: {
                   8757:        struct audio_attach_args *arg;
                   8758:        const char *type;
                   8759:
                   8760:        if (pnp != NULL) {
                   8761:                arg = aux;
                   8762:                switch (arg->type) {
                   8763:                case AUDIODEV_TYPE_AUDIO:
                   8764:                        type = "audio";
                   8765:                        break;
                   8766:                case AUDIODEV_TYPE_MIDI:
                   8767:                        type = "midi";
                   8768:                        break;
                   8769:                case AUDIODEV_TYPE_OPL:
                   8770:                        type = "opl";
                   8771:                        break;
                   8772:                case AUDIODEV_TYPE_MPU:
                   8773:                        type = "mpu";
                   8774:                        break;
                   8775:                default:
                   8776:                        panic("audioprint: unknown type %d", arg->type);
                   8777:                }
                   8778:                aprint_normal("%s at %s", type, pnp);
                   8779:        }
                   8780:        return UNCONF;
                   8781: }
                   8782:
                   8783: #endif /* NAUDIO > 0 || (NMIDI > 0 || NMIDIBUS > 0) */
                   8784:
                   8785: #ifdef _MODULE
                   8786:
                   8787: devmajor_t audio_bmajor = -1, audio_cmajor = -1;
                   8788:
                   8789: #include "ioconf.c"
                   8790:
                   8791: #endif
                   8792:
                   8793: MODULE(MODULE_CLASS_DRIVER, audio, NULL);
                   8794:
                   8795: static int
                   8796: audio_modcmd(modcmd_t cmd, void *arg)
                   8797: {
                   8798:        int error = 0;
                   8799:
                   8800:        switch (cmd) {
                   8801:        case MODULE_CMD_INIT:
1.56      isaki    8802:                /* XXX interrupt level? */
                   8803:                audio_psref_class = psref_class_create("audio", IPL_SOFTSERIAL);
                   8804: #ifdef _MODULE
1.2       isaki    8805:                error = devsw_attach(audio_cd.cd_name, NULL, &audio_bmajor,
                   8806:                    &audio_cdevsw, &audio_cmajor);
                   8807:                if (error)
                   8808:                        break;
                   8809:
                   8810:                error = config_init_component(cfdriver_ioconf_audio,
                   8811:                    cfattach_ioconf_audio, cfdata_ioconf_audio);
                   8812:                if (error) {
                   8813:                        devsw_detach(NULL, &audio_cdevsw);
                   8814:                }
1.56      isaki    8815: #endif
1.2       isaki    8816:                break;
                   8817:        case MODULE_CMD_FINI:
1.56      isaki    8818: #ifdef _MODULE
1.2       isaki    8819:                devsw_detach(NULL, &audio_cdevsw);
                   8820:                error = config_fini_component(cfdriver_ioconf_audio,
                   8821:                   cfattach_ioconf_audio, cfdata_ioconf_audio);
                   8822:                if (error)
                   8823:                        devsw_attach(audio_cd.cd_name, NULL, &audio_bmajor,
                   8824:                            &audio_cdevsw, &audio_cmajor);
1.56      isaki    8825: #endif
                   8826:                psref_class_destroy(audio_psref_class);
1.2       isaki    8827:                break;
                   8828:        default:
                   8829:                error = ENOTTY;
                   8830:                break;
                   8831:        }
                   8832:
                   8833:        return error;
                   8834: }

CVSweb <webmaster@jp.NetBSD.org>