Commit 0e1f0edf authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[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: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 87cb0278
...@@ -258,7 +258,6 @@ struct s2255_dev { ...@@ -258,7 +258,6 @@ struct s2255_dev {
atomic_t num_channels; atomic_t num_channels;
int frames; int frames;
struct mutex lock; /* channels[].vdev.lock */ struct mutex lock; /* channels[].vdev.lock */
struct mutex open_lock;
struct usb_device *udev; struct usb_device *udev;
struct usb_interface *interface; struct usb_interface *interface;
u8 read_endpoint; u8 read_endpoint;
...@@ -1684,7 +1683,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv, ...@@ -1684,7 +1683,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
return 0; return 0;
} }
static int s2255_open(struct file *file) static int __s2255_open(struct file *file)
{ {
struct video_device *vdev = video_devdata(file); struct video_device *vdev = video_devdata(file);
struct s2255_channel *channel = video_drvdata(file); struct s2255_channel *channel = video_drvdata(file);
...@@ -1694,16 +1693,9 @@ static int s2255_open(struct file *file) ...@@ -1694,16 +1693,9 @@ static int s2255_open(struct file *file)
int state; int state;
dprintk(1, "s2255: open called (dev=%s)\n", dprintk(1, "s2255: open called (dev=%s)\n",
video_device_node_name(vdev)); 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); state = atomic_read(&dev->fw_data->fw_state);
switch (state) { switch (state) {
case S2255_FW_DISCONNECTING: case S2255_FW_DISCONNECTING:
mutex_unlock(&dev->open_lock);
return -ENODEV; return -ENODEV;
case S2255_FW_FAILED: case S2255_FW_FAILED:
s2255_dev_err(&dev->udev->dev, s2255_dev_err(&dev->udev->dev,
...@@ -1742,11 +1734,9 @@ static int s2255_open(struct file *file) ...@@ -1742,11 +1734,9 @@ static int s2255_open(struct file *file)
break; break;
case S2255_FW_FAILED: case S2255_FW_FAILED:
printk(KERN_INFO "2255 firmware load failed.\n"); printk(KERN_INFO "2255 firmware load failed.\n");
mutex_unlock(&dev->open_lock);
return -ENODEV; return -ENODEV;
case S2255_FW_DISCONNECTING: case S2255_FW_DISCONNECTING:
printk(KERN_INFO "%s: disconnecting\n", __func__); printk(KERN_INFO "%s: disconnecting\n", __func__);
mutex_unlock(&dev->open_lock);
return -ENODEV; return -ENODEV;
case S2255_FW_LOADED_DSPWAIT: case S2255_FW_LOADED_DSPWAIT:
case S2255_FW_NOTLOADED: case S2255_FW_NOTLOADED:
...@@ -1760,14 +1750,11 @@ static int s2255_open(struct file *file) ...@@ -1760,14 +1750,11 @@ static int s2255_open(struct file *file)
*/ */
atomic_set(&dev->fw_data->fw_state, atomic_set(&dev->fw_data->fw_state,
S2255_FW_FAILED); S2255_FW_FAILED);
mutex_unlock(&dev->open_lock);
return -EAGAIN; return -EAGAIN;
default: default:
printk(KERN_INFO "%s: unknown state\n", __func__); printk(KERN_INFO "%s: unknown state\n", __func__);
mutex_unlock(&dev->open_lock);
return -EFAULT; return -EFAULT;
} }
mutex_unlock(&dev->open_lock);
/* allocate + initialize per filehandle data */ /* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL); fh = kzalloc(sizeof(*fh), GFP_KERNEL);
if (NULL == fh) if (NULL == fh)
...@@ -1798,16 +1785,30 @@ static int s2255_open(struct file *file) ...@@ -1798,16 +1785,30 @@ static int s2255_open(struct file *file)
return 0; 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, static unsigned int s2255_poll(struct file *file,
struct poll_table_struct *wait) struct poll_table_struct *wait)
{ {
struct s2255_fh *fh = file->private_data; struct s2255_fh *fh = file->private_data;
struct s2255_dev *dev = fh->dev;
int rc; int rc;
dprintk(100, "%s\n", __func__); dprintk(100, "%s\n", __func__);
if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
return POLLERR; return POLLERR;
mutex_lock(&dev->lock);
rc = videobuf_poll_stream(file, &fh->vb_vidq, wait); rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
mutex_unlock(&dev->lock);
return rc; return rc;
} }
...@@ -1827,7 +1828,6 @@ static void s2255_destroy(struct s2255_dev *dev) ...@@ -1827,7 +1828,6 @@ static void s2255_destroy(struct s2255_dev *dev)
kfree(dev->fw_data); kfree(dev->fw_data);
/* reset the DSP so firmware can be reloaded next time */ /* reset the DSP so firmware can be reloaded next time */
s2255_reset_dsppower(dev); s2255_reset_dsppower(dev);
mutex_destroy(&dev->open_lock);
mutex_destroy(&dev->lock); mutex_destroy(&dev->lock);
usb_put_dev(dev->udev); usb_put_dev(dev->udev);
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
...@@ -1843,6 +1843,7 @@ static int s2255_release(struct file *file) ...@@ -1843,6 +1843,7 @@ static int s2255_release(struct file *file)
struct s2255_channel *channel = fh->channel; struct s2255_channel *channel = fh->channel;
if (!dev) if (!dev)
return -ENODEV; return -ENODEV;
mutex_lock(&dev->lock);
/* turn off stream */ /* turn off stream */
if (res_check(fh)) { if (res_check(fh)) {
if (channel->b_acquire) if (channel->b_acquire)
...@@ -1851,6 +1852,7 @@ static int s2255_release(struct file *file) ...@@ -1851,6 +1852,7 @@ static int s2255_release(struct file *file)
res_free(fh); res_free(fh);
} }
videobuf_mmap_free(&fh->vb_vidq); videobuf_mmap_free(&fh->vb_vidq);
mutex_unlock(&dev->lock);
dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev)); dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
kfree(fh); kfree(fh);
return 0; return 0;
...@@ -1859,12 +1861,16 @@ static int s2255_release(struct file *file) ...@@ -1859,12 +1861,16 @@ static int s2255_release(struct file *file)
static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma) static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
{ {
struct s2255_fh *fh = file->private_data; struct s2255_fh *fh = file->private_data;
struct s2255_dev *dev = fh->dev;
int ret; int ret;
if (!fh) if (!fh)
return -ENODEV; return -ENODEV;
dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma); 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); 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__, dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
(unsigned long)vma->vm_start, (unsigned long)vma->vm_start,
(unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret); (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
...@@ -1944,10 +1950,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev) ...@@ -1944,10 +1950,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
/* register 4 video devices */ /* register 4 video devices */
channel->vdev = template; channel->vdev = template;
channel->vdev.lock = &dev->lock; 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; channel->vdev.v4l2_dev = &dev->v4l2_dev;
video_set_drvdata(&channel->vdev, channel); video_set_drvdata(&channel->vdev, channel);
if (video_nr == -1) if (video_nr == -1)
...@@ -2535,7 +2537,6 @@ static int s2255_probe(struct usb_interface *interface, ...@@ -2535,7 +2537,6 @@ static int s2255_probe(struct usb_interface *interface,
if (!dev->fw_data) if (!dev->fw_data)
goto errorFWDATA1; goto errorFWDATA1;
mutex_init(&dev->lock); mutex_init(&dev->lock);
mutex_init(&dev->open_lock);
/* grab usb_device and save it */ /* grab usb_device and save it */
dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->udev = usb_get_dev(interface_to_usbdev(interface));
if (dev->udev == NULL) { if (dev->udev == NULL) {
...@@ -2637,7 +2638,6 @@ static int s2255_probe(struct usb_interface *interface, ...@@ -2637,7 +2638,6 @@ static int s2255_probe(struct usb_interface *interface,
usb_put_dev(dev->udev); usb_put_dev(dev->udev);
errorUDEV: errorUDEV:
kfree(dev->fw_data); kfree(dev->fw_data);
mutex_destroy(&dev->open_lock);
mutex_destroy(&dev->lock); mutex_destroy(&dev->lock);
errorFWDATA1: errorFWDATA1:
kfree(dev); kfree(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment