From e31a0ba7df6ce21ac4ed58c4182ec12ca8fd78fb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 2 Jan 2015 12:18:23 -0300 Subject: [media] media: Fix DVB devnode representation at media controller The previous provision for DVB media controller support were to define an ID (likely meaning the adapter number) for the DVB devnodes. This is just plain wrong. Just like V4L, DVB devices (and any other device node)) are uniquely identified via a (major, minor) tuple. This is enough to uniquely identify a devnode, no matter what API it implements. So, before we go too far, let's mark the old v4l, fb, dvb and alsa "devnode" info as deprecated, and just call it as "dev". We can latter add fields specific to each API if needed. As we don't want to break compilation on already existing apps, let's just keep the old definitions as-is, adding a note that those are deprecated at media-entity.h. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/v4l2-core/v4l2-dev.c') diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 86bb93fd7db8..d89d5cb465d9 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -943,8 +943,8 @@ int __video_register_device(struct video_device *vdev, int type, int nr, vdev->vfl_type != VFL_TYPE_SUBDEV) { vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; vdev->entity.name = vdev->name; - vdev->entity.info.v4l.major = VIDEO_MAJOR; - vdev->entity.info.v4l.minor = vdev->minor; + vdev->entity.info.dev.major = VIDEO_MAJOR; + vdev->entity.info.dev.minor = vdev->minor; ret = media_device_register_entity(vdev->v4l2_dev->mdev, &vdev->entity); if (ret < 0) -- cgit From 5cf6f7f327c95f09be859889be39e78950516556 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 17 Feb 2015 05:44:09 -0300 Subject: [media] v4l2-core: remove the old .ioctl BKL replacement To keep V4L2 drivers that did not yet convert to unlocked_ioctl happy, the v4l2 core had a .ioctl file operation that took a V4L2 lock. The last drivers are now converted to unlocked_ioctl, so all this old code can now be removed. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 28 ---------------------------- drivers/media/v4l2-core/v4l2-device.c | 1 - include/media/v4l2-dev.h | 1 - include/media/v4l2-device.h | 2 -- 4 files changed, 32 deletions(-) (limited to 'drivers/media/v4l2-core/v4l2-dev.c') diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index d89d5cb465d9..9f4538ce09c2 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -357,34 +357,6 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); 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 - * yet converted to use unlocked_ioctl. - * - * All drivers implement struct v4l2_device, so we use the - * lock defined there to serialize the ioctls. - * - * However, if the driver sleeps, then it blocks all ioctls - * since the lock is still held. This is very common for - * VIDIOC_DQBUF since that normally waits for a frame to arrive. - * As a result any other ioctl calls will proceed very, very - * slowly since each call will have to wait for the VIDIOC_QBUF - * to finish. Things that should take 0.01s may now take 10-20 - * seconds. - * - * The workaround is to *not* take the lock for VIDIOC_DQBUF. - * This actually works OK for videobuf-based drivers, since - * videobuf will take its own internal lock. - */ - struct mutex *m = &vdev->v4l2_dev->ioctl_lock; - - if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m)) - return -ERESTARTSYS; - if (video_is_registered(vdev)) - ret = vdev->fops->ioctl(filp, cmd, arg); - if (cmd != VIDIOC_DQBUF) - mutex_unlock(m); } else ret = -ENOTTY; diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 204cc67c84e8..5b0a30b9252b 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -37,7 +37,6 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) INIT_LIST_HEAD(&v4l2_dev->subdevs); spin_lock_init(&v4l2_dev->lock); - mutex_init(&v4l2_dev->ioctl_lock); v4l2_prio_init(&v4l2_dev->prio); kref_init(&v4l2_dev->ref); get_device(dev); diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 3e4fddfc840c..acbcd2f5fe7f 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -65,7 +65,6 @@ struct v4l2_file_operations { ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); unsigned int (*poll) (struct file *, struct poll_table_struct *); - long (*ioctl) (struct file *, unsigned int, unsigned long); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); #ifdef CONFIG_COMPAT long (*compat_ioctl32) (struct file *, unsigned int, unsigned long); diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index ffb69da3ce9e..9c581578783f 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h @@ -58,8 +58,6 @@ struct v4l2_device { struct v4l2_ctrl_handler *ctrl_handler; /* Device's priority state */ struct v4l2_prio_state prio; - /* BKL replacement mutex. Temporary solution only. */ - struct mutex ioctl_lock; /* Keep track of the references to this struct. */ struct kref ref; /* Release function that is called when the ref count goes to 0. */ -- cgit From 2438e78a48643d41defd4b90da19d17b9c3e65f3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 3 Feb 2015 10:46:56 -0300 Subject: [media] v4l2-core: drop g/s_priority ops The handling of VIDIOC_G/S_PRIORITY is now entirely done by the V4L2 core, so we can drop the g/s_priority ioctl ops. We do have to make sure though that when S_PRIORITY is called we check that the driver used struct v4l2_fh. This check can be removed once all drivers are converted to that structure. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 7 +++---- drivers/media/v4l2-core/v4l2-ioctl.c | 6 ++---- include/media/v4l2-ioctl.h | 6 ------ 3 files changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers/media/v4l2-core/v4l2-dev.c') diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 9f4538ce09c2..e2b8b3ed6ef3 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -532,10 +532,9 @@ static void determine_valid_ioctls(struct video_device *vdev) /* vfl_type and vfl_dir independent ioctls */ SET_VALID_IOCTL(ops, VIDIOC_QUERYCAP, vidioc_querycap); - if (ops->vidioc_g_priority) - set_bit(_IOC_NR(VIDIOC_G_PRIORITY), valid_ioctls); - if (ops->vidioc_s_priority) - set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls); + set_bit(_IOC_NR(VIDIOC_G_PRIORITY), valid_ioctls); + set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls); + /* Note: the control handler can also be passed through the filehandle, and that can't be tested here. If the bit for these control ioctls is set, then the ioctl is valid. But if it is 0, then it can still diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index b08407225db1..09ad8ddfaaf9 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1046,8 +1046,6 @@ static int v4l_g_priority(const struct v4l2_ioctl_ops *ops, struct video_device *vfd; u32 *p = arg; - if (ops->vidioc_g_priority) - return ops->vidioc_g_priority(file, fh, arg); vfd = video_devdata(file); *p = v4l2_prio_max(vfd->prio); return 0; @@ -1060,9 +1058,9 @@ static int v4l_s_priority(const struct v4l2_ioctl_ops *ops, struct v4l2_fh *vfh; u32 *p = arg; - if (ops->vidioc_s_priority) - return ops->vidioc_s_priority(file, fh, *p); vfd = video_devdata(file); + if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) + return -ENOTTY; vfh = file->private_data; return v4l2_prio_change(vfd->prio, &vfh->prio, *p); } diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 8537983b9b22..8fbbd76d78e8 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -23,12 +23,6 @@ struct v4l2_ioctl_ops { /* VIDIOC_QUERYCAP handler */ int (*vidioc_querycap)(struct file *file, void *fh, struct v4l2_capability *cap); - /* Priority handling */ - int (*vidioc_g_priority) (struct file *file, void *fh, - enum v4l2_priority *p); - int (*vidioc_s_priority) (struct file *file, void *fh, - enum v4l2_priority p); - /* VIDIOC_ENUM_FMT handlers */ int (*vidioc_enum_fmt_vid_cap) (struct file *file, void *fh, struct v4l2_fmtdesc *f); -- cgit From 2c9fc463d60b9d09111fde5903e1f3e8e891a674 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 13 Mar 2015 13:25:53 -0300 Subject: [media] v4l2-dev: disable selection ioctls for non-video devices The selection/cropping ioctls are only valid for video nodes, not for vbi. Found by v4l2-compliance when run on a VBI device node. Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/media/v4l2-core/v4l2-dev.c') diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index e2b8b3ed6ef3..71a1b93b0790 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -611,6 +611,14 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes); SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals); + if (ops->vidioc_g_crop || ops->vidioc_g_selection) + set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls); + if (ops->vidioc_s_crop || ops->vidioc_s_selection) + set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls); + SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection); + SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); + if (ops->vidioc_cropcap || ops->vidioc_g_selection) + set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls); } else if (is_vbi) { /* vbi specific ioctls */ if ((is_rx && (ops->vidioc_g_fmt_vbi_cap || @@ -679,14 +687,6 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout); SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout); } - if (ops->vidioc_g_crop || ops->vidioc_g_selection) - set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls); - if (ops->vidioc_s_crop || ops->vidioc_s_selection) - set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls); - SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection); - SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); - if (ops->vidioc_cropcap || ops->vidioc_g_selection) - set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls); if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER && ops->vidioc_g_std)) set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); -- cgit