summaryrefslogtreecommitdiff
path: root/drivers/media/video/videobuf-vmalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/videobuf-vmalloc.c')
-rw-r--r--drivers/media/video/videobuf-vmalloc.c49
1 files changed, 23 insertions, 26 deletions
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index 5266ecc91dab..0bd447d9abe9 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -33,7 +33,7 @@
#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
{ printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
-static int debug = 0;
+static int debug;
module_param(debug, int, 0644);
MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers");
@@ -78,8 +78,6 @@ videobuf_vm_close(struct vm_area_struct *vma)
if (q->bufs[i]->map != map)
continue;
- q->ops->buf_release(q,q->bufs[i]);
-
q->bufs[i]->map = NULL;
q->bufs[i]->baddr = 0;
}
@@ -102,7 +100,7 @@ static struct vm_operations_struct videobuf_vm_ops =
/* Allocated area consists on 3 parts:
struct video_buffer
struct <driver>_buffer (cx88_buffer, saa7134_buf, ...)
- struct videobuf_pci_sg_memory
+ struct videobuf_dma_sg_memory
*/
static void *__videobuf_alloc(size_t size)
@@ -153,21 +151,26 @@ static int __videobuf_iolock (struct videobuf_queue* q,
(unsigned long)mem->vmalloc,
pages << PAGE_SHIFT);
- /* It seems that some kernel versions need to do remap *after*
- the mmap() call
- */
- if (mem->vma) {
- int retval=remap_vmalloc_range(mem->vma, mem->vmalloc,0);
- kfree(mem->vma);
- mem->vma=NULL;
- if (retval<0) {
- dprintk(1,"mmap app bug: remap_vmalloc_range area %p error %d\n",
- mem->vmalloc,retval);
- return retval;
+ return 0;
+}
+
+static int __videobuf_mmap_setup(struct videobuf_queue *q,
+ struct videobuf_buffer *vb)
+{
+ int retval = 0;
+ BUG_ON(vb->memory != V4L2_MEMORY_MMAP);
+ if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ /* bsize == size since the buffer needs to be large enough to
+ * hold an entire frame, not the case in the read case for
+ * example*/
+ vb->size = vb->bsize;
+ retval = __videobuf_iolock(q, vb, NULL);
+ if (!retval) {
+ /* Don't IOLOCK later */
+ vb->state = VIDEOBUF_IDLE;
}
}
-
- return 0;
+ return retval;
}
static int __videobuf_sync(struct videobuf_queue *q,
@@ -240,15 +243,8 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
/* Try to remap memory */
retval=remap_vmalloc_range(vma, mem->vmalloc,0);
if (retval<0) {
- dprintk(1,"mmap: postponing remap_vmalloc_range\n");
-
- mem->vma=kmalloc(sizeof(*vma),GFP_KERNEL);
- if (!mem->vma) {
- kfree(map);
- q->bufs[first]->map=NULL;
- return -ENOMEM;
- }
- memcpy(mem->vma,vma,sizeof(*vma));
+ dprintk(1, "mmap: failed to remap_vmalloc_range\n");
+ return -EINVAL;
}
dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
@@ -316,6 +312,7 @@ static struct videobuf_qtype_ops qops = {
.alloc = __videobuf_alloc,
.iolock = __videobuf_iolock,
.sync = __videobuf_sync,
+ .mmap_setup = __videobuf_mmap_setup,
.mmap_free = __videobuf_mmap_free,
.mmap_mapper = __videobuf_mmap_mapper,
.video_copy_to_user = __videobuf_copy_to_user,