diff mbox

usb: gadget: aspeed-vhub: Fix SETUP packets with OUT data phase

Message ID 3b75bd42a21f5239704cc736d134c32998a3fbcf.camel@kernel.crashing.org (mailing list archive)
State New, archived
Headers show

Commit Message

Benjamin Herrenschmidt June 27, 2018, 11:01 p.m. UTC
A couple of bugs in the driver are preventing SETUP packets
with an OUT data phase from working properly.

Interestingly those are incredibly rare (RNDIS typically
uses them and thus is broken without this fix).

The main problem was an incorrect register offset being
applied for arming RX on EP0. The other problem relates
to stalling such a packet before the data phase, in which
case we don't get an ACK cycle, and get the next SETUP
packet directly, so we shouldn't reject it.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

Felipe, please send upstream before 4.18 close.

(Resent with proper [PATCH] tag... ops)

 drivers/usb/gadget/udc/aspeed-vhub/ep0.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/usb/gadget/udc/aspeed-vhub/ep0.c b/drivers/usb/gadget/udc/aspeed-vhub/ep0.c
index 20ffb03ff6ac..44f2b3b53b2f 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/ep0.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/ep0.c
@@ -108,6 +108,13 @@  void ast_vhub_ep0_handle_setup(struct ast_vhub_ep *ep)
 	/* Check our state, cancel pending requests if needed */
 	if (ep->ep0.state != ep0_state_token) {
 		EPDBG(ep, "wrong state\n");
+		ast_vhub_nuke(ep, -EIO);
+
+		/*
+		 * Accept the packet regardless, this seems to happen
+		 * when stalling a SETUP packet that has an OUT data
+		 * phase.
+		 */
 		ast_vhub_nuke(ep, 0);
 		goto stall;
 	}
@@ -224,7 +231,7 @@  static void ast_vhub_ep0_rx_prime(struct ast_vhub_ep *ep)
 	EPVDBG(ep, "rx prime\n");
 
 	/* Prime endpoint for receiving data */
-	writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat + AST_VHUB_EP0_CTRL);
+	writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat);
 }
 
 static void ast_vhub_ep0_do_receive(struct ast_vhub_ep *ep, struct ast_vhub_req *req,