Annotation of qemu/hw/usb/bus.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.