uvc : fix close uvc video device error
authorddl <ddl@rock-chips.com>
Fri, 28 Sep 2012 08:55:08 +0000 (16:55 +0800)
committerddl <ddl@rock-chips.com>
Fri, 28 Sep 2012 08:55:26 +0000 (16:55 +0800)
drivers/media/video/uvc/uvc_queue.c
drivers/media/video/uvc/uvc_video.c
drivers/media/video/uvc/uvcvideo.h

index 21280925452759decad512f22d0e260e1f160f18..1b9f12696a9ba79874bc653e3c877cb8870ac973 100644 (file)
@@ -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:
index fb32eb11ee536462ef8279b87750ca29e92edf18..c7a054fa655467803f4b42890f84072a19d30be2 100755 (executable)
@@ -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);
 }
 
index 4dc3c2de8eb549ab031c436ac65ad7163d2dc223..4abb2f2f0a2be9a8f9d3d5388b906a529e6fd1e9 100755 (executable)
@@ -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 {