Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp5310513ybl; Wed, 22 Jan 2020 14:29:30 -0800 (PST) X-Google-Smtp-Source: APXvYqwDspamUf5WCJ0lCF7iO06rm4Ja2wdi9570evKtWTByck4WhBZK7fY4NugpdraZRARmbKNn X-Received: by 2002:aca:f20b:: with SMTP id q11mr8193769oih.78.1579732169913; Wed, 22 Jan 2020 14:29:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579732169; cv=none; d=google.com; s=arc-20160816; b=Dx+v6OjRajbP3FC8U+XDPvPm2cw049DIak6XogmAwDIoFsgKUK7JQE5QYDAjg5bG7J keZcuDtNnpXUNDgofqZa1NDLZ/AaGE9OaL2e2rQPt3MulPC4KC2NRn3RUnIJONUOqlMC bcXvbLzMBFY8LAIWV68YNCPpzOsVfTntaR4Flxj6XgUWVR88PskMYx4BGxUHICfmneI7 rteqb1Qjb4vBzXQvUyqFUN9L0/FE/ThMb+Kk8vBWzUi9xYUPBTpre5mlZfqhdKBVYEPu IcT5vOe72zI4OYQypFYZ+/TcTf66qofJhAFKuwip9mW2sQJG22eg8FVdMEhkTuLv/ZHZ iFwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=swWbt3aJL3q8h4lz+/4twKGtWH3pxZbO2/WppH1VqRE=; b=PVL6lleMSzTWpCe2kPMnZB8x0RZv1NBD7P4jL76SXAE62EwbkbBVIgNQS+ol+zpVj7 0OKx/8tz8z+tz7aYyNYeyYKtDI8nJ5g9QnsNdG9rj/CvB3mcdmSfPLXG9d8+AG3Gw91S OfTvagYdAdZ5PAwjhYKj2ntcB9/dgsIDK0R1QXgmRM8Z20BkcUQJJWjfgBVWchkjNrGw YiUWbXuwo7IKNoufD2JQJ0DwxhC2Bfr0os7JYfQTIq0pqmh7KBiYEJxl05CvofILhRVf MM1uL6lnXeWWtO2QpD9NTK62GL2ZtTJTp5kEnlbwSL/zfwtfgWCGlYpyaYENEfDLh+kb fRxw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=K0ohNbHM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w1si21833629oia.169.2020.01.22.14.29.18; Wed, 22 Jan 2020 14:29:29 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=K0ohNbHM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728981AbgAVW07 (ORCPT + 99 others); Wed, 22 Jan 2020 17:26:59 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:37505 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728709AbgAVW0x (ORCPT ); Wed, 22 Jan 2020 17:26:53 -0500 Received: by mail-pf1-f195.google.com with SMTP id p14so508405pfn.4 for ; Wed, 22 Jan 2020 14:26:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=swWbt3aJL3q8h4lz+/4twKGtWH3pxZbO2/WppH1VqRE=; b=K0ohNbHMOAsVb4M6Ck8cIf3BM8XchMabhMit1TMM4M9rA7DOOGd/sgBcVKqk4Dkfyl MzkiSn6mrkDn4Rzo4C7qixNHdL/CFF78glRDZyCApSy9ECeubN35sr+56Jowj5rwc1qX P0nCx7C1QsIOrrIqxRuZIJCWeIkHckFcMN5GGbk1NVw9Y/JbCuMS4i3CzwgBPRDfpjcq SBIyfImGz9ImHeT0LopgirqAnevkSzpfLi+UMd7UT0MkGdqNkR32HmrLKL2wP3KNBLbp aDB8LJZb1z0/CHBTLZbYRBbK4qL9hHXMe7uTtYP/yX1g1i8LefORegdQRnX/eR1YsnR8 UbNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=swWbt3aJL3q8h4lz+/4twKGtWH3pxZbO2/WppH1VqRE=; b=XHkRBEli5ooBPmtZkk5pYT8kQmKhLOrODfFZd7O5QwVkvPt4H+LO+D3QwHUVILmeZy a2UlUTzKwy7nKWnVmD7LK0HL7k2AcO0U9WJYIcscg08LlULwimnP4mSdLpUHApBHbLSU UZaJ9rppr/Jv9no7/QtaASCCzUR4pOiOB1GWqu88LMJdSs2BjaQDw8J0Jxccba7K1VUh Ft1LMzKEm4YV6/SpQhG3LDGXG0zO3Vxkp61uzRtSMx6n6k0MKzCehaMuYAPL7P9x4lSH cN27cXstYxR3dFfoUz0O9t8qdGnCblW6Q8EwUK6Jm745VGFyTN/LcgXCVXGzCC5s4K2e ZRmw== X-Gm-Message-State: APjAAAWmwCqsZREv9+Q8igIPNi4PM9tYeE3pUS4E8PBxZpqjwdeaDzKe 2dvk6VL5K9pfskNPcVxEUtRWEWXqhlg= X-Received: by 2002:a62:3892:: with SMTP id f140mr4552209pfa.190.1579732012776; Wed, 22 Jan 2020 14:26:52 -0800 (PST) Received: from localhost.localdomain ([2601:1c2:680:1319:692:26ff:feda:3a81]) by smtp.gmail.com with ESMTPSA id a28sm47793509pfh.119.2020.01.22.14.26.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Jan 2020 14:26:52 -0800 (PST) From: John Stultz To: lkml Cc: Anurag Kumar Vulisha , Felipe Balbi , Yang Fei , Thinh Nguyen , Tejas Joglekar , Andrzej Pietrasiewicz , Jack Pham , Todd Kjos , Greg KH , Linux USB List , stable , John Stultz Subject: [RFC][PATCH 2/2] usb: dwc3: gadget: Correct the logic for finding last SG entry Date: Wed, 22 Jan 2020 22:26:45 +0000 Message-Id: <20200122222645.38805-3-john.stultz@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200122222645.38805-1-john.stultz@linaro.org> References: <20200122222645.38805-1-john.stultz@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Anurag Kumar Vulisha As a process of preparing TRBs usb_gadget_map_request_by_dev() is called from dwc3_prepare_trbs() for mapping the request. This will call dma_map_sg() if req->num_sgs are greater than 0. dma_map_sg() will map the sg entries in sglist and return the number of mapped SGs. As a part of mapping, some sg entries having contigous memory may be merged together into a single sg (when IOMMU used). So, the number of mapped sg entries may not be equal to the number of orginal sg entries in the request (req->num_sgs). As a part of preparing the TRBs, dwc3_prepare_one_trb_sg() iterates over the sg entries present in the sglist and calls sg_is_last() to identify whether the sg entry is last and set IOC bit for the last sg entry. The sg_is_last() determines last sg if SG_END is set in sg->page_link. When IOMMU used, dma_map_sg() merges 2 or more sgs into a single sg and it doesn't retain the page_link properties. Because of this reason the sg_is_last() may not find SG_END and thus resulting in IOC bit never getting set. For example: Consider a request having 8 sg entries with each entry having a length of 4096 bytes. Assume that sg1 & sg2, sg3 & sg4, sg5 & sg6, sg7 & sg8 are having contigous memory regions. Before calling dma_map_sg(): sg1-->sg2-->sg3-->sg4-->sg6-->sg7-->sg8 dma_length: 4K 4K 4K 4K 4K 4K 4K SG_END: False False False False False False True num_sgs = 8 num_mapped_sgs = 0 The dma_map_sg() merges sg1 & sg2 memory regions into sg1->dma_address. Similarly sg3 & sg4 into sg2->dma_address, sg5 & sg6 into the sg3->dma_address and sg6 & sg8 into sg4->dma_address. Here the memory regions are merged but the page_link properties like SG_END are not retained into the merged sgs. After calling dma_map_sg(); sg1-->sg2-->sg3-->sg4-->sg6-->sg7-->sg8 dma_length: 8K 8K 8K 8K 0K 0K 0K SG_END: False False False False False False True num_sgs = 8 num_mapped_sgs = 4 After calling dma_map_sg(), sg1,sg2,sg3,sg4 are having dma_length of 8096 bytes each and remaining sg4,sg5,sg6,sg7 are having 0 bytes of dma_length. After dma_map_sg() is performed dma_perpare_trb_sg() iterates on all sg entries and sets IOC bit only for the sg8 (since sg_is_last() returns true only for sg8). But after calling dma_map_sg() the valid data are present only till sg4 and the IOC bit should be set for sg4 TRB only (which is not happening in the present code) The above mentioned issue can be fixed by determining last sg based on the req->num_queued_sgs instead of sg_is_last(). If (req->num_queued_sgs + 1) is equal to req->num_mapped_sgs, then this sg is the last sg. In the above example, the dwc3 driver has already queued 3 sgs (upto sg3), so the num_queued_sgs = 3. On preparing the next sg (i.e sg4), check for last sg (num_queued_sgs + 1) == num_mapped_sgs becomes true. So, the driver sets IOC bit for sg4. This patch does the same. At a practical level, this patch resolves USB transfer stalls seen with adb on dwc3 based db845c, pixel3 and other qcom hardware after functionfs gadget added scatter-gather support around v4.20. Cc: Felipe Balbi Cc: Yang Fei Cc: Thinh Nguyen Cc: Tejas Joglekar Cc: Andrzej Pietrasiewicz Cc: Jack Pham Cc: Todd Kjos Cc: Greg KH Cc: Linux USB List Cc: stable Signed-off-by: Anurag Kumar Vulisha [jstultz: Add note to end of commit message on specific issue this resovles] Signed-off-by: John Stultz --- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1edce3bbb55c..30a80bc97cfe 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1068,7 +1068,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, unsigned int rem = length % maxp; unsigned chain = true; - if (sg_is_last(s)) + if ((req->num_queued_sgs + 1) == req->request.num_mapped_sgs) chain = false; if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) { -- 2.17.1