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