From 80131fe06e0bdd7b429594493c1317ddede89a61 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 Jun 2012 06:37:38 -0300 Subject: [media] v4l2-dev.c: add debug sysfs entry Since this could theoretically change the debug value while in the middle of v4l2-ioctl.c, we make a copy of vfd->debug to ensure consistent debug behavior. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/media/video/v4l2-dev.c') diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 83dbb2ddff1..c2122e53f05 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -46,6 +46,29 @@ static ssize_t show_index(struct device *cd, return sprintf(buf, "%i\n", vdev->index); } +static ssize_t show_debug(struct device *cd, + struct device_attribute *attr, char *buf) +{ + struct video_device *vdev = to_video_device(cd); + + return sprintf(buf, "%i\n", vdev->debug); +} + +static ssize_t set_debug(struct device *cd, struct device_attribute *attr, + const char *buf, size_t len) +{ + struct video_device *vdev = to_video_device(cd); + int res = 0; + u16 value; + + res = kstrtou16(buf, 0, &value); + if (res) + return res; + + vdev->debug = value; + return len; +} + static ssize_t show_name(struct device *cd, struct device_attribute *attr, char *buf) { @@ -56,6 +79,7 @@ static ssize_t show_name(struct device *cd, static struct device_attribute video_device_attrs[] = { __ATTR(name, S_IRUGO, show_name, NULL), + __ATTR(debug, 0644, show_debug, set_debug), __ATTR(index, S_IRUGO, show_index, NULL), __ATTR_NULL }; -- cgit v1.2.3 From 5a5adf6b669cf1a3dd2af419cd68a4c491f384a3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 Jun 2012 07:29:35 -0300 Subject: [media] v4l2-dev/ioctl.c: add vb2_queue support to video_device This prepares struct video_device for easier integration with vb2. It also introduces a new lock that protects the vb2_queue. It is up to the driver to use it or not. And the driver can associate an owner filehandle with the queue to check whether queuing requests are permitted for the calling filehandle. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers/media/video/v4l2-dev.c') diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index c2122e53f05..b82778174ee 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -348,20 +348,14 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) int ret = -ENODEV; if (vdev->fops->unlocked_ioctl) { - bool locked = false; + struct mutex *lock = v4l2_ioctl_get_lock(vdev, cmd); - if (vdev->lock) { - /* always lock unless the cmd is marked as "don't use lock" */ - locked = !v4l2_is_known_ioctl(cmd) || - !test_bit(_IOC_NR(cmd), vdev->disable_locking); - - if (locked && mutex_lock_interruptible(vdev->lock)) - return -ERESTARTSYS; - } + if (lock && mutex_lock_interruptible(lock)) + return -ERESTARTSYS; if (video_is_registered(vdev)) ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); - if (locked) - mutex_unlock(vdev->lock); + if (lock) + mutex_unlock(lock); } else if (vdev->fops->ioctl) { /* This code path is a replacement for the BKL. It is a major * hack but it will have to do for those drivers that are not -- cgit v1.2.3 From cc4b7e7f5755d304ffbfc1d44c11ba8e981347b0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 9 Jun 2012 12:13:29 -0300 Subject: [media] v4l2-dev.c: also add debug support for the fops Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'drivers/media/video/v4l2-dev.c') diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index b82778174ee..d13c47fc720 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -305,6 +305,9 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, ret = vdev->fops->read(filp, buf, sz, off); if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) mutex_unlock(vdev->lock); + if (vdev->debug) + printk(KERN_DEBUG "%s: read: %zd (%d)\n", + video_device_node_name(vdev), sz, ret); return ret; } @@ -323,6 +326,9 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, ret = vdev->fops->write(filp, buf, sz, off); if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) mutex_unlock(vdev->lock); + if (vdev->debug) + printk(KERN_DEBUG "%s: write: %zd (%d)\n", + video_device_node_name(vdev), sz, ret); return ret; } @@ -339,6 +345,9 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) ret = vdev->fops->poll(filp, poll); if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) mutex_unlock(vdev->lock); + if (vdev->debug) + printk(KERN_DEBUG "%s: poll: %08x\n", + video_device_node_name(vdev), ret); return ret; } @@ -403,12 +412,17 @@ static unsigned long v4l2_get_unmapped_area(struct file *filp, unsigned long flags) { struct video_device *vdev = video_devdata(filp); + int ret; if (!vdev->fops->get_unmapped_area) return -ENOSYS; if (!video_is_registered(vdev)) return -ENODEV; - return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags); + ret = vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags); + if (vdev->debug) + printk(KERN_DEBUG "%s: get_unmapped_area (%d)\n", + video_device_node_name(vdev), ret); + return ret; } #endif @@ -426,6 +440,9 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) ret = vdev->fops->mmap(filp, vm); if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) mutex_unlock(vdev->lock); + if (vdev->debug) + printk(KERN_DEBUG "%s: mmap (%d)\n", + video_device_node_name(vdev), ret); return ret; } @@ -464,6 +481,9 @@ err: /* decrease the refcount in case of an error */ if (ret) video_put(vdev); + if (vdev->debug) + printk(KERN_DEBUG "%s: open (%d)\n", + video_device_node_name(vdev), ret); return ret; } @@ -483,6 +503,9 @@ static int v4l2_release(struct inode *inode, struct file *filp) /* decrease the refcount unconditionally since the release() return value is ignored. */ video_put(vdev); + if (vdev->debug) + printk(KERN_DEBUG "%s: release\n", + video_device_node_name(vdev)); return ret; } -- cgit v1.2.3 From 4c1110aabe6283112a2d7c08b16769d0a32be83b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 11 Jul 2012 09:12:45 -0300 Subject: [media] v4l2-dev: forgot to add VIDIOC_DV_TIMINGS_CAP The VIDIOC_DV_TIMINGS_CAP ioctl check wasn't added to determine_valid_ioctls(). This caused this ioctl to always return -ENOTTY. Signed-off-by: Hans Verkuil Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/video/v4l2-dev.c') diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index d13c47fc720..af70f931727 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -722,6 +722,7 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); + SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap); /* yes, really vidioc_subscribe_event */ SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); -- cgit v1.2.3 From 837c7e4256d5285700fe0d500eeb15801b55bb0e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 19 Jul 2012 08:49:25 -0300 Subject: [media] v4l2-dev: G_PARM was incorrectly enabled for all video nodes G_PARM should only be enabled if: - vidioc_g_parm is present - or: it is a video node and vidioc_g_std or tvnorms are set. Without this additional check v4l2-compliance would complain about being able to use g_parm when it didn't expect it. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media/video/v4l2-dev.c') diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index af70f931727..1b2f1c52e6c 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -697,7 +697,8 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); - if (ops->vidioc_g_parm || vdev->vfl_type == VFL_TYPE_GRABBER) + if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER && + (ops->vidioc_g_std || vdev->tvnorms))) set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); -- cgit v1.2.3 From 82b655bfc32b793344ef0ddd46df8af8b98b55c7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Jul 2012 06:37:08 -0300 Subject: [media] v4l2: add core support for the new VIDIOC_ENUM_FREQ_BANDS ioctl This adds the usual core support code for this new ioctl. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media/video/v4l2-dev.c') diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 1b2f1c52e6c..625248585c8 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -730,6 +730,8 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_UNSUBSCRIBE_EVENT, vidioc_unsubscribe_event); SET_VALID_IOCTL(ops, VIDIOC_CREATE_BUFS, vidioc_create_bufs); SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf); + if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || ops->vidioc_g_modulator) + set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls); bitmap_andnot(vdev->valid_ioctls, valid_ioctls, vdev->valid_ioctls, BASE_VIDIOC_PRIVATE); } -- cgit v1.2.3 From 8f695d3f07bf9fd2914d18d1d2f89e3574b809ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= Date: Thu, 26 Jul 2012 07:59:04 -0300 Subject: [media] v4l2-dev.c: Move video_put() after debug printk It is possible that video_put() releases video_device struct, provoking a panic when debug printk wants to get video_device node name. Signed-off-by: Ezequiel Garcia Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/media/video/v4l2-dev.c') diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 625248585c8..07aeafca9ea 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -478,12 +478,12 @@ static int v4l2_open(struct inode *inode, struct file *filp) } err: - /* decrease the refcount in case of an error */ - if (ret) - video_put(vdev); if (vdev->debug) printk(KERN_DEBUG "%s: open (%d)\n", video_device_node_name(vdev), ret); + /* decrease the refcount in case of an error */ + if (ret) + video_put(vdev); return ret; } @@ -500,12 +500,12 @@ static int v4l2_release(struct inode *inode, struct file *filp) if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) mutex_unlock(vdev->lock); } - /* decrease the refcount unconditionally since the release() - return value is ignored. */ - video_put(vdev); if (vdev->debug) printk(KERN_DEBUG "%s: release\n", video_device_node_name(vdev)); + /* decrease the refcount unconditionally since the release() + return value is ignored. */ + video_put(vdev); return ret; } -- cgit v1.2.3