From 4d345708ca2688a06ca22e758d3eecc0352f5461 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 23 Jun 2012 08:03:50 -0300 Subject: [PATCH] [media] usbvision: remove V4L2_FL_LOCK_ALL_FOPS Add proper locking to the file operations, allowing for the removal of the V4L2_FL_LOCK_ALL_FOPS flag. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/video/usbvision/usbvision-video.c | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 9bd8f084f348..8a4317979a43 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -349,6 +349,8 @@ static int usbvision_v4l2_open(struct file *file) PDEBUG(DBG_IO, "open"); + if (mutex_lock_interruptible(&usbvision->v4l2_lock)) + return -ERESTARTSYS; usbvision_reset_power_off_timer(usbvision); if (usbvision->user) @@ -402,6 +404,7 @@ static int usbvision_v4l2_open(struct file *file) /* prepare queues */ usbvision_empty_framequeues(usbvision); + mutex_unlock(&usbvision->v4l2_lock); PDEBUG(DBG_IO, "success"); return err_code; @@ -421,6 +424,7 @@ static int usbvision_v4l2_close(struct file *file) PDEBUG(DBG_IO, "close"); + mutex_lock(&usbvision->v4l2_lock); usbvision_audio_off(usbvision); usbvision_restart_isoc(usbvision); usbvision_stop_isoc(usbvision); @@ -443,6 +447,7 @@ static int usbvision_v4l2_close(struct file *file) printk(KERN_INFO "%s: Final disconnect\n", __func__); usbvision_release(usbvision); } + mutex_unlock(&usbvision->v4l2_lock); PDEBUG(DBG_IO, "success"); return 0; @@ -956,7 +961,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return 0; } -static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, +static ssize_t usbvision_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct usb_usbvision *usbvision = video_drvdata(file); @@ -1060,7 +1065,20 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, return count; } -static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) +static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct usb_usbvision *usbvision = video_drvdata(file); + int res; + + if (mutex_lock_interruptible(&usbvision->v4l2_lock)) + return -ERESTARTSYS; + res = usbvision_read(file, buf, count, ppos); + mutex_unlock(&usbvision->v4l2_lock); + return res; +} + +static int usbvision_mmap(struct file *file, struct vm_area_struct *vma) { unsigned long size = vma->vm_end - vma->vm_start, start = vma->vm_start; @@ -1107,6 +1125,17 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) return 0; } +static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct usb_usbvision *usbvision = video_drvdata(file); + int res; + + if (mutex_lock_interruptible(&usbvision->v4l2_lock)) + return -ERESTARTSYS; + res = usbvision_mmap(file, vma); + mutex_unlock(&usbvision->v4l2_lock); + return res; +} /* * Here comes the stuff for radio on usbvision based devices @@ -1119,6 +1148,8 @@ static int usbvision_radio_open(struct file *file) PDEBUG(DBG_IO, "%s:", __func__); + if (mutex_lock_interruptible(&usbvision->v4l2_lock)) + return -ERESTARTSYS; if (usbvision->user) { dev_err(&usbvision->rdev->dev, "%s: Someone tried to open an already opened USBVision Radio!\n", @@ -1156,6 +1187,7 @@ static int usbvision_radio_open(struct file *file) } } out: + mutex_unlock(&usbvision->v4l2_lock); return err_code; } @@ -1167,6 +1199,7 @@ static int usbvision_radio_close(struct file *file) PDEBUG(DBG_IO, ""); + mutex_lock(&usbvision->v4l2_lock); /* Set packet size to 0 */ usbvision->iface_alt = 0; err_code = usb_set_interface(usbvision->dev, usbvision->iface, @@ -1186,6 +1219,7 @@ static int usbvision_radio_close(struct file *file) usbvision_release(usbvision); } + mutex_unlock(&usbvision->v4l2_lock); PDEBUG(DBG_IO, "success"); return err_code; } @@ -1296,10 +1330,6 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, if (NULL == vdev) return NULL; *vdev = *vdev_template; - /* Locking in file operations other than ioctl should be done - by the driver, not the V4L2 core. - This driver needs auditing so that this flag can be removed. */ - set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags); vdev->lock = &usbvision->v4l2_lock; vdev->v4l2_dev = &usbvision->v4l2_dev; snprintf(vdev->name, sizeof(vdev->name), "%s", name); -- 2.30.2