xref: /qemu/hw/usb/bus.c (revision 401e311f)
1 #include "qemu/osdep.h"
2 #include "hw/qdev-properties.h"
3 #include "hw/usb.h"
4 #include "qapi/error.h"
5 #include "qapi/qapi-commands-machine.h"
6 #include "qapi/type-helpers.h"
7 #include "qemu/error-report.h"
8 #include "qemu/module.h"
9 #include "sysemu/sysemu.h"
10 #include "migration/vmstate.h"
11 #include "monitor/monitor.h"
12 #include "trace.h"
13 #include "qemu/cutils.h"
14 
15 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
16 
17 static char *usb_get_dev_path(DeviceState *dev);
18 static char *usb_get_fw_dev_path(DeviceState *qdev);
19 static void usb_qdev_unrealize(DeviceState *qdev);
20 
21 static Property usb_props[] = {
22     DEFINE_PROP_STRING("port", USBDevice, port_path),
23     DEFINE_PROP_STRING("serial", USBDevice, serial),
24     DEFINE_PROP_BIT("msos-desc", USBDevice, flags,
25                     USB_DEV_FLAG_MSOS_DESC_ENABLE, true),
26     DEFINE_PROP_STRING("pcap", USBDevice, pcap_filename),
27     DEFINE_PROP_END_OF_LIST()
28 };
29 
30 static void usb_bus_class_init(ObjectClass *klass, void *data)
31 {
32     BusClass *k = BUS_CLASS(klass);
33     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
34 
35     k->print_dev = usb_bus_dev_print;
36     k->get_dev_path = usb_get_dev_path;
37     k->get_fw_dev_path = usb_get_fw_dev_path;
38     hc->unplug = qdev_simple_device_unplug_cb;
39 }
40 
41 static const TypeInfo usb_bus_info = {
42     .name = TYPE_USB_BUS,
43     .parent = TYPE_BUS,
44     .instance_size = sizeof(USBBus),
45     .class_init = usb_bus_class_init,
46     .interfaces = (InterfaceInfo[]) {
47         { TYPE_HOTPLUG_HANDLER },
48         { }
49     }
50 };
51 
52 static int next_usb_bus = 0;
53 static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses);
54 
55 static int usb_device_post_load(void *opaque, int version_id)
56 {
57     USBDevice *dev = opaque;
58 
59     if (dev->state == USB_STATE_NOTATTACHED) {
60         dev->attached = false;
61     } else {
62         dev->attached = true;
63     }
64     return 0;
65 }
66 
67 const VMStateDescription vmstate_usb_device = {
68     .name = "USBDevice",
69     .version_id = 1,
70     .minimum_version_id = 1,
71     .post_load = usb_device_post_load,
72     .fields = (const VMStateField[]) {
73         VMSTATE_UINT8(addr, USBDevice),
74         VMSTATE_INT32(state, USBDevice),
75         VMSTATE_INT32(remote_wakeup, USBDevice),
76         VMSTATE_INT32(setup_state, USBDevice),
77         VMSTATE_INT32(setup_len, USBDevice),
78         VMSTATE_INT32(setup_index, USBDevice),
79         VMSTATE_UINT8_ARRAY(setup_buf, USBDevice, 8),
80         VMSTATE_END_OF_LIST(),
81     }
82 };
83 
84 void usb_bus_new(USBBus *bus, size_t bus_size,
85                  USBBusOps *ops, DeviceState *host)
86 {
87     qbus_init(bus, bus_size, TYPE_USB_BUS, host, NULL);
88     qbus_set_bus_hotplug_handler(BUS(bus));
89     bus->ops = ops;
90     bus->busnr = next_usb_bus++;
91     QTAILQ_INIT(&bus->free);
92     QTAILQ_INIT(&bus->used);
93     QTAILQ_INSERT_TAIL(&busses, bus, next);
94 }
95 
96 void usb_bus_release(USBBus *bus)
97 {
98     assert(next_usb_bus > 0);
99 
100     QTAILQ_REMOVE(&busses, bus, next);
101 }
102 
103 static void usb_device_realize(USBDevice *dev, Error **errp)
104 {
105     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
106 
107     if (klass->realize) {
108         klass->realize(dev, errp);
109     }
110 }
111 
112 USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr)
113 {
114     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
115     if (klass->find_device) {
116         return klass->find_device(dev, addr);
117     }
118     return NULL;
119 }
120 
121 static void usb_device_unrealize(USBDevice *dev)
122 {
123     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
124 
125     if (klass->unrealize) {
126         klass->unrealize(dev);
127     }
128 }
129 
130 void usb_device_cancel_packet(USBDevice *dev, USBPacket *p)
131 {
132     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
133     if (klass->cancel_packet) {
134         klass->cancel_packet(dev, p);
135     }
136 }
137 
138 void usb_device_handle_attach(USBDevice *dev)
139 {
140     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
141     if (klass->handle_attach) {
142         klass->handle_attach(dev);
143     }
144 }
145 
146 void usb_device_handle_reset(USBDevice *dev)
147 {
148     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
149     if (klass->handle_reset) {
150         klass->handle_reset(dev);
151     }
152 }
153 
154 void usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
155                                int value, int index, int length, uint8_t *data)
156 {
157     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
158     if (klass->handle_control) {
159         klass->handle_control(dev, p, request, value, index, length, data);
160     }
161 }
162 
163 void usb_device_handle_data(USBDevice *dev, USBPacket *p)
164 {
165     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
166     if (klass->handle_data) {
167         klass->handle_data(dev, p);
168     }
169 }
170 
171 const char *usb_device_get_product_desc(USBDevice *dev)
172 {
173     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
174     return klass->product_desc;
175 }
176 
177 const USBDesc *usb_device_get_usb_desc(USBDevice *dev)
178 {
179     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
180     if (dev->usb_desc) {
181         return dev->usb_desc;
182     }
183     return klass->usb_desc;
184 }
185 
186 void usb_device_set_interface(USBDevice *dev, int interface,
187                               int alt_old, int alt_new)
188 {
189     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
190     if (klass->set_interface) {
191         klass->set_interface(dev, interface, alt_old, alt_new);
192     }
193 }
194 
195 void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
196 {
197     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
198     if (klass->flush_ep_queue) {
199         klass->flush_ep_queue(dev, ep);
200     }
201 }
202 
203 void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep)
204 {
205     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
206     if (klass->ep_stopped) {
207         klass->ep_stopped(dev, ep);
208     }
209 }
210 
211 int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
212                              int streams)
213 {
214     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
215     if (klass->alloc_streams) {
216         return klass->alloc_streams(dev, eps, nr_eps, streams);
217     }
218     return 0;
219 }
220 
221 void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps)
222 {
223     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
224     if (klass->free_streams) {
225         klass->free_streams(dev, eps, nr_eps);
226     }
227 }
228 
229 static void usb_qdev_realize(DeviceState *qdev, Error **errp)
230 {
231     USBDevice *dev = USB_DEVICE(qdev);
232     Error *local_err = NULL;
233 
234     pstrcpy(dev->product_desc, sizeof(dev->product_desc),
235             usb_device_get_product_desc(dev));
236     dev->auto_attach = 1;
237     QLIST_INIT(&dev->strings);
238     usb_ep_init(dev);
239 
240     usb_claim_port(dev, &local_err);
241     if (local_err) {
242         error_propagate(errp, local_err);
243         return;
244     }
245 
246     usb_device_realize(dev, &local_err);
247     if (local_err) {
248         usb_release_port(dev);
249         error_propagate(errp, local_err);
250         return;
251     }
252 
253     if (dev->auto_attach) {
254         usb_device_attach(dev, &local_err);
255         if (local_err) {
256             usb_qdev_unrealize(qdev);
257             error_propagate(errp, local_err);
258             return;
259         }
260     }
261 
262     if (dev->pcap_filename) {
263         int fd = qemu_open_old(dev->pcap_filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
264         if (fd < 0) {
265             error_setg(errp, "open %s failed", dev->pcap_filename);
266             usb_qdev_unrealize(qdev);
267             return;
268         }
269         dev->pcap = fdopen(fd, "w");
270         usb_pcap_init(dev->pcap);
271     }
272 }
273 
274 static void usb_qdev_unrealize(DeviceState *qdev)
275 {
276     USBDevice *dev = USB_DEVICE(qdev);
277     USBDescString *s, *next;
278 
279     QLIST_FOREACH_SAFE(s, &dev->strings, next, next) {
280         QLIST_REMOVE(s, next);
281         g_free(s->str);
282         g_free(s);
283     }
284 
285     if (dev->pcap) {
286         fclose(dev->pcap);
287     }
288 
289     if (dev->attached) {
290         usb_device_detach(dev);
291     }
292     usb_device_unrealize(dev);
293     if (dev->port) {
294         usb_release_port(dev);
295     }
296 }
297 
298 typedef struct LegacyUSBFactory
299 {
300     const char *name;
301     const char *usbdevice_name;
302     USBDevice *(*usbdevice_init)(void);
303 } LegacyUSBFactory;
304 
305 static GSList *legacy_usb_factory;
306 
307 void usb_legacy_register(const char *typename, const char *usbdevice_name,
308                          USBDevice *(*usbdevice_init)(void))
309 {
310     if (usbdevice_name) {
311         LegacyUSBFactory *f = g_malloc0(sizeof(*f));
312         f->name = typename;
313         f->usbdevice_name = usbdevice_name;
314         f->usbdevice_init = usbdevice_init;
315         legacy_usb_factory = g_slist_append(legacy_usb_factory, f);
316     }
317 }
318 
319 static void usb_fill_port(USBPort *port, void *opaque, int index,
320                           USBPortOps *ops, int speedmask)
321 {
322     port->opaque = opaque;
323     port->index = index;
324     port->ops = ops;
325     port->speedmask = speedmask;
326     usb_port_location(port, NULL, index + 1);
327 }
328 
329 void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
330                        USBPortOps *ops, int speedmask)
331 {
332     usb_fill_port(port, opaque, index, ops, speedmask);
333     QTAILQ_INSERT_TAIL(&bus->free, port, next);
334     bus->nfree++;
335 }
336 
337 void usb_register_companion(const char *masterbus, USBPort *ports[],
338                             uint32_t portcount, uint32_t firstport,
339                             void *opaque, USBPortOps *ops, int speedmask,
340                             Error **errp)
341 {
342     USBBus *bus;
343     int i;
344 
345     QTAILQ_FOREACH(bus, &busses, next) {
346         if (strcmp(bus->qbus.name, masterbus) == 0) {
347             break;
348         }
349     }
350 
351     if (!bus) {
352         error_setg(errp, "USB bus '%s' not found", masterbus);
353         return;
354     }
355     if (!bus->ops->register_companion) {
356         error_setg(errp, "Can't use USB bus '%s' as masterbus,"
357                    " it doesn't support companion controllers",
358                    masterbus);
359         return;
360     }
361 
362     for (i = 0; i < portcount; i++) {
363         usb_fill_port(ports[i], opaque, i, ops, speedmask);
364     }
365 
366     bus->ops->register_companion(bus, ports, portcount, firstport, errp);
367 }
368 
369 void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr)
370 {
371     if (upstream) {
372         int l = snprintf(downstream->path, sizeof(downstream->path), "%s.%d",
373                          upstream->path, portnr);
374         /* Max string is nn.nn.nn.nn.nn, which fits in 16 bytes */
375         assert(l < sizeof(downstream->path));
376         downstream->hubcount = upstream->hubcount + 1;
377     } else {
378         snprintf(downstream->path, sizeof(downstream->path), "%d", portnr);
379         downstream->hubcount = 0;
380     }
381 }
382 
383 void usb_unregister_port(USBBus *bus, USBPort *port)
384 {
385     if (port->dev) {
386         object_unparent(OBJECT(port->dev));
387     }
388     QTAILQ_REMOVE(&bus->free, port, next);
389     bus->nfree--;
390 }
391 
392 void usb_claim_port(USBDevice *dev, Error **errp)
393 {
394     USBBus *bus = usb_bus_from_device(dev);
395     USBPort *port;
396     USBDevice *hub;
397 
398     assert(dev->port == NULL);
399 
400     if (dev->port_path) {
401         QTAILQ_FOREACH(port, &bus->free, next) {
402             if (strcmp(port->path, dev->port_path) == 0) {
403                 break;
404             }
405         }
406         if (port == NULL) {
407             error_setg(errp, "usb port %s (bus %s) not found (in use?)",
408                        dev->port_path, bus->qbus.name);
409             return;
410         }
411     } else {
412         if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) {
413             /* Create a new hub and chain it on */
414             hub = usb_try_new("usb-hub");
415             if (hub) {
416                 usb_realize_and_unref(hub, bus, NULL);
417             }
418         }
419         if (bus->nfree == 0) {
420             error_setg(errp, "tried to attach usb device %s to a bus "
421                        "with no free ports", dev->product_desc);
422             return;
423         }
424         port = QTAILQ_FIRST(&bus->free);
425     }
426     trace_usb_port_claim(bus->busnr, port->path);
427 
428     QTAILQ_REMOVE(&bus->free, port, next);
429     bus->nfree--;
430 
431     dev->port = port;
432     port->dev = dev;
433 
434     QTAILQ_INSERT_TAIL(&bus->used, port, next);
435     bus->nused++;
436 }
437 
438 void usb_release_port(USBDevice *dev)
439 {
440     USBBus *bus = usb_bus_from_device(dev);
441     USBPort *port = dev->port;
442 
443     assert(port != NULL);
444     trace_usb_port_release(bus->busnr, port->path);
445 
446     QTAILQ_REMOVE(&bus->used, port, next);
447     bus->nused--;
448 
449     dev->port = NULL;
450     port->dev = NULL;
451 
452     QTAILQ_INSERT_TAIL(&bus->free, port, next);
453     bus->nfree++;
454 }
455 
456 static void usb_mask_to_str(char *dest, size_t size,
457                             unsigned int speedmask)
458 {
459     static const struct {
460         unsigned int mask;
461         const char *name;
462     } speeds[] = {
463         { .mask = USB_SPEED_MASK_FULL,  .name = "full"  },
464         { .mask = USB_SPEED_MASK_HIGH,  .name = "high"  },
465         { .mask = USB_SPEED_MASK_SUPER, .name = "super" },
466     };
467     int i, pos = 0;
468 
469     for (i = 0; i < ARRAY_SIZE(speeds); i++) {
470         if (speeds[i].mask & speedmask) {
471             pos += snprintf(dest + pos, size - pos, "%s%s",
472                             pos ? "+" : "",
473                             speeds[i].name);
474         }
475     }
476 
477     if (pos == 0) {
478         snprintf(dest, size, "unknown");
479     }
480 }
481 
482 void usb_check_attach(USBDevice *dev, Error **errp)
483 {
484     USBBus *bus = usb_bus_from_device(dev);
485     USBPort *port = dev->port;
486     char devspeed[32], portspeed[32];
487 
488     assert(port != NULL);
489     assert(!dev->attached);
490     usb_mask_to_str(devspeed, sizeof(devspeed), dev->speedmask);
491     usb_mask_to_str(portspeed, sizeof(portspeed), port->speedmask);
492     trace_usb_port_attach(bus->busnr, port->path,
493                           devspeed, portspeed);
494 
495     if (!(port->speedmask & dev->speedmask)) {
496         error_setg(errp, "Warning: speed mismatch trying to attach"
497                    " usb device \"%s\" (%s speed)"
498                    " to bus \"%s\", port \"%s\" (%s speed)",
499                    dev->product_desc, devspeed,
500                    bus->qbus.name, port->path, portspeed);
501         return;
502     }
503 }
504 
505 void usb_device_attach(USBDevice *dev, Error **errp)
506 {
507     USBPort *port = dev->port;
508     Error *local_err = NULL;
509 
510     usb_check_attach(dev, &local_err);
511     if (local_err) {
512         error_propagate(errp, local_err);
513         return;
514     }
515 
516     dev->attached = true;
517     usb_attach(port);
518 }
519 
520 int usb_device_detach(USBDevice *dev)
521 {
522     USBBus *bus = usb_bus_from_device(dev);
523     USBPort *port = dev->port;
524 
525     assert(port != NULL);
526     assert(dev->attached);
527     trace_usb_port_detach(bus->busnr, port->path);
528 
529     usb_detach(port);
530     dev->attached = false;
531     return 0;
532 }
533 
534 static const char *usb_speed(unsigned int speed)
535 {
536     static const char *txt[] = {
537         [ USB_SPEED_LOW  ] = "1.5",
538         [ USB_SPEED_FULL ] = "12",
539         [ USB_SPEED_HIGH ] = "480",
540         [ USB_SPEED_SUPER ] = "5000",
541     };
542     if (speed >= ARRAY_SIZE(txt))
543         return "?";
544     return txt[speed];
545 }
546 
547 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
548 {
549     USBDevice *dev = USB_DEVICE(qdev);
550     USBBus *bus = usb_bus_from_device(dev);
551 
552     monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
553                    indent, "", bus->busnr, dev->addr,
554                    dev->port ? dev->port->path : "-",
555                    usb_speed(dev->speed), dev->product_desc,
556                    dev->attached ? ", attached" : "");
557 }
558 
559 static char *usb_get_dev_path(DeviceState *qdev)
560 {
561     USBDevice *dev = USB_DEVICE(qdev);
562     DeviceState *hcd = qdev->parent_bus->parent;
563     char *id = qdev_get_dev_path(hcd);
564 
565     if (id) {
566         char *ret = g_strdup_printf("%s/%s", id, dev->port->path);
567         g_free(id);
568         return ret;
569     } else {
570         return g_strdup(dev->port->path);
571     }
572 }
573 
574 static char *usb_get_fw_dev_path(DeviceState *qdev)
575 {
576     USBDevice *dev = USB_DEVICE(qdev);
577     char *fw_path, *in;
578     ssize_t pos = 0, fw_len;
579     long nr;
580 
581     fw_len = 32 + strlen(dev->port->path) * 6;
582     fw_path = g_malloc(fw_len);
583     in = dev->port->path;
584     while (fw_len - pos > 0) {
585         nr = strtol(in, &in, 10);
586         if (in[0] == '.') {
587             /* some hub between root port and device */
588             pos += snprintf(fw_path + pos, fw_len - pos, "hub@%lx/", nr);
589             in++;
590         } else {
591             /* the device itself */
592             snprintf(fw_path + pos, fw_len - pos, "%s@%lx",
593                      qdev_fw_name(qdev), nr);
594             break;
595         }
596     }
597     return fw_path;
598 }
599 
600 HumanReadableText *qmp_x_query_usb(Error **errp)
601 {
602     g_autoptr(GString) buf = g_string_new("");
603     USBBus *bus;
604     USBDevice *dev;
605     USBPort *port;
606 
607     if (QTAILQ_EMPTY(&busses)) {
608         error_setg(errp, "USB support not enabled");
609         return NULL;
610     }
611 
612     QTAILQ_FOREACH(bus, &busses, next) {
613         QTAILQ_FOREACH(port, &bus->used, next) {
614             dev = port->dev;
615             if (!dev)
616                 continue;
617             g_string_append_printf(buf,
618                                    "  Device %d.%d, Port %s, Speed %s Mb/s, "
619                                    "Product %s%s%s\n",
620                                    bus->busnr, dev->addr, port->path,
621                                    usb_speed(dev->speed), dev->product_desc,
622                                    dev->qdev.id ? ", ID: " : "",
623                                    dev->qdev.id ?: "");
624         }
625     }
626 
627     return human_readable_text_from_str(buf);
628 }
629 
630 /* handle legacy -usbdevice cmd line option */
631 USBDevice *usbdevice_create(const char *driver)
632 {
633     USBBus *bus = QTAILQ_FIRST(&busses);
634     LegacyUSBFactory *f = NULL;
635     Error *err = NULL;
636     GSList *i;
637     USBDevice *dev;
638 
639     if (strchr(driver, ':')) {
640         error_report("usbdevice parameters are not supported anymore");
641         return NULL;
642     }
643 
644     for (i = legacy_usb_factory; i; i = i->next) {
645         f = i->data;
646         if (strcmp(f->usbdevice_name, driver) == 0) {
647             break;
648         }
649     }
650     if (i == NULL) {
651 #if 0
652         /* no error because some drivers are not converted (yet) */
653         error_report("usbdevice %s not found", driver);
654 #endif
655         return NULL;
656     }
657 
658     if (!bus) {
659         error_report("Error: no usb bus to attach usbdevice %s, "
660                      "please try -machine usb=on and check that "
661                      "the machine model supports USB", driver);
662         return NULL;
663     }
664 
665     dev = f->usbdevice_init ? f->usbdevice_init() : usb_new(f->name);
666     if (!dev) {
667         error_report("Failed to create USB device '%s'", f->name);
668         return NULL;
669     }
670     if (!usb_realize_and_unref(dev, bus, &err)) {
671         error_reportf_err(err, "Failed to initialize USB device '%s': ",
672                           f->name);
673         object_unparent(OBJECT(dev));
674         return NULL;
675     }
676     return dev;
677 }
678 
679 static bool usb_get_attached(Object *obj, Error **errp)
680 {
681     USBDevice *dev = USB_DEVICE(obj);
682 
683     return dev->attached;
684 }
685 
686 static void usb_set_attached(Object *obj, bool value, Error **errp)
687 {
688     USBDevice *dev = USB_DEVICE(obj);
689 
690     if (dev->attached == value) {
691         return;
692     }
693 
694     if (value) {
695         usb_device_attach(dev, errp);
696     } else {
697         usb_device_detach(dev);
698     }
699 }
700 
701 static void usb_device_instance_init(Object *obj)
702 {
703     USBDevice *dev = USB_DEVICE(obj);
704     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
705 
706     if (klass->attached_settable) {
707         object_property_add_bool(obj, "attached",
708                                  usb_get_attached, usb_set_attached);
709     } else {
710         object_property_add_bool(obj, "attached",
711                                  usb_get_attached, NULL);
712     }
713 }
714 
715 static void usb_device_class_init(ObjectClass *klass, void *data)
716 {
717     DeviceClass *k = DEVICE_CLASS(klass);
718     k->bus_type = TYPE_USB_BUS;
719     k->realize  = usb_qdev_realize;
720     k->unrealize = usb_qdev_unrealize;
721     device_class_set_props(k, usb_props);
722 }
723 
724 static const TypeInfo usb_device_type_info = {
725     .name = TYPE_USB_DEVICE,
726     .parent = TYPE_DEVICE,
727     .instance_size = sizeof(USBDevice),
728     .instance_init = usb_device_instance_init,
729     .abstract = true,
730     .class_size = sizeof(USBDeviceClass),
731     .class_init = usb_device_class_init,
732 };
733 
734 static void usb_register_types(void)
735 {
736     type_register_static(&usb_bus_info);
737     type_register_static(&usb_device_type_info);
738 }
739 
740 type_init(usb_register_types)
741