/*
 * QEMU ESP/NCR53C9x emulation
 *
 * Copyright (c) 2005-2006 Fabrice Bellard
 * Copyright (c) 2012 Herve Poussineau
 * Copyright (c) 2023 Mark Cave-Ayland
 *
 * 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)
{
    if (!(s->drq_state)) {
        qemu_irq_raise(s->drq_irq);
        trace_esp_raise_drq();
        s->drq_state = true;
    }
}

static void esp_lower_drq(ESPState *s)
{
    if (s->drq_state) {
        qemu_irq_lower(s->drq_irq);
        trace_esp_lower_drq();
        s->drq_state = false;
    }
}

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;
}

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_update_drq(ESPState *s)
{
    bool to_device;

    switch (esp_get_phase(s)) {
    case STAT_MO:
    case STAT_CD:
    case STAT_DO:
        to_device = true;
        break;

    case STAT_DI:
    case STAT_ST:
    case STAT_MI:
        to_device = false;
        break;

    default:
        return;
    }

    if (s->dma) {
        /* DMA request so update DRQ according to transfer direction */
        if (to_device) {
            if (fifo8_num_free(&s->fifo) < 2) {
                esp_lower_drq(s);
            } else {
                esp_raise_drq(s);
            }
        } else {
            if (fifo8_num_used(&s->fifo) < 2) {
                esp_lower_drq(s);
            } else {
                esp_raise_drq(s);
            }
        }
    } else {
        /* Not a DMA request */
        esp_lower_drq(s);
    }
}

static void esp_fifo_push(ESPState *s, uint8_t val)
{
    if (fifo8_num_used(&s->fifo) == s->fifo.capacity) {
        trace_esp_error_fifo_overrun();
    } else {
        fifo8_push(&s->fifo, val);
    }

    esp_update_drq(s);
}

static void esp_fifo_push_buf(ESPState *s, uint8_t *buf, int len)
{
    fifo8_push_all(&s->fifo, buf, len);
    esp_update_drq(s);
}

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

    if (fifo8_is_empty(&s->fifo)) {
        val = 0;
    } else {
        val = fifo8_pop(&s->fifo);
    }

    esp_update_drq(s);
    return val;
}

static uint32_t esp_fifo_pop_buf(ESPState *s, uint8_t *dest, int maxlen)
{
    uint32_t len = fifo8_pop_buf(&s->fifo, dest, maxlen);

    esp_update_drq(s);
    return len;
}

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 uint8_t esp_pdma_read(ESPState *s)
{
    return esp_fifo_pop(s);
}

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

    esp_fifo_push(s, val);

    if (dmalen && s->drq_state) {
        dmalen--;
        esp_set_tc(s, dmalen);
    }
}

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

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

    s->ti_size = 0;
    s->rregs[ESP_RSEQ] = SEQ_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->asc_mode = ESP_ASC_MODE_DIS;
        s->rregs[ESP_RINTR] = INTR_DC;
        esp_raise_irq(s);
        return -1;
    }

    /*
     * Note that we deliberately don't raise the IRQ here: this will be done
     * either in esp_transfer_data() or esp_command_complete()
     */
    s->asc_mode = ESP_ASC_MODE_INI;
    return 0;
}

static void esp_do_dma(ESPState *s);
static void esp_do_nodma(ESPState *s);

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;
    }
    fifo8_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->asc_mode = ESP_ASC_MODE_DIS;
        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);
    s->data_ready = false;
    if (datalen != 0) {
        /*
         * Switch to DATA phase but wait until initial data xfer is
         * complete before raising the command completion interrupt
         */
        if (datalen > 0) {
            esp_set_phase(s, STAT_DI);
        } else {
            esp_set_phase(s, STAT_DO);
        }
        scsi_req_continue(s->current_req);
        return;
    }
}

