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