From: Mauro Carvalho Chehab <mchehab@s-opensource.com>
To: Hans Verkuil <hverkuil@xs4all.nl>
Cc: linux-media@vger.kernel.org, Hans Verkuil <hans.verkuil@cisco.com>
Subject: Re: [RFCv11 PATCH 04/29] media-request: core request support
Date: Tue, 10 Apr 2018 07:32:06 -0300 [thread overview]
Message-ID: <20180410073206.12d4c67d@vento.lan> (raw)
In-Reply-To: <20180409142026.19369-5-hverkuil@xs4all.nl>
Em Mon, 9 Apr 2018 16:20:01 +0200
Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> From: Hans Verkuil <hans.verkuil@cisco.com>
>
> Implement the core of the media request processing.
>
> Drivers can bind request objects to a request. These objects
> can then be marked completed if the driver finished using them,
> or just be unbound if the results do not need to be kept (e.g.
> in the case of buffers).
>
> Once all objects that were added are either unbound or completed,
> the request is marked 'complete' and a POLLPRI signal is sent
> via poll.
>
> Both requests and request objects are refcounted.
>
> While a request is queued its refcount is incremented (since it
> is in use by a driver). Once it is completed the refcount is
> decremented. When the user closes the request file descriptor
> the refcount is also decremented. Once it reaches 0 all request
> objects in the request are unbound and put() and the request
> itself is freed.
>
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
> drivers/media/media-request.c | 284 +++++++++++++++++++++++++++++++++++++++++-
> include/media/media-request.h | 156 +++++++++++++++++++++++
> 2 files changed, 439 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
> index ead78613fdbe..dffc290e4ada 100644
> --- a/drivers/media/media-request.c
> +++ b/drivers/media/media-request.c
> @@ -16,8 +16,290 @@
> #include <media/media-device.h>
> #include <media/media-request.h>
>
> +static const char * const request_state[] = {
> + "idle",
> + "queueing",
> + "queued",
> + "complete",
> + "cleaning",
> +};
Please use c99 designated inits here, e. g.:
static const char * const request_state[] = {
[MEDIA_REQUEST_STATE_IDLE] = "idle",
...
};
> +
> +static const char *
> +media_request_state_str(enum media_request_state state)
> +{
> + if (WARN_ON(state >= ARRAY_SIZE(request_state)))
> + return "unknown";
> + return request_state[state];
> +}
> +
> +static void media_request_clean(struct media_request *req)
> +{
> + struct media_request_object *obj, *obj_safe;
> +
> + WARN_ON(req->state != MEDIA_REQUEST_STATE_CLEANING);
> +
> + list_for_each_entry_safe(obj, obj_safe, &req->objects, list) {
> + media_request_object_unbind(obj);
> + media_request_object_put(obj);
> + }
> +
> + req->num_incomplete_objects = 0;
> + wake_up_interruptible(&req->poll_wait);
> +}
> +
> +static void media_request_release(struct kref *kref)
> +{
> + struct media_request *req =
> + container_of(kref, struct media_request, kref);
> + struct media_device *mdev = req->mdev;
> + unsigned long flags;
> +
> + dev_dbg(mdev->dev, "request: release %s\n", req->debug_str);
> +
> + spin_lock_irqsave(&req->lock, flags);
> + req->state = MEDIA_REQUEST_STATE_CLEANING;
> + spin_unlock_irqrestore(&req->lock, flags);
> +
> + media_request_clean(req);
> +
> + if (mdev->ops->req_free)
> + mdev->ops->req_free(req);
> + else
> + kfree(req);
Without looking at req_free() implementation, I would actually prefer
to always do a kfree(req) here. So, a req_free() function would only
free "extra" allocations, and not the request itself. e. g.:
...
if (mdev->ops->req_free)
mdev->ops->req_free(req);
kfree(req);
}
> +}
> +
> +void media_request_put(struct media_request *req)
> +{
> + kref_put(&req->kref, media_request_release);
> +}
> +EXPORT_SYMBOL_GPL(media_request_put);
> +
> +void media_request_cancel(struct media_request *req)
> +{
> + struct media_request_object *obj, *obj_safe;
> +
> + if (req->state != MEDIA_REQUEST_STATE_QUEUED)
> + return;
> +
> + list_for_each_entry_safe(obj, obj_safe, &req->objects, list)
> + if (obj->ops->cancel)
> + obj->ops->cancel(obj);
> +}
> +EXPORT_SYMBOL_GPL(media_request_cancel);
> +
> +static int media_request_close(struct inode *inode, struct file *filp)
> +{
> + struct media_request *req = filp->private_data;
> +
> + media_request_put(req);
> + return 0;
> +}
> +
> +static unsigned int media_request_poll(struct file *filp,
> + struct poll_table_struct *wait)
> +{
> + struct media_request *req = filp->private_data;
> + unsigned long flags;
> + enum media_request_state state;
> +
> + if (!(poll_requested_events(wait) & POLLPRI))
> + return 0;
> +
> + spin_lock_irqsave(&req->lock, flags);
> + state = req->state;
> + spin_unlock_irqrestore(&req->lock, flags);
IMO, it would be better to use an atomic var for state, having a
lockless access to it.
> +
> + if (state == MEDIA_REQUEST_STATE_COMPLETE)
> + return POLLPRI;
> + if (state == MEDIA_REQUEST_STATE_IDLE)
> + return POLLERR;
> +
> + poll_wait(filp, &req->poll_wait, wait);
> + return 0;
> +}
> +
> +static long media_request_ioctl(struct file *filp, unsigned int cmd,
> + unsigned long __arg)
> +{
> + return -ENOIOCTLCMD;
> +}
> +
> +static const struct file_operations request_fops = {
> + .owner = THIS_MODULE,
> + .poll = media_request_poll,
> + .unlocked_ioctl = media_request_ioctl,
> + .release = media_request_close,
> +};
> +
> int media_request_alloc(struct media_device *mdev,
> struct media_request_alloc *alloc)
> {
> - return -ENOMEM;
> + struct media_request *req;
> + struct file *filp;
> + char comm[TASK_COMM_LEN];
> + int fd;
> + int ret;
> +
> + fd = get_unused_fd_flags(O_CLOEXEC);
> + if (fd < 0)
> + return fd;
> +
> + filp = anon_inode_getfile("request", &request_fops, NULL, O_CLOEXEC);
> + if (IS_ERR(filp)) {
> + ret = PTR_ERR(filp);
> + goto err_put_fd;
> + }
> +
> + if (mdev->ops->req_alloc)
> + req = mdev->ops->req_alloc(mdev);
> + else
> + req = kzalloc(sizeof(*req), GFP_KERNEL);
> + if (!req) {
> + ret = -ENOMEM;
> + goto err_fput;
> + }
> +
> + filp->private_data = req;
> + req->mdev = mdev;
> + req->state = MEDIA_REQUEST_STATE_IDLE;
> + req->num_incomplete_objects = 0;
> + kref_init(&req->kref);
> + INIT_LIST_HEAD(&req->objects);
> + spin_lock_init(&req->lock);
> + init_waitqueue_head(&req->poll_wait);
> +
> + alloc->fd = fd;
Btw, this is a very good reason why you should define the ioctl to
have an integer argument instead of a struct with a __s32 field
on it, as per my comment to patch 02/29:
#define MEDIA_IOC_REQUEST_ALLOC _IOWR('|', 0x05, int)
At 64 bit architectures, you're truncating the file descriptor!
> + get_task_comm(comm, current);
> + snprintf(req->debug_str, sizeof(req->debug_str), "%s:%d",
> + comm, fd);
Not sure if it is a good idea to store the task that allocated
the request. While it makes sense for the dev_dbg() below, it
may not make sense anymore on other dev_dbg() you would be
using it.
> + dev_dbg(mdev->dev, "request: allocated %s\n", req->debug_str);
> +
> + fd_install(fd, filp);
> +
> + return 0;
> +
> +err_fput:
> + fput(filp);
> +
> +err_put_fd:
> + put_unused_fd(fd);
> +
> + return ret;
> +}
> +
> +static void media_request_object_release(struct kref *kref)
> +{
> + struct media_request_object *obj =
> + container_of(kref, struct media_request_object, kref);
> + struct media_request *req = obj->req;
> +
> + if (req)
> + media_request_object_unbind(obj);
> + obj->ops->release(obj);
> +}
> +
> +void media_request_object_put(struct media_request_object *obj)
> +{
> + kref_put(&obj->kref, media_request_object_release);
> +}
> +EXPORT_SYMBOL_GPL(media_request_object_put);
> +
> +void media_request_object_init(struct media_request_object *obj)
> +{
> + obj->ops = NULL;
> + obj->req = NULL;
> + obj->priv = NULL;
> + obj->completed = false;
> + INIT_LIST_HEAD(&obj->list);
> + kref_init(&obj->kref);
> +}
> +EXPORT_SYMBOL_GPL(media_request_object_init);
> +
> +void media_request_object_bind(struct media_request *req,
> + const struct media_request_object_ops *ops,
> + void *priv,
> + struct media_request_object *obj)
> +{
> + unsigned long flags;
> +
> + if (WARN_ON(!ops->release || !ops->cancel))
> + return;
> +
> + obj->req = req;
> + obj->ops = ops;
> + obj->priv = priv;
> + spin_lock_irqsave(&req->lock, flags);
> + if (WARN_ON(req->state != MEDIA_REQUEST_STATE_IDLE))
> + goto unlock;
> + list_add_tail(&obj->list, &req->objects);
> + req->num_incomplete_objects++;
> +unlock:
> + spin_unlock_irqrestore(&req->lock, flags);
> +}
> +EXPORT_SYMBOL_GPL(media_request_object_bind);
> +
> +void media_request_object_unbind(struct media_request_object *obj)
> +{
> + struct media_request *req = obj->req;
> + unsigned long flags;
> + bool completed = false;
> +
> + if (!req)
> + return;
> +
> + spin_lock_irqsave(&req->lock, flags);
> + list_del(&obj->list);
> + obj->req = NULL;
> +
> + if (req->state == MEDIA_REQUEST_STATE_COMPLETE ||
> + req->state == MEDIA_REQUEST_STATE_CLEANING)
> + goto unlock;
> +
> + if (WARN_ON(req->state == MEDIA_REQUEST_STATE_QUEUEING))
> + goto unlock;
> +
> + if (WARN_ON(!req->num_incomplete_objects))
> + goto unlock;
> +
> + req->num_incomplete_objects--;
> + if (req->state == MEDIA_REQUEST_STATE_QUEUED &&
> + !req->num_incomplete_objects) {
> + req->state = MEDIA_REQUEST_STATE_COMPLETE;
> + completed = true;
> + wake_up_interruptible(&req->poll_wait);
> + }
> +unlock:
> + spin_unlock_irqrestore(&req->lock, flags);
> + if (obj->ops->unbind)
> + obj->ops->unbind(obj);
> + if (completed)
> + media_request_put(req);
> +}
> +EXPORT_SYMBOL_GPL(media_request_object_unbind);
> +
> +void media_request_object_complete(struct media_request_object *obj)
> +{
> + struct media_request *req = obj->req;
> + unsigned long flags;
> + bool completed = false;
> +
> + spin_lock_irqsave(&req->lock, flags);
> + if (obj->completed)
> + goto unlock;
> + obj->completed = true;
> + if (WARN_ON(!req->num_incomplete_objects) ||
> + WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED))
> + goto unlock;
> +
> + if (!--req->num_incomplete_objects) {
> + req->state = MEDIA_REQUEST_STATE_COMPLETE;
> + wake_up_interruptible(&req->poll_wait);
> + completed = true;
> + }
> +unlock:
> + spin_unlock_irqrestore(&req->lock, flags);
> + if (completed)
> + media_request_put(req);
> }
> +EXPORT_SYMBOL_GPL(media_request_object_complete);
> diff --git a/include/media/media-request.h b/include/media/media-request.h
> index dae3eccd9aa7..082c3cae04ac 100644
> --- a/include/media/media-request.h
> +++ b/include/media/media-request.h
> @@ -16,7 +16,163 @@
>
> #include <media/media-device.h>
>
> +enum media_request_state {
> + MEDIA_REQUEST_STATE_IDLE,
> + MEDIA_REQUEST_STATE_QUEUEING,
> + MEDIA_REQUEST_STATE_QUEUED,
> + MEDIA_REQUEST_STATE_COMPLETE,
> + MEDIA_REQUEST_STATE_CLEANING,
> +};
> +
> +struct media_request_object;
> +
> +/**
> + * struct media_request - Media device request
> + * @mdev: Media device this request belongs to
> + * @kref: Reference count
> + * @debug_prefix: Prefix for debug messages (process name:fd)
> + * @state: The state of the request
> + * @objects: List of @struct media_request_object request objects
> + * @num_objects: The number objects in the request
> + * @num_completed_objects: The number of completed objects in the request
This doesn't match any var...
> + * @poll_wait: Wait queue for poll
> + * @lock: Serializes access to this struct
> + */
> +struct media_request {
> + struct media_device *mdev;
> + struct kref kref;
> + char debug_str[TASK_COMM_LEN + 11];
> + enum media_request_state state;
> + struct list_head objects;
> + unsigned int num_incomplete_objects;
... as it seems that you decide to count incomplete objects, instead
of complete ones.
> + struct wait_queue_head poll_wait;
> + spinlock_t lock;
> +};
> +
> +#ifdef CONFIG_MEDIA_CONTROLLER
> +
> +static inline void media_request_get(struct media_request *req)
> +{
> + kref_get(&req->kref);
> +}
> +
> +void media_request_put(struct media_request *req);
> +void media_request_cancel(struct media_request *req);
> +
> int media_request_alloc(struct media_device *mdev,
> struct media_request_alloc *alloc);
> +#else
> +static inline void media_request_get(struct media_request *req)
> +{
> +}
> +
> +static inline void media_request_put(struct media_request *req)
> +{
> +}
> +
> +static inline void media_request_cancel(struct media_request *req)
> +{
> +}
> +
> +#endif
> +
> +struct media_request_object_ops {
> + int (*prepare)(struct media_request_object *object);
> + void (*unprepare)(struct media_request_object *object);
> + void (*queue)(struct media_request_object *object);
> + void (*unbind)(struct media_request_object *object);
> + void (*cancel)(struct media_request_object *object);
> + void (*release)(struct media_request_object *object);
> +};
-ENODESCRIPTION. Please describe the struct and its fields.
> +
> +/**
> + * struct media_request_object - An opaque object that belongs to a media
> + * request
> + *
> + * @priv: object's priv pointer
> + * @list: List entry of the object for @struct media_request
> + * @kref: Reference count of the object, acquire before releasing req->lock
Field descriptions missing.
> + *
> + * An object related to the request. This struct is embedded in the
> + * larger object data.
> + */
> +struct media_request_object {
> + const struct media_request_object_ops *ops;
> + void *priv;
> + struct media_request *req;
> + struct list_head list;
> + struct kref kref;
> + bool completed;
> +};
> +
> +#ifdef CONFIG_MEDIA_CONTROLLER
> +static inline void media_request_object_get(struct media_request_object *obj)
> +{
> + kref_get(&obj->kref);
> +}
Why do you need a function? Just use kref_get() were needed, instead of
aliasing it for no good reason.
> +
> +/**
> + * media_request_object_put - Put a media request object
> + *
> + * @obj: The object
> + *
> + * Put a media request object. Once all references are gone, the
> + * object's memory is released.
> + */
> +void media_request_object_put(struct media_request_object *obj);
> +
> +/**
> + * media_request_object_init - Initialise a media request object
> + *
> + * Initialise a media request object. The object will be released using the
> + * release callback of the ops once it has no references (this function
> + * initialises references to one).
> + */
> +void media_request_object_init(struct media_request_object *obj);
> +
> +/**
> + * media_request_object_bind - Bind a media request object to a request
> + */
> +void media_request_object_bind(struct media_request *req,
> + const struct media_request_object_ops *ops,
> + void *priv,
> + struct media_request_object *obj);
> +
> +void media_request_object_unbind(struct media_request_object *obj);
> +
> +/**
> + * media_request_object_complete - Mark the media request object as complete
> + */
> +void media_request_object_complete(struct media_request_object *obj);
The kernel-doc tags there are wrong: They don't describe the function
arguments.
Please validate it with sphinx to be sure that everything is ok.
> +#else
> +static inline void media_request_object_get(struct media_request_object *obj)
> +{
> +}
> +
> +static inline void media_request_object_put(struct media_request_object *obj)
> +{
> +}
> +
> +static inline void media_request_object_init(struct media_request_object *obj)
> +{
> + obj->ops = NULL;
> + obj->req = NULL;
> +}
> +
> +static inline void media_request_object_bind(struct media_request *req,
> + const struct media_request_object_ops *ops,
> + void *priv,
> + struct media_request_object *obj)
> +{
> +}
> +
> +static inline void media_request_object_unbind(struct media_request_object *obj)
> +{
> +}
> +
> +static inline void media_request_object_complete(struct media_request_object *obj)
> +{
> +}
> +#endif
>
> #endif
Thanks,
Mauro
next prev parent reply other threads:[~2018-04-10 10:32 UTC|newest]
Thread overview: 135+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-09 14:19 [RFCv11 PATCH 00/29] Request API Hans Verkuil
2018-04-09 14:19 ` [RFCv11 PATCH 01/29] v4l2-device.h: always expose mdev Hans Verkuil
2018-04-17 4:34 ` Alexandre Courbot
2018-04-09 14:19 ` [RFCv11 PATCH 02/29] uapi/linux/media.h: add request API Hans Verkuil
2018-04-10 5:26 ` Tomasz Figa
2018-04-23 9:55 ` Hans Verkuil
2018-04-10 9:38 ` Mauro Carvalho Chehab
2018-04-10 11:00 ` Sakari Ailus
2018-04-23 11:41 ` Hans Verkuil
2018-04-23 13:32 ` Mauro Carvalho Chehab
2018-04-17 4:34 ` Alexandre Courbot
2018-04-09 14:20 ` [RFCv11 PATCH 03/29] media-request: allocate media requests Hans Verkuil
2018-04-10 5:35 ` Tomasz Figa
2018-04-10 9:54 ` Mauro Carvalho Chehab
2018-04-23 9:59 ` Hans Verkuil
2018-04-10 9:52 ` Mauro Carvalho Chehab
2018-04-10 11:14 ` Sakari Ailus
2018-04-11 10:13 ` Mauro Carvalho Chehab
2018-04-23 9:46 ` Hans Verkuil
2018-04-23 11:49 ` Hans Verkuil
2018-04-23 13:35 ` Mauro Carvalho Chehab
2018-04-17 4:34 ` Alexandre Courbot
2018-04-09 14:20 ` [RFCv11 PATCH 04/29] media-request: core request support Hans Verkuil
2018-04-10 8:21 ` Tomasz Figa
2018-04-10 13:04 ` Sakari Ailus
2018-04-23 11:24 ` Hans Verkuil
2018-04-23 12:14 ` Hans Verkuil
2018-04-10 10:32 ` Mauro Carvalho Chehab [this message]
2018-04-10 12:32 ` Sakari Ailus
2018-04-10 14:51 ` Mauro Carvalho Chehab
2018-04-11 13:21 ` Sakari Ailus
2018-04-11 13:49 ` Mauro Carvalho Chehab
2018-04-11 15:02 ` Sakari Ailus
2018-04-11 15:17 ` Mauro Carvalho Chehab
2018-04-11 15:35 ` Sakari Ailus
2018-04-11 16:13 ` Mauro Carvalho Chehab
2018-04-12 7:11 ` Sakari Ailus
2018-04-23 12:43 ` Hans Verkuil
2018-05-07 10:05 ` Sakari Ailus
2018-04-23 12:23 ` Hans Verkuil
2018-04-23 14:07 ` Mauro Carvalho Chehab
2018-04-10 12:17 ` Sakari Ailus
2018-04-17 4:35 ` Alexandre Courbot
2018-04-23 14:28 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 05/29] media-request: add request ioctls Hans Verkuil
2018-04-10 8:59 ` Tomasz Figa
2018-04-12 7:35 ` Sakari Ailus
2018-04-23 12:40 ` Hans Verkuil
2018-04-23 11:34 ` Hans Verkuil
2018-04-10 10:57 ` Mauro Carvalho Chehab
2018-04-12 10:40 ` Sakari Ailus
2018-04-23 13:45 ` Hans Verkuil
2018-04-12 7:31 ` Sakari Ailus
2018-04-09 14:20 ` [RFCv11 PATCH 06/29] media-request: add media_request_find Hans Verkuil
2018-04-10 11:04 ` Mauro Carvalho Chehab
2018-04-12 10:52 ` Sakari Ailus
2018-04-12 12:08 ` Sakari Ailus
2018-04-23 13:50 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 07/29] media-request: add media_request_object_find Hans Verkuil
2018-04-10 11:07 ` Mauro Carvalho Chehab
2018-04-10 11:10 ` Hans Verkuil
2018-04-12 12:23 ` Sakari Ailus
2018-04-23 13:55 ` Hans Verkuil
2018-04-17 4:36 ` Alexandre Courbot
2018-04-23 14:32 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 08/29] videodev2.h: add request_fd field to v4l2_ext_controls Hans Verkuil
2018-04-10 11:11 ` Mauro Carvalho Chehab
2018-04-12 12:24 ` Sakari Ailus
2018-04-09 14:20 ` [RFCv11 PATCH 09/29] videodev2.h: add V4L2_CTRL_FLAG_IN_REQUEST Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 10/29] v4l2-ctrls: v4l2_ctrl_add_handler: add from_other_dev Hans Verkuil
2018-04-10 11:42 ` Mauro Carvalho Chehab
2018-04-12 13:35 ` Sakari Ailus
2018-04-09 14:20 ` [RFCv11 PATCH 11/29] v4l2-ctrls: prepare internal structs for request API Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 12/29] v4l2-ctrls: alloc memory for p_req Hans Verkuil
2018-04-10 9:32 ` Tomasz Figa
2018-04-10 13:57 ` Mauro Carvalho Chehab
2018-04-23 11:39 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 13/29] v4l2-ctrls: use ref in helper instead of ctrl Hans Verkuil
2018-04-10 12:47 ` Mauro Carvalho Chehab
2018-04-09 14:20 ` [RFCv11 PATCH 14/29] v4l2-ctrls: add core request support Hans Verkuil
2018-04-11 8:37 ` Paul Kocialkowski
2018-04-11 9:43 ` Tomasz Figa
2018-04-23 9:23 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 15/29] v4l2-ctrls: support g/s_ext_ctrls for requests Hans Verkuil
2018-04-10 13:00 ` Mauro Carvalho Chehab
2018-04-09 14:20 ` [RFCv11 PATCH 16/29] videodev2.h: Add request_fd field to v4l2_buffer Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 17/29] vb2: store userspace data in vb2_v4l2_buffer Hans Verkuil
2018-04-09 15:11 ` Kieran Bingham
2018-04-23 9:53 ` Hans Verkuil
2018-04-10 13:32 ` Mauro Carvalho Chehab
2018-04-09 14:20 ` [RFCv11 PATCH 18/29] videobuf2-core: embed media_request_object Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 19/29] videobuf2-core: integrate with media requests Hans Verkuil
2018-04-12 8:13 ` Tomasz Figa
2018-04-23 12:49 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 20/29] videobuf2-v4l2: " Hans Verkuil
2018-04-10 13:52 ` Mauro Carvalho Chehab
2018-04-17 4:36 ` Alexandre Courbot
2018-04-23 14:53 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 21/29] videobuf2-core: add vb2_core_request_has_buffers Hans Verkuil
2018-04-10 13:53 ` Mauro Carvalho Chehab
2018-04-09 14:20 ` [RFCv11 PATCH 22/29] videobuf2-v4l2: add vb2_request_queue helper Hans Verkuil
2018-04-12 8:29 ` Tomasz Figa
2018-04-23 12:51 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 23/29] videobuf2-v4l2: export request_fd Hans Verkuil
2018-04-10 13:59 ` Mauro Carvalho Chehab
2018-04-09 14:20 ` [RFCv11 PATCH 24/29] Documentation: v4l: document request API Hans Verkuil
2018-04-10 14:19 ` Mauro Carvalho Chehab
2018-04-12 8:51 ` Tomasz Figa
2018-04-09 14:20 ` [RFCv11 PATCH 25/29] media: vim2m: add media device Hans Verkuil
2018-04-12 8:54 ` Tomasz Figa
2018-04-23 13:23 ` Hans Verkuil
2018-04-17 4:37 ` Alexandre Courbot
2018-04-09 14:20 ` [RFCv11 PATCH 26/29] vim2m: use workqueue Hans Verkuil
2018-04-11 14:06 ` Paul Kocialkowski
2018-04-30 14:51 ` Hans Verkuil
2018-04-12 9:02 ` Tomasz Figa
2018-04-30 14:58 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 27/29] vim2m: support requests Hans Verkuil
2018-04-11 14:01 ` Paul Kocialkowski
2018-04-12 9:15 ` Tomasz Figa
2018-04-23 13:30 ` Hans Verkuil
2018-04-17 4:37 ` Alexandre Courbot
2018-04-23 15:06 ` Hans Verkuil
2018-04-17 11:42 ` Paul Kocialkowski
2018-04-23 15:10 ` Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 28/29] vivid: add mc Hans Verkuil
2018-04-09 14:20 ` [RFCv11 PATCH 29/29] vivid: add request support Hans Verkuil
2018-04-10 14:31 ` [RFCv11 PATCH 00/29] Request API Mauro Carvalho Chehab
2018-04-17 4:33 ` Alexandre Courbot
2018-04-17 6:12 ` Hans Verkuil
2018-04-17 6:17 ` Alexandre Courbot
2018-04-17 11:40 ` Paul Kocialkowski
2018-04-18 2:06 ` Alexandre Courbot
2018-04-19 7:48 ` Paul Kocialkowski
2018-04-23 15:10 ` Hans Verkuil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180410073206.12d4c67d@vento.lan \
--to=mchehab@s-opensource.com \
--cc=hans.verkuil@cisco.com \
--cc=hverkuil@xs4all.nl \
--cc=linux-media@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox