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