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