/*
 * 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_fifo8_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_bufptr(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_bufptr(fifo, len, &n2);
        if (dest) {
            memcpy(&dest[n], buf, n2);
        }
        n += n2;
    }

    return n;
}

static uint32_t esp_fifo_pop_buf(ESPState *s, uint8_t *dest, int maxlen)
{
    uint32_t len = esp_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)
{
    uint8_t val;

    val = esp_fifo_pop(s);
    return val;
}

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->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()
     */
    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;
    }
    esp_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->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));
        esp_fifo8_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 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));
            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));
            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) {
                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) {
                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) {
                    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) {
                    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;
             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;
             break;

        case CMD_TI | CMD_DMA:
        case CMD_TI:
            /*
             * Bus service interrupt raised because of initial change to
             * DATA phase
             */
            s->rregs[ESP_CMD] = 0;
            s->rregs[ESP_RINTR] |= INTR_BS;
            break;
        }

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

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

const VMStateDescription vmstate_esp = {
    .name = "esp",
    .version_id = 7,
    .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_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, 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 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_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)
