Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b62b737 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB: v4l videobuf: add videobuf_buffer *buf as argument to mmap_mapper



mmap_mapper should operate on a buffer, not on a complete queue. So let
the videobuf-core find the correct buffer instead of duplicating that
code in each mmap_mapper implementation.

The dma-sg implementation has backwards compatibility code for handling
the V4L1_COMPAT layer. This code is now under the v4L1_COMPAT config option.

Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 37111039
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -1123,15 +1123,29 @@ EXPORT_SYMBOL_GPL(videobuf_poll_stream);

int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma)
{
	int retval;
	int rc = -EINVAL;
	int i;

	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);

	if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) {
		dprintk(1, "mmap appl bug: PROT_WRITE and MAP_SHARED are required\n");
		return -EINVAL;
	}

	mutex_lock(&q->vb_lock);
	retval = CALL(q, mmap_mapper, q, vma);
	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
		struct videobuf_buffer *buf = q->bufs[i];

		if (buf && buf->memory == V4L2_MEMORY_MMAP &&
				buf->boff == (vma->vm_pgoff << PAGE_SHIFT)) {
			rc = CALL(q, mmap_mapper, q, buf, vma);
			break;
		}
	}
	mutex_unlock(&q->vb_lock);

	return retval;
	return rc;
}
EXPORT_SYMBOL_GPL(videobuf_mmap_mapper);

+8 −26
Original line number Diff line number Diff line
@@ -264,51 +264,33 @@ static int __videobuf_iolock(struct videobuf_queue *q,
}

static int __videobuf_mmap_mapper(struct videobuf_queue *q,
				  struct videobuf_buffer *buf,
				  struct vm_area_struct *vma)
{
	struct videobuf_dma_contig_memory *mem;
	struct videobuf_mapping *map;
	unsigned int first;
	int retval;
	unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT;
	unsigned long size;

	dev_dbg(q->dev, "%s\n", __func__);
	if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
		return -EINVAL;

	/* look for first buffer to map */
	for (first = 0; first < VIDEO_MAX_FRAME; first++) {
		if (!q->bufs[first])
			continue;

		if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
			continue;
		if (q->bufs[first]->boff == offset)
			break;
	}
	if (VIDEO_MAX_FRAME == first) {
		dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n",
			offset);
		return -EINVAL;
	}

	/* create mapping + update buffer list */
	map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
	if (!map)
		return -ENOMEM;

	q->bufs[first]->map = map;
	buf->map = map;
	map->start = vma->vm_start;
	map->end = vma->vm_end;
	map->q = q;

	q->bufs[first]->baddr = vma->vm_start;
	buf->baddr = vma->vm_start;

	mem = q->bufs[first]->priv;
	mem = buf->priv;
	BUG_ON(!mem);
	MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);

	mem->size = PAGE_ALIGN(q->bufs[first]->bsize);
	mem->size = PAGE_ALIGN(buf->bsize);
	mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
					&mem->dma_handle, GFP_KERNEL);
	if (!mem->vaddr) {
@@ -341,8 +323,8 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,

	dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
		map, q, vma->vm_start, vma->vm_end,
		(long int) q->bufs[first]->bsize,
		vma->vm_pgoff, first);
		(long int)buf->bsize,
		vma->vm_pgoff, buf->i);

	videobuf_vm_open(vma);

+33 −36
Original line number Diff line number Diff line
@@ -549,22 +549,15 @@ static int __videobuf_sync(struct videobuf_queue *q,
}

static int __videobuf_mmap_mapper(struct videobuf_queue *q,
				  struct videobuf_buffer *buf,
				  struct vm_area_struct *vma)
{
	struct videobuf_dma_sg_memory *mem;
	struct videobuf_dma_sg_memory *mem = buf->priv;
	struct videobuf_mapping *map;
	unsigned int first, last, size, i;
	int retval;

	retval = -EINVAL;
	if (!(vma->vm_flags & VM_WRITE)) {
		dprintk(1, "mmap app bug: PROT_WRITE please\n");
		goto done;
	}
	if (!(vma->vm_flags & VM_SHARED)) {
		dprintk(1, "mmap app bug: MAP_SHARED please\n");
		goto done;
	}

	/* This function maintains backwards compatibility with V4L1 and will
	 * map more than one buffer if the vma length is equal to the combined
@@ -574,27 +567,29 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
	 * TODO: Allow drivers to specify if they support this mode
	 */

	/* look for first buffer to map */
	for (first = 0; first < VIDEO_MAX_FRAME; first++) {
		if (NULL == q->bufs[first])
			continue;
		mem = q->bufs[first]->priv;
	BUG_ON(!mem);
	MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);

		if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
			continue;
		if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
	/* look for first buffer to map */
	for (first = 0; first < VIDEO_MAX_FRAME; first++) {
		if (buf == q->bufs[first]) {
			size = PAGE_ALIGN(q->bufs[first]->bsize);
			break;
		}
	}

	/* paranoia, should never happen since buf is always valid. */
	if (VIDEO_MAX_FRAME == first) {
		dprintk(1, "mmap app bug: offset invalid [offset=0x%lx]\n",
				(vma->vm_pgoff << PAGE_SHIFT));
		goto done;
	}

	last = first;
#ifdef CONFIG_VIDEO_V4L1_COMPAT
	if (size != (vma->vm_end - vma->vm_start)) {
		/* look for last buffer to map */
	for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) {
		for (last = first + 1; last < VIDEO_MAX_FRAME; last++) {
			if (NULL == q->bufs[last])
				continue;
			if (V4L2_MEMORY_MMAP != q->bufs[last]->memory)
@@ -612,6 +607,8 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
					(vma->vm_end - vma->vm_start));
			goto done;
		}
	}
#endif

	/* create mapping + update buffer list */
	retval = -ENOMEM;
+7 −26
Original line number Diff line number Diff line
@@ -236,47 +236,28 @@ static int __videobuf_sync(struct videobuf_queue *q,
}

static int __videobuf_mmap_mapper(struct videobuf_queue *q,
				  struct videobuf_buffer *buf,
				  struct vm_area_struct *vma)
{
	struct videobuf_vmalloc_memory *mem;
	struct videobuf_mapping *map;
	unsigned int first;
	int retval, pages;
	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;

	dprintk(1, "%s\n", __func__);
	if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
		return -EINVAL;

	/* look for first buffer to map */
	for (first = 0; first < VIDEO_MAX_FRAME; first++) {
		if (NULL == q->bufs[first])
			continue;

		if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
			continue;
		if (q->bufs[first]->boff == offset)
			break;
	}
	if (VIDEO_MAX_FRAME == first) {
		dprintk(1, "mmap app bug: offset invalid [offset=0x%lx]\n",
			(vma->vm_pgoff << PAGE_SHIFT));
		return -EINVAL;
	}

	/* create mapping + update buffer list */
	map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
	if (NULL == map)
		return -ENOMEM;

	q->bufs[first]->map = map;
	buf->map = map;
	map->start = vma->vm_start;
	map->end   = vma->vm_end;
	map->q     = q;

	q->bufs[first]->baddr = vma->vm_start;
	buf->baddr = vma->vm_start;

	mem = q->bufs[first]->priv;
	mem = buf->priv;
	BUG_ON(!mem);
	MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);

@@ -302,8 +283,8 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,

	dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
		map, q, vma->vm_start, vma->vm_end,
		(long int) q->bufs[first]->bsize,
		vma->vm_pgoff, first);
		(long int)buf->bsize,
		vma->vm_pgoff, buf->i);

	videobuf_vm_open(vma);

+2 −1
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ struct videobuf_qtype_ops {
	int (*sync)		(struct videobuf_queue *q,
				 struct videobuf_buffer *buf);
	int (*mmap_mapper)	(struct videobuf_queue *q,
				 struct videobuf_buffer *buf,
				 struct vm_area_struct *vma);
};