Re: [PATCH v2 11/27] media: videobuf2-v4l2: Support vb2_queue embedded in a context
John Cox <[email protected]>
| Newsgroups | org.kernel.vger.linux-media,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAFyCYyMaKT9zDxZCruS84S0DvSWrAR_==jjokTPXwBcJAp01pA@mail.gmail.com> |
> Support device drivers that implement multi-context operations in the > videobuf2 core by providing an helper to retrieve the vb2_queue from > the context associated with an open file handle. If no context is > associated with a file handle, retrieve it from the video device > default context, created by the core for multi-context aware drivers. > > Fall-back to use the vb2_queue from the video_device to support existing > drivers which are not context aware. > > Signed-off-by: Jacopo Mondi <[email protected]> > --- > drivers/media/common/videobuf2/videobuf2-v4l2.c | 139 +++++++++++++++--------- > 1 file changed, 88 insertions(+), 51 deletions(-) > > diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c > index 1cd26faee50338aefeb670c6865da7c2d43f44d3..ad7892551f54c5abc7db7641bb8fb89d77b1337f 100644 > --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c > +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c > @@ -998,23 +998,46 @@ EXPORT_SYMBOL_GPL(vb2_poll); > * and so they simplify the driver code. > */ > > +/* > + * Helper to get the vb2 queue either from: > + * 1) The video context bound to the open file handle > + * 2) The default context for context-aware drivers if userspace has not bound > + * a context to the file handle > + * 3) From the video device for non-context aware drivers > + */ > +static struct vb2_queue *get_vb2_queue(struct file *file, > + struct video_device *vdev) > +{ > +#if defined(CONFIG_MEDIA_CONTROLLER) > + struct video_device_context *ctx = > + video_device_context_from_file(file, vdev); > + > + return ctx ? &ctx->queue > + : vdev->default_context ? &vdev->default_context->queue > + : vdev->queue; > +#else > + return vdev->queue; > +#endif /* CONFIG_MEDIA_CONTROLLER */ > +} > + > /* vb2 ioctl helpers */ > > int vb2_ioctl_remove_bufs(struct file *file, void *priv, > struct v4l2_remove_buffers *d) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > - if (vdev->queue->type != d->type) > + if (q->type != d->type) > return -EINVAL; > > if (d->count == 0) > return 0; > > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > return -EBUSY; > > - return vb2_core_remove_bufs(vdev->queue, d->index, d->count); > + return vb2_core_remove_bufs(q, d->index, d->count); > } > EXPORT_SYMBOL_GPL(vb2_ioctl_remove_bufs); > > @@ -1022,21 +1045,21 @@ int vb2_ioctl_reqbufs(struct file *file, void *priv, > struct v4l2_requestbuffers *p) > { > struct video_device *vdev = video_devdata(file); > - int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > + int res = vb2_verify_memory_type(q, p->memory, p->type); > u32 flags = p->flags; > > - vb2_set_flags_and_caps(vdev->queue, p->memory, &flags, > - &p->capabilities, NULL); > + vb2_set_flags_and_caps(q, p->memory, &flags, &p->capabilities, NULL); > p->flags = flags; > if (res) > return res; > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > return -EBUSY; > - res = vb2_core_reqbufs(vdev->queue, p->memory, p->flags, &p->count); > + res = vb2_core_reqbufs(q, p->memory, p->flags, &p->count); > /* If count == 0, then the owner has released all buffers and he > is no longer owner of the queue. Otherwise we have a new owner. */ > if (res == 0) > - vdev->queue->owner = p->count ? file->private_data : NULL; > + q->owner = p->count ? file->private_data : NULL; > return res; > } > EXPORT_SYMBOL_GPL(vb2_ioctl_reqbufs); > @@ -1045,11 +1068,12 @@ int vb2_ioctl_create_bufs(struct file *file, void *priv, > struct v4l2_create_buffers *p) > { > struct video_device *vdev = video_devdata(file); > - int res = vb2_verify_memory_type(vdev->queue, p->memory, p->format.type); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > + int res = vb2_verify_memory_type(q, p->memory, p->format.type); > > - p->index = vb2_get_num_buffers(vdev->queue); > - vb2_set_flags_and_caps(vdev->queue, p->memory, &p->flags, > - &p->capabilities, &p->max_num_buffers); > + p->index = vb2_get_num_buffers(q); > + vb2_set_flags_and_caps(q, p->memory, &p->flags, &p->capabilities, > + &p->max_num_buffers); > /* > * If count == 0, then just check if memory and type are valid. > * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0. > @@ -1058,12 +1082,12 @@ int vb2_ioctl_create_bufs(struct file *file, void *priv, > return res != -EBUSY ? res : 0; > if (res) > return res; > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > return -EBUSY; > > - res = vb2_create_bufs(vdev->queue, p); > + res = vb2_create_bufs(q, p); > if (res == 0) > - vdev->queue->owner = file->private_data; > + q->owner = file->private_data; > return res; > } > EXPORT_SYMBOL_GPL(vb2_ioctl_create_bufs); > @@ -1072,69 +1096,76 @@ int vb2_ioctl_prepare_buf(struct file *file, void *priv, > struct v4l2_buffer *p) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > return -EBUSY; > - return vb2_prepare_buf(vdev->queue, vdev->v4l2_dev->mdev, p); > + return vb2_prepare_buf(q, vdev->v4l2_dev->mdev, p); > } > EXPORT_SYMBOL_GPL(vb2_ioctl_prepare_buf); > > int vb2_ioctl_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > /* No need to call vb2_queue_is_busy(), anyone can query buffers. */ > - return vb2_querybuf(vdev->queue, p); > + return vb2_querybuf(q, p); > } > EXPORT_SYMBOL_GPL(vb2_ioctl_querybuf); > > int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > return -EBUSY; > - return vb2_qbuf(vdev->queue, vdev->v4l2_dev->mdev, p); > + return vb2_qbuf(q, vdev->v4l2_dev->mdev, p); > } > EXPORT_SYMBOL_GPL(vb2_ioctl_qbuf); > > int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > return -EBUSY; > - return vb2_dqbuf(vdev->queue, p, file->f_flags & O_NONBLOCK); > + return vb2_dqbuf(q, p, file->f_flags & O_NONBLOCK); > } > EXPORT_SYMBOL_GPL(vb2_ioctl_dqbuf); > > int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > return -EBUSY; > - return vb2_streamon(vdev->queue, i); > + return vb2_streamon(q, i); > } > EXPORT_SYMBOL_GPL(vb2_ioctl_streamon); > > int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > return -EBUSY; > - return vb2_streamoff(vdev->queue, i); > + return vb2_streamoff(q, i); > } > EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff); > > int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > return -EBUSY; > - return vb2_expbuf(vdev->queue, p); > + return vb2_expbuf(q, p); > } > EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf); > > @@ -1143,20 +1174,22 @@ EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf); > int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > - return vb2_mmap(vdev->queue, vma); > + return vb2_mmap(q, vma); > } > EXPORT_SYMBOL_GPL(vb2_fop_mmap); > > int _vb2_fop_release(struct file *file, struct mutex *lock) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > if (lock) > mutex_lock(lock); > - if (!vdev->queue->owner || file->private_data == vdev->queue->owner) { > - vb2_queue_release(vdev->queue); > - vdev->queue->owner = NULL; > + if (!q->owner || file->private_data == q->owner) { > + vb2_queue_release(q); > + q->owner = NULL; > } > if (lock) > mutex_unlock(lock); > @@ -1167,7 +1200,8 @@ EXPORT_SYMBOL_GPL(_vb2_fop_release); > int vb2_fop_release(struct file *file) > { > struct video_device *vdev = video_devdata(file); > - struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; > + struct vb2_queue *q = get_vb2_queue(file, vdev); > + struct mutex *lock = q->lock ? q->lock : vdev->lock; > > return _vb2_fop_release(file, lock); > } > @@ -1177,19 +1211,20 @@ ssize_t vb2_fop_write(struct file *file, const char __user *buf, > size_t count, loff_t *ppos) > { > struct video_device *vdev = video_devdata(file); > - struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; > + struct vb2_queue *q = get_vb2_queue(file, vdev); > + struct mutex *lock = q->lock ? q->lock : vdev->lock; > int err = -EBUSY; > > - if (!(vdev->queue->io_modes & VB2_WRITE)) > + if (!(q->io_modes & VB2_WRITE)) > return -EINVAL; > if (lock && mutex_lock_interruptible(lock)) > return -ERESTARTSYS; > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > goto exit; > - err = vb2_write(vdev->queue, buf, count, ppos, > - file->f_flags & O_NONBLOCK); > - if (vdev->queue->fileio) > - vdev->queue->owner = file->private_data; > + err = vb2_write(q, buf, count, ppos, > + file->f_flags & O_NONBLOCK); > + if (q->fileio) > + q->owner = file->private_data; > exit: > if (lock) > mutex_unlock(lock); > @@ -1201,20 +1236,21 @@ ssize_t vb2_fop_read(struct file *file, char __user *buf, > size_t count, loff_t *ppos) > { > struct video_device *vdev = video_devdata(file); > - struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; > + struct vb2_queue *q = get_vb2_queue(file, vdev); > + struct mutex *lock = q->lock ? q->lock : vdev->lock; > int err = -EBUSY; > > - if (!(vdev->queue->io_modes & VB2_READ)) > + if (!(q->io_modes & VB2_READ)) > return -EINVAL; > if (lock && mutex_lock_interruptible(lock)) > return -ERESTARTSYS; > - if (vb2_queue_is_busy(vdev->queue, file)) > + if (vb2_queue_is_busy(q, file)) > goto exit; > - vdev->queue->owner = file->private_data; > - err = vb2_read(vdev->queue, buf, count, ppos, > + q->owner = file->private_data; > + err = vb2_read(q, buf, count, ppos, > file->f_flags & O_NONBLOCK); > - if (!vdev->queue->fileio) > - vdev->queue->owner = NULL; > + if (!q->fileio) > + q->owner = NULL; > exit: > if (lock) > mutex_unlock(lock); > @@ -1225,7 +1261,7 @@ EXPORT_SYMBOL_GPL(vb2_fop_read); > __poll_t vb2_fop_poll(struct file *file, poll_table *wait) > { > struct video_device *vdev = video_devdata(file); > - struct vb2_queue *q = vdev->queue; > + struct vb2_queue *q = get_vb2_queue(file, vdev); > struct mutex *lock = q->lock ? q->lock : vdev->lock; > __poll_t res; > void *fileio; > @@ -1241,7 +1277,7 @@ __poll_t vb2_fop_poll(struct file *file, poll_table *wait) > > fileio = q->fileio; > > - res = vb2_poll(vdev->queue, file, wait); > + res = vb2_poll(q, file, wait); > > /* If fileio was started, then we have a new queue owner. */ > if (!fileio && q->fileio) > @@ -1257,8 +1293,9 @@ unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr, > unsigned long len, unsigned long pgoff, unsigned long flags) > { > struct video_device *vdev = video_devdata(file); > + struct vb2_queue *q = get_vb2_queue(file, vdev); > > - return vb2_get_unmapped_area(vdev->queue, addr, len, pgoff, flags); > + return vb2_get_unmapped_area(q, addr, len, pgoff, flags); > } > EXPORT_SYMBOL_GPL(vb2_fop_get_unmapped_area); > #endif You need similar logic in v4l2-ioctl.c to retrieve the correct queue from a video_device and v4l2_fh so v4l2_ioctl_get_lock retrieves the correct lock. Regards John Cox