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

Commit 456cf0d2 authored by Sriharsha Allenki's avatar Sriharsha Allenki Committed by Hemant Kumar
Browse files

USB: dwc3: Fix issues in ISOC endpoint handling



If the interval for which the requests are
intended is already expired, START TRANSFER fails.
Handle this by issuing ENDXFER command and wait
for the XFERNOTREADY event to try once again.

Change-Id: I05fb3564d02528d9c952c789ec7a1b39b0bcedff
Signed-off-by: default avatarSriharsha Allenki <sallenki@codeaurora.org>
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent cbf2565c
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
@@ -1356,7 +1356,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param)
{
	struct dwc3_gadget_ep_cmd_params params;
	struct dwc3_request		*req;
	struct dwc3_request		*req, *req1, *n;
	struct dwc3			*dwc = dep->dwc;
	int				starting;
	int				ret;
@@ -1386,6 +1386,31 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param)

	ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
	if (ret < 0) {
		if ((ret == -EAGAIN) && starting &&
				usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
			dbg_event(dep->number, "CMD_STS", ret);
			/* If bit13 in Command complete event is set, software
			 * must issue ENDTRANDFER command and wait for
			 * Xfernotready event to queue the requests again.
			 */
			if (!dep->resource_index) {
				dep->resource_index =
					 dwc3_gadget_ep_get_transfer_index(dep);
				WARN_ON_ONCE(!dep->resource_index);
			}
			dwc3_stop_active_transfer(dwc, dep->number, true);

			list_for_each_entry_safe_reverse(req1, n,
						&dep->started_list, list) {
				req1->trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
				req1->trb = NULL;
				dwc3_gadget_move_pending_list_front(req1);
				dwc3_ep_inc_deq(dep);
			}

			return ret;
		}

		/*
		 * FIXME we need to iterate over the list of requests
		 * here and stop, unmap, free and del each of the linked
@@ -2834,18 +2859,17 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,

	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
			list_empty(&dep->started_list)) {
		if (list_empty(&dep->pending_list)) {
		if (list_empty(&dep->pending_list))
			/*
			 * If there is no entry in request list then do
			 * not issue END TRANSFER now. Just set PENDING
			 * flag, so that END TRANSFER is issued when an
			 * entry is added into request list.
			 */
			dep->flags = DWC3_EP_PENDING_REQUEST;
		} else {
			dep->flags |= DWC3_EP_PENDING_REQUEST;
		else
			dwc3_stop_active_transfer(dwc, dep->number, true);
			dep->flags = DWC3_EP_ENABLED;
		}
		dep->flags &= ~DWC3_EP_MISSED_ISOC;
		return 1;
	}

+8 −0
Original line number Diff line number Diff line
@@ -89,6 +89,14 @@ static inline void dwc3_gadget_move_started_request(struct dwc3_request *req)
	list_move_tail(&req->list, &dep->started_list);
}

static inline void dwc3_gadget_move_pending_list_front(struct dwc3_request *req)
{
	struct dwc3_ep		*dep = req->dep;

	req->started = false;
	list_move(&req->list, &dep->pending_list);
}

static inline enum dwc3_link_state dwc3_get_link_state(struct dwc3 *dwc)
{
	u32 reg;