]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: gadget: u_audio: Check return codes from usb_ep_enable and config_ep_by_speed.
authorChris Wulff <crwulff@gmail.com>
Sun, 21 Jul 2024 19:23:15 +0000 (15:23 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 31 Jul 2024 08:38:57 +0000 (10:38 +0200)
These functions can fail if descriptors are malformed, or missing,
for the selected USB speed.

Fixes: eb9fecb9e69b ("usb: gadget: f_uac2: split out audio core")
Fixes: 24f779dac8f3 ("usb: gadget: f_uac2/u_audio: add feedback endpoint support")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Wulff <crwulff@gmail.com>
Link: https://lore.kernel.org/r/20240721192314.3532697-2-crwulff@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/function/u_audio.c

index 89af0feb75120864665a7c8004dfd7e66cb010f0..24299576972fe1d758bf1e9f39c63a0c3eb1fe3e 100644 (file)
@@ -592,16 +592,25 @@ int u_audio_start_capture(struct g_audio *audio_dev)
        struct usb_ep *ep, *ep_fback;
        struct uac_rtd_params *prm;
        struct uac_params *params = &audio_dev->params;
-       int req_len, i;
+       int req_len, i, ret;
 
        prm = &uac->c_prm;
        dev_dbg(dev, "start capture with rate %d\n", prm->srate);
        ep = audio_dev->out_ep;
-       config_ep_by_speed(gadget, &audio_dev->func, ep);
+       ret = config_ep_by_speed(gadget, &audio_dev->func, ep);
+       if (ret < 0) {
+               dev_err(dev, "config_ep_by_speed for out_ep failed (%d)\n", ret);
+               return ret;
+       }
+
        req_len = ep->maxpacket;
 
        prm->ep_enabled = true;
-       usb_ep_enable(ep);
+       ret = usb_ep_enable(ep);
+       if (ret < 0) {
+               dev_err(dev, "usb_ep_enable failed for out_ep (%d)\n", ret);
+               return ret;
+       }
 
        for (i = 0; i < params->req_number; i++) {
                if (!prm->reqs[i]) {
@@ -629,9 +638,18 @@ int u_audio_start_capture(struct g_audio *audio_dev)
                return 0;
 
        /* Setup feedback endpoint */
-       config_ep_by_speed(gadget, &audio_dev->func, ep_fback);
+       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
+       }
+
        prm->fb_ep_enabled = true;
-       usb_ep_enable(ep_fback);
+       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
+       }
        req_len = ep_fback->maxpacket;
 
        req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC);
@@ -687,13 +705,17 @@ int u_audio_start_playback(struct g_audio *audio_dev)
        struct uac_params *params = &audio_dev->params;
        unsigned int factor;
        const struct usb_endpoint_descriptor *ep_desc;
-       int req_len, i;
+       int req_len, i, ret;
        unsigned int p_pktsize;
 
        prm = &uac->p_prm;
        dev_dbg(dev, "start playback with rate %d\n", prm->srate);
        ep = audio_dev->in_ep;
-       config_ep_by_speed(gadget, &audio_dev->func, ep);
+       ret = config_ep_by_speed(gadget, &audio_dev->func, ep);
+       if (ret < 0) {
+               dev_err(dev, "config_ep_by_speed for in_ep failed (%d)\n", ret);
+               return ret;
+       }
 
        ep_desc = ep->desc;
        /*
@@ -720,7 +742,11 @@ int u_audio_start_playback(struct g_audio *audio_dev)
        uac->p_residue_mil = 0;
 
        prm->ep_enabled = true;
-       usb_ep_enable(ep);
+       ret = usb_ep_enable(ep);
+       if (ret < 0) {
+               dev_err(dev, "usb_ep_enable failed for in_ep (%d)\n", ret);
+               return ret;
+       }
 
        for (i = 0; i < params->req_number; i++) {
                if (!prm->reqs[i]) {