/*
 * QEMU ESP/NCR53C9x emulation
 *
 * Copyright (c) 2005-2006 Fabrice Bellard
 * Copyright (c) 2012 Herve Poussineau
 *
 * 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/sysbus.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
#include "hw/scsi/esp.h"
#include "trace.h"
#include "qemu/log.h"
#include "qemu/module.h"

/*
 * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
 * also produced as NCR89C100. See
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
 * and
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
 *
 * On Macintosh Quadra it is a NCR53C96.
 */

static void esp_raise_irq(ESPState *s)
{
    if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
        s->rregs[ESP_RSTAT] |= STAT_INT;
        qemu_irq_raise(s->irq);
        trace_esp_raise_irq();
    }
}

static void esp_lower_irq(ESPState *s)
{
    if (s->rregs[ESP_RSTAT] & STAT_INT) {
        s->rregs[ESP_RSTAT] &= ~STAT_INT;
        qemu_irq_lower(s->irq);
        trace_esp_lower_irq();
    }
}

static void esp_raise_drq(ESPState *s)
{
    qemu_irq_raise(s->irq_data);
    trace_esp_raise_drq();
}

static void esp_lower_drq(ESPState *s)
{
    qemu_irq_lower(s->irq_data);
    trace_esp_lower_drq();
}

void esp_dma_enable(ESPState *s, int irq, int level)
{
    if (level) {
        s->dma_enabled = 1;
        trace_esp_dma_enable();
        if (s->dma_cb) {
            s->dma_cb(s);
            s->dma_cb = NULL;
        }
    } else {
        trace_esp_dma_disable();
        s->dma_enabled = 0;
    }
}

void esp_request_cancelled(SCSIRequest *req)
{
    ESPState *s = req->hba_private;

    if (req == s->current_req) {
        scsi_req_unref(s->current_req);
        s->current_req = NULL;
        s->current_dev = NULL;
        s->async_len = 0;
    }
}

static void esp_fifo_push(Fifo8 *fifo, uint8_t val)
{
    if (fifo8_num_used(fifo) == fifo->capacity) {
        trace_esp_error_fifo_overrun();
        return;
    }

    fifo8_push(fifo, val);
}

static uint8_t esp_fifo_pop(Fifo8 *fifo)
{
    if (fifo8_is_empty(fifo)) {
        return 0;
    }

    return fifo8_pop(fifo);
}

static uint32_t esp_fifo_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen)
{
    const uint8_t *buf;
    uint32_t n, n2;
    int len;

    if (maxlen == 0) {
        return 0;
    }

    len = maxlen;
    buf = fifo8_pop_buf(fifo, len, &n);
    if (dest) {
        memcpy(dest, buf, n);
    }

    /* Add FIFO wraparound if needed */
    len -= n;
    len = MIN(len, fifo8_num_used(fifo));
    if (len) {
        buf = fifo8_pop_buf(fifo, len, &n2);
        if (dest) {
            memcpy(&dest[n], buf, n2);
        }
        n += n2;
    }

    return n;
}

static uint32_t esp_get_tc(ESPState *s)
{
    uint32_t dmalen;

    dmalen = s->rregs[ESP_TCLO];
    dmalen |= s->rregs[ESP_TCMID] << 8;
    dmalen |= s->rregs[ESP_TCHI] << 16;

    return dmalen;
}

static void esp_set_tc(ESPState *s, uint32_t dmalen)
{
    uint32_t old_tc = esp_get_tc(s);

    s->rregs[ESP_TCLO] = dmalen;
    s->rregs[ESP_TCMID] = dmalen >> 8;
    s->rregs[ESP_TCHI] = dmalen >> 16;

    if (old_tc && dmalen == 0) {
        s->rregs[ESP_RSTAT] |= STAT_TC;
    }
}

static uint32_t esp_get_stc(ESPState *s)
{
    uint32_t dmalen;

    dmalen = s->wregs[ESP_TCLO];
    dmalen |= s->wregs[ESP_TCMID] << 8;
    dmalen |= s->wregs[ESP_TCHI] << 16;

    return dmalen;
}

static const char *esp_phase_names[8] = {
    "DATA OUT", "DATA IN", "COMMAND", "STATUS",
    "(reserved)", "(reserved)", "MESSAGE OUT", "MESSAGE IN"
};

static void esp_set_phase(ESPState *s, uint8_t phase)
{
    s->rregs[ESP_RSTAT] &= ~7;
    s->rregs[ESP_RSTAT] |= phase;

    trace_esp_set_phase(esp_phase_names[phase]);
}

static uint8_t esp_get_phase(ESPState *s)
{
    return s->rregs[ESP_RSTAT] & 7;
}

static uint8_t esp_pdma_read(ESPState *s)
{
    uint8_t val;

    val = esp_fifo_pop(&s->fifo);
    return val;
}

static void esp_pdma_write(ESPState *s, uint8_t val)
{
    uint32_t dmalen = esp_get_tc(s);

    if (dmalen == 0) {
        return;
    }

    esp_fifo_push(&s->fifo, val);

    dmalen--;
    esp_set_tc(s, dmalen);
}

static void esp_set_pdma_cb(ESPState *s, enum pdma_cb cb)
{
    s->pdma_cb = cb;
}

static int esp_select(ESPState *s)
{
    int target;

    target = s->wregs[ESP_WBUSID] & BUSID_DID;

    s->ti_size = 0;

    if (s->current_req) {
        /* Started a new command before the old one finished. Cancel it. */
        scsi_req_cancel(s->current_req);
    }

    s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
    if (!s->current_dev) {
        /* No such drive */
        s->rregs[ESP_RSTAT] = 0;
        s->rregs[ESP_RINTR] = INTR_DC;
        s->rregs[ESP_RSEQ] = SEQ_0;
        esp_raise_irq(s);
        return -1;
    }

    /*
     * Note that we deliberately don't raise the IRQ here: this will be done
     * either in do_command_phase() for DATA OUT transfers or by the deferred
     * IRQ mechanism in esp_transfer_data() for DATA IN transfers
     */
    s->rregs[ESP_RINTR] |= INTR_FC;
    s->rregs[ESP_RSEQ] = SEQ_CD;
    return 0;
}

static uint32_t get_cmd(ESPState *s, uint32_t maxlen)
{
    uint8_t buf[ESP_CMDFIFO_SZ];
    uint32_t dmalen, n;
    int target;

    target = s->wregs[ESP_WBUSID] & BUSID_DID;
    if (s->dma) {
        dmalen = MIN(esp_get_tc(s), maxlen);
        if (dmalen == 0) {
            return 0;
        }
        if (s->dma_memory_read) {
            s->dma_memory_read(s->dma_opaque, buf, dmalen);
            dmalen = MIN(fifo8_num_free(&s->cmdfifo), dmalen);
            fifo8_push_all(&s->cmdfifo, buf, dmalen);
            esp_set_tc(s, esp_get_tc(s) - dmalen);
        } else {
            return 0;
        }
    } else {
        dmalen = MIN(fifo8_num_used(&s->fifo), maxlen);
        if (dmalen == 0) {
            return 0;
        }
        n = esp_fifo_pop_buf(&s->fifo, buf, dmalen);
        n = MIN(fifo8_num_free(&s->cmdfifo), n);
        fifo8_push_all(&s->cmdfifo, buf, n);
    }
    trace_esp_get_cmd(dmalen, target);

    return dmalen;
}

static void do_command_phase(ESPState *s)
{
    uint32_t cmdlen;
    int32_t datalen;
    SCSIDevice *current_lun;
    uint8_t buf[ESP_CMDFIFO_SZ];

    trace_esp_do_command_phase(s->lun);
    cmdlen = fifo8_num_used(&s->cmdfifo);
    if (!cmdlen || !s->current_dev) {
        return;
    }
    esp_fifo_pop_buf(&s->cmdfifo, buf, cmdlen);

    current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, s->lun);
    if (!current_lun) {
        /* No such drive */
        s->rregs[ESP_RSTAT] = 0;
        s->rregs[ESP_RINTR] = INTR_DC;
        s->rregs[ESP_RSEQ] = SEQ_0;
        esp_raise_irq(s);
        return;
    }

    s->current_req = scsi_req_new(current_lun, 0, s->lun, buf, cmdlen, s);
    datalen = scsi_req_enqueue(s->current_req);
    s->ti_size = datalen;
    fifo8_reset(&s->cmdfifo);
    if (datalen != 0) {
        s->ti_cmd = 0;
        if (datalen > 0) {
            /*
             * Switch to DATA IN phase but wait until initial data xfer is
             * complete before raising the command completion interrupt
             */
            s->data_in_ready = false;
            esp_set_phase(s, STAT_DI);
        } else {
            esp_set_phase(s, STAT_DO);
            s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
            esp_raise_irq(s);
            esp_lower_drq(s);
        }
        scsi_req_continue(s->current_req);
        return;
    }
}

static void do_message_phase(ESPState *s)
{
    if (s->cmdfifo_cdb_offset) {
        uint8_t message = esp_fifo_pop(&s->cmdfifo);

        trace_esp_do_identify(message);
        s->lun = message & 7;
        s->cmdfifo_cdb_offset--;
    }

    /* Ignore extended messages for now */
    if (s->cmdfifo_cdb_offset) {
        int len = MIN(s->cmdfifo_cdb_offset, fifo8_num_used(&s->cmdfifo));
        esp_fifo_pop_buf(&s->cmdfifo, NULL, len);
        s->cmdfifo_cdb_offset = 0;
    }
}

static void do_cmd(ESPState *s)
{
    do_message_phase(s);
    assert(s->cmdfifo_cdb_offset == 0);
    do_command_phase(s);
}

static void satn_pdma_cb(ESPState *s)
{
    uint8_t buf[ESP_FIFO_SZ];
    int n;

    /* Copy FIFO into cmdfifo */
    n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
    n = MIN(fifo8_num_free(&s->cmdfifo), n);
    fifo8_push_all(&s->cmdfifo, buf, n);

    if (!esp_get_tc(s) && !fifo8_is_empty(&s->cmdfifo)) {
        s->cmdfifo_cdb_offset = 1;
        do_cmd(s);
    }
}

static void handle_satn(ESPState *s)
{
    int32_t cmdlen;

    if (s->dma && !s->dma_enabled) {
        s->dma_cb = handle_satn;
        return;
    }
    esp_set_pdma_cb(s, SATN_PDMA_CB);
    if (esp_select(s) < 0) {
        return;
    }
    cmdlen = get_cmd(s, ESP_CMDFIFO_SZ);
    if (cmdlen > 0) {
        s->cmdfifo_cdb_offset = 1;
        do_cmd(s);
    } else if (cmdlen == 0) {
        if (s->dma) {
            esp_raise_drq(s);
        }
        /* Target present, but no cmd yet - switch to command phase */
        s->rregs[ESP_RSEQ] = SEQ_CD;
        esp_set_phase(s, STAT_CD);
    }
}

static void handle_s_without_atn(ESPState *s)
{
    int32_t cmdlen;

    if (s->dma && !s->dma_enabled) {
        s->dma_cb = handle_s_without_atn;
        return;
    }
    esp_set_pdma_cb(s, DO_DMA_PDMA_CB);
    if (esp_select(s) < 0) {
        return;
    }
    cmdlen = get_cmd(s, ESP_CMDFIFO_SZ);
    if (cmdlen > 0) {
        s->cmdfifo_cdb_offset = 0;
        do_cmd(s);
    } else if (cmdlen == 0) {
        if (s->dma) {
            esp_raise_drq(s);
        }
        /* Target present, but no cmd yet - switch to command phase */
        s->rregs[ESP_RSEQ] = SEQ_CD;
        esp_set_phase(s, STAT_CD);
    }
}

static void satn_stop_pdma_cb(ESPState *s)
{
    uint8_t buf[ESP_FIFO_SZ];
    int n;

    /* Copy FIFO into cmdfifo */
    n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
    n = MIN(fifo8_num_free(&s->cmdfifo), n);
    fifo8_push_all(&s->cmdfifo, buf, n);

    if (!esp_get_tc(s) && !fifo8_is_empty(&s->cmdfifo)) {
        trace_esp_handle_satn_stop(fifo8_num_used(&s->cmdfifo));
        s->cmdfifo_cdb_offset = 1;
        esp_set_phase(s, STAT_CD);
        s->rregs[ESP_RSTAT] |= STAT_TC;
        s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
        s->rregs[ESP_RSEQ] = SEQ_CD;
        esp_raise_irq(s);
    }
}

static void handle_satn_stop(ESPState *s)
{
    int32_t cmdlen;

    if (s->dma && !s->dma_enabled) {
        s->dma_cb = handle_satn_stop;
        return;
    }
    esp_set_pdma_cb(s, SATN_STOP_PDMA_CB);
    if (esp_select(s) < 0) {
        return;
    }
    cmdlen = get_cmd(s, 1);
    if (cmdlen > 0) {
        trace_esp_handle_satn_stop(fifo8_num_used(&s->cmdfifo));
        s->cmdfifo_cdb_offset = 1;
        esp_set_phase(s, STAT_MO);
        s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
        s->rregs[ESP_RSEQ] = SEQ_MO;
        esp_raise_irq(s);
    } else if (cmdlen == 0) {
        if (s->dma) {
            esp_raise_drq(s);
        }
        /* Target present, switch to message out phase */
        s->rregs[ESP_RSEQ] = SEQ_MO;
        esp_set_phase(s, STAT_MO);
    }
}

static void write_response_pdma_cb(ESPState *s)
{
    esp_set_phase(s, STAT_ST);
    s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
    s->rregs[ESP_RSEQ] = SEQ_CD;
    esp_raise_irq(s);
}

static void write_response(ESPState *s)
{
    uint8_t buf[2];

    trace_esp_write_response(s->status);

    buf[0] = s->status;
    buf[1] = 0;

    if (s->dma) {
        if (s->dma_memory_write) {
            s->dma_memory_write(s->dma_opaque, buf, 2);
            esp_set_phase(s, STAT_ST);
            s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
            s->rregs[ESP_RSEQ] = SEQ_CD;
        } else {
            esp_set_pdma_cb(s, WRITE_RESPONSE_PDMA_CB);
            esp_raise_drq(s);
            return;
        }
    } else {
        fifo8_reset(&s->fifo);
        fifo8_push_all(&s->fifo, buf, 2);
        s->rregs[ESP_RFLAGS] = 2;
    }
    esp_raise_irq(s);
}

static void esp_dma_ti_check(ESPState *s)
{
    if (esp_get_tc(s) == 0 && fifo8_num_used(&s->fifo) < 2) {
        s->rregs[ESP_RINTR] |= INTR_BS;
        esp_raise_irq(s);
        esp_lower_drq(s);
    }
}

static void do_dma_pdma_cb(ESPState *s)
{
    uint8_t buf[ESP_CMDFIFO_SZ];
    int len;
    uint32_t n;

    switch (esp_get_phase(s)) {
    case STAT_MO:
    case STAT_CD:
        /* Copy FIFO into cmdfifo */
        n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
        n = MIN(fifo8_num_free(&s->cmdfifo), n);
        fifo8_push_all(&s->cmdfifo, buf, n);

        /* Ensure we have received complete command after SATN and stop */
        if (esp_get_tc(s) || fifo8_is_empty(&s->cmdfifo)) {
            return;
        }

        s->ti_size = 0;
        if (esp_get_phase(s) == STAT_CD) {
            /* No command received */
            if (s->cmdfifo_cdb_offset == fifo8_num_used(&s->cmdfifo)) {
                return;
            }

            /* Command has been received */
            do_cmd(s);
        } else {
            /*
             * Extra message out bytes received: update cmdfifo_cdb_offset
             * and then switch to command phase
             */
            s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo);
            esp_set_phase(s, STAT_CD);
            s->rregs[ESP_RSEQ] = SEQ_CD;
            s->rregs[ESP_RINTR] |= INTR_BS;
            esp_raise_irq(s);
        }
        break;

    case STAT_DO:
        if (!s->current_req) {
            return;
        }
        /* Copy FIFO data to device */
        len = MIN(s->async_len, ESP_FIFO_SZ);
        len = MIN(len, fifo8_num_used(&s->fifo));
        n = esp_fifo_pop_buf(&s->fifo, s->async_buf, len);
        s->async_buf += n;
        s->async_len -= n;
        s->ti_size += n;

        if (s->async_len == 0 && fifo8_num_used(&s->fifo) < 2) {
            /* Defer until the scsi layer has completed */
            scsi_req_continue(s->current_req);
            return;
        }

        esp_dma_ti_check(s);
        break;

    case STAT_DI:
        if (!s->current_req) {
            return;
        }
        /* Copy device data to FIFO */
        len = MIN(s->async_len, esp_get_tc(s));
        len = MIN(len, fifo8_num_free(&s->fifo));
        fifo8_push_all(&s->fifo, s->async_buf, len);
        s->async_buf += len;
        s->async_len -= len;
        s->ti_size -= len;
        esp_set_tc(s, esp_get_tc(s) - len);

        if (s->async_len == 0 && fifo8_num_used(&s->fifo) < 2) {
            /* Defer until the scsi layer has completed */
            scsi_req_continue(s->current_req);
            s->data_in_ready = false;
            return;
        }

        esp_dma_ti_check(s);
        break;
    }
}

static void esp_do_dma(ESPState *s)
{
    uint32_t len, cmdlen;
    uint8_t buf[ESP_CMDFIFO_SZ];
    int n;

    len = esp_get_tc(s);

    switch (esp_get_phase(s)) {
    case STAT_MO:
        if (s->dma_memory_read) {
            len = MIN(len, fifo8_num_free(&s->cmdfifo));
            s->dma_memory_read(s->dma_opaque, buf, len);
            fifo8_push_all(&s->cmdfifo, buf, len);
            esp_set_tc(s, esp_get_tc(s) - len);
            s->cmdfifo_cdb_offset += len;
        } else {
            n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
            n = MIN(fifo8_num_free(&s->cmdfifo), n);
            fifo8_push_all(&s->cmdfifo, buf, n);
            s->cmdfifo_cdb_offset += n;
        }

        esp_set_pdma_cb(s, DO_DMA_PDMA_CB);
        esp_raise_drq(s);

        /* ATN remains asserted until TC == 0 */
        if (esp_get_tc(s) == 0) {
            esp_set_phase(s, STAT_CD);
            s->rregs[ESP_RSEQ] = SEQ_CD;
            s->rregs[ESP_RINTR] |= INTR_BS;
            esp_raise_irq(s);
        }
        break;

    case STAT_CD:
        cmdlen = fifo8_num_used(&s->cmdfifo);
        trace_esp_do_dma(cmdlen, len);
        if (s->dma_memory_read) {
            len = MIN(len, fifo8_num_free(&s->cmdfifo));
            s->dma_memory_read(s->dma_opaque, buf, len);
            fifo8_push_all(&s->cmdfifo, buf, len);
            esp_set_tc(s, esp_get_tc(s) - len);
        } else {
            n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
            n = MIN(fifo8_num_free(&s->cmdfifo), n);
            fifo8_push_all(&s->cmdfifo, buf, n);

            esp_set_pdma_cb(s, DO_DMA_PDMA_CB);
            esp_raise_drq(s);
        }
        trace_esp_handle_ti_cmd(cmdlen);
        s->ti_size = 0;
        if (esp_get_tc(s) == 0) {
            /* Command has been received */
            do_cmd(s);
        }
        break;

    case STAT_DO:
        if (!s->current_req) {
            return;
        }
        if (s->async_len == 0 && esp_get_tc(s) && s->ti_size) {
            /* Defer until data is available.  */
            return;
        }
        if (len > s->async_len) {
            len = s->async_len;
        }
        if (s->dma_memory_read) {
            s->dma_memory_read(s->dma_opaque, s->async_buf, len);

            esp_set_tc(s, esp_get_tc(s) - len);
            s->async_buf += len;
            s->async_len -= len;
            s->ti_size += len;

            if (s->async_len == 0 && fifo8_num_used(&s->fifo) < 2) {
                /* Defer until the scsi layer has completed */
                scsi_req_continue(s->current_req);
                return;
            }

            esp_dma_ti_check(s);
        } else {
            /* Copy FIFO data to device */
            len = MIN(s->async_len, ESP_FIFO_SZ);
            len = MIN(len, fifo8_num_used(&s->fifo));
            n = esp_fifo_pop_buf(&s->fifo, s->async_buf, len);
            s->async_buf += n;
            s->async_len -= n;
            s->ti_size += n;

            esp_set_pdma_cb(s, DO_DMA_PDMA_CB);
            esp_raise_drq(s);

            if (s->async_len == 0 && fifo8_num_used(&s->fifo) < 2) {
                /* Defer until the scsi layer has completed */
                scsi_req_continue(s->current_req);
                return;
            }

            esp_dma_ti_check(s);
        }
        break;

    case STAT_DI:
        if (!s->current_req) {
            return;
        }
        if (s->async_len == 0 && esp_get_tc(s) && s->ti_size) {
            /* Defer until data is available.  */
            return;
        }
        if (len > s->async_len) {
            len = s->async_len;
        }
        if (s->dma_memory_write) {
            s->dma_memory_write(s->dma_opaque, s->async_buf, len);

            esp_set_tc(s, esp_get_tc(s) - len);
            s->async_buf += len;
            s->async_len -= len;
            s->ti_size -= len;

            if (s->async_len == 0 && fifo8_num_used(&s->fifo) < 2) {
                /* Defer until the scsi layer has completed */
                scsi_req_continue(s->current_req);
                return;
            }

            esp_dma_ti_check(s);
        } else {
            /* Copy device data to FIFO */
            len = MIN(len, fifo8_num_free(&s->fifo));
            fifo8_push_all(&s->fifo, s->async_buf, len);
            s->async_buf += len;
            s->async_len -= len;
            s->ti_size -= len;
            esp_set_tc(s, esp_get_tc(s) - len);
            esp_set_pdma_cb(s, DO_DMA_PDMA_CB);
            esp_raise_drq(s);

            if (s->async_len == 0 && fifo8_num_used(&s->fifo) < 2) {
                /* Defer until the scsi layer has completed */
                scsi_req_continue(s->current_req);
                return;
            }

            esp_dma_ti_check(s);
        }
        break;
    }
}

static void esp_do_nodma(ESPState *s)
{
    uint8_t buf[ESP_FIFO_SZ];
    uint32_t cmdlen;
    int len, n;

    switch (esp_get_phase(s)) {
    case STAT_MO:
    case STAT_CD:
        /* Copy FIFO into cmdfifo */
        n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
        n = MIN(fifo8_num_free(&s->cmdfifo), n);
        fifo8_push_all(&s->cmdfifo, buf, n);

        cmdlen = fifo8_num_used(&s->cmdfifo);
        trace_esp_handle_ti_cmd(cmdlen);
        s->ti_size = 0;
        if (esp_get_phase(s) == STAT_CD) {
            /* No command received */
            if (s->cmdfifo_cdb_offset == fifo8_num_used(&s->cmdfifo)) {
                return;
            }

            /* Command has been received */
            do_cmd(s);
        } else {
            /*
             * Extra message out bytes received: update cmdfifo_cdb_offset
             * and then switch to command phase
             */
            s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo);
            esp_set_phase(s, STAT_CD);
            s->rregs[ESP_RSEQ] = SEQ_CD;
            s->rregs[ESP_RINTR] |= INTR_BS;
            esp_raise_irq(s);
        }
        break;

    case STAT_DO:
        if (!s->current_req) {
            return;
        }
        if (s->async_len == 0) {
            /* Defer until data is available.  */
            return;
        }
        len = MIN(s->async_len, ESP_FIFO_SZ);
        len = MIN(len, fifo8_num_used(&s->fifo));
        esp_fifo_pop_buf(&s->fifo, s->async_buf, len);
        s->async_buf += len;
        s->async_len -= len;
        s->ti_size += len;

        if (s->async_len == 0) {
            scsi_req_continue(s->current_req);
            return;
        }

        s->rregs[ESP_RINTR] |= INTR_BS;
        esp_raise_irq(s);
        break;

    case STAT_DI:
        if (!s->current_req) {
            return;
        }
        if (s->async_len == 0) {
            /* Defer until data is available.  */
            return;
        }
        if (fifo8_is_empty(&s->fifo)) {
            fifo8_push(&s->fifo, s->async_buf[0]);
            s->async_buf++;
            s->async_len--;
            s->ti_size--;
        }

        if (s->async_len == 0) {
            scsi_req_continue(s->current_req);
            return;
        }

        s->rregs[ESP_RINTR] |= INTR_BS;
        esp_raise_irq(s);
        break;
    }
}

static void esp_pdma_cb(ESPState *s)
{
    switch (s->pdma_cb) {
    case SATN_PDMA_CB:
        satn_pdma_cb(s);
        break;
    case SATN_STOP_PDMA_CB:
        satn_stop_pdma_cb(s);
        break;
    case WRITE_RESPONSE_PDMA_CB:
        write_response_pdma_cb(s);
        break;
    case DO_DMA_PDMA_CB:
        do_dma_pdma_cb(s);
        break;
    default:
        g_assert_not_reached();
    }
}

void esp_command_complete(SCSIRequest *req, size_t resid)
{
    ESPState *s = req->hba_private;
    int to_device = (esp_get_phase(s) == STAT_DO);

    trace_esp_command_complete();

    /*
     * Non-DMA transfers from the target will leave the last byte in
     * the FIFO so don't reset ti_size in this case
     */
    if (s->dma || to_device) {
        if (s->ti_size != 0) {
            trace_esp_command_complete_unexpected();
        }
    }

    s->async_len = 0;
    if (req->status) {
        trace_esp_command_complete_fail();
    }
    s->status = req->status;

    /*
     * Switch to status phase. For non-DMA transfers from the target the last
     * byte is still in the FIFO
     */
    esp_set_phase(s, STAT_ST);
    if (s->ti_size == 0) {
        /*
         * Transfer complete: force TC to zero just in case a TI command was
         * requested for more data than the command returns (Solaris 8 does
         * this)
         */
        esp_set_tc(s, 0);
        esp_dma_ti_check(s);
    } else {
        /*
         * Transfer truncated: raise INTR_BS to indicate early change of
         * phase
         */
        s->rregs[ESP_RINTR] |= INTR_BS;
        esp_raise_irq(s);
        s->ti_size = 0;
    }

    if (s->current_req) {
        scsi_req_unref(s->current_req);
        s->current_req = NULL;
        s->current_dev = NULL;
    }
}

void esp_transfer_data(SCSIRequest *req, uint32_t len)
{
    ESPState *s = req->hba_private;
    int to_device = (esp_get_phase(s) == STAT_DO);
    uint32_t dmalen = esp_get_tc(s);

    trace_esp_transfer_data(dmalen, s->ti_size);
    s->async_len = len;
    s->async_buf = scsi_req_get_buf(req);

    if (!to_device && !s->data_in_ready) {
        /*
         * Initial incoming data xfer is complete so raise command
         * completion interrupt
         */
        s->data_in_ready = true;
        s->rregs[ESP_RINTR] |= INTR_BS;
        esp_raise_irq(s);
    }

    /*
     * Always perform the initial transfer upon reception of the next TI
     * command to ensure the DMA/non-DMA status of the command is correct.
     * It is not possible to use s->dma directly in the section below as
     * some OSs send non-DMA NOP commands after a DMA transfer. Hence if the
     * async data transfer is delayed then s->dma is set incorrectly.
     */

    if (s->ti_cmd == (CMD_TI | CMD_DMA)) {
        /* When the SCSI layer returns more data, raise deferred INTR_BS */
        esp_dma_ti_check(s);

        esp_do_dma(s);
    } else if (s->ti_cmd == CMD_TI) {
        esp_do_nodma(s);
    }
}

static void handle_ti(ESPState *s)
{
    uint32_t dmalen;

    if (s->dma && !s->dma_enabled) {
        s->dma_cb = handle_ti;
        return;
    }

    s->ti_cmd = s->rregs[ESP_CMD];
    if (s->dma) {
        dmalen = esp_get_tc(s);
        trace_esp_handle_ti(dmalen);
        esp_do_dma(s);
    } else {
        trace_esp_handle_ti(s->ti_size);
        esp_do_nodma(s);
    }
}

void esp_hard_reset(ESPState *s)
{
    memset(s->rregs, 0, ESP_REGS);
    memset(s->wregs, 0, ESP_REGS);
    s->tchi_written = 0;
    s->ti_size = 0;
    s->async_len = 0;
    fifo8_reset(&s->fifo);
    fifo8_reset(&s->cmdfifo);
    s->dma = 0;
    s->dma_cb = NULL;

    s->rregs[ESP_CFG1] = 7;
}

static void esp_soft_reset(ESPState *s)
{
    qemu_irq_lower(s->irq);
    qemu_irq_lower(s->irq_data);
    esp_hard_reset(s);
}

static void esp_bus_reset(ESPState *s)
{
    bus_cold_reset(BUS(&s->bus));
}

static void parent_esp_reset(ESPState *s, int irq, int level)
{
    if (level) {
        esp_soft_reset(s);
    }
}

static void esp_run_cmd(ESPState *s)
{
    uint8_t cmd = s->rregs[ESP_CMD];

    if (cmd & CMD_DMA) {
        s->dma = 1;
        /* Reload DMA counter.  */
        if (esp_get_stc(s) == 0) {
            esp_set_tc(s, 0x10000);
        } else {
            esp_set_tc(s, esp_get_stc(s));
        }
    } else {
        s->dma = 0;
    }
    switch (cmd & CMD_CMD) {
    case CMD_NOP:
        trace_esp_mem_writeb_cmd_nop(cmd);
        break;
    case CMD_FLUSH:
        trace_esp_mem_writeb_cmd_flush(cmd);
        fifo8_reset(&s->fifo);
        break;
    case CMD_RESET:
        trace_esp_mem_writeb_cmd_reset(cmd);
        esp_soft_reset(s);
        break;
    case CMD_BUSRESET:
        trace_esp_mem_writeb_cmd_bus_reset(cmd);
        esp_bus_reset(s);
        if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
            s->rregs[ESP_RINTR] |= INTR_RST;
            esp_raise_irq(s);
        }
        break;
    case CMD_TI:
        trace_esp_mem_writeb_cmd_ti(cmd);
        handle_ti(s);
        break;
    case CMD_ICCS:
        trace_esp_mem_writeb_cmd_iccs(cmd);
        write_response(s);
        s->rregs[ESP_RINTR] |= INTR_FC;
        esp_set_phase(s, STAT_MI);
        break;
    case CMD_MSGACC:
        trace_esp_mem_writeb_cmd_msgacc(cmd);
        s->rregs[ESP_RINTR] |= INTR_DC;
        s->rregs[ESP_RSEQ] = 0;
        s->rregs[ESP_RFLAGS] = 0;
        esp_raise_irq(s);
        break;
    case CMD_PAD:
        trace_esp_mem_writeb_cmd_pad(cmd);
        s->rregs[ESP_RSTAT] = STAT_TC;
        s->rregs[ESP_RINTR] |= INTR_FC;
        s->rregs[ESP_RSEQ] = 0;
        break;
    case CMD_SATN:
        trace_esp_mem_writeb_cmd_satn(cmd);
        break;
    case CMD_RSTATN:
        trace_esp_mem_writeb_cmd_rstatn(cmd);
        break;
    case CMD_SEL:
        trace_esp_mem_writeb_cmd_sel(cmd);
        handle_s_without_atn(s);
        break;
    case CMD_SELATN:
        trace_esp_mem_writeb_cmd_selatn(cmd);
        handle_satn(s);
        break;
    case CMD_SELATNS:
        trace_esp_mem_writeb_cmd_selatns(cmd);
        handle_satn_stop(s);
        break;
    case CMD_ENSEL:
        trace_esp_mem_writeb_cmd_ensel(cmd);
        s->rregs[ESP_RINTR] = 0;
        break;
    case CMD_DISSEL:
        trace_esp_mem_writeb_cmd_dissel(cmd);
        s->rregs[ESP_RINTR] = 0;
        esp_raise_irq(s);
        break;
    default:
        trace_esp_error_unhandled_command(cmd);
        break;
    }
}

uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
{
    uint32_t val;

    switch (saddr) {
    case ESP_FIFO:
        if (s->dma_memory_read && s->dma_memory_write &&
                (s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
            /* Data out.  */
            qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n");
            s->rregs[ESP_FIFO] = 0;
        } else {
            if (esp_get_phase(s) == STAT_DI) {
                if (s->ti_size) {
                    esp_do_nodma(s);
                } else {
                    /*
                     * The last byte of a non-DMA transfer has been read out
                     * of the FIFO so switch to status phase
                     */
                    esp_set_phase(s, STAT_ST);
                }
            }
            s->rregs[ESP_FIFO] = esp_fifo_pop(&s->fifo);
        }
        val = s->rregs[ESP_FIFO];
        break;
    case ESP_RINTR:
        /*
         * Clear sequence step, interrupt register and all status bits
         * except TC
         */
        val = s->rregs[ESP_RINTR];
        s->rregs[ESP_RINTR] = 0;
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
        /*
         * According to the datasheet ESP_RSEQ should be cleared, but as the
         * emulation currently defers information transfers to the next TI
         * command leave it for now so that pedantic guests such as the old
         * Linux 2.6 driver see the correct flags before the next SCSI phase
         * transition.
         *
         * s->rregs[ESP_RSEQ] = SEQ_0;
         */
        esp_lower_irq(s);
        break;
    case ESP_TCHI:
        /* Return the unique id if the value has never been written */
        if (!s->tchi_written) {
            val = s->chip_id;
        } else {
            val = s->rregs[saddr];
        }
        break;
     case ESP_RFLAGS:
        /* Bottom 5 bits indicate number of bytes in FIFO */
        val = fifo8_num_used(&s->fifo);
        break;
    default:
        val = s->rregs[saddr];
        break;
    }

    trace_esp_mem_readb(saddr, val);
    return val;
}

void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
{
    trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
    switch (saddr) {
    case ESP_TCHI:
        s->tchi_written = true;
        /* fall through */
    case ESP_TCLO:
    case ESP_TCMID:
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
        break;
    case ESP_FIFO:
        if (esp_get_phase(s) == STAT_MO || esp_get_phase(s) == STAT_CD) {
            if (!fifo8_is_full(&s->fifo)) {
                esp_fifo_push(&s->fifo, val);
                esp_fifo_push(&s->cmdfifo, fifo8_pop(&s->fifo));
            }

            /*
             * If any unexpected message out/command phase data is
             * transferred using non-DMA, raise the interrupt
             */
            if (s->rregs[ESP_CMD] == CMD_TI) {
                s->rregs[ESP_RINTR] |= INTR_BS;
                esp_raise_irq(s);
            }
        } else {
            esp_fifo_push(&s->fifo, val);
        }
        break;
    case ESP_CMD:
        s->rregs[saddr] = val;
        esp_run_cmd(s);
        break;
    case ESP_WBUSID ... ESP_WSYNO:
        break;
    case ESP_CFG1:
    case ESP_CFG2: case ESP_CFG3:
    case ESP_RES3: case ESP_RES4:
        s->rregs[saddr] = val;
        break;
    case ESP_WCCF ... ESP_WTEST:
        break;
    default:
        trace_esp_error_invalid_write(val, saddr);
        return;
    }
    s->wregs[saddr] = val;
}

static bool esp_mem_accepts(void *opaque, hwaddr addr,
                            unsigned size, bool is_write,
                            MemTxAttrs attrs)
{
    return (size == 1) || (is_write && size == 4);
}

static bool esp_is_before_version_5(void *opaque, int version_id)
{
    ESPState *s = ESP(opaque);

    version_id = MIN(version_id, s->mig_version_id);
    return version_id < 5;
}

static bool esp_is_version_5(void *opaque, int version_id)
{
    ESPState *s = ESP(opaque);

    version_id = MIN(version_id, s->mig_version_id);
    return version_id >= 5;
}

static bool esp_is_version_6(void *opaque, int version_id)
{
    ESPState *s = ESP(opaque);

    version_id = MIN(version_id, s->mig_version_id);
    return version_id >= 6;
}

int esp_pre_save(void *opaque)
{
    ESPState *s = ESP(object_resolve_path_component(
                      OBJECT(opaque), "esp"));

    s->mig_version_id = vmstate_esp.version_id;
    return 0;
}

static int esp_post_load(void *opaque, int version_id)
{
    ESPState *s = ESP(opaque);
    int len, i;

    version_id = MIN(version_id, s->mig_version_id);

    if (version_id < 5) {
        esp_set_tc(s, s->mig_dma_left);

        /* Migrate ti_buf to fifo */
        len = s->mig_ti_wptr - s->mig_ti_rptr;
        for (i = 0; i < len; i++) {
            fifo8_push(&s->fifo, s->mig_ti_buf[i]);
        }

        /* Migrate cmdbuf to cmdfifo */
        for (i = 0; i < s->mig_cmdlen; i++) {
            fifo8_push(&s->cmdfifo, s->mig_cmdbuf[i]);
        }
    }

    s->mig_version_id = vmstate_esp.version_id;
    return 0;
}

/*
 * PDMA (or pseudo-DMA) is only used on the Macintosh and requires the
 * guest CPU to perform the transfers between the SCSI bus and memory
 * itself. This is indicated by the dma_memory_read and dma_memory_write
 * functions being NULL (in contrast to the ESP PCI device) whilst
 * dma_enabled is still set.
 */

static bool esp_pdma_needed(void *opaque)
{
    ESPState *s = ESP(opaque);

    return s->dma_memory_read == NULL && s->dma_memory_write == NULL &&
           s->dma_enabled;
}

static const VMStateDescription vmstate_esp_pdma = {
    .name = "esp/pdma",
    .version_id = 0,
    .minimum_version_id = 0,
    .needed = esp_pdma_needed,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT8(pdma_cb, ESPState),
        VMSTATE_END_OF_LIST()
    }
};

const VMStateDescription vmstate_esp = {
    .name = "esp",
    .version_id = 6,
    .minimum_version_id = 3,
    .post_load = esp_post_load,
    .fields = (const VMStateField[]) {
        VMSTATE_BUFFER(rregs, ESPState),
        VMSTATE_BUFFER(wregs, ESPState),
        VMSTATE_INT32(ti_size, ESPState),
        VMSTATE_UINT32_TEST(mig_ti_rptr, ESPState, esp_is_before_version_5),
        VMSTATE_UINT32_TEST(mig_ti_wptr, ESPState, esp_is_before_version_5),
        VMSTATE_BUFFER_TEST(mig_ti_buf, ESPState, esp_is_before_version_5),
        VMSTATE_UINT32(status, ESPState),
        VMSTATE_UINT32_TEST(mig_deferred_status, ESPState,
                            esp_is_before_version_5),
        VMSTATE_BOOL_TEST(mig_deferred_complete, ESPState,
                          esp_is_before_version_5),
        VMSTATE_UINT32(dma, ESPState),
        VMSTATE_STATIC_BUFFER(mig_cmdbuf, ESPState, 0,
                              esp_is_before_version_5, 0, 16),
        VMSTATE_STATIC_BUFFER(mig_cmdbuf, ESPState, 4,
                              esp_is_before_version_5, 16,
                              sizeof(typeof_field(ESPState, mig_cmdbuf))),
        VMSTATE_UINT32_TEST(mig_cmdlen, ESPState, esp_is_before_version_5),
        VMSTATE_UINT32(do_cmd, ESPState),
        VMSTATE_UINT32_TEST(mig_dma_left, ESPState, esp_is_before_version_5),
        VMSTATE_BOOL_TEST(data_in_ready, ESPState, esp_is_version_5),
        VMSTATE_UINT8_TEST(cmdfifo_cdb_offset, ESPState, esp_is_version_5),
        VMSTATE_FIFO8_TEST(fifo, ESPState, esp_is_version_5),
        VMSTATE_FIFO8_TEST(cmdfifo, ESPState, esp_is_version_5),
        VMSTATE_UINT8_TEST(ti_cmd, ESPState, esp_is_version_5),
        VMSTATE_UINT8_TEST(lun, ESPState, esp_is_version_6),
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription * const []) {
        &vmstate_esp_pdma,
        NULL
    }
};

static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
                                 uint64_t val, unsigned int size)
{
    SysBusESPState *sysbus = opaque;
    ESPState *s = ESP(&sysbus->esp);
    uint32_t saddr;

    saddr = addr >> sysbus->it_shift;
    esp_reg_write(s, saddr, val);
}

static uint64_t sysbus_esp_mem_read(void *opaque, hwaddr addr,
                                    unsigned int size)
{
    SysBusESPState *sysbus = opaque;
    ESPState *s = ESP(&sysbus->esp);
    uint32_t saddr;

    saddr = addr >> sysbus->it_shift;
    return esp_reg_read(s, saddr);
}

static const MemoryRegionOps sysbus_esp_mem_ops = {
    .read = sysbus_esp_mem_read,
    .write = sysbus_esp_mem_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid.accepts = esp_mem_accepts,
};

static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
                                  uint64_t val, unsigned int size)
{
    SysBusESPState *sysbus = opaque;
    ESPState *s = ESP(&sysbus->esp);

    trace_esp_pdma_write(size);

    switch (size) {
    case 1:
        esp_pdma_write(s, val);
        break;
    case 2:
        esp_pdma_write(s, val >> 8);
        esp_pdma_write(s, val);
        break;
    }
    esp_pdma_cb(s);
}

static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
                                     unsigned int size)
{
    SysBusESPState *sysbus = opaque;
    ESPState *s = ESP(&sysbus->esp);
    uint64_t val = 0;

    trace_esp_pdma_read(size);

    switch (size) {
    case 1:
        val = esp_pdma_read(s);
        break;
    case 2:
        val = esp_pdma_read(s);
        val = (val << 8) | esp_pdma_read(s);
        break;
    }
    esp_pdma_cb(s);
    return val;
}

static void *esp_load_request(QEMUFile *f, SCSIRequest *req)
{
    ESPState *s = container_of(req->bus, ESPState, bus);

    scsi_req_ref(req);
    s->current_req = req;
    return s;
}

static const MemoryRegionOps sysbus_esp_pdma_ops = {
    .read = sysbus_esp_pdma_read,
    .write = sysbus_esp_pdma_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .impl.min_access_size = 1,
    .impl.max_access_size = 2,
};

static const struct SCSIBusInfo esp_scsi_info = {
    .tcq = false,
    .max_target = ESP_MAX_DEVS,
    .max_lun = 7,

    .load_request = esp_load_request,
    .transfer_data = esp_transfer_data,
    .complete = esp_command_complete,
    .cancel = esp_request_cancelled
};

static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
{
    SysBusESPState *sysbus = SYSBUS_ESP(opaque);
    ESPState *s = ESP(&sysbus->esp);

    switch (irq) {
    case 0:
        parent_esp_reset(s, irq, level);
        break;
    case 1:
        esp_dma_enable(s, irq, level);
        break;
    }
}

static void sysbus_esp_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    SysBusESPState *sysbus = SYSBUS_ESP(dev);
    ESPState *s = ESP(&sysbus->esp);

    if (!qdev_realize(DEVICE(s), NULL, errp)) {
        return;
    }

    sysbus_init_irq(sbd, &s->irq);
    sysbus_init_irq(sbd, &s->irq_data);
    assert(sysbus->it_shift != -1);

    s->chip_id = TCHI_FAS100A;
    memory_region_init_io(&sysbus->iomem, OBJECT(sysbus), &sysbus_esp_mem_ops,
                          sysbus, "esp-regs", ESP_REGS << sysbus->it_shift);
    sysbus_init_mmio(sbd, &sysbus->iomem);
    memory_region_init_io(&sysbus->pdma, OBJECT(sysbus), &sysbus_esp_pdma_ops,
                          sysbus, "esp-pdma", 4);
    sysbus_init_mmio(sbd, &sysbus->pdma);

    qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);

    scsi_bus_init(&s->bus, sizeof(s->bus), dev, &esp_scsi_info);
}

static void sysbus_esp_hard_reset(DeviceState *dev)
{
    SysBusESPState *sysbus = SYSBUS_ESP(dev);
    ESPState *s = ESP(&sysbus->esp);

    esp_hard_reset(s);
}

static void sysbus_esp_init(Object *obj)
{
    SysBusESPState *sysbus = SYSBUS_ESP(obj);

    object_initialize_child(obj, "esp", &sysbus->esp, TYPE_ESP);
}

static const VMStateDescription vmstate_sysbus_esp_scsi = {
    .name = "sysbusespscsi",
    .version_id = 2,
    .minimum_version_id = 1,
    .pre_save = esp_pre_save,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT8_V(esp.mig_version_id, SysBusESPState, 2),
        VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
        VMSTATE_END_OF_LIST()
    }
};

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

    dc->realize = sysbus_esp_realize;
    dc->reset = sysbus_esp_hard_reset;
    dc->vmsd = &vmstate_sysbus_esp_scsi;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static const TypeInfo sysbus_esp_info = {
    .name          = TYPE_SYSBUS_ESP,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_init = sysbus_esp_init,
    .instance_size = sizeof(SysBusESPState),
    .class_init    = sysbus_esp_class_init,
};

static void esp_finalize(Object *obj)
{
    ESPState *s = ESP(obj);

    fifo8_destroy(&s->fifo);
    fifo8_destroy(&s->cmdfifo);
}

static void esp_init(Object *obj)
{
    ESPState *s = ESP(obj);

    fifo8_create(&s->fifo, ESP_FIFO_SZ);
    fifo8_create(&s->cmdfifo, ESP_CMDFIFO_SZ);
}

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

    /* internal device for sysbusesp/pciespscsi, not user-creatable */
    dc->user_creatable = false;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static const TypeInfo esp_info = {
    .name = TYPE_ESP,
    .parent = TYPE_DEVICE,
    .instance_init = esp_init,
    .instance_finalize = esp_finalize,
    .instance_size = sizeof(ESPState),
    .class_init = esp_class_init,
};

static void esp_register_types(void)
{
    type_register_static(&sysbus_esp_info);
    type_register_static(&esp_info);
}

type_init(esp_register_types)
