On Tue Jun 16 14:42:16 2026 +0200, Hans Verkuil wrote:
> If start_streaming fails, then all queued buffers must be
> returned to vb2 in state QUEUED.
> 
> Otherwise it will trigger a WARN_ON.
> 
> Signed-off-by: Hans Verkuil <[email protected]>
> Tested-by: Hans Verkuil <[email protected]>
> Signed-off-by: Mauro Carvalho Chehab <[email protected]>

Patch committed.

Thanks,
Mauro Carvalho Chehab

 drivers/media/usb/em28xx/em28xx-video.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

---

diff --git a/drivers/media/usb/em28xx/em28xx-video.c 
b/drivers/media/usb/em28xx/em28xx-video.c
index e4554d015944..c418add65bb5 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -1213,6 +1213,9 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, 
unsigned int count)
 {
        struct em28xx *dev = vb2_get_drv_priv(vq);
        struct em28xx_v4l2 *v4l2 = dev->v4l2;
+       struct em28xx_dmaqueue *dmaq = vq->type == V4L2_BUF_TYPE_VBI_CAPTURE ?
+               &dev->vbiq : &dev->vidq;
+       unsigned long flags = 0;
        struct v4l2_frequency f;
        struct v4l2_fh *owner;
        int rc = 0;
@@ -1227,7 +1230,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, 
unsigned int count)
         */
        rc = res_get(dev, vq->type);
        if (rc)
-               return rc;
+               goto exit;
 
        if (v4l2->streaming_users == 0) {
                /* First active streaming user, so allocate all the URBs */
@@ -1250,7 +1253,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, 
unsigned int count)
                                          em28xx_urb_data_copy);
                if (rc < 0) {
                        res_free(dev, vq->type);
-                       return rc;
+                       goto exit;
                }
 
                /*
@@ -1275,7 +1278,18 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, 
unsigned int count)
        }
 
        v4l2->streaming_users++;
+       return 0;
 
+exit:
+       spin_lock_irqsave(&dev->slock, flags);
+       while (!list_empty(&dmaq->active)) {
+               struct em28xx_buffer *buf;
+
+               buf = list_entry(dmaq->active.next, struct em28xx_buffer, list);
+               list_del(&buf->list);
+               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+       }
+       spin_unlock_irqrestore(&dev->slock, flags);
        return rc;
 }
 
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to