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

Commit f0b846ce authored by Thinh Nguyen's avatar Thinh Nguyen Committed by Mayank Rana
Browse files

usb: dwc3: gadget: Properly handle failed kick_transfer



If dwc3 fails to issue START_TRANSFER/UPDATE_TRANSFER command, then we
should properly end an active transfer and give back all the started
requests. However if it's for an isoc endpoint, the failure maybe due to
bus-expiry status. In this case, don't give back the requests and wait
for the next retry.

Change-Id: I64ff69a663a9ad7701f877a0cf3bcd87b93c792a
Fixes: 72246da4 ("usb: Introduce DesignWare USB3 DRD Driver")
Signed-off-by: default avatarThinh Nguyen <thinhn@synopsys.com>
Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
Git-commit: 8d99087c2db863c5fa3a4a1f3cb82b3a493705ca
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent d831e159
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -1339,6 +1339,8 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
	}
}

static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep);

static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
{
	struct dwc3_gadget_ep_cmd_params params;
@@ -1380,14 +1382,20 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)

	ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
	if (ret < 0) {
		/*
		 * FIXME we need to iterate over the list of requests
		 * here and stop, unmap, free and del each of the linked
		 * requests instead of what we do now.
		 */
		if (req->trb)
			memset(req->trb, 0, sizeof(struct dwc3_trb));
		dwc3_gadget_del_and_unmap_request(dep, req, ret);
		struct dwc3_request *tmp;

		if (ret == -EAGAIN)
			return ret;

		dwc3_stop_active_transfer(dep, true, true);

		list_for_each_entry_safe(req, tmp, &dep->started_list, list)
			dwc3_gadget_move_cancelled_request(req);

		/* If ep isn't started, then there's no end transfer pending */
		if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
			dwc3_gadget_ep_cleanup_cancelled_requests(dep);

		return ret;
	}