[media] cx23885: Add busy checks before changing formats
authorHans Verkuil <hans.verkuil@cisco.com>
Thu, 14 Aug 2014 09:43:36 +0000 (06:43 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Mon, 8 Sep 2014 13:01:01 +0000 (10:01 -0300)
Before you can change the standard or the capture format, make sure the
various vb2_queues aren't in use since you cannot change the buffer size from
underneath a a busy vb2_queue.

Also make sure that the return code of cx23885_set_tvnorm is returned
correctly, otherwise the -EBUSY will be lost.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/pci/cx23885/cx23885-417.c
drivers/media/pci/cx23885/cx23885-video.c

index f1ef901..6973055 100644 (file)
@@ -1248,18 +1248,18 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
 {
        struct cx23885_dev *dev = video_drvdata(file);
        unsigned int i;
+       int ret;
 
        for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
                if (id & cx23885_tvnorms[i].id)
                        break;
        if (i == ARRAY_SIZE(cx23885_tvnorms))
                return -EINVAL;
-       dev->encodernorm = cx23885_tvnorms[i];
-
-       /* Have the drier core notify the subdevices */
-       cx23885_set_tvnorm(dev, id);
 
-       return 0;
+       ret = cx23885_set_tvnorm(dev, id);
+       if (!ret)
+               dev->encodernorm = cx23885_tvnorms[i];
+       return ret;
 }
 
 static int vidioc_enum_input(struct file *file, void *priv,
index defdf74..f0ea904 100644 (file)
@@ -119,6 +119,12 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
                (unsigned int)norm,
                v4l2_norm_to_name(norm));
 
+       if (dev->tvnorm != norm) {
+               if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
+                   vb2_is_busy(&dev->vb2_mpegq))
+                       return -EBUSY;
+       }
+
        dev->tvnorm = norm;
 
        call_all(dev, video, s_std, norm);
@@ -591,6 +597,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 
        if (0 != err)
                return err;
+
+       if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
+           vb2_is_busy(&dev->vb2_mpegq))
+               return -EBUSY;
+
        dev->fmt        = format_by_fourcc(f->fmt.pix.pixelformat);
        dev->width      = f->fmt.pix.width;
        dev->height     = f->fmt.pix.height;
@@ -654,9 +665,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)
        struct cx23885_dev *dev = video_drvdata(file);
        dprintk(1, "%s()\n", __func__);
 
-       cx23885_set_tvnorm(dev, tvnorms);
-
-       return 0;
+       return cx23885_set_tvnorm(dev, tvnorms);
 }
 
 int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)