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_copy_data(MSDState *s, USBPacket *p)
 181{
 182    uint32_t len;
 183    len = p->iov.size - p->actual_length;
 184    if (len > s->scsi_len)
 185        len = s->scsi_len;
 186    usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len);
 187    s->scsi_len -= len;
 188    s->scsi_off += len;
 189    if (len > s->data_len) {
 190        len = s->data_len;
 191    }
 192    s->data_len -= len;
 193    if (s->scsi_len == 0 || s->data_len == 0) {
 194        scsi_req_continue(s->req);
 195    }
 196}
 197
 198static void usb_msd_send_status(MSDState *s, USBPacket *p)
 199{
 200    int len;
 201
 202    trace_usb_msd_send_status(s->csw.status, le32_to_cpu(s->csw.tag),
 203                              p->iov.size);
 204
 205    assert(s->csw.sig == cpu_to_le32(0x53425355));
 206    len = MIN(sizeof(s->csw), p->iov.size);
 207    usb_packet_copy(p, &s->csw, len);
 208    memset(&s->csw, 0, sizeof(s->csw));
 209}
 210
 211static void usb_msd_packet_complete(MSDState *s)
 212{
 213    USBPacket *p = s->packet;
 214
 215    /* Set s->packet to NULL before calling usb_packet_complete
 216       because another request may be issued before
 217       usb_packet_complete returns.  */
 218    trace_usb_msd_packet_complete();
 219    s->packet = NULL;
 220    usb_packet_complete(&s->dev, p);
 221}
 222
 223void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
 224{
 225    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 226    USBPacket *p = s->packet;
 227
 228    assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV));
 229    s->scsi_len = len;
 230    s->scsi_off = 0;
 231    if (p) {
 232        usb_msd_copy_data(s, p);
 233        p = s->packet;
 234        if (p && p->actual_length == p->iov.size) {
 235            p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
 236            usb_msd_packet_complete(s);
 237        }
 238    }
 239}
 240
 241void usb_msd_command_complete(SCSIRequest *req, size_t resid)
 242{
 243    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 244    USBPacket *p = s->packet;
 245
 246    trace_usb_msd_cmd_complete(req->status, req->tag);
 247
 248    s->csw.sig = cpu_to_le32(0x53425355);
 249    s->csw.tag = cpu_to_le32(req->tag);
 250    s->csw.residue = cpu_to_le32(s->data_len);
 251    s->csw.status = req->status != 0;
 252
 253    if (s->packet) {
 254        if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
 255            /* A deferred packet with no write data remaining must be
 256               the status read packet.  */
 257            usb_msd_send_status(s, p);
 258            s->mode = USB_MSDM_CBW;
 259        } else if (s->mode == USB_MSDM_CSW) {
 260            usb_msd_send_status(s, p);
 261            s->mode = USB_MSDM_CBW;
 262        } else {
 263            if (s->data_len) {
 264                int len = (p->iov.size - p->actual_length);
 265                usb_packet_skip(p, len);
 266                if (len > s->data_len) {
 267                    len = s->data_len;
 268                }
 269                s->data_len -= len;
 270            }
 271            if (s->data_len == 0) {
 272                s->mode = USB_MSDM_CSW;
 273            }
 274        }
 275        p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
 276        usb_msd_packet_complete(s);
 277    } else if (s->data_len == 0) {
 278        s->mode = USB_MSDM_CSW;
 279    }
 280    scsi_req_unref(req);
 281    s->req = NULL;
 282}
 283
 284void usb_msd_request_cancelled(SCSIRequest *req)
 285{
 286    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 287
 288    trace_usb_msd_cmd_cancel(req->tag);
 289
 290    if (req == s->req) {
 291        s->csw.sig = cpu_to_le32(0x53425355);
 292        s->csw.tag = cpu_to_le32(req->tag);
 293        s->csw.status = 1; /* error */
 294
 295        scsi_req_unref(s->req);
 296        s->req = NULL;
 297        s->scsi_len = 0;
 298    }
 299}
 300
 301void usb_msd_handle_reset(USBDevice *dev)
 302{
 303    MSDState *s = (MSDState *)dev;
 304
 305    trace_usb_msd_reset();
 306    if (s->req) {
 307        scsi_req_cancel(s->req);
 308    }
 309    assert(s->req == NULL);
 310
 311    if (s->packet) {
 312        s->packet->status = USB_RET_STALL;
 313        usb_msd_packet_complete(s);
 314    }
 315
 316    memset(&s->csw, 0, sizeof(s->csw));
 317    s->mode = USB_MSDM_CBW;
 318}
 319
 320static void usb_msd_handle_control(USBDevice *dev, USBPacket *p,
 321               int request, int value, int index, int length, uint8_t *data)
 322{
 323    MSDState *s = (MSDState *)dev;
 324    SCSIDevice *scsi_dev;
 325    int ret, maxlun;
 326
 327    ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
 328    if (ret >= 0) {
 329        return;
 330    }
 331
 332    switch (request) {
 333    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
 334        break;
 335        /* Class specific requests.  */
 336    case ClassInterfaceOutRequest | MassStorageReset:
 337        /* Reset state ready for the next CBW.  */
 338        s->mode = USB_MSDM_CBW;
 339        break;
 340    case ClassInterfaceRequest | GetMaxLun:
 341        maxlun = 0;
 342        for (;;) {
 343            scsi_dev = scsi_device_find(&s->bus, 0, 0, maxlun+1);
 344            if (scsi_dev == NULL) {
 345                break;
 346            }
 347            if (scsi_dev->lun != maxlun+1) {
 348                break;
 349            }
 350            maxlun++;
 351        }
 352        trace_usb_msd_maxlun(maxlun);
 353        data[0] = maxlun;
 354        p->actual_length = 1;
 355        break;
 356    default:
 357        p->status = USB_RET_STALL;
 358        break;
 359    }
 360}
 361
 362static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p)
 363{
 364    MSDState *s = USB_STORAGE_DEV(dev);
 365
 366    assert(s->packet == p);
 367    s->packet = NULL;
 368
 369    if (s->req) {
 370        scsi_req_cancel(s->req);
 371    }
 372}
 373
 374static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
 375{
 376    MSDState *s = (MSDState *)dev;
 377    uint32_t tag;
 378    struct usb_msd_cbw cbw;
 379    uint8_t devep = p->ep->nr;
 380    SCSIDevice *scsi_dev;
 381    uint32_t len;
 382
 383    switch (p->pid) {
 384    case USB_TOKEN_OUT:
 385        if (devep != 2)
 386            goto fail;
 387
 388        switch (s->mode) {
 389        case USB_MSDM_CBW:
 390            if (p->iov.size != 31) {
 391                error_report("usb-msd: Bad CBW size");
 392                goto fail;
 393            }
 394            usb_packet_copy(p, &cbw, 31);
 395            if (le32_to_cpu(cbw.sig) != 0x43425355) {
 396                error_report("usb-msd: Bad signature %08x",
 397                             le32_to_cpu(cbw.sig));
 398                goto fail;
 399            }
 400            scsi_dev = scsi_device_find(&s->bus, 0, 0, cbw.lun);
 401            if (scsi_dev == NULL) {
 402                error_report("usb-msd: Bad LUN %d", cbw.lun);
 403                goto fail;
 404            }
 405            tag = le32_to_cpu(cbw.tag);
 406            s->data_len = le32_to_cpu(cbw.data_len);
 407            if (s->data_len == 0) {
 408                s->mode = USB_MSDM_CSW;
 409            } else if (cbw.flags & 0x80) {
 410                s->mode = USB_MSDM_DATAIN;
 411            } else {
 412                s->mode = USB_MSDM_DATAOUT;
 413            }
 414            trace_usb_msd_cmd_submit(cbw.lun, tag, cbw.flags,
 415                                     cbw.cmd_len, s->data_len);
 416            assert(le32_to_cpu(s->csw.residue) == 0);
 417            s->scsi_len = 0;
 418            s->req = scsi_req_new(scsi_dev, tag, cbw.lun, cbw.cmd, NULL);
 419            if (s->commandlog) {
 420                scsi_req_print(s->req);
 421            }
 422            len = scsi_req_enqueue(s->req);
 423            if (len) {
 424                scsi_req_continue(s->req);
 425            }
 426            break;
 427
 428        case USB_MSDM_DATAOUT:
 429            trace_usb_msd_data_out(p->iov.size, s->data_len);
 430            if (p->iov.size > s->data_len) {
 431                goto fail;
 432            }
 433
 434            if (s->scsi_len) {
 435                usb_msd_copy_data(s, p);
 436            }
 437            if (le32_to_cpu(s->csw.residue)) {
 438                int len = p->iov.size - p->actual_length;
 439                if (len) {
 440                    usb_packet_skip(p, len);
 441                    if (len > s->data_len) {
 442                        len = s->data_len;
 443                    }
 444                    s->data_len -= len;
 445                    if (s->data_len == 0) {
 446                        s->mode = USB_MSDM_CSW;
 447                    }
 448                }
 449            }
 450            if (p->actual_length < p->iov.size) {
 451                trace_usb_msd_packet_async();
 452                s->packet = p;
 453                p->status = USB_RET_ASYNC;
 454            }
 455            break;
 456
 457        default:
 458            goto fail;
 459        }
 460        break;
 461
 462    case USB_TOKEN_IN:
 463        if (devep != 1)
 464            goto fail;
 465
 466        switch (s->mode) {
 467        case USB_MSDM_DATAOUT:
 468            if (s->data_len != 0 || p->iov.size < 13) {
 469                goto fail;
 470            }
 471            /* Waiting for SCSI write to complete.  */
 472            trace_usb_msd_packet_async();
 473            s->packet = p;
 474            p->status = USB_RET_ASYNC;
 475            break;
 476
 477        case USB_MSDM_CSW:
 478            if (p->iov.size < 13) {
 479                goto fail;
 480            }
 481
 482            if (s->req) {
 483                /* still in flight */
 484                trace_usb_msd_packet_async();
 485                s->packet = p;
 486                p->status = USB_RET_ASYNC;
 487            } else {
 488                usb_msd_send_status(s, p);
 489                s->mode = USB_MSDM_CBW;
 490            }
 491            break;
 492
 493        case USB_MSDM_DATAIN:
 494            trace_usb_msd_data_in(p->iov.size, s->data_len, s->scsi_len);
 495            if (s->scsi_len) {
 496                usb_msd_copy_data(s, p);
 497            }
 498            if (le32_to_cpu(s->csw.residue)) {
 499                int len = p->iov.size - p->actual_length;
 500                if (len) {
 501                    usb_packet_skip(p, len);
 502                    if (len > s->data_len) {
 503                        len = s->data_len;
 504                    }
 505                    s->data_len -= len;
 506                    if (s->data_len == 0) {
 507                        s->mode = USB_MSDM_CSW;
 508                    }
 509                }
 510            }
 511            if (p->actual_length < p->iov.size && s->mode == USB_MSDM_DATAIN) {
 512                trace_usb_msd_packet_async();
 513                s->packet = p;
 514                p->status = USB_RET_ASYNC;
 515            }
 516            break;
 517
 518        default:
 519            goto fail;
 520        }
 521        break;
 522
 523    default:
 524    fail:
 525        p->status = USB_RET_STALL;
 526        break;
 527    }
 528}
 529
 530void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req)
 531{
 532    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
 533
 534    /* nothing to load, just store req in our state struct */
 535    assert(s->req == NULL);
 536    scsi_req_ref(req);
 537    s->req = req;
 538    return NULL;
 539}
 540
 541static const VMStateDescription vmstate_usb_msd = {
 542    .name = "usb-storage",
 543    .version_id = 1,
 544    .minimum_version_id = 1,
 545    .fields = (VMStateField[]) {
 546        VMSTATE_USB_DEVICE(dev, MSDState),
 547        VMSTATE_UINT32(mode, MSDState),
 548        VMSTATE_UINT32(scsi_len, MSDState),
 549        VMSTATE_UINT32(scsi_off, MSDState),
 550        VMSTATE_UINT32(data_len, MSDState),
 551        VMSTATE_UINT32(csw.sig, MSDState),
 552        VMSTATE_UINT32(csw.tag, MSDState),
 553        VMSTATE_UINT32(csw.residue, MSDState),
 554        VMSTATE_UINT8(csw.status, MSDState),
 555        VMSTATE_END_OF_LIST()
 556    }
 557};
 558
 559static void usb_msd_class_initfn_common(ObjectClass *klass, void *data)
 560{
 561    DeviceClass *dc = DEVICE_CLASS(klass);
 562    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 563
 564    uc->product_desc   = "QEMU USB MSD";
 565    uc->usb_desc       = &desc;
 566    uc->cancel_packet  = usb_msd_cancel_io;
 567    uc->handle_attach  = usb_desc_attach;
 568    uc->handle_reset   = usb_msd_handle_reset;
 569    uc->handle_control = usb_msd_handle_control;
 570    uc->handle_data    = usb_msd_handle_data;
 571    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 572    dc->fw_name = "storage";
 573    dc->vmsd = &vmstate_usb_msd;
 574}
 575
 576static const TypeInfo usb_storage_dev_type_info = {
 577    .name = TYPE_USB_STORAGE,
 578    .parent = TYPE_USB_DEVICE,
 579    .instance_size = sizeof(MSDState),
 580    .abstract = true,
 581    .class_init = usb_msd_class_initfn_common,
 582};
 583
 584static void usb_msd_register_types(void)
 585{
 586    type_register_static(&usb_storage_dev_type_info);
 587}
 588
 589type_init(usb_msd_register_types)
 590