/*
 * QEMU LSI SAS1068 Host Bus Adapter emulation
 * Based on the QEMU Megaraid emulator
 *
 * Copyright (c) 2009-2012 Hannes Reinecke, SUSE Labs
 * Copyright (c) 2012 Verizon, Inc.
 * Copyright (c) 2016 Red Hat, Inc.
 *
 * Authors: Don Slutz, Paolo Bonzini
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "sysemu/dma.h"
#include "hw/pci/msi.h"
#include "qemu/iov.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "hw/scsi/scsi.h"
#include "scsi/constants.h"
#include "trace.h"
#include "qapi/error.h"
#include "mptsas.h"
#include "migration/qemu-file-types.h"
#include "migration/vmstate.h"
#include "mpi.h"

#define NAA_LOCALLY_ASSIGNED_ID 0x3ULL
#define IEEE_COMPANY_LOCALLY_ASSIGNED 0x525400

#define MPTSAS1068_PRODUCT_ID                  \
    (MPI_FW_HEADER_PID_FAMILY_1068_SAS |       \
     MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI |   \
     MPI_FW_HEADER_PID_TYPE_SAS)

struct MPTSASRequest {
    MPIMsgSCSIIORequest scsi_io;
    SCSIRequest *sreq;
    QEMUSGList qsg;
    MPTSASState *dev;

    QTAILQ_ENTRY(MPTSASRequest) next;
};

static void mptsas_update_interrupt(MPTSASState *s)
{
    PCIDevice *pci = (PCIDevice *) s;
    uint32_t state = s->intr_status & ~(s->intr_mask | MPI_HIS_IOP_DOORBELL_STATUS);

    if (msi_enabled(pci)) {
        if (state) {
            trace_mptsas_irq_msi(s);
            msi_notify(pci, 0);
        }
    }

    trace_mptsas_irq_intx(s, !!state);
    pci_set_irq(pci, !!state);
}

static void mptsas_set_fault(MPTSASState *s, uint32_t code)
{
    if ((s->state & MPI_IOC_STATE_FAULT) == 0) {
        s->state = MPI_IOC_STATE_FAULT | code;
    }
}

#define MPTSAS_FIFO_INVALID(s, name)                     \
    ((s)->name##_head > ARRAY_SIZE((s)->name) ||         \
     (s)->name##_tail > ARRAY_SIZE((s)->name))

#define MPTSAS_FIFO_EMPTY(s, name)                       \
    ((s)->name##_head == (s)->name##_tail)

#define MPTSAS_FIFO_FULL(s, name)                        \
    ((s)->name##_head == ((s)->name##_tail + 1) % ARRAY_SIZE((s)->name))

#define MPTSAS_FIFO_GET(s, name) ({                      \
    uint32_t _val = (s)->name[(s)->name##_head++];       \
    (s)->name##_head %= ARRAY_SIZE((s)->name);           \
    _val;                                                \
})

#define MPTSAS_FIFO_PUT(s, name, val) do {       \
    (s)->name[(s)->name##_tail++] = (val);       \
    (s)->name##_tail %= ARRAY_SIZE((s)->name);   \
} while(0)

static void mptsas_post_reply(MPTSASState *s, MPIDefaultReply *reply)
{
    PCIDevice *pci = (PCIDevice *) s;
    uint32_t addr_lo;

    if (MPTSAS_FIFO_EMPTY(s, reply_free) || MPTSAS_FIFO_FULL(s, reply_post)) {
        mptsas_set_fault(s, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES);
        return;
    }

    addr_lo = MPTSAS_FIFO_GET(s, reply_free);

    pci_dma_write(pci, addr_lo | s->host_mfa_high_addr, reply,
                  MIN(s->reply_frame_size, 4 * reply->MsgLength));

    MPTSAS_FIFO_PUT(s, reply_post, MPI_ADDRESS_REPLY_A_BIT | (addr_lo >> 1));

    s->intr_status |= MPI_HIS_REPLY_MESSAGE_INTERRUPT;
    if (s->doorbell_state == DOORBELL_WRITE) {
        s->doorbell_state = DOORBELL_NONE;
        s->intr_status |= MPI_HIS_DOORBELL_INTERRUPT;
    }
    mptsas_update_interrupt(s);
}

void mptsas_reply(MPTSASState *s, MPIDefaultReply *reply)
{
    if (s->doorbell_state == DOORBELL_WRITE) {
        /* The reply is sent out in 16 bit chunks, while the size
         * in the reply is in 32 bit units.
         */
        s->doorbell_state = DOORBELL_READ;
        s->doorbell_reply_idx = 0;
        s->doorbell_reply_size = reply->MsgLength * 2;
        memcpy(s->doorbell_reply, reply, s->doorbell_reply_size * 2);
        s->intr_status |= MPI_HIS_DOORBELL_INTERRUPT;
        mptsas_update_interrupt(s);
    } else {
        mptsas_post_reply(s, reply);
    }
}

static void mptsas_turbo_reply(MPTSASState *s, uint32_t msgctx)
{
    if (MPTSAS_FIFO_FULL(s, reply_post)) {
        mptsas_set_fault(s, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES);
        return;
    }

    /* The reply is just the message context ID (bit 31 = clear). */
    MPTSAS_FIFO_PUT(s, reply_post, msgctx);

    s->intr_status |= MPI_HIS_REPLY_MESSAGE_INTERRUPT;
    mptsas_update_interrupt(s);
}

#define MPTSAS_MAX_REQUEST_SIZE 52

static const int mpi_request_sizes[] = {
    [MPI_FUNCTION_SCSI_IO_REQUEST]    = sizeof(MPIMsgSCSIIORequest),
    [MPI_FUNCTION_SCSI_TASK_MGMT]     = sizeof(MPIMsgSCSITaskMgmt),
    [MPI_FUNCTION_IOC_INIT]           = sizeof(MPIMsgIOCInit),
    [MPI_FUNCTION_IOC_FACTS]          = sizeof(MPIMsgIOCFacts),
    [MPI_FUNCTION_CONFIG]             = sizeof(MPIMsgConfig),
    [MPI_FUNCTION_PORT_FACTS]         = sizeof(MPIMsgPortFacts),
    [MPI_FUNCTION_PORT_ENABLE]        = sizeof(MPIMsgPortEnable),
    [MPI_FUNCTION_EVENT_NOTIFICATION] = sizeof(MPIMsgEventNotify),
};

static dma_addr_t mptsas_ld_sg_base(MPTSASState *s, uint32_t flags_and_length,
                                    dma_addr_t *sgaddr)
{
    const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
    PCIDevice *pci = (PCIDevice *) s;
    dma_addr_t addr;

    if (flags_and_length & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
        uint64_t addr64;

        ldq_le_pci_dma(pci, *sgaddr + 4, &addr64, attrs);
        addr = addr64;
        *sgaddr += 12;
    } else {
        uint32_t addr32;

        ldl_le_pci_dma(pci, *sgaddr + 4, &addr32, attrs);
        addr = addr32;
        *sgaddr += 8;
    }
    return addr;
}

static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr req_addr)
{
    PCIDevice *pci = (PCIDevice *) s;
    hwaddr next_chain_addr;
    uint32_t left;
    hwaddr sgaddr;
    uint32_t chain_offset;

    chain_offset = req->scsi_io.ChainOffset;
    next_chain_addr = req_addr + chain_offset * sizeof(uint32_t);
    sgaddr = req_addr + sizeof(MPIMsgSCSIIORequest);
    pci_dma_sglist_init(&req->qsg, pci, 4);
    left = req->scsi_io.DataLength;

    for(;;) {
        dma_addr_t addr, len;
        uint32_t flags_and_length;

        ldl_le_pci_dma(pci, sgaddr, &flags_and_length, MEMTXATTRS_UNSPECIFIED);
        len = flags_and_length & MPI_SGE_LENGTH_MASK;
        if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK)
            != MPI_SGE_FLAGS_SIMPLE_ELEMENT ||
            (!len &&
             !(flags_and_length & MPI_SGE_FLAGS_END_OF_LIST) &&
             !(flags_and_length & MPI_SGE_FLAGS_END_OF_BUFFER))) {
            return MPI_IOCSTATUS_INVALID_SGL;
        }

        len = MIN(len, left);
        if (!len) {
            /* We reached the desired transfer length, ignore extra
             * elements of the s/g list.
             */
            break;
        }

        addr = mptsas_ld_sg_base(s, flags_and_length, &sgaddr);
        qemu_sglist_add(&req->qsg, addr, len);
        left -= len;

        if (flags_and_length & MPI_SGE_FLAGS_END_OF_LIST) {
            break;
        }

        if (flags_and_length & MPI_SGE_FLAGS_LAST_ELEMENT) {
            if (!chain_offset) {
                break;
            }

            ldl_le_pci_dma(pci, next_chain_addr, &flags_and_length,
                           MEMTXATTRS_UNSPECIFIED);
            if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK)
                != MPI_SGE_FLAGS_CHAIN_ELEMENT) {
                return MPI_IOCSTATUS_INVALID_SGL;
            }

            sgaddr = mptsas_ld_sg_base(s, flags_and_length, &next_chain_addr);
            chain_offset =
                (flags_and_length & MPI_SGE_CHAIN_OFFSET_MASK) >> MPI_SGE_CHAIN_OFFSET_SHIFT;
            next_chain_addr = sgaddr + chain_offset * sizeof(uint32_t);
        }
    }
    return 0;
}

static void mptsas_free_request(MPTSASRequest *req)
{
    if (req->sreq != NULL) {
        req->sreq->hba_private = NULL;
        scsi_req_unref(req->sreq);
        req->sreq = NULL;
    }
    qemu_sglist_destroy(&req->qsg);
    g_free(req);
}

static int mptsas_scsi_device_find(MPTSASState *s, int bus, int target,
                                   uint8_t *lun, SCSIDevice **sdev)
{
    if (bus != 0) {
        return MPI_IOCSTATUS_SCSI_INVALID_BUS;
    }

    if (target >= s->max_devices) {
        return MPI_IOCSTATUS_SCSI_INVALID_TARGETID;
    }

    *sdev = scsi_device_find(&s->bus, bus, target, lun[1]);
    if (!*sdev) {
        return MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE;
    }

    return 0;
}

static int mptsas_process_scsi_io_request(MPTSASState *s,
                                          MPIMsgSCSIIORequest *scsi_io,
                                          hwaddr addr)
{
    MPTSASRequest *req;
    MPIMsgSCSIIOReply reply;
    SCSIDevice *sdev;
    int status;

    mptsas_fix_scsi_io_endianness(scsi_io);

    trace_mptsas_process_scsi_io_request(s, scsi_io->Bus, scsi_io->TargetID,
                                         scsi_io->LUN[1], scsi_io->DataLength);

    status = mptsas_scsi_device_find(s, scsi_io->Bus, scsi_io->TargetID,
                                     scsi_io->LUN, &sdev);
    if (status) {
        goto bad;
    }

    req = g_new0(MPTSASRequest, 1);
    req->scsi_io = *scsi_io;
    req->dev = s;

    status = mptsas_build_sgl(s, req, addr);
    if (status) {
        goto free_bad;
    }

    if (req->qsg.size < scsi_io->DataLength) {
        trace_mptsas_sgl_overflow(s, scsi_io->MsgContext, scsi_io->DataLength,
                                  req->qsg.size);
        status = MPI_IOCSTATUS_INVALID_SGL;
        goto free_bad;
    }

    req->sreq = scsi_req_new(sdev, scsi_io->MsgContext,
                             scsi_io->LUN[1], scsi_io->CDB,
                             scsi_io->CDBLength, req);

    if (req->sreq->cmd.xfer > scsi_io->DataLength) {
        goto overrun;
    }
    switch (scsi_io->Control & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK) {
    case MPI_SCSIIO_CONTROL_NODATATRANSFER:
        if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
            goto overrun;
        }
        break;

    case MPI_SCSIIO_CONTROL_WRITE:
        if (req->sreq->cmd.mode != SCSI_XFER_TO_DEV) {
            goto overrun;
        }
        break;

    case MPI_SCSIIO_CONTROL_READ:
        if (req->sreq->cmd.mode != SCSI_XFER_FROM_DEV) {
            goto overrun;
        }
        break;
    }

    if (scsi_req_enqueue(req->sreq)) {
        scsi_req_continue(req->sreq);
    }
    return 0;

overrun:
    trace_mptsas_scsi_overflow(s, scsi_io->MsgContext, req->sreq->cmd.xfer,
                               scsi_io->DataLength);
    status = MPI_IOCSTATUS_SCSI_DATA_OVERRUN;
free_bad:
    mptsas_free_request(req);
bad:
    memset(&reply, 0, sizeof(reply));
    reply.TargetID          = scsi_io->TargetID;
    reply.Bus               = scsi_io->Bus;
    reply.MsgLength         = sizeof(reply) / 4;
    reply.Function          = scsi_io->Function;
    reply.CDBLength         = scsi_io->CDBLength;
    reply.SenseBufferLength = scsi_io->SenseBufferLength;
    reply.MsgContext        = scsi_io->MsgContext;
    reply.SCSIState         = MPI_SCSI_STATE_NO_SCSI_STATUS;
    reply.IOCStatus         = status;

    mptsas_fix_scsi_io_reply_endianness(&reply);
    mptsas_reply(s, (MPIDefaultReply *)&reply);

    return 0;
}

typedef struct {
    Notifier                notifier;
    MPTSASState             *s;
    MPIMsgSCSITaskMgmtReply *reply;
} MPTSASCancelNotifier;

static void mptsas_cancel_notify(Notifier *notifier, void *data)
{
    MPTSASCancelNotifier *n = container_of(notifier,
                                           MPTSASCancelNotifier,
                                           notifier);

    /* Abusing IOCLogInfo to store the expected number of requests... */
    if (++n->reply->TerminationCount == n->reply->IOCLogInfo) {
        n->reply->IOCLogInfo = 0;
        mptsas_fix_scsi_task_mgmt_reply_endianness(n->reply);
        mptsas_post_reply(n->s, (MPIDefaultReply *)n->reply);
        g_free(n->reply);
    }
    g_free(n);
}

static void mptsas_process_scsi_task_mgmt(MPTSASState *s, MPIMsgSCSITaskMgmt *req)
{
    MPIMsgSCSITaskMgmtReply reply;
    MPIMsgSCSITaskMgmtReply *reply_async;
    int status, count;
    SCSIDevice *sdev;
    SCSIRequest *r, *next;
    BusChild *kid;

    mptsas_fix_scsi_task_mgmt_endianness(req);

    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));

    memset(&reply, 0, sizeof(reply));
    reply.TargetID   = req->TargetID;
    reply.Bus        = req->Bus;
    reply.MsgLength  = sizeof(reply) / 4;
    reply.Function   = req->Function;
    reply.TaskType   = req->TaskType;
    reply.MsgContext = req->MsgContext;

    switch (req->TaskType) {
    case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
    case MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
        status = mptsas_scsi_device_find(s, req->Bus, req->TargetID,
                                         req->LUN, &sdev);
        if (status) {
            reply.IOCStatus = status;
            goto out;
        }
        if (sdev->lun != req->LUN[1]) {
            reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN;
            goto out;
        }

        QTAILQ_FOREACH_SAFE(r, &sdev->requests, next, next) {
            MPTSASRequest *cmd_req = r->hba_private;
            if (cmd_req && cmd_req->scsi_io.MsgContext == req->TaskMsgContext) {
                break;
            }
        }
        if (r) {
            /*
             * Assert that the request has not been completed yet, we
             * check for it in the loop above.
             */
            assert(r->hba_private);
            if (req->TaskType == MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK) {
                /* "If the specified command is present in the task set, then
                 * return a service response set to FUNCTION SUCCEEDED".
                 */
                reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED;
            } else {
                MPTSASCancelNotifier *notifier;

                reply_async = g_memdup(&reply, sizeof(MPIMsgSCSITaskMgmtReply));
                reply_async->IOCLogInfo = INT_MAX;

                count = 1;
                notifier = g_new(MPTSASCancelNotifier, 1);
                notifier->s = s;
                notifier->reply = reply_async;
                notifier->notifier.notify = mptsas_cancel_notify;
                scsi_req_cancel_async(r, &notifier->notifier);
                goto reply_maybe_async;
            }
        }
        break;

    case MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
    case MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET:
        status = mptsas_scsi_device_find(s, req->Bus, req->TargetID,
                                         req->LUN, &sdev);
        if (status) {
            reply.IOCStatus = status;
            goto out;
        }
        if (sdev->lun != req->LUN[1]) {
            reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN;
            goto out;
        }

        reply_async = g_memdup(&reply, sizeof(MPIMsgSCSITaskMgmtReply));
        reply_async->IOCLogInfo = INT_MAX;

        count = 0;
        QTAILQ_FOREACH_SAFE(r, &sdev->requests, next, next) {
            if (r->hba_private) {
                MPTSASCancelNotifier *notifier;

                count++;
                notifier = g_new(MPTSASCancelNotifier, 1);
                notifier->s = s;
                notifier->reply = reply_async;
                notifier->notifier.notify = mptsas_cancel_notify;
                scsi_req_cancel_async(r, &notifier->notifier);
            }
        }

reply_maybe_async:
        if (reply_async->TerminationCount < count) {
            reply_async->IOCLogInfo = count;
            return;
        }
        g_free(reply_async);
        reply.TerminationCount = count;
        break;

    case MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
        status = mptsas_scsi_device_find(s, req->Bus, req->TargetID,
                                         req->LUN, &sdev);
        if (status) {
            reply.IOCStatus = status;
            goto out;
        }
        if (sdev->lun != req->LUN[1]) {
            reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN;
            goto out;
        }
        device_cold_reset(&sdev->qdev);
        break;

    case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
        if (req->Bus != 0) {
            reply.IOCStatus = MPI_IOCSTATUS_SCSI_INVALID_BUS;
            goto out;
        }
        if (req->TargetID > s->max_devices) {
            reply.IOCStatus = MPI_IOCSTATUS_SCSI_INVALID_TARGETID;
            goto out;
        }

        QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
            sdev = SCSI_DEVICE(kid->child);
            if (sdev->channel == 0 && sdev->id == req->TargetID) {
                device_cold_reset(kid->child);
            }
        }
        break;

    case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
        bus_cold_reset(BUS(&s->bus));
        break;

    default:
        reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED;
        break;
    }

out:
    mptsas_fix_scsi_task_mgmt_reply_endianness(&reply);
    mptsas_post_reply(s, (MPIDefaultReply *)&reply);
}

static void mptsas_process_ioc_init(MPTSASState *s, MPIMsgIOCInit *req)
{
    MPIMsgIOCInitReply reply;

    mptsas_fix_ioc_init_endianness(req);

    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));

    s->who_init               = req->WhoInit;
    s->reply_frame_size       = req->ReplyFrameSize;
    s->max_buses              = req->MaxBuses;
    s->max_devices            = req->MaxDevices ? req->MaxDevices : 256;
    s->host_mfa_high_addr     = (hwaddr)req->HostMfaHighAddr << 32;
    s->sense_buffer_high_addr = (hwaddr)req->SenseBufferHighAddr << 32;

    if (s->state == MPI_IOC_STATE_READY) {
        s->state = MPI_IOC_STATE_OPERATIONAL;
    }

    memset(&reply, 0, sizeof(reply));
    reply.WhoInit    = s->who_init;
    reply.MsgLength  = sizeof(reply) / 4;
    reply.Function   = req->Function;
    reply.MaxDevices = s->max_devices;
    reply.MaxBuses   = s->max_buses;
    reply.MsgContext = req->MsgContext;

    mptsas_fix_ioc_init_reply_endianness(&reply);
    mptsas_reply(s, (MPIDefaultReply *)&reply);
}

static void mptsas_process_ioc_facts(MPTSASState *s,
                                     MPIMsgIOCFacts *req)
{
    MPIMsgIOCFactsReply reply;

    mptsas_fix_ioc_facts_endianness(req);

    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));

    memset(&reply, 0, sizeof(reply));
    reply.MsgVersion                 = 0x0105;
    reply.MsgLength                  = sizeof(reply) / 4;
    reply.Function                   = req->Function;
    reply.MsgContext                 = req->MsgContext;
    reply.MaxChainDepth              = MPTSAS_MAXIMUM_CHAIN_DEPTH;
    reply.WhoInit                    = s->who_init;
    reply.BlockSize                  = MPTSAS_MAX_REQUEST_SIZE / sizeof(uint32_t);
    reply.ReplyQueueDepth            = ARRAY_SIZE(s->reply_post) - 1;
    QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->reply_post) != ARRAY_SIZE(s->reply_free));

    reply.RequestFrameSize           = 128;
    reply.ProductID                  = MPTSAS1068_PRODUCT_ID;
    reply.CurrentHostMfaHighAddr     = s->host_mfa_high_addr >> 32;
    reply.GlobalCredits              = ARRAY_SIZE(s->request_post) - 1;
    reply.NumberOfPorts              = MPTSAS_NUM_PORTS;
    reply.CurrentSenseBufferHighAddr = s->sense_buffer_high_addr >> 32;
    reply.CurReplyFrameSize          = s->reply_frame_size;
    reply.MaxDevices                 = s->max_devices;
    reply.MaxBuses                   = s->max_buses;
    reply.FWVersionDev               = 0;
    reply.FWVersionUnit              = 0x92;
    reply.FWVersionMinor             = 0x32;
    reply.FWVersionMajor             = 0x1;

    mptsas_fix_ioc_facts_reply_endianness(&reply);
    mptsas_reply(s, (MPIDefaultReply *)&reply);
}

static void mptsas_process_port_facts(MPTSASState *s,
                                     MPIMsgPortFacts *req)
{
    MPIMsgPortFactsReply reply;

    mptsas_fix_port_facts_endianness(req);

    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));

    memset(&reply, 0, sizeof(reply));
    reply.MsgLength  = sizeof(reply) / 4;
    reply.Function   = req->Function;
    reply.PortNumber = req->PortNumber;
    reply.MsgContext = req->MsgContext;

    if (req->PortNumber < MPTSAS_NUM_PORTS) {
        reply.PortType      = MPI_PORTFACTS_PORTTYPE_SAS;
        reply.MaxDevices    = MPTSAS_NUM_PORTS;
        reply.PortSCSIID    = MPTSAS_NUM_PORTS;
        reply.ProtocolFlags = MPI_PORTFACTS_PROTOCOL_LOGBUSADDR | MPI_PORTFACTS_PROTOCOL_INITIATOR;
    }

    mptsas_fix_port_facts_reply_endianness(&reply);
    mptsas_reply(s, (MPIDefaultReply *)&reply);
}

static void mptsas_process_port_enable(MPTSASState *s,
                                       MPIMsgPortEnable *req)
{
    MPIMsgPortEnableReply reply;

    mptsas_fix_port_enable_endianness(req);

    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));

    memset(&reply, 0, sizeof(reply));
    reply.MsgLength  = sizeof(reply) / 4;
    reply.PortNumber = req->PortNumber;
    reply.Function   = req->Function;
    reply.MsgContext = req->MsgContext;

    mptsas_fix_port_enable_reply_endianness(&reply);
    mptsas_reply(s, (MPIDefaultReply *)&reply);
}

static void mptsas_process_event_notification(MPTSASState *s,
                                              MPIMsgEventNotify *req)
{
    MPIMsgEventNotifyReply reply;

    mptsas_fix_event_notification_endianness(req);

    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));

    /* Don't even bother storing whether event notification is enabled,
     * since it is not accessible.
     */

    memset(&reply, 0, sizeof(reply));
    reply.EventDataLength = sizeof(reply.Data) / 4;
    reply.MsgLength       = sizeof(reply) / 4;
    reply.Function        = req->Function;

    /* This is set because events are sent through the reply FIFOs.  */
    reply.MsgFlags        = MPI_MSGFLAGS_CONTINUATION_REPLY;

    reply.MsgContext      = req->MsgContext;
    reply.Event           = MPI_EVENT_EVENT_CHANGE;
    reply.Data[0]         = !!req->Switch;

    mptsas_fix_event_notification_reply_endianness(&reply);
    mptsas_reply(s, (MPIDefaultReply *)&reply);
}

static void mptsas_process_message(MPTSASState *s, MPIRequestHeader *req)
{
    trace_mptsas_process_message(s, req->Function, req->MsgContext);
    switch (req->Function) {
    case MPI_FUNCTION_SCSI_TASK_MGMT:
        mptsas_process_scsi_task_mgmt(s, (MPIMsgSCSITaskMgmt *)req);
        break;

    case MPI_FUNCTION_IOC_INIT:
        mptsas_process_ioc_init(s, (MPIMsgIOCInit *)req);
        break;

    case MPI_FUNCTION_IOC_FACTS:
        mptsas_process_ioc_facts(s, (MPIMsgIOCFacts *)req);
        break;

    case MPI_FUNCTION_PORT_FACTS:
        mptsas_process_port_facts(s, (MPIMsgPortFacts *)req);
        break;

    case MPI_FUNCTION_PORT_ENABLE:
        mptsas_process_port_enable(s, (MPIMsgPortEnable *)req);
        break;

    case MPI_FUNCTION_EVENT_NOTIFICATION:
        mptsas_process_event_notification(s, (MPIMsgEventNotify *)req);
        break;

    case MPI_FUNCTION_CONFIG:
        mptsas_process_config(s, (MPIMsgConfig *)req);
        break;

    default:
        trace_mptsas_unhandled_cmd(s, req->Function, 0);
        mptsas_set_fault(s, MPI_IOCSTATUS_INVALID_FUNCTION);
        break;
    }
}

static void mptsas_fetch_request(MPTSASState *s)
{
    PCIDevice *pci = (PCIDevice *) s;
    char req[MPTSAS_MAX_REQUEST_SIZE];
    MPIRequestHeader *hdr = (MPIRequestHeader *)req;
    hwaddr addr;
    int size;

    /* Read the message header from the guest first. */
    addr = s->host_mfa_high_addr | MPTSAS_FIFO_GET(s, request_post);
    pci_dma_read(pci, addr, req, sizeof(*hdr));

    if (hdr->Function < ARRAY_SIZE(mpi_request_sizes) &&
        mpi_request_sizes[hdr->Function]) {
        /* Read the rest of the request based on the type.  Do not
         * reread everything, as that could cause a TOC/TOU mismatch
         * and leak data from the QEMU stack.
         */
        size = mpi_request_sizes[hdr->Function];
        assert(size <= MPTSAS_MAX_REQUEST_SIZE);
        pci_dma_read(pci, addr + sizeof(*hdr), &req[sizeof(*hdr)],
                     size - sizeof(*hdr));
    }

    if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
        /* SCSI I/O requests are separate from mptsas_process_message
         * because they cannot be sent through the doorbell yet.
         */
        mptsas_process_scsi_io_request(s, (MPIMsgSCSIIORequest *)req, addr);
    } else {
        mptsas_process_message(s, (MPIRequestHeader *)req);
    }
}

static void mptsas_fetch_requests(void *opaque)
{
    MPTSASState *s = opaque;

    if (s->state != MPI_IOC_STATE_OPERATIONAL) {
        mptsas_set_fault(s, MPI_IOCSTATUS_INVALID_STATE);
        return;
    }
    while (!MPTSAS_FIFO_EMPTY(s, request_post)) {
        mptsas_fetch_request(s);
    }
}

static void mptsas_soft_reset(MPTSASState *s)
{
    uint32_t save_mask;

    trace_mptsas_reset(s);

    /* Temporarily disable interrupts */
    save_mask = s->intr_mask;
    s->intr_mask = MPI_HIM_DIM | MPI_HIM_RIM;
    mptsas_update_interrupt(s);

    bus_cold_reset(BUS(&s->bus));
    s->intr_status = 0;
    s->intr_mask = save_mask;

    s->reply_free_tail = 0;
    s->reply_free_head = 0;
    s->reply_post_tail = 0;
    s->reply_post_head = 0;
    s->request_post_tail = 0;
    s->request_post_head = 0;
    qemu_bh_cancel(s->request_bh);

    s->state = MPI_IOC_STATE_READY;
}

static uint32_t mptsas_doorbell_read(MPTSASState *s)
{
    uint32_t ret;

    ret = (s->who_init << MPI_DOORBELL_WHO_INIT_SHIFT) & MPI_DOORBELL_WHO_INIT_MASK;
    ret |= s->state;
    switch (s->doorbell_state) {
    case DOORBELL_NONE:
        break;

    case DOORBELL_WRITE:
        ret |= MPI_DOORBELL_ACTIVE;
        break;

    case DOORBELL_READ:
        /* Get rid of the IOC fault code.  */
        ret &= ~MPI_DOORBELL_DATA_MASK;

        assert(s->intr_status & MPI_HIS_DOORBELL_INTERRUPT);
        assert(s->doorbell_reply_idx <= s->doorbell_reply_size);

        ret |= MPI_DOORBELL_ACTIVE;
        if (s->doorbell_reply_idx < s->doorbell_reply_size) {
            /* For more information about this endian switch, see the
             * commit message for commit 36b62ae ("fw_cfg: fix endianness in
             * fw_cfg_data_mem_read() / _write()", 2015-01-16).
             */
            ret |= le16_to_cpu(s->doorbell_reply[s->doorbell_reply_idx++]);
        }
        break;

    default:
        abort();
    }

    return ret;
}

static void mptsas_doorbell_write(MPTSASState *s, uint32_t val)
{
    if (s->doorbell_state == DOORBELL_WRITE) {
        if (s->doorbell_idx < s->doorbell_cnt) {
            /* For more information about this endian switch, see the
             * commit message for commit 36b62ae ("fw_cfg: fix endianness in
             * fw_cfg_data_mem_read() / _write()", 2015-01-16).
             */
            s->doorbell_msg[s->doorbell_idx++] = cpu_to_le32(val);
            if (s->doorbell_idx == s->doorbell_cnt) {
                mptsas_process_message(s, (MPIRequestHeader *)s->doorbell_msg);
            }
        }
        return;
    }

    switch ((val & MPI_DOORBELL_FUNCTION_MASK) >> MPI_DOORBELL_FUNCTION_SHIFT) {
    case MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET:
        mptsas_soft_reset(s);
        break;
    case MPI_FUNCTION_IO_UNIT_RESET:
        break;
    case MPI_FUNCTION_HANDSHAKE:
        s->doorbell_state = DOORBELL_WRITE;
        s->doorbell_idx = 0;
        s->doorbell_cnt = (val & MPI_DOORBELL_ADD_DWORDS_MASK)
            >> MPI_DOORBELL_ADD_DWORDS_SHIFT;
        s->intr_status |= MPI_HIS_DOORBELL_INTERRUPT;
        mptsas_update_interrupt(s);
        break;
    default:
        trace_mptsas_unhandled_doorbell_cmd(s, val);
        break;
    }
}

static void mptsas_write_sequence_write(MPTSASState *s, uint32_t val)
{
    /* If the diagnostic register is enabled, any write to this register
     * will disable it.  Otherwise, the guest has to do a magic five-write
     * sequence.
     */
    if (s->diagnostic & MPI_DIAG_DRWE) {
        goto disable;
    }

    switch (s->diagnostic_idx) {
    case 0:
        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_1ST_KEY_VALUE) {
            goto disable;
        }
        break;
    case 1:
        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_2ND_KEY_VALUE) {
            goto disable;
        }
        break;
    case 2:
        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_3RD_KEY_VALUE) {
            goto disable;
        }
        break;
    case 3:
        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_4TH_KEY_VALUE) {
            goto disable;
        }
        break;
    case 4:
        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_5TH_KEY_VALUE) {
            goto disable;
        }
        /* Prepare Spaceball One for departure, and change the
         * combination on my luggage!
         */
        s->diagnostic |= MPI_DIAG_DRWE;
        break;
    }
    s->diagnostic_idx++;
    return;

disable:
    s->diagnostic &= ~MPI_DIAG_DRWE;
    s->diagnostic_idx = 0;
}

static int mptsas_hard_reset(MPTSASState *s)
{
    mptsas_soft_reset(s);

    s->intr_mask = MPI_HIM_DIM | MPI_HIM_RIM;

    s->host_mfa_high_addr = 0;
    s->sense_buffer_high_addr = 0;
    s->reply_frame_size = 0;
    s->max_devices = MPTSAS_NUM_PORTS;
    s->max_buses = 1;

    return 0;
}

static void mptsas_interrupt_status_write(MPTSASState *s)
{
    switch (s->doorbell_state) {
    case DOORBELL_NONE:
    case DOORBELL_WRITE:
        s->intr_status &= ~MPI_HIS_DOORBELL_INTERRUPT;
        break;

    case DOORBELL_READ:
        /* The reply can be read continuously, so leave the interrupt up.  */
        assert(s->intr_status & MPI_HIS_DOORBELL_INTERRUPT);
        if (s->doorbell_reply_idx == s->doorbell_reply_size) {
            s->doorbell_state = DOORBELL_NONE;
        }
        break;

    default:
        abort();
    }
    mptsas_update_interrupt(s);
}

static uint32_t mptsas_reply_post_read(MPTSASState *s)
{
    uint32_t ret;

    if (!MPTSAS_FIFO_EMPTY(s, reply_post)) {
        ret = MPTSAS_FIFO_GET(s, reply_post);
    } else {
        ret = -1;
        s->intr_status &= ~MPI_HIS_REPLY_MESSAGE_INTERRUPT;
        mptsas_update_interrupt(s);
    }

    return ret;
}

static uint64_t mptsas_mmio_read(void *opaque, hwaddr addr,
                                  unsigned size)
{
    MPTSASState *s = opaque;
    uint32_t ret = 0;

    switch (addr & ~3) {
    case MPI_DOORBELL_OFFSET:
        ret = mptsas_doorbell_read(s);
        break;

    case MPI_DIAGNOSTIC_OFFSET:
        ret = s->diagnostic;
        break;

    case MPI_HOST_INTERRUPT_STATUS_OFFSET:
        ret = s->intr_status;
        break;

    case MPI_HOST_INTERRUPT_MASK_OFFSET:
        ret = s->intr_mask;
        break;

    case MPI_REPLY_POST_FIFO_OFFSET:
        ret = mptsas_reply_post_read(s);
        break;

    default:
        trace_mptsas_mmio_unhandled_read(s, addr);
        break;
    }
    trace_mptsas_mmio_read(s, addr, ret);
    return ret;
}

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

    trace_mptsas_mmio_write(s, addr, val);
    switch (addr) {
    case MPI_DOORBELL_OFFSET:
        mptsas_doorbell_write(s, val);
        break;

    case MPI_WRITE_SEQUENCE_OFFSET:
        mptsas_write_sequence_write(s, val);
        break;

    case MPI_DIAGNOSTIC_OFFSET:
        if (val & MPI_DIAG_RESET_ADAPTER) {
            mptsas_hard_reset(s);
        }
        break;

    case MPI_HOST_INTERRUPT_STATUS_OFFSET:
        mptsas_interrupt_status_write(s);
        break;

    case MPI_HOST_INTERRUPT_MASK_OFFSET:
        s->intr_mask = val & (MPI_HIM_RIM | MPI_HIM_DIM);
        mptsas_update_interrupt(s);
        break;

    case MPI_REQUEST_POST_FIFO_OFFSET:
        if (MPTSAS_FIFO_FULL(s, request_post)) {
            mptsas_set_fault(s, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES);
        } else {
            MPTSAS_FIFO_PUT(s, request_post, val & ~0x03);
            qemu_bh_schedule(s->request_bh);
        }
        break;

    case MPI_REPLY_FREE_FIFO_OFFSET:
        if (MPTSAS_FIFO_FULL(s, reply_free)) {
            mptsas_set_fault(s, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES);
        } else {
            MPTSAS_FIFO_PUT(s, reply_free, val);
        }
        break;

    default:
        trace_mptsas_mmio_unhandled_write(s, addr, val);
        break;
    }
}

static const MemoryRegionOps mptsas_mmio_ops = {
    .read = mptsas_mmio_read,
    .write = mptsas_mmio_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    }
};

static const MemoryRegionOps mptsas_port_ops = {
    .read = mptsas_mmio_read,
    .write = mptsas_mmio_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    }
};

static uint64_t mptsas_diag_read(void *opaque, hwaddr addr,
                                   unsigned size)
{
    MPTSASState *s = opaque;
    trace_mptsas_diag_read(s, addr, 0);
    return 0;
}

static void mptsas_diag_write(void *opaque, hwaddr addr,
                               uint64_t val, unsigned size)
{
    MPTSASState *s = opaque;
    trace_mptsas_diag_write(s, addr, val);
}

static const MemoryRegionOps mptsas_diag_ops = {
    .read = mptsas_diag_read,
    .write = mptsas_diag_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    }
};

static QEMUSGList *mptsas_get_sg_list(SCSIRequest *sreq)
{
    MPTSASRequest *req = sreq->hba_private;

    return &req->qsg;
}

static void mptsas_command_complete(SCSIRequest *sreq,
        size_t resid)
{
    MPTSASRequest *req = sreq->hba_private;
    MPTSASState *s = req->dev;
    uint8_t sense_buf[SCSI_SENSE_BUF_SIZE];
    uint8_t sense_len;

    hwaddr sense_buffer_addr = req->dev->sense_buffer_high_addr |
            req->scsi_io.SenseBufferLowAddr;

    trace_mptsas_command_complete(s, req->scsi_io.MsgContext,
                                  sreq->status, resid);

    sense_len = scsi_req_get_sense(sreq, sense_buf, SCSI_SENSE_BUF_SIZE);
    if (sense_len > 0) {
        pci_dma_write(PCI_DEVICE(s), sense_buffer_addr, sense_buf,
                      MIN(req->scsi_io.SenseBufferLength, sense_len));
    }

    if (sreq->status != GOOD || resid ||
        req->dev->doorbell_state == DOORBELL_WRITE) {
        MPIMsgSCSIIOReply reply;

        memset(&reply, 0, sizeof(reply));
        reply.TargetID          = req->scsi_io.TargetID;
        reply.Bus               = req->scsi_io.Bus;
        reply.MsgLength         = sizeof(reply) / 4;
        reply.Function          = req->scsi_io.Function;
        reply.CDBLength         = req->scsi_io.CDBLength;
        reply.SenseBufferLength = req->scsi_io.SenseBufferLength;
        reply.MsgFlags          = req->scsi_io.MsgFlags;
        reply.MsgContext        = req->scsi_io.MsgContext;
        reply.SCSIStatus        = sreq->status;
        if (sreq->status == GOOD) {
            reply.TransferCount = req->scsi_io.DataLength - resid;
            if (resid) {
                reply.IOCStatus     = MPI_IOCSTATUS_SCSI_DATA_UNDERRUN;
            }
        } else {
            reply.SCSIState     = MPI_SCSI_STATE_AUTOSENSE_VALID;
            reply.SenseCount    = sense_len;
            reply.IOCStatus     = MPI_IOCSTATUS_SCSI_DATA_UNDERRUN;
        }

        mptsas_fix_scsi_io_reply_endianness(&reply);
        mptsas_post_reply(req->dev, (MPIDefaultReply *)&reply);
    } else {
        mptsas_turbo_reply(req->dev, req->scsi_io.MsgContext);
    }

    mptsas_free_request(req);
}

static void mptsas_request_cancelled(SCSIRequest *sreq)
{
    MPTSASRequest *req = sreq->hba_private;
    MPIMsgSCSIIOReply reply;

    memset(&reply, 0, sizeof(reply));
    reply.TargetID          = req->scsi_io.TargetID;
    reply.Bus               = req->scsi_io.Bus;
    reply.MsgLength         = sizeof(reply) / 4;
    reply.Function          = req->scsi_io.Function;
    reply.CDBLength         = req->scsi_io.CDBLength;
    reply.SenseBufferLength = req->scsi_io.SenseBufferLength;
    reply.MsgFlags          = req->scsi_io.MsgFlags;
    reply.MsgContext        = req->scsi_io.MsgContext;
    reply.SCSIState         = MPI_SCSI_STATE_NO_SCSI_STATUS;
    reply.IOCStatus         = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;

    mptsas_fix_scsi_io_reply_endianness(&reply);
    mptsas_post_reply(req->dev, (MPIDefaultReply *)&reply);
    mptsas_free_request(req);
}

static void mptsas_save_request(QEMUFile *f, SCSIRequest *sreq)
{
    MPTSASRequest *req = sreq->hba_private;
    int i;

    qemu_put_buffer(f, (unsigned char *)&req->scsi_io, sizeof(req->scsi_io));
    qemu_put_be32(f, req->qsg.nsg);
    for (i = 0; i < req->qsg.nsg; i++) {
        qemu_put_be64(f, req->qsg.sg[i].base);
        qemu_put_be64(f, req->qsg.sg[i].len);
    }
}

static void *mptsas_load_request(QEMUFile *f, SCSIRequest *sreq)
{
    SCSIBus *bus = sreq->bus;
    MPTSASState *s = container_of(bus, MPTSASState, bus);
    PCIDevice *pci = PCI_DEVICE(s);
    MPTSASRequest *req;
    int i, n;

    req = g_new(MPTSASRequest, 1);
    qemu_get_buffer(f, (unsigned char *)&req->scsi_io, sizeof(req->scsi_io));

    n = qemu_get_be32(f);
    /* TODO: add a way for SCSIBusInfo's load_request to fail,
     * and fail migration instead of asserting here.
     * This is just one thing (there are probably more) that must be
     * fixed before we can allow NDEBUG compilation.
     */
    assert(n >= 0);

    pci_dma_sglist_init(&req->qsg, pci, n);
    for (i = 0; i < n; i++) {
        uint64_t base = qemu_get_be64(f);
        uint64_t len = qemu_get_be64(f);
        qemu_sglist_add(&req->qsg, base, len);
    }

    scsi_req_ref(sreq);
    req->sreq = sreq;
    req->dev = s;

    return req;
}

static const struct SCSIBusInfo mptsas_scsi_info = {
    .tcq = true,
    .max_target = MPTSAS_NUM_PORTS,
    .max_lun = 1,

    .get_sg_list = mptsas_get_sg_list,
    .complete = mptsas_command_complete,
    .cancel = mptsas_request_cancelled,
    .save_request = mptsas_save_request,
    .load_request = mptsas_load_request,
};

static void mptsas_scsi_realize(PCIDevice *dev, Error **errp)
{
    MPTSASState *s = MPT_SAS(dev);
    Error *err = NULL;
    int ret;

    dev->config[PCI_LATENCY_TIMER] = 0;
    dev->config[PCI_INTERRUPT_PIN] = 0x01;

    if (s->msi != ON_OFF_AUTO_OFF) {
        ret = msi_init(dev, 0, 1, true, false, &err);
        /* Any error other than -ENOTSUP(board's MSI support is broken)
         * is a programming error */
        assert(!ret || ret == -ENOTSUP);
        if (ret && s->msi == ON_OFF_AUTO_ON) {
            /* Can't satisfy user's explicit msi=on request, fail */
            error_append_hint(&err, "You have to use msi=auto (default) or "
                    "msi=off with this machine type.\n");
            error_propagate(errp, err);
            return;
        }
        assert(!err || s->msi == ON_OFF_AUTO_AUTO);
        /* With msi=auto, we fall back to MSI off silently */
        error_free(err);

        /* Only used for migration.  */
        s->msi_in_use = (ret == 0);
    }

    memory_region_init_io(&s->mmio_io, OBJECT(s), &mptsas_mmio_ops, s,
                          "mptsas-mmio", 0x4000);
    memory_region_init_io(&s->port_io, OBJECT(s), &mptsas_port_ops, s,
                          "mptsas-io", 256);
    memory_region_init_io(&s->diag_io, OBJECT(s), &mptsas_diag_ops, s,
                          "mptsas-diag", 0x10000);

    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->port_io);
    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY |
                                 PCI_BASE_ADDRESS_MEM_TYPE_32, &s->mmio_io);
    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY |
                                 PCI_BASE_ADDRESS_MEM_TYPE_32, &s->diag_io);

    if (!s->sas_addr) {
        s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
                       IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
        s->sas_addr |= (pci_dev_bus_num(dev) << 16);
        s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
        s->sas_addr |= PCI_FUNC(dev->devfn);
    }
    s->max_devices = MPTSAS_NUM_PORTS;

    s->request_bh = qemu_bh_new_guarded(mptsas_fetch_requests, s,
                                        &DEVICE(dev)->mem_reentrancy_guard);

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

static void mptsas_scsi_uninit(PCIDevice *dev)
{
    MPTSASState *s = MPT_SAS(dev);

    qemu_bh_delete(s->request_bh);
    msi_uninit(dev);
}

static void mptsas_reset(DeviceState *dev)
{
    MPTSASState *s = MPT_SAS(dev);

    mptsas_hard_reset(s);
}

static int mptsas_post_load(void *opaque, int version_id)
{
    MPTSASState *s = opaque;

    if (s->doorbell_idx > s->doorbell_cnt ||
        s->doorbell_cnt > ARRAY_SIZE(s->doorbell_msg) ||
        s->doorbell_reply_idx > s->doorbell_reply_size ||
        s->doorbell_reply_size > ARRAY_SIZE(s->doorbell_reply) ||
        MPTSAS_FIFO_INVALID(s, request_post) ||
        MPTSAS_FIFO_INVALID(s, reply_post) ||
        MPTSAS_FIFO_INVALID(s, reply_free) ||
        s->diagnostic_idx > 4) {
        return -EINVAL;
    }

    return 0;
}

static const VMStateDescription vmstate_mptsas = {
    .name = "mptsas",
    .version_id = 0,
    .minimum_version_id = 0,
    .post_load = mptsas_post_load,
    .fields      = (VMStateField[]) {
        VMSTATE_PCI_DEVICE(dev, MPTSASState),
        VMSTATE_BOOL(msi_in_use, MPTSASState),
        VMSTATE_UINT32(state, MPTSASState),
        VMSTATE_UINT8(who_init, MPTSASState),
        VMSTATE_UINT8(doorbell_state, MPTSASState),
        VMSTATE_UINT32_ARRAY(doorbell_msg, MPTSASState, 256),
        VMSTATE_INT32(doorbell_idx, MPTSASState),
        VMSTATE_INT32(doorbell_cnt, MPTSASState),

        VMSTATE_UINT16_ARRAY(doorbell_reply, MPTSASState, 256),
        VMSTATE_INT32(doorbell_reply_idx, MPTSASState),
        VMSTATE_INT32(doorbell_reply_size, MPTSASState),

        VMSTATE_UINT32(diagnostic, MPTSASState),
        VMSTATE_UINT8(diagnostic_idx, MPTSASState),

        VMSTATE_UINT32(intr_status, MPTSASState),
        VMSTATE_UINT32(intr_mask, MPTSASState),

        VMSTATE_UINT32_ARRAY(request_post, MPTSASState,
                             MPTSAS_REQUEST_QUEUE_DEPTH + 1),
        VMSTATE_UINT16(request_post_head, MPTSASState),
        VMSTATE_UINT16(request_post_tail, MPTSASState),

        VMSTATE_UINT32_ARRAY(reply_post, MPTSASState,
                             MPTSAS_REPLY_QUEUE_DEPTH + 1),
        VMSTATE_UINT16(reply_post_head, MPTSASState),
        VMSTATE_UINT16(reply_post_tail, MPTSASState),

        VMSTATE_UINT32_ARRAY(reply_free, MPTSASState,
                             MPTSAS_REPLY_QUEUE_DEPTH + 1),
        VMSTATE_UINT16(reply_free_head, MPTSASState),
        VMSTATE_UINT16(reply_free_tail, MPTSASState),

        VMSTATE_UINT16(max_buses, MPTSASState),
        VMSTATE_UINT16(max_devices, MPTSASState),
        VMSTATE_UINT16(reply_frame_size, MPTSASState),
        VMSTATE_UINT64(host_mfa_high_addr, MPTSASState),
        VMSTATE_UINT64(sense_buffer_high_addr, MPTSASState),
        VMSTATE_END_OF_LIST()
    }
};

static Property mptsas_properties[] = {
    DEFINE_PROP_UINT64("sas_address", MPTSASState, sas_addr, 0),
    /* TODO: test MSI support under Windows */
    DEFINE_PROP_ON_OFF_AUTO("msi", MPTSASState, msi, ON_OFF_AUTO_AUTO),
    DEFINE_PROP_END_OF_LIST(),
};

static void mptsas1068_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc);

    pc->realize = mptsas_scsi_realize;
    pc->exit = mptsas_scsi_uninit;
    pc->romfile = 0;
    pc->vendor_id = PCI_VENDOR_ID_LSI_LOGIC;
    pc->device_id = PCI_DEVICE_ID_LSI_SAS1068;
    pc->subsystem_vendor_id = PCI_VENDOR_ID_LSI_LOGIC;
    pc->subsystem_id = 0x8000;
    pc->class_id = PCI_CLASS_STORAGE_SCSI;
    device_class_set_props(dc, mptsas_properties);
    dc->reset = mptsas_reset;
    dc->vmsd = &vmstate_mptsas;
    dc->desc = "LSI SAS 1068";
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static const TypeInfo mptsas_info = {
    .name = TYPE_MPTSAS1068,
    .parent = TYPE_PCI_DEVICE,
    .instance_size = sizeof(MPTSASState),
    .class_init = mptsas1068_class_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

static void mptsas_register_types(void)
{
    type_register(&mptsas_info);
}

type_init(mptsas_register_types)
