cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

mptsas.c (45584B)


      1/*
      2 * QEMU LSI SAS1068 Host Bus Adapter emulation
      3 * Based on the QEMU Megaraid emulator
      4 *
      5 * Copyright (c) 2009-2012 Hannes Reinecke, SUSE Labs
      6 * Copyright (c) 2012 Verizon, Inc.
      7 * Copyright (c) 2016 Red Hat, Inc.
      8 *
      9 * Authors: Don Slutz, Paolo Bonzini
     10 *
     11 * This library is free software; you can redistribute it and/or
     12 * modify it under the terms of the GNU Lesser General Public
     13 * License as published by the Free Software Foundation; either
     14 * version 2.1 of the License, or (at your option) any later version.
     15 *
     16 * This library is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19 * Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public
     22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     23 */
     24
     25#include "qemu/osdep.h"
     26#include "hw/pci/pci.h"
     27#include "hw/qdev-properties.h"
     28#include "sysemu/dma.h"
     29#include "hw/pci/msi.h"
     30#include "qemu/iov.h"
     31#include "qemu/main-loop.h"
     32#include "qemu/module.h"
     33#include "hw/scsi/scsi.h"
     34#include "scsi/constants.h"
     35#include "trace.h"
     36#include "qapi/error.h"
     37#include "mptsas.h"
     38#include "migration/qemu-file-types.h"
     39#include "migration/vmstate.h"
     40#include "mpi.h"
     41
     42#define NAA_LOCALLY_ASSIGNED_ID 0x3ULL
     43#define IEEE_COMPANY_LOCALLY_ASSIGNED 0x525400
     44
     45#define MPTSAS1068_PRODUCT_ID                  \
     46    (MPI_FW_HEADER_PID_FAMILY_1068_SAS |       \
     47     MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI |   \
     48     MPI_FW_HEADER_PID_TYPE_SAS)
     49
     50struct MPTSASRequest {
     51    MPIMsgSCSIIORequest scsi_io;
     52    SCSIRequest *sreq;
     53    QEMUSGList qsg;
     54    MPTSASState *dev;
     55
     56    QTAILQ_ENTRY(MPTSASRequest) next;
     57};
     58
     59static void mptsas_update_interrupt(MPTSASState *s)
     60{
     61    PCIDevice *pci = (PCIDevice *) s;
     62    uint32_t state = s->intr_status & ~(s->intr_mask | MPI_HIS_IOP_DOORBELL_STATUS);
     63
     64    if (msi_enabled(pci)) {
     65        if (state) {
     66            trace_mptsas_irq_msi(s);
     67            msi_notify(pci, 0);
     68        }
     69    }
     70
     71    trace_mptsas_irq_intx(s, !!state);
     72    pci_set_irq(pci, !!state);
     73}
     74
     75static void mptsas_set_fault(MPTSASState *s, uint32_t code)
     76{
     77    if ((s->state & MPI_IOC_STATE_FAULT) == 0) {
     78        s->state = MPI_IOC_STATE_FAULT | code;
     79    }
     80}
     81
     82#define MPTSAS_FIFO_INVALID(s, name)                     \
     83    ((s)->name##_head > ARRAY_SIZE((s)->name) ||         \
     84     (s)->name##_tail > ARRAY_SIZE((s)->name))
     85
     86#define MPTSAS_FIFO_EMPTY(s, name)                       \
     87    ((s)->name##_head == (s)->name##_tail)
     88
     89#define MPTSAS_FIFO_FULL(s, name)                        \
     90    ((s)->name##_head == ((s)->name##_tail + 1) % ARRAY_SIZE((s)->name))
     91
     92#define MPTSAS_FIFO_GET(s, name) ({                      \
     93    uint32_t _val = (s)->name[(s)->name##_head++];       \
     94    (s)->name##_head %= ARRAY_SIZE((s)->name);           \
     95    _val;                                                \
     96})
     97
     98#define MPTSAS_FIFO_PUT(s, name, val) do {       \
     99    (s)->name[(s)->name##_tail++] = (val);       \
    100    (s)->name##_tail %= ARRAY_SIZE((s)->name);   \
    101} while(0)
    102
    103static void mptsas_post_reply(MPTSASState *s, MPIDefaultReply *reply)
    104{
    105    PCIDevice *pci = (PCIDevice *) s;
    106    uint32_t addr_lo;
    107
    108    if (MPTSAS_FIFO_EMPTY(s, reply_free) || MPTSAS_FIFO_FULL(s, reply_post)) {
    109        mptsas_set_fault(s, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES);
    110        return;
    111    }
    112
    113    addr_lo = MPTSAS_FIFO_GET(s, reply_free);
    114
    115    pci_dma_write(pci, addr_lo | s->host_mfa_high_addr, reply,
    116                  MIN(s->reply_frame_size, 4 * reply->MsgLength));
    117
    118    MPTSAS_FIFO_PUT(s, reply_post, MPI_ADDRESS_REPLY_A_BIT | (addr_lo >> 1));
    119
    120    s->intr_status |= MPI_HIS_REPLY_MESSAGE_INTERRUPT;
    121    if (s->doorbell_state == DOORBELL_WRITE) {
    122        s->doorbell_state = DOORBELL_NONE;
    123        s->intr_status |= MPI_HIS_DOORBELL_INTERRUPT;
    124    }
    125    mptsas_update_interrupt(s);
    126}
    127
    128void mptsas_reply(MPTSASState *s, MPIDefaultReply *reply)
    129{
    130    if (s->doorbell_state == DOORBELL_WRITE) {
    131        /* The reply is sent out in 16 bit chunks, while the size
    132         * in the reply is in 32 bit units.
    133         */
    134        s->doorbell_state = DOORBELL_READ;
    135        s->doorbell_reply_idx = 0;
    136        s->doorbell_reply_size = reply->MsgLength * 2;
    137        memcpy(s->doorbell_reply, reply, s->doorbell_reply_size * 2);
    138        s->intr_status |= MPI_HIS_DOORBELL_INTERRUPT;
    139        mptsas_update_interrupt(s);
    140    } else {
    141        mptsas_post_reply(s, reply);
    142    }
    143}
    144
    145static void mptsas_turbo_reply(MPTSASState *s, uint32_t msgctx)
    146{
    147    if (MPTSAS_FIFO_FULL(s, reply_post)) {
    148        mptsas_set_fault(s, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES);
    149        return;
    150    }
    151
    152    /* The reply is just the message context ID (bit 31 = clear). */
    153    MPTSAS_FIFO_PUT(s, reply_post, msgctx);
    154
    155    s->intr_status |= MPI_HIS_REPLY_MESSAGE_INTERRUPT;
    156    mptsas_update_interrupt(s);
    157}
    158
    159#define MPTSAS_MAX_REQUEST_SIZE 52
    160
    161static const int mpi_request_sizes[] = {
    162    [MPI_FUNCTION_SCSI_IO_REQUEST]    = sizeof(MPIMsgSCSIIORequest),
    163    [MPI_FUNCTION_SCSI_TASK_MGMT]     = sizeof(MPIMsgSCSITaskMgmt),
    164    [MPI_FUNCTION_IOC_INIT]           = sizeof(MPIMsgIOCInit),
    165    [MPI_FUNCTION_IOC_FACTS]          = sizeof(MPIMsgIOCFacts),
    166    [MPI_FUNCTION_CONFIG]             = sizeof(MPIMsgConfig),
    167    [MPI_FUNCTION_PORT_FACTS]         = sizeof(MPIMsgPortFacts),
    168    [MPI_FUNCTION_PORT_ENABLE]        = sizeof(MPIMsgPortEnable),
    169    [MPI_FUNCTION_EVENT_NOTIFICATION] = sizeof(MPIMsgEventNotify),
    170};
    171
    172static dma_addr_t mptsas_ld_sg_base(MPTSASState *s, uint32_t flags_and_length,
    173                                    dma_addr_t *sgaddr)
    174{
    175    PCIDevice *pci = (PCIDevice *) s;
    176    dma_addr_t addr;
    177
    178    if (flags_and_length & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
    179        addr = ldq_le_pci_dma(pci, *sgaddr + 4);
    180        *sgaddr += 12;
    181    } else {
    182        addr = ldl_le_pci_dma(pci, *sgaddr + 4);
    183        *sgaddr += 8;
    184    }
    185    return addr;
    186}
    187
    188static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr addr)
    189{
    190    PCIDevice *pci = (PCIDevice *) s;
    191    hwaddr next_chain_addr;
    192    uint32_t left;
    193    hwaddr sgaddr;
    194    uint32_t chain_offset;
    195
    196    chain_offset = req->scsi_io.ChainOffset;
    197    next_chain_addr = addr + chain_offset * sizeof(uint32_t);
    198    sgaddr = addr + sizeof(MPIMsgSCSIIORequest);
    199    pci_dma_sglist_init(&req->qsg, pci, 4);
    200    left = req->scsi_io.DataLength;
    201
    202    for(;;) {
    203        dma_addr_t addr, len;
    204        uint32_t flags_and_length;
    205
    206        flags_and_length = ldl_le_pci_dma(pci, sgaddr);
    207        len = flags_and_length & MPI_SGE_LENGTH_MASK;
    208        if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK)
    209            != MPI_SGE_FLAGS_SIMPLE_ELEMENT ||
    210            (!len &&
    211             !(flags_and_length & MPI_SGE_FLAGS_END_OF_LIST) &&
    212             !(flags_and_length & MPI_SGE_FLAGS_END_OF_BUFFER))) {
    213            return MPI_IOCSTATUS_INVALID_SGL;
    214        }
    215
    216        len = MIN(len, left);
    217        if (!len) {
    218            /* We reached the desired transfer length, ignore extra
    219             * elements of the s/g list.
    220             */
    221            break;
    222        }
    223
    224        addr = mptsas_ld_sg_base(s, flags_and_length, &sgaddr);
    225        qemu_sglist_add(&req->qsg, addr, len);
    226        left -= len;
    227
    228        if (flags_and_length & MPI_SGE_FLAGS_END_OF_LIST) {
    229            break;
    230        }
    231
    232        if (flags_and_length & MPI_SGE_FLAGS_LAST_ELEMENT) {
    233            if (!chain_offset) {
    234                break;
    235            }
    236
    237            flags_and_length = ldl_le_pci_dma(pci, next_chain_addr);
    238            if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK)
    239                != MPI_SGE_FLAGS_CHAIN_ELEMENT) {
    240                return MPI_IOCSTATUS_INVALID_SGL;
    241            }
    242
    243            sgaddr = mptsas_ld_sg_base(s, flags_and_length, &next_chain_addr);
    244            chain_offset =
    245                (flags_and_length & MPI_SGE_CHAIN_OFFSET_MASK) >> MPI_SGE_CHAIN_OFFSET_SHIFT;
    246            next_chain_addr = sgaddr + chain_offset * sizeof(uint32_t);
    247        }
    248    }
    249    return 0;
    250}
    251
    252static void mptsas_free_request(MPTSASRequest *req)
    253{
    254    if (req->sreq != NULL) {
    255        req->sreq->hba_private = NULL;
    256        scsi_req_unref(req->sreq);
    257        req->sreq = NULL;
    258    }
    259    qemu_sglist_destroy(&req->qsg);
    260    g_free(req);
    261}
    262
    263static int mptsas_scsi_device_find(MPTSASState *s, int bus, int target,
    264                                   uint8_t *lun, SCSIDevice **sdev)
    265{
    266    if (bus != 0) {
    267        return MPI_IOCSTATUS_SCSI_INVALID_BUS;
    268    }
    269
    270    if (target >= s->max_devices) {
    271        return MPI_IOCSTATUS_SCSI_INVALID_TARGETID;
    272    }
    273
    274    *sdev = scsi_device_find(&s->bus, bus, target, lun[1]);
    275    if (!*sdev) {
    276        return MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE;
    277    }
    278
    279    return 0;
    280}
    281
    282static int mptsas_process_scsi_io_request(MPTSASState *s,
    283                                          MPIMsgSCSIIORequest *scsi_io,
    284                                          hwaddr addr)
    285{
    286    MPTSASRequest *req;
    287    MPIMsgSCSIIOReply reply;
    288    SCSIDevice *sdev;
    289    int status;
    290
    291    mptsas_fix_scsi_io_endianness(scsi_io);
    292
    293    trace_mptsas_process_scsi_io_request(s, scsi_io->Bus, scsi_io->TargetID,
    294                                         scsi_io->LUN[1], scsi_io->DataLength);
    295
    296    status = mptsas_scsi_device_find(s, scsi_io->Bus, scsi_io->TargetID,
    297                                     scsi_io->LUN, &sdev);
    298    if (status) {
    299        goto bad;
    300    }
    301
    302    req = g_new0(MPTSASRequest, 1);
    303    req->scsi_io = *scsi_io;
    304    req->dev = s;
    305
    306    status = mptsas_build_sgl(s, req, addr);
    307    if (status) {
    308        goto free_bad;
    309    }
    310
    311    if (req->qsg.size < scsi_io->DataLength) {
    312        trace_mptsas_sgl_overflow(s, scsi_io->MsgContext, scsi_io->DataLength,
    313                                  req->qsg.size);
    314        status = MPI_IOCSTATUS_INVALID_SGL;
    315        goto free_bad;
    316    }
    317
    318    req->sreq = scsi_req_new(sdev, scsi_io->MsgContext,
    319                            scsi_io->LUN[1], scsi_io->CDB, req);
    320
    321    if (req->sreq->cmd.xfer > scsi_io->DataLength) {
    322        goto overrun;
    323    }
    324    switch (scsi_io->Control & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK) {
    325    case MPI_SCSIIO_CONTROL_NODATATRANSFER:
    326        if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
    327            goto overrun;
    328        }
    329        break;
    330
    331    case MPI_SCSIIO_CONTROL_WRITE:
    332        if (req->sreq->cmd.mode != SCSI_XFER_TO_DEV) {
    333            goto overrun;
    334        }
    335        break;
    336
    337    case MPI_SCSIIO_CONTROL_READ:
    338        if (req->sreq->cmd.mode != SCSI_XFER_FROM_DEV) {
    339            goto overrun;
    340        }
    341        break;
    342    }
    343
    344    if (scsi_req_enqueue(req->sreq)) {
    345        scsi_req_continue(req->sreq);
    346    }
    347    return 0;
    348
    349overrun:
    350    trace_mptsas_scsi_overflow(s, scsi_io->MsgContext, req->sreq->cmd.xfer,
    351                               scsi_io->DataLength);
    352    status = MPI_IOCSTATUS_SCSI_DATA_OVERRUN;
    353free_bad:
    354    mptsas_free_request(req);
    355bad:
    356    memset(&reply, 0, sizeof(reply));
    357    reply.TargetID          = scsi_io->TargetID;
    358    reply.Bus               = scsi_io->Bus;
    359    reply.MsgLength         = sizeof(reply) / 4;
    360    reply.Function          = scsi_io->Function;
    361    reply.CDBLength         = scsi_io->CDBLength;
    362    reply.SenseBufferLength = scsi_io->SenseBufferLength;
    363    reply.MsgContext        = scsi_io->MsgContext;
    364    reply.SCSIState         = MPI_SCSI_STATE_NO_SCSI_STATUS;
    365    reply.IOCStatus         = status;
    366
    367    mptsas_fix_scsi_io_reply_endianness(&reply);
    368    mptsas_reply(s, (MPIDefaultReply *)&reply);
    369
    370    return 0;
    371}
    372
    373typedef struct {
    374    Notifier                notifier;
    375    MPTSASState             *s;
    376    MPIMsgSCSITaskMgmtReply *reply;
    377} MPTSASCancelNotifier;
    378
    379static void mptsas_cancel_notify(Notifier *notifier, void *data)
    380{
    381    MPTSASCancelNotifier *n = container_of(notifier,
    382                                           MPTSASCancelNotifier,
    383                                           notifier);
    384
    385    /* Abusing IOCLogInfo to store the expected number of requests... */
    386    if (++n->reply->TerminationCount == n->reply->IOCLogInfo) {
    387        n->reply->IOCLogInfo = 0;
    388        mptsas_fix_scsi_task_mgmt_reply_endianness(n->reply);
    389        mptsas_post_reply(n->s, (MPIDefaultReply *)n->reply);
    390        g_free(n->reply);
    391    }
    392    g_free(n);
    393}
    394
    395static void mptsas_process_scsi_task_mgmt(MPTSASState *s, MPIMsgSCSITaskMgmt *req)
    396{
    397    MPIMsgSCSITaskMgmtReply reply;
    398    MPIMsgSCSITaskMgmtReply *reply_async;
    399    int status, count;
    400    SCSIDevice *sdev;
    401    SCSIRequest *r, *next;
    402    BusChild *kid;
    403
    404    mptsas_fix_scsi_task_mgmt_endianness(req);
    405
    406    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    407    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    408    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));
    409
    410    memset(&reply, 0, sizeof(reply));
    411    reply.TargetID   = req->TargetID;
    412    reply.Bus        = req->Bus;
    413    reply.MsgLength  = sizeof(reply) / 4;
    414    reply.Function   = req->Function;
    415    reply.TaskType   = req->TaskType;
    416    reply.MsgContext = req->MsgContext;
    417
    418    switch (req->TaskType) {
    419    case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
    420    case MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
    421        status = mptsas_scsi_device_find(s, req->Bus, req->TargetID,
    422                                         req->LUN, &sdev);
    423        if (status) {
    424            reply.IOCStatus = status;
    425            goto out;
    426        }
    427        if (sdev->lun != req->LUN[1]) {
    428            reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN;
    429            goto out;
    430        }
    431
    432        QTAILQ_FOREACH_SAFE(r, &sdev->requests, next, next) {
    433            MPTSASRequest *cmd_req = r->hba_private;
    434            if (cmd_req && cmd_req->scsi_io.MsgContext == req->TaskMsgContext) {
    435                break;
    436            }
    437        }
    438        if (r) {
    439            /*
    440             * Assert that the request has not been completed yet, we
    441             * check for it in the loop above.
    442             */
    443            assert(r->hba_private);
    444            if (req->TaskType == MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK) {
    445                /* "If the specified command is present in the task set, then
    446                 * return a service response set to FUNCTION SUCCEEDED".
    447                 */
    448                reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED;
    449            } else {
    450                MPTSASCancelNotifier *notifier;
    451
    452                reply_async = g_memdup(&reply, sizeof(MPIMsgSCSITaskMgmtReply));
    453                reply_async->IOCLogInfo = INT_MAX;
    454
    455                count = 1;
    456                notifier = g_new(MPTSASCancelNotifier, 1);
    457                notifier->s = s;
    458                notifier->reply = reply_async;
    459                notifier->notifier.notify = mptsas_cancel_notify;
    460                scsi_req_cancel_async(r, &notifier->notifier);
    461                goto reply_maybe_async;
    462            }
    463        }
    464        break;
    465
    466    case MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
    467    case MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET:
    468        status = mptsas_scsi_device_find(s, req->Bus, req->TargetID,
    469                                         req->LUN, &sdev);
    470        if (status) {
    471            reply.IOCStatus = status;
    472            goto out;
    473        }
    474        if (sdev->lun != req->LUN[1]) {
    475            reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN;
    476            goto out;
    477        }
    478
    479        reply_async = g_memdup(&reply, sizeof(MPIMsgSCSITaskMgmtReply));
    480        reply_async->IOCLogInfo = INT_MAX;
    481
    482        count = 0;
    483        QTAILQ_FOREACH_SAFE(r, &sdev->requests, next, next) {
    484            if (r->hba_private) {
    485                MPTSASCancelNotifier *notifier;
    486
    487                count++;
    488                notifier = g_new(MPTSASCancelNotifier, 1);
    489                notifier->s = s;
    490                notifier->reply = reply_async;
    491                notifier->notifier.notify = mptsas_cancel_notify;
    492                scsi_req_cancel_async(r, &notifier->notifier);
    493            }
    494        }
    495
    496reply_maybe_async:
    497        if (reply_async->TerminationCount < count) {
    498            reply_async->IOCLogInfo = count;
    499            return;
    500        }
    501        g_free(reply_async);
    502        reply.TerminationCount = count;
    503        break;
    504
    505    case MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
    506        status = mptsas_scsi_device_find(s, req->Bus, req->TargetID,
    507                                         req->LUN, &sdev);
    508        if (status) {
    509            reply.IOCStatus = status;
    510            goto out;
    511        }
    512        if (sdev->lun != req->LUN[1]) {
    513            reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN;
    514            goto out;
    515        }
    516        qdev_reset_all(&sdev->qdev);
    517        break;
    518
    519    case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
    520        if (req->Bus != 0) {
    521            reply.IOCStatus = MPI_IOCSTATUS_SCSI_INVALID_BUS;
    522            goto out;
    523        }
    524        if (req->TargetID > s->max_devices) {
    525            reply.IOCStatus = MPI_IOCSTATUS_SCSI_INVALID_TARGETID;
    526            goto out;
    527        }
    528
    529        QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
    530            sdev = SCSI_DEVICE(kid->child);
    531            if (sdev->channel == 0 && sdev->id == req->TargetID) {
    532                qdev_reset_all(kid->child);
    533            }
    534        }
    535        break;
    536
    537    case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
    538        qbus_reset_all(BUS(&s->bus));
    539        break;
    540
    541    default:
    542        reply.ResponseCode = MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED;
    543        break;
    544    }
    545
    546out:
    547    mptsas_fix_scsi_task_mgmt_reply_endianness(&reply);
    548    mptsas_post_reply(s, (MPIDefaultReply *)&reply);
    549}
    550
    551static void mptsas_process_ioc_init(MPTSASState *s, MPIMsgIOCInit *req)
    552{
    553    MPIMsgIOCInitReply reply;
    554
    555    mptsas_fix_ioc_init_endianness(req);
    556
    557    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    558    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    559    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));
    560
    561    s->who_init               = req->WhoInit;
    562    s->reply_frame_size       = req->ReplyFrameSize;
    563    s->max_buses              = req->MaxBuses;
    564    s->max_devices            = req->MaxDevices ? req->MaxDevices : 256;
    565    s->host_mfa_high_addr     = (hwaddr)req->HostMfaHighAddr << 32;
    566    s->sense_buffer_high_addr = (hwaddr)req->SenseBufferHighAddr << 32;
    567
    568    if (s->state == MPI_IOC_STATE_READY) {
    569        s->state = MPI_IOC_STATE_OPERATIONAL;
    570    }
    571
    572    memset(&reply, 0, sizeof(reply));
    573    reply.WhoInit    = s->who_init;
    574    reply.MsgLength  = sizeof(reply) / 4;
    575    reply.Function   = req->Function;
    576    reply.MaxDevices = s->max_devices;
    577    reply.MaxBuses   = s->max_buses;
    578    reply.MsgContext = req->MsgContext;
    579
    580    mptsas_fix_ioc_init_reply_endianness(&reply);
    581    mptsas_reply(s, (MPIDefaultReply *)&reply);
    582}
    583
    584static void mptsas_process_ioc_facts(MPTSASState *s,
    585                                     MPIMsgIOCFacts *req)
    586{
    587    MPIMsgIOCFactsReply reply;
    588
    589    mptsas_fix_ioc_facts_endianness(req);
    590
    591    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    592    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    593    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));
    594
    595    memset(&reply, 0, sizeof(reply));
    596    reply.MsgVersion                 = 0x0105;
    597    reply.MsgLength                  = sizeof(reply) / 4;
    598    reply.Function                   = req->Function;
    599    reply.MsgContext                 = req->MsgContext;
    600    reply.MaxChainDepth              = MPTSAS_MAXIMUM_CHAIN_DEPTH;
    601    reply.WhoInit                    = s->who_init;
    602    reply.BlockSize                  = MPTSAS_MAX_REQUEST_SIZE / sizeof(uint32_t);
    603    reply.ReplyQueueDepth            = ARRAY_SIZE(s->reply_post) - 1;
    604    QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->reply_post) != ARRAY_SIZE(s->reply_free));
    605
    606    reply.RequestFrameSize           = 128;
    607    reply.ProductID                  = MPTSAS1068_PRODUCT_ID;
    608    reply.CurrentHostMfaHighAddr     = s->host_mfa_high_addr >> 32;
    609    reply.GlobalCredits              = ARRAY_SIZE(s->request_post) - 1;
    610    reply.NumberOfPorts              = MPTSAS_NUM_PORTS;
    611    reply.CurrentSenseBufferHighAddr = s->sense_buffer_high_addr >> 32;
    612    reply.CurReplyFrameSize          = s->reply_frame_size;
    613    reply.MaxDevices                 = s->max_devices;
    614    reply.MaxBuses                   = s->max_buses;
    615    reply.FWVersionDev               = 0;
    616    reply.FWVersionUnit              = 0x92;
    617    reply.FWVersionMinor             = 0x32;
    618    reply.FWVersionMajor             = 0x1;
    619
    620    mptsas_fix_ioc_facts_reply_endianness(&reply);
    621    mptsas_reply(s, (MPIDefaultReply *)&reply);
    622}
    623
    624static void mptsas_process_port_facts(MPTSASState *s,
    625                                     MPIMsgPortFacts *req)
    626{
    627    MPIMsgPortFactsReply reply;
    628
    629    mptsas_fix_port_facts_endianness(req);
    630
    631    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    632    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    633    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));
    634
    635    memset(&reply, 0, sizeof(reply));
    636    reply.MsgLength  = sizeof(reply) / 4;
    637    reply.Function   = req->Function;
    638    reply.PortNumber = req->PortNumber;
    639    reply.MsgContext = req->MsgContext;
    640
    641    if (req->PortNumber < MPTSAS_NUM_PORTS) {
    642        reply.PortType      = MPI_PORTFACTS_PORTTYPE_SAS;
    643        reply.MaxDevices    = MPTSAS_NUM_PORTS;
    644        reply.PortSCSIID    = MPTSAS_NUM_PORTS;
    645        reply.ProtocolFlags = MPI_PORTFACTS_PROTOCOL_LOGBUSADDR | MPI_PORTFACTS_PROTOCOL_INITIATOR;
    646    }
    647
    648    mptsas_fix_port_facts_reply_endianness(&reply);
    649    mptsas_reply(s, (MPIDefaultReply *)&reply);
    650}
    651
    652static void mptsas_process_port_enable(MPTSASState *s,
    653                                       MPIMsgPortEnable *req)
    654{
    655    MPIMsgPortEnableReply reply;
    656
    657    mptsas_fix_port_enable_endianness(req);
    658
    659    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    660    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    661    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));
    662
    663    memset(&reply, 0, sizeof(reply));
    664    reply.MsgLength  = sizeof(reply) / 4;
    665    reply.PortNumber = req->PortNumber;
    666    reply.Function   = req->Function;
    667    reply.MsgContext = req->MsgContext;
    668
    669    mptsas_fix_port_enable_reply_endianness(&reply);
    670    mptsas_reply(s, (MPIDefaultReply *)&reply);
    671}
    672
    673static void mptsas_process_event_notification(MPTSASState *s,
    674                                              MPIMsgEventNotify *req)
    675{
    676    MPIMsgEventNotifyReply reply;
    677
    678    mptsas_fix_event_notification_endianness(req);
    679
    680    QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE < sizeof(*req));
    681    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_msg) < sizeof(*req));
    682    QEMU_BUILD_BUG_ON(sizeof(s->doorbell_reply) < sizeof(reply));
    683
    684    /* Don't even bother storing whether event notification is enabled,
    685     * since it is not accessible.
    686     */
    687
    688    memset(&reply, 0, sizeof(reply));
    689    reply.EventDataLength = sizeof(reply.Data) / 4;
    690    reply.MsgLength       = sizeof(reply) / 4;
    691    reply.Function        = req->Function;
    692
    693    /* This is set because events are sent through the reply FIFOs.  */
    694    reply.MsgFlags        = MPI_MSGFLAGS_CONTINUATION_REPLY;
    695
    696    reply.MsgContext      = req->MsgContext;
    697    reply.Event           = MPI_EVENT_EVENT_CHANGE;
    698    reply.Data[0]         = !!req->Switch;
    699
    700    mptsas_fix_event_notification_reply_endianness(&reply);
    701    mptsas_reply(s, (MPIDefaultReply *)&reply);
    702}
    703
    704static void mptsas_process_message(MPTSASState *s, MPIRequestHeader *req)
    705{
    706    trace_mptsas_process_message(s, req->Function, req->MsgContext);
    707    switch (req->Function) {
    708    case MPI_FUNCTION_SCSI_TASK_MGMT:
    709        mptsas_process_scsi_task_mgmt(s, (MPIMsgSCSITaskMgmt *)req);
    710        break;
    711
    712    case MPI_FUNCTION_IOC_INIT:
    713        mptsas_process_ioc_init(s, (MPIMsgIOCInit *)req);
    714        break;
    715
    716    case MPI_FUNCTION_IOC_FACTS:
    717        mptsas_process_ioc_facts(s, (MPIMsgIOCFacts *)req);
    718        break;
    719
    720    case MPI_FUNCTION_PORT_FACTS:
    721        mptsas_process_port_facts(s, (MPIMsgPortFacts *)req);
    722        break;
    723
    724    case MPI_FUNCTION_PORT_ENABLE:
    725        mptsas_process_port_enable(s, (MPIMsgPortEnable *)req);
    726        break;
    727
    728    case MPI_FUNCTION_EVENT_NOTIFICATION:
    729        mptsas_process_event_notification(s, (MPIMsgEventNotify *)req);
    730        break;
    731
    732    case MPI_FUNCTION_CONFIG:
    733        mptsas_process_config(s, (MPIMsgConfig *)req);
    734        break;
    735
    736    default:
    737        trace_mptsas_unhandled_cmd(s, req->Function, 0);
    738        mptsas_set_fault(s, MPI_IOCSTATUS_INVALID_FUNCTION);
    739        break;
    740    }
    741}
    742
    743static void mptsas_fetch_request(MPTSASState *s)
    744{
    745    PCIDevice *pci = (PCIDevice *) s;
    746    char req[MPTSAS_MAX_REQUEST_SIZE];
    747    MPIRequestHeader *hdr = (MPIRequestHeader *)req;
    748    hwaddr addr;
    749    int size;
    750
    751    /* Read the message header from the guest first. */
    752    addr = s->host_mfa_high_addr | MPTSAS_FIFO_GET(s, request_post);
    753    pci_dma_read(pci, addr, req, sizeof(*hdr));
    754
    755    if (hdr->Function < ARRAY_SIZE(mpi_request_sizes) &&
    756        mpi_request_sizes[hdr->Function]) {
    757        /* Read the rest of the request based on the type.  Do not
    758         * reread everything, as that could cause a TOC/TOU mismatch
    759         * and leak data from the QEMU stack.
    760         */
    761        size = mpi_request_sizes[hdr->Function];
    762        assert(size <= MPTSAS_MAX_REQUEST_SIZE);
    763        pci_dma_read(pci, addr + sizeof(*hdr), &req[sizeof(*hdr)],
    764                     size - sizeof(*hdr));
    765    }
    766
    767    if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
    768        /* SCSI I/O requests are separate from mptsas_process_message
    769         * because they cannot be sent through the doorbell yet.
    770         */
    771        mptsas_process_scsi_io_request(s, (MPIMsgSCSIIORequest *)req, addr);
    772    } else {
    773        mptsas_process_message(s, (MPIRequestHeader *)req);
    774    }
    775}
    776
    777static void mptsas_fetch_requests(void *opaque)
    778{
    779    MPTSASState *s = opaque;
    780
    781    if (s->state != MPI_IOC_STATE_OPERATIONAL) {
    782        mptsas_set_fault(s, MPI_IOCSTATUS_INVALID_STATE);
    783        return;
    784    }
    785    while (!MPTSAS_FIFO_EMPTY(s, request_post)) {
    786        mptsas_fetch_request(s);
    787    }
    788}
    789
    790static void mptsas_soft_reset(MPTSASState *s)
    791{
    792    uint32_t save_mask;
    793
    794    trace_mptsas_reset(s);
    795
    796    /* Temporarily disable interrupts */
    797    save_mask = s->intr_mask;
    798    s->intr_mask = MPI_HIM_DIM | MPI_HIM_RIM;
    799    mptsas_update_interrupt(s);
    800
    801    qbus_reset_all(BUS(&s->bus));
    802    s->intr_status = 0;
    803    s->intr_mask = save_mask;
    804
    805    s->reply_free_tail = 0;
    806    s->reply_free_head = 0;
    807    s->reply_post_tail = 0;
    808    s->reply_post_head = 0;
    809    s->request_post_tail = 0;
    810    s->request_post_head = 0;
    811    qemu_bh_cancel(s->request_bh);
    812
    813    s->state = MPI_IOC_STATE_READY;
    814}
    815
    816static uint32_t mptsas_doorbell_read(MPTSASState *s)
    817{
    818    uint32_t ret;
    819
    820    ret = (s->who_init << MPI_DOORBELL_WHO_INIT_SHIFT) & MPI_DOORBELL_WHO_INIT_MASK;
    821    ret |= s->state;
    822    switch (s->doorbell_state) {
    823    case DOORBELL_NONE:
    824        break;
    825
    826    case DOORBELL_WRITE:
    827        ret |= MPI_DOORBELL_ACTIVE;
    828        break;
    829
    830    case DOORBELL_READ:
    831        /* Get rid of the IOC fault code.  */
    832        ret &= ~MPI_DOORBELL_DATA_MASK;
    833
    834        assert(s->intr_status & MPI_HIS_DOORBELL_INTERRUPT);
    835        assert(s->doorbell_reply_idx <= s->doorbell_reply_size);
    836
    837        ret |= MPI_DOORBELL_ACTIVE;
    838        if (s->doorbell_reply_idx < s->doorbell_reply_size) {
    839            /* For more information about this endian switch, see the
    840             * commit message for commit 36b62ae ("fw_cfg: fix endianness in
    841             * fw_cfg_data_mem_read() / _write()", 2015-01-16).
    842             */
    843            ret |= le16_to_cpu(s->doorbell_reply[s->doorbell_reply_idx++]);
    844        }
    845        break;
    846
    847    default:
    848        abort();
    849    }
    850
    851    return ret;
    852}
    853
    854static void mptsas_doorbell_write(MPTSASState *s, uint32_t val)
    855{
    856    if (s->doorbell_state == DOORBELL_WRITE) {
    857        if (s->doorbell_idx < s->doorbell_cnt) {
    858            /* For more information about this endian switch, see the
    859             * commit message for commit 36b62ae ("fw_cfg: fix endianness in
    860             * fw_cfg_data_mem_read() / _write()", 2015-01-16).
    861             */
    862            s->doorbell_msg[s->doorbell_idx++] = cpu_to_le32(val);
    863            if (s->doorbell_idx == s->doorbell_cnt) {
    864                mptsas_process_message(s, (MPIRequestHeader *)s->doorbell_msg);
    865            }
    866        }
    867        return;
    868    }
    869
    870    switch ((val & MPI_DOORBELL_FUNCTION_MASK) >> MPI_DOORBELL_FUNCTION_SHIFT) {
    871    case MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET:
    872        mptsas_soft_reset(s);
    873        break;
    874    case MPI_FUNCTION_IO_UNIT_RESET:
    875        break;
    876    case MPI_FUNCTION_HANDSHAKE:
    877        s->doorbell_state = DOORBELL_WRITE;
    878        s->doorbell_idx = 0;
    879        s->doorbell_cnt = (val & MPI_DOORBELL_ADD_DWORDS_MASK)
    880            >> MPI_DOORBELL_ADD_DWORDS_SHIFT;
    881        s->intr_status |= MPI_HIS_DOORBELL_INTERRUPT;
    882        mptsas_update_interrupt(s);
    883        break;
    884    default:
    885        trace_mptsas_unhandled_doorbell_cmd(s, val);
    886        break;
    887    }
    888}
    889
    890static void mptsas_write_sequence_write(MPTSASState *s, uint32_t val)
    891{
    892    /* If the diagnostic register is enabled, any write to this register
    893     * will disable it.  Otherwise, the guest has to do a magic five-write
    894     * sequence.
    895     */
    896    if (s->diagnostic & MPI_DIAG_DRWE) {
    897        goto disable;
    898    }
    899
    900    switch (s->diagnostic_idx) {
    901    case 0:
    902        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_1ST_KEY_VALUE) {
    903            goto disable;
    904        }
    905        break;
    906    case 1:
    907        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_2ND_KEY_VALUE) {
    908            goto disable;
    909        }
    910        break;
    911    case 2:
    912        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_3RD_KEY_VALUE) {
    913            goto disable;
    914        }
    915        break;
    916    case 3:
    917        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_4TH_KEY_VALUE) {
    918            goto disable;
    919        }
    920        break;
    921    case 4:
    922        if ((val & MPI_WRSEQ_KEY_VALUE_MASK) != MPI_WRSEQ_5TH_KEY_VALUE) {
    923            goto disable;
    924        }
    925        /* Prepare Spaceball One for departure, and change the
    926         * combination on my luggage!
    927         */
    928        s->diagnostic |= MPI_DIAG_DRWE;
    929        break;
    930    }
    931    s->diagnostic_idx++;
    932    return;
    933
    934disable:
    935    s->diagnostic &= ~MPI_DIAG_DRWE;
    936    s->diagnostic_idx = 0;
    937}
    938
    939static int mptsas_hard_reset(MPTSASState *s)
    940{
    941    mptsas_soft_reset(s);
    942
    943    s->intr_mask = MPI_HIM_DIM | MPI_HIM_RIM;
    944
    945    s->host_mfa_high_addr = 0;
    946    s->sense_buffer_high_addr = 0;
    947    s->reply_frame_size = 0;
    948    s->max_devices = MPTSAS_NUM_PORTS;
    949    s->max_buses = 1;
    950
    951    return 0;
    952}
    953
    954static void mptsas_interrupt_status_write(MPTSASState *s)
    955{
    956    switch (s->doorbell_state) {
    957    case DOORBELL_NONE:
    958    case DOORBELL_WRITE:
    959        s->intr_status &= ~MPI_HIS_DOORBELL_INTERRUPT;
    960        break;
    961
    962    case DOORBELL_READ:
    963        /* The reply can be read continuously, so leave the interrupt up.  */
    964        assert(s->intr_status & MPI_HIS_DOORBELL_INTERRUPT);
    965        if (s->doorbell_reply_idx == s->doorbell_reply_size) {
    966            s->doorbell_state = DOORBELL_NONE;
    967        }
    968        break;
    969
    970    default:
    971        abort();
    972    }
    973    mptsas_update_interrupt(s);
    974}
    975
    976static uint32_t mptsas_reply_post_read(MPTSASState *s)
    977{
    978    uint32_t ret;
    979
    980    if (!MPTSAS_FIFO_EMPTY(s, reply_post)) {
    981        ret = MPTSAS_FIFO_GET(s, reply_post);
    982    } else {
    983        ret = -1;
    984        s->intr_status &= ~MPI_HIS_REPLY_MESSAGE_INTERRUPT;
    985        mptsas_update_interrupt(s);
    986    }
    987
    988    return ret;
    989}
    990
    991static uint64_t mptsas_mmio_read(void *opaque, hwaddr addr,
    992                                  unsigned size)
    993{
    994    MPTSASState *s = opaque;
    995    uint32_t ret = 0;
    996
    997    switch (addr & ~3) {
    998    case MPI_DOORBELL_OFFSET:
    999        ret = mptsas_doorbell_read(s);
   1000        break;
   1001
   1002    case MPI_DIAGNOSTIC_OFFSET:
   1003        ret = s->diagnostic;
   1004        break;
   1005
   1006    case MPI_HOST_INTERRUPT_STATUS_OFFSET:
   1007        ret = s->intr_status;
   1008        break;
   1009
   1010    case MPI_HOST_INTERRUPT_MASK_OFFSET:
   1011        ret = s->intr_mask;
   1012        break;
   1013
   1014    case MPI_REPLY_POST_FIFO_OFFSET:
   1015        ret = mptsas_reply_post_read(s);
   1016        break;
   1017
   1018    default:
   1019        trace_mptsas_mmio_unhandled_read(s, addr);
   1020        break;
   1021    }
   1022    trace_mptsas_mmio_read(s, addr, ret);
   1023    return ret;
   1024}
   1025
   1026static void mptsas_mmio_write(void *opaque, hwaddr addr,
   1027                               uint64_t val, unsigned size)
   1028{
   1029    MPTSASState *s = opaque;
   1030
   1031    trace_mptsas_mmio_write(s, addr, val);
   1032    switch (addr) {
   1033    case MPI_DOORBELL_OFFSET:
   1034        mptsas_doorbell_write(s, val);
   1035        break;
   1036
   1037    case MPI_WRITE_SEQUENCE_OFFSET:
   1038        mptsas_write_sequence_write(s, val);
   1039        break;
   1040
   1041    case MPI_DIAGNOSTIC_OFFSET:
   1042        if (val & MPI_DIAG_RESET_ADAPTER) {
   1043            mptsas_hard_reset(s);
   1044        }
   1045        break;
   1046
   1047    case MPI_HOST_INTERRUPT_STATUS_OFFSET:
   1048        mptsas_interrupt_status_write(s);
   1049        break;
   1050
   1051    case MPI_HOST_INTERRUPT_MASK_OFFSET:
   1052        s->intr_mask = val & (MPI_HIM_RIM | MPI_HIM_DIM);
   1053        mptsas_update_interrupt(s);
   1054        break;
   1055
   1056    case MPI_REQUEST_POST_FIFO_OFFSET:
   1057        if (MPTSAS_FIFO_FULL(s, request_post)) {
   1058            mptsas_set_fault(s, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES);
   1059        } else {
   1060            MPTSAS_FIFO_PUT(s, request_post, val & ~0x03);
   1061            qemu_bh_schedule(s->request_bh);
   1062        }
   1063        break;
   1064
   1065    case MPI_REPLY_FREE_FIFO_OFFSET:
   1066        if (MPTSAS_FIFO_FULL(s, reply_free)) {
   1067            mptsas_set_fault(s, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES);
   1068        } else {
   1069            MPTSAS_FIFO_PUT(s, reply_free, val);
   1070        }
   1071        break;
   1072
   1073    default:
   1074        trace_mptsas_mmio_unhandled_write(s, addr, val);
   1075        break;
   1076    }
   1077}
   1078
   1079static const MemoryRegionOps mptsas_mmio_ops = {
   1080    .read = mptsas_mmio_read,
   1081    .write = mptsas_mmio_write,
   1082    .endianness = DEVICE_LITTLE_ENDIAN,
   1083    .impl = {
   1084        .min_access_size = 4,
   1085        .max_access_size = 4,
   1086    }
   1087};
   1088
   1089static const MemoryRegionOps mptsas_port_ops = {
   1090    .read = mptsas_mmio_read,
   1091    .write = mptsas_mmio_write,
   1092    .endianness = DEVICE_LITTLE_ENDIAN,
   1093    .impl = {
   1094        .min_access_size = 4,
   1095        .max_access_size = 4,
   1096    }
   1097};
   1098
   1099static uint64_t mptsas_diag_read(void *opaque, hwaddr addr,
   1100                                   unsigned size)
   1101{
   1102    MPTSASState *s = opaque;
   1103    trace_mptsas_diag_read(s, addr, 0);
   1104    return 0;
   1105}
   1106
   1107static void mptsas_diag_write(void *opaque, hwaddr addr,
   1108                               uint64_t val, unsigned size)
   1109{
   1110    MPTSASState *s = opaque;
   1111    trace_mptsas_diag_write(s, addr, val);
   1112}
   1113
   1114static const MemoryRegionOps mptsas_diag_ops = {
   1115    .read = mptsas_diag_read,
   1116    .write = mptsas_diag_write,
   1117    .endianness = DEVICE_LITTLE_ENDIAN,
   1118    .impl = {
   1119        .min_access_size = 4,
   1120        .max_access_size = 4,
   1121    }
   1122};
   1123
   1124static QEMUSGList *mptsas_get_sg_list(SCSIRequest *sreq)
   1125{
   1126    MPTSASRequest *req = sreq->hba_private;
   1127
   1128    return &req->qsg;
   1129}
   1130
   1131static void mptsas_command_complete(SCSIRequest *sreq,
   1132        size_t resid)
   1133{
   1134    MPTSASRequest *req = sreq->hba_private;
   1135    MPTSASState *s = req->dev;
   1136    uint8_t sense_buf[SCSI_SENSE_BUF_SIZE];
   1137    uint8_t sense_len;
   1138
   1139    hwaddr sense_buffer_addr = req->dev->sense_buffer_high_addr |
   1140            req->scsi_io.SenseBufferLowAddr;
   1141
   1142    trace_mptsas_command_complete(s, req->scsi_io.MsgContext,
   1143                                  sreq->status, resid);
   1144
   1145    sense_len = scsi_req_get_sense(sreq, sense_buf, SCSI_SENSE_BUF_SIZE);
   1146    if (sense_len > 0) {
   1147        pci_dma_write(PCI_DEVICE(s), sense_buffer_addr, sense_buf,
   1148                      MIN(req->scsi_io.SenseBufferLength, sense_len));
   1149    }
   1150
   1151    if (sreq->status != GOOD || resid ||
   1152        req->dev->doorbell_state == DOORBELL_WRITE) {
   1153        MPIMsgSCSIIOReply reply;
   1154
   1155        memset(&reply, 0, sizeof(reply));
   1156        reply.TargetID          = req->scsi_io.TargetID;
   1157        reply.Bus               = req->scsi_io.Bus;
   1158        reply.MsgLength         = sizeof(reply) / 4;
   1159        reply.Function          = req->scsi_io.Function;
   1160        reply.CDBLength         = req->scsi_io.CDBLength;
   1161        reply.SenseBufferLength = req->scsi_io.SenseBufferLength;
   1162        reply.MsgFlags          = req->scsi_io.MsgFlags;
   1163        reply.MsgContext        = req->scsi_io.MsgContext;
   1164        reply.SCSIStatus        = sreq->status;
   1165        if (sreq->status == GOOD) {
   1166            reply.TransferCount = req->scsi_io.DataLength - resid;
   1167            if (resid) {
   1168                reply.IOCStatus     = MPI_IOCSTATUS_SCSI_DATA_UNDERRUN;
   1169            }
   1170        } else {
   1171            reply.SCSIState     = MPI_SCSI_STATE_AUTOSENSE_VALID;
   1172            reply.SenseCount    = sense_len;
   1173            reply.IOCStatus     = MPI_IOCSTATUS_SCSI_DATA_UNDERRUN;
   1174        }
   1175
   1176        mptsas_fix_scsi_io_reply_endianness(&reply);
   1177        mptsas_post_reply(req->dev, (MPIDefaultReply *)&reply);
   1178    } else {
   1179        mptsas_turbo_reply(req->dev, req->scsi_io.MsgContext);
   1180    }
   1181
   1182    mptsas_free_request(req);
   1183}
   1184
   1185static void mptsas_request_cancelled(SCSIRequest *sreq)
   1186{
   1187    MPTSASRequest *req = sreq->hba_private;
   1188    MPIMsgSCSIIOReply reply;
   1189
   1190    memset(&reply, 0, sizeof(reply));
   1191    reply.TargetID          = req->scsi_io.TargetID;
   1192    reply.Bus               = req->scsi_io.Bus;
   1193    reply.MsgLength         = sizeof(reply) / 4;
   1194    reply.Function          = req->scsi_io.Function;
   1195    reply.CDBLength         = req->scsi_io.CDBLength;
   1196    reply.SenseBufferLength = req->scsi_io.SenseBufferLength;
   1197    reply.MsgFlags          = req->scsi_io.MsgFlags;
   1198    reply.MsgContext        = req->scsi_io.MsgContext;
   1199    reply.SCSIState         = MPI_SCSI_STATE_NO_SCSI_STATUS;
   1200    reply.IOCStatus         = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
   1201
   1202    mptsas_fix_scsi_io_reply_endianness(&reply);
   1203    mptsas_post_reply(req->dev, (MPIDefaultReply *)&reply);
   1204    mptsas_free_request(req);
   1205}
   1206
   1207static void mptsas_save_request(QEMUFile *f, SCSIRequest *sreq)
   1208{
   1209    MPTSASRequest *req = sreq->hba_private;
   1210    int i;
   1211
   1212    qemu_put_buffer(f, (unsigned char *)&req->scsi_io, sizeof(req->scsi_io));
   1213    qemu_put_be32(f, req->qsg.nsg);
   1214    for (i = 0; i < req->qsg.nsg; i++) {
   1215        qemu_put_be64(f, req->qsg.sg[i].base);
   1216        qemu_put_be64(f, req->qsg.sg[i].len);
   1217    }
   1218}
   1219
   1220static void *mptsas_load_request(QEMUFile *f, SCSIRequest *sreq)
   1221{
   1222    SCSIBus *bus = sreq->bus;
   1223    MPTSASState *s = container_of(bus, MPTSASState, bus);
   1224    PCIDevice *pci = PCI_DEVICE(s);
   1225    MPTSASRequest *req;
   1226    int i, n;
   1227
   1228    req = g_new(MPTSASRequest, 1);
   1229    qemu_get_buffer(f, (unsigned char *)&req->scsi_io, sizeof(req->scsi_io));
   1230
   1231    n = qemu_get_be32(f);
   1232    /* TODO: add a way for SCSIBusInfo's load_request to fail,
   1233     * and fail migration instead of asserting here.
   1234     * This is just one thing (there are probably more) that must be
   1235     * fixed before we can allow NDEBUG compilation.
   1236     */
   1237    assert(n >= 0);
   1238
   1239    pci_dma_sglist_init(&req->qsg, pci, n);
   1240    for (i = 0; i < n; i++) {
   1241        uint64_t base = qemu_get_be64(f);
   1242        uint64_t len = qemu_get_be64(f);
   1243        qemu_sglist_add(&req->qsg, base, len);
   1244    }
   1245
   1246    scsi_req_ref(sreq);
   1247    req->sreq = sreq;
   1248    req->dev = s;
   1249
   1250    return req;
   1251}
   1252
   1253static const struct SCSIBusInfo mptsas_scsi_info = {
   1254    .tcq = true,
   1255    .max_target = MPTSAS_NUM_PORTS,
   1256    .max_lun = 1,
   1257
   1258    .get_sg_list = mptsas_get_sg_list,
   1259    .complete = mptsas_command_complete,
   1260    .cancel = mptsas_request_cancelled,
   1261    .save_request = mptsas_save_request,
   1262    .load_request = mptsas_load_request,
   1263};
   1264
   1265static void mptsas_scsi_realize(PCIDevice *dev, Error **errp)
   1266{
   1267    MPTSASState *s = MPT_SAS(dev);
   1268    Error *err = NULL;
   1269    int ret;
   1270
   1271    dev->config[PCI_LATENCY_TIMER] = 0;
   1272    dev->config[PCI_INTERRUPT_PIN] = 0x01;
   1273
   1274    if (s->msi != ON_OFF_AUTO_OFF) {
   1275        ret = msi_init(dev, 0, 1, true, false, &err);
   1276        /* Any error other than -ENOTSUP(board's MSI support is broken)
   1277         * is a programming error */
   1278        assert(!ret || ret == -ENOTSUP);
   1279        if (ret && s->msi == ON_OFF_AUTO_ON) {
   1280            /* Can't satisfy user's explicit msi=on request, fail */
   1281            error_append_hint(&err, "You have to use msi=auto (default) or "
   1282                    "msi=off with this machine type.\n");
   1283            error_propagate(errp, err);
   1284            return;
   1285        }
   1286        assert(!err || s->msi == ON_OFF_AUTO_AUTO);
   1287        /* With msi=auto, we fall back to MSI off silently */
   1288        error_free(err);
   1289
   1290        /* Only used for migration.  */
   1291        s->msi_in_use = (ret == 0);
   1292    }
   1293
   1294    memory_region_init_io(&s->mmio_io, OBJECT(s), &mptsas_mmio_ops, s,
   1295                          "mptsas-mmio", 0x4000);
   1296    memory_region_init_io(&s->port_io, OBJECT(s), &mptsas_port_ops, s,
   1297                          "mptsas-io", 256);
   1298    memory_region_init_io(&s->diag_io, OBJECT(s), &mptsas_diag_ops, s,
   1299                          "mptsas-diag", 0x10000);
   1300
   1301    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->port_io);
   1302    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY |
   1303                                 PCI_BASE_ADDRESS_MEM_TYPE_32, &s->mmio_io);
   1304    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY |
   1305                                 PCI_BASE_ADDRESS_MEM_TYPE_32, &s->diag_io);
   1306
   1307    if (!s->sas_addr) {
   1308        s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
   1309                       IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
   1310        s->sas_addr |= (pci_dev_bus_num(dev) << 16);
   1311        s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
   1312        s->sas_addr |= PCI_FUNC(dev->devfn);
   1313    }
   1314    s->max_devices = MPTSAS_NUM_PORTS;
   1315
   1316    s->request_bh = qemu_bh_new(mptsas_fetch_requests, s);
   1317
   1318    scsi_bus_init(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info);
   1319}
   1320
   1321static void mptsas_scsi_uninit(PCIDevice *dev)
   1322{
   1323    MPTSASState *s = MPT_SAS(dev);
   1324
   1325    qemu_bh_delete(s->request_bh);
   1326    msi_uninit(dev);
   1327}
   1328
   1329static void mptsas_reset(DeviceState *dev)
   1330{
   1331    MPTSASState *s = MPT_SAS(dev);
   1332
   1333    mptsas_hard_reset(s);
   1334}
   1335
   1336static int mptsas_post_load(void *opaque, int version_id)
   1337{
   1338    MPTSASState *s = opaque;
   1339
   1340    if (s->doorbell_idx > s->doorbell_cnt ||
   1341        s->doorbell_cnt > ARRAY_SIZE(s->doorbell_msg) ||
   1342        s->doorbell_reply_idx > s->doorbell_reply_size ||
   1343        s->doorbell_reply_size > ARRAY_SIZE(s->doorbell_reply) ||
   1344        MPTSAS_FIFO_INVALID(s, request_post) ||
   1345        MPTSAS_FIFO_INVALID(s, reply_post) ||
   1346        MPTSAS_FIFO_INVALID(s, reply_free) ||
   1347        s->diagnostic_idx > 4) {
   1348        return -EINVAL;
   1349    }
   1350
   1351    return 0;
   1352}
   1353
   1354static const VMStateDescription vmstate_mptsas = {
   1355    .name = "mptsas",
   1356    .version_id = 0,
   1357    .minimum_version_id = 0,
   1358    .minimum_version_id_old = 0,
   1359    .post_load = mptsas_post_load,
   1360    .fields      = (VMStateField[]) {
   1361        VMSTATE_PCI_DEVICE(dev, MPTSASState),
   1362        VMSTATE_BOOL(msi_in_use, MPTSASState),
   1363        VMSTATE_UINT32(state, MPTSASState),
   1364        VMSTATE_UINT8(who_init, MPTSASState),
   1365        VMSTATE_UINT8(doorbell_state, MPTSASState),
   1366        VMSTATE_UINT32_ARRAY(doorbell_msg, MPTSASState, 256),
   1367        VMSTATE_INT32(doorbell_idx, MPTSASState),
   1368        VMSTATE_INT32(doorbell_cnt, MPTSASState),
   1369
   1370        VMSTATE_UINT16_ARRAY(doorbell_reply, MPTSASState, 256),
   1371        VMSTATE_INT32(doorbell_reply_idx, MPTSASState),
   1372        VMSTATE_INT32(doorbell_reply_size, MPTSASState),
   1373
   1374        VMSTATE_UINT32(diagnostic, MPTSASState),
   1375        VMSTATE_UINT8(diagnostic_idx, MPTSASState),
   1376
   1377        VMSTATE_UINT32(intr_status, MPTSASState),
   1378        VMSTATE_UINT32(intr_mask, MPTSASState),
   1379
   1380        VMSTATE_UINT32_ARRAY(request_post, MPTSASState,
   1381                             MPTSAS_REQUEST_QUEUE_DEPTH + 1),
   1382        VMSTATE_UINT16(request_post_head, MPTSASState),
   1383        VMSTATE_UINT16(request_post_tail, MPTSASState),
   1384
   1385        VMSTATE_UINT32_ARRAY(reply_post, MPTSASState,
   1386                             MPTSAS_REPLY_QUEUE_DEPTH + 1),
   1387        VMSTATE_UINT16(reply_post_head, MPTSASState),
   1388        VMSTATE_UINT16(reply_post_tail, MPTSASState),
   1389
   1390        VMSTATE_UINT32_ARRAY(reply_free, MPTSASState,
   1391                             MPTSAS_REPLY_QUEUE_DEPTH + 1),
   1392        VMSTATE_UINT16(reply_free_head, MPTSASState),
   1393        VMSTATE_UINT16(reply_free_tail, MPTSASState),
   1394
   1395        VMSTATE_UINT16(max_buses, MPTSASState),
   1396        VMSTATE_UINT16(max_devices, MPTSASState),
   1397        VMSTATE_UINT16(reply_frame_size, MPTSASState),
   1398        VMSTATE_UINT64(host_mfa_high_addr, MPTSASState),
   1399        VMSTATE_UINT64(sense_buffer_high_addr, MPTSASState),
   1400        VMSTATE_END_OF_LIST()
   1401    }
   1402};
   1403
   1404static Property mptsas_properties[] = {
   1405    DEFINE_PROP_UINT64("sas_address", MPTSASState, sas_addr, 0),
   1406    /* TODO: test MSI support under Windows */
   1407    DEFINE_PROP_ON_OFF_AUTO("msi", MPTSASState, msi, ON_OFF_AUTO_AUTO),
   1408    DEFINE_PROP_END_OF_LIST(),
   1409};
   1410
   1411static void mptsas1068_class_init(ObjectClass *oc, void *data)
   1412{
   1413    DeviceClass *dc = DEVICE_CLASS(oc);
   1414    PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc);
   1415
   1416    pc->realize = mptsas_scsi_realize;
   1417    pc->exit = mptsas_scsi_uninit;
   1418    pc->romfile = 0;
   1419    pc->vendor_id = PCI_VENDOR_ID_LSI_LOGIC;
   1420    pc->device_id = PCI_DEVICE_ID_LSI_SAS1068;
   1421    pc->subsystem_vendor_id = PCI_VENDOR_ID_LSI_LOGIC;
   1422    pc->subsystem_id = 0x8000;
   1423    pc->class_id = PCI_CLASS_STORAGE_SCSI;
   1424    device_class_set_props(dc, mptsas_properties);
   1425    dc->reset = mptsas_reset;
   1426    dc->vmsd = &vmstate_mptsas;
   1427    dc->desc = "LSI SAS 1068";
   1428    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
   1429}
   1430
   1431static const TypeInfo mptsas_info = {
   1432    .name = TYPE_MPTSAS1068,
   1433    .parent = TYPE_PCI_DEVICE,
   1434    .instance_size = sizeof(MPTSASState),
   1435    .class_init = mptsas1068_class_init,
   1436    .interfaces = (InterfaceInfo[]) {
   1437        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
   1438        { },
   1439    },
   1440};
   1441
   1442static void mptsas_register_types(void)
   1443{
   1444    type_register(&mptsas_info);
   1445}
   1446
   1447type_init(mptsas_register_types)