aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 1e2f3f495843..53c2e296467f 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2973,8 +2973,58 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
2973 } 2973 }
2974 2974
2975 while (1) { 2975 while (1) {
2976 if (room_on_ring(xhci, ep_ring, num_trbs)) 2976 if (room_on_ring(xhci, ep_ring, num_trbs)) {
2977 break; 2977 union xhci_trb *trb = ep_ring->enqueue;
2978 unsigned int usable = ep_ring->enq_seg->trbs +
2979 TRBS_PER_SEGMENT - 1 - trb;
2980 u32 nop_cmd;
2981
2982 /*
2983 * Section 4.11.7.1 TD Fragments states that a link
2984 * TRB must only occur at the boundary between
2985 * data bursts (eg 512 bytes for 480M).
2986 * While it is possible to split a large fragment
2987 * we don't know the size yet.
2988 * Simplest solution is to fill the trb before the
2989 * LINK with nop commands.
2990 */
2991 if (num_trbs == 1 || num_trbs <= usable || usable == 0)
2992 break;
2993
2994 if (ep_ring->type != TYPE_BULK)
2995 /*
2996 * While isoc transfers might have a buffer that
2997 * crosses a 64k boundary it is unlikely.
2998 * Since we can't add NOPs without generating
2999 * gaps in the traffic just hope it never
3000 * happens at the end of the ring.
3001 * This could be fixed by writing a LINK TRB
3002 * instead of the first NOP - however the
3003 * TRB_TYPE_LINK_LE32() calls would all need
3004 * changing to check the ring length.
3005 */
3006 break;
3007
3008 if (num_trbs >= TRBS_PER_SEGMENT) {
3009 xhci_err(xhci, "Too many fragments %d, max %d\n",
3010 num_trbs, TRBS_PER_SEGMENT - 1);
3011 return -ENOMEM;
3012 }
3013
3014 nop_cmd = cpu_to_le32(TRB_TYPE(TRB_TR_NOOP) |
3015 ep_ring->cycle_state);
3016 ep_ring->num_trbs_free -= usable;
3017 do {
3018 trb->generic.field[0] = 0;
3019 trb->generic.field[1] = 0;
3020 trb->generic.field[2] = 0;
3021 trb->generic.field[3] = nop_cmd;
3022 trb++;
3023 } while (--usable);
3024 ep_ring->enqueue = trb;
3025 if (room_on_ring(xhci, ep_ring, num_trbs))
3026 break;
3027 }
2978 3028
2979 if (ep_ring == xhci->cmd_ring) { 3029 if (ep_ring == xhci->cmd_ring) {
2980 xhci_err(xhci, "Do not support expand command ring\n"); 3030 xhci_err(xhci, "Do not support expand command ring\n");