Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7af40558 authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa Committed by Vamsi Krishna Samavedam
Browse files

dwc3: gadget: Stop active transfer pending on ep0 out/in during reset



if USB bus reset is received from Host in middle of control transfer
request, SW needs to complete pending control transfer and setup core
for next setup stage as per data book. Hence check ep0 state during
reset interrupt handling and make sure active transfers on ep0 out/in
endpoint are stopped by queuing ENDXFER command for that endpoint
and restart ep0 out again to receive next setup packet.

Change-Id: Idf8adf3c2416e7945d879bf88c321e1eea3c31d4
Signed-off-by: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
parent 139b0fbc
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -1163,13 +1163,18 @@ static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
	__dwc3_ep0_do_control_status(dwc, dep);
}

static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep)
void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep)
{
	struct dwc3_gadget_ep_cmd_params params;
	u32			cmd;
	int			ret;

	if (!dep->resource_index)
	/*
	 * For status/DATA OUT stage, TRB will be queued on ep0 out
	 * endpoint for which resource index is zero. Hence allow
	 * queuing ENDXFER command for ep0 out endpoint.
	 */
	if (!dep->resource_index && dep->number)
		return;

	cmd = DWC3_DEPCMD_ENDTRANSFER;
+10 −1
Original line number Diff line number Diff line
@@ -3193,8 +3193,17 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
	 * that EP0 is in setup phase by issuing a stall
	 * and restart if EP0 is not in setup phase.
	 */
	if (dwc->ep0state != EP0_SETUP_PHASE)
	if (dwc->ep0state != EP0_SETUP_PHASE) {
		unsigned int	dir;

		dbg_event(0xFF, "CONTRPEND", dwc->ep0state);
		dir = !!dwc->ep0_expect_in;
		if (dwc->ep0state == EP0_DATA_PHASE)
			dwc3_ep0_end_control_data(dwc, dwc->eps[dir]);
		else
			dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]);
		dwc3_ep0_stall_and_restart(dwc);
	}

	dwc3_stop_active_transfers(dwc);
	dwc3_clear_stall_all_ep(dwc);
+1 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
void dwc3_ep0_interrupt(struct dwc3 *dwc,
		const struct dwc3_event_depevt *event);
void dwc3_ep0_out_start(struct dwc3 *dwc);
void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep);
void dwc3_ep0_stall_and_restart(struct dwc3 *dwc);
int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);