usb: gadget: u_audio: clean up capture endpoint on feedback failure

u_audio_start_capture() enables the capture OUT endpoint, queues capture
requests and marks the stream active before setting up the optional
feedback endpoint.

If feedback endpoint configuration or enablement fails, the function
returns an error while the capture endpoint remains enabled and its
requests may remain queued. The current code even leaves TODO comments
at these return paths.

Unwind the already started capture endpoint on these failures. Also set
fb_ep_enabled only after usb_ep_enable() succeeds, so the software state
matches the endpoint state.

Signed-off-by: Xu Rao <raoxu@uniontech.com>
Link: https://patch.msgid.link/183621D513E0DE8B+20260611091229.4017443-1-raoxu@uniontech.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Xu Rao 2026-06-11 17:12:28 +08:00 committed by Greg Kroah-Hartman
parent 6c562228d0
commit 7a0d4f60da

View File

@ -641,15 +641,15 @@ int u_audio_start_capture(struct g_audio *audio_dev)
ret = config_ep_by_speed(gadget, &audio_dev->func, ep_fback);
if (ret < 0) {
dev_err(dev, "config_ep_by_speed in_ep_fback failed (%d)\n", ret);
return ret; // TODO: Clean up out_ep
goto err_out_ep;
}
prm->fb_ep_enabled = true;
ret = usb_ep_enable(ep_fback);
if (ret < 0) {
dev_err(dev, "usb_ep_enable failed for in_ep_fback (%d)\n", ret);
return ret; // TODO: Clean up out_ep
goto err_out_ep;
}
prm->fb_ep_enabled = true;
req_len = ep_fback->maxpacket;
req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC);
@ -680,6 +680,12 @@ int u_audio_start_capture(struct g_audio *audio_dev)
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
return 0;
err_out_ep:
set_active(prm, false);
free_ep(prm, ep);
return ret;
}
EXPORT_SYMBOL_GPL(u_audio_start_capture);