36 lines
1.5 KiB
Diff
36 lines
1.5 KiB
Diff
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
|
|
--- a/drivers/usb/host/xhci-mem.c
|
|
+++ b/drivers/usb/host/xhci-mem.c
|
|
@@ -2301,7 +2301,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags)
|
|
if (!segs)
|
|
segs = ERST_DEFAULT_SEGS;
|
|
|
|
- max_segs = FIELD_GET(HCS_ERST_MAX, xhci->hcs_params2) << 2;
|
|
+ max_segs = BIT(FIELD_GET(HCS_ERST_MAX, xhci->hcs_params2));
|
|
segs = min(segs, max_segs);
|
|
|
|
ir = kzalloc_node(sizeof(*ir), flags, dev_to_node(dev));
|
|
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
|
|
--- a/drivers/usb/host/xhci-ring.c
|
|
+++ b/drivers/usb/host/xhci-ring.c
|
|
@@ -4328,11 +4328,16 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|
check_interval(urb, ep_ctx);
|
|
|
|
/*
|
|
- * Check if this starts the isoc data flow. Relies on hw setting ep ctx
|
|
- * state after doorbell ring. Consider adding list_empty(td_list) check
|
|
+ * Schedule the URB discontiguously if all previous URBs have completed.
|
|
+ * XXX core can't tell if completions are pending but not running yet.
|
|
*/
|
|
- if (GET_EP_CTX_STATE(ep_ctx) != EP_STATE_RUNNING)
|
|
+ if (list_empty(&ep_ring->td_list) &&
|
|
+ !hcd_periodic_completion_in_progress(xhci_to_hcd(xhci), urb->ep)) {
|
|
+ if (GET_EP_CTX_STATE(ep_ctx) == EP_STATE_RUNNING)
|
|
+ xhci_dbg(xhci, "Unexpected running ring at isoc stream start, uframe: %d\n",
|
|
+ xep->next_uframe);
|
|
xep->next_uframe = -1;
|
|
+ }
|
|
|
|
return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index);
|
|
}
|