summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/ep0.c
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2011-09-08 18:27:33 +0300
committerFelipe Balbi <balbi@ti.com>2011-09-09 13:05:29 +0300
commit55f3fba6c822f05b02f06070efaadf0300b5f9f1 (patch)
tree1ba2067f9f1ada811eab75008e54ea8d527626e5 /drivers/usb/dwc3/ep0.c
parentd742220b357769fa0a764d238373b8667116cf64 (diff)
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>
Diffstat (limited to 'drivers/usb/dwc3/ep0.c')
-rw-r--r--drivers/usb/dwc3/ep0.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 4cc72fdc057..b66d9690572 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -545,6 +545,8 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
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 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
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;