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; }
/* 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; }