virtio-scsi.c 24.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Virtio SCSI HBA
 *
 * Copyright IBM, Corp. 2010
 * Copyright Red Hat, Inc. 2011
 *
 * Authors:
 *   Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com>
 *   Paolo Bonzini      <pbonzini@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

P
Paolo Bonzini 已提交
16
#include "hw/virtio/virtio-scsi.h"
17
#include "qemu/error-report.h"
18
#include "qemu/iov.h"
P
Paolo Bonzini 已提交
19 20 21
#include <hw/scsi/scsi.h>
#include <block/scsi.h>
#include <hw/virtio/virtio-bus.h>
22
#include "hw/virtio/virtio-access.h"
23

24 25 26 27
typedef struct VirtIOSCSIReq {
    VirtIOSCSI *dev;
    VirtQueue *vq;
    QEMUSGList qsgl;
28 29 30 31 32 33 34 35 36
    QEMUIOVector resp_iov;

    /* Note:
     * - fields before elem are initialized by virtio_scsi_init_req;
     * - elem is uninitialized at the time of allocation.
     * - fields after elem are zeroed by virtio_scsi_init_req.
     * */

    VirtQueueElement elem;
37
    SCSIRequest *sreq;
38
    size_t resp_size;
39
    enum SCSIXferMode mode;
40
    union {
41 42 43 44
        VirtIOSCSICmdResp     cmd;
        VirtIOSCSICtrlTMFResp tmf;
        VirtIOSCSICtrlANResp  an;
        VirtIOSCSIEvent       event;
45
    } resp;
46
    union {
47 48 49 50 51 52
        struct {
            VirtIOSCSICmdReq  cmd;
            uint8_t           cdb[];
        } QEMU_PACKED;
        VirtIOSCSICtrlTMFReq  tmf;
        VirtIOSCSICtrlANReq   an;
53
    } req;
54 55
} VirtIOSCSIReq;

56 57 58
QEMU_BUILD_BUG_ON(offsetof(VirtIOSCSIReq, req.cdb) !=
                  offsetof(VirtIOSCSIReq, req.cmd) + sizeof(VirtIOSCSICmdReq));

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
static inline int virtio_scsi_get_lun(uint8_t *lun)
{
    return ((lun[2] << 8) | lun[3]) & 0x3FFF;
}

static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun)
{
    if (lun[0] != 1) {
        return NULL;
    }
    if (lun[2] != 0 && !(lun[2] >= 0x40 && lun[2] < 0x80)) {
        return NULL;
    }
    return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun));
}

75 76 77
static VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)
{
    VirtIOSCSIReq *req;
78 79 80
    VirtIOSCSICommon *vs = (VirtIOSCSICommon *)s;
    const size_t zero_skip = offsetof(VirtIOSCSIReq, elem)
                             + sizeof(VirtQueueElement);
81

82
    req = g_slice_alloc(sizeof(*req) + vs->cdb_size);
83 84 85
    req->vq = vq;
    req->dev = s;
    qemu_sglist_init(&req->qsgl, DEVICE(s), 8, &address_space_memory);
86
    qemu_iovec_init(&req->resp_iov, 1);
87
    memset((uint8_t *)req + zero_skip, 0, sizeof(*req) - zero_skip);
88 89 90 91 92
    return req;
}

static void virtio_scsi_free_req(VirtIOSCSIReq *req)
{
93 94
    VirtIOSCSICommon *vs = (VirtIOSCSICommon *)req->dev;

95
    qemu_iovec_destroy(&req->resp_iov);
96
    qemu_sglist_destroy(&req->qsgl);
97
    g_slice_free1(sizeof(*req) + vs->cdb_size, req);
98 99
}

100 101 102 103
static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
{
    VirtIOSCSI *s = req->dev;
    VirtQueue *vq = req->vq;
104
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
105 106 107

    qemu_iovec_from_buf(&req->resp_iov, 0, &req->resp, req->resp_size);
    virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size);
108 109 110 111
    if (req->sreq) {
        req->sreq->hba_private = NULL;
        scsi_req_unref(req->sreq);
    }
112
    virtio_scsi_free_req(req);
113
    virtio_notify(vdev, vq);
114 115 116 117 118 119 120 121
}

static void virtio_scsi_bad_req(void)
{
    error_report("wrong size for virtio-scsi headers");
    exit(1);
}

122 123
static size_t qemu_sgl_concat(VirtIOSCSIReq *req, struct iovec *iov,
                              hwaddr *addr, int num, size_t skip)
124
{
125
    QEMUSGList *qsgl = &req->qsgl;
126 127 128 129 130 131 132 133 134 135 136 137 138
    size_t copied = 0;

    while (num) {
        if (skip >= iov->iov_len) {
            skip -= iov->iov_len;
        } else {
            qemu_sglist_add(qsgl, *addr + skip, iov->iov_len - skip);
            copied += iov->iov_len - skip;
            skip = 0;
        }
        iov++;
        addr++;
        num--;
139
    }
140 141 142

    assert(skip == 0);
    return copied;
143 144
}

145 146
static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
                                 unsigned req_size, unsigned resp_size)
147
{
148
    size_t in_size, out_size;
149

150 151
    if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,
                   &req->req, req_size) < req_size) {
152 153 154
        return -EINVAL;
    }

155 156 157
    if (qemu_iovec_concat_iov(&req->resp_iov,
                              req->elem.in_sg, req->elem.in_num, 0,
                              resp_size) < resp_size) {
158 159
        return -EINVAL;
    }
160
    req->resp_size = resp_size;
161

162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
    out_size = qemu_sgl_concat(req, req->elem.out_sg,
                               &req->elem.out_addr[0], req->elem.out_num,
                               req_size);
    in_size = qemu_sgl_concat(req, req->elem.in_sg,
                              &req->elem.in_addr[0], req->elem.in_num,
                              resp_size);

    if (out_size && in_size) {
        return -ENOTSUP;
    }

    if (out_size) {
        req->mode = SCSI_XFER_TO_DEV;
    } else if (in_size) {
        req->mode = SCSI_XFER_FROM_DEV;
177
    }
178 179

    return 0;
180 181 182 183
}

static VirtIOSCSIReq *virtio_scsi_pop_req(VirtIOSCSI *s, VirtQueue *vq)
{
184
    VirtIOSCSIReq *req = virtio_scsi_init_req(s, vq);
185
    if (!virtqueue_pop(vq, &req->elem)) {
186
        virtio_scsi_free_req(req);
187 188 189 190 191
        return NULL;
    }
    return req;
}

192 193 194
static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq)
{
    VirtIOSCSIReq *req = sreq->hba_private;
195
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev);
196
    uint32_t n = virtio_queue_get_id(req->vq) - 2;
197

198
    assert(n < vs->conf.num_queues);
199
    qemu_put_be32s(f, &n);
200 201 202 203 204 205 206
    qemu_put_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
}

static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
{
    SCSIBus *bus = sreq->bus;
    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
207
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
208
    VirtIOSCSIReq *req;
209
    uint32_t n;
210

211
    qemu_get_be32s(f, &n);
212
    assert(n < vs->conf.num_queues);
213
    req = virtio_scsi_init_req(s, vs->cmd_vqs[n]);
214
    qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
215 216 217 218 219 220 221 222 223
    /* TODO: add a way for SCSIBusInfo's load_request to fail,
     * and fail migration instead of asserting here.
     * When we do, we might be able to re-enable NDEBUG below.
     */
#ifdef NDEBUG
#error building with NDEBUG is not supported
#endif
    assert(req->elem.in_num <= ARRAY_SIZE(req->elem.in_sg));
    assert(req->elem.out_num <= ARRAY_SIZE(req->elem.out_sg));
224 225 226 227 228 229

    if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
                              sizeof(VirtIOSCSICmdResp) + vs->sense_size) < 0) {
        error_report("invalid SCSI request migration data");
        exit(1);
    }
230 231 232 233

    scsi_req_ref(sreq);
    req->sreq = sreq;
    if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
234
        assert(req->sreq->cmd.mode == req->mode);
235 236 237 238
    }
    return req;
}

239
static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
240
{
241
    SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf.lun);
242
    SCSIRequest *r, *next;
A
Anthony Liguori 已提交
243
    BusChild *kid;
244 245 246
    int target;

    /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE".  */
247
    req->resp.tmf.response = VIRTIO_SCSI_S_OK;
248

249
    virtio_tswap32s(VIRTIO_DEVICE(s), &req->req.tmf.subtype);
250
    switch (req->req.tmf.subtype) {
251 252 253 254 255
    case VIRTIO_SCSI_T_TMF_ABORT_TASK:
    case VIRTIO_SCSI_T_TMF_QUERY_TASK:
        if (!d) {
            goto fail;
        }
256
        if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
257 258 259
            goto incorrect_lun;
        }
        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
260
            VirtIOSCSIReq *cmd_req = r->hba_private;
261
            if (cmd_req && cmd_req->req.cmd.tag == req->req.tmf.tag) {
262 263 264
                break;
            }
        }
265 266 267 268 269 270
        if (r) {
            /*
             * Assert that the request has not been completed yet, we
             * check for it in the loop above.
             */
            assert(r->hba_private);
271
            if (req->req.tmf.subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK) {
272 273 274
                /* "If the specified command is present in the task set, then
                 * return a service response set to FUNCTION SUCCEEDED".
                 */
275
                req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
276 277 278 279 280 281 282 283 284 285
            } else {
                scsi_req_cancel(r);
            }
        }
        break;

    case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
        if (!d) {
            goto fail;
        }
286
        if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
287 288 289 290 291 292 293 294 295 296 297 298 299
            goto incorrect_lun;
        }
        s->resetting++;
        qdev_reset_all(&d->qdev);
        s->resetting--;
        break;

    case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET:
    case VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET:
    case VIRTIO_SCSI_T_TMF_QUERY_TASK_SET:
        if (!d) {
            goto fail;
        }
300
        if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
301 302 303 304
            goto incorrect_lun;
        }
        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
            if (r->hba_private) {
305
                if (req->req.tmf.subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK_SET) {
306 307 308
                    /* "If there is any command present in the task set, then
                     * return a service response set to FUNCTION SUCCEEDED".
                     */
309
                    req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
310 311 312 313 314 315 316 317 318
                    break;
                } else {
                    scsi_req_cancel(r);
                }
            }
        }
        break;

    case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
319
        target = req->req.tmf.lun[1];
320
        s->resetting++;
A
Anthony Liguori 已提交
321 322
        QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
             d = DO_UPCAST(SCSIDevice, qdev, kid->child);
323 324 325 326 327 328 329 330 331
             if (d->channel == 0 && d->id == target) {
                qdev_reset_all(&d->qdev);
             }
        }
        s->resetting--;
        break;

    case VIRTIO_SCSI_T_TMF_CLEAR_ACA:
    default:
332
        req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_REJECTED;
333
        break;
334 335
    }

336 337 338
    return;

incorrect_lun:
339
    req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN;
340 341 342
    return;

fail:
343
    req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET;
344 345
}

346 347
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
{
348 349 350 351
    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
    VirtIOSCSIReq *req;

    while ((req = virtio_scsi_pop_req(s, vq))) {
352 353 354 355
        int type;

        if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,
                       &type, sizeof(type)) < sizeof(type)) {
356
            virtio_scsi_bad_req();
357 358
            continue;
        }
359

360
        virtio_tswap32s(vdev, &req->req.tmf.type);
361
        if (req->req.tmf.type == VIRTIO_SCSI_T_TMF) {
362 363
            if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlTMFReq),
                                      sizeof(VirtIOSCSICtrlTMFResp)) < 0) {
364
                virtio_scsi_bad_req();
365 366
            } else {
                virtio_scsi_do_tmf(s, req);
367 368
            }

369 370
        } else if (req->req.tmf.type == VIRTIO_SCSI_T_AN_QUERY ||
                   req->req.tmf.type == VIRTIO_SCSI_T_AN_SUBSCRIBE) {
371 372
            if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlANReq),
                                      sizeof(VirtIOSCSICtrlANResp)) < 0) {
373
                virtio_scsi_bad_req();
374
            } else {
375 376
                req->resp.an.event_actual = 0;
                req->resp.an.response = VIRTIO_SCSI_S_OK;
377 378 379
            }
        }
        virtio_scsi_complete_req(req);
380 381 382
    }
}

383 384
static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req)
{
385 386 387 388
    /* Sense data is not in req->resp and is copied separately
     * in virtio_scsi_command_complete.
     */
    req->resp_size = sizeof(VirtIOSCSICmdResp);
389 390 391
    virtio_scsi_complete_req(req);
}

392 393 394 395
static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
                                         size_t resid)
{
    VirtIOSCSIReq *req = r->hba_private;
396
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
397
    uint32_t sense_len;
398
    VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);
399

400 401 402 403
    if (r->io_canceled) {
        return;
    }

404 405 406
    req->resp.cmd.response = VIRTIO_SCSI_S_OK;
    req->resp.cmd.status = status;
    if (req->resp.cmd.status == GOOD) {
407
        req->resp.cmd.resid = virtio_tswap32(vdev, resid);
408
    } else {
409
        req->resp.cmd.resid = 0;
410
        sense_len = scsi_req_get_sense(r, sense, sizeof(sense));
411 412 413
        sense_len = MIN(sense_len, req->resp_iov.size - sizeof(req->resp.cmd));
        qemu_iovec_from_buf(&req->resp_iov, sizeof(req->resp.cmd),
                            &req->resp, sense_len);
414
        req->resp.cmd.sense_len = virtio_tswap32(vdev, sense_len);
415
    }
416
    virtio_scsi_complete_cmd_req(req);
417 418
}

P
Paolo Bonzini 已提交
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
static int virtio_scsi_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
                                 uint8_t *buf, void *hba_private)
{
    VirtIOSCSIReq *req = hba_private;

    if (cmd->len == 0) {
        cmd->len = MIN(VIRTIO_SCSI_CDB_SIZE, SCSI_CMD_BUF_SIZE);
        memcpy(cmd->buf, buf, cmd->len);
    }

    /* Extract the direction and mode directly from the request, for
     * host device passthrough.
     */
    cmd->xfer = req->qsgl.size;
    if (cmd->xfer == 0) {
        cmd->mode = SCSI_XFER_NONE;
    } else if (iov_size(req->elem.in_sg, req->elem.in_num) > req->resp_size) {
        cmd->mode = SCSI_XFER_FROM_DEV;
    } else {
        cmd->mode = SCSI_XFER_TO_DEV;
    }
    return 0;
}

443 444 445 446 447 448 449 450 451 452 453 454 455 456
static QEMUSGList *virtio_scsi_get_sg_list(SCSIRequest *r)
{
    VirtIOSCSIReq *req = r->hba_private;

    return &req->qsgl;
}

static void virtio_scsi_request_cancelled(SCSIRequest *r)
{
    VirtIOSCSIReq *req = r->hba_private;

    if (!req) {
        return;
    }
457
    if (req->dev->resetting) {
458
        req->resp.cmd.response = VIRTIO_SCSI_S_RESET;
459
    } else {
460
        req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED;
461
    }
462
    virtio_scsi_complete_cmd_req(req);
463 464 465
}

static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
466
{
467
    req->resp.cmd.response = VIRTIO_SCSI_S_FAILURE;
468
    virtio_scsi_complete_cmd_req(req);
469 470 471 472
}

static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
{
473
    /* use non-QOM casts in the data path */
474
    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
475 476
    VirtIOSCSICommon *vs = &s->parent_obj;

477
    VirtIOSCSIReq *req;
478
    int n;
479 480

    while ((req = virtio_scsi_pop_req(s, vq))) {
481
        SCSIDevice *d;
482
        int rc;
483

484 485 486
        rc = virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
                                   sizeof(VirtIOSCSICmdResp) + vs->sense_size);
        if (rc < 0) {
487 488 489 490 491 492
            if (rc == -ENOTSUP) {
                virtio_scsi_fail_cmd_req(req);
            } else {
                virtio_scsi_bad_req();
            }
            continue;
493 494
        }

495
        d = virtio_scsi_device_find(s, req->req.cmd.lun);
496
        if (!d) {
497
            req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET;
498
            virtio_scsi_complete_cmd_req(req);
499 500
            continue;
        }
501 502 503 504 505 506 507 508 509 510
        req->sreq = scsi_req_new(d, req->req.cmd.tag,
                                 virtio_scsi_get_lun(req->req.cmd.lun),
                                 req->req.cdb, req);

        if (req->sreq->cmd.mode != SCSI_XFER_NONE
            && (req->sreq->cmd.mode != req->mode ||
                req->sreq->cmd.xfer > req->qsgl.size)) {
            req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN;
            virtio_scsi_complete_cmd_req(req);
            continue;
511 512 513 514 515 516
        }

        n = scsi_req_enqueue(req->sreq);
        if (n) {
            scsi_req_continue(req->sreq);
        }
517
    }
518 519 520 521 522 523
}

static void virtio_scsi_get_config(VirtIODevice *vdev,
                                   uint8_t *config)
{
    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
524
    VirtIOSCSICommon *s = VIRTIO_SCSI_COMMON(vdev);
525

526 527 528 529 530 531 532 533 534 535
    virtio_stl_p(vdev, &scsiconf->num_queues, s->conf.num_queues);
    virtio_stl_p(vdev, &scsiconf->seg_max, 128 - 2);
    virtio_stl_p(vdev, &scsiconf->max_sectors, s->conf.max_sectors);
    virtio_stl_p(vdev, &scsiconf->cmd_per_lun, s->conf.cmd_per_lun);
    virtio_stl_p(vdev, &scsiconf->event_info_size, sizeof(VirtIOSCSIEvent));
    virtio_stl_p(vdev, &scsiconf->sense_size, s->sense_size);
    virtio_stl_p(vdev, &scsiconf->cdb_size, s->cdb_size);
    virtio_stw_p(vdev, &scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL);
    virtio_stw_p(vdev, &scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET);
    virtio_stl_p(vdev, &scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN);
536 537 538 539 540 541
}

static void virtio_scsi_set_config(VirtIODevice *vdev,
                                   const uint8_t *config)
{
    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
542
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
543

544 545
    if ((uint32_t) virtio_ldl_p(vdev, &scsiconf->sense_size) >= 65536 ||
        (uint32_t) virtio_ldl_p(vdev, &scsiconf->cdb_size) >= 256) {
546 547 548 549
        error_report("bad data written to virtio-scsi configuration space");
        exit(1);
    }

550 551
    vs->sense_size = virtio_ldl_p(vdev, &scsiconf->sense_size);
    vs->cdb_size = virtio_ldl_p(vdev, &scsiconf->cdb_size);
552 553 554 555 556 557 558 559 560 561
}

static uint32_t virtio_scsi_get_features(VirtIODevice *vdev,
                                         uint32_t requested_features)
{
    return requested_features;
}

static void virtio_scsi_reset(VirtIODevice *vdev)
{
562 563
    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
564

565 566 567 568
    s->resetting++;
    qbus_reset_all(&s->bus.qbus);
    s->resetting--;

569 570
    vs->sense_size = VIRTIO_SCSI_SENSE_SIZE;
    vs->cdb_size = VIRTIO_SCSI_CDB_SIZE;
571
    s->events_dropped = false;
572 573
}

574 575 576 577 578
/* The device does not have anything to save beyond the virtio data.
 * Request data is saved with callbacks from SCSI devices.
 */
static void virtio_scsi_save(QEMUFile *f, void *opaque)
{
579 580
    VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
    virtio_save(vdev, f);
581 582 583 584
}

static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id)
{
585
    VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
586 587
    int ret;

588
    ret = virtio_load(vdev, f, version_id);
589 590 591
    if (ret) {
        return ret;
    }
592 593 594
    return 0;
}

595 596 597
static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
                                   uint32_t event, uint32_t reason)
{
598
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
599
    VirtIOSCSIReq *req;
600
    VirtIOSCSIEvent *evt;
601
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
602

603
    if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
604 605 606
        return;
    }

607
    req = virtio_scsi_pop_req(s, vs->event_vq);
608 609 610 611
    if (!req) {
        s->events_dropped = true;
        return;
    }
612

613 614 615 616 617
    if (s->events_dropped) {
        event |= VIRTIO_SCSI_T_EVENTS_MISSED;
        s->events_dropped = false;
    }

618
    if (virtio_scsi_parse_req(req, 0, sizeof(VirtIOSCSIEvent))) {
619 620 621
        virtio_scsi_bad_req();
    }

622
    evt = &req->resp.event;
623
    memset(evt, 0, sizeof(VirtIOSCSIEvent));
624 625
    evt->event = virtio_tswap32(vdev, event);
    evt->reason = virtio_tswap32(vdev, reason);
626
    if (!dev) {
627
        assert(event == VIRTIO_SCSI_T_EVENTS_MISSED);
628
    } else {
629 630 631 632 633 634 635 636
        evt->lun[0] = 1;
        evt->lun[1] = dev->id;

        /* Linux wants us to keep the same encoding we use for REPORT LUNS.  */
        if (dev->lun >= 256) {
            evt->lun[2] = (dev->lun >> 8) | 0x40;
        }
        evt->lun[3] = dev->lun & 0xFF;
637 638 639 640 641 642
    }
    virtio_scsi_complete_req(req);
}

static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
{
643
    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
644 645 646

    if (s->events_dropped) {
        virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
647 648 649
    }
}

650 651 652
static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
{
    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
653
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
654

655
    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
656 657 658 659 660 661
        dev->type != TYPE_ROM) {
        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
                               sense.asc | (sense.ascq << 8));
    }
}

662 663 664
static void virtio_scsi_hotplug(SCSIBus *bus, SCSIDevice *dev)
{
    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
665
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
666

667
    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
668 669 670 671 672 673 674 675
        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET,
                               VIRTIO_SCSI_EVT_RESET_RESCAN);
    }
}

static void virtio_scsi_hot_unplug(SCSIBus *bus, SCSIDevice *dev)
{
    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
676
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
677

678
    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
679 680 681 682 683
        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET,
                               VIRTIO_SCSI_EVT_RESET_REMOVED);
    }
}

684 685 686 687 688 689 690 691
static struct SCSIBusInfo virtio_scsi_scsi_info = {
    .tcq = true,
    .max_channel = VIRTIO_SCSI_MAX_CHANNEL,
    .max_target = VIRTIO_SCSI_MAX_TARGET,
    .max_lun = VIRTIO_SCSI_MAX_LUN,

    .complete = virtio_scsi_command_complete,
    .cancel = virtio_scsi_request_cancelled,
692
    .change = virtio_scsi_change,
693 694
    .hotplug = virtio_scsi_hotplug,
    .hot_unplug = virtio_scsi_hot_unplug,
P
Paolo Bonzini 已提交
695
    .parse_cdb = virtio_scsi_parse_cdb,
696
    .get_sg_list = virtio_scsi_get_sg_list,
697 698
    .save_request = virtio_scsi_save_request,
    .load_request = virtio_scsi_load_request,
699 700
};

701 702 703
void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
                                HandleOutput ctrl, HandleOutput evt,
                                HandleOutput cmd)
704
{
705 706
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOSCSICommon *s = VIRTIO_SCSI_COMMON(dev);
707
    int i;
708

709
    virtio_init(vdev, "virtio-scsi", VIRTIO_ID_SCSI,
710
                sizeof(VirtIOSCSIConfig));
711

712 713 714 715 716 717
    if (s->conf.num_queues <= 0 || s->conf.num_queues > VIRTIO_PCI_QUEUE_MAX) {
        error_setg(errp, "Invalid number of queues (= %" PRId32 "), "
                         "must be a positive integer less than %d.",
                   s->conf.num_queues, VIRTIO_PCI_QUEUE_MAX);
        return;
    }
718
    s->cmd_vqs = g_malloc0(s->conf.num_queues * sizeof(VirtQueue *));
719 720
    s->sense_size = VIRTIO_SCSI_SENSE_SIZE;
    s->cdb_size = VIRTIO_SCSI_CDB_SIZE;
721

722
    s->ctrl_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
723
                                  ctrl);
724
    s->event_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
725
                                   evt);
726
    for (i = 0; i < s->conf.num_queues; i++) {
727
        s->cmd_vqs[i] = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
728
                                         cmd);
729
    }
730 731
}

732
static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
733
{
734
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
735
    VirtIOSCSI *s = VIRTIO_SCSI(dev);
736
    static int virtio_scsi_id;
737
    Error *err = NULL;
738

739 740 741
    virtio_scsi_common_realize(dev, &err, virtio_scsi_handle_ctrl,
                               virtio_scsi_handle_event,
                               virtio_scsi_handle_cmd);
742 743 744
    if (err != NULL) {
        error_propagate(errp, err);
        return;
745 746
    }

747
    scsi_bus_new(&s->bus, sizeof(s->bus), dev,
748
                 &virtio_scsi_scsi_info, vdev->bus_name);
749

750
    if (!dev->hotplugged) {
751 752
        scsi_bus_legacy_handle_cmdline(&s->bus, &err);
        if (err != NULL) {
753 754
            error_propagate(errp, err);
            return;
755
        }
756 757
    }

758
    register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1,
759
                    virtio_scsi_save, virtio_scsi_load, s);
760 761
}

762
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp)
763
{
764 765
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
766 767

    g_free(vs->cmd_vqs);
768
    virtio_cleanup(vdev);
769 770
}

771
static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp)
772
{
773 774 775
    VirtIOSCSI *s = VIRTIO_SCSI(dev);

    unregister_savevm(dev, "virtio-scsi", s);
776

777
    virtio_scsi_common_unrealize(dev, errp);
778 779 780
}

static Property virtio_scsi_properties[] = {
781
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSI, parent_obj.conf),
782 783 784
    DEFINE_PROP_END_OF_LIST(),
};

785 786 787
static void virtio_scsi_common_class_init(ObjectClass *klass, void *data)
{
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
788
    DeviceClass *dc = DEVICE_CLASS(klass);
789 790

    vdc->get_config = virtio_scsi_get_config;
791
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
792 793
}

794 795 796 797
static void virtio_scsi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
798

799
    dc->props = virtio_scsi_properties;
800
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
801
    vdc->realize = virtio_scsi_device_realize;
802
    vdc->unrealize = virtio_scsi_device_unrealize;
803 804 805 806 807
    vdc->set_config = virtio_scsi_set_config;
    vdc->get_features = virtio_scsi_get_features;
    vdc->reset = virtio_scsi_reset;
}

808 809 810 811
static const TypeInfo virtio_scsi_common_info = {
    .name = TYPE_VIRTIO_SCSI_COMMON,
    .parent = TYPE_VIRTIO_DEVICE,
    .instance_size = sizeof(VirtIOSCSICommon),
812
    .abstract = true,
813 814 815
    .class_init = virtio_scsi_common_class_init,
};

816 817
static const TypeInfo virtio_scsi_info = {
    .name = TYPE_VIRTIO_SCSI,
818
    .parent = TYPE_VIRTIO_SCSI_COMMON,
819 820 821 822 823 824
    .instance_size = sizeof(VirtIOSCSI),
    .class_init = virtio_scsi_class_init,
};

static void virtio_register_types(void)
{
825
    type_register_static(&virtio_scsi_common_info);
826 827 828 829
    type_register_static(&virtio_scsi_info);
}

type_init(virtio_register_types)