Browse Source

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>
Oliver Neukum 17 năm trước cách đây
mục cha
commit
77571f05a4
1 tập tin đã thay đổi với 7 bổ sung2 xóa
  1. 7 2
      drivers/usb/core/urb.c

+ 7 - 2
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)
 void usb_unlink_anchored_urbs(struct usb_anchor *anchor)
 {
 {
 	struct urb *victim;
 	struct urb *victim;
+	unsigned long flags;
 
 
-	spin_lock_irq(&anchor->lock);
+	spin_lock_irqsave(&anchor->lock, flags);
 	while (!list_empty(&anchor->urb_list)) {
 	while (!list_empty(&anchor->urb_list)) {
 		victim = list_entry(anchor->urb_list.prev, struct urb,
 		victim = list_entry(anchor->urb_list.prev, struct urb,
 				    anchor_list);
 				    anchor_list);
+		usb_get_urb(victim);
+		spin_unlock_irqrestore(&anchor->lock, flags);
 		/* this will unanchor the URB */
 		/* this will unanchor the URB */
 		usb_unlink_urb(victim);
 		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);
 EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs);