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 "hw/virtio/virtio-scsi.h"
  17#include "qemu/error-report.h"
  18#include <hw/scsi/scsi.h>
  19#include <block/scsi.h>
  20#include <hw/virtio/virtio-bus.h>
  21
  22typedef struct VirtIOSCSIReq {
  23    VirtIOSCSI *dev;
  24    VirtQueue *vq;
  25    VirtQueueElement elem;
  26    QEMUSGList qsgl;
  27    SCSIRequest *sreq;
  28    union {
  29        char                  *buf;
  30        VirtIOSCSICmdReq      *cmd;
  31        VirtIOSCSICtrlTMFReq  *tmf;
  32        VirtIOSCSICtrlANReq   *an;
  33    } req;
  34    union {
  35        char                  *buf;
  36        VirtIOSCSICmdResp     *cmd;
  37        VirtIOSCSICtrlTMFResp *tmf;
  38        VirtIOSCSICtrlANResp  *an;
  39        VirtIOSCSIEvent       *event;
  40    } resp;
  41} VirtIOSCSIReq;
  42
  43static inline int virtio_scsi_get_lun(uint8_t *lun)
  44{
  45    return ((lun[2] << 8) | lun[3]) & 0x3FFF;
  46}
  47
  48static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun)
  49{
  50    if (lun[0] != 1) {
  51        return NULL;
  52    }
  53    if (lun[2] != 0 && !(lun[2] >= 0x40 && lun[2] < 0x80)) {
  54        return NULL;
  55    }
  56    return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun));
  57}
  58
  59static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
  60{
  61    VirtIOSCSI *s = req->dev;
  62    VirtQueue *vq = req->vq;
  63    VirtIODevice *vdev = VIRTIO_DEVICE(s);
  64    virtqueue_push(vq, &req->elem, req->qsgl.size + req->elem.in_sg[0].iov_len);
  65    qemu_sglist_destroy(&req->qsgl);
  66    if (req->sreq) {
  67        req->sreq->hba_private = NULL;
  68        scsi_req_unref(req->sreq);
  69    }
  70    g_free(req);
  71    virtio_notify(vdev, vq);
  72}
  73
  74static void virtio_scsi_bad_req(void)
  75{
  76    error_report("wrong size for virtio-scsi headers");
  77    exit(1);
  78}
  79
  80static void qemu_sgl_init_external(VirtIOSCSIReq *req, struct iovec *sg,
  81                                   hwaddr *addr, int num)
  82{
  83    QEMUSGList *qsgl = &req->qsgl;
  84
  85    qemu_sglist_init(qsgl, DEVICE(req->dev), num, &address_space_memory);
  86    while (num--) {
  87        qemu_sglist_add(qsgl, *(addr++), (sg++)->iov_len);
  88    }
  89}
  90
  91static void virtio_scsi_parse_req(VirtIOSCSI *s, VirtQueue *vq,
  92                                  VirtIOSCSIReq *req)
  93{
  94    assert(req->elem.in_num);
  95    req->vq = vq;
  96    req->dev = s;
  97    req->sreq = NULL;
  98    if (req->elem.out_num) {
  99        req->req.buf = req->elem.out_sg[0].iov_base;
 100    }
 101    req->resp.buf = req->elem.in_sg[0].iov_base;
 102
 103    if (req->elem.out_num > 1) {
 104        qemu_sgl_init_external(req, &req->elem.out_sg[1],
 105                               &req->elem.out_addr[1],
 106                               req->elem.out_num - 1);
 107    } else {
 108        qemu_sgl_init_external(req, &req->elem.in_sg[1],
 109                               &req->elem.in_addr[1],
 110                               req->elem.in_num - 1);
 111    }
 112}
 113
 114static VirtIOSCSIReq *virtio_scsi_pop_req(VirtIOSCSI *s, VirtQueue *vq)
 115{
 116    VirtIOSCSIReq *req;
 117    req = g_malloc(sizeof(*req));
 118    if (!virtqueue_pop(vq, &req->elem)) {
 119        g_free(req);
 120        return NULL;
 121    }
 122
 123    virtio_scsi_parse_req(s, vq, req);
 124    return req;
 125}
 126
 127static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq)
 128{
 129    VirtIOSCSIReq *req = sreq->hba_private;
 130    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev);
 131    uint32_t n = virtio_queue_get_id(req->vq) - 2;
 132
 133    assert(n < vs->conf.num_queues);
 134    qemu_put_be32s(f, &n);
 135    qemu_put_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
 136}
 137
 138static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
 139{
 140    SCSIBus *bus = sreq->bus;
 141    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
 142    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
 143    VirtIOSCSIReq *req;
 144    uint32_t n;
 145
 146    req = g_malloc(sizeof(*req));
 147    qemu_get_be32s(f, &n);
 148    assert(n < vs->conf.num_queues);
 149    qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
 150    virtio_scsi_parse_req(s, vs->cmd_vqs[n], req);
 151
 152    scsi_req_ref(sreq);
 153    req->sreq = sreq;
 154    if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
 155        int req_mode =
 156            (req->elem.in_num > 1 ? SCSI_XFER_FROM_DEV : SCSI_XFER_TO_DEV);
 157
 158        assert(req->sreq->cmd.mode == req_mode);
 159    }
 160    return req;
 161}
 162
 163static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
 164{
 165    SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf->lun);
 166    SCSIRequest *r, *next;
 167    BusChild *kid;
 168    int target;
 169
 170    /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE".  */
 171    req->resp.tmf->response = VIRTIO_SCSI_S_OK;
 172
 173    switch (req->req.tmf->subtype) {
 174    case VIRTIO_SCSI_T_TMF_ABORT_TASK:
 175    case VIRTIO_SCSI_T_TMF_QUERY_TASK:
 176        if (!d) {
 177            goto fail;
 178        }
 179        if (d->lun != virtio_scsi_get_lun(req->req.tmf->lun)) {
 180            goto incorrect_lun;
 181        }
 182        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
 183            VirtIOSCSIReq *cmd_req = r->hba_private;
 184            if (cmd_req && cmd_req->req.cmd->tag == req->req.tmf->tag) {
 185                break;
 186            }
 187        }
 188        if (r) {
 189            /*
 190             * Assert that the request has not been completed yet, we
 191             * check for it in the loop above.
 192             */
 193            assert(r->hba_private);
 194            if (req->req.tmf->subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK) {
 195                /* "If the specified command is present in the task set, then
 196                 * return a service response set to FUNCTION SUCCEEDED".
 197                 */
 198                req->resp.tmf->response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
 199            } else {
 200                scsi_req_cancel(r);
 201            }
 202        }
 203        break;
 204
 205    case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
 206        if (!d) {
 207            goto fail;
 208        }
 209        if (d->lun != virtio_scsi_get_lun(req->req.tmf->lun)) {
 210            goto incorrect_lun;
 211        }
 212        s->resetting++;
 213        qdev_reset_all(&d->qdev);
 214        s->resetting--;
 215        break;
 216
 217    case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET:
 218    case VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET:
 219    case VIRTIO_SCSI_T_TMF_QUERY_TASK_SET:
 220        if (!d) {
 221            goto fail;
 222        }
 223        if (d->lun != virtio_scsi_get_lun(req->req.tmf->lun)) {
 224            goto incorrect_lun;
 225        }
 226        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
 227            if (r->hba_private) {
 228                if (req->req.tmf->subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK_SET) {
 229                    /* "If there is any command present in the task set, then
 230                     * return a service response set to FUNCTION SUCCEEDED".
 231                     */
 232                    req->resp.tmf->response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
 233                    break;
 234                } else {
 235                    scsi_req_cancel(r);
 236                }
 237            }
 238        }
 239        break;
 240
 241    case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
 242        target = req->req.tmf->lun[1];
 243        s->resetting++;
 244        QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
 245             d = DO_UPCAST(SCSIDevice, qdev, kid->child);
 246             if (d->channel == 0 && d->id == target) {
 247                qdev_reset_all(&d->qdev);
 248             }
 249        }
 250        s->resetting--;
 251        break;
 252
 253    case VIRTIO_SCSI_T_TMF_CLEAR_ACA:
 254    default:
 255        req->resp.tmf->response = VIRTIO_SCSI_S_FUNCTION_REJECTED;
 256        break;
 257    }
 258
 259    return;
 260
 261incorrect_lun:
 262    req->resp.tmf->response = VIRTIO_SCSI_S_INCORRECT_LUN;
 263    return;
 264
 265fail:
 266    req->resp.tmf->response = VIRTIO_SCSI_S_BAD_TARGET;
 267}
 268
 269static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
 270{
 271    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
 272    VirtIOSCSIReq *req;
 273
 274    while ((req = virtio_scsi_pop_req(s, vq))) {
 275        int out_size, in_size;
 276        if (req->elem.out_num < 1 || req->elem.in_num < 1) {
 277            virtio_scsi_bad_req();
 278            continue;
 279        }
 280
 281        out_size = req->elem.out_sg[0].iov_len;
 282        in_size = req->elem.in_sg[0].iov_len;
 283        if (req->req.tmf->type == VIRTIO_SCSI_T_TMF) {
 284            if (out_size < sizeof(VirtIOSCSICtrlTMFReq) ||
 285                in_size < sizeof(VirtIOSCSICtrlTMFResp)) {
 286                virtio_scsi_bad_req();
 287            }
 288            virtio_scsi_do_tmf(s, req);
 289
 290        } else if (req->req.tmf->type == VIRTIO_SCSI_T_AN_QUERY ||
 291                   req->req.tmf->type == VIRTIO_SCSI_T_AN_SUBSCRIBE) {
 292            if (out_size < sizeof(VirtIOSCSICtrlANReq) ||
 293                in_size < sizeof(VirtIOSCSICtrlANResp)) {
 294                virtio_scsi_bad_req();
 295            }
 296            req->resp.an->event_actual = 0;
 297            req->resp.an->response = VIRTIO_SCSI_S_OK;
 298        }
 299        virtio_scsi_complete_req(req);
 300    }
 301}
 302
 303static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
 304                                         size_t resid)
 305{
 306    VirtIOSCSIReq *req = r->hba_private;
 307    uint32_t sense_len;
 308
 309    req->resp.cmd->response = VIRTIO_SCSI_S_OK;
 310    req->resp.cmd->status = status;
 311    if (req->resp.cmd->status == GOOD) {
 312        req->resp.cmd->resid = tswap32(resid);
 313    } else {
 314        req->resp.cmd->resid = 0;
 315        sense_len = scsi_req_get_sense(r, req->resp.cmd->sense,
 316                                       VIRTIO_SCSI_SENSE_SIZE);
 317        req->resp.cmd->sense_len = tswap32(sense_len);
 318    }
 319    virtio_scsi_complete_req(req);
 320}
 321
 322static QEMUSGList *virtio_scsi_get_sg_list(SCSIRequest *r)
 323{
 324    VirtIOSCSIReq *req = r->hba_private;
 325
 326    return &req->qsgl;
 327}
 328
 329static void virtio_scsi_request_cancelled(SCSIRequest *r)
 330{
 331    VirtIOSCSIReq *req = r->hba_private;
 332
 333    if (!req) {
 334        return;
 335    }
 336    if (req->dev->resetting) {
 337        req->resp.cmd->response = VIRTIO_SCSI_S_RESET;
 338    } else {
 339        req->resp.cmd->response = VIRTIO_SCSI_S_ABORTED;
 340    }
 341    virtio_scsi_complete_req(req);
 342}
 343
 344static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
 345{
 346    req->resp.cmd->response = VIRTIO_SCSI_S_FAILURE;
 347    virtio_scsi_complete_req(req);
 348}
 349
 350static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
 351{
 352    /* use non-QOM casts in the data path */
 353    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
 354    VirtIOSCSICommon *vs = &s->parent_obj;
 355
 356    VirtIOSCSIReq *req;
 357    int n;
 358
 359    while ((req = virtio_scsi_pop_req(s, vq))) {
 360        SCSIDevice *d;
 361        int out_size, in_size;
 362        if (req->elem.out_num < 1 || req->elem.in_num < 1) {
 363            virtio_scsi_bad_req();
 364        }
 365
 366        out_size = req->elem.out_sg[0].iov_len;
 367        in_size = req->elem.in_sg[0].iov_len;
 368        if (out_size < sizeof(VirtIOSCSICmdReq) + vs->cdb_size ||
 369            in_size < sizeof(VirtIOSCSICmdResp) + vs->sense_size) {
 370            virtio_scsi_bad_req();
 371        }
 372
 373        if (req->elem.out_num > 1 && req->elem.in_num > 1) {
 374            virtio_scsi_fail_cmd_req(req);
 375            continue;
 376        }
 377
 378        d = virtio_scsi_device_find(s, req->req.cmd->lun);
 379        if (!d) {
 380            req->resp.cmd->response = VIRTIO_SCSI_S_BAD_TARGET;
 381            virtio_scsi_complete_req(req);
 382            continue;
 383        }
 384        req->sreq = scsi_req_new(d, req->req.cmd->tag,
 385                                 virtio_scsi_get_lun(req->req.cmd->lun),
 386                                 req->req.cmd->cdb, req);
 387
 388        if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
 389            int req_mode =
 390                (req->elem.in_num > 1 ? SCSI_XFER_FROM_DEV : SCSI_XFER_TO_DEV);
 391
 392            if (req->sreq->cmd.mode != req_mode ||
 393                req->sreq->cmd.xfer > req->qsgl.size) {
 394                req->resp.cmd->response = VIRTIO_SCSI_S_OVERRUN;
 395                virtio_scsi_complete_req(req);
 396                continue;
 397            }
 398        }
 399
 400        n = scsi_req_enqueue(req->sreq);
 401        if (n) {
 402            scsi_req_continue(req->sreq);
 403        }
 404    }
 405}
 406
 407static void virtio_scsi_get_config(VirtIODevice *vdev,
 408                                   uint8_t *config)
 409{
 410    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
 411    VirtIOSCSICommon *s = VIRTIO_SCSI_COMMON(vdev);
 412
 413    stl_raw(&scsiconf->num_queues, s->conf.num_queues);
 414    stl_raw(&scsiconf->seg_max, 128 - 2);
 415    stl_raw(&scsiconf->max_sectors, s->conf.max_sectors);
 416    stl_raw(&scsiconf->cmd_per_lun, s->conf.cmd_per_lun);
 417    stl_raw(&scsiconf->event_info_size, sizeof(VirtIOSCSIEvent));
 418    stl_raw(&scsiconf->sense_size, s->sense_size);
 419    stl_raw(&scsiconf->cdb_size, s->cdb_size);
 420    stw_raw(&scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL);
 421    stw_raw(&scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET);
 422    stl_raw(&scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN);
 423}
 424
 425static void virtio_scsi_set_config(VirtIODevice *vdev,
 426                                   const uint8_t *config)
 427{
 428    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
 429    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
 430
 431    if ((uint32_t) ldl_raw(&scsiconf->sense_size) >= 65536 ||
 432        (uint32_t) ldl_raw(&scsiconf->cdb_size) >= 256) {
 433        error_report("bad data written to virtio-scsi configuration space");
 434        exit(1);
 435    }
 436
 437    vs->sense_size = ldl_raw(&scsiconf->sense_size);
 438    vs->cdb_size = ldl_raw(&scsiconf->cdb_size);
 439}
 440
 441static uint32_t virtio_scsi_get_features(VirtIODevice *vdev,
 442                                         uint32_t requested_features)
 443{
 444    return requested_features;
 445}
 446
 447static void virtio_scsi_reset(VirtIODevice *vdev)
 448{
 449    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
 450    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
 451
 452    s->resetting++;
 453    qbus_reset_all(&s->bus.qbus);
 454    s->resetting--;
 455
 456    vs->sense_size = VIRTIO_SCSI_SENSE_SIZE;
 457    vs->cdb_size = VIRTIO_SCSI_CDB_SIZE;
 458    s->events_dropped = false;
 459}
 460
 461/* The device does not have anything to save beyond the virtio data.
 462 * Request data is saved with callbacks from SCSI devices.
 463 */
 464static void virtio_scsi_save(QEMUFile *f, void *opaque)
 465{
 466    VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
 467    virtio_save(vdev, f);
 468}
 469
 470static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id)
 471{
 472    VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
 473    int ret;
 474
 475    ret = virtio_load(vdev, f);
 476    if (ret) {
 477        return ret;
 478    }
 479    return 0;
 480}
 481
 482static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
 483                                   uint32_t event, uint32_t reason)
 484{
 485    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
 486    VirtIOSCSIReq *req = virtio_scsi_pop_req(s, vs->event_vq);
 487    VirtIOSCSIEvent *evt;
 488    VirtIODevice *vdev = VIRTIO_DEVICE(s);
 489    int in_size;
 490
 491    if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
 492        return;
 493    }
 494
 495    if (!req) {
 496        s->events_dropped = true;
 497        return;
 498    }
 499
 500    if (req->elem.out_num || req->elem.in_num != 1) {
 501        virtio_scsi_bad_req();
 502    }
 503
 504    if (s->events_dropped) {
 505        event |= VIRTIO_SCSI_T_EVENTS_MISSED;
 506        s->events_dropped = false;
 507    }
 508
 509    in_size = req->elem.in_sg[0].iov_len;
 510    if (in_size < sizeof(VirtIOSCSIEvent)) {
 511        virtio_scsi_bad_req();
 512    }
 513
 514    evt = req->resp.event;
 515    memset(evt, 0, sizeof(VirtIOSCSIEvent));
 516    evt->event = event;
 517    evt->reason = reason;
 518    if (!dev) {
 519        assert(event == VIRTIO_SCSI_T_NO_EVENT);
 520    } else {
 521        evt->lun[0] = 1;
 522        evt->lun[1] = dev->id;
 523
 524        /* Linux wants us to keep the same encoding we use for REPORT LUNS.  */
 525        if (dev->lun >= 256) {
 526            evt->lun[2] = (dev->lun >> 8) | 0x40;
 527        }
 528        evt->lun[3] = dev->lun & 0xFF;
 529    }
 530    virtio_scsi_complete_req(req);
 531}
 532
 533static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
 534{
 535    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
 536
 537    if (s->events_dropped) {
 538        virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
 539    }
 540}
 541
 542static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
 543{
 544    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
 545    VirtIODevice *vdev = VIRTIO_DEVICE(s);
 546
 547    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
 548        dev->type != TYPE_ROM) {
 549        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
 550                               sense.asc | (sense.ascq << 8));
 551    }
 552}
 553
 554static void virtio_scsi_hotplug(SCSIBus *bus, SCSIDevice *dev)
 555{
 556    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
 557    VirtIODevice *vdev = VIRTIO_DEVICE(s);
 558
 559    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
 560        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET,
 561                               VIRTIO_SCSI_EVT_RESET_RESCAN);
 562    }
 563}
 564
 565static void virtio_scsi_hot_unplug(SCSIBus *bus, SCSIDevice *dev)
 566{
 567    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
 568    VirtIODevice *vdev = VIRTIO_DEVICE(s);
 569
 570    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
 571        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET,
 572                               VIRTIO_SCSI_EVT_RESET_REMOVED);
 573    }
 574}
 575
 576static struct SCSIBusInfo virtio_scsi_scsi_info = {
 577    .tcq = true,
 578    .max_channel = VIRTIO_SCSI_MAX_CHANNEL,
 579    .max_target = VIRTIO_SCSI_MAX_TARGET,
 580    .max_lun = VIRTIO_SCSI_MAX_LUN,
 581
 582    .complete = virtio_scsi_command_complete,
 583    .cancel = virtio_scsi_request_cancelled,
 584    .change = virtio_scsi_change,
 585    .hotplug = virtio_scsi_hotplug,
 586    .hot_unplug = virtio_scsi_hot_unplug,
 587    .get_sg_list = virtio_scsi_get_sg_list,
 588    .save_request = virtio_scsi_save_request,
 589    .load_request = virtio_scsi_load_request,
 590};
 591
 592int virtio_scsi_common_init(VirtIOSCSICommon *s)
 593{
 594    VirtIODevice *vdev = VIRTIO_DEVICE(s);
 595    int i;
 596
 597    virtio_init(VIRTIO_DEVICE(s), "virtio-scsi", VIRTIO_ID_SCSI,
 598                sizeof(VirtIOSCSIConfig));
 599
 600    s->cmd_vqs = g_malloc0(s->conf.num_queues * sizeof(VirtQueue *));
 601    s->sense_size = VIRTIO_SCSI_SENSE_SIZE;
 602    s->cdb_size = VIRTIO_SCSI_CDB_SIZE;
 603
 604    s->ctrl_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
 605                                  virtio_scsi_handle_ctrl);
 606    s->event_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
 607                                   virtio_scsi_handle_event);
 608    for (i = 0; i < s->conf.num_queues; i++) {
 609        s->cmd_vqs[i] = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
 610                                         virtio_scsi_handle_cmd);
 611    }
 612
 613    return 0;
 614}
 615
 616static int virtio_scsi_device_init(VirtIODevice *vdev)
 617{
 618    DeviceState *qdev = DEVICE(vdev);
 619    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
 620    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
 621    static int virtio_scsi_id;
 622    Error *err = NULL;
 623    int ret;
 624
 625    ret = virtio_scsi_common_init(vs);
 626    if (ret < 0) {
 627        return ret;
 628    }
 629
 630    scsi_bus_new(&s->bus, qdev, &virtio_scsi_scsi_info, vdev->bus_name);
 631
 632    if (!qdev->hotplugged) {
 633        scsi_bus_legacy_handle_cmdline(&s->bus, &err);
 634        if (err != NULL) {
 635            error_free(err);
 636            return -1;
 637        }
 638    }
 639
 640    register_savevm(qdev, "virtio-scsi", virtio_scsi_id++, 1,
 641                    virtio_scsi_save, virtio_scsi_load, s);
 642
 643    return 0;
 644}
 645
 646int virtio_scsi_common_exit(VirtIOSCSICommon *vs)
 647{
 648    VirtIODevice *vdev = VIRTIO_DEVICE(vs);
 649
 650    g_free(vs->cmd_vqs);
 651    virtio_cleanup(vdev);
 652    return 0;
 653}
 654
 655static int virtio_scsi_device_exit(DeviceState *qdev)
 656{
 657    VirtIOSCSI *s = VIRTIO_SCSI(qdev);
 658    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev);
 659
 660    unregister_savevm(qdev, "virtio-scsi", s);
 661    return virtio_scsi_common_exit(vs);
 662}
 663
 664static Property virtio_scsi_properties[] = {
 665    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSI, parent_obj.conf),
 666    DEFINE_PROP_END_OF_LIST(),
 667};
 668
 669static void virtio_scsi_common_class_init(ObjectClass *klass, void *data)
 670{
 671    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
 672    DeviceClass *dc = DEVICE_CLASS(klass);
 673
 674    vdc->get_config = virtio_scsi_get_config;
 675    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 676}
 677
 678static void virtio_scsi_class_init(ObjectClass *klass, void *data)
 679{
 680    DeviceClass *dc = DEVICE_CLASS(klass);
 681    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
 682    dc->exit = virtio_scsi_device_exit;
 683    dc->props = virtio_scsi_properties;
 684    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 685    vdc->init = virtio_scsi_device_init;
 686    vdc->set_config = virtio_scsi_set_config;
 687    vdc->get_features = virtio_scsi_get_features;
 688    vdc->reset = virtio_scsi_reset;
 689}
 690
 691static const TypeInfo virtio_scsi_common_info = {
 692    .name = TYPE_VIRTIO_SCSI_COMMON,
 693    .parent = TYPE_VIRTIO_DEVICE,
 694    .instance_size = sizeof(VirtIOSCSICommon),
 695    .class_init = virtio_scsi_common_class_init,
 696};
 697
 698static const TypeInfo virtio_scsi_info = {
 699    .name = TYPE_VIRTIO_SCSI,
 700    .parent = TYPE_VIRTIO_SCSI_COMMON,
 701    .instance_size = sizeof(VirtIOSCSI),
 702    .class_init = virtio_scsi_class_init,
 703};
 704
 705static void virtio_register_types(void)
 706{
 707    type_register_static(&virtio_scsi_common_info);
 708    type_register_static(&virtio_scsi_info);
 709}
 710
 711type_init(virtio_register_types)
 712