diff options
author | Oliver Neukum <oliver@neukum.org> | 2012-04-30 03:13:46 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-05-01 13:22:13 -0400 |
commit | 8815bb09af21316aeb5f8948b24ac62181670db2 (patch) | |
tree | a6667e719e124f06257f1b9cb11abe6bce9295b0 /include/linux/usb.h | |
parent | 166cb70e97bd83d7ae9bbec6ae59a178fd9bb823 (diff) |
usbhid: prevent deadlock during timeout
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>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/usb.h')
-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 8fa9a93a4ec4..5483cd70390b 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -1369,6 +1369,7 @@ extern int usb_unlink_urb(struct urb *urb); | |||
1369 | extern void usb_kill_urb(struct urb *urb); | 1369 | extern void usb_kill_urb(struct urb *urb); |
1370 | extern void usb_poison_urb(struct urb *urb); | 1370 | extern void usb_poison_urb(struct urb *urb); |
1371 | extern void usb_unpoison_urb(struct urb *urb); | 1371 | extern void usb_unpoison_urb(struct urb *urb); |
1372 | extern void usb_block_urb(struct urb *urb); | ||
1372 | extern void usb_kill_anchored_urbs(struct usb_anchor *anchor); | 1373 | extern void usb_kill_anchored_urbs(struct usb_anchor *anchor); |
1373 | extern void usb_poison_anchored_urbs(struct usb_anchor *anchor); | 1374 | extern void usb_poison_anchored_urbs(struct usb_anchor *anchor); |
1374 | extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor); | 1375 | extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor); |
@@ -1381,6 +1382,8 @@ extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor); | |||
1381 | extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor); | 1382 | extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor); |
1382 | extern int usb_anchor_empty(struct usb_anchor *anchor); | 1383 | extern int usb_anchor_empty(struct usb_anchor *anchor); |
1383 | 1384 | ||
1385 | #define usb_unblock_urb usb_unpoison_urb | ||
1386 | |||
1384 | /** | 1387 | /** |
1385 | * usb_urb_dir_in - check if an URB describes an IN transfer | 1388 | * usb_urb_dir_in - check if an URB describes an IN transfer |
1386 | * @urb: URB to be checked | 1389 | * @urb: URB to be checked |