xref: /qemu/hw/usb/dev-mtp.c (revision cae9fc56)
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 "qemu/osdep.h"
13 #include <wchar.h>
14 #include <dirent.h>
15 
16 #include <sys/statvfs.h>
17 #ifdef __linux__
18 #include <sys/inotify.h>
19 #include "qemu/main-loop.h"
20 #endif
21 
22 #include "qemu-common.h"
23 #include "qemu/iov.h"
24 #include "trace.h"
25 #include "hw/usb.h"
26 #include "hw/usb/desc.h"
27 
28 /* ----------------------------------------------------------------------- */
29 
30 enum mtp_container_type {
31     TYPE_COMMAND  = 1,
32     TYPE_DATA     = 2,
33     TYPE_RESPONSE = 3,
34     TYPE_EVENT    = 4,
35 };
36 
37 enum mtp_code {
38     /* command codes */
39     CMD_GET_DEVICE_INFO            = 0x1001,
40     CMD_OPEN_SESSION               = 0x1002,
41     CMD_CLOSE_SESSION              = 0x1003,
42     CMD_GET_STORAGE_IDS            = 0x1004,
43     CMD_GET_STORAGE_INFO           = 0x1005,
44     CMD_GET_NUM_OBJECTS            = 0x1006,
45     CMD_GET_OBJECT_HANDLES         = 0x1007,
46     CMD_GET_OBJECT_INFO            = 0x1008,
47     CMD_GET_OBJECT                 = 0x1009,
48     CMD_GET_PARTIAL_OBJECT         = 0x101b,
49 
50     /* response codes */
51     RES_OK                         = 0x2001,
52     RES_GENERAL_ERROR              = 0x2002,
53     RES_SESSION_NOT_OPEN           = 0x2003,
54     RES_INVALID_TRANSACTION_ID     = 0x2004,
55     RES_OPERATION_NOT_SUPPORTED    = 0x2005,
56     RES_PARAMETER_NOT_SUPPORTED    = 0x2006,
57     RES_INCOMPLETE_TRANSFER        = 0x2007,
58     RES_INVALID_STORAGE_ID         = 0x2008,
59     RES_INVALID_OBJECT_HANDLE      = 0x2009,
60     RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014,
61     RES_INVALID_PARENT_OBJECT      = 0x201a,
62     RES_INVALID_PARAMETER          = 0x201d,
63     RES_SESSION_ALREADY_OPEN       = 0x201e,
64 
65     /* format codes */
66     FMT_UNDEFINED_OBJECT           = 0x3000,
67     FMT_ASSOCIATION                = 0x3001,
68 
69     /* event codes */
70     EVT_OBJ_ADDED                  = 0x4002,
71     EVT_OBJ_REMOVED                = 0x4003,
72     EVT_OBJ_INFO_CHANGED           = 0x4007,
73 };
74 
75 typedef struct {
76     uint32_t length;
77     uint16_t type;
78     uint16_t code;
79     uint32_t trans;
80 } QEMU_PACKED mtp_container;
81 
82 /* ----------------------------------------------------------------------- */
83 
84 typedef struct MTPState MTPState;
85 typedef struct MTPControl MTPControl;
86 typedef struct MTPData MTPData;
87 typedef struct MTPObject MTPObject;
88 
89 enum {
90     EP_DATA_IN = 1,
91     EP_DATA_OUT,
92     EP_EVENT,
93 };
94 
95 #ifdef __linux__
96 typedef struct MTPMonEntry MTPMonEntry;
97 
98 struct MTPMonEntry {
99     uint32_t event;
100     uint32_t handle;
101 
102     QTAILQ_ENTRY(MTPMonEntry) next;
103 };
104 #endif
105 
106 struct MTPControl {
107     uint16_t     code;
108     uint32_t     trans;
109     int          argc;
110     uint32_t     argv[5];
111 };
112 
113 struct MTPData {
114     uint16_t     code;
115     uint32_t     trans;
116     uint32_t     offset;
117     uint32_t     length;
118     uint32_t     alloc;
119     uint8_t      *data;
120     bool         first;
121     int          fd;
122 };
123 
124 struct MTPObject {
125     uint32_t     handle;
126     uint16_t     format;
127     char         *name;
128     char         *path;
129     struct stat  stat;
130 #ifdef __linux__
131     /* inotify watch cookie */
132     int          watchfd;
133 #endif
134     MTPObject    *parent;
135     uint32_t     nchildren;
136     QLIST_HEAD(, MTPObject) children;
137     QLIST_ENTRY(MTPObject) list;
138     bool         have_children;
139     QTAILQ_ENTRY(MTPObject) next;
140 };
141 
142 struct MTPState {
143     USBDevice    dev;
144     char         *root;
145     char         *desc;
146     uint32_t     flags;
147 
148     MTPData      *data_in;
149     MTPData      *data_out;
150     MTPControl   *result;
151     uint32_t     session;
152     uint32_t     next_handle;
153 
154     QTAILQ_HEAD(, MTPObject) objects;
155 #ifdef __linux__
156     /* inotify descriptor */
157     int          inotifyfd;
158     QTAILQ_HEAD(events, MTPMonEntry) events;
159 #endif
160 };
161 
162 #define TYPE_USB_MTP "usb-mtp"
163 #define USB_MTP(obj) OBJECT_CHECK(MTPState, (obj), TYPE_USB_MTP)
164 
165 #define QEMU_STORAGE_ID 0x00010001
166 
167 #define MTP_FLAG_WRITABLE 0
168 
169 #define FLAG_SET(_mtp, _flag)  ((_mtp)->flags & (1 << (_flag)))
170 
171 /* ----------------------------------------------------------------------- */
172 
173 #define MTP_MANUFACTURER  "QEMU"
174 #define MTP_PRODUCT       "QEMU filesharing"
175 
176 enum {
177     STR_MANUFACTURER = 1,
178     STR_PRODUCT,
179     STR_SERIALNUMBER,
180     STR_MTP,
181     STR_CONFIG_FULL,
182     STR_CONFIG_HIGH,
183     STR_CONFIG_SUPER,
184 };
185 
186 static const USBDescStrings desc_strings = {
187     [STR_MANUFACTURER] = MTP_MANUFACTURER,
188     [STR_PRODUCT]      = MTP_PRODUCT,
189     [STR_SERIALNUMBER] = "34617",
190     [STR_MTP]          = "MTP",
191     [STR_CONFIG_FULL]  = "Full speed config (usb 1.1)",
192     [STR_CONFIG_HIGH]  = "High speed config (usb 2.0)",
193     [STR_CONFIG_SUPER] = "Super speed config (usb 3.0)",
194 };
195 
196 static const USBDescIface desc_iface_full = {
197     .bInterfaceNumber              = 0,
198     .bNumEndpoints                 = 3,
199     .bInterfaceClass               = USB_CLASS_STILL_IMAGE,
200     .bInterfaceSubClass            = 0x01,
201     .bInterfaceProtocol            = 0x01,
202     .iInterface                    = STR_MTP,
203     .eps = (USBDescEndpoint[]) {
204         {
205             .bEndpointAddress      = USB_DIR_IN | EP_DATA_IN,
206             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
207             .wMaxPacketSize        = 64,
208         },{
209             .bEndpointAddress      = USB_DIR_OUT | EP_DATA_OUT,
210             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
211             .wMaxPacketSize        = 64,
212         },{
213             .bEndpointAddress      = USB_DIR_IN | EP_EVENT,
214             .bmAttributes          = USB_ENDPOINT_XFER_INT,
215             .wMaxPacketSize        = 64,
216             .bInterval             = 0x0a,
217         },
218     }
219 };
220 
221 static const USBDescDevice desc_device_full = {
222     .bcdUSB                        = 0x0200,
223     .bMaxPacketSize0               = 8,
224     .bNumConfigurations            = 1,
225     .confs = (USBDescConfig[]) {
226         {
227             .bNumInterfaces        = 1,
228             .bConfigurationValue   = 1,
229             .iConfiguration        = STR_CONFIG_FULL,
230             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
231             .bMaxPower             = 2,
232             .nif = 1,
233             .ifs = &desc_iface_full,
234         },
235     },
236 };
237 
238 static const USBDescIface desc_iface_high = {
239     .bInterfaceNumber              = 0,
240     .bNumEndpoints                 = 3,
241     .bInterfaceClass               = USB_CLASS_STILL_IMAGE,
242     .bInterfaceSubClass            = 0x01,
243     .bInterfaceProtocol            = 0x01,
244     .iInterface                    = STR_MTP,
245     .eps = (USBDescEndpoint[]) {
246         {
247             .bEndpointAddress      = USB_DIR_IN | EP_DATA_IN,
248             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
249             .wMaxPacketSize        = 512,
250         },{
251             .bEndpointAddress      = USB_DIR_OUT | EP_DATA_OUT,
252             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
253             .wMaxPacketSize        = 512,
254         },{
255             .bEndpointAddress      = USB_DIR_IN | EP_EVENT,
256             .bmAttributes          = USB_ENDPOINT_XFER_INT,
257             .wMaxPacketSize        = 64,
258             .bInterval             = 0x0a,
259         },
260     }
261 };
262 
263 static const USBDescDevice desc_device_high = {
264     .bcdUSB                        = 0x0200,
265     .bMaxPacketSize0               = 64,
266     .bNumConfigurations            = 1,
267     .confs = (USBDescConfig[]) {
268         {
269             .bNumInterfaces        = 1,
270             .bConfigurationValue   = 1,
271             .iConfiguration        = STR_CONFIG_HIGH,
272             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
273             .bMaxPower             = 2,
274             .nif = 1,
275             .ifs = &desc_iface_high,
276         },
277     },
278 };
279 
280 static const USBDescMSOS desc_msos = {
281     .CompatibleID = "MTP",
282     .SelectiveSuspendEnabled = true,
283 };
284 
285 static const USBDesc desc = {
286     .id = {
287         .idVendor          = 0x46f4, /* CRC16() of "QEMU" */
288         .idProduct         = 0x0004,
289         .bcdDevice         = 0,
290         .iManufacturer     = STR_MANUFACTURER,
291         .iProduct          = STR_PRODUCT,
292         .iSerialNumber     = STR_SERIALNUMBER,
293     },
294     .full  = &desc_device_full,
295     .high  = &desc_device_high,
296     .str   = desc_strings,
297     .msos  = &desc_msos,
298 };
299 
300 /* ----------------------------------------------------------------------- */
301 
302 static MTPObject *usb_mtp_object_alloc(MTPState *s, uint32_t handle,
303                                        MTPObject *parent, char *name)
304 {
305     MTPObject *o = g_new0(MTPObject, 1);
306 
307     if (name[0] == '.') {
308         goto ignore;
309     }
310 
311     o->handle = handle;
312     o->parent = parent;
313     o->name = g_strdup(name);
314     if (parent == NULL) {
315         o->path = g_strdup(name);
316     } else {
317         o->path = g_strdup_printf("%s/%s", parent->path, name);
318     }
319 
320     if (lstat(o->path, &o->stat) != 0) {
321         goto ignore;
322     }
323     if (S_ISREG(o->stat.st_mode)) {
324         o->format = FMT_UNDEFINED_OBJECT;
325     } else if (S_ISDIR(o->stat.st_mode)) {
326         o->format = FMT_ASSOCIATION;
327     } else {
328         goto ignore;
329     }
330 
331     if (access(o->path, R_OK) != 0) {
332         goto ignore;
333     }
334 
335     trace_usb_mtp_object_alloc(s->dev.addr, o->handle, o->path);
336 
337     QTAILQ_INSERT_TAIL(&s->objects, o, next);
338     return o;
339 
340 ignore:
341     g_free(o->name);
342     g_free(o->path);
343     g_free(o);
344     return NULL;
345 }
346 
347 static void usb_mtp_object_free(MTPState *s, MTPObject *o)
348 {
349     MTPObject *iter;
350 
351     if (!o) {
352         return;
353     }
354 
355     trace_usb_mtp_object_free(s->dev.addr, o->handle, o->path);
356 
357     QTAILQ_REMOVE(&s->objects, o, next);
358     if (o->parent) {
359         QLIST_REMOVE(o, list);
360         o->parent->nchildren--;
361     }
362 
363     while (!QLIST_EMPTY(&o->children)) {
364         iter = QLIST_FIRST(&o->children);
365         usb_mtp_object_free(s, iter);
366     }
367     g_free(o->name);
368     g_free(o->path);
369     g_free(o);
370 }
371 
372 static MTPObject *usb_mtp_object_lookup(MTPState *s, uint32_t handle)
373 {
374     MTPObject *o;
375 
376     QTAILQ_FOREACH(o, &s->objects, next) {
377         if (o->handle == handle) {
378             return o;
379         }
380     }
381     return NULL;
382 }
383 
384 static MTPObject *usb_mtp_add_child(MTPState *s, MTPObject *o,
385                                     char *name)
386 {
387     MTPObject *child =
388         usb_mtp_object_alloc(s, s->next_handle++, o, name);
389 
390     if (child) {
391         trace_usb_mtp_add_child(s->dev.addr, child->handle, child->path);
392         QLIST_INSERT_HEAD(&o->children, child, list);
393         o->nchildren++;
394 
395         if (child->format == FMT_ASSOCIATION) {
396             QLIST_INIT(&child->children);
397         }
398     }
399 
400     return child;
401 }
402 
403 #ifdef __linux__
404 static MTPObject *usb_mtp_object_lookup_name(MTPObject *parent,
405                                              char *name, int len)
406 {
407     MTPObject *iter;
408 
409     QLIST_FOREACH(iter, &parent->children, list) {
410         if (strncmp(iter->name, name, len) == 0) {
411             return iter;
412         }
413     }
414 
415     return NULL;
416 }
417 
418 static MTPObject *usb_mtp_object_lookup_wd(MTPState *s, int wd)
419 {
420     MTPObject *iter;
421 
422     QTAILQ_FOREACH(iter, &s->objects, next) {
423         if (iter->watchfd == wd) {
424             return iter;
425         }
426     }
427 
428     return NULL;
429 }
430 
431 static void inotify_watchfn(void *arg)
432 {
433     MTPState *s = arg;
434     ssize_t bytes;
435     /* From the man page: atleast one event can be read */
436     int len = sizeof(struct inotify_event) + NAME_MAX + 1;
437     int pos;
438     char buf[len];
439 
440     for (;;) {
441         bytes = read(s->inotifyfd, buf, len);
442         pos = 0;
443 
444         if (bytes <= 0) {
445             /* Better luck next time */
446             return;
447         }
448 
449         /*
450          * TODO: Ignore initiator initiated events.
451          * For now we are good because the store is RO
452          */
453         while (bytes > 0) {
454             char *p = buf + pos;
455             struct inotify_event *event = (struct inotify_event *)p;
456             int watchfd = 0;
457             uint32_t mask = event->mask & (IN_CREATE | IN_DELETE |
458                                            IN_MODIFY | IN_IGNORED);
459             MTPObject *parent = usb_mtp_object_lookup_wd(s, event->wd);
460             MTPMonEntry *entry = NULL;
461             MTPObject *o;
462 
463             pos = pos + sizeof(struct inotify_event) + event->len;
464             bytes = bytes - pos;
465 
466             if (!parent) {
467                 continue;
468             }
469 
470             switch (mask) {
471             case IN_CREATE:
472                 if (usb_mtp_object_lookup_name
473                     (parent, event->name, event->len)) {
474                     /* Duplicate create event */
475                     continue;
476                 }
477                 entry = g_new0(MTPMonEntry, 1);
478                 entry->handle = s->next_handle;
479                 entry->event = EVT_OBJ_ADDED;
480                 o = usb_mtp_add_child(s, parent, event->name);
481                 if (!o) {
482                     g_free(entry);
483                     continue;
484                 }
485                 o->watchfd = watchfd;
486                 trace_usb_mtp_inotify_event(s->dev.addr, event->name,
487                                             event->mask, "Obj Added");
488                 break;
489 
490             case IN_DELETE:
491                 /*
492                  * The kernel issues a IN_IGNORED event
493                  * when a dir containing a watchpoint is
494                  * deleted, so we don't have to delete the
495                  * watchpoint
496                  */
497                 o = usb_mtp_object_lookup_name(parent, event->name, event->len);
498                 if (!o) {
499                     continue;
500                 }
501                 entry = g_new0(MTPMonEntry, 1);
502                 entry->handle = o->handle;
503                 entry->event = EVT_OBJ_REMOVED;
504                 trace_usb_mtp_inotify_event(s->dev.addr, o->path,
505                                       event->mask, "Obj Deleted");
506                 usb_mtp_object_free(s, o);
507                 break;
508 
509             case IN_MODIFY:
510                 o = usb_mtp_object_lookup_name(parent, event->name, event->len);
511                 if (!o) {
512                     continue;
513                 }
514                 entry = g_new0(MTPMonEntry, 1);
515                 entry->handle = o->handle;
516                 entry->event = EVT_OBJ_INFO_CHANGED;
517                 trace_usb_mtp_inotify_event(s->dev.addr, o->path,
518                                       event->mask, "Obj Modified");
519                 break;
520 
521             case IN_IGNORED:
522                 o = usb_mtp_object_lookup_name(parent, event->name, event->len);
523                 trace_usb_mtp_inotify_event(s->dev.addr, o->path,
524                                       event->mask, "Obj ignored");
525                 break;
526 
527             default:
528                 fprintf(stderr, "usb-mtp: failed to parse inotify event\n");
529                 continue;
530             }
531 
532             if (entry) {
533                 QTAILQ_INSERT_HEAD(&s->events, entry, next);
534             }
535         }
536     }
537 }
538 
539 static int usb_mtp_inotify_init(MTPState *s)
540 {
541     int fd;
542 
543     fd = inotify_init1(IN_NONBLOCK);
544     if (fd == -1) {
545         return 1;
546     }
547 
548     QTAILQ_INIT(&s->events);
549     s->inotifyfd = fd;
550 
551     qemu_set_fd_handler(fd, inotify_watchfn, NULL, s);
552 
553     return 0;
554 }
555 
556 static void usb_mtp_inotify_cleanup(MTPState *s)
557 {
558     MTPMonEntry *e, *p;
559 
560     if (!s->inotifyfd) {
561         return;
562     }
563 
564     qemu_set_fd_handler(s->inotifyfd, NULL, NULL, s);
565     close(s->inotifyfd);
566 
567     QTAILQ_FOREACH_SAFE(e, &s->events, next, p) {
568         QTAILQ_REMOVE(&s->events, e, next);
569         g_free(e);
570     }
571 }
572 
573 static int usb_mtp_add_watch(int inotifyfd, char *path)
574 {
575     uint32_t mask = IN_CREATE | IN_DELETE | IN_MODIFY |
576         IN_ISDIR;
577 
578     return inotify_add_watch(inotifyfd, path, mask);
579 }
580 #endif
581 
582 static void usb_mtp_object_readdir(MTPState *s, MTPObject *o)
583 {
584     struct dirent *entry;
585     DIR *dir;
586 
587     if (o->have_children) {
588         return;
589     }
590     o->have_children = true;
591 
592     dir = opendir(o->path);
593     if (!dir) {
594         return;
595     }
596 #ifdef __linux__
597     int watchfd = usb_mtp_add_watch(s->inotifyfd, o->path);
598     if (watchfd == -1) {
599         fprintf(stderr, "usb-mtp: failed to add watch for %s\n", o->path);
600     } else {
601         trace_usb_mtp_inotify_event(s->dev.addr, o->path,
602                                     0, "Watch Added");
603         o->watchfd = watchfd;
604     }
605 #endif
606     while ((entry = readdir(dir)) != NULL) {
607         usb_mtp_add_child(s, o, entry->d_name);
608     }
609     closedir(dir);
610 }
611 
612 /* ----------------------------------------------------------------------- */
613 
614 static MTPData *usb_mtp_data_alloc(MTPControl *c)
615 {
616     MTPData *data = g_new0(MTPData, 1);
617 
618     data->code  = c->code;
619     data->trans = c->trans;
620     data->fd    = -1;
621     data->first = true;
622     return data;
623 }
624 
625 static void usb_mtp_data_free(MTPData *data)
626 {
627     if (data == NULL) {
628         return;
629     }
630     if (data->fd != -1) {
631         close(data->fd);
632     }
633     g_free(data->data);
634     g_free(data);
635 }
636 
637 static void usb_mtp_realloc(MTPData *data, uint32_t bytes)
638 {
639     if (data->length + bytes <= data->alloc) {
640         return;
641     }
642     data->alloc = (data->length + bytes + 0xff) & ~0xff;
643     data->data  = g_realloc(data->data, data->alloc);
644 }
645 
646 static void usb_mtp_add_u8(MTPData *data, uint8_t val)
647 {
648     usb_mtp_realloc(data, 1);
649     data->data[data->length++] = val;
650 }
651 
652 static void usb_mtp_add_u16(MTPData *data, uint16_t val)
653 {
654     usb_mtp_realloc(data, 2);
655     data->data[data->length++] = (val >> 0) & 0xff;
656     data->data[data->length++] = (val >> 8) & 0xff;
657 }
658 
659 static void usb_mtp_add_u32(MTPData *data, uint32_t val)
660 {
661     usb_mtp_realloc(data, 4);
662     data->data[data->length++] = (val >>  0) & 0xff;
663     data->data[data->length++] = (val >>  8) & 0xff;
664     data->data[data->length++] = (val >> 16) & 0xff;
665     data->data[data->length++] = (val >> 24) & 0xff;
666 }
667 
668 static void usb_mtp_add_u64(MTPData *data, uint64_t val)
669 {
670     usb_mtp_realloc(data, 8);
671     data->data[data->length++] = (val >>  0) & 0xff;
672     data->data[data->length++] = (val >>  8) & 0xff;
673     data->data[data->length++] = (val >> 16) & 0xff;
674     data->data[data->length++] = (val >> 24) & 0xff;
675     data->data[data->length++] = (val >> 32) & 0xff;
676     data->data[data->length++] = (val >> 40) & 0xff;
677     data->data[data->length++] = (val >> 48) & 0xff;
678     data->data[data->length++] = (val >> 56) & 0xff;
679 }
680 
681 static void usb_mtp_add_u16_array(MTPData *data, uint32_t len,
682                                   const uint16_t *vals)
683 {
684     int i;
685 
686     usb_mtp_add_u32(data, len);
687     for (i = 0; i < len; i++) {
688         usb_mtp_add_u16(data, vals[i]);
689     }
690 }
691 
692 static void usb_mtp_add_u32_array(MTPData *data, uint32_t len,
693                                   const uint32_t *vals)
694 {
695     int i;
696 
697     usb_mtp_add_u32(data, len);
698     for (i = 0; i < len; i++) {
699         usb_mtp_add_u32(data, vals[i]);
700     }
701 }
702 
703 static void usb_mtp_add_wstr(MTPData *data, const wchar_t *str)
704 {
705     uint32_t len = wcslen(str);
706     int i;
707 
708     if (len > 0) {
709         len++; /* include terminating L'\0' */
710     }
711 
712     usb_mtp_add_u8(data, len);
713     for (i = 0; i < len; i++) {
714         usb_mtp_add_u16(data, str[i]);
715     }
716 }
717 
718 static void usb_mtp_add_str(MTPData *data, const char *str)
719 {
720     uint32_t len = strlen(str)+1;
721     wchar_t wstr[len];
722     size_t ret;
723 
724     ret = mbstowcs(wstr, str, len);
725     if (ret == -1) {
726         usb_mtp_add_wstr(data, L"Oops");
727     } else {
728         usb_mtp_add_wstr(data, wstr);
729     }
730 }
731 
732 static void usb_mtp_add_time(MTPData *data, time_t time)
733 {
734     char buf[16];
735     struct tm tm;
736 
737     gmtime_r(&time, &tm);
738     strftime(buf, sizeof(buf), "%Y%m%dT%H%M%S", &tm);
739     usb_mtp_add_str(data, buf);
740 }
741 
742 /* ----------------------------------------------------------------------- */
743 
744 static void usb_mtp_queue_result(MTPState *s, uint16_t code, uint32_t trans,
745                                  int argc, uint32_t arg0, uint32_t arg1)
746 {
747     MTPControl *c = g_new0(MTPControl, 1);
748 
749     c->code  = code;
750     c->trans = trans;
751     c->argc  = argc;
752     if (argc > 0) {
753         c->argv[0] = arg0;
754     }
755     if (argc > 1) {
756         c->argv[1] = arg1;
757     }
758 
759     assert(s->result == NULL);
760     s->result = c;
761 }
762 
763 /* ----------------------------------------------------------------------- */
764 
765 static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c)
766 {
767     static const uint16_t ops[] = {
768         CMD_GET_DEVICE_INFO,
769         CMD_OPEN_SESSION,
770         CMD_CLOSE_SESSION,
771         CMD_GET_STORAGE_IDS,
772         CMD_GET_STORAGE_INFO,
773         CMD_GET_NUM_OBJECTS,
774         CMD_GET_OBJECT_HANDLES,
775         CMD_GET_OBJECT_INFO,
776         CMD_GET_OBJECT,
777         CMD_GET_PARTIAL_OBJECT,
778     };
779     static const uint16_t fmt[] = {
780         FMT_UNDEFINED_OBJECT,
781         FMT_ASSOCIATION,
782     };
783     MTPData *d = usb_mtp_data_alloc(c);
784 
785     trace_usb_mtp_op_get_device_info(s->dev.addr);
786 
787     usb_mtp_add_u16(d, 100);
788     usb_mtp_add_u32(d, 0xffffffff);
789     usb_mtp_add_u16(d, 0x0101);
790     usb_mtp_add_wstr(d, L"");
791     usb_mtp_add_u16(d, 0x0000);
792 
793     usb_mtp_add_u16_array(d, ARRAY_SIZE(ops), ops);
794     usb_mtp_add_u16_array(d, 0, NULL);
795     usb_mtp_add_u16_array(d, 0, NULL);
796     usb_mtp_add_u16_array(d, 0, NULL);
797     usb_mtp_add_u16_array(d, ARRAY_SIZE(fmt), fmt);
798 
799     usb_mtp_add_wstr(d, L"" MTP_MANUFACTURER);
800     usb_mtp_add_wstr(d, L"" MTP_PRODUCT);
801     usb_mtp_add_wstr(d, L"0.1");
802     usb_mtp_add_wstr(d, L"0123456789abcdef0123456789abcdef");
803 
804     return d;
805 }
806 
807 static MTPData *usb_mtp_get_storage_ids(MTPState *s, MTPControl *c)
808 {
809     static const uint32_t ids[] = {
810         QEMU_STORAGE_ID,
811     };
812     MTPData *d = usb_mtp_data_alloc(c);
813 
814     trace_usb_mtp_op_get_storage_ids(s->dev.addr);
815 
816     usb_mtp_add_u32_array(d, ARRAY_SIZE(ids), ids);
817 
818     return d;
819 }
820 
821 static MTPData *usb_mtp_get_storage_info(MTPState *s, MTPControl *c)
822 {
823     MTPData *d = usb_mtp_data_alloc(c);
824     struct statvfs buf;
825     int rc;
826 
827     trace_usb_mtp_op_get_storage_info(s->dev.addr);
828 
829     if (FLAG_SET(s, MTP_FLAG_WRITABLE)) {
830         usb_mtp_add_u16(d, 0x0003);
831         usb_mtp_add_u16(d, 0x0002);
832         usb_mtp_add_u16(d, 0x0000);
833     } else {
834         usb_mtp_add_u16(d, 0x0001);
835         usb_mtp_add_u16(d, 0x0002);
836         usb_mtp_add_u16(d, 0x0001);
837     }
838 
839     rc = statvfs(s->root, &buf);
840     if (rc == 0) {
841         usb_mtp_add_u64(d, (uint64_t)buf.f_frsize * buf.f_blocks);
842         usb_mtp_add_u64(d, (uint64_t)buf.f_bavail * buf.f_blocks);
843         usb_mtp_add_u32(d, buf.f_ffree);
844     } else {
845         usb_mtp_add_u64(d, 0xffffffff);
846         usb_mtp_add_u64(d, 0xffffffff);
847         usb_mtp_add_u32(d, 0xffffffff);
848     }
849 
850     usb_mtp_add_str(d, s->desc);
851     usb_mtp_add_wstr(d, L"123456789abcdef");
852     return d;
853 }
854 
855 static MTPData *usb_mtp_get_object_handles(MTPState *s, MTPControl *c,
856                                            MTPObject *o)
857 {
858     MTPData *d = usb_mtp_data_alloc(c);
859     uint32_t i = 0, handles[o->nchildren];
860     MTPObject *iter;
861 
862     trace_usb_mtp_op_get_object_handles(s->dev.addr, o->handle, o->path);
863 
864     QLIST_FOREACH(iter, &o->children, list) {
865         handles[i++] = iter->handle;
866     }
867     assert(i == o->nchildren);
868     usb_mtp_add_u32_array(d, o->nchildren, handles);
869 
870     return d;
871 }
872 
873 static MTPData *usb_mtp_get_object_info(MTPState *s, MTPControl *c,
874                                         MTPObject *o)
875 {
876     MTPData *d = usb_mtp_data_alloc(c);
877 
878     trace_usb_mtp_op_get_object_info(s->dev.addr, o->handle, o->path);
879 
880     usb_mtp_add_u32(d, QEMU_STORAGE_ID);
881     usb_mtp_add_u16(d, o->format);
882     usb_mtp_add_u16(d, 0);
883     usb_mtp_add_u32(d, o->stat.st_size);
884 
885     usb_mtp_add_u16(d, 0);
886     usb_mtp_add_u32(d, 0);
887     usb_mtp_add_u32(d, 0);
888     usb_mtp_add_u32(d, 0);
889     usb_mtp_add_u32(d, 0);
890     usb_mtp_add_u32(d, 0);
891     usb_mtp_add_u32(d, 0);
892 
893     if (o->parent) {
894         usb_mtp_add_u32(d, o->parent->handle);
895     } else {
896         usb_mtp_add_u32(d, 0);
897     }
898     if (o->format == FMT_ASSOCIATION) {
899         usb_mtp_add_u16(d, 0x0001);
900         usb_mtp_add_u32(d, 0x00000001);
901         usb_mtp_add_u32(d, 0);
902     } else {
903         usb_mtp_add_u16(d, 0);
904         usb_mtp_add_u32(d, 0);
905         usb_mtp_add_u32(d, 0);
906     }
907 
908     usb_mtp_add_str(d, o->name);
909     usb_mtp_add_time(d, o->stat.st_ctime);
910     usb_mtp_add_time(d, o->stat.st_mtime);
911     usb_mtp_add_wstr(d, L"");
912 
913     return d;
914 }
915 
916 static MTPData *usb_mtp_get_object(MTPState *s, MTPControl *c,
917                                    MTPObject *o)
918 {
919     MTPData *d = usb_mtp_data_alloc(c);
920 
921     trace_usb_mtp_op_get_object(s->dev.addr, o->handle, o->path);
922 
923     d->fd = open(o->path, O_RDONLY);
924     if (d->fd == -1) {
925         usb_mtp_data_free(d);
926         return NULL;
927     }
928     d->length = o->stat.st_size;
929     d->alloc  = 512;
930     d->data   = g_malloc(d->alloc);
931     return d;
932 }
933 
934 static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,
935                                            MTPObject *o)
936 {
937     MTPData *d = usb_mtp_data_alloc(c);
938     off_t offset;
939 
940     trace_usb_mtp_op_get_partial_object(s->dev.addr, o->handle, o->path,
941                                         c->argv[1], c->argv[2]);
942 
943     d->fd = open(o->path, O_RDONLY);
944     if (d->fd == -1) {
945         usb_mtp_data_free(d);
946         return NULL;
947     }
948 
949     offset = c->argv[1];
950     if (offset > o->stat.st_size) {
951         offset = o->stat.st_size;
952     }
953     if (lseek(d->fd, offset, SEEK_SET) < 0) {
954         usb_mtp_data_free(d);
955         return NULL;
956     }
957 
958     d->length = c->argv[2];
959     if (d->length > o->stat.st_size - offset) {
960         d->length = o->stat.st_size - offset;
961     }
962 
963     return d;
964 }
965 
966 static void usb_mtp_command(MTPState *s, MTPControl *c)
967 {
968     MTPData *data_in = NULL;
969     MTPObject *o;
970     uint32_t nres = 0, res0 = 0;
971 
972     /* sanity checks */
973     if (c->code >= CMD_CLOSE_SESSION && s->session == 0) {
974         usb_mtp_queue_result(s, RES_SESSION_NOT_OPEN,
975                              c->trans, 0, 0, 0);
976         return;
977     }
978 
979     /* process commands */
980     switch (c->code) {
981     case CMD_GET_DEVICE_INFO:
982         data_in = usb_mtp_get_device_info(s, c);
983         break;
984     case CMD_OPEN_SESSION:
985         if (s->session) {
986             usb_mtp_queue_result(s, RES_SESSION_ALREADY_OPEN,
987                                  c->trans, 1, s->session, 0);
988             return;
989         }
990         if (c->argv[0] == 0) {
991             usb_mtp_queue_result(s, RES_INVALID_PARAMETER,
992                                  c->trans, 0, 0, 0);
993             return;
994         }
995         trace_usb_mtp_op_open_session(s->dev.addr);
996         s->session = c->argv[0];
997         usb_mtp_object_alloc(s, s->next_handle++, NULL, s->root);
998 #ifdef __linux__
999         if (usb_mtp_inotify_init(s)) {
1000             fprintf(stderr, "usb-mtp: file monitoring init failed\n");
1001         }
1002 #endif
1003         break;
1004     case CMD_CLOSE_SESSION:
1005         trace_usb_mtp_op_close_session(s->dev.addr);
1006         s->session = 0;
1007         s->next_handle = 0;
1008 #ifdef __linux__
1009         usb_mtp_inotify_cleanup(s);
1010 #endif
1011         usb_mtp_object_free(s, QTAILQ_FIRST(&s->objects));
1012         assert(QTAILQ_EMPTY(&s->objects));
1013         break;
1014     case CMD_GET_STORAGE_IDS:
1015         data_in = usb_mtp_get_storage_ids(s, c);
1016         break;
1017     case CMD_GET_STORAGE_INFO:
1018         if (c->argv[0] != QEMU_STORAGE_ID &&
1019             c->argv[0] != 0xffffffff) {
1020             usb_mtp_queue_result(s, RES_INVALID_STORAGE_ID,
1021                                  c->trans, 0, 0, 0);
1022             return;
1023         }
1024         data_in = usb_mtp_get_storage_info(s, c);
1025         break;
1026     case CMD_GET_NUM_OBJECTS:
1027     case CMD_GET_OBJECT_HANDLES:
1028         if (c->argv[0] != QEMU_STORAGE_ID &&
1029             c->argv[0] != 0xffffffff) {
1030             usb_mtp_queue_result(s, RES_INVALID_STORAGE_ID,
1031                                  c->trans, 0, 0, 0);
1032             return;
1033         }
1034         if (c->argv[1] != 0x00000000) {
1035             usb_mtp_queue_result(s, RES_SPEC_BY_FORMAT_UNSUPPORTED,
1036                                  c->trans, 0, 0, 0);
1037             return;
1038         }
1039         if (c->argv[2] == 0x00000000 ||
1040             c->argv[2] == 0xffffffff) {
1041             o = QTAILQ_FIRST(&s->objects);
1042         } else {
1043             o = usb_mtp_object_lookup(s, c->argv[2]);
1044         }
1045         if (o == NULL) {
1046             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
1047                                  c->trans, 0, 0, 0);
1048             return;
1049         }
1050         if (o->format != FMT_ASSOCIATION) {
1051             usb_mtp_queue_result(s, RES_INVALID_PARENT_OBJECT,
1052                                  c->trans, 0, 0, 0);
1053             return;
1054         }
1055         usb_mtp_object_readdir(s, o);
1056         if (c->code == CMD_GET_NUM_OBJECTS) {
1057             trace_usb_mtp_op_get_num_objects(s->dev.addr, o->handle, o->path);
1058             nres = 1;
1059             res0 = o->nchildren;
1060         } else {
1061             data_in = usb_mtp_get_object_handles(s, c, o);
1062         }
1063         break;
1064     case CMD_GET_OBJECT_INFO:
1065         o = usb_mtp_object_lookup(s, c->argv[0]);
1066         if (o == NULL) {
1067             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
1068                                  c->trans, 0, 0, 0);
1069             return;
1070         }
1071         data_in = usb_mtp_get_object_info(s, c, o);
1072         break;
1073     case CMD_GET_OBJECT:
1074         o = usb_mtp_object_lookup(s, c->argv[0]);
1075         if (o == NULL) {
1076             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
1077                                  c->trans, 0, 0, 0);
1078             return;
1079         }
1080         if (o->format == FMT_ASSOCIATION) {
1081             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
1082                                  c->trans, 0, 0, 0);
1083             return;
1084         }
1085         data_in = usb_mtp_get_object(s, c, o);
1086         if (data_in == NULL) {
1087             usb_mtp_queue_result(s, RES_GENERAL_ERROR,
1088                                  c->trans, 0, 0, 0);
1089             return;
1090         }
1091         break;
1092     case CMD_GET_PARTIAL_OBJECT:
1093         o = usb_mtp_object_lookup(s, c->argv[0]);
1094         if (o == NULL) {
1095             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
1096                                  c->trans, 0, 0, 0);
1097             return;
1098         }
1099         if (o->format == FMT_ASSOCIATION) {
1100             usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
1101                                  c->trans, 0, 0, 0);
1102             return;
1103         }
1104         data_in = usb_mtp_get_partial_object(s, c, o);
1105         if (data_in == NULL) {
1106             usb_mtp_queue_result(s, RES_GENERAL_ERROR,
1107                                  c->trans, 0, 0, 0);
1108             return;
1109         }
1110         nres = 1;
1111         res0 = data_in->length;
1112         break;
1113     default:
1114         trace_usb_mtp_op_unknown(s->dev.addr, c->code);
1115         usb_mtp_queue_result(s, RES_OPERATION_NOT_SUPPORTED,
1116                              c->trans, 0, 0, 0);
1117         return;
1118     }
1119 
1120     /* return results on success */
1121     if (data_in) {
1122         assert(s->data_in == NULL);
1123         s->data_in = data_in;
1124     }
1125     usb_mtp_queue_result(s, RES_OK, c->trans, nres, res0, 0);
1126 }
1127 
1128 /* ----------------------------------------------------------------------- */
1129 
1130 static void usb_mtp_handle_reset(USBDevice *dev)
1131 {
1132     MTPState *s = USB_MTP(dev);
1133 
1134     trace_usb_mtp_reset(s->dev.addr);
1135 
1136 #ifdef __linux__
1137     usb_mtp_inotify_cleanup(s);
1138 #endif
1139     usb_mtp_object_free(s, QTAILQ_FIRST(&s->objects));
1140     s->session = 0;
1141     usb_mtp_data_free(s->data_in);
1142     s->data_in = NULL;
1143     usb_mtp_data_free(s->data_out);
1144     s->data_out = NULL;
1145     g_free(s->result);
1146     s->result = NULL;
1147 }
1148 
1149 static void usb_mtp_handle_control(USBDevice *dev, USBPacket *p,
1150                                    int request, int value, int index,
1151                                    int length, uint8_t *data)
1152 {
1153     int ret;
1154 
1155     ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
1156     if (ret >= 0) {
1157         return;
1158     }
1159 
1160     trace_usb_mtp_stall(dev->addr, "unknown control request");
1161     p->status = USB_RET_STALL;
1162 }
1163 
1164 static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p)
1165 {
1166     /* we don't use async packets, so this should never be called */
1167     fprintf(stderr, "%s\n", __func__);
1168 }
1169 
1170 static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p)
1171 {
1172     MTPState *s = USB_MTP(dev);
1173     MTPControl cmd;
1174     mtp_container container;
1175     uint32_t params[5];
1176     int i, rc;
1177 
1178     switch (p->ep->nr) {
1179     case EP_DATA_IN:
1180         if (s->data_out != NULL) {
1181             /* guest bug */
1182             trace_usb_mtp_stall(s->dev.addr, "awaiting data-out");
1183             p->status = USB_RET_STALL;
1184             return;
1185         }
1186         if (p->iov.size < sizeof(container)) {
1187             trace_usb_mtp_stall(s->dev.addr, "packet too small");
1188             p->status = USB_RET_STALL;
1189             return;
1190         }
1191         if (s->data_in !=  NULL) {
1192             MTPData *d = s->data_in;
1193             int dlen = d->length - d->offset;
1194             if (d->first) {
1195                 trace_usb_mtp_data_in(s->dev.addr, d->trans, d->length);
1196                 container.length = cpu_to_le32(d->length + sizeof(container));
1197                 container.type   = cpu_to_le16(TYPE_DATA);
1198                 container.code   = cpu_to_le16(d->code);
1199                 container.trans  = cpu_to_le32(d->trans);
1200                 usb_packet_copy(p, &container, sizeof(container));
1201                 d->first = false;
1202                 if (dlen > p->iov.size - sizeof(container)) {
1203                     dlen = p->iov.size - sizeof(container);
1204                 }
1205             } else {
1206                 if (dlen > p->iov.size) {
1207                     dlen = p->iov.size;
1208                 }
1209             }
1210             if (d->fd == -1) {
1211                 usb_packet_copy(p, d->data + d->offset, dlen);
1212             } else {
1213                 if (d->alloc < p->iov.size) {
1214                     d->alloc = p->iov.size;
1215                     d->data = g_realloc(d->data, d->alloc);
1216                 }
1217                 rc = read(d->fd, d->data, dlen);
1218                 if (rc != dlen) {
1219                     memset(d->data, 0, dlen);
1220                     s->result->code = RES_INCOMPLETE_TRANSFER;
1221                 }
1222                 usb_packet_copy(p, d->data, dlen);
1223             }
1224             d->offset += dlen;
1225             if (d->offset == d->length) {
1226                 usb_mtp_data_free(s->data_in);
1227                 s->data_in = NULL;
1228             }
1229         } else if (s->result != NULL) {
1230             MTPControl *r = s->result;
1231             int length = sizeof(container) + r->argc * sizeof(uint32_t);
1232             if (r->code == RES_OK) {
1233                 trace_usb_mtp_success(s->dev.addr, r->trans,
1234                                       (r->argc > 0) ? r->argv[0] : 0,
1235                                       (r->argc > 1) ? r->argv[1] : 0);
1236             } else {
1237                 trace_usb_mtp_error(s->dev.addr, r->code, r->trans,
1238                                     (r->argc > 0) ? r->argv[0] : 0,
1239                                     (r->argc > 1) ? r->argv[1] : 0);
1240             }
1241             container.length = cpu_to_le32(length);
1242             container.type   = cpu_to_le16(TYPE_RESPONSE);
1243             container.code   = cpu_to_le16(r->code);
1244             container.trans  = cpu_to_le32(r->trans);
1245             for (i = 0; i < r->argc; i++) {
1246                 params[i] = cpu_to_le32(r->argv[i]);
1247             }
1248             usb_packet_copy(p, &container, sizeof(container));
1249             usb_packet_copy(p, &params, length - sizeof(container));
1250             g_free(s->result);
1251             s->result = NULL;
1252         }
1253         break;
1254     case EP_DATA_OUT:
1255         if (p->iov.size < sizeof(container)) {
1256             trace_usb_mtp_stall(s->dev.addr, "packet too small");
1257             p->status = USB_RET_STALL;
1258             return;
1259         }
1260         usb_packet_copy(p, &container, sizeof(container));
1261         switch (le16_to_cpu(container.type)) {
1262         case TYPE_COMMAND:
1263             if (s->data_in || s->data_out || s->result) {
1264                 trace_usb_mtp_stall(s->dev.addr, "transaction inflight");
1265                 p->status = USB_RET_STALL;
1266                 return;
1267             }
1268             cmd.code = le16_to_cpu(container.code);
1269             cmd.argc = (le32_to_cpu(container.length) - sizeof(container))
1270                 / sizeof(uint32_t);
1271             cmd.trans = le32_to_cpu(container.trans);
1272             if (cmd.argc > ARRAY_SIZE(cmd.argv)) {
1273                 cmd.argc = ARRAY_SIZE(cmd.argv);
1274             }
1275             if (p->iov.size < sizeof(container) + cmd.argc * sizeof(uint32_t)) {
1276                 trace_usb_mtp_stall(s->dev.addr, "packet too small");
1277                 p->status = USB_RET_STALL;
1278                 return;
1279             }
1280             usb_packet_copy(p, &params, cmd.argc * sizeof(uint32_t));
1281             for (i = 0; i < cmd.argc; i++) {
1282                 cmd.argv[i] = le32_to_cpu(params[i]);
1283             }
1284             trace_usb_mtp_command(s->dev.addr, cmd.code, cmd.trans,
1285                                   (cmd.argc > 0) ? cmd.argv[0] : 0,
1286                                   (cmd.argc > 1) ? cmd.argv[1] : 0,
1287                                   (cmd.argc > 2) ? cmd.argv[2] : 0,
1288                                   (cmd.argc > 3) ? cmd.argv[3] : 0,
1289                                   (cmd.argc > 4) ? cmd.argv[4] : 0);
1290             usb_mtp_command(s, &cmd);
1291             break;
1292         default:
1293             /* not needed as long as the mtp device is read-only */
1294             p->status = USB_RET_STALL;
1295             return;
1296         }
1297         break;
1298     case EP_EVENT:
1299 #ifdef __linux__
1300         if (!QTAILQ_EMPTY(&s->events)) {
1301             struct MTPMonEntry *e = QTAILQ_LAST(&s->events, events);
1302             uint32_t handle;
1303             int len = sizeof(container) + sizeof(uint32_t);
1304 
1305             if (p->iov.size < len) {
1306                 trace_usb_mtp_stall(s->dev.addr,
1307                                     "packet too small to send event");
1308                 p->status = USB_RET_STALL;
1309                 return;
1310             }
1311 
1312             QTAILQ_REMOVE(&s->events, e, next);
1313             container.length = cpu_to_le32(len);
1314             container.type = cpu_to_le32(TYPE_EVENT);
1315             container.code = cpu_to_le16(e->event);
1316             container.trans = 0; /* no trans specific events */
1317             handle = cpu_to_le32(e->handle);
1318             usb_packet_copy(p, &container, sizeof(container));
1319             usb_packet_copy(p, &handle, sizeof(uint32_t));
1320             g_free(e);
1321             return;
1322         }
1323 #endif
1324         p->status = USB_RET_NAK;
1325         return;
1326     default:
1327         trace_usb_mtp_stall(s->dev.addr, "invalid endpoint");
1328         p->status = USB_RET_STALL;
1329         return;
1330     }
1331 
1332     if (p->actual_length == 0) {
1333         trace_usb_mtp_nak(s->dev.addr, p->ep->nr);
1334         p->status = USB_RET_NAK;
1335         return;
1336     } else {
1337         trace_usb_mtp_xfer(s->dev.addr, p->ep->nr, p->actual_length,
1338                            p->iov.size);
1339         return;
1340     }
1341 }
1342 
1343 static void usb_mtp_realize(USBDevice *dev, Error **errp)
1344 {
1345     MTPState *s = USB_MTP(dev);
1346 
1347     usb_desc_create_serial(dev);
1348     usb_desc_init(dev);
1349     QTAILQ_INIT(&s->objects);
1350     if (s->desc == NULL) {
1351         if (s->root == NULL) {
1352             error_setg(errp, "usb-mtp: x-root property must be configured");
1353             return;
1354         }
1355         s->desc = strrchr(s->root, '/');
1356         if (s->desc && s->desc[0]) {
1357             s->desc = g_strdup(s->desc + 1);
1358         } else {
1359             s->desc = g_strdup("none");
1360         }
1361     }
1362 }
1363 
1364 static const VMStateDescription vmstate_usb_mtp = {
1365     .name = "usb-mtp",
1366     .unmigratable = 1,
1367     .version_id = 1,
1368     .minimum_version_id = 1,
1369     .fields = (VMStateField[]) {
1370         VMSTATE_USB_DEVICE(dev, MTPState),
1371         VMSTATE_END_OF_LIST()
1372     }
1373 };
1374 
1375 static Property mtp_properties[] = {
1376     DEFINE_PROP_STRING("x-root", MTPState, root),
1377     DEFINE_PROP_STRING("desc", MTPState, desc),
1378     DEFINE_PROP_END_OF_LIST(),
1379 };
1380 
1381 static void usb_mtp_class_initfn(ObjectClass *klass, void *data)
1382 {
1383     DeviceClass *dc = DEVICE_CLASS(klass);
1384     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1385 
1386     uc->realize        = usb_mtp_realize;
1387     uc->product_desc   = "QEMU USB MTP";
1388     uc->usb_desc       = &desc;
1389     uc->cancel_packet  = usb_mtp_cancel_packet;
1390     uc->handle_attach  = usb_desc_attach;
1391     uc->handle_reset   = usb_mtp_handle_reset;
1392     uc->handle_control = usb_mtp_handle_control;
1393     uc->handle_data    = usb_mtp_handle_data;
1394     dc->fw_name = "mtp";
1395     dc->vmsd = &vmstate_usb_mtp;
1396     dc->props = mtp_properties;
1397 }
1398 
1399 static TypeInfo mtp_info = {
1400     .name          = TYPE_USB_MTP,
1401     .parent        = TYPE_USB_DEVICE,
1402     .instance_size = sizeof(MTPState),
1403     .class_init    = usb_mtp_class_initfn,
1404 };
1405 
1406 static void usb_mtp_register_types(void)
1407 {
1408     type_register_static(&mtp_info);
1409 }
1410 
1411 type_init(usb_mtp_register_types)
1412