From f1b6a735328b507810d2436891ee977fb8cd62d7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 14 Aug 2014 06:43:36 -0300 Subject: [PATCH] [media] cx23885: Add busy checks before changing formats 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 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-417.c | 10 +++++----- drivers/media/pci/cx23885/cx23885-video.c | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index f1ef9017e2a7..6973055f0814 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c @@ -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, diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index defdf7486eda..f0ea904d4669 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -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) -- 2.20.1