]> Git Repo - qemu.git/blob - hw/usb-msd.c
usb-storage: don't call usb_packet_complete twice
[qemu.git] / hw / usb-msd.c
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 "usb-desc.h"
15 #include "scsi.h"
16 #include "console.h"
17 #include "monitor.h"
18 #include "sysemu.h"
19 #include "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 typedef struct {
42     USBDevice dev;
43     enum USBMSDMode mode;
44     uint32_t scsi_len;
45     uint8_t *scsi_buf;
46     uint32_t usb_len;
47     uint8_t *usb_buf;
48     uint32_t data_len;
49     uint32_t residue;
50     uint32_t tag;
51     SCSIBus bus;
52     BlockConf conf;
53     SCSIDevice *scsi_dev;
54     uint32_t removable;
55     int result;
56     /* For async completion.  */
57     USBPacket *packet;
58 } MSDState;
59
60 struct usb_msd_cbw {
61     uint32_t sig;
62     uint32_t tag;
63     uint32_t data_len;
64     uint8_t flags;
65     uint8_t lun;
66     uint8_t cmd_len;
67     uint8_t cmd[16];
68 };
69
70 struct usb_msd_csw {
71     uint32_t sig;
72     uint32_t tag;
73     uint32_t residue;
74     uint8_t status;
75 };
76
77 enum {
78     STR_MANUFACTURER = 1,
79     STR_PRODUCT,
80     STR_SERIALNUMBER,
81     STR_CONFIG_FULL,
82     STR_CONFIG_HIGH,
83 };
84
85 static const USBDescStrings desc_strings = {
86     [STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
87     [STR_PRODUCT]      = "QEMU USB HARDDRIVE",
88     [STR_SERIALNUMBER] = "1",
89     [STR_CONFIG_FULL]  = "Full speed config (usb 1.1)",
90     [STR_CONFIG_HIGH]  = "High speed config (usb 2.0)",
91 };
92
93 static const USBDescIface desc_iface_full = {
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        = 64,
104         },{
105             .bEndpointAddress      = USB_DIR_OUT | 0x02,
106             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
107             .wMaxPacketSize        = 64,
108         },
109     }
110 };
111
112 static const USBDescDevice desc_device_full = {
113     .bcdUSB                        = 0x0200,
114     .bMaxPacketSize0               = 8,
115     .bNumConfigurations            = 1,
116     .confs = (USBDescConfig[]) {
117         {
118             .bNumInterfaces        = 1,
119             .bConfigurationValue   = 1,
120             .iConfiguration        = STR_CONFIG_FULL,
121             .bmAttributes          = 0xc0,
122             .nif = 1,
123             .ifs = &desc_iface_full,
124         },
125     },
126 };
127
128 static const USBDescIface desc_iface_high = {
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        = 512,
139         },{
140             .bEndpointAddress      = USB_DIR_OUT | 0x02,
141             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
142             .wMaxPacketSize        = 512,
143         },
144     }
145 };
146
147 static const USBDescDevice desc_device_high = {
148     .bcdUSB                        = 0x0200,
149     .bMaxPacketSize0               = 64,
150     .bNumConfigurations            = 1,
151     .confs = (USBDescConfig[]) {
152         {
153             .bNumInterfaces        = 1,
154             .bConfigurationValue   = 1,
155             .iConfiguration        = STR_CONFIG_HIGH,
156             .bmAttributes          = 0xc0,
157             .nif = 1,
158             .ifs = &desc_iface_high,
159         },
160     },
161 };
162
163 static const USBDesc desc = {
164     .id = {
165         .idVendor          = 0,
166         .idProduct         = 0,
167         .bcdDevice         = 0,
168         .iManufacturer     = STR_MANUFACTURER,
169         .iProduct          = STR_PRODUCT,
170         .iSerialNumber     = STR_SERIALNUMBER,
171     },
172     .full = &desc_device_full,
173     .high = &desc_device_high,
174     .str  = desc_strings,
175 };
176
177 static void usb_msd_copy_data(MSDState *s)
178 {
179     uint32_t len;
180     len = s->usb_len;
181     if (len > s->scsi_len)
182         len = s->scsi_len;
183     if (s->mode == USB_MSDM_DATAIN) {
184         memcpy(s->usb_buf, s->scsi_buf, len);
185     } else {
186         memcpy(s->scsi_buf, s->usb_buf, len);
187     }
188     s->usb_len -= len;
189     s->scsi_len -= len;
190     s->usb_buf += len;
191     s->scsi_buf += len;
192     s->data_len -= len;
193     if (s->scsi_len == 0 || s->data_len == 0) {
194         if (s->mode == USB_MSDM_DATAIN) {
195             s->scsi_dev->info->read_data(s->scsi_dev, s->tag);
196         } else if (s->mode == USB_MSDM_DATAOUT) {
197             s->scsi_dev->info->write_data(s->scsi_dev, s->tag);
198         }
199     }
200 }
201
202 static void usb_msd_send_status(MSDState *s, USBPacket *p)
203 {
204     struct usb_msd_csw csw;
205     int len;
206
207     csw.sig = cpu_to_le32(0x53425355);
208     csw.tag = cpu_to_le32(s->tag);
209     csw.residue = s->residue;
210     csw.status = s->result;
211
212     len = MIN(sizeof(csw), p->len);
213     memcpy(p->data, &csw, len);
214 }
215
216 static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag,
217                                      uint32_t arg)
218 {
219     MSDState *s = DO_UPCAST(MSDState, dev.qdev, bus->qbus.parent);
220     USBPacket *p = s->packet;
221
222     if (tag != s->tag) {
223         fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", tag);
224     }
225     if (reason == SCSI_REASON_DONE) {
226         DPRINTF("Command complete %d\n", arg);
227         s->residue = s->data_len;
228         s->result = arg != 0;
229         if (s->packet) {
230             if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
231                 /* A deferred packet with no write data remaining must be
232                    the status read packet.  */
233                 usb_msd_send_status(s, p);
234                 s->mode = USB_MSDM_CBW;
235             } else {
236                 if (s->data_len) {
237                     s->data_len -= s->usb_len;
238                     if (s->mode == USB_MSDM_DATAIN)
239                         memset(s->usb_buf, 0, s->usb_len);
240                     s->usb_len = 0;
241                 }
242                 if (s->data_len == 0)
243                     s->mode = USB_MSDM_CSW;
244             }
245             s->packet = NULL;
246             usb_packet_complete(&s->dev, p);
247         } else if (s->data_len == 0) {
248             s->mode = USB_MSDM_CSW;
249         }
250         return;
251     }
252     s->scsi_len = arg;
253     s->scsi_buf = s->scsi_dev->info->get_buf(s->scsi_dev, tag);
254     if (p) {
255         usb_msd_copy_data(s);
256         if (s->packet && s->usb_len == 0) {
257             /* Set s->packet to NULL before calling usb_packet_complete
258                because another request may be issued before
259                usb_packet_complete returns.  */
260             DPRINTF("Packet complete %p\n", p);
261             s->packet = NULL;
262             usb_packet_complete(&s->dev, p);
263         }
264     }
265 }
266
267 static void usb_msd_handle_reset(USBDevice *dev)
268 {
269     MSDState *s = (MSDState *)dev;
270
271     DPRINTF("Reset\n");
272     s->mode = USB_MSDM_CBW;
273 }
274
275 static int usb_msd_handle_control(USBDevice *dev, USBPacket *p,
276                int request, int value, int index, int length, uint8_t *data)
277 {
278     MSDState *s = (MSDState *)dev;
279     int ret;
280
281     ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
282     if (ret >= 0) {
283         return ret;
284     }
285
286     ret = 0;
287     switch (request) {
288     case DeviceRequest | USB_REQ_GET_INTERFACE:
289         data[0] = 0;
290         ret = 1;
291         break;
292     case DeviceOutRequest | USB_REQ_SET_INTERFACE:
293         ret = 0;
294         break;
295     case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
296         ret = 0;
297         break;
298     case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
299         ret = 0;
300         break;
301         /* Class specific requests.  */
302     case ClassInterfaceOutRequest | MassStorageReset:
303         /* Reset state ready for the next CBW.  */
304         s->mode = USB_MSDM_CBW;
305         ret = 0;
306         break;
307     case ClassInterfaceRequest | GetMaxLun:
308         data[0] = 0;
309         ret = 1;
310         break;
311     default:
312         ret = USB_RET_STALL;
313         break;
314     }
315     return ret;
316 }
317
318 static void usb_msd_cancel_io(USBPacket *p, void *opaque)
319 {
320     MSDState *s = opaque;
321     s->scsi_dev->info->cancel_io(s->scsi_dev, s->tag);
322     s->packet = NULL;
323     s->scsi_len = 0;
324 }
325
326 static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
327 {
328     MSDState *s = (MSDState *)dev;
329     int ret = 0;
330     struct usb_msd_cbw cbw;
331     uint8_t devep = p->devep;
332     uint8_t *data = p->data;
333     int len = p->len;
334
335     switch (p->pid) {
336     case USB_TOKEN_OUT:
337         if (devep != 2)
338             goto fail;
339
340         switch (s->mode) {
341         case USB_MSDM_CBW:
342             if (len != 31) {
343                 fprintf(stderr, "usb-msd: Bad CBW size");
344                 goto fail;
345             }
346             memcpy(&cbw, data, 31);
347             if (le32_to_cpu(cbw.sig) != 0x43425355) {
348                 fprintf(stderr, "usb-msd: Bad signature %08x\n",
349                         le32_to_cpu(cbw.sig));
350                 goto fail;
351             }
352             DPRINTF("Command on LUN %d\n", cbw.lun);
353             if (cbw.lun != 0) {
354                 fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun);
355                 goto fail;
356             }
357             s->tag = le32_to_cpu(cbw.tag);
358             s->data_len = le32_to_cpu(cbw.data_len);
359             if (s->data_len == 0) {
360                 s->mode = USB_MSDM_CSW;
361             } else if (cbw.flags & 0x80) {
362                 s->mode = USB_MSDM_DATAIN;
363             } else {
364                 s->mode = USB_MSDM_DATAOUT;
365             }
366             DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
367                     s->tag, cbw.flags, cbw.cmd_len, s->data_len);
368             s->residue = 0;
369             s->scsi_len = 0;
370             s->scsi_dev->info->send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
371             /* ??? Should check that USB and SCSI data transfer
372                directions match.  */
373             if (s->residue == 0) {
374                 if (s->mode == USB_MSDM_DATAIN) {
375                     s->scsi_dev->info->read_data(s->scsi_dev, s->tag);
376                 } else if (s->mode == USB_MSDM_DATAOUT) {
377                     s->scsi_dev->info->write_data(s->scsi_dev, s->tag);
378                 }
379             }
380             ret = len;
381             break;
382
383         case USB_MSDM_DATAOUT:
384             DPRINTF("Data out %d/%d\n", len, s->data_len);
385             if (len > s->data_len)
386                 goto fail;
387
388             s->usb_buf = data;
389             s->usb_len = len;
390             if (s->scsi_len) {
391                 usb_msd_copy_data(s);
392             }
393             if (s->residue && s->usb_len) {
394                 s->data_len -= s->usb_len;
395                 if (s->data_len == 0)
396                     s->mode = USB_MSDM_CSW;
397                 s->usb_len = 0;
398             }
399             if (s->usb_len) {
400                 DPRINTF("Deferring packet %p\n", p);
401                 usb_defer_packet(p, usb_msd_cancel_io, s);
402                 s->packet = p;
403                 ret = USB_RET_ASYNC;
404             } else {
405                 ret = len;
406             }
407             break;
408
409         default:
410             DPRINTF("Unexpected write (len %d)\n", len);
411             goto fail;
412         }
413         break;
414
415     case USB_TOKEN_IN:
416         if (devep != 1)
417             goto fail;
418
419         switch (s->mode) {
420         case USB_MSDM_DATAOUT:
421             if (s->data_len != 0 || len < 13)
422                 goto fail;
423             /* Waiting for SCSI write to complete.  */
424             usb_defer_packet(p, usb_msd_cancel_io, s);
425             s->packet = p;
426             ret = USB_RET_ASYNC;
427             break;
428
429         case USB_MSDM_CSW:
430             DPRINTF("Command status %d tag 0x%x, len %d\n",
431                     s->result, s->tag, len);
432             if (len < 13)
433                 goto fail;
434
435             usb_msd_send_status(s, p);
436             s->mode = USB_MSDM_CBW;
437             ret = 13;
438             break;
439
440         case USB_MSDM_DATAIN:
441             DPRINTF("Data in %d/%d, scsi_len %d\n", len, s->data_len, s->scsi_len);
442             if (len > s->data_len)
443                 len = s->data_len;
444             s->usb_buf = data;
445             s->usb_len = len;
446             if (s->scsi_len) {
447                 usb_msd_copy_data(s);
448             }
449             if (s->residue && s->usb_len) {
450                 s->data_len -= s->usb_len;
451                 memset(s->usb_buf, 0, s->usb_len);
452                 if (s->data_len == 0)
453                     s->mode = USB_MSDM_CSW;
454                 s->usb_len = 0;
455             }
456             if (s->usb_len) {
457                 DPRINTF("Deferring packet %p\n", p);
458                 usb_defer_packet(p, usb_msd_cancel_io, s);
459                 s->packet = p;
460                 ret = USB_RET_ASYNC;
461             } else {
462                 ret = len;
463             }
464             break;
465
466         default:
467             DPRINTF("Unexpected read (len %d)\n", len);
468             goto fail;
469         }
470         break;
471
472     default:
473         DPRINTF("Bad token\n");
474     fail:
475         ret = USB_RET_STALL;
476         break;
477     }
478
479     return ret;
480 }
481
482 static void usb_msd_password_cb(void *opaque, int err)
483 {
484     MSDState *s = opaque;
485
486     if (!err)
487         usb_device_attach(&s->dev);
488     else
489         qdev_unplug(&s->dev.qdev);
490 }
491
492 static int usb_msd_initfn(USBDevice *dev)
493 {
494     MSDState *s = DO_UPCAST(MSDState, dev, dev);
495     BlockDriverState *bs = s->conf.bs;
496     DriveInfo *dinfo;
497
498     if (!bs) {
499         error_report("usb-msd: drive property not set");
500         return -1;
501     }
502
503     /*
504      * Hack alert: this pretends to be a block device, but it's really
505      * a SCSI bus that can serve only a single device, which it
506      * creates automatically.  But first it needs to detach from its
507      * blockdev, or else scsi_bus_legacy_add_drive() dies when it
508      * attaches again.
509      *
510      * The hack is probably a bad idea.
511      */
512     bdrv_detach(bs, &s->dev.qdev);
513     s->conf.bs = NULL;
514
515     dinfo = drive_get_by_blockdev(bs);
516     if (dinfo && dinfo->serial) {
517         usb_desc_set_string(dev, STR_SERIALNUMBER, dinfo->serial);
518     }
519
520     usb_desc_init(dev);
521     scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete);
522     s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable);
523     if (!s->scsi_dev) {
524         return -1;
525     }
526     s->bus.qbus.allow_hotplug = 0;
527     usb_msd_handle_reset(dev);
528
529     if (bdrv_key_required(bs)) {
530         if (cur_mon) {
531             monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb, s);
532             s->dev.auto_attach = 0;
533         } else {
534             autostart = 0;
535         }
536     }
537
538     add_boot_device_path(s->conf.bootindex, &dev->qdev, "/disk@0,0");
539     return 0;
540 }
541
542 static USBDevice *usb_msd_init(const char *filename)
543 {
544     static int nr=0;
545     char id[8];
546     QemuOpts *opts;
547     DriveInfo *dinfo;
548     USBDevice *dev;
549     const char *p1;
550     char fmt[32];
551
552     /* parse -usbdevice disk: syntax into drive opts */
553     snprintf(id, sizeof(id), "usb%d", nr++);
554     opts = qemu_opts_create(qemu_find_opts("drive"), id, 0);
555
556     p1 = strchr(filename, ':');
557     if (p1++) {
558         const char *p2;
559
560         if (strstart(filename, "format=", &p2)) {
561             int len = MIN(p1 - p2, sizeof(fmt));
562             pstrcpy(fmt, len, p2);
563             qemu_opt_set(opts, "format", fmt);
564         } else if (*filename != ':') {
565             printf("unrecognized USB mass-storage option %s\n", filename);
566             return NULL;
567         }
568         filename = p1;
569     }
570     if (!*filename) {
571         printf("block device specification needed\n");
572         return NULL;
573     }
574     qemu_opt_set(opts, "file", filename);
575     qemu_opt_set(opts, "if", "none");
576
577     /* create host drive */
578     dinfo = drive_init(opts, 0);
579     if (!dinfo) {
580         qemu_opts_del(opts);
581         return NULL;
582     }
583
584     /* create guest device */
585     dev = usb_create(NULL /* FIXME */, "usb-storage");
586     if (!dev) {
587         return NULL;
588     }
589     if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
590         qdev_free(&dev->qdev);
591         return NULL;
592     }
593     if (qdev_init(&dev->qdev) < 0)
594         return NULL;
595
596     return dev;
597 }
598
599 static struct USBDeviceInfo msd_info = {
600     .product_desc   = "QEMU USB MSD",
601     .qdev.name      = "usb-storage",
602     .qdev.fw_name      = "storage",
603     .qdev.size      = sizeof(MSDState),
604     .usb_desc       = &desc,
605     .init           = usb_msd_initfn,
606     .handle_packet  = usb_generic_handle_packet,
607     .handle_attach  = usb_desc_attach,
608     .handle_reset   = usb_msd_handle_reset,
609     .handle_control = usb_msd_handle_control,
610     .handle_data    = usb_msd_handle_data,
611     .usbdevice_name = "disk",
612     .usbdevice_init = usb_msd_init,
613     .qdev.props     = (Property[]) {
614         DEFINE_BLOCK_PROPERTIES(MSDState, conf),
615         DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
616         DEFINE_PROP_END_OF_LIST(),
617     },
618 };
619
620 static void usb_msd_register_devices(void)
621 {
622     usb_qdev_register(&msd_info);
623 }
624 device_init(usb_msd_register_devices)
This page took 0.058931 seconds and 4 git commands to generate.