From 125b33192537575136e07c012a5b124011485f1f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 8 Sep 2011 18:27:33 +0300 Subject: [PATCH] --- yaml --- r: 264991 b: refs/heads/master c: 55f3fba6c822f05b02f06070efaadf0300b5f9f1 h: refs/heads/master i: 264989: 062e4f6897d79f2a3d093a55f24aeb280f276682 264987: 0d6bac13ce37dd62d3dbcedafaaa5e0e3d7ca72e 264983: e1f20cd0c947d8684e6f31e5e5d6b97b7493d9e6 264975: f76a03e268ddca5745771f63afc68f23a2d77b36 264959: 5257f8786329dfe53e308ed673541240d4b064f7 v: v3 --- [refs] | 2 +- trunk/drivers/usb/dwc3/core.h | 2 ++ trunk/drivers/usb/dwc3/ep0.c | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 0bfa98d5d795..ae25da785442 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d742220b357769fa0a764d238373b8667116cf64 +refs/heads/master: 55f3fba6c822f05b02f06070efaadf0300b5f9f1 diff --git a/trunk/drivers/usb/dwc3/core.h b/trunk/drivers/usb/dwc3/core.h index 92673fd5314d..07d20186e46d 100644 --- a/trunk/drivers/usb/dwc3/core.h +++ b/trunk/drivers/usb/dwc3/core.h @@ -529,6 +529,7 @@ static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat) * @three_stage_setup: set if we perform a three phase setup * @ep0_status_pending: ep0 status response without a req is pending * @ep0_bounced: true when we used bounce buffer + * @ep0_expect_in: true when we expect a DATA IN transfer * @ep0_next_event: hold the next expected event * @ep0state: state of endpoint zero * @link_state: link state @@ -575,6 +576,7 @@ struct dwc3 { unsigned three_stage_setup:1; unsigned ep0_status_pending:1; unsigned ep0_bounced:1; + unsigned ep0_expect_in:1; enum dwc3_ep0_next ep0_next_event; enum dwc3_ep0_state ep0state; diff --git a/trunk/drivers/usb/dwc3/ep0.c b/trunk/drivers/usb/dwc3/ep0.c index 4cc72fdc0575..b66d96905728 100644 --- a/trunk/drivers/usb/dwc3/ep0.c +++ b/trunk/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;