From: Hans Verkuil Date: Sun, 24 Jun 2012 09:10:32 +0000 (-0300) Subject: [media] s2255drv: remove V4L2_FL_LOCK_ALL_FOPS X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=0e1f0edfdd25a3462662cdf65796577147c67e53;p=openwrt%2Fstaging%2Fblogic.git [media] s2255drv: 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 --- diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 95007dda0c93..6c7960cc7506 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -258,7 +258,6 @@ struct s2255_dev { atomic_t num_channels; int frames; struct mutex lock; /* channels[].vdev.lock */ - struct mutex open_lock; struct usb_device *udev; struct usb_interface *interface; u8 read_endpoint; @@ -1684,7 +1683,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv, return 0; } -static int s2255_open(struct file *file) +static int __s2255_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct s2255_channel *channel = video_drvdata(file); @@ -1694,16 +1693,9 @@ static int s2255_open(struct file *file) int state; dprintk(1, "s2255: open called (dev=%s)\n", video_device_node_name(vdev)); - /* - * open lock necessary to prevent multiple instances - * of v4l-conf (or other programs) from simultaneously - * reloading firmware. - */ - mutex_lock(&dev->open_lock); state = atomic_read(&dev->fw_data->fw_state); switch (state) { case S2255_FW_DISCONNECTING: - mutex_unlock(&dev->open_lock); return -ENODEV; case S2255_FW_FAILED: s2255_dev_err(&dev->udev->dev, @@ -1742,11 +1734,9 @@ static int s2255_open(struct file *file) break; case S2255_FW_FAILED: printk(KERN_INFO "2255 firmware load failed.\n"); - mutex_unlock(&dev->open_lock); return -ENODEV; case S2255_FW_DISCONNECTING: printk(KERN_INFO "%s: disconnecting\n", __func__); - mutex_unlock(&dev->open_lock); return -ENODEV; case S2255_FW_LOADED_DSPWAIT: case S2255_FW_NOTLOADED: @@ -1760,14 +1750,11 @@ static int s2255_open(struct file *file) */ atomic_set(&dev->fw_data->fw_state, S2255_FW_FAILED); - mutex_unlock(&dev->open_lock); return -EAGAIN; default: printk(KERN_INFO "%s: unknown state\n", __func__); - mutex_unlock(&dev->open_lock); return -EFAULT; } - mutex_unlock(&dev->open_lock); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); if (NULL == fh) @@ -1798,16 +1785,30 @@ static int s2255_open(struct file *file) return 0; } +static int s2255_open(struct file *file) +{ + struct video_device *vdev = video_devdata(file); + int ret; + + if (mutex_lock_interruptible(vdev->lock)) + return -ERESTARTSYS; + ret = __s2255_open(file); + mutex_unlock(vdev->lock); + return ret; +} static unsigned int s2255_poll(struct file *file, struct poll_table_struct *wait) { struct s2255_fh *fh = file->private_data; + struct s2255_dev *dev = fh->dev; int rc; dprintk(100, "%s\n", __func__); if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) return POLLERR; + mutex_lock(&dev->lock); rc = videobuf_poll_stream(file, &fh->vb_vidq, wait); + mutex_unlock(&dev->lock); return rc; } @@ -1827,7 +1828,6 @@ static void s2255_destroy(struct s2255_dev *dev) kfree(dev->fw_data); /* reset the DSP so firmware can be reloaded next time */ s2255_reset_dsppower(dev); - mutex_destroy(&dev->open_lock); mutex_destroy(&dev->lock); usb_put_dev(dev->udev); v4l2_device_unregister(&dev->v4l2_dev); @@ -1843,6 +1843,7 @@ static int s2255_release(struct file *file) struct s2255_channel *channel = fh->channel; if (!dev) return -ENODEV; + mutex_lock(&dev->lock); /* turn off stream */ if (res_check(fh)) { if (channel->b_acquire) @@ -1851,6 +1852,7 @@ static int s2255_release(struct file *file) res_free(fh); } videobuf_mmap_free(&fh->vb_vidq); + mutex_unlock(&dev->lock); dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev)); kfree(fh); return 0; @@ -1859,12 +1861,16 @@ static int s2255_release(struct file *file) static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma) { struct s2255_fh *fh = file->private_data; + struct s2255_dev *dev = fh->dev; int ret; if (!fh) return -ENODEV; dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma); + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); + mutex_unlock(&dev->lock); dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__, (unsigned long)vma->vm_start, (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret); @@ -1944,10 +1950,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev) /* register 4 video devices */ channel->vdev = template; channel->vdev.lock = &dev->lock; - /* 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, &channel->vdev.flags); channel->vdev.v4l2_dev = &dev->v4l2_dev; video_set_drvdata(&channel->vdev, channel); if (video_nr == -1) @@ -2535,7 +2537,6 @@ static int s2255_probe(struct usb_interface *interface, if (!dev->fw_data) goto errorFWDATA1; mutex_init(&dev->lock); - mutex_init(&dev->open_lock); /* grab usb_device and save it */ dev->udev = usb_get_dev(interface_to_usbdev(interface)); if (dev->udev == NULL) { @@ -2637,7 +2638,6 @@ errorEP: usb_put_dev(dev->udev); errorUDEV: kfree(dev->fw_data); - mutex_destroy(&dev->open_lock); mutex_destroy(&dev->lock); errorFWDATA1: kfree(dev);