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