diff options
author | Oliver Neukum <oliver@neukum.org> | 2012-04-30 09:13:46 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-01 15:18:17 +0800 |
commit | 774a93aa647f8939867c8ff956847bc63dd51cb3 (patch) | |
tree | e7438e4bc3a45e6e45cb2968c70809eeaa62e663 /include | |
parent | 59784034b157f70d1e8cf56b114527faeadecfaf (diff) |
usbhid: prevent deadlock during timeout
commit 8815bb09af21316aeb5f8948b24ac62181670db2 upstream.
On some HCDs usb_unlink_urb() can directly call the
completion handler. That limits the spinlocks that can
be taken in the handler to locks not held while calling
usb_unlink_urb()
To prevent a race with resubmission, this patch exposes
usbcore's infrastructure for blocking submission, uses it
and so drops the lock without causing a race in usbhid.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Acked-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/usb.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/include/linux/usb.h b/include/linux/usb.h index 73b68d1f2cb0..26229fd8d617 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1379,6 +1379,7 @@ extern int usb_unlink_urb(struct urb *urb); extern void usb_kill_urb(struct urb *urb); extern void usb_poison_urb(struct urb *urb); extern void usb_unpoison_urb(struct urb *urb); +extern void usb_block_urb(struct urb *urb); extern void usb_kill_anchored_urbs(struct usb_anchor *anchor); extern void usb_poison_anchored_urbs(struct usb_anchor *anchor); extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor); @@ -1391,6 +1392,8 @@ extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor); extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor); extern int usb_anchor_empty(struct usb_anchor *anchor); +#define usb_unblock_urb usb_unpoison_urb + /** * usb_urb_dir_in - check if an URB describes an IN transfer * @urb: URB to be checked |