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

Annotation of src/tests/dev/audio/audiotest.c, Revision 1.8

1.8     ! isaki       1: /*     $NetBSD: audiotest.c,v 1.7 2020/03/04 14:20:44 isaki Exp $      */
1.1       isaki       2:
                      3: /*
                      4:  * Copyright (C) 2019 Tetsuya Isaki. All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     17:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     18:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     19:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
                     20:  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
                     21:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
                     22:  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
                     23:  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     25:  * SUCH DAMAGE.
                     26:  */
                     27:
                     28: #include <sys/cdefs.h>
1.8     ! isaki      29: __RCSID("$NetBSD: audiotest.c,v 1.7 2020/03/04 14:20:44 isaki Exp $");
1.1       isaki      30:
                     31: #include <errno.h>
                     32: #include <fcntl.h>
                     33: #define __STDC_FORMAT_MACROS   /* for PRIx64 */
                     34: #include <inttypes.h>
                     35: #include <pthread.h>
                     36: #include <stdarg.h>
                     37: #include <stdbool.h>
                     38: #include <stdio.h>
                     39: #include <stdlib.h>
                     40: #include <string.h>
                     41: #include <unistd.h>
                     42: #include <util.h>
                     43: #include <sys/audioio.h>
                     44: #include <sys/event.h>
                     45: #include <sys/ioctl.h>
                     46: #include <sys/mman.h>
                     47: #include <sys/poll.h>
                     48: #include <sys/sysctl.h>
                     49: #include <sys/time.h>
                     50: #include <sys/wait.h>
                     51: #if !defined(NO_RUMP)
                     52: #include <rump/rump.h>
                     53: #include <rump/rump_syscalls.h>
                     54: #endif
                     55:
                     56: #if !defined(AUDIO_ENCODING_SLINEAR_NE)
                     57: #if BYTE_ORDER == LITTLE_ENDIAN
                     58: #define AUDIO_ENCODING_SLINEAR_NE AUDIO_ENCODING_SLINEAR_LE
                     59: #define AUDIO_ENCODING_ULINEAR_NE AUDIO_ENCODING_ULINEAR_LE
                     60: #define AUDIO_ENCODING_SLINEAR_OE AUDIO_ENCODING_SLINEAR_BE
                     61: #define AUDIO_ENCODING_ULINEAR_OE AUDIO_ENCODING_ULINEAR_BE
                     62: #else
                     63: #define AUDIO_ENCODING_SLINEAR_NE AUDIO_ENCODING_SLINEAR_BE
                     64: #define AUDIO_ENCODING_ULINEAR_NE AUDIO_ENCODING_ULINEAR_BE
                     65: #define AUDIO_ENCODING_SLINEAR_OE AUDIO_ENCODING_SLINEAR_LE
                     66: #define AUDIO_ENCODING_ULINEAR_OE AUDIO_ENCODING_ULINEAR_LE
                     67: #endif
                     68: #endif
                     69:
                     70: struct testentry {
                     71:        const char *name;
                     72:        void (*func)(void);
                     73: };
                     74:
                     75: void usage(void) __dead;
                     76: void xp_err(int, int, const char *, ...) __printflike(3, 4) __dead;
                     77: void xp_errx(int, int, const char *, ...) __printflike(3, 4) __dead;
1.8     ! isaki      78: bool match(const char *, const char *);
1.1       isaki      79: void xxx_close_wait(void);
                     80: int mixer_get_outputs_master(int);
                     81: void do_test(int);
                     82: int rump_or_open(const char *, int);
                     83: int rump_or_write(int, const void *, size_t);
                     84: int rump_or_read(int, void *, size_t);
                     85: int rump_or_ioctl(int, u_long, void *);
                     86: int rump_or_close(int);
                     87: int rump_or_fcntl(int, int, ...);
                     88: int rump_or_poll(struct pollfd *, nfds_t, int);
                     89: int rump_or_kqueue(void);
                     90: int rump_or_kevent(int, const struct kevent *, size_t,
                     91:        struct kevent *, size_t, const struct timespec *);
                     92: int hw_canplay(void);
                     93: int hw_canrec(void);
                     94: int hw_bidir(void);
                     95: int hw_fulldup(void);
                     96: void init(int);
                     97: void *consumer_thread(void *);
                     98: void cleanup_audiofd(void);
                     99: void TEST(const char *, ...) __printflike(1, 2);
                    100: bool xp_fail(int, const char *, ...) __printflike(2, 3);
                    101: void xp_skip(int, const char *, ...) __printflike(2, 3);
                    102: bool xp_eq(int, int, int, const char *);
                    103: bool xp_eq_str(int, const char *, const char *, const char *);
                    104: bool xp_ne(int, int, int, const char *);
                    105: bool xp_if(int, bool, const char *);
                    106: bool xp_sys_eq(int, int, int, const char *);
                    107: bool xp_sys_ok(int, int, const char *);
                    108: bool xp_sys_ng(int, int, int, const char *);
                    109: bool xp_sys_ptr(int, int, void *, const char *);
                    110: int debug_open(int, const char *, int);
                    111: int debug_write(int, int, const void *, size_t);
                    112: int debug_read(int, int, void *, size_t);
                    113: int debug_ioctl(int, int, u_long, const char *, void *, const char *, ...)
                    114:        __printflike(6, 7);
                    115: int debug_fcntl(int, int, int, const char *, ...) __printflike(4, 5);
                    116: int debug_close(int, int);
                    117: void *debug_mmap(int, void *, size_t, int, int, int, off_t);
                    118: int debug_munmap(int, void *, int);
                    119: const char *event_tostr(int);
                    120: int debug_poll(int, struct pollfd *, int, int);
                    121: int debug_kqueue(int);
                    122: int debug_kevent_set(int, int, const struct kevent *, size_t);
                    123: int debug_kevent_poll(int, int, struct kevent *, size_t,
                    124:        const struct timespec *);
                    125: void debug_kev(int, const char *, const struct kevent *);
                    126: uid_t debug_getuid(int);
                    127: int debug_seteuid(int, uid_t);
                    128: int debug_sysctlbyname(int, const char *, void *, size_t *, const void *,
                    129:        size_t);
                    130:
                    131: int openable_mode(void);
                    132: int mode2aumode(int);
                    133: int mode2play(int);
                    134: int mode2rec(int);
                    135: void reset_after_mmap(void);
                    136:
                    137: /* from audio.c */
                    138: static const char *encoding_names[] __unused = {
                    139:        "none",
                    140:        AudioEmulaw,
                    141:        AudioEalaw,
                    142:        "pcm16",
                    143:        "pcm8",
                    144:        AudioEadpcm,
                    145:        AudioEslinear_le,
                    146:        AudioEslinear_be,
                    147:        AudioEulinear_le,
                    148:        AudioEulinear_be,
                    149:        AudioEslinear,
                    150:        AudioEulinear,
                    151:        AudioEmpeg_l1_stream,
                    152:        AudioEmpeg_l1_packets,
                    153:        AudioEmpeg_l1_system,
                    154:        AudioEmpeg_l2_stream,
                    155:        AudioEmpeg_l2_packets,
                    156:        AudioEmpeg_l2_system,
                    157:        AudioEac3,
                    158: };
                    159:
                    160: int debug;
                    161: int props;
                    162: int hwfull;
                    163: int netbsd;
                    164: bool opt_atf;
                    165: char testname[64];
                    166: int testcount;
                    167: int failcount;
                    168: int skipcount;
                    169: int unit;
                    170: bool use_rump;
                    171: bool use_pad;
1.8     ! isaki     172: bool exact_match;
1.1       isaki     173: int padfd;
                    174: int maxfd;
                    175: pthread_t th;
                    176: char devicename[16];   /* "audioN" */
                    177: char devaudio[16];     /* "/dev/audioN" */
                    178: char devsound[16];     /* "/dev/soundN" */
                    179: char devaudioctl[16];  /* "/dev/audioctlN" */
                    180: char devmixer[16];     /* "/dev/mixerN" */
                    181: extern struct testentry testtable[];
                    182:
                    183: void
                    184: usage(void)
                    185: {
                    186:        fprintf(stderr, "usage:\t%s [<options>] [<testname>...]\n",
                    187:            getprogname());
                    188:        fprintf(stderr, "\t-A        : make output suitable for ATF\n");
                    189:        fprintf(stderr, "\t-a        : Test all\n");
                    190:        fprintf(stderr, "\t-d        : Increase debug level\n");
1.8     ! isaki     191:        fprintf(stderr, "\t-e        : Use exact match for testnames "
        !           192:            "(default is forward match)\n");
1.1       isaki     193:        fprintf(stderr, "\t-l        : List all tests\n");
                    194:        fprintf(stderr, "\t-p        : Open pad\n");
                    195: #if !defined(NO_RUMP)
                    196:        fprintf(stderr, "\t-R        : Use rump (implies -p)\n");
                    197: #endif
                    198:        fprintf(stderr, "\t-u <unit> : Use audio<unit> (default:0)\n");
                    199:        exit(1);
                    200: }
                    201:
                    202: /* Customized err(3) */
                    203: void
                    204: xp_err(int code, int line, const char *fmt, ...)
                    205: {
                    206:        va_list ap;
                    207:        int backup_errno;
                    208:
                    209:        backup_errno = errno;
                    210:        printf("%s %d: ", (opt_atf ? "Line" : " ERROR:"), line);
                    211:        va_start(ap, fmt);
                    212:        vprintf(fmt, ap);
                    213:        va_end(ap);
                    214:        printf(": %s\n", strerror(backup_errno));
                    215:
                    216:        exit(code);
                    217: }
                    218:
                    219: /* Customized errx(3) */
                    220: void
                    221: xp_errx(int code, int line, const char *fmt, ...)
                    222: {
                    223:        va_list ap;
                    224:
                    225:        printf("%s %d: ", (opt_atf ? "Line" : " ERROR:"), line);
                    226:        va_start(ap, fmt);
                    227:        vprintf(fmt, ap);
                    228:        va_end(ap);
                    229:        printf("\n");
                    230:
                    231:        exit(code);
                    232: }
                    233:
                    234: int
                    235: main(int argc, char *argv[])
                    236: {
                    237:        int i;
                    238:        int j;
                    239:        int c;
                    240:        enum {
                    241:                CMD_TEST,
                    242:                CMD_ALL,
                    243:                CMD_LIST,
                    244:        } cmd;
                    245:        bool found;
                    246:
                    247:        props = -1;
                    248:        hwfull = 0;
                    249:        unit = 0;
                    250:        cmd = CMD_TEST;
                    251:        use_pad = false;
                    252:        padfd = -1;
1.8     ! isaki     253:        exact_match = false;
1.1       isaki     254:
1.8     ! isaki     255:        while ((c = getopt(argc, argv, "AadelpRu:")) != -1) {
1.1       isaki     256:                switch (c) {
                    257:                case 'A':
                    258:                        opt_atf = true;
                    259:                        break;
                    260:                case 'a':
                    261:                        cmd = CMD_ALL;
                    262:                        break;
                    263:                case 'd':
                    264:                        debug++;
                    265:                        break;
1.8     ! isaki     266:                case 'e':
        !           267:                        exact_match = true;
        !           268:                        break;
1.1       isaki     269:                case 'l':
                    270:                        cmd = CMD_LIST;
                    271:                        break;
                    272:                case 'p':
                    273:                        use_pad = true;
                    274:                        break;
                    275:                case 'R':
                    276: #if !defined(NO_RUMP)
                    277:                        use_rump = true;
                    278:                        use_pad = true;
                    279: #else
                    280:                        usage();
                    281: #endif
                    282:                        break;
                    283:                case 'u':
                    284:                        unit = atoi(optarg);
                    285:                        break;
                    286:                default:
                    287:                        usage();
                    288:                }
                    289:        }
                    290:        argc -= optind;
                    291:        argv += optind;
                    292:
                    293:        if (cmd == CMD_LIST) {
                    294:                /* List all */
                    295:                for (i = 0; testtable[i].name != NULL; i++)
                    296:                        printf("%s\n", testtable[i].name);
                    297:                return 0;
                    298:        }
                    299:
                    300:        init(unit);
                    301:
                    302:        if (cmd == CMD_ALL) {
                    303:                /* Test all */
                    304:                if (argc > 0)
                    305:                        usage();
                    306:                for (i = 0; testtable[i].name != NULL; i++)
                    307:                        do_test(i);
                    308:        } else {
                    309:                /* Test only matched */
                    310:                if (argc == 0)
                    311:                        usage();
                    312:
                    313:                found = false;
                    314:                for (j = 0; j < argc; j++) {
                    315:                        for (i = 0; testtable[i].name != NULL; i++) {
1.8     ! isaki     316:                                if (match(argv[j], testtable[i].name)) {
1.1       isaki     317:                                        do_test(i);
                    318:                                        found = true;
                    319:                                }
                    320:                        }
                    321:                }
                    322:                if (!found) {
                    323:                        printf("test not found\n");
                    324:                        exit(1);
                    325:                }
                    326:        }
                    327:
                    328:        if (opt_atf == false) {
                    329:                printf("Result: %d tests, %d success",
                    330:                    testcount,
                    331:                    testcount - failcount - skipcount);
                    332:                if (failcount > 0)
                    333:                        printf(", %d failed", failcount);
                    334:                if (skipcount > 0)
                    335:                        printf(", %d skipped", skipcount);
                    336:                printf("\n");
                    337:        }
                    338:
                    339:        if (skipcount > 0)
                    340:                return 2;
                    341:        if (failcount > 0)
                    342:                return 1;
                    343:
                    344:        return 0;
                    345: }
                    346:
1.8     ! isaki     347: bool
        !           348: match(const char *arg, const char *name)
        !           349: {
        !           350:        if (exact_match) {
        !           351:                /* Exact match */
        !           352:                if (strcmp(arg, name) == 0)
        !           353:                        return true;
        !           354:        } else {
        !           355:                /* Forward match */
        !           356:                if (strncmp(arg, name, strlen(arg)) == 0)
        !           357:                        return true;
        !           358:        }
        !           359:        return false;
        !           360: }
        !           361:
