/*
         * Now that the ASL is updated, complete the removal of any
         * removed qsets.
+        *
+        * If the qset was to be reset, do so and reinsert it into the
+        * ASL if it has pending transfers.
         */
        spin_lock_irq(&whc->lock);
 
        list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) {
                qset_remove_complete(whc, qset);
+               if (qset->reset) {
+                       qset_reset(whc, qset);
+                       if (!list_empty(&qset->stds)) {
+                               asl_qset_insert_begin(whc, qset);
+                               queue_work(whc->workqueue, &whc->async_work);
+                       }
+               }
        }
 
        spin_unlock_irq(&whc->lock);
        else
                err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
        if (!err) {
-               if (!qset->in_sw_list)
+               if (!qset->in_sw_list && !qset->remove)
                        asl_qset_insert_begin(whc, qset);
        } else
                usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);
 
        struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
        struct whc *whc = wusbhc_to_whc(wusbhc);
        struct whc_qset *qset;
+       unsigned long flags;
+
+       spin_lock_irqsave(&whc->lock, flags);
 
        qset = ep->hcpriv;
        if (qset) {
                qset->remove = 1;
+               qset->reset = 1;
 
                if (usb_endpoint_xfer_bulk(&ep->desc)
                    || usb_endpoint_xfer_control(&ep->desc))
                        queue_work(whc->workqueue, &whc->async_work);
                else
                        queue_work(whc->workqueue, &whc->periodic_work);
-
-               qset_reset(whc, qset);
        }
+
+       spin_unlock_irqrestore(&whc->lock, flags);
 }
 
 
 
        /*
         * Now that the PZL is updated, complete the removal of any
         * removed qsets.
+        *
+        * If the qset was to be reset, do so and reinsert it into the
+        * PZL if it has pending transfers.
         */
        spin_lock_irq(&whc->lock);
 
        list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) {
                qset_remove_complete(whc, qset);
+               if (qset->reset) {
+                       qset_reset(whc, qset);
+                       if (!list_empty(&qset->stds)) {
+                               qset_insert_in_sw_list(whc, qset);
+                               queue_work(whc->workqueue, &whc->periodic_work);
+                       }
+               }
        }
 
        spin_unlock_irq(&whc->lock);
        else
                err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
        if (!err) {
-               if (!qset->in_sw_list)
+               if (!qset->in_sw_list && !qset->remove)
                        qset_insert_in_sw_list(whc, qset);
        } else
                usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);
 
 void qset_clear(struct whc *whc, struct whc_qset *qset)
 {
        qset->td_start = qset->td_end = qset->ntds = 0;
-       qset->remove = 0;
 
        qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
        qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK;
  */
 void qset_reset(struct whc *whc, struct whc_qset *qset)
 {
-       wait_for_completion(&qset->remove_complete);
+       qset->reset = 0;
 
        qset->qh.status &= ~QH_STATUS_SEQ_MASK;
        qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
 
 void qset_remove_complete(struct whc *whc, struct whc_qset *qset)
 {
+       qset->remove = 0;
        list_del_init(&qset->list_node);
        complete(&qset->remove_complete);
 }
 
        unsigned in_sw_list:1;
        unsigned in_hw_list:1;
        unsigned remove:1;
+       unsigned reset:1;
        struct urb *pause_after_urb;
        struct completion remove_complete;
        int max_burst;