virtio-scsi.c 22.1 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

23 24 25 26 27 28
typedef struct VirtIOSCSIReq {
    VirtIOSCSI *dev;
    VirtQueue *vq;
    VirtQueueElement elem;
    QEMUSGList qsgl;
    SCSIRequest *sreq;
29
    size_t resp_size;
30 31 32 33 34 35 36
    union {
        char                  *buf;
        VirtIOSCSICmdResp     *cmd;
        VirtIOSCSICtrlTMFResp *tmf;
        VirtIOSCSICtrlANResp  *an;
        VirtIOSCSIEvent       *event;
    } resp;
37 38 39 40 41 42
    union {
        char                  *buf;
        VirtIOSCSICmdReq      *cmd;
        VirtIOSCSICtrlTMFReq  *tmf;
        VirtIOSCSICtrlANReq   *an;
    } req;
43 44
} VirtIOSCSIReq;

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
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));
}

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
static VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)
{
    VirtIOSCSIReq *req;
    req = g_malloc(sizeof(*req));

    req->vq = vq;
    req->dev = s;
    req->sreq = NULL;
    qemu_sglist_init(&req->qsgl, DEVICE(s), 8, &address_space_memory);
    return req;
}

static void virtio_scsi_free_req(VirtIOSCSIReq *req)
{
    qemu_sglist_destroy(&req->qsgl);
    g_free(req);
}

79 80 81 82
static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
{
    VirtIOSCSI *s = req->dev;
    VirtQueue *vq = req->vq;
83
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
84 85 86 87 88
    virtqueue_push(vq, &req->elem, req->qsgl.size + req->elem.in_sg[0].iov_len);
    if (req->sreq) {
        req->sreq->hba_private = NULL;
        scsi_req_unref(req->sreq);
    }
89
    virtio_scsi_free_req(req);
90
    virtio_notify(vdev, vq);
91 92 93 94 95 96 97 98
}

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

99 100
static size_t qemu_sgl_concat(VirtIOSCSIReq *req, struct iovec *iov,
                              hwaddr *addr, int num, size_t skip)
101
{
102
    QEMUSGList *qsgl = &req->qsgl;
103 104 105 106 107 108 109 110 111 112 113 114 115
    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--;
116
    }
117 118 119

    assert(skip == 0);
    return copied;
120 121
}

122 123
static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
                                 unsigned req_size, unsigned resp_size)
124
{
125 126 127 128 129 130 131
    if (req->elem.in_num == 0) {
        return -EINVAL;
    }

    if (req->elem.out_sg[0].iov_len < req_size) {
        return -EINVAL;
    }
132 133 134
    if (req->elem.out_num) {
        req->req.buf = req->elem.out_sg[0].iov_base;
    }
135 136 137 138

    if (req->elem.in_sg[0].iov_len < resp_size) {
        return -EINVAL;
    }
139
    req->resp.buf = req->elem.in_sg[0].iov_base;
140
    req->resp_size = resp_size;
141 142

    if (req->elem.out_num > 1) {
143 144
        qemu_sgl_concat(req, &req->elem.out_sg[1],
                        &req->elem.out_addr[1],
145
                        req->elem.out_num - 1, 0);
146
    } else {
147 148
        qemu_sgl_concat(req, &req->elem.in_sg[1],
                        &req->elem.in_addr[1],
149
                        req->elem.in_num - 1, 0);
150
    }
151 152

    return 0;
153 154 155 156
}

static VirtIOSCSIReq *virtio_scsi_pop_req(VirtIOSCSI *s, VirtQueue *vq)
{
157
    VirtIOSCSIReq *req = virtio_scsi_init_req(s, vq);
158
    if (!virtqueue_pop(vq, &req->elem)) {
159
        virtio_scsi_free_req(req);
160 161 162 163 164
        return NULL;
    }
    return req;
}

165 166 167
static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq)
{
    VirtIOSCSIReq *req = sreq->hba_private;
168
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev);
169
    uint32_t n = virtio_queue_get_id(req->vq) - 2;
170

171
    assert(n < vs->conf.num_queues);
172
    qemu_put_be32s(f, &n);
173 174 175 176 177 178 179
    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);
180
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
181
    VirtIOSCSIReq *req;
182
    uint32_t n;
183

184
    qemu_get_be32s(f, &n);
185
    assert(n < vs->conf.num_queues);
186
    req = virtio_scsi_init_req(s, vs->cmd_vqs[n]);
187
    qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
188 189 190 191 192 193 194 195 196
    /* 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));
197 198 199 200 201 202

    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);
    }
203 204 205 206 207 208 209 210 211 212 213 214

    scsi_req_ref(sreq);
    req->sreq = sreq;
    if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
        int req_mode =
            (req->elem.in_num > 1 ? SCSI_XFER_FROM_DEV : SCSI_XFER_TO_DEV);

        assert(req->sreq->cmd.mode == req_mode);
    }
    return req;
}

215
static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
216
{
217 218
    SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf->lun);
    SCSIRequest *r, *next;
A
Anthony Liguori 已提交
219
    BusChild *kid;
220 221 222 223 224
    int target;

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

225
    tswap32s(&req->req.tmf->subtype);
226 227 228 229 230 231 232 233 234 235
    switch (req->req.tmf->subtype) {
    case VIRTIO_SCSI_T_TMF_ABORT_TASK:
    case VIRTIO_SCSI_T_TMF_QUERY_TASK:
        if (!d) {
            goto fail;
        }
        if (d->lun != virtio_scsi_get_lun(req->req.tmf->lun)) {
            goto incorrect_lun;
        }
        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
236 237
            VirtIOSCSIReq *cmd_req = r->hba_private;
            if (cmd_req && cmd_req->req.cmd->tag == req->req.tmf->tag) {
238 239 240
                break;
            }
        }
241 242 243 244 245 246
        if (r) {
            /*
             * Assert that the request has not been completed yet, we
             * check for it in the loop above.
             */
            assert(r->hba_private);
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
            if (req->req.tmf->subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK) {
                /* "If the specified command is present in the task set, then
                 * return a service response set to FUNCTION SUCCEEDED".
                 */
                req->resp.tmf->response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
            } else {
                scsi_req_cancel(r);
            }
        }
        break;

    case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
        if (!d) {
            goto fail;
        }
        if (d->lun != virtio_scsi_get_lun(req->req.tmf->lun)) {
            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;
        }
        if (d->lun != virtio_scsi_get_lun(req->req.tmf->lun)) {
            goto incorrect_lun;
        }
        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
            if (r->hba_private) {
                if (req->req.tmf->subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK_SET) {
                    /* "If there is any command present in the task set, then
                     * return a service response set to FUNCTION SUCCEEDED".
                     */
                    req->resp.tmf->response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
                    break;
                } else {
                    scsi_req_cancel(r);
                }
            }
        }
        break;

    case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
        target = req->req.tmf->lun[1];
        s->resetting++;
A
Anthony Liguori 已提交
297 298
        QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
             d = DO_UPCAST(SCSIDevice, qdev, kid->child);
299 300 301 302 303 304 305 306 307 308 309
             if (d->channel == 0 && d->id == target) {
                qdev_reset_all(&d->qdev);
             }
        }
        s->resetting--;
        break;

    case VIRTIO_SCSI_T_TMF_CLEAR_ACA:
    default:
        req->resp.tmf->response = VIRTIO_SCSI_S_FUNCTION_REJECTED;
        break;
310 311
    }

312 313 314 315 316 317 318 319
    return;

incorrect_lun:
    req->resp.tmf->response = VIRTIO_SCSI_S_INCORRECT_LUN;
    return;

fail:
    req->resp.tmf->response = VIRTIO_SCSI_S_BAD_TARGET;
320 321
}

322 323
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
{
324 325 326 327
    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
    VirtIOSCSIReq *req;

    while ((req = virtio_scsi_pop_req(s, vq))) {
328 329 330 331
        int type;

        if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,
                       &type, sizeof(type)) < sizeof(type)) {
332
            virtio_scsi_bad_req();
333 334
            continue;
        }
335

336 337
        tswap32s(&req->req.tmf->type);
        if (req->req.tmf->type == VIRTIO_SCSI_T_TMF) {
338 339
            if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlTMFReq),
                                      sizeof(VirtIOSCSICtrlTMFResp)) < 0) {
340
                virtio_scsi_bad_req();
341 342
            } else {
                virtio_scsi_do_tmf(s, req);
343 344 345 346
            }

        } else if (req->req.tmf->type == VIRTIO_SCSI_T_AN_QUERY ||
                   req->req.tmf->type == VIRTIO_SCSI_T_AN_SUBSCRIBE) {
347 348
            if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlANReq),
                                      sizeof(VirtIOSCSICtrlANResp)) < 0) {
349
                virtio_scsi_bad_req();
350 351 352
            } else {
                req->resp.an->event_actual = 0;
                req->resp.an->response = VIRTIO_SCSI_S_OK;
353 354 355
            }
        }
        virtio_scsi_complete_req(req);
356 357 358
    }
}

359 360 361 362
static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
                                         size_t resid)
{
    VirtIOSCSIReq *req = r->hba_private;
363
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
364
    uint32_t sense_len;
365

366 367 368 369
    if (r->io_canceled) {
        return;
    }

370 371 372
    req->resp.cmd->response = VIRTIO_SCSI_S_OK;
    req->resp.cmd->status = status;
    if (req->resp.cmd->status == GOOD) {
373
        req->resp.cmd->resid = tswap32(resid);
374 375
    } else {
        req->resp.cmd->resid = 0;
376 377 378
        sense_len = scsi_req_get_sense(r, sense, sizeof(sense));
        sense_len = MIN(sense_len, req->resp_size - sizeof(req->resp.cmd));
        memcpy(req->resp.cmd->sense, sense, sense_len);
379
        req->resp.cmd->sense_len = tswap32(sense_len);
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
    }
    virtio_scsi_complete_req(req);
}

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;
    }
398 399 400 401 402
    if (req->dev->resetting) {
        req->resp.cmd->response = VIRTIO_SCSI_S_RESET;
    } else {
        req->resp.cmd->response = VIRTIO_SCSI_S_ABORTED;
    }
403 404 405 406
    virtio_scsi_complete_req(req);
}

static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
407 408 409
{
    req->resp.cmd->response = VIRTIO_SCSI_S_FAILURE;
    virtio_scsi_complete_req(req);
410 411 412 413
}

static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
{
414
    /* use non-QOM casts in the data path */
415
    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
416 417
    VirtIOSCSICommon *vs = &s->parent_obj;

418
    VirtIOSCSIReq *req;
419
    int n;
420 421

    while ((req = virtio_scsi_pop_req(s, vq))) {
422
        SCSIDevice *d;
423
        int rc;
424
        if (req->elem.out_num > 1 && req->elem.in_num > 1) {
425
            virtio_scsi_fail_cmd_req(req);
426 427 428
            continue;
        }

429 430 431 432 433 434
        rc = virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
                                   sizeof(VirtIOSCSICmdResp) + vs->sense_size);
        if (rc < 0) {
            virtio_scsi_bad_req();
        }

435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
        d = virtio_scsi_device_find(s, req->req.cmd->lun);
        if (!d) {
            req->resp.cmd->response = VIRTIO_SCSI_S_BAD_TARGET;
            virtio_scsi_complete_req(req);
            continue;
        }
        req->sreq = scsi_req_new(d, req->req.cmd->tag,
                                 virtio_scsi_get_lun(req->req.cmd->lun),
                                 req->req.cmd->cdb, req);

        if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
            int req_mode =
                (req->elem.in_num > 1 ? SCSI_XFER_FROM_DEV : SCSI_XFER_TO_DEV);

            if (req->sreq->cmd.mode != req_mode ||
                req->sreq->cmd.xfer > req->qsgl.size) {
                req->resp.cmd->response = VIRTIO_SCSI_S_OVERRUN;
                virtio_scsi_complete_req(req);
                continue;
            }
        }

        n = scsi_req_enqueue(req->sreq);
        if (n) {
            scsi_req_continue(req->sreq);
        }
461
    }
462 463 464 465 466 467
}

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

470 471 472 473 474 475 476 477 478 479
    stl_p(&scsiconf->num_queues, s->conf.num_queues);
    stl_p(&scsiconf->seg_max, 128 - 2);
    stl_p(&scsiconf->max_sectors, s->conf.max_sectors);
    stl_p(&scsiconf->cmd_per_lun, s->conf.cmd_per_lun);
    stl_p(&scsiconf->event_info_size, sizeof(VirtIOSCSIEvent));
    stl_p(&scsiconf->sense_size, s->sense_size);
    stl_p(&scsiconf->cdb_size, s->cdb_size);
    stw_p(&scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL);
    stw_p(&scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET);
    stl_p(&scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN);
480 481 482 483 484 485
}

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

488 489
    if ((uint32_t) ldl_p(&scsiconf->sense_size) >= 65536 ||
        (uint32_t) ldl_p(&scsiconf->cdb_size) >= 256) {
490 491 492 493
        error_report("bad data written to virtio-scsi configuration space");
        exit(1);
    }

494 495
    vs->sense_size = ldl_p(&scsiconf->sense_size);
    vs->cdb_size = ldl_p(&scsiconf->cdb_size);
496 497 498 499 500 501 502 503 504 505
}

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

static void virtio_scsi_reset(VirtIODevice *vdev)
{
506 507
    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
508

509 510 511 512
    s->resetting++;
    qbus_reset_all(&s->bus.qbus);
    s->resetting--;

513 514
    vs->sense_size = VIRTIO_SCSI_SENSE_SIZE;
    vs->cdb_size = VIRTIO_SCSI_CDB_SIZE;
515
    s->events_dropped = false;
516 517
}

518 519 520 521 522
/* 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)
{
523 524
    VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
    virtio_save(vdev, f);
525 526 527 528
}

static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id)
{
529
    VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
530 531
    int ret;

532
    ret = virtio_load(vdev, f);
533 534 535
    if (ret) {
        return ret;
    }
536 537 538
    return 0;
}

539 540 541
static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
                                   uint32_t event, uint32_t reason)
{
542
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
543
    VirtIOSCSIReq *req;
544
    VirtIOSCSIEvent *evt;
545
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
546
    int in_size;
547

548
    if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
549 550 551
        return;
    }

552
    req = virtio_scsi_pop_req(s, vs->event_vq);
553 554 555 556
    if (!req) {
        s->events_dropped = true;
        return;
    }
557

558 559 560
    if (req->elem.out_num || req->elem.in_num != 1) {
        virtio_scsi_bad_req();
    }
561

562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
    if (s->events_dropped) {
        event |= VIRTIO_SCSI_T_EVENTS_MISSED;
        s->events_dropped = false;
    }

    in_size = req->elem.in_sg[0].iov_len;
    if (in_size < sizeof(VirtIOSCSIEvent)) {
        virtio_scsi_bad_req();
    }

    evt = req->resp.event;
    memset(evt, 0, sizeof(VirtIOSCSIEvent));
    evt->event = event;
    evt->reason = reason;
    if (!dev) {
577
        assert(event == VIRTIO_SCSI_T_EVENTS_MISSED);
578
    } else {
579 580 581 582 583 584 585 586
        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;
587 588 589 590 591 592
    }
    virtio_scsi_complete_req(req);
}

static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
{
593
    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
594 595 596

    if (s->events_dropped) {
        virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
597 598 599
    }
}

600 601 602
static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
{
    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
603
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
604

605
    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
606 607 608 609 610 611
        dev->type != TYPE_ROM) {
        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
                               sense.asc | (sense.ascq << 8));
    }
}

612 613 614
static void virtio_scsi_hotplug(SCSIBus *bus, SCSIDevice *dev)
{
    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
615
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
616

617
    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
618 619 620 621 622 623 624 625
        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);
626
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
627

628
    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
629 630 631 632 633
        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET,
                               VIRTIO_SCSI_EVT_RESET_REMOVED);
    }
}

634 635 636 637 638 639 640 641
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,
642
    .change = virtio_scsi_change,
643 644
    .hotplug = virtio_scsi_hotplug,
    .hot_unplug = virtio_scsi_hot_unplug,
645
    .get_sg_list = virtio_scsi_get_sg_list,
646 647
    .save_request = virtio_scsi_save_request,
    .load_request = virtio_scsi_load_request,
648 649
};

650
void virtio_scsi_common_realize(DeviceState *dev, Error **errp)
651
{
652 653
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOSCSICommon *s = VIRTIO_SCSI_COMMON(dev);
654
    int i;
655

656
    virtio_init(vdev, "virtio-scsi", VIRTIO_ID_SCSI,
657
                sizeof(VirtIOSCSIConfig));
658

659
    s->cmd_vqs = g_malloc0(s->conf.num_queues * sizeof(VirtQueue *));
660 661
    s->sense_size = VIRTIO_SCSI_SENSE_SIZE;
    s->cdb_size = VIRTIO_SCSI_CDB_SIZE;
662

663 664 665
    s->ctrl_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
                                  virtio_scsi_handle_ctrl);
    s->event_vq = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
666
                                   virtio_scsi_handle_event);
667
    for (i = 0; i < s->conf.num_queues; i++) {
668
        s->cmd_vqs[i] = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
669 670
                                         virtio_scsi_handle_cmd);
    }
671 672
}

673
static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
674
{
675
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
676
    VirtIOSCSI *s = VIRTIO_SCSI(dev);
677
    static int virtio_scsi_id;
678
    Error *err = NULL;
679

680 681 682 683
    virtio_scsi_common_realize(dev, &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
684 685
    }

686
    scsi_bus_new(&s->bus, sizeof(s->bus), dev,
687
                 &virtio_scsi_scsi_info, vdev->bus_name);
688

689
    if (!dev->hotplugged) {
690 691
        scsi_bus_legacy_handle_cmdline(&s->bus, &err);
        if (err != NULL) {
692 693
            error_propagate(errp, err);
            return;
694
        }
695 696
    }

697
    register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1,
698
                    virtio_scsi_save, virtio_scsi_load, s);
699 700
}

701
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp)
702
{
703 704
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
705 706

    g_free(vs->cmd_vqs);
707
    virtio_cleanup(vdev);
708 709
}

710
static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp)
711
{
712 713 714
    VirtIOSCSI *s = VIRTIO_SCSI(dev);

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

716
    virtio_scsi_common_unrealize(dev, errp);
717 718 719
}

static Property virtio_scsi_properties[] = {
720
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSI, parent_obj.conf),
721 722 723
    DEFINE_PROP_END_OF_LIST(),
};

724 725 726
static void virtio_scsi_common_class_init(ObjectClass *klass, void *data)
{
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
727
    DeviceClass *dc = DEVICE_CLASS(klass);
728 729

    vdc->get_config = virtio_scsi_get_config;
730
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
731 732
}

733 734 735 736
static void virtio_scsi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
737

738
    dc->props = virtio_scsi_properties;
739
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
740
    vdc->realize = virtio_scsi_device_realize;
741
    vdc->unrealize = virtio_scsi_device_unrealize;
742 743 744 745 746
    vdc->set_config = virtio_scsi_set_config;
    vdc->get_features = virtio_scsi_get_features;
    vdc->reset = virtio_scsi_reset;
}

747 748 749 750
static const TypeInfo virtio_scsi_common_info = {
    .name = TYPE_VIRTIO_SCSI_COMMON,
    .parent = TYPE_VIRTIO_DEVICE,
    .instance_size = sizeof(VirtIOSCSICommon),
751
    .abstract = true,
752 753 754
    .class_init = virtio_scsi_common_class_init,
};

755 756
static const TypeInfo virtio_scsi_info = {
    .name = TYPE_VIRTIO_SCSI,
757
    .parent = TYPE_VIRTIO_SCSI_COMMON,
758 759 760 761 762 763
    .instance_size = sizeof(VirtIOSCSI),
    .class_init = virtio_scsi_class_init,
};

static void virtio_register_types(void)
{
764
    type_register_static(&virtio_scsi_common_info);
765 766 767 768
    type_register_static(&virtio_scsi_info);
}

type_init(virtio_register_types)