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