From patchwork Tue Apr 21 09:48: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: 11500945 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 A8B55913 for ; Tue, 21 Apr 2020 09:48:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8A52221D94 for ; Tue, 21 Apr 2020 09:48:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="H4n5GW/O" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727042AbgDUJsP (ORCPT ); Tue, 21 Apr 2020 05:48:15 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:35400 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726741AbgDUJsP (ORCPT ); Tue, 21 Apr 2020 05:48:15 -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 E37104050B; Tue, 21 Apr 2020 09:48:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1587462495; bh=pEl+BqajQpxKEU6q4ersObSMeKbSkHMMBoPiWf2oh+8=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=H4n5GW/OyNgghmNUf48YLQnLRN56uPNJOoVMdA434Qg5E6LxvLht/lyQ3a98AFuyw k+Qf295QQBkeMAIUnZS1a5QGDrQVR0qd5Ol3wyPZMB5Hqhs9CXm+BsKRYSSr2UjJUm iK/f40gZe30suQQaLIvWDyhsoxLSwj+jlSRmO2DbvILyqsUyacunLLaGflYQgf5BBG NIOO7OJnsm/IyVMSLdpMDNK07apRZGzGX/tznOEHhLGea0OiClLuqlHO4vZtOkiI9o LvXosPiER1Ejgap5+nvwqcywqq51Dn6I5VWArX7RZYzi8zE+nodFviA5JnzFeV6fT1 FCDyU2n8rjz3A== Received: from tejas-VirtualBox (joglekar-e7480.internal.synopsys.com [10.146.16.13]) (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 4B242A005C; Tue, 21 Apr 2020 09:48:11 +0000 (UTC) Received: by tejas-VirtualBox (sSMTP sendmail emulation); Tue, 21 Apr 2020 15:18:09 +0530 Date: Tue, 21 Apr 2020 15:18:09 +0530 Message-Id: <5f5fdfbd323159133fced5b1340f5eb5fd11a17a.1587461220.git.joglekar@synopsys.com> In-Reply-To: References: From: Tejas Joglekar Subject: [RFC PATCH v2 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 --- Changes in v2: - Renamed the property 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 9946ff9ba735..6d0418ee4dbd 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -104,6 +104,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 3f378951d624..14d900474894 100644 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt @@ -43,6 +43,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 Tue Apr 21 09:48:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejas Joglekar X-Patchwork-Id: 11500947 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 EDC80913 for ; Tue, 21 Apr 2020 09:48:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D569D206D4 for ; Tue, 21 Apr 2020 09:48:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="kfCTFfcQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727043AbgDUJsk (ORCPT ); Tue, 21 Apr 2020 05:48:40 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:51488 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726691AbgDUJsj (ORCPT ); Tue, 21 Apr 2020 05:48:39 -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 4BB7BC0350; Tue, 21 Apr 2020 09:48:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1587462519; bh=kbF7sy2jH1FAfrgokDoooDZ2WmVWXX6ZOtDlH4/1MaU=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=kfCTFfcQPcF3DcZgTmioCq3qWzb94NKi5RLeLsRmHi+PchA6+i1k/lXcR9S6VQPjG YdtQWS2mDt3hszv49ykWIYLWLceCcKyAW7s90+T452lzM1B8q+5ZstRSL91rQR27g7 vbSQvpVCbcVa0aIJIk1BzQfxKjIKVRlaPS4BiHH5NMZaCII+v4UTWwdwAUtsTMMKqD 8MvXpzH/X7Fk7+rIr0zBp6vSkxvdoS++tGF2CzboxsxQkM048ZUbJ1dAAcuK+g15m3 rbVOZys8ct/lbJHIoUk3vX8j+yNrO1g9Ge9SHNhnL7LuUCQFbuOYXHeRvz5gxfF1og pKx983dDZKmag== Received: from tejas-VirtualBox (joglekar-e7480.internal.synopsys.com [10.146.16.13]) (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 CD01EA005B; Tue, 21 Apr 2020 09:48:35 +0000 (UTC) Received: by tejas-VirtualBox (sSMTP sendmail emulation); Tue, 21 Apr 2020 15:18:33 +0530 Date: Tue, 21 Apr 2020 15:18:33 +0530 Message-Id: In-Reply-To: References: From: Tejas Joglekar Subject: [RFC PATCH v2 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 --- Changes in v2: - Renamed the quirk - Renamed the property 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 3289bb516201..4db825459b40 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 Tue Apr 21 09:48:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejas Joglekar X-Patchwork-Id: 11500949 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 C586113B2 for ; Tue, 21 Apr 2020 09:49:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ACC5421473 for ; Tue, 21 Apr 2020 09:49:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="CheXiLPf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726874AbgDUJtE (ORCPT ); Tue, 21 Apr 2020 05:49:04 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:51510 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726628AbgDUJtE (ORCPT ); Tue, 21 Apr 2020 05:49:04 -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 8818EC0350; Tue, 21 Apr 2020 09:49:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1587462543; bh=HFowMbPhmFZpI2RfUFW3cHan0oDGMyMQ+vVs81lilBA=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=CheXiLPf8P91WgNEqBLKE+xeqphsi4e2miUpPQectGQmq37q6NFrklcF3BZrelE+L 5oCBrV/r1u79nILu/20q6VDLkP8KTYSQhqSYZE6BX1m6+Y0Nf4thBl8BY57bLOmJea m8SMHjiKu68jLfOnpA9OltdEw3MhfY9yLr1PlLb2OEm6PrP5+Nd6P3oDPAiqEtqu7W 9nGPZyNi1xrga1IeiZOMehHGfml+JWZgKlhCXCgvjRfkkY0lrVFCmytjWwv2cJwJQd 4a/nfcJOzmQSkc+TJenKQhd3r6Nb/kYKINeM3O004sZwNQmzwKqOUQOEO4B0U6e4GS 5KS422E+njAaA== Received: from tejas-VirtualBox (joglekar-e7480.internal.synopsys.com [10.146.16.13]) (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 62F84A005C; Tue, 21 Apr 2020 09:49:00 +0000 (UTC) Received: by tejas-VirtualBox (sSMTP sendmail emulation); Tue, 21 Apr 2020 15:18:58 +0530 Date: Tue, 21 Apr 2020 15:18:58 +0530 Message-Id: <77fb2e745a73d4fd2945e161fa3bc713f834fbc2.1587461220.git.joglekar@synopsys.com> In-Reply-To: References: From: Tejas Joglekar Subject: [RFC PATCH v2 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 --- Changes in v2: - Renamed the property 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 ab6323b8e323..beb95f5fdce3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1303,6 +1303,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 bfc5c780a963..10647cbeea68 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1007,6 +1007,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 @@ -1206,6 +1207,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 86dbd012b984..c1d851ff39b1 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 Tue Apr 21 09:49:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejas Joglekar X-Patchwork-Id: 11500951 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 978CF13B2 for ; Tue, 21 Apr 2020 09:49:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77D9120CC7 for ; Tue, 21 Apr 2020 09:49:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="h1w2yx+7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728316AbgDUJta (ORCPT ); Tue, 21 Apr 2020 05:49:30 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:51516 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726628AbgDUJt3 (ORCPT ); Tue, 21 Apr 2020 05:49:29 -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 CB509C0350; Tue, 21 Apr 2020 09:49:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1587462568; bh=FXUsSzx9CFp59s0UgA504wi0fMwRhEtDOLFrnewrLDU=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=h1w2yx+7BnVjSczN237UtAZXE2fdoG8pEgm0RwkW5EsNRmb5rp+O3PcuE1EGFyOWm jYSBblKMxBkvAPLlD6oaLJ/lAliMA+fbD4CKd9oU0eLfDYwmaRMoSbakvmEazxgEt3 EmOgjDU3D8aK9Z7HpuvgeDpLnADA7G+8mcF4UC0NG7WrnUDJWZOavESgsPk1FErS9A fi3wi1UP5SXYWWDkR/IbDUMkowyiKfiQLEXopnZbXn4zVjRYH/vWjyhJ0RuDpno+kR o1eMJ+ecmr9R55kvvUlifjO4GOs71ULZ6oAyPOlzWX3sIDYarQCof2Q6u+8NuiWMG2 V9/+uPg9oA+Zw== Received: from tejas-VirtualBox (joglekar-e7480.internal.synopsys.com [10.146.16.13]) (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 A46E2A005B; Tue, 21 Apr 2020 09:49:24 +0000 (UTC) Received: by tejas-VirtualBox (sSMTP sendmail emulation); Tue, 21 Apr 2020 15:19:22 +0530 Date: Tue, 21 Apr 2020 15:19:22 +0530 Message-Id: <969b5c9f31807635785ecc74b2ae2559ddc3bbeb.1587461220.git.joglekar@synopsys.com> In-Reply-To: References: From: Tejas Joglekar Subject: [RFC PATCH v2 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 --- Changes in v2: - Removed redundant debug messages - Modified logic to remove unnecessary changes in hcd.c - Rename the quirk drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci.c | 125 +++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci.h | 4 ++ 3 files changed, 130 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index a78787bb5133..2fad9474912a 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3291,7 +3291,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 fe38275363e0..15f06bc6b1ad 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1256,6 +1256,106 @@ 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 urb *urb) +{ + struct scatterlist *sg; + unsigned int len; + unsigned int buf_len; + + sg = urb->sg; + buf_len = urb->transfer_buffer_length; + + if (usb_urb_dir_in(urb)) { + len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, + urb->transfer_buffer, + buf_len, + 0); + } + + 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 +1365,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; + + usb_hcd_unmap_urb_for_dma(hcd, urb); + + if ((xhci->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK) && unmap_temp_buf) + xhci_unmap_temp_buf(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 +5439,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 4db825459b40..14600214188f 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]; };