/*
 * QEMU ETRAX DMA Controller.
 *
 * Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB.
 *
 * 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 "hw/hw.h"
#include "hw/irq.h"
#include "qemu/main-loop.h"
#include "sysemu/runstate.h"
#include "exec/address-spaces.h"
#include "exec/memory.h"

#include "hw/cris/etraxfs_dma.h"

#define D(x)

#define RW_DATA           (0x0 / 4)
#define RW_SAVED_DATA     (0x58 / 4)
#define RW_SAVED_DATA_BUF (0x5c / 4)
#define RW_GROUP          (0x60 / 4)
#define RW_GROUP_DOWN     (0x7c / 4)
#define RW_CMD            (0x80 / 4)
#define RW_CFG            (0x84 / 4)
#define RW_STAT           (0x88 / 4)
#define RW_INTR_MASK      (0x8c / 4)
#define RW_ACK_INTR       (0x90 / 4)
#define R_INTR            (0x94 / 4)
#define R_MASKED_INTR     (0x98 / 4)
#define RW_STREAM_CMD     (0x9c / 4)

#define DMA_REG_MAX       (0x100 / 4)

/* descriptors */

// ------------------------------------------------------------ dma_descr_group
typedef struct dma_descr_group {
  uint32_t                      next;
  unsigned                      eol        : 1;
  unsigned                      tol        : 1;
  unsigned                      bol        : 1;
  unsigned                                 : 1;
  unsigned                      intr       : 1;
  unsigned                                 : 2;
  unsigned                      en         : 1;
  unsigned                                 : 7;
  unsigned                      dis        : 1;
  unsigned                      md         : 16;
  struct dma_descr_group       *up;
  union {
    struct dma_descr_context   *context;
    struct dma_descr_group     *group;
  }                             down;
} dma_descr_group;

// ---------------------------------------------------------- dma_descr_context
typedef struct dma_descr_context {
  uint32_t                      next;
  unsigned                      eol        : 1;
  unsigned                                 : 3;
  unsigned                      intr       : 1;
  unsigned                                 : 1;
  unsigned                      store_mode : 1;
  unsigned                      en         : 1;
  unsigned                                 : 7;
  unsigned                      dis        : 1;
  unsigned                      md0        : 16;
  unsigned                      md1;
  unsigned                      md2;
  unsigned                      md3;
  unsigned                      md4;
  uint32_t                      saved_data;
  uint32_t                      saved_data_buf;
} dma_descr_context;

// ------------------------------------------------------------- dma_descr_data
typedef struct dma_descr_data {
  uint32_t                      next;
  uint32_t                      buf;
  unsigned                      eol        : 1;
  unsigned                                 : 2;
  unsigned                      out_eop    : 1;
  unsigned                      intr       : 1;
  unsigned                      wait       : 1;
  unsigned                                 : 2;
  unsigned                                 : 3;
  unsigned                      in_eop     : 1;
  unsigned                                 : 4;
  unsigned                      md         : 16;
  uint32_t                      after;
} dma_descr_data;

/* Constants */
enum {
  regk_dma_ack_pkt                         = 0x00000100,
  regk_dma_anytime                         = 0x00000001,
  regk_dma_array                           = 0x00000008,
  regk_dma_burst                           = 0x00000020,
  regk_dma_client                          = 0x00000002,
  regk_dma_copy_next                       = 0x00000010,
  regk_dma_copy_up                         = 0x00000020,
  regk_dma_data_at_eol                     = 0x00000001,
  regk_dma_dis_c                           = 0x00000010,
  regk_dma_dis_g                           = 0x00000020,
  regk_dma_idle                            = 0x00000001,
  regk_dma_intern                          = 0x00000004,
  regk_dma_load_c                          = 0x00000200,
  regk_dma_load_c_n                        = 0x00000280,
  regk_dma_load_c_next                     = 0x00000240,
  regk_dma_load_d                          = 0x00000140,
  regk_dma_load_g                          = 0x00000300,
  regk_dma_load_g_down                     = 0x000003c0,
  regk_dma_load_g_next                     = 0x00000340,
  regk_dma_load_g_up                       = 0x00000380,
  regk_dma_next_en                         = 0x00000010,
  regk_dma_next_pkt                        = 0x00000010,
  regk_dma_no                              = 0x00000000,
  regk_dma_only_at_wait                    = 0x00000000,
  regk_dma_restore                         = 0x00000020,
  regk_dma_rst                             = 0x00000001,
  regk_dma_running                         = 0x00000004,
  regk_dma_rw_cfg_default                  = 0x00000000,
  regk_dma_rw_cmd_default                  = 0x00000000,
  regk_dma_rw_intr_mask_default            = 0x00000000,
  regk_dma_rw_stat_default                 = 0x00000101,
  regk_dma_rw_stream_cmd_default           = 0x00000000,
  regk_dma_save_down                       = 0x00000020,
  regk_dma_save_up                         = 0x00000020,
  regk_dma_set_reg                         = 0x00000050,
  regk_dma_set_w_size1                     = 0x00000190,
  regk_dma_set_w_size2                     = 0x000001a0,
  regk_dma_set_w_size4                     = 0x000001c0,
  regk_dma_stopped                         = 0x00000002,
  regk_dma_store_c                         = 0x00000002,
  regk_dma_store_descr                     = 0x00000000,
  regk_dma_store_g                         = 0x00000004,
  regk_dma_store_md                        = 0x00000001,
  regk_dma_sw                              = 0x00000008,
  regk_dma_update_down                     = 0x00000020,
  regk_dma_yes                             = 0x00000001
};

enum dma_ch_state
{
    RST = 1,
    STOPPED = 2,
    RUNNING = 4
};

struct fs_dma_channel
{
    qemu_irq irq;
    struct etraxfs_dma_client *client;

    /* Internal status.  */
    int stream_cmd_src;
    enum dma_ch_state state;

    unsigned int input : 1;
    unsigned int eol : 1;

    struct dma_descr_group current_g;
    struct dma_descr_context current_c;
    struct dma_descr_data current_d;

    /* Control registers.  */
    uint32_t regs[DMA_REG_MAX];
};

struct fs_dma_ctrl
{
    MemoryRegion mmio;
    int nr_channels;
    struct fs_dma_channel *channels;

    QEMUBH *bh;
};

static void DMA_run(void *opaque);
static int channel_out_run(struct fs_dma_ctrl *ctrl, int c);

static inline uint32_t channel_reg(struct fs_dma_ctrl *ctrl, int c, int reg)
{
    return ctrl->channels[c].regs[reg];
}

static inline int channel_stopped(struct fs_dma_ctrl *ctrl, int c)
{
    return channel_reg(ctrl, c, RW_CFG) & 2;
}

static inline int channel_en(struct fs_dma_ctrl *ctrl, int c)
{
    return (channel_reg(ctrl, c, RW_CFG) & 1)
            && ctrl->channels[c].client;
}

static inline int fs_channel(hwaddr addr)
{
    /* Every channel has a 0x2000 ctrl register map.  */
    return addr >> 13;
}

#ifdef USE_THIS_DEAD_CODE
static void channel_load_g(struct fs_dma_ctrl *ctrl, int c)
{
    hwaddr addr = channel_reg(ctrl, c, RW_GROUP);

    /* Load and decode. FIXME: handle endianness.  */
    cpu_physical_memory_read(addr, &ctrl->channels[c].current_g,
                             sizeof(ctrl->channels[c].current_g));
}

static void dump_c(int ch, struct dma_descr_context *c)
{
    printf("%s ch=%d\n", __func__, ch);
    printf("next=%x\n", c->next);
    printf("saved_data=%x\n", c->saved_data);
    printf("saved_data_buf=%x\n", c->saved_data_buf);
    printf("eol=%x\n", (uint32_t) c->eol);
}

static void dump_d(int ch, struct dma_descr_data *d)
{
    printf("%s ch=%d\n", __func__, ch);
    printf("next=%x\n", d->next);
    printf("buf=%x\n", d->buf);
    printf("after=%x\n", d->after);
    printf("intr=%x\n", (uint32_t) d->intr);
    printf("out_eop=%x\n", (uint32_t) d->out_eop);
    printf("in_eop=%x\n", (uint32_t) d->in_eop);
    printf("eol=%x\n", (uint32_t) d->eol);
}
#endif

static void channel_load_c(struct fs_dma_ctrl *ctrl, int c)
{
    hwaddr addr = channel_reg(ctrl, c, RW_GROUP_DOWN);

    /* Load and decode. FIXME: handle endianness.  */
    cpu_physical_memory_read(addr, &ctrl->channels[c].current_c,
                             sizeof(ctrl->channels[c].current_c));

    D(dump_c(c, &ctrl->channels[c].current_c));
    /* I guess this should update the current pos.  */
    ctrl->channels[c].regs[RW_SAVED_DATA] =
        (uint32_t)(unsigned long)ctrl->channels[c].current_c.saved_data;
    ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
        (uint32_t)(unsigned long)ctrl->channels[c].current_c.saved_data_buf;
}

static void channel_load_d(struct fs_dma_ctrl *ctrl, int c)
{
    hwaddr addr = channel_reg(ctrl, c, RW_SAVED_DATA);

    /* Load and decode. FIXME: handle endianness.  */
    D(printf("%s ch=%d addr=" HWADDR_FMT_plx "\n", __func__, c, addr));
    cpu_physical_memory_read(addr, &ctrl->channels[c].current_d,
                             sizeof(ctrl->channels[c].current_d));

    D(dump_d(c, &ctrl->channels[c].current_d));
    ctrl->channels[c].regs[RW_DATA] = addr;
}

static void channel_store_c(struct fs_dma_ctrl *ctrl, int c)
{
    hwaddr addr = channel_reg(ctrl, c, RW_GROUP_DOWN);

    /* Encode and store. FIXME: handle endianness.  */
    D(printf("%s ch=%d addr=" HWADDR_FMT_plx "\n", __func__, c, addr));
    D(dump_d(c, &ctrl->channels[c].current_d));
    cpu_physical_memory_write(addr, &ctrl->channels[c].current_c,
                              sizeof(ctrl->channels[c].current_c));
}

static void channel_store_d(struct fs_dma_ctrl *ctrl, int c)
{
    hwaddr addr = channel_reg(ctrl, c, RW_SAVED_DATA);

    /* Encode and store. FIXME: handle endianness.  */
    D(printf("%s ch=%d addr=" HWADDR_FMT_plx "\n", __func__, c, addr));
    cpu_physical_memory_write(addr, &ctrl->channels[c].current_d,
                              sizeof(ctrl->channels[c].current_d));
}

static inline void channel_stop(struct fs_dma_ctrl *ctrl, int c)
{
    /* FIXME:  */
}

static inline void channel_start(struct fs_dma_ctrl *ctrl, int c)
{
    if (ctrl->channels[c].client)
    {
        ctrl->channels[c].eol = 0;
        ctrl->channels[c].state = RUNNING;
        if (!ctrl->channels[c].input)
            channel_out_run(ctrl, c);
    } else
        printf("WARNING: starting DMA ch %d with no client\n", c);

    qemu_bh_schedule_idle(ctrl->bh);
}

static void channel_continue(struct fs_dma_ctrl *ctrl, int c)
{
    if (!channel_en(ctrl, c)
        || channel_stopped(ctrl, c)
        || ctrl->channels[c].state != RUNNING
        /* Only reload the current data descriptor if it has eol set.  */
        || !ctrl->channels[c].current_d.eol) {
        D(printf("continue failed ch=%d state=%d stopped=%d en=%d eol=%d\n",
                 c, ctrl->channels[c].state,
                 channel_stopped(ctrl, c),
                 channel_en(ctrl,c),
                 ctrl->channels[c].eol));
        D(dump_d(c, &ctrl->channels[c].current_d));
        return;
    }

    /* Reload the current descriptor.  */
    channel_load_d(ctrl, c);

    /* If the current descriptor cleared the eol flag and we had already
       reached eol state, do the continue.  */
    if (!ctrl->channels[c].current_d.eol && ctrl->channels[c].eol) {
        D(printf("continue %d ok %x\n", c,
                 ctrl->channels[c].current_d.next));
        ctrl->channels[c].regs[RW_SAVED_DATA] =
            (uint32_t)(unsigned long)ctrl->channels[c].current_d.next;
        channel_load_d(ctrl, c);
        ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
            (uint32_t)(unsigned long)ctrl->channels[c].current_d.buf;

        channel_start(ctrl, c);
    }
    ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
        (uint32_t)(unsigned long)ctrl->channels[c].current_d.buf;
}

static void channel_stream_cmd(struct fs_dma_ctrl *ctrl, int c, uint32_t v)
{
    unsigned int cmd = v & ((1 << 10) - 1);

    D(printf("%s ch=%d cmd=%x\n",
             __func__, c, cmd));
    if (cmd & regk_dma_load_d) {
        channel_load_d(ctrl, c);
        if (cmd & regk_dma_burst)
            channel_start(ctrl, c);
    }

    if (cmd & regk_dma_load_c) {
        channel_load_c(ctrl, c);
    }
}

static void channel_update_irq(struct fs_dma_ctrl *ctrl, int c)
{
    D(printf("%s %d\n", __func__, c));
    ctrl->channels[c].regs[R_INTR] &=
        ~(ctrl->channels[c].regs[RW_ACK_INTR]);

    ctrl->channels[c].regs[R_MASKED_INTR] =
        ctrl->channels[c].regs[R_INTR]
        & ctrl->channels[c].regs[RW_INTR_MASK];

    D(printf("%s: chan=%d masked_intr=%x\n", __func__,
             c,
             ctrl->channels[c].regs[R_MASKED_INTR]));

    qemu_set_irq(ctrl->channels[c].irq,
                 !!ctrl->channels[c].regs[R_MASKED_INTR]);
}

static int channel_out_run(struct fs_dma_ctrl *ctrl, int c)
{
    uint32_t len;
    uint32_t saved_data_buf;
    unsigned char buf[2 * 1024];

    struct dma_context_metadata meta;
    bool send_context = true;

    if (ctrl->channels[c].eol)
        return 0;

    do {
        bool out_eop;
        D(printf("ch=%d buf=%x after=%x\n",
                 c,
                 (uint32_t)ctrl->channels[c].current_d.buf,
                 (uint32_t)ctrl->channels[c].current_d.after));

        if (send_context) {
            if (ctrl->channels[c].client->client.metadata_push) {
                meta.metadata = ctrl->channels[c].current_d.md;
                ctrl->channels[c].client->client.metadata_push(
                    ctrl->channels[c].client->client.opaque,
                    &meta);
            }
            send_context = false;
        }

        channel_load_d(ctrl, c);
        saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
        len = (uint32_t)(unsigned long)
            ctrl->channels[c].current_d.after;
        len -= saved_data_buf;

        if (len > sizeof buf)
            len = sizeof buf;
        cpu_physical_memory_read (saved_data_buf, buf, len);

        out_eop = ((saved_data_buf + len) ==
                   ctrl->channels[c].current_d.after) &&
                   ctrl->channels[c].current_d.out_eop;

        D(printf("channel %d pushes %x %u bytes eop=%u\n", c,
                 saved_data_buf, len, out_eop));

        if (ctrl->channels[c].client->client.push) {
            if (len > 0) {
                ctrl->channels[c].client->client.push(
                    ctrl->channels[c].client->client.opaque,
                    buf, len, out_eop);
            }
        } else {
            printf("WARNING: DMA ch%d dataloss,"
                   " no attached client.\n", c);
        }

        saved_data_buf += len;

        if (saved_data_buf == (uint32_t)(unsigned long)
                ctrl->channels[c].current_d.after) {
            /* Done. Step to next.  */
            if (ctrl->channels[c].current_d.out_eop) {
                send_context = true;
            }
            if (ctrl->channels[c].current_d.intr) {
                /* data intr.  */
                D(printf("signal intr %d eol=%d\n",
                         len, ctrl->channels[c].current_d.eol));
                ctrl->channels[c].regs[R_INTR] |= (1 << 2);
                channel_update_irq(ctrl, c);
            }
            channel_store_d(ctrl, c);
            if (ctrl->channels[c].current_d.eol) {
                D(printf("channel %d EOL\n", c));
                ctrl->channels[c].eol = 1;

                /* Mark the context as disabled.  */
                ctrl->channels[c].current_c.dis = 1;
                channel_store_c(ctrl, c);

                channel_stop(ctrl, c);
            } else {
                ctrl->channels[c].regs[RW_SAVED_DATA] =
                    (uint32_t)(unsigned long)ctrl->
                        channels[c].current_d.next;
                /* Load new descriptor.  */
                channel_load_d(ctrl, c);
                saved_data_buf = (uint32_t)(unsigned long)
                    ctrl->channels[c].current_d.buf;
            }

            ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
                            saved_data_buf;
            D(dump_d(c, &ctrl->channels[c].current_d));
        }
        ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
    } while (!ctrl->channels[c].eol);
    return 1;
}

static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, 
                              unsigned char *buf, int buflen, int eop)
{
    uint32_t len;
    uint32_t saved_data_buf;

    if (ctrl->channels[c].eol == 1)
        return 0;

    channel_load_d(ctrl, c);
    saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
    len = (uint32_t)(unsigned long)ctrl->channels[c].current_d.after;
    len -= saved_data_buf;

    if (len > buflen)
        len = buflen;

    cpu_physical_memory_write (saved_data_buf, buf, len);
    saved_data_buf += len;

    if (saved_data_buf ==
        (uint32_t)(unsigned long)ctrl->channels[c].current_d.after
        || eop) {
        uint32_t r_intr = ctrl->channels[c].regs[R_INTR];

        D(printf("in dscr end len=%d\n",
                 ctrl->channels[c].current_d.after
                 - ctrl->channels[c].current_d.buf));
        ctrl->channels[c].current_d.after = saved_data_buf;

        /* Done. Step to next.  */
        if (ctrl->channels[c].current_d.intr) {
            /* TODO: signal eop to the client.  */
            /* data intr.  */
            ctrl->channels[c].regs[R_INTR] |= 3;
        }
        if (eop) {
            ctrl->channels[c].current_d.in_eop = 1;
            ctrl->channels[c].regs[R_INTR] |= 8;
        }
        if (r_intr != ctrl->channels[c].regs[R_INTR])
            channel_update_irq(ctrl, c);

        channel_store_d(ctrl, c);
        D(dump_d(c, &ctrl->channels[c].current_d));

        if (ctrl->channels[c].current_d.eol) {
            D(printf("channel %d EOL\n", c));
            ctrl->channels[c].eol = 1;

            /* Mark the context as disabled.  */
            ctrl->channels[c].current_c.dis = 1;
            channel_store_c(ctrl, c);

            channel_stop(ctrl, c);
        } else {
            ctrl->channels[c].regs[RW_SAVED_DATA] =
                (uint32_t)(unsigned long)ctrl->
                    channels[c].current_d.next;
            /* Load new descriptor.  */
            channel_load_d(ctrl, c);
            saved_data_buf = (uint32_t)(unsigned long)
                ctrl->channels[c].current_d.buf;
        }
    }

    ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
    return len;
}

static inline int channel_in_run(struct fs_dma_ctrl *ctrl, int c)
{
    if (ctrl->channels[c].client->client.pull) {
        ctrl->channels[c].client->client.pull(
            ctrl->channels[c].client->client.opaque);
        return 1;
    } else
        return 0;
}

static uint32_t dma_rinvalid (void *opaque, hwaddr addr)
{
    hw_error("Unsupported short raccess. reg=" HWADDR_FMT_plx "\n", addr);
    return 0;
}

static uint64_t
dma_read(void *opaque, hwaddr addr, unsigned int size)
{
    struct fs_dma_ctrl *ctrl = opaque;
    int c;
    uint32_t r = 0;

    if (size != 4) {
        dma_rinvalid(opaque, addr);
    }

    /* Make addr relative to this channel and bounded to nr regs.  */
    c = fs_channel(addr);
    addr &= 0xff;
    addr >>= 2;
    switch (addr)
    {
    case RW_STAT:
        r = ctrl->channels[c].state & 7;
        r |= ctrl->channels[c].eol << 5;
        r |= ctrl->channels[c].stream_cmd_src << 8;
        break;

    default:
        r = ctrl->channels[c].regs[addr];
        D(printf("%s c=%d addr=" HWADDR_FMT_plx "\n",
                 __func__, c, addr));
        break;
    }
    return r;
}

static void
dma_winvalid (void *opaque, hwaddr addr, uint32_t value)
{
    hw_error("Unsupported short waccess. reg=" HWADDR_FMT_plx "\n", addr);
}

static void
dma_update_state(struct fs_dma_ctrl *ctrl, int c)
{
    if (ctrl->channels[c].regs[RW_CFG] & 2)
        ctrl->channels[c].state = STOPPED;
    if (!(ctrl->channels[c].regs[RW_CFG] & 1))
        ctrl->channels[c].state = RST;
}

static void
dma_write(void *opaque, hwaddr addr,
          uint64_t val64, unsigned int size)
{
    struct fs_dma_ctrl *ctrl = opaque;
    uint32_t value = val64;
    int c;

    if (size != 4) {
        dma_winvalid(opaque, addr, value);
    }

        /* Make addr relative to this channel and bounded to nr regs.  */
    c = fs_channel(addr);
    addr &= 0xff;
    addr >>= 2;
    switch (addr)
    {
    case RW_DATA:
        ctrl->channels[c].regs[addr] = value;
        break;

    case RW_CFG:
        ctrl->channels[c].regs[addr] = value;
        dma_update_state(ctrl, c);
        break;
    case RW_CMD:
        /* continue.  */
        if (value & ~1)
            printf("Invalid store to ch=%d RW_CMD %x\n",
                   c, value);
        ctrl->channels[c].regs[addr] = value;
        channel_continue(ctrl, c);
        break;

    case RW_SAVED_DATA:
    case RW_SAVED_DATA_BUF:
    case RW_GROUP:
    case RW_GROUP_DOWN:
        ctrl->channels[c].regs[addr] = value;
        break;

    case RW_ACK_INTR:
    case RW_INTR_MASK:
        ctrl->channels[c].regs[addr] = value;
        channel_update_irq(ctrl, c);
        if (addr == RW_ACK_INTR)
            ctrl->channels[c].regs[RW_ACK_INTR] = 0;
        break;

    case RW_STREAM_CMD:
        if (value & ~1023)
            printf("Invalid store to ch=%d "
                   "RW_STREAMCMD %x\n",
                   c, value);
        ctrl->channels[c].regs[addr] = value;
        D(printf("stream_cmd ch=%d\n", c));
        channel_stream_cmd(ctrl, c, value);
        break;

    default:
        D(printf("%s c=%d " HWADDR_FMT_plx "\n",
                 __func__, c, addr));
        break;
    }
}

static const MemoryRegionOps dma_ops = {
    .read = dma_read,
    .write = dma_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4
    }
};

static int etraxfs_dmac_run(void *opaque)
{
    struct fs_dma_ctrl *ctrl = opaque;
    int i;
    int p = 0;

    for (i = 0;
         i < ctrl->nr_channels;
         i++)
    {
        if (ctrl->channels[i].state == RUNNING)
        {
            if (ctrl->channels[i].input) {
                p += channel_in_run(ctrl, i);
            } else {
                p += channel_out_run(ctrl, i);
            }
        }
    }
    return p;
}

int etraxfs_dmac_input(struct etraxfs_dma_client *client, 
                       void *buf, int len, int eop)
{
    return channel_in_process(client->ctrl, client->channel,
                              buf, len, eop);
}

/* Connect an IRQ line with a channel.  */
void etraxfs_dmac_connect(void *opaque, int c, qemu_irq *line, int input)
{
    struct fs_dma_ctrl *ctrl = opaque;
    ctrl->channels[c].irq = *line;
    ctrl->channels[c].input = input;
}

void etraxfs_dmac_connect_client(void *opaque, int c, 
                                 struct etraxfs_dma_client *cl)
{
    struct fs_dma_ctrl *ctrl = opaque;
    cl->ctrl = ctrl;
    cl->channel = c;
    ctrl->channels[c].client = cl;
}


static void DMA_run(void *opaque)
{
    struct fs_dma_ctrl *etraxfs_dmac = opaque;
    int p = 1;

    if (runstate_is_running())
        p = etraxfs_dmac_run(etraxfs_dmac);

    if (p)
        qemu_bh_schedule_idle(etraxfs_dmac->bh);
}

void *etraxfs_dmac_init(hwaddr base, int nr_channels)
{
    struct fs_dma_ctrl *ctrl = NULL;

    ctrl = g_malloc0(sizeof *ctrl);

    ctrl->bh = qemu_bh_new(DMA_run, ctrl);

    ctrl->nr_channels = nr_channels;
    ctrl->channels = g_malloc0(sizeof ctrl->channels[0] * nr_channels);

    memory_region_init_io(&ctrl->mmio, NULL, &dma_ops, ctrl, "etraxfs-dma",
                          nr_channels * 0x2000);
    memory_region_add_subregion(get_system_memory(), base, &ctrl->mmio);

    return ctrl;
}
