From 62d024454dedf644cd1c453ebd06be9646a0ab22 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 11 Aug 2005 10:15:39 -0400 Subject: [PATCH] --- yaml --- r: 7969 b: refs/heads/master c: 3ea15966ed59f2bc20928c7b0496b4585f6de206 h: refs/heads/master i: 7967: 1251ff37c8a290f9a659e267d0c6ae0e1e5d73b5 v: v3 --- [refs] | 2 +- trunk/drivers/usb/core/usb.c | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 49bc9364a8a4..414ed9f3a1af 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e52b1d3afe698cb77c080ecbe9e745257ff8c81b +refs/heads/master: 3ea15966ed59f2bc20928c7b0496b4585f6de206 diff --git a/trunk/drivers/usb/core/usb.c b/trunk/drivers/usb/core/usb.c index bc966dbc6021..109f7558167a 100644 --- a/trunk/drivers/usb/core/usb.c +++ b/trunk/drivers/usb/core/usb.c @@ -912,7 +912,7 @@ int usb_trylock_device(struct usb_device *udev) * 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_trylock_device(struct usb_device *udev) 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 @@ int usb_lock_device_for_reset(struct usb_device *udev, } 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;