Linux-USB Archive on
 help / color / Atom feed
From: John Stultz <>
To: lkml <>
Cc: Pratham Pratap <>,
	Felipe Balbi <>, Yang Fei <>,
	Thinh Nguyen <>,
	Tejas Joglekar <>,
	Andrzej Pietrasiewicz <>,
	Jack Pham <>, Todd Kjos <>,
	Greg KH <>,
	Linux USB List <>,
	stable <>,
	John Stultz <>
Subject: [RESEND][PATCH v2] usb: dwc3: gadget: Update chain bit correctly when using sg list
Date: Mon,  2 Mar 2020 21:44:43 +0000
Message-ID: <> (raw)

From: Pratham Pratap <>

If scatter-gather operation is allowed, a large USB request is split
into multiple TRBs. For preparing TRBs for sg list, driver iterates
over the list and creates TRB for each sg and mark the chain bit to
false for the last sg. The current IOMMU driver is clubbing the list
of sgs which shares a page boundary into one and giving it to USB driver.
With this the number of sgs mapped it not equal to the the number of sgs
passed. Because of this USB driver is not marking the chain bit to false
since it couldn't iterate to the last sg. This patch addresses this issue
by marking the chain bit to false if it is the last mapped sg.

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.

Credit also to Anurag Kumar Vulisha <>
who implemented a very similar fix to this issue.

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 <> #4.20+
Signed-off-by: Pratham Pratap <>
[jstultz: Slight tweak to remove sg_is_last() usage, reworked
          commit message, minor comment tweak]
Signed-off-by: John Stultz <>
* Fix typeos and unnecssary parens as suggested by Jack
 drivers/usb/dwc3/gadget.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1b7d2f9cb673..1e00bf2d65a2 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1071,7 +1071,14 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
 		unsigned int rem = length % maxp;
 		unsigned chain = true;
-		if (sg_is_last(s))
+		/*
+		 * IOMMU driver is coalescing the list of sgs which shares a
+		 * page boundary into one and giving it to USB driver. With
+		 * this the number of sgs mapped is not equal to the number of
+		 * sgs passed. So mark the chain bit to false if it isthe last
+		 * mapped sg.
+		 */
+		if (i == remaining - 1)
 			chain = false;
 		if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) {

                 reply index

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-USB Archive on

Archives are clonable:
	git clone --mirror linux-usb/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-usb linux-usb/ \
	public-inbox-index linux-usb

Example config snippet for mirrors

Newsgroup available over NNTP:

AGPL code for this site: git clone