/*
 * QEMU OSS audio driver
 *
 * Copyright (c) 2003-2005 Vassili Karpov (malc)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "qemu/osdep.h"
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include "qemu-common.h"
#include "qemu/main-loop.h"
#include "qemu/host-utils.h"
#include "audio.h"
#include "trace.h"

#define AUDIO_CAP "oss"
#include "audio_int.h"

#if defined OSS_GETVERSION && defined SNDCTL_DSP_POLICY
#define USE_DSP_POLICY
#endif

typedef struct OSSVoiceOut {
    HWVoiceOut hw;
    void *pcm_buf;
    int fd;
    int wpos;
    int nfrags;
    int fragsize;
    int mmapped;
    int pending;
    Audiodev *dev;
} OSSVoiceOut;

typedef struct OSSVoiceIn {
    HWVoiceIn hw;
    void *pcm_buf;
    int fd;
    int nfrags;
    int fragsize;
    Audiodev *dev;
} OSSVoiceIn;

struct oss_params {
    int freq;
    int fmt;
    int nchannels;
    int nfrags;
    int fragsize;
};

static void GCC_FMT_ATTR (2, 3) oss_logerr (int err, const char *fmt, ...)
{
    va_list ap;

    va_start (ap, fmt);
    AUD_vlog (AUDIO_CAP, fmt, ap);
    va_end (ap);

    AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
}

static void GCC_FMT_ATTR (3, 4) oss_logerr2 (
    int err,
    const char *typ,
    const char *fmt,
    ...
    )
{
    va_list ap;

    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);

    va_start (ap, fmt);
    AUD_vlog (AUDIO_CAP, fmt, ap);
    va_end (ap);

    AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
}

static void oss_anal_close (int *fdp)
{
    int err;

    qemu_set_fd_handler (*fdp, NULL, NULL, NULL);
    err = close (*fdp);
    if (err) {
        oss_logerr (errno, "Failed to close file(fd=%d)\n", *fdp);
    }
    *fdp = -1;
}

static void oss_helper_poll_out (void *opaque)
{
    (void) opaque;
    audio_run ("oss_poll_out");
}

static void oss_helper_poll_in (void *opaque)
{
    (void) opaque;
    audio_run ("oss_poll_in");
}

static void oss_poll_out (HWVoiceOut *hw)
{
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;

    qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL);
}

static void oss_poll_in (HWVoiceIn *hw)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;

    qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL);
}

static int oss_write (SWVoiceOut *sw, void *buf, int len)
{
    return audio_pcm_sw_write (sw, buf, len);
}

static int aud_to_ossfmt (AudioFormat fmt, int endianness)
{
    switch (fmt) {
    case AUDIO_FORMAT_S8:
        return AFMT_S8;

    case AUDIO_FORMAT_U8:
        return AFMT_U8;

    case AUDIO_FORMAT_S16:
        if (endianness) {
            return AFMT_S16_BE;
        }
        else {
            return AFMT_S16_LE;
        }

    case AUDIO_FORMAT_U16:
        if (endianness) {
            return AFMT_U16_BE;
        }
        else {
            return AFMT_U16_LE;
        }

    default:
        dolog ("Internal logic error: Bad audio format %d\n", fmt);
#ifdef DEBUG_AUDIO
        abort ();
#endif
        return AFMT_U8;
    }
}

static int oss_to_audfmt (int ossfmt, AudioFormat *fmt, int *endianness)
{
    switch (ossfmt) {
    case AFMT_S8:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_S8;
        break;

    case AFMT_U8:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_U8;
        break;

    case AFMT_S16_LE:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_S16;
        break;

    case AFMT_U16_LE:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_U16;
        break;

    case AFMT_S16_BE:
        *endianness = 1;
        *fmt = AUDIO_FORMAT_S16;
        break;

    case AFMT_U16_BE:
        *endianness = 1;
        *fmt = AUDIO_FORMAT_U16;
        break;

    default:
        dolog ("Unrecognized audio format %d\n", ossfmt);
        return -1;
    }

    return 0;
}

#if defined DEBUG_MISMATCHES || defined DEBUG
static void oss_dump_info (struct oss_params *req, struct oss_params *obt)
{
    dolog ("parameter | requested value | obtained value\n");
    dolog ("format    |      %10d |     %10d\n", req->fmt, obt->fmt);
    dolog ("channels  |      %10d |     %10d\n",
           req->nchannels, obt->nchannels);
    dolog ("frequency |      %10d |     %10d\n", req->freq, obt->freq);
    dolog ("nfrags    |      %10d |     %10d\n", req->nfrags, obt->nfrags);
    dolog ("fragsize  |      %10d |     %10d\n",
           req->fragsize, obt->fragsize);
}
#endif

#ifdef USE_DSP_POLICY
static int oss_get_version (int fd, int *version, const char *typ)
{
    if (ioctl (fd, OSS_GETVERSION, &version)) {
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
        /*
         * Looks like atm (20100109) FreeBSD knows OSS_GETVERSION
         * since 7.x, but currently only on the mixer device (or in
         * the Linuxolator), and in the native version that part of
         * the code is in fact never reached so the ioctl fails anyway.
         * Until this is fixed, just check the errno and if its what
         * FreeBSD's sound drivers return atm assume they are new enough.
         */
        if (errno == EINVAL) {
            *version = 0x040000;
            return 0;
        }
#endif
        oss_logerr2 (errno, typ, "Failed to get OSS version\n");
        return -1;
    }
    return 0;
}
#endif

static int oss_open(int in, struct oss_params *req, audsettings *as,
                    struct oss_params *obt, int *pfd, Audiodev *dev)
{
    AudiodevOssOptions *oopts = &dev->u.oss;
    AudiodevOssPerDirectionOptions *opdo = in ? oopts->in : oopts->out;
    int fd;
    int oflags = (oopts->has_exclusive && oopts->exclusive) ? O_EXCL : 0;
    audio_buf_info abinfo;
    int fmt, freq, nchannels;
    int setfragment = 1;
    const char *dspname = opdo->has_dev ? opdo->dev : "/dev/dsp";
    const char *typ = in ? "ADC" : "DAC";
#ifdef USE_DSP_POLICY
    int policy = oopts->has_dsp_policy ? oopts->dsp_policy : 5;
#endif

    /* Kludge needed to have working mmap on Linux */
    oflags |= (oopts->has_try_mmap && oopts->try_mmap) ?
        O_RDWR : (in ? O_RDONLY : O_WRONLY);

    fd = open (dspname, oflags | O_NONBLOCK);
    if (-1 == fd) {
        oss_logerr2 (errno, typ, "Failed to open `%s'\n", dspname);
        return -1;
    }

    freq = req->freq;
    nchannels = req->nchannels;
    fmt = req->fmt;
    req->nfrags = opdo->has_buffer_count ? opdo->buffer_count : 4;
    req->fragsize = audio_buffer_bytes(
        qapi_AudiodevOssPerDirectionOptions_base(opdo), as, 23220);

    if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
        oss_logerr2 (errno, typ, "Failed to set sample size %d\n", req->fmt);
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) {
        oss_logerr2 (errno, typ, "Failed to set number of channels %d\n",
                     req->nchannels);
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) {
        oss_logerr2 (errno, typ, "Failed to set frequency %d\n", req->freq);
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_NONBLOCK, NULL)) {
        oss_logerr2 (errno, typ, "Failed to set non-blocking mode\n");
        goto err;
    }

#ifdef USE_DSP_POLICY
    if (policy >= 0) {
        int version;

        if (!oss_get_version (fd, &version, typ)) {
            trace_oss_version(version);

            if (version >= 0x040000) {
                int policy2 = policy;
                if (ioctl(fd, SNDCTL_DSP_POLICY, &policy2)) {
                    oss_logerr2 (errno, typ,
                                 "Failed to set timing policy to %d\n",
                                 policy);
                    goto err;
                }
                setfragment = 0;
            }
        }
    }
#endif

    if (setfragment) {
        int mmmmssss = (req->nfrags << 16) | ctz32 (req->fragsize);
        if (ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) {
            oss_logerr2 (errno, typ, "Failed to set buffer length (%d, %d)\n",
                         req->nfrags, req->fragsize);
            goto err;
        }
    }

    if (ioctl (fd, in ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &abinfo)) {
        oss_logerr2 (errno, typ, "Failed to get buffer length\n");
        goto err;
    }

    if (!abinfo.fragstotal || !abinfo.fragsize) {
        AUD_log (AUDIO_CAP, "Returned bogus buffer information(%d, %d) for %s\n",
                 abinfo.fragstotal, abinfo.fragsize, typ);
        goto err;
    }

    obt->fmt = fmt;
    obt->nchannels = nchannels;
    obt->freq = freq;
    obt->nfrags = abinfo.fragstotal;
    obt->fragsize = abinfo.fragsize;
    *pfd = fd;

#ifdef DEBUG_MISMATCHES
    if ((req->fmt != obt->fmt) ||
        (req->nchannels != obt->nchannels) ||
        (req->freq != obt->freq) ||
        (req->fragsize != obt->fragsize) ||
        (req->nfrags != obt->nfrags)) {
        dolog ("Audio parameters mismatch\n");
        oss_dump_info (req, obt);
    }
#endif

#ifdef DEBUG
    oss_dump_info (req, obt);
#endif
    return 0;

 err:
    oss_anal_close (&fd);
    return -1;
}

static void oss_write_pending (OSSVoiceOut *oss)
{
    HWVoiceOut *hw = &oss->hw;

    if (oss->mmapped) {
        return;
    }

    while (oss->pending) {
        int samples_written;
        ssize_t bytes_written;
        int samples_till_end = hw->samples - oss->wpos;
        int samples_to_write = audio_MIN (oss->pending, samples_till_end);
        int bytes_to_write = samples_to_write << hw->info.shift;
        void *pcm = advance (oss->pcm_buf, oss->wpos << hw->info.shift);

        bytes_written = write (oss->fd, pcm, bytes_to_write);
        if (bytes_written < 0) {
            if (errno != EAGAIN) {
                oss_logerr (errno, "failed to write %d bytes\n",
                            bytes_to_write);
            }
            break;
        }

        if (bytes_written & hw->info.align) {
            dolog ("misaligned write asked for %d, but got %zd\n",
                   bytes_to_write, bytes_written);
            return;
        }

        samples_written = bytes_written >> hw->info.shift;
        oss->pending -= samples_written;
        oss->wpos = (oss->wpos + samples_written) % hw->samples;
        if (bytes_written - bytes_to_write) {
            break;
        }
    }
}

static int oss_run_out (HWVoiceOut *hw, int live)
{
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;
    int err, decr;
    struct audio_buf_info abinfo;
    struct count_info cntinfo;
    int bufsize;

    bufsize = hw->samples << hw->info.shift;

    if (oss->mmapped) {
        int bytes, pos;

        err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo);
        if (err < 0) {
            oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
            return 0;
        }

        pos = hw->rpos << hw->info.shift;
        bytes = audio_ring_dist (cntinfo.ptr, pos, bufsize);
        decr = audio_MIN (bytes >> hw->info.shift, live);
    }
    else {
        err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo);
        if (err < 0) {
            oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
            return 0;
        }

        if (abinfo.bytes > bufsize) {
            trace_oss_invalid_available_size(abinfo.bytes, bufsize);
            abinfo.bytes = bufsize;
        }

        if (abinfo.bytes < 0) {
            trace_oss_invalid_available_size(abinfo.bytes, bufsize);
            return 0;
        }

        decr = audio_MIN (abinfo.bytes >> hw->info.shift, live);
        if (!decr) {
            return 0;
        }
    }

    decr = audio_pcm_hw_clip_out (hw, oss->pcm_buf, decr, oss->pending);
    oss->pending += decr;
    oss_write_pending (oss);

    return decr;
}

static void oss_fini_out (HWVoiceOut *hw)
{
    int err;
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;

    ldebug ("oss_fini\n");
    oss_anal_close (&oss->fd);

    if (oss->pcm_buf) {
        if (oss->mmapped) {
            err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
            if (err) {
                oss_logerr (errno, "Failed to unmap buffer %p, size %d\n",
                            oss->pcm_buf, hw->samples << hw->info.shift);
            }
        }
        else {
            g_free (oss->pcm_buf);
        }
        oss->pcm_buf = NULL;
    }
}

static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
                        void *drv_opaque)
{
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;
    struct oss_params req, obt;
    int endianness;
    int err;
    int fd;
    AudioFormat effective_fmt;
    struct audsettings obt_as;
    Audiodev *dev = drv_opaque;
    AudiodevOssOptions *oopts = &dev->u.oss;

    oss->fd = -1;

    req.fmt = aud_to_ossfmt (as->fmt, as->endianness);
    req.freq = as->freq;
    req.nchannels = as->nchannels;

    if (oss_open(0, &req, as, &obt, &fd, dev)) {
        return -1;
    }

    err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
    if (err) {
        oss_anal_close (&fd);
        return -1;
    }

    obt_as.freq = obt.freq;
    obt_as.nchannels = obt.nchannels;
    obt_as.fmt = effective_fmt;
    obt_as.endianness = endianness;

    audio_pcm_init_info (&hw->info, &obt_as);
    oss->nfrags = obt.nfrags;
    oss->fragsize = obt.fragsize;

    if (obt.nfrags * obt.fragsize & hw->info.align) {
        dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n",
               obt.nfrags * obt.fragsize, hw->info.align + 1);
    }

    hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;

    oss->mmapped = 0;
    if (oopts->has_try_mmap && oopts->try_mmap) {
        oss->pcm_buf = mmap (
            NULL,
            hw->samples << hw->info.shift,
            PROT_READ | PROT_WRITE,
            MAP_SHARED,
            fd,
            0
            );
        if (oss->pcm_buf == MAP_FAILED) {
            oss_logerr (errno, "Failed to map %d bytes of DAC\n",
                        hw->samples << hw->info.shift);
        }
        else {
            int err;
            int trig = 0;
            if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
                oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
            }
            else {
                trig = PCM_ENABLE_OUTPUT;
                if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
                    oss_logerr (
                        errno,
                        "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
                        );
                }
                else {
                    oss->mmapped = 1;
                }
            }

            if (!oss->mmapped) {
                err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
                if (err) {
                    oss_logerr (errno, "Failed to unmap buffer %p size %d\n",
                                oss->pcm_buf, hw->samples << hw->info.shift);
                }
            }
        }
    }

    if (!oss->mmapped) {
        oss->pcm_buf = audio_calloc(__func__,
                                    hw->samples,
                                    1 << hw->info.shift);
        if (!oss->pcm_buf) {
            dolog (
                "Could not allocate DAC buffer (%d samples, each %d bytes)\n",
                hw->samples,
                1 << hw->info.shift
                );
            oss_anal_close (&fd);
            return -1;
        }
    }

    oss->fd = fd;
    oss->dev = dev;
    return 0;
}

static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
    int trig;
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;
    AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.out;

    switch (cmd) {
    case VOICE_ENABLE:
        {
            bool poll_mode = opdo->try_poll;

            ldebug ("enabling voice\n");
            if (poll_mode) {
                oss_poll_out (hw);
                poll_mode = 0;
            }
            hw->poll_mode = poll_mode;

            if (!oss->mmapped) {
                return 0;
            }

            audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples);
            trig = PCM_ENABLE_OUTPUT;
            if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
                oss_logerr (
                    errno,
                    "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
                    );
                return -1;
            }
        }
        break;

    case VOICE_DISABLE:
        if (hw->poll_mode) {
            qemu_set_fd_handler (oss->fd, NULL, NULL, NULL);
            hw->poll_mode = 0;
        }

        if (!oss->mmapped) {
            return 0;
        }

        ldebug ("disabling voice\n");
        trig = 0;
        if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
            oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
            return -1;
        }
        break;
    }
    return 0;
}

static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;
    struct oss_params req, obt;
    int endianness;
    int err;
    int fd;
    AudioFormat effective_fmt;
    struct audsettings obt_as;
    Audiodev *dev = drv_opaque;

    oss->fd = -1;

    req.fmt = aud_to_ossfmt (as->fmt, as->endianness);
    req.freq = as->freq;
    req.nchannels = as->nchannels;
    if (oss_open(1, &req, as, &obt, &fd, dev)) {
        return -1;
    }

    err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
    if (err) {
        oss_anal_close (&fd);
        return -1;
    }

    obt_as.freq = obt.freq;
    obt_as.nchannels = obt.nchannels;
    obt_as.fmt = effective_fmt;
    obt_as.endianness = endianness;

    audio_pcm_init_info (&hw->info, &obt_as);
    oss->nfrags = obt.nfrags;
    oss->fragsize = obt.fragsize;

    if (obt.nfrags * obt.fragsize & hw->info.align) {
        dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n",
               obt.nfrags * obt.fragsize, hw->info.align + 1);
    }

    hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
    oss->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift);
    if (!oss->pcm_buf) {
        dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
               hw->samples, 1 << hw->info.shift);
        oss_anal_close (&fd);
        return -1;
    }

    oss->fd = fd;
    oss->dev = dev;
    return 0;
}

static void oss_fini_in (HWVoiceIn *hw)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;

    oss_anal_close (&oss->fd);

    g_free(oss->pcm_buf);
    oss->pcm_buf = NULL;
}

