aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-08-11 10:15:39 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-09-08 19:28:21 -0400
commit3ea15966ed59f2bc20928c7b0496b4585f6de206 (patch)
tree45c392aa393fe4ad245b6593b5a74f212f010637 /drivers/usb
parente52b1d3afe698cb77c080ecbe9e745257ff8c81b (diff)
[PATCH] USB: Add timeout to usb_lock_device_for_reset
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 <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/usb.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index bc966dbc6021..109f7558167a 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -912,7 +912,7 @@ int usb_trylock_device(struct usb_device *udev)
912 * is neither BINDING nor BOUND. Rather than sleeping to wait for the 912 * is neither BINDING nor BOUND. Rather than sleeping to wait for the
913 * lock, the routine polls repeatedly. This is to prevent deadlock with 913 * lock, the routine polls repeatedly. This is to prevent deadlock with
914 * disconnect; in some drivers (such as usb-storage) the disconnect() 914 * disconnect; in some drivers (such as usb-storage) the disconnect()
915 * callback will block waiting for a device reset to complete. 915 * or suspend() method will block waiting for a device reset to complete.
916 * 916 *
917 * Returns a negative error code for failure, otherwise 1 or 0 to indicate 917 * Returns a negative error code for failure, otherwise 1 or 0 to indicate
918 * that the device will or will not have to be unlocked. (0 can be 918 * that the device will or will not have to be unlocked. (0 can be
@@ -922,6 +922,8 @@ int usb_trylock_device(struct usb_device *udev)
922int usb_lock_device_for_reset(struct usb_device *udev, 922int usb_lock_device_for_reset(struct usb_device *udev,
923 struct usb_interface *iface) 923 struct usb_interface *iface)
924{ 924{
925 unsigned long jiffies_expire = jiffies + HZ;
926
925 if (udev->state == USB_STATE_NOTATTACHED) 927 if (udev->state == USB_STATE_NOTATTACHED)
926 return -ENODEV; 928 return -ENODEV;
927 if (udev->state == USB_STATE_SUSPENDED) 929 if (udev->state == USB_STATE_SUSPENDED)
@@ -938,6 +940,12 @@ int usb_lock_device_for_reset(struct usb_device *udev,
938 } 940 }
939 941
940 while (!usb_trylock_device(udev)) { 942 while (!usb_trylock_device(udev)) {
943
944 /* If we can't acquire the lock after waiting one second,
945 * we're probably deadlocked */
946 if (time_after(jiffies, jiffies_expire))
947 return -EBUSY;
948
941 msleep(15); 949 msleep(15);
942 if (udev->state == USB_STATE_NOTATTACHED) 950 if (udev->state == USB_STATE_NOTATTACHED)
943 return -ENODEV; 951 return -ENODEV;