diff --git a/.gitignore b/.gitignore index c36d837..8ae61f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /libusbx-1.0.11.tar.bz2 +/libusbx-1.0.13.tar.bz2 diff --git a/0001-linux_usbfs-Work-around-a-driver-binding-race-in-res.patch b/0001-linux_usbfs-Work-around-a-driver-binding-race-in-res.patch new file mode 100644 index 0000000..3a39c1c --- /dev/null +++ b/0001-linux_usbfs-Work-around-a-driver-binding-race-in-res.patch @@ -0,0 +1,86 @@ +From 78a150bfbbd84eb524e878bf05101c1ad2eac0b8 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 6 Jul 2012 14:35:53 +0200 +Subject: [PATCH 3/3] linux_usbfs: Work around a driver binding race in reset + handling + +I've been seeing these intermittent failures to reclaim an interface after +a device reset. After much debugging and inserting sleeps in strategic +places to make the race window larger I've found the following race: +1) A user is running some software using libusb which will automatically + detect, and "bind" to, any newly plugged in USB-devices. For example + a virtual machine viewer with automatic USB-redirection +2) The user plugs in a new usb-storage device +3) The usb-storage driver is not yet loaded, udev spawns + "modprobe usb-storage", this blocks on disk-io +4) The libusb app opens the device, claims all interfaces, does a device-reset +5) While the IOCTL_USBFS_RESET is running the modprobe completes +6) The driver registration blocks on an USB lock held by the reset code path +7) When the reset finishes the driver registration completes and the driver + binds itself to the device, before IOCTL_USBFS_RESET returns to userspace +8) libusb tries to re-claim all interfaces it had claimed before the reset +9) libusb fails as usb-storage is now bound to it + +This patch works around this issue by simply unbinding the driver for all +interfaces which were claimed before the reset. Normally this is a no-op as +no driver (other then usbfs) can be bound for claimed interfaces before the +reset. + +But as the above example shows, the exception is a driver completing +registration, and as part of this binding to any elegible devices, between +IOCTL_USBFS_RESET and our re-claiming of the interface. The largest part +of the race window here is the time IOCTL_USBFS_RESET takes, as that does a +fair amount of IO with the device. This part of the race window is +worked around by this patch. + +This still leaves a theoretical race window where the driver registration +finishes between our driver-unbind and interface-reclaim, I'm afraid there +is nothing we can against this. + +This patch also improves the error logging, and makes libusb_device_reset +properly return an error when re-claiming fails. + +Signed-off-by: Hans de Goede +--- + libusb/os/linux_usbfs.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c +index 3894554..10d138a 100644 +--- a/libusb/os/linux_usbfs.c ++++ b/libusb/os/linux_usbfs.c +@@ -108,6 +108,9 @@ static int sysfs_can_relate_devices = 0; + /* do we have a descriptors file? */ + static int sysfs_has_descriptors = 0; + ++static int op_detach_kernel_driver(struct libusb_device_handle *handle, ++ int interface); ++ + struct linux_device_priv { + char *sysfs_dir; + unsigned char *dev_descriptor; +@@ -1497,11 +1500,20 @@ static int op_reset_device(struct libusb_device_handle *handle) + /* And re-claim any interfaces which were claimed before the reset */ + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (handle->claimed_interfaces & (1L << i)) { ++ /* ++ * A driver may have completed modprobing during ++ * IOCTL_USBFS_RESET, and bound itself as soon as ++ * IOCTL_USBFS_RESET released the device lock ++ */ ++ op_detach_kernel_driver(handle, i); ++ + r = op_claim_interface(handle, i); + if (r) { + usbi_warn(HANDLE_CTX(handle), +- "failed to re-claim interface %d after reset", i); ++ "failed to re-claim interface %d after reset: %s", ++ i, libusb_error_name(r)); + handle->claimed_interfaces &= ~(1L << i); ++ ret = LIBUSB_ERROR_NOT_FOUND; + } + } + } +-- +1.7.11.2 + diff --git a/libusbx.spec b/libusbx.spec index 7ab37c3..d9d6495 100644 --- a/libusbx.spec +++ b/libusbx.spec @@ -1,8 +1,9 @@ Summary: Library for accessing USB devices Name: libusbx -Version: 1.0.11 -Release: 3%{?dist} +Version: 1.0.13 +Release: 1%{?dist} Source0: http://downloads.sourceforge.net/libusbx/libusbx-%{version}.tar.bz2 +Patch1: 0001-linux_usbfs-Work-around-a-driver-binding-race-in-res.patch License: LGPLv2+ Group: System Environment/Libraries URL: http://sourceforge.net/apps/mediawiki/libusbx/ @@ -49,11 +50,7 @@ This package contains API documentation for %{name}. %prep %setup -q -for i in examples/*.c; do - iconv -f ISO-8859-1 -t UTF-8 -o $i.new $i - touch -r $i $i.new - mv $i.new $i -done +%patch1 -p1 %build @@ -87,6 +84,9 @@ rm $RPM_BUILD_ROOT%{_libdir}/*.la %changelog +* Mon Sep 24 2012 Hans de Goede - 1.0.13-1 +- Upgrade to 1.0.13 + * Thu Jul 19 2012 Fedora Release Engineering - 1.0.11-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild diff --git a/sources b/sources index 3364f50..b87707c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -9aaab6aee72f65900cc731ecbffb4cf4 libusbx-1.0.11.tar.bz2 +f43819133126a9fdb311b18ea3c6a875 libusbx-1.0.13.tar.bz2