/*
 * QEMU VMWARE PVSCSI paravirtual SCSI bus
 *
 * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
 *
 * Developed by Daynix Computing LTD (http://www.daynix.com)
 *
 * Based on implementation by Paolo Bonzini
 * http://lists.gnu.org/archive/html/qemu-devel/2011-08/msg00729.html
 *
 * Authors:
 * Paolo Bonzini <pbonzini@redhat.com>
 * Dmitry Fleytman <dmitry@daynix.com>
 * Yan Vugenfirer <yan@daynix.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.
 * See the COPYING file in the top-level directory.
 *
 * NOTE about MSI-X:
 * MSI-X support has been removed for the moment because it leads Windows OS
 * to crash on startup. The crash happens because Windows driver requires
 * MSI-X shared memory to be part of the same BAR used for rings state
 * registers, etc. This is not supported by QEMU infrastructure so separate
 * BAR created from MSI-X purposes. Windows driver fails to deal with 2 BARs.
 *
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/scsi/scsi.h"
#include <block/scsi.h>
#include "hw/pci/msi.h"
#include "vmw_pvscsi.h"
#include "trace.h"


#define PVSCSI_USE_64BIT         (true)
#define PVSCSI_PER_VECTOR_MASK   (false)

#define PVSCSI_MAX_DEVS                   (64)
#define PVSCSI_MSIX_NUM_VECTORS           (1)

#define PVSCSI_MAX_CMD_DATA_WORDS \
    (sizeof(PVSCSICmdDescSetupRings)/sizeof(uint32_t))

#define RS_GET_FIELD(m, field) \
    (ldl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \
                 (m)->rs_pa + offsetof(struct PVSCSIRingsState, field)))
#define RS_SET_FIELD(m, field, val) \
    (stl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \
                 (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val))

typedef struct PVSCSIClass {
    PCIDeviceClass parent_class;
    DeviceRealize parent_dc_realize;
} PVSCSIClass;

#define TYPE_PVSCSI "pvscsi"
#define PVSCSI(obj) OBJECT_CHECK(PVSCSIState, (obj), TYPE_PVSCSI)

#define PVSCSI_DEVICE_CLASS(klass) \
    OBJECT_CLASS_CHECK(PVSCSIClass, (klass), TYPE_PVSCSI)
#define PVSCSI_DEVICE_GET_CLASS(obj) \
    OBJECT_GET_CLASS(PVSCSIClass, (obj), TYPE_PVSCSI)

/* Compatability flags for migration */
#define PVSCSI_COMPAT_OLD_PCI_CONFIGURATION_BIT 0
#define PVSCSI_COMPAT_OLD_PCI_CONFIGURATION \
    (1 << PVSCSI_COMPAT_OLD_PCI_CONFIGURATION_BIT)
#define PVSCSI_COMPAT_DISABLE_PCIE_BIT 1
#define PVSCSI_COMPAT_DISABLE_PCIE \
    (1 << PVSCSI_COMPAT_DISABLE_PCIE_BIT)

#define PVSCSI_USE_OLD_PCI_CONFIGURATION(s) \
    ((s)->compat_flags & PVSCSI_COMPAT_OLD_PCI_CONFIGURATION)
#define PVSCSI_MSI_OFFSET(s) \
    (PVSCSI_USE_OLD_PCI_CONFIGURATION(s) ? 0x50 : 0x7c)
#define PVSCSI_EXP_EP_OFFSET (0x40)

typedef struct PVSCSIRingInfo {
    uint64_t            rs_pa;
    uint32_t            txr_len_mask;
    uint32_t            rxr_len_mask;
    uint32_t            msg_len_mask;
    uint64_t            req_ring_pages_pa[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
    uint64_t            cmp_ring_pages_pa[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
    uint64_t            msg_ring_pages_pa[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES];
    uint64_t            consumed_ptr;
    uint64_t            filled_cmp_ptr;
    uint64_t            filled_msg_ptr;
} PVSCSIRingInfo;

typedef struct PVSCSISGState {
    hwaddr elemAddr;
    hwaddr dataAddr;
    uint32_t resid;
} PVSCSISGState;

typedef QTAILQ_HEAD(, PVSCSIRequest) PVSCSIRequestList;

typedef struct {
    PCIDevice parent_obj;
    MemoryRegion io_space;
    SCSIBus bus;
    QEMUBH *completion_worker;
    PVSCSIRequestList pending_queue;
    PVSCSIRequestList completion_queue;

    uint64_t reg_interrupt_status;        /* Interrupt status register value */
    uint64_t reg_interrupt_enabled;       /* Interrupt mask register value   */
    uint64_t reg_command_status;          /* Command status register value   */

    /* Command data adoption mechanism */
    uint64_t curr_cmd;                   /* Last command arrived             */
    uint32_t curr_cmd_data_cntr;         /* Amount of data for last command  */

    /* Collector for current command data */
    uint32_t curr_cmd_data[PVSCSI_MAX_CMD_DATA_WORDS];

    uint8_t rings_info_valid;            /* Whether data rings initialized   */
    uint8_t msg_ring_info_valid;         /* Whether message ring initialized */
    uint8_t use_msg;                     /* Whether to use message ring      */

    uint8_t msi_used;    /* Whether MSI support was installed successfully   */

    PVSCSIRingInfo rings;                /* Data transfer rings manager      */
    uint32_t resetting;                  /* Reset in progress                */

    uint32_t compat_flags;
} PVSCSIState;

typedef struct PVSCSIRequest {
    SCSIRequest *sreq;
    PVSCSIState *dev;
    uint8_t sense_key;
    uint8_t completed;
    int lun;
    QEMUSGList sgl;
    PVSCSISGState sg;
    struct PVSCSIRingReqDesc req;
    struct PVSCSIRingCmpDesc cmp;
    QTAILQ_ENTRY(PVSCSIRequest) next;
} PVSCSIRequest;

/* Integer binary logarithm */
static int
pvscsi_log2(uint32_t input)
{
    int log = 0;
    assert(input > 0);
    while (input >> ++log) {
    }
    return log;
}

static void
pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
{
    int i;
    uint32_t txr_len_log2, rxr_len_log2;
    uint32_t req_ring_size, cmp_ring_size;
    m->rs_pa = ri->ringsStatePPN << VMW_PAGE_SHIFT;

    req_ring_size = ri->reqRingNumPages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
    cmp_ring_size = ri->cmpRingNumPages * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE;
    txr_len_log2 = pvscsi_log2(req_ring_size - 1);
    rxr_len_log2 = pvscsi_log2(cmp_ring_size - 1);

    m->txr_len_mask = MASK(txr_len_log2);
    m->rxr_len_mask = MASK(rxr_len_log2);

    m->consumed_ptr = 0;
    m->filled_cmp_ptr = 0;

    for (i = 0; i < ri->reqRingNumPages; i++) {
        m->req_ring_pages_pa[i] = ri->reqRingPPNs[i] << VMW_PAGE_SHIFT;
    }

    for (i = 0; i < ri->cmpRingNumPages; i++) {
        m->cmp_ring_pages_pa[i] = ri->cmpRingPPNs[i] << VMW_PAGE_SHIFT;
    }

    RS_SET_FIELD(m, reqProdIdx, 0);
    RS_SET_FIELD(m, reqConsIdx, 0);
    RS_SET_FIELD(m, reqNumEntriesLog2, txr_len_log2);

    RS_SET_FIELD(m, cmpProdIdx, 0);
    RS_SET_FIELD(m, cmpConsIdx, 0);
    RS_SET_FIELD(m, cmpNumEntriesLog2, rxr_len_log2);

    trace_pvscsi_ring_init_data(txr_len_log2, rxr_len_log2);

    /* Flush ring state page changes */
    smp_wmb();
}

static void
pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri)
{
    int i;
    uint32_t len_log2;
    uint32_t ring_size;

    ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;
    len_log2 = pvscsi_log2(ring_size - 1);

    m->msg_len_mask = MASK(len_log2);

    m->filled_msg_ptr = 0;

    for (i = 0; i < ri->numPages; i++) {
        m->msg_ring_pages_pa[i] = ri->ringPPNs[i] << VMW_PAGE_SHIFT;
    }

    RS_SET_FIELD(m, msgProdIdx, 0);
    RS_SET_FIELD(m, msgConsIdx, 0);
    RS_SET_FIELD(m, msgNumEntriesLog2, len_log2);

    trace_pvscsi_ring_init_msg(len_log2);

    /* Flush ring state page changes */
    smp_wmb();
}

static void
pvscsi_ring_cleanup(PVSCSIRingInfo *mgr)
{
    mgr->rs_pa = 0;
    mgr->txr_len_mask = 0;
    mgr->rxr_len_mask = 0;
    mgr->msg_len_mask = 0;
    mgr->consumed_ptr = 0;
    mgr->filled_cmp_ptr = 0;
    mgr->filled_msg_ptr = 0;
    memset(mgr->req_ring_pages_pa, 0, sizeof(mgr->req_ring_pages_pa));
    memset(mgr->cmp_ring_pages_pa, 0, sizeof(mgr->cmp_ring_pages_pa));
    memset(mgr->msg_ring_pages_pa, 0, sizeof(mgr->msg_ring_pages_pa));
}

static hwaddr
pvscsi_ring_pop_req_descr(PVSCSIRingInfo *mgr)
{
    uint32_t ready_ptr = RS_GET_FIELD(mgr, reqProdIdx);

    if (ready_ptr != mgr->consumed_ptr) {
        uint32_t next_ready_ptr =
            mgr->consumed_ptr++ & mgr->txr_len_mask;
        uint32_t next_ready_page =
            next_ready_ptr / PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
        uint32_t inpage_idx =
            next_ready_ptr % PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;

        return mgr->req_ring_pages_pa[next_ready_page] +
               inpage_idx * sizeof(PVSCSIRingReqDesc);
    } else {
        return 0;
    }
}

static void
pvscsi_ring_flush_req(PVSCSIRingInfo *mgr)
{
    RS_SET_FIELD(mgr, reqConsIdx, mgr->consumed_ptr);
}

static hwaddr
pvscsi_ring_pop_cmp_descr(PVSCSIRingInfo *mgr)
{
    /*
     * According to Linux driver code it explicitly verifies that number
     * of requests being processed by device is less then the size of
     * completion queue, so device may omit completion queue overflow
     * conditions check. We assume that this is true for other (Windows)
     * drivers as well.
     */

    uint32_t free_cmp_ptr =
        mgr->filled_cmp_ptr++ & mgr->rxr_len_mask;
    uint32_t free_cmp_page =
        free_cmp_ptr / PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE;
    uint32_t inpage_idx =
        free_cmp_ptr % PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE;
    return mgr->cmp_ring_pages_pa[free_cmp_page] +
           inpage_idx * sizeof(PVSCSIRingCmpDesc);
}

static hwaddr
pvscsi_ring_pop_msg_descr(PVSCSIRingInfo *mgr)
{
    uint32_t free_msg_ptr =
        mgr->filled_msg_ptr++ & mgr->msg_len_mask;
    uint32_t free_msg_page =
        free_msg_ptr / PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;
    uint32_t inpage_idx =
        free_msg_ptr % PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;
    return mgr->msg_ring_pages_pa[free_msg_page] +
           inpage_idx * sizeof(PVSCSIRingMsgDesc);
}

static void
pvscsi_ring_flush_cmp(PVSCSIRingInfo *mgr)
{
    /* Flush descriptor changes */
    smp_wmb();

    trace_pvscsi_ring_flush_cmp(mgr->filled_cmp_ptr);

    RS_SET_FIELD(mgr, cmpProdIdx, mgr->filled_cmp_ptr);
}

static bool
pvscsi_ring_msg_has_room(PVSCSIRingInfo *mgr)
{
    uint32_t prodIdx = RS_GET_FIELD(mgr, msgProdIdx);
    uint32_t consIdx = RS_GET_FIELD(mgr, msgConsIdx);

    return (prodIdx - consIdx) < (mgr->msg_len_mask + 1);
}

static void
pvscsi_ring_flush_msg(PVSCSIRingInfo *mgr)
{
    /* Flush descriptor changes */
    smp_wmb();

    trace_pvscsi_ring_flush_msg(mgr->filled_msg_ptr);

    RS_SET_FIELD(mgr, msgProdIdx, mgr->filled_msg_ptr);
}

static void
pvscsi_reset_state(PVSCSIState *s)
{
    s->curr_cmd = PVSCSI_CMD_FIRST;
    s->curr_cmd_data_cntr = 0;
    s->reg_command_status = PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
    s->reg_interrupt_status = 0;
    pvscsi_ring_cleanup(&s->rings);
    s->rings_info_valid = FALSE;
    s->msg_ring_info_valid = FALSE;
    QTAILQ_INIT(&s->pending_queue);
    QTAILQ_INIT(&s->completion_queue);
}

static void
pvscsi_update_irq_status(PVSCSIState *s)
{
    PCIDevice *d = PCI_DEVICE(s);
    bool should_raise = s->reg_interrupt_enabled & s->reg_interrupt_status;

    trace_pvscsi_update_irq_level(should_raise, s->reg_interrupt_enabled,
                                  s->reg_interrupt_status);

    if (s->msi_used && msi_enabled(d)) {
        if (should_raise) {
            trace_pvscsi_update_irq_msi();
            msi_notify(d, PVSCSI_VECTOR_COMPLETION);
        }
        return;
    }

    pci_set_irq(d, !!should_raise);
}

static void
pvscsi_raise_completion_interrupt(PVSCSIState *s)
{
    s->reg_interrupt_status |= PVSCSI_INTR_CMPL_0;

    /* Memory barrier to flush interrupt status register changes*/
    smp_wmb();

    pvscsi_update_irq_status(s);
}

static void
pvscsi_raise_message_interrupt(PVSCSIState *s)
{
    s->reg_interrupt_status |= PVSCSI_INTR_MSG_0;

    /* Memory barrier to flush interrupt status register changes*/
    smp_wmb();

    pvscsi_update_irq_status(s);
}

static void
pvscsi_cmp_ring_put(PVSCSIState *s, struct PVSCSIRingCmpDesc *cmp_desc)
{
    hwaddr cmp_descr_pa;

    cmp_descr_pa = pvscsi_ring_pop_cmp_descr(&s->rings);
    trace_pvscsi_cmp_ring_put(cmp_descr_pa);
    cpu_physical_memory_write(cmp_descr_pa, (void *)cmp_desc,
                              sizeof(*cmp_desc));
}

static void
pvscsi_msg_ring_put(PVSCSIState *s, struct PVSCSIRingMsgDesc *msg_desc)
{
    hwaddr msg_descr_pa;

    msg_descr_pa = pvscsi_ring_pop_msg_descr(&s->rings);
    trace_pvscsi_msg_ring_put(msg_descr_pa);
    cpu_physical_memory_write(msg_descr_pa, (void *)msg_desc,
                              sizeof(*msg_desc));
}

static void
pvscsi_process_completion_queue(void *opaque)
{
    PVSCSIState *s = opaque;
    PVSCSIRequest *pvscsi_req;
    bool has_completed = false;

    while (!QTAILQ_EMPTY(&s->completion_queue)) {
        pvscsi_req = QTAILQ_FIRST(&s->completion_queue);
        QTAILQ_REMOVE(&s->completion_queue, pvscsi_req, next);
        pvscsi_cmp_ring_put(s, &pvscsi_req->cmp);
        g_free(pvscsi_req);
        has_completed = true;
    }

    if (has_completed) {
        pvscsi_ring_flush_cmp(&s->rings);
        pvscsi_raise_completion_interrupt(s);
    }
}

static void
pvscsi_reset_adapter(PVSCSIState *s)
{
    s->resetting++;
    qbus_reset_all_fn(&s->bus);
    s->resetting--;
    pvscsi_process_completion_queue(s);
    assert(QTAILQ_EMPTY(&s->pending_queue));
    pvscsi_reset_state(s);
}

static void
pvscsi_schedule_completion_processing(PVSCSIState *s)
{
    /* Try putting more complete requests on the ring. */
    if (!QTAILQ_EMPTY(&s->completion_queue)) {
        qemu_bh_schedule(s->completion_worker);
    }
}

static void
pvscsi_complete_request(PVSCSIState *s, PVSCSIRequest *r)
{
    assert(!r->completed);

    trace_pvscsi_complete_request(r->cmp.context, r->cmp.dataLen,
                                  r->sense_key);
    if (r->sreq != NULL) {
        scsi_req_unref(r->sreq);
        r->sreq = NULL;
    }
    r->completed = 1;
    QTAILQ_REMOVE(&s->pending_queue, r, next);
    QTAILQ_INSERT_TAIL(&s->completion_queue, r, next);
    pvscsi_schedule_completion_processing(s);
}

static QEMUSGList *pvscsi_get_sg_list(SCSIRequest *r)
{
    PVSCSIRequest *req = r->hba_private;

    trace_pvscsi_get_sg_list(req->sgl.nsg, req->sgl.size);

    return &req->sgl;
}

static void
pvscsi_get_next_sg_elem(PVSCSISGState *sg)
{
    struct PVSCSISGElement elem;

    cpu_physical_memory_read(sg->elemAddr, (void *)&elem, sizeof(elem));
    if ((elem.flags & ~PVSCSI_KNOWN_FLAGS) != 0) {
        /*
            * There is PVSCSI_SGE_FLAG_CHAIN_ELEMENT flag described in
            * header file but its value is unknown. This flag requires
            * additional processing, so we put warning here to catch it
            * some day and make proper implementation
            */
        trace_pvscsi_get_next_sg_elem(elem.flags);
    }

    sg->elemAddr += sizeof(elem);
    sg->dataAddr = elem.addr;
    sg->resid = elem.length;
}

static void
pvscsi_write_sense(PVSCSIRequest *r, uint8_t *sense, int len)
{
    r->cmp.senseLen = MIN(r->req.senseLen, len);
    r->sense_key = sense[(sense[0] & 2) ? 1 : 2];
    cpu_physical_memory_write(r->req.senseAddr, sense, r->cmp.senseLen);
}

static void
pvscsi_command_complete(SCSIRequest *req, uint32_t status, size_t resid)
{
    PVSCSIRequest *pvscsi_req = req->hba_private;
    PVSCSIState *s;

    if (!pvscsi_req) {
        trace_pvscsi_command_complete_not_found(req->tag);
        return;
    }
    s = pvscsi_req->dev;

    if (resid) {
        /* Short transfer.  */
        trace_pvscsi_command_complete_data_run();
        pvscsi_req->cmp.hostStatus = BTSTAT_DATARUN;
    }

    pvscsi_req->cmp.scsiStatus = status;
    if (pvscsi_req->cmp.scsiStatus == CHECK_CONDITION) {
        uint8_t sense[SCSI_SENSE_BUF_SIZE];
        int sense_len =
            scsi_req_get_sense(pvscsi_req->sreq, sense, sizeof(sense));

        trace_pvscsi_command_complete_sense_len(sense_len);
        pvscsi_write_sense(pvscsi_req, sense, sense_len);
    }
    qemu_sglist_destroy(&pvscsi_req->sgl);
    pvscsi_complete_request(s, pvscsi_req);
}

static void
pvscsi_send_msg(PVSCSIState *s, SCSIDevice *dev, uint32_t msg_type)
{
    if (s->msg_ring_info_valid && pvscsi_ring_msg_has_room(&s->rings)) {
        PVSCSIMsgDescDevStatusChanged msg = {0};

        msg.type = msg_type;
        msg.bus = dev->channel;
        msg.target = dev->id;
        msg.lun[1] = dev->lun;

        pvscsi_msg_ring_put(s, (PVSCSIRingMsgDesc *)&msg);
        pvscsi_ring_flush_msg(&s->rings);
        pvscsi_raise_message_interrupt(s);
    }
}

static void
pvscsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp)
{
    PVSCSIState *s = PVSCSI(hotplug_dev);

    pvscsi_send_msg(s, SCSI_DEVICE(dev), PVSCSI_MSG_DEV_ADDED);
}

