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