From 61751f1934af3eefbf3d6134a2f400af6b8f336c Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Tue, 25 May 2010 04:11:13 +0200 Subject: Detach kernel drivers before changing configurations This is especially useful when bConfigurationValue is 2, which tends to be a mixed HID/USB-Audio configuration that the kernel likes to use. Otherwise usbmuxd cannot change the configuration. --- daemon/usb-linux.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/daemon/usb-linux.c b/daemon/usb-linux.c index cc1bbaf..c9420c8 100644 --- a/daemon/usb-linux.c +++ b/daemon/usb-linux.c @@ -286,6 +286,26 @@ int usb_discover(void) continue; } if (current_config != devdesc.bNumConfigurations) { + struct libusb_config_descriptor *config; + if((res = libusb_get_active_config_descriptor(dev, &config)) != 0) { + usbmuxd_log(LL_NOTICE, "Could not get old configuration descriptor for device %d-%d: %d", bus, address, res); + } else { + for(j=0; jbNumInterfaces; j++) { + const struct libusb_interface_descriptor *intf = &config->interface[j].altsetting[0]; + if((res = libusb_kernel_driver_active(handle, intf->bInterfaceNumber)) < 0) { + usbmuxd_log(LL_NOTICE, "Could not check kernel ownership of interface %d for device %d-%d: %d", intf->bInterfaceNumber, bus, address, res); + continue; + } + if(res == 1) { + usbmuxd_log(LL_INFO, "Detaching kernel driver for device %d-%d, interface %d", bus, address, intf->bInterfaceNumber); + if((res = libusb_detach_kernel_driver(handle, intf->bInterfaceNumber)) < 0) { + usbmuxd_log(LL_WARNING, "Could not detach kernel driver (%d), configuration change will probably fail!", res); + continue; + } + } + } + libusb_free_config_descriptor(config); + } if((res = libusb_set_configuration(handle, devdesc.bNumConfigurations)) != 0) { usbmuxd_log(LL_WARNING, "Could not set configuration %d for device %d-%d: %d", devdesc.bNumConfigurations, bus, address, res); libusb_close(handle); -- cgit v1.1-32-gdbae