EXPORT_SYMBOL_GPL(usb_block_urb);
 
 /**
- * usb_kill_anchored_urbs - cancel transfer requests en masse
+ * usb_kill_anchored_urbs - kill all URBs associated with an anchor
  * @anchor: anchor the requests are bound to
  *
- * this allows all outstanding URBs to be killed starting
- * from the back of the queue
+ * This kills all outstanding URBs starting from the back of the queue,
+ * with guarantee that no completer callbacks will take place from the
+ * anchor after this function returns.
  *
  * This routine should not be called by a driver after its disconnect
  * method has returned.
 void usb_kill_anchored_urbs(struct usb_anchor *anchor)
 {
        struct urb *victim;
+       int surely_empty;
 
-       spin_lock_irq(&anchor->lock);
-       while (!list_empty(&anchor->urb_list)) {
-               victim = list_entry(anchor->urb_list.prev, struct urb,
-                                   anchor_list);
-               /* we must make sure the URB isn't freed before we kill it*/
-               usb_get_urb(victim);
-               spin_unlock_irq(&anchor->lock);
-               /* this will unanchor the URB */
-               usb_kill_urb(victim);
-               usb_put_urb(victim);
+       do {
                spin_lock_irq(&anchor->lock);
-       }
-       spin_unlock_irq(&anchor->lock);
+               while (!list_empty(&anchor->urb_list)) {
+                       victim = list_entry(anchor->urb_list.prev,
+                                           struct urb, anchor_list);
+                       /* make sure the URB isn't freed before we kill it */
+                       usb_get_urb(victim);
+                       spin_unlock_irq(&anchor->lock);
+                       /* this will unanchor the URB */
+                       usb_kill_urb(victim);
+                       usb_put_urb(victim);
+                       spin_lock_irq(&anchor->lock);
+               }
+               surely_empty = usb_anchor_check_wakeup(anchor);
+
+               spin_unlock_irq(&anchor->lock);
+               cpu_relax();
+       } while (!surely_empty);
 }
 EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
 
 void usb_poison_anchored_urbs(struct usb_anchor *anchor)
 {
        struct urb *victim;
+       int surely_empty;
 
-       spin_lock_irq(&anchor->lock);
-       anchor->poisoned = 1;
-       while (!list_empty(&anchor->urb_list)) {
-               victim = list_entry(anchor->urb_list.prev, struct urb,
-                                   anchor_list);
-               /* we must make sure the URB isn't freed before we kill it*/
-               usb_get_urb(victim);
-               spin_unlock_irq(&anchor->lock);
-               /* this will unanchor the URB */
-               usb_poison_urb(victim);
-               usb_put_urb(victim);
+       do {
                spin_lock_irq(&anchor->lock);
-       }
-       spin_unlock_irq(&anchor->lock);
+               anchor->poisoned = 1;
+               while (!list_empty(&anchor->urb_list)) {
+                       victim = list_entry(anchor->urb_list.prev,
+                                           struct urb, anchor_list);
+                       /* make sure the URB isn't freed before we kill it */
+                       usb_get_urb(victim);
+                       spin_unlock_irq(&anchor->lock);
+                       /* this will unanchor the URB */
+                       usb_poison_urb(victim);
+                       usb_put_urb(victim);
+                       spin_lock_irq(&anchor->lock);
+               }
+               surely_empty = usb_anchor_check_wakeup(anchor);
+
+               spin_unlock_irq(&anchor->lock);
+               cpu_relax();
+       } while (!surely_empty);
 }
 EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs);
 
 {
        struct urb *victim;
        unsigned long flags;
+       int surely_empty;
+
+       do {
+               spin_lock_irqsave(&anchor->lock, flags);
+               while (!list_empty(&anchor->urb_list)) {
+                       victim = list_entry(anchor->urb_list.prev,
+                                           struct urb, anchor_list);
+                       __usb_unanchor_urb(victim, anchor);
+               }
+               surely_empty = usb_anchor_check_wakeup(anchor);
 
-       spin_lock_irqsave(&anchor->lock, flags);
-       while (!list_empty(&anchor->urb_list)) {
-               victim = list_entry(anchor->urb_list.prev, struct urb,
-                                   anchor_list);
-               __usb_unanchor_urb(victim, anchor);
-       }
-       spin_unlock_irqrestore(&anchor->lock, flags);
+               spin_unlock_irqrestore(&anchor->lock, flags);
+               cpu_relax();
+       } while (!surely_empty);
 }
 
 EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs);