[PATCH 2/2] usb: dwc2: fix data toggle reset direction on ClearFeature(ENDPOINT_HALT)

Sascha Hauer s.hauer at pengutronix.de
Mon Apr 20 04:20:54 PDT 2026


From: Sascha Hauer <sascha at saschahauer.de>

dwc2_submit_control_msg() resets the data toggle after a successful
ClearFeature(ENDPOINT_HALT) request. It passes usb_pipein(pipe) as the
direction to dwc2_endpoint_reset(), but pipe is always the control-out
pipe used to send the request, so usb_pipein() always returns 0 (OUT).

As a result, clearing an IN endpoint halt resets the OUT toggle instead
of the IN toggle, leaving the IN data toggle in an incorrect state for
subsequent transfers.

Fix by extracting the direction from the endpoint address in setup->index
(wIndex), where bit 7 is the direction flag per USB 2.0 section 9.3.4.

Fixes: 446bcf875395 ("usb: dwc2: host: Fix toggle reset")
Co-Authored-By: Claude Sonnet 4.6 <noreply at anthropic.com>
Signed-off-by: Sascha Hauer <sascha at saschahauer.de>
---
 drivers/usb/dwc2/host.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/host.c b/drivers/usb/dwc2/host.c
index ddad51c882..2be2666574 100644
--- a/drivers/usb/dwc2/host.c
+++ b/drivers/usb/dwc2/host.c
@@ -401,8 +401,8 @@ static int dwc2_submit_control_msg(struct usb_device *udev,
 		 * ClearFeature(ENDPOINT_HALT) request always results
 		 * in the data toggle being reinitialized to DATA0.
 		 */
-		int ep = le16_to_cpu(setup->index) & 0xf;
-		dwc2_endpoint_reset(dwc2, usb_pipein(pipe), devnum, ep);
+		int ep_addr = le16_to_cpu(setup->index);
+		dwc2_endpoint_reset(dwc2, ep_addr >> 7, devnum, ep_addr & 0xf);
 	}
 
 	udev->act_len = act_len;

-- 
2.47.3




More information about the barebox mailing list