From: ddl Date: Fri, 28 Sep 2012 08:55:08 +0000 (+0800) Subject: uvc : fix close uvc video device error X-Git-Tag: firefly_0821_release~8511 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b0da7311bf44aa687d9bcdcbadc3fe45695a7722;p=firefly-linux-kernel-4.4.55.git uvc : fix close uvc video device error --- diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 212809254527..1b9f12696a9b 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c @@ -349,6 +349,11 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue, v4l2_buf->memory); return -EINVAL; } + /* ddl@rock-chips.com */ + if (!(queue->flags & UVC_QUEUE_STREAMING)) { + printk("uvcvideo: Not streaming\n"); + return -EINVAL; + } mutex_lock(&queue->mutex); /* ddl@rock-chips.com : This design copied from video-buf */ @@ -371,8 +376,10 @@ checks: ((!list_empty(&queue->mainqueue)) || (!(queue->flags & UVC_QUEUE_STREAMING)))); mutex_lock(&queue->mutex); - if (ret || (!(queue->flags & UVC_QUEUE_STREAMING))) - goto done; + if (ret || (!(queue->flags & UVC_QUEUE_STREAMING))) { + printk("uvcvideo: Stream off\n"); + goto done; + } goto checks; } @@ -592,6 +599,7 @@ int uvc_queue_enable(struct uvc_video_queue *queue, int enable) queue->flags |= UVC_QUEUE_STREAMING; queue->buf_used = 0; } else { + queue->flags &= ~UVC_QUEUE_STREAMING; uvc_queue_cancel(queue, 0); INIT_LIST_HEAD(&queue->mainqueue); @@ -599,8 +607,6 @@ int uvc_queue_enable(struct uvc_video_queue *queue, int enable) queue->buffer[i].error = 0; queue->buffer[i].state = UVC_BUF_STATE_IDLE; } - - queue->flags &= ~UVC_QUEUE_STREAMING; } done: diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index fb32eb11ee53..c7a054fa6554 100755 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -898,7 +898,7 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) { struct urb *urb; unsigned int i; - + for (i = 0; i < UVC_URBS; ++i) { urb = stream->urb[i]; if (urb == NULL) @@ -1312,11 +1312,14 @@ int uvc_video_init(struct uvc_streaming *stream) int uvc_video_enable(struct uvc_streaming *stream, int enable) { int ret; - + if (!enable) { - uvc_uninit_video(stream, 1); - usb_set_interface(stream->dev->udev, stream->intfnum, 0); - uvc_queue_enable(&stream->queue, 0); + if (stream->flags & UVC_QUEUE_STREAMING) { /* ddl@rock-chips.com */ + uvc_queue_enable(&stream->queue, 0); + uvc_uninit_video(stream, 1); + usb_set_interface(stream->dev->udev, stream->intfnum, 0); + stream->flags &= ~UVC_QUEUE_STREAMING; + } return 0; } @@ -1330,7 +1333,7 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) uvc_queue_enable(&stream->queue, 0); return ret; } - + stream->flags |= UVC_QUEUE_STREAMING; return uvc_init_video(stream, GFP_KERNEL); } diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 4dc3c2de8eb5..4abb2f2f0a2b 100755 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -501,6 +501,7 @@ struct uvc_streaming { __u8 last_fid; struct tasklet_struct *tasklet[UVC_URBS]; /* ddl@rock-chips.com */ + unsigned int flags; }; enum uvc_device_state {