1.1       isaki     362: /*
                    363:  * XXX
                    364:  * Some hardware drivers (e.g. hdafg(4)) require a little "rest" between
                    365:  * close(2) and re-open(2).
                    366:  * audio(4) uses hw_if->close() to tell the hardware to close.  However,
                    367:  * there is no agreement to wait for completion between MI and MD layer.
                    368:  * audio(4) immediately shifts the "closed" state, and that is, the next
                    369:  * open() will be acceptable immediately in audio layer.  But the real
                    370:  * hardware may not have been closed actually at that point.
                    371:  * It's troublesome issue but should be fixed...
                    372:  *
                    373:  * However, the most frequently used pad(4) (for ATF tests) doesn't have
                    374:  * such problem, so avoids it to reduce time.
                    375:  */
                    376: void
                    377: xxx_close_wait(void)
                    378: {
                    379:
                    380:        if (!use_pad)
                    381:                usleep(500 * 1000);
                    382: }
                    383:
                    384: void
                    385: do_test(int testnumber)
                    386: {
                    387:        /* Sentinel */
                    388:        strlcpy(testname, "<NoName>", sizeof(testname));
                    389:        /* Do test */
                    390:        testtable[testnumber].func();
                    391:
                    392:        cleanup_audiofd();
                    393:        xxx_close_wait();
                    394: }
                    395:
                    396: /*
                    397:  * system call wrappers for rump.
                    398:  */
                    399:
                    400: /* open(2) or rump_sys_open(3) */
                    401: int
                    402: rump_or_open(const char *filename, int flag)
                    403: {
                    404:        int r;
                    405:
                    406: #if !defined(NO_RUMP)
                    407:        if (use_rump)
                    408:                r = rump_sys_open(filename, flag);
                    409:        else
                    410: #endif
                    411:                r = open(filename, flag);
                    412:
                    413:        if (r > maxfd)
                    414:                maxfd = r;
                    415:        return r;
                    416: }
                    417:
                    418: /* write(2) or rump_sys_write(3) */
                    419: int
                    420: rump_or_write(int fd, const void *buf, size_t len)
                    421: {
                    422:        int r;
                    423:
                    424: #if !defined(NO_RUMP)
                    425:        if (use_rump)
                    426:                r = rump_sys_write(fd, buf, len);
                    427:        else
                    428: #endif
                    429:                r = write(fd, buf, len);
                    430:        return r;
                    431: }
                    432:
                    433: /* read(2) or rump_sys_read(3) */
                    434: int
                    435: rump_or_read(int fd, void *buf, size_t len)
                    436: {
                    437:        int r;
                    438:
                    439: #if !defined(NO_RUMP)
                    440:        if (use_rump)
                    441:                r = rump_sys_read(fd, buf, len);
                    442:        else
                    443: #endif
                    444:                r = read(fd, buf, len);
                    445:        return r;
                    446: }
                    447:
                    448: /* ioctl(2) or rump_sys_ioctl(3) */
                    449: int
                    450: rump_or_ioctl(int fd, u_long cmd, void *arg)
                    451: {
                    452:        int r;
                    453:
                    454: #if !defined(NO_RUMP)
                    455:        if (use_rump)
                    456:                r = rump_sys_ioctl(fd, cmd, arg);
                    457:        else
                    458: #endif
                    459:                r = ioctl(fd, cmd, arg);
                    460:        return r;
                    461: }
                    462:
                    463: /* close(2) or rump_sys_close(3) */
                    464: int
                    465: rump_or_close(int fd)
                    466: {
                    467:        int r;
                    468:
                    469: #if !defined(NO_RUMP)
                    470:        if (use_rump)
                    471:                r = rump_sys_close(fd);
                    472:        else
                    473: #endif
                    474:                r = close(fd);
                    475:
                    476:        /* maxfd-1 may not valid fd but no matter */
                    477:        if (fd == maxfd)
                    478:                maxfd--;
                    479:        return r;
                    480: }
                    481:
                    482: /* fcntl(2) or rump_sys_fcntl(3) */
                    483: /* XXX Supported only with no arguments for now */
                    484: int
                    485: rump_or_fcntl(int fd, int cmd, ...)
                    486: {
                    487:        int r;
                    488:
                    489: #if !defined(NO_RUMP)
                    490:        if (use_rump)
                    491:                r = rump_sys_fcntl(fd, cmd);
                    492:        else
                    493: #endif
                    494:                r = fcntl(fd, cmd);
                    495:        return r;
                    496: }
                    497:
                    498: /* poll(2) or rump_sys_poll(3) */
                    499: int
                    500: rump_or_poll(struct pollfd *fds, nfds_t nfds, int timeout)
                    501: {
                    502:        int r;
                    503:
                    504: #if !defined(NO_RUMP)
                    505:        if (use_rump)
                    506:                r = rump_sys_poll(fds, nfds, timeout);
                    507:        else
                    508: #endif
                    509:                r = poll(fds, nfds, timeout);
                    510:        return r;
                    511: }
                    512:
                    513: /* kqueue(2) or rump_sys_kqueue(3) */
                    514: int
                    515: rump_or_kqueue(void)
                    516: {
                    517:        int r;
                    518:
                    519: #if !defined(NO_RUMP)
                    520:        if (use_rump)
                    521:                r = rump_sys_kqueue();
                    522:        else
                    523: #endif
                    524:                r = kqueue();
                    525:        return r;
                    526: }
                    527:
                    528: /* kevent(2) or rump_sys_kevent(3) */
                    529: int
                    530: rump_or_kevent(int kq, const struct kevent *chlist, size_t nch,
                    531:        struct kevent *evlist, size_t nev,
                    532:        const struct timespec *timeout)
                    533: {
                    534:        int r;
                    535:
                    536: #if !defined(NO_RUMP)
                    537:        if (use_rump)
                    538:                r = rump_sys_kevent(kq, chlist, nch, evlist, nev, timeout);
                    539:        else
                    540: #endif
                    541:                r = kevent(kq, chlist, nch, evlist, nev, timeout);
                    542:        return r;
                    543: }
                    544:
                    545: int
                    546: hw_canplay(void)
                    547: {
                    548:        return (props & AUDIO_PROP_PLAYBACK) ? 1 : 0;
                    549: }
                    550:
                    551: int
                    552: hw_canrec(void)
                    553: {
                    554:        return (props & AUDIO_PROP_CAPTURE) ? 1 : 0;
                    555: }
                    556:
                    557: int
                    558: hw_bidir(void)
                    559: {
                    560:        return hw_canplay() & hw_canrec();
                    561: }
                    562:
                    563: int
                    564: hw_fulldup(void)
                    565: {
                    566:        return (props & AUDIO_PROP_FULLDUPLEX) ? 1 : 0;
                    567: }
                    568:
                    569: #define DPRINTF(fmt...) do {   \
                    570:        if (debug)              \
                    571:                printf(fmt);    \
                    572: } while (0)
                    573:
                    574: #define DPRINTFF(line, fmt...) do {            \
                    575:        if (debug) {                            \
                    576:                printf("  > %d: ", line);       \
                    577:                DPRINTF(fmt);                   \
                    578:                fflush(stdout);                 \
                    579:        }                                       \
                    580: } while (0)
                    581:
                    582: #define DRESULT(r) do {                                \
                    583:        int backup_errno = errno;               \
                    584:        if (r == -1) {                          \
                    585:                DPRINTF(" = %d, err#%d %s\n",   \
                    586:                    r, backup_errno,            \
                    587:                    strerror(backup_errno));    \
                    588:        } else {                                \
                    589:                DPRINTF(" = %d\n", r);          \
                    590:        }                                       \
                    591:        errno = backup_errno;                   \
                    592:        return r;                               \
                    593: } while (0)
                    594:
                    595: /* pointer variants for mmap */
                    596: #define DRESULT_PTR(r) do {                    \
                    597:        int backup_errno = errno;               \
                    598:        if (r == (void *)-1) {                  \
                    599:                DPRINTF(" = -1, err#%d %s\n",   \
                    600:                    backup_errno,               \
                    601:                    strerror(backup_errno));    \
                    602:        } else {                                \
                    603:                DPRINTF(" = %p\n", r);          \
                    604:        }                                       \
                    605:        errno = backup_errno;                   \
                    606:        return r;                               \
                    607: } while (0)
                    608:
                    609:
                    610: /*
                    611:  * requnit <  0: Use auto by pad (not implemented).
                    612:  * requnit >= 0: Use audio<requnit>.
                    613:  */
                    614: void
                    615: init(int requnit)
                    616: {
                    617:        struct audio_device devinfo;
                    618:        size_t len;
                    619:        int rel;
                    620:        int fd;
                    621:        int r;
                    622:
                    623:        /* XXX */
                    624:        atexit(cleanup_audiofd);
                    625:
                    626:        if (requnit < 0) {
                    627:                xp_errx(1, __LINE__, "requnit < 0 not implemented.");
                    628:        } else {
                    629:                unit = requnit;
                    630:        }
                    631:
                    632:        /* Set device name */
                    633:        snprintf(devicename, sizeof(devicename), "audio%d", unit);
                    634:        snprintf(devaudio, sizeof(devaudio), "/dev/audio%d", unit);
                    635:        snprintf(devsound, sizeof(devsound), "/dev/sound%d", unit);
                    636:        snprintf(devaudioctl, sizeof(devaudioctl), "/dev/audioctl%d", unit);
                    637:        snprintf(devmixer, sizeof(devmixer), "/dev/mixer%d", unit);
                    638:
                    639:        /*
                    640:         * version
                    641:         * audio2 is merged in 8.99.39.
                    642:         */
                    643:        len = sizeof(rel);
                    644:        r = sysctlbyname("kern.osrevision", &rel, &len, NULL, 0);
                    645:        if (r == -1)
                    646:                xp_err(1, __LINE__, "sysctl kern.osrevision");
                    647:        netbsd = rel / 100000000;
                    648:        if (rel >=  899003900)
                    649:                netbsd = 9;
                    650:
                    651: #if !defined(NO_RUMP)
                    652:        if (use_rump) {
                    653:                DPRINTF("  use rump\n");
                    654:                rump_init();
                    655:        }
                    656: #endif
                    657:
                    658:        /*
                    659:         * Open pad device before all accesses (including /dev/audioctl).
                    660:         */
                    661:        if (use_pad) {
                    662:                padfd = rump_or_open("/dev/pad0", O_RDONLY);
                    663:                if (padfd == -1)
                    664:                        xp_err(1, __LINE__, "rump_or_open");
                    665:
                    666:                /* Create consumer thread */
                    667:                pthread_create(&th, NULL, consumer_thread, NULL);
                    668:                /* Set this thread's name */
                    669:                pthread_setname_np(pthread_self(), "main", NULL);
                    670:        }
                    671:
                    672:        /*
                    673:         * Get device properties, etc.
                    674:         */
                    675:        fd = rump_or_open(devaudioctl, O_RDONLY);
                    676:        if (fd == -1)
                    677:                xp_err(1, __LINE__, "open %s", devaudioctl);
                    678:        r = rump_or_ioctl(fd, AUDIO_GETPROPS, &props);
                    679:        if (r == -1)
                    680:                xp_err(1, __LINE__, "AUDIO_GETPROPS");
                    681:        r = rump_or_ioctl(fd, AUDIO_GETDEV, &devinfo);
                    682:        if (r == -1)
                    683:                xp_err(1, __LINE__, "AUDIO_GETDEV");
                    684:        rump_or_close(fd);
                    685:
                    686:        if (debug) {
                    687:                printf("  device = %s, %s, %s\n",
                    688:                    devinfo.name, devinfo.version, devinfo.config);
                    689:                printf("  hw props =");
                    690:                if (hw_canplay())
                    691:                        printf(" playback");
                    692:                if (hw_canrec())
                    693:                        printf(" capture");
                    694:                if (hw_fulldup())
                    695:                        printf(" fullduplex");
                    696:                printf("\n");
                    697:        }
                    698:
                    699: }
                    700:
                    701: /* Consumer thread used by pad */
                    702: void *
                    703: consumer_thread(void *arg)
                    704: {
                    705:        char buf[1024];
                    706:        int r;
                    707:
                    708:        pthread_setname_np(pthread_self(), "consumer", NULL);
                    709:        pthread_detach(pthread_self());
                    710:
                    711:        /* throw away data anyway */
                    712:        for (;;) {
                    713:                r = read(padfd, buf, sizeof(buf));
                    714:                if (r < 1)
                    715:                        break;
                    716:        }
                    717:
                    718:        pthread_exit(NULL);
                    719: }
                    720:
                    721: /*
                    722:  * XXX
                    723:  * Closing pad descriptor before audio descriptor causes panic (kern/54427).
                    724:  * To avoid this, close non-pad descriptor first using atexit(3) for now.
                    725:  * This is just a workaround and this function should be removed.
                    726:  */
                    727: void cleanup_audiofd()
                    728: {
                    729:        int fd;
                    730:
                    731:        for (fd = 3; fd <= maxfd; fd++) {
                    732:                if (fd != padfd)
                    733:                        close(fd);
                    734:        }
                    735:        maxfd = 3;
                    736: }
                    737:
                    738: /*
                    739:  * Support functions
                    740:  */
                    741:
                    742: /* Set testname */
                    743: void
                    744: TEST(const char *name, ...)
                    745: {
                    746:        va_list ap;
                    747:
                    748:        va_start(ap, name);
                    749:        vsnprintf(testname, sizeof(testname), name, ap);
                    750:        va_end(ap);
                    751:        if (opt_atf == false) {
                    752:                printf("%s\n", testname);
                    753:                fflush(stdout);
                    754:        }
                    755: }
                    756:
                    757: /*
                    758:  * XP_FAIL() should be called when this test fails.
                    759:  * If caller already count up testcount, call xp_fail() instead.
                    760:  */
                    761: #define XP_FAIL(fmt...)        do {    \
                    762:        testcount++;    \
                    763:        xp_fail(__LINE__, fmt); \
                    764: } while (0)
                    765: bool xp_fail(int line, const char *fmt, ...)
                    766: {
                    767:        va_list ap;
                    768:
                    769:        printf("%s %d: ", (opt_atf ? "Line" : " FAIL:"), line);
                    770:        va_start(ap, fmt);
                    771:        vprintf(fmt, ap);
                    772:        va_end(ap);
                    773:        printf("\n");
                    774:        fflush(stdout);
                    775:        failcount++;
                    776:
                    777:        return false;
                    778: }
                    779:
                    780: /*
                    781:  * XP_SKIP() should be called when you want to skip this test.
                    782:  * If caller already count up testcount, call xp_skip() instead.
                    783:  */
                    784: #define XP_SKIP(fmt...)        do { \
                    785:        testcount++;    \
                    786:        xp_skip(__LINE__, fmt); \
                    787: } while (0)
                    788: void xp_skip(int line, const char *fmt, ...)
                    789: {
                    790:        va_list ap;
                    791:
                    792:        printf("%s %d: ", (opt_atf ? "Line" : " SKIP:"), line);
                    793:        va_start(ap, fmt);
                    794:        vprintf(fmt, ap);
                    795:        va_end(ap);
                    796:        printf("\n");
                    797:        fflush(stdout);
                    798:        skipcount++;
                    799: }
                    800:
                    801: #define XP_EQ(exp, act)        xp_eq(__LINE__, exp, act, #act)
                    802: bool xp_eq(int line, int exp, int act, const char *varname)
                    803: {
                    804:        bool r = true;
                    805:
                    806:        testcount++;
                    807:        if (exp != act) {
                    808:                r = xp_fail(line, "%s expects %d but %d", varname, exp, act);
                    809:        }
                    810:        return r;
                    811: }
                    812: #define XP_EQ_STR(exp, act) xp_eq_str(__LINE__, exp, act, #act)
                    813: bool xp_eq_str(int line, const char *exp, const char *act, const char *varname)
                    814: {
                    815:        bool r = true;
                    816:
                    817:        testcount++;
                    818:        if (strcmp(exp, act) != 0) {
                    819:                r = xp_fail(line, "%s expects \"%s\" but \"%s\"",
                    820:                    varname, exp, act);
                    821:        }
                    822:        return r;
                    823: }
                    824:
                    825: #define XP_NE(exp, act)        xp_ne(__LINE__, exp, act, #act)
                    826: bool xp_ne(int line, int exp, int act, const char *varname)
                    827: {
                    828:        bool r = true;
                    829:
                    830:        testcount++;
                    831:        if (exp == act) {
                    832:                r = xp_fail(line, "%s expects != %d but %d", varname, exp, act);
                    833:        }
                    834:        return r;
                    835: }
                    836:
                    837: /* This expects that result is expressed in expr. */
                    838: /* GCC extension */
                    839: #define XP_IF(expr) xp_if(__LINE__, (expr), #expr)
                    840: bool xp_if(int line, bool expr, const char *exprname)
                    841: {
                    842:        bool r = true;
                    843:        testcount++;
                    844:        if (!expr) {
                    845:                r = xp_fail(__LINE__, "(%s) is expected but not met", exprname);
                    846:        }
                    847:        return r;
                    848: }
                    849:
                    850: /* This expects that the system call returns 'exp'. */
                    851: #define XP_SYS_EQ(exp, act)    xp_sys_eq(__LINE__, exp, act, #act)
                    852: bool xp_sys_eq(int line, int exp, int act, const char *varname)
                    853: {
                    854:        bool r = true;
                    855:
                    856:        testcount++;
                    857:        if (act == -1) {
                    858:                r = xp_fail(line, "%s expects %d but -1,err#%d(%s)",
                    859:                    varname, exp, errno, strerror(errno));
                    860:        } else {
                    861:                r = xp_eq(line, exp, act, varname);
                    862:        }
                    863:        return r;
                    864: }
                    865:
                    866: /*
                    867:  * This expects that system call succeeds.
                    868:  * This is useful when you expect the system call succeeds but don't know
                    869:  * the expected return value, such as open(2).
                    870:  */
                    871: #define XP_SYS_OK(act) xp_sys_ok(__LINE__, act, #act)
                    872: bool xp_sys_ok(int line, int act, const char *varname)
                    873: {
                    874:        bool r = true;
                    875:
                    876:        testcount++;
                    877:        if (act == -1) {
                    878:                r = xp_fail(line, "%s expects success but -1,err#%d(%s)",
                    879:                    varname, errno, strerror(errno));
                    880:        }
                    881:        return r;
                    882: }
                    883:
                    884: /* This expects that the system call fails with 'experrno'. */
                    885: #define XP_SYS_NG(experrno, act) xp_sys_ng(__LINE__, experrno, act, #act)
                    886: bool xp_sys_ng(int line, int experrno, int act, const char *varname)
                    887: {
                    888:        bool r = true;
                    889:
                    890:        testcount++;
                    891:        if (act != -1) {
                    892:                r = xp_fail(line, "%s expects -1,err#%d but %d",
                    893:                    varname, experrno, act);
                    894:        } else if (experrno != errno) {
                    895:                char acterrbuf[100];
                    896:                int acterrno = errno;
                    897:                strlcpy(acterrbuf, strerror(acterrno), sizeof(acterrbuf));
                    898:                r = xp_fail(line, "%s expects -1,err#%d(%s) but -1,err#%d(%s)",
                    899:                    varname, experrno, strerror(experrno),
                    900:                    acterrno, acterrbuf);
                    901:        }
                    902:        return r;
                    903: }
                    904:
                    905: /*
                    906:  * When exp == 0, this expects that the system call succeeds with returned
                    907:  * pointer is not -1.
                    908:  * When exp != 0, this expects that the system call fails with returned
                    909:  * pointer is -1 and its errno is exp.
                    910:  * It's only for mmap().
                    911:  */
                    912: #define XP_SYS_PTR(exp, act) xp_sys_ptr(__LINE__, exp, act, #act)
                    913: bool xp_sys_ptr(int line, int exp, void *act, const char *varname)
                    914: {
                    915:        char errbuf[256];
                    916:        int actual_errno;
                    917:        bool r = true;
                    918:
                    919:        testcount++;
                    920:        if (exp == 0) {
                    921:                /* expects to succeed */
                    922:                if (act == (void *)-1) {
                    923:                        r = xp_fail(line,
                    924:                            "%s expects success but -1,err#%d(%s)",
                    925:                            varname, errno, strerror(errno));
                    926:                }
                    927:        } else {
                    928:                /* expects to fail */
                    929:                if (act != (void *)-1) {
                    930:                        r = xp_fail(line,
                    931:                            "%s expects -1,err#%d(%s) but success",
                    932:                            varname, exp, strerror(exp));
                    933:                } else if (exp != errno) {
                    934:                        actual_errno = errno;
                    935:                        strerror_r(actual_errno, errbuf, sizeof(errbuf));
                    936:                        r = xp_fail(line,
                    937:                            "%s expects -1,err#%d(%s) but -1,err#%d(%s)",
                    938:                            varname, exp, strerror(exp), actual_errno, errbuf);
                    939:                }
                    940:        }
                    941:        return r;
                    942: }
                    943:
                    944:
                    945: /*
                    946:  * REQUIRED_* return immediately if condition does not meet.
                    947:  */
                    948: #define REQUIRED_EQ(e, a) do { if (!XP_EQ(e, a)) return; } while (0)
                    949: #define REQUIRED_NE(e, a) do { if (!XP_NE(e, a)) return; } while (0)
                    950: #define REQUIRED_IF(expr) do { if (!XP_IF(expr)) return; } while (0)
                    951: #define REQUIRED_SYS_EQ(e, a) do { if (!XP_SYS_EQ(e, a)) return; } while (0)
                    952: #define REQUIRED_SYS_OK(a)    do { if (!XP_SYS_OK(a))    return; } while (0)
                    953:
                    954:
                    955: static const char *openmode_str[] = {
                    956:        "O_RDONLY",
                    957:        "O_WRONLY",
                    958:        "O_RDWR",
                    959: };
                    960:
                    961:
                    962: /*
                    963:  * All system calls in following tests should be called with these macros.
                    964:  */
                    965:
                    966: #define OPEN(name, mode)       \
                    967:        debug_open(__LINE__, name, mode)
                    968: int debug_open(int line, const char *name, int mode)
                    969: {
                    970:        char modestr[32];
                    971:        int n;
                    972:
                    973:        if ((mode & 3) != 3) {
                    974:                n = snprintf(modestr, sizeof(modestr), "%s",
                    975:                    openmode_str[mode & 3]);
                    976:        } else {
                    977:                n = snprintf(modestr, sizeof(modestr), "%d", mode & 3);
                    978:        }
                    979:        if ((mode & O_NONBLOCK))
                    980:                n += snprintf(modestr + n, sizeof(modestr) - n, "|O_NONBLOCK");
                    981:
                    982:        DPRINTFF(line, "open(\"%s\", %s)", name, modestr);
                    983:        int r = rump_or_open(name, mode);
                    984:        DRESULT(r);
                    985: }
                    986:
                    987: #define WRITE(fd, addr, len)   \
                    988:        debug_write(__LINE__, fd, addr, len)
                    989: int debug_write(int line, int fd, const void *addr, size_t len)
                    990: {
                    991:        DPRINTFF(line, "write(%d, %p, %zd)", fd, addr, len);
                    992:        int r = rump_or_write(fd, addr, len);
                    993:        DRESULT(r);
                    994: }
                    995:
                    996: #define READ(fd, addr, len)    \
                    997:        debug_read(__LINE__, fd, addr, len)
                    998: int debug_read(int line, int fd, void *addr, size_t len)
                    999: {
                   1000:        DPRINTFF(line, "read(%d, %p, %zd)", fd, addr, len);
                   1001:        int r = rump_or_read(fd, addr, len);
                   1002:        DRESULT(r);
                   1003: }
                   1004:
                   1005: /*
                   1006:  * addrstr is the comment for debug message.
                   1007:  *   int onoff = 0;
                   1008:  *   ioctl(fd, SWITCH, onoff); -> IOCTL(fd, SWITCH, onoff, "off");
                   1009:  */
                   1010: #define IOCTL(fd, name, addr, addrfmt...)      \
                   1011:        debug_ioctl(__LINE__, fd, name, #name, addr, addrfmt)
                   1012: int debug_ioctl(int line, int fd, u_long name, const char *namestr,
                   1013:        void *addr, const char *addrfmt, ...)
                   1014: {
                   1015:        char addrbuf[100];
                   1016:        va_list ap;
                   1017:
                   1018:        va_start(ap, addrfmt);
                   1019:        vsnprintf(addrbuf, sizeof(addrbuf), addrfmt, ap);
                   1020:        va_end(ap);
                   1021:        DPRINTFF(line, "ioctl(%d, %s, %s)", fd, namestr, addrbuf);
                   1022:        int r = rump_or_ioctl(fd, name, addr);
                   1023:        DRESULT(r);
                   1024: }
                   1025:
                   1026: #define FCNTL(fd, name...)     \
                   1027:        debug_fcntl(__LINE__, fd, name, #name)
                   1028: int debug_fcntl(int line, int fd, int name, const char *namestr, ...)
                   1029: {
                   1030:        int r;
                   1031:
                   1032:        switch (name) {
                   1033:         case F_GETFL:  /* no arguments */
                   1034:                DPRINTFF(line, "fcntl(%d, %s)", fd, namestr);
                   1035:                r = rump_or_fcntl(fd, name);
                   1036:                break;
                   1037:         default:
                   1038:                __unreachable();
                   1039:        }
                   1040:        DRESULT(r);
                   1041:        return r;
                   1042: }
                   1043:
                   1044: #define CLOSE(fd)      \
                   1045:        debug_close(__LINE__, fd)
                   1046: int debug_close(int line, int fd)
                   1047: {
                   1048:        DPRINTFF(line, "close(%d)", fd);
                   1049:        int r = rump_or_close(fd);
                   1050:        DRESULT(r);
                   1051: }
                   1052:
                   1053: #define MMAP(ptr, len, prot, flags, fd, offset)        \
                   1054:        debug_mmap(__LINE__, ptr, len, prot, flags, fd, offset)
                   1055: void *debug_mmap(int line, void *ptr, size_t len, int prot, int flags, int fd,
                   1056:        off_t offset)
                   1057: {
                   1058:        char protbuf[256];
                   1059:        char flagbuf[256];
                   1060:        int n;
                   1061:
                   1062: #define ADDFLAG(buf, var, name)        do {                            \
                   1063:        if (((var) & (name)))                                   \
                   1064:                n = strlcat(buf, "|" #name, sizeof(buf));       \
                   1065:                var &= ~(name);                                 \
                   1066: } while (0)
                   1067:
                   1068:        n = 0;
                   1069:        protbuf[n] = '\0';
                   1070:        if (prot == 0) {
                   1071:                strlcpy(protbuf, "|PROT_NONE", sizeof(protbuf));
                   1072:        } else {
                   1073:                ADDFLAG(protbuf, prot, PROT_EXEC);
                   1074:                ADDFLAG(protbuf, prot, PROT_WRITE);
                   1075:                ADDFLAG(protbuf, prot, PROT_READ);
                   1076:                if (prot != 0) {
                   1077:                        snprintf(protbuf + n, sizeof(protbuf) - n,
                   1078:                            "|prot=0x%x", prot);
                   1079:                }
                   1080:        }
                   1081:
                   1082:        n = 0;
                   1083:        flagbuf[n] = '\0';
                   1084:        if (flags == 0) {
                   1085:                strlcpy(flagbuf, "|MAP_FILE", sizeof(flagbuf));
                   1086:        } else {
                   1087:                ADDFLAG(flagbuf, flags, MAP_SHARED);
                   1088:                ADDFLAG(flagbuf, flags, MAP_PRIVATE);
                   1089:                ADDFLAG(flagbuf, flags, MAP_FIXED);
                   1090:                ADDFLAG(flagbuf, flags, MAP_INHERIT);
                   1091:                ADDFLAG(flagbuf, flags, MAP_HASSEMAPHORE);
                   1092:                ADDFLAG(flagbuf, flags, MAP_TRYFIXED);
                   1093:                ADDFLAG(flagbuf, flags, MAP_WIRED);
                   1094:                ADDFLAG(flagbuf, flags, MAP_ANON);
                   1095:                if (flags != 0) {
                   1096:                        n += snprintf(flagbuf + n, sizeof(flagbuf) - n,
                   1097:                            "|flag=0x%x", flags);
                   1098:                }
                   1099:        }
                   1100:
                   1101:        DPRINTFF(line, "mmap(%p, %zd, %s, %s, %d, %jd)",
                   1102:            ptr, len, protbuf + 1, flagbuf + 1, fd, offset);
                   1103:        void *r = mmap(ptr, len, prot, flags, fd, offset);
                   1104:        DRESULT_PTR(r);
                   1105: }
                   1106:
                   1107: #define MUNMAP(ptr, len)       \
                   1108:        debug_munmap(__LINE__, ptr, len)
                   1109: int debug_munmap(int line, void *ptr, int len)
                   1110: {
                   1111: #if !defined(NO_RUMP)
                   1112:        if (use_rump)
                   1113:                xp_errx(1, __LINE__, "rump doesn't support munmap");
                   1114: #endif
                   1115:        DPRINTFF(line, "munmap(%p, %d)", ptr, len);
                   1116:        int r = munmap(ptr, len);
                   1117:        DRESULT(r);
                   1118: }
                   1119:
                   1120: const char *
                   1121: event_tostr(int events)
                   1122: {
                   1123:        static char buf[64];
                   1124:
                   1125:        snprintb(buf, sizeof(buf),
                   1126:            "\177\020" \
                   1127:            "b\10WRBAND\0" \
                   1128:            "b\7RDBAND\0" "b\6RDNORM\0" "b\5NVAL\0" "b\4HUP\0" \
                   1129:            "b\3ERR\0" "b\2OUT\0" "b\1PRI\0" "b\0IN\0",
                   1130:            events);
                   1131:        return buf;
                   1132: }
                   1133:
                   1134: #define POLL(pfd, nfd, timeout)        \
                   1135:        debug_poll(__LINE__, pfd, nfd, timeout)
                   1136: int debug_poll(int line, struct pollfd *pfd, int nfd, int timeout)
                   1137: {
                   1138:        char buf[256];
                   1139:        int n = 0;
                   1140:        buf[n] = '\0';
                   1141:        for (int i = 0; i < nfd; i++) {
                   1142:                n += snprintf(buf + n, sizeof(buf) - n, "{fd=%d,events=%s}",
                   1143:                    pfd[i].fd, event_tostr(pfd[i].events));
                   1144:        }
                   1145:        DPRINTFF(line, "poll(%s, %d, %d)", buf, nfd, timeout);
                   1146:        int r = rump_or_poll(pfd, nfd, timeout);
                   1147:        DRESULT(r);
                   1148: }
                   1149:
                   1150: #define KQUEUE()       \
                   1151:        debug_kqueue(__LINE__)
                   1152: int debug_kqueue(int line)
                   1153: {
                   1154:        DPRINTFF(line, "kqueue()");
                   1155:        int r = rump_or_kqueue();
                   1156:        DRESULT(r);
                   1157: }
                   1158:
                   1159: #define KEVENT_SET(kq, kev, nev)       \
                   1160:        debug_kevent_set(__LINE__, kq, kev, nev)
                   1161: int debug_kevent_set(int line, int kq, const struct kevent *kev, size_t nev)
                   1162: {
                   1163:        DPRINTFF(line, "kevent_set(%d, %p, %zd)", kq, kev, nev);
                   1164:        int r = rump_or_kevent(kq, kev, nev, NULL, 0, NULL);
                   1165:        DRESULT(r);
                   1166: }
                   1167:
                   1168: #define KEVENT_POLL(kq, kev, nev, ts) \
                   1169:        debug_kevent_poll(__LINE__, kq, kev, nev, ts)
                   1170: int debug_kevent_poll(int line, int kq, struct kevent *kev, size_t nev,
                   1171:        const struct timespec *ts)
                   1172: {
                   1173:        char tsbuf[32];
                   1174:
                   1175:        if (ts == NULL) {
                   1176:                snprintf(tsbuf, sizeof(tsbuf), "NULL");
                   1177:        } else if (ts->tv_sec == 0 && ts->tv_nsec == 0) {
                   1178:                snprintf(tsbuf, sizeof(tsbuf), "0.0");
                   1179:        } else {
                   1180:                snprintf(tsbuf, sizeof(tsbuf), "%d.%09ld",
                   1181:                        (int)ts->tv_sec, ts->tv_nsec);
                   1182:        }
                   1183:        DPRINTFF(line, "kevent_poll(%d, %p, %zd, %s)", kq, kev, nev, tsbuf);
                   1184:        int r = rump_or_kevent(kq, NULL, 0, kev, nev, ts);
                   1185:        DRESULT(r);
                   1186: }
                   1187:
                   1188: #define DEBUG_KEV(name, kev)   \
                   1189:        debug_kev(__LINE__, name, kev)
                   1190: void debug_kev(int line, const char *name, const struct kevent *kev)
                   1191: {
                   1192:        char flagbuf[256];
                   1193:        const char *filterbuf;
                   1194:        uint32_t v;
                   1195:        int n;
                   1196:
                   1197:        n = 0;
                   1198:        flagbuf[n] = '\0';
                   1199:        if (kev->flags == 0) {
                   1200:                strcpy(flagbuf, "|0?");
                   1201:        } else {
                   1202:                v = kev->flags;
                   1203:                ADDFLAG(flagbuf, v, EV_ADD);
                   1204:                if (v != 0)
                   1205:                        snprintf(flagbuf + n, sizeof(flagbuf)-n, "|0x%x", v);
                   1206:        }
                   1207:
                   1208:        switch (kev->filter) {
                   1209:         case EVFILT_READ:      filterbuf = "EVFILT_READ";      break;
                   1210:         case EVFILT_WRITE:     filterbuf = "EVFILT_WRITE";     break;
                   1211:         default:               filterbuf = "EVFILT_?";         break;
                   1212:        }
                   1213:
                   1214:        DPRINTFF(line,
                   1215:            "%s={id:%d,%s,%s,fflags:0x%x,data:0x%" PRIx64 ",udata:0x%x}\n",
                   1216:            name,
                   1217:            (int)kev->ident,
                   1218:            flagbuf + 1,
                   1219:            filterbuf,
                   1220:            kev->fflags,
                   1221:            kev->data,
                   1222:            (int)(intptr_t)kev->udata);
                   1223: }
                   1224:
                   1225: /* XXX rump? */
                   1226: #define GETUID()       \
                   1227:        debug_getuid(__LINE__)
                   1228: uid_t debug_getuid(int line)
                   1229: {
                   1230:        DPRINTFF(line, "getuid");
                   1231:        uid_t r = getuid();
                   1232:        /* getuid() never fails */
                   1233:        DPRINTF(" = %u\n", r);
                   1234:        return r;
                   1235: }
                   1236:
                   1237: /* XXX rump? */
                   1238: #define SETEUID(id)    \
                   1239:        debug_seteuid(__LINE__, id)
                   1240: int debug_seteuid(int line, uid_t id)
                   1241: {
                   1242:        DPRINTFF(line, "seteuid(%d)", (int)id);
                   1243:        int r = seteuid(id);
                   1244:        DRESULT(r);
                   1245: }
                   1246:
                   1247: #define SYSCTLBYNAME(name, oldp, oldlenp, newp, newlen)        \
                   1248:        debug_sysctlbyname(__LINE__, name, oldp, oldlenp, newp, newlen)
                   1249: int debug_sysctlbyname(int line, const char *name, void *oldp, size_t *oldlenp,
                   1250:        const void *newp, size_t newlen)
                   1251: {
                   1252:        DPRINTFF(line, "sysctlbyname(\"%s\")", name);
                   1253:        int r = sysctlbyname(name, oldp, oldlenp, newp, newlen);
                   1254:        DRESULT(r);
                   1255: }
                   1256:
                   1257:
                   1258: /* Return openable mode on this hardware property */
                   1259: int
                   1260: openable_mode(void)
                   1261: {
                   1262:        if (hw_bidir())
                   1263:                return O_RDWR;
                   1264:        if (hw_canplay())
                   1265:                return O_WRONLY;
                   1266:        else
                   1267:                return O_RDONLY;
                   1268: }
                   1269:
                   1270: int mode2aumode_full[] = {
                   1271:                                        AUMODE_RECORD,  /* O_RDONLY */
                   1272:        AUMODE_PLAY | AUMODE_PLAY_ALL,                  /* O_WRONLY */
                   1273:        AUMODE_PLAY | AUMODE_PLAY_ALL | AUMODE_RECORD,  /* O_RDWR   */
                   1274: };
                   1275:
                   1276: /* Convert openmode(O_*) to AUMODE_*, with hardware property */
                   1277: int
                   1278: mode2aumode(int mode)
                   1279: {
                   1280:        int aumode;
                   1281:
                   1282:        aumode = mode2aumode_full[mode];
                   1283:        if (hw_canplay() == 0)
                   1284:                aumode &= ~(AUMODE_PLAY | AUMODE_PLAY_ALL);
                   1285:        if (hw_canrec() == 0)
                   1286:                aumode &= ~AUMODE_RECORD;
                   1287:
                   1288:        if (netbsd >= 9) {
                   1289:                /* half-duplex treats O_RDWR as O_WRONLY */
                   1290:                if (mode == O_RDWR && hw_bidir() && hw_fulldup() == 0)
                   1291:                        aumode &= ~AUMODE_RECORD;
                   1292:        }
                   1293:
                   1294:        return aumode;
                   1295: }
                   1296:
                   1297: /* Is this mode + hardware playable? */
                   1298: int
                   1299: mode2play(int mode)
                   1300: {
                   1301:        int aumode;
                   1302:
                   1303:        aumode = mode2aumode(mode);
                   1304:        return ((aumode & AUMODE_PLAY)) ? 1 : 0;
                   1305: }
                   1306:
                   1307: /* Is this mode + hardware recordable? */
                   1308: int
                   1309: mode2rec(int mode)
                   1310: {
                   1311:        int aumode;
                   1312:
                   1313:        aumode = mode2aumode(mode);
                   1314:        return ((aumode & AUMODE_RECORD)) ? 1 : 0;
                   1315: }
                   1316:
                   1317: /*
                   1318:  * On NetBSD7, open() after-closing-mmap fails due to a bug.
                   1319:  * It happens once every two times like flip-flop, so the workaround is
                   1320:  * to open it again.
                   1321:  */
                   1322: void
                   1323: reset_after_mmap(void)
                   1324: {
                   1325:        int fd;
                   1326:
                   1327:        if (netbsd < 8) {
                   1328:                fd = OPEN(devaudio, O_WRONLY);
                   1329:                if (fd != -1)
                   1330:                        CLOSE(fd);
                   1331:        }
                   1332: }
                   1333:
                   1334: /*
                   1335:  * Lookup "outputs.master" and return its mixer device index.
                   1336:  * It may not be strict but I'm not sure.
                   1337:  */
                   1338: int
                   1339: mixer_get_outputs_master(int mixerfd)
                   1340: {
                   1341:        const char * const typename[] = { "CLASS", "ENUM", "SET", "VALUE" };
                   1342:        mixer_devinfo_t di;
                   1343:        int class_outputs;
                   1344:        int i;
                   1345:        int r;
                   1346:
                   1347:        class_outputs = -1;
                   1348:        for (i = 0; ; i++) {
                   1349:                memset(&di, 0, sizeof(di));
                   1350:                di.index = i;
                   1351:                r = IOCTL(mixerfd, AUDIO_MIXER_DEVINFO, &di, "index=%d", i);
                   1352:                if (r < 0)
                   1353:                        break;
                   1354:                DPRINTF("  > type=%s(%d) mixer_class=%d name=%s\n",
                   1355:                    (0 <= di.type && di.type <= 3) ? typename[di.type] : "",
                   1356:                    di.type, di.mixer_class, di.label.name);
                   1357:                if (di.type == AUDIO_MIXER_CLASS &&
                   1358:                    strcmp(di.label.name, "outputs") == 0) {
                   1359:                        class_outputs = di.mixer_class;
                   1360:                        DPRINTF("  > class_output=%d\n", class_outputs);
                   1361:                        continue;
                   1362:                }
                   1363:                if (di.type == AUDIO_MIXER_VALUE &&
                   1364:                    di.mixer_class == class_outputs &&
                   1365:                    strcmp(di.label.name, "master") == 0) {
                   1366:                        return i;
                   1367:                }
                   1368:        }
                   1369:        /* Not found */
                   1370:        return -1;
                   1371: }
                   1372:
                   1373: /*
                   1374:  * Tests
                   1375:  */
                   1376:
                   1377: void test_open_mode(int);
1.7       isaki    1378: void test_open(const char *, int);
1.1       isaki    1379: void test_open_simul(int, int);
1.4       isaki    1380: void try_open_multiuser(bool);
                   1381: void test_open_multiuser(bool);
1.1       isaki    1382: void test_rdwr_fallback(int, bool, bool);
                   1383: void test_rdwr_two(int, int);
                   1384: void test_mmap_mode(int, int);
                   1385: void test_poll_mode(int, int, int);
                   1386: void test_kqueue_mode(int, int, int);
                   1387: volatile int sigio_caught;
                   1388: void signal_FIOASYNC(int);
                   1389: void test_AUDIO_SETFD_xxONLY(int);
                   1390: void test_AUDIO_SETINFO_mode(int, int, int, int);
                   1391: void test_AUDIO_SETINFO_params_set(int, int, int);
                   1392: void test_AUDIO_SETINFO_pause(int, int, int);
                   1393: int getenc_make_table(int, int[][5]);
                   1394: void xp_getenc(int[][5], int, int, int, struct audio_prinfo *);
                   1395: void getenc_check_encodings(int, int[][5]);
                   1396: void test_AUDIO_ERROR(int);
                   1397: void test_audioctl_open_1(int, int);
                   1398: void test_audioctl_open_2(int, int);
1.4       isaki    1399: void try_audioctl_open_multiuser(const char *, const char *);
                   1400: void test_audioctl_open_multiuser(bool, const char *, const char *);
1.1       isaki    1401: void test_audioctl_rw(int);
                   1402:
                   1403: #define DEF(name) \
                   1404:        void test__ ## name (void); \
                   1405:        void test__ ## name (void)
                   1406:
                   1407: /*
                   1408:  * Whether it can be open()ed with specified mode.
                   1409:  */
                   1410: void
                   1411: test_open_mode(int mode)
                   1412: {
                   1413:        int fd;
                   1414:        int r;
                   1415:
                   1416:        TEST("open_mode_%s", openmode_str[mode] + 2);
                   1417:
                   1418:        fd = OPEN(devaudio, mode);
                   1419:        if (mode2aumode(mode) != 0) {
                   1420:                XP_SYS_OK(fd);
                   1421:        } else {
                   1422:                XP_SYS_NG(ENXIO, fd);
                   1423:        }
                   1424:
                   1425:        if (fd >= 0) {
                   1426:                r = CLOSE(fd);
                   1427:                XP_SYS_EQ(0, r);
                   1428:        }
                   1429: }
                   1430: DEF(open_mode_RDONLY)  { test_open_mode(O_RDONLY); }
                   1431: DEF(open_mode_WRONLY)  { test_open_mode(O_WRONLY); }
                   1432: DEF(open_mode_RDWR)    { test_open_mode(O_RDWR);   }
                   1433:
                   1434: /*
1.7       isaki    1435:  * Check the initial parameters and stickiness.
                   1436:  * /dev/audio
                   1437:  *     The initial parameters are always the same whenever you open.
                   1438:  * /dev/sound and /dev/audioctl
                   1439:  *     The initial parameters are inherited from the last /dev/sound or
                   1440:  *     /dev/audio.
1.1       isaki    1441:  */
                   1442: void
1.7       isaki    1443: test_open(const char *devname, int mode)
1.1       isaki    1444: {
                   1445:        struct audio_info ai;
                   1446:        struct audio_info ai0;
1.7       isaki    1447:        char devfile[16];
1.1       isaki    1448:        int fd;
                   1449:        int r;
                   1450:        int can_play;
                   1451:        int can_rec;
1.7       isaki    1452:        int exp_mode;
                   1453:        int exp_encoding;
                   1454:        int exp_precision;
                   1455:        int exp_channels;
                   1456:        int exp_sample_rate;
                   1457:        int exp_pause;
                   1458:        int exp_popen;
                   1459:        int exp_ropen;
1.1       isaki    1460:
1.7       isaki    1461:        TEST("open_%s_%s", devname, openmode_str[mode] + 2);
1.1       isaki    1462:
1.7       isaki    1463:        snprintf(devfile, sizeof(devfile), "/dev/%s%d", devname, unit);
1.1       isaki    1464:        can_play = mode2play(mode);
                   1465:        can_rec  = mode2rec(mode);
1.7       isaki    1466:        if (strcmp(devname, "audioctl") != 0) {
                   1467:                if (can_play + can_rec == 0) {
                   1468:                        /* Check whether it cannot be opened */
                   1469:                        fd = OPEN(devaudio, mode);
                   1470:                        XP_SYS_NG(ENXIO, fd);
                   1471:                        return;
                   1472:                }
1.1       isaki    1473:        }
                   1474:
1.7       isaki    1475:        /* /dev/audio is always initialized */
                   1476:        if (strcmp(devname, "audio") == 0) {
                   1477:                exp_encoding = AUDIO_ENCODING_ULAW;
                   1478:                exp_precision = 8;
                   1479:                exp_channels = 1;
                   1480:                exp_sample_rate = 8000;
                   1481:                exp_pause = 0;
1.1       isaki    1482:        } else {
1.7       isaki    1483:                exp_encoding = AUDIO_ENCODING_SLINEAR_LE;
                   1484:                exp_precision = 16;
                   1485:                exp_channels = 2;
                   1486:                exp_sample_rate = 11025;
                   1487:                exp_pause = 1;
1.1       isaki    1488:        }
                   1489:
1.7       isaki    1490:        /* /dev/audioctl is always "not opened" */
                   1491:        if (strcmp(devname, "audioctl") == 0) {
                   1492:                exp_mode = 0;
                   1493:                exp_popen = 0;
                   1494:                exp_ropen = 0;
1.1       isaki    1495:        } else {
1.7       isaki    1496:                exp_mode = mode2aumode(mode);
                   1497:                exp_popen = can_play;
                   1498:                exp_ropen = can_rec;
1.1       isaki    1499:        }
                   1500:
                   1501:
                   1502:        /*
1.7       isaki    1503:         * At first, initialize the sticky parameters both of play and rec.
                   1504:         * This uses /dev/audio to verify /dev/audio.  It's not good way but
                   1505:         * I don't have better one...
1.1       isaki    1506:         */
1.7       isaki    1507:        fd = OPEN(devaudio, openable_mode());
1.1       isaki    1508:        REQUIRED_SYS_OK(fd);
                   1509:        r = CLOSE(fd);
                   1510:        REQUIRED_SYS_EQ(0, r);
                   1511:
                   1512:        /*
1.7       isaki    1513:         * Open target device and check the initial parameters
                   1514:         * At this moment, all devices are initialized by default.
1.1       isaki    1515:         */
1.7       isaki    1516:        fd = OPEN(devfile, mode);
1.1       isaki    1517:        REQUIRED_SYS_OK(fd);
                   1518:        memset(&ai, 0, sizeof(ai));
                   1519:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   1520:        REQUIRED_SYS_EQ(0, r);
                   1521:
                   1522:        XP_NE(0, ai.blocksize);
                   1523:                /* hiwat/lowat */
1.7       isaki    1524:        XP_EQ(exp_mode, ai.mode);
1.1       isaki    1525:        /* ai.play */
                   1526:        XP_EQ(8000, ai.play.sample_rate);
                   1527:        XP_EQ(1, ai.play.channels);
                   1528:        XP_EQ(8, ai.play.precision);
                   1529:        XP_EQ(AUDIO_ENCODING_ULAW, ai.play.encoding);
                   1530:                /* gain */
                   1531:                /* port */
                   1532:        XP_EQ(0, ai.play.seek);
                   1533:                /* avail_ports */
1.7       isaki    1534:        XP_NE(0, ai.play.buffer_size);
1.1       isaki    1535:        XP_EQ(0, ai.play.samples);
                   1536:        XP_EQ(0, ai.play.eof);
                   1537:        XP_EQ(0, ai.play.pause);
                   1538:        XP_EQ(0, ai.play.error);
                   1539:        XP_EQ(0, ai.play.waiting);
                   1540:                /* balance */
1.7       isaki    1541:        XP_EQ(exp_popen, ai.play.open);
1.1       isaki    1542:        XP_EQ(0, ai.play.active);
                   1543:        /* ai.record */
                   1544:        XP_EQ(8000, ai.record.sample_rate);
                   1545:        XP_EQ(1, ai.record.channels);
                   1546:        XP_EQ(8, ai.record.precision);
                   1547:        XP_EQ(AUDIO_ENCODING_ULAW, ai.record.encoding);
                   1548:                /* gain */
                   1549:                /* port */
                   1550:        XP_EQ(0, ai.record.seek);
                   1551:                /* avail_ports */
1.7       isaki    1552:        XP_NE(0, ai.record.buffer_size);
1.1       isaki    1553:        XP_EQ(0, ai.record.samples);
                   1554:        XP_EQ(0, ai.record.eof);
                   1555:        XP_EQ(0, ai.record.pause);
                   1556:        XP_EQ(0, ai.record.error);
                   1557:        XP_EQ(0, ai.record.waiting);
                   1558:                /* balance */
1.7       isaki    1559:        XP_EQ(exp_ropen, ai.record.open);
1.1       isaki    1560:        /*
                   1561:         * NetBSD7,8 (may?) be active when opened in recording mode but
                   1562:         * recording has not started yet. (?)
                   1563:         * NetBSD9 is not active at that time.
                   1564:         */
                   1565:        if (netbsd < 9) {
                   1566:        } else {
                   1567:                XP_EQ(0, ai.record.active);
                   1568:        }
                   1569:        /* Save it */
                   1570:        ai0 = ai;
                   1571:
                   1572:        /*
                   1573:         * Change much as possible
                   1574:         */
                   1575:        AUDIO_INITINFO(&ai);
1.7       isaki    1576:        ai.mode = ai0.mode ^ AUMODE_PLAY_ALL;
1.1       isaki    1577:        ai.play.sample_rate = 11025;
                   1578:        ai.play.channels = 2;
                   1579:        ai.play.precision = 16;
                   1580:        ai.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
                   1581:        ai.play.pause = 1;
                   1582:        ai.record.sample_rate = 11025;
                   1583:        ai.record.channels = 2;
                   1584:        ai.record.precision = 16;
                   1585:        ai.record.encoding = AUDIO_ENCODING_SLINEAR_LE;
                   1586:        ai.record.pause = 1;
                   1587:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "ai");
                   1588:        REQUIRED_SYS_EQ(0, r);
                   1589:        r = CLOSE(fd);
                   1590:        REQUIRED_SYS_EQ(0, r);
                   1591:
                   1592:        /*
1.7       isaki    1593:         * Open the same target device again and check
1.1       isaki    1594:         */
1.7       isaki    1595:        fd = OPEN(devfile, mode);
1.1       isaki    1596:        REQUIRED_SYS_OK(fd);
                   1597:        memset(&ai, 0, sizeof(ai));
                   1598:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   1599:        REQUIRED_SYS_EQ(0, r);
                   1600:
1.7       isaki    1601:        XP_NE(0, ai.blocksize);
1.1       isaki    1602:                /* hiwat/lowat */
                   1603:        if (netbsd < 8) {
                   1604:                /*
1.7       isaki    1605:                 * On NetBSD7, the behavior when changing ai.mode on
1.1       isaki    1606:                 * /dev/audioctl can not be explained yet but I won't
                   1607:                 * verify it more over.
                   1608:                 */
                   1609:        } else {
1.7       isaki    1610:                /* On NetBSD9, changing mode never affects other fds */
                   1611:                XP_EQ(exp_mode, ai.mode);
1.1       isaki    1612:        }
                   1613:        /* ai.play */
1.7       isaki    1614:        XP_EQ(exp_sample_rate, ai.play.sample_rate);
                   1615:        XP_EQ(exp_channels, ai.play.channels);
                   1616:        XP_EQ(exp_precision, ai.play.precision);
                   1617:        XP_EQ(exp_encoding, ai.play.encoding);
1.1       isaki    1618:                /* gain */
                   1619:                /* port */
                   1620:        XP_EQ(0, ai.play.seek);
                   1621:                /* avail_ports */
1.7       isaki    1622:        XP_NE(0, ai.play.buffer_size);
1.1       isaki    1623:        XP_EQ(0, ai.play.samples);
                   1624:        XP_EQ(0, ai.play.eof);
1.7       isaki    1625:        XP_EQ(exp_pause, ai.play.pause);
1.1       isaki    1626:        XP_EQ(0, ai.play.error);
                   1627:        XP_EQ(0, ai.play.waiting);
                   1628:                /* balance */
1.7       isaki    1629:        XP_EQ(exp_popen, ai.play.open);
1.1       isaki    1630:        XP_EQ(0, ai.play.active);
                   1631:        /* ai.record */
1.7       isaki    1632:        XP_EQ(exp_sample_rate, ai.record.sample_rate);
                   1633:        XP_EQ(exp_channels, ai.record.channels);
                   1634:        XP_EQ(exp_precision, ai.record.precision);
                   1635:        XP_EQ(exp_encoding, ai.record.encoding);
1.1       isaki    1636:                /* gain */
                   1637:                /* port */
                   1638:        XP_EQ(0, ai.record.seek);
                   1639:                /* avail_ports */
1.7       isaki    1640:        XP_NE(0, ai.record.buffer_size);
1.1       isaki    1641:        XP_EQ(0, ai.record.samples);
                   1642:        XP_EQ(0, ai.record.eof);
1.7       isaki    1643:        XP_EQ(exp_pause, ai.record.pause);
1.1       isaki    1644:        XP_EQ(0, ai.record.error);
                   1645:        XP_EQ(0, ai.record.waiting);
                   1646:                /* balance */
1.7       isaki    1647:        XP_EQ(exp_ropen, ai.record.open);
1.1       isaki    1648:        if (netbsd < 9) {
                   1649:        } else {
                   1650:                XP_EQ(0, ai.record.active);
                   1651:        }
                   1652:
                   1653:        r = CLOSE(fd);
                   1654:        REQUIRED_SYS_EQ(0, r);
                   1655: }
1.7       isaki    1656: DEF(open_audio_RDONLY)         { test_open("audio", O_RDONLY); }
                   1657: DEF(open_audio_WRONLY)         { test_open("audio", O_WRONLY); }
                   1658: DEF(open_audio_RDWR)           { test_open("audio", O_RDWR);   }
                   1659: DEF(open_sound_RDONLY)         { test_open("sound", O_RDONLY); }
                   1660: DEF(open_sound_WRONLY)         { test_open("sound", O_WRONLY); }
                   1661: DEF(open_sound_RDWR)           { test_open("sound", O_RDWR);   }
                   1662: DEF(open_audioctl_RDONLY)      { test_open("audioctl", O_RDONLY); }
                   1663: DEF(open_audioctl_WRONLY)      { test_open("audioctl", O_WRONLY); }
                   1664: DEF(open_audioctl_RDWR)                { test_open("audioctl", O_RDWR);   }
1.1       isaki    1665:
                   1666: /*
                   1667:  * Open (1) /dev/sound -> (2) /dev/audio -> (3) /dev/sound,
                   1668:  * Both of /dev/audio and /dev/sound share the sticky parameters,
                   1669:  * /dev/sound inherits and use it but /dev/audio initialize and use it.
                   1670:  * So 2nd audio descriptor affects 3rd sound descriptor.
                   1671:  */
                   1672: DEF(open_sound_sticky)
                   1673: {
                   1674:        struct audio_info ai;
                   1675:        int fd;
                   1676:        int r;
                   1677:        int openmode;
                   1678:
                   1679:        TEST("open_sound_sticky");
                   1680:
                   1681:        openmode = openable_mode();
                   1682:
                   1683:        /* First, open /dev/sound and change encoding as a delegate */
                   1684:        fd = OPEN(devsound, openmode);
                   1685:        REQUIRED_SYS_OK(fd);
                   1686:        AUDIO_INITINFO(&ai);
                   1687:        ai.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
                   1688:        ai.record.encoding = AUDIO_ENCODING_SLINEAR_LE;
                   1689:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "");
                   1690:        REQUIRED_SYS_EQ(0, r);
                   1691:        r = CLOSE(fd);
                   1692:        REQUIRED_SYS_EQ(0, r);
                   1693:
                   1694:        /* Next, open /dev/audio.  It makes the encoding mulaw */
                   1695:        fd = OPEN(devaudio, openmode);
                   1696:        REQUIRED_SYS_OK(fd);
                   1697:        r = CLOSE(fd);
                   1698:        REQUIRED_SYS_EQ(0, r);
                   1699:
                   1700:        /* And then, open /dev/sound again */
                   1701:        fd = OPEN(devsound, openmode);
                   1702:        REQUIRED_SYS_OK(fd);
                   1703:        memset(&ai, 0, sizeof(ai));
                   1704:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   1705:        REQUIRED_SYS_EQ(0, r);
                   1706:        XP_EQ(AUDIO_ENCODING_ULAW, ai.play.encoding);
                   1707:        XP_EQ(AUDIO_ENCODING_ULAW, ai.record.encoding);
                   1708:        r = CLOSE(fd);
                   1709:        REQUIRED_SYS_EQ(0, r);
                   1710: }
                   1711:
                   1712: /*
1.7       isaki    1713:  * /dev/audioctl has stickiness like /dev/sound.
1.1       isaki    1714:  */
                   1715: DEF(open_audioctl_sticky)
                   1716: {
                   1717:        struct audio_info ai;
                   1718:        int fd;
                   1719:        int r;
                   1720:        int openmode;
                   1721:
                   1722:        TEST("open_audioctl_sticky");
                   1723:
                   1724:        openmode = openable_mode();
                   1725:
1.7       isaki    1726:        /* First, open /dev/audio and change encoding */
                   1727:        fd = OPEN(devaudio, openmode);
1.1       isaki    1728:        REQUIRED_SYS_OK(fd);
                   1729:        AUDIO_INITINFO(&ai);
                   1730:        ai.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
1.7       isaki    1731:        ai.play.precision = 16;
1.1       isaki    1732:        ai.record.encoding = AUDIO_ENCODING_SLINEAR_LE;
1.7       isaki    1733:        ai.record.precision = 16;
                   1734:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "SLINEAR_LE");
1.1       isaki    1735:        REQUIRED_SYS_EQ(0, r);
                   1736:        r = CLOSE(fd);
                   1737:        REQUIRED_SYS_EQ(0, r);
                   1738:
1.7       isaki    1739:        /* Next, open /dev/audioctl.  It should be affected */
1.1       isaki    1740:        fd = OPEN(devaudioctl, openmode);
                   1741:        REQUIRED_SYS_OK(fd);
                   1742:        memset(&ai, 0, sizeof(ai));
                   1743:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   1744:        REQUIRED_SYS_EQ(0, r);
                   1745:        XP_EQ(AUDIO_ENCODING_SLINEAR_LE, ai.play.encoding);
1.7       isaki    1746:        XP_EQ(16, ai.play.precision);
1.1       isaki    1747:        XP_EQ(AUDIO_ENCODING_SLINEAR_LE, ai.record.encoding);
1.7       isaki    1748:        XP_EQ(16, ai.record.precision);
                   1749:
                   1750:        /* Then, change /dev/audioctl */
                   1751:        AUDIO_INITINFO(&ai);
                   1752:        ai.play.encoding = AUDIO_ENCODING_ULAW;
                   1753:        ai.play.precision = 8;
                   1754:        ai.record.encoding = AUDIO_ENCODING_ULAW;
                   1755:        ai.record.precision = 8;
                   1756:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "ULAW");
                   1757:        REQUIRED_SYS_EQ(0, r);
                   1758:        r = CLOSE(fd);
                   1759:        REQUIRED_SYS_EQ(0, r);
                   1760:
                   1761:        /* Finally, open /dev/sound.  It also should be affected  */
                   1762:        fd = OPEN(devsound, openmode);
                   1763:        REQUIRED_SYS_OK(fd);
                   1764:        memset(&ai, 0, sizeof(ai));
                   1765:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   1766:        REQUIRED_SYS_EQ(0, r);
                   1767:        XP_EQ(AUDIO_ENCODING_ULAW, ai.play.encoding);
                   1768:        XP_EQ(8, ai.play.precision);
                   1769:        XP_EQ(AUDIO_ENCODING_ULAW, ai.record.encoding);
                   1770:        XP_EQ(8, ai.record.precision);
1.1       isaki    1771:        r = CLOSE(fd);
                   1772:        REQUIRED_SYS_EQ(0, r);
                   1773: }
                   1774:
                   1775: /*
                   1776:  * Open two descriptors simultaneously.
                   1777:  */
                   1778: void
                   1779: test_open_simul(int mode0, int mode1)
                   1780: {
                   1781:        struct audio_info ai;
                   1782:        int fd0, fd1;
                   1783:        int i;
                   1784:        int r;
                   1785:        int actmode;
                   1786: #define AUMODE_BOTH (AUMODE_PLAY | AUMODE_RECORD)
                   1787:        struct {
                   1788:                int mode0;
                   1789:                int mode1;
                   1790:        } expfulltable[] = {
                   1791:                /* expected fd0         expected fd1 (-errno expects error) */
                   1792:                { AUMODE_RECORD,        AUMODE_RECORD },        // REC, REC
                   1793:                { AUMODE_RECORD,        AUMODE_PLAY },          // REC, PLAY
                   1794:                { AUMODE_RECORD,        AUMODE_BOTH },          // REC, BOTH
                   1795:                { AUMODE_PLAY,          AUMODE_RECORD },        // PLAY, REC
                   1796:                { AUMODE_PLAY,          AUMODE_PLAY },          // PLAY, PLAY
                   1797:                { AUMODE_PLAY,          AUMODE_BOTH },          // PLAY, BOTH
                   1798:                { AUMODE_BOTH,          AUMODE_RECORD },        // BOTH, REC
                   1799:                { AUMODE_BOTH,          AUMODE_PLAY },          // BOTH, PLAY
                   1800:                { AUMODE_BOTH,          AUMODE_BOTH },          // BOTH, BOTH
                   1801:        },
                   1802:        exphalftable[] = {
                   1803:                /* expected fd0         expected fd1 (-errno expects error) */
                   1804:                { AUMODE_RECORD,        AUMODE_RECORD },        // REC, REC
                   1805:                { AUMODE_RECORD,        -ENODEV },              // REC, PLAY
                   1806:                { AUMODE_RECORD,        -ENODEV },              // REC, BOTH
                   1807:                { AUMODE_PLAY,          -ENODEV },              // PLAY, REC
                   1808:                { AUMODE_PLAY,          AUMODE_PLAY },          // PLAY, PLAY
                   1809:                { AUMODE_PLAY,          AUMODE_PLAY },          // PLAY, BOTH
                   1810:                { AUMODE_PLAY,          -ENODEV },              // BOTH, REC
                   1811:                { AUMODE_PLAY,          AUMODE_PLAY },          // BOTH, PLAY
                   1812:                { AUMODE_PLAY,          AUMODE_PLAY },          // BOTH, BOTH
                   1813:        }, *exptable;
                   1814:
                   1815:        /* The expected values are different in half-duplex or full-duplex */
                   1816:        if (hw_fulldup()) {
                   1817:                exptable = expfulltable;
                   1818:        } else {
                   1819:                exptable = exphalftable;
                   1820:        }
                   1821:
                   1822:        TEST("open_simul_%s_%s",
                   1823:            openmode_str[mode0] + 2,
                   1824:            openmode_str[mode1] + 2);
                   1825:
                   1826:        if (netbsd < 8) {
                   1827:                XP_SKIP("Multiple open is not supported");
                   1828:                return;
                   1829:        }
                   1830:
                   1831:        if (mode2aumode(mode0) == 0 || mode2aumode(mode1) == 0) {
                   1832:                XP_SKIP("Operation not allowed on this hardware property");
                   1833:                return;
                   1834:        }
                   1835:
                   1836:        i = mode0 * 3 + mode1;
                   1837:
                   1838:        /* Open first one */
                   1839:        fd0 = OPEN(devaudio, mode0);
                   1840:        REQUIRED_SYS_OK(fd0);
                   1841:        r = IOCTL(fd0, AUDIO_GETBUFINFO, &ai, "");
                   1842:        REQUIRED_SYS_EQ(0, r);
                   1843:        actmode = ai.mode & AUMODE_BOTH;
                   1844:        XP_EQ(exptable[i].mode0, actmode);
                   1845:
                   1846:        /* Open second one */
                   1847:        fd1 = OPEN(devaudio, mode1);
                   1848:        if (exptable[i].mode1 >= 0) {
                   1849:                /* Case to expect to be able to open */
                   1850:                REQUIRED_SYS_OK(fd1);
                   1851:                r = IOCTL(fd1, AUDIO_GETBUFINFO, &ai, "");
                   1852:                XP_SYS_EQ(0, r);
                   1853:                if (r == 0) {
                   1854:                        actmode = ai.mode & AUMODE_BOTH;
                   1855:                        XP_EQ(exptable[i].mode1, actmode);
                   1856:                }
                   1857:        } else {
                   1858:                /* Case to expect not to be able to open */
                   1859:                XP_SYS_NG(ENODEV, fd1);
                   1860:                if (fd1 == -1) {
                   1861:                        XP_EQ(-exptable[i].mode1, errno);
                   1862:                } else {
                   1863:                        r = IOCTL(fd1, AUDIO_GETBUFINFO, &ai, "");
                   1864:                        XP_SYS_EQ(0, r);
                   1865:                        if (r == 0) {
                   1866:                                actmode = ai.mode & AUMODE_BOTH;
                   1867:                                XP_FAIL("expects error but %d", actmode);
                   1868:                        }
                   1869:                }
                   1870:        }
                   1871:
                   1872:        if (fd1 >= 0) {
                   1873:                r = CLOSE(fd1);
                   1874:                XP_SYS_EQ(0, r);
                   1875:        }
                   1876:
                   1877:        r = CLOSE(fd0);
                   1878:        XP_SYS_EQ(0, r);
                   1879: }
                   1880: DEF(open_simul_RDONLY_RDONLY)  { test_open_simul(O_RDONLY, O_RDONLY);  }
                   1881: DEF(open_simul_RDONLY_WRONLY)  { test_open_simul(O_RDONLY, O_WRONLY);  }
                   1882: DEF(open_simul_RDONLY_RDWR)    { test_open_simul(O_RDONLY, O_RDWR);    }
                   1883: DEF(open_simul_WRONLY_RDONLY)  { test_open_simul(O_WRONLY, O_RDONLY);  }
                   1884: DEF(open_simul_WRONLY_WRONLY)  { test_open_simul(O_WRONLY, O_WRONLY);  }
                   1885: DEF(open_simul_WRONLY_RDWR)    { test_open_simul(O_WRONLY, O_RDWR);    }
                   1886: DEF(open_simul_RDWR_RDONLY)    { test_open_simul(O_RDWR, O_RDONLY);    }
                   1887: DEF(open_simul_RDWR_WRONLY)    { test_open_simul(O_RDWR, O_WRONLY);    }
                   1888: DEF(open_simul_RDWR_RDWR)      { test_open_simul(O_RDWR, O_RDWR);      }
                   1889:
                   1890: /*
                   1891:  * /dev/audio can be opened by other user who opens /dev/audio.
                   1892:  */
                   1893: void
1.4       isaki    1894: try_open_multiuser(bool multiuser)
1.1       isaki    1895: {
                   1896:        int fd0;
                   1897:        int fd1;
                   1898:        int r;
                   1899:        uid_t ouid;
                   1900:
                   1901:        /*
                   1902:         * Test1: Open as root first and then unprivileged user.
                   1903:         */
                   1904:
                   1905:        /* At first, open as root */
                   1906:        fd0 = OPEN(devaudio, openable_mode());
                   1907:        REQUIRED_SYS_OK(fd0);
                   1908:
                   1909:        ouid = GETUID();
                   1910:        r = SETEUID(1);
                   1911:        REQUIRED_SYS_EQ(0, r);
                   1912:
                   1913:        /* Then, open as unprivileged user */
                   1914:        fd1 = OPEN(devaudio, openable_mode());
                   1915:        if (multiuser) {
                   1916:                /* If multiuser, another user also can open */
                   1917:                XP_SYS_OK(fd1);
                   1918:        } else {
                   1919:                /* If not multiuser, another user cannot open */
                   1920:                XP_SYS_NG(EPERM, fd1);
                   1921:        }
                   1922:        if (fd1 != -1) {
                   1923:                r = CLOSE(fd1);
                   1924:                XP_SYS_EQ(0, r);
                   1925:        }
                   1926:
                   1927:        r = SETEUID(ouid);
                   1928:        REQUIRED_SYS_EQ(0, r);
                   1929:
                   1930:        r = CLOSE(fd0);
                   1931:        XP_SYS_EQ(0, r);
                   1932:
                   1933:        /*
                   1934:         * Test2: Open as unprivileged user first and then root.
                   1935:         */
                   1936:
                   1937:        /* At first, open as unprivileged user */
                   1938:        ouid = GETUID();
                   1939:        r = SETEUID(1);
                   1940:        REQUIRED_SYS_EQ(0, r);
                   1941:
                   1942:        fd0 = OPEN(devaudio, openable_mode());
                   1943:        REQUIRED_SYS_OK(fd0);
                   1944:
                   1945:        /* Then open as root */
                   1946:        r = SETEUID(ouid);
                   1947:        REQUIRED_SYS_EQ(0, r);
                   1948:
                   1949:        /* root always can open */
                   1950:        fd1 = OPEN(devaudio, openable_mode());
                   1951:        XP_SYS_OK(fd1);
                   1952:        if (fd1 != -1) {
                   1953:                r = CLOSE(fd1);
                   1954:                XP_SYS_EQ(0, r);
                   1955:        }
                   1956:
                   1957:        /* Close first one as unprivileged user */
                   1958:        r = SETEUID(1);
                   1959:        REQUIRED_SYS_EQ(0, r);
                   1960:        r = CLOSE(fd0);
                   1961:        XP_SYS_EQ(0, r);
                   1962:        r = SETEUID(ouid);
                   1963:        REQUIRED_SYS_EQ(0, r);
                   1964: }
                   1965: /*
                   1966:  * This is a wrapper for open_multiuser.
                   1967:  * XXX XP_* macros are not compatible with on-error-goto, we need try-catch...
                   1968:  */
                   1969: void
1.4       isaki    1970: test_open_multiuser(bool multiuser)
1.1       isaki    1971: {
                   1972:        char mibname[32];
                   1973:        bool oldval;
                   1974:        size_t oldlen;
                   1975:        int r;
                   1976:
                   1977:        TEST("open_multiuser_%d", multiuser);
                   1978:        if (netbsd < 8) {
                   1979:                XP_SKIP("Multiple open is not supported");
                   1980:                return;
                   1981:        }
                   1982:        if (netbsd < 9) {
                   1983:                /* NetBSD8 has no way (difficult) to determine device name */
                   1984:                XP_SKIP("NetBSD8 cannot determine device name");
                   1985:                return;
                   1986:        }
                   1987:        if (geteuid() != 0) {
                   1988:                XP_SKIP("Must be run as a privileged user");
                   1989:                return;
                   1990:        }
                   1991:
                   1992:        /* Get current multiuser mode (and save it) */
                   1993:        snprintf(mibname, sizeof(mibname), "hw.%s.multiuser", devicename);
                   1994:        oldlen = sizeof(oldval);
                   1995:        r = SYSCTLBYNAME(mibname, &oldval, &oldlen, NULL, 0);
                   1996:        REQUIRED_SYS_EQ(0, r);
                   1997:        DPRINTF("  > multiuser=%d\n", oldval);
                   1998:
                   1999:        /* Change if necessary */
                   2000:        if (oldval != multiuser) {
1.4       isaki    2001:                r = SYSCTLBYNAME(mibname, NULL, NULL, &multiuser,
                   2002:                    sizeof(multiuser));
1.1       isaki    2003:                REQUIRED_SYS_EQ(0, r);
                   2004:                DPRINTF("  > new multiuser=%d\n", multiuser);
                   2005:        }
                   2006:
                   2007:        /* Do test */
                   2008:        try_open_multiuser(multiuser);
                   2009:
                   2010:        /* Restore multiuser mode */
1.4       isaki    2011:        if (oldval != multiuser) {
1.1       isaki    2012:                DPRINTF("  > restore multiuser to %d\n", oldval);
                   2013:                r = SYSCTLBYNAME(mibname, NULL, NULL, &oldval, sizeof(oldval));
                   2014:                REQUIRED_SYS_EQ(0, r);
                   2015:        }
                   2016: }
1.4       isaki    2017: DEF(open_multiuser_0)  { test_open_multiuser(false); }
                   2018: DEF(open_multiuser_1)  { test_open_multiuser(true); }
1.1       isaki    2019:
                   2020: /*
                   2021:  * Normal playback (with PLAY_ALL).
                   2022:  * It does not verify real playback data.
                   2023:  */
                   2024: DEF(write_PLAY_ALL)
                   2025: {
                   2026:        char buf[8000];
                   2027:        int fd;
                   2028:        int r;
                   2029:
                   2030:        TEST("write_PLAY_ALL");
                   2031:
                   2032:        fd = OPEN(devaudio, O_WRONLY);
                   2033:        if (hw_canplay()) {
                   2034:                REQUIRED_SYS_OK(fd);
                   2035:        } else {
                   2036:                XP_SYS_NG(ENXIO, fd);
                   2037:                return;
                   2038:        }
                   2039:
                   2040:        /* mulaw 1sec silence */
                   2041:        memset(buf, 0xff, sizeof(buf));
                   2042:        r = WRITE(fd, buf, sizeof(buf));
                   2043:        XP_SYS_EQ(sizeof(buf), r);
                   2044:
                   2045:        r = CLOSE(fd);
                   2046:        XP_SYS_EQ(0, r);
                   2047: }
                   2048:
                   2049: /*
                   2050:  * Normal playback (without PLAY_ALL).
                   2051:  * It does not verify real playback data.
                   2052:  */
                   2053: DEF(write_PLAY)
                   2054: {
                   2055:        struct audio_info ai;
                   2056:        char *wav;
                   2057:        int wavsize;
                   2058:        int totalsize;
                   2059:        int fd;
                   2060:        int r;
                   2061:
                   2062:        TEST("write_PLAY");
                   2063:
                   2064:        fd = OPEN(devaudio, O_WRONLY);
                   2065:        if (hw_canplay()) {
                   2066:                REQUIRED_SYS_OK(fd);
                   2067:        } else {
                   2068:                XP_SYS_NG(ENXIO, fd);
                   2069:                return;
                   2070:        }
                   2071:
                   2072:        /* Drop PLAY_ALL */
                   2073:        AUDIO_INITINFO(&ai);
                   2074:        ai.mode = AUMODE_PLAY;
                   2075:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "mode");
                   2076:        REQUIRED_SYS_EQ(0, r);
                   2077:
                   2078:        /* Check mode and get blocksize */
                   2079:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   2080:        REQUIRED_SYS_EQ(0, r);
                   2081:        XP_EQ(AUMODE_PLAY, ai.mode);
                   2082:
                   2083:        wavsize = ai.blocksize;
                   2084:        wav = (char *)malloc(wavsize);
                   2085:        REQUIRED_IF(wav != NULL);
                   2086:        memset(wav, 0xff, wavsize);
                   2087:
                   2088:        /* Write blocks until 1sec */
                   2089:        for (totalsize = 0; totalsize < 8000; ) {
                   2090:                r = WRITE(fd, wav, wavsize);
                   2091:                XP_SYS_EQ(wavsize, r);
                   2092:                if (r == -1)
                   2093:                        break;  /* XXX */
                   2094:                totalsize += r;
                   2095:        }
                   2096:
                   2097:        /* XXX What should I test it? */
                   2098:        /* Check ai.play.error */
                   2099:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   2100:        REQUIRED_SYS_EQ(0, r);
                   2101:        XP_EQ(0, ai.play.error);
                   2102:
                   2103:        /* Playback data is no longer necessary */
                   2104:        r = IOCTL(fd, AUDIO_FLUSH, NULL, "");
                   2105:        REQUIRED_SYS_EQ(0, r);
                   2106:
                   2107:        r = CLOSE(fd);
                   2108:        REQUIRED_SYS_EQ(0, r);
                   2109:
                   2110:        free(wav);
                   2111: }
                   2112:
                   2113: /*
                   2114:  * Normal recording.
                   2115:  * It does not verify real recorded data.
                   2116:  */
                   2117: DEF(read)
                   2118: {
                   2119:        char buf[8000];
                   2120:        int fd;
                   2121:        int r;
                   2122:
                   2123:        TEST("read");
                   2124:
                   2125:        fd = OPEN(devaudio, O_RDONLY);
                   2126:        if (hw_canrec()) {
                   2127:                REQUIRED_SYS_OK(fd);
                   2128:        } else {
                   2129:                XP_SYS_NG(ENXIO, fd);
                   2130:                return;
                   2131:        }
                   2132:
                   2133:        /* mulaw 1sec */
                   2134:        r = READ(fd, buf, sizeof(buf));
                   2135:        XP_SYS_EQ(sizeof(buf), r);
                   2136:
                   2137:        r = CLOSE(fd);
                   2138:        XP_SYS_EQ(0, r);
                   2139: }
                   2140:
                   2141: /*
                   2142:  * Repeat open-write-close cycle.
                   2143:  */
                   2144: DEF(rept_write)
                   2145: {
                   2146:        struct timeval start, end, result;
                   2147:        double res;
                   2148:        char buf[8000]; /* 1sec in 8bit-mulaw,1ch,8000Hz */
                   2149:        int fd;
                   2150:        int r;
                   2151:        int n;
                   2152:
                   2153:        TEST("rept_write");
                   2154:
                   2155:        if (hw_canplay() == 0) {
                   2156:                XP_SKIP("This test is only for playable device");
                   2157:                return;
                   2158:        }
                   2159:
                   2160:        /* XXX It may timeout on some hardware driver. */
                   2161:        XP_SKIP("not yet");
                   2162:        return;
                   2163:
                   2164:        memset(buf, 0xff, sizeof(buf));
                   2165:        n = 3;
                   2166:        gettimeofday(&start, NULL);
                   2167:        for (int i = 0; i < n; i++) {
                   2168:                fd = OPEN(devaudio, O_WRONLY);
                   2169:                REQUIRED_SYS_OK(fd);
                   2170:
                   2171:                r = WRITE(fd, buf, sizeof(buf));
                   2172:                XP_SYS_EQ(sizeof(buf), r);
                   2173:
                   2174:                r = CLOSE(fd);
                   2175:                XP_SYS_EQ(0, r);
                   2176:        }
                   2177:        gettimeofday(&end, NULL);
                   2178:        timersub(&end, &start, &result);
                   2179:        res = (double)result.tv_sec + (double)result.tv_usec / 1000000;
                   2180:        /* Make judgement but not too strict */
                   2181:        if (res >= n * 1.5) {
                   2182:                XP_FAIL("expects %d sec but %4.1f sec", n, res);
                   2183:                return;
                   2184:        }
                   2185: }
                   2186:
                   2187: /*
                   2188:  * Repeat open-read-close cycle.
                   2189:  */
                   2190: DEF(rept_read)
                   2191: {
                   2192:        struct timeval start, end, result;
                   2193:        double res;
                   2194:        char buf[8000]; /* 1sec in 8bit-mulaw,1ch,8000Hz */
                   2195:        int fd;
                   2196:        int r;
                   2197:        int n;
                   2198:
                   2199:        TEST("rept_read");
                   2200:
                   2201:        if (hw_canrec() == 0) {
                   2202:                XP_SKIP("This test is only for recordable device");
                   2203:                return;
                   2204:        }
                   2205:
                   2206:        /* XXX It may timeout on some hardware driver. */
                   2207:        XP_SKIP("not yet");
                   2208:        return;
                   2209:
                   2210:        n = 3;
                   2211:        gettimeofday(&start, NULL);
                   2212:        for (int i = 0; i < n; i++) {
                   2213:                fd = OPEN(devaudio, O_RDONLY);
                   2214:                REQUIRED_SYS_OK(fd);
                   2215:
                   2216:                r = READ(fd, buf, sizeof(buf));
                   2217:                XP_SYS_EQ(sizeof(buf), r);
                   2218:
                   2219:                r = CLOSE(fd);
                   2220:                XP_SYS_EQ(0, r);
                   2221:        }
                   2222:        gettimeofday(&end, NULL);
                   2223:        timersub(&end, &start, &result);
                   2224:        res = (double)result.tv_sec + (double)result.tv_usec / 1000000;
                   2225:        /* Make judgement but not too strict */
                   2226:        if (res >= n * 1.5) {
                   2227:                XP_FAIL("expects %d sec but %4.1f sec", n, res);
                   2228:                return;
                   2229:        }
                   2230: }
                   2231:
                   2232: /*
                   2233:  * Opening with O_RDWR on half-duplex hardware falls back to O_WRONLY.
                   2234:  * expwrite: expected to be able to play.
                   2235:  * expread : expected to be able to recored.
                   2236:  */
                   2237: void
                   2238: test_rdwr_fallback(int openmode, bool expwrite, bool expread)
                   2239: {
                   2240:        struct audio_info ai;
                   2241:        char buf[10];
                   2242:        int fd;
                   2243:        int r;
                   2244:
                   2245:        TEST("rdwr_fallback_%s", openmode_str[openmode] + 2);
                   2246:
                   2247:        if (hw_bidir() == 0) {
                   2248:                XP_SKIP("This test is only for bi-directional device");
                   2249:                return;
                   2250:        }
                   2251:
                   2252:        AUDIO_INITINFO(&ai);
                   2253:        ai.play.pause = 1;
                   2254:        ai.record.pause = 1;
                   2255:
                   2256:        fd = OPEN(devaudio, openmode);
                   2257:        REQUIRED_SYS_OK(fd);
                   2258:
                   2259:        /* Set pause not to play noise */
                   2260:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause");
                   2261:        REQUIRED_SYS_EQ(0, r);
                   2262:
                   2263:        memset(buf, 0xff, sizeof(buf));
                   2264:        r = WRITE(fd, buf, sizeof(buf));
                   2265:        if (expwrite) {
                   2266:                XP_SYS_EQ(sizeof(buf), r);
                   2267:        } else {
                   2268:                XP_SYS_NG(EBADF, r);
                   2269:        }
                   2270:
                   2271:        r = READ(fd, buf, 0);
                   2272:        if (expread) {
                   2273:                XP_SYS_EQ(0, r);
                   2274:        } else {
                   2275:                XP_SYS_NG(EBADF, r);
                   2276:        }
                   2277:
                   2278:        r = CLOSE(fd);
                   2279:        REQUIRED_SYS_EQ(0, r);
                   2280: }
                   2281: DEF(rdwr_fallback_RDONLY) { test_rdwr_fallback(O_RDONLY, false, true); }
                   2282: DEF(rdwr_fallback_WRONLY) { test_rdwr_fallback(O_WRONLY, true, false); }
                   2283: DEF(rdwr_fallback_RDWR) {
                   2284:        bool expread;
                   2285:        /*
                   2286:         * On NetBSD7, O_RDWR on half-duplex is accepted. It's possible to
                   2287:         * read and write if they don't occur at the same time.
                   2288:         * On NetBSD9, O_RDWR on half-duplex falls back O_WRONLY.
                   2289:         */
                   2290:        if (netbsd < 8) {
                   2291:                expread = true;
                   2292:        } else {
                   2293:                expread = hw_fulldup() ? true : false;
                   2294:        }
                   2295:        test_rdwr_fallback(O_RDWR, true, expread);
                   2296: }
                   2297:
                   2298: /*
                   2299:  * On full-duplex hardware, the second descriptor's readablity/writability
                   2300:  * is not depend on the first descriptor('s open mode).
                   2301:  * On half-duplex hardware, it depends on the first descriptor's open mode.
                   2302:  */
                   2303: void
                   2304: test_rdwr_two(int mode0, int mode1)
                   2305: {
                   2306:        struct audio_info ai;
                   2307:        char wbuf[100]; /* 1/80sec in 8bit-mulaw,1ch,8000Hz */
                   2308:        char rbuf[100]; /* 1/80sec in 8bit-mulaw,1ch,8000Hz */
                   2309:        bool canopen;
                   2310:        bool canwrite;
                   2311:        bool canread;
                   2312:        int fd0;
                   2313:        int fd1;
                   2314:        int r;
                   2315:        struct {
                   2316:                bool canopen;
                   2317:                bool canwrite;
                   2318:                bool canread;
                   2319:        } exptable_full[] = {
                   2320:        /*      open write read    1st, 2nd mode */
                   2321:                { 1, 0, 1 },    /* REC, REC */
                   2322:                { 1, 1, 0 },    /* REC, PLAY */
                   2323:                { 1, 1, 1 },    /* REC, BOTH */
                   2324:                { 1, 0, 1 },    /* PLAY, REC */
                   2325:                { 1, 1, 0 },    /* PLAY, PLAY */
                   2326:                { 1, 1, 1 },    /* PLAY, BOTH */
                   2327:                { 1, 0, 1 },    /* BOTH, REC */
                   2328:                { 1, 1, 0 },    /* BOTH, PLAY */
                   2329:                { 1, 1, 1 },    /* BOTH, BOTH */
                   2330:        },
                   2331:        exptable_half[] = {
                   2332:                { 1, 0, 1 },    /* REC, REC */
                   2333:                { 0, 0, 0 },    /* REC, PLAY */
                   2334:                { 0, 0, 0 },    /* REC, BOTH */
                   2335:                { 0, 0, 0 },    /* PLAY, REC */
                   2336:                { 1, 1, 0 },    /* PLAY, PLAY */
                   2337:                { 1, 1, 0 },    /* PLAY, BOTH */
                   2338:                { 0, 0, 0 },    /* BOTH, REC */
                   2339:                { 1, 1, 0 },    /* BOTH, PLAY */
                   2340:                { 0, 0, 0 },    /* BOTH, BOTH */
                   2341:        }, *exptable;
                   2342:
                   2343:        TEST("rdwr_two_%s_%s",
                   2344:            openmode_str[mode0] + 2,
                   2345:            openmode_str[mode1] + 2);
                   2346:
                   2347:        if (netbsd < 8) {
                   2348:                XP_SKIP("Multiple open is not supported");
                   2349:                return;
                   2350:        }
                   2351:        if (hw_bidir() == 0) {
                   2352:                XP_SKIP("This test is only for bi-directional device");
                   2353:                return;
                   2354:        }
                   2355:
                   2356:        exptable = hw_fulldup() ? exptable_full : exptable_half;
                   2357:
                   2358:        canopen  = exptable[mode0 * 3 + mode1].canopen;
                   2359:        canwrite = exptable[mode0 * 3 + mode1].canwrite;
                   2360:        canread  = exptable[mode0 * 3 + mode1].canread;
                   2361:
                   2362:        if (!canopen) {
                   2363:                XP_SKIP("This combination is not openable on half-duplex");
                   2364:                return;
                   2365:        }
                   2366:
                   2367:        fd0 = OPEN(devaudio, mode0);
                   2368:        REQUIRED_SYS_OK(fd0);
                   2369:
                   2370:        fd1 = OPEN(devaudio, mode1);
                   2371:        REQUIRED_SYS_OK(fd1);
                   2372:
                   2373:        /* Silent data to make no sound */
                   2374:        memset(&wbuf, 0xff, sizeof(wbuf));
                   2375:        /* Pause to make no sound */
                   2376:        AUDIO_INITINFO(&ai);
                   2377:        ai.play.pause = 1;
                   2378:        r = IOCTL(fd0, AUDIO_SETINFO, &ai, "pause");
                   2379:        XP_SYS_EQ(0, r);
                   2380:
                   2381:        /* write(fd1) */
                   2382:        r = WRITE(fd1, wbuf, sizeof(wbuf));
                   2383:        if (canwrite) {
                   2384:                XP_SYS_EQ(100, r);
                   2385:        } else {
                   2386:                XP_SYS_NG(EBADF, r);
                   2387:        }
                   2388:
                   2389:        /* read(fd1) */
                   2390:        r = READ(fd1, rbuf, sizeof(rbuf));
                   2391:        if (canread) {
                   2392:                XP_SYS_EQ(100, r);
                   2393:        } else {
                   2394:                XP_SYS_NG(EBADF, r);
                   2395:        }
                   2396:
                   2397:        r = CLOSE(fd0);
                   2398:        XP_SYS_EQ(0, r);
                   2399:        r = CLOSE(fd1);
                   2400:        XP_SYS_EQ(0, r);
                   2401: }
                   2402: DEF(rdwr_two_RDONLY_RDONLY)    { test_rdwr_two(O_RDONLY, O_RDONLY);    }
                   2403: DEF(rdwr_two_RDONLY_WRONLY)    { test_rdwr_two(O_RDONLY, O_WRONLY);    }
                   2404: DEF(rdwr_two_RDONLY_RDWR)      { test_rdwr_two(O_RDONLY, O_RDWR);      }
                   2405: DEF(rdwr_two_WRONLY_RDONLY)    { test_rdwr_two(O_WRONLY, O_RDONLY);    }
                   2406: DEF(rdwr_two_WRONLY_WRONLY)    { test_rdwr_two(O_WRONLY, O_WRONLY);    }
                   2407: DEF(rdwr_two_WRONLY_RDWR)      { test_rdwr_two(O_WRONLY, O_RDWR);      }
                   2408: DEF(rdwr_two_RDWR_RDONLY)      { test_rdwr_two(O_RDWR, O_RDONLY);      }
                   2409: DEF(rdwr_two_RDWR_WRONLY)      { test_rdwr_two(O_RDWR, O_WRONLY);      }
                   2410: DEF(rdwr_two_RDWR_RDWR)                { test_rdwr_two(O_RDWR, O_RDWR);        }
                   2411:
                   2412: /*
                   2413:  * Read and write different descriptors simultaneously.
                   2414:  * Only on full-duplex.
                   2415:  */
                   2416: DEF(rdwr_simul)
                   2417: {
                   2418:        char wbuf[1000];        /* 1/8sec in mulaw,1ch,8kHz */
                   2419:        char rbuf[1000];
                   2420:        int fd0;
                   2421:        int fd1;
                   2422:        int r;
                   2423:        int status;
                   2424:        pid_t pid;
                   2425:
                   2426:        TEST("rdwr_simul");
                   2427:        if (netbsd < 8) {
                   2428:                XP_SKIP("Multiple open is not supported");
                   2429:                return;
                   2430:        }
                   2431:        if (!hw_fulldup()) {
                   2432:                XP_SKIP("This test is only for full-duplex device");
                   2433:                return;
                   2434:        }
                   2435:
                   2436:        /* Silence data to make no sound */
                   2437:        memset(wbuf, 0xff, sizeof(wbuf));
                   2438:
                   2439:        fd0 = OPEN(devaudio, O_WRONLY);
                   2440:        REQUIRED_SYS_OK(fd0);
                   2441:        fd1 = OPEN(devaudio, O_RDONLY);
                   2442:        REQUIRED_SYS_OK(fd1);
                   2443:
                   2444:        fflush(stdout);
                   2445:        fflush(stderr);
                   2446:        pid = fork();
                   2447:        if (pid == -1)
                   2448:                xp_err(1, __LINE__, "fork");
                   2449:
                   2450:        if (pid == 0) {
                   2451:                /* child (read) */
                   2452:                for (int i = 0; i < 10; i++) {
                   2453:                        r = READ(fd1, rbuf, sizeof(rbuf));
                   2454:                        if (r == -1)
                   2455:                                xp_err(1, __LINE__, "read(i=%d)", i);
                   2456:                }
                   2457:                exit(0);
                   2458:        } else {
                   2459:                /* parent (write) */
                   2460:                for (int i = 0; i < 10; i++) {
                   2461:                        r = WRITE(fd0, wbuf, sizeof(wbuf));
                   2462:                        if (r == -1)
                   2463:                                xp_err(1, __LINE__, "write(i=%d)", i);
                   2464:                }
                   2465:                waitpid(pid, &status, 0);
                   2466:        }
                   2467:
                   2468:        CLOSE(fd0);
                   2469:        CLOSE(fd1);
                   2470:        /* If you reach here, consider as success */
                   2471:        XP_EQ(0, 0);
                   2472: }
                   2473:
                   2474: /*
                   2475:  * DRAIN should work even on incomplete data left.
                   2476:  */
                   2477: DEF(drain_incomplete)
                   2478: {
                   2479:        struct audio_info ai;
                   2480:        int r;
                   2481:        int fd;
                   2482:
                   2483:        TEST("drain_incomplete");
                   2484:
                   2485:        if (hw_canplay() == 0) {
                   2486:                XP_SKIP("This test is only for playable device");
                   2487:                return;
                   2488:        }
                   2489:
                   2490:        fd = OPEN(devaudio, O_WRONLY);
                   2491:        REQUIRED_SYS_OK(fd);
                   2492:
                   2493:        AUDIO_INITINFO(&ai);
                   2494:        /* let precision > 8 */
                   2495:        ai.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
                   2496:        ai.play.precision = 16;
                   2497:        ai.mode = AUMODE_PLAY;
                   2498:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "");
                   2499:        REQUIRED_SYS_EQ(0, r);
                   2500:        /* Write one byte and then close */
                   2501:        r = WRITE(fd, &r, 1);
                   2502:        XP_SYS_EQ(1, r);
                   2503:        r = CLOSE(fd);
                   2504:        XP_SYS_EQ(0, r);
                   2505: }
                   2506:
                   2507: /*
                   2508:  * DRAIN should work even in pause.
                   2509:  */
                   2510: DEF(drain_pause)
                   2511: {
                   2512:        struct audio_info ai;
                   2513:        int r;
                   2514:        int fd;
                   2515:
                   2516:        TEST("drain_pause");
                   2517:
                   2518:        if (hw_canplay() == 0) {
                   2519:                XP_SKIP("This test is only for playable device");
                   2520:                return;
                   2521:        }
                   2522:
                   2523:        fd = OPEN(devaudio, O_WRONLY);
                   2524:        REQUIRED_SYS_OK(fd);
                   2525:
                   2526:        /* Set pause */
                   2527:        AUDIO_INITINFO(&ai);
                   2528:        ai.play.pause = 1;
                   2529:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "");
                   2530:        XP_SYS_EQ(0, r);
                   2531:        /* Write some data and then close */
                   2532:        r = WRITE(fd, &r, 4);
                   2533:        XP_SYS_EQ(4, r);
                   2534:        r = CLOSE(fd);
                   2535:        XP_SYS_EQ(0, r);
                   2536: }
                   2537:
                   2538: /*
                   2539:  * DRAIN does not affect for record-only descriptor.
                   2540:  */
                   2541: DEF(drain_onrec)
                   2542: {
                   2543:        int fd;
                   2544:        int r;
                   2545:
                   2546:        TEST("drain_onrec");
                   2547:
                   2548:        if (hw_canrec() == 0) {
                   2549:                XP_SKIP("This test is only for recordable device");
                   2550:                return;
                   2551:        }
                   2552:
                   2553:        fd = OPEN(devaudio, O_RDONLY);
                   2554:        REQUIRED_SYS_OK(fd);
                   2555:
                   2556:        r = IOCTL(fd, AUDIO_DRAIN, NULL, "");
                   2557:        XP_SYS_EQ(0, r);
                   2558:
                   2559:        r = CLOSE(fd);
                   2560:        XP_SYS_EQ(0, r);
                   2561: }
                   2562:
                   2563: /*
                   2564:  * Whether mmap() succeeds with specified parameter.
                   2565:  */
                   2566: void
                   2567: test_mmap_mode(int mode, int prot)
                   2568: {
                   2569:        char buf[10];
                   2570:        struct audio_info ai;
                   2571:        const char *protstr;
                   2572:        int expected;
                   2573:        int fd;
                   2574:        int r;
                   2575:        int len;
                   2576:        void *ptr;
                   2577:
                   2578:        if (prot == PROT_NONE) {
                   2579:                protstr = "NONE";
                   2580:        } else if (prot == PROT_READ) {
                   2581:                protstr = "READ";
                   2582:        } else if (prot == PROT_WRITE) {
                   2583:                protstr = "WRITE";
                   2584:        } else if (prot == (PROT_READ | PROT_WRITE)) {
                   2585:                protstr = "READWRITE";
                   2586:        } else {
                   2587:                xp_errx(1, __LINE__, "unknown prot %x\n", prot);
                   2588:        }
                   2589:        TEST("mmap_%s_%s", openmode_str[mode] + 2, protstr);
                   2590:        if ((props & AUDIO_PROP_MMAP) == 0) {
                   2591:                XP_SKIP("This test is only for mmap-able device");
                   2592:                return;
                   2593:        }
                   2594:        if (mode2aumode(mode) == 0) {
                   2595:                XP_SKIP("Operation not allowed on this hardware property");
                   2596:                return;
                   2597:        }
                   2598: #if !defined(NO_RUMP)
                   2599:        if (use_rump) {
                   2600:                XP_SKIP("rump doesn't support mmap");
                   2601:                return;
                   2602:        }
                   2603: #endif
                   2604:
                   2605:        /*
                   2606:         * On NetBSD7 and 8, mmap() always succeeds regardless of open mode.
                   2607:         * On NetBSD9, mmap() succeeds only for writable descriptor.
                   2608:         */
                   2609:        expected = mode2play(mode);
                   2610:        if (netbsd < 9) {
                   2611:                expected = true;
                   2612:        }
                   2613:
                   2614:        fd = OPEN(devaudio, mode);
                   2615:        REQUIRED_SYS_OK(fd);
                   2616:
                   2617:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "get");
                   2618:        REQUIRED_SYS_EQ(0, r);
                   2619:
                   2620:        len = ai.play.buffer_size;
                   2621:
                   2622:        /* Make it pause */
                   2623:        AUDIO_INITINFO(&ai);
                   2624:        ai.play.pause = 1;
                   2625:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause");
                   2626:        REQUIRED_SYS_EQ(0, r);
                   2627:
                   2628:        ptr = MMAP(NULL, len, prot, MAP_FILE, fd, 0);
                   2629:        XP_SYS_PTR(expected ? 0 : EACCES, ptr);
                   2630:        if (expected) {
                   2631:                /* XXX Doing mmap(2) doesn't inhibit read(2) */
                   2632:                if (mode2rec(mode)) {
                   2633:                        r = READ(fd, buf, 0);
                   2634:                        XP_SYS_EQ(0, r);
                   2635:                }
                   2636:                /* Doing mmap(2) inhibits write(2) */
                   2637:                if (mode2play(mode)) {
                   2638:                        /* NetBSD9 changes errno */
                   2639:                        r = WRITE(fd, buf, 0);
                   2640:                        if (netbsd < 9) {
                   2641:                                XP_SYS_NG(EINVAL, r);
                   2642:                        } else {
                   2643:                                XP_SYS_NG(EPERM, r);
                   2644:                        }
                   2645:                }
                   2646:        }
                   2647:        if (ptr != MAP_FAILED) {
                   2648:                r = MUNMAP(ptr, len);
                   2649:                XP_SYS_EQ(0, r);
                   2650:        }
                   2651:
                   2652:        /* Whether the pause is still valid */
                   2653:        if (mode2play(mode)) {
                   2654:                r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   2655:                XP_SYS_EQ(0, r);
                   2656:                XP_EQ(1, ai.play.pause);
                   2657:        }
                   2658:
                   2659:        r = CLOSE(fd);
                   2660:        XP_SYS_EQ(0, r);
                   2661:
                   2662:        reset_after_mmap();
                   2663: }
                   2664: #define PROT_READWRITE (PROT_READ | PROT_WRITE)
                   2665: DEF(mmap_mode_RDONLY_NONE)     { test_mmap_mode(O_RDONLY, PROT_NONE); }
                   2666: DEF(mmap_mode_RDONLY_READ)     { test_mmap_mode(O_RDONLY, PROT_READ); }
                   2667: DEF(mmap_mode_RDONLY_WRITE)    { test_mmap_mode(O_RDONLY, PROT_WRITE); }
                   2668: DEF(mmap_mode_RDONLY_READWRITE)        { test_mmap_mode(O_RDONLY, PROT_READWRITE); }
                   2669: DEF(mmap_mode_WRONLY_NONE)     { test_mmap_mode(O_WRONLY, PROT_NONE); }
                   2670: DEF(mmap_mode_WRONLY_READ)     { test_mmap_mode(O_WRONLY, PROT_READ); }
                   2671: DEF(mmap_mode_WRONLY_WRITE)    { test_mmap_mode(O_WRONLY, PROT_WRITE); }
                   2672: DEF(mmap_mode_WRONLY_READWRITE)        { test_mmap_mode(O_WRONLY, PROT_READWRITE); }
                   2673: DEF(mmap_mode_RDWR_NONE)       { test_mmap_mode(O_RDWR, PROT_NONE); }
                   2674: DEF(mmap_mode_RDWR_READ)       { test_mmap_mode(O_RDWR, PROT_READ); }
                   2675: DEF(mmap_mode_RDWR_WRITE)      { test_mmap_mode(O_RDWR, PROT_WRITE); }
                   2676: DEF(mmap_mode_RDWR_READWRITE)  { test_mmap_mode(O_RDWR, PROT_READWRITE); }
                   2677:
                   2678: /*
                   2679:  * Check mmap()'s length and offset.
                   2680:  */
                   2681: DEF(mmap_len)
                   2682: {
                   2683:        struct audio_info ai;
                   2684:        int fd;
                   2685:        int r;
                   2686:        size_t len;
                   2687:        off_t offset;
                   2688:        void *ptr;
                   2689:        int bufsize;
                   2690:        int pagesize;
                   2691:        int lsize;
                   2692:
                   2693:        TEST("mmap_len");
                   2694:        if ((props & AUDIO_PROP_MMAP) == 0) {
                   2695:                XP_SKIP("This test is only for mmap-able device");
                   2696:                return;
                   2697:        }
                   2698: #if !defined(NO_RUMP)
                   2699:        if (use_rump) {
                   2700:                XP_SKIP("rump doesn't support mmap");
                   2701:                return;
                   2702:        }
                   2703: #endif
                   2704:
                   2705:        len = sizeof(pagesize);
                   2706:        r = SYSCTLBYNAME("hw.pagesize", &pagesize, &len, NULL, 0);
                   2707:        REQUIRED_SYS_EQ(0, r);
                   2708:
                   2709:        fd = OPEN(devaudio, O_WRONLY);
                   2710:        REQUIRED_SYS_OK(r);
                   2711:
                   2712:        /* Get buffer_size */
                   2713:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   2714:        REQUIRED_SYS_EQ(0, r);
                   2715:        bufsize = ai.play.buffer_size;
                   2716:
                   2717:        /*
                   2718:         * XXX someone refers bufsize and another one does pagesize.
                   2719:         * I'm not sure.
                   2720:         */
                   2721:        lsize = roundup2(bufsize, pagesize);
                   2722:        struct {
                   2723:                size_t len;
                   2724:                off_t offset;
                   2725:                int exp;
                   2726:        } table[] = {
                   2727:                /* len offset   expected */
                   2728:
                   2729:                { 0,    0,      0 },            /* len is 0  */
                   2730:                { 1,    0,      0 },            /* len is smaller than lsize */
                   2731:                { lsize, 0,     0 },            /* len is the same as lsize */
                   2732:                { lsize + 1, 0, EOVERFLOW },    /* len is larger */
                   2733:
                   2734:                { 0, -1,        EINVAL },       /* offset is negative */
                   2735:                { 0, lsize,     0 },            /* pointless param but ok */
                   2736:                { 0, lsize + 1, EOVERFLOW },    /* exceed */
                   2737:                { 1, lsize,     EOVERFLOW },    /* exceed */
                   2738:
                   2739:                /*
                   2740:                 * When you treat offset as 32bit, offset will be 0
                   2741:                 * and thus it incorrectly succeeds.
                   2742:                 */
                   2743:                { lsize,        1ULL<<32,       EOVERFLOW },
                   2744:        };
                   2745:
                   2746:        for (int i = 0; i < (int)__arraycount(table); i++) {
                   2747:                len = table[i].len;
                   2748:                offset = table[i].offset;
                   2749:                int exp = table[i].exp;
                   2750:
                   2751:                ptr = MMAP(NULL, len, PROT_WRITE, MAP_FILE, fd, offset);
                   2752:                if (exp == 0) {
                   2753:                        XP_SYS_PTR(0, ptr);
                   2754:                } else {
                   2755:                        /* NetBSD8 introduces EOVERFLOW */
                   2756:                        if (netbsd < 8 && exp == EOVERFLOW)
                   2757:                                exp = EINVAL;
                   2758:                        XP_SYS_PTR(exp, ptr);
                   2759:                }
                   2760:
                   2761:                if (ptr != MAP_FAILED) {
                   2762:                        r = MUNMAP(ptr, len);
                   2763:                        XP_SYS_EQ(0, r);
                   2764:                }
                   2765:        }
                   2766:
                   2767:        r = CLOSE(fd);
                   2768:        XP_SYS_EQ(0, r);
                   2769:
                   2770:        reset_after_mmap();
                   2771: }
                   2772:
                   2773: /*
                   2774:  * mmap() the same descriptor twice.
                   2775:  */
                   2776: DEF(mmap_twice)
                   2777: {
                   2778:        struct audio_info ai;
                   2779:        int fd;
                   2780:        int r;
                   2781:        int len;
                   2782:        void *ptr1;
                   2783:        void *ptr2;
                   2784:
                   2785:        TEST("mmap_twice");
                   2786:        if ((props & AUDIO_PROP_MMAP) == 0) {
                   2787:                XP_SKIP("This test is only for mmap-able device");
                   2788:                return;
                   2789:        }
                   2790: #if !defined(NO_RUMP)
                   2791:        if (use_rump) {
                   2792:                XP_SKIP("rump doesn't support mmap");
                   2793:                return;
                   2794:        }
                   2795: #endif
                   2796:
                   2797:        fd = OPEN(devaudio, O_WRONLY);
                   2798:        REQUIRED_SYS_OK(fd);
                   2799:
                   2800:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "get");
                   2801:        REQUIRED_SYS_EQ(0, r);
                   2802:        len = ai.play.buffer_size;
                   2803:
                   2804:        ptr1 = MMAP(NULL, len, PROT_WRITE, MAP_FILE, fd, 0);
                   2805:        XP_SYS_PTR(0, ptr1);
                   2806:
                   2807:        /* XXX I'm not sure this sucess is intended.  Anyway I follow it */
                   2808:        ptr2 = MMAP(NULL, len, PROT_WRITE, MAP_FILE, fd, 0);
                   2809:        XP_SYS_PTR(0, ptr2);
                   2810:
                   2811:        if (ptr2 != MAP_FAILED) {
                   2812:                r = MUNMAP(ptr2, len);
                   2813:                XP_SYS_EQ(0, r);
                   2814:        }
                   2815:        if (ptr1 != MAP_FAILED) {
                   2816:                r = MUNMAP(ptr1, len);
                   2817:                XP_SYS_EQ(0, r);
                   2818:        }
                   2819:
                   2820:        r = CLOSE(fd);
                   2821:        XP_SYS_EQ(0, r);
                   2822:
                   2823:        reset_after_mmap();
                   2824: }
                   2825:
                   2826: /*
                   2827:  * mmap() different descriptors.
                   2828:  */
                   2829: DEF(mmap_multi)
                   2830: {
                   2831:        struct audio_info ai;
                   2832:        int fd0;
                   2833:        int fd1;
                   2834:        int r;
                   2835:        int len;
                   2836:        void *ptr0;
                   2837:        void *ptr1;
                   2838:
                   2839:        TEST("mmap_multi");
                   2840:        if (netbsd < 8) {
                   2841:                XP_SKIP("Multiple open is not supported");
                   2842:                return;
                   2843:        }
                   2844:        if ((props & AUDIO_PROP_MMAP) == 0) {
                   2845:                XP_SKIP("This test is only for mmap-able device");
                   2846:                return;
                   2847:        }
                   2848: #if !defined(NO_RUMP)
                   2849:        if (use_rump) {
                   2850:                XP_SKIP("rump doesn't support mmap");
                   2851:                return;
                   2852:        }
                   2853: #endif
                   2854:
                   2855:        fd0 = OPEN(devaudio, O_WRONLY);
                   2856:        REQUIRED_SYS_OK(fd0);
                   2857:
                   2858:        r = IOCTL(fd0, AUDIO_GETBUFINFO, &ai, "get");
                   2859:        REQUIRED_SYS_EQ(0, r);
                   2860:        len = ai.play.buffer_size;
                   2861:
                   2862:        fd1 = OPEN(devaudio, O_WRONLY);
                   2863:        REQUIRED_SYS_OK(fd1);
                   2864:
                   2865:        ptr0 = MMAP(NULL, len, PROT_WRITE, MAP_FILE, fd0, 0);
                   2866:        XP_SYS_PTR(0, ptr0);
                   2867:
                   2868:        ptr1 = MMAP(NULL, len,  PROT_WRITE, MAP_FILE, fd1, 0);
                   2869:        XP_SYS_PTR(0, ptr1);
                   2870:
                   2871:        if (ptr0 != MAP_FAILED) {
                   2872:                r = MUNMAP(ptr1, len);
                   2873:                XP_SYS_EQ(0, r);
                   2874:        }
                   2875:
                   2876:        r = CLOSE(fd1);
                   2877:        XP_SYS_EQ(0, r);
                   2878:
                   2879:        if (ptr1 != MAP_FAILED) {
                   2880:                r = MUNMAP(ptr0, len);
                   2881:                XP_SYS_EQ(0, r);
                   2882:        }
                   2883:
                   2884:        r = CLOSE(fd0);
                   2885:        XP_SYS_EQ(0, r);
                   2886:
                   2887:        reset_after_mmap();
                   2888: }
                   2889:
                   2890: #define IN     POLLIN
                   2891: #define OUT    POLLOUT
                   2892: /*
                   2893:  * Whether poll() succeeds with specified mode.
                   2894:  */
                   2895: void
                   2896: test_poll_mode(int mode, int events, int expected_revents)
                   2897: {
                   2898:        struct pollfd pfd;
                   2899:        const char *events_str;
                   2900:        int fd;
                   2901:        int r;
                   2902:        int expected_r;
                   2903:
                   2904:        if (events == IN) {
                   2905:                events_str = "IN";
                   2906:        } else if (events == OUT) {
                   2907:                events_str = "OUT";
                   2908:        } else if (events == (IN | OUT)) {
                   2909:                events_str = "INOUT";
                   2910:        } else {
                   2911:                events_str = "?";
                   2912:        }
                   2913:        TEST("poll_mode_%s_%s", openmode_str[mode] + 2, events_str);
                   2914:        if (mode2aumode(mode) == 0) {
                   2915:                XP_SKIP("Operation not allowed on this hardware property");
                   2916:                return;
                   2917:        }
                   2918:
                   2919:        expected_r = (expected_revents != 0) ? 1 : 0;
                   2920:
                   2921:        fd = OPEN(devaudio, mode);
                   2922:        REQUIRED_SYS_OK(fd);
                   2923:
                   2924:        memset(&pfd, 0, sizeof(pfd));
                   2925:        pfd.fd = fd;
                   2926:        pfd.events = events;
                   2927:
                   2928:        r = POLL(&pfd, 1, 100);
                   2929:        /* It's a bit complicated..  */
                   2930:        if (r < 0 || r > 1) {
                   2931:                /*
                   2932:                 * Check these two cases first:
                   2933:                 * - system call fails.
                   2934:                 * - poll() with one nfds returns >1.  It's strange.
                   2935:                 */
                   2936:                XP_SYS_EQ(expected_r, r);
                   2937:        } else {
                   2938:                /*
                   2939:                 * Otherwise, poll() returned 0 or 1.
                   2940:                 */
                   2941:                DPRINTF("  > pfd.revents=%s\n", event_tostr(pfd.revents));
                   2942:
                   2943:                /* NetBSD7,8 have several strange behavior.  It must be bug. */
                   2944:
                   2945:                XP_SYS_EQ(expected_r, r);
                   2946:                XP_EQ(expected_revents, pfd.revents);
                   2947:        }
                   2948:        r = CLOSE(fd);
                   2949:        XP_SYS_EQ(0, r);
                   2950: }
                   2951: DEF(poll_mode_RDONLY_IN)       { test_poll_mode(O_RDONLY, IN,     0); }
                   2952: DEF(poll_mode_RDONLY_OUT)      { test_poll_mode(O_RDONLY, OUT,    0); }
                   2953: DEF(poll_mode_RDONLY_INOUT)    { test_poll_mode(O_RDONLY, IN|OUT, 0); }
                   2954: DEF(poll_mode_WRONLY_IN)       { test_poll_mode(O_WRONLY, IN,     0); }
                   2955: DEF(poll_mode_WRONLY_OUT)      { test_poll_mode(O_WRONLY, OUT,    OUT); }
                   2956: DEF(poll_mode_WRONLY_INOUT)    { test_poll_mode(O_WRONLY, IN|OUT, OUT); }
                   2957: DEF(poll_mode_RDWR_IN)         { test_poll_mode(O_RDWR,   IN,     0); }
                   2958: DEF(poll_mode_RDWR_OUT)                { test_poll_mode(O_RDWR,   OUT,    OUT); }
                   2959: DEF(poll_mode_RDWR_INOUT)      { test_poll_mode(O_RDWR,   IN|OUT, OUT); }
                   2960:
                   2961: /*
                   2962:  * Poll(OUT) when buffer is empty.
                   2963:  */
                   2964: DEF(poll_out_empty)
                   2965: {
                   2966:        struct pollfd pfd;
                   2967:        int fd;
                   2968:        int r;
                   2969:
                   2970:        TEST("poll_out_empty");
                   2971:
                   2972:        fd = OPEN(devaudio, O_WRONLY);
                   2973:        REQUIRED_SYS_OK(fd);
                   2974:
                   2975:        memset(&pfd, 0, sizeof(pfd));
                   2976:        pfd.fd = fd;
                   2977:        pfd.events = POLLOUT;
                   2978:
                   2979:        /* Check when empty.  It should succeed even if timeout == 0 */
                   2980:        r = POLL(&pfd, 1, 0);
                   2981:        XP_SYS_EQ(1, r);
                   2982:        XP_EQ(POLLOUT, pfd.revents);
                   2983:
                   2984:        r = CLOSE(fd);
                   2985:        XP_SYS_EQ(0, r);
                   2986: }
                   2987:
                   2988: /*
                   2989:  * Poll(OUT) when buffer is full.
                   2990:  */
                   2991: DEF(poll_out_full)
                   2992: {
                   2993:        struct audio_info ai;
                   2994:        struct pollfd pfd;
                   2995:        int fd;
                   2996:        int r;
                   2997:        char *buf;
                   2998:        int buflen;
                   2999:
                   3000:        TEST("poll_out_full");
                   3001:
                   3002:        fd = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3003:        REQUIRED_SYS_OK(fd);
                   3004:
                   3005:        /* Pause */
                   3006:        AUDIO_INITINFO(&ai);
                   3007:        ai.play.pause = 1;
                   3008:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "");
                   3009:        XP_SYS_EQ(0, r);
                   3010:
                   3011:        /* Get buffer size */
                   3012:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3013:        XP_SYS_EQ(0, r);
                   3014:
                   3015:        /* Write until full */
                   3016:        buflen = ai.play.buffer_size;
                   3017:        buf = (char *)malloc(buflen);
                   3018:        REQUIRED_IF(buf != NULL);
                   3019:        memset(buf, 0xff, buflen);
                   3020:        do {
                   3021:                r = WRITE(fd, buf, buflen);
                   3022:        } while (r == buflen);
                   3023:        if (r == -1) {
                   3024:                XP_SYS_NG(EAGAIN, r);
                   3025:        }
                   3026:
                   3027:        /* Do poll */
                   3028:        memset(&pfd, 0, sizeof(pfd));
                   3029:        pfd.fd = fd;
                   3030:        pfd.events = POLLOUT;
                   3031:        r = POLL(&pfd, 1, 0);
                   3032:        XP_SYS_EQ(0, r);
                   3033:        XP_EQ(0, pfd.revents);
                   3034:
                   3035:        r = CLOSE(fd);
                   3036:        XP_SYS_EQ(0, r);
                   3037:        free(buf);
                   3038: }
                   3039:
                   3040: /*
                   3041:  * Poll(OUT) when buffer is full but hiwat sets lower than full.
                   3042:  */
                   3043: DEF(poll_out_hiwat)
                   3044: {
                   3045:        struct audio_info ai;
                   3046:        struct pollfd pfd;
                   3047:        int fd;
                   3048:        int r;
                   3049:        char *buf;
                   3050:        int buflen;
                   3051:        int newhiwat;
                   3052:
                   3053:        TEST("poll_out_hiwat");
                   3054:
                   3055:        fd = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3056:        REQUIRED_SYS_OK(fd);
                   3057:
                   3058:        /* Get buffer size and hiwat */
                   3059:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3060:        XP_SYS_EQ(0, r);
                   3061:        /* Change hiwat some different value */
                   3062:        newhiwat = ai.lowat;
                   3063:
                   3064:        /* Set pause and hiwat */
                   3065:        AUDIO_INITINFO(&ai);
                   3066:        ai.play.pause = 1;
                   3067:        ai.hiwat = newhiwat;
                   3068:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause=1;hiwat");
                   3069:        XP_SYS_EQ(0, r);
                   3070:
                   3071:        /* Get the set hiwat again */
                   3072:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3073:        XP_SYS_EQ(0, r);
                   3074:
                   3075:        /* Write until full */
                   3076:        buflen = ai.blocksize * ai.hiwat;
                   3077:        buf = (char *)malloc(buflen);
                   3078:        REQUIRED_IF(buf != NULL);
                   3079:        memset(buf, 0xff, buflen);
                   3080:        do {
                   3081:                r = WRITE(fd, buf, buflen);
                   3082:        } while (r == buflen);
                   3083:        if (r == -1) {
                   3084:                XP_SYS_NG(EAGAIN, r);
                   3085:        }
                   3086:
                   3087:        /* Do poll */
                   3088:        memset(&pfd, 0, sizeof(pfd));
                   3089:        pfd.fd = fd;
                   3090:        pfd.events = POLLOUT;
                   3091:        r = POLL(&pfd, 1, 0);
                   3092:        XP_SYS_EQ(0, r);
                   3093:        XP_EQ(0, pfd.revents);
                   3094:
                   3095:        r = CLOSE(fd);
                   3096:        XP_SYS_EQ(0, r);
                   3097:        free(buf);
                   3098: }
                   3099:
                   3100: /*
                   3101:  * Unpause from buffer full, POLLOUT should raise.
                   3102:  * XXX poll(2) on NetBSD7 is really incomplete and wierd.  I don't test it.
                   3103:  */
                   3104: DEF(poll_out_unpause)
                   3105: {
                   3106:        struct audio_info ai;
                   3107:        struct pollfd pfd;
                   3108:        int fd;
                   3109:        int r;
                   3110:        char *buf;
                   3111:        int buflen;
                   3112:        u_int blocksize;
                   3113:        int hiwat;
                   3114:        int lowat;
                   3115:
                   3116:        TEST("poll_out_unpause");
                   3117:        if (netbsd < 8) {
                   3118:                XP_SKIP("NetBSD7's poll() is too incomplete to test.");
                   3119:                return;
                   3120:        }
                   3121:
                   3122:        /* Non-blocking open */
                   3123:        fd = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3124:        REQUIRED_SYS_OK(fd);
                   3125:
                   3126:        /* Adjust block size and hiwat/lowat to make the test time 1sec */
                   3127:        blocksize = 1000;       /* 1/8 sec in mulaw,1ch,8000Hz */
                   3128:        hiwat = 12;             /* 1.5sec */
                   3129:        lowat = 4;              /* 0.5sec */
                   3130:        AUDIO_INITINFO(&ai);
                   3131:        ai.blocksize = blocksize;
                   3132:        ai.hiwat = hiwat;
                   3133:        ai.lowat = lowat;
                   3134:        /* and also set encoding */
                   3135:        /*
                   3136:         * XXX NetBSD7 has different results depending on whether the input
                   3137:         * encoding is emulated (AUDIO_ENCODINGFLAG_EMULATED) or not.  It's
                   3138:         * not easy to ensure this situation on all hardware environment.
                   3139:         * On NetBSD9, the result is the same regardless of input encoding.
                   3140:         */
                   3141:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "blocksize=%d", blocksize);
                   3142:        XP_SYS_EQ(0, r);
                   3143:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3144:        if (ai.blocksize != blocksize) {
                   3145:                /*
                   3146:                 * NetBSD9 can not change the blocksize.  Then,
                   3147:                 * adjust using hiwat/lowat.
                   3148:                 */
                   3149:                blocksize = ai.blocksize;
                   3150:                hiwat = howmany(8000 * 1.5, blocksize);
                   3151:                lowat = howmany(8000 * 0.5, blocksize);
                   3152:        }
                   3153:        /* Anyway, set the parameters */
                   3154:        AUDIO_INITINFO(&ai);
                   3155:        ai.blocksize = blocksize;
                   3156:        ai.hiwat = hiwat;
                   3157:        ai.lowat = lowat;
                   3158:        ai.play.pause = 1;
                   3159:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause=1");
                   3160:        XP_SYS_EQ(0, r);
                   3161:
                   3162:        /* Get the set parameters again */
                   3163:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3164:        XP_SYS_EQ(0, r);
                   3165:
                   3166:        /* Write until full */
                   3167:        buflen = ai.blocksize * ai.hiwat;
                   3168:        buf = (char *)malloc(buflen);
                   3169:        REQUIRED_IF(buf != NULL);
                   3170:        memset(buf, 0xff, buflen);
                   3171:        do {
                   3172:                r = WRITE(fd, buf, buflen);
                   3173:        } while (r == buflen);
                   3174:        if (r == -1) {
                   3175:                XP_SYS_NG(EAGAIN, r);
                   3176:        }
                   3177:
                   3178:        /* At this time, POLLOUT should not be set because buffer is full */
                   3179:        memset(&pfd, 0, sizeof(pfd));
                   3180:        pfd.fd = fd;
                   3181:        pfd.events = POLLOUT;
                   3182:        r = POLL(&pfd, 1, 0);
                   3183:        XP_SYS_EQ(0, r);
                   3184:        XP_EQ(0, pfd.revents);
                   3185:
                   3186:        /* Unpause */
                   3187:        AUDIO_INITINFO(&ai);
                   3188:        ai.play.pause = 0;
                   3189:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause=0");
                   3190:        XP_SYS_EQ(0, r);
                   3191:
                   3192:        /*
                   3193:         * When unpause occurs:
                   3194:         * - NetBSD7 (emul=0) -> the buffer remains.
                   3195:         * - NetBSD7 (emul=1) -> the buffer is cleared.
                   3196:         * - NetBSD8          -> the buffer remains.
                   3197:         * - NetBSD9          -> the buffer remains.
                   3198:         */
                   3199:
                   3200:        /* Check poll() up to 2sec */
                   3201:        pfd.revents = 0;
                   3202:        r = POLL(&pfd, 1, 2000);
                   3203:        XP_SYS_EQ(1, r);
                   3204:        XP_EQ(POLLOUT, pfd.revents);
                   3205:
                   3206:        /*
                   3207:         * Since POLLOUT is set, it should be writable.
                   3208:         * But at this time, no all buffer may be writable.
                   3209:         */
                   3210:        r = WRITE(fd, buf, buflen);
                   3211:        XP_SYS_OK(r);
                   3212:
                   3213:        /* Flush it because there is no need to play it */
                   3214:        r = IOCTL(fd, AUDIO_FLUSH, NULL, "");
                   3215:        XP_SYS_EQ(0, r);
                   3216:
                   3217:        r = CLOSE(fd);
                   3218:        XP_SYS_EQ(0, r);
                   3219:        free(buf);
                   3220: }
                   3221:
                   3222: /*
                   3223:  * poll(2) must not be affected by playback of other descriptors.
                   3224:  */
                   3225: DEF(poll_out_simul)
                   3226: {
                   3227:        struct audio_info ai;
                   3228:        struct pollfd pfd[2];
                   3229:        int fd[2];
                   3230:        int r;
                   3231:        char *buf;
                   3232:        u_int blocksize;
                   3233:        int hiwat;
                   3234:        int lowat;
                   3235:        int buflen;
                   3236:        int time;
                   3237:
                   3238:        TEST("poll_out_simul");
                   3239:        if (netbsd < 8) {
                   3240:                XP_SKIP("Multiple open is not supported");
                   3241:                return;
                   3242:        }
                   3243:
                   3244:        /* Make sure that it's not affected by descriptor order */
                   3245:        for (int i = 0; i < 2; i++) {
                   3246:                int a = i;
                   3247:                int b = 1 - i;
                   3248:
                   3249:                fd[0] = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3250:                REQUIRED_SYS_OK(fd[0]);
                   3251:                fd[1] = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3252:                REQUIRED_SYS_OK(fd[1]);
                   3253:
                   3254:                /*
                   3255:                 * Adjust block size and hiwat/lowat.
                   3256:                 * I want to choice suitable blocksize (if possible).
                   3257:                 */
                   3258:                blocksize = 1000;       /* 1/8 sec in mulaw,1ch,8000Hz */
                   3259:                hiwat = 12;             /* 1.5sec */
                   3260:                lowat = 4;              /* 0.5sec */
                   3261:                AUDIO_INITINFO(&ai);
                   3262:                ai.blocksize = blocksize;
                   3263:                ai.hiwat = hiwat;
                   3264:                ai.lowat = lowat;
                   3265:                r = IOCTL(fd[0], AUDIO_SETINFO, &ai, "blocksize=1000");
                   3266:                XP_SYS_EQ(0, r);
                   3267:                r = IOCTL(fd[0], AUDIO_GETBUFINFO, &ai, "read back blocksize");
                   3268:                if (ai.blocksize != blocksize) {
                   3269:                        /*
                   3270:                         * NetBSD9 can not change the blocksize.  Then,
                   3271:                         * adjust using hiwat/lowat.
                   3272:                         */
                   3273:                        blocksize = ai.blocksize;
                   3274:                        hiwat = howmany(8000 * 1.5, blocksize);
                   3275:                        lowat = howmany(8000 * 0.5, blocksize);
                   3276:                }
                   3277:                /* Anyway, set the parameters */
                   3278:                AUDIO_INITINFO(&ai);
                   3279:                ai.blocksize = blocksize;
                   3280:                ai.hiwat = hiwat;
                   3281:                ai.lowat = lowat;
                   3282:                /* Pause fdA */
                   3283:                ai.play.pause = 1;
                   3284:                r = IOCTL(fd[a], AUDIO_SETINFO, &ai, "pause=1");
                   3285:                XP_SYS_EQ(0, r);
                   3286:                /* Unpause fdB */
                   3287:                ai.play.pause = 0;
                   3288:                r = IOCTL(fd[b], AUDIO_SETINFO, &ai, "pause=0");
                   3289:                XP_SYS_EQ(0, r);
                   3290:
                   3291:                /* Get again. XXX two individual ioctls are correct */
                   3292:                r = IOCTL(fd[0], AUDIO_GETBUFINFO, &ai, "");
                   3293:                XP_SYS_EQ(0, r);
                   3294:                DPRINTF("  > blocksize=%d lowat=%d hiwat=%d\n",
                   3295:                        ai.blocksize, ai.lowat, ai.hiwat);
                   3296:
                   3297:                /* Enough long time than the playback time */
                   3298:                time = (ai.hiwat - ai.lowat) * blocksize / 8;  /*[msec]*/
                   3299:                time *= 2;
                   3300:
                   3301:                /* Write fdA full */
                   3302:                buflen = blocksize * ai.lowat;
                   3303:                buf = (char *)malloc(buflen);
                   3304:                REQUIRED_IF(buf != NULL);
                   3305:                memset(buf, 0xff, buflen);
                   3306:                do {
                   3307:                        r = WRITE(fd[a], buf, buflen);
                   3308:                } while (r == buflen);
                   3309:                if (r == -1) {
                   3310:                        XP_SYS_NG(EAGAIN, r);
                   3311:                }
                   3312:
                   3313:                /* POLLOUT should not be set, because fdA is buffer full */
                   3314:                memset(pfd, 0, sizeof(pfd));
                   3315:                pfd[0].fd = fd[a];
                   3316:                pfd[0].events = POLLOUT;
                   3317:                r = POLL(pfd, 1, 0);
                   3318:                XP_SYS_EQ(0, r);
                   3319:                XP_EQ(0, pfd[0].revents);
                   3320:
                   3321:                /* Write fdB at least lowat */
                   3322:                r = WRITE(fd[b], buf, buflen);
                   3323:                XP_SYS_EQ(buflen, r);
                   3324:                r = WRITE(fd[b], buf, buflen);
                   3325:                if (r == -1) {
                   3326:                        XP_SYS_NG(EAGAIN, r);
                   3327:                }
                   3328:
                   3329:                /* Only fdB should become POLLOUT */
                   3330:                memset(pfd, 0, sizeof(pfd));
                   3331:                pfd[0].fd = fd[0];
                   3332:                pfd[0].events = POLLOUT;
                   3333:                pfd[1].fd = fd[1];
                   3334:                pfd[1].events = POLLOUT;
                   3335:                r = POLL(pfd, 2, time);
                   3336:                XP_SYS_EQ(1, r);
                   3337:                if (r != -1) {
                   3338:                        XP_EQ(0, pfd[a].revents);
                   3339:                        XP_EQ(POLLOUT, pfd[b].revents);
                   3340:                }
                   3341:
                   3342:                /* Drop the rest */
                   3343:                r = IOCTL(fd[0], AUDIO_FLUSH, NULL, "");
                   3344:                XP_SYS_EQ(0, r);
                   3345:                r = IOCTL(fd[1], AUDIO_FLUSH, NULL, "");
                   3346:                XP_SYS_EQ(0, r);
                   3347:
                   3348:                r = CLOSE(fd[0]);
                   3349:                XP_SYS_EQ(0, r);
                   3350:                r = CLOSE(fd[1]);
                   3351:                XP_SYS_EQ(0, r);
                   3352:                free(buf);
                   3353:
                   3354:                xxx_close_wait();
                   3355:        }
                   3356: }
                   3357:
                   3358: /*
                   3359:  * poll(2) must not be affected by other recording descriptors even if
                   3360:  * playback descriptor waits with POLLIN (though it's not normal usage).
                   3361:  * In other words, two POLLIN must not interfere.
                   3362:  */
                   3363: DEF(poll_in_simul)
                   3364: {
                   3365:        struct audio_info ai;
                   3366:        struct pollfd pfd;
                   3367:        int fd[2];
                   3368:        int r;
                   3369:        char *buf;
                   3370:        int blocksize;
                   3371:
                   3372:        TEST("poll_in_simul");
                   3373:        if (netbsd < 8) {
                   3374:                XP_SKIP("Multiple open is not supported");
                   3375:                return;
                   3376:        }
                   3377:        if (hw_fulldup() == 0) {
                   3378:                XP_SKIP("This test is only for full-duplex device");
                   3379:                return;
                   3380:        }
                   3381:
                   3382:        int play = 0;
                   3383:        int rec = 1;
                   3384:
                   3385:        fd[play] = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3386:        REQUIRED_SYS_OK(fd[play]);
                   3387:        fd[rec] = OPEN(devaudio, O_RDONLY);
                   3388:        REQUIRED_SYS_OK(fd[rec]);
                   3389:
                   3390:        /* Get block size */
                   3391:        r = IOCTL(fd[rec], AUDIO_GETBUFINFO, &ai, "");
                   3392:        XP_SYS_EQ(0, r);
                   3393:        blocksize = ai.blocksize;
                   3394:
                   3395:        buf = (char *)malloc(blocksize);
                   3396:        REQUIRED_IF(buf != NULL);
                   3397:
                   3398:        /*
                   3399:         * At first, make sure the playback one doesn't return POLLIN.
                   3400:         */
                   3401:        memset(&pfd, 0, sizeof(pfd));
                   3402:        pfd.fd = fd[play];
                   3403:        pfd.events = POLLIN;
                   3404:        r = POLL(&pfd, 1, 0);
                   3405:        if (r == 0 && pfd.revents == 0) {
                   3406:                XP_SYS_EQ(0, r);
                   3407:                XP_EQ(0, pfd.revents);
                   3408:        } else {
                   3409:                XP_FAIL("play fd returns POLLIN");
                   3410:                goto abort;
                   3411:        }
                   3412:
                   3413:        /* Start recording */
                   3414:        r = READ(fd[rec], buf, blocksize);
                   3415:        XP_SYS_EQ(blocksize, r);
                   3416:
                   3417:        /* Poll()ing playback descriptor with POLLIN should not raise */
                   3418:        r = POLL(&pfd, 1, 1000);
                   3419:        XP_SYS_EQ(0, r);
                   3420:        XP_EQ(0, pfd.revents);
                   3421:
                   3422:        /* Poll()ing recording descriptor with POLLIN should raise */
                   3423:        pfd.fd = fd[rec];
                   3424:        r = POLL(&pfd, 1, 0);
                   3425:        XP_SYS_EQ(1, r);
                   3426:        XP_EQ(POLLIN, pfd.revents);
                   3427:
                   3428: abort:
                   3429:        r = CLOSE(fd[play]);
                   3430:        XP_SYS_EQ(0, r);
                   3431:        r = CLOSE(fd[rec]);
                   3432:        XP_SYS_EQ(0, r);
                   3433:        free(buf);
                   3434: }
                   3435:
                   3436: /*
                   3437:  * Whether kqueue() succeeds with specified mode.
                   3438:  */
                   3439: void
                   3440: test_kqueue_mode(int openmode, int filt, int expected)
                   3441: {
                   3442:        struct kevent kev;
                   3443:        struct timespec ts;
                   3444:        int fd;
                   3445:        int kq;
                   3446:        int r;
                   3447:
                   3448:        TEST("kqueue_mode_%s_%s",
                   3449:            openmode_str[openmode] + 2,
                   3450:            (filt == EVFILT_READ) ? "READ" : "WRITE");
                   3451:        if (mode2aumode(openmode) == 0) {
                   3452:                XP_SKIP("Operation not allowed on this hardware property");
                   3453:                return;
                   3454:        }
                   3455:
                   3456:        ts.tv_sec = 0;
                   3457:        ts.tv_nsec = 100 * 1000 * 1000; // 100msec
                   3458:
                   3459:        kq = KQUEUE();
                   3460:        XP_SYS_OK(kq);
                   3461:
                   3462:        fd = OPEN(devaudio, openmode);
                   3463:        REQUIRED_SYS_OK(fd);
                   3464:
                   3465:        /*
                   3466:         * Check whether the specified filter can be set.
                   3467:         * Any filters can always be set, even if pointless combination.
                   3468:         * For example, EVFILT_READ can be set on O_WRONLY descriptor
                   3469:         * though it will never raise.
                   3470:         * I will not mention about good or bad of this behavior here.
                   3471:         */
                   3472:        EV_SET(&kev, fd, filt, EV_ADD, 0, 0, 0);
                   3473:        r = KEVENT_SET(kq, &kev, 1);
                   3474:        XP_SYS_EQ(0, r);
                   3475:
                   3476:        if (r == 0) {
                   3477:                /* If the filter can be set, try kevent(poll) */
                   3478:                r = KEVENT_POLL(kq, &kev, 1, &ts);
                   3479:                XP_SYS_EQ(expected, r);
                   3480:
                   3481:                /* Delete it */
                   3482:                EV_SET(&kev, fd, filt, EV_DELETE, 0, 0, 0);
                   3483:                r = KEVENT_SET(kq, &kev, 1);
                   3484:                XP_SYS_EQ(0, r);
                   3485:        }
                   3486:
                   3487:        r = CLOSE(fd);
                   3488:        XP_SYS_EQ(0, r);
                   3489:        r = CLOSE(kq);
                   3490:        XP_SYS_EQ(0, r);
                   3491: }
                   3492: DEF(kqueue_mode_RDONLY_READ) {
                   3493:        /* Should not raise yet (NetBSD7 has bugs?) */
                   3494:        int expected = (netbsd < 8) ? 1 : 0;
                   3495:        test_kqueue_mode(O_RDONLY, EVFILT_READ, expected);
                   3496: }
                   3497: DEF(kqueue_mode_RDONLY_WRITE) {
                   3498:        /* Should never raise (NetBSD7 has bugs) */
                   3499:        int expected = (netbsd < 8) ? 1 : 0;
                   3500:        test_kqueue_mode(O_RDONLY, EVFILT_WRITE, expected);
                   3501: }
                   3502: DEF(kqueue_mode_WRONLY_READ) {
                   3503:        /* Should never raise */
                   3504:        test_kqueue_mode(O_WRONLY, EVFILT_READ, 0);
                   3505: }
                   3506: DEF(kqueue_mode_WRONLY_WRITE) {
                   3507:        /* Should raise */
                   3508:        test_kqueue_mode(O_WRONLY, EVFILT_WRITE, 1);
                   3509: }
                   3510: DEF(kqueue_mode_RDWR_READ) {
                   3511:        /* Should not raise yet (NetBSD7 is something strange) */
                   3512:        int expected = (netbsd < 8 && hw_fulldup()) ? 1 : 0;
                   3513:        test_kqueue_mode(O_RDWR, EVFILT_READ, expected);
                   3514: }
                   3515: DEF(kqueue_mode_RDWR_WRITE) {
                   3516:        /* Should raise */
                   3517:        test_kqueue_mode(O_RDWR, EVFILT_WRITE, 1);
                   3518: }
                   3519:
                   3520: /*
                   3521:  * kqueue(2) when buffer is empty.
                   3522:  */
                   3523: DEF(kqueue_empty)
                   3524: {
                   3525:        struct audio_info ai;
                   3526:        struct kevent kev;
                   3527:        struct timespec ts;
                   3528:        int kq;
                   3529:        int fd;
                   3530:        int r;
                   3531:
                   3532:        TEST("kqueue_empty");
                   3533:
                   3534:        fd = OPEN(devaudio, O_WRONLY);
                   3535:        REQUIRED_SYS_OK(fd);
                   3536:
                   3537:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3538:        XP_SYS_EQ(0, r);
                   3539:
                   3540:        kq = KQUEUE();
                   3541:        XP_SYS_OK(kq);
                   3542:
                   3543:        EV_SET(&kev, fd, EV_ADD, EVFILT_WRITE, 0, 0, 0);
                   3544:        r = KEVENT_SET(kq, &kev, 1);
                   3545:        XP_SYS_EQ(0, r);
                   3546:
                   3547:        /* When the buffer is empty, it should succeed even if timeout == 0 */
                   3548:        memset(&ts, 0, sizeof(ts));
                   3549:        r = KEVENT_POLL(kq, &kev, 1, &ts);
                   3550:        XP_SYS_EQ(1, r);
                   3551:        XP_EQ(fd, kev.ident);
                   3552:        /*
                   3553:         * XXX According to kqueue(2) manpage, returned kev.data contains
                   3554:         * "the amount of space remaining in the write buffer".
                   3555:         * NetBSD7 returns buffer_size.  Shouldn't it be blocksize * hiwat?
                   3556:         */
                   3557:        /* XP_EQ(ai.blocksize * ai.hiwat, kev.data); */
                   3558:        XP_EQ(ai.play.buffer_size, kev.data);
                   3559:
                   3560:        r = CLOSE(fd);
                   3561:        XP_SYS_EQ(0, r);
                   3562:        r = CLOSE(kq);
                   3563:        XP_SYS_EQ(0, r);
                   3564: }
                   3565:
                   3566: /*
                   3567:  * kqueue(2) when buffer is full.
                   3568:  */
                   3569: DEF(kqueue_full)
                   3570: {
                   3571:        struct audio_info ai;
                   3572:        struct kevent kev;
                   3573:        struct timespec ts;
                   3574:        int kq;
                   3575:        int fd;
                   3576:        int r;
                   3577:        char *buf;
                   3578:        int buflen;
                   3579:
                   3580:        TEST("kqueue_full");
                   3581:
                   3582:        fd = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3583:        REQUIRED_SYS_OK(fd);
                   3584:
                   3585:        /* Pause */
                   3586:        AUDIO_INITINFO(&ai);
                   3587:        ai.play.pause = 1;
                   3588:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "");
                   3589:        XP_SYS_EQ(0, r);
                   3590:
                   3591:        /* Get buffer size */
                   3592:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3593:        XP_SYS_EQ(0, r);
                   3594:
                   3595:        /* Write until full */
                   3596:        buflen = ai.play.buffer_size;
                   3597:        buf = (char *)malloc(buflen);
                   3598:        REQUIRED_IF(buf != NULL);
                   3599:        memset(buf, 0xff, buflen);
                   3600:        do {
                   3601:                r = WRITE(fd, buf, buflen);
                   3602:        } while (r == buflen);
                   3603:        if (r == -1) {
                   3604:                XP_SYS_NG(EAGAIN, r);
                   3605:        }
                   3606:
                   3607:        kq = KQUEUE();
                   3608:        XP_SYS_OK(kq);
                   3609:
                   3610:        EV_SET(&kev, fd, EV_ADD, EVFILT_WRITE, 0, 0, 0);
                   3611:        r = KEVENT_SET(kq, &kev, 1);
                   3612:        XP_SYS_EQ(0, r);
                   3613:
                   3614:        /* kevent() should not raise */
                   3615:        ts.tv_sec = 0;
                   3616:        ts.tv_nsec = 100L * 1000 * 1000;        /* 100msec */
                   3617:        r = KEVENT_POLL(kq, &kev, 1, &ts);
                   3618:        XP_SYS_EQ(0, r);
                   3619:        if (r > 0) {
                   3620:                XP_EQ(fd, kev.ident);
                   3621:                XP_EQ(0, kev.data);
                   3622:        }
                   3623:
                   3624:        r = CLOSE(fd);
                   3625:        XP_SYS_EQ(0, r);
                   3626:        r = CLOSE(kq);
                   3627:        XP_SYS_EQ(0, r);
                   3628:        free(buf);
                   3629: }
                   3630:
                   3631: /*
                   3632:  * kqueue(2) when buffer is full but hiwat sets lower than full.
                   3633:  */
                   3634: DEF(kqueue_hiwat)
                   3635: {
                   3636:        struct audio_info ai;
                   3637:        struct kevent kev;
                   3638:        struct timespec ts;
                   3639:        int kq;
                   3640:        int fd;
                   3641:        int r;
                   3642:        char *buf;
                   3643:        int buflen;
                   3644:        int newhiwat;
                   3645:
                   3646:        TEST("kqueue_hiwat");
                   3647:
                   3648:        fd = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3649:        REQUIRED_SYS_OK(fd);
                   3650:
                   3651:        /* Get buffer size and hiwat */
                   3652:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "hiwat");
                   3653:        XP_SYS_EQ(0, r);
                   3654:        /* Change hiwat some different value */
                   3655:        newhiwat = ai.hiwat - 1;
                   3656:
                   3657:        /* Set pause and hiwat */
                   3658:        AUDIO_INITINFO(&ai);
                   3659:        ai.play.pause = 1;
                   3660:        ai.hiwat = newhiwat;
                   3661:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause=1;hiwat");
                   3662:        XP_SYS_EQ(0, r);
                   3663:
                   3664:        /* Get the set parameters again */
                   3665:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3666:        XP_SYS_EQ(0, r);
                   3667:        XP_EQ(1, ai.play.pause);
                   3668:        XP_EQ(newhiwat, ai.hiwat);
                   3669:
                   3670:        /* Write until full */
                   3671:        buflen = ai.blocksize * ai.hiwat;
                   3672:        buf = (char *)malloc(buflen);
                   3673:        REQUIRED_IF(buf != NULL);
                   3674:        memset(buf, 0xff, buflen);
                   3675:        do {
                   3676:                r = WRITE(fd, buf, buflen);
                   3677:        } while (r == buflen);
                   3678:        if (r == -1) {
                   3679:                XP_SYS_NG(EAGAIN, r);
                   3680:        }
                   3681:
                   3682:        kq = KQUEUE();
                   3683:        XP_SYS_OK(kq);
                   3684:
                   3685:        EV_SET(&kev, fd, EV_ADD, EVFILT_WRITE, 0, 0, 0);
                   3686:        r = KEVENT_SET(kq, &kev, 1);
                   3687:        XP_SYS_EQ(0, r);
                   3688:
                   3689:        /* Should not raise because it's not possible to write */
                   3690:        ts.tv_sec = 0;
                   3691:        ts.tv_nsec = 100L * 1000 * 1000;        /* 100msec */
                   3692:        r = KEVENT_POLL(kq, &kev, 1, &ts);
                   3693:        if (r > 0)
                   3694:                DEBUG_KEV("kev", &kev);
                   3695:        XP_SYS_EQ(0, r);
                   3696:
                   3697:        r = CLOSE(fd);
                   3698:        XP_SYS_EQ(0, r);
                   3699:        r = CLOSE(kq);
                   3700:        XP_SYS_EQ(0, r);
                   3701:        free(buf);
                   3702: }
                   3703:
                   3704: /*
                   3705:  * Unpause from buffer full, kevent() should raise.
                   3706:  */
                   3707: DEF(kqueue_unpause)
                   3708: {
                   3709:        struct audio_info ai;
                   3710:        struct kevent kev;
                   3711:        struct timespec ts;
                   3712:        int fd;
                   3713:        int r;
                   3714:        int kq;
                   3715:        char *buf;
                   3716:        int buflen;
                   3717:        u_int blocksize;
                   3718:        int hiwat;
                   3719:        int lowat;
                   3720:
                   3721:        TEST("kqueue_unpause");
                   3722:
                   3723:        /* Non-blocking open */
                   3724:        fd = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3725:        REQUIRED_SYS_OK(fd);
                   3726:
                   3727:        /* Adjust block size and hiwat/lowat to make the test time 1sec */
                   3728:        blocksize = 1000;       /* 1/8 sec in mulaw,1ch,8000Hz */
                   3729:        hiwat = 12;             /* 1.5sec */
                   3730:        lowat = 4;              /* 0.5sec */
                   3731:        AUDIO_INITINFO(&ai);
                   3732:        ai.blocksize = blocksize;
                   3733:        ai.hiwat = hiwat;
                   3734:        ai.lowat = lowat;
                   3735:        /* and also set encoding */
                   3736:        /*
                   3737:         * XXX NetBSD7 has different results depending on whether the input
                   3738:         * encoding is emulated (AUDIO_ENCODINGFLAG_EMULATED) or not.  It's
                   3739:         * not easy to ensure this situation on all hardware environment.
                   3740:         * On NetBSD9, the result is the same regardless of input encoding.
                   3741:         */
                   3742:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "blocksize=%d", blocksize);
                   3743:        XP_SYS_EQ(0, r);
                   3744:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3745:        if (ai.blocksize != blocksize) {
                   3746:                /*
                   3747:                 * NetBSD9 can not change the blocksize.  Then,
                   3748:                 * adjust using hiwat/lowat.
                   3749:                 */
                   3750:                blocksize = ai.blocksize;
                   3751:                hiwat = howmany(8000 * 1.5, blocksize);
                   3752:                lowat = howmany(8000 * 0.5, blocksize);
                   3753:        }
                   3754:        /* Anyway, set the parameters */
                   3755:        AUDIO_INITINFO(&ai);
                   3756:        ai.blocksize = blocksize;
                   3757:        ai.hiwat = hiwat;
                   3758:        ai.lowat = lowat;
                   3759:        ai.play.pause = 1;
                   3760:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause=1");
                   3761:        XP_SYS_EQ(0, r);
                   3762:
                   3763:        /* Get the set parameters again */
                   3764:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   3765:        XP_SYS_EQ(0, r);
                   3766:        DPRINTF("  > blocksize=%d hiwat=%d lowat=%d buffer_size=%d\n",
                   3767:            ai.blocksize, ai.hiwat, ai.lowat, ai.play.buffer_size);
                   3768:
                   3769:        /* Write until full */
                   3770:        buflen = ai.blocksize * ai.hiwat;
                   3771:        buf = (char *)malloc(buflen);
                   3772:        REQUIRED_IF(buf != NULL);
                   3773:        memset(buf, 0xff, buflen);
                   3774:        do {
                   3775:                r = WRITE(fd, buf, buflen);
                   3776:        } while (r == buflen);
                   3777:        if (r == -1) {
                   3778:                XP_SYS_NG(EAGAIN, r);
                   3779:        }
                   3780:
                   3781:        kq = KQUEUE();
                   3782:        XP_SYS_OK(kq);
                   3783:
                   3784:        EV_SET(&kev, fd, EV_ADD, EVFILT_WRITE, 0, 0, 0);
                   3785:        r = KEVENT_SET(kq, &kev, 1);
                   3786:        XP_SYS_EQ(0, r);
                   3787:
                   3788:        /* Unpause */
                   3789:        AUDIO_INITINFO(&ai);
                   3790:        ai.play.pause = 0;
                   3791:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause=0");
                   3792:        XP_SYS_EQ(0, r);
                   3793:
                   3794:        /* Check kevent() up to 2sec */
                   3795:        ts.tv_sec = 2;
                   3796:        ts.tv_nsec = 0;
                   3797:        r = KEVENT_POLL(kq, &kev, 1, &ts);
                   3798:        if (r >= 1)
                   3799:                DEBUG_KEV("kev", &kev);
                   3800:        if (netbsd < 8) {
                   3801:                /*
                   3802:                 * NetBSD7 with EMULATED_FLAG unset has bugs.  Unpausing
                   3803:                 * unintentionally clears buffer (and therefore it becomes
                   3804:                 * writable) but it doesn't raise EVFILT_WRITE.
                   3805:                 */
                   3806:        } else {
                   3807:                XP_SYS_EQ(1, r);
                   3808:        }
                   3809:
                   3810:        /* Flush it because there is no need to play it */
                   3811:        r = IOCTL(fd, AUDIO_FLUSH, NULL, "");
                   3812:        XP_SYS_EQ(0, r);
                   3813:
                   3814:        r = CLOSE(fd);
                   3815:        XP_SYS_EQ(0, r);
                   3816:        r = CLOSE(kq);
                   3817:        XP_SYS_EQ(0, r);
                   3818:        free(buf);
                   3819: }
                   3820:
                   3821: /*
                   3822:  * kevent(2) must not be affected by other audio descriptors.
                   3823:  */
                   3824: DEF(kqueue_simul)
                   3825: {
                   3826:        struct audio_info ai;
                   3827:        struct audio_info ai2;
                   3828:        struct kevent kev[2];
                   3829:        struct timespec ts;
                   3830:        int fd[2];
                   3831:        int r;
                   3832:        int kq;
                   3833:        u_int blocksize;
                   3834:        int hiwat;
                   3835:        int lowat;
                   3836:        char *buf;
                   3837:        int buflen;
                   3838:
                   3839:        TEST("kqueue_simul");
                   3840:        if (netbsd < 8) {
                   3841:                XP_SKIP("Multiple open is not supported");
                   3842:                return;
                   3843:        }
                   3844:
                   3845:        memset(&ts, 0, sizeof(ts));
                   3846:
                   3847:        /* Make sure that it's not affected by descriptor order */
                   3848:        for (int i = 0; i < 2; i++) {
                   3849:                int a = i;
                   3850:                int b = 1 - i;
                   3851:
                   3852:                fd[0] = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3853:                REQUIRED_SYS_OK(fd[0]);
                   3854:                fd[1] = OPEN(devaudio, O_WRONLY | O_NONBLOCK);
                   3855:                REQUIRED_SYS_OK(fd[1]);
                   3856:
                   3857:                /*
                   3858:                 * Adjust block size and hiwat/lowat.
                   3859:                 * I want to choice suitable blocksize (if possible).
                   3860:                 */
                   3861:                blocksize = 1000;       /* 1/8 sec in mulaw,1ch,8000Hz */
                   3862:                hiwat = 12;             /* 1.5sec */
                   3863:                lowat = 4;              /* 0.5sec */
                   3864:                AUDIO_INITINFO(&ai);
                   3865:                ai.blocksize = blocksize;
                   3866:                ai.hiwat = hiwat;
                   3867:                ai.lowat = lowat;
                   3868:                r = IOCTL(fd[0], AUDIO_SETINFO, &ai, "blocksize=1000");
                   3869:                XP_SYS_EQ(0, r);
                   3870:                r = IOCTL(fd[0], AUDIO_GETBUFINFO, &ai, "read back blocksize");
                   3871:                if (ai.blocksize != blocksize) {
                   3872:                        /*
                   3873:                         * NetBSD9 can not change the blocksize.  Then,
                   3874:                         * adjust using hiwat/lowat.
                   3875:                         */
                   3876:                        blocksize = ai.blocksize;
                   3877:                        hiwat = howmany(8000 * 1.5, blocksize);
                   3878:                        lowat = howmany(8000 * 0.5, blocksize);
                   3879:                }
                   3880:                /* Anyway, set the parameters to both */
                   3881:                AUDIO_INITINFO(&ai);
                   3882:                ai.blocksize = blocksize;
                   3883:                ai.hiwat = hiwat;
                   3884:                ai.lowat = lowat;
                   3885:                ai.play.pause = 1;
                   3886:                r = IOCTL(fd[a], AUDIO_SETINFO, &ai, "pause=1");
                   3887:                XP_SYS_EQ(0, r);
                   3888:                r = IOCTL(fd[b], AUDIO_SETINFO, &ai, "pause=1");
                   3889:                XP_SYS_EQ(0, r);
                   3890:
                   3891:                /* Write both until full */
                   3892:                buflen = ai.blocksize * ai.hiwat;
                   3893:                buf = (char *)malloc(buflen);
                   3894:                REQUIRED_IF(buf != NULL);
                   3895:                memset(buf, 0xff, buflen);
                   3896:                /* Write fdA */
                   3897:                do {
                   3898:                        r = WRITE(fd[a], buf, buflen);
                   3899:                } while (r == buflen);
                   3900:                if (r == -1) {
                   3901:                        XP_SYS_NG(EAGAIN, r);
                   3902:                }
                   3903:                /* Write fdB */
                   3904:                do {
                   3905:                        r = WRITE(fd[b], buf, buflen);
                   3906:                } while (r == buflen);
                   3907:                if (r == -1) {
                   3908:                        XP_SYS_NG(EAGAIN, r);
                   3909:                }
                   3910:
                   3911:                /* Get fdB's initial seek for later */
                   3912:                r = IOCTL(fd[b], AUDIO_GETBUFINFO, &ai2, "");
                   3913:                XP_SYS_EQ(0, r);
                   3914:
                   3915:                kq = KQUEUE();
                   3916:                XP_SYS_OK(kq);
                   3917:
                   3918:                /* Both aren't raised at this point */
                   3919:                EV_SET(&kev[0], fd[a], EV_ADD, EVFILT_WRITE, 0, 0, 0);
                   3920:                EV_SET(&kev[1], fd[b], EV_ADD, EVFILT_WRITE, 0, 0, 0);
                   3921:                r = KEVENT_SET(kq, kev, 2);
                   3922:                XP_SYS_EQ(0, r);
                   3923:
                   3924:                /* Unpause only fdA */
                   3925:                AUDIO_INITINFO(&ai);
                   3926:                ai.play.pause = 0;
                   3927:                r = IOCTL(fd[a], AUDIO_SETINFO, &ai, "pause=0");
                   3928:                XP_SYS_EQ(0, r);
                   3929:
                   3930:                /* kevent() up to 2sec */
                   3931:                ts.tv_sec = 2;
                   3932:                ts.tv_nsec = 0;
                   3933:                r = KEVENT_POLL(kq, &kev[0], 1, &ts);
                   3934:                if (r >= 1)
                   3935:                        DEBUG_KEV("kev", &kev[0]);
                   3936:                /* fdA should raise */
                   3937:                XP_SYS_EQ(1, r);
                   3938:                XP_EQ(fd[a], kev[0].ident);
                   3939:
                   3940:                /* Make sure that fdB keeps whole data */
                   3941:                r = IOCTL(fd[b], AUDIO_GETBUFINFO, &ai, "");
                   3942:                XP_EQ(ai2.play.seek, ai.play.seek);
                   3943:
                   3944:                /* Flush it because there is no need to play it */
                   3945:                r = IOCTL(fd[0], AUDIO_FLUSH, NULL, "");
                   3946:                XP_SYS_EQ(0, r);
                   3947:                r = IOCTL(fd[1], AUDIO_FLUSH, NULL, "");
                   3948:                XP_SYS_EQ(0, r);
                   3949:
                   3950:                r = CLOSE(fd[0]);
                   3951:                XP_SYS_EQ(0, r);
                   3952:                r = CLOSE(fd[1]);
                   3953:                XP_SYS_EQ(0, r);
                   3954:                r = CLOSE(kq);
                   3955:                XP_SYS_EQ(0, r);
                   3956:                free(buf);
                   3957:
                   3958:                xxx_close_wait();
                   3959:        }
                   3960: }
                   3961:
                   3962: /* Shared data between threads for ioctl_while_write */
                   3963: struct ioctl_while_write_data {
                   3964:        int fd;
                   3965:        struct timeval start;
                   3966:        int terminated;
                   3967: };
                   3968:
                   3969: /* Test thread for ioctl_while_write */
                   3970: void *thread_ioctl_while_write(void *);
                   3971: void *
                   3972: thread_ioctl_while_write(void *arg)
                   3973: {
                   3974:        struct ioctl_while_write_data *data = arg;
                   3975:        struct timeval now, res;
                   3976:        struct audio_info ai;
                   3977:        int r;
                   3978:
                   3979:        /* If 0.5 seconds have elapsed since writing, assume it's blocked */
                   3980:        do {
                   3981:                usleep(100);
                   3982:                gettimeofday(&now, NULL);
                   3983:                timersub(&now, &data->start, &res);
                   3984:        } while (res.tv_usec < 500000);
                   3985:
                   3986:        /* Then, do ioctl() */
                   3987:        r = IOCTL(data->fd, AUDIO_GETBUFINFO, &ai, "");
                   3988:        XP_SYS_EQ(0, r);
                   3989:
                   3990:        /* Terminate */
                   3991:        data->terminated = 1;
                   3992:
                   3993:        /* Resume write() by unpause */
                   3994:        AUDIO_INITINFO(&ai);
                   3995:        if (netbsd < 8) {
                   3996:                /*
                   3997:                 * XXX NetBSD7 has bugs and it cannot be unpaused.
                   3998:                 * However, it also has another bug and it clears buffer
                   3999:                 * when encoding is changed.  I use it. :-P
                   4000:                 */
                   4001:                ai.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
                   4002:        }
                   4003:        ai.play.pause = 0;
                   4004:        r = IOCTL(data->fd, AUDIO_SETINFO, &ai, "pause=0");
                   4005:        XP_SYS_EQ(0, r);
                   4006:
                   4007:        return NULL;
                   4008: }
                   4009:
                   4010: /*
                   4011:  * ioctl(2) can be issued while write(2)-ing.
                   4012:  */
                   4013: DEF(ioctl_while_write)
                   4014: {
                   4015:        struct audio_info ai;
                   4016:        struct ioctl_while_write_data data0, *data;
                   4017:        char buf[8000]; /* 1sec in mulaw,1ch,8000Hz */
                   4018:        pthread_t tid;
                   4019:        int r;
                   4020:
                   4021:        TEST("ioctl_while_write");
                   4022:
                   4023:        data = &data0;
                   4024:        memset(data, 0, sizeof(*data));
                   4025:        memset(buf, 0xff, sizeof(buf));
                   4026:
                   4027:        data->fd = OPEN(devaudio, O_WRONLY);
                   4028:        REQUIRED_SYS_OK(data->fd);
                   4029:
                   4030:        /* Pause to block write(2)ing */
                   4031:        AUDIO_INITINFO(&ai);
                   4032:        ai.play.pause = 1;
                   4033:        r = IOCTL(data->fd, AUDIO_SETINFO, &ai, "pause=1");
                   4034:        XP_SYS_EQ(0, r);
                   4035:
                   4036:        gettimeofday(&data->start, NULL);
                   4037:
                   4038:        pthread_create(&tid, NULL, thread_ioctl_while_write, data);
                   4039:
                   4040:        /* Write until blocking */
                   4041:        for (;;) {
                   4042:                r = WRITE(data->fd, buf, sizeof(buf));
                   4043:                if (data->terminated)
                   4044:                        break;
                   4045:                XP_SYS_EQ(sizeof(buf), r);
                   4046:
                   4047:                /* Update written time */
                   4048:                gettimeofday(&data->start, NULL);
                   4049:        }
                   4050:
                   4051:        pthread_join(tid, NULL);
                   4052:
                   4053:        /* Flush */
                   4054:        r = IOCTL(data->fd, AUDIO_FLUSH, NULL, "");
                   4055:        XP_SYS_EQ(0, r);
                   4056:        r = CLOSE(data->fd);
                   4057:        XP_SYS_EQ(0, r);
                   4058: }
                   4059:
                   4060: volatile int sigio_caught;
                   4061: void
                   4062: signal_FIOASYNC(int signo)
                   4063: {
                   4064:        if (signo == SIGIO) {
                   4065:                sigio_caught = 1;
                   4066:                DPRINTF("  > %d: pid %d got SIGIO\n", __LINE__, (int)getpid());
                   4067:        }
                   4068: }
                   4069:
                   4070: /*
                   4071:  * FIOASYNC between two descriptors should be splitted.
                   4072:  */
                   4073: DEF(FIOASYNC_reset)
                   4074: {
                   4075:        int fd0, fd1;
                   4076:        int r;
                   4077:        int val;
                   4078:
                   4079:        TEST("FIOASYNC_reset");
                   4080:        if (netbsd < 8) {
                   4081:                XP_SKIP("Multiple open is not supported");
                   4082:                return;
                   4083:        }
                   4084:
                   4085:        /* The first one opens */
                   4086:        fd0 = OPEN(devaudio, O_WRONLY);
                   4087:        REQUIRED_SYS_OK(fd0);
                   4088:
                   4089:        /* The second one opens, enables ASYNC, and closes */
                   4090:        fd1 = OPEN(devaudio, O_WRONLY);
                   4091:        REQUIRED_SYS_OK(fd1);
                   4092:        val = 1;
                   4093:        r = IOCTL(fd1, FIOASYNC, &val, "on");
                   4094:        XP_SYS_EQ(0, r);
                   4095:        r = CLOSE(fd1);
                   4096:        XP_SYS_EQ(0, r);
                   4097:
                   4098:        /* Again, the second one opens and enables ASYNC */
                   4099:        fd1 = OPEN(devaudio, O_WRONLY);
                   4100:        REQUIRED_SYS_OK(fd1);
                   4101:        val = 1;
                   4102:        r = IOCTL(fd1, FIOASYNC, &val, "on");
                   4103:        XP_SYS_EQ(0, r);        /* NetBSD8 fails */
                   4104:        r = CLOSE(fd1);
                   4105:        XP_SYS_EQ(0, r);
                   4106:        r = CLOSE(fd0);
                   4107:        XP_SYS_EQ(0, r);
                   4108: }
                   4109:
                   4110: /*
                   4111:  * Whether SIGIO is emitted on plyaback.
                   4112:  * XXX I don't understand conditions that NetBSD7 emits signal.
                   4113:  */
                   4114: DEF(FIOASYNC_play_signal)
                   4115: {
                   4116:        struct audio_info ai;
                   4117:        int r;
                   4118:        int fd;
                   4119:        int val;
                   4120:        char *data;
                   4121:        int i;
                   4122:
                   4123:        TEST("FIOASYNC_play_signal");
                   4124:        if (hw_canplay() == 0) {
                   4125:                XP_SKIP("This test is only for playable device");
                   4126:                return;
                   4127:        }
                   4128:
                   4129:        signal(SIGIO, signal_FIOASYNC);
                   4130:        sigio_caught = 0;
                   4131:
                   4132:        fd = OPEN(devaudio, O_WRONLY);
                   4133:        REQUIRED_SYS_OK(fd);
                   4134:
                   4135:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4136:        REQUIRED_SYS_EQ(0, r);
                   4137:        REQUIRED_IF(ai.blocksize != 0);
                   4138:        data = (char *)malloc(ai.blocksize);
                   4139:        REQUIRED_IF(data != NULL);
                   4140:        memset(data, 0xff, ai.blocksize);
                   4141:
                   4142:        val = 1;
                   4143:        r = IOCTL(fd, FIOASYNC, &val, "on");
                   4144:        XP_SYS_EQ(0, r);
                   4145:
                   4146:        r = WRITE(fd, data, ai.blocksize);
                   4147:        XP_SYS_EQ(ai.blocksize, r);
                   4148:
                   4149:        /* Waits signal until 1sec */
                   4150:        for (i = 0; i < 100 && sigio_caught == 0; i++) {
                   4151:                usleep(10000);
                   4152:        }
                   4153:        signal(SIGIO, SIG_IGN);
                   4154:        XP_EQ(1, sigio_caught);
                   4155:
                   4156:        r = CLOSE(fd);
                   4157:        XP_SYS_EQ(0, r);
                   4158:
                   4159:        free(data);
                   4160:        signal(SIGIO, SIG_IGN);
                   4161:        sigio_caught = 0;
                   4162: }
                   4163:
                   4164: /*
                   4165:  * Whether SIGIO is emitted on recording.
                   4166:  */
                   4167: DEF(FIOASYNC_rec_signal)
                   4168: {
                   4169:        char buf[10];
                   4170:        int r;
                   4171:        int fd;
                   4172:        int val;
                   4173:        int i;
                   4174:
                   4175:        TEST("FIOASYNC_rec_signal");
                   4176:        if (hw_canrec() == 0) {
                   4177:                XP_SKIP("This test is only for recordable device");
                   4178:                return;
                   4179:        }
                   4180:
                   4181:        signal(SIGIO, signal_FIOASYNC);
                   4182:        sigio_caught = 0;
                   4183:
                   4184:        fd = OPEN(devaudio, O_RDONLY);
                   4185:        REQUIRED_SYS_OK(fd);
                   4186:
                   4187:        val = 1;
                   4188:        r = IOCTL(fd, FIOASYNC, &val, "on");
                   4189:        XP_SYS_EQ(0, r);
                   4190:
                   4191:        r = READ(fd, buf, sizeof(buf));
                   4192:        XP_SYS_EQ(sizeof(buf), r);
                   4193:
                   4194:        /* Wait signal until 1sec */
                   4195:        for (i = 0; i < 100 && sigio_caught == 0; i++) {
                   4196:                usleep(10000);
                   4197:        }
                   4198:        signal(SIGIO, SIG_IGN);
                   4199:        XP_EQ(1, sigio_caught);
                   4200:
                   4201:        r = CLOSE(fd);
                   4202:        XP_SYS_EQ(0, r);
                   4203:
                   4204:        signal(SIGIO, SIG_IGN);
                   4205:        sigio_caught = 0;
                   4206: }
                   4207:
                   4208: /*
                   4209:  * FIOASYNC doesn't affect other descriptor.
                   4210:  * For simplify, test only for playback...
                   4211:  */
                   4212: DEF(FIOASYNC_multi)
                   4213: {
                   4214:        struct audio_info ai;
                   4215:        char *buf;
                   4216:        char pipebuf[1];
                   4217:        int r;
                   4218:        int i;
                   4219:        int fd1;
                   4220:        int fd2;
                   4221:        int pd[2];
                   4222:        int val;
                   4223:        pid_t pid;
                   4224:        int status;
                   4225:
                   4226:        TEST("FIOASYNC_multi");
                   4227:        if (netbsd < 8) {
                   4228:                XP_SKIP("Multiple open is not supported");
                   4229:                return;
                   4230:        }
                   4231:        if (hw_canplay() == 0) {
                   4232:                XP_SKIP("This test is only for playable device");
                   4233:                return;
                   4234:        }
                   4235:
                   4236:        /* Pipe used between parent and child */
                   4237:        r = pipe(pd);
                   4238:        REQUIRED_SYS_EQ(0, r);
                   4239:
                   4240:        fd1 = OPEN(devaudio, O_WRONLY);
                   4241:        REQUIRED_SYS_OK(fd1);
                   4242:        fd2 = OPEN(devaudio, O_WRONLY);
                   4243:        REQUIRED_SYS_OK(fd2);
                   4244:
                   4245:        /* Pause fd2 */
                   4246:        AUDIO_INITINFO(&ai);
                   4247:        ai.play.pause = 1;
                   4248:        r = IOCTL(fd2, AUDIO_SETINFO, &ai, "pause");
                   4249:        REQUIRED_SYS_EQ(0, r);
                   4250:
                   4251:        /* Fill both */
                   4252:        r = IOCTL(fd1, AUDIO_GETBUFINFO, &ai, "");
                   4253:        REQUIRED_SYS_EQ(0, r);
                   4254:        REQUIRED_IF(ai.blocksize != 0);
                   4255:        buf = (char *)malloc(ai.blocksize);
                   4256:        REQUIRED_IF(buf != NULL);
                   4257:        memset(buf, 0xff, ai.blocksize);
                   4258:        r = WRITE(fd1, buf, ai.blocksize);
                   4259:        XP_SYS_EQ(ai.blocksize, r);
                   4260:
                   4261:        sigio_caught = 0;
                   4262:        val = 1;
                   4263:
                   4264:        fflush(stdout);
                   4265:        fflush(stderr);
                   4266:        pid = fork();
                   4267:        if (pid == -1) {
                   4268:                REQUIRED_SYS_OK(pid);
                   4269:        }
                   4270:        if (pid == 0) {
                   4271:                /* Child */
                   4272:                close(fd1);
                   4273:
                   4274:                /* Child enables ASYNC on fd2 */
                   4275:                signal(SIGIO, signal_FIOASYNC);
                   4276:                r = IOCTL(fd2, FIOASYNC, &val, "on");
                   4277:                /* It cannot count errors because here is a child process */
                   4278:                /* XP_SYS_EQ(0, r); */
                   4279:
                   4280:                /*
                   4281:                 * Waits signal until 1sec.
                   4282:                 * But fd2 is paused so it should never raise.
                   4283:                 */
                   4284:                for (i = 0; i < 100 && sigio_caught == 0; i++) {
                   4285:                        usleep(10000);
                   4286:                }
                   4287:                signal(SIGIO, SIG_IGN);
                   4288:                pipebuf[0] = sigio_caught;
                   4289:                /* This is not WRITE() macro here */
                   4290:                write(pd[1], pipebuf, sizeof(pipebuf));
                   4291:
                   4292:                /* XXX? */
                   4293:                close(fd2);
                   4294:                sleep(1);
                   4295:                exit(0);
                   4296:        } else {
                   4297:                /* Parent */
                   4298:                DPRINTF("  > fork() = %d\n", (int)pid);
                   4299:
                   4300:                /* Parent enables ASYNC on fd1 */
                   4301:                signal(SIGIO, signal_FIOASYNC);
                   4302:                r = IOCTL(fd1, FIOASYNC, &val, "on");
                   4303:                XP_SYS_EQ(0, r);
                   4304:
                   4305:                /* Waits signal until 1sec */
                   4306:                for (i = 0; i < 100 && sigio_caught == 0; i++) {
                   4307:                        usleep(10000);
                   4308:                }
                   4309:                signal(SIGIO, SIG_IGN);
                   4310:                XP_EQ(1, sigio_caught);
                   4311:
                   4312:                /* Then read child's result from pipe */
                   4313:                r = read(pd[0], pipebuf, sizeof(pipebuf));
                   4314:                if (r != 1) {
                   4315:                        XP_FAIL("reading from child failed");
                   4316:                }
                   4317:                DPRINTF("  > child's sigio_cauht = %d\n", pipebuf[0]);
                   4318:                XP_EQ(0, pipebuf[0]);
                   4319:
                   4320:                waitpid(pid, &status, 0);
                   4321:        }
                   4322:
                   4323:        r = CLOSE(fd1);
                   4324:        XP_SYS_EQ(0, r);
                   4325:        r = CLOSE(fd2);
                   4326:        XP_SYS_EQ(0, r);
                   4327:
                   4328:        signal(SIGIO, SIG_IGN);
                   4329:        sigio_caught = 0;
                   4330:        free(buf);
                   4331: }
                   4332:
                   4333: /*
                   4334:  * Check AUDIO_WSEEK behavior.
                   4335:  */
                   4336: DEF(AUDIO_WSEEK)
                   4337: {
                   4338:        char buf[4];
                   4339:        struct audio_info ai;
                   4340:        int r;
                   4341:        int fd;
                   4342:        int n;
                   4343:
                   4344:        TEST("AUDIO_WSEEK");
                   4345:
                   4346:        fd = OPEN(devaudio, O_WRONLY);
                   4347:        REQUIRED_SYS_OK(fd);
                   4348:
                   4349:        /* Pause to count sample data */
                   4350:        AUDIO_INITINFO(&ai);
                   4351:        ai.play.pause = 1;
                   4352:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause=1");
                   4353:        REQUIRED_SYS_EQ(0, r);
                   4354:
                   4355:        /* On the initial state, it should be 0 bytes */
                   4356:        n = 0;
                   4357:        r = IOCTL(fd, AUDIO_WSEEK, &n, "");
                   4358:        XP_SYS_EQ(0, r);
                   4359:        XP_EQ(0, n);
                   4360:
                   4361:        /* When writing 4 bytes, it should be 4 bytes */
                   4362:        memset(buf, 0xff, sizeof(buf));
                   4363:        r = WRITE(fd, buf, sizeof(buf));
                   4364:        REQUIRED_EQ(sizeof(buf), r);
                   4365:        r = IOCTL(fd, AUDIO_WSEEK, &n, "");
                   4366:        XP_SYS_EQ(0, r);
                   4367:        if (netbsd < 9) {
                   4368:                /*
                   4369:                 * On NetBSD7, it will return 0.
                   4370:                 * Perhaps, WSEEK returns the number of pustream bytes but
                   4371:                 * data has already advanced...
                   4372:                 */
                   4373:                XP_EQ(0, n);
                   4374:        } else {
                   4375:                /* Data less than one block remains here */
                   4376:                XP_EQ(4, n);
                   4377:        }
                   4378:
                   4379:        r = CLOSE(fd);
                   4380:        XP_SYS_EQ(0, r);
                   4381: }
                   4382:
                   4383: /*
                   4384:  * Check AUDIO_SETFD behavior for O_*ONLY descriptor.
                   4385:  * On NetBSD7, SETFD modify audio layer's state (and MD driver's state)
                   4386:  * regardless of open mode.  GETFD obtains audio layer's duplex.
                   4387:  * On NetBSD9, SETFD is obsoleted.  GETFD obtains hardware's duplex.
                   4388:  */
                   4389: void
                   4390: test_AUDIO_SETFD_xxONLY(int openmode)
                   4391: {
                   4392:        struct audio_info ai;
                   4393:        int r;
                   4394:        int fd;
                   4395:        int n;
                   4396:
                   4397:        TEST("AUDIO_SETFD_%s", openmode_str[openmode] + 2);
                   4398:        if (openmode == O_RDONLY && hw_canrec() == 0) {
                   4399:                XP_SKIP("This test is for recordable device");
                   4400:                return;
                   4401:        }
                   4402:        if (openmode == O_WRONLY && hw_canplay() == 0) {
                   4403:                XP_SKIP("This test is for playable device");
                   4404:                return;
                   4405:        }
                   4406:
                   4407:        fd = OPEN(devaudio, openmode);
                   4408:        REQUIRED_SYS_OK(fd);
                   4409:
                   4410:        /*
                   4411:         * Just after open(2),
                   4412:         * - On NetBSD7, it's always half-duplex.
                   4413:         * - On NetBSD9, it's the same as hardware one regardless of openmode.
                   4414:         */
                   4415:        n = 0;
                   4416:        r = IOCTL(fd, AUDIO_GETFD, &n, "");
                   4417:        XP_SYS_EQ(0, r);
                   4418:        if (netbsd < 9) {
                   4419:                XP_EQ(0, n);
                   4420:        } else {
                   4421:                XP_EQ(hw_fulldup(), n);
                   4422:        }
                   4423:
                   4424:        /*
                   4425:         * When trying to set to full-duplex,
                   4426:         * - On NetBSD7, it will succeed if the hardware is full-duplex, or
                   4427:         *   will fail if the hardware is half-duplex.
                   4428:         * - On NetBSD9, it will always succeed but will not be modified.
                   4429:         */
                   4430:        n = 1;
                   4431:        r = IOCTL(fd, AUDIO_SETFD, &n, "on");
                   4432:        if (netbsd < 8) {
                   4433:                if (hw_fulldup()) {
                   4434:                        XP_SYS_EQ(0, r);
                   4435:                } else {
                   4436:                        XP_SYS_NG(ENOTTY, r);
                   4437:                }
                   4438:        } else if (netbsd == 8) {
                   4439:                XP_FAIL("expected result is unknown");
                   4440:        } else {
                   4441:                XP_SYS_EQ(0, r);
                   4442:        }
                   4443:
                   4444:        /*
                   4445:         * When obtain it,
                   4446:         * - On NetBSD7, it will be 1 if the hardware is full-duplex or
                   4447:         *   0 if half-duplex.
                   4448:         * - On NetBSD9, it will never be changed because it's the hardware
                   4449:         *   property.
                   4450:         */
                   4451:        n = 0;
                   4452:        r = IOCTL(fd, AUDIO_GETFD, &n, "");
                   4453:        XP_SYS_EQ(0, r);
                   4454:        if (netbsd < 8) {
                   4455:                XP_EQ(hw_fulldup(), n);
                   4456:        } else if (netbsd == 8) {
                   4457:                XP_FAIL("expected result is unknown");
                   4458:        } else {
                   4459:                XP_EQ(hw_fulldup(), n);
                   4460:        }
                   4461:
                   4462:        /* Some track parameters like ai.*.open should not change */
                   4463:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4464:        XP_SYS_EQ(0, r);
                   4465:        XP_EQ(mode2play(openmode), ai.play.open);
                   4466:        XP_EQ(mode2rec(openmode), ai.record.open);
                   4467:
                   4468:        /*
                   4469:         * When trying to set to half-duplex,
                   4470:         * - On NetBSD7, it will succeed if the hardware is full-duplex, or
                   4471:         *   it will succeed with nothing happens.
                   4472:         * - On NetBSD9, it will always succeed but nothing happens.
                   4473:         */
                   4474:        n = 0;
                   4475:        r = IOCTL(fd, AUDIO_SETFD, &n, "off");
                   4476:        XP_SYS_EQ(0, r);
                   4477:
                   4478:        /*
                   4479:         * When obtain it again,
                   4480:         * - On NetBSD7, it will be 0 if the hardware is full-duplex, or
                   4481:         *   still 0 if half-duplex.
                   4482:         * - On NetBSD9, it should not change.
                   4483:         */
                   4484:        n = 0;
                   4485:        r = IOCTL(fd, AUDIO_GETFD, &n, "");
                   4486:        XP_SYS_EQ(0, r);
                   4487:        if (netbsd < 9) {
                   4488:                XP_EQ(0, n);
                   4489:        } else {
                   4490:                XP_EQ(hw_fulldup(), n);
                   4491:        }
                   4492:
                   4493:        /* Some track parameters like ai.*.open should not change */
                   4494:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4495:        XP_SYS_EQ(0, r);
                   4496:        XP_EQ(mode2play(openmode), ai.play.open);
                   4497:        XP_EQ(mode2rec(openmode), ai.record.open);
                   4498:
                   4499:        r = CLOSE(fd);
                   4500:        XP_SYS_EQ(0, r);
                   4501: }
                   4502: DEF(AUDIO_SETFD_RDONLY)        { test_AUDIO_SETFD_xxONLY(O_RDONLY); }
                   4503: DEF(AUDIO_SETFD_WRONLY)        { test_AUDIO_SETFD_xxONLY(O_WRONLY); }
                   4504:
                   4505: /*
                   4506:  * Check AUDIO_SETFD behavior for O_RDWR descriptor.
                   4507:  */
                   4508: DEF(AUDIO_SETFD_RDWR)
                   4509: {
                   4510:        struct audio_info ai;
                   4511:        int r;
                   4512:        int fd;
                   4513:        int n;
                   4514:
                   4515:        TEST("AUDIO_SETFD_RDWR");
                   4516:        if (!hw_fulldup()) {
                   4517:                XP_SKIP("This test is only for full-duplex device");
                   4518:                return;
                   4519:        }
                   4520:
                   4521:        fd = OPEN(devaudio, O_RDWR);
                   4522:        REQUIRED_SYS_OK(fd);
                   4523:
                   4524:        /*
                   4525:         * - audio(4) manpage until NetBSD7 said "If a full-duplex capable
                   4526:         *   audio device is opened for both reading and writing it will
                   4527:         *   start in half-duplex play mode", but implementation doesn't
                   4528:         *   seem to follow it.  It returns full-duplex.
                   4529:         * - On NetBSD9, it should return full-duplex on full-duplex, or
                   4530:         *   half-duplex on half-duplex.
                   4531:         */
                   4532:        n = 0;
                   4533:        r = IOCTL(fd, AUDIO_GETFD, &n, "");
                   4534:        XP_SYS_EQ(0, r);
                   4535:        XP_EQ(hw_fulldup(), n);
                   4536:
                   4537:        /*
                   4538:         * When trying to set to full-duplex,
                   4539:         * - On NetBSD7, it will succeed with nothing happens if full-duplex,
                   4540:         *   or will fail if half-duplex.
                   4541:         * - On NetBSD9, it will always succeed with nothing happens.
                   4542:         */
                   4543:        n = 1;
                   4544:        r = IOCTL(fd, AUDIO_SETFD, &n, "on");
                   4545:        if (netbsd < 9) {
                   4546:                if (hw_fulldup()) {
                   4547:                        XP_SYS_EQ(0, r);
                   4548:                } else {
                   4549:                        XP_SYS_NG(ENOTTY, r);
                   4550:                }
                   4551:        } else {
                   4552:                XP_SYS_EQ(0, r);
                   4553:        }
                   4554:
                   4555:        /* When obtains it, it retuns half/full-duplex as is */
                   4556:        n = 0;
                   4557:        r = IOCTL(fd, AUDIO_GETFD, &n, "");
                   4558:        XP_SYS_EQ(0, r);
                   4559:        XP_EQ(hw_fulldup(), n);
                   4560:
                   4561:        /* Some track parameters like ai.*.open should not change */
                   4562:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4563:        XP_SYS_EQ(0, r);
                   4564:        XP_EQ(1, ai.play.open);
                   4565:        XP_EQ(mode2rec(O_RDWR), ai.record.open);
                   4566:
                   4567:        /*
                   4568:         * When trying to set to half-duplex,
                   4569:         * - On NetBSD7, it will succeed if the hardware is full-duplex, or
                   4570:         *   it will succeed with nothing happens.
                   4571:         * - On NetBSD9, it will always succeed but nothing happens.
                   4572:         */
                   4573:        n = 0;
                   4574:        r = IOCTL(fd, AUDIO_SETFD, &n, "off");
                   4575:        if (netbsd < 8) {
                   4576:                XP_SYS_EQ(0, r);
                   4577:        } else if (netbsd == 8) {
                   4578:                XP_FAIL("expected result is unknown");
                   4579:        } else {
                   4580:                XP_SYS_EQ(0, r);
                   4581:        }
                   4582:
                   4583:        /*
                   4584:         * When obtain it again,
                   4585:         * - On NetBSD7, it will be 0 if the hardware is full-duplex, or
                   4586:         *   still 0 if half-duplex.
                   4587:         * - On NetBSD9, it should be 1 if the hardware is full-duplex, or
                   4588:         *   0 if half-duplex.
                   4589:         */
                   4590:        n = 0;
                   4591:        r = IOCTL(fd, AUDIO_GETFD, &n, "");
                   4592:        XP_SYS_EQ(0, r);
                   4593:        if (netbsd < 8) {
                   4594:                XP_EQ(0, n);
                   4595:        } else if (netbsd == 8) {
                   4596:                XP_FAIL("expected result is unknown");
                   4597:        } else {
                   4598:                XP_EQ(hw_fulldup(), n);
                   4599:        }
                   4600:
                   4601:        /* Some track parameters like ai.*.open should not change */
                   4602:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4603:        XP_SYS_EQ(0, r);
                   4604:        XP_EQ(1, ai.play.open);
                   4605:        XP_EQ(mode2rec(O_RDWR), ai.record.open);
                   4606:
                   4607:        r = CLOSE(fd);
                   4608:        XP_SYS_EQ(0, r);
                   4609: }
                   4610:
                   4611: /*
                   4612:  * Check AUDIO_GETINFO.eof behavior.
                   4613:  */
                   4614: DEF(AUDIO_GETINFO_eof)
                   4615: {
                   4616:        struct audio_info ai;
                   4617:        char buf[4];
                   4618:        int r;
                   4619:        int fd, fd1;
                   4620:
                   4621:        TEST("AUDIO_GETINFO_eof");
                   4622:        if (hw_canplay() == 0) {
                   4623:                XP_SKIP("This test is for playable device");
                   4624:                return;
                   4625:        }
                   4626:
                   4627:        fd = OPEN(devaudio, O_RDWR);
                   4628:        REQUIRED_SYS_OK(fd);
                   4629:
                   4630:        /* Pause to make no sound */
                   4631:        AUDIO_INITINFO(&ai);
                   4632:        ai.play.pause = 1;
                   4633:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "pause");
                   4634:        REQUIRED_SYS_EQ(0, r);
                   4635:
                   4636:        /* It should be 0 initially */
                   4637:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4638:        XP_SYS_EQ(0, r);
                   4639:        XP_EQ(0, ai.play.eof);
                   4640:        XP_EQ(0, ai.record.eof);
                   4641:
                   4642:        /* Writing zero bytes should increment it */
                   4643:        r = WRITE(fd, &r, 0);
                   4644:        REQUIRED_SYS_OK(r);
                   4645:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4646:        XP_SYS_EQ(0, r);
                   4647:        XP_EQ(1, ai.play.eof);
                   4648:        XP_EQ(0, ai.record.eof);
                   4649:
                   4650:        /* Writing one ore more bytes should noto increment it */
                   4651:        memset(buf, 0xff, sizeof(buf));
                   4652:        r = WRITE(fd, buf, sizeof(buf));
                   4653:        REQUIRED_SYS_OK(r);
                   4654:        memset(&ai, 0, sizeof(ai));
                   4655:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4656:        XP_SYS_EQ(0, r);
                   4657:        XP_EQ(1, ai.play.eof);
                   4658:        XP_EQ(0, ai.record.eof);
                   4659:
                   4660:        /* Writing zero bytes again should increment it */
                   4661:        r = WRITE(fd, buf, 0);
                   4662:        REQUIRED_SYS_OK(r);
                   4663:        memset(&ai, 0, sizeof(ai));
                   4664:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4665:        XP_SYS_EQ(0, r);
                   4666:        XP_EQ(2, ai.play.eof);
                   4667:        XP_EQ(0, ai.record.eof);
                   4668:
                   4669:        /* Reading zero bytes should not increment it */
                   4670:        if (hw_fulldup()) {
                   4671:                r = READ(fd, buf, 0);
                   4672:                REQUIRED_SYS_OK(r);
                   4673:                memset(&ai, 0, sizeof(ai));
                   4674:                r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4675:                XP_SYS_EQ(0, r);
                   4676:                XP_EQ(2, ai.play.eof);
                   4677:                XP_EQ(0, ai.record.eof);
                   4678:        }
                   4679:
                   4680:        /* should not interfere with other descriptor */
                   4681:        if (netbsd >= 8) {
                   4682:                fd1 = OPEN(devaudio, O_RDWR);
                   4683:                REQUIRED_SYS_OK(fd1);
                   4684:                memset(&ai, 0, sizeof(ai));
                   4685:                r = IOCTL(fd1, AUDIO_GETBUFINFO, &ai, "");
                   4686:                XP_SYS_EQ(0, r);
                   4687:                XP_EQ(0, ai.play.eof);
                   4688:                XP_EQ(0, ai.record.eof);
                   4689:                r = CLOSE(fd1);
                   4690:                XP_SYS_EQ(0, r);
                   4691:        }
                   4692:
                   4693:        r = CLOSE(fd);
                   4694:        XP_SYS_EQ(0, r);
                   4695:
                   4696:        xxx_close_wait();
                   4697:
                   4698:        /* When reopen, it should reset the counter */
                   4699:        fd = OPEN(devaudio, O_RDWR);
                   4700:        REQUIRED_SYS_OK(fd);
                   4701:
                   4702:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4703:        XP_SYS_EQ(0, r);
                   4704:        XP_EQ(0, ai.play.eof);
                   4705:        XP_EQ(0, ai.record.eof);
                   4706:
                   4707:        r = CLOSE(fd);
                   4708:        XP_SYS_EQ(0, r);
                   4709: }
                   4710:
                   4711: /*
                   4712:  * Check relationship between openmode and mode set by AUDIO_SETINFO.
                   4713:  */
                   4714: void
                   4715: test_AUDIO_SETINFO_mode(int openmode, int index, int setmode, int expected)
                   4716: {
                   4717:        struct audio_info ai;
                   4718:        char buf[10];
                   4719:        int inimode;
                   4720:        int r;
                   4721:        int fd;
                   4722:        bool canwrite;
                   4723:        bool canread;
                   4724:
                   4725:        /* index was passed only for displaying here */
                   4726:        TEST("AUDIO_SETINFO_mode_%s_%d", openmode_str[openmode] + 2, index);
                   4727:        if (mode2aumode(openmode) == 0) {
                   4728:                XP_SKIP("Operation not allowed on this hardware property");
                   4729:                return;
                   4730:        }
                   4731:
                   4732:        inimode = mode2aumode(openmode);
                   4733:
                   4734:        fd = OPEN(devaudio, openmode);
                   4735:        REQUIRED_SYS_OK(fd);
                   4736:
                   4737:        /* When just after opening */
                   4738:        memset(&ai, 0, sizeof(ai));
                   4739:        r = IOCTL(fd, AUDIO_GETINFO, &ai, "");
                   4740:        REQUIRED_SYS_EQ(0, r);
                   4741:        XP_EQ(inimode, ai.mode);
                   4742:        XP_EQ(mode2play(openmode), ai.play.open);
                   4743:        XP_EQ(mode2rec(openmode),  ai.record.open);
1.7       isaki    4744:        XP_NE(0, ai.play.buffer_size);
                   4745:        XP_NE(0, ai.record.buffer_size);
1.1       isaki    4746:
                   4747:        /* Change mode (and pause here) */
                   4748:        ai.mode = setmode;
                   4749:        ai.play.pause = 1;
                   4750:        ai.record.pause = 1;
                   4751:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "mode");
                   4752:        XP_SYS_EQ(0, r);
                   4753:        if (r == 0) {
                   4754:                r = IOCTL(fd, AUDIO_GETINFO, &ai, "");
                   4755:                XP_SYS_EQ(0, r);
                   4756:                XP_EQ(expected, ai.mode);
                   4757:
                   4758:                /* It seems to keep the initial openmode regardless of mode */
                   4759:                XP_EQ(mode2play(openmode), ai.play.open);
                   4760:                XP_EQ(mode2rec(openmode), ai.record.open);
1.7       isaki    4761:                XP_NE(0, ai.play.buffer_size);
                   4762:                XP_NE(0, ai.record.buffer_size);
1.1       isaki    4763:        }
                   4764:
                   4765:        /*
                   4766:         * On NetBSD7, whether writable depends openmode when open.
                   4767:         * On NetBSD9, whether writable should depend inimode when open.
                   4768:         * Modifying after open should not affect this mode.
                   4769:         */
                   4770:        if (netbsd < 9) {
                   4771:                canwrite = (openmode != O_RDONLY);
                   4772:        } else {
                   4773:                canwrite = ((inimode & AUMODE_PLAY) != 0);
                   4774:        }
                   4775:        r = WRITE(fd, buf, 0);
                   4776:        if (canwrite) {
                   4777:                XP_SYS_EQ(0, r);
                   4778:        } else {
                   4779:                XP_SYS_NG(EBADF, r);
                   4780:        }
                   4781:
                   4782:        /*
                   4783:         * On NetBSD7, whether readable depends openmode when open.
                   4784:         * On NetBSD9, whether readable should depend inimode when open.
                   4785:         * Modifying after open should not affect this mode.
                   4786:         */
                   4787:        if (netbsd < 9) {
                   4788:                canread = (openmode != O_WRONLY);
                   4789:        } else {
                   4790:                canread = ((inimode & AUMODE_RECORD) != 0);
                   4791:        }
                   4792:        r = READ(fd, buf, 0);
                   4793:        if (canread) {
                   4794:                XP_SYS_EQ(0, r);
                   4795:        } else {
                   4796:                XP_SYS_NG(EBADF, r);
                   4797:        }
                   4798:
                   4799:        r = CLOSE(fd);
                   4800:        XP_SYS_EQ(0, r);
                   4801: }
                   4802: /*
                   4803:  * XXX hmm... it's too complex
                   4804:  */
                   4805: /* shortcut for table form */
                   4806: #define P      AUMODE_PLAY
                   4807: #define A      AUMODE_PLAY_ALL
                   4808: #define R      AUMODE_RECORD
                   4809: struct setinfo_mode_t {
                   4810:        int setmode;    /* mode used in SETINFO */
                   4811:        int expmode7;   /* expected mode on NetBSD7 */
                   4812:        int expmode9;   /* expected mode on NetBSD9 */
                   4813: };
                   4814: /*
                   4815:  * The following tables show this operation on NetBSD7 is almost 'undefined'.
                   4816:  * In contrast, NetBSD9 never changes mode by AUDIO_SETINFO except
                   4817:  * AUMODE_PLAY_ALL.
                   4818:  *
                   4819:  * setmode == 0 and 8 are out of range and invalid input samples.
                   4820:  * But NetBSD7 seems to accept it as is.
                   4821:  */
                   4822: struct setinfo_mode_t table_SETINFO_mode_O_RDONLY[] = {
                   4823:        /* setmode      expmode7        expmode9 */
                   4824:        {     0,             0,          R    },
                   4825:        {     P,             P,          R    },
                   4826:        {   A  ,           A|P,          R    },
                   4827:        {   A|P,           A|P,          R    },
                   4828:        { R    ,         R    ,          R    },
                   4829:        { R|  P,             P,          R    },
                   4830:        { R|A  ,           A|P,          R    },
                   4831:        { R|A|P,           A|P,          R    },
                   4832:        {     8,             8,          R    },
                   4833: };
                   4834: struct setinfo_mode_t table_SETINFO_mode_O_WRONLY[] = {
                   4835:        /* setmode      expmode7        expmode9 */
                   4836:        {     0,             0,              P },
                   4837:        {     P,             P,              P },
                   4838:        {   A  ,           A|P,            A|P },
                   4839:        {   A|P,           A|P,            A|P },
                   4840:        { R    ,         R    ,              P },
                   4841:        { R|  P,             P,              P },
                   4842:        { R|A  ,           A|P,            A|P },
                   4843:        { R|A|P,           A|P,            A|P },
                   4844:        {     8,             8,              P },
                   4845: };
                   4846: #define f(openmode, index)     do {                                    \
                   4847:        struct setinfo_mode_t *table = table_SETINFO_mode_##openmode;   \
                   4848:        int setmode = table[index].setmode;                             \
                   4849:        int expected = (netbsd < 9)                                     \
                   4850:            ? table[index].expmode7                                     \
                   4851:            : table[index].expmode9;                                    \
                   4852:        test_AUDIO_SETINFO_mode(openmode, index, setmode, expected);    \
                   4853: } while (0)
                   4854: DEF(AUDIO_SETINFO_mode_RDONLY_0) { f(O_RDONLY, 0); }
                   4855: DEF(AUDIO_SETINFO_mode_RDONLY_1) { f(O_RDONLY, 1); }
                   4856: DEF(AUDIO_SETINFO_mode_RDONLY_2) { f(O_RDONLY, 2); }
                   4857: DEF(AUDIO_SETINFO_mode_RDONLY_3) { f(O_RDONLY, 3); }
                   4858: DEF(AUDIO_SETINFO_mode_RDONLY_4) { f(O_RDONLY, 4); }
                   4859: DEF(AUDIO_SETINFO_mode_RDONLY_5) { f(O_RDONLY, 5); }
                   4860: DEF(AUDIO_SETINFO_mode_RDONLY_6) { f(O_RDONLY, 6); }
                   4861: DEF(AUDIO_SETINFO_mode_RDONLY_7) { f(O_RDONLY, 7); }
                   4862: DEF(AUDIO_SETINFO_mode_RDONLY_8) { f(O_RDONLY, 8); }
                   4863: DEF(AUDIO_SETINFO_mode_WRONLY_0) { f(O_WRONLY, 0); }
                   4864: DEF(AUDIO_SETINFO_mode_WRONLY_1) { f(O_WRONLY, 1); }
                   4865: DEF(AUDIO_SETINFO_mode_WRONLY_2) { f(O_WRONLY, 2); }
                   4866: DEF(AUDIO_SETINFO_mode_WRONLY_3) { f(O_WRONLY, 3); }
                   4867: DEF(AUDIO_SETINFO_mode_WRONLY_4) { f(O_WRONLY, 4); }
                   4868: DEF(AUDIO_SETINFO_mode_WRONLY_5) { f(O_WRONLY, 5); }
                   4869: DEF(AUDIO_SETINFO_mode_WRONLY_6) { f(O_WRONLY, 6); }
                   4870: DEF(AUDIO_SETINFO_mode_WRONLY_7) { f(O_WRONLY, 7); }
                   4871: DEF(AUDIO_SETINFO_mode_WRONLY_8) { f(O_WRONLY, 8); }
                   4872: #undef f
                   4873: /*
                   4874:  * The following tables also show that NetBSD7's behavior is almost
                   4875:  * 'undefined'.
                   4876:  */
                   4877: struct setinfo_mode_t table_SETINFO_mode_O_RDWR_full[] = {
                   4878:        /* setmode      expmode7        expmode9 */
                   4879:        {     0,            0,          R|  P },
                   4880:        {     P,            P,          R|  P },
                   4881:        {   A  ,          A|P,          R|A|P },
                   4882:        {   A|P,          A|P,          R|A|P },
                   4883:        { R    ,        R    ,          R|  P },
                   4884:        { R|  P,        R|  P,          R|  P },
                   4885:        { R|A  ,        R|A|P,          R|A|P },
                   4886:        { R|A|P,        R|A|P,          R|A|P },
                   4887:        {     8,            8,          R|  P },
                   4888: };
                   4889: struct setinfo_mode_t table_SETINFO_mode_O_RDWR_half[] = {
                   4890:        /* setmode      expmode7        expmode9 */
                   4891:        {     0,            0,              P },
                   4892:        {     P,            P,              P },
                   4893:        {   A  ,          A|P,            A|P },
                   4894:        {   A|P,          A|P,            A|P },
                   4895:        { R    ,        R    ,              P },
                   4896:        { R|  P,            P,              P },
                   4897:        { R|A  ,          A|P,            A|P },
                   4898:        { R|A|P,          A|P,            A|P },
                   4899:        {     8,            8,              P },
                   4900: };
                   4901: #define f(index)       do {                                            \
                   4902:        struct setinfo_mode_t *table = (hw_fulldup())                   \
                   4903:            ? table_SETINFO_mode_O_RDWR_full                            \
                   4904:            : table_SETINFO_mode_O_RDWR_half;                           \
                   4905:        int setmode = table[index].setmode;                             \
                   4906:        int expected = (netbsd < 9)                                     \
                   4907:            ? table[index].expmode7                                     \
                   4908:            : table[index].expmode9;                                    \
                   4909:        test_AUDIO_SETINFO_mode(O_RDWR, index, setmode, expected);      \
                   4910: } while (0)
                   4911: DEF(AUDIO_SETINFO_mode_RDWR_0) { f(0); }
                   4912: DEF(AUDIO_SETINFO_mode_RDWR_1) { f(1); }
                   4913: DEF(AUDIO_SETINFO_mode_RDWR_2) { f(2); }
                   4914: DEF(AUDIO_SETINFO_mode_RDWR_3) { f(3); }
                   4915: DEF(AUDIO_SETINFO_mode_RDWR_4) { f(4); }
                   4916: DEF(AUDIO_SETINFO_mode_RDWR_5) { f(5); }
                   4917: DEF(AUDIO_SETINFO_mode_RDWR_6) { f(6); }
                   4918: DEF(AUDIO_SETINFO_mode_RDWR_7) { f(7); }
                   4919: DEF(AUDIO_SETINFO_mode_RDWR_8) { f(8); }
                   4920: #undef f
                   4921: #undef P
                   4922: #undef A
                   4923: #undef R
                   4924:
                   4925: /*
                   4926:  * Check whether encoding params can be set.
                   4927:  */
                   4928: void
                   4929: test_AUDIO_SETINFO_params_set(int openmode, int aimode, int pause)
                   4930: {
                   4931:        struct audio_info ai;
                   4932:        int r;
                   4933:        int fd;
                   4934:
                   4935:        /*
                   4936:         * aimode is bool value that indicates whether to change ai.mode.
                   4937:         * pause is bool value that indicates whether to change ai.*.pause.
                   4938:         */
                   4939:
                   4940:        TEST("AUDIO_SETINFO_params_%s_%d_%d",
                   4941:            openmode_str[openmode] + 2, aimode, pause);
                   4942:        if (mode2aumode(openmode) == 0) {
                   4943:                XP_SKIP("Operation not allowed on this hardware property");
                   4944:                return;
                   4945:        }
                   4946:
                   4947:        /* On half-duplex, O_RDWR is the same as O_WRONLY, so skip it */
                   4948:        if (!hw_fulldup() && openmode == O_RDWR) {
                   4949:                XP_SKIP("This is the same with O_WRONLY on half-duplex");
                   4950:                return;
                   4951:        }
                   4952:
                   4953:        fd = OPEN(devaudio, openmode);
                   4954:        REQUIRED_SYS_OK(fd);
                   4955:
                   4956:        AUDIO_INITINFO(&ai);
                   4957:        /*
                   4958:         * It takes time and effort to check all parameters independently,
                   4959:         * so that use sample_rate as a representative.
                   4960:         */
                   4961:        ai.play.sample_rate = 11025;
                   4962:        ai.record.sample_rate = 11025;
                   4963:        if (aimode)
                   4964:                ai.mode = mode2aumode(openmode) & ~AUMODE_PLAY_ALL;
                   4965:        if (pause) {
                   4966:                ai.play.pause = 1;
                   4967:                ai.record.pause = 1;
                   4968:        }
                   4969:
                   4970:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "");
                   4971:        XP_SYS_EQ(0, r);
                   4972:
                   4973:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   4974:        XP_SYS_EQ(0, r);
                   4975:        int expmode = (aimode)
                   4976:            ? (mode2aumode(openmode) & ~AUMODE_PLAY_ALL)
                   4977:            : mode2aumode(openmode);
                   4978:        XP_EQ(expmode, ai.mode);
1.7       isaki    4979:        XP_EQ(11025, ai.play.sample_rate);
                   4980:        XP_EQ(pause, ai.play.pause);
                   4981:        XP_EQ(11025, ai.record.sample_rate);
                   4982:        XP_EQ(pause, ai.record.pause);
1.1       isaki    4983:
                   4984:        r = CLOSE(fd);
                   4985:        XP_SYS_EQ(0, r);
                   4986: }
                   4987: #define f(a,b,c) test_AUDIO_SETINFO_params_set(a, b, c)
                   4988: DEF(AUDIO_SETINFO_params_set_RDONLY_0) { f(O_RDONLY, 0, 0); }
                   4989: DEF(AUDIO_SETINFO_params_set_RDONLY_1) { f(O_RDONLY, 0, 1); }
                   4990: /* On RDONLY, ai.mode is not changable
                   4991:  *  AUDIO_SETINFO_params_set_RDONLY_2) { f(O_RDONLY, 1, 0); }
                   4992:  *  AUDIO_SETINFO_params_set_RDONLY_3) { f(O_RDONLY, 1, 1); }
                   4993:  */
                   4994: DEF(AUDIO_SETINFO_params_set_WRONLY_0) { f(O_WRONLY, 0, 0); }
                   4995: DEF(AUDIO_SETINFO_params_set_WRONLY_1) { f(O_WRONLY, 0, 1); }
                   4996: DEF(AUDIO_SETINFO_params_set_WRONLY_2) { f(O_WRONLY, 1, 0); }
                   4997: DEF(AUDIO_SETINFO_params_set_WRONLY_3) { f(O_WRONLY, 1, 1); }
                   4998: DEF(AUDIO_SETINFO_params_set_RDWR_0)   { f(O_RDWR, 0, 0); }
                   4999: DEF(AUDIO_SETINFO_params_set_RDWR_1)   { f(O_RDWR, 0, 1); }
                   5000: DEF(AUDIO_SETINFO_params_set_RDWR_2)   { f(O_RDWR, 1, 0); }
                   5001: DEF(AUDIO_SETINFO_params_set_RDWR_3)   { f(O_RDWR, 1, 1); }
                   5002: #undef f
                   5003:
                   5004: /*
1.7       isaki    5005:  * AUDIO_SETINFO for existing track should not be interfered by other
                   5006:  * descriptor.
                   5007:  * AUDIO_SETINFO for non-existing track affects/is affected sticky parameters
                   5008:  * for backward compatibility.
1.1       isaki    5009:  */
                   5010: DEF(AUDIO_SETINFO_params_simul)
                   5011: {
                   5012:        struct audio_info ai;
                   5013:        int fd0;
                   5014:        int fd1;
                   5015:        int r;
                   5016:
                   5017:        TEST("AUDIO_SETINFO_params_simul");
                   5018:        if (netbsd < 8) {
                   5019:                XP_SKIP("Multiple open is not supported");
                   5020:                return;
                   5021:        }
1.7       isaki    5022:        if (hw_canplay() == 0) {
                   5023:                XP_SKIP("This test is for playable device");
                   5024:                return;
                   5025:        }
1.1       isaki    5026:
                   5027:        /* Open the 1st one as playback only */
                   5028:        fd0 = OPEN(devaudio, O_WRONLY);
                   5029:        REQUIRED_SYS_OK(fd0);
                   5030:
                   5031:        /* Open the 2nd one as both of playback and recording */
                   5032:        fd1 = OPEN(devaudio, O_RDWR);
                   5033:        REQUIRED_SYS_OK(fd1);
                   5034:
                   5035:        /* Change some parameters of both track on the 2nd one */
                   5036:        AUDIO_INITINFO(&ai);
                   5037:        ai.play.sample_rate = 11025;
                   5038:        ai.record.sample_rate = 11025;
                   5039:        r = IOCTL(fd1, AUDIO_SETINFO, &ai, "");
                   5040:        XP_SYS_EQ(0, r);
                   5041:
1.7       isaki    5042:        /*
                   5043:         * The 1st one doesn't have recording track so that only recording
                   5044:         * parameter is affected by sticky parameter.
                   5045:         */
1.1       isaki    5046:        memset(&ai, 0, sizeof(ai));
1.7       isaki    5047:        r = IOCTL(fd0, AUDIO_GETBUFINFO, &ai, "");
1.1       isaki    5048:        XP_SYS_EQ(0, r);
                   5049:        XP_EQ(8000, ai.play.sample_rate);
1.7       isaki    5050:        XP_EQ(11025, ai.record.sample_rate);
                   5051:
                   5052:        /* Next, change some parameters of both track on the 1st one */
                   5053:        AUDIO_INITINFO(&ai);
                   5054:        ai.play.sample_rate = 16000;
                   5055:        ai.record.sample_rate = 16000;
                   5056:        r = IOCTL(fd0, AUDIO_SETINFO, &ai, "");
                   5057:        XP_SYS_EQ(0, r);
                   5058:
                   5059:        /*
                   5060:         * On bi-directional device, the 2nd one has both track so that
                   5061:         * both track are not affected by sticky parameter.
                   5062:         * On uni-directional device, the 2nd one has only playback track
                   5063:         * so that playback track is not affected by sticky parameter.
                   5064:         */
                   5065:        memset(&ai, 0, sizeof(ai));
                   5066:        r = IOCTL(fd1, AUDIO_GETBUFINFO, &ai, "");
                   5067:        XP_SYS_EQ(0, r);
                   5068:        XP_EQ(11025, ai.play.sample_rate);
                   5069:        if (hw_bidir()) {
                   5070:                XP_EQ(11025, ai.record.sample_rate);
                   5071:        } else {
                   5072:                XP_EQ(16000, ai.record.sample_rate);
                   5073:        }
1.1       isaki    5074:
                   5075:        r = CLOSE(fd0);
                   5076:        XP_SYS_EQ(0, r);
                   5077:        r = CLOSE(fd1);
                   5078:        XP_SYS_EQ(0, r);
                   5079: }
                   5080:
                   5081: /*
1.5       isaki    5082:  * AUDIO_SETINFO(encoding/precision) is tested in AUDIO_GETENC_range below.
                   5083:  */
                   5084:
                   5085: /*
                   5086:  * Check whether the number of channels can be set.
                   5087:  */
                   5088: DEF(AUDIO_SETINFO_channels)
                   5089: {
1.6       isaki    5090:        struct audio_info hwinfo;
1.5       isaki    5091:        struct audio_info ai;
                   5092:        int mode;
                   5093:        int r;
                   5094:        int fd;
                   5095:        int i;
1.6       isaki    5096:        unsigned int ch;
1.5       isaki    5097:        struct {
                   5098:                int ch;
                   5099:                bool expected;
                   5100:        } table[] = {
                   5101:                {  0,   false },
                   5102:                {  1,   true }, /* monaural */
                   5103:                {  2,   true }, /* stereo */
                   5104:        };
                   5105:
                   5106:        TEST("AUDIO_SETINFO_channels");
                   5107:        if (netbsd < 8) {
                   5108:                /*
                   5109:                 * On NetBSD7, the result depends the hardware and there is
                   5110:                 * no way to know it.
                   5111:                 */
                   5112:                XP_SKIP("The test doesn't make sense on NetBSD7");
                   5113:                return;
                   5114:        }
                   5115:
                   5116:        mode = openable_mode();
                   5117:        fd = OPEN(devaudio, mode);
                   5118:        REQUIRED_SYS_OK(fd);
                   5119:
1.6       isaki    5120:        /*
                   5121:         * The audio layer always supports monaural and stereo regardless of
                   5122:         * the hardware capability.
                   5123:         */
1.5       isaki    5124:        for (i = 0; i < (int)__arraycount(table); i++) {
1.6       isaki    5125:                ch = table[i].ch;
1.5       isaki    5126:                bool expected = table[i].expected;
                   5127:
                   5128:                AUDIO_INITINFO(&ai);
                   5129:                if (mode != O_RDONLY)
                   5130:                        ai.play.channels = ch;
                   5131:                if (mode != O_WRONLY)
                   5132:                        ai.record.channels = ch;
                   5133:                r = IOCTL(fd, AUDIO_SETINFO, &ai, "channels=%d", ch);
                   5134:                if (expected) {
                   5135:                        /* Expects to succeed */
                   5136:                        XP_SYS_EQ(0, r);
                   5137:
                   5138:                        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   5139:                        XP_SYS_EQ(0, r);
                   5140:                        if (mode != O_RDONLY)
                   5141:                                XP_EQ(ch, ai.play.channels);
                   5142:                        if (mode != O_WRONLY)
                   5143:                                XP_EQ(ch, ai.record.channels);
                   5144:                } else {
                   5145:                        /* Expects to fail */
                   5146:                        XP_SYS_NG(EINVAL, r);
                   5147:                }
                   5148:        }
                   5149:
1.6       isaki    5150:        /*
                   5151:         * The maximum number of supported channels depends the hardware.
                   5152:         */
                   5153:        /* Get the number of channels that the hardware supports */
                   5154:        r = IOCTL(fd, AUDIO_GETFORMAT, &hwinfo, "");
                   5155:        REQUIRED_SYS_EQ(0, r);
                   5156:
                   5157:        if ((hwinfo.mode & AUMODE_PLAY)) {
                   5158:                DPRINTF("  > hwinfo.play.channels = %d\n",
                   5159:                    hwinfo.play.channels);
                   5160:                for (ch = 3; ch <= hwinfo.play.channels; ch++) {
                   5161:                        AUDIO_INITINFO(&ai);
                   5162:                        ai.play.channels = ch;
                   5163:                        r = IOCTL(fd, AUDIO_SETINFO, &ai, "channels=%d", ch);
                   5164:                        XP_SYS_EQ(0, r);
                   5165:
                   5166:                        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   5167:                        XP_SYS_EQ(0, r);
                   5168:                        XP_EQ(ch, ai.play.channels);
                   5169:                }
                   5170:
                   5171:                AUDIO_INITINFO(&ai);
                   5172:                ai.play.channels = ch;
                   5173:                r = IOCTL(fd, AUDIO_SETINFO, &ai, "channels=%d", ch);
                   5174:                XP_SYS_NG(EINVAL, r);
                   5175:        }
                   5176:        if ((hwinfo.mode & AUMODE_RECORD)) {
                   5177:                DPRINTF("  > hwinfo.record.channels = %d\n",
                   5178:                    hwinfo.record.channels);
                   5179:                for (ch = 3; ch <= hwinfo.record.channels; ch++) {
                   5180:                        AUDIO_INITINFO(&ai);
                   5181:                        ai.record.channels = ch;
                   5182:                        r = IOCTL(fd, AUDIO_SETINFO, &ai, "channels=%d", ch);
                   5183:                        XP_SYS_EQ(0, r);
                   5184:
                   5185:                        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   5186:                        XP_SYS_EQ(0, r);
                   5187:                        XP_EQ(ch, ai.record.channels);
                   5188:                }
                   5189:
                   5190:                AUDIO_INITINFO(&ai);
                   5191:                ai.record.channels = ch;
                   5192:                r = IOCTL(fd, AUDIO_SETINFO, &ai, "channels=%d", ch);
                   5193:                XP_SYS_NG(EINVAL, r);
                   5194:        }
                   5195:
1.5       isaki    5196:        r = CLOSE(fd);
                   5197:        XP_SYS_EQ(0, r);
                   5198: }
                   5199:
                   5200: /*
                   5201:  * Check whether the sample rate can be set.
                   5202:  */
                   5203: DEF(AUDIO_SETINFO_sample_rate)
                   5204: {
                   5205:        struct audio_info ai;
                   5206:        int mode;
                   5207:        int r;
                   5208:        int fd;
                   5209:        int i;
                   5210:        struct {
                   5211:                int freq;
                   5212:                bool expected;
                   5213:        } table[] = {
                   5214:                {    999,       false },
                   5215:                {   1000,       true }, /* lower limit */
                   5216:                {  48000,       true },
                   5217:                { 192000,       true }, /* upper limit */
                   5218:                { 192001,       false },
                   5219:        };
                   5220:
                   5221:        TEST("AUDIO_SETINFO_sample_rate");
                   5222:        if (netbsd < 8) {
                   5223:                /*
                   5224:                 * On NetBSD7, the result depends the hardware and there is
                   5225:                 * no way to know it.
                   5226:                 */
                   5227:                XP_SKIP("The test doesn't make sense on NetBSD7");
                   5228:                return;
                   5229:        }
                   5230:
                   5231:        mode = openable_mode();
                   5232:        fd = OPEN(devaudio, mode);
                   5233:        REQUIRED_SYS_OK(fd);
                   5234:
                   5235:        for (i = 0; i < (int)__arraycount(table); i++) {
                   5236:                int freq = table[i].freq;
                   5237:                bool expected = table[i].expected;
                   5238:
                   5239:                AUDIO_INITINFO(&ai);
                   5240:                if (mode != O_RDONLY)
                   5241:                        ai.play.sample_rate = freq;
                   5242:                if (mode != O_WRONLY)
                   5243:                        ai.record.sample_rate = freq;
                   5244:                r = IOCTL(fd, AUDIO_SETINFO, &ai, "sample_rate=%d", freq);
                   5245:                if (expected) {
                   5246:                        /* Expects to succeed */
                   5247:                        XP_SYS_EQ(0, r);
                   5248:
                   5249:                        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   5250:                        XP_SYS_EQ(0, r);
                   5251:                        if (mode != O_RDONLY)
                   5252:                                XP_EQ(freq, ai.play.sample_rate);
                   5253:                        if (mode != O_WRONLY)
                   5254:                                XP_EQ(freq, ai.record.sample_rate);
                   5255:                } else {
                   5256:                        /* Expects to fail */
                   5257:                        XP_SYS_NG(EINVAL, r);
                   5258:                }
                   5259:        }
                   5260:
                   5261:        r = CLOSE(fd);
                   5262:        XP_SYS_EQ(0, r);
                   5263: }
                   5264:
                   5265: /*
                   5266:  * SETINFO(sample_rate = 0) should fail correctly.
                   5267:  */
                   5268: DEF(AUDIO_SETINFO_sample_rate_0)
                   5269: {
                   5270:        struct audio_info ai;
                   5271:        int mode;
                   5272:        int r;
                   5273:        int fd;
                   5274:
                   5275:        TEST("AUDIO_SETINFO_sample_rate_0");
                   5276:        if (netbsd < 9) {
                   5277:                /*
                   5278:                 * On NetBSD7,8 this will block system call and you will not
                   5279:                 * even be able to shutdown...
                   5280:                 */
                   5281:                XP_SKIP("This will cause an infinate loop in the kernel");
                   5282:                return;
                   5283:        }
                   5284:
                   5285:        mode = openable_mode();
                   5286:        fd = OPEN(devaudio, mode);
                   5287:        REQUIRED_SYS_OK(fd);
                   5288:
                   5289:        AUDIO_INITINFO(&ai);
                   5290:        ai.play.sample_rate = 0;
                   5291:        ai.record.sample_rate = 0;
                   5292:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "sample_rate=0");
                   5293:        /* Expects to fail */
                   5294:        XP_SYS_NG(EINVAL, r);
                   5295:
                   5296:        r = CLOSE(fd);
                   5297:        XP_SYS_EQ(0, r);
                   5298: }
                   5299:
                   5300: /*
1.1       isaki    5301:  * Check whether the pause/unpause works.
                   5302:  */
                   5303: void
                   5304: test_AUDIO_SETINFO_pause(int openmode, int aimode, int param)
                   5305: {
                   5306:        struct audio_info ai;
                   5307:        int r;
                   5308:        int fd;
                   5309:
                   5310:        /*
                   5311:         * aimode is bool value that indicates whether to change ai.mode.
                   5312:         * param is bool value that indicates whether to change encoding
                   5313:         * parameters of ai.{play,record}.*.
                   5314:         */
                   5315:
                   5316:        TEST("AUDIO_SETINFO_pause_%s_%d_%d",
                   5317:            openmode_str[openmode] + 2, aimode, param);
                   5318:        if (mode2aumode(openmode) == 0) {
                   5319:                XP_SKIP("Operation not allowed on this hardware property");
                   5320:                return;
                   5321:        }
                   5322:
                   5323:        /* On half-duplex, O_RDWR is the same as O_WRONLY, so skip it */
                   5324:        if (!hw_fulldup() && openmode == O_RDWR) {
                   5325:                XP_SKIP("This is the same with O_WRONLY on half-duplex");
                   5326:                return;
                   5327:        }
                   5328:
                   5329:        fd = OPEN(devaudio, openmode);
                   5330:        REQUIRED_SYS_OK(fd);
                   5331:
                   5332:        /* Set pause */
                   5333:        AUDIO_INITINFO(&ai);
                   5334:        ai.play.pause = 1;
                   5335:        ai.record.pause = 1;
                   5336:        if (aimode)
                   5337:                ai.mode = mode2aumode(openmode) & ~AUMODE_PLAY_ALL;
                   5338:        if (param) {
                   5339:                ai.play.sample_rate = 11025;
                   5340:                ai.record.sample_rate = 11025;
                   5341:        }
                   5342:
                   5343:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "");
                   5344:        XP_SYS_EQ(0, r);
                   5345:
                   5346:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   5347:        XP_SYS_EQ(0, r);
                   5348:        int expmode = (aimode)
                   5349:            ? (mode2aumode(openmode) & ~AUMODE_PLAY_ALL)
                   5350:            : mode2aumode(openmode);
                   5351:        XP_EQ(expmode, ai.mode);
1.7       isaki    5352:        XP_EQ(1, ai.play.pause);
                   5353:        XP_EQ(param ? 11025 : 8000, ai.play.sample_rate);
                   5354:        XP_EQ(1, ai.record.pause);
                   5355:        XP_EQ(param ? 11025 : 8000, ai.record.sample_rate);
1.1       isaki    5356:
                   5357:        /* Set unpause (?) */
                   5358:        AUDIO_INITINFO(&ai);
                   5359:        ai.play.pause = 0;
                   5360:        ai.record.pause = 0;
                   5361:        if (aimode)
                   5362:                ai.mode = mode2aumode(openmode);
                   5363:        if (param) {
                   5364:                ai.play.sample_rate = 16000;
                   5365:                ai.record.sample_rate = 16000;
                   5366:        }
                   5367:
                   5368:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "");
                   5369:        XP_SYS_EQ(0, r);
                   5370:
                   5371:        r = IOCTL(fd, AUDIO_GETBUFINFO, &ai, "");
                   5372:        XP_SYS_EQ(0, r);
                   5373:        XP_EQ(mode2aumode(openmode), ai.mode);
                   5374:        XP_EQ(0, ai.play.pause);
                   5375:        XP_EQ(0, ai.record.pause);
                   5376:        if (openmode != O_RDONLY)
                   5377:                XP_EQ(param ? 16000 : 8000, ai.play.sample_rate);
                   5378:        if (openmode != O_WRONLY)
                   5379:                XP_EQ(param ? 16000 : 8000, ai.record.sample_rate);
                   5380:
                   5381:        r = CLOSE(fd);
                   5382:        XP_SYS_EQ(0, r);
                   5383: }
                   5384: DEF(AUDIO_SETINFO_pause_RDONLY_0) { test_AUDIO_SETINFO_pause(O_RDONLY, 0, 0); }
                   5385: DEF(AUDIO_SETINFO_pause_RDONLY_1) { test_AUDIO_SETINFO_pause(O_RDONLY, 0, 1); }
                   5386: /* On RDONLY, ai.mode is not changable
                   5387:  *  AUDIO_SETINFO_pause_RDONLY_2) { test_AUDIO_SETINFO_pause(O_RDONLY, 1, 0); }
                   5388:  *  AUDIO_SETINFO_pause_RDONLY_3) { test_AUDIO_SETINFO_pause(O_RDONLY, 1, 1); }
                   5389:  */
                   5390: DEF(AUDIO_SETINFO_pause_WRONLY_0) { test_AUDIO_SETINFO_pause(O_WRONLY, 0, 0); }
                   5391: DEF(AUDIO_SETINFO_pause_WRONLY_1) { test_AUDIO_SETINFO_pause(O_WRONLY, 0, 1); }
                   5392: DEF(AUDIO_SETINFO_pause_WRONLY_2) { test_AUDIO_SETINFO_pause(O_WRONLY, 1, 0); }
                   5393: DEF(AUDIO_SETINFO_pause_WRONLY_3) { test_AUDIO_SETINFO_pause(O_WRONLY, 1, 1); }
                   5394: DEF(AUDIO_SETINFO_pause_RDWR_0)   { test_AUDIO_SETINFO_pause(O_RDWR, 0, 0); }
                   5395: DEF(AUDIO_SETINFO_pause_RDWR_1)   { test_AUDIO_SETINFO_pause(O_RDWR, 0, 1); }
                   5396: DEF(AUDIO_SETINFO_pause_RDWR_2)   { test_AUDIO_SETINFO_pause(O_RDWR, 1, 0); }
                   5397: DEF(AUDIO_SETINFO_pause_RDWR_3)   { test_AUDIO_SETINFO_pause(O_RDWR, 1, 1); }
                   5398:
                   5399: /*
                   5400:  * Check whether gain can be obtained/set.
                   5401:  * And the gain should work with rich mixer.
                   5402:  * PR kern/52781
                   5403:  */
                   5404: DEF(AUDIO_SETINFO_gain)
                   5405: {
                   5406:        struct audio_info ai;
                   5407:        mixer_ctrl_t m;
                   5408:        int index;
                   5409:        int master;
                   5410:        int master_backup;
                   5411:        int gain;
                   5412:        int fd;
                   5413:        int mixerfd;
                   5414:        int r;
                   5415:
                   5416:        TEST("AUDIO_SETINFO_gain");
                   5417:
                   5418:        /* Open /dev/mixer */
                   5419:        mixerfd = OPEN(devmixer, O_RDWR);
                   5420:        REQUIRED_SYS_OK(mixerfd);
                   5421:        index = mixer_get_outputs_master(mixerfd);
                   5422:        if (index == -1) {
                   5423:                XP_SKIP("Hardware has no outputs.master");
                   5424:                CLOSE(mixerfd);
                   5425:                return;
                   5426:        }
                   5427:
                   5428:        /*
                   5429:         * Get current outputs.master.
                   5430:         * auich(4) requires class type (m.type) and number of channels
                   5431:         * (un.value.num_channels) in addition to the index (m.dev)...
                   5432:         * What is the index...?
                   5433:         */
                   5434:        memset(&m, 0, sizeof(m));
                   5435:        m.dev = index;
                   5436:        m.type = AUDIO_MIXER_VALUE;
                   5437:        m.un.value.num_channels = 1; /* dummy */
                   5438:        r = IOCTL(mixerfd, AUDIO_MIXER_READ, &m, "m.dev=%d", m.dev);
                   5439:        REQUIRED_SYS_EQ(0, r);
                   5440:        master = m.un.value.level[0];
                   5441:        DPRINTF("  > outputs.master = %d\n", master);
                   5442:        master_backup = master;
                   5443:
                   5444:        /* Open /dev/audio */
                   5445:        fd = OPEN(devaudio, O_WRONLY);
                   5446:        REQUIRED_SYS_OK(fd);
                   5447:
                   5448:        /* Check ai.play.gain */
                   5449:        r = IOCTL(fd, AUDIO_GETINFO, &ai, "");
                   5450:        XP_SYS_EQ(0, r);
                   5451:        XP_EQ(master, ai.play.gain);
                   5452:
                   5453:        /* Change it some different value */
                   5454:        AUDIO_INITINFO(&ai);
                   5455:        if (master == 0)
                   5456:                gain = 255;
                   5457:        else
                   5458:                gain = 0;
                   5459:        ai.play.gain = gain;
                   5460:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "play.gain=%d", ai.play.gain);
                   5461:        XP_SYS_EQ(0, r);
                   5462:
                   5463:        /* Check gain has changed */
                   5464:        r = IOCTL(fd, AUDIO_GETINFO, &ai, "play.gain");
                   5465:        XP_SYS_EQ(0, r);
                   5466:        XP_NE(master, ai.play.gain);
                   5467:
                   5468:        /* Check whether outputs.master work with gain */
                   5469:        r = IOCTL(mixerfd, AUDIO_MIXER_READ, &m, "");
                   5470:        XP_SYS_EQ(0, r);
                   5471:        XP_EQ(ai.play.gain, m.un.value.level[0]);
                   5472:
                   5473:        /* Restore outputs.master */
                   5474:        AUDIO_INITINFO(&ai);
                   5475:        ai.play.gain = master_backup;
                   5476:        r = IOCTL(fd, AUDIO_SETINFO, &ai, "play.gain=%d", ai.play.gain);
                   5477:        XP_SYS_EQ(0, r);
                   5478:
                   5479:        r = CLOSE(fd);
                   5480:        XP_SYS_EQ(0, r);
                   5481:        r = CLOSE(mixerfd);
                   5482:        XP_SYS_EQ(0, r);
                   5483: }
                   5484:
                   5485: #define NENC   (AUDIO_ENCODING_AC3 + 1)
                   5486: #define NPREC  (5)
                   5487: /*
                   5488:  * Make table of encoding+precision supported by this device.
                   5489:  * Return last used index .
                   5490:  * This function is called from test_AUDIO_GETENC_*()
                   5491:  */
                   5492: int
                   5493: getenc_make_table(int fd, int expected[][5])
                   5494: {
                   5495:        audio_encoding_t ae;
                   5496:        int idx;
                   5497:        int p;
                   5498:        int r;
                   5499:
                   5500:        /*
                   5501:         * expected[][] is two dimensional table.
                   5502:         * encoding \ precision| 4  8  16  24  32
                   5503:         * --------------------+-----------------
                   5504:         * AUDIO_ENCODING_NONE |
                   5505:         * AUDIO_ENCODING_ULAW |
                   5506:         *  :
                   5507:         *
                   5508:         * Each cell has expected behavior.
                   5509:         *  0: the hardware doesn't support this encoding/precision.
                   5510:         *  1: the hardware supports this encoding/precision.
                   5511:         *  2: the hardware doesn't support this encoding/precision but
                   5512:         *     audio layer will respond as supported for compatibility.
                   5513:         */
                   5514:        for (idx = 0; ; idx++) {
                   5515:                memset(&ae, 0, sizeof(ae));
                   5516:                ae.index = idx;
                   5517:                r = IOCTL(fd, AUDIO_GETENC, &ae, "index=%d", idx);
                   5518:                if (r != 0) {
                   5519:                        XP_SYS_NG(EINVAL, r);
                   5520:                        break;
                   5521:                }
                   5522:
                   5523:                XP_EQ(idx, ae.index);
                   5524:                if (0 <= ae.encoding && ae.encoding <= AUDIO_ENCODING_AC3) {
                   5525:                        XP_EQ_STR(encoding_names[ae.encoding], ae.name);
                   5526:                } else {
                   5527:                        XP_FAIL("ae.encoding %d", ae.encoding);
                   5528:                }
                   5529:
                   5530:                if (ae.precision != 4 &&
                   5531:                    ae.precision != 8 &&
                   5532:                    ae.precision != 16 &&
                   5533:                    ae.precision != 24 &&
                   5534:                    ae.precision != 32)
                   5535:                {
                   5536:                        XP_FAIL("ae.precision %d", ae.precision);
                   5537:                }
                   5538:                /* Other bits should not be set */
                   5539:                XP_EQ(0, (ae.flags & ~AUDIO_ENCODINGFLAG_EMULATED));
                   5540:
                   5541:                expected[ae.encoding][ae.precision / 8] = 1;
                   5542:                DPRINTF("  > encoding=%s precision=%d\n",
                   5543:                    encoding_names[ae.encoding], ae.precision);
                   5544:        }
                   5545:
                   5546:        /*
                   5547:         * Backward compatibility bandaid.
                   5548:         *
                   5549:         * - Some encoding/precision pairs are obviously inconsistent
                   5550:         *   (e.g., encoding=AUDIO_ENCODING_PCM8, precision=16) but
                   5551:         *   it's due to historical reasons.
                   5552:         * - It's incomplete for NetBSD7 and NetBSD8.  I don't really
                   5553:         *   understand thier rule...  This is just memo, not specification.
                   5554:         */
                   5555: #define SET(x) do {    \
                   5556:        if ((x) == 0)   \
                   5557:                x = 2;  \
                   5558:  } while (0)
                   5559: #define p4 (0)
                   5560: #define p8 (1)
                   5561: #define p16 (2)
                   5562: #define p24 (3)
                   5563: #define p32 (4)
                   5564:
                   5565:        if (expected[AUDIO_ENCODING_SLINEAR][p8]) {
                   5566:                SET(expected[AUDIO_ENCODING_SLINEAR_LE][p8]);
                   5567:                SET(expected[AUDIO_ENCODING_SLINEAR_BE][p8]);
                   5568:        }
                   5569:        if (expected[AUDIO_ENCODING_ULINEAR][p8]) {
                   5570:                SET(expected[AUDIO_ENCODING_ULINEAR_LE][p8]);
                   5571:                SET(expected[AUDIO_ENCODING_ULINEAR_BE][p8]);
                   5572:                SET(expected[AUDIO_ENCODING_PCM8][p8]);
                   5573:                SET(expected[AUDIO_ENCODING_PCM16][p8]);
                   5574:        }
                   5575:        for (p = p16; p <= p32; p++) {
                   5576: #if !defined(AUDIO_SUPPORT_LINEAR24)
                   5577:                if (p == p24)
                   5578:                        continue;
                   5579: #endif
                   5580:                if (expected[AUDIO_ENCODING_SLINEAR_NE][p]) {
                   5581:                        SET(expected[AUDIO_ENCODING_SLINEAR][p]);
                   5582:                        SET(expected[AUDIO_ENCODING_PCM16][p]);
                   5583:                }
                   5584:                if (expected[AUDIO_ENCODING_ULINEAR_NE][p]) {
                   5585:                        SET(expected[AUDIO_ENCODING_ULINEAR][p]);
                   5586:                }
                   5587:        }
                   5588:
                   5589:        if (netbsd < 9) {
                   5590:                if (expected[AUDIO_ENCODING_SLINEAR_LE][p16] ||
                   5591:                    expected[AUDIO_ENCODING_SLINEAR_BE][p16] ||
                   5592:                    expected[AUDIO_ENCODING_ULINEAR_LE][p16] ||
                   5593:                    expected[AUDIO_ENCODING_ULINEAR_BE][p16])
                   5594:                {
                   5595:                        SET(expected[AUDIO_ENCODING_PCM8][p8]);
                   5596:                        SET(expected[AUDIO_ENCODING_PCM16][p8]);
                   5597:                        SET(expected[AUDIO_ENCODING_SLINEAR_LE][p8]);
                   5598:                        SET(expected[AUDIO_ENCODING_SLINEAR_BE][p8]);
                   5599:                        SET(expected[AUDIO_ENCODING_ULINEAR_LE][p8]);
                   5600:                        SET(expected[AUDIO_ENCODING_ULINEAR_BE][p8]);
                   5601:                        SET(expected[AUDIO_ENCODING_SLINEAR][p8]);
                   5602:                        SET(expected[AUDIO_ENCODING_ULINEAR][p8]);
                   5603:                }
                   5604:        }
                   5605:
                   5606:        /* Return last used index */
                   5607:        return idx;
                   5608: #undef SET
                   5609: #undef p4
                   5610: #undef p8
                   5611: #undef p16
                   5612: #undef p24
                   5613: #undef p32
                   5614: }
                   5615:
                   5616: /*
                   5617:  * This function is called from test_AUDIO_GETENC below.
                   5618:  */
                   5619: void
                   5620: xp_getenc(int expected[][5], int enc, int j, int r, struct audio_prinfo *pr)
                   5621: {
                   5622:        int prec = (j == 0) ? 4 : j * 8;
                   5623:
                   5624:        if (expected[enc][j]) {
                   5625:                /* expect to succeed */
                   5626:                XP_SYS_EQ(0, r);
                   5627:
                   5628:                XP_EQ(enc, pr->encoding);
                   5629:                XP_EQ(prec, pr->precision);
                   5630:        } else {
                   5631:                /* expect to fail */
                   5632:                XP_SYS_NG(EINVAL, r);
                   5633:        }
                   5634: }
                   5635:
                   5636: /*
                   5637:  * This function is called from test_AUDIO_GETENC below.
                   5638:  */
                   5639: void
                   5640: getenc_check_encodings(int openmode, int expected[][5])
                   5641: {
                   5642:        struct audio_info ai;
                   5643:        int fd;
                   5644:        int i, j;
                   5645:        int r;
                   5646:
                   5647:        fd = OPEN(devaudio, openmode);
                   5648:        REQUIRED_SYS_OK(fd);
                   5649:
                   5650:        for (i = 0; i < NENC; i++) {
                   5651:                for (j = 0; j < NPREC; j++) {
                   5652:                        /* precisions are 4 and 8, 16, 24, 32 */
                   5653:                        int prec = (j == 0) ? 4 : j * 8;
                   5654:
                   5655:                        /*
                   5656:                         * AUDIO_GETENC has no way to know range of
                   5657:                         * supported channels and sample_rate.
                   5658:                         */
                   5659:                        AUDIO_INITINFO(&ai);
                   5660:                        ai.play.encoding = i;
                   5661:                        ai.play.precision = prec;
                   5662:                        ai.record.encoding = i;
                   5663:                        ai.record.precision = prec;
                   5664:
                   5665:                        r = IOCTL(fd, AUDIO_SETINFO, &ai, "%s:%d",
                   5666:                            encoding_names[i], prec);
                   5667:                        if (mode2play(openmode))
                   5668:                                xp_getenc(expected, i, j, r, &ai.play);
                   5669:                        if (mode2rec(openmode))
                   5670:                                xp_getenc(expected, i, j, r, &ai.record);
                   5671:                }
                   5672:        }
                   5673:        r = CLOSE(fd);
                   5674:        XP_SYS_EQ(0, r);
                   5675: }
                   5676:
                   5677: /*
                   5678:  * Check whether encoding+precision obtained by AUDIO_GETENC can be set.
                   5679:  */
                   5680: DEF(AUDIO_GETENC_range)
                   5681: {
                   5682:        audio_encoding_t ae;
                   5683:        int fd;
                   5684:        int r;
                   5685:        int expected[NENC][NPREC];
                   5686:        int i, j;
                   5687:
                   5688:        TEST("AUDIO_GETENC_range");
                   5689:
                   5690:        fd = OPEN(devaudio, openable_mode());
                   5691:        REQUIRED_SYS_OK(fd);
                   5692:
                   5693:        memset(&expected, 0, sizeof(expected));
                   5694:        i = getenc_make_table(fd, expected);
                   5695:
                   5696:        /* When error has occured, the next index should also occur error */
                   5697:        ae.index = i + 1;
                   5698:        r = IOCTL(fd, AUDIO_GETENC, &ae, "index=%d", ae.index);
                   5699:        XP_SYS_NG(EINVAL, r);
                   5700:
                   5701:        r = CLOSE(fd);
                   5702:        XP_SYS_EQ(0, r);
                   5703:
                   5704:        /* For debug */
                   5705:        if (debug) {
                   5706:                for (i = 0; i < NENC; i++) {
                   5707:                        printf("expected[%2d] %15s", i, encoding_names[i]);
                   5708:                        for (j = 0; j < NPREC; j++) {
                   5709:                                printf(" %d", expected[i][j]);
                   5710:                        }
                   5711:                        printf("\n");
                   5712:                }
                   5713:        }
                   5714:
                   5715:        /* Whether obtained encodings can be actually set */
                   5716:        if (hw_fulldup()) {
                   5717:                /* Test both R/W at once using single descriptor */
                   5718:                getenc_check_encodings(O_RDWR, expected);
                   5719:        } else {
                   5720:                /* Test playback and recording if available */
                   5721:                if (hw_canplay()) {
                   5722:                        getenc_check_encodings(O_WRONLY, expected);
                   5723:                }
                   5724:                if (hw_canplay() && hw_canrec()) {
                   5725:                        xxx_close_wait();
                   5726:                }
                   5727:                if (hw_canrec()) {
                   5728:                        getenc_check_encodings(O_RDONLY, expected);
                   5729:                }
                   5730:        }
                   5731: }
                   5732: #undef NENC
                   5733: #undef NPREC
                   5734:
                   5735: /*
                   5736:  * Check AUDIO_GETENC out of range.
                   5737:  */
                   5738: DEF(AUDIO_GETENC_error)
                   5739: {
                   5740:        audio_encoding_t e;
                   5741:        int fd;
                   5742:        int r;
                   5743:
                   5744:        TEST("AUDIO_GETENC_error");
                   5745:
                   5746:        fd = OPEN(devaudio, openable_mode());
                   5747:        REQUIRED_SYS_OK(fd);
                   5748:
                   5749:        memset(&e, 0, sizeof(e));
                   5750:        e.index = -1;
                   5751:        r = IOCTL(fd, AUDIO_GETENC, &e, "index=-1");
                   5752:        /* NetBSD7 may not fail depending on hardware driver */
                   5753:        XP_SYS_NG(EINVAL, r);
                   5754:
                   5755:        r = CLOSE(fd);
                   5756:        XP_SYS_EQ(0, r);
                   5757: }
                   5758:
                   5759: /*
                   5760:  * AUDIO_[PR]ERROR should be zero on the initial state even on non-existent
                   5761:  * track.
                   5762:  */
                   5763: void
                   5764: test_AUDIO_ERROR(int openmode)
                   5765: {
                   5766:        int fd;
                   5767:        int r;
                   5768:        int errors;
                   5769:
                   5770:        TEST("AUDIO_ERROR_%s", openmode_str[openmode] + 2);
                   5771:        if (mode2aumode(openmode) == 0) {
                   5772:                XP_SKIP("Operation not allowed on this hardware property");
                   5773:                return;
                   5774:        }
                   5775:
                   5776:        fd = OPEN(devaudio, openmode);
                   5777:        REQUIRED_SYS_OK(fd);
                   5778:
                   5779:        /* Check PERROR */
                   5780:        errors = 0xdeadbeef;
                   5781:        r = IOCTL(fd, AUDIO_PERROR, &errors, "");
                   5782:        XP_SYS_EQ(0, r);
                   5783:        XP_EQ(0, errors);
                   5784:
                   5785:        /* Check RERROR */
                   5786:        errors = 0xdeadbeef;
                   5787:        r = IOCTL(fd, AUDIO_RERROR, &errors, "");
                   5788:        XP_SYS_EQ(0, r);
                   5789:        XP_EQ(0, errors);
                   5790:
                   5791:        r = CLOSE(fd);
                   5792:        XP_SYS_EQ(0, r);
                   5793: }
                   5794: DEF(AUDIO_ERROR_RDONLY)        { test_AUDIO_ERROR(O_RDONLY); }
                   5795: DEF(AUDIO_ERROR_WRONLY)        { test_AUDIO_ERROR(O_WRONLY); }
                   5796: DEF(AUDIO_ERROR_RDWR)  { test_AUDIO_ERROR(O_RDWR); }
                   5797:
                   5798: /*
                   5799:  * /dev/audioctl can always be opened while /dev/audio is open.
                   5800:  */
                   5801: void
                   5802: test_audioctl_open_1(int fmode, int cmode)
                   5803: {
                   5804:        int fd;
                   5805:        int ctl;
                   5806:        int r;
                   5807:
                   5808:        TEST("audioctl_open_1_%s_%s",
                   5809:            openmode_str[fmode] + 2, openmode_str[cmode] + 2);
                   5810:        if (hw_canplay() == 0 && fmode == O_WRONLY) {
                   5811:                XP_SKIP("This test is for playable device");
                   5812:                return;
                   5813:        }
                   5814:        if (hw_canrec() == 0 && fmode == O_RDONLY) {
                   5815:                XP_SKIP("This test is for recordable device");
                   5816:                return;
                   5817:        }
                   5818:
                   5819:        fd = OPEN(devaudio, fmode);
                   5820:        REQUIRED_SYS_OK(fd);
                   5821:
                   5822:        ctl = OPEN(devaudioctl, cmode);
                   5823:        XP_SYS_OK(ctl);
                   5824:
                   5825:        r = CLOSE(ctl);
                   5826:        XP_SYS_EQ(0, r);
                   5827:
                   5828:        r = CLOSE(fd);
                   5829:        XP_SYS_EQ(0, r);
                   5830: }
                   5831: DEF(audioctl_open_1_RDONLY_RDONLY) { test_audioctl_open_1(O_RDONLY, O_RDONLY); }
                   5832: DEF(audioctl_open_1_RDONLY_RWONLY) { test_audioctl_open_1(O_RDONLY, O_WRONLY); }
                   5833: DEF(audioctl_open_1_RDONLY_RDWR)   { test_audioctl_open_1(O_RDONLY, O_RDWR); }
                   5834: DEF(audioctl_open_1_WRONLY_RDONLY) { test_audioctl_open_1(O_WRONLY, O_RDONLY); }
                   5835: DEF(audioctl_open_1_WRONLY_RWONLY) { test_audioctl_open_1(O_WRONLY, O_WRONLY); }
                   5836: DEF(audioctl_open_1_WRONLY_RDWR)   { test_audioctl_open_1(O_WRONLY, O_RDWR); }
                   5837: DEF(audioctl_open_1_RDWR_RDONLY)   { test_audioctl_open_1(O_RDWR, O_RDONLY); }
                   5838: DEF(audioctl_open_1_RDWR_RWONLY)   { test_audioctl_open_1(O_RDWR, O_WRONLY); }
                   5839: DEF(audioctl_open_1_RDWR_RDWR)     { test_audioctl_open_1(O_RDWR, O_RDWR); }
                   5840:
                   5841: /*
                   5842:  * /dev/audio can always be opened while /dev/audioctl is open.
                   5843:  */
                   5844: void
                   5845: test_audioctl_open_2(int fmode, int cmode)
                   5846: {
                   5847:        int fd;
                   5848:        int ctl;
                   5849:        int r;
                   5850:
                   5851:        TEST("audioctl_open_2_%s_%s",
                   5852:            openmode_str[fmode] + 2, openmode_str[cmode] + 2);
                   5853:        if (hw_canplay() == 0 && fmode == O_WRONLY) {
                   5854:                XP_SKIP("This test is for playable device");
                   5855:                return;
                   5856:        }
                   5857:        if (hw_canrec() == 0 && fmode == O_RDONLY) {
                   5858:                XP_SKIP("This test is for recordable device");
                   5859:                return;
                   5860:        }
                   5861:
                   5862:        ctl = OPEN(devaudioctl, cmode);
                   5863:        REQUIRED_SYS_OK(ctl);
                   5864:
                   5865:        fd = OPEN(devaudio, fmode);
                   5866:        XP_SYS_OK(fd);
                   5867:
                   5868:        r = CLOSE(fd);
                   5869:        XP_SYS_EQ(0, r);
                   5870:
                   5871:        r = CLOSE(ctl);
                   5872:        XP_SYS_EQ(0, r);
                   5873: }
                   5874: DEF(audioctl_open_2_RDONLY_RDONLY) { test_audioctl_open_2(O_RDONLY, O_RDONLY); }
                   5875: DEF(audioctl_open_2_RDONLY_RWONLY) { test_audioctl_open_2(O_RDONLY, O_WRONLY); }
                   5876: DEF(audioctl_open_2_RDONLY_RDWR)   { test_audioctl_open_2(O_RDONLY, O_RDWR); }
                   5877: DEF(audioctl_open_2_WRONLY_RDONLY) { test_audioctl_open_2(O_WRONLY, O_RDONLY); }
                   5878: DEF(audioctl_open_2_WRONLY_RWONLY) { test_audioctl_open_2(O_WRONLY, O_WRONLY); }
                   5879: DEF(audioctl_open_2_WRONLY_RDWR)   { test_audioctl_open_2(O_WRONLY, O_RDWR); }
                   5880: DEF(audioctl_open_2_RDWR_RDONLY)   { test_audioctl_open_2(O_RDWR, O_RDONLY); }
                   5881: DEF(audioctl_open_2_RDWR_RWONLY)   { test_audioctl_open_2(O_RDWR, O_WRONLY); }
                   5882: DEF(audioctl_open_2_RDWR_RDWR)     { test_audioctl_open_2(O_RDWR, O_RDWR); }
                   5883:
                   5884: /*
                   5885:  * Open multiple /dev/audioctl.
                   5886:  */
                   5887: DEF(audioctl_open_simul)
                   5888: {
                   5889:        int ctl0;
                   5890:        int ctl1;
                   5891:        int r;
                   5892:
                   5893:        TEST("audioctl_open_simul");
                   5894:
                   5895:        ctl0 = OPEN(devaudioctl, O_RDWR);
                   5896:        REQUIRED_SYS_OK(ctl0);
                   5897:
                   5898:        ctl1 = OPEN(devaudioctl, O_RDWR);
                   5899:        XP_SYS_OK(ctl1);
                   5900:
                   5901:        r = CLOSE(ctl0);
                   5902:        XP_SYS_EQ(0, r);
                   5903:
                   5904:        r = CLOSE(ctl1);
                   5905:        XP_SYS_EQ(0, r);
                   5906: }
                   5907:
                   5908: /*
1.4       isaki    5909:  * /dev/audioctl can be opened by other user who opens /dev/audioctl,
                   5910:  * /dev/audioctl can be opened by other user who opens /dev/audio,
                   5911:  * /dev/audio    can be opened by other user who opens /dev/audioctl,
                   5912:  * regardless of multiuser mode.
1.1       isaki    5913:  */
                   5914: void
1.4       isaki    5915: try_audioctl_open_multiuser(const char *dev1, const char *dev2)
1.1       isaki    5916: {
                   5917:        int fd1;
                   5918:        int fd2;
                   5919:        int r;
                   5920:        uid_t ouid;
                   5921:
                   5922:        /*
                   5923:         * At first, open dev1 as root.
                   5924:         * And then open dev2 as unprivileged user.
                   5925:         */
                   5926:
                   5927:        fd1 = OPEN(dev1, O_RDWR);
                   5928:        REQUIRED_SYS_OK(fd1);
                   5929:
                   5930:        ouid = GETUID();
                   5931:        r = SETEUID(1);
                   5932:        REQUIRED_SYS_EQ(0, r);
                   5933:
                   5934:        fd2 = OPEN(dev2, O_RDWR);
                   5935:        XP_SYS_OK(fd2);
                   5936:
                   5937:        /* Close */
                   5938:        r = CLOSE(fd2);
                   5939:        XP_SYS_EQ(0, r);
                   5940:
                   5941:        r = SETEUID(ouid);
                   5942:        REQUIRED_SYS_EQ(0, r);
                   5943:
                   5944:        r = CLOSE(fd1);
                   5945:        XP_SYS_EQ(0, r);
                   5946: }
                   5947: /*
                   5948:  * This is a wrapper for audioctl_open_multiuser.
                   5949:  * XXX XP_* macros are not compatible with on-error-goto, we need try-catch...
                   5950:  */
                   5951: void
1.4       isaki    5952: test_audioctl_open_multiuser(bool multiuser,
                   5953:        const char *dev1, const char *dev2)
1.1       isaki    5954: {
                   5955:        char mibname[32];
                   5956:        bool oldval;
                   5957:        size_t oldlen;
                   5958:        int r;
                   5959:
                   5960:        if (netbsd < 8 && multiuser == 1) {
                   5961:                XP_SKIP("multiuser is not supported");
                   5962:                return;
                   5963:        }
                   5964:        if (netbsd < 9) {
                   5965:                /* NetBSD8 has no way (difficult) to determine device name */
                   5966:                XP_SKIP("NetBSD8 cannot determine device name");
                   5967:                return;
                   5968:        }
                   5969:        if (geteuid() != 0) {
                   5970:                XP_SKIP("This test must be priviledged user");
                   5971:                return;
                   5972:        }
                   5973:
                   5974:        /* Get current multiuser mode (and save it) */
                   5975:        snprintf(mibname, sizeof(mibname), "hw.%s.multiuser", devicename);
                   5976:        oldlen = sizeof(oldval);
                   5977:        r = SYSCTLBYNAME(mibname, &oldval, &oldlen, NULL, 0);
                   5978:        REQUIRED_SYS_EQ(0, r);
                   5979:        DPRINTF("  > multiuser=%d\n", oldval);
                   5980:
                   5981:        /* Change if necessary */
                   5982:        if (oldval != multiuser) {
1.4       isaki    5983:                r = SYSCTLBYNAME(mibname, NULL, NULL, &multiuser,
                   5984:                    sizeof(multiuser));
1.1       isaki    5985:                REQUIRED_SYS_EQ(0, r);
                   5986:                DPRINTF("  > new multiuser=%d\n", multiuser);
                   5987:        }
                   5988:
                   5989:        /* Do test */
1.4       isaki    5990:        try_audioctl_open_multiuser(dev1, dev2);
1.1       isaki    5991:
                   5992:        /* Restore multiuser mode */
1.4       isaki    5993:        if (oldval != multiuser) {
1.1       isaki    5994:                DPRINTF("  > restore multiuser to %d\n", oldval);
                   5995:                r = SYSCTLBYNAME(mibname, NULL, NULL, &oldval, sizeof(oldval));
                   5996:                XP_SYS_EQ(0, r);
                   5997:        }
                   5998: }
                   5999: DEF(audioctl_open_multiuser0_audio1) {
                   6000:        TEST("audioctl_open_multiuser0_audio1");
1.4       isaki    6001:        test_audioctl_open_multiuser(false, devaudio, devaudioctl);
1.1       isaki    6002: }
                   6003: DEF(audioctl_open_multiuser1_audio1) {
                   6004:        TEST("audioctl_open_multiuser1_audio1");
1.4       isaki    6005:        test_audioctl_open_multiuser(true, devaudio, devaudioctl);
1.1       isaki    6006: }
                   6007: DEF(audioctl_open_multiuser0_audio2) {
                   6008:        TEST("audioctl_open_multiuser0_audio2");
1.4       isaki    6009:        test_audioctl_open_multiuser(false, devaudioctl, devaudio);
1.1       isaki    6010: }
                   6011: DEF(audioctl_open_multiuser1_audio2) {
                   6012:        TEST("audioctl_open_multiuser1_audio2");
1.4       isaki    6013:        test_audioctl_open_multiuser(true, devaudioctl, devaudio);
1.1       isaki    6014: }
                   6015: DEF(audioctl_open_multiuser0_audioctl) {
                   6016:        TEST("audioctl_open_multiuser0_audioctl");
1.4       isaki    6017:        test_audioctl_open_multiuser(false, devaudioctl, devaudioctl);
1.1       isaki    6018: }
                   6019: DEF(audioctl_open_multiuser1_audioctl) {
                   6020:        TEST("audioctl_open_multiuser1_audioctl");
1.4       isaki    6021:        test_audioctl_open_multiuser(true, devaudioctl, devaudioctl);
1.1       isaki    6022: }
                   6023:
                   6024: /*
                   6025:  * /dev/audioctl cannot be read/written regardless of its open mode.
                   6026:  */
                   6027: void
                   6028: test_audioctl_rw(int openmode)
                   6029: {
                   6030:        char buf[1];
                   6031:        int fd;
                   6032:        int r;
                   6033:
                   6034:        TEST("audioctl_rw_%s", openmode_str[openmode] + 2);
                   6035:
                   6036:        fd = OPEN(devaudioctl, openmode);
                   6037:        REQUIRED_SYS_OK(fd);
                   6038:
                   6039:        if (mode2play(openmode)) {
                   6040:                r = WRITE(fd, buf, sizeof(buf));
                   6041:                XP_SYS_NG(ENODEV, r);
                   6042:        }
                   6043:
                   6044:        if (mode2rec(openmode)) {
                   6045:                r = READ(fd, buf, sizeof(buf));
                   6046:                XP_SYS_NG(ENODEV, r);
                   6047:        }
                   6048:
                   6049:        r = CLOSE(fd);
                   6050:        XP_SYS_EQ(0, r);
                   6051: }
                   6052: DEF(audioctl_rw_RDONLY)        { test_audioctl_rw(O_RDONLY); }
                   6053: DEF(audioctl_rw_WRONLY)        { test_audioctl_rw(O_WRONLY); }
                   6054: DEF(audioctl_rw_RDWR)  { test_audioctl_rw(O_RDWR); }
                   6055:
                   6056: /*
                   6057:  * poll(2) for /dev/audioctl should never raise.
                   6058:  * I'm not sure about consistency between poll(2) and kqueue(2) but
                   6059:  * anyway I follow it.
                   6060:  * XXX Omit checking each openmode
                   6061:  */
                   6062: DEF(audioctl_poll)
                   6063: {
                   6064:        struct pollfd pfd;
                   6065:        int fd;
                   6066:        int r;
                   6067:
                   6068:        TEST("audioctl_poll");
                   6069:
                   6070:        fd = OPEN(devaudioctl, O_WRONLY);
                   6071:        REQUIRED_SYS_OK(fd);
                   6072:
                   6073:        pfd.fd = fd;
                   6074:        pfd.events = POLLOUT;
                   6075:        r = POLL(&pfd, 1, 100);
                   6076:        XP_SYS_EQ(0, r);
                   6077:        XP_EQ(0, pfd.revents);
                   6078:
                   6079:        r = CLOSE(fd);
                   6080:        XP_SYS_EQ(0, r);
                   6081: }
                   6082:
                   6083: /*
                   6084:  * kqueue(2) for /dev/audioctl fails.
                   6085:  * I'm not sure about consistency between poll(2) and kqueue(2) but
                   6086:  * anyway I follow it.
                   6087:  * XXX Omit checking each openmode
                   6088:  */
                   6089: DEF(audioctl_kqueue)
                   6090: {
                   6091:        struct kevent kev;
                   6092:        int fd;
                   6093:        int kq;
                   6094:        int r;
                   6095:
                   6096:        TEST("audioctl_kqueue");
                   6097:
                   6098:        fd = OPEN(devaudioctl, O_WRONLY);
                   6099:        REQUIRED_SYS_OK(fd);
                   6100:
                   6101:        kq = KQUEUE();
                   6102:        XP_SYS_OK(kq);
                   6103:
                   6104:        EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
                   6105:        r = KEVENT_SET(kq, &kev, 1);
                   6106:        /*
                   6107:         * NetBSD7 has a bug.  It looks to wanted to treat it as successful
                   6108:         * but returned 1(== EPERM).
                   6109:         * On NetBSD9, I decided to return ENODEV.
                   6110:         */
                   6111:        if (netbsd < 8) {
                   6112:                XP_SYS_NG(1/*EPERM*/, r);
                   6113:        } else {
                   6114:                XP_SYS_NG(ENODEV, r);
                   6115:        }
                   6116:
                   6117:        r = CLOSE(fd);
                   6118:        XP_SYS_EQ(0, r);
                   6119: }
                   6120:
                   6121:
                   6122: /*
                   6123:  * This table is processed by t_audio.awk!
                   6124:  * Keep /^\tENT(testname),/ format in order to add to atf.
                   6125:  */
                   6126: #define ENT(x) { #x, test__ ## x }
                   6127: struct testentry testtable[] = {
                   6128:        ENT(open_mode_RDONLY),
                   6129:        ENT(open_mode_WRONLY),
                   6130:        ENT(open_mode_RDWR),
                   6131:        ENT(open_audio_RDONLY),
                   6132:        ENT(open_audio_WRONLY),
                   6133:        ENT(open_audio_RDWR),
                   6134:        ENT(open_sound_RDONLY),
                   6135:        ENT(open_sound_WRONLY),
                   6136:        ENT(open_sound_RDWR),
                   6137:        ENT(open_audioctl_RDONLY),
                   6138:        ENT(open_audioctl_WRONLY),
                   6139:        ENT(open_audioctl_RDWR),
                   6140:        ENT(open_sound_sticky),
                   6141:        ENT(open_audioctl_sticky),
                   6142:        ENT(open_simul_RDONLY_RDONLY),
                   6143:        ENT(open_simul_RDONLY_WRONLY),
                   6144:        ENT(open_simul_RDONLY_RDWR),
                   6145:        ENT(open_simul_WRONLY_RDONLY),
                   6146:        ENT(open_simul_WRONLY_WRONLY),
                   6147:        ENT(open_simul_WRONLY_RDWR),
                   6148:        ENT(open_simul_RDWR_RDONLY),
                   6149:        ENT(open_simul_RDWR_WRONLY),
                   6150:        ENT(open_simul_RDWR_RDWR),
                   6151: /**/   ENT(open_multiuser_0),          // XXX TODO sysctl
                   6152: /**/   ENT(open_multiuser_1),          // XXX TODO sysctl
                   6153:        ENT(write_PLAY_ALL),
                   6154:        ENT(write_PLAY),
                   6155:        ENT(read),
                   6156:        ENT(rept_write),
                   6157:        ENT(rept_read),
                   6158:        ENT(rdwr_fallback_RDONLY),
                   6159:        ENT(rdwr_fallback_WRONLY),
                   6160:        ENT(rdwr_fallback_RDWR),
                   6161:        ENT(rdwr_two_RDONLY_RDONLY),
                   6162:        ENT(rdwr_two_RDONLY_WRONLY),
                   6163:        ENT(rdwr_two_RDONLY_RDWR),
                   6164:        ENT(rdwr_two_WRONLY_RDONLY),
                   6165:        ENT(rdwr_two_WRONLY_WRONLY),
                   6166:        ENT(rdwr_two_WRONLY_RDWR),
                   6167:        ENT(rdwr_two_RDWR_RDONLY),
                   6168:        ENT(rdwr_two_RDWR_WRONLY),
                   6169:        ENT(rdwr_two_RDWR_RDWR),
                   6170:        ENT(rdwr_simul),
                   6171:        ENT(drain_incomplete),
                   6172:        ENT(drain_pause),
                   6173:        ENT(drain_onrec),
                   6174: /**/   ENT(mmap_mode_RDONLY_NONE),     // XXX rump doesn't supprot mmap
                   6175: /**/   ENT(mmap_mode_RDONLY_READ),     // XXX rump doesn't supprot mmap
                   6176: /**/   ENT(mmap_mode_RDONLY_WRITE),    // XXX rump doesn't supprot mmap
                   6177: /**/   ENT(mmap_mode_RDONLY_READWRITE),// XXX rump doesn't supprot mmap
                   6178: /**/   ENT(mmap_mode_WRONLY_NONE),     // XXX rump doesn't supprot mmap
                   6179: /**/   ENT(mmap_mode_WRONLY_READ),     // XXX rump doesn't supprot mmap
                   6180: /**/   ENT(mmap_mode_WRONLY_WRITE),    // XXX rump doesn't supprot mmap
                   6181: /**/   ENT(mmap_mode_WRONLY_READWRITE),// XXX rump doesn't supprot mmap
                   6182: /**/   ENT(mmap_mode_RDWR_NONE),       // XXX rump doesn't supprot mmap
                   6183: /**/   ENT(mmap_mode_RDWR_READ),       // XXX rump doesn't supprot mmap
                   6184: /**/   ENT(mmap_mode_RDWR_WRITE),      // XXX rump doesn't supprot mmap
                   6185: /**/   ENT(mmap_mode_RDWR_READWRITE),  // XXX rump doesn't supprot mmap
                   6186: /**/   ENT(mmap_len),                  // XXX rump doesn't supprot mmap
                   6187: /**/   ENT(mmap_twice),                // XXX rump doesn't supprot mmap
                   6188: /**/   ENT(mmap_multi),                // XXX rump doesn't supprot mmap
                   6189:        ENT(poll_mode_RDONLY_IN),
                   6190:        ENT(poll_mode_RDONLY_OUT),
                   6191:        ENT(poll_mode_RDONLY_INOUT),
                   6192:        ENT(poll_mode_WRONLY_IN),
                   6193:        ENT(poll_mode_WRONLY_OUT),
                   6194:        ENT(poll_mode_WRONLY_INOUT),
                   6195:        ENT(poll_mode_RDWR_IN),
                   6196:        ENT(poll_mode_RDWR_OUT),
                   6197:        ENT(poll_mode_RDWR_INOUT),
                   6198:        ENT(poll_out_empty),
                   6199:        ENT(poll_out_full),
                   6200:        ENT(poll_out_hiwat),
                   6201: /**/   ENT(poll_out_unpause),          // XXX does not seem to work on rump
                   6202: /**/   ENT(poll_out_simul),            // XXX does not seem to work on rump
                   6203:        ENT(poll_in_simul),
                   6204:        ENT(kqueue_mode_RDONLY_READ),
                   6205:        ENT(kqueue_mode_RDONLY_WRITE),
                   6206:        ENT(kqueue_mode_WRONLY_READ),
                   6207:        ENT(kqueue_mode_WRONLY_WRITE),
                   6208:        ENT(kqueue_mode_RDWR_READ),
                   6209:        ENT(kqueue_mode_RDWR_WRITE),
                   6210:        ENT(kqueue_empty),
                   6211:        ENT(kqueue_full),
                   6212:        ENT(kqueue_hiwat),
                   6213: /**/   ENT(kqueue_unpause),            // XXX does not seem to work on rump
                   6214: /**/   ENT(kqueue_simul),              // XXX does not seem to work on rump
                   6215:        ENT(ioctl_while_write),
                   6216:        ENT(FIOASYNC_reset),
                   6217:        ENT(FIOASYNC_play_signal),
                   6218:        ENT(FIOASYNC_rec_signal),
                   6219: /**/   ENT(FIOASYNC_multi),            // XXX does not seem to work on rump
                   6220:        ENT(AUDIO_WSEEK),
                   6221:        ENT(AUDIO_SETFD_RDONLY),
                   6222:        ENT(AUDIO_SETFD_WRONLY),
                   6223:        ENT(AUDIO_SETFD_RDWR),
                   6224:        ENT(AUDIO_GETINFO_eof),
                   6225:        ENT(AUDIO_SETINFO_mode_RDONLY_0),
                   6226:        ENT(AUDIO_SETINFO_mode_RDONLY_1),
                   6227:        ENT(AUDIO_SETINFO_mode_RDONLY_2),
                   6228:        ENT(AUDIO_SETINFO_mode_RDONLY_3),
                   6229:        ENT(AUDIO_SETINFO_mode_RDONLY_4),
                   6230:        ENT(AUDIO_SETINFO_mode_RDONLY_5),
                   6231:        ENT(AUDIO_SETINFO_mode_RDONLY_6),
                   6232:        ENT(AUDIO_SETINFO_mode_RDONLY_7),
                   6233:        ENT(AUDIO_SETINFO_mode_RDONLY_8),
                   6234:        ENT(AUDIO_SETINFO_mode_WRONLY_0),
                   6235:        ENT(AUDIO_SETINFO_mode_WRONLY_1),
                   6236:        ENT(AUDIO_SETINFO_mode_WRONLY_2),
                   6237:        ENT(AUDIO_SETINFO_mode_WRONLY_3),
                   6238:        ENT(AUDIO_SETINFO_mode_WRONLY_4),
                   6239:        ENT(AUDIO_SETINFO_mode_WRONLY_5),
                   6240:        ENT(AUDIO_SETINFO_mode_WRONLY_6),
                   6241:        ENT(AUDIO_SETINFO_mode_WRONLY_7),
                   6242:        ENT(AUDIO_SETINFO_mode_WRONLY_8),
                   6243:        ENT(AUDIO_SETINFO_mode_RDWR_0),
                   6244:        ENT(AUDIO_SETINFO_mode_RDWR_1),
                   6245:        ENT(AUDIO_SETINFO_mode_RDWR_2),
                   6246:        ENT(AUDIO_SETINFO_mode_RDWR_3),
                   6247:        ENT(AUDIO_SETINFO_mode_RDWR_4),
                   6248:        ENT(AUDIO_SETINFO_mode_RDWR_5),
                   6249:        ENT(AUDIO_SETINFO_mode_RDWR_6),
                   6250:        ENT(AUDIO_SETINFO_mode_RDWR_7),
                   6251:        ENT(AUDIO_SETINFO_mode_RDWR_8),
                   6252:        ENT(AUDIO_SETINFO_params_set_RDONLY_0),
                   6253:        ENT(AUDIO_SETINFO_params_set_RDONLY_1),
                   6254:        ENT(AUDIO_SETINFO_params_set_WRONLY_0),
                   6255:        ENT(AUDIO_SETINFO_params_set_WRONLY_1),
                   6256:        ENT(AUDIO_SETINFO_params_set_WRONLY_2),
                   6257:        ENT(AUDIO_SETINFO_params_set_WRONLY_3),
                   6258:        ENT(AUDIO_SETINFO_params_set_RDWR_0),
                   6259:        ENT(AUDIO_SETINFO_params_set_RDWR_1),
                   6260:        ENT(AUDIO_SETINFO_params_set_RDWR_2),
                   6261:        ENT(AUDIO_SETINFO_params_set_RDWR_3),
                   6262:        ENT(AUDIO_SETINFO_params_simul),
1.5       isaki    6263:        ENT(AUDIO_SETINFO_channels),
                   6264:        ENT(AUDIO_SETINFO_sample_rate),
                   6265:        ENT(AUDIO_SETINFO_sample_rate_0),
1.1       isaki    6266:        ENT(AUDIO_SETINFO_pause_RDONLY_0),
                   6267:        ENT(AUDIO_SETINFO_pause_RDONLY_1),
                   6268:        ENT(AUDIO_SETINFO_pause_WRONLY_0),
                   6269:        ENT(AUDIO_SETINFO_pause_WRONLY_1),
                   6270:        ENT(AUDIO_SETINFO_pause_WRONLY_2),
                   6271:        ENT(AUDIO_SETINFO_pause_WRONLY_3),
                   6272:        ENT(AUDIO_SETINFO_pause_RDWR_0),
                   6273:        ENT(AUDIO_SETINFO_pause_RDWR_1),
                   6274:        ENT(AUDIO_SETINFO_pause_RDWR_2),
                   6275:        ENT(AUDIO_SETINFO_pause_RDWR_3),
                   6276:        ENT(AUDIO_SETINFO_gain),
                   6277:        ENT(AUDIO_GETENC_range),
                   6278:        ENT(AUDIO_GETENC_error),
                   6279:        ENT(AUDIO_ERROR_RDONLY),
                   6280:        ENT(AUDIO_ERROR_WRONLY),
                   6281:        ENT(AUDIO_ERROR_RDWR),
                   6282:        ENT(audioctl_open_1_RDONLY_RDONLY),
                   6283:        ENT(audioctl_open_1_RDONLY_RWONLY),
                   6284:        ENT(audioctl_open_1_RDONLY_RDWR),
                   6285:        ENT(audioctl_open_1_WRONLY_RDONLY),
                   6286:        ENT(audioctl_open_1_WRONLY_RWONLY),
                   6287:        ENT(audioctl_open_1_WRONLY_RDWR),
                   6288:        ENT(audioctl_open_1_RDWR_RDONLY),
                   6289:        ENT(audioctl_open_1_RDWR_RWONLY),
                   6290:        ENT(audioctl_open_1_RDWR_RDWR),
                   6291:        ENT(audioctl_open_2_RDONLY_RDONLY),
                   6292:        ENT(audioctl_open_2_RDONLY_RWONLY),
                   6293:        ENT(audioctl_open_2_RDONLY_RDWR),
                   6294:        ENT(audioctl_open_2_WRONLY_RDONLY),
                   6295:        ENT(audioctl_open_2_WRONLY_RWONLY),
                   6296:        ENT(audioctl_open_2_WRONLY_RDWR),
                   6297:        ENT(audioctl_open_2_RDWR_RDONLY),
                   6298:        ENT(audioctl_open_2_RDWR_RWONLY),
                   6299:        ENT(audioctl_open_2_RDWR_RDWR),
                   6300:        ENT(audioctl_open_simul),
                   6301: /**/   ENT(audioctl_open_multiuser0_audio1),   // XXX TODO sysctl
                   6302: /**/   ENT(audioctl_open_multiuser1_audio1),   // XXX TODO sysctl
                   6303: /**/   ENT(audioctl_open_multiuser0_audio2),   // XXX TODO sysctl
                   6304: /**/   ENT(audioctl_open_multiuser1_audio2),   // XXX TODO sysctl
                   6305: /**/   ENT(audioctl_open_multiuser0_audioctl), // XXX TODO sysctl
                   6306: /**/   ENT(audioctl_open_multiuser1_audioctl), // XXX TODO sysctl
                   6307:        ENT(audioctl_rw_RDONLY),
                   6308:        ENT(audioctl_rw_WRONLY),
                   6309:        ENT(audioctl_rw_RDWR),
                   6310:        ENT(audioctl_poll),
                   6311:        ENT(audioctl_kqueue),
1.2       martin   6312:        {.name = NULL},
1.1       isaki    6313: };

CVSweb <webmaster@jp.NetBSD.org>