[media] pwc: fix WARN_ON
authorHans Verkuil <hverkuil@xs4all.nl>
Mon, 4 Aug 2014 10:29:59 +0000 (07:29 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Thu, 29 Jan 2015 20:27:03 +0000 (18:27 -0200)
If start_streaming fails, then the buffers must be given back to vb2 with state
QUEUED, not ERROR. Otherwise a WARN_ON will be generated.

In the disconnect it is pointless to call pwc_cleanup_queued_bufs() as stop_streaming()
will be called anyway.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Tested-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/usb/pwc/pwc-if.c

index 15b754da4a2c22f37f3cc763c2a1535b534778bf..702267e208ba4ecc6245ad0b09a13534456fbe3f 100644 (file)
@@ -508,7 +508,8 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev)
 }
 
 /* Must be called with vb_queue_lock hold */
-static void pwc_cleanup_queued_bufs(struct pwc_device *pdev)
+static void pwc_cleanup_queued_bufs(struct pwc_device *pdev,
+                                   enum vb2_buffer_state state)
 {
        unsigned long flags = 0;
 
@@ -519,7 +520,7 @@ static void pwc_cleanup_queued_bufs(struct pwc_device *pdev)
                buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf,
                                 list);
                list_del(&buf->list);
-               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+               vb2_buffer_done(&buf->vb, state);
        }
        spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
 }
@@ -674,7 +675,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
                pwc_set_leds(pdev, 0, 0);
                pwc_camera_power(pdev, 0);
                /* And cleanup any queued bufs!! */
-               pwc_cleanup_queued_bufs(pdev);
+               pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED);
        }
        mutex_unlock(&pdev->v4l2_lock);
 
@@ -692,7 +693,9 @@ static void stop_streaming(struct vb2_queue *vq)
                pwc_isoc_cleanup(pdev);
        }
 
-       pwc_cleanup_queued_bufs(pdev);
+       pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_ERROR);
+       if (pdev->fill_buf)
+               vb2_buffer_done(&pdev->fill_buf->vb, VB2_BUF_STATE_ERROR);
        mutex_unlock(&pdev->v4l2_lock);
 }
 
@@ -1125,7 +1128,6 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
        if (pdev->vb_queue.streaming)
                pwc_isoc_cleanup(pdev);
        pdev->udev = NULL;
-       pwc_cleanup_queued_bufs(pdev);
 
        v4l2_device_disconnect(&pdev->v4l2_dev);
        video_unregister_device(&pdev->vdev);