static void
pvscsi_hot_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp)
{
    PVSCSIState *s = PVSCSI(hotplug_dev);

    pvscsi_send_msg(s, SCSI_DEVICE(dev), PVSCSI_MSG_DEV_REMOVED);
    qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
}

static void
pvscsi_request_cancelled(SCSIRequest *req)
{
    PVSCSIRequest *pvscsi_req = req->hba_private;
    PVSCSIState *s = pvscsi_req->dev;

    if (pvscsi_req->completed) {
        return;
    }

   if (pvscsi_req->dev->resetting) {
       pvscsi_req->cmp.hostStatus = BTSTAT_BUSRESET;
    } else {
       pvscsi_req->cmp.hostStatus = BTSTAT_ABORTQUEUE;
    }

    pvscsi_complete_request(s, pvscsi_req);
}

static SCSIDevice*
pvscsi_device_find(PVSCSIState *s, int channel, int target,
                   uint8_t *requested_lun, uint8_t *target_lun)
{
    if (requested_lun[0] || requested_lun[2] || requested_lun[3] ||
        requested_lun[4] || requested_lun[5] || requested_lun[6] ||
        requested_lun[7] || (target > PVSCSI_MAX_DEVS)) {
        return NULL;
    } else {
        *target_lun = requested_lun[1];
        return scsi_device_find(&s->bus, channel, target, *target_lun);
    }
}

