qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

dev-storage.c (17763B)


      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 
     30 struct 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 
     40 enum {
     41     STR_MANUFACTURER = 1,
     42     STR_PRODUCT,
     43     STR_SERIALNUMBER,
     44     STR_CONFIG_FULL,
     45     STR_CONFIG_HIGH,
     46     STR_CONFIG_SUPER,
     47 };
     48 
     49 static 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 
     58 static 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 
     77 static 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 
     93 static 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 
    112 static 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 
    128 static 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 
    149 static 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 
    165 static 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 
    180 static 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 
    194 static 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 
    211 static 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 
    229 static 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 
    242 void 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 
    264 void 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 
    307 void 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 
    324 void 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 
    345 static 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 
    387 static 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 
    399 static 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 
    560 void *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 
    571 static 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 
    589 static 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 
    606 static 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 
    614 static void usb_msd_register_types(void)
    615 {
    616     type_register_static(&usb_storage_dev_type_info);
    617 }
    618 
    619 type_init(usb_msd_register_types)