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