USBDevice *usb_host_device_open(const char *devname)
{
    int bus_num, addr;
    char product_name[PRODUCT_NAME_SZ];

    if (strstr(devname, "auto:")) {
        usb_host_auto_add(devname);
        return NULL;
    }

    if (usb_host_find_device(&bus_num, &addr, product_name, sizeof(product_name),
                             devname) < 0)
        return NULL;

    if (hostdev_find(bus_num, addr)) {
       term_printf("husb: host usb device %d.%d is already open\n", bus_num, addr);
       return NULL;
    }

    return usb_host_device_open_addr(bus_num, addr, product_name);
}
int usb_host_device_close(const char *devname)
{
    char product_name[PRODUCT_NAME_SZ];
    int bus_num, addr;
    USBHostDevice *s;

    if (strstr(devname, "auto:"))
        return usb_host_auto_del(devname);

    if (usb_host_find_device(&bus_num, &addr, product_name, sizeof(product_name),
                             devname) < 0)
        return -1;
 
    s = hostdev_find(bus_num, addr);
    if (s) {
        usb_device_del_addr(0, s->dev.addr);
        return 0;
    }

    return -1;
}
Example #3
0
/* XXX: exclude high speed devices or implement EHCI */
USBDevice *usb_host_device_open(const char *devname)
{
    USBHostDevice *dev;
    struct usb_dev_handle *udev = NULL;
    struct usb_device *device = NULL;
    struct usb_config_descriptor config_desc;
    int config_descr_len, nb_interfaces;
    int bus_num, addr, interface, ret;
    char product_name[32] ;
    
    if ((ret = usb_host_find_device(&bus_num, &addr, devname, &device)) < 0) 
        return NULL;

    if (!device)
        return NULL;
    
    udev = usb_open(device);

    if (!udev) {
#ifdef DEBUG
        printf("couldn't open usb device at %d.%d\n", bus_num, addr);
#endif
        return NULL;
    }
    
    /* read the 1st config descriptor */
    config_descr_len = usb_get_descriptor(udev, 2, 0, &config_desc, sizeof(config_desc));
    if (config_descr_len <= 0) {
        printf("read config_desc: %s", usb_strerror());
        goto fail;
    }
    
    if (config_descr_len > sizeof(config_desc)) {
        printf("config_desc size mismatch\n");
        goto fail;
    }
        
    nb_interfaces = config_desc.bNumInterfaces;
    usb_set_configuration(udev, config_desc.bConfigurationValue);
    
    for (interface = 0; interface < nb_interfaces; interface++) {
        /* might as well */
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
        usb_detach_kernel_driver_np(udev, interface);
#endif
    
        ret = usb_claim_interface(udev, interface);
    
        if (ret < 0) {
            printf("usb_claim_interface: %s", usb_strerror());
        fail:
            if (udev)
                usb_close(udev);
            return NULL;
        }
    }

#ifdef DEBUG
    printf("host USB device %d.%d grabbed\n", bus_num, addr);
#endif

    dev = qemu_mallocz(sizeof(USBHostDevice));
    if (!dev)
        goto fail;
    
    /* not accurate - might be better off reporting only low/full */
    switch (device->descriptor.bcdUSB) {
        case 0x0110:
            dev->dev.speed = USB_SPEED_FULL;
            break;
        case 0x0200:
            dev->dev.speed = USB_SPEED_HIGH;
            break;
        case 0x0100:
            dev->dev.speed = USB_SPEED_LOW;
            break;
        default:
            dev->dev.speed = USB_SPEED_FULL;
    }
    
    dev->udev = udev;
    dev->num_interfaces = nb_interfaces;
    dev->dev.handle_packet = usb_generic_handle_packet;

    dev->dev.handle_reset = usb_host_handle_reset;
    dev->dev.handle_control = usb_host_handle_control;
    dev->dev.handle_data = usb_host_handle_data;
    dev->dev.handle_destroy = usb_host_handle_destroy;
    
    /* get product string if available */
    usb_get_string_simple(udev, device->descriptor.iProduct,
                                   product_name, sizeof(product_name));
    
    if (product_name[0] == '\0')
        snprintf(dev->dev.devname, sizeof(dev->dev.devname),
                   "host:%s", devname);
    else
        pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
                   product_name);
    
    return (USBDevice *)dev;
}