Re: Reap URB on disconnected device never returns

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Alan,
I tried your patch with my kernel (2.6.27.7) and it works !
I have tried also the latest kernel (2.6.29-rc7-git1), but this kernel has also the problem.
Can you estimate when this patch will be applied to the mainline?

Martin Poupe

Alan Stern wrote:
On Thu, 5 Mar 2009, Martin Poupe wrote:

Hello,
I have found folowing bug in linux kernel (see also in http://bugzilla.kernel.org/show_bug.cgi?id=12817):

Distribution:Slackware 12.2 Kernel: 2.6.27.7 Problem Description and steps to reproduce:
1. Submit urb to read from interrupt (or bulk) endpoint from USB device
2. call ioctl to reap this urb (USBDEVS_REAPURB), there are no other requests pending for this device (fd)
3. the thread is blocked in the kernel (which is OK)
4. disconnect the USB device
5. the thread is blocked in the kernel for ever (!)
6. try to discard urb (USBDEVS_DISCARDURB)from another thread, this fails
(probably because the fd is no longer valid), but this doesn't unblock the
first thread (!)
I am attaching simple test program (modified testlibusb.c from libusb-0.1.12 to demonstrate this).
To compile: gcc -o test test.c -lusb
To run: ./test <VID> <PID>, where VID and PID are hex numbers (e.g. ./test 1234 90ab)
You need to find some USB hardware, which is NOT drive by dedicated driver (so you cannot test this by USB mouse or flash drive,
because as early as submit urb fails by error EBUSY )

Here is a patch which should fix the problem. The patch was written for 2.6.29 but I think it will apply okay to 2.6.27.

Alan Stern



Index: usb-2.6/drivers/usb/core/devio.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/devio.c
+++ usb-2.6/drivers/usb/core/devio.c
@@ -359,11 +359,6 @@ static void destroy_async(struct dev_sta
 		spin_lock_irqsave(&ps->lock, flags);
 	}
 	spin_unlock_irqrestore(&ps->lock, flags);
-	as = async_getcompleted(ps);
-	while (as) {
-		free_async(as);
-		as = async_getcompleted(ps);
-	}
 }
static void destroy_async_on_interface(struct dev_state *ps,
@@ -644,6 +639,7 @@ static int usbdev_release(struct inode *
 	struct dev_state *ps = file->private_data;
 	struct usb_device *dev = ps->dev;
 	unsigned int ifnum;
+	struct async *as;
usb_lock_device(dev); @@ -662,6 +658,12 @@ static int usbdev_release(struct inode *
 	usb_unlock_device(dev);
 	usb_put_dev(dev);
 	put_pid(ps->disc_pid);
+
+	as = async_getcompleted(ps);
+	while (as) {
+		free_async(as);
+		as = async_getcompleted(ps);
+	}
 	kfree(ps);
 	return 0;
 }



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux