Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 876cb14d authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] em28xx: 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 4d345708
Loading
Loading
Loading
Loading
+35 −17
Original line number Original line Diff line number Diff line
@@ -2146,9 +2146,12 @@ static int em28xx_v4l2_open(struct file *filp)
			dev->users);
			dev->users);




	if (mutex_lock_interruptible(&dev->lock))
		return -ERESTARTSYS;
	fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
	fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
	if (!fh) {
	if (!fh) {
		em28xx_errdev("em28xx-video.c: Out of memory?!\n");
		em28xx_errdev("em28xx-video.c: Out of memory?!\n");
		mutex_unlock(&dev->lock);
		return -ENOMEM;
		return -ENOMEM;
	}
	}
	fh->dev = dev;
	fh->dev = dev;
@@ -2189,6 +2192,7 @@ static int em28xx_v4l2_open(struct file *filp)
				    V4L2_BUF_TYPE_VBI_CAPTURE,
				    V4L2_BUF_TYPE_VBI_CAPTURE,
				    V4L2_FIELD_SEQ_TB,
				    V4L2_FIELD_SEQ_TB,
				    sizeof(struct em28xx_buffer), fh, &dev->lock);
				    sizeof(struct em28xx_buffer), fh, &dev->lock);
	mutex_unlock(&dev->lock);


	return errCode;
	return errCode;
}
}
@@ -2243,6 +2247,7 @@ static int em28xx_v4l2_close(struct file *filp)


	em28xx_videodbg("users=%d\n", dev->users);
	em28xx_videodbg("users=%d\n", dev->users);


	mutex_lock(&dev->lock);
	if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
	if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
		videobuf_stop(&fh->vb_vidq);
		videobuf_stop(&fh->vb_vidq);
		res_free(fh, EM28XX_RESOURCE_VIDEO);
		res_free(fh, EM28XX_RESOURCE_VIDEO);
@@ -2261,6 +2266,7 @@ static int em28xx_v4l2_close(struct file *filp)
			kfree(dev->alt_max_pkt_size);
			kfree(dev->alt_max_pkt_size);
			kfree(dev);
			kfree(dev);
			kfree(fh);
			kfree(fh);
			mutex_unlock(&dev->lock);
			return 0;
			return 0;
		}
		}


@@ -2285,6 +2291,7 @@ static int em28xx_v4l2_close(struct file *filp)
	videobuf_mmap_free(&fh->vb_vbiq);
	videobuf_mmap_free(&fh->vb_vbiq);
	kfree(fh);
	kfree(fh);
	dev->users--;
	dev->users--;
	mutex_unlock(&dev->lock);
	return 0;
	return 0;
}
}


@@ -2304,35 +2311,35 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
	if (rc < 0)
	if (rc < 0)
		return rc;
		return rc;


	if (mutex_lock_interruptible(&dev->lock))
		return -ERESTARTSYS;
	/* FIXME: read() is not prepared to allow changing the video
	/* FIXME: read() is not prepared to allow changing the video
	   resolution while streaming. Seems a bug at em28xx_set_fmt
	   resolution while streaming. Seems a bug at em28xx_set_fmt
	 */
	 */


	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
		if (res_locked(dev, EM28XX_RESOURCE_VIDEO))
		if (res_locked(dev, EM28XX_RESOURCE_VIDEO))
			return -EBUSY;
			rc = -EBUSY;

		else
		return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
			rc = videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
					filp->f_flags & O_NONBLOCK);
					filp->f_flags & O_NONBLOCK);
	}
	} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {


	if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
		if (!res_get(fh, EM28XX_RESOURCE_VBI))
		if (!res_get(fh, EM28XX_RESOURCE_VBI))
			return -EBUSY;
			rc = -EBUSY;

		else
		return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
			rc = videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
					filp->f_flags & O_NONBLOCK);
					filp->f_flags & O_NONBLOCK);
	}
	}
	mutex_unlock(&dev->lock);


	return 0;
	return rc;
}
}


/*
/*
 * em28xx_v4l2_poll()
 * em28xx_poll()
 * will allocate buffers when called for the first time
 * will allocate buffers when called for the first time
 */
 */
static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
static unsigned int em28xx_poll(struct file *filp, poll_table *wait)
{
{
	struct em28xx_fh *fh = filp->private_data;
	struct em28xx_fh *fh = filp->private_data;
	struct em28xx *dev = fh->dev;
	struct em28xx *dev = fh->dev;
@@ -2355,6 +2362,18 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
	}
	}
}
}


static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
{
	struct em28xx_fh *fh = filp->private_data;
	struct em28xx *dev = fh->dev;
	unsigned int res;

	mutex_lock(&dev->lock);
	res = em28xx_poll(filp, wait);
	mutex_unlock(&dev->lock);
	return res;
}

/*
/*
 * em28xx_v4l2_mmap()
 * em28xx_v4l2_mmap()
 */
 */
@@ -2368,10 +2387,13 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
	if (rc < 0)
	if (rc < 0)
		return rc;
		return rc;


	if (mutex_lock_interruptible(&dev->lock))
		return -ERESTARTSYS;
	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
		rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
		rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
	else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
	else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
		rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
		rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
	mutex_unlock(&dev->lock);


	em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
	em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
		(unsigned long)vma->vm_start,
		(unsigned long)vma->vm_start,
@@ -2495,10 +2517,6 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
	vfd->release	= video_device_release;
	vfd->release	= video_device_release;
	vfd->debug	= video_debug;
	vfd->debug	= video_debug;
	vfd->lock	= &dev->lock;
	vfd->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, &vfd->flags);


	snprintf(vfd->name, sizeof(vfd->name), "%s %s",
	snprintf(vfd->name, sizeof(vfd->name), "%s %s",
		 dev->name, type_name);
		 dev->name, type_name);