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

Commit ba14e961 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull media fixes from Mauro Carvalho Chehab:
 "Some regression fixes:

   - videobuf2 core: avoid the risk of going past buffer on multi-planes
     and fix rw mode

   - fix support for 4K formats at V4L2 core

   - fix a trouble at davinci_fpe, caused by a bad patch

   - usbvision: revert a patch with a partial fixup.  The fixup patch
     was merged already, and this one has some issues"

* tag 'media/v4.6-4' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  [media] vb2-memops: Fix over allocation of frame vectors
  [media] media: vb2: Fix regression on poll() for RW mode
  [media] v4l2-dv-timings.h: fix polarity for 4k formats
  [media] davinci_vpfe: Revert "staging: media: davinci_vpfe: remove,unnecessary ret variable"
  [media] usbvision: revert commit 588afcc1
  [media] videobuf2-v4l2: Verify planes array in buffer dequeueing
  [media] videobuf2-core: Check user space planes array in dqbuf
parents e1f14a54 89a09566
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -1452,13 +1452,6 @@ static int usbvision_probe(struct usb_interface *intf,
	printk(KERN_INFO "%s: %s found\n", __func__,
				usbvision_device_data[model].model_string);

	/*
	 * this is a security check.
	 * an exploit using an incorrect bInterfaceNumber is known
	 */
	if (ifnum >= USB_MAXINTERFACES || !dev->actconfig->interface[ifnum])
		return -ENODEV;

	if (usbvision_device_data[model].interface >= 0)
		interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0];
	else if (ifnum < dev->actconfig->desc.bNumInterfaces)
+15 −5
Original line number Diff line number Diff line
@@ -1645,7 +1645,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
 * Will sleep if required for nonblocking == false.
 */
static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
				int nonblocking)
			     void *pb, int nonblocking)
{
	unsigned long flags;
	int ret;
@@ -1666,9 +1666,9 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
	/*
	 * Only remove the buffer from done_list if v4l2_buffer can handle all
	 * the planes.
	 * Verifying planes is NOT necessary since it already has been checked
	 * before the buffer is queued/prepared. So it can never fail.
	 */
	ret = call_bufop(q, verify_planes_array, *vb, pb);
	if (!ret)
		list_del(&(*vb)->done_entry);
	spin_unlock_irqrestore(&q->done_lock, flags);

@@ -1748,7 +1748,7 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb,
	struct vb2_buffer *vb = NULL;
	int ret;

	ret = __vb2_get_done_vb(q, &vb, nonblocking);
	ret = __vb2_get_done_vb(q, &vb, pb, nonblocking);
	if (ret < 0)
		return ret;

@@ -2297,6 +2297,16 @@ unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file,
	if (!vb2_is_streaming(q) || q->error)
		return POLLERR;

	/*
	 * If this quirk is set and QBUF hasn't been called yet then
	 * return POLLERR as well. This only affects capture queues, output
	 * queues will always initialize waiting_for_buffers to false.
	 * This quirk is set by V4L2 for backwards compatibility reasons.
	 */
	if (q->quirk_poll_must_check_waiting_for_buffers &&
	    q->waiting_for_buffers && (req_events & (POLLIN | POLLRDNORM)))
		return POLLERR;

	/*
	 * For output streams you can call write() as long as there are fewer
	 * buffers queued than there are buffers available.
+1 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ struct frame_vector *vb2_create_framevec(unsigned long start,
	vec = frame_vector_create(nr);
	if (!vec)
		return ERR_PTR(-ENOMEM);
	ret = get_vaddr_frames(start, nr, write, 1, vec);
	ret = get_vaddr_frames(start & PAGE_MASK, nr, write, true, vec);
	if (ret < 0)
		goto out_destroy;
	/* We accept only complete set of PFNs */
+12 −8
Original line number Diff line number Diff line
@@ -74,6 +74,11 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer
	return 0;
}

static int __verify_planes_array_core(struct vb2_buffer *vb, const void *pb)
{
	return __verify_planes_array(vb, pb);
}

/**
 * __verify_length() - Verify that the bytesused value for each plane fits in
 * the plane length and that the data offset doesn't exceed the bytesused value.
@@ -437,6 +442,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
}

static const struct vb2_buf_ops v4l2_buf_ops = {
	.verify_planes_array	= __verify_planes_array_core,
	.fill_user_buffer	= __fill_v4l2_buffer,
	.fill_vb2_buffer	= __fill_vb2_buffer,
	.copy_timestamp		= __copy_timestamp,
@@ -765,6 +771,12 @@ int vb2_queue_init(struct vb2_queue *q)
	q->is_output = V4L2_TYPE_IS_OUTPUT(q->type);
	q->copy_timestamp = (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK)
			== V4L2_BUF_FLAG_TIMESTAMP_COPY;
	/*
	 * For compatibility with vb1: if QBUF hasn't been called yet, then
	 * return POLLERR as well. This only affects capture queues, output
	 * queues will always initialize waiting_for_buffers to false.
	 */
	q->quirk_poll_must_check_waiting_for_buffers = true;

	return vb2_core_queue_init(q);
}
@@ -818,14 +830,6 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
			poll_wait(file, &fh->wait, wait);
	}

	/*
	 * For compatibility with vb1: if QBUF hasn't been called yet, then
	 * return POLLERR as well. This only affects capture queues, output
	 * queues will always initialize waiting_for_buffers to false.
	 */
	if (q->waiting_for_buffers && (req_events & (POLLIN | POLLRDNORM)))
		return POLLERR;

	return res | vb2_core_poll(q, file, wait);
}
EXPORT_SYMBOL_GPL(vb2_poll);
+34 −20
Original line number Diff line number Diff line
@@ -172,9 +172,11 @@ static int vpfe_prepare_pipeline(struct vpfe_video_device *video)
static int vpfe_update_pipe_state(struct vpfe_video_device *video)
{
	struct vpfe_pipeline *pipe = &video->pipe;
	int ret;

	if (vpfe_prepare_pipeline(video))
		return vpfe_prepare_pipeline(video);
	ret = vpfe_prepare_pipeline(video);
	if (ret)
		return ret;

	/*
	 * Find out if there is any input video
@@ -182,9 +184,10 @@ static int vpfe_update_pipe_state(struct vpfe_video_device *video)
	 */
	if (pipe->input_num == 0) {
		pipe->state = VPFE_PIPELINE_STREAM_CONTINUOUS;
		if (vpfe_update_current_ext_subdev(video)) {
		ret = vpfe_update_current_ext_subdev(video);
		if (ret) {
			pr_err("Invalid external subdev\n");
			return vpfe_update_current_ext_subdev(video);
			return ret;
		}
	} else {
		pipe->state = VPFE_PIPELINE_STREAM_SINGLESHOT;
@@ -667,6 +670,7 @@ static int vpfe_enum_fmt(struct file *file, void *priv,
	struct v4l2_subdev *subdev;
	struct v4l2_format format;
	struct media_pad *remote;
	int ret;

	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt\n");

@@ -695,10 +699,11 @@ static int vpfe_enum_fmt(struct file *file, void *priv,
	sd_fmt.pad = remote->index;
	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
	/* get output format of remote subdev */
	if (v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt)) {
	ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt);
	if (ret) {
		v4l2_err(&vpfe_dev->v4l2_dev,
			 "invalid remote subdev for video node\n");
		return v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt);
		return ret;
	}
	/* convert to pix format */
	mbus.code = sd_fmt.format.code;
@@ -725,6 +730,7 @@ static int vpfe_s_fmt(struct file *file, void *priv,
	struct vpfe_video_device *video = video_drvdata(file);
	struct vpfe_device *vpfe_dev = video->vpfe_dev;
	struct v4l2_format format;
	int ret;

	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt\n");
	/* If streaming is started, return error */
@@ -733,8 +739,9 @@ static int vpfe_s_fmt(struct file *file, void *priv,
		return -EBUSY;
	}
	/* get adjacent subdev's output pad format */
	if (__vpfe_video_get_format(video, &format))
		return __vpfe_video_get_format(video, &format);
	ret = __vpfe_video_get_format(video, &format);
	if (ret)
		return ret;
	*fmt = format;
	video->fmt = *fmt;
	return 0;
@@ -757,11 +764,13 @@ static int vpfe_try_fmt(struct file *file, void *priv,
	struct vpfe_video_device *video = video_drvdata(file);
	struct vpfe_device *vpfe_dev = video->vpfe_dev;
	struct v4l2_format format;
	int ret;

	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt\n");
	/* get adjacent subdev's output pad format */
	if (__vpfe_video_get_format(video, &format))
		return __vpfe_video_get_format(video, &format);
	ret = __vpfe_video_get_format(video, &format);
	if (ret)
		return ret;

	*fmt = format;
	return 0;
@@ -838,8 +847,9 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index)

	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n");

	if (mutex_lock_interruptible(&video->lock))
		return mutex_lock_interruptible(&video->lock);
	ret = mutex_lock_interruptible(&video->lock);
	if (ret)
		return ret;
	/*
	 * If streaming is started return device busy
	 * error
@@ -940,8 +950,9 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id)
	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n");

	/* Call decoder driver function to set the standard */
	if (mutex_lock_interruptible(&video->lock))
		return mutex_lock_interruptible(&video->lock);
	ret = mutex_lock_interruptible(&video->lock);
	if (ret)
		return ret;
	sdinfo = video->current_ext_subdev;
	/* If streaming is started, return device busy error */
	if (video->started) {
@@ -1327,8 +1338,9 @@ static int vpfe_reqbufs(struct file *file, void *priv,
		return -EINVAL;
	}

	if (mutex_lock_interruptible(&video->lock))
		return mutex_lock_interruptible(&video->lock);
	ret = mutex_lock_interruptible(&video->lock);
	if (ret)
		return ret;

	if (video->io_usrs != 0) {
		v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n");
@@ -1354,10 +1366,11 @@ static int vpfe_reqbufs(struct file *file, void *priv,
	q->buf_struct_size = sizeof(struct vpfe_cap_buffer);
	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;

	if (vb2_queue_init(q)) {
	ret = vb2_queue_init(q);
	if (ret) {
		v4l2_err(&vpfe_dev->v4l2_dev, "vb2_queue_init() failed\n");
		vb2_dma_contig_cleanup_ctx(vpfe_dev->pdev);
		return vb2_queue_init(q);
		return ret;
	}

	fh->io_allowed = 1;
@@ -1533,8 +1546,9 @@ static int vpfe_streamoff(struct file *file, void *priv,
		return -EINVAL;
	}

	if (mutex_lock_interruptible(&video->lock))
		return mutex_lock_interruptible(&video->lock);
	ret = mutex_lock_interruptible(&video->lock);
	if (ret)
		return ret;

	vpfe_stop_capture(video);
	ret = vb2_streamoff(&video->buffer_queue, buf_type);
Loading