• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "usb.h"
12 #include "block.h"
13 #include "scsi-disk.h"
14 #include "console.h"
15 
16 //#define DEBUG_MSD
17 
18 #ifdef DEBUG_MSD
19 #define DPRINTF(fmt, ...) \
20 do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0)
21 #else
22 #define DPRINTF(fmt, ...) do {} while(0)
23 #endif
24 
25 /* USB requests.  */
26 #define MassStorageReset  0xff
27 #define GetMaxLun         0xfe
28 
29 enum USBMSDMode {
30     USB_MSDM_CBW, /* Command Block.  */
31     USB_MSDM_DATAOUT, /* Tranfer data to device.  */
32     USB_MSDM_DATAIN, /* Transfer data from device.  */
33     USB_MSDM_CSW /* Command Status.  */
34 };
35 
36 typedef struct {
37     USBDevice dev;
38     enum USBMSDMode mode;
39     uint32_t scsi_len;
40     uint8_t *scsi_buf;
41     uint32_t usb_len;
42     uint8_t *usb_buf;
43     uint32_t data_len;
44     uint32_t residue;
45     uint32_t tag;
46     BlockDriverState *bs;
47     SCSIDevice *scsi_dev;
48     int result;
49     /* For async completion.  */
50     USBPacket *packet;
51 } MSDState;
52 
53 struct usb_msd_cbw {
54     uint32_t sig;
55     uint32_t tag;
56     uint32_t data_len;
57     uint8_t flags;
58     uint8_t lun;
59     uint8_t cmd_len;
60     uint8_t cmd[16];
61 };
62 
63 struct usb_msd_csw {
64     uint32_t sig;
65     uint32_t tag;
66     uint32_t residue;
67     uint8_t status;
68 };
69 
70 static const uint8_t qemu_msd_dev_descriptor[] = {
71 	0x12,       /*  u8 bLength; */
72 	0x01,       /*  u8 bDescriptorType; Device */
73 	0x00, 0x01, /*  u16 bcdUSB; v1.0 */
74 
75 	0x00,	    /*  u8  bDeviceClass; */
76 	0x00,	    /*  u8  bDeviceSubClass; */
77 	0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
78 	0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
79 
80         /* Vendor and product id are arbitrary.  */
81 	0x00, 0x00, /*  u16 idVendor; */
82  	0x00, 0x00, /*  u16 idProduct; */
83 	0x00, 0x00, /*  u16 bcdDevice */
84 
85 	0x01,       /*  u8  iManufacturer; */
86 	0x02,       /*  u8  iProduct; */
87 	0x03,       /*  u8  iSerialNumber; */
88 	0x01        /*  u8  bNumConfigurations; */
89 };
90 
91 static const uint8_t qemu_msd_config_descriptor[] = {
92 
93 	/* one configuration */
94 	0x09,       /*  u8  bLength; */
95 	0x02,       /*  u8  bDescriptorType; Configuration */
96 	0x20, 0x00, /*  u16 wTotalLength; */
97 	0x01,       /*  u8  bNumInterfaces; (1) */
98 	0x01,       /*  u8  bConfigurationValue; */
99 	0x00,       /*  u8  iConfiguration; */
100 	0xc0,       /*  u8  bmAttributes;
101 				 Bit 7: must be set,
102 				     6: Self-powered,
103 				     5: Remote wakeup,
104 				     4..0: resvd */
105 	0x00,       /*  u8  MaxPower; */
106 
107 	/* one interface */
108 	0x09,       /*  u8  if_bLength; */
109 	0x04,       /*  u8  if_bDescriptorType; Interface */
110 	0x00,       /*  u8  if_bInterfaceNumber; */
111 	0x00,       /*  u8  if_bAlternateSetting; */
112 	0x02,       /*  u8  if_bNumEndpoints; */
113 	0x08,       /*  u8  if_bInterfaceClass; MASS STORAGE */
114 	0x06,       /*  u8  if_bInterfaceSubClass; SCSI */
115 	0x50,       /*  u8  if_bInterfaceProtocol; Bulk Only */
116 	0x00,       /*  u8  if_iInterface; */
117 
118 	/* Bulk-In endpoint */
119 	0x07,       /*  u8  ep_bLength; */
120 	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
121 	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
122  	0x02,       /*  u8  ep_bmAttributes; Bulk */
123  	0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
124 	0x00,       /*  u8  ep_bInterval; */
125 
126 	/* Bulk-Out endpoint */
127 	0x07,       /*  u8  ep_bLength; */
128 	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
129 	0x02,       /*  u8  ep_bEndpointAddress; OUT Endpoint 2 */
130  	0x02,       /*  u8  ep_bmAttributes; Bulk */
131  	0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
132 	0x00        /*  u8  ep_bInterval; */
133 };
134 
usb_msd_copy_data(MSDState * s)135 static void usb_msd_copy_data(MSDState *s)
136 {
137     uint32_t len;
138     len = s->usb_len;
139     if (len > s->scsi_len)
140         len = s->scsi_len;
141     if (s->mode == USB_MSDM_DATAIN) {
142         memcpy(s->usb_buf, s->scsi_buf, len);
143     } else {
144         memcpy(s->scsi_buf, s->usb_buf, len);
145     }
146     s->usb_len -= len;
147     s->scsi_len -= len;
148     s->usb_buf += len;
149     s->scsi_buf += len;
150     s->data_len -= len;
151     if (s->scsi_len == 0) {
152         if (s->mode == USB_MSDM_DATAIN) {
153             s->scsi_dev->read_data(s->scsi_dev, s->tag);
154         } else if (s->mode == USB_MSDM_DATAOUT) {
155             s->scsi_dev->write_data(s->scsi_dev, s->tag);
156         }
157     }
158 }
159 
usb_msd_send_status(MSDState * s)160 static void usb_msd_send_status(MSDState *s)
161 {
162     struct usb_msd_csw csw;
163 
164     csw.sig = cpu_to_le32(0x53425355);
165     csw.tag = cpu_to_le32(s->tag);
166     csw.residue = s->residue;
167     csw.status = s->result;
168     memcpy(s->usb_buf, &csw, 13);
169 }
170 
usb_msd_command_complete(void * opaque,int reason,uint32_t tag,uint32_t arg)171 static void usb_msd_command_complete(void *opaque, int reason, uint32_t tag,
172                                      uint32_t arg)
173 {
174     MSDState *s = (MSDState *)opaque;
175     USBPacket *p = s->packet;
176 
177     if (tag != s->tag) {
178         fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", tag);
179     }
180     if (reason == SCSI_REASON_DONE) {
181         DPRINTF("Command complete %d\n", arg);
182         s->residue = s->data_len;
183         s->result = arg != 0;
184         if (s->packet) {
185             if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
186                 /* A deferred packet with no write data remaining must be
187                    the status read packet.  */
188                 usb_msd_send_status(s);
189                 s->mode = USB_MSDM_CBW;
190             } else {
191                 if (s->data_len) {
192                     s->data_len -= s->usb_len;
193                     if (s->mode == USB_MSDM_DATAIN)
194                         memset(s->usb_buf, 0, s->usb_len);
195                     s->usb_len = 0;
196                 }
197                 if (s->data_len == 0)
198                     s->mode = USB_MSDM_CSW;
199             }
200             s->packet = NULL;
201             usb_packet_complete(p);
202         } else if (s->data_len == 0) {
203             s->mode = USB_MSDM_CSW;
204         }
205         return;
206     }
207     s->scsi_len = arg;
208     s->scsi_buf = s->scsi_dev->get_buf(s->scsi_dev, tag);
209     if (p) {
210         usb_msd_copy_data(s);
211         if (s->usb_len == 0) {
212             /* Set s->packet to NULL before calling usb_packet_complete
213                because annother request may be issued before
214                usb_packet_complete returns.  */
215             DPRINTF("Packet complete %p\n", p);
216             s->packet = NULL;
217             usb_packet_complete(p);
218         }
219     }
220 }
221 
usb_msd_handle_reset(USBDevice * dev)222 static void usb_msd_handle_reset(USBDevice *dev)
223 {
224     MSDState *s = (MSDState *)dev;
225 
226     DPRINTF("Reset\n");
227     s->mode = USB_MSDM_CBW;
228 }
229 
usb_msd_handle_control(USBDevice * dev,int request,int value,int index,int length,uint8_t * data)230 static int usb_msd_handle_control(USBDevice *dev, int request, int value,
231                                   int index, int length, uint8_t *data)
232 {
233     MSDState *s = (MSDState *)dev;
234     int ret = 0;
235 
236     switch (request) {
237     case DeviceRequest | USB_REQ_GET_STATUS:
238         data[0] = (1 << USB_DEVICE_SELF_POWERED) |
239             (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
240         data[1] = 0x00;
241         ret = 2;
242         break;
243     case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
244         if (value == USB_DEVICE_REMOTE_WAKEUP) {
245             dev->remote_wakeup = 0;
246         } else {
247             goto fail;
248         }
249         ret = 0;
250         break;
251     case DeviceOutRequest | USB_REQ_SET_FEATURE:
252         if (value == USB_DEVICE_REMOTE_WAKEUP) {
253             dev->remote_wakeup = 1;
254         } else {
255             goto fail;
256         }
257         ret = 0;
258         break;
259     case DeviceOutRequest | USB_REQ_SET_ADDRESS:
260         dev->addr = value;
261         ret = 0;
262         break;
263     case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
264         switch(value >> 8) {
265         case USB_DT_DEVICE:
266             memcpy(data, qemu_msd_dev_descriptor,
267                    sizeof(qemu_msd_dev_descriptor));
268             ret = sizeof(qemu_msd_dev_descriptor);
269             break;
270         case USB_DT_CONFIG:
271             memcpy(data, qemu_msd_config_descriptor,
272                    sizeof(qemu_msd_config_descriptor));
273             ret = sizeof(qemu_msd_config_descriptor);
274             break;
275         case USB_DT_STRING:
276             switch(value & 0xff) {
277             case 0:
278                 /* language ids */
279                 data[0] = 4;
280                 data[1] = 3;
281                 data[2] = 0x09;
282                 data[3] = 0x04;
283                 ret = 4;
284                 break;
285             case 1:
286                 /* vendor description */
287                 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
288                 break;
289             case 2:
290                 /* product description */
291                 ret = set_usb_string(data, "QEMU USB HARDDRIVE");
292                 break;
293             case 3:
294                 /* serial number */
295                 ret = set_usb_string(data, "1");
296                 break;
297             default:
298                 goto fail;
299             }
300             break;
301         default:
302             goto fail;
303         }
304         break;
305     case DeviceRequest | USB_REQ_GET_CONFIGURATION:
306         data[0] = 1;
307         ret = 1;
308         break;
309     case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
310         ret = 0;
311         break;
312     case DeviceRequest | USB_REQ_GET_INTERFACE:
313         data[0] = 0;
314         ret = 1;
315         break;
316     case DeviceOutRequest | USB_REQ_SET_INTERFACE:
317         ret = 0;
318         break;
319     case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
320         if (value == 0 && index != 0x81) { /* clear ep halt */
321             goto fail;
322         }
323         ret = 0;
324         break;
325         /* Class specific requests.  */
326     case MassStorageReset:
327         /* Reset state ready for the next CBW.  */
328         s->mode = USB_MSDM_CBW;
329         ret = 0;
330         break;
331     case GetMaxLun:
332         data[0] = 0;
333         ret = 1;
334         break;
335     default:
336     fail:
337         ret = USB_RET_STALL;
338         break;
339     }
340     return ret;
341 }
342 
usb_msd_cancel_io(USBPacket * p,void * opaque)343 static void usb_msd_cancel_io(USBPacket *p, void *opaque)
344 {
345     MSDState *s = opaque;
346     s->scsi_dev->cancel_io(s->scsi_dev, s->tag);
347     s->packet = NULL;
348     s->scsi_len = 0;
349 }
350 
usb_msd_handle_data(USBDevice * dev,USBPacket * p)351 static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
352 {
353     MSDState *s = (MSDState *)dev;
354     int ret = 0;
355     struct usb_msd_cbw cbw;
356     uint8_t devep = p->devep;
357     uint8_t *data = p->data;
358     int len = p->len;
359 
360     switch (p->pid) {
361     case USB_TOKEN_OUT:
362         if (devep != 2)
363             goto fail;
364 
365         switch (s->mode) {
366         case USB_MSDM_CBW:
367             if (len != 31) {
368                 fprintf(stderr, "usb-msd: Bad CBW size");
369                 goto fail;
370             }
371             memcpy(&cbw, data, 31);
372             if (le32_to_cpu(cbw.sig) != 0x43425355) {
373                 fprintf(stderr, "usb-msd: Bad signature %08x\n",
374                         le32_to_cpu(cbw.sig));
375                 goto fail;
376             }
377             DPRINTF("Command on LUN %d\n", cbw.lun);
378             if (cbw.lun != 0) {
379                 fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun);
380                 goto fail;
381             }
382             s->tag = le32_to_cpu(cbw.tag);
383             s->data_len = le32_to_cpu(cbw.data_len);
384             if (s->data_len == 0) {
385                 s->mode = USB_MSDM_CSW;
386             } else if (cbw.flags & 0x80) {
387                 s->mode = USB_MSDM_DATAIN;
388             } else {
389                 s->mode = USB_MSDM_DATAOUT;
390             }
391             DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
392                     s->tag, cbw.flags, cbw.cmd_len, s->data_len);
393             s->residue = 0;
394             s->scsi_dev->send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
395             /* ??? Should check that USB and SCSI data transfer
396                directions match.  */
397             if (s->residue == 0) {
398                 if (s->mode == USB_MSDM_DATAIN) {
399                     s->scsi_dev->read_data(s->scsi_dev, s->tag);
400                 } else if (s->mode == USB_MSDM_DATAOUT) {
401                     s->scsi_dev->write_data(s->scsi_dev, s->tag);
402                 }
403             }
404             ret = len;
405             break;
406 
407         case USB_MSDM_DATAOUT:
408             DPRINTF("Data out %d/%d\n", len, s->data_len);
409             if (len > s->data_len)
410                 goto fail;
411 
412             s->usb_buf = data;
413             s->usb_len = len;
414             if (s->scsi_len) {
415                 usb_msd_copy_data(s);
416             }
417             if (s->residue && s->usb_len) {
418                 s->data_len -= s->usb_len;
419                 if (s->data_len == 0)
420                     s->mode = USB_MSDM_CSW;
421                 s->usb_len = 0;
422             }
423             if (s->usb_len) {
424                 DPRINTF("Deferring packet %p\n", p);
425                 usb_defer_packet(p, usb_msd_cancel_io, s);
426                 s->packet = p;
427                 ret = USB_RET_ASYNC;
428             } else {
429                 ret = len;
430             }
431             break;
432 
433         default:
434             DPRINTF("Unexpected write (len %d)\n", len);
435             goto fail;
436         }
437         break;
438 
439     case USB_TOKEN_IN:
440         if (devep != 1)
441             goto fail;
442 
443         switch (s->mode) {
444         case USB_MSDM_DATAOUT:
445             if (s->data_len != 0 || len < 13)
446                 goto fail;
447             /* Waiting for SCSI write to complete.  */
448             usb_defer_packet(p, usb_msd_cancel_io, s);
449             s->packet = p;
450             ret = USB_RET_ASYNC;
451             break;
452 
453         case USB_MSDM_CSW:
454             DPRINTF("Command status %d tag 0x%x, len %d\n",
455                     s->result, s->tag, len);
456             if (len < 13)
457                 goto fail;
458 
459             s->usb_len = len;
460             s->usb_buf = data;
461             usb_msd_send_status(s);
462             s->mode = USB_MSDM_CBW;
463             ret = 13;
464             break;
465 
466         case USB_MSDM_DATAIN:
467             DPRINTF("Data in %d/%d\n", len, s->data_len);
468             if (len > s->data_len)
469                 len = s->data_len;
470             s->usb_buf = data;
471             s->usb_len = len;
472             if (s->scsi_len) {
473                 usb_msd_copy_data(s);
474             }
475             if (s->residue && s->usb_len) {
476                 s->data_len -= s->usb_len;
477                 memset(s->usb_buf, 0, s->usb_len);
478                 if (s->data_len == 0)
479                     s->mode = USB_MSDM_CSW;
480                 s->usb_len = 0;
481             }
482             if (s->usb_len) {
483                 DPRINTF("Deferring packet %p\n", p);
484                 usb_defer_packet(p, usb_msd_cancel_io, s);
485                 s->packet = p;
486                 ret = USB_RET_ASYNC;
487             } else {
488                 ret = len;
489             }
490             break;
491 
492         default:
493             DPRINTF("Unexpected read (len %d)\n", len);
494             goto fail;
495         }
496         break;
497 
498     default:
499         DPRINTF("Bad token\n");
500     fail:
501         ret = USB_RET_STALL;
502         break;
503     }
504 
505     return ret;
506 }
507 
usb_msd_handle_destroy(USBDevice * dev)508 static void usb_msd_handle_destroy(USBDevice *dev)
509 {
510     MSDState *s = (MSDState *)dev;
511 
512     s->scsi_dev->destroy(s->scsi_dev);
513     bdrv_delete(s->bs);
514     qemu_free(s);
515 }
516 
usb_msd_init(const char * filename)517 USBDevice *usb_msd_init(const char *filename)
518 {
519     MSDState *s;
520     BlockDriverState *bdrv;
521     BlockDriver *drv = NULL;
522     const char *p1;
523     char fmt[32];
524 
525     p1 = strchr(filename, ':');
526     if (p1++) {
527         const char *p2;
528 
529         if (strstart(filename, "format=", &p2)) {
530             int len = MIN(p1 - p2, sizeof(fmt));
531             pstrcpy(fmt, len, p2);
532 
533             drv = bdrv_find_format(fmt);
534             if (!drv) {
535                 printf("invalid format %s\n", fmt);
536                 return NULL;
537             }
538         } else if (*filename != ':') {
539             printf("unrecognized USB mass-storage option %s\n", filename);
540             return NULL;
541         }
542 
543         filename = p1;
544     }
545 
546     if (!*filename) {
547         printf("block device specification needed\n");
548         return NULL;
549     }
550 
551     s = qemu_mallocz(sizeof(MSDState));
552 
553     bdrv = bdrv_new("usb");
554     if (bdrv_open(bdrv, filename, 0, drv) < 0)
555         goto fail;
556     s->bs = bdrv;
557 
558     s->dev.speed = USB_SPEED_FULL;
559     s->dev.handle_packet = usb_generic_handle_packet;
560 
561     s->dev.handle_reset = usb_msd_handle_reset;
562     s->dev.handle_control = usb_msd_handle_control;
563     s->dev.handle_data = usb_msd_handle_data;
564     s->dev.handle_destroy = usb_msd_handle_destroy;
565 
566     snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB MSD(%.16s)",
567              filename);
568 
569     s->scsi_dev = scsi_disk_init(bdrv, 0, usb_msd_command_complete, s);
570     usb_msd_handle_reset((USBDevice *)s);
571     return (USBDevice *)s;
572  fail:
573     qemu_free(s);
574     return NULL;
575 }
576 
usb_msd_get_bdrv(USBDevice * dev)577 BlockDriverState *usb_msd_get_bdrv(USBDevice *dev)
578 {
579     MSDState *s = (MSDState *)dev;
580 
581     return s->bs;
582 }
583