Statistics
| Branch: | Revision:

root / hw / usb / dev-storage.c @ 71938a09

History | View | Annotate | Download (21.7 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

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

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

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

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

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

    
638
    return 0;
639
}
640

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

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

    
651
    return 0;
652
}
653

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

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

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

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

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

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

    
708
    return dev;
709
}
710

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

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

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

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

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

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

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

    
765
    uc->init = usb_msd_initfn_bot;
766
    usb_msd_class_initfn_common(klass);
767
}
768

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

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

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

    
790
type_init(usb_msd_register_types)