Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp691519pxb; Mon, 25 Oct 2021 16:44:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwEAVO+yFZBhxUABVL97KelsxxhwzBIZGCgTo9u9vaMsFQS4nkX6Qix6XcNQxq7Z7/qqbMN X-Received: by 2002:a50:8dcb:: with SMTP id s11mr30090270edh.143.1635205490000; Mon, 25 Oct 2021 16:44:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1635205489; cv=none; d=google.com; s=arc-20160816; b=EB3ayS7cO7wk99MTkRUUMhConTqrZ8etXSIBhPsmnJEGIsPcYbvmMrejr2hGvWx8Ub mDuoFiARvKDUm67d3Q1TLgsraTqIvCXSMui19oOKt06vNWPRdTyMuTJZFKA+lL4b91bF EpdSffQC08YcpQn8iXvHf6OPVHO3vSu02aKYm7Du+nEpmS95Muv43lDJ8s0mmwIMvqPk KGnf7gJr2498oH3L4FtE2vmQTa+0ZOIKsKqKdVlY+lMk5DZipKDXjb0ssBCboRJf3Np1 erh5CV0UHVJLeeRf06x7AfUs/mG+xew7+HeatIqn3hQCKT8hx+JvM06cb8gvwWUHnBMR aCFg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=9C17ArQRYOHBzbeMmLUpmn+u4e8aLJkxkUkQtTZCWj4=; b=j/DPsiDbu8pH+Qr+q+nAGjDjtnW4ysr3VdbpGZ33nQ3jI7aiZ7JVjxs4kW6ra8g5gI OY7sYTlqImxbSGlc6w3jI7t3mLCPLAFp/hmVm3vMSX0nZUjTibl7/qBdhUQeM6dhe0g4 Djfs9dGFXfwKIodyMEIdtTZeCj1oKIwn582Vn0mB0qaOBv6APa4F0zZzQlJnnw9qy8gQ O3AgvQdjOUsT2/CGTyT9ITMW4PnHetugn3J/sKvBBB22MWSh/lTRGfXqOMela/b+BCXP FrpSStma643C/WDuK+8/dWWDkWMZbasZJMkA48468EyaptuZ2yPYEyE4Gr3kW3m1EHkp XBcQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PFHKNmwN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e1si26087935ejy.755.2021.10.25.16.44.25; Mon, 25 Oct 2021 16:44:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PFHKNmwN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234839AbhJYTkm (ORCPT + 99 others); Mon, 25 Oct 2021 15:40:42 -0400 Received: from mail.kernel.org ([198.145.29.99]:53204 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236214AbhJYTdt (ORCPT ); Mon, 25 Oct 2021 15:33:49 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2698F60232; Mon, 25 Oct 2021 19:29:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1635190173; bh=oueeT3Ejw0NUqkE4HNdl3LdrQQ5dQ8UbbGmUSZKLAVk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PFHKNmwNj16AkUSJL235mi0cFarenyFKNSYwSOg6Nz1EzrDjRQeBSsCcgGCmGAWsL XKu5dYTy9QMHsTd78nO+OmlVj+Rf20BxAwCJ+wWqA8SslEG+Ltk9ZRrX/L+eEpNcVm PXCub3lF1ranGKQa8CzAMbdJ8aVaykFLn/5w06U0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jonathan Bell , =?UTF-8?q?Bj=C3=B8rn=20Mork?= , Mathias Nyman Subject: [PATCH 5.10 02/95] xhci: add quirk for host controllers that dont update endpoint DCS Date: Mon, 25 Oct 2021 21:13:59 +0200 Message-Id: <20211025190956.727361004@linuxfoundation.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211025190956.374447057@linuxfoundation.org> References: <20211025190956.374447057@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jonathan Bell commit 5255660b208aebfdb71d574f3952cf48392f4306 upstream. 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. [ bjorn: rebased to v5.14-rc2 ] Link: https://github.com/raspberrypi/linux/issues/3060 Cc: stable@vger.kernel.org Signed-off-by: Jonathan Bell Signed-off-by: Bjørn Mork Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20211008092547.3996295-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- 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(-) --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -276,8 +276,10 @@ static void xhci_pci_quirks(struct devic 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) --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -562,7 +562,10 @@ void xhci_find_new_dequeue_state(struct 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; @@ -600,7 +603,28 @@ void xhci_find_new_dequeue_state(struct 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; /* --- 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;