media: vb2: refactor setting flags and caps, fix missing cap
Several functions implementing VIDIOC_REQBUFS and _CREATE_BUFS all use
almost the same code to fill in the flags and capability fields. Refactor
this into a new vb2_set_flags_and_caps() function that replaces the old
fill_buf_caps() and validate_memory_flags() functions.
This also fixes a bug where vb2_ioctl_create_bufs() would not set the
V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS cap and also not fill in the
max_num_buffers field.
Fixes: d055a76c00
("media: core: Report the maximum possible number of buffers for the queue")
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Acked-by: Tomasz Figa <tfiga@chromium.org>
This commit is contained in:
@ -671,8 +671,20 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vb2_querybuf);
|
EXPORT_SYMBOL(vb2_querybuf);
|
||||||
|
|
||||||
static void fill_buf_caps(struct vb2_queue *q, u32 *caps)
|
static void vb2_set_flags_and_caps(struct vb2_queue *q, u32 memory,
|
||||||
|
u32 *flags, u32 *caps, u32 *max_num_bufs)
|
||||||
{
|
{
|
||||||
|
if (!q->allow_cache_hints || memory != V4L2_MEMORY_MMAP) {
|
||||||
|
/*
|
||||||
|
* This needs to clear V4L2_MEMORY_FLAG_NON_COHERENT only,
|
||||||
|
* but in order to avoid bugs we zero out all bits.
|
||||||
|
*/
|
||||||
|
*flags = 0;
|
||||||
|
} else {
|
||||||
|
/* Clear all unknown flags. */
|
||||||
|
*flags &= V4L2_MEMORY_FLAG_NON_COHERENT;
|
||||||
|
}
|
||||||
|
|
||||||
*caps = V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS;
|
*caps = V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS;
|
||||||
if (q->io_modes & VB2_MMAP)
|
if (q->io_modes & VB2_MMAP)
|
||||||
*caps |= V4L2_BUF_CAP_SUPPORTS_MMAP;
|
*caps |= V4L2_BUF_CAP_SUPPORTS_MMAP;
|
||||||
@ -686,21 +698,9 @@ static void fill_buf_caps(struct vb2_queue *q, u32 *caps)
|
|||||||
*caps |= V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS;
|
*caps |= V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS;
|
||||||
if (q->supports_requests)
|
if (q->supports_requests)
|
||||||
*caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS;
|
*caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS;
|
||||||
}
|
if (max_num_bufs) {
|
||||||
|
*max_num_bufs = q->max_num_buffers;
|
||||||
static void validate_memory_flags(struct vb2_queue *q,
|
*caps |= V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS;
|
||||||
int memory,
|
|
||||||
u32 *flags)
|
|
||||||
{
|
|
||||||
if (!q->allow_cache_hints || memory != V4L2_MEMORY_MMAP) {
|
|
||||||
/*
|
|
||||||
* This needs to clear V4L2_MEMORY_FLAG_NON_COHERENT only,
|
|
||||||
* but in order to avoid bugs we zero out all bits.
|
|
||||||
*/
|
|
||||||
*flags = 0;
|
|
||||||
} else {
|
|
||||||
/* Clear all unknown flags. */
|
|
||||||
*flags &= V4L2_MEMORY_FLAG_NON_COHERENT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,8 +709,8 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
|
|||||||
int ret = vb2_verify_memory_type(q, req->memory, req->type);
|
int ret = vb2_verify_memory_type(q, req->memory, req->type);
|
||||||
u32 flags = req->flags;
|
u32 flags = req->flags;
|
||||||
|
|
||||||
fill_buf_caps(q, &req->capabilities);
|
vb2_set_flags_and_caps(q, req->memory, &flags,
|
||||||
validate_memory_flags(q, req->memory, &flags);
|
&req->capabilities, NULL);
|
||||||
req->flags = flags;
|
req->flags = flags;
|
||||||
return ret ? ret : vb2_core_reqbufs(q, req->memory,
|
return ret ? ret : vb2_core_reqbufs(q, req->memory,
|
||||||
req->flags, &req->count);
|
req->flags, &req->count);
|
||||||
@ -751,11 +751,9 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
|
|||||||
int ret = vb2_verify_memory_type(q, create->memory, f->type);
|
int ret = vb2_verify_memory_type(q, create->memory, f->type);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
fill_buf_caps(q, &create->capabilities);
|
|
||||||
validate_memory_flags(q, create->memory, &create->flags);
|
|
||||||
create->index = vb2_get_num_buffers(q);
|
create->index = vb2_get_num_buffers(q);
|
||||||
create->max_num_buffers = q->max_num_buffers;
|
vb2_set_flags_and_caps(q, create->memory, &create->flags,
|
||||||
create->capabilities |= V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS;
|
&create->capabilities, &create->max_num_buffers);
|
||||||
if (create->count == 0)
|
if (create->count == 0)
|
||||||
return ret != -EBUSY ? ret : 0;
|
return ret != -EBUSY ? ret : 0;
|
||||||
|
|
||||||
@ -1006,8 +1004,8 @@ int vb2_ioctl_reqbufs(struct file *file, void *priv,
|
|||||||
int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type);
|
int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type);
|
||||||
u32 flags = p->flags;
|
u32 flags = p->flags;
|
||||||
|
|
||||||
fill_buf_caps(vdev->queue, &p->capabilities);
|
vb2_set_flags_and_caps(vdev->queue, p->memory, &flags,
|
||||||
validate_memory_flags(vdev->queue, p->memory, &flags);
|
&p->capabilities, NULL);
|
||||||
p->flags = flags;
|
p->flags = flags;
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
@ -1026,12 +1024,11 @@ int vb2_ioctl_create_bufs(struct file *file, void *priv,
|
|||||||
struct v4l2_create_buffers *p)
|
struct v4l2_create_buffers *p)
|
||||||
{
|
{
|
||||||
struct video_device *vdev = video_devdata(file);
|
struct video_device *vdev = video_devdata(file);
|
||||||
int res = vb2_verify_memory_type(vdev->queue, p->memory,
|
int res = vb2_verify_memory_type(vdev->queue, p->memory, p->format.type);
|
||||||
p->format.type);
|
|
||||||
|
|
||||||
p->index = vb2_get_num_buffers(vdev->queue);
|
p->index = vb2_get_num_buffers(vdev->queue);
|
||||||
fill_buf_caps(vdev->queue, &p->capabilities);
|
vb2_set_flags_and_caps(vdev->queue, p->memory, &p->flags,
|
||||||
validate_memory_flags(vdev->queue, p->memory, &p->flags);
|
&p->capabilities, &p->max_num_buffers);
|
||||||
/*
|
/*
|
||||||
* If count == 0, then just check if memory and type are valid.
|
* 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.
|
* Any -EBUSY result from vb2_verify_memory_type can be mapped to 0.
|
||||||
|
Reference in New Issue
Block a user