Revert "usb: gadget: f_uvc: change endpoint allocation in uvc_function_bind()"
authorFrank Li <Frank.Li@nxp.com>
Sun, 24 Dec 2023 15:38:16 +0000 (10:38 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Jan 2024 23:35:42 +0000 (15:35 -0800)
commit 895ee5aefb7e24203de5dffae7ce9a02d78fa3d1 upstream.

This reverts commit 3c5b006f3ee800b4bd9ed37b3a8f271b8560126e.

gadget_is_{super|dual}speed() API check UDC controller capitblity. It
should pass down highest speed endpoint descriptor to UDC controller. So
UDC controller driver can reserve enough resource at check_config(),
especially mult and maxburst. So UDC driver (such as cdns3) can know need
at least (mult + 1) * (maxburst + 1) * wMaxPacketSize internal memory for
this uvc functions.

Cc: <stable@vger.kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231224153816.1664687-5-Frank.Li@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/function/f_uvc.c

index faa3981..3d5c03e 100644 (file)
@@ -719,13 +719,29 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
        }
        uvc->enable_interrupt_ep = opts->enable_interrupt_ep;
 
-       ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep);
+       /*
+        * gadget_is_{super|dual}speed() API check UDC controller capitblity. It should pass down
+        * highest speed endpoint descriptor to UDC controller. So UDC controller driver can reserve
+        * enough resource at check_config(), especially mult and maxburst. So UDC driver (such as
+        * cdns3) can know need at least (mult + 1) * (maxburst + 1) * wMaxPacketSize internal
+        * memory for this uvc functions. This is the only straightforward method to resolve the UDC
+        * resource allocation issue in the current gadget framework.
+        */
+       if (gadget_is_superspeed(c->cdev->gadget))
+               ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep,
+                                         &uvc_ss_streaming_comp);
+       else if (gadget_is_dualspeed(cdev->gadget))
+               ep = usb_ep_autoconfig(cdev->gadget, &uvc_hs_streaming_ep);
+       else
+               ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep);
+
        if (!ep) {
                uvcg_info(f, "Unable to allocate streaming EP\n");
                goto error;
        }
        uvc->video.ep = ep;
 
+       uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
        uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
        uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address;