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

Commit ed7f3f15 authored by Manu Gautam's avatar Manu Gautam
Browse files

usb: gadget: f_mbim: Ignore -EBUSY error for notify_req



notify_request can be queued from mbim_response_complete
or from mbim_write. Since, spin_lock needs to be dropped
before queuing usb_request, there is a possibility of race
between these two contexts. If mbim_response_complete preempts
mbim_write just before queuing the notify_request then
ep_queue from mbim_write subsequently fails with -EBUSY error.
mbim_write treats this as fatal error and drops modem response.
This results in driver returning STALL later when notify_req
gets completed. Fix this by not treating -EBUSY from ep_queue
as fatal error and don't free the response.

Change-Id: Ieb39569b31bc63c67aa27a971156552209e917b5
Signed-off-by: default avatarManu Gautam <mgautam@codeaurora.org>
parent e701f80b
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
/* Copyright (c) 2012-2016,2017 The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1910,9 +1910,12 @@ mbim_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos)

	ret = usb_func_ep_queue(&dev->function, dev->not_port.notify,
			   req, GFP_ATOMIC);
	if (ret == -ENOTSUPP || (ret < 0 && ret != -EAGAIN)) {
	if (ret == -ENOTSUPP || (ret < 0 && ret != -EAGAIN && ret != -EBUSY)) {
		spin_lock_irqsave(&dev->lock, flags);
		/* check if device disconnected while we dropped lock */
		/*
		 * cpkt already freed if device disconnected while we
		 * dropped lock. Nothing to be done in that case.
		 */
		if (atomic_read(&dev->online)) {
			list_del(&cpkt->list);
			atomic_dec(&dev->not_port.notify_count);