/*
 * QEMU AHCI Emulation
 *
 * Copyright (c) 2010 qiaochong@loongson.cn
 * Copyright (c) 2010 Roland Elek <elek.roland@gmail.com>
 * Copyright (c) 2010 Sebastian Herbszt <herbszt@gmx.de>
 * Copyright (c) 2010 Alexander Graf <agraf@suse.de>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/pci/msi.h"
#include "hw/i386/pc.h"
#include "hw/pci/pci.h"

#include "qemu/error-report.h"
#include "sysemu/block-backend.h"
#include "sysemu/dma.h"
#include "hw/ide/internal.h"
#include "hw/ide/pci.h"
#include "hw/ide/ahci.h"

#define DEBUG_AHCI 0

#define DPRINTF(port, fmt, ...) \
do { \
    if (DEBUG_AHCI) { \
        fprintf(stderr, "ahci: %s: [%d] ", __func__, port); \
        fprintf(stderr, fmt, ## __VA_ARGS__); \
    } \
} while (0)

static void check_cmd(AHCIState *s, int port);
static int handle_cmd(AHCIState *s, int port, uint8_t slot);
static void ahci_reset_port(AHCIState *s, int port);
static bool ahci_write_fis_d2h(AHCIDevice *ad);
static void ahci_init_d2h(AHCIDevice *ad);
static int ahci_dma_prepare_buf(IDEDMA *dma, int32_t limit);
static bool ahci_map_clb_address(AHCIDevice *ad);
static bool ahci_map_fis_address(AHCIDevice *ad);
static void ahci_unmap_clb_address(AHCIDevice *ad);
static void ahci_unmap_fis_address(AHCIDevice *ad);


static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
{
    uint32_t val;
    AHCIPortRegs *pr;
    pr = &s->dev[port].port_regs;

    switch (offset) {
    case PORT_LST_ADDR:
        val = pr->lst_addr;
        break;
    case PORT_LST_ADDR_HI:
        val = pr->lst_addr_hi;
        break;
    case PORT_FIS_ADDR:
        val = pr->fis_addr;
        break;
    case PORT_FIS_ADDR_HI:
        val = pr->fis_addr_hi;
        break;
    case PORT_IRQ_STAT:
        val = pr->irq_stat;
        break;
    case PORT_IRQ_MASK:
        val = pr->irq_mask;
        break;
    case PORT_CMD:
        val = pr->cmd;
        break;
    case PORT_TFDATA:
        val = pr->tfdata;
        break;
    case PORT_SIG:
        val = pr->sig;
        break;
    case PORT_SCR_STAT:
        if (s->dev[port].port.ifs[0].blk) {
            val = SATA_SCR_SSTATUS_DET_DEV_PRESENT_PHY_UP |
                  SATA_SCR_SSTATUS_SPD_GEN1 | SATA_SCR_SSTATUS_IPM_ACTIVE;
        } else {
            val = SATA_SCR_SSTATUS_DET_NODEV;
        }
        break;
    case PORT_SCR_CTL:
        val = pr->scr_ctl;
        break;
    case PORT_SCR_ERR:
        val = pr->scr_err;
        break;
    case PORT_SCR_ACT:
        val = pr->scr_act;
        break;
    case PORT_CMD_ISSUE:
        val = pr->cmd_issue;
        break;
    case PORT_RESERVED:
    default:
        val = 0;
    }
    DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
    return val;

}

static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)
{
    DeviceState *dev_state = s->container;
    PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
                                                           TYPE_PCI_DEVICE);

    DPRINTF(0, "raise irq\n");

    if (pci_dev && msi_enabled(pci_dev)) {
        msi_notify(pci_dev, 0);
    } else {
        qemu_irq_raise(s->irq);
    }
}

static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)
{
    DeviceState *dev_state = s->container;
    PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
                                                           TYPE_PCI_DEVICE);

    DPRINTF(0, "lower irq\n");

    if (!pci_dev || !msi_enabled(pci_dev)) {
        qemu_irq_lower(s->irq);
    }
}

static void ahci_check_irq(AHCIState *s)
{
    int i;

    DPRINTF(-1, "check irq %#x\n", s->control_regs.irqstatus);

    s->control_regs.irqstatus = 0;
    for (i = 0; i < s->ports; i++) {
        AHCIPortRegs *pr = &s->dev[i].port_regs;
        if (pr->irq_stat & pr->irq_mask) {
            s->control_regs.irqstatus |= (1 << i);
        }
    }

    if (s->control_regs.irqstatus &&
        (s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
            ahci_irq_raise(s, NULL);
    } else {
        ahci_irq_lower(s, NULL);
    }
}

static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d,
                             int irq_type)
{
    DPRINTF(d->port_no, "trigger irq %#x -> %x\n",
            irq_type, d->port_regs.irq_mask & irq_type);

    d->port_regs.irq_stat |= irq_type;
    ahci_check_irq(s);
}

static void map_page(AddressSpace *as, uint8_t **ptr, uint64_t addr,
                     uint32_t wanted)
{
    hwaddr len = wanted;

    if (*ptr) {
        dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len);
    }

    *ptr = dma_memory_map(as, addr, &len, DMA_DIRECTION_FROM_DEVICE);
    if (len < wanted) {
        dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len);
        *ptr = NULL;
    }
}

/**
 * Check the cmd register to see if we should start or stop
 * the DMA or FIS RX engines.
 *
 * @ad: Device to dis/engage.
 *
 * @return 0 on success, -1 on error.
 */
static int ahci_cond_start_engines(AHCIDevice *ad)
{
    AHCIPortRegs *pr = &ad->port_regs;
    bool cmd_start = pr->cmd & PORT_CMD_START;
    bool cmd_on    = pr->cmd & PORT_CMD_LIST_ON;
    bool fis_start = pr->cmd & PORT_CMD_FIS_RX;
    bool fis_on    = pr->cmd & PORT_CMD_FIS_ON;

    if (cmd_start && !cmd_on) {
        if (!ahci_map_clb_address(ad)) {
            pr->cmd &= ~PORT_CMD_START;
            error_report("AHCI: Failed to start DMA engine: "
                         "bad command list buffer address");
            return -1;
        }
    } else if (!cmd_start && cmd_on) {
        ahci_unmap_clb_address(ad);
    }

    if (fis_start && !fis_on) {
        if (!ahci_map_fis_address(ad)) {
            pr->cmd &= ~PORT_CMD_FIS_RX;
            error_report("AHCI: Failed to start FIS receive engine: "
                         "bad FIS receive buffer address");
            return -1;
        }
    } else if (!fis_start && fis_on) {
        ahci_unmap_fis_address(ad);
    }

    return 0;
}

static void  ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
{
    AHCIPortRegs *pr = &s->dev[port].port_regs;

    DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
    switch (offset) {
        case PORT_LST_ADDR:
            pr->lst_addr = val;
            break;
        case PORT_LST_ADDR_HI:
            pr->lst_addr_hi = val;
            break;
        case PORT_FIS_ADDR:
            pr->fis_addr = val;
            break;
        case PORT_FIS_ADDR_HI:
            pr->fis_addr_hi = val;
            break;
        case PORT_IRQ_STAT:
            pr->irq_stat &= ~val;
            ahci_check_irq(s);
            break;
        case PORT_IRQ_MASK:
            pr->irq_mask = val & 0xfdc000ff;
            ahci_check_irq(s);
            break;
        case PORT_CMD:
            /* Block any Read-only fields from being set;
             * including LIST_ON and FIS_ON.
             * The spec requires to set ICC bits to zero after the ICC change
             * is done. We don't support ICC state changes, therefore always
             * force the ICC bits to zero.
             */
            pr->cmd = (pr->cmd & PORT_CMD_RO_MASK) |
                      (val & ~(PORT_CMD_RO_MASK|PORT_CMD_ICC_MASK));

            /* Check FIS RX and CLB engines */
            ahci_cond_start_engines(&s->dev[port]);

            /* XXX usually the FIS would be pending on the bus here and
                   issuing deferred until the OS enables FIS receival.
                   Instead, we only submit it once - which works in most
                   cases, but is a hack. */
            if ((pr->cmd & PORT_CMD_FIS_ON) &&
                !s->dev[port].init_d2h_sent) {
                ahci_init_d2h(&s->dev[port]);
            }

            check_cmd(s, port);
            break;
        case PORT_TFDATA:
            /* Read Only. */
            break;
        case PORT_SIG:
            /* Read Only */
            break;
        case PORT_SCR_STAT:
            /* Read Only */
            break;
        case PORT_SCR_CTL:
            if (((pr->scr_ctl & AHCI_SCR_SCTL_DET) == 1) &&
                ((val & AHCI_SCR_SCTL_DET) == 0)) {
                ahci_reset_port(s, port);
            }
            pr->scr_ctl = val;
            break;
        case PORT_SCR_ERR:
            pr->scr_err &= ~val;
            break;
        case PORT_SCR_ACT:
            /* RW1 */
            pr->scr_act |= val;
            break;
        case PORT_CMD_ISSUE:
            pr->cmd_issue |= val;
            check_cmd(s, port);
            break;
        default:
            break;
    }
}

static uint64_t ahci_mem_read_32(void *opaque, hwaddr addr)
{
    AHCIState *s = opaque;
    uint32_t val = 0;

    if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
        switch (addr) {
        case HOST_CAP:
            val = s->control_regs.cap;
            break;
        case HOST_CTL:
            val = s->control_regs.ghc;
            break;
        case HOST_IRQ_STAT:
            val = s->control_regs.irqstatus;
            break;
        case HOST_PORTS_IMPL:
            val = s->control_regs.impl;
            break;
        case HOST_VERSION:
            val = s->control_regs.version;
            break;
        }

        DPRINTF(-1, "(addr 0x%08X), val 0x%08X\n", (unsigned) addr, val);
    } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
               (addr < (AHCI_PORT_REGS_START_ADDR +
                (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
        val = ahci_port_read(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
                             addr & AHCI_PORT_ADDR_OFFSET_MASK);
    }

    return val;
}


/**
 * AHCI 1.3 section 3 ("HBA Memory Registers")
 * Support unaligned 8/16/32 bit reads, and 64 bit aligned reads.
 * Caller is responsible for masking unwanted higher order bytes.
 */
static uint64_t ahci_mem_read(void *opaque, hwaddr addr, unsigned size)
{
    hwaddr aligned = addr & ~0x3;
    int ofst = addr - aligned;
    uint64_t lo = ahci_mem_read_32(opaque, aligned);
    uint64_t hi;
    uint64_t val;

    /* if < 8 byte read does not cross 4 byte boundary */
    if (ofst + size <= 4) {
        val = lo >> (ofst * 8);
    } else {
        g_assert_cmpint(size, >, 1);

        /* If the 64bit read is unaligned, we will produce undefined
         * results. AHCI does not support unaligned 64bit reads. */
        hi = ahci_mem_read_32(opaque, aligned + 4);
        val = (hi << 32 | lo) >> (ofst * 8);
    }

    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
            addr, val, size);
    return val;
}


static void ahci_mem_write(void *opaque, hwaddr addr,
                           uint64_t val, unsigned size)
{
    AHCIState *s = opaque;

    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
            addr, val, size);

    /* Only aligned reads are allowed on AHCI */
    if (addr & 3) {
        fprintf(stderr, "ahci: Mis-aligned write to addr 0x"
                TARGET_FMT_plx "\n", addr);
        return;
    }

    if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
        DPRINTF(-1, "(addr 0x%08X), val 0x%08"PRIX64"\n", (unsigned) addr, val);

        switch (addr) {
            case HOST_CAP: /* R/WO, RO */
                /* FIXME handle R/WO */
                break;
            case HOST_CTL: /* R/W */
                if (val & HOST_CTL_RESET) {
                    DPRINTF(-1, "HBA Reset\n");
                    ahci_reset(s);
                } else {
                    s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
                    ahci_check_irq(s);
                }
                break;
            case HOST_IRQ_STAT: /* R/WC, RO */
                s->control_regs.irqstatus &= ~val;
                ahci_check_irq(s);
                break;
            case HOST_PORTS_IMPL: /* R/WO, RO */
                /* FIXME handle R/WO */
                break;
            case HOST_VERSION: /* RO */
                /* FIXME report write? */
                break;
            default:
                DPRINTF(-1, "write to unknown register 0x%x\n", (unsigned)addr);
        }
    } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
               (addr < (AHCI_PORT_REGS_START_ADDR +
                (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
        ahci_port_write(s, (addr - AHCI_PORT_REGS_START_ADDR) >> 7,
                        addr & AHCI_PORT_ADDR_OFFSET_MASK, val);
    }

}

static const MemoryRegionOps ahci_mem_ops = {
    .read = ahci_mem_read,
    .write = ahci_mem_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static uint64_t ahci_idp_read(void *opaque, hwaddr addr,
                              unsigned size)
{
    AHCIState *s = opaque;

    if (addr == s->idp_offset) {
        /* index register */
        return s->idp_index;
    } else if (addr == s->idp_offset + 4) {
        /* data register - do memory read at location selected by index */
        return ahci_mem_read(opaque, s->idp_index, size);
    } else {
        return 0;
    }
}

static void ahci_idp_write(void *opaque, hwaddr addr,
                           uint64_t val, unsigned size)
{
    AHCIState *s = opaque;

    if (addr == s->idp_offset) {
        /* index register - mask off reserved bits */
        s->idp_index = (uint32_t)val & ((AHCI_MEM_BAR_SIZE - 1) & ~3);
    } else if (addr == s->idp_offset + 4) {
        /* data register - do memory write at location selected by index */
        ahci_mem_write(opaque, s->idp_index, val, size);
    }
}

static const MemoryRegionOps ahci_idp_ops = {
    .read = ahci_idp_read,
    .write = ahci_idp_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};


static void ahci_reg_init(AHCIState *s)
{
    int i;

    s->control_regs.cap = (s->ports - 1) |
                          (AHCI_NUM_COMMAND_SLOTS << 8) |
                          (AHCI_SUPPORTED_SPEED_GEN1 << AHCI_SUPPORTED_SPEED) |
                          HOST_CAP_NCQ | HOST_CAP_AHCI;

    s->control_regs.impl = (1 << s->ports) - 1;

    s->control_regs.version = AHCI_VERSION_1_0;

    for (i = 0; i < s->ports; i++) {
        s->dev[i].port_state = STATE_RUN;
    }
}

static void check_cmd(AHCIState *s, int port)
{
    AHCIPortRegs *pr = &s->dev[port].port_regs;
    uint8_t slot;

    if ((pr->cmd & PORT_CMD_START) && pr->cmd_issue) {
        for (slot = 0; (slot < 32) && pr->cmd_issue; slot++) {
            if ((pr->cmd_issue & (1U << slot)) &&
                !handle_cmd(s, port, slot)) {
                pr->cmd_issue &= ~(1U << slot);
            }
        }
    }
}

static void ahci_check_cmd_bh(void *opaque)
{
    AHCIDevice *ad = opaque;

    qemu_bh_delete(ad->check_bh);
    ad->check_bh = NULL;

    if ((ad->busy_slot != -1) &&
        !(ad->port.ifs[0].status & (BUSY_STAT|DRQ_STAT))) {
        /* no longer busy */
        ad->port_regs.cmd_issue &= ~(1 << ad->busy_slot);
        ad->busy_slot = -1;
    }

    check_cmd(ad->hba, ad->port_no);
}

static void ahci_init_d2h(AHCIDevice *ad)
{
    IDEState *ide_state = &ad->port.ifs[0];
    AHCIPortRegs *pr = &ad->port_regs;

    if (ad->init_d2h_sent) {
        return;
    }

    if (ahci_write_fis_d2h(ad)) {
        ad->init_d2h_sent = true;
        /* We're emulating receiving the first Reg H2D Fis from the device;
         * Update the SIG register, but otherwise proceed as normal. */
        pr->sig = ((uint32_t)ide_state->hcyl << 24) |
            (ide_state->lcyl << 16) |
            (ide_state->sector << 8) |
            (ide_state->nsector & 0xFF);
    }
}

static void ahci_set_signature(AHCIDevice *ad, uint32_t sig)
{
    IDEState *s = &ad->port.ifs[0];
    s->hcyl = sig >> 24 & 0xFF;
    s->lcyl = sig >> 16 & 0xFF;
    s->sector = sig >> 8 & 0xFF;
    s->nsector = sig & 0xFF;

    DPRINTF(ad->port_no, "set hcyl:lcyl:sect:nsect = 0x%08x\n", sig);
}

static void ahci_reset_port(AHCIState *s, int port)
{
    AHCIDevice *d = &s->dev[port];
    AHCIPortRegs *pr = &d->port_regs;
    IDEState *ide_state = &d->port.ifs[0];
    int i;

    DPRINTF(port, "reset port\n");

    ide_bus_reset(&d->port);
    ide_state->ncq_queues = AHCI_MAX_CMDS;

    pr->scr_stat = 0;
    pr->scr_err = 0;
    pr->scr_act = 0;
    pr->tfdata = 0x7F;
    pr->sig = 0xFFFFFFFF;
    d->busy_slot = -1;
    d->init_d2h_sent = false;

    ide_state = &s->dev[port].port.ifs[0];
    if (!ide_state->blk) {
        return;
    }

    /* reset ncq queue */
    for (i = 0; i < AHCI_MAX_CMDS; i++) {
        NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[i];
        ncq_tfs->halt = false;
        if (!ncq_tfs->used) {
            continue;
        }

        if (ncq_tfs->aiocb) {
            blk_aio_cancel(ncq_tfs->aiocb);
            ncq_tfs->aiocb = NULL;
        }

        /* Maybe we just finished the request thanks to blk_aio_cancel() */
        if (!ncq_tfs->used) {
            continue;
        }

        qemu_sglist_destroy(&ncq_tfs->sglist);
        ncq_tfs->used = 0;
    }

    s->dev[port].port_state = STATE_RUN;
    if (ide_state->drive_kind == IDE_CD) {
        ahci_set_signature(d, SATA_SIGNATURE_CDROM);\
        ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
    } else {
        ahci_set_signature(d, SATA_SIGNATURE_DISK);
        ide_state->status = SEEK_STAT | WRERR_STAT;
    }

    ide_state->error = 1;
    ahci_init_d2h(d);
}

static void debug_print_fis(uint8_t *fis, int cmd_len)
{
#if DEBUG_AHCI
    int i;

    fprintf(stderr, "fis:");
    for (i = 0; i < cmd_len; i++) {
        if ((i & 0xf) == 0) {
            fprintf(stderr, "\n%02x:",i);
        }
        fprintf(stderr, "%02x ",fis[i]);
    }
    fprintf(stderr, "\n");
#endif
}

static bool ahci_map_fis_address(AHCIDevice *ad)
{
    AHCIPortRegs *pr = &ad->port_regs;
    map_page(ad->hba->as, &ad->res_fis,
             ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
    if (ad->res_fis != NULL) {
        pr->cmd |= PORT_CMD_FIS_ON;
        return true;
    }

    pr->cmd &= ~PORT_CMD_FIS_ON;
    return false;
}

static void ahci_unmap_fis_address(AHCIDevice *ad)
{
    if (ad->res_fis == NULL) {
        DPRINTF(ad->port_no, "Attempt to unmap NULL FIS address\n");
        return;
    }
    ad->port_regs.cmd &= ~PORT_CMD_FIS_ON;
    dma_memory_unmap(ad->hba->as, ad->res_fis, 256,
                     DMA_DIRECTION_FROM_DEVICE, 256);
    ad->res_fis = NULL;
}

static bool ahci_map_clb_address(AHCIDevice *ad)
{
    AHCIPortRegs *pr = &ad->port_regs;
    ad->cur_cmd = NULL;
    map_page(ad->hba->as, &ad->lst,
             ((uint64_t)pr->lst_addr_hi << 32) | pr->lst_addr, 1024);
    if (ad->lst != NULL) {
        pr->cmd |= PORT_CMD_LIST_ON;
        return true;
    }

    pr->cmd &= ~PORT_CMD_LIST_ON;
    return false;
}

static void ahci_unmap_clb_address(AHCIDevice *ad)
{
    if (ad->lst == NULL) {
        DPRINTF(ad->port_no, "Attempt to unmap NULL CLB address\n");
        return;
    }
    ad->port_regs.cmd &= ~PORT_CMD_LIST_ON;
    dma_memory_unmap(ad->hba->as, ad->lst, 1024,
                     DMA_DIRECTION_FROM_DEVICE, 1024);
    ad->lst = NULL;
}

static void ahci_write_fis_sdb(AHCIState *s, NCQTransferState *ncq_tfs)
{
    AHCIDevice *ad = ncq_tfs->drive;
    AHCIPortRegs *pr = &ad->port_regs;
    IDEState *ide_state;
    SDBFIS *sdb_fis;

    if (!ad->res_fis ||
        !(pr->cmd & PORT_CMD_FIS_RX)) {
        return;
    }

    sdb_fis = (SDBFIS *)&ad->res_fis[RES_FIS_SDBFIS];
    ide_state = &ad->port.ifs[0];

    sdb_fis->type = SATA_FIS_TYPE_SDB;
    /* Interrupt pending & Notification bit */
    sdb_fis->flags = 0x40; /* Interrupt bit, always 1 for NCQ */
    sdb_fis->status = ide_state->status & 0x77;
    sdb_fis->error = ide_state->error;
    /* update SAct field in SDB_FIS */
    sdb_fis->payload = cpu_to_le32(ad->finished);

    /* Update shadow registers (except BSY 0x80 and DRQ 0x08) */
    pr->tfdata = (ad->port.ifs[0].error << 8) |
        (ad->port.ifs[0].status & 0x77) |
        (pr->tfdata & 0x88);
    pr->scr_act &= ~ad->finished;
    ad->finished = 0;

    /* Trigger IRQ if interrupt bit is set (which currently, it always is) */
    if (sdb_fis->flags & 0x40) {
        ahci_trigger_irq(s, ad, PORT_IRQ_SDB_FIS);
    }
}

static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len)
{
    AHCIPortRegs *pr = &ad->port_regs;
    uint8_t *pio_fis;
    IDEState *s = &ad->port.ifs[0];

    if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) {
        return;
    }

    pio_fis = &ad->res_fis[RES_FIS_PSFIS];

    pio_fis[0] = SATA_FIS_TYPE_PIO_SETUP;
    pio_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
    pio_fis[2] = s->status;
    pio_fis[3] = s->error;

    pio_fis[4] = s->sector;
    pio_fis[5] = s->lcyl;
    pio_fis[6] = s->hcyl;
    pio_fis[7] = s->select;
    pio_fis[8] = s->hob_sector;
    pio_fis[9] = s->hob_lcyl;
    pio_fis[10] = s->hob_hcyl;
    pio_fis[11] = 0;
    pio_fis[12] = s->nsector & 0xFF;
    pio_fis[13] = (s->nsector >> 8) & 0xFF;
    pio_fis[14] = 0;
    pio_fis[15] = s->status;
    pio_fis[16] = len & 255;
    pio_fis[17] = len >> 8;
    pio_fis[18] = 0;
    pio_fis[19] = 0;

    /* Update shadow registers: */
    pr->tfdata = (ad->port.ifs[0].error << 8) |
        ad->port.ifs[0].status;

    if (pio_fis[2] & ERR_STAT) {
        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_TF_ERR);
    }

    ahci_trigger_irq(ad->hba, ad, PORT_IRQ_PIOS_FIS);
}

static bool ahci_write_fis_d2h(AHCIDevice *ad)
{
    AHCIPortRegs *pr = &ad->port_regs;
    uint8_t *d2h_fis;
    int i;
    IDEState *s = &ad->port.ifs[0];

    if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) {
        return false;
    }

    d2h_fis = &ad->res_fis[RES_FIS_RFIS];

    d2h_fis[0] = SATA_FIS_TYPE_REGISTER_D2H;
    d2h_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
    d2h_fis[2] = s->status;
    d2h_fis[3] = s->error;

    d2h_fis[4] = s->sector;
    d2h_fis[5] = s->lcyl;
    d2h_fis[6] = s->hcyl;
    d2h_fis[7] = s->select;
    d2h_fis[8] = s->hob_sector;
    d2h_fis[9] = s->hob_lcyl;
    d2h_fis[10] = s->hob_hcyl;
    d2h_fis[11] = 0;
    d2h_fis[12] = s->nsector & 0xFF;
    d2h_fis[13] = (s->nsector >> 8) & 0xFF;
    for (i = 14; i < 20; i++) {
        d2h_fis[i] = 0;
    }

    /* Update shadow registers: */
    pr->tfdata = (ad->port.ifs[0].error << 8) |
        ad->port.ifs[0].status;

    if (d2h_fis[2] & ERR_STAT) {
        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_TF_ERR);
    }

    ahci_trigger_irq(ad->hba, ad, PORT_IRQ_D2H_REG_FIS);
    return true;
}

static int prdt_tbl_entry_size(const AHCI_SG *tbl)
{
    /* flags_size is zero-based */
    return (le32_to_cpu(tbl->flags_size) & AHCI_PRDT_SIZE_MASK) + 1;
}

/**
 * Fetch entries in a guest-provided PRDT and convert it into a QEMU SGlist.
 * @ad: The AHCIDevice for whom we are building the SGList.
 * @sglist: The SGList target to add PRD entries to.
 * @cmd: The AHCI Command Header that describes where the PRDT is.
 * @limit: The remaining size of the S/ATA transaction, in bytes.
 * @offset: The number of bytes already transferred, in bytes.
 *
 * The AHCI PRDT can describe up to 256GiB. S/ATA only support transactions of
 * up to 32MiB as of ATA8-ACS3 rev 1b, assuming a 512 byte sector size. We stop
 * building the sglist from the PRDT as soon as we hit @limit bytes,
 * which is <= INT32_MAX/2GiB.
 */
static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist,
                                AHCICmdHdr *cmd, int64_t limit, uint64_t offset)
{
    uint16_t opts = le16_to_cpu(cmd->opts);
    uint16_t prdtl = le16_to_cpu(cmd->prdtl);
    uint64_t cfis_addr = le64_to_cpu(cmd->tbl_addr);
    uint64_t prdt_addr = cfis_addr + 0x80;
    dma_addr_t prdt_len = (prdtl * sizeof(AHCI_SG));
    dma_addr_t real_prdt_len = prdt_len;
    uint8_t *prdt;
    int i;
    int r = 0;
    uint64_t sum = 0;
    int off_idx = -1;
    int64_t off_pos = -1;
    int tbl_entry_size;
    IDEBus *bus = &ad->port;
    BusState *qbus = BUS(bus);

    if (!prdtl) {
        DPRINTF(ad->port_no, "no sg list given by guest: 0x%08x\n", opts);
        return -1;
    }

    /* map PRDT */
    if (!(prdt = dma_memory_map(ad->hba->as, prdt_addr, &prdt_len,
                                DMA_DIRECTION_TO_DEVICE))){
        DPRINTF(ad->port_no, "map failed\n");
        return -1;
    }

    if (prdt_len < real_prdt_len) {
        DPRINTF(ad->port_no, "mapped less than expected\n");
        r = -1;
        goto out;
    }

    /* Get entries in the PRDT, init a qemu sglist accordingly */
    if (prdtl > 0) {
        AHCI_SG *tbl = (AHCI_SG *)prdt;
        sum = 0;
        for (i = 0; i < prdtl; i++) {
            tbl_entry_size = prdt_tbl_entry_size(&tbl[i]);
            if (offset < (sum + tbl_entry_size)) {
                off_idx = i;
                off_pos = offset - sum;
                break;
            }
            sum += tbl_entry_size;
        }
        if ((off_idx == -1) || (off_pos < 0) || (off_pos > tbl_entry_size)) {
            DPRINTF(ad->port_no, "%s: Incorrect offset! "
                            "off_idx: %d, off_pos: %"PRId64"\n",
                            __func__, off_idx, off_pos);
            r = -1;
            goto out;
        }

        qemu_sglist_init(sglist, qbus->parent, (prdtl - off_idx),
                         ad->hba->as);
        qemu_sglist_add(sglist, le64_to_cpu(tbl[off_idx].addr) + off_pos,
                        MIN(prdt_tbl_entry_size(&tbl[off_idx]) - off_pos,
                            limit));

        for (i = off_idx + 1; i < prdtl && sglist->size < limit; i++) {
            qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr),
                            MIN(prdt_tbl_entry_size(&tbl[i]),
                                limit - sglist->size));
        }
    }

out:
    dma_memory_unmap(ad->hba->as, prdt, prdt_len,
                     DMA_DIRECTION_TO_DEVICE, prdt_len);
    return r;
}

static void ncq_err(NCQTransferState *ncq_tfs)
{
    IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];

    ide_state->error = ABRT_ERR;
    ide_state->status = READY_STAT | ERR_STAT;
    ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
    qemu_sglist_destroy(&ncq_tfs->sglist);
    ncq_tfs->used = 0;
}

static void ncq_finish(NCQTransferState *ncq_tfs)
{
    /* If we didn't error out, set our finished bit. Errored commands
     * do not get a bit set for the SDB FIS ACT register, nor do they
     * clear the outstanding bit in scr_act (PxSACT). */
    if (!(ncq_tfs->drive->port_regs.scr_err & (1 << ncq_tfs->tag))) {
        ncq_tfs->drive->finished |= (1 << ncq_tfs->tag);
    }

    ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs);

    DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
            ncq_tfs->tag);

    block_acct_done(blk_get_stats(ncq_tfs->drive->port.ifs[0].blk),
                    &ncq_tfs->acct);
    qemu_sglist_destroy(&ncq_tfs->sglist);
    ncq_tfs->used = 0;
}

static void ncq_cb(void *opaque, int ret)
{
    NCQTransferState *ncq_tfs = (NCQTransferState *)opaque;
    IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];

    ncq_tfs->aiocb = NULL;
    if (ret == -ECANCELED) {
        return;
    }

    if (ret < 0) {
        bool is_read = ncq_tfs->cmd == READ_FPDMA_QUEUED;
        BlockErrorAction action = blk_get_error_action(ide_state->blk,
                                                       is_read, -ret);
        if (action == BLOCK_ERROR_ACTION_STOP) {
            ncq_tfs->halt = true;
            ide_state->bus->error_status = IDE_RETRY_HBA;
        } else if (action == BLOCK_ERROR_ACTION_REPORT) {
            ncq_err(ncq_tfs);
        }
        blk_error_action(ide_state->blk, action, is_read, -ret);
    } else {
        ide_state->status = READY_STAT | SEEK_STAT;
    }

    if (!ncq_tfs->halt) {
        ncq_finish(ncq_tfs);
    }
}

static int is_ncq(uint8_t ata_cmd)
{
    /* Based on SATA 3.2 section 13.6.3.2 */
    switch (ata_cmd) {
    case READ_FPDMA_QUEUED:
    case WRITE_FPDMA_QUEUED:
    case NCQ_NON_DATA:
    case RECEIVE_FPDMA_QUEUED:
    case SEND_FPDMA_QUEUED:
        return 1;
    default:
        return 0;
    }
}

static void execute_ncq_command(NCQTransferState *ncq_tfs)
{
    AHCIDevice *ad = ncq_tfs->drive;
    IDEState *ide_state = &ad->port.ifs[0];
    int port = ad->port_no;

    g_assert(is_ncq(ncq_tfs->cmd));
    ncq_tfs->halt = false;

    switch (ncq_tfs->cmd) {
    case READ_FPDMA_QUEUED:
        DPRINTF(port, "NCQ reading %d sectors from LBA %"PRId64", tag %d\n",
                ncq_tfs->sector_count, ncq_tfs->lba, ncq_tfs->tag);

        DPRINTF(port, "tag %d aio read %"PRId64"\n",
                ncq_tfs->tag, ncq_tfs->lba);

        dma_acct_start(ide_state->blk, &ncq_tfs->acct,
                       &ncq_tfs->sglist, BLOCK_ACCT_READ);
        ncq_tfs->aiocb = dma_blk_read(ide_state->blk, &ncq_tfs->sglist,
                                      ncq_tfs->lba << BDRV_SECTOR_BITS,
                                      BDRV_SECTOR_SIZE,
                                      ncq_cb, ncq_tfs);
        break;
    case WRITE_FPDMA_QUEUED:
        DPRINTF(port, "NCQ writing %d sectors to LBA %"PRId64", tag %d\n",
                ncq_tfs->sector_count, ncq_tfs->lba, ncq_tfs->tag);

        DPRINTF(port, "tag %d aio write %"PRId64"\n",
                ncq_tfs->tag, ncq_tfs->lba);

        dma_acct_start(ide_state->blk, &ncq_tfs->acct,
                       &ncq_tfs->sglist, BLOCK_ACCT_WRITE);
        ncq_tfs->aiocb = dma_blk_write(ide_state->blk, &ncq_tfs->sglist,
                                       ncq_tfs->lba << BDRV_SECTOR_BITS,
                                       BDRV_SECTOR_SIZE,
                                       ncq_cb, ncq_tfs);
        break;
    default:
        DPRINTF(port, "error: unsupported NCQ command (0x%02x) received\n",
                ncq_tfs->cmd);
        ncq_err(ncq_tfs);
    }
}


static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
                                uint8_t slot)
{
    AHCIDevice *ad = &s->dev[port];
    IDEState *ide_state = &ad->port.ifs[0];
    NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;
    uint8_t tag = ncq_fis->tag >> 3;
    NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag];
    size_t size;

    g_assert(is_ncq(ncq_fis->command));
    if (ncq_tfs->used) {
        /* error - already in use */
        fprintf(stderr, "%s: tag %d already used\n", __FUNCTION__, tag);
        return;
    }

    ncq_tfs->used = 1;
    ncq_tfs->drive = ad;
    ncq_tfs->slot = slot;
    ncq_tfs->cmdh = &((AHCICmdHdr *)ad->lst)[slot];
    ncq_tfs->cmd = ncq_fis->command;
    ncq_tfs->lba = ((uint64_t)ncq_fis->lba5 << 40) |
                   ((uint64_t)ncq_fis->lba4 << 32) |
                   ((uint64_t)ncq_fis->lba3 << 24) |
                   ((uint64_t)ncq_fis->lba2 << 16) |
                   ((uint64_t)ncq_fis->lba1 << 8) |
                   (uint64_t)ncq_fis->lba0;
    ncq_tfs->tag = tag;

    /* Sanity-check the NCQ packet */
    if (tag != slot) {
        DPRINTF(port, "Warn: NCQ slot (%d) did not match the given tag (%d)\n",
                slot, tag);
    }

    if (ncq_fis->aux0 || ncq_fis->aux1 || ncq_fis->aux2 || ncq_fis->aux3) {
        DPRINTF(port, "Warn: Attempt to use NCQ auxiliary fields.\n");
    }
    if (ncq_fis->prio || ncq_fis->icc) {
        DPRINTF(port, "Warn: Unsupported attempt to use PRIO/ICC fields\n");
    }
    if (ncq_fis->fua & NCQ_FIS_FUA_MASK) {
        DPRINTF(port, "Warn: Unsupported attempt to use Force Unit Access\n");
    }
    if (ncq_fis->tag & NCQ_FIS_RARC_MASK) {
        DPRINTF(port, "Warn: Unsupported attempt to use Rebuild Assist\n");
    }

    ncq_tfs->sector_count = ((ncq_fis->sector_count_high << 8) |
                             ncq_fis->sector_count_low);
    if (!ncq_tfs->sector_count) {
        ncq_tfs->sector_count = 0x10000;
    }
    size = ncq_tfs->sector_count * 512;
    ahci_populate_sglist(ad, &ncq_tfs->sglist, ncq_tfs->cmdh, size, 0);

    if (ncq_tfs->sglist.size < size) {
        error_report("ahci: PRDT length for NCQ command (0x%zx) "
                     "is smaller than the requested size (0x%zx)",
                     ncq_tfs->sglist.size, size);
        ncq_err(ncq_tfs);
        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_OVERFLOW);
        return;
    } else if (ncq_tfs->sglist.size != size) {
        DPRINTF(port, "Warn: PRDTL (0x%zx)"
                " does not match requested size (0x%zx)",
                ncq_tfs->sglist.size, size);
    }

    DPRINTF(port, "NCQ transfer LBA from %"PRId64" to %"PRId64", "
            "drive max %"PRId64"\n",
            ncq_tfs->lba, ncq_tfs->lba + ncq_tfs->sector_count - 1,
            ide_state->nb_sectors - 1);

    execute_ncq_command(ncq_tfs);
}

static AHCICmdHdr *get_cmd_header(AHCIState *s, uint8_t port, uint8_t slot)
{
    if (port >= s->ports || slot >= AHCI_MAX_CMDS) {
        return NULL;
    }

    return s->dev[port].lst ? &((AHCICmdHdr *)s->dev[port].lst)[slot] : NULL;
}

static void handle_reg_h2d_fis(AHCIState *s, int port,
                               uint8_t slot, uint8_t *cmd_fis)
{
    IDEState *ide_state = &s->dev[port].port.ifs[0];
    AHCICmdHdr *cmd = get_cmd_header(s, port, slot);
    uint16_t opts = le16_to_cpu(cmd->opts);

    if (cmd_fis[1] & 0x0F) {
        DPRINTF(port, "Port Multiplier not supported."
                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
        return;
    }

    if (cmd_fis[1] & 0x70) {
        DPRINTF(port, "Reserved flags set in H2D Register FIS."
                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
        return;
    }

    if (!(cmd_fis[1] & SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER)) {
        switch (s->dev[port].port_state) {
        case STATE_RUN:
            if (cmd_fis[15] & ATA_SRST) {
                s->dev[port].port_state = STATE_RESET;
            }
            break;
        case STATE_RESET:
            if (!(cmd_fis[15] & ATA_SRST)) {
                ahci_reset_port(s, port);
            }
            break;
        }
        return;
    }

    /* Check for NCQ command */
    if (is_ncq(cmd_fis[2])) {
        process_ncq_command(s, port, cmd_fis, slot);
        return;
    }

    /* Decompose the FIS:
     * AHCI does not interpret FIS packets, it only forwards them.
     * SATA 1.0 describes how to decode LBA28 and CHS FIS packets.
     * Later specifications, e.g, SATA 3.2, describe LBA48 FIS packets.
     *
     * ATA4 describes sector number for LBA28/CHS commands.
     * ATA6 describes sector number for LBA48 commands.
     * ATA8 deprecates CHS fully, describing only LBA28/48.
     *
     * We dutifully convert the FIS into IDE registers, and allow the
     * core layer to interpret them as needed. */
    ide_state->feature = cmd_fis[3];
    ide_state->sector = cmd_fis[4];      /* LBA 7:0 */
    ide_state->lcyl = cmd_fis[5];        /* LBA 15:8  */
    ide_state->hcyl = cmd_fis[6];        /* LBA 23:16 */
    ide_state->select = cmd_fis[7];      /* LBA 27:24 (LBA28) */
    ide_state->hob_sector = cmd_fis[8];  /* LBA 31:24 */
    ide_state->hob_lcyl = cmd_fis[9];    /* LBA 39:32 */
    ide_state->hob_hcyl = cmd_fis[10];   /* LBA 47:40 */
    ide_state->hob_feature = cmd_fis[11];
    ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
    /* 14, 16, 17, 18, 19: Reserved (SATA 1.0) */
    /* 15: Only valid when UPDATE_COMMAND not set. */

    /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
     * table to ide_state->io_buffer */
    if (opts & AHCI_CMD_ATAPI) {
        memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
        debug_print_fis(ide_state->io_buffer, 0x10);
        s->dev[port].done_atapi_packet = false;
        /* XXX send PIO setup FIS */
    }

    ide_state->error = 0;

    /* Reset transferred byte counter */
    cmd->status = 0;

    /* We're ready to process the command in FIS byte 2. */
    ide_exec_cmd(&s->dev[port].port, cmd_fis[2]);
}

static int handle_cmd(AHCIState *s, int port, uint8_t slot)
{
    IDEState *ide_state;
    uint64_t tbl_addr;
    AHCICmdHdr *cmd;
    uint8_t *cmd_fis;
    dma_addr_t cmd_len;

    if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
        /* Engine currently busy, try again later */
        DPRINTF(port, "engine busy\n");
        return -1;
    }

    if (!s->dev[port].lst) {
        DPRINTF(port, "error: lst not given but cmd handled");
        return -1;
    }
    cmd = get_cmd_header(s, port, slot);
    /* remember current slot handle for later */
    s->dev[port].cur_cmd = cmd;

    /* The device we are working for */
    ide_state = &s->dev[port].port.ifs[0];
    if (!ide_state->blk) {
        DPRINTF(port, "error: guest accessed unused port");
        return -1;
    }

    tbl_addr = le64_to_cpu(cmd->tbl_addr);
    cmd_len = 0x80;
    cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
                             DMA_DIRECTION_FROM_DEVICE);
    if (!cmd_fis) {
        DPRINTF(port, "error: guest passed us an invalid cmd fis\n");
        return -1;
    } else if (cmd_len != 0x80) {
        ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_HBUS_ERR);
        DPRINTF(port, "error: dma_memory_map failed: "
                "(len(%02"PRIx64") != 0x80)\n",
                cmd_len);
        goto out;
    }
    debug_print_fis(cmd_fis, 0x80);

    switch (cmd_fis[0]) {
        case SATA_FIS_TYPE_REGISTER_H2D:
            handle_reg_h2d_fis(s, port, slot, cmd_fis);
            break;
        default:
            DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
                          "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
                          cmd_fis[2]);
            break;
    }

out:
    dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_FROM_DEVICE,
                     cmd_len);

    if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
        /* async command, complete later */
        s->dev[port].busy_slot = slot;
        return -1;
    }

    /* done handling the command */
    return 0;
}

/* DMA dev <-> ram */
static void ahci_start_transfer(IDEDMA *dma)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    IDEState *s = &ad->port.ifs[0];
    uint32_t size = (uint32_t)(s->data_end - s->data_ptr);
    /* write == ram -> device */
    uint16_t opts = le16_to_cpu(ad->cur_cmd->opts);
    int is_write = opts & AHCI_CMD_WRITE;
    int is_atapi = opts & AHCI_CMD_ATAPI;
    int has_sglist = 0;

    if (is_atapi && !ad->done_atapi_packet) {
        /* already prepopulated iobuffer */
        ad->done_atapi_packet = true;
        size = 0;
        goto out;
    }

    if (ahci_dma_prepare_buf(dma, size)) {
        has_sglist = 1;
    }

    DPRINTF(ad->port_no, "%sing %d bytes on %s w/%s sglist\n",
            is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata",
            has_sglist ? "" : "o");

    if (has_sglist && size) {
        if (is_write) {
            dma_buf_write(s->data_ptr, size, &s->sg);
        } else {
            dma_buf_read(s->data_ptr, size, &s->sg);
        }
    }

out:
    /* declare that we processed everything */
    s->data_ptr = s->data_end;

    /* Update number of transferred bytes, destroy sglist */
    dma_buf_commit(s, size);

    s->end_transfer_func(s);

    if (!(s->status & DRQ_STAT)) {
        /* done with PIO send/receive */
        ahci_write_fis_pio(ad, le32_to_cpu(ad->cur_cmd->status));
    }
}

static void ahci_start_dma(IDEDMA *dma, IDEState *s,
                           BlockCompletionFunc *dma_cb)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    DPRINTF(ad->port_no, "\n");
    s->io_buffer_offset = 0;
    dma_cb(s, 0);
}

static void ahci_restart_dma(IDEDMA *dma)
{
    /* Nothing to do, ahci_start_dma already resets s->io_buffer_offset.  */
}

/**
 * IDE/PIO restarts are handled by the core layer, but NCQ commands
 * need an extra kick from the AHCI HBA.
 */
static void ahci_restart(IDEDMA *dma)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    int i;

    for (i = 0; i < AHCI_MAX_CMDS; i++) {
        NCQTransferState *ncq_tfs = &ad->ncq_tfs[i];
        if (ncq_tfs->halt) {
            execute_ncq_command(ncq_tfs);
        }
    }
}

/**
 * Called in DMA and PIO R/W chains to read the PRDT.
 * Not shared with NCQ pathways.
 */
static int32_t ahci_dma_prepare_buf(IDEDMA *dma, int32_t limit)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    IDEState *s = &ad->port.ifs[0];

    if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd,
                             limit, s->io_buffer_offset) == -1) {
        DPRINTF(ad->port_no, "ahci_dma_prepare_buf failed.\n");
        return -1;
    }
    s->io_buffer_size = s->sg.size;

    DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
    return s->io_buffer_size;
}

/**
 * Updates the command header with a bytes-read value.
 * Called via dma_buf_commit, for both DMA and PIO paths.
 * sglist destruction is handled within dma_buf_commit.
 */
static void ahci_commit_buf(IDEDMA *dma, uint32_t tx_bytes)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);

    tx_bytes += le32_to_cpu(ad->cur_cmd->status);
    ad->cur_cmd->status = cpu_to_le32(tx_bytes);
}

static int ahci_dma_rw_buf(IDEDMA *dma, int is_write)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
    IDEState *s = &ad->port.ifs[0];
    uint8_t *p = s->io_buffer + s->io_buffer_index;
    int l = s->io_buffer_size - s->io_buffer_index;

    if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd, l, s->io_buffer_offset)) {
        return 0;
    }

    if (is_write) {
        dma_buf_read(p, l, &s->sg);
    } else {
        dma_buf_write(p, l, &s->sg);
    }

    /* free sglist, update byte count */
    dma_buf_commit(s, l);

    s->io_buffer_index += l;

    DPRINTF(ad->port_no, "len=%#x\n", l);

    return 1;
}

static void ahci_cmd_done(IDEDMA *dma)
{
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);

    DPRINTF(ad->port_no, "cmd done\n");

    /* update d2h status */
    ahci_write_fis_d2h(ad);

    if (!ad->check_bh) {
        /* maybe we still have something to process, check later */
        ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
        qemu_bh_schedule(ad->check_bh);
    }
}

static void ahci_irq_set(void *opaque, int n, int level)
{
}

static const IDEDMAOps ahci_dma_ops = {
    .start_dma = ahci_start_dma,
    .restart = ahci_restart,
    .restart_dma = ahci_restart_dma,
    .start_transfer = ahci_start_transfer,
    .prepare_buf = ahci_dma_prepare_buf,
    .commit_buf = ahci_commit_buf,
    .rw_buf = ahci_dma_rw_buf,
    .cmd_done = ahci_cmd_done,
};

void ahci_init(AHCIState *s, DeviceState *qdev)
{
    s->container = qdev;
    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
    memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s,
                          "ahci", AHCI_MEM_BAR_SIZE);
    memory_region_init_io(&s->idp, OBJECT(qdev), &ahci_idp_ops, s,
                          "ahci-idp", 32);
}

void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
{
    qemu_irq *irqs;
    int i;

    s->as = as;
    s->ports = ports;
    s->dev = g_new0(AHCIDevice, ports);
    ahci_reg_init(s);
    irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);
    for (i = 0; i < s->ports; i++) {
        AHCIDevice *ad = &s->dev[i];

        ide_bus_new(&ad->port, sizeof(ad->port), qdev, i, 1);
        ide_init2(&ad->port, irqs[i]);

        ad->hba = s;
        ad->port_no = i;
        ad->port.dma = &ad->dma;
        ad->port.dma->ops = &ahci_dma_ops;
        ide_register_restart_cb(&ad->port);
    }
    g_free(irqs);
}

void ahci_uninit(AHCIState *s)
{
    g_free(s->dev);
}

void ahci_reset(AHCIState *s)
{
    AHCIPortRegs *pr;
    int i;

    s->control_regs.irqstatus = 0;
    /* AHCI Enable (AE)
     * The implementation of this bit is dependent upon the value of the
     * CAP.SAM bit. If CAP.SAM is '0', then GHC.AE shall be read-write and
     * shall have a reset value of '0'. If CAP.SAM is '1', then AE shall be
     * read-only and shall have a reset value of '1'.
     *
     * We set HOST_CAP_AHCI so we must enable AHCI at reset.
     */
    s->control_regs.ghc = HOST_CTL_AHCI_EN;

    for (i = 0; i < s->ports; i++) {
        pr = &s->dev[i].port_regs;
        pr->irq_stat = 0;
        pr->irq_mask = 0;
        pr->scr_ctl = 0;
        pr->cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;
        ahci_reset_port(s, i);
    }
}

static const VMStateDescription vmstate_ncq_tfs = {
    .name = "ncq state",
    .version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(sector_count, NCQTransferState),
        VMSTATE_UINT64(lba, NCQTransferState),
        VMSTATE_UINT8(tag, NCQTransferState),
        VMSTATE_UINT8(cmd, NCQTransferState),
        VMSTATE_UINT8(slot, NCQTransferState),
        VMSTATE_BOOL(used, NCQTransferState),
        VMSTATE_BOOL(halt, NCQTransferState),
        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription vmstate_ahci_device = {
    .name = "ahci port",
    .version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_IDE_BUS(port, AHCIDevice),
        VMSTATE_IDE_DRIVE(port.ifs[0], AHCIDevice),
        VMSTATE_UINT32(port_state, AHCIDevice),
        VMSTATE_UINT32(finished, AHCIDevice),
        VMSTATE_UINT32(port_regs.lst_addr, AHCIDevice),
        VMSTATE_UINT32(port_regs.lst_addr_hi, AHCIDevice),
        VMSTATE_UINT32(port_regs.fis_addr, AHCIDevice),
        VMSTATE_UINT32(port_regs.fis_addr_hi, AHCIDevice),
        VMSTATE_UINT32(port_regs.irq_stat, AHCIDevice),
        VMSTATE_UINT32(port_regs.irq_mask, AHCIDevice),
        VMSTATE_UINT32(port_regs.cmd, AHCIDevice),
        VMSTATE_UINT32(port_regs.tfdata, AHCIDevice),
        VMSTATE_UINT32(port_regs.sig, AHCIDevice),
        VMSTATE_UINT32(port_regs.scr_stat, AHCIDevice),
        VMSTATE_UINT32(port_regs.scr_ctl, AHCIDevice),
        VMSTATE_UINT32(port_regs.scr_err, AHCIDevice),
        VMSTATE_UINT32(port_regs.scr_act, AHCIDevice),
        VMSTATE_UINT32(port_regs.cmd_issue, AHCIDevice),
        VMSTATE_BOOL(done_atapi_packet, AHCIDevice),
        VMSTATE_INT32(busy_slot, AHCIDevice),
        VMSTATE_BOOL(init_d2h_sent, AHCIDevice),
        VMSTATE_STRUCT_ARRAY(ncq_tfs, AHCIDevice, AHCI_MAX_CMDS,
                             1, vmstate_ncq_tfs, NCQTransferState),
        VMSTATE_END_OF_LIST()
    },
};

static int ahci_state_post_load(void *opaque, int version_id)
{
    int i, j;
    struct AHCIDevice *ad;
    NCQTransferState *ncq_tfs;
    AHCIPortRegs *pr;
    AHCIState *s = opaque;

    for (i = 0; i < s->ports; i++) {
        ad = &s->dev[i];
        pr = &ad->port_regs;

        if (!(pr->cmd & PORT_CMD_START) && (pr->cmd & PORT_CMD_LIST_ON)) {
            error_report("AHCI: DMA engine should be off, but status bit "
                         "indicates it is still running.");
            return -1;
        }
        if (!(pr->cmd & PORT_CMD_FIS_RX) && (pr->cmd & PORT_CMD_FIS_ON)) {
            error_report("AHCI: FIS RX engine should be off, but status bit "
                         "indicates it is still running.");
            return -1;
        }

        /* After a migrate, the DMA/FIS engines are "off" and
         * need to be conditionally restarted */
        pr->cmd &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON);
        if (ahci_cond_start_engines(ad) != 0) {
            return -1;
        }

        for (j = 0; j < AHCI_MAX_CMDS; j++) {
            ncq_tfs = &ad->ncq_tfs[j];
            ncq_tfs->drive = ad;

            if (ncq_tfs->used != ncq_tfs->halt) {
                return -1;
            }
            if (!ncq_tfs->halt) {
                continue;
            }
            if (!is_ncq(ncq_tfs->cmd)) {
                return -1;
            }
            if (ncq_tfs->slot != ncq_tfs->tag) {
                return -1;
            }
            /* If ncq_tfs->halt is justly set, the engine should be engaged,
             * and the command list buffer should be mapped. */
            ncq_tfs->cmdh = get_cmd_header(s, i, ncq_tfs->slot);
            if (!ncq_tfs->cmdh) {
                return -1;
            }
            ahci_populate_sglist(ncq_tfs->drive, &ncq_tfs->sglist,
                                 ncq_tfs->cmdh, ncq_tfs->sector_count * 512,
                                 0);
            if (ncq_tfs->sector_count != ncq_tfs->sglist.size >> 9) {
                return -1;
            }
        }


        /*
         * If an error is present, ad->busy_slot will be valid and not -1.
         * In this case, an operation is waiting to resume and will re-check
         * for additional AHCI commands to execute upon completion.
         *
         * In the case where no error was present, busy_slot will be -1,
         * and we should check to see if there are additional commands waiting.
         */
        if (ad->busy_slot == -1) {
            check_cmd(s, i);
        } else {
            /* We are in the middle of a command, and may need to access
             * the command header in guest memory again. */
            if (ad->busy_slot < 0 || ad->busy_slot >= AHCI_MAX_CMDS) {
                return -1;
            }
            ad->cur_cmd = get_cmd_header(s, i, ad->busy_slot);
        }
    }

    return 0;
}

const VMStateDescription vmstate_ahci = {
    .name = "ahci",
    .version_id = 1,
    .post_load = ahci_state_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT_VARRAY_POINTER_INT32(dev, AHCIState, ports,
                                     vmstate_ahci_device, AHCIDevice),
        VMSTATE_UINT32(control_regs.cap, AHCIState),
        VMSTATE_UINT32(control_regs.ghc, AHCIState),
        VMSTATE_UINT32(control_regs.irqstatus, AHCIState),
        VMSTATE_UINT32(control_regs.impl, AHCIState),
        VMSTATE_UINT32(control_regs.version, AHCIState),
        VMSTATE_UINT32(idp_index, AHCIState),
        VMSTATE_INT32_EQUAL(ports, AHCIState),
        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription vmstate_sysbus_ahci = {
    .name = "sysbus-ahci",
    .fields = (VMStateField[]) {
        VMSTATE_AHCI(ahci, SysbusAHCIState),
        VMSTATE_END_OF_LIST()
    },
};

static void sysbus_ahci_reset(DeviceState *dev)
{
    SysbusAHCIState *s = SYSBUS_AHCI(dev);

    ahci_reset(&s->ahci);
}

static void sysbus_ahci_init(Object *obj)
{
    SysbusAHCIState *s = SYSBUS_AHCI(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    ahci_init(&s->ahci, DEVICE(obj));

    sysbus_init_mmio(sbd, &s->ahci.mem);
    sysbus_init_irq(sbd, &s->ahci.irq);
}

static void sysbus_ahci_realize(DeviceState *dev, Error **errp)
{
    SysbusAHCIState *s = SYSBUS_AHCI(dev);

    ahci_realize(&s->ahci, dev, &address_space_memory, s->num_ports);
}

static Property sysbus_ahci_properties[] = {
    DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, num_ports, 1),
    DEFINE_PROP_END_OF_LIST(),
};

static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = sysbus_ahci_realize;
    dc->vmsd = &vmstate_sysbus_ahci;
    dc->props = sysbus_ahci_properties;
    dc->reset = sysbus_ahci_reset;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static const TypeInfo sysbus_ahci_info = {
    .name          = TYPE_SYSBUS_AHCI,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(SysbusAHCIState),
    .instance_init = sysbus_ahci_init,
    .class_init    = sysbus_ahci_class_init,
};

#define ALLWINNER_AHCI_BISTAFR    ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_BISTCR     ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_BISTFCTR   ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_BISTSR     ((0xac - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_BISTDECR   ((0xb0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_DIAGNR0    ((0xb4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_DIAGNR1    ((0xb8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_OOBR       ((0xbc - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_PHYCS0R    ((0xc0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_PHYCS1R    ((0xc4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_PHYCS2R    ((0xc8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_TIMER1MS   ((0xe0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_GPARAM1R   ((0xe8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_GPARAM2R   ((0xec - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_PPARAMR    ((0xf0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_TESTR      ((0xf4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_VERSIONR   ((0xf8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_IDR        ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_RWCR       ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)

static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr,
                                        unsigned size)
{
    AllwinnerAHCIState *a = opaque;
    uint64_t val = a->regs[addr/4];

    switch (addr / 4) {
    case ALLWINNER_AHCI_PHYCS0R:
        val |= 0x2 << 28;
        break;
    case ALLWINNER_AHCI_PHYCS2R:
        val &= ~(0x1 << 24);
        break;
    }
    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
            addr, val, size);
    return  val;
}

static void allwinner_ahci_mem_write(void *opaque, hwaddr addr,
                                     uint64_t val, unsigned size)
{
    AllwinnerAHCIState *a = opaque;

    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
            addr, val, size);
    a->regs[addr/4] = val;
}

static const MemoryRegionOps allwinner_ahci_mem_ops = {
    .read = allwinner_ahci_mem_read,
    .write = allwinner_ahci_mem_write,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void allwinner_ahci_init(Object *obj)
{
    SysbusAHCIState *s = SYSBUS_AHCI(obj);
    AllwinnerAHCIState *a = ALLWINNER_AHCI(obj);

    memory_region_init_io(&a->mmio, OBJECT(obj), &allwinner_ahci_mem_ops, a,
                          "allwinner-ahci", ALLWINNER_AHCI_MMIO_SIZE);
    memory_region_add_subregion(&s->ahci.mem, ALLWINNER_AHCI_MMIO_OFF,
                                &a->mmio);
}

static const VMStateDescription vmstate_allwinner_ahci = {
    .name = "allwinner-ahci",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, AllwinnerAHCIState,
                             ALLWINNER_AHCI_MMIO_SIZE/4),
        VMSTATE_END_OF_LIST()
    }
};

static void allwinner_ahci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->vmsd = &vmstate_allwinner_ahci;
}

static const TypeInfo allwinner_ahci_info = {
    .name          = TYPE_ALLWINNER_AHCI,
    .parent        = TYPE_SYSBUS_AHCI,
    .instance_size = sizeof(AllwinnerAHCIState),
    .instance_init = allwinner_ahci_init,
    .class_init    = allwinner_ahci_class_init,
};

static void sysbus_ahci_register_types(void)
{
    type_register_static(&sysbus_ahci_info);
    type_register_static(&allwinner_ahci_info);
}

type_init(sysbus_ahci_register_types)

void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd)
{
    AHCIPCIState *d = ICH_AHCI(dev);
    AHCIState *ahci = &d->ahci;
    int i;

    for (i = 0; i < ahci->ports; i++) {
        if (hd[i] == NULL) {
            continue;
        }
        ide_create_drive(&ahci->dev[i].port, 0, hd[i]);
    }

}
