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

Commit baf29f99 authored by Udipto Goswami's avatar Udipto Goswami
Browse files

usb: dwc3: gadget: Fix double add due to cleanup_cancelled_request



Commit 6a247993 ("usb: dwc3: gadget: Properly handle failed
kick_transfer") introduces a piece of code where if gadget_ep_cmd
fails in kick_transfer, it calls stop_active_transfer for that ep
& move the request from started_list to cancelled_list. Finally
it checks for DWC3_EP_END_TRANSFER_PENDING flag, if not set then
moves ahead and calls dwc3_gadget_cleanup_cancelled_request as part
of which gadget giveback for the request is called. This will
ultimately mean ep_queue failure as ep_queue returns the status of
kick_transfer.

Now from the function driver perspective, when ep_queue fails
it tries to add the request back to the pool from which the request
was queued.

But,since we did a cleanup_cancelled_request the completion handler
of the function driver is also called which tries to add the same
request back to the pool, resulting in a double add scenario.

Fix this by returning 0 from ep_queue rather then returning the
status of kick_transfer. For a function driver it would mean
ep_queue success and will not add the request back to read pool
and since we already are giving back the request as part of
cleanup_cancelled_requests, the request will be added back to
the pool and avoid the double add scenario.

Change-Id: I82bc21c34a795820998483c4a88e1891495a6906
Signed-off-by: default avatarUdipto Goswami <ugoswami@codeaurora.org>
parent 0389e99d
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1572,6 +1572,7 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
			return ret;
		}

		dbg_event(0xFF, "GADGET_EP_CMD Failure", ret);
		dwc3_stop_active_transfer(dwc, dep->number, true);

		list_for_each_entry_safe(req, n, &dep->started_list, list)
@@ -1678,7 +1679,9 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
		}
	}

	return __dwc3_gadget_kick_transfer(dep);
	__dwc3_gadget_kick_transfer(dep);

	return 0;
}

static int dwc3_gadget_wakeup(struct usb_gadget *g)