static void do_message_phase(ESPState *s)
{
    if (s->cmdfifo_cdb_offset) {
        uint8_t message = fifo8_is_empty(&s->cmdfifo) ? 0 :
                          fifo8_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));
        fifo8_drop(&s->cmdfifo, 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 handle_satn(ESPState *s)
{
    if (s->dma && !s->dma_enabled) {
        s->dma_cb = handle_satn;
        return;
    }

    if (esp_select(s) < 0) {
        return;
    }

    esp_set_phase(s, STAT_MO);

    if (s->dma) {
        esp_do_dma(s);
    } else {
        esp_do_nodma(s);
    }
}

static void handle_s_without_atn(ESPState *s)
{
    if (s->dma && !s->dma_enabled) {
        s->dma_cb = handle_s_without_atn;
        return;
    }

    if (esp_select(s) < 0) {
        return;
    }

    esp_set_phase(s, STAT_CD);
    s->cmdfifo_cdb_offset = 0;

    if (s->dma) {
        esp_do_dma(s);
    } else {
        esp_do_nodma(s);
    }
}

static void handle_satn_stop(ESPState *s)
{
    if (s->dma && !s->dma_enabled) {
        s->dma_cb = handle_satn_stop;
        return;
    }

    if (esp_select(s) < 0) {
        return;
    }

    esp_set_phase(s, STAT_MO);
    s->cmdfifo_cdb_offset = 0;

    if (s->dma) {
        esp_do_dma(s);
    } else {
        esp_do_nodma(s);
    }
}

static void handle_pad(ESPState *s)
{
    if (s->dma) {
        esp_do_dma(s);
    } else {
        esp_do_nodma(s);
    }
}

static void write_response(ESPState *s)
{
    trace_esp_write_response(s->status);

    if (s->dma) {
        esp_do_dma(s);
    } else {
        esp_do_nodma(s);
    }
}

static bool esp_cdb_ready(ESPState *s)
{
    int len = fifo8_num_used(&s->cmdfifo) - s->cmdfifo_cdb_offset;
    const uint8_t *pbuf;
    uint32_t n;
    int cdblen;

    if (len <= 0) {
        return false;
    }

    pbuf = fifo8_peek_bufptr(&s->cmdfifo, len, &n);
    if (n < len) {
        /*
         * In normal use the cmdfifo should never wrap, but include this check
         * to prevent a malicious guest from reading past the end of the
         * cmdfifo data buffer below
         */
        return false;
    }

    cdblen = scsi_cdb_length((uint8_t *)&pbuf[s->cmdfifo_cdb_offset]);

    return cdblen < 0 ? false : (len >= cdblen);
}

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);
    }
}

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

    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));
            if (len) {
                s->dma_memory_read(s->dma_opaque, buf, len);
                esp_set_tc(s, esp_get_tc(s) - len);
            }
        } else {
            len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo));
            len = MIN(fifo8_num_free(&s->cmdfifo), len);
        }

        fifo8_push_all(&s->cmdfifo, buf, len);
        s->cmdfifo_cdb_offset += len;

        switch (s->rregs[ESP_CMD]) {
        case CMD_SELATN | CMD_DMA:
            if (fifo8_num_used(&s->cmdfifo) >= 1) {
                /* First byte received, switch to command phase */
                esp_set_phase(s, STAT_CD);
                s->rregs[ESP_RSEQ] = SEQ_CD;
                s->cmdfifo_cdb_offset = 1;

                if (fifo8_num_used(&s->cmdfifo) > 1) {
                    /* Process any additional command phase data */
                    esp_do_dma(s);
                }
            }
            break;

        case CMD_SELATNS | CMD_DMA:
            if (fifo8_num_used(&s->cmdfifo) == 1) {
                /* First byte received, stop in message out phase */
                s->rregs[ESP_RSEQ] = SEQ_MO;
                s->cmdfifo_cdb_offset = 1;

                /* Raise command completion interrupt */
                s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
                esp_raise_irq(s);
            }
            break;

        case CMD_TI | CMD_DMA:
            /* ATN remains asserted until TC == 0 */
            if (esp_get_tc(s) == 0) {
                esp_set_phase(s, STAT_CD);
                s->rregs[ESP_CMD] = 0;
                s->rregs[ESP_RINTR] |= INTR_BS;
                esp_raise_irq(s);
            }
            break;
        }
        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));
            if (len) {
                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 {
            len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo));
            len = MIN(fifo8_num_free(&s->cmdfifo), len);
            fifo8_push_all(&s->cmdfifo, buf, len);
        }
        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)) {
            /* Defer until data is available.  */
            return;
        }
        if (len > s->async_len) {
            len = s->async_len;
        }

        switch (s->rregs[ESP_CMD]) {
        case CMD_TI | CMD_DMA:
            if (s->dma_memory_read) {
                if (len) {
                    s->dma_memory_read(s->dma_opaque, s->async_buf, len);
                    esp_set_tc(s, esp_get_tc(s) - len);
                }
            } else {
                /* Copy FIFO data to device */
                len = MIN(s->async_len, ESP_FIFO_SZ);
                len = MIN(len, fifo8_num_used(&s->fifo));
                len = esp_fifo_pop_buf(s, s->async_buf, len);
            }

            s->async_buf += len;
            s->async_len -= len;
            s->ti_size += len;
            break;

        case CMD_PAD | CMD_DMA:
            /* Copy TC zero bytes into the incoming stream */
            if (!s->dma_memory_read) {
                len = MIN(s->async_len, ESP_FIFO_SZ);
                len = MIN(len, fifo8_num_free(&s->fifo));
            }

            memset(s->async_buf, 0, len);

            s->async_buf += len;
            s->async_len -= len;
            s->ti_size += len;
            break;
        }

        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)) {
            /* Defer until data is available.  */
            return;
        }
        if (len > s->async_len) {
            len = s->async_len;
        }

        switch (s->rregs[ESP_CMD]) {
        case CMD_TI | CMD_DMA:
            if (s->dma_memory_write) {
                if (len) {
                    s->dma_memory_write(s->dma_opaque, s->async_buf, len);
                }
            } else {
                /* Copy device data to FIFO */
                len = MIN(len, fifo8_num_free(&s->fifo));
                esp_fifo_push_buf(s, 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);
            break;

        case CMD_PAD | CMD_DMA:
            /* Drop TC bytes from the incoming stream */
            if (!s->dma_memory_write) {
                len = MIN(len, fifo8_num_free(&s->fifo));
            }

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

        if (s->async_len == 0 && s->ti_size == 0 && esp_get_tc(s)) {
            /* If the guest underflows TC then terminate SCSI request */
            scsi_req_continue(s->current_req);
            return;
        }

        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_ST:
        switch (s->rregs[ESP_CMD]) {
        case CMD_ICCS | CMD_DMA:
            len = MIN(len, 1);

            if (len) {
                buf[0] = s->status;

                if (s->dma_memory_write) {
                    /* Length already non-zero */
                    s->dma_memory_write(s->dma_opaque, buf, len);
                } else {
                    esp_fifo_push_buf(s, buf, len);
                }

                esp_set_tc(s, esp_get_tc(s) - len);
                esp_set_phase(s, STAT_MI);

                if (esp_get_tc(s) > 0) {
                    /* Process any message in phase data */
                    esp_do_dma(s);
                }
            }
            break;

        default:
            /* Consume remaining data if the guest underflows TC */
            if (fifo8_num_used(&s->fifo) < 2) {
                s->rregs[ESP_RINTR] |= INTR_BS;
                esp_raise_irq(s);
            }
            break;
        }
        break;

    case STAT_MI:
        switch (s->rregs[ESP_CMD]) {
        case CMD_ICCS | CMD_DMA:
            len = MIN(len, 1);

            if (len) {
                buf[0] = 0;

                if (s->dma_memory_write) {
                    /* Length already non-zero */
                    s->dma_memory_write(s->dma_opaque, buf, len);
                } else {
                    esp_fifo_push_buf(s, buf, len);
                }

                esp_set_tc(s, esp_get_tc(s) - len);

                /* Raise end of command interrupt */
                s->rregs[ESP_RINTR] |= INTR_FC;
                esp_raise_irq(s);
            }
            break;
        }
        break;
    }
}

