| From 09f736aa95476631227d2dc0e6b9aeee1ad7ed58 Mon Sep 17 00:00:00 2001 |
| From: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Date: Fri, 26 Nov 2021 14:23:40 +0200 |
| Subject: xhci: Fix commad ring abort, write all 64 bits to CRCR register. |
| |
| From: Mathias Nyman <mathias.nyman@linux.intel.com> |
| |
| commit 09f736aa95476631227d2dc0e6b9aeee1ad7ed58 upstream. |
| |
| Turns out some xHC controllers require all 64 bits in the CRCR register |
| to be written to execute a command abort. |
| |
| The lower 32 bits containing the command abort bit is written first. |
| In case the command ring stops before we write the upper 32 bits then |
| hardware may use these upper bits to set the commnd ring dequeue pointer. |
| |
| Solve this by making sure the upper 32 bits contain a valid command |
| ring dequeue pointer. |
| |
| The original patch that only wrote the first 32 to stop the ring went |
| to stable, so this fix should go there as well. |
| |
| Fixes: ff0e50d3564f ("xhci: Fix command ring pointer corruption while aborting a command") |
| Cc: stable@vger.kernel.org |
| Tested-by: Pavankumar Kondeti <quic_pkondeti@quicinc.com> |
| Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Link: https://lore.kernel.org/r/20211126122340.1193239-2-mathias.nyman@linux.intel.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/usb/host/xhci-ring.c | 21 ++++++++++++++------- |
| 1 file changed, 14 insertions(+), 7 deletions(-) |
| |
| --- a/drivers/usb/host/xhci-ring.c |
| +++ b/drivers/usb/host/xhci-ring.c |
| @@ -342,7 +342,9 @@ static void xhci_handle_stopped_cmd_ring |
| /* Must be called with xhci->lock held, releases and aquires lock back */ |
| static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) |
| { |
| - u32 temp_32; |
| + struct xhci_segment *new_seg = xhci->cmd_ring->deq_seg; |
| + union xhci_trb *new_deq = xhci->cmd_ring->dequeue; |
| + u64 crcr; |
| int ret; |
| |
| xhci_dbg(xhci, "Abort command ring\n"); |
| @@ -351,13 +353,18 @@ static int xhci_abort_cmd_ring(struct xh |
| |
| /* |
| * The control bits like command stop, abort are located in lower |
| - * dword of the command ring control register. Limit the write |
| - * to the lower dword to avoid corrupting the command ring pointer |
| - * in case if the command ring is stopped by the time upper dword |
| - * is written. |
| + * dword of the command ring control register. |
| + * Some controllers require all 64 bits to be written to abort the ring. |
| + * Make sure the upper dword is valid, pointing to the next command, |
| + * avoiding corrupting the command ring pointer in case the command ring |
| + * is stopped by the time the upper dword is written. |
| */ |
| - temp_32 = readl(&xhci->op_regs->cmd_ring); |
| - writel(temp_32 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); |
| + next_trb(xhci, NULL, &new_seg, &new_deq); |
| + if (trb_is_link(new_deq)) |
| + next_trb(xhci, NULL, &new_seg, &new_deq); |
| + |
| + crcr = xhci_trb_virt_to_dma(new_seg, new_deq); |
| + xhci_write_64(xhci, crcr | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); |
| |
| /* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the |
| * completion of the Command Abort operation. If CRR is not negated in 5 |