qemu/hw/usb/dev-storage.c
<<
>>
Prefs
   1/*
   2 * USB Mass Storage Device emulation
   3 *
   4 * Copyright (c) 2006 CodeSourcery.
   5 * Written by Paul Brook
   6 *
   7 * This code is licensed under the LGPL.
   8 */
   9
  10#include "qemu/osdep.h"
  11#include "qapi/error.h"
  12#include "qemu/error-report.h"
  13#include "qemu/module.h"
  14#include "qemu/option.h"
  15#include "qemu/config-file.h"
  16#include "hw/usb.h"
  17#include "desc.h"
  18#include "hw/scsi/scsi.h"
  19#include "ui/console.h"
  20#include "monitor/monitor.h"
  21#include "sysemu/sysemu.h"
  22#include "sysemu/block-backend.h"
  23#include "qapi/visitor.h"
  24#include "qemu/cutils.h"
  25
  26//#define DEBUG_MSD
  27
  28#ifdef DEBUG_MSD
  29#define DPRINTF(fmt, ...) \
  30do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0)
  31#else
  32#define DPRINTF(fmt, ...) do {} while(0)
  33#endif
  34
  35/* USB requests.  */
  36#define MassStorageReset  0xff
  37#define GetMaxLun         0xfe
  38
  39enum USBMSDMode {
  40    USB_MSDM_CBW, /* Command Block.  */
  41    USB_MSDM_DATAOUT, /* Transfer data to device.  */
  42    USB_MSDM_DATAIN, /* Transfer data from device.  */
  43    USB_MSDM_CSW /* Command Status.  */
  44};
  45
  46struct usb_msd_csw {
  47    uint32_t sig;
  48    uint32_t tag;
  49    uint32_t residue;
  50    uint8_t status;
  51};
  52
  53typedef struct {
  54    USBDevice dev;
  55    enum USBMSDMode mode;
  56    uint32_t scsi_off;
  57    uint32_t scsi_len;
  58    uint32_t data_len;
  59    struct usb_msd_csw csw;
  60    SCSIRequest *req;
  61    SCSIBus bus;
  62    /* For async completion.  */
  63    USBPacket *packet;
  64    /* usb-storage only */
  65    BlockConf conf;
  66    uint32_t removable;
  67    SCSIDevice *scsi_dev;
  68} MSDState;
  69
  70#define TYPE_USB_STORAGE "usb-storage-dev"
  71#define USB_STORAGE_DEV(obj) OBJECT_CHECK(MSDState, (obj), TYPE_USB_STORAGE)
  72
  73struct usb_msd_cbw {
  74    uint32_t sig;
  75    uint32_t tag;
  76    uint32_t data_len;
  77    uint8_t flags;
  78    uint8_t lun;
  79    uint8_t cmd_len;
  80    uint8_t cmd[16];
  81};
  82
  83enum {
  84    STR_MANUFACTURER = 1,
  85    STR_PRODUCT,
  86    STR_SERIALNUMBER,
  87    STR_CONFIG_FULL,
  88    STR_CONFIG_HIGH,
  89    STR_CONFIG_SUPER,
  90};
  91
  92static const USBDescStrings desc_strings = {
  93    [STR_MANUFACTURER] = "QEMU",
  94    [STR_PRODUCT]      = "QEMU USB HARDDRIVE",
  95    [STR_SERIALNUMBER] = "1",
  96    [STR_CONFIG_FULL]  = "Full speed config (usb 1.1)",
  97    [STR_CONFIG_HIGH]  = "High speed config (usb 2.0)",
  98    [STR_CONFIG_SUPER] = "Super speed config (usb 3.0)",
  99};
 100
 101static const USBDescIface desc_iface_full = {
 102    .bInterfaceNumber              = 0,
 103    .bNumEndpoints                 = 2,
 104    .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
 105    .bInterfaceSubClass            = 0x06, /* SCSI */
 106    .bInterfaceProtocol            = 0x50, /* Bulk */
 107    .eps = (USBDescEndpoint[]) {
 108        {
 109            .bEndpointAddress      = USB_DIR_IN | 0x01,
 110            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 111            .wMaxPacketSize        = 64,
 112        },{
 113            .bEndpointAddress      = USB_DIR_OUT | 0x02,
 114            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 115            .wMaxPacketSize        = 64,
 116        },
 117    }
 118};
 119
 120static const USBDescDevice desc_device_full = {
 121    .bcdUSB                        = 0x0200,
 122    .bMaxPacketSize0               = 8,
 123    .bNumConfigurations            = 1,
 124    .confs = (USBDescConfig[]) {
 125        {
 126            .bNumInterfaces        = 1,
 127            .bConfigurationValue   = 1,
 128            .iConfiguration        = STR_CONFIG_FULL,
 129            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
 130            .nif = 1,
 131            .ifs = &desc_iface_full,
 132        },
 133    },
 134};
 135
 136static const USBDescIface desc_iface_high = {
 137    .bInterfaceNumber              = 0,
 138    .bNumEndpoints                 = 2,
 139    .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
 140    .bInterfaceSubClass            = 0x06, /* SCSI */
 141    .bInterfaceProtocol            = 0x50, /* Bulk */
 142    .eps = (USBDescEndpoint[]) {
 143        {
 144            .bEndpointAddress      = USB_DIR_IN | 0x01,
 145            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 146            .wMaxPacketSize        = 512,
 147        },{
 148            .bEndpointAddress      = USB_DIR_OUT | 0x02,
 149            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 150            .wMaxPacketSize        = 512,
 151        },
 152    }
 153};
 154
 155static const USBDescDevice desc_device_high = {
 156    .bcdUSB                        = 0x0200,
 157    .bMaxPacketSize0               = 64,
 158    .bNumConfigurations            = 1,
 159    .confs = (USBDescConfig[]) {
 160        {
 161            .bNumInterfaces        = 1,
 162            .bConfigurationValue   = 1,
 163            .iConfiguration        = STR_CONFIG_HIGH,
 164            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
 165            .nif = 1,
 166            .ifs = &desc_iface_high,
 167        },
 168    },
 169};
 170
 171static const USBDescIface desc_iface_super = {
 172    .bInterfaceNumber              = 0,
 173    .bNumEndpoints                 = 2,
 174    .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
 175    .bInterfaceSubClass            = 0x06, /* SCSI */
 176    .bInterfaceProtocol            = 0x50, /* Bulk */
 177    .eps = (USBDescEndpoint[]) {
 178        {
 179            .bEndpointAddress      = USB_DIR_IN | 0x01,
 180            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 181            .wMaxPacketSize        = 1024,
 182            .bMaxBurst             = 15,
 183        },{
 184            .bEndpointAddress      = USB_DIR_OUT | 0x02,
 185            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 186            .wMaxPacketSize        = 1024,
 187            .bMaxBurst             = 15,
 188        },
 189    }
 190};
 191
 192static const USBDescDevice desc_device_super = {
 193    .bcdUSB                        = 0x0300,
 194    .bMaxPacketSize0               = 9,
 195    .bNumConfigurations            = 1,
 196    .confs = (USBDescConfig[]) {
 197        {
 198            .bNumInterfaces        = 1,
 199            .bConfigurationValue   = 1,
 200            .iConfiguration        = STR_CONFIG_SUPER,
 201            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
 202            .nif = 1,
 203            .ifs = &desc_iface_super,
 204        },
 205    },
 206};
 207
 208static const USBDesc desc = {
 209    .id = {
 210        .idVendor          = 0x46f4, /* CRC16() of "QEMU" */
 211        .idProduct         = 0x0001,
 212        .bcdDevice         = 0,
 213        .iManufacturer     = STR_MANUFACTURER,
 214        .iProduct          = STR_PRODUCT,
 215        .iSerialNumber     = STR_SERIALNUMBER,
 216    },
 217    .full  = &desc_device_full,
 218    .high  = &desc_device_high,
 219    .super = &desc_device_super,
 220    .str   = desc_strings,
 221};
 222
 223static void usb_msd_copy_data(MSDState *s, USBPacket *p)
 224{
 225    uint32_t len;
 226    len = p->iov.size - p->actual_length;
 227    if (len > s->scsi_len)
 228        len = s->scsi_len;
 229    usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len);
 230    s->scsi_len -= len;
 231    s->scsi_off += len;
 232    s->data_len -= len;
 233    if (s->scsi_len == 0 || s->data_len == 0) {
 234        scsi_req_continue(s->req);
 235    }
 236}
 237
 238static void usb_msd_send_status(MSDState *s, USBPacket *p)
 239{
 240    int len;
 241
 242    DPRINTF("Command status %d tag 0x%x, len %zd\n",
 243            s->csw.status, le32_to_cpu(s->csw.tag), p->iov.size);
 244
 245    assert(s->csw.sig == cpu_to_le32(0x53425355));
 246    len = MIN(sizeof(s->csw), p->iov.size);
 247    usb_packet_copy(p, &s->csw, len);
 248    memset(&s->csw, 0, sizeof(s->csw));
 249}
 250
 251static void usb_msd_packet_complete(MSDState *s)
 252{
 253    USBPacket *p = s->packet;
 254
 255    /* Set s->packet to NULL before calling usb_packet_complete
 256       because another request may be issued before
 257       usb_packet_complete returns.  */
 258    DPRINTF("Packet complete %p\n", p);
 259    s->packet = NULL;
 260    usb_packet_complete(&s->dev, p);
 261}
 262
 263static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
 264{
 265    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 266    USBPacket *p = s->packet;
 267
 268    assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV));
 269    s->scsi_len = len;
 270    s->scsi_off = 0;
 271    if (p) {
 272        usb_msd_copy_data(s, p);
 273        p = s->packet;
 274        if (p && p->actual_length == p->iov.size) {
 275            p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
 276            usb_msd_packet_complete(s);
 277        }
 278    }
 279}
 280
 281static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, size_t resid)
 282{
 283    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 284    USBPacket *p = s->packet;
 285
 286    DPRINTF("Command complete %d tag 0x%x\n", status, req->tag);
 287
 288    s->csw.sig = cpu_to_le32(0x53425355);
 289    s->csw.tag = cpu_to_le32(req->tag);
 290    s->csw.residue = cpu_to_le32(s->data_len);
 291    s->csw.status = status != 0;
 292
 293    if (s->packet) {
 294        if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
 295            /* A deferred packet with no write data remaining must be
 296               the status read packet.  */
 297            usb_msd_send_status(s, p);
 298            s->mode = USB_MSDM_CBW;
 299        } else if (s->mode == USB_MSDM_CSW) {
 300            usb_msd_send_status(s, p);
 301            s->mode = USB_MSDM_CBW;
 302        } else {
 303            if (s->data_len) {
 304                int len = (p->iov.size - p->actual_length);
 305                usb_packet_skip(p, len);
 306                s->data_len -= len;
 307            }
 308            if (s->data_len == 0) {
 309                s->mode = USB_MSDM_CSW;
 310            }
 311        }
 312        p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
 313        usb_msd_packet_complete(s);
 314    } else if (s->data_len == 0) {
 315        s->mode = USB_MSDM_CSW;
 316    }
 317    scsi_req_unref(req);
 318    s->req = NULL;
 319}
 320
 321static void usb_msd_request_cancelled(SCSIRequest *req)
 322{
 323    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 324
 325    if (req == s->req) {
 326        scsi_req_unref(s->req);
 327        s->req = NULL;
 328        s->scsi_len = 0;
 329    }
 330}
 331
 332static void usb_msd_handle_reset(USBDevice *dev)
 333{
 334    MSDState *s = (MSDState *)dev;
 335
 336    DPRINTF("Reset\n");
 337    if (s->req) {
 338        scsi_req_cancel(s->req);
 339    }
 340    assert(s->req == NULL);
 341
 342    if (s->packet) {
 343        s->packet->status = USB_RET_STALL;
 344        usb_msd_packet_complete(s);
 345    }
 346
 347    s->mode = USB_MSDM_CBW;
 348}
 349
 350static void usb_msd_handle_control(USBDevice *dev, USBPacket *p,
 351               int request, int value, int index, int length, uint8_t *data)
 352{
 353    MSDState *s = (MSDState *)dev;
 354    SCSIDevice *scsi_dev;
 355    int ret, maxlun;
 356
 357    ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
 358    if (ret >= 0) {
 359        return;
 360    }
 361
 362    switch (request) {
 363    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
 364        break;
 365        /* Class specific requests.  */
 366    case ClassInterfaceOutRequest | MassStorageReset:
 367        /* Reset state ready for the next CBW.  */
 368        s->mode = USB_MSDM_CBW;
 369        break;
 370    case ClassInterfaceRequest | GetMaxLun:
 371        maxlun = 0;
 372        for (;;) {
 373            scsi_dev = scsi_device_find(&s->bus, 0, 0, maxlun+1);
 374            if (scsi_dev == NULL) {
 375                break;
 376            }
 377            if (scsi_dev->lun != maxlun+1) {
 378                break;
 379            }
 380            maxlun++;
 381        }
 382        DPRINTF("MaxLun %d\n", maxlun);
 383        data[0] = maxlun;
 384        p->actual_length = 1;
 385        break;
 386    default:
 387        p->status = USB_RET_STALL;
 388        break;
 389    }
 390}
 391
 392static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p)
 393{
 394    MSDState *s = USB_STORAGE_DEV(dev);
 395
 396    assert(s->packet == p);
 397    s->packet = NULL;
 398
 399    if (s->req) {
 400        scsi_req_cancel(s->req);
 401    }
 402}
 403
 404static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
 405{
 406    MSDState *s = (MSDState *)dev;
 407    uint32_t tag;
 408    struct usb_msd_cbw cbw;
 409    uint8_t devep = p->ep->nr;
 410    SCSIDevice *scsi_dev;
 411    uint32_t len;
 412
 413    switch (p->pid) {
 414    case USB_TOKEN_OUT:
 415        if (devep != 2)
 416            goto fail;
 417
 418        switch (s->mode) {
 419        case USB_MSDM_CBW:
 420            if (p->iov.size != 31) {
 421                error_report("usb-msd: Bad CBW size");
 422                goto fail;
 423            }
 424            usb_packet_copy(p, &cbw, 31);
 425            if (le32_to_cpu(cbw.sig) != 0x43425355) {
 426                error_report("usb-msd: Bad signature %08x",
 427                             le32_to_cpu(cbw.sig));
 428                goto fail;
 429            }
 430            DPRINTF("Command on LUN %d\n", cbw.lun);
 431            scsi_dev = scsi_device_find(&s->bus, 0, 0, cbw.lun);
 432            if (scsi_dev == NULL) {
 433                error_report("usb-msd: Bad LUN %d", cbw.lun);
 434                goto fail;
 435            }
 436            tag = le32_to_cpu(cbw.tag);
 437            s->data_len = le32_to_cpu(cbw.data_len);
 438            if (s->data_len == 0) {
 439                s->mode = USB_MSDM_CSW;
 440            } else if (cbw.flags & 0x80) {
 441                s->mode = USB_MSDM_DATAIN;
 442            } else {
 443                s->mode = USB_MSDM_DATAOUT;
 444            }
 445            DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
 446                    tag, cbw.flags, cbw.cmd_len, s->data_len);
 447            assert(le32_to_cpu(s->csw.residue) == 0);
 448            s->scsi_len = 0;
 449            s->req = scsi_req_new(scsi_dev, tag, cbw.lun, cbw.cmd, NULL);
 450#ifdef DEBUG_MSD
 451            scsi_req_print(s->req);
 452#endif
 453            len = scsi_req_enqueue(s->req);
 454            if (len) {
 455                scsi_req_continue(s->req);
 456            }
 457            break;
 458
 459        case USB_MSDM_DATAOUT:
 460            DPRINTF("Data out %zd/%d\n", p->iov.size, s->data_len);
 461            if (p->iov.size > s->data_len) {
 462                goto fail;
 463            }
 464
 465            if (s->scsi_len) {
 466                usb_msd_copy_data(s, p);
 467            }
 468            if (le32_to_cpu(s->csw.residue)) {
 469                int len = p->iov.size - p->actual_length;
 470                if (len) {
 471                    usb_packet_skip(p, len);
 472                    s->data_len -= len;
 473                    if (s->data_len == 0) {
 474                        s->mode = USB_MSDM_CSW;
 475                    }
 476                }
 477            }
 478            if (p->actual_length < p->iov.size) {
 479                DPRINTF("Deferring packet %p [wait data-out]\n", p);
 480                s->packet = p;
 481                p->status = USB_RET_ASYNC;
 482            }
 483            break;
 484
 485        default:
 486            DPRINTF("Unexpected write (len %zd)\n", p->iov.size);
 487            goto fail;
 488        }
 489        break;
 490
 491    case USB_TOKEN_IN:
 492        if (devep != 1)
 493            goto fail;
 494
 495        switch (s->mode) {
 496        case USB_MSDM_DATAOUT:
 497            if (s->data_len != 0 || p->iov.size < 13) {
 498                goto fail;
 499            }
 500            /* Waiting for SCSI write to complete.  */
 501            s->packet = p;
 502            p->status = USB_RET_ASYNC;
 503            break;
 504
 505        case USB_MSDM_CSW:
 506            if (p->iov.size < 13) {
 507                goto fail;
 508            }
 509
 510            if (s->req) {
 511                /* still in flight */
 512                DPRINTF("Deferring packet %p [wait status]\n", p);
 513                s->packet = p;
 514                p->status = USB_RET_ASYNC;
 515            } else {
 516                usb_msd_send_status(s, p);
 517                s->mode = USB_MSDM_CBW;
 518            }
 519            break;
 520
 521        case USB_MSDM_DATAIN:
 522            DPRINTF("Data in %zd/%d, scsi_len %d\n",
 523                    p->iov.size, s->data_len, s->scsi_len);
 524            if (s->scsi_len) {
 525                usb_msd_copy_data(s, p);
 526            }
 527            if (le32_to_cpu(s->csw.residue)) {
 528                int len = p->iov.size - p->actual_length;
 529                if (len) {
 530                    usb_packet_skip(p, len);
 531                    s->data_len -= len;
 532                    if (s->data_len == 0) {
 533                        s->mode = USB_MSDM_CSW;
 534                    }
 535                }
 536            }
 537            if (p->actual_length < p->iov.size) {
 538                DPRINTF("Deferring packet %p [wait data-in]\n", p);
 539                s->packet = p;
 540                p->status = USB_RET_ASYNC;
 541            }
 542            break;
 543
 544        default:
 545            DPRINTF("Unexpected read (len %zd)\n", p->iov.size);
 546            goto fail;
 547        }
 548        break;
 549
 550    default:
 551        DPRINTF("Bad token\n");
 552    fail:
 553        p->status = USB_RET_STALL;
 554        break;
 555    }
 556}
 557
 558static void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req)
 559{
 560    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 561
 562    /* nothing to load, just store req in our state struct */
 563    assert(s->req == NULL);
 564    scsi_req_ref(req);
 565    s->req = req;
 566    return NULL;
 567}
 568
 569static const struct SCSIBusInfo usb_msd_scsi_info_storage = {
 570    .tcq = false,
 571    .max_target = 0,
 572    .max_lun = 0,
 573
 574    .transfer_data = usb_msd_transfer_data,
 575    .complete = usb_msd_command_complete,
 576    .cancel = usb_msd_request_cancelled,
 577    .load_request = usb_msd_load_request,
 578};
 579
 580static const struct SCSIBusInfo usb_msd_scsi_info_bot = {
 581    .tcq = false,
 582    .max_target = 0,
 583    .max_lun = 15,
 584
 585    .transfer_data = usb_msd_transfer_data,
 586    .complete = usb_msd_command_complete,
 587    .cancel = usb_msd_request_cancelled,
 588    .load_request = usb_msd_load_request,
 589};
 590
 591static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
 592{
 593    MSDState *s = USB_STORAGE_DEV(dev);
 594    BlockBackend *blk = s->conf.blk;
 595    SCSIDevice *scsi_dev;
 596
 597    if (!blk) {
 598        error_setg(errp, "drive property not set");
 599        return;
 600    }
 601
 602    blkconf_blocksizes(&s->conf);
 603    if (!blkconf_apply_backend_options(&s->conf, blk_is_read_only(blk), true,
 604                                       errp)) {
 605        return;
 606    }
 607
 608    /*
 609     * Hack alert: this pretends to be a block device, but it's really
 610     * a SCSI bus that can serve only a single device, which it
 611     * creates automatically.  But first it needs to detach from its
 612     * blockdev, or else scsi_bus_legacy_add_drive() dies when it
 613     * attaches again. We also need to take another reference so that
 614     * blk_detach_dev() doesn't free blk while we still need it.
 615     *
 616     * The hack is probably a bad idea.
 617     */
 618    blk_ref(blk);
 619    blk_detach_dev(blk, DEVICE(s));
 620    s->conf.blk = NULL;
 621
 622    usb_desc_create_serial(dev);
 623    usb_desc_init(dev);
 624    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
 625                 &usb_msd_scsi_info_storage, NULL);
 626    scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
 627                                         s->conf.bootindex, s->conf.share_rw,
 628                                         s->conf.rerror, s->conf.werror,
 629                                         dev->serial,
 630                                         errp);
 631    blk_unref(blk);
 632    if (!scsi_dev) {
 633        return;
 634    }
 635    usb_msd_handle_reset(dev);
 636    s->scsi_dev = scsi_dev;
 637}
 638
 639static void usb_msd_bot_realize(USBDevice *dev, Error **errp)
 640{
 641    MSDState *s = USB_STORAGE_DEV(dev);
 642    DeviceState *d = DEVICE(dev);
 643
 644    usb_desc_create_serial(dev);
 645    usb_desc_init(dev);
 646    if (d->hotplugged) {
 647        s->dev.auto_attach = 0;
 648    }
 649
 650    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
 651                 &usb_msd_scsi_info_bot, NULL);
 652    usb_msd_handle_reset(dev);
 653}
 654
 655static const VMStateDescription vmstate_usb_msd = {
 656    .name = "usb-storage",
 657    .version_id = 1,
 658    .minimum_version_id = 1,
 659    .fields = (VMStateField[]) {
 660        VMSTATE_USB_DEVICE(dev, MSDState),
 661        VMSTATE_UINT32(mode, MSDState),
 662        VMSTATE_UINT32(scsi_len, MSDState),
 663        VMSTATE_UINT32(scsi_off, MSDState),
 664        VMSTATE_UINT32(data_len, MSDState),
 665        VMSTATE_UINT32(csw.sig, MSDState),
 666        VMSTATE_UINT32(csw.tag, MSDState),
 667        VMSTATE_UINT32(csw.residue, MSDState),
 668        VMSTATE_UINT8(csw.status, MSDState),
 669        VMSTATE_END_OF_LIST()
 670    }
 671};
 672
 673static Property msd_properties[] = {
 674    DEFINE_BLOCK_PROPERTIES(MSDState, conf),
 675    DEFINE_BLOCK_ERROR_PROPERTIES(MSDState, conf),
 676    DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
 677    DEFINE_PROP_END_OF_LIST(),
 678};
 679
 680static void usb_msd_class_initfn_common(ObjectClass *klass, void *data)
 681{
 682    DeviceClass *dc = DEVICE_CLASS(klass);
 683    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 684
 685    uc->product_desc   = "QEMU USB MSD";
 686    uc->usb_desc       = &desc;
 687    uc->cancel_packet  = usb_msd_cancel_io;
 688    uc->handle_attach  = usb_desc_attach;
 689    uc->handle_reset   = usb_msd_handle_reset;
 690    uc->handle_control = usb_msd_handle_control;
 691    uc->handle_data    = usb_msd_handle_data;
 692    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 693    dc->fw_name = "storage";
 694    dc->vmsd = &vmstate_usb_msd;
 695}
 696
 697static void usb_msd_class_storage_initfn(ObjectClass *klass, void *data)
 698{
 699    DeviceClass *dc = DEVICE_CLASS(klass);
 700    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 701
 702    uc->realize = usb_msd_storage_realize;
 703    dc->props = msd_properties;
 704}
 705
 706static void usb_msd_get_bootindex(Object *obj, Visitor *v, const char *name,
 707                                  void *opaque, Error **errp)
 708{
 709    USBDevice *dev = USB_DEVICE(obj);
 710    MSDState *s = USB_STORAGE_DEV(dev);
 711
 712    visit_type_int32(v, name, &s->conf.bootindex, errp);
 713}
 714
 715static void usb_msd_set_bootindex(Object *obj, Visitor *v, const char *name,
 716                                  void *opaque, Error **errp)
 717{
 718    USBDevice *dev = USB_DEVICE(obj);
 719    MSDState *s = USB_STORAGE_DEV(dev);
 720    int32_t boot_index;
 721    Error *local_err = NULL;
 722
 723    visit_type_int32(v, name, &boot_index, &local_err);
 724    if (local_err) {
 725        goto out;
 726    }
 727    /* check whether bootindex is present in fw_boot_order list  */
 728    check_boot_index(boot_index, &local_err);
 729    if (local_err) {
 730        goto out;
 731    }
 732    /* change bootindex to a new one */
 733    s->conf.bootindex = boot_index;
 734
 735    if (s->scsi_dev) {
 736        object_property_set_int(OBJECT(s->scsi_dev), boot_index, "bootindex",
 737                                &error_abort);
 738    }
 739
 740out:
 741    error_propagate(errp, local_err);
 742}
 743
 744static const TypeInfo usb_storage_dev_type_info = {
 745    .name = TYPE_USB_STORAGE,
 746    .parent = TYPE_USB_DEVICE,
 747    .instance_size = sizeof(MSDState),
 748    .abstract = true,
 749    .class_init = usb_msd_class_initfn_common,
 750};
 751
 752static void usb_msd_instance_init(Object *obj)
 753{
 754    object_property_add(obj, "bootindex", "int32",
 755                        usb_msd_get_bootindex,
 756                        usb_msd_set_bootindex, NULL, NULL, NULL);
 757    object_property_set_int(obj, -1, "bootindex", NULL);
 758}
 759
 760static void usb_msd_class_bot_initfn(ObjectClass *klass, void *data)
 761{
 762    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 763
 764    uc->realize = usb_msd_bot_realize;
 765    uc->attached_settable = true;
 766}
 767
 768static const TypeInfo msd_info = {
 769    .name          = "usb-storage",
 770    .parent        = TYPE_USB_STORAGE,
 771    .class_init    = usb_msd_class_storage_initfn,
 772    .instance_init = usb_msd_instance_init,
 773};
 774
 775static const TypeInfo bot_info = {
 776    .name          = "usb-bot",
 777    .parent        = TYPE_USB_STORAGE,
 778    .class_init    = usb_msd_class_bot_initfn,
 779};
 780
 781static void usb_msd_register_types(void)
 782{
 783    type_register_static(&usb_storage_dev_type_info);
 784    type_register_static(&msd_info);
 785    type_register_static(&bot_info);
 786}
 787
 788type_init(usb_msd_register_types)
 789