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