public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH backport for v5.10] xhci: add quirk for host controllers that don't update endpoint DCS
@ 2021-10-18 17:06 Bjørn Mork
  2021-10-20 12:36 ` Greg KH
  0 siblings, 1 reply; 2+ messages in thread
From: Bjørn Mork @ 2021-10-18 17:06 UTC (permalink / raw)
  To: stable; +Cc: Jonathan Bell, Bjørn Mork, Mathias Nyman

From: Jonathan Bell <jonathan@raspberrypi.org>

upstream commit 5255660b208a

Seen on a VLI VL805 PCIe to USB controller. For non-stream endpoints
at least, if the xHC halts on a particular TRB due to an error then
the DCS field in the Out Endpoint Context maintained by the hardware
is not updated with the current cycle state.

Using the quirk XHCI_EP_CTX_BROKEN_DCS and instead fetch the DCS bit
from the TRB that the xHC stopped on.

See: https://github.com/raspberrypi/linux/issues/3060

Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Cc: Mathias Nyman <mathias.nyman@linux.intel.com>
---

This isn't really a backport.  It's the original patch for 5.10 from
https://github.com/raspberrypi/linux.git , which was forward ported
and ended up as upstream commit 5255660b208a

The XHCI_EP_CTX_BROKEN_DCS constant has been syncronozed with upstream
to avoid collisions, though.

I hope that is OK.



Bjørn

 drivers/usb/host/xhci-pci.c  |  4 +++-
 drivers/usb/host/xhci-ring.c | 26 +++++++++++++++++++++++++-
 drivers/usb/host/xhci.h      |  1 +
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 119d1a8fbb19..618a131bdd53 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -274,8 +274,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
 			pdev->device == 0x3432)
 		xhci->quirks |= XHCI_BROKEN_STREAMS;
 
-	if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483)
+	if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) {
 		xhci->quirks |= XHCI_LPM_SUPPORT;
+		xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS;
+	}
 
 	if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
 		pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index dc2068e3bedb..c8d733ff3eb5 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -556,7 +556,10 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
 	struct xhci_virt_ep *ep = &dev->eps[ep_index];
 	struct xhci_ring *ep_ring;
 	struct xhci_segment *new_seg;
+	struct xhci_segment *halted_seg = NULL;
 	union xhci_trb *new_deq;
+	union xhci_trb *halted_trb;
+	int index = 0;
 	dma_addr_t addr;
 	u64 hw_dequeue;
 	bool cycle_found = false;
@@ -594,7 +597,28 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
 	hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id);
 	new_seg = ep_ring->deq_seg;
 	new_deq = ep_ring->dequeue;
-	state->new_cycle_state = hw_dequeue & 0x1;
+
+	/*
+	 * Quirk: xHC write-back of the DCS field in the hardware dequeue
+	 * pointer is wrong - use the cycle state of the TRB pointed to by
+	 * the dequeue pointer.
+	 */
+	if (xhci->quirks & XHCI_EP_CTX_BROKEN_DCS &&
+	    !(ep->ep_state & EP_HAS_STREAMS))
+		halted_seg = trb_in_td(xhci, cur_td->start_seg,
+				       cur_td->first_trb, cur_td->last_trb,
+				       hw_dequeue & ~0xf, false);
+	if (halted_seg) {
+		index = ((dma_addr_t)(hw_dequeue & ~0xf) - halted_seg->dma) /
+			 sizeof(*halted_trb);
+		halted_trb = &halted_seg->trbs[index];
+		state->new_cycle_state = halted_trb->generic.field[3] & 0x1;
+		xhci_dbg(xhci, "Endpoint DCS = %d TRB index = %d cycle = %d\n",
+			 (u8)(hw_dequeue & 0x1), index,
+			 state->new_cycle_state);
+	} else {
+		state->new_cycle_state = hw_dequeue & 0x1;
+	}
 	state->stream_id = stream_id;
 
 	/*
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 1c97c8d81154..45584a278336 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1884,6 +1884,7 @@ struct xhci_hcd {
 #define XHCI_DISABLE_SPARSE	BIT_ULL(38)
 #define XHCI_SG_TRB_CACHE_SIZE_QUIRK	BIT_ULL(39)
 #define XHCI_NO_SOFT_RETRY	BIT_ULL(40)
+#define XHCI_EP_CTX_BROKEN_DCS	BIT_ULL(42)
 
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH backport for v5.10] xhci: add quirk for host controllers that don't update endpoint DCS
  2021-10-18 17:06 [PATCH backport for v5.10] xhci: add quirk for host controllers that don't update endpoint DCS Bjørn Mork
@ 2021-10-20 12:36 ` Greg KH
  0 siblings, 0 replies; 2+ messages in thread
From: Greg KH @ 2021-10-20 12:36 UTC (permalink / raw)
  To: Bjørn Mork; +Cc: stable, Jonathan Bell, Mathias Nyman

On Mon, Oct 18, 2021 at 07:06:34PM +0200, Bjørn Mork wrote:
> From: Jonathan Bell <jonathan@raspberrypi.org>
> 
> upstream commit 5255660b208a
> 
> Seen on a VLI VL805 PCIe to USB controller. For non-stream endpoints
> at least, if the xHC halts on a particular TRB due to an error then
> the DCS field in the Out Endpoint Context maintained by the hardware
> is not updated with the current cycle state.
> 
> Using the quirk XHCI_EP_CTX_BROKEN_DCS and instead fetch the DCS bit
> from the TRB that the xHC stopped on.
> 
> See: https://github.com/raspberrypi/linux/issues/3060
> 
> Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
> Signed-off-by: Bjørn Mork <bjorn@mork.no>
> Cc: Mathias Nyman <mathias.nyman@linux.intel.com>
> ---
> 
> This isn't really a backport.  It's the original patch for 5.10 from
> https://github.com/raspberrypi/linux.git , which was forward ported
> and ended up as upstream commit 5255660b208a
> 
> The XHCI_EP_CTX_BROKEN_DCS constant has been syncronozed with upstream
> to avoid collisions, though.

Now queued up, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-10-20 12:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-10-18 17:06 [PATCH backport for v5.10] xhci: add quirk for host controllers that don't update endpoint DCS Bjørn Mork
2021-10-20 12:36 ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox