Commit bd52b813 authored by Michael Grzeschik's avatar Michael Grzeschik Committed by Felipe Balbi

usb: gadget: uvc: fix possible lockup in uvc gadget

If the pending buffers in the queue could not be pushed to the udc
endpoint we have to cancel the uvc_queue. Otherwise the gadget will get
stuck on this error. This patch calls uvc_queue_cancel if usb_ep_queue
failed.
Acked-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMichael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 7166c32d
...@@ -195,6 +195,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) ...@@ -195,6 +195,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
printk(KERN_INFO "Failed to queue request (%d).\n", ret); printk(KERN_INFO "Failed to queue request (%d).\n", ret);
usb_ep_set_halt(ep); usb_ep_set_halt(ep);
spin_unlock_irqrestore(&video->queue.irqlock, flags); spin_unlock_irqrestore(&video->queue.irqlock, flags);
uvc_queue_cancel(queue, 0);
goto requeue; goto requeue;
} }
spin_unlock_irqrestore(&video->queue.irqlock, flags); spin_unlock_irqrestore(&video->queue.irqlock, flags);
...@@ -281,6 +282,7 @@ uvc_video_alloc_requests(struct uvc_video *video) ...@@ -281,6 +282,7 @@ uvc_video_alloc_requests(struct uvc_video *video)
static int static int
uvc_video_pump(struct uvc_video *video) uvc_video_pump(struct uvc_video *video)
{ {
struct uvc_video_queue *queue = &video->queue;
struct usb_request *req; struct usb_request *req;
struct uvc_buffer *buf; struct uvc_buffer *buf;
unsigned long flags; unsigned long flags;
...@@ -322,6 +324,7 @@ uvc_video_pump(struct uvc_video *video) ...@@ -322,6 +324,7 @@ uvc_video_pump(struct uvc_video *video)
printk(KERN_INFO "Failed to queue request (%d)\n", ret); printk(KERN_INFO "Failed to queue request (%d)\n", ret);
usb_ep_set_halt(video->ep); usb_ep_set_halt(video->ep);
spin_unlock_irqrestore(&video->queue.irqlock, flags); spin_unlock_irqrestore(&video->queue.irqlock, flags);
uvc_queue_cancel(queue, 0);
break; break;
} }
spin_unlock_irqrestore(&video->queue.irqlock, flags); spin_unlock_irqrestore(&video->queue.irqlock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment