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

Commit e9e13928 authored by wHemant Kumar's avatar wHemant Kumar Committed by Mayank Rana
Browse files

usb: gadget: Fix bug is queuing req upon function suspend



In case of super speed function suspend without bus suspend,
if function driver queues a request, usb_gadget_func_wakeup()
directly issues function wakeup command to controller and returns
success. As a result request is queued to endpoint before receiving
function resume from host. This causes ep queue to fail when it is
done upon function resume as request is already queued. If function
driver tries to queue any request further this results into request
packet drop as ep queue returns error -EBUSY. Hence do not queue
request in function wake up context, instead wait for function
resume to queue the request.

CRs-Fixed: 848622
Change-Id: I00aea59fb2cbe59190dadb4c838534cc9e4ffcf3
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 8edd6776
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -477,12 +477,14 @@ EXPORT_SYMBOL(usb_func_wakeup);
int usb_func_ep_queue(struct usb_function *func, struct usb_ep *ep,
			       struct usb_request *req, gfp_t gfp_flags)
{
	int ret = -ENOTSUPP;
	int ret;
	struct usb_gadget *gadget;

	if (!func || !func->config || !func->config->cdev ||
			!func->config->cdev->gadget || !ep || !req)
		return -EINVAL;
			!func->config->cdev->gadget || !ep || !req) {
		ret = -EINVAL;
		goto done;
	}

	pr_debug("Function %s queueing new data into ep %u\n",
		func->name ? func->name : "", ep->address);
@@ -497,13 +499,19 @@ int usb_func_ep_queue(struct usb_function *func, struct usb_ep *ep,
			pr_err("Failed to wake function %s from suspend state. ret=%d.\n",
				func->name ? func->name : "", ret);
		}
		goto done;
	}

	if (!func->func_is_suspended)
		ret = 0;
	if (!ret)
		ret = usb_ep_queue(ep, req, gfp_flags);

	if (func->func_is_suspended && !func->func_wakeup_allowed) {
		ret = -ENOTSUPP;
		goto done;
	}

	ret = usb_ep_queue(ep, req, gfp_flags);
done:
	return ret;
}
EXPORT_SYMBOL(usb_func_ep_queue);