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

virtio-scsi.c (36143B)


      1/*
      2 * Virtio SCSI HBA
      3 *
      4 * Copyright IBM, Corp. 2010
      5 * Copyright Red Hat, Inc. 2011
      6 *
      7 * Authors:
      8 *   Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com>
      9 *   Paolo Bonzini      <pbonzini@redhat.com>
     10 *
     11 * This work is licensed under the terms of the GNU GPL, version 2 or later.
     12 * See the COPYING file in the top-level directory.
     13 *
     14 */
     15
     16#include "qemu/osdep.h"
     17#include "qapi/error.h"
     18#include "standard-headers/linux/virtio_ids.h"
     19#include "hw/virtio/virtio-scsi.h"
     20#include "migration/qemu-file-types.h"
     21#include "qemu/error-report.h"
     22#include "qemu/iov.h"
     23#include "qemu/module.h"
     24#include "sysemu/block-backend.h"
     25#include "hw/qdev-properties.h"
     26#include "hw/scsi/scsi.h"
     27#include "scsi/constants.h"
     28#include "hw/virtio/virtio-bus.h"
     29#include "hw/virtio/virtio-access.h"
     30#include "trace.h"
     31
     32static inline int virtio_scsi_get_lun(uint8_t *lun)
     33{
     34    return ((lun[2] << 8) | lun[3]) & 0x3FFF;
     35}
     36
     37static inline SCSIDevice *virtio_scsi_device_get(VirtIOSCSI *s, uint8_t *lun)
     38{
     39    if (lun[0] != 1) {
     40        return NULL;
     41    }
     42    if (lun[2] != 0 && !(lun[2] >= 0x40 && lun[2] < 0x80)) {
     43        return NULL;
     44    }
     45    return scsi_device_get(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun));
     46}
     47
     48void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req)
     49{
     50    VirtIODevice *vdev = VIRTIO_DEVICE(s);
     51    const size_t zero_skip =
     52        offsetof(VirtIOSCSIReq, resp_iov) + sizeof(req->resp_iov);
     53
     54    req->vq = vq;
     55    req->dev = s;
     56    qemu_sglist_init(&req->qsgl, DEVICE(s), 8, vdev->dma_as);
     57    qemu_iovec_init(&req->resp_iov, 1);
     58    memset((uint8_t *)req + zero_skip, 0, sizeof(*req) - zero_skip);
     59}
     60
     61void virtio_scsi_free_req(VirtIOSCSIReq *req)
     62{
     63    qemu_iovec_destroy(&req->resp_iov);
     64    qemu_sglist_destroy(&req->qsgl);
     65    g_free(req);
     66}
     67
     68static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
     69{
     70    VirtIOSCSI *s = req->dev;
     71    VirtQueue *vq = req->vq;
     72    VirtIODevice *vdev = VIRTIO_DEVICE(s);
     73
     74    qemu_iovec_from_buf(&req->resp_iov, 0, &req->resp, req->resp_size);
     75    virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size);
     76    if (s->dataplane_started && !s->dataplane_fenced) {
     77        virtio_notify_irqfd(vdev, vq);
     78    } else {
     79        virtio_notify(vdev, vq);
     80    }
     81
     82    if (req->sreq) {
     83        req->sreq->hba_private = NULL;
     84        scsi_req_unref(req->sreq);
     85    }
     86    virtio_scsi_free_req(req);
     87}
     88
     89static void virtio_scsi_bad_req(VirtIOSCSIReq *req)
     90{
     91    virtio_error(VIRTIO_DEVICE(req->dev), "wrong size for virtio-scsi headers");
     92    virtqueue_detach_element(req->vq, &req->elem, 0);
     93    virtio_scsi_free_req(req);
     94}
     95
     96static size_t qemu_sgl_concat(VirtIOSCSIReq *req, struct iovec *iov,
     97                              hwaddr *addr, int num, size_t skip)
     98{
     99    QEMUSGList *qsgl = &req->qsgl;
    100    size_t copied = 0;
    101
    102    while (num) {
    103        if (skip >= iov->iov_len) {
    104            skip -= iov->iov_len;
    105        } else {
    106            qemu_sglist_add(qsgl, *addr + skip, iov->iov_len - skip);
    107            copied += iov->iov_len - skip;
    108            skip = 0;
    109        }
    110        iov++;
    111        addr++;
    112        num--;
    113    }
    114
    115    assert(skip == 0);
    116    return copied;
    117}
    118
    119static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
    120                                 unsigned req_size, unsigned resp_size)
    121{
    122    VirtIODevice *vdev = (VirtIODevice *) req->dev;
    123    size_t in_size, out_size;
    124
    125    if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,
    126                   &req->req, req_size) < req_size) {
    127        return -EINVAL;
    128    }
    129
    130    if (qemu_iovec_concat_iov(&req->resp_iov,
    131                              req->elem.in_sg, req->elem.in_num, 0,
    132                              resp_size) < resp_size) {
    133        return -EINVAL;
    134    }
    135
    136    req->resp_size = resp_size;
    137
    138    /* Old BIOSes left some padding by mistake after the req_size/resp_size.
    139     * As a workaround, always consider the first buffer as the virtio-scsi
    140     * request/response, making the payload start at the second element
    141     * of the iovec.
    142     *
    143     * The actual length of the response header, stored in req->resp_size,
    144     * does not change.
    145     *
    146     * TODO: always disable this workaround for virtio 1.0 devices.
    147     */
    148    if (!virtio_vdev_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
    149        if (req->elem.out_num) {
    150            req_size = req->elem.out_sg[0].iov_len;
    151        }
    152        if (req->elem.in_num) {
    153            resp_size = req->elem.in_sg[0].iov_len;
    154        }
    155    }
    156
    157    out_size = qemu_sgl_concat(req, req->elem.out_sg,
    158                               &req->elem.out_addr[0], req->elem.out_num,
    159                               req_size);
    160    in_size = qemu_sgl_concat(req, req->elem.in_sg,
    161                              &req->elem.in_addr[0], req->elem.in_num,
    162                              resp_size);
    163
    164    if (out_size && in_size) {
    165        return -ENOTSUP;
    166    }
    167
    168    if (out_size) {
    169        req->mode = SCSI_XFER_TO_DEV;
    170    } else if (in_size) {
    171        req->mode = SCSI_XFER_FROM_DEV;
    172    }
    173
    174    return 0;
    175}
    176
    177static VirtIOSCSIReq *virtio_scsi_pop_req(VirtIOSCSI *s, VirtQueue *vq)
    178{
    179    VirtIOSCSICommon *vs = (VirtIOSCSICommon *)s;
    180    VirtIOSCSIReq *req;
    181
    182    req = virtqueue_pop(vq, sizeof(VirtIOSCSIReq) + vs->cdb_size);
    183    if (!req) {
    184        return NULL;
    185    }
    186    virtio_scsi_init_req(s, vq, req);
    187    return req;
    188}
    189
    190static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq)
    191{
    192    VirtIOSCSIReq *req = sreq->hba_private;
    193    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev);
    194    VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);
    195    uint32_t n = virtio_get_queue_index(req->vq) - VIRTIO_SCSI_VQ_NUM_FIXED;
    196
    197    assert(n < vs->conf.num_queues);
    198    qemu_put_be32s(f, &n);
    199    qemu_put_virtqueue_element(vdev, f, &req->elem);
    200}
    201
    202static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
    203{
    204    SCSIBus *bus = sreq->bus;
    205    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
    206    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
    207    VirtIODevice *vdev = VIRTIO_DEVICE(s);
    208    VirtIOSCSIReq *req;
    209    uint32_t n;
    210
    211    qemu_get_be32s(f, &n);
    212    assert(n < vs->conf.num_queues);
    213    req = qemu_get_virtqueue_element(vdev, f,
    214                                     sizeof(VirtIOSCSIReq) + vs->cdb_size);
    215    virtio_scsi_init_req(s, vs->cmd_vqs[n], req);
    216
    217    if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
    218                              sizeof(VirtIOSCSICmdResp) + vs->sense_size) < 0) {
    219        error_report("invalid SCSI request migration data");
    220        exit(1);
    221    }
    222
    223    scsi_req_ref(sreq);
    224    req->sreq = sreq;
    225    if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
    226        assert(req->sreq->cmd.mode == req->mode);
    227    }
    228    return req;
    229}
    230
    231typedef struct {
    232    Notifier        notifier;
    233    VirtIOSCSIReq  *tmf_req;
    234} VirtIOSCSICancelNotifier;
    235
    236static void virtio_scsi_cancel_notify(Notifier *notifier, void *data)
    237{
    238    VirtIOSCSICancelNotifier *n = container_of(notifier,
    239                                               VirtIOSCSICancelNotifier,
    240                                               notifier);
    241
    242    if (--n->tmf_req->remaining == 0) {
    243        VirtIOSCSIReq *req = n->tmf_req;
    244
    245        trace_virtio_scsi_tmf_resp(virtio_scsi_get_lun(req->req.tmf.lun),
    246                                   req->req.tmf.tag, req->resp.tmf.response);
    247        virtio_scsi_complete_req(req);
    248    }
    249    g_free(n);
    250}
    251
    252static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d)
    253{
    254    if (s->dataplane_started && d && blk_is_available(d->conf.blk)) {
    255        assert(blk_get_aio_context(d->conf.blk) == s->ctx);
    256    }
    257}
    258
    259/* Return 0 if the request is ready to be completed and return to guest;
    260 * -EINPROGRESS if the request is submitted and will be completed later, in the
    261 *  case of async cancellation. */
    262static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
    263{
    264    SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun);
    265    SCSIRequest *r, *next;
    266    BusChild *kid;
    267    int target;
    268    int ret = 0;
    269
    270    virtio_scsi_ctx_check(s, d);
    271    /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE".  */
    272    req->resp.tmf.response = VIRTIO_SCSI_S_OK;
    273
    274    /*
    275     * req->req.tmf has the QEMU_PACKED attribute. Don't use virtio_tswap32s()
    276     * to avoid compiler errors.
    277     */
    278    req->req.tmf.subtype =
    279        virtio_tswap32(VIRTIO_DEVICE(s), req->req.tmf.subtype);
    280
    281    trace_virtio_scsi_tmf_req(virtio_scsi_get_lun(req->req.tmf.lun),
    282                              req->req.tmf.tag, req->req.tmf.subtype);
    283
    284    switch (req->req.tmf.subtype) {
    285    case VIRTIO_SCSI_T_TMF_ABORT_TASK:
    286    case VIRTIO_SCSI_T_TMF_QUERY_TASK:
    287        if (!d) {
    288            goto fail;
    289        }
    290        if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
    291            goto incorrect_lun;
    292        }
    293        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
    294            VirtIOSCSIReq *cmd_req = r->hba_private;
    295            if (cmd_req && cmd_req->req.cmd.tag == req->req.tmf.tag) {
    296                break;
    297            }
    298        }
    299        if (r) {
    300            /*
    301             * Assert that the request has not been completed yet, we
    302             * check for it in the loop above.
    303             */
    304            assert(r->hba_private);
    305            if (req->req.tmf.subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK) {
    306                /* "If the specified command is present in the task set, then
    307                 * return a service response set to FUNCTION SUCCEEDED".
    308                 */
    309                req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
    310            } else {
    311                VirtIOSCSICancelNotifier *notifier;
    312
    313                req->remaining = 1;
    314                notifier = g_new(VirtIOSCSICancelNotifier, 1);
    315                notifier->tmf_req = req;
    316                notifier->notifier.notify = virtio_scsi_cancel_notify;
    317                scsi_req_cancel_async(r, &notifier->notifier);
    318                ret = -EINPROGRESS;
    319            }
    320        }
    321        break;
    322
    323    case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
    324        if (!d) {
    325            goto fail;
    326        }
    327        if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
    328            goto incorrect_lun;
    329        }
    330        s->resetting++;
    331        qdev_reset_all(&d->qdev);
    332        s->resetting--;
    333        break;
    334
    335    case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET:
    336    case VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET:
    337    case VIRTIO_SCSI_T_TMF_QUERY_TASK_SET:
    338        if (!d) {
    339            goto fail;
    340        }
    341        if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
    342            goto incorrect_lun;
    343        }
    344
    345        /* Add 1 to "remaining" until virtio_scsi_do_tmf returns.
    346         * This way, if the bus starts calling back to the notifiers
    347         * even before we finish the loop, virtio_scsi_cancel_notify
    348         * will not complete the TMF too early.
    349         */
    350        req->remaining = 1;
    351        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
    352            if (r->hba_private) {
    353                if (req->req.tmf.subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK_SET) {
    354                    /* "If there is any command present in the task set, then
    355                     * return a service response set to FUNCTION SUCCEEDED".
    356                     */
    357                    req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
    358                    break;
    359                } else {
    360                    VirtIOSCSICancelNotifier *notifier;
    361
    362                    req->remaining++;
    363                    notifier = g_new(VirtIOSCSICancelNotifier, 1);
    364                    notifier->notifier.notify = virtio_scsi_cancel_notify;
    365                    notifier->tmf_req = req;
    366                    scsi_req_cancel_async(r, &notifier->notifier);
    367                }
    368            }
    369        }
    370        if (--req->remaining > 0) {
    371            ret = -EINPROGRESS;
    372        }
    373        break;
    374
    375    case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
    376        target = req->req.tmf.lun[1];
    377        s->resetting++;
    378
    379        rcu_read_lock();
    380        QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) {
    381            SCSIDevice *d1 = SCSI_DEVICE(kid->child);
    382            if (d1->channel == 0 && d1->id == target) {
    383                qdev_reset_all(&d1->qdev);
    384            }
    385        }
    386        rcu_read_unlock();
    387
    388        s->resetting--;
    389        break;
    390
    391    case VIRTIO_SCSI_T_TMF_CLEAR_ACA:
    392    default:
    393        req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_REJECTED;
    394        break;
    395    }
    396
    397    object_unref(OBJECT(d));
    398    return ret;
    399
    400incorrect_lun:
    401    req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN;
    402    object_unref(OBJECT(d));
    403    return ret;
    404
    405fail:
    406    req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET;
    407    object_unref(OBJECT(d));
    408    return ret;
    409}
    410
    411static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
    412{
    413    VirtIODevice *vdev = (VirtIODevice *)s;
    414    uint32_t type;
    415    int r = 0;
    416
    417    if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,
    418                &type, sizeof(type)) < sizeof(type)) {
    419        virtio_scsi_bad_req(req);
    420        return;
    421    }
    422
    423    virtio_tswap32s(vdev, &type);
    424    if (type == VIRTIO_SCSI_T_TMF) {
    425        if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlTMFReq),
    426                    sizeof(VirtIOSCSICtrlTMFResp)) < 0) {
    427            virtio_scsi_bad_req(req);
    428            return;
    429        } else {
    430            r = virtio_scsi_do_tmf(s, req);
    431        }
    432
    433    } else if (type == VIRTIO_SCSI_T_AN_QUERY ||
    434               type == VIRTIO_SCSI_T_AN_SUBSCRIBE) {
    435        if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlANReq),
    436                    sizeof(VirtIOSCSICtrlANResp)) < 0) {
    437            virtio_scsi_bad_req(req);
    438            return;
    439        } else {
    440            req->req.an.event_requested =
    441                virtio_tswap32(VIRTIO_DEVICE(s), req->req.an.event_requested);
    442            trace_virtio_scsi_an_req(virtio_scsi_get_lun(req->req.an.lun),
    443                                     req->req.an.event_requested);
    444            req->resp.an.event_actual = 0;
    445            req->resp.an.response = VIRTIO_SCSI_S_OK;
    446        }
    447    }
    448    if (r == 0) {
    449        if (type == VIRTIO_SCSI_T_TMF)
    450            trace_virtio_scsi_tmf_resp(virtio_scsi_get_lun(req->req.tmf.lun),
    451                                       req->req.tmf.tag,
    452                                       req->resp.tmf.response);
    453        else if (type == VIRTIO_SCSI_T_AN_QUERY ||
    454                 type == VIRTIO_SCSI_T_AN_SUBSCRIBE)
    455            trace_virtio_scsi_an_resp(virtio_scsi_get_lun(req->req.an.lun),
    456                                      req->resp.an.response);
    457        virtio_scsi_complete_req(req);
    458    } else {
    459        assert(r == -EINPROGRESS);
    460    }
    461}
    462
    463bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq)
    464{
    465    VirtIOSCSIReq *req;
    466    bool progress = false;
    467
    468    while ((req = virtio_scsi_pop_req(s, vq))) {
    469        progress = true;
    470        virtio_scsi_handle_ctrl_req(s, req);
    471    }
    472    return progress;
    473}
    474
    475static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
    476{
    477    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
    478
    479    if (s->ctx) {
    480        virtio_device_start_ioeventfd(vdev);
    481        if (!s->dataplane_fenced) {
    482            return;
    483        }
    484    }
    485    virtio_scsi_acquire(s);
    486    virtio_scsi_handle_ctrl_vq(s, vq);
    487    virtio_scsi_release(s);
    488}
    489
    490static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req)
    491{
    492    trace_virtio_scsi_cmd_resp(virtio_scsi_get_lun(req->req.cmd.lun),
    493                               req->req.cmd.tag,
    494                               req->resp.cmd.response,
    495                               req->resp.cmd.status);
    496    /* Sense data is not in req->resp and is copied separately
    497     * in virtio_scsi_command_complete.
    498     */
    499    req->resp_size = sizeof(VirtIOSCSICmdResp);
    500    virtio_scsi_complete_req(req);
    501}
    502
    503static void virtio_scsi_command_failed(SCSIRequest *r)
    504{
    505    VirtIOSCSIReq *req = r->hba_private;
    506
    507    if (r->io_canceled) {
    508        return;
    509    }
    510
    511    req->resp.cmd.status = GOOD;
    512    switch (r->host_status) {
    513    case SCSI_HOST_NO_LUN:
    514        req->resp.cmd.response = VIRTIO_SCSI_S_INCORRECT_LUN;
    515        break;
    516    case SCSI_HOST_BUSY:
    517        req->resp.cmd.response = VIRTIO_SCSI_S_BUSY;
    518        break;
    519    case SCSI_HOST_TIME_OUT:
    520    case SCSI_HOST_ABORTED:
    521        req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED;
    522        break;
    523    case SCSI_HOST_BAD_RESPONSE:
    524        req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET;
    525        break;
    526    case SCSI_HOST_RESET:
    527        req->resp.cmd.response = VIRTIO_SCSI_S_RESET;
    528        break;
    529    case SCSI_HOST_TRANSPORT_DISRUPTED:
    530        req->resp.cmd.response = VIRTIO_SCSI_S_TRANSPORT_FAILURE;
    531        break;
    532    case SCSI_HOST_TARGET_FAILURE:
    533        req->resp.cmd.response = VIRTIO_SCSI_S_TARGET_FAILURE;
    534        break;
    535    case SCSI_HOST_RESERVATION_ERROR:
    536        req->resp.cmd.response = VIRTIO_SCSI_S_NEXUS_FAILURE;
    537        break;
    538    case SCSI_HOST_ALLOCATION_FAILURE:
    539    case SCSI_HOST_MEDIUM_ERROR:
    540    case SCSI_HOST_ERROR:
    541    default:
    542        req->resp.cmd.response = VIRTIO_SCSI_S_FAILURE;
    543        break;
    544    }
    545    virtio_scsi_complete_cmd_req(req);
    546}
    547
    548static void virtio_scsi_command_complete(SCSIRequest *r, size_t resid)
    549{
    550    VirtIOSCSIReq *req = r->hba_private;
    551    uint8_t sense[SCSI_SENSE_BUF_SIZE];
    552    uint32_t sense_len;
    553    VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);
    554
    555    if (r->io_canceled) {
    556        return;
    557    }
    558
    559    req->resp.cmd.response = VIRTIO_SCSI_S_OK;
    560    req->resp.cmd.status = r->status;
    561    if (req->resp.cmd.status == GOOD) {
    562        req->resp.cmd.resid = virtio_tswap32(vdev, resid);
    563    } else {
    564        req->resp.cmd.resid = 0;
    565        sense_len = scsi_req_get_sense(r, sense, sizeof(sense));
    566        sense_len = MIN(sense_len, req->resp_iov.size - sizeof(req->resp.cmd));
    567        qemu_iovec_from_buf(&req->resp_iov, sizeof(req->resp.cmd),
    568                            sense, sense_len);
    569        req->resp.cmd.sense_len = virtio_tswap32(vdev, sense_len);
    570    }
    571    virtio_scsi_complete_cmd_req(req);
    572}
    573
    574static int virtio_scsi_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
    575                                 uint8_t *buf, void *hba_private)
    576{
    577    VirtIOSCSIReq *req = hba_private;
    578
    579    if (cmd->len == 0) {
    580        cmd->len = MIN(VIRTIO_SCSI_CDB_DEFAULT_SIZE, SCSI_CMD_BUF_SIZE);
    581        memcpy(cmd->buf, buf, cmd->len);
    582    }
    583
    584    /* Extract the direction and mode directly from the request, for
    585     * host device passthrough.
    586     */
    587    cmd->xfer = req->qsgl.size;
    588    cmd->mode = req->mode;
    589    return 0;
    590}
    591
    592static QEMUSGList *virtio_scsi_get_sg_list(SCSIRequest *r)
    593{
    594    VirtIOSCSIReq *req = r->hba_private;
    595
    596    return &req->qsgl;
    597}
    598
    599static void virtio_scsi_request_cancelled(SCSIRequest *r)
    600{
    601    VirtIOSCSIReq *req = r->hba_private;
    602
    603    if (!req) {
    604        return;
    605    }
    606    if (req->dev->resetting) {
    607        req->resp.cmd.response = VIRTIO_SCSI_S_RESET;
    608    } else {
    609        req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED;
    610    }
    611    virtio_scsi_complete_cmd_req(req);
    612}
    613
    614static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
    615{
    616    req->resp.cmd.response = VIRTIO_SCSI_S_FAILURE;
    617    virtio_scsi_complete_cmd_req(req);
    618}
    619
    620static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
    621{
    622    VirtIOSCSICommon *vs = &s->parent_obj;
    623    SCSIDevice *d;
    624    int rc;
    625
    626    rc = virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
    627                               sizeof(VirtIOSCSICmdResp) + vs->sense_size);
    628    if (rc < 0) {
    629        if (rc == -ENOTSUP) {
    630            virtio_scsi_fail_cmd_req(req);
    631            return -ENOTSUP;
    632        } else {
    633            virtio_scsi_bad_req(req);
    634            return -EINVAL;
    635        }
    636    }
    637    trace_virtio_scsi_cmd_req(virtio_scsi_get_lun(req->req.cmd.lun),
    638                              req->req.cmd.tag, req->req.cmd.cdb[0]);
    639
    640    d = virtio_scsi_device_get(s, req->req.cmd.lun);
    641    if (!d) {
    642        req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET;
    643        virtio_scsi_complete_cmd_req(req);
    644        return -ENOENT;
    645    }
    646    virtio_scsi_ctx_check(s, d);
    647    req->sreq = scsi_req_new(d, req->req.cmd.tag,
    648                             virtio_scsi_get_lun(req->req.cmd.lun),
    649                             req->req.cmd.cdb, req);
    650
    651    if (req->sreq->cmd.mode != SCSI_XFER_NONE
    652        && (req->sreq->cmd.mode != req->mode ||
    653            req->sreq->cmd.xfer > req->qsgl.size)) {
    654        req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN;
    655        virtio_scsi_complete_cmd_req(req);
    656        object_unref(OBJECT(d));
    657        return -ENOBUFS;
    658    }
    659    scsi_req_ref(req->sreq);
    660    blk_io_plug(d->conf.blk);
    661    object_unref(OBJECT(d));
    662    return 0;
    663}
    664
    665static void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
    666{
    667    SCSIRequest *sreq = req->sreq;
    668    if (scsi_req_enqueue(sreq)) {
    669        scsi_req_continue(sreq);
    670    }
    671    blk_io_unplug(sreq->dev->conf.blk);
    672    scsi_req_unref(sreq);
    673}
    674
    675bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
    676{
    677    VirtIOSCSIReq *req, *next;
    678    int ret = 0;
    679    bool suppress_notifications = virtio_queue_get_notification(vq);
    680    bool progress = false;
    681
    682    QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
    683
    684    do {
    685        if (suppress_notifications) {
    686            virtio_queue_set_notification(vq, 0);
    687        }
    688
    689        while ((req = virtio_scsi_pop_req(s, vq))) {
    690            progress = true;
    691            ret = virtio_scsi_handle_cmd_req_prepare(s, req);
    692            if (!ret) {
    693                QTAILQ_INSERT_TAIL(&reqs, req, next);
    694            } else if (ret == -EINVAL) {
    695                /* The device is broken and shouldn't process any request */
    696                while (!QTAILQ_EMPTY(&reqs)) {
    697                    req = QTAILQ_FIRST(&reqs);
    698                    QTAILQ_REMOVE(&reqs, req, next);
    699                    blk_io_unplug(req->sreq->dev->conf.blk);
    700                    scsi_req_unref(req->sreq);
    701                    virtqueue_detach_element(req->vq, &req->elem, 0);
    702                    virtio_scsi_free_req(req);
    703                }
    704            }
    705        }
    706
    707        if (suppress_notifications) {
    708            virtio_queue_set_notification(vq, 1);
    709        }
    710    } while (ret != -EINVAL && !virtio_queue_empty(vq));
    711
    712    QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {
    713        virtio_scsi_handle_cmd_req_submit(s, req);
    714    }
    715    return progress;
    716}
    717
    718static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
    719{
    720    /* use non-QOM casts in the data path */
    721    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
    722
    723    if (s->ctx) {
    724        virtio_device_start_ioeventfd(vdev);
    725        if (!s->dataplane_fenced) {
    726            return;
    727        }
    728    }
    729    virtio_scsi_acquire(s);
    730    virtio_scsi_handle_cmd_vq(s, vq);
    731    virtio_scsi_release(s);
    732}
    733
    734static void virtio_scsi_get_config(VirtIODevice *vdev,
    735                                   uint8_t *config)
    736{
    737    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
    738    VirtIOSCSICommon *s = VIRTIO_SCSI_COMMON(vdev);
    739
    740    virtio_stl_p(vdev, &scsiconf->num_queues, s->conf.num_queues);
    741    virtio_stl_p(vdev, &scsiconf->seg_max,
    742                 s->conf.seg_max_adjust ? s->conf.virtqueue_size - 2 : 128 - 2);
    743    virtio_stl_p(vdev, &scsiconf->max_sectors, s->conf.max_sectors);
    744    virtio_stl_p(vdev, &scsiconf->cmd_per_lun, s->conf.cmd_per_lun);
    745    virtio_stl_p(vdev, &scsiconf->event_info_size, sizeof(VirtIOSCSIEvent));
    746    virtio_stl_p(vdev, &scsiconf->sense_size, s->sense_size);
    747    virtio_stl_p(vdev, &scsiconf->cdb_size, s->cdb_size);
    748    virtio_stw_p(vdev, &scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL);
    749    virtio_stw_p(vdev, &scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET);
    750    virtio_stl_p(vdev, &scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN);
    751}
    752
    753static void virtio_scsi_set_config(VirtIODevice *vdev,
    754                                   const uint8_t *config)
    755{
    756    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
    757    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
    758
    759    if ((uint32_t) virtio_ldl_p(vdev, &scsiconf->sense_size) >= 65536 ||
    760        (uint32_t) virtio_ldl_p(vdev, &scsiconf->cdb_size) >= 256) {
    761        virtio_error(vdev,
    762                     "bad data written to virtio-scsi configuration space");
    763        return;
    764    }
    765
    766    vs->sense_size = virtio_ldl_p(vdev, &scsiconf->sense_size);
    767    vs->cdb_size = virtio_ldl_p(vdev, &scsiconf->cdb_size);
    768}
    769
    770static uint64_t virtio_scsi_get_features(VirtIODevice *vdev,
    771                                         uint64_t requested_features,
    772                                         Error **errp)
    773{
    774    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
    775
    776    /* Firstly sync all virtio-scsi possible supported features */
    777    requested_features |= s->host_features;
    778    return requested_features;
    779}
    780
    781static void virtio_scsi_reset(VirtIODevice *vdev)
    782{
    783    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
    784    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
    785
    786    assert(!s->dataplane_started);
    787    s->resetting++;
    788    qbus_reset_all(BUS(&s->bus));
    789    s->resetting--;
    790
    791    vs->sense_size = VIRTIO_SCSI_SENSE_DEFAULT_SIZE;
    792    vs->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE;
    793    s->events_dropped = false;
    794}
    795
    796void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
    797                            uint32_t event, uint32_t reason)
    798{
    799    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
    800    VirtIOSCSIReq *req;
    801    VirtIOSCSIEvent *evt;
    802    VirtIODevice *vdev = VIRTIO_DEVICE(s);
    803
    804    if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
    805        return;
    806    }
    807
    808    req = virtio_scsi_pop_req(s, vs->event_vq);
    809    if (!req) {
    810        s->events_dropped = true;
    811        return;
    812    }
    813
    814    if (s->events_dropped) {
    815        event |= VIRTIO_SCSI_T_EVENTS_MISSED;
    816        s->events_dropped = false;
    817    }
    818
    819    if (virtio_scsi_parse_req(req, 0, sizeof(VirtIOSCSIEvent))) {
    820        virtio_scsi_bad_req(req);
    821        return;
    822    }
    823
    824    evt = &req->resp.event;
    825    memset(evt, 0, sizeof(VirtIOSCSIEvent));
    826    evt->event = virtio_tswap32(vdev, event);
    827    evt->reason = virtio_tswap32(vdev, reason);
    828    if (!dev) {
    829        assert(event == VIRTIO_SCSI_T_EVENTS_MISSED);
    830    } else {
    831        evt->lun[0] = 1;
    832        evt->lun[1] = dev->id;
    833
    834        /* Linux wants us to keep the same encoding we use for REPORT LUNS.  */
    835        if (dev->lun >= 256) {
    836            evt->lun[2] = (dev->lun >> 8) | 0x40;
    837        }
    838        evt->lun[3] = dev->lun & 0xFF;
    839    }
    840    trace_virtio_scsi_event(virtio_scsi_get_lun(evt->lun), event, reason);
    841     
    842    virtio_scsi_complete_req(req);
    843}
    844
    845bool virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq)
    846{
    847    if (s->events_dropped) {
    848        virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
    849        return true;
    850    }
    851    return false;
    852}
    853
    854static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
    855{
    856    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
    857
    858    if (s->ctx) {
    859        virtio_device_start_ioeventfd(vdev);
    860        if (!s->dataplane_fenced) {
    861            return;
    862        }
    863    }
    864    virtio_scsi_acquire(s);
    865    virtio_scsi_handle_event_vq(s, vq);
    866    virtio_scsi_release(s);
    867}
    868
    869static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
    870{
    871    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
    872    VirtIODevice *vdev = VIRTIO_DEVICE(s);
    873
    874    if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) &&
    875        dev->type != TYPE_ROM) {
    876        virtio_scsi_acquire(s);
    877        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
    878                               sense.asc | (sense.ascq << 8));
    879        virtio_scsi_release(s);
    880    }
    881}
    882
    883static void virtio_scsi_pre_hotplug(HotplugHandler *hotplug_dev,
    884                                    DeviceState *dev, Error **errp)
    885{
    886    SCSIDevice *sd = SCSI_DEVICE(dev);
    887    sd->hba_supports_iothread = true;
    888}
    889
    890static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
    891                                Error **errp)
    892{
    893    VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev);
    894    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
    895    SCSIDevice *sd = SCSI_DEVICE(dev);
    896    AioContext *old_context;
    897    int ret;
    898
    899    if (s->ctx && !s->dataplane_fenced) {
    900        if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
    901            return;
    902        }
    903        old_context = blk_get_aio_context(sd->conf.blk);
    904        aio_context_acquire(old_context);
    905        ret = blk_set_aio_context(sd->conf.blk, s->ctx, errp);
    906        aio_context_release(old_context);
    907        if (ret < 0) {
    908            return;
    909        }
    910    }
    911
    912    if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
    913        virtio_scsi_acquire(s);
    914        virtio_scsi_push_event(s, sd,
    915                               VIRTIO_SCSI_T_TRANSPORT_RESET,
    916                               VIRTIO_SCSI_EVT_RESET_RESCAN);
    917        virtio_scsi_release(s);
    918    }
    919}
    920
    921static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
    922                                  Error **errp)
    923{
    924    VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev);
    925    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
    926    SCSIDevice *sd = SCSI_DEVICE(dev);
    927    AioContext *ctx = s->ctx ?: qemu_get_aio_context();
    928
    929    if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
    930        virtio_scsi_acquire(s);
    931        virtio_scsi_push_event(s, sd,
    932                               VIRTIO_SCSI_T_TRANSPORT_RESET,
    933                               VIRTIO_SCSI_EVT_RESET_REMOVED);
    934        virtio_scsi_release(s);
    935    }
    936
    937    aio_disable_external(ctx);
    938    qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
    939    aio_enable_external(ctx);
    940
    941    if (s->ctx) {
    942        virtio_scsi_acquire(s);
    943        /* If other users keep the BlockBackend in the iothread, that's ok */
    944        blk_set_aio_context(sd->conf.blk, qemu_get_aio_context(), NULL);
    945        virtio_scsi_release(s);
    946    }
    947}
    948
    949static struct SCSIBusInfo virtio_scsi_scsi_info = {
    950    .tcq = true,
    951    .max_channel = VIRTIO_SCSI_MAX_CHANNEL,
    952    .max_target = VIRTIO_SCSI_MAX_TARGET,
    953    .max_lun = VIRTIO_SCSI_MAX_LUN,
    954
    955    .complete = virtio_scsi_command_complete,
    956    .fail = virtio_scsi_command_failed,
    957    .cancel = virtio_scsi_request_cancelled,
    958    .change = virtio_scsi_change,
    959    .parse_cdb = virtio_scsi_parse_cdb,
    960    .get_sg_list = virtio_scsi_get_sg_list,
    961    .save_request = virtio_scsi_save_request,
    962    .load_request = virtio_scsi_load_request,
    963};
    964
    965void virtio_scsi_common_realize(DeviceState *dev,
    966                                VirtIOHandleOutput ctrl,
    967                                VirtIOHandleOutput evt,
    968                                VirtIOHandleOutput cmd,
    969                                Error **errp)
    970{
    971    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    972    VirtIOSCSICommon *s = VIRTIO_SCSI_COMMON(dev);
    973    int i;
    974
    975    virtio_init(vdev, "virtio-scsi", VIRTIO_ID_SCSI,
    976                sizeof(VirtIOSCSIConfig));
    977
    978    if (s->conf.num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) {
    979        s->conf.num_queues = 1;
    980    }
    981    if (s->conf.num_queues == 0 ||
    982            s->conf.num_queues > VIRTIO_QUEUE_MAX - VIRTIO_SCSI_VQ_NUM_FIXED) {
    983        error_setg(errp, "Invalid number of queues (= %" PRIu32 "), "
    984                         "must be a positive integer less than %d.",
    985                   s->conf.num_queues,
    986                   VIRTIO_QUEUE_MAX - VIRTIO_SCSI_VQ_NUM_FIXED);
    987        virtio_cleanup(vdev);
    988        return;
    989    }
    990    if (s->conf.virtqueue_size <= 2) {
    991        error_setg(errp, "invalid virtqueue_size property (= %" PRIu32 "), "
    992                   "must be > 2", s->conf.virtqueue_size);
    993        return;
    994    }
    995    s->cmd_vqs = g_new0(VirtQueue *, s->conf.num_queues);
    996    s->sense_size = VIRTIO_SCSI_SENSE_DEFAULT_SIZE;
    997    s->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE;
    998
    999    s->ctrl_vq = virtio_add_queue(vdev, s->conf.virtqueue_size, ctrl);
   1000    s->event_vq = virtio_add_queue(vdev, s->conf.virtqueue_size, evt);
   1001    for (i = 0; i < s->conf.num_queues; i++) {
   1002        s->cmd_vqs[i] = virtio_add_queue(vdev, s->conf.virtqueue_size, cmd);
   1003    }
   1004}
   1005
   1006static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
   1007{
   1008    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
   1009    VirtIOSCSI *s = VIRTIO_SCSI(dev);
   1010    Error *err = NULL;
   1011
   1012    virtio_scsi_common_realize(dev,
   1013                               virtio_scsi_handle_ctrl,
   1014                               virtio_scsi_handle_event,
   1015                               virtio_scsi_handle_cmd,
   1016                               &err);
   1017    if (err != NULL) {
   1018        error_propagate(errp, err);
   1019        return;
   1020    }
   1021
   1022    scsi_bus_init_named(&s->bus, sizeof(s->bus), dev,
   1023                       &virtio_scsi_scsi_info, vdev->bus_name);
   1024    /* override default SCSI bus hotplug-handler, with virtio-scsi's one */
   1025    qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev));
   1026
   1027    virtio_scsi_dataplane_setup(s, errp);
   1028}
   1029
   1030void virtio_scsi_common_unrealize(DeviceState *dev)
   1031{
   1032    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
   1033    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
   1034    int i;
   1035
   1036    virtio_delete_queue(vs->ctrl_vq);
   1037    virtio_delete_queue(vs->event_vq);
   1038    for (i = 0; i < vs->conf.num_queues; i++) {
   1039        virtio_delete_queue(vs->cmd_vqs[i]);
   1040    }
   1041    g_free(vs->cmd_vqs);
   1042    virtio_cleanup(vdev);
   1043}
   1044
   1045static void virtio_scsi_device_unrealize(DeviceState *dev)
   1046{
   1047    VirtIOSCSI *s = VIRTIO_SCSI(dev);
   1048
   1049    qbus_set_hotplug_handler(BUS(&s->bus), NULL);
   1050    virtio_scsi_common_unrealize(dev);
   1051}
   1052
   1053static Property virtio_scsi_properties[] = {
   1054    DEFINE_PROP_UINT32("num_queues", VirtIOSCSI, parent_obj.conf.num_queues,
   1055                       VIRTIO_SCSI_AUTO_NUM_QUEUES),
   1056    DEFINE_PROP_UINT32("virtqueue_size", VirtIOSCSI,
   1057                                         parent_obj.conf.virtqueue_size, 256),
   1058    DEFINE_PROP_BOOL("seg_max_adjust", VirtIOSCSI,
   1059                      parent_obj.conf.seg_max_adjust, true),
   1060    DEFINE_PROP_UINT32("max_sectors", VirtIOSCSI, parent_obj.conf.max_sectors,
   1061                                                  0xFFFF),
   1062    DEFINE_PROP_UINT32("cmd_per_lun", VirtIOSCSI, parent_obj.conf.cmd_per_lun,
   1063                                                  128),
   1064    DEFINE_PROP_BIT("hotplug", VirtIOSCSI, host_features,
   1065                                           VIRTIO_SCSI_F_HOTPLUG, true),
   1066    DEFINE_PROP_BIT("param_change", VirtIOSCSI, host_features,
   1067                                                VIRTIO_SCSI_F_CHANGE, true),
   1068    DEFINE_PROP_LINK("iothread", VirtIOSCSI, parent_obj.conf.iothread,
   1069                     TYPE_IOTHREAD, IOThread *),
   1070    DEFINE_PROP_END_OF_LIST(),
   1071};
   1072
   1073static const VMStateDescription vmstate_virtio_scsi = {
   1074    .name = "virtio-scsi",
   1075    .minimum_version_id = 1,
   1076    .version_id = 1,
   1077    .fields = (VMStateField[]) {
   1078        VMSTATE_VIRTIO_DEVICE,
   1079        VMSTATE_END_OF_LIST()
   1080    },
   1081};
   1082
   1083static void virtio_scsi_common_class_init(ObjectClass *klass, void *data)
   1084{
   1085    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
   1086    DeviceClass *dc = DEVICE_CLASS(klass);
   1087
   1088    vdc->get_config = virtio_scsi_get_config;
   1089    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
   1090}
   1091
   1092static void virtio_scsi_class_init(ObjectClass *klass, void *data)
   1093{
   1094    DeviceClass *dc = DEVICE_CLASS(klass);
   1095    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
   1096    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
   1097
   1098    device_class_set_props(dc, virtio_scsi_properties);
   1099    dc->vmsd = &vmstate_virtio_scsi;
   1100    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
   1101    vdc->realize = virtio_scsi_device_realize;
   1102    vdc->unrealize = virtio_scsi_device_unrealize;
   1103    vdc->set_config = virtio_scsi_set_config;
   1104    vdc->get_features = virtio_scsi_get_features;
   1105    vdc->reset = virtio_scsi_reset;
   1106    vdc->start_ioeventfd = virtio_scsi_dataplane_start;
   1107    vdc->stop_ioeventfd = virtio_scsi_dataplane_stop;
   1108    hc->pre_plug = virtio_scsi_pre_hotplug;
   1109    hc->plug = virtio_scsi_hotplug;
   1110    hc->unplug = virtio_scsi_hotunplug;
   1111}
   1112
   1113static const TypeInfo virtio_scsi_common_info = {
   1114    .name = TYPE_VIRTIO_SCSI_COMMON,
   1115    .parent = TYPE_VIRTIO_DEVICE,
   1116    .instance_size = sizeof(VirtIOSCSICommon),
   1117    .abstract = true,
   1118    .class_init = virtio_scsi_common_class_init,
   1119};
   1120
   1121static const TypeInfo virtio_scsi_info = {
   1122    .name = TYPE_VIRTIO_SCSI,
   1123    .parent = TYPE_VIRTIO_SCSI_COMMON,
   1124    .instance_size = sizeof(VirtIOSCSI),
   1125    .class_init = virtio_scsi_class_init,
   1126    .interfaces = (InterfaceInfo[]) {
   1127        { TYPE_HOTPLUG_HANDLER },
   1128        { }
   1129    }
   1130};
   1131
   1132static void virtio_register_types(void)
   1133{
   1134    type_register_static(&virtio_scsi_common_info);
   1135    type_register_static(&virtio_scsi_info);
   1136}
   1137
   1138type_init(virtio_register_types)