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.fruc...@st.com>
> ---
>  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);

This is now used for both video capture and metadata capture. I don't think it
makes sense to support this for metadata capture, so you should test for that.

Regards,

        Hans

> +
> +     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;
>  
>       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,
> 

Reply via email to