From patchwork Wed May 27 10:40:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejas Joglekar X-Patchwork-Id: 11572595 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3D5D11392 for ; Wed, 27 May 2020 10:43:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2389D20888 for ; Wed, 27 May 2020 10:43:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="BYrPVPO0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729956AbgE0KnC (ORCPT ); Wed, 27 May 2020 06:43:02 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:34648 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729354AbgE0KnB (ORCPT ); Wed, 27 May 2020 06:43:01 -0400 Received: from mailhost.synopsys.com (mdc-mailhost2.synopsys.com [10.225.0.210]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 4B5D6C0519; Wed, 27 May 2020 10:43:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1590576181; bh=c8cXuZnPUVhDrm8TnZwka2SdniDodmtUoYnu1RdfkT8=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=BYrPVPO02B5iGjtVTiNucEtRVgT09AbX2i5B5CAiriLpq3U+XuXsI87GxIjK2XUui LZ+zpeyFG1abmoTpldPEeCwAqDQEjlFrlmTDhxJ5YcUTlN+wSsww6j/gEB+adHleG3 CmSavSgSi1kWVcbjvQmrY760lJYS7soiyKPFnOLOjRTdClelVWWiyZ6n9aqx6gaPRZ 2WYu9L0TTBDtMoM0eIqLb8YunOAxCTDbNOuqsrYnncVrRpTAyd/Gk15Gbsw3V1mqWP FE81z+SFEgi4l9onS7Jnj6LE4imRV9ism0+RV5VSKwnrN236+ET1gLJFLryqm3gMoy Twu1DPkXoG9JQ== Received: from tejas-VirtualBox (joglekar-e7480.internal.synopsys.com [10.146.20.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id D6C91A005C; Wed, 27 May 2020 10:42:57 +0000 (UTC) Received: by tejas-VirtualBox (sSMTP sendmail emulation); Wed, 27 May 2020 16:10:55 +0530 Date: Wed, 27 May 2020 16:10:55 +0530 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Tejas Joglekar Subject: [PATCH v3 1/4] dt-bindings: usb: Add documentation for SG trb cache size quirk To: Greg Kroah-Hartman , Tejas Joglekar , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, Rob Herring Cc: John Youn Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This commit adds the documentation for sgl-trb-cache-size-quirk, and snps,sgl-trb-cache-size-quirk property. These when set enables the quirk for XHCI driver for consolidation of sg list into a temporary buffer when small buffer sizes are scattered over the sg list not making up to MPS or total transfer size within TRB cache size with Synopsys xHC. Signed-off-by: Tejas Joglekar --- Documentation/devicetree/bindings/usb/dwc3.txt | 4 ++++ Documentation/devicetree/bindings/usb/usb-xhci.txt | 3 +++ 2 files changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index d03edf9d3935..0fcbaa51f66e 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -102,6 +102,10 @@ Optional properties: this and tx-thr-num-pkt-prd to a valid, non-zero value 1-16 (DWC_usb31 programming guide section 1.2.3) to enable periodic ESS TX threshold. + - snps,sgl-trb-cache-size-quirk: enable sg list consolidation - host mode + only. Set to use SG buffers of at least MPS size + by consolidating smaller SG buffers list into a + single buffer. - tx-fifo-resize: determines if the FIFO *has* to be reallocated. - snps,incr-burst-type-adjustment: Value for INCR burst type of GSBUSCFG0 diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt index dc025f126d71..c53eb19ae67e 100644 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt @@ -44,6 +44,9 @@ Optional properties: - quirk-broken-port-ped: set if the controller has broken port disable mechanism - imod-interval-ns: default interrupt moderation interval is 5000ns - phys : see usb-hcd.yaml in the current directory + - sgl-trb-cache-size-quirk: set if you need to consolidate sg list into a + temporary buffer when small SG buffer sizes does not make upto MPS + size or total transfer size across the TRB cache size. additionally the properties from usb-hcd.yaml (in the current directory) are supported. From patchwork Wed May 27 10:41:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejas Joglekar X-Patchwork-Id: 11572597 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D201D1392 for ; Wed, 27 May 2020 10:43:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B474E2075F for ; Wed, 27 May 2020 10:43:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="lPwTUSjG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729963AbgE0Kn1 (ORCPT ); Wed, 27 May 2020 06:43:27 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:35318 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729354AbgE0Kn1 (ORCPT ); Wed, 27 May 2020 06:43:27 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 8E5B44095E; Wed, 27 May 2020 10:43:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1590576206; bh=mhcwbkE2f7Vc6KcigKXQ2SD2KBjY2NCf0dZqTLcGO6k=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=lPwTUSjG9ns52grm0NCYzaQvmhsxw+n6hCo14gAkL8mTbQ/WWfop5iDoKMFs/VLFP WJBc0+d/TMCjDR4Rl1Irc1XinTrGNZZ+PIXoMbJhr19tQhmRMZHhH8/debhSbUZkcV GW703sShEcJhJfEyJKPvSkGLdlA2PC9ASdP+3z9wuE2ZfKfeXVjm4SVfefQ3BDVwx8 9swPDO5c316PsLJsHBwev1bSa4QuFgMh+uFFDVDpIReCS9M3BW4mx7RAJzanPw9mEz ziCDe9CSy3Y54Jpj5+MTacirMKtpLkp70lkF3VHIXhW5xW+mMsUZkuMNbGxmX3ugRt Blk58fOURu1vQ== Received: from tejas-VirtualBox (joglekar-e7480.internal.synopsys.com [10.146.20.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id E438EA005B; Wed, 27 May 2020 10:43:22 +0000 (UTC) Received: by tejas-VirtualBox (sSMTP sendmail emulation); Wed, 27 May 2020 16:11:20 +0530 Date: Wed, 27 May 2020 16:11:20 +0530 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Tejas Joglekar Subject: [PATCH v3 2/4] usb: xhci: Set quirk for XHCI_SG_TRB_CACHE_SIZE_QUIRK To: Greg Kroah-Hartman , Tejas Joglekar , linux-usb@vger.kernel.org, Mathias Nyman Cc: John Youn Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This commit enables the sgl-trb-cache-size-quirk property is set for the Synopsys xHC. This patch fixes the SNPS xHC hang issue when the data is scattered across small buffers which does not make atleast MPS size for given TRB cache size of SNPS xHC. Signed-off-by: Tejas Joglekar --- drivers/usb/host/xhci-pci.c | 3 +++ drivers/usb/host/xhci-plat.c | 4 ++++ drivers/usb/host/xhci.h | 1 + 3 files changed, 8 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 766b74723e64..05b743a819ac 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -268,6 +268,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == 0x9026) xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT; + if (pdev->vendor == PCI_VENDOR_ID_SYNOPSYS) + xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK; + if (xhci->quirks & XHCI_RESET_ON_RESUME) xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "QUIRK: Resetting on resume"); diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 1d4f6f85f0fe..a8526fe50811 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -288,6 +288,10 @@ static int xhci_plat_probe(struct platform_device *pdev) if (device_property_read_bool(tmpdev, "quirk-broken-port-ped")) xhci->quirks |= XHCI_BROKEN_PORT_PED; + if (device_property_read_bool(tmpdev, + "sgl-trb-cache-size-quirk")) + xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK; + device_property_read_u32(tmpdev, "imod-interval-ns", &xhci->imod_interval); } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 86cfefdd6632..69e3587e805c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1873,6 +1873,7 @@ struct xhci_hcd { #define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) +#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(36) unsigned int num_active_eps; unsigned int limit_active_eps; From patchwork Wed May 27 10:41:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejas Joglekar X-Patchwork-Id: 11572599 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DAC9814B7 for ; Wed, 27 May 2020 10:43:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BCE3920888 for ; Wed, 27 May 2020 10:43:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="G6oC8fyd" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726835AbgE0Knw (ORCPT ); Wed, 27 May 2020 06:43:52 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:35330 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726320AbgE0Knv (ORCPT ); Wed, 27 May 2020 06:43:51 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id E262D4095E; Wed, 27 May 2020 10:43:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1590576231; bh=ZRDwNcpRxjH2Zef4WlLrcZ/7QuTxowQfGggwkdDixY4=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=G6oC8fydQMeK+BWOH7MkavUuIi5CAog/UCI+y3RnopCs1QLO8Ge0SkSb2Ea9kIR9V hqZav63QPsmik8ZVqqJzBDx978YDVyFEAFKP5DtU3LH2kecKDDn8RF7CyJRpvBUpT+ R6iZ5VZbTliSOu91sG9TGeRvGeYTnVdzZafe8hcc3KUFaSS0VhP66BrU93tUFjPeTm WcLsq2O1jrDKf2/5MXEK+b6nt+MRBTdzf7bFG2vymKJNqqZac6tNJeXHkovUT0FIe/ 2dY2A+KR5BEnWRPQFWA+vtMgVpzuR4gwPOYNEPVyrOgGKxKbHz6Cw6YjagpoiB/fha tZLxlyKdwzoZA== Received: from tejas-VirtualBox (joglekar-e7480.internal.synopsys.com [10.146.20.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 74513A005B; Wed, 27 May 2020 10:43:47 +0000 (UTC) Received: by tejas-VirtualBox (sSMTP sendmail emulation); Wed, 27 May 2020 16:11:45 +0530 Date: Wed, 27 May 2020 16:11:45 +0530 Message-Id: <83eba2e9f0069f20ccc94537e3b99cbaec209441.1590415123.git.joglekar@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Tejas Joglekar Subject: [PATCH v3 3/4] usb: dwc3: Add device property sgl-trb-cache-size-quirk To: Felipe Balbi , Greg Kroah-Hartman , Tejas Joglekar , linux-usb@vger.kernel.org Cc: John Youn Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This commit adds the sgl-trb-cache-size-quirk property to enable quirk for the XHCI driver with Synopsys xHC. This property is enabled as initial property for the dwc3-haps driver. Signed-off-by: Tejas Joglekar --- drivers/usb/dwc3/core.c | 2 ++ drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/dwc3-haps.c | 1 + drivers/usb/dwc3/host.c | 6 +++++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 25c686a752b0..bc295477e1bc 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1299,6 +1299,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) "snps,usb3_lpm_capable"); dwc->usb2_lpm_disable = device_property_read_bool(dev, "snps,usb2-lpm-disable"); + dwc->sgl_trb_cache_size_quirk = device_property_read_bool(dev, + "snps,sgl-trb-cache-size-quirk"); device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd", &rx_thr_num_pkt_prd); device_property_read_u8(dev, "snps,rx-max-burst-prd", diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 013f42a2b5dc..0dca0dbf4309 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1021,6 +1021,7 @@ struct dwc3_scratchpad_array { * not needed for DWC_usb31 version 1.70a-ea06 and below * @usb3_lpm_capable: set if hadrware supports Link Power Management * @usb2_lpm_disable: set to disable usb2 lpm + * @sgl_trb_cache_size_quirk: set to enable the SG list consolidation * @disable_scramble_quirk: set if we enable the disable scramble quirk * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk @@ -1220,6 +1221,7 @@ struct dwc3 { unsigned dis_start_transfer_quirk:1; unsigned usb3_lpm_capable:1; unsigned usb2_lpm_disable:1; + unsigned sgl_trb_cache_size_quirk:1; unsigned disable_scramble_quirk:1; unsigned u2exit_lfps_quirk:1; diff --git a/drivers/usb/dwc3/dwc3-haps.c b/drivers/usb/dwc3/dwc3-haps.c index 3cecbf169452..9311cbe5f264 100644 --- a/drivers/usb/dwc3/dwc3-haps.c +++ b/drivers/usb/dwc3/dwc3-haps.c @@ -29,6 +29,7 @@ static const struct property_entry initial_properties[] = { PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"), PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"), + PROPERTY_ENTRY_BOOL("snps,sgl-trb-cache-size-quirk"), PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), { }, }; diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index bef1c1ac2067..e0089c82728e 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -44,7 +44,7 @@ static int dwc3_host_get_irq(struct dwc3 *dwc) int dwc3_host_init(struct dwc3 *dwc) { - struct property_entry props[4]; + struct property_entry props[5]; struct platform_device *xhci; int ret, irq; struct resource *res; @@ -95,6 +95,10 @@ int dwc3_host_init(struct dwc3 *dwc) if (dwc->usb2_lpm_disable) props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb2-lpm-disable"); + if (dwc->sgl_trb_cache_size_quirk) + props[prop_idx++] = + PROPERTY_ENTRY_BOOL("sgl-trb-cache-size-quirk"); + /** * WORKAROUND: dwc3 revisions <=3.00a have a limitation * where Port Disable command doesn't work. From patchwork Wed May 27 10:42:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejas Joglekar X-Patchwork-Id: 11572601 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EE86014B7 for ; Wed, 27 May 2020 10:44:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CFBC120888 for ; Wed, 27 May 2020 10:44:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="NfnwRhd3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728313AbgE0KoR (ORCPT ); Wed, 27 May 2020 06:44:17 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:34694 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727027AbgE0KoQ (ORCPT ); Wed, 27 May 2020 06:44:16 -0400 Received: from mailhost.synopsys.com (mdc-mailhost2.synopsys.com [10.225.0.210]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 2235EC0519; Wed, 27 May 2020 10:44:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1590576255; bh=855GjQn1FEeqOyUJZosAn+Z7OiUOrt0Wo2sq8fiAPc0=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=NfnwRhd3BdNcw3Bz/8oim6Meqj2EnM6UToAW8RN75KyDgxZsWp/I7r/lov4a8MAo+ nvslKH2oc58aym7fHAFT46LpqG5glD4rZGN2ehZ1bVH5tA2QPHvzm9iKqN5UncIhJm CMZqz6ZgqC/GwL+JmkHSzGLxxN6tsQ3SO2Co2bwWNph04g6+DJ1ldlZsmf/mZWWPzP GatQDkn5Z6edp4aqIrVoEuJ8OgEE95bHpoOwKVs4Vix/Jb+qSwhBqZCO33hfAbTINh R4tDaDaULSNRW5l/ef9QbOguf2Keenpg8FDUOdRaftCff40vUvowaFo2XvHw6fU4hh +O40+zIBLff7A== Received: from tejas-VirtualBox (joglekar-e7480.internal.synopsys.com [10.146.20.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id EEE86A005C; Wed, 27 May 2020 10:44:11 +0000 (UTC) Received: by tejas-VirtualBox (sSMTP sendmail emulation); Wed, 27 May 2020 16:12:09 +0530 Date: Wed, 27 May 2020 16:12:09 +0530 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Tejas Joglekar Subject: [PATCH v3 4/4] usb: xhci: Use temporary buffer to consolidate SG To: Greg Kroah-Hartman , Tejas Joglekar , linux-usb@vger.kernel.org, Mathias Nyman Cc: John Youn Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The Synopsys xHC has an internal TRB cache of size TRB_CACHE_SIZE for each endpoint. The default value for TRB_CACHE_SIZE is 16 for SS and 8 for HS. The controller loads and updates the TRB cache from the transfer ring in system memory whenever the driver issues a start transfer or update transfer command. For chained TRBs, the Synopsys xHC requires that the total amount of bytes for all TRBs loaded in the TRB cache be greater than or equal to 1 MPS. Or the chain ends within the TRB cache (with a last TRB). If this requirement is not met, the controller will not be able to send or receive a packet and it will hang causing a driver timeout and error. This can be a problem if a class driver queues SG requests with many small-buffer entries. The XHCI driver will create a chained TRB for each entry which may trigger this issue. This patch adds logic to the XHCI driver to detect and prevent this from happening. For every (TRB_CACHE_SIZE - 2), we check the total buffer size of the SG list and if the last window of (TRB_CACHE_SIZE - 2) SG list length and we don't make up at least 1 MPS, we create a temporary buffer to consolidate full SG list into the buffer. We check at (TRB_CACHE_SIZE - 2) window because it is possible that there would be a link and/or event data TRB that take up to 2 of the cache entries. We discovered this issue with devices on other platforms but have not yet come across any device that triggers this on Linux. But it could be a real problem now or in the future. All it takes is N number of small chained TRBs. And other instances of the Synopsys IP may have smaller values for the TRB_CACHE_SIZE which would exacerbate the problem. Signed-off-by: Tejas Joglekar --- drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci.c | 135 +++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci.h | 4 ++ 3 files changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 0fda0c0f4d31..104c9f683375 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3325,7 +3325,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, full_len = urb->transfer_buffer_length; /* If we have scatter/gather list, we use it. */ - if (urb->num_sgs) { + if (urb->num_sgs && !(urb->transfer_flags & URB_DMA_MAP_SINGLE)) { num_sgs = urb->num_mapped_sgs; sg = urb->sg; addr = (u64) sg_dma_address(sg); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index bee5deccc83d..646a6a542ec7 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1256,6 +1256,116 @@ EXPORT_SYMBOL_GPL(xhci_resume); /*-------------------------------------------------------------------------*/ +static int xhci_map_temp_buffer(struct usb_hcd *hcd, struct urb *urb) +{ + void *temp; + int ret = 0; + unsigned int len; + unsigned int buf_len; + enum dma_data_direction dir; + struct xhci_hcd *xhci; + + xhci = hcd_to_xhci(hcd); + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + buf_len = urb->transfer_buffer_length; + + temp = kzalloc_node(buf_len, GFP_ATOMIC, + dev_to_node(hcd->self.sysdev)); + + if (usb_urb_dir_out(urb)) + len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs, + temp, buf_len, 0); + + urb->transfer_buffer = temp; + urb->transfer_dma = dma_map_single(hcd->self.sysdev, + urb->transfer_buffer, + urb->transfer_buffer_length, + dir); + + if (dma_mapping_error(hcd->self.sysdev, + urb->transfer_dma)) { + ret = -EAGAIN; + kfree(temp); + } else { + urb->transfer_flags |= URB_DMA_MAP_SINGLE; + } + + return ret; +} + +static bool xhci_urb_temp_buffer_required(struct usb_hcd *hcd, + struct urb *urb) +{ + bool ret = false; + unsigned int i; + unsigned int len = 0; + unsigned int buf_len; + unsigned int trb_size; + unsigned int max_pkt; + struct scatterlist *sg; + struct scatterlist *tail_sg; + + sg = urb->sg; + tail_sg = urb->sg; + buf_len = urb->transfer_buffer_length; + max_pkt = usb_endpoint_maxp(&urb->ep->desc); + + if (!urb->num_sgs) + return ret; + + if (urb->dev->speed >= USB_SPEED_SUPER) + trb_size = TRB_CACHE_SIZE_SS; + else + trb_size = TRB_CACHE_SIZE_HS; + + if (urb->transfer_buffer_length != 0 && + !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { + for_each_sg(urb->sg, sg, urb->num_sgs, i) { + len = len + sg->length; + if (i > trb_size - 2) { + len = len - tail_sg->length; + if (len < max_pkt) { + ret = true; + break; + } + + tail_sg = sg_next(tail_sg); + } + } + } + return ret; +} + +static void xhci_unmap_temp_buf(struct usb_hcd *hcd, struct urb *urb) +{ + struct scatterlist *sg; + unsigned int len; + unsigned int buf_len; + enum dma_data_direction dir; + + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + sg = urb->sg; + buf_len = urb->transfer_buffer_length; + + if (IS_ENABLED(CONFIG_HAS_DMA) && + (urb->transfer_flags & URB_DMA_MAP_SINGLE)) + dma_unmap_single(hcd->self.sysdev, + urb->transfer_dma, + urb->transfer_buffer_length, + dir); + + if (usb_urb_dir_in(urb)) + len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, + urb->transfer_buffer, + buf_len, + 0); + + urb->transfer_flags &= ~URB_DMA_MAP_SINGLE; + kfree(urb->transfer_buffer); + urb->transfer_buffer = NULL; +} + /* * Bypass the DMA mapping if URB is suitable for Immediate Transfer (IDT), * we'll copy the actual data into the TRB address register. This is limited to @@ -1265,12 +1375,36 @@ EXPORT_SYMBOL_GPL(xhci_resume); static int xhci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) { + struct xhci_hcd *xhci; + + xhci = hcd_to_xhci(hcd); + if (xhci_urb_suitable_for_idt(urb)) return 0; + if (xhci->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK) { + if (xhci_urb_temp_buffer_required(hcd, urb)) + return xhci_map_temp_buffer(hcd, urb); + } return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); } +static void xhci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +{ + struct xhci_hcd *xhci; + bool unmap_temp_buf = false; + + xhci = hcd_to_xhci(hcd); + + if (urb->num_sgs && (urb->transfer_flags & URB_DMA_MAP_SINGLE)) + unmap_temp_buf = true; + + if ((xhci->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK) && unmap_temp_buf) + xhci_unmap_temp_buf(hcd, urb); + else + usb_hcd_unmap_urb_for_dma(hcd, urb); +} + /** * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and * HCDs. Find the index for an endpoint given its descriptor. Use the return @@ -5315,6 +5449,7 @@ static const struct hc_driver xhci_hc_driver = { * managing i/o requests and associated device resources */ .map_urb_for_dma = xhci_map_urb_for_dma, + .unmap_urb_for_dma = xhci_unmap_urb_for_dma, .urb_enqueue = xhci_urb_enqueue, .urb_dequeue = xhci_urb_dequeue, .alloc_dev = xhci_alloc_dev, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 69e3587e805c..2d3ae699e40c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1330,6 +1330,10 @@ enum xhci_setup_dev { #define TRB_SIA (1<<31) #define TRB_FRAME_ID(p) (((p) & 0x7ff) << 20) +/* TRB cache size for xHC with TRB cache */ +#define TRB_CACHE_SIZE_HS 8 +#define TRB_CACHE_SIZE_SS 16 + struct xhci_generic_trb { __le32 field[4]; };