Oliver Neukum e9d3a4
From e91ac20889d1a26d077cc511365cd7ff4346a6f3 Mon Sep 17 00:00:00 2001
Oliver Neukum e9d3a4
From: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
Oliver Neukum e9d3a4
Date: Fri, 8 Apr 2022 16:48:21 +0300
Oliver Neukum e9d3a4
Subject: [PATCH] USB: Fix xhci event ring dequeue pointer ERDP update issue
Oliver Neukum e9d3a4
Git-commit: e91ac20889d1a26d077cc511365cd7ff4346a6f3
Oliver Neukum e9d3a4
References: git-fixes
Oliver Neukum e9d3a4
Patch-mainline: v5.18-rc5
Oliver Neukum e9d3a4
Oliver Neukum e9d3a4
In some situations software handles TRB events slower than adding TRBs.
Oliver Neukum e9d3a4
If the number of TRB events to be processed in a given interrupt is exactly
Oliver Neukum e9d3a4
the same as the event ring size 256, then the local variable
Oliver Neukum e9d3a4
"event_ring_deq" that holds the initial dequeue position is equal to
Oliver Neukum e9d3a4
software_dequeue after handling all 256 interrupts.
Oliver Neukum e9d3a4
Oliver Neukum e9d3a4
It will cause driver to not update ERDP to hardware,
Oliver Neukum e9d3a4
Oliver Neukum e9d3a4
Software dequeue pointer is out of sync with ERDP on interrupt exit.
Oliver Neukum e9d3a4
On the next interrupt, the event ring may full but driver will not
Oliver Neukum e9d3a4
update ERDP as software_dequeue is equal to ERDP.
Oliver Neukum e9d3a4
Oliver Neukum e9d3a4
[  536.377115] xhci_hcd 0000:00:12.0: ERROR unknown event type 37
Oliver Neukum e9d3a4
[  566.933173] sd 8:0:0:0: [sdb] tag#27 uas_eh_abort_handler 0 uas-tag 7 inflight: CMD OUT
Oliver Neukum e9d3a4
[  566.933181] sd 8:0:0:0: [sdb] tag#27 CDB: Write(10) 2a 00 17 71 e6 78 00 00 08 00
Oliver Neukum e9d3a4
[  572.041186] xhci_hcd On some situataions,the0000:00:12.0: xHCI host not responding to stop endpoint command.
Oliver Neukum e9d3a4
[  572.057193] xhci_hcd 0000:00:12.0: Host halt failed, -110
Oliver Neukum e9d3a4
[  572.057196] xhci_hcd 0000:00:12.0: xHCI host controller not responding, assume dead
Oliver Neukum e9d3a4
[  572.057236] sd 8:0:0:0: [sdb] tag#26 uas_eh_abort_handler 0 uas-tag 6 inflight: CMD
Oliver Neukum e9d3a4
[  572.057240] sd 8:0:0:0: [sdb] tag#26 CDB: Write(10) 2a 00 38 eb cc d8 00 00 08 00
Oliver Neukum e9d3a4
[  572.057244] sd 8:0:0:0: [sdb] tag#25 uas_eh_abort_handler 0 uas-tag 5 inflight: CMD
Oliver Neukum e9d3a4
Oliver Neukum e9d3a4
Hardware ERDP is updated mid event handling if there are more than 128
Oliver Neukum e9d3a4
events in an interrupt (half of ring size).
Oliver Neukum e9d3a4
Fix this by updating the software local variable at the same time as
Oliver Neukum e9d3a4
hardware ERDP.
Oliver Neukum e9d3a4
Oliver Neukum e9d3a4
[commit message rewording -Mathias]
Oliver Neukum e9d3a4
Oliver Neukum e9d3a4
Fixes: dc0ffbea5729 ("usb: host: xhci: update event ring dequeue pointer on purpose")
Oliver Neukum e9d3a4
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Oliver Neukum e9d3a4
Signed-off-by: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
Oliver Neukum e9d3a4
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Oliver Neukum e9d3a4
Link: https://lore.kernel.org/r/20220408134823.2527272-2-mathias.nyman@linux.intel.com
Oliver Neukum e9d3a4
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Oliver Neukum e9d3a4
Signed-off-by: Oliver Neukum <oneukum@suse.com>
Oliver Neukum e9d3a4
---
Oliver Neukum e9d3a4
 drivers/usb/host/xhci-ring.c |    1 +
Oliver Neukum e9d3a4
 1 file changed, 1 insertion(+)
Oliver Neukum e9d3a4
Oliver Neukum e9d3a4
--- a/drivers/usb/host/xhci-ring.c
Oliver Neukum e9d3a4
+++ b/drivers/usb/host/xhci-ring.c
Oliver Neukum e9d3a4
@@ -2916,6 +2916,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd
Oliver Neukum e9d3a4
 	}
Oliver Neukum e9d3a4
 
Oliver Neukum e9d3a4
 	xhci_update_erst_dequeue(xhci, event_ring_deq);
Oliver Neukum e9d3a4
+	event_ring_deq = xhci->event_ring->dequeue;
Oliver Neukum e9d3a4
 	ret = IRQ_HANDLED;
Oliver Neukum e9d3a4
 
Oliver Neukum e9d3a4
 out: