Commit 2cc59d8c authored by Hans de Goede's avatar Hans de Goede Committed by Anthony Liguori
Browse files

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: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent 71d71bbd
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -152,6 +152,8 @@ static QTAILQ_HEAD(, USBHostDevice) hostdevs = QTAILQ_HEAD_INITIALIZER(hostdevs)
static int usb_host_close(USBHostDevice *dev);
static int parse_filter(const char *spec, struct USBAutoFilter *f);
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)
{
@@ -781,6 +783,23 @@ static int usb_linux_get_configuration(USBHostDevice *s)
    struct usb_ctrltransfer ct;
    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.bRequest = USB_REQ_GET_CONFIGURATION;
    ct.wValue = 0;