From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Cc: Sascha Hauer <sascha@saschahauer.de>,
"Claude Sonnet 4.6" <noreply@anthropic.com>
Subject: [PATCH 1/2] usb: dwc2: handle NAK when CHHLTD does not fire
Date: Mon, 20 Apr 2026 13:20:53 +0200 [thread overview]
Message-ID: <20260420-usb-dwc2-usb-c-stick-v1-1-c86f733f24f8@pengutronix.de> (raw)
In-Reply-To: <20260420-usb-dwc2-usb-c-stick-v1-0-c86f733f24f8@pengutronix.de>
From: Sascha Hauer <sascha@saschahauer.de>
Some DWC2 configurations do not assert CHHLTD when a NAK is received;
the hardware keeps the channel active and only sets the NAK bit in HCINT.
wait_for_chhltd() polls for CHHLTD with a 10ms timeout; when CHHLTD never
fires the timeout expires and -ETIMEDOUT is returned without inspecting
HCINT. This causes the caller to treat the NAK as a hard error instead of
a retryable condition.
The symptom is that devices which NAK bulk or control transfers during
initialisation (e.g. some Samsung USB-C flash drives that NAK while their
firmware starts up) fail immediately rather than being retried via the
5-second NAK-retry loop in dwc2_submit_bulk_msg() or the do/while loops
in dwc2_submit_control_msg().
Fix by reading HCINT before aborting the channel when the CHHLTD timeout
fires. If the NAK or FRMOVRUN bit is set, abort the channel, wait for the
abort to complete, and return -EAGAIN so that the existing retry logic can
handle the NAK. Log a diagnostic message if the channel abort itself times
out, which would indicate a real hardware problem.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Sascha Hauer <sascha@saschahauer.de>
---
drivers/usb/dwc2/host.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc2/host.c b/drivers/usb/dwc2/host.c
index 93994f0be3..ddad51c882 100644
--- a/drivers/usb/dwc2/host.c
+++ b/drivers/usb/dwc2/host.c
@@ -134,9 +134,14 @@ static int wait_for_chhltd(struct dwc2 *dwc2, u8 hc, uint32_t *sub, u8 *tgl)
ret = dwc2_wait_bit_set(dwc2, HCINT(hc), HCINTMSK_CHHLTD, 10000);
if (ret) {
+ hcint = dwc2_readl(dwc2, HCINT(hc));
hcchar = dwc2_readl(dwc2, HCCHAR(hc));
dwc2_writel(dwc2, hcchar | HCCHAR_CHDIS, HCCHAR(hc));
- dwc2_wait_bit_set(dwc2, HCINT(hc), HCINTMSK_CHHLTD, 10000);
+ if (dwc2_wait_bit_set(dwc2, HCINT(hc), HCINTMSK_CHHLTD, 10000))
+ dwc2_err(dwc2, "%s: channel abort timed out: HCINT=%08x HCCHAR=%08x\n",
+ __func__, hcint, hcchar);
+ if (hcint & (HCINTMSK_NAK | HCINTMSK_FRMOVRUN))
+ return -EAGAIN;
return ret;
}
--
2.47.3
next prev parent reply other threads:[~2026-04-20 11:21 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-20 11:20 [PATCH 0/2] USB: dwc2: Fix handling NAK Sascha Hauer
2026-04-20 11:20 ` Sascha Hauer [this message]
2026-04-20 11:32 ` [PATCH 1/2] usb: dwc2: handle NAK when CHHLTD does not fire Ahmad Fatoum
2026-04-20 12:18 ` Sascha Hauer
2026-04-20 14:11 ` Ahmad Fatoum
2026-04-20 15:40 ` anis chali
2026-04-21 2:28 ` anis chali
2026-04-21 7:54 ` Sascha Hauer
2026-04-21 13:48 ` anis chali
2026-04-20 11:20 ` [PATCH 2/2] usb: dwc2: fix data toggle reset direction on ClearFeature(ENDPOINT_HALT) Sascha Hauer
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:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260420-usb-dwc2-usb-c-stick-v1-1-c86f733f24f8@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=barebox@lists.infradead.org \
--cc=noreply@anthropic.com \
--cc=sascha@saschahauer.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox