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