usb: dwc3: ep0: introduce ep0_expect_in flag
This flag will tell us which direction we're
expecting on the next (data or status) phase.
It will help us catching errors of host going
crazy and requesting data of the wrong direction.
Signed-off-by: Felipe Balbi <balbi@ti.com>
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 4cc72fd..b66d969 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -545,6 +545,8 @@
dwc->ep0_next_event = DWC3_EP0_NRDY_DATA;
}
+ dwc->ep0_expect_in = !!(ctrl->bRequestType & USB_DIR_IN);
+
if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
ret = dwc3_ep0_std_request(dwc, ctrl);
else
@@ -758,6 +760,20 @@
return;
}
+ /*
+ * One of the possible error cases is when Host _does_
+ * request for Data Phase, but it does so on the wrong
+ * direction.
+ *
+ * Here, we already know ep0_next_event is DATA (see above),
+ * so we only need to check for direction.
+ */
+ if (dwc->ep0_expect_in != event->endpoint_number) {
+ dev_vdbg(dwc->dev, "Wrong direction for Data phase\n");
+ dwc3_ep0_stall_and_restart(dwc);
+ return;
+ }
+
dwc3_ep0_do_control_data(dwc, event);
break;