spin_lock_irq(&bh->lock);
        bh->running = true;
- restart:
        list_replace_init(&bh->head, &local_list);
        spin_unlock_irq(&bh->lock);
 
                bh->completing_ep = NULL;
        }
 
-       /* check if there are new URBs to giveback */
+       /*
+        * giveback new URBs next time to prevent this function
+        * from not exiting for a long time.
+        */
        spin_lock_irq(&bh->lock);
-       if (!list_empty(&bh->head))
-               goto restart;
+       if (!list_empty(&bh->head)) {
+               if (bh->high_prio)
+                       tasklet_hi_schedule(&bh->bh);
+               else
+                       tasklet_schedule(&bh->bh);
+       }
        bh->running = false;
        spin_unlock_irq(&bh->lock);
 }
 void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
 {
        struct giveback_urb_bh *bh;
-       bool running, high_prio_bh;
+       bool running;
 
        /* pass status to tasklet via unlinked */
        if (likely(!urb->unlinked))
                return;
        }
 
-       if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)) {
+       if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe))
                bh = &hcd->high_prio_bh;
-               high_prio_bh = true;
-       } else {
+       else
                bh = &hcd->low_prio_bh;
-               high_prio_bh = false;
-       }
 
        spin_lock(&bh->lock);
        list_add_tail(&urb->urb_list, &bh->head);
 
        if (running)
                ;
-       else if (high_prio_bh)
+       else if (bh->high_prio)
                tasklet_hi_schedule(&bh->bh);
        else
                tasklet_schedule(&bh->bh);
 
        /* initialize tasklets */
        init_giveback_urb_bh(&hcd->high_prio_bh);
+       hcd->high_prio_bh.high_prio = true;
        init_giveback_urb_bh(&hcd->low_prio_bh);
 
        /* enable irqs just before we start the controller,