Statistics
| Branch: | Revision:

root / hw / usb-msd.c @ e7b43f7e

History | View | Annotate | Download (17.9 kB)

1
/*
2
 * USB Mass Storage Device emulation
3
 *
4
 * Copyright (c) 2006 CodeSourcery.
5
 * Written by Paul Brook
6
 *
7
 * This code is licenced under the LGPL.
8
 */
9

    
10
#include "qemu-common.h"
11
#include "qemu-option.h"
12
#include "qemu-config.h"
13
#include "usb.h"
14
#include "scsi.h"
15
#include "console.h"
16
#include "monitor.h"
17
#include "sysemu.h"
18
#include "blockdev.h"
19

    
20
//#define DEBUG_MSD
21

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

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

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

    
40
typedef struct {
41
    USBDevice dev;
42
    enum USBMSDMode mode;
43
    uint32_t scsi_len;
44
    uint8_t *scsi_buf;
45
    uint32_t usb_len;
46
    uint8_t *usb_buf;
47
    uint32_t data_len;
48
    uint32_t residue;
49
    uint32_t tag;
50
    SCSIBus bus;
51
    BlockConf conf;
52
    SCSIDevice *scsi_dev;
53
    int result;
54
    /* For async completion.  */
55
    USBPacket *packet;
56
} MSDState;
57

    
58
struct usb_msd_cbw {
59
    uint32_t sig;
60
    uint32_t tag;
61
    uint32_t data_len;
62
    uint8_t flags;
63
    uint8_t lun;
64
    uint8_t cmd_len;
65
    uint8_t cmd[16];
66
};
67

    
68
struct usb_msd_csw {
69
    uint32_t sig;
70
    uint32_t tag;
71
    uint32_t residue;
72
    uint8_t status;
73
};
74

    
75
static const uint8_t qemu_msd_dev_descriptor[] = {
76
        0x12,       /*  u8 bLength; */
77
        0x01,       /*  u8 bDescriptorType; Device */
78
        0x00, 0x01, /*  u16 bcdUSB; v1.0 */
79

    
80
        0x00,            /*  u8  bDeviceClass; */
81
        0x00,            /*  u8  bDeviceSubClass; */
82
        0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
83
        0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
84

    
85
        /* Vendor and product id are arbitrary.  */
86
        0x00, 0x00, /*  u16 idVendor; */
87
         0x00, 0x00, /*  u16 idProduct; */
88
        0x00, 0x00, /*  u16 bcdDevice */
89

    
90
        0x01,       /*  u8  iManufacturer; */
91
        0x02,       /*  u8  iProduct; */
92
        0x03,       /*  u8  iSerialNumber; */
93
        0x01        /*  u8  bNumConfigurations; */
94
};
95

    
96
static const uint8_t qemu_msd_config_descriptor[] = {
97

    
98
        /* one configuration */
99
        0x09,       /*  u8  bLength; */
100
        0x02,       /*  u8  bDescriptorType; Configuration */
101
        0x20, 0x00, /*  u16 wTotalLength; */
102
        0x01,       /*  u8  bNumInterfaces; (1) */
103
        0x01,       /*  u8  bConfigurationValue; */
104
        0x00,       /*  u8  iConfiguration; */
105
        0xc0,       /*  u8  bmAttributes;
106
                                 Bit 7: must be set,
107
                                     6: Self-powered,
108
                                     5: Remote wakeup,
109
                                     4..0: resvd */
110
        0x00,       /*  u8  MaxPower; */
111

    
112
        /* one interface */
113
        0x09,       /*  u8  if_bLength; */
114
        0x04,       /*  u8  if_bDescriptorType; Interface */
115
        0x00,       /*  u8  if_bInterfaceNumber; */
116
        0x00,       /*  u8  if_bAlternateSetting; */
117
        0x02,       /*  u8  if_bNumEndpoints; */
118
        0x08,       /*  u8  if_bInterfaceClass; MASS STORAGE */
119
        0x06,       /*  u8  if_bInterfaceSubClass; SCSI */
120
        0x50,       /*  u8  if_bInterfaceProtocol; Bulk Only */
121
        0x00,       /*  u8  if_iInterface; */
122

    
123
        /* Bulk-In endpoint */
124
        0x07,       /*  u8  ep_bLength; */
125
        0x05,       /*  u8  ep_bDescriptorType; Endpoint */
126
        0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
127
         0x02,       /*  u8  ep_bmAttributes; Bulk */
128
         0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
129
        0x00,       /*  u8  ep_bInterval; */
130

    
131
        /* Bulk-Out endpoint */
132
        0x07,       /*  u8  ep_bLength; */
133
        0x05,       /*  u8  ep_bDescriptorType; Endpoint */
134
        0x02,       /*  u8  ep_bEndpointAddress; OUT Endpoint 2 */
135
         0x02,       /*  u8  ep_bmAttributes; Bulk */
136
         0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
137
        0x00        /*  u8  ep_bInterval; */
138
};
139

    
140
static void usb_msd_copy_data(MSDState *s)
141
{
142
    uint32_t len;
143
    len = s->usb_len;
144
    if (len > s->scsi_len)
145
        len = s->scsi_len;
146
    if (s->mode == USB_MSDM_DATAIN) {
147
        memcpy(s->usb_buf, s->scsi_buf, len);
148
    } else {
149
        memcpy(s->scsi_buf, s->usb_buf, len);
150
    }
151
    s->usb_len -= len;
152
    s->scsi_len -= len;
153
    s->usb_buf += len;
154
    s->scsi_buf += len;
155
    s->data_len -= len;
156
    if (s->scsi_len == 0) {
157
        if (s->mode == USB_MSDM_DATAIN) {
158
            s->scsi_dev->info->read_data(s->scsi_dev, s->tag);
159
        } else if (s->mode == USB_MSDM_DATAOUT) {
160
            s->scsi_dev->info->write_data(s->scsi_dev, s->tag);
161
        }
162
    }
163
}
164

    
165
static void usb_msd_send_status(MSDState *s)
166
{
167
    struct usb_msd_csw csw;
168

    
169
    csw.sig = cpu_to_le32(0x53425355);
170
    csw.tag = cpu_to_le32(s->tag);
171
    csw.residue = s->residue;
172
    csw.status = s->result;
173
    memcpy(s->usb_buf, &csw, 13);
174
}
175

    
176
static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag,
177
                                     uint32_t arg)
178
{
179
    MSDState *s = DO_UPCAST(MSDState, dev.qdev, bus->qbus.parent);
180
    USBPacket *p = s->packet;
181

    
182
    if (tag != s->tag) {
183
        fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", tag);
184
    }
185
    if (reason == SCSI_REASON_DONE) {
186
        DPRINTF("Command complete %d\n", arg);
187
        s->residue = s->data_len;
188
        s->result = arg != 0;
189
        if (s->packet) {
190
            if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
191
                /* A deferred packet with no write data remaining must be
192
                   the status read packet.  */
193
                usb_msd_send_status(s);
194
                s->mode = USB_MSDM_CBW;
195
            } else {
196
                if (s->data_len) {
197
                    s->data_len -= s->usb_len;
198
                    if (s->mode == USB_MSDM_DATAIN)
199
                        memset(s->usb_buf, 0, s->usb_len);
200
                    s->usb_len = 0;
201
                }
202
                if (s->data_len == 0)
203
                    s->mode = USB_MSDM_CSW;
204
            }
205
            s->packet = NULL;
206
            usb_packet_complete(p);
207
        } else if (s->data_len == 0) {
208
            s->mode = USB_MSDM_CSW;
209
        }
210
        return;
211
    }
212
    s->scsi_len = arg;
213
    s->scsi_buf = s->scsi_dev->info->get_buf(s->scsi_dev, tag);
214
    if (p) {
215
        usb_msd_copy_data(s);
216
        if (s->usb_len == 0) {
217
            /* Set s->packet to NULL before calling usb_packet_complete
218
               because annother request may be issued before
219
               usb_packet_complete returns.  */
220
            DPRINTF("Packet complete %p\n", p);
221
            s->packet = NULL;
222
            usb_packet_complete(p);
223
        }
224
    }
225
}
226

    
227
static void usb_msd_handle_reset(USBDevice *dev)
228
{
229
    MSDState *s = (MSDState *)dev;
230

    
231
    DPRINTF("Reset\n");
232
    s->mode = USB_MSDM_CBW;
233
}
234

    
235
static int usb_msd_handle_control(USBDevice *dev, int request, int value,
236
                                  int index, int length, uint8_t *data)
237
{
238
    MSDState *s = (MSDState *)dev;
239
    int ret = 0;
240

    
241
    switch (request) {
242
    case DeviceRequest | USB_REQ_GET_STATUS:
243
        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
244
            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
245
        data[1] = 0x00;
246
        ret = 2;
247
        break;
248
    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
249
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
250
            dev->remote_wakeup = 0;
251
        } else {
252
            goto fail;
253
        }
254
        ret = 0;
255
        break;
256
    case DeviceOutRequest | USB_REQ_SET_FEATURE:
257
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
258
            dev->remote_wakeup = 1;
259
        } else {
260
            goto fail;
261
        }
262
        ret = 0;
263
        break;
264
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
265
        dev->addr = value;
266
        ret = 0;
267
        break;
268
    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
269
        switch(value >> 8) {
270
        case USB_DT_DEVICE:
271
            memcpy(data, qemu_msd_dev_descriptor,
272
                   sizeof(qemu_msd_dev_descriptor));
273
            ret = sizeof(qemu_msd_dev_descriptor);
274
            break;
275
        case USB_DT_CONFIG:
276
            memcpy(data, qemu_msd_config_descriptor,
277
                   sizeof(qemu_msd_config_descriptor));
278
            ret = sizeof(qemu_msd_config_descriptor);
279
            break;
280
        case USB_DT_STRING:
281
            switch(value & 0xff) {
282
            case 0:
283
                /* language ids */
284
                data[0] = 4;
285
                data[1] = 3;
286
                data[2] = 0x09;
287
                data[3] = 0x04;
288
                ret = 4;
289
                break;
290
            case 1:
291
                /* vendor description */
292
                ret = set_usb_string(data, "QEMU " QEMU_VERSION);
293
                break;
294
            case 2:
295
                /* product description */
296
                ret = set_usb_string(data, "QEMU USB HARDDRIVE");
297
                break;
298
            case 3:
299
                /* serial number */
300
                ret = set_usb_string(data, "1");
301
                break;
302
            default:
303
                goto fail;
304
            }
305
            break;
306
        default:
307
            goto fail;
308
        }
309
        break;
310
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
311
        data[0] = 1;
312
        ret = 1;
313
        break;
314
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
315
        ret = 0;
316
        break;
317
    case DeviceRequest | USB_REQ_GET_INTERFACE:
318
        data[0] = 0;
319
        ret = 1;
320
        break;
321
    case DeviceOutRequest | USB_REQ_SET_INTERFACE:
322
        ret = 0;
323
        break;
324
    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
325
        ret = 0;
326
        break;
327
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
328
        ret = 0;
329
        break;
330
        /* Class specific requests.  */
331
    case ClassInterfaceOutRequest | MassStorageReset:
332
        /* Reset state ready for the next CBW.  */
333
        s->mode = USB_MSDM_CBW;
334
        ret = 0;
335
        break;
336
    case ClassInterfaceRequest | GetMaxLun:
337
        data[0] = 0;
338
        ret = 1;
339
        break;
340
    default:
341
    fail:
342
        ret = USB_RET_STALL;
343
        break;
344
    }
345
    return ret;
346
}
347

    
348
static void usb_msd_cancel_io(USBPacket *p, void *opaque)
349
{
350
    MSDState *s = opaque;
351
    s->scsi_dev->info->cancel_io(s->scsi_dev, s->tag);
352
    s->packet = NULL;
353
    s->scsi_len = 0;
354
}
355

    
356
static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
357
{
358
    MSDState *s = (MSDState *)dev;
359
    int ret = 0;
360
    struct usb_msd_cbw cbw;
361
    uint8_t devep = p->devep;
362
    uint8_t *data = p->data;
363
    int len = p->len;
364

    
365
    switch (p->pid) {
366
    case USB_TOKEN_OUT:
367
        if (devep != 2)
368
            goto fail;
369

    
370
        switch (s->mode) {
371
        case USB_MSDM_CBW:
372
            if (len != 31) {
373
                fprintf(stderr, "usb-msd: Bad CBW size");
374
                goto fail;
375
            }
376
            memcpy(&cbw, data, 31);
377
            if (le32_to_cpu(cbw.sig) != 0x43425355) {
378
                fprintf(stderr, "usb-msd: Bad signature %08x\n",
379
                        le32_to_cpu(cbw.sig));
380
                goto fail;
381
            }
382
            DPRINTF("Command on LUN %d\n", cbw.lun);
383
            if (cbw.lun != 0) {
384
                fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun);
385
                goto fail;
386
            }
387
            s->tag = le32_to_cpu(cbw.tag);
388
            s->data_len = le32_to_cpu(cbw.data_len);
389
            if (s->data_len == 0) {
390
                s->mode = USB_MSDM_CSW;
391
            } else if (cbw.flags & 0x80) {
392
                s->mode = USB_MSDM_DATAIN;
393
            } else {
394
                s->mode = USB_MSDM_DATAOUT;
395
            }
396
            DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
397
                    s->tag, cbw.flags, cbw.cmd_len, s->data_len);
398
            s->residue = 0;
399
            s->scsi_dev->info->send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
400
            /* ??? Should check that USB and SCSI data transfer
401
               directions match.  */
402
            if (s->residue == 0) {
403
                if (s->mode == USB_MSDM_DATAIN) {
404
                    s->scsi_dev->info->read_data(s->scsi_dev, s->tag);
405
                } else if (s->mode == USB_MSDM_DATAOUT) {
406
                    s->scsi_dev->info->write_data(s->scsi_dev, s->tag);
407
                }
408
            }
409
            ret = len;
410
            break;
411

    
412
        case USB_MSDM_DATAOUT:
413
            DPRINTF("Data out %d/%d\n", len, s->data_len);
414
            if (len > s->data_len)
415
                goto fail;
416

    
417
            s->usb_buf = data;
418
            s->usb_len = len;
419
            if (s->scsi_len) {
420
                usb_msd_copy_data(s);
421
            }
422
            if (s->residue && s->usb_len) {
423
                s->data_len -= s->usb_len;
424
                if (s->data_len == 0)
425
                    s->mode = USB_MSDM_CSW;
426
                s->usb_len = 0;
427
            }
428
            if (s->usb_len) {
429
                DPRINTF("Deferring packet %p\n", p);
430
                usb_defer_packet(p, usb_msd_cancel_io, s);
431
                s->packet = p;
432
                ret = USB_RET_ASYNC;
433
            } else {
434
                ret = len;
435
            }
436
            break;
437

    
438
        default:
439
            DPRINTF("Unexpected write (len %d)\n", len);
440
            goto fail;
441
        }
442
        break;
443

    
444
    case USB_TOKEN_IN:
445
        if (devep != 1)
446
            goto fail;
447

    
448
        switch (s->mode) {
449
        case USB_MSDM_DATAOUT:
450
            if (s->data_len != 0 || len < 13)
451
                goto fail;
452
            /* Waiting for SCSI write to complete.  */
453
            usb_defer_packet(p, usb_msd_cancel_io, s);
454
            s->packet = p;
455
            ret = USB_RET_ASYNC;
456
            break;
457

    
458
        case USB_MSDM_CSW:
459
            DPRINTF("Command status %d tag 0x%x, len %d\n",
460
                    s->result, s->tag, len);
461
            if (len < 13)
462
                goto fail;
463

    
464
            s->usb_len = len;
465
            s->usb_buf = data;
466
            usb_msd_send_status(s);
467
            s->mode = USB_MSDM_CBW;
468
            ret = 13;
469
            break;
470

    
471
        case USB_MSDM_DATAIN:
472
            DPRINTF("Data in %d/%d\n", len, s->data_len);
473
            if (len > s->data_len)
474
                len = s->data_len;
475
            s->usb_buf = data;
476
            s->usb_len = len;
477
            if (s->scsi_len) {
478
                usb_msd_copy_data(s);
479
            }
480
            if (s->residue && s->usb_len) {
481
                s->data_len -= s->usb_len;
482
                memset(s->usb_buf, 0, s->usb_len);
483
                if (s->data_len == 0)
484
                    s->mode = USB_MSDM_CSW;
485
                s->usb_len = 0;
486
            }
487
            if (s->usb_len) {
488
                DPRINTF("Deferring packet %p\n", p);
489
                usb_defer_packet(p, usb_msd_cancel_io, s);
490
                s->packet = p;
491
                ret = USB_RET_ASYNC;
492
            } else {
493
                ret = len;
494
            }
495
            break;
496

    
497
        default:
498
            DPRINTF("Unexpected read (len %d)\n", len);
499
            goto fail;
500
        }
501
        break;
502

    
503
    default:
504
        DPRINTF("Bad token\n");
505
    fail:
506
        ret = USB_RET_STALL;
507
        break;
508
    }
509

    
510
    return ret;
511
}
512

    
513
static void usb_msd_password_cb(void *opaque, int err)
514
{
515
    MSDState *s = opaque;
516

    
517
    if (!err)
518
        usb_device_attach(&s->dev);
519
    else
520
        qdev_unplug(&s->dev.qdev);
521
}
522

    
523
static int usb_msd_initfn(USBDevice *dev)
524
{
525
    MSDState *s = DO_UPCAST(MSDState, dev, dev);
526
    BlockDriverState *bs = s->conf.bs;
527

    
528
    if (!bs) {
529
        error_report("usb-msd: drive property not set");
530
        return -1;
531
    }
532

    
533
    /*
534
     * Hack alert: this pretends to be a block device, but it's really
535
     * a SCSI bus that can serve only a single device, which it
536
     * creates automatically.  But first it needs to detach from its
537
     * blockdev, or else scsi_bus_legacy_add_drive() dies when it
538
     * attaches again.
539
     *
540
     * The hack is probably a bad idea.
541
     */
542
    bdrv_detach(bs, &s->dev.qdev);
543
    s->conf.bs = NULL;
544

    
545
    s->dev.speed = USB_SPEED_FULL;
546
    scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete);
547
    s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0);
548
    if (!s->scsi_dev) {
549
        return -1;
550
    }
551
    s->bus.qbus.allow_hotplug = 0;
552
    usb_msd_handle_reset(dev);
553

    
554
    if (bdrv_key_required(bs)) {
555
        if (cur_mon) {
556
            monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb, s);
557
            s->dev.auto_attach = 0;
558
        } else {
559
            autostart = 0;
560
        }
561
    }
562

    
563
    return 0;
564
}
565

    
566
static USBDevice *usb_msd_init(const char *filename)
567
{
568
    static int nr=0;
569
    char id[8];
570
    QemuOpts *opts;
571
    DriveInfo *dinfo;
572
    USBDevice *dev;
573
    int fatal_error;
574
    const char *p1;
575
    char fmt[32];
576

    
577
    /* parse -usbdevice disk: syntax into drive opts */
578
    snprintf(id, sizeof(id), "usb%d", nr++);
579
    opts = qemu_opts_create(qemu_find_opts("drive"), id, 0);
580

    
581
    p1 = strchr(filename, ':');
582
    if (p1++) {
583
        const char *p2;
584

    
585
        if (strstart(filename, "format=", &p2)) {
586
            int len = MIN(p1 - p2, sizeof(fmt));
587
            pstrcpy(fmt, len, p2);
588
            qemu_opt_set(opts, "format", fmt);
589
        } else if (*filename != ':') {
590
            printf("unrecognized USB mass-storage option %s\n", filename);
591
            return NULL;
592
        }
593
        filename = p1;
594
    }
595
    if (!*filename) {
596
        printf("block device specification needed\n");
597
        return NULL;
598
    }
599
    qemu_opt_set(opts, "file", filename);
600
    qemu_opt_set(opts, "if", "none");
601

    
602
    /* create host drive */
603
    dinfo = drive_init(opts, 0, &fatal_error);
604
    if (!dinfo) {
605
        qemu_opts_del(opts);
606
        return NULL;
607
    }
608

    
609
    /* create guest device */
610
    dev = usb_create(NULL /* FIXME */, "usb-storage");
611
    if (!dev) {
612
        return NULL;
613
    }
614
    if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
615
        qdev_free(&dev->qdev);
616
        return NULL;
617
    }
618
    if (qdev_init(&dev->qdev) < 0)
619
        return NULL;
620

    
621
    return dev;
622
}
623

    
624
static struct USBDeviceInfo msd_info = {
625
    .product_desc   = "QEMU USB MSD",
626
    .qdev.name      = "usb-storage",
627
    .qdev.size      = sizeof(MSDState),
628
    .init           = usb_msd_initfn,
629
    .handle_packet  = usb_generic_handle_packet,
630
    .handle_reset   = usb_msd_handle_reset,
631
    .handle_control = usb_msd_handle_control,
632
    .handle_data    = usb_msd_handle_data,
633
    .usbdevice_name = "disk",
634
    .usbdevice_init = usb_msd_init,
635
    .qdev.props     = (Property[]) {
636
        DEFINE_BLOCK_PROPERTIES(MSDState, conf),
637
        DEFINE_PROP_END_OF_LIST(),
638
    },
639
};
640

    
641
static void usb_msd_register_devices(void)
642
{
643
    usb_qdev_register(&msd_info);
644
}
645
device_init(usb_msd_register_devices)