static void esp_nodma_ti_dataout(ESPState *s)
{
    int len;

    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, 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);
}

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

    switch (esp_get_phase(s)) {
    case STAT_MO:
        switch (s->rregs[ESP_CMD]) {
        case CMD_SELATN:
            /* Copy FIFO into cmdfifo */
            len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo));
            len = MIN(fifo8_num_free(&s->cmdfifo), len);
            fifo8_push_all(&s->cmdfifo, buf, len);

            if (fifo8_num_used(&s->cmdfifo) >= 1) {
                /* First byte received, switch to command phase */
                esp_set_phase(s, STAT_CD);
                s->rregs[ESP_RSEQ] = SEQ_CD;
                s->cmdfifo_cdb_offset = 1;

                if (fifo8_num_used(&s->cmdfifo) > 1) {
                    /* Process any additional command phase data */
                    esp_do_nodma(s);
                }
            }
            break;

        case CMD_SELATNS:
            /* Copy one byte from FIFO into cmdfifo */
            len = esp_fifo_pop_buf(s, buf,
                                   MIN(fifo8_num_used(&s->fifo), 1));
            len = MIN(fifo8_num_free(&s->cmdfifo), len);
            fifo8_push_all(&s->cmdfifo, buf, len);

            if (fifo8_num_used(&s->cmdfifo) >= 1) {
                /* First byte received, stop in message out phase */
                s->rregs[ESP_RSEQ] = SEQ_MO;
                s->cmdfifo_cdb_offset = 1;

                /* Raise command completion interrupt */
                s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
                esp_raise_irq(s);
            }
            break;

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

            /* ATN remains asserted until FIFO empty */
            s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo);
            esp_set_phase(s, STAT_CD);
            s->rregs[ESP_CMD] = 0;
            s->rregs[ESP_RINTR] |= INTR_BS;
            esp_raise_irq(s);
            break;
        }
        break;

    case STAT_CD:
        switch (s->rregs[ESP_CMD]) {
        case CMD_TI:
            /* Copy FIFO into cmdfifo */
            len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo));
            len = MIN(fifo8_num_free(&s->cmdfifo), len);
            fifo8_push_all(&s->cmdfifo, buf, len);

            cmdlen = fifo8_num_used(&s->cmdfifo);
            trace_esp_handle_ti_cmd(cmdlen);

            /* CDB may be transferred in one or more TI commands */
            if (esp_cdb_ready(s)) {
                /* Command has been received */
                do_cmd(s);
            } else {
                /*
                 * If data was transferred from the FIFO then raise bus
                 * service interrupt to indicate transfer complete. Otherwise
                 * defer until the next FIFO write.
                 */
                if (len) {
                    /* Raise interrupt to indicate transfer complete */
                    s->rregs[ESP_RINTR] |= INTR_BS;
                    esp_raise_irq(s);
                }
            }
            break;

        case CMD_SEL | CMD_DMA:
        case CMD_SELATN | CMD_DMA:
            /* Copy FIFO into cmdfifo */
            len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo));
            len = MIN(fifo8_num_free(&s->cmdfifo), len);
            fifo8_push_all(&s->cmdfifo, buf, len);

            /* Handle when DMA transfer is terminated by non-DMA FIFO write */
            if (esp_cdb_ready(s)) {
                /* Command has been received */
                do_cmd(s);
            }
            break;

        case CMD_SEL:
        case CMD_SELATN:
            /* FIFO already contain entire CDB: copy to cmdfifo and execute */
            len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo));
            len = MIN(fifo8_num_free(&s->cmdfifo), len);
            fifo8_push_all(&s->cmdfifo, buf, len);

            do_cmd(s);
            break;
        }
        break;

    case STAT_DO:
        /* Accumulate data in FIFO until non-DMA TI is executed */
        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)) {
            esp_fifo_push(s, 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;
        }

        /* If preloading the FIFO, defer until TI command issued */
        if (s->rregs[ESP_CMD] != CMD_TI) {
            return;
        }

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

    case STAT_ST:
        switch (s->rregs[ESP_CMD]) {
        case CMD_ICCS:
            esp_fifo_push(s, s->status);
            esp_set_phase(s, STAT_MI);

            /* Process any message in phase data */
            esp_do_nodma(s);
            break;
        }
        break;

    case STAT_MI:
        switch (s->rregs[ESP_CMD]) {
        case CMD_ICCS:
            esp_fifo_push(s, 0);

            /* Raise end of command interrupt */
            s->rregs[ESP_RINTR] |= INTR_FC;
            esp_raise_irq(s);
            break;
        }
        break;
    }
}

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
     */
    s->ti_size = 0;

    switch (s->rregs[ESP_CMD]) {
    case CMD_SEL | CMD_DMA:
    case CMD_SEL:
    case CMD_SELATN | CMD_DMA:
    case CMD_SELATN:
        /*
         * No data phase for sequencer command so raise deferred bus service
         * and function complete interrupt
         */
        s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
        s->rregs[ESP_RSEQ] = SEQ_CD;
        break;

    case CMD_TI | CMD_DMA:
    case CMD_TI:
        s->rregs[ESP_CMD] = 0;
        break;
    }

    /* Raise bus service interrupt to indicate change to STATUS phase */
    esp_set_phase(s, STAT_ST);
    s->rregs[ESP_RINTR] |= INTR_BS;
    esp_raise_irq(s);

    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;
    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 (!s->data_ready) {
        s->data_ready = true;

        switch (s->rregs[ESP_CMD]) {
        case CMD_SEL | CMD_DMA:
        case CMD_SEL:
        case CMD_SELATN | CMD_DMA:
        case CMD_SELATN:
            /*
             * Initial incoming data xfer is complete for sequencer command
             * so raise deferred bus service and function complete interrupt
             */
             s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
             s->rregs[ESP_RSEQ] = SEQ_CD;
             esp_raise_irq(s);
             break;

        case CMD_SELATNS | CMD_DMA:
        case CMD_SELATNS:
            /*
             * Initial incoming data xfer is complete so raise command
             * completion interrupt
             */
             s->rregs[ESP_RINTR] |= INTR_BS;
             s->rregs[ESP_RSEQ] = SEQ_MO;
             esp_raise_irq(s);
             break;

        case CMD_TI | CMD_DMA:
        case CMD_TI:
            /*
             * If the final COMMAND phase data was transferred using a TI
             * command, clear ESP_CMD to terminate the TI command and raise
             * the completion interrupt
             */
            s->rregs[ESP_CMD] = 0;
            s->rregs[ESP_RINTR] |= INTR_BS;
            esp_raise_irq(s);
            break;
        }
    }

    /*
     * 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->rregs[ESP_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->rregs[ESP_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;
    }

    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);

        if (esp_get_phase(s) == STAT_DO) {
            esp_nodma_ti_dataout(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->asc_mode = ESP_ASC_MODE_DIS;

    s->rregs[ESP_CFG1] = 7;
}

static void esp_soft_reset(ESPState *s)
{
    qemu_irq_lower(s->irq);
    qemu_irq_lower(s->drq_irq);
    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 bool esp_cmd_is_valid(ESPState *s, uint8_t cmd)
{
    uint8_t cmd_group = (cmd & CMD_GRP_MASK) >> 4;

    /* Always allow misc commands */
    if (cmd_group == CMD_GRP_MISC) {
        return true;
    }

    switch (s->asc_mode) {
    case ESP_ASC_MODE_DIS:
        /* Disconnected mode: only allow disconnected commands */
        if (cmd_group == CMD_GRP_DISC) {
            return true;
        }
        break;

    case ESP_ASC_MODE_INI:
        /* Initiator mode: allow initiator commands */
        if (cmd_group == CMD_GRP_INIT) {
            return true;
        }
        break;

    default:
        g_assert_not_reached();
    }

    trace_esp_invalid_cmd(cmd, s->asc_mode);
    return false;
}

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);
        break;
    case CMD_MSGACC:
        trace_esp_mem_writeb_cmd_msgacc(cmd);
        s->asc_mode = ESP_ASC_MODE_DIS;
        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);
        handle_pad(s);
        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:
        s->rregs[ESP_FIFO] = esp_fifo_pop(s);
        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;
        esp_lower_irq(s);
        s->rregs[ESP_RSTAT] &= STAT_TC | 7;
        /*
         * 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;
         */
        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 (!fifo8_is_full(&s->fifo)) {
            esp_fifo_push(s, val);
        }
        esp_do_nodma(s);
        break;
    case ESP_CMD:
        s->rregs[saddr] = val;
        if (!esp_cmd_is_valid(s, s->rregs[saddr])) {
            s->rregs[ESP_RSTAT] |= INTR_IL;
            esp_raise_irq(s);
            break;
        }
        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;
}

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

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

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

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

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]);
        }
    }

    if (version_id < 8) {
        /* Assume initiator mode to allow all commands to continue */
        s->asc_mode = ESP_ASC_MODE_INI;
    }

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

const VMStateDescription vmstate_esp = {
    .name = "esp",
    .version_id = 8,
    .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_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(mig_ti_cmd, ESPState,
                           esp_is_between_version_5_and_6),
        VMSTATE_UINT8_TEST(lun, ESPState, esp_is_version_6),
        VMSTATE_BOOL(drq_state, ESPState),
        VMSTATE_UINT8_TEST(asc_mode, ESPState, esp_is_version_8),
        VMSTATE_END_OF_LIST()
    },
};

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_do_dma(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_do_dma(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->drq_irq);
    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, const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

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

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, const 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_types[] = {
    {
        .name          = TYPE_SYSBUS_ESP,
        .parent        = TYPE_SYS_BUS_DEVICE,
        .instance_init = sysbus_esp_init,
        .instance_size = sizeof(SysBusESPState),
        .class_init    = sysbus_esp_class_init,
    },
    {
        .name = TYPE_ESP,
        .parent = TYPE_DEVICE,
        .instance_init = esp_init,
        .instance_finalize = esp_finalize,
        .instance_size = sizeof(ESPState),
        .class_init = esp_class_init,
    },
};

DEFINE_TYPES(esp_info_types)
