diff options
| author | Michael Grzeschik <m.grzeschik@pengutronix.de> | 2014-08-08 11:38:57 -0400 |
|---|---|---|
| committer | Felipe Balbi <balbi@ti.com> | 2014-08-19 15:34:18 -0400 |
| commit | bd52b813a999e44d2e35c2390d02fa4d0f61d08a (patch) | |
| tree | a8c29ec3a6f203a1186c5c4e1fce6cd3b4627da6 | |
| parent | 7166c32d9a6b8655ce13b0844482526734ac41b3 (diff) | |
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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
| -rw-r--r-- | drivers/usb/gadget/function/uvc_video.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 71e896d4c5ae..a5eb9a3fbb7a 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c | |||
| @@ -195,6 +195,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 195 | printk(KERN_INFO "Failed to queue request (%d).\n", ret); | 195 | printk(KERN_INFO "Failed to queue request (%d).\n", ret); |
| 196 | usb_ep_set_halt(ep); | 196 | usb_ep_set_halt(ep); |
| 197 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 197 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
| 198 | uvc_queue_cancel(queue, 0); | ||
| 198 | goto requeue; | 199 | goto requeue; |
| 199 | } | 200 | } |
| 200 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 201 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
| @@ -281,6 +282,7 @@ error: | |||
| 281 | static int | 282 | static int |
| 282 | uvc_video_pump(struct uvc_video *video) | 283 | uvc_video_pump(struct uvc_video *video) |
| 283 | { | 284 | { |
| 285 | struct uvc_video_queue *queue = &video->queue; | ||
| 284 | struct usb_request *req; | 286 | struct usb_request *req; |
| 285 | struct uvc_buffer *buf; | 287 | struct uvc_buffer *buf; |
| 286 | unsigned long flags; | 288 | unsigned long flags; |
| @@ -322,6 +324,7 @@ uvc_video_pump(struct uvc_video *video) | |||
| 322 | printk(KERN_INFO "Failed to queue request (%d)\n", ret); | 324 | printk(KERN_INFO "Failed to queue request (%d)\n", ret); |
| 323 | usb_ep_set_halt(video->ep); | 325 | usb_ep_set_halt(video->ep); |
| 324 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 326 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
| 327 | uvc_queue_cancel(queue, 0); | ||
| 325 | break; | 328 | break; |
| 326 | } | 329 | } |
| 327 | spin_unlock_irqrestore(&video->queue.irqlock, flags); | 330 | spin_unlock_irqrestore(&video->queue.irqlock, flags); |
