diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 57bb93f200cb..9b03de54ce05 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -291,6 +291,9 @@ static int xhci_plat_probe(struct platform_device *pdev) if (device_property_read_bool(tmpdev, "xhci-slow-suspend")) xhci->quirks |= XHCI_SLOW_SUSPEND; + if (device_property_read_bool(tmpdev, "xhci-trb-ent-quirk")) + xhci->quirks |= XHCI_TRB_ENT_QUIRK; + device_property_read_u32(tmpdev, "imod-interval-ns", &xhci->imod_interval); } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 9ae17a666bdb..d91fd550d52a 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3166,6 +3166,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, bool more_trbs_coming = true; bool need_zero_pkt = false; bool first_trb = true; + bool en_trb_ent = true; unsigned int num_trbs; unsigned int start_cycle, num_sgs = 0; unsigned int enqd_len, block_len, trb_buff_len, full_len; @@ -3202,6 +3203,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (urb->transfer_flags & URB_ZERO_PACKET && urb_priv->num_tds > 1) need_zero_pkt = true; + /* + * Don't enable the ENT flag in the TRB if + * the EP support bulk streaming protocol. + */ + if (urb->stream_id) + en_trb_ent = false; + td = &urb_priv->td[0]; /* @@ -3230,6 +3238,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, first_trb = false; if (start_cycle == 0) field |= TRB_CYCLE; + /* + * Don't enable the ENT flag in the TRB if the + * transfer length of the first TRB isn't an + * integer multiple of the EP maxpacket. + */ + if (trb_buff_len % usb_endpoint_maxp(&urb->ep->desc)) + en_trb_ent = false; } else field |= ring->cycle_state; @@ -3238,6 +3253,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, */ if (enqd_len + trb_buff_len < full_len) { field |= TRB_CHAIN; + if (xhci->quirks & XHCI_TRB_ENT_QUIRK && en_trb_ent) + field |= TRB_ENT; if (trb_is_link(ring->enqueue + 1)) { if (xhci_align_td(xhci, urb, enqd_len, &trb_buff_len, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 568f7611d573..b59b3f07bb32 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1852,6 +1852,7 @@ struct xhci_hcd { #define XHCI_ZERO_64B_REGS BIT_ULL(32) #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) +#define XHCI_TRB_ENT_QUIRK BIT_ULL(36) unsigned int num_active_eps; unsigned int limit_active_eps;