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

Commit daaa9359 authored by Ajay Agarwal's avatar Ajay Agarwal
Browse files

usb: gadget: f_ipc: Use timeout when waiting for request completion



If a certain host does not receive IPC hello messages with the
connected device, then the USB transport is blocked to be added
to the xprt_list maintained by IPC router core, which ultimately
blocks all other transports to be added leading to subsystem
level failures.
Fix this by using timeout version of the wait_for_completion API
in the IPC function driver so as to bail out if the host fails to
receive hello packets.

Change-Id: I4ad789776fffbc28eb099e00631d0bb834f215b7
Signed-off-by: default avatarAjay Agarwal <ajaya@codeaurora.org>
parent 4b967be4
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#define IPC_BRIDGE_MAX_READ_SZ	(8 * 1024)
#define IPC_BRIDGE_MAX_WRITE_SZ	(8 * 1024)

#define IPC_WRITE_WAIT_TIMEOUT	10000

/* for configfs support */
struct ipc_opts {
	struct usb_function_instance func_inst;
@@ -239,6 +241,7 @@ static int ipc_write(struct platform_device *pdev, char *buf,
	unsigned long flags;
	struct usb_request *req;
	struct usb_ep *in;
	int ret;

	if (!ipc_dev)
		return -ENODEV;
@@ -274,12 +277,23 @@ static int ipc_write(struct platform_device *pdev, char *buf,
		goto retry_write;
	}

	if (unlikely(wait_for_completion_interruptible(&ipc_dev->write_done))) {
		usb_ep_dequeue(in, req);
		return -EINTR;
	ret = wait_for_completion_interruptible_timeout(&ipc_dev->write_done,
				msecs_to_jiffies(IPC_WRITE_WAIT_TIMEOUT));
	if (ret < 0) {
		pr_err("%s: Interruption triggered\n", __func__);
		ret = -EINTR;
		goto fail;
	} else if (ret == 0) {
		pr_err("%s: Request timed out\n", __func__);
		ret = -ETIMEDOUT;
		goto fail;
	}

	return !req->status ? req->actual : req->status;

fail:
	usb_ep_dequeue(in, req);
	return ret;
}

static void ipc_out_complete(struct usb_ep *ep, struct usb_request *req)