static PVSCSIRequest *
pvscsi_queue_pending_descriptor(PVSCSIState *s, SCSIDevice **d,
                                struct PVSCSIRingReqDesc *descr)
{
    PVSCSIRequest *pvscsi_req;
    uint8_t lun;

    pvscsi_req = g_malloc0(sizeof(*pvscsi_req));
    pvscsi_req->dev = s;
    pvscsi_req->req = *descr;
    pvscsi_req->cmp.context = pvscsi_req->req.context;
    QTAILQ_INSERT_TAIL(&s->pending_queue, pvscsi_req, next);

    *d = pvscsi_device_find(s, descr->bus, descr->target, descr->lun, &lun);
    if (*d) {
        pvscsi_req->lun = lun;
    }

    return pvscsi_req;
}

static void
pvscsi_convert_sglist(PVSCSIRequest *r)
{
    int chunk_size;
    uint64_t data_length = r->req.dataLen;
    PVSCSISGState sg = r->sg;
    while (data_length) {
        while (!sg.resid) {
            pvscsi_get_next_sg_elem(&sg);
            trace_pvscsi_convert_sglist(r->req.context, r->sg.dataAddr,
                                        r->sg.resid);
        }
        assert(data_length > 0);
        chunk_size = MIN((unsigned) data_length, sg.resid);
        if (chunk_size) {
            qemu_sglist_add(&r->sgl, sg.dataAddr, chunk_size);
        }

        sg.dataAddr += chunk_size;
        data_length -= chunk_size;
        sg.resid -= chunk_size;
    }
}

