| From: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Date: Wed, 11 Dec 2019 16:20:06 +0200 |
| Subject: xhci: handle some XHCI_TRUST_TX_LENGTH quirks cases as default |
| behaviour. |
| |
| commit 7ff11162808cc2ec66353fc012c58bb449c892c3 upstream. |
| |
| xhci driver claims it needs XHCI_TRUST_TX_LENGTH quirk for both |
| Broadcom/Cavium and a Renesas xHC controllers. |
| |
| The quirk was inteded for handling false "success" complete event for |
| transfers that had data left untransferred. |
| These transfers should complete with "short packet" events instead. |
| |
| In these two new cases the false "success" completion is reported |
| after a "short packet" if the TD consists of several TRBs. |
| xHCI specs 4.10.1.1.2 say remaining TRBs should report "short packet" |
| as well after the first short packet in a TD, but this issue seems so |
| common it doesn't make sense to add the quirk for all vendors. |
| |
| Turn these events into short packets automatically instead. |
| |
| This gets rid of the "The WARN Successful completion on short TX for |
| slot 1 ep 1: needs XHCI_TRUST_TX_LENGTH quirk" warning in many cases. |
| |
| Reported-by: Eli Billauer <eli.billauer@gmail.com> |
| Reported-by: Ard Biesheuvel <ardb@kernel.org> |
| Tested-by: Eli Billauer <eli.billauer@gmail.com> |
| Tested-by: Ard Biesheuvel <ardb@kernel.org> |
| Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Link: https://lore.kernel.org/r/20191211142007.8847-6-mathias.nyman@linux.intel.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| [bwh: Backported to 3.16: adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/usb/host/xhci-ring.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/usb/host/xhci-ring.c |
| +++ b/drivers/usb/host/xhci-ring.c |
| @@ -2345,7 +2345,8 @@ static int handle_tx_event(struct xhci_h |
| case COMP_SUCCESS: |
| if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) |
| break; |
| - if (xhci->quirks & XHCI_TRUST_TX_LENGTH) |
| + if (xhci->quirks & XHCI_TRUST_TX_LENGTH || |
| + ep_ring->last_td_was_short) |
| trb_comp_code = COMP_SHORT_TX; |
| else |
| xhci_warn_ratelimited(xhci, |