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