diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/usb.c | 10 |
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) | |||
922 | int usb_lock_device_for_reset(struct usb_device *udev, | 922 | int 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; |