Commit 9d1ff5dc authored by Laurent Pinchart's avatar Laurent Pinchart
Browse files

usb: gadget: uvc: Factor out video USB request queueing



USB requests for video data are queued from two different locations in
the driver, with the same code block occurring twice. Factor it out to a
function.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarPaul Elder <paul.elder@ideasonboard.com>
Tested-by: default avatarPaul Elder <paul.elder@ideasonboard.com>
Reviewed-by: default avatarKieran Bingham <kieran.bingham@ideasonboard.com>
parent 89969a84
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -125,6 +125,19 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
 * Request handling
 */

static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req)
{
	int ret;

	ret = usb_ep_queue(video->ep, req, GFP_ATOMIC);
	if (ret < 0) {
		printk(KERN_INFO "Failed to queue request (%d).\n", ret);
		usb_ep_set_halt(video->ep);
	}

	return ret;
}

/*
 * I somehow feel that synchronisation won't be easy to achieve here. We have
 * three events that control USB requests submission:
@@ -189,14 +202,13 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)

	video->encode(req, video, buf);

	if ((ret = usb_ep_queue(ep, req, GFP_ATOMIC)) < 0) {
		printk(KERN_INFO "Failed to queue request (%d).\n", ret);
		usb_ep_set_halt(ep);
	ret = uvcg_video_ep_queue(video, req);
	spin_unlock_irqrestore(&video->queue.irqlock, flags);

	if (ret < 0) {
		uvcg_queue_cancel(queue, 0);
		goto requeue;
	}
	spin_unlock_irqrestore(&video->queue.irqlock, flags);

	return;

@@ -316,15 +328,13 @@ int uvcg_video_pump(struct uvc_video *video)
		video->encode(req, video, buf);

		/* Queue the USB request */
		ret = usb_ep_queue(video->ep, req, GFP_ATOMIC);
		if (ret < 0) {
			printk(KERN_INFO "Failed to queue request (%d)\n", ret);
			usb_ep_set_halt(video->ep);
		ret = uvcg_video_ep_queue(video, req);
		spin_unlock_irqrestore(&queue->irqlock, flags);

		if (ret < 0) {
			uvcg_queue_cancel(queue, 0);
			break;
		}
		spin_unlock_irqrestore(&queue->irqlock, flags);
	}

	spin_lock_irqsave(&video->req_lock, flags);