static void
pvscsi_build_sglist(PVSCSIState *s, PVSCSIRequest *r)
{
    PCIDevice *d = PCI_DEVICE(s);

    pci_dma_sglist_init(&r->sgl, d, 1);
    if (r->req.flags & PVSCSI_FLAG_CMD_WITH_SG_LIST) {
        pvscsi_convert_sglist(r);
    } else {
        qemu_sglist_add(&r->sgl, r->req.dataAddr, r->req.dataLen);
    }
}

static void
pvscsi_process_request_descriptor(PVSCSIState *s,
                                  struct PVSCSIRingReqDesc *descr)
{
    SCSIDevice *d;
    PVSCSIRequest *r = pvscsi_queue_pending_descriptor(s, &d, descr);
    int64_t n;

    trace_pvscsi_process_req_descr(descr->cdb[0], descr->context);

    if (!d) {
        r->cmp.hostStatus = BTSTAT_SELTIMEO;
        trace_pvscsi_process_req_descr_unknown_device();
        pvscsi_complete_request(s, r);
        return;
    }

    if (descr->flags & PVSCSI_FLAG_CMD_WITH_SG_LIST) {
        r->sg.elemAddr = descr->dataAddr;
    }

    r->sreq = scsi_req_new(d, descr->context, r->lun, descr->cdb, r);
    if (r->sreq->cmd.mode == SCSI_XFER_FROM_DEV &&
        (descr->flags & PVSCSI_FLAG_CMD_DIR_TODEVICE)) {
        r->cmp.hostStatus = BTSTAT_BADMSG;
        trace_pvscsi_process_req_descr_invalid_dir();
        scsi_req_cancel(r->sreq);
        return;
    }
    if (r->sreq->cmd.mode == SCSI_XFER_TO_DEV &&
        (descr->flags & PVSCSI_FLAG_CMD_DIR_TOHOST)) {
        r->cmp.hostStatus = BTSTAT_BADMSG;
        trace_pvscsi_process_req_descr_invalid_dir();
        scsi_req_cancel(r->sreq);
        return;
    }

    pvscsi_build_sglist(s, r);
    n = scsi_req_enqueue(r->sreq);

    if (n) {
        scsi_req_continue(r->sreq);
    }
}

static void
pvscsi_process_io(PVSCSIState *s)
{
    PVSCSIRingReqDesc descr;
    hwaddr next_descr_pa;

    assert(s->rings_info_valid);
    while ((next_descr_pa = pvscsi_ring_pop_req_descr(&s->rings)) != 0) {

        /* Only read after production index verification */
        smp_rmb();

        trace_pvscsi_process_io(next_descr_pa);
        cpu_physical_memory_read(next_descr_pa, &descr, sizeof(descr));
        pvscsi_process_request_descriptor(s, &descr);
    }

    pvscsi_ring_flush_req(&s->rings);
}

static void
pvscsi_dbg_dump_tx_rings_config(PVSCSICmdDescSetupRings *rc)
{
    int i;
    trace_pvscsi_tx_rings_ppn("Rings State", rc->ringsStatePPN);

    trace_pvscsi_tx_rings_num_pages("Request Ring", rc->reqRingNumPages);
    for (i = 0; i < rc->reqRingNumPages; i++) {
        trace_pvscsi_tx_rings_ppn("Request Ring", rc->reqRingPPNs[i]);
    }

    trace_pvscsi_tx_rings_num_pages("Confirm Ring", rc->cmpRingNumPages);
    for (i = 0; i < rc->cmpRingNumPages; i++) {
        trace_pvscsi_tx_rings_ppn("Confirm Ring", rc->reqRingPPNs[i]);
    }
}

static uint64_t
pvscsi_on_cmd_config(PVSCSIState *s)
{
    trace_pvscsi_on_cmd_noimpl("PVSCSI_CMD_CONFIG");
    return PVSCSI_COMMAND_PROCESSING_FAILED;
}

static uint64_t
pvscsi_on_cmd_unplug(PVSCSIState *s)
{
    trace_pvscsi_on_cmd_noimpl("PVSCSI_CMD_DEVICE_UNPLUG");
    return PVSCSI_COMMAND_PROCESSING_FAILED;
}

static uint64_t
pvscsi_on_issue_scsi(PVSCSIState *s)
{
    trace_pvscsi_on_cmd_noimpl("PVSCSI_CMD_ISSUE_SCSI");
    return PVSCSI_COMMAND_PROCESSING_FAILED;
}

static uint64_t
pvscsi_on_cmd_setup_rings(PVSCSIState *s)
{
    PVSCSICmdDescSetupRings *rc =
        (PVSCSICmdDescSetupRings *) s->curr_cmd_data;

    trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_RINGS");

    pvscsi_dbg_dump_tx_rings_config(rc);
    pvscsi_ring_init_data(&s->rings, rc);
    s->rings_info_valid = TRUE;
    return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
}

static uint64_t
pvscsi_on_cmd_abort(PVSCSIState *s)
{
    PVSCSICmdDescAbortCmd *cmd = (PVSCSICmdDescAbortCmd *) s->curr_cmd_data;
    PVSCSIRequest *r, *next;

    trace_pvscsi_on_cmd_abort(cmd->context, cmd->target);

    QTAILQ_FOREACH_SAFE(r, &s->pending_queue, next, next) {
        if (r->req.context == cmd->context) {
            break;
        }
    }
    if (r) {
        assert(!r->completed);
        r->cmp.hostStatus = BTSTAT_ABORTQUEUE;
        scsi_req_cancel(r->sreq);
    }

    return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
}

static uint64_t
pvscsi_on_cmd_unknown(PVSCSIState *s)
{
    trace_pvscsi_on_cmd_unknown_data(s->curr_cmd_data[0]);
    return PVSCSI_COMMAND_PROCESSING_FAILED;
}

static uint64_t
pvscsi_on_cmd_reset_device(PVSCSIState *s)
{
    uint8_t target_lun = 0;
    struct PVSCSICmdDescResetDevice *cmd =
        (struct PVSCSICmdDescResetDevice *) s->curr_cmd_data;
    SCSIDevice *sdev;

    sdev = pvscsi_device_find(s, 0, cmd->target, cmd->lun, &target_lun);

    trace_pvscsi_on_cmd_reset_dev(cmd->target, (int) target_lun, sdev);

    if (sdev != NULL) {
        s->resetting++;
        device_reset(&sdev->qdev);
        s->resetting--;
        return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
    }

    return PVSCSI_COMMAND_PROCESSING_FAILED;
}

static uint64_t
pvscsi_on_cmd_reset_bus(PVSCSIState *s)
{
    trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_RESET_BUS");

    s->resetting++;
    qbus_reset_all_fn(&s->bus);
    s->resetting--;
    return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
}

static uint64_t
pvscsi_on_cmd_setup_msg_ring(PVSCSIState *s)
{
    PVSCSICmdDescSetupMsgRing *rc =
        (PVSCSICmdDescSetupMsgRing *) s->curr_cmd_data;

    trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_MSG_RING");

    if (!s->use_msg) {
        return PVSCSI_COMMAND_PROCESSING_FAILED;
    }

    if (s->rings_info_valid) {
        pvscsi_ring_init_msg(&s->rings, rc);
        s->msg_ring_info_valid = TRUE;
    }
    return sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(uint32_t);
}

static uint64_t
pvscsi_on_cmd_adapter_reset(PVSCSIState *s)
{
    trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_ADAPTER_RESET");

    pvscsi_reset_adapter(s);
    return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
}

static const struct {
    int       data_size;
    uint64_t  (*handler_fn)(PVSCSIState *s);
} pvscsi_commands[] = {
    [PVSCSI_CMD_FIRST] = {
        .data_size = 0,
        .handler_fn = pvscsi_on_cmd_unknown,
    },

    /* Not implemented, data size defined based on what arrives on windows */
    [PVSCSI_CMD_CONFIG] = {
        .data_size = 6 * sizeof(uint32_t),
        .handler_fn = pvscsi_on_cmd_config,
    },

    /* Command not implemented, data size is unknown */
    [PVSCSI_CMD_ISSUE_SCSI] = {
        .data_size = 0,
        .handler_fn = pvscsi_on_issue_scsi,
    },

    /* Command not implemented, data size is unknown */
    [PVSCSI_CMD_DEVICE_UNPLUG] = {
        .data_size = 0,
        .handler_fn = pvscsi_on_cmd_unplug,
    },

    [PVSCSI_CMD_SETUP_RINGS] = {
        .data_size = sizeof(PVSCSICmdDescSetupRings),
        .handler_fn = pvscsi_on_cmd_setup_rings,
    },

    [PVSCSI_CMD_RESET_DEVICE] = {
        .data_size = sizeof(struct PVSCSICmdDescResetDevice),
        .handler_fn = pvscsi_on_cmd_reset_device,
    },

    [PVSCSI_CMD_RESET_BUS] = {
        .data_size = 0,
        .handler_fn = pvscsi_on_cmd_reset_bus,
    },

    [PVSCSI_CMD_SETUP_MSG_RING] = {
        .data_size = sizeof(PVSCSICmdDescSetupMsgRing),
        .handler_fn = pvscsi_on_cmd_setup_msg_ring,
    },

    [PVSCSI_CMD_ADAPTER_RESET] = {
        .data_size = 0,
        .handler_fn = pvscsi_on_cmd_adapter_reset,
    },

    [PVSCSI_CMD_ABORT_CMD] = {
        .data_size = sizeof(struct PVSCSICmdDescAbortCmd),
        .handler_fn = pvscsi_on_cmd_abort,
    },
};

static void
pvscsi_do_command_processing(PVSCSIState *s)
{
    size_t bytes_arrived = s->curr_cmd_data_cntr * sizeof(uint32_t);

    assert(s->curr_cmd < PVSCSI_CMD_LAST);
    if (bytes_arrived >= pvscsi_commands[s->curr_cmd].data_size) {
        s->reg_command_status = pvscsi_commands[s->curr_cmd].handler_fn(s);
        s->curr_cmd = PVSCSI_CMD_FIRST;
        s->curr_cmd_data_cntr   = 0;
    }
}

static void
pvscsi_on_command_data(PVSCSIState *s, uint32_t value)
{
    size_t bytes_arrived = s->curr_cmd_data_cntr * sizeof(uint32_t);

    assert(bytes_arrived < sizeof(s->curr_cmd_data));
    s->curr_cmd_data[s->curr_cmd_data_cntr++] = value;

    pvscsi_do_command_processing(s);
}

static void
pvscsi_on_command(PVSCSIState *s, uint64_t cmd_id)
{
    if ((cmd_id > PVSCSI_CMD_FIRST) && (cmd_id < PVSCSI_CMD_LAST)) {
        s->curr_cmd = cmd_id;
    } else {
        s->curr_cmd = PVSCSI_CMD_FIRST;
        trace_pvscsi_on_cmd_unknown(cmd_id);
    }

    s->curr_cmd_data_cntr = 0;
    s->reg_command_status = PVSCSI_COMMAND_NOT_ENOUGH_DATA;

    pvscsi_do_command_processing(s);
}

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

    switch (addr) {
    case PVSCSI_REG_OFFSET_COMMAND:
        pvscsi_on_command(s, val);
        break;

    case PVSCSI_REG_OFFSET_COMMAND_DATA:
        pvscsi_on_command_data(s, (uint32_t) val);
        break;

    case PVSCSI_REG_OFFSET_INTR_STATUS:
        trace_pvscsi_io_write("PVSCSI_REG_OFFSET_INTR_STATUS", val);
        s->reg_interrupt_status &= ~val;
        pvscsi_update_irq_status(s);
        pvscsi_schedule_completion_processing(s);
        break;

    case PVSCSI_REG_OFFSET_INTR_MASK:
        trace_pvscsi_io_write("PVSCSI_REG_OFFSET_INTR_MASK", val);
        s->reg_interrupt_enabled = val;
        pvscsi_update_irq_status(s);
        break;

    case PVSCSI_REG_OFFSET_KICK_NON_RW_IO:
        trace_pvscsi_io_write("PVSCSI_REG_OFFSET_KICK_NON_RW_IO", val);
        pvscsi_process_io(s);
        break;

    case PVSCSI_REG_OFFSET_KICK_RW_IO:
        trace_pvscsi_io_write("PVSCSI_REG_OFFSET_KICK_RW_IO", val);
        pvscsi_process_io(s);
        break;

    case PVSCSI_REG_OFFSET_DEBUG:
        trace_pvscsi_io_write("PVSCSI_REG_OFFSET_DEBUG", val);
        break;

    default:
        trace_pvscsi_io_write_unknown(addr, size, val);
        break;
    }

}

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

    switch (addr) {
    case PVSCSI_REG_OFFSET_INTR_STATUS:
        trace_pvscsi_io_read("PVSCSI_REG_OFFSET_INTR_STATUS",
                             s->reg_interrupt_status);
        return s->reg_interrupt_status;

    case PVSCSI_REG_OFFSET_INTR_MASK:
        trace_pvscsi_io_read("PVSCSI_REG_OFFSET_INTR_MASK",
                             s->reg_interrupt_status);
        return s->reg_interrupt_enabled;

    case PVSCSI_REG_OFFSET_COMMAND_STATUS:
        trace_pvscsi_io_read("PVSCSI_REG_OFFSET_COMMAND_STATUS",
                             s->reg_interrupt_status);
        return s->reg_command_status;

    default:
        trace_pvscsi_io_read_unknown(addr, size);
        return 0;
    }
}


static bool
pvscsi_init_msi(PVSCSIState *s)
{
    int res;
    PCIDevice *d = PCI_DEVICE(s);

    res = msi_init(d, PVSCSI_MSI_OFFSET(s), PVSCSI_MSIX_NUM_VECTORS,
                   PVSCSI_USE_64BIT, PVSCSI_PER_VECTOR_MASK);
    if (res < 0) {
        trace_pvscsi_init_msi_fail(res);
        s->msi_used = false;
    } else {
        s->msi_used = true;
    }

    return s->msi_used;
}

static void
pvscsi_cleanup_msi(PVSCSIState *s)
{
    PCIDevice *d = PCI_DEVICE(s);

    if (s->msi_used) {
        msi_uninit(d);
    }
}

static const MemoryRegionOps pvscsi_ops = {
        .read = pvscsi_io_read,
        .write = pvscsi_io_write,
        .endianness = DEVICE_LITTLE_ENDIAN,
        .impl = {
                .min_access_size = 4,
                .max_access_size = 4,
        },
};

static const struct SCSIBusInfo pvscsi_scsi_info = {
        .tcq = true,
        .max_target = PVSCSI_MAX_DEVS,
        .max_channel = 0,
        .max_lun = 0,

        .get_sg_list = pvscsi_get_sg_list,
        .complete = pvscsi_command_complete,
        .cancel = pvscsi_request_cancelled,
};

static int
pvscsi_init(PCIDevice *pci_dev)
{
    PVSCSIState *s = PVSCSI(pci_dev);

    trace_pvscsi_state("init");

    /* PCI subsystem ID, subsystem vendor ID, revision */
    if (PVSCSI_USE_OLD_PCI_CONFIGURATION(s)) {
        pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, 0x1000);
    } else {
        pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
                     PCI_VENDOR_ID_VMWARE);
        pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
                     PCI_DEVICE_ID_VMWARE_PVSCSI);
        pci_config_set_revision(pci_dev->config, 0x2);
    }

    /* PCI latency timer = 255 */
    pci_dev->config[PCI_LATENCY_TIMER] = 0xff;

    /* Interrupt pin A */
    pci_config_set_interrupt_pin(pci_dev->config, 1);

    memory_region_init_io(&s->io_space, OBJECT(s), &pvscsi_ops, s,
                          "pvscsi-io", PVSCSI_MEM_SPACE_SIZE);
    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->io_space);

    pvscsi_init_msi(s);

    if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus)) {
        pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET);
    }

    s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
    if (!s->completion_worker) {
        pvscsi_cleanup_msi(s);
        return -ENOMEM;
    }

    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
                 &pvscsi_scsi_info, NULL);
    /* override default SCSI bus hotplug-handler, with pvscsi's one */
    qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(s), &error_abort);
    pvscsi_reset_state(s);

    return 0;
}

static void
pvscsi_uninit(PCIDevice *pci_dev)
{
    PVSCSIState *s = PVSCSI(pci_dev);

    trace_pvscsi_state("uninit");
    qemu_bh_delete(s->completion_worker);

    pvscsi_cleanup_msi(s);
}

static void
pvscsi_reset(DeviceState *dev)
{
    PCIDevice *d = PCI_DEVICE(dev);
    PVSCSIState *s = PVSCSI(d);

    trace_pvscsi_state("reset");
    pvscsi_reset_adapter(s);
}

static void
pvscsi_pre_save(void *opaque)
{
    PVSCSIState *s = (PVSCSIState *) opaque;

    trace_pvscsi_state("presave");

    assert(QTAILQ_EMPTY(&s->pending_queue));
    assert(QTAILQ_EMPTY(&s->completion_queue));
}

static int
pvscsi_post_load(void *opaque, int version_id)
{
    trace_pvscsi_state("postload");
    return 0;
}

static bool pvscsi_vmstate_need_pcie_device(void *opaque)
{
    PVSCSIState *s = PVSCSI(opaque);

    return !(s->compat_flags & PVSCSI_COMPAT_DISABLE_PCIE);
}

static bool pvscsi_vmstate_test_pci_device(void *opaque, int version_id)
{
    return !pvscsi_vmstate_need_pcie_device(opaque);
}

static const VMStateDescription vmstate_pvscsi_pcie_device = {
    .name = "pvscsi/pcie",
    .needed = pvscsi_vmstate_need_pcie_device,
    .fields = (VMStateField[]) {
        VMSTATE_PCIE_DEVICE(parent_obj, PVSCSIState),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_pvscsi = {
    .name = "pvscsi",
    .version_id = 0,
    .minimum_version_id = 0,
    .pre_save = pvscsi_pre_save,
    .post_load = pvscsi_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT_TEST(parent_obj, PVSCSIState,
                            pvscsi_vmstate_test_pci_device, 0,
                            vmstate_pci_device, PCIDevice),
        VMSTATE_UINT8(msi_used, PVSCSIState),
        VMSTATE_UINT32(resetting, PVSCSIState),
        VMSTATE_UINT64(reg_interrupt_status, PVSCSIState),
        VMSTATE_UINT64(reg_interrupt_enabled, PVSCSIState),
        VMSTATE_UINT64(reg_command_status, PVSCSIState),
        VMSTATE_UINT64(curr_cmd, PVSCSIState),
        VMSTATE_UINT32(curr_cmd_data_cntr, PVSCSIState),
        VMSTATE_UINT32_ARRAY(curr_cmd_data, PVSCSIState,
                             ARRAY_SIZE(((PVSCSIState *)NULL)->curr_cmd_data)),
        VMSTATE_UINT8(rings_info_valid, PVSCSIState),
        VMSTATE_UINT8(msg_ring_info_valid, PVSCSIState),
        VMSTATE_UINT8(use_msg, PVSCSIState),

        VMSTATE_UINT64(rings.rs_pa, PVSCSIState),
        VMSTATE_UINT32(rings.txr_len_mask, PVSCSIState),
        VMSTATE_UINT32(rings.rxr_len_mask, PVSCSIState),
        VMSTATE_UINT64_ARRAY(rings.req_ring_pages_pa, PVSCSIState,
                             PVSCSI_SETUP_RINGS_MAX_NUM_PAGES),
        VMSTATE_UINT64_ARRAY(rings.cmp_ring_pages_pa, PVSCSIState,
                             PVSCSI_SETUP_RINGS_MAX_NUM_PAGES),
        VMSTATE_UINT64(rings.consumed_ptr, PVSCSIState),
        VMSTATE_UINT64(rings.filled_cmp_ptr, PVSCSIState),

        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription*[]) {
        &vmstate_pvscsi_pcie_device,
        NULL
    }
};

static Property pvscsi_properties[] = {
    DEFINE_PROP_UINT8("use_msg", PVSCSIState, use_msg, 1),
    DEFINE_PROP_BIT("x-old-pci-configuration", PVSCSIState, compat_flags,
                    PVSCSI_COMPAT_OLD_PCI_CONFIGURATION_BIT, false),
    DEFINE_PROP_BIT("x-disable-pcie", PVSCSIState, compat_flags,
                    PVSCSI_COMPAT_DISABLE_PCIE_BIT, false),
    DEFINE_PROP_END_OF_LIST(),
};

static void pvscsi_realize(DeviceState *qdev, Error **errp)
{
    PVSCSIClass *pvs_c = PVSCSI_DEVICE_GET_CLASS(qdev);
    PCIDevice *pci_dev = PCI_DEVICE(qdev);
    PVSCSIState *s = PVSCSI(qdev);

    if (!(s->compat_flags & PVSCSI_COMPAT_DISABLE_PCIE)) {
        pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
    }

    pvs_c->parent_dc_realize(qdev, errp);
}

static void pvscsi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    PVSCSIClass *pvs_k = PVSCSI_DEVICE_CLASS(klass);
    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);

    k->init = pvscsi_init;
    k->exit = pvscsi_uninit;
    k->vendor_id = PCI_VENDOR_ID_VMWARE;
    k->device_id = PCI_DEVICE_ID_VMWARE_PVSCSI;
    k->class_id = PCI_CLASS_STORAGE_SCSI;
    k->subsystem_id = 0x1000;
    pvs_k->parent_dc_realize = dc->realize;
    dc->realize = pvscsi_realize;
    dc->reset = pvscsi_reset;
    dc->vmsd = &vmstate_pvscsi;
    dc->props = pvscsi_properties;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
    hc->unplug = pvscsi_hot_unplug;
    hc->plug = pvscsi_hotplug;
}

static const TypeInfo pvscsi_info = {
    .name          = TYPE_PVSCSI,
    .parent        = TYPE_PCI_DEVICE,
    .class_size    = sizeof(PVSCSIClass),
    .instance_size = sizeof(PVSCSIState),
    .class_init    = pvscsi_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_HOTPLUG_HANDLER },
        { }
    }
};

static void
pvscsi_register_types(void)
{
    type_register_static(&pvscsi_info);
}

type_init(pvscsi_register_types);
