usb-linux: Get the active configuration from sysfs rather then asking the dev

Some devices seem to choke on receiving a USB_REQ_GET_CONFIGURATION ctrl msg
(witnessed with a digital picture frame usb id 1908:1320).
When usb_fs_type == USB_FS_SYS, the active configuration can be read directly
from sysfs, which allows using this device through qemu's usb redirection.
More in general it seems a good idea to not send needless control msg's to
devices, esp. as the code in question is called every time a set_interface
is done. Which happens multiple times during virtual machine startup, and
when device drivers are activating the usb device.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Hans de Goede 2010-11-10 10:06:25 +01:00 committed by Anthony Liguori
parent 71d71bbdeb
commit 2cc59d8cb0

View File

@ -152,6 +152,8 @@ static QTAILQ_HEAD(, USBHostDevice) hostdevs = QTAILQ_HEAD_INITIALIZER(hostdevs)
static int usb_host_close(USBHostDevice *dev); static int usb_host_close(USBHostDevice *dev);
static int parse_filter(const char *spec, struct USBAutoFilter *f); static int parse_filter(const char *spec, struct USBAutoFilter *f);
static void usb_host_auto_check(void *unused); static void usb_host_auto_check(void *unused);
static int usb_host_read_file(char *line, size_t line_size,
const char *device_file, const char *device_name);
static int is_isoc(USBHostDevice *s, int ep) static int is_isoc(USBHostDevice *s, int ep)
{ {
@ -781,6 +783,23 @@ static int usb_linux_get_configuration(USBHostDevice *s)
struct usb_ctrltransfer ct; struct usb_ctrltransfer ct;
int ret; int ret;
if (usb_fs_type == USB_FS_SYS) {
char device_name[32], line[1024];
int configuration;
sprintf(device_name, "%d-%d", s->bus_num, s->devpath);
if (!usb_host_read_file(line, sizeof(line), "bConfigurationValue",
device_name)) {
goto usbdevfs;
}
if (sscanf(line, "%d", &configuration) != 1) {
goto usbdevfs;
}
return configuration;
}
usbdevfs:
ct.bRequestType = USB_DIR_IN; ct.bRequestType = USB_DIR_IN;
ct.bRequest = USB_REQ_GET_CONFIGURATION; ct.bRequest = USB_REQ_GET_CONFIGURATION;
ct.wValue = 0; ct.wValue = 0;