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:15:44 +0800 |
| commit | 06d5f73748c6a78f612880f190b151801aca046c (patch) | |
| tree | 07d01c00b064392d36810b261e7a127ecf5bf413 /drivers/usb | |
| parent | 5b3a8e30b04642379e6f5ca87e050497e439ca2f (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 'drivers/usb')
| -rw-r--r-- | drivers/usb/core/urb.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 909625b91eb3..0f362cc0df70 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -671,6 +671,27 @@ void usb_unpoison_urb(struct urb *urb) EXPORT_SYMBOL_GPL(usb_unpoison_urb); /** + * usb_block_urb - reliably prevent further use of an URB + * @urb: pointer to URB to be blocked, may be NULL + * + * After the routine has run, attempts to resubmit the URB will fail + * with error -EPERM. Thus even if the URB's completion handler always + * tries to resubmit, it will not succeed and the URB will become idle. + * + * The URB must not be deallocated while this routine is running. In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + */ +void usb_block_urb(struct urb *urb) +{ + if (!urb) + return; + + atomic_inc(&urb->reject); +} +EXPORT_SYMBOL_GPL(usb_block_urb); + +/** * usb_kill_anchored_urbs - cancel transfer requests en masse * @anchor: anchor the requests are bound to * |
