unsigned int            slot_id = ep->vdev->slot_id;
        int                     err;
 
+       /*
+        * This is not going to work if the hardware is changing its dequeue
+        * pointers as we look at them. Completion handler will call us later.
+        */
+       if (ep->ep_state & SET_DEQ_PENDING)
+               return 0;
+
        xhci = ep->xhci;
 
        list_for_each_entry_safe(td, tmp_td, &ep->cancelled_td_list, cancelled_td_list) {
        struct xhci_slot_ctx *slot_ctx;
        struct xhci_stream_ctx *stream_ctx;
        struct xhci_td *td, *tmp_td;
-       bool deferred = false;
 
        ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
        stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
                        xhci_dbg(ep->xhci, "%s: Giveback cancelled URB %p TD\n",
                                 __func__, td->urb);
                        xhci_td_cleanup(ep->xhci, td, ep_ring, td->status);
-               } else if (td->cancel_status == TD_CLEARING_CACHE_DEFERRED) {
-                       deferred = true;
                } else {
                        xhci_dbg(ep->xhci, "%s: Keep cancelled URB %p TD as cancel_status is %d\n",
                                 __func__, td->urb, td->cancel_status);
        ep->queued_deq_seg = NULL;
        ep->queued_deq_ptr = NULL;
 
-       if (deferred) {
-               /* We have more streams to clear */
+       /* Check for deferred or newly cancelled TDs */
+       if (!list_empty(&ep->cancelled_td_list)) {
                xhci_dbg(ep->xhci, "%s: Pending TDs to clear, continuing with invalidation\n",
                         __func__);
                xhci_invalidate_cancelled_tds(ep);
+               /* Try to restart the endpoint if all is done */
+               ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
+               /* Start giving back any TDs invalidated above */
+               xhci_giveback_invalidated_tds(ep);
        } else {
                /* Restart any rings with pending URBs */
                xhci_dbg(ep->xhci, "%s: All TDs cleared, ring doorbell\n", __func__);