The overhead of preparing sg data is high for transfers with limited
payload. When transferring isoc over high-speed usb the maximum payload
is rather small which is a good argument no to use sg. This patch is
changing the uvc_video_encode_isoc_sg encode function only to be used
for super speed gadgets.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Cc: stable <stable@kernel.org>
Link: https://lore.kernel.org/r/20221017221141.3134818-1-m.grzeschik@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
                return -ENODEV;
 
        buf->state = UVC_BUF_STATE_QUEUED;
-       if (queue->use_sg) {
-               buf->sgt = vb2_dma_sg_plane_desc(vb, 0);
-               buf->sg = buf->sgt->sgl;
-       } else {
-               buf->mem = vb2_plane_vaddr(vb, 0);
-       }
+       buf->sgt = vb2_dma_sg_plane_desc(vb, 0);
+       buf->sg = buf->sgt->sgl;
+       buf->mem = vb2_plane_vaddr(vb, 0);
        buf->length = vb2_plane_size(vb, 0);
        if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
                buf->bytesused = 0;
 
  */
 int uvcg_video_enable(struct uvc_video *video, int enable)
 {
+       struct uvc_device *uvc = video->uvc;
+       struct usb_composite_dev *cdev = uvc->func.config->cdev;
+       struct usb_gadget *gadget = cdev->gadget;
        unsigned int i;
        int ret;
 
        if (video->max_payload_size) {
                video->encode = uvc_video_encode_bulk;
                video->payload_size = 0;
-       } else
-               video->encode = video->queue.use_sg ?
+       } else {
+               video->encode = (video->queue.use_sg &&
+                                !(gadget->speed <= USB_SPEED_HIGH)) ?
                        uvc_video_encode_isoc_sg : uvc_video_encode_isoc;
+       }
 
        video->req_int_count = 0;