xref: /openbmc/qemu/hw/usb/dev-mtp.c (revision b3dd1b8c)
1 /*
2  * Media Transfer Protocol implementation, backed by host filesystem.
3  *
4  * Copyright Red Hat, Inc 2014
5  *
6  * Author:
7  *   Gerd Hoffmann <kraxel@redhat.com>
8  *
9  * This code is licensed under the GPL v2 or later.
10  */
11 
12 #include <wchar.h>
13 #include <dirent.h>
14 #include <unistd.h>
15 
16 #include <sys/stat.h>
17 #include <sys/statvfs.h>
18 
19 #include "qemu-common.h"
20 #include "qemu/iov.h"
21 #include "trace.h"
22 #include "hw/usb.h"
23 #include "hw/usb/desc.h"
24 
25 /* ----------------------------------------------------------------------- */
26 
27 enum mtp_container_type {
28     TYPE_COMMAND  = 1,
29     TYPE_DATA     = 2,
30     TYPE_RESPONSE = 3,
31     TYPE_EVENT    = 4,
32 };
33 
34 enum mtp_code {
35     /* command codes */
36     CMD_GET_DEVICE_INFO            = 0x1001,
37     CMD_OPEN_SESSION               = 0x1002,
38     CMD_CLOSE_SESSION              = 0x1003,
39     CMD_GET_STORAGE_IDS            = 0x1004,
40     CMD_GET_STORAGE_INFO           = 0x1005,
41     CMD_GET_NUM_OBJECTS            = 0x1006,
42     CMD_GET_OBJECT_HANDLES         = 0x1007,
43     CMD_GET_OBJECT_INFO            = 0x1008,
44     CMD_GET_OBJECT                 = 0x1009,
45     CMD_GET_PARTIAL_OBJECT         = 0x101b,
46 
47     /* response codes */
48     RES_OK                         = 0x2001,
49     RES_GENERAL_ERROR              = 0x2002,
50     RES_SESSION_NOT_OPEN           = 0x2003,
51     RES_INVALID_TRANSACTION_ID     = 0x2004,
52     RES_OPERATION_NOT_SUPPORTED    = 0x2005,
53     RES_PARAMETER_NOT_SUPPORTED    = 0x2006,
54     RES_INCOMPLETE_TRANSFER        = 0x2007,
55     RES_INVALID_STORAGE_ID         = 0x2008,
56     RES_INVALID_OBJECT_HANDLE      = 0x2009,
57     RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014,
58     RES_INVALID_PARENT_OBJECT      = 0x201a,
59     RES_INVALID_PARAMETER          = 0x201d,
60     RES_SESSION_ALREADY_OPEN       = 0x201e,
61 
62     /* format codes */
63     FMT_UNDEFINED_OBJECT           = 0x3000,
64     FMT_ASSOCIATION                = 0x3001,
65 };
66 
67 typedef struct {
68     uint32_t length;
69     uint16_t type;
70     uint16_t code;
71     uint32_t trans;
72 } QEMU_PACKED mtp_container;
73 
74 /* ----------------------------------------------------------------------- */
75 
76 typedef struct MTPState MTPState;
77 typedef struct MTPControl MTPControl;
78 typedef struct MTPData MTPData;
79 typedef struct MTPObject MTPObject;
80 
81 enum {
82     EP_DATA_IN = 1,
83     EP_DATA_OUT,
84     EP_EVENT,
85 };
86 
87 struct MTPControl {
88     uint16_t     code;
89     uint32_t     trans;
90     int          argc;
91     uint32_t     argv[5];
92 };
93 
94 struct MTPData {
95     uint16_t     code;
96     uint32_t     trans;
97     uint32_t     offset;
98     uint32_t     length;
99     uint32_t     alloc;
100     uint8_t      *data;
101     bool         first;
102     int          fd;
103 };
104 
105 struct MTPObject {
106     uint32_t     handle;
107     uint16_t     format;
108     char         *name;
109     char         *path;
110     struct stat  stat;
111     MTPObject    *parent;
112     MTPObject    **children;
113     uint32_t     nchildren;
114     bool         have_children;
115     QTAILQ_ENTRY(MTPObject) next;
116 };
117 
118 struct MTPState {
119     USBDevice    dev;
120     char         *root;
121     char         *desc;
122     uint32_t     flags;
123 
124     MTPData      *data_in;
125     MTPData      *data_out;
126     MTPControl   *result;
127     uint32_t     session;
128     uint32_t     next_handle;
129 
130     QTAILQ_HEAD(, MTPObject) objects;
131 };
132 
133 #define QEMU_STORAGE_ID 0x00010001
134 
135 #define MTP_FLAG_WRITABLE 0
136 
137 #define FLAG_SET(_mtp, _flag)  ((_mtp)->flags & (1 << (_flag)))
138 
139 /* ----------------------------------------------------------------------- */
140 
141 #define MTP_MANUFACTURER  "QEMU"
142 #define MTP_PRODUCT       "QEMU filesharing"
143 
144 enum {
145     STR_MANUFACTURER = 1,
146     STR_PRODUCT,
147     STR_SERIALNUMBER,
148     STR_MTP,
149     STR_CONFIG_FULL,
150     STR_CONFIG_HIGH,
151     STR_CONFIG_SUPER,
152 };
153 
154 static const USBDescStrings desc_strings = {
155     [STR_MANUFACTURER] = MTP_MANUFACTURER,
156     [STR_PRODUCT]      = MTP_PRODUCT,
157     [STR_SERIALNUMBER] = "34617",
158     [STR_MTP]          = "MTP",
159     [STR_CONFIG_FULL]  = "Full speed config (usb 1.1)",
160     [STR_CONFIG_HIGH]  = "High speed config (usb 2.0)",
161     [STR_CONFIG_SUPER] = "Super speed config (usb 3.0)",
162 };
163 
164 static const USBDescIface desc_iface_full = {
165     .bInterfaceNumber              = 0,
166     .bNumEndpoints                 = 3,
167     .bInterfaceClass               = USB_CLASS_STILL_IMAGE,
168     .bInterfaceSubClass            = 0x01,
169     .bInterfaceProtocol            = 0x01,
170     .iInterface                    = STR_MTP,
171     .eps = (USBDescEndpoint[]) {
172         {
173             .bEndpointAddress      = USB_DIR_IN | EP_DATA_IN,
174             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
175             .wMaxPacketSize        = 64,
176         },{
177             .bEndpointAddress      = USB_DIR_OUT | EP_DATA_OUT,
178             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
179             .wMaxPacketSize        = 64,
180         },{
181             .bEndpointAddress      = USB_DIR_IN | EP_EVENT,
182             .bmAttributes          = USB_ENDPOINT_XFER_INT,
183             .wMaxPacketSize        = 8,
184             .bInterval             = 0x0a,
185         },
186     }
187 };
188 
189 static const USBDescDevice desc_device_full = {
190     .bcdUSB                        = 0x0200,
191     .bMaxPacketSize0               = 8,
192     .bNumConfigurations            = 1,
193     .confs = (USBDescConfig[]) {
194         {
195             .bNumInterfaces        = 1,
196             .bConfigurationValue   = 1,
197             .iConfiguration        = STR_CONFIG_FULL,
198             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
199             .bMaxPower             = 2,
200             .nif = 1,
201             .ifs = &desc_iface_full,
202         },
203     },
204 };
205 
206 static const USBDescIface desc_iface_high = {
207     .bInterfaceNumber              = 0,
208     .bNumEndpoints                 = 3,
209     .bInterfaceClass               = USB_CLASS_STILL_IMAGE,
210     .bInterfaceSubClass            = 0x01,
211     .bInterfaceProtocol            = 0x01,
212     .iInterface                    = STR_MTP,
213     .eps = (USBDescEndpoint[]) {
214         {
215             .bEndpointAddress      = USB_DIR_IN | EP_DATA_IN,
216             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
217             .wMaxPacketSize        = 512,
218         },{
219             .bEndpointAddress      = USB_DIR_OUT | EP_DATA_OUT,
220             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
221             .wMaxPacketSize        = 512,
222         },{
223             .bEndpointAddress      = USB_DIR_IN | EP_EVENT,
224             .bmAttributes          = USB_ENDPOINT_XFER_INT,
225             .wMaxPacketSize        = 8,
226             .bInterval             = 0x0a,
227         },
228     }
229 };
230 
231 static const USBDescDevice desc_device_high = {
232     .bcdUSB                        = 0x0200,
233     .bMaxPacketSize0               = 64,
234     .bNumConfigurations            = 1,
235     .confs = (USBDescConfig[]) {
236         {
237             .bNumInterfaces        = 1,
238             .bConfigurationValue   = 1,
239             .iConfiguration        = STR_CONFIG_HIGH,
240             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
241             .bMaxPower             = 2,
242             .nif = 1,
243             .ifs = &desc_iface_high,
244         },
245     },
246 };
247 
248 static const USBDescMSOS desc_msos = {
249     .CompatibleID = "MTP",
250     .SelectiveSuspendEnabled = true,
251 };
252 
253 static const USBDesc desc = {
254     .id = {
255         .idVendor          = 0x46f4, /* CRC16() of "QEMU" */
256         .idProduct         = 0x0004,
257         .bcdDevice         = 0,
258         .iManufacturer     = STR_MANUFACTURER,
259         .iProduct          = STR_PRODUCT,
260         .iSerialNumber     = STR_SERIALNUMBER,
261     },
262     .full  = &desc_device_full,
263     .high  = &desc_device_high,
264     .str   = desc_strings,
265     .msos  = &desc_msos,
266 };
267 
268 /* ----------------------------------------------------------------------- */
269 
270 static MTPObject *usb_mtp_object_alloc(MTPState *s, uint32_t handle,
271                                        MTPObject *parent, char *name)
272 {
273     MTPObject *o = g_new0(MTPObject, 1);
274 
275     if (name[0] == '.') {
276         goto ignore;
277     }
278 
279     o->handle = handle;
280     o->parent = parent;
281     o->name = g_strdup(name);
282     if (parent == NULL) {
283         o->path = g_strdup(name);
284     } else {
285         o->path = g_strdup_printf("%s/%s", parent->path, name);
286     }
287 
288     if (lstat(o->path, &o->stat) != 0) {
289         goto ignore;
290     }
291     if (S_ISREG(o->stat.st_mode)) {
292         o->format = FMT_UNDEFINED_OBJECT;
293     } else if (S_ISDIR(o->stat.st_mode)) {
294         o->format = FMT_ASSOCIATION;
295     } else {
296         goto ignore;
297     }
298 
299     if (access(o->path, R_OK) != 0) {
300         goto ignore;
301     }
302 
303     trace_usb_mtp_object_alloc(s->dev.addr, o->handle, o->path);
304 
305     QTAILQ_INSERT_TAIL(&s->objects, o, next);
306     return o;
307 
308 ignore:
309     g_free(o->name);
310     g_free(o->path);
311     g_free(o);
312     return NULL;
313 }
314 
315 static void usb_mtp_object_free(MTPState *s, MTPObject *o)
316 {
317     int i;
318 
319     trace_usb_mtp_object_free(s->dev.addr, o->handle, o->path);
320 
321     QTAILQ_REMOVE(&s->objects, o, next);
322     for (i = 0; i < o->nchildren; i++) {
323         usb_mtp_object_free(s, o->children[i]);
324     }
325     g_free(o->children);
326     g_free(o->name);
327     g_free(o->path);
328     g_free(o);
329 }
330 
331 static MTPObject *usb_mtp_object_lookup(MTPState *s, uint32_t handle)
332 {
333     MTPObject *o;
334 
335     QTAILQ_FOREACH(o, &s->objects, next) {
336         if (o->handle == handle) {
337             return o;
338         }
339     }
340     return NULL;
341 }
342 
343 static void usb_mtp_object_readdir(MTPState *s, MTPObject *o)
344 {
345     struct dirent *entry;
346     DIR *dir;
347 
348     if (o->have_children) {
349         return;
350     }
351     o->have_children = true;
352 
353     dir = opendir(o->path);
354     if (!dir) {
355         return;
356     }
357     while ((entry = readdir(dir)) != NULL) {
358         if ((o->nchildren % 32) == 0) {
359             o->children = g_realloc(o->children,
360                                     (o->nchildren + 32) * sizeof(MTPObject *));
361         }
362         o->children[o->nchildren] =
363             usb_mtp_object_alloc(s, s->next_handle++, o, entry->d_name);
364         if (o->children[o->nchildren] != NULL) {
365             o->nchildren++;
366         }
367     }
368     closedir(dir);
369 }
370 
371 /* ----------------------------------------------------------------------- */
372 
373 static MTPData *usb_mtp_data_alloc(MTPControl *c)
374 {
375     MTPData *data = g_new0(MTPData, 1);
376 
377     data->code  = c->code;
378     data->trans = c->trans;
379     data->fd    = -1;
380     data->first = true;
381     return data;
382 }
383 
384 static void usb_mtp_data_free(MTPData *data)
385 {
386     if (data == NULL) {
387         return;
388     }
389     if (data->fd != -1) {
390         close(data->fd);
391     }
392     g_free(data->data);
393     g_free(data);
394 }
395 
396 static void usb_mtp_realloc(MTPData *data, uint32_t bytes)
397 {
398     if (data->length + bytes <= data->alloc) {
399         return;
400     }
401     data->alloc = (data->length + bytes + 0xff) & ~0xff;
402     data->data  = g_realloc(data->data, data->alloc);
403 }
404 
405 static void usb_mtp_add_u8(MTPData *data, uint8_t val)
406 {
407     usb_mtp_realloc(data, 1);
408     data->data[data->length++] = val;
409 }
410 
411 static void usb_mtp_add_u16(MTPData *data, uint16_t val)
412 {
413     usb_mtp_realloc(data, 2);
414     data->data[data->length++] = (val >> 0) & 0xff;
415     data->data[data->length++] = (val >> 8) & 0xff;
416 }
417 
418 static void usb_mtp_add_u32(MTPData *data, uint32_t val)
419 {
420     usb_mtp_realloc(data, 4);
421     data->data[data->length++] = (val >>  0) & 0xff;
422     data->data[data->length++] = (val >>  8) & 0xff;
423     data->data[data->length++] = (val >> 16) & 0xff;
424     data->data[data->length++] = (val >> 24) & 0xff;
425 }
426 
427 static void usb_mtp_add_u64(MTPData *data, uint64_t val)
428 {
429     usb_mtp_realloc(data, 8);
430     data->data[data->length++] = (val >>  0) & 0xff;
431     data->data[data->length++] = (val >>  8) & 0xff;
432     data->data[data->length++] = (val >> 16) & 0xff;
433     data->data[data->length++] = (val >> 24) & 0xff;
434     data->data[data->length++] = (val >> 32) & 0xff;
435     data->data[data->length++] = (val >> 40) & 0xff;
436     data->data[data->length++] = (val >> 48) & 0xff;
437     data->data[data->length++] = (val >> 56) & 0xff;
438 }
439 
440 static void usb_mtp_add_u16_array(MTPData *data, uint32_t len,
441                                   const uint16_t *vals)
442 {
443     int i;
444 
445     usb_mtp_add_u32(data, len);
446     for (i = 0; i < len; i++) {
447         usb_mtp_add_u16(data, vals[i]);
448     }
449 }
450 
451 static void usb_mtp_add_u32_array(MTPData *data, uint32_t len,
452                                   const uint32_t *vals)
453 {
454     int i;
455 
456     usb_mtp_add_u32(data, len);
457     for (i = 0; i < len; i++) {
458         usb_mtp_add_u32(data, vals[i]);
459     }
460 }
461 
462 static void usb_mtp_add_wstr(MTPData *data, const wchar_t *str)
463 {
464     uint32_t len = wcslen(str);
465     int i;
466 
467     if (len > 0) {
468         len++; /* include terminating L'\0' */
469     }
470 
471     usb_mtp_add_u8(data, len);
472     for (i = 0; i < len; i++) {
473         usb_mtp_add_u16(data, str[i]);
474     }
475 }
476 
477 static void usb_mtp_add_str(MTPData *data, const char *str)
478 {
479     uint32_t len = strlen(str)+1;
480     wchar_t wstr[len];
481     size_t ret;
482 
483     ret = mbstowcs(wstr, str, len);
484     if (ret == -1) {
485         usb_mtp_add_wstr(data, L"Oops");
486     } else {
487         usb_mtp_add_wstr(data, wstr);
488     }
489 }
490 
491 static void usb_mtp_add_time(MTPData *data, time_t time)
492 {
493     char buf[16];
494     struct tm tm;
495 
496     gmtime_r(&time, &tm);
497     strftime(buf, sizeof(buf), "%Y%m%dT%H%M%S", &tm);
498     usb_mtp_add_str(data, buf);
499 }
500 
501 /* ----------------------------------------------------------------------- */
502 
503 static void usb_mtp_queue_result(MTPState *s, uint16_t code, uint32_t trans,
504                                  int argc, uint32_t arg0, uint32_t arg1)
505 {
506     MTPControl *c = g_new0(MTPControl, 1);
507 
508     c->code  = code;
509     c->trans = trans;
510     c->argc  = argc;
511     if (argc > 0) {
512         c->argv[0] = arg0;
513     }
514     if (argc > 1) {
515         c->argv[1] = arg1;
516     }
517 
518     assert(s->result == NULL);
519     s->result = c;
520 }
521 
522 /* ----------------------------------------------------------------------- */
523 
524 static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c)
525 {
526     static const uint16_t ops[] = {
527         CMD_GET_DEVICE_INFO,
528         CMD_OPEN_SESSION,
529         CMD_CLOSE_SESSION,
530         CMD_GET_STORAGE_IDS,
531         CMD_GET_STORAGE_INFO,
532         CMD_GET_NUM_OBJECTS,
533         CMD_GET_OBJECT_HANDLES,
534         CMD_GET_OBJECT_INFO,
535         CMD_GET_OBJECT,
536         CMD_GET_PARTIAL_OBJECT,
537     };
538     static const uint16_t fmt[] = {
539         FMT_UNDEFINED_OBJECT,
540         FMT_ASSOCIATION,
541     };
542     MTPData *d = usb_mtp_data_alloc(c);
543 
544     trace_usb_mtp_op_get_device_info(s->dev.addr);
545 
546     usb_mtp_add_u16(d, 100);
547     usb_mtp_add_u32(d, 0xffffffff);
548     usb_mtp_add_u16(d, 0x0101);
549     usb_mtp_add_wstr(d, L"");
550     usb_mtp_add_u16(d, 0x0000);
551 
552     usb_mtp_add_u16_array(d, ARRAY_SIZE(ops), ops);
553     usb_mtp_add_u16_array(d, 0, NULL);
554     usb_mtp_add_u16_array(d, 0, NULL);
555     usb_mtp_add_u16_array(d, 0, NULL);
556     usb_mtp_add_u16_array(d, ARRAY_SIZE(fmt), fmt);
557 
558     usb_mtp_add_wstr(d, L"" MTP_MANUFACTURER);
559     usb_mtp_add_wstr(d, L"" MTP_PRODUCT);
560     usb_mtp_add_wstr(d, L"0.1");
561     usb_mtp_add_wstr(d, L"0123456789abcdef0123456789abcdef");
562 
563     return d;
564 }
565 
566 static MTPData *usb_mtp_get_storage_ids(MTPState *s, MTPControl *c)
567 {
568     static const uint32_t ids[] = {
569         QEMU_STORAGE_ID,
570     };
571     MTPData *d = usb_mtp_data_alloc(c);
572 
573     trace_usb_mtp_op_get_storage_ids(s->dev.addr);
574 
575     usb_mtp_add_u32_array(d, ARRAY_SIZE(ids), ids);
576 
577     return d;
578 }
579 
580 static MTPData *usb_mtp_get_storage_info(MTPState *s, MTPControl *c)
581 {
582     MTPData *d = usb_mtp_data_alloc(c);
583     struct statvfs buf;
584     int rc;
585 
586     trace_usb_mtp_op_get_storage_info(s->dev.addr);
587 
588     if (FLAG_SET(s, MTP_FLAG_WRITABLE)) {
589         usb_mtp_add_u16(d, 0x0003);
590         usb_mtp_add_u16(d, 0x0002);
591         usb_mtp_add_u16(d, 0x0000);
592     } else {
593         usb_mtp_add_u16(d, 0x0001);
594         usb_mtp_add_u16(d, 0x0002);
595         usb_mtp_add_u16(d, 0x0001);
596     }
597 
598     rc = statvfs(s->root, &buf);
599     if (rc == 0) {
600         usb_mtp_add_u64(d, (uint64_t)buf.f_frsize * buf.f_blocks);
601         usb_mtp_add_u64(d, (uint64_t)buf.f_bavail * buf.f_blocks);
602         usb_mtp_add_u32(d, buf.f_ffree);
603     } else {
604         usb_mtp_add_u64(d, 0xffffffff);
605         usb_mtp_add_u64(d, 0xffffffff);
606         usb_mtp_add_u32(d, 0xffffffff);
607     }
608 
609     usb_mtp_add_str(d, s->desc);
610     usb_mtp_add_wstr(d, L"123456789abcdef");
611     return d;
612 }
613 
614 static MTPData *usb_mtp_get_object_handles(MTPState *s, MTPControl *c,
615                                            MTPObject *o)
616 {
617     MTPData *d = usb_mtp_data_alloc(c);
618     uint32_t i, handles[o->nchildren];
619 
620     trace_usb_mtp_op_get_object_handles(s->dev.addr, o->handle, o->path);
621 
622     for (i = 0; i < o->nchildren; i++) {
623         handles[i] = o->children[i]->handle;
624     }
625     usb_mtp_add_u32_array(d, o->nchildren, handles);
626 
627     return d;
628 }
629 
630 static MTPData *usb_mtp_get_object_info(MTPState *s, MTPControl *c,
631                                         MTPObject *o)
632 {
633     MTPData *d = usb_mtp_data_alloc(c);
634 
635     trace_usb_mtp_op_get_object_info(s->dev.addr, o->handle, o->path);
636 
637     usb_mtp_add_u32(d, QEMU_STORAGE_ID);
638     usb_mtp_add_u16(d, o->format);
639     usb_mtp_add_u16(d, 0);
640     usb_mtp_add_u32(d, o->stat.st_size);
641 
642     usb_mtp_add_u16(d, 0);
643     usb_mtp_add_u32(d, 0);
644     usb_mtp_add_u32(d, 0);
645     usb_mtp_add_u32(d, 0);
646     usb_mtp_add_u32(d, 0);
647     usb_mtp_add_u32(d, 0);
648     usb_mtp_add_u32(d, 0);
649 
650     if (o->parent) {
651         usb_mtp_add_u32(d, o->parent->handle);
652     } else {
653         usb_mtp_add_u32(d, 0);
654     }
655     if (o->format == FMT_ASSOCIATION) {
656         usb_mtp_add_u16(d, 0x0001);
657         usb_mtp_add_u32(d, 0x00000001);
658         usb_mtp_add_u32(d, 0);
659     } else {
660         usb_mtp_add_u16(d, 0);
661         usb_mtp_add_u32(d, 0);
662         usb_mtp_add_u32(d, 0);
663     }
664 
665     usb_mtp_add_str(d, o->name);
666     usb_mtp_add_time(d, o->stat.st_ctime);
667     usb_mtp_add_time(d, o->stat.st_mtime);
668     usb_mtp_add_wstr(d, L"");
669 
670     return d;
671 }
672 
673 static MTPData *usb_mtp_get_object(MTPState *s, MTPControl *c,
674                                    MTPObject *o)
675 {
676     MTPData *d = usb_mtp_data_alloc(c);
677 
678     trace_usb_mtp_op_get_object(s->dev.addr, o->handle, o->path);
679 
680     d->fd = open(o->path, O_RDONLY);
681     if (d->fd == -1) {
682         usb_mtp_data_free(d);
683         return NULL;
684     }
685     d->length = o->stat.st_size;
686     d->alloc  = 512;
687     d->data   = g_malloc(d->alloc);
688     return d;
689 }
690 
691 static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,
692                                            MTPObject *o)
693 {
694     MTPData *d = usb_mtp_data_alloc(c);
695     off_t offset;
696 
697     trace_usb_mtp_op_get_partial_object(s->dev.addr, o->handle, o->path,
698                                         c->argv[1], c->argv[2]);
699 
700     d->fd = open(o->path, O_RDONLY);
701     if (d->fd == -1) {
702         usb_mtp_data_free(d);
703         return NULL;
704     }
705 
706     offset = c->argv[1];
707     if (offset > o->stat.st_size) {
708         offset = o->stat.st_size;
709     }
710     if (lseek(d->fd, offset, SEEK_SET) < 0) {
711         usb_mtp_data_free(d);
712         return NULL;
713     }
714 
715     d->length = c->argv[2];
716     if (d->length > o->stat.st_size - offset) {
717         d->length = o->stat.st_size - offset;
718     }
719 
720     return d;
721 }
722 
723 static void usb_mtp_command(MTPState *s, MTPControl *c)
724 {
725     MTPData *data_in = NULL;
726     MTPObject *o;
727     uint32_t nres = 0, res0 = 0;
728 
729     /* sanity checks */
730     if (c->code >= CMD_CLOSE_SESSION && s->session == 0) {
731         usb_mtp_queue_result(s, RES_SESSION_NOT_OPEN,
732                              c->trans, 0, 0, 0);
733         return;
734     }
735 
736     /* process commands */
737     switch (c->code) {
738     case CMD_GET_DEVICE_INFO:
739         data_in = usb_mtp_get_device_info(s, c);
740         break;
741     case CMD_OPEN_SESSION:
742         if (s->session) {
743             usb_mtp_queue_result(s, RES_SESSION_ALREADY_OPEN,
744                                  c->trans, 1, s->session, 0);
745             return;
746         }
747         if (c->argv[0] == 0) {
748             usb_mtp_queue_result(s, RES_INVALID_PARAMETER,
749                                  c->trans, 0, 0, 0);
750             return;
751         }
752         trace_usb_mtp_op_open_session(s->dev.addr);
753         s->session = c->argv[0];
754         usb_mtp_object_alloc(s, s->next_handle++, NULL, s->root);
755         break;
756     case CMD_CLOSE_SESSION:
757         trace_usb_mtp_op_close_session(s->dev.addr);
758         s->session = 0;
759         s->next_handle = 0;
760         usb_mtp_object_free(s, QTAILQ_FIRST(&s->objects));
761         assert(QTAILQ_EMPTY(&s->objects));
762         break;
763     case CMD_GET_STORAGE_IDS:
764         data_in = usb_mtp_get_storage_ids(s, c);
765         break;
766     case CMD_GET_STORAGE_INFO:
767         if (c->argv[0] != QEMU_STORAGE_ID &&
768             c->argv[0] != 0xffffffff) {
769             usb_mtp_queue_result(s, RES_INVALID_STORAGE_ID,
770                                  c->trans, 0, 0, 0);
771             return;
772         }
773         data_in = usb_mtp_get_storage_info(s, c);
774         break;
775     case CMD_GET_NUM_OBJECTS:
776     case CMD_GET_OBJECT_HANDLES:
777         if (c->argv[0] != QEMU_STORAGE_ID &&
778             c->argv[0] != 0xffffffff) {
779             usb_mtp_queue_result(s, RES_INVALID_STORAGE_ID,
780                                  c->trans, 0, 0, 0);
781             return;
782         }
783         if (c->argv[1] != 0x00000000) {
784             usb_mtp_queue_result(s, RES_SPEC_BY_FORMAT_UNSUPPORTED,
785                                  c->trans, 0, 0, 0);
786             return;
787         }
788         if (c->argv[2] == 0x00000000 ||
789             c->argv[2] == 0xffffffff) {
790             o = QTAILQ_FIRST(&s->objects);
791         } else {
792             o = usb_mtp_object_lookup(s, c->argv[2]);
793         }
794         if (o == NULL) {
795             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
796                                  c->trans, 0, 0, 0);
797             return;
798         }
799         if (o->format != FMT_ASSOCIATION) {
800             usb_mtp_queue_result(s, RES_INVALID_PARENT_OBJECT,
801                                  c->trans, 0, 0, 0);
802             return;
803         }
804         usb_mtp_object_readdir(s, o);
805         if (c->code == CMD_GET_NUM_OBJECTS) {
806             trace_usb_mtp_op_get_num_objects(s->dev.addr, o->handle, o->path);
807             nres = 1;
808             res0 = o->nchildren;
809         } else {
810             data_in = usb_mtp_get_object_handles(s, c, o);
811         }
812         break;
813     case CMD_GET_OBJECT_INFO:
814         o = usb_mtp_object_lookup(s, c->argv[0]);
815         if (o == NULL) {
816             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
817                                  c->trans, 0, 0, 0);
818             return;
819         }
820         data_in = usb_mtp_get_object_info(s, c, o);
821         break;
822     case CMD_GET_OBJECT:
823         o = usb_mtp_object_lookup(s, c->argv[0]);
824         if (o == NULL) {
825             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
826                                  c->trans, 0, 0, 0);
827             return;
828         }
829         if (o->format == FMT_ASSOCIATION) {
830             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
831                                  c->trans, 0, 0, 0);
832             return;
833         }
834         data_in = usb_mtp_get_object(s, c, o);
835         if (data_in == NULL) {
836             usb_mtp_queue_result(s, RES_GENERAL_ERROR,
837                                  c->trans, 0, 0, 0);
838             return;
839         }
840         break;
841     case CMD_GET_PARTIAL_OBJECT:
842         o = usb_mtp_object_lookup(s, c->argv[0]);
843         if (o == NULL) {
844             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
845                                  c->trans, 0, 0, 0);
846             return;
847         }
848         if (o->format == FMT_ASSOCIATION) {
849             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
850                                  c->trans, 0, 0, 0);
851             return;
852         }
853         data_in = usb_mtp_get_partial_object(s, c, o);
854         if (data_in == NULL) {
855             usb_mtp_queue_result(s, RES_GENERAL_ERROR,
856                                  c->trans, 0, 0, 0);
857             return;
858         }
859         nres = 1;
860         res0 = data_in->length;
861         break;
862     default:
863         trace_usb_mtp_op_unknown(s->dev.addr, c->code);
864         usb_mtp_queue_result(s, RES_OPERATION_NOT_SUPPORTED,
865                              c->trans, 0, 0, 0);
866         return;
867     }
868 
869     /* return results on success */
870     if (data_in) {
871         assert(s->data_in == NULL);
872         s->data_in = data_in;
873     }
874     usb_mtp_queue_result(s, RES_OK, c->trans, nres, res0, 0);
875 }
876 
877 /* ----------------------------------------------------------------------- */
878 
879 static void usb_mtp_handle_reset(USBDevice *dev)
880 {
881     MTPState *s = DO_UPCAST(MTPState, dev, dev);
882 
883     trace_usb_mtp_reset(s->dev.addr);
884 
885     s->session = 0;
886     usb_mtp_data_free(s->data_in);
887     s->data_in = NULL;
888     usb_mtp_data_free(s->data_out);
889     s->data_out = NULL;
890     g_free(s->result);
891     s->result = NULL;
892 }
893 
894 static void usb_mtp_handle_control(USBDevice *dev, USBPacket *p,
895                                    int request, int value, int index,
896                                    int length, uint8_t *data)
897 {
898     int ret;
899 
900     ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
901     if (ret >= 0) {
902         return;
903     }
904 
905     trace_usb_mtp_stall(dev->addr, "unknown control request");
906     p->status = USB_RET_STALL;
907 }
908 
909 static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p)
910 {
911     /* we don't use async packets, so this should never be called */
912     fprintf(stderr, "%s\n", __func__);
913 }
914 
915 static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p)
916 {
917     MTPState *s = DO_UPCAST(MTPState, dev, dev);
918     MTPControl cmd;
919     mtp_container container;
920     uint32_t params[5];
921     int i, rc;
922 
923     switch (p->ep->nr) {
924     case EP_DATA_IN:
925         if (s->data_out != NULL) {
926             /* guest bug */
927             trace_usb_mtp_stall(s->dev.addr, "awaiting data-out");
928             p->status = USB_RET_STALL;
929             return;
930         }
931         if (p->iov.size < sizeof(container)) {
932             trace_usb_mtp_stall(s->dev.addr, "packet too small");
933             p->status = USB_RET_STALL;
934             return;
935         }
936         if (s->data_in !=  NULL) {
937             MTPData *d = s->data_in;
938             int dlen = d->length - d->offset;
939             if (d->first) {
940                 trace_usb_mtp_data_in(s->dev.addr, d->trans, d->length);
941                 container.length = cpu_to_le32(d->length + sizeof(container));
942                 container.type   = cpu_to_le16(TYPE_DATA);
943                 container.code   = cpu_to_le16(d->code);
944                 container.trans  = cpu_to_le32(d->trans);
945                 usb_packet_copy(p, &container, sizeof(container));
946                 d->first = false;
947                 if (dlen > p->iov.size - sizeof(container)) {
948                     dlen = p->iov.size - sizeof(container);
949                 }
950             } else {
951                 if (dlen > p->iov.size) {
952                     dlen = p->iov.size;
953                 }
954             }
955             if (d->fd == -1) {
956                 usb_packet_copy(p, d->data + d->offset, dlen);
957             } else {
958                 if (d->alloc < p->iov.size) {
959                     d->alloc = p->iov.size;
960                     d->data = g_realloc(d->data, d->alloc);
961                 }
962                 rc = read(d->fd, d->data, dlen);
963                 if (rc != dlen) {
964                     memset(d->data, 0, dlen);
965                     s->result->code = RES_INCOMPLETE_TRANSFER;
966                 }
967                 usb_packet_copy(p, d->data, dlen);
968             }
969             d->offset += dlen;
970             if (d->offset == d->length) {
971                 usb_mtp_data_free(s->data_in);
972                 s->data_in = NULL;
973             }
974         } else if (s->result != NULL) {
975             MTPControl *r = s->result;
976             int length = sizeof(container) + r->argc * sizeof(uint32_t);
977             if (r->code == RES_OK) {
978                 trace_usb_mtp_success(s->dev.addr, r->trans,
979                                       (r->argc > 0) ? r->argv[0] : 0,
980                                       (r->argc > 1) ? r->argv[1] : 0);
981             } else {
982                 trace_usb_mtp_error(s->dev.addr, r->code, r->trans,
983                                     (r->argc > 0) ? r->argv[0] : 0,
984                                     (r->argc > 1) ? r->argv[1] : 0);
985             }
986             container.length = cpu_to_le32(length);
987             container.type   = cpu_to_le16(TYPE_RESPONSE);
988             container.code   = cpu_to_le16(r->code);
989             container.trans  = cpu_to_le32(r->trans);
990             for (i = 0; i < r->argc; i++) {
991                 params[i] = cpu_to_le32(r->argv[i]);
992             }
993             usb_packet_copy(p, &container, sizeof(container));
994             usb_packet_copy(p, &params, length - sizeof(container));
995             g_free(s->result);
996             s->result = NULL;
997         }
998         break;
999     case EP_DATA_OUT:
1000         if (p->iov.size < sizeof(container)) {
1001             trace_usb_mtp_stall(s->dev.addr, "packet too small");
1002             p->status = USB_RET_STALL;
1003             return;
1004         }
1005         usb_packet_copy(p, &container, sizeof(container));
1006         switch (le16_to_cpu(container.type)) {
1007         case TYPE_COMMAND:
1008             if (s->data_in || s->data_out || s->result) {
1009                 trace_usb_mtp_stall(s->dev.addr, "transaction inflight");
1010                 p->status = USB_RET_STALL;
1011                 return;
1012             }
1013             cmd.code = le16_to_cpu(container.code);
1014             cmd.argc = (le32_to_cpu(container.length) - sizeof(container))
1015                 / sizeof(uint32_t);
1016             cmd.trans = le32_to_cpu(container.trans);
1017             if (cmd.argc > ARRAY_SIZE(cmd.argv)) {
1018                 cmd.argc = ARRAY_SIZE(cmd.argv);
1019             }
1020             if (p->iov.size < sizeof(container) + cmd.argc * sizeof(uint32_t)) {
1021                 trace_usb_mtp_stall(s->dev.addr, "packet too small");
1022                 p->status = USB_RET_STALL;
1023                 return;
1024             }
1025             usb_packet_copy(p, &params, cmd.argc * sizeof(uint32_t));
1026             for (i = 0; i < cmd.argc; i++) {
1027                 cmd.argv[i] = le32_to_cpu(params[i]);
1028             }
1029             trace_usb_mtp_command(s->dev.addr, cmd.code, cmd.trans,
1030                                   (cmd.argc > 0) ? cmd.argv[0] : 0,
1031                                   (cmd.argc > 1) ? cmd.argv[1] : 0,
1032                                   (cmd.argc > 2) ? cmd.argv[2] : 0,
1033                                   (cmd.argc > 3) ? cmd.argv[3] : 0,
1034                                   (cmd.argc > 4) ? cmd.argv[4] : 0);
1035             usb_mtp_command(s, &cmd);
1036             break;
1037         default:
1038             /* not needed as long as the mtp device is read-only */
1039             p->status = USB_RET_STALL;
1040             return;
1041         }
1042         break;
1043     case EP_EVENT:
1044         p->status = USB_RET_NAK;
1045         return;
1046     default:
1047         trace_usb_mtp_stall(s->dev.addr, "invalid endpoint");
1048         p->status = USB_RET_STALL;
1049         return;
1050     }
1051 
1052     if (p->actual_length == 0) {
1053         trace_usb_mtp_nak(s->dev.addr, p->ep->nr);
1054         p->status = USB_RET_NAK;
1055         return;
1056     } else {
1057         trace_usb_mtp_xfer(s->dev.addr, p->ep->nr, p->actual_length,
1058                            p->iov.size);
1059         return;
1060     }
1061 }
1062 
1063 static int usb_mtp_initfn(USBDevice *dev)
1064 {
1065     MTPState *s = DO_UPCAST(MTPState, dev, dev);
1066 
1067     usb_desc_create_serial(dev);
1068     usb_desc_init(dev);
1069     QTAILQ_INIT(&s->objects);
1070     if (s->desc == NULL) {
1071         s->desc = strrchr(s->root, '/');
1072         if (s->desc && s->desc[0]) {
1073             s->desc = g_strdup(s->desc + 1);
1074         } else {
1075             s->desc = g_strdup("none");
1076         }
1077     }
1078     return 0;
1079 }
1080 
1081 static const VMStateDescription vmstate_usb_mtp = {
1082     .name = "usb-mtp",
1083     .unmigratable = 1,
1084     .version_id = 1,
1085     .minimum_version_id = 1,
1086     .fields = (VMStateField[]) {
1087         VMSTATE_USB_DEVICE(dev, MTPState),
1088         VMSTATE_END_OF_LIST()
1089     }
1090 };
1091 
1092 static Property mtp_properties[] = {
1093     DEFINE_PROP_STRING("x-root", MTPState, root),
1094     DEFINE_PROP_STRING("desc", MTPState, desc),
1095     DEFINE_PROP_END_OF_LIST(),
1096 };
1097 
1098 static void usb_mtp_class_initfn(ObjectClass *klass, void *data)
1099 {
1100     DeviceClass *dc = DEVICE_CLASS(klass);
1101     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1102 
1103     uc->init           = usb_mtp_initfn;
1104     uc->product_desc   = "QEMU USB MTP";
1105     uc->usb_desc       = &desc;
1106     uc->cancel_packet  = usb_mtp_cancel_packet;
1107     uc->handle_attach  = usb_desc_attach;
1108     uc->handle_reset   = usb_mtp_handle_reset;
1109     uc->handle_control = usb_mtp_handle_control;
1110     uc->handle_data    = usb_mtp_handle_data;
1111     dc->fw_name = "mtp";
1112     dc->vmsd = &vmstate_usb_mtp;
1113     dc->props = mtp_properties;
1114 }
1115 
1116 static TypeInfo mtp_info = {
1117     .name          = "usb-mtp",
1118     .parent        = TYPE_USB_DEVICE,
1119     .instance_size = sizeof(MTPState),
1120     .class_init    = usb_mtp_class_initfn,
1121 };
1122 
1123 static void usb_mtp_register_types(void)
1124 {
1125     type_register_static(&mtp_info);
1126 }
1127 
1128 type_init(usb_mtp_register_types)
1129