From stern@rowland.harvard.edu Thu Aug 11 08:23:42 2005 Date: Thu, 11 Aug 2005 10:15:39 -0400 (EDT) From: Alan Stern To: Greg KH Subject: USB: Add timeout to usb_lock_device_for_reset Message-ID: This patch (as555) modifies the already-awkward usb_lock_device_for_reset routine in usbcore by adding a timeout. The whole point of the routine is that the caller wants to acquire some semaphores in the wrong order; protecting against the possibility of deadlock by timing out seems only prudent. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/usb.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletion(-) --- gregkh-2.6.orig/drivers/usb/core/usb.c 2005-08-12 14:48:01.000000000 -0700 +++ gregkh-2.6/drivers/usb/core/usb.c 2005-08-12 14:48:30.000000000 -0700 @@ -912,7 +912,7 @@ * is neither BINDING nor BOUND. Rather than sleeping to wait for the * lock, the routine polls repeatedly. This is to prevent deadlock with * disconnect; in some drivers (such as usb-storage) the disconnect() - * callback will block waiting for a device reset to complete. + * or suspend() method will block waiting for a device reset to complete. * * Returns a negative error code for failure, otherwise 1 or 0 to indicate * that the device will or will not have to be unlocked. (0 can be @@ -922,6 +922,8 @@ int usb_lock_device_for_reset(struct usb_device *udev, struct usb_interface *iface) { + unsigned long jiffies_expire = jiffies + HZ; + if (udev->state == USB_STATE_NOTATTACHED) return -ENODEV; if (udev->state == USB_STATE_SUSPENDED) @@ -938,6 +940,12 @@ } while (!usb_trylock_device(udev)) { + + /* If we can't acquire the lock after waiting one second, + * we're probably deadlocked */ + if (time_after(jiffies, jiffies_expire)) + return -EBUSY; + msleep(15); if (udev->state == USB_STATE_NOTATTACHED) return -ENODEV;