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