Skip to content

Commit

Permalink
usb: dwc3: ep0: introduce ep0_expect_in flag
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Felipe Balbi committed Sep 9, 2011
1 parent d742220 commit 55f3fba
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/usb/dwc3/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
16 changes: 16 additions & 0 deletions drivers/usb/dwc3/ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit 55f3fba

Please sign in to comment.