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 "hw/usb/msd.h"
  18#include "desc.h"
  19#include "hw/qdev-properties.h"
  20#include "hw/scsi/scsi.h"
  21#include "migration/vmstate.h"
  22#include "qemu/cutils.h"
  23#include "qom/object.h"
  24#include "trace.h"
  25
  26/* USB requests.  */
  27#define MassStorageReset  0xff
  28#define GetMaxLun         0xfe
  29
  30struct usb_msd_cbw {
  31    uint32_t sig;
  32    uint32_t tag;
  33    uint32_t data_len;
  34    uint8_t flags;
  35    uint8_t lun;
  36    uint8_t cmd_len;
  37    uint8_t cmd[16];
  38};
  39
  40enum {
  41    STR_MANUFACTURER = 1,
  42    STR_PRODUCT,
  43    STR_SERIALNUMBER,
  44    STR_CONFIG_FULL,
  45    STR_CONFIG_HIGH,
  46    STR_CONFIG_SUPER,
  47};
  48
  49static const USBDescStrings desc_strings = {
  50    [STR_MANUFACTURER] = "QEMU",
  51    [STR_PRODUCT]      = "QEMU USB HARDDRIVE",
  52    [STR_SERIALNUMBER] = "1",
  53    [STR_CONFIG_FULL]  = "Full speed config (usb 1.1)",
  54    [STR_CONFIG_HIGH]  = "High speed config (usb 2.0)",
  55    [STR_CONFIG_SUPER] = "Super speed config (usb 3.0)",
  56};
  57
  58static const USBDescIface desc_iface_full = {
  59    .bInterfaceNumber              = 0,
  60    .bNumEndpoints                 = 2,
  61    .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
  62    .bInterfaceSubClass            = 0x06, /* SCSI */
  63    .bInterfaceProtocol            = 0x50, /* Bulk */
  64    .eps = (USBDescEndpoint[]) {
  65        {
  66            .bEndpointAddress      = USB_DIR_IN | 0x01,
  67            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
  68            .wMaxPacketSize        = 64,
  69        },{
  70            .bEndpointAddress      = USB_DIR_OUT | 0x02,
  71            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
  72            .wMaxPacketSize        = 64,
  73        },
  74    }
  75};
  76
  77static const USBDescDevice desc_device_full = {
  78    .bcdUSB                        = 0x0200,
  79    .bMaxPacketSize0               = 8,
  80    .bNumConfigurations            = 1,
  81    .confs = (USBDescConfig[]) {
  82        {
  83            .bNumInterfaces        = 1,
  84            .bConfigurationValue   = 1,
  85            .iConfiguration        = STR_CONFIG_FULL,
  86            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
  87            .nif = 1,
  88            .ifs = &desc_iface_full,
  89        },
  90    },
  91};
  92
  93static const USBDescIface desc_iface_high = {
  94    .bInterfaceNumber              = 0,
  95    .bNumEndpoints                 = 2,
  96    .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
  97    .bInterfaceSubClass            = 0x06, /* SCSI */
  98    .bInterfaceProtocol            = 0x50, /* Bulk */
  99    .eps = (USBDescEndpoint[]) {
 100        {
 101            .bEndpointAddress      = USB_DIR_IN | 0x01,
 102            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 103            .wMaxPacketSize        = 512,
 104        },{
 105            .bEndpointAddress      = USB_DIR_OUT | 0x02,
 106            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 107            .wMaxPacketSize        = 512,
 108        },
 109    }
 110};
 111
 112static const USBDescDevice desc_device_high = {
 113    .bcdUSB                        = 0x0200,
 114    .bMaxPacketSize0               = 64,
 115    .bNumConfigurations            = 1,
 116    .confs = (USBDescConfig[]) {
 117        {
 118            .bNumInterfaces        = 1,
 119            .bConfigurationValue   = 1,
 120            .iConfiguration        = STR_CONFIG_HIGH,
 121            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
 122            .nif = 1,
 123            .ifs = &desc_iface_high,
 124        },
 125    },
 126};
 127
 128static const USBDescIface desc_iface_super = {
 129    .bInterfaceNumber              = 0,
 130    .bNumEndpoints                 = 2,
 131    .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
 132    .bInterfaceSubClass            = 0x06, /* SCSI */
 133    .bInterfaceProtocol            = 0x50, /* Bulk */
 134    .eps = (USBDescEndpoint[]) {
 135        {
 136            .bEndpointAddress      = USB_DIR_IN | 0x01,
 137            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 138            .wMaxPacketSize        = 1024,
 139            .bMaxBurst             = 15,
 140        },{
 141            .bEndpointAddress      = USB_DIR_OUT | 0x02,
 142            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
 143            .wMaxPacketSize        = 1024,
 144            .bMaxBurst             = 15,
 145        },
 146    }
 147};
 148
 149static const USBDescDevice desc_device_super = {
 150    .bcdUSB                        = 0x0300,
 151    .bMaxPacketSize0               = 9,
 152    .bNumConfigurations            = 1,
 153    .confs = (USBDescConfig[]) {
 154        {
 155            .bNumInterfaces        = 1,
 156            .bConfigurationValue   = 1,
 157            .iConfiguration        = STR_CONFIG_SUPER,
 158            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
 159            .nif = 1,
 160            .ifs = &desc_iface_super,
 161        },
 162    },
 163};
 164
 165static const USBDesc desc = {
 166    .id = {
 167        .idVendor          = 0x46f4, /* CRC16() of "QEMU" */
 168        .idProduct         = 0x0001,
 169        .bcdDevice         = 0,
 170        .iManufacturer     = STR_MANUFACTURER,
 171        .iProduct          = STR_PRODUCT,
 172        .iSerialNumber     = STR_SERIALNUMBER,
 173    },
 174    .full  = &desc_device_full,
 175    .high  = &desc_device_high,
 176    .super = &desc_device_super,
 177    .str   = desc_strings,
 178};
 179
 180static void usb_msd_packet_complete(MSDState *s)
 181{
 182    USBPacket *p = s->packet;
 183
 184    /*
 185     * Set s->packet to NULL before calling usb_packet_complete
 186     * because another request may be issued before
 187     * usb_packet_complete returns.
 188     */
 189    trace_usb_msd_packet_complete();
 190    s->packet = NULL;
 191    usb_packet_complete(&s->dev, p);
 192}
 193
 194static void usb_msd_fatal_error(MSDState *s)
 195{
 196    trace_usb_msd_fatal_error();
 197
 198    if (s->packet) {
 199        s->packet->status = USB_RET_STALL;
 200        usb_msd_packet_complete(s);
 201    }
 202
 203    /*
 204     * Guest messed up up device state with illegal requests.  Go
 205     * ignore any requests until the guests resets the device (and
 206     * brings it into a known state that way).
 207     */
 208    s->needs_reset = true;
 209}
 210
 211static void usb_msd_copy_data(MSDState *s, USBPacket *p)
 212{
 213    uint32_t len;
 214    len = p->iov.size - p->actual_length;
 215    if (len > s->scsi_len)
 216        len = s->scsi_len;
 217    usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len);
 218    s->scsi_len -= len;
 219    s->scsi_off += len;
 220    if (len > s->data_len) {
 221        len = s->data_len;
 222    }
 223    s->data_len -= len;
 224    if (s->scsi_len == 0 || s->data_len == 0) {
 225        scsi_req_continue(s->req);
 226    }
 227}
 228
 229static void usb_msd_send_status(MSDState *s, USBPacket *p)
 230{
 231    int len;
 232
 233    trace_usb_msd_send_status(s->csw.status, le32_to_cpu(s->csw.tag),
 234                              p->iov.size);
 235
 236    assert(s->csw.sig == cpu_to_le32(0x53425355));
 237    len = MIN(sizeof(s->csw), p->iov.size);
 238    usb_packet_copy(p, &s->csw, len);
 239    memset(&s->csw, 0, sizeof(s->csw));
 240}
 241
 242void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
 243{
 244    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 245    USBPacket *p = s->packet;
 246
 247    if ((s->mode == USB_MSDM_DATAOUT) != (req->cmd.mode == SCSI_XFER_TO_DEV)) {
 248        usb_msd_fatal_error(s);
 249        return;
 250    }
 251
 252    s->scsi_len = len;
 253    s->scsi_off = 0;
 254    if (p) {
 255        usb_msd_copy_data(s, p);
 256        p = s->packet;
 257        if (p && p->actual_length == p->iov.size) {
 258            p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
 259            usb_msd_packet_complete(s);
 260        }
 261    }
 262}
 263
 264void usb_msd_command_complete(SCSIRequest *req, size_t resid)
 265{
 266    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 267    USBPacket *p = s->packet;
 268
 269    trace_usb_msd_cmd_complete(req->status, req->tag);
 270
 271    s->csw.sig = cpu_to_le32(0x53425355);
 272    s->csw.tag = cpu_to_le32(req->tag);
 273    s->csw.residue = cpu_to_le32(s->data_len);
 274    s->csw.status = req->status != 0;
 275
 276    if (s->packet) {
 277        if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
 278            /* A deferred packet with no write data remaining must be
 279               the status read packet.  */
 280            usb_msd_send_status(s, p);
 281            s->mode = USB_MSDM_CBW;
 282        } else if (s->mode == USB_MSDM_CSW) {
 283            usb_msd_send_status(s, p);
 284            s->mode = USB_MSDM_CBW;
 285        } else {
 286            if (s->data_len) {
 287                int len = (p->iov.size - p->actual_length);
 288                usb_packet_skip(p, len);
 289                if (len > s->data_len) {
 290                    len = s->data_len;
 291                }
 292                s->data_len -= len;
 293            }
 294            if (s->data_len == 0) {
 295                s->mode = USB_MSDM_CSW;
 296            }
 297        }
 298        p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
 299        usb_msd_packet_complete(s);
 300    } else if (s->data_len == 0) {
 301        s->mode = USB_MSDM_CSW;
 302    }
 303    scsi_req_unref(req);
 304    s->req = NULL;
 305}
 306
 307void usb_msd_request_cancelled(SCSIRequest *req)
 308{
 309    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 310
 311    trace_usb_msd_cmd_cancel(req->tag);
 312
 313    if (req == s->req) {
 314        s->csw.sig = cpu_to_le32(0x53425355);
 315        s->csw.tag = cpu_to_le32(req->tag);
 316        s->csw.status = 1; /* error */
 317
 318        scsi_req_unref(s->req);
 319        s->req = NULL;
 320        s->scsi_len = 0;
 321    }
 322}
 323
 324void usb_msd_handle_reset(USBDevice *dev)
 325{
 326    MSDState *s = (MSDState *)dev;
 327
 328    trace_usb_msd_reset();
 329    if (s->req) {
 330        scsi_req_cancel(s->req);
 331    }
 332    assert(s->req == NULL);
 333
 334    if (s->packet) {
 335        s->packet->status = USB_RET_STALL;
 336        usb_msd_packet_complete(s);
 337    }
 338
 339    memset(&s->csw, 0, sizeof(s->csw));
 340    s->mode = USB_MSDM_CBW;
 341
 342    s->needs_reset = false;
 343}
 344
 345static void usb_msd_handle_control(USBDevice *dev, USBPacket *p,
 346               int request, int value, int index, int length, uint8_t *data)
 347{
 348    MSDState *s = (MSDState *)dev;
 349    SCSIDevice *scsi_dev;
 350    int ret, maxlun;
 351
 352    ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
 353    if (ret >= 0) {
 354        return;
 355    }
 356
 357    switch (request) {
 358    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
 359        break;
 360        /* Class specific requests.  */
 361    case ClassInterfaceOutRequest | MassStorageReset:
 362        /* Reset state ready for the next CBW.  */
 363        s->mode = USB_MSDM_CBW;
 364        break;
 365    case ClassInterfaceRequest | GetMaxLun:
 366        maxlun = 0;
 367        for (;;) {
 368            scsi_dev = scsi_device_find(&s->bus, 0, 0, maxlun+1);
 369            if (scsi_dev == NULL) {
 370                break;
 371            }
 372            if (scsi_dev->lun != maxlun+1) {
 373                break;
 374            }
 375            maxlun++;
 376        }
 377        trace_usb_msd_maxlun(maxlun);
 378        data[0] = maxlun;
 379        p->actual_length = 1;
 380        break;
 381    default:
 382        p->status = USB_RET_STALL;
 383        break;
 384    }
 385}
 386
 387static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p)
 388{
 389    MSDState *s = USB_STORAGE_DEV(dev);
 390
 391    assert(s->packet == p);
 392    s->packet = NULL;
 393
 394    if (s->req) {
 395        scsi_req_cancel(s->req);
 396    }
 397}
 398
 399static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
 400{
 401    MSDState *s = (MSDState *)dev;
 402    uint32_t tag;
 403    struct usb_msd_cbw cbw;
 404    uint8_t devep = p->ep->nr;
 405    SCSIDevice *scsi_dev;
 406    uint32_t len;
 407
 408    if (s->needs_reset) {
 409        p->status = USB_RET_STALL;
 410        return;
 411    }
 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            scsi_dev = scsi_device_find(&s->bus, 0, 0, cbw.lun);
 431            if (scsi_dev == NULL) {
 432                error_report("usb-msd: Bad LUN %d", cbw.lun);
 433                goto fail;
 434            }
 435            tag = le32_to_cpu(cbw.tag);
 436            s->data_len = le32_to_cpu(cbw.data_len);
 437            if (s->data_len == 0) {
 438                s->mode = USB_MSDM_CSW;
 439            } else if (cbw.flags & 0x80) {
 440                s->mode = USB_MSDM_DATAIN;
 441            } else {
 442                s->mode = USB_MSDM_DATAOUT;
 443            }
 444            trace_usb_msd_cmd_submit(cbw.lun, tag, cbw.flags,
 445                                     cbw.cmd_len, s->data_len);
 446            assert(le32_to_cpu(s->csw.residue) == 0);
 447            s->scsi_len = 0;
 448            s->req = scsi_req_new(scsi_dev, tag, cbw.lun, cbw.cmd, cbw.cmd_len, NULL);
 449            if (s->commandlog) {
 450                scsi_req_print(s->req);
 451            }
 452            len = scsi_req_enqueue(s->req);
 453            if (len) {
 454                scsi_req_continue(s->req);
 455            }
 456            break;
 457
 458        case USB_MSDM_DATAOUT:
 459            trace_usb_msd_data_out(p->iov.size, s->data_len);
 460            if (p->iov.size > s->data_len) {
 461                goto fail;
 462            }
 463
 464            if (s->scsi_len) {
 465                usb_msd_copy_data(s, p);
 466            }
 467            if (le32_to_cpu(s->csw.residue)) {
 468                int len = p->iov.size - p->actual_length;
 469                if (len) {
 470                    usb_packet_skip(p, len);
 471                    if (len > s->data_len) {
 472                        len = s->data_len;
 473                    }
 474                    s->data_len -= len;
 475                    if (s->data_len == 0) {
 476                        s->mode = USB_MSDM_CSW;
 477                    }
 478                }
 479            }
 480            if (p->actual_length < p->iov.size) {
 481                trace_usb_msd_packet_async();
 482                s->packet = p;
 483                p->status = USB_RET_ASYNC;
 484            }
 485            break;
 486
 487        default:
 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            trace_usb_msd_packet_async();
 503            s->packet = p;
 504            p->status = USB_RET_ASYNC;
 505            break;
 506
 507        case USB_MSDM_CSW:
 508            if (p->iov.size < 13) {
 509                goto fail;
 510            }
 511
 512            if (s->req) {
 513                /* still in flight */
 514                trace_usb_msd_packet_async();
 515                s->packet = p;
 516                p->status = USB_RET_ASYNC;
 517            } else {
 518                usb_msd_send_status(s, p);
 519                s->mode = USB_MSDM_CBW;
 520            }
 521            break;
 522
 523        case USB_MSDM_DATAIN:
 524            trace_usb_msd_data_in(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                    if (len > s->data_len) {
 533                        len = s->data_len;
 534                    }
 535                    s->data_len -= len;
 536                    if (s->data_len == 0) {
 537                        s->mode = USB_MSDM_CSW;
 538                    }
 539                }
 540            }
 541            if (p->actual_length < p->iov.size && s->mode == USB_MSDM_DATAIN) {
 542                trace_usb_msd_packet_async();
 543                s->packet = p;
 544                p->status = USB_RET_ASYNC;
 545            }
 546            break;
 547
 548        default:
 549            goto fail;
 550        }
 551        break;
 552
 553    default:
 554    fail:
 555        p->status = USB_RET_STALL;
 556        break;
 557    }
 558}
 559
 560void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req)
 561{
 562    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 563
 564    /* nothing to load, just store req in our state struct */
 565    assert(s->req == NULL);
 566    scsi_req_ref(req);
 567    s->req = req;
 568    return NULL;
 569}
 570
 571static const VMStateDescription vmstate_usb_msd = {
 572    .name = "usb-storage",
 573    .version_id = 1,
 574    .minimum_version_id = 1,
 575    .fields = (VMStateField[]) {
 576        VMSTATE_USB_DEVICE(dev, MSDState),
 577        VMSTATE_UINT32(mode, MSDState),
 578        VMSTATE_UINT32(scsi_len, MSDState),
 579        VMSTATE_UINT32(scsi_off, MSDState),
 580        VMSTATE_UINT32(data_len, MSDState),
 581        VMSTATE_UINT32(csw.sig, MSDState),
 582        VMSTATE_UINT32(csw.tag, MSDState),
 583        VMSTATE_UINT32(csw.residue, MSDState),
 584        VMSTATE_UINT8(csw.status, MSDState),
 585        VMSTATE_END_OF_LIST()
 586    }
 587};
 588
 589static void usb_msd_class_initfn_common(ObjectClass *klass, void *data)
 590{
 591    DeviceClass *dc = DEVICE_CLASS(klass);
 592    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 593
 594    uc->product_desc   = "QEMU USB MSD";
 595    uc->usb_desc       = &desc;
 596    uc->cancel_packet  = usb_msd_cancel_io;
 597    uc->handle_attach  = usb_desc_attach;
 598    uc->handle_reset   = usb_msd_handle_reset;
 599    uc->handle_control = usb_msd_handle_control;
 600    uc->handle_data    = usb_msd_handle_data;
 601    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 602    dc->fw_name = "storage";
 603    dc->vmsd = &vmstate_usb_msd;
 604}
 605
 606static const TypeInfo usb_storage_dev_type_info = {
 607    .name = TYPE_USB_STORAGE,
 608    .parent = TYPE_USB_DEVICE,
 609    .instance_size = sizeof(MSDState),
 610    .abstract = true,
 611    .class_init = usb_msd_class_initfn_common,
 612};
 613
 614static void usb_msd_register_types(void)
 615{
 616    type_register_static(&usb_storage_dev_type_info);
 617}
 618
 619type_init(usb_msd_register_types)
 620