Statistics
| Branch: | Revision:

root / hw / usb / dev-storage.c @ caad4eb3

History | View | Annotate | Download (21.8 kB)

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-common.h"
11
#include "qemu/option.h"
12
#include "qemu/config-file.h"
13
#include "hw/usb.h"
14
#include "hw/usb/desc.h"
15
#include "hw/scsi/scsi.h"
16
#include "ui/console.h"
17
#include "monitor/monitor.h"
18
#include "sysemu/sysemu.h"
19
#include "sysemu/blockdev.h"
20

    
21
//#define DEBUG_MSD
22

    
23
#ifdef DEBUG_MSD
24
#define DPRINTF(fmt, ...) \
25
do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0)
26
#else
27
#define DPRINTF(fmt, ...) do {} while(0)
28
#endif
29

    
30
/* USB requests.  */
31
#define MassStorageReset  0xff
32
#define GetMaxLun         0xfe
33

    
34
enum USBMSDMode {
35
    USB_MSDM_CBW, /* Command Block.  */
36
    USB_MSDM_DATAOUT, /* Transfer data to device.  */
37
    USB_MSDM_DATAIN, /* Transfer data from device.  */
38
    USB_MSDM_CSW /* Command Status.  */
39
};
40

    
41
struct usb_msd_csw {
42
    uint32_t sig;
43
    uint32_t tag;
44
    uint32_t residue;
45
    uint8_t status;
46
};
47

    
48
typedef struct {
49
    USBDevice dev;
50
    enum USBMSDMode mode;
51
    uint32_t scsi_off;
52
    uint32_t scsi_len;
53
    uint32_t data_len;
54
    struct usb_msd_csw csw;
55
    SCSIRequest *req;
56
    SCSIBus bus;
57
    /* For async completion.  */
58
    USBPacket *packet;
59
    /* usb-storage only */
60
    BlockConf conf;
61
    uint32_t removable;
62
} MSDState;
63

    
64
struct usb_msd_cbw {
65
    uint32_t sig;
66
    uint32_t tag;
67
    uint32_t data_len;
68
    uint8_t flags;
69
    uint8_t lun;
70
    uint8_t cmd_len;
71
    uint8_t cmd[16];
72
};
73

    
74
enum {
75
    STR_MANUFACTURER = 1,
76
    STR_PRODUCT,
77
    STR_SERIALNUMBER,
78
    STR_CONFIG_FULL,
79
    STR_CONFIG_HIGH,
80
    STR_CONFIG_SUPER,
81
};
82

    
83
static const USBDescStrings desc_strings = {
84
    [STR_MANUFACTURER] = "QEMU",
85
    [STR_PRODUCT]      = "QEMU USB HARDDRIVE",
86
    [STR_SERIALNUMBER] = "1",
87
    [STR_CONFIG_FULL]  = "Full speed config (usb 1.1)",
88
    [STR_CONFIG_HIGH]  = "High speed config (usb 2.0)",
89
    [STR_CONFIG_SUPER] = "Super speed config (usb 3.0)",
90
};
91

    
92
static const USBDescIface desc_iface_full = {
93
    .bInterfaceNumber              = 0,
94
    .bNumEndpoints                 = 2,
95
    .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
96
    .bInterfaceSubClass            = 0x06, /* SCSI */
97
    .bInterfaceProtocol            = 0x50, /* Bulk */
98
    .eps = (USBDescEndpoint[]) {
99
        {
100
            .bEndpointAddress      = USB_DIR_IN | 0x01,
101
            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
102
            .wMaxPacketSize        = 64,
103
        },{
104
            .bEndpointAddress      = USB_DIR_OUT | 0x02,
105
            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
106
            .wMaxPacketSize        = 64,
107
        },
108
    }
109
};
110

    
111
static const USBDescDevice desc_device_full = {
112
    .bcdUSB                        = 0x0200,
113
    .bMaxPacketSize0               = 8,
114
    .bNumConfigurations            = 1,
115
    .confs = (USBDescConfig[]) {
116
        {
117
            .bNumInterfaces        = 1,
118
            .bConfigurationValue   = 1,
119
            .iConfiguration        = STR_CONFIG_FULL,
120
            .bmAttributes          = 0xc0,
121
            .nif = 1,
122
            .ifs = &desc_iface_full,
123
        },
124
    },
125
};
126

    
127
static const USBDescIface desc_iface_high = {
128
    .bInterfaceNumber              = 0,
129
    .bNumEndpoints                 = 2,
130
    .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
131
    .bInterfaceSubClass            = 0x06, /* SCSI */
132
    .bInterfaceProtocol            = 0x50, /* Bulk */
133
    .eps = (USBDescEndpoint[]) {
134
        {
135
            .bEndpointAddress      = USB_DIR_IN | 0x01,
136
            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
137
            .wMaxPacketSize        = 512,
138
        },{
139
            .bEndpointAddress      = USB_DIR_OUT | 0x02,
140
            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
141
            .wMaxPacketSize        = 512,
142
        },
143
    }
144
};
145

    
146
static const USBDescDevice desc_device_high = {
147
    .bcdUSB                        = 0x0200,
148
    .bMaxPacketSize0               = 64,
149
    .bNumConfigurations            = 1,
150
    .confs = (USBDescConfig[]) {
151
        {
152
            .bNumInterfaces        = 1,
153
            .bConfigurationValue   = 1,
154
            .iConfiguration        = STR_CONFIG_HIGH,
155
            .bmAttributes          = 0xc0,
156
            .nif = 1,
157
            .ifs = &desc_iface_high,
158
        },
159
    },
160
};
161

    
162
static const USBDescIface desc_iface_super = {
163
    .bInterfaceNumber              = 0,
164
    .bNumEndpoints                 = 2,
165
    .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
166
    .bInterfaceSubClass            = 0x06, /* SCSI */
167
    .bInterfaceProtocol            = 0x50, /* Bulk */
168
    .eps = (USBDescEndpoint[]) {
169
        {
170
            .bEndpointAddress      = USB_DIR_IN | 0x01,
171
            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
172
            .wMaxPacketSize        = 1024,
173
            .bMaxBurst             = 15,
174
        },{
175
            .bEndpointAddress      = USB_DIR_OUT | 0x02,
176
            .bmAttributes          = USB_ENDPOINT_XFER_BULK,
177
            .wMaxPacketSize        = 1024,
178
            .bMaxBurst             = 15,
179
        },
180
    }
181
};
182

    
183
static const USBDescDevice desc_device_super = {
184
    .bcdUSB                        = 0x0300,
185
    .bMaxPacketSize0               = 9,
186
    .bNumConfigurations            = 1,
187
    .confs = (USBDescConfig[]) {
188
        {
189
            .bNumInterfaces        = 1,
190
            .bConfigurationValue   = 1,
191
            .iConfiguration        = STR_CONFIG_SUPER,
192
            .bmAttributes          = 0xc0,
193
            .nif = 1,
194
            .ifs = &desc_iface_super,
195
        },
196
    },
197
};
198

    
199
static const USBDesc desc = {
200
    .id = {
201
        .idVendor          = 0x46f4, /* CRC16() of "QEMU" */
202
        .idProduct         = 0x0001,
203
        .bcdDevice         = 0,
204
        .iManufacturer     = STR_MANUFACTURER,
205
        .iProduct          = STR_PRODUCT,
206
        .iSerialNumber     = STR_SERIALNUMBER,
207
    },
208
    .full  = &desc_device_full,
209
    .high  = &desc_device_high,
210
    .super = &desc_device_super,
211
    .str   = desc_strings,
212
};
213

    
214
static void usb_msd_copy_data(MSDState *s, USBPacket *p)
215
{
216
    uint32_t len;
217
    len = p->iov.size - p->actual_length;
218
    if (len > s->scsi_len)
219
        len = s->scsi_len;
220
    usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len);
221
    s->scsi_len -= len;
222
    s->scsi_off += len;
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
    DPRINTF("Command status %d tag 0x%x, len %zd\n",
234
            s->csw.status, le32_to_cpu(s->csw.tag), 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
static void usb_msd_packet_complete(MSDState *s)
243
{
244
    USBPacket *p = s->packet;
245

    
246
    /* Set s->packet to NULL before calling usb_packet_complete
247
       because another request may be issued before
248
       usb_packet_complete returns.  */
249
    DPRINTF("Packet complete %p\n", p);
250
    s->packet = NULL;
251
    usb_packet_complete(&s->dev, p);
252
}
253

    
254
static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
255
{
256
    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
257
    USBPacket *p = s->packet;
258

    
259
    assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV));
260
    s->scsi_len = len;
261
    s->scsi_off = 0;
262
    if (p) {
263
        usb_msd_copy_data(s, p);
264
        p = s->packet;
265
        if (p && p->actual_length == p->iov.size) {
266
            p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
267
            usb_msd_packet_complete(s);
268
        }
269
    }
270
}
271

    
272
static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, size_t resid)
273
{
274
    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
275
    USBPacket *p = s->packet;
276

    
277
    DPRINTF("Command complete %d tag 0x%x\n", status, req->tag);
278

    
279
    s->csw.sig = cpu_to_le32(0x53425355);
280
    s->csw.tag = cpu_to_le32(req->tag);
281
    s->csw.residue = cpu_to_le32(s->data_len);
282
    s->csw.status = status != 0;
283

    
284
    if (s->packet) {
285
        if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
286
            /* A deferred packet with no write data remaining must be
287
               the status read packet.  */
288
            usb_msd_send_status(s, p);
289
            s->mode = USB_MSDM_CBW;
290
        } else if (s->mode == USB_MSDM_CSW) {
291
            usb_msd_send_status(s, p);
292
            s->mode = USB_MSDM_CBW;
293
        } else {
294
            if (s->data_len) {
295
                int len = (p->iov.size - p->actual_length);
296
                usb_packet_skip(p, len);
297
                s->data_len -= len;
298
            }
299
            if (s->data_len == 0) {
300
                s->mode = USB_MSDM_CSW;
301
            }
302
        }
303
        p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
304
        usb_msd_packet_complete(s);
305
    } else if (s->data_len == 0) {
306
        s->mode = USB_MSDM_CSW;
307
    }
308
    scsi_req_unref(req);
309
    s->req = NULL;
310
}
311

    
312
static void usb_msd_request_cancelled(SCSIRequest *req)
313
{
314
    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
315

    
316
    if (req == s->req) {
317
        scsi_req_unref(s->req);
318
        s->req = NULL;
319
        s->scsi_len = 0;
320
    }
321
}
322

    
323
static void usb_msd_handle_reset(USBDevice *dev)
324
{
325
    MSDState *s = (MSDState *)dev;
326

    
327
    DPRINTF("Reset\n");
328
    if (s->req) {
329
        scsi_req_cancel(s->req);
330
    }
331
    assert(s->req == NULL);
332

    
333
    if (s->packet) {
334
        s->packet->status = USB_RET_STALL;
335
        usb_msd_packet_complete(s);
336
    }
337

    
338
    s->mode = USB_MSDM_CBW;
339
}
340

    
341
static void usb_msd_handle_control(USBDevice *dev, USBPacket *p,
342
               int request, int value, int index, int length, uint8_t *data)
343
{
344
    MSDState *s = (MSDState *)dev;
345
    SCSIDevice *scsi_dev;
346
    int ret, maxlun;
347

    
348
    ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
349
    if (ret >= 0) {
350
        return;
351
    }
352

    
353
    switch (request) {
354
    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
355
        break;
356
        /* Class specific requests.  */
357
    case ClassInterfaceOutRequest | MassStorageReset:
358
        /* Reset state ready for the next CBW.  */
359
        s->mode = USB_MSDM_CBW;
360
        break;
361
    case ClassInterfaceRequest | GetMaxLun:
362
        maxlun = 0;
363
        for (;;) {
364
            scsi_dev = scsi_device_find(&s->bus, 0, 0, maxlun+1);
365
            if (scsi_dev == NULL) {
366
                break;
367
            }
368
            if (scsi_dev->lun != maxlun+1) {
369
                break;
370
            }
371
            maxlun++;
372
        }
373
        DPRINTF("MaxLun %d\n", maxlun);
374
        data[0] = maxlun;
375
        p->actual_length = 1;
376
        break;
377
    default:
378
        p->status = USB_RET_STALL;
379
        break;
380
    }
381
}
382

    
383
static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p)
384
{
385
    MSDState *s = DO_UPCAST(MSDState, dev, dev);
386

    
387
    assert(s->packet == p);
388
    s->packet = NULL;
389

    
390
    if (s->req) {
391
        scsi_req_cancel(s->req);
392
    }
393
}
394

    
395
static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
396
{
397
    MSDState *s = (MSDState *)dev;
398
    uint32_t tag;
399
    struct usb_msd_cbw cbw;
400
    uint8_t devep = p->ep->nr;
401
    SCSIDevice *scsi_dev;
402
    uint32_t len;
403

    
404
    switch (p->pid) {
405
    case USB_TOKEN_OUT:
406
        if (devep != 2)
407
            goto fail;
408

    
409
        switch (s->mode) {
410
        case USB_MSDM_CBW:
411
            if (p->iov.size != 31) {
412
                fprintf(stderr, "usb-msd: Bad CBW size");
413
                goto fail;
414
            }
415
            usb_packet_copy(p, &cbw, 31);
416
            if (le32_to_cpu(cbw.sig) != 0x43425355) {
417
                fprintf(stderr, "usb-msd: Bad signature %08x\n",
418
                        le32_to_cpu(cbw.sig));
419
                goto fail;
420
            }
421
            DPRINTF("Command on LUN %d\n", cbw.lun);
422
            scsi_dev = scsi_device_find(&s->bus, 0, 0, cbw.lun);
423
            if (scsi_dev == NULL) {
424
                fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun);
425
                goto fail;
426
            }
427
            tag = le32_to_cpu(cbw.tag);
428
            s->data_len = le32_to_cpu(cbw.data_len);
429
            if (s->data_len == 0) {
430
                s->mode = USB_MSDM_CSW;
431
            } else if (cbw.flags & 0x80) {
432
                s->mode = USB_MSDM_DATAIN;
433
            } else {
434
                s->mode = USB_MSDM_DATAOUT;
435
            }
436
            DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
437
                    tag, cbw.flags, cbw.cmd_len, s->data_len);
438
            assert(le32_to_cpu(s->csw.residue) == 0);
439
            s->scsi_len = 0;
440
            s->req = scsi_req_new(scsi_dev, tag, cbw.lun, cbw.cmd, NULL);
441
#ifdef DEBUG_MSD
442
            scsi_req_print(s->req);
443
#endif
444
            len = scsi_req_enqueue(s->req);
445
            if (len) {
446
                scsi_req_continue(s->req);
447
            }
448
            break;
449

    
450
        case USB_MSDM_DATAOUT:
451
            DPRINTF("Data out %zd/%d\n", p->iov.size, s->data_len);
452
            if (p->iov.size > s->data_len) {
453
                goto fail;
454
            }
455

    
456
            if (s->scsi_len) {
457
                usb_msd_copy_data(s, p);
458
            }
459
            if (le32_to_cpu(s->csw.residue)) {
460
                int len = p->iov.size - p->actual_length;
461
                if (len) {
462
                    usb_packet_skip(p, len);
463
                    s->data_len -= len;
464
                    if (s->data_len == 0) {
465
                        s->mode = USB_MSDM_CSW;
466
                    }
467
                }
468
            }
469
            if (p->actual_length < p->iov.size) {
470
                DPRINTF("Deferring packet %p [wait data-out]\n", p);
471
                s->packet = p;
472
                p->status = USB_RET_ASYNC;
473
            }
474
            break;
475

    
476
        default:
477
            DPRINTF("Unexpected write (len %zd)\n", p->iov.size);
478
            goto fail;
479
        }
480
        break;
481

    
482
    case USB_TOKEN_IN:
483
        if (devep != 1)
484
            goto fail;
485

    
486
        switch (s->mode) {
487
        case USB_MSDM_DATAOUT:
488
            if (s->data_len != 0 || p->iov.size < 13) {
489
                goto fail;
490
            }
491
            /* Waiting for SCSI write to complete.  */
492
            s->packet = p;
493
            p->status = USB_RET_ASYNC;
494
            break;
495

    
496
        case USB_MSDM_CSW:
497
            if (p->iov.size < 13) {
498
                goto fail;
499
            }
500

    
501
            if (s->req) {
502
                /* still in flight */
503
                DPRINTF("Deferring packet %p [wait status]\n", p);
504
                s->packet = p;
505
                p->status = USB_RET_ASYNC;
506
            } else {
507
                usb_msd_send_status(s, p);
508
                s->mode = USB_MSDM_CBW;
509
            }
510
            break;
511

    
512
        case USB_MSDM_DATAIN:
513
            DPRINTF("Data in %zd/%d, scsi_len %d\n",
514
                    p->iov.size, s->data_len, s->scsi_len);
515
            if (s->scsi_len) {
516
                usb_msd_copy_data(s, p);
517
            }
518
            if (le32_to_cpu(s->csw.residue)) {
519
                int len = p->iov.size - p->actual_length;
520
                if (len) {
521
                    usb_packet_skip(p, len);
522
                    s->data_len -= len;
523
                    if (s->data_len == 0) {
524
                        s->mode = USB_MSDM_CSW;
525
                    }
526
                }
527
            }
528
            if (p->actual_length < p->iov.size) {
529
                DPRINTF("Deferring packet %p [wait data-in]\n", p);
530
                s->packet = p;
531
                p->status = USB_RET_ASYNC;
532
            }
533
            break;
534

    
535
        default:
536
            DPRINTF("Unexpected read (len %zd)\n", p->iov.size);
537
            goto fail;
538
        }
539
        break;
540

    
541
    default:
542
        DPRINTF("Bad token\n");
543
    fail:
544
        p->status = USB_RET_STALL;
545
        break;
546
    }
547
}
548

    
549
static void usb_msd_password_cb(void *opaque, int err)
550
{
551
    MSDState *s = opaque;
552

    
553
    if (!err)
554
        err = usb_device_attach(&s->dev);
555

    
556
    if (err)
557
        qdev_unplug(&s->dev.qdev, NULL);
558
}
559

    
560
static 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 struct SCSIBusInfo usb_msd_scsi_info_storage = {
572
    .tcq = false,
573
    .max_target = 0,
574
    .max_lun = 0,
575

    
576
    .transfer_data = usb_msd_transfer_data,
577
    .complete = usb_msd_command_complete,
578
    .cancel = usb_msd_request_cancelled,
579
    .load_request = usb_msd_load_request,
580
};
581

    
582
static const struct SCSIBusInfo usb_msd_scsi_info_bot = {
583
    .tcq = false,
584
    .max_target = 0,
585
    .max_lun = 15,
586

    
587
    .transfer_data = usb_msd_transfer_data,
588
    .complete = usb_msd_command_complete,
589
    .cancel = usb_msd_request_cancelled,
590
    .load_request = usb_msd_load_request,
591
};
592

    
593
static int usb_msd_initfn_storage(USBDevice *dev)
594
{
595
    MSDState *s = DO_UPCAST(MSDState, dev, dev);
596
    BlockDriverState *bs = s->conf.bs;
597
    SCSIDevice *scsi_dev;
598
    Error *err = NULL;
599

    
600
    if (!bs) {
601
        error_report("drive property not set");
602
        return -1;
603
    }
604

    
605
    blkconf_serial(&s->conf, &dev->serial);
606

    
607
    /*
608
     * Hack alert: this pretends to be a block device, but it's really
609
     * a SCSI bus that can serve only a single device, which it
610
     * creates automatically.  But first it needs to detach from its
611
     * blockdev, or else scsi_bus_legacy_add_drive() dies when it
612
     * attaches again.
613
     *
614
     * The hack is probably a bad idea.
615
     */
616
    bdrv_detach_dev(bs, &s->dev.qdev);
617
    s->conf.bs = NULL;
618

    
619
    usb_desc_create_serial(dev);
620
    usb_desc_init(dev);
621
    scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_storage, NULL);
622
    scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable,
623
                                         s->conf.bootindex, dev->serial,
624
                                         &err);
625
    if (!scsi_dev) {
626
        return -1;
627
    }
628
    s->bus.qbus.allow_hotplug = 0;
629
    usb_msd_handle_reset(dev);
630

    
631
    if (bdrv_key_required(bs)) {
632
        if (cur_mon) {
633
            monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb, s);
634
            s->dev.auto_attach = 0;
635
        } else {
636
            autostart = 0;
637
        }
638
    }
639

    
640
    return 0;
641
}
642

    
643
static int usb_msd_initfn_bot(USBDevice *dev)
644
{
645
    MSDState *s = DO_UPCAST(MSDState, dev, dev);
646

    
647
    usb_desc_create_serial(dev);
648
    usb_desc_init(dev);
649
    scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_bot, NULL);
650
    s->bus.qbus.allow_hotplug = 0;
651
    usb_msd_handle_reset(dev);
652

    
653
    return 0;
654
}
655

    
656
static USBDevice *usb_msd_init(USBBus *bus, const char *filename)
657
{
658
    static int nr=0;
659
    char id[8];
660
    QemuOpts *opts;
661
    DriveInfo *dinfo;
662
    USBDevice *dev;
663
    const char *p1;
664
    char fmt[32];
665

    
666
    /* parse -usbdevice disk: syntax into drive opts */
667
    snprintf(id, sizeof(id), "usb%d", nr++);
668
    opts = qemu_opts_create(qemu_find_opts("drive"), id, 0, NULL);
669

    
670
    p1 = strchr(filename, ':');
671
    if (p1++) {
672
        const char *p2;
673

    
674
        if (strstart(filename, "format=", &p2)) {
675
            int len = MIN(p1 - p2, sizeof(fmt));
676
            pstrcpy(fmt, len, p2);
677
            qemu_opt_set(opts, "format", fmt);
678
        } else if (*filename != ':') {
679
            printf("unrecognized USB mass-storage option %s\n", filename);
680
            return NULL;
681
        }
682
        filename = p1;
683
    }
684
    if (!*filename) {
685
        printf("block device specification needed\n");
686
        return NULL;
687
    }
688
    qemu_opt_set(opts, "file", filename);
689
    qemu_opt_set(opts, "if", "none");
690

    
691
    /* create host drive */
692
    dinfo = drive_init(opts, 0);
693
    if (!dinfo) {
694
        qemu_opts_del(opts);
695
        return NULL;
696
    }
697

    
698
    /* create guest device */
699
    dev = usb_create(bus, "usb-storage");
700
    if (!dev) {
701
        return NULL;
702
    }
703
    if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
704
        qdev_free(&dev->qdev);
705
        return NULL;
706
    }
707
    if (qdev_init(&dev->qdev) < 0)
708
        return NULL;
709

    
710
    return dev;
711
}
712

    
713
static const VMStateDescription vmstate_usb_msd = {
714
    .name = "usb-storage",
715
    .version_id = 1,
716
    .minimum_version_id = 1,
717
    .fields = (VMStateField []) {
718
        VMSTATE_USB_DEVICE(dev, MSDState),
719
        VMSTATE_UINT32(mode, MSDState),
720
        VMSTATE_UINT32(scsi_len, MSDState),
721
        VMSTATE_UINT32(scsi_off, MSDState),
722
        VMSTATE_UINT32(data_len, MSDState),
723
        VMSTATE_UINT32(csw.sig, MSDState),
724
        VMSTATE_UINT32(csw.tag, MSDState),
725
        VMSTATE_UINT32(csw.residue, MSDState),
726
        VMSTATE_UINT8(csw.status, MSDState),
727
        VMSTATE_END_OF_LIST()
728
    }
729
};
730

    
731
static Property msd_properties[] = {
732
    DEFINE_BLOCK_PROPERTIES(MSDState, conf),
733
    DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
734
    DEFINE_PROP_END_OF_LIST(),
735
};
736

    
737
static void usb_msd_class_initfn_common(ObjectClass *klass)
738
{
739
    DeviceClass *dc = DEVICE_CLASS(klass);
740
    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
741

    
742
    uc->product_desc   = "QEMU USB MSD";
743
    uc->usb_desc       = &desc;
744
    uc->cancel_packet  = usb_msd_cancel_io;
745
    uc->handle_attach  = usb_desc_attach;
746
    uc->handle_reset   = usb_msd_handle_reset;
747
    uc->handle_control = usb_msd_handle_control;
748
    uc->handle_data    = usb_msd_handle_data;
749
    dc->fw_name = "storage";
750
    dc->vmsd = &vmstate_usb_msd;
751
}
752

    
753
static void usb_msd_class_initfn_storage(ObjectClass *klass, void *data)
754
{
755
    DeviceClass *dc = DEVICE_CLASS(klass);
756
    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
757

    
758
    uc->init = usb_msd_initfn_storage;
759
    dc->props = msd_properties;
760
    usb_msd_class_initfn_common(klass);
761
}
762

    
763
static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
764
{
765
    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
766

    
767
    uc->init = usb_msd_initfn_bot;
768
    usb_msd_class_initfn_common(klass);
769
}
770

    
771
static const TypeInfo msd_info = {
772
    .name          = "usb-storage",
773
    .parent        = TYPE_USB_DEVICE,
774
    .instance_size = sizeof(MSDState),
775
    .class_init    = usb_msd_class_initfn_storage,
776
};
777

    
778
static const TypeInfo bot_info = {
779
    .name          = "usb-bot",
780
    .parent        = TYPE_USB_DEVICE,
781
    .instance_size = sizeof(MSDState),
782
    .class_init    = usb_msd_class_initfn_bot,
783
};
784

    
785
static void usb_msd_register_types(void)
786
{
787
    type_register_static(&msd_info);
788
    type_register_static(&bot_info);
789
    usb_legacy_register("usb-storage", "disk", usb_msd_init);
790
}
791

    
792
type_init(usb_msd_register_types)