summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2008-08-18 18:36:52 +0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-08-21 21:26:32 +0400
commit77571f05a483c0259e42ba2f482c82debc9a63af (patch)
treedb4624d3c0fba8d3ab94df32ebbc7d8578ca4266
parentf8033827d8e92db6159d34ed45c608522674ecd8 (diff)
downloadlinux-77571f05a483c0259e42ba2f482c82debc9a63af.tar.xz
USB: fix bug in usb_unlink_anchored_urbs()
Irqs must not accidentally be reenabled. Signed-off-by: Oliver Neukum <oneukum@suse.de> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/core/urb.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index c0b1ae25ae2a..47111e88f791 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -601,15 +601,20 @@ EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
void usb_unlink_anchored_urbs(struct usb_anchor *anchor)
{
struct urb *victim;
+ unsigned long flags;
- spin_lock_irq(&anchor->lock);
+ spin_lock_irqsave(&anchor->lock, flags);
while (!list_empty(&anchor->urb_list)) {
victim = list_entry(anchor->urb_list.prev, struct urb,
anchor_list);
+ usb_get_urb(victim);
+ spin_unlock_irqrestore(&anchor->lock, flags);
/* this will unanchor the URB */
usb_unlink_urb(victim);
+ usb_put_urb(victim);
+ spin_lock_irqsave(&anchor->lock, flags);
}
- spin_unlock_irq(&anchor->lock);
+ spin_unlock_irqrestore(&anchor->lock, flags);
}
EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs);