Re: [PATCH] media: uvcvideo: Read support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 3/4/19 1:35 PM, Hugues Fruchet wrote:
> Add support of read() call from userspace by implementing
> uvc_v4l2_read() with vb2_read() helper.
> 
> Signed-off-by: Hugues Fruchet <hugues.fruchet@xxxxxx>
> ---
>  drivers/media/usb/uvc/uvc_queue.c | 15 ++++++++++++++-
>  drivers/media/usb/uvc/uvc_v4l2.c  | 11 ++++++++---
>  drivers/media/usb/uvc/uvcvideo.h  |  2 ++
>  3 files changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> index 682698e..0c8a0a8 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -227,7 +227,7 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
>  	int ret;
>  
>  	queue->queue.type = type;
> -	queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
> +	queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
>  	queue->queue.drv_priv = queue;
>  	queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
>  	queue->queue.mem_ops = &vb2_vmalloc_memops;
> @@ -361,6 +361,19 @@ int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type)
>  	return ret;
>  }
>  
> +ssize_t uvc_queue_read(struct uvc_video_queue *queue, struct file *file,
> +		       char __user *buf, size_t count, loff_t *ppos)
> +{
> +	ssize_t ret;
> +
> +	mutex_lock(&queue->mutex);
> +	ret = vb2_read(&queue->queue, buf, count, ppos,
> +		       file->f_flags & O_NONBLOCK);
> +	mutex_unlock(&queue->mutex);
> +
> +	return ret;
> +}
> +
>  int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
>  {
>  	return vb2_mmap(&queue->queue, vma);
> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
> index 84be596..3866832 100644
> --- a/drivers/media/usb/uvc/uvc_v4l2.c
> +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> @@ -594,7 +594,8 @@ static int uvc_ioctl_querycap(struct file *file, void *fh,
>  	strscpy(cap->driver, "uvcvideo", sizeof(cap->driver));
>  	strscpy(cap->card, vdev->name, sizeof(cap->card));
>  	usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
> -	cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
> +	cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING |
> +			    V4L2_CAP_READWRITE
>  			  | chain->caps;

device_caps for VIDEO_CAPTURE should also get V4L2_CAP_READWRITE. See uvc_register_video_device().

Regards,

	Hans

>  
>  	return 0;
> @@ -1434,8 +1435,12 @@ static long uvc_v4l2_compat_ioctl32(struct file *file,
>  static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
>  		    size_t count, loff_t *ppos)
>  {
> -	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
> -	return -EINVAL;
> +	struct uvc_fh *handle = file->private_data;
> +	struct uvc_streaming *stream = handle->stream;
> +
> +	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read\n");
> +
> +	return uvc_queue_read(&stream->queue, file, data, count, ppos);
>  }
>  
>  static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index c7c1baa..5d0515c 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -766,6 +766,8 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
>  					 struct uvc_buffer *buf);
>  struct uvc_buffer *uvc_queue_get_current_buffer(struct uvc_video_queue *queue);
>  void uvc_queue_buffer_release(struct uvc_buffer *buf);
> +ssize_t uvc_queue_read(struct uvc_video_queue *queue, struct file *file,
> +		       char __user *buf, size_t count, loff_t *ppos);
>  int uvc_queue_mmap(struct uvc_video_queue *queue,
>  		   struct vm_area_struct *vma);
>  __poll_t uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
> 




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux