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

Commit 144a0eec authored by Mayank Rana's avatar Mayank Rana
Browse files

f_gsi: Fix error handling with usb_func_ep_queue() return value



usb_func_ep_queue() returns -EAGAIN if usb is function suspended and
successfully remote wakeup is performed. This change fixes error
handling with USB GSI function driver to make sure caller knows that
request is actually queued or not from this context. This makes sure
that USB request is queued once USB host has resumed USB bus.

CRs-Fixed: 1033093
Change-Id: I3f3cb1b6b42530bfa93e0d4badacfe651b6bbb4c
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent f75272fe
Loading
Loading
Loading
Loading
+6 −21
Original line number Diff line number Diff line
@@ -1482,9 +1482,9 @@ static ssize_t gsi_ctrl_dev_write(struct file *fp, const char __user *buf,
	list_add_tail(&cpkt->list, &c_port->cpkt_resp_q);
	spin_unlock_irqrestore(&c_port->lock, flags);

	ret = gsi_ctrl_send_notification(gsi);

	if (!gsi_ctrl_send_notification(gsi))
		c_port->modem_to_host++;

	log_event_dbg("Exit %zu", count);

	return ret ? ret : count;
@@ -1849,33 +1849,18 @@ static int queue_notification_request(struct f_gsi *gsi)
{
	int ret;
	unsigned long flags;
	struct usb_cdc_notification *event;
	struct gsi_ctrl_pkt *cpkt;

	ret = usb_func_ep_queue(&gsi->function, gsi->c_port.notify,
			   gsi->c_port.notify_req, GFP_ATOMIC);
	if (ret == -ENOTSUPP || (ret < 0 && ret != -EAGAIN)) {
	if (ret < 0) {
		spin_lock_irqsave(&gsi->c_port.lock, flags);
		gsi->c_port.notify_req_queued = false;
		/* check if device disconnected while we dropped lock */
		if (atomic_read(&gsi->connected) &&
			!list_empty(&gsi->c_port.cpkt_resp_q)) {
			cpkt = list_first_entry(&gsi->c_port.cpkt_resp_q,
					struct gsi_ctrl_pkt, list);
			list_del(&cpkt->list);
			log_event_err("%s: drop ctrl pkt of len %d error %d",
						__func__, cpkt->len, ret);
			gsi_ctrl_pkt_free(cpkt);
		}
		gsi->c_port.cpkt_drop_cnt++;
		spin_unlock_irqrestore(&gsi->c_port.lock, flags);
	} else {
		ret = 0;
		event = gsi->c_port.notify_req->buf;
		log_event_dbg("%s: Queued Notify type %02x", __func__,
				event->bNotificationType);
	}

	log_event_dbg("%s: ret:%d req_queued:%d",
		__func__, ret, gsi->c_port.notify_req_queued);

	return ret;
}