From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Thu, 5 Oct 2023 08:50:57 +0000 (+0200)
Subject: Revert "usb: gadget: uvc: rework pump worker to avoid while loop"
X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=e0fa80bbede825f470869f41b132daff99f33a1c;p=linux.git

Revert "usb: gadget: uvc: rework pump worker to avoid while loop"

This reverts commit bb00788bd62778ef80a97d67a0e3c569ac6be06f.

Based on review comments, it was applied too soon and needs more work.

Reported-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://lore.kernel.org/r/20231005081716.GA13853@pendragon.ideasonboard.com
Cc: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---

diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
index 97d875c27dcf9..c48c904f500ff 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c
@@ -397,7 +397,7 @@ static void uvcg_video_pump(struct work_struct *work)
 	bool buf_done;
 	int ret;
 
-	if (video->ep->enabled && uvc->state == UVC_STATE_STREAMING) {
+	while (video->ep->enabled && uvc->state == UVC_STATE_STREAMING) {
 		/*
 		 * Retrieve the first available USB request, protected by the
 		 * request lock.
@@ -409,11 +409,6 @@ static void uvcg_video_pump(struct work_struct *work)
 		}
 		req = list_first_entry(&video->req_free, struct usb_request,
 					list);
-		if (!req) {
-			spin_unlock_irqrestore(&video->req_lock, flags);
-			return;
-		}
-
 		list_del(&req->list);
 		spin_unlock_irqrestore(&video->req_lock, flags);
 
@@ -442,7 +437,7 @@ static void uvcg_video_pump(struct work_struct *work)
 			 * further.
 			 */
 			spin_unlock_irqrestore(&queue->irqlock, flags);
-			goto out;
+			break;
 		}
 
 		/*
@@ -475,23 +470,20 @@ static void uvcg_video_pump(struct work_struct *work)
 		/* Queue the USB request */
 		ret = uvcg_video_ep_queue(video, req);
 		spin_unlock_irqrestore(&queue->irqlock, flags);
+
 		if (ret < 0) {
 			uvcg_queue_cancel(queue, 0);
-			goto out;
+			break;
 		}
 
 		/* Endpoint now owns the request */
 		req = NULL;
 		video->req_int_count++;
-	} else {
-		return;
 	}
 
-	if (uvc->state == UVC_STATE_STREAMING)
-		queue_work(video->async_wq, &video->pump);
+	if (!req)
+		return;
 
-	return;
-out:
 	spin_lock_irqsave(&video->req_lock, flags);
 	list_add_tail(&req->list, &video->req_free);
 	spin_unlock_irqrestore(&video->req_lock, flags);