static int oss_run_in (HWVoiceIn *hw)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;
    int hwshift = hw->info.shift;
    int i;
    int live = audio_pcm_hw_get_live_in (hw);
    int dead = hw->samples - live;
    size_t read_samples = 0;
    struct {
        int add;
        int len;
    } bufs[2] = {
        { .add = hw->wpos, .len = 0 },
        { .add = 0,        .len = 0 }
    };

    if (!dead) {
        return 0;
    }

    if (hw->wpos + dead > hw->samples) {
        bufs[0].len = (hw->samples - hw->wpos) << hwshift;
        bufs[1].len = (dead - (hw->samples - hw->wpos)) << hwshift;
    }
    else {
        bufs[0].len = dead << hwshift;
    }

    for (i = 0; i < 2; ++i) {
        ssize_t nread;

        if (bufs[i].len) {
            void *p = advance (oss->pcm_buf, bufs[i].add << hwshift);
            nread = read (oss->fd, p, bufs[i].len);

            if (nread > 0) {
                if (nread & hw->info.align) {
                    dolog ("warning: Misaligned read %zd (requested %d), "
                           "alignment %d\n", nread, bufs[i].add << hwshift,
                           hw->info.align + 1);
                }
                read_samples += nread >> hwshift;
                hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift);
            }

            if (bufs[i].len - nread) {
                if (nread == -1) {
                    switch (errno) {
                    case EINTR:
                    case EAGAIN:
                        break;
                    default:
                        oss_logerr (
                            errno,
                            "Failed to read %d bytes of audio (to %p)\n",
                            bufs[i].len, p
                            );
                        break;
                    }
                }
                break;
            }
        }
    }

    hw->wpos = (hw->wpos + read_samples) % hw->samples;
    return read_samples;
}

static int oss_read (SWVoiceIn *sw, void *buf, int size)
{
    return audio_pcm_sw_read (sw, buf, size);
}

static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;
    AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.out;

    switch (cmd) {
    case VOICE_ENABLE:
        {
            bool poll_mode = opdo->try_poll;

            if (poll_mode) {
                oss_poll_in (hw);
                poll_mode = 0;
            }
            hw->poll_mode = poll_mode;
        }
        break;

    case VOICE_DISABLE:
        if (hw->poll_mode) {
            hw->poll_mode = 0;
            qemu_set_fd_handler (oss->fd, NULL, NULL, NULL);
        }
        break;
    }
    return 0;
}

static void oss_init_per_direction(AudiodevOssPerDirectionOptions *opdo)
{
    if (!opdo->has_try_poll) {
        opdo->try_poll = true;
        opdo->has_try_poll = true;
    }
}

static void *oss_audio_init(Audiodev *dev)
{
    AudiodevOssOptions *oopts;
    assert(dev->driver == AUDIODEV_DRIVER_OSS);

    oopts = &dev->u.oss;
    oss_init_per_direction(oopts->in);
    oss_init_per_direction(oopts->out);

    if (access(oopts->in->has_dev ? oopts->in->dev : "/dev/dsp",
               R_OK | W_OK) < 0 ||
        access(oopts->out->has_dev ? oopts->out->dev : "/dev/dsp",
               R_OK | W_OK) < 0) {
        return NULL;
    }
    return dev;
}

static void oss_audio_fini (void *opaque)
{
}

static struct audio_pcm_ops oss_pcm_ops = {
    .init_out = oss_init_out,
    .fini_out = oss_fini_out,
    .run_out  = oss_run_out,
    .write    = oss_write,
    .ctl_out  = oss_ctl_out,

    .init_in  = oss_init_in,
    .fini_in  = oss_fini_in,
    .run_in   = oss_run_in,
    .read     = oss_read,
    .ctl_in   = oss_ctl_in
};

static struct audio_driver oss_audio_driver = {
    .name           = "oss",
    .descr          = "OSS http://www.opensound.com",
    .init           = oss_audio_init,
    .fini           = oss_audio_fini,
    .pcm_ops        = &oss_pcm_ops,
    .can_be_default = 1,
    .max_voices_out = INT_MAX,
    .max_voices_in  = INT_MAX,
    .voice_size_out = sizeof (OSSVoiceOut),
    .voice_size_in  = sizeof (OSSVoiceIn)
};

static void register_audio_oss(void)
{
    audio_driver_register(&oss_audio_driver);
}
type_init(register_audio_oss);
