diff options
Diffstat (limited to 'linux/drivers')
-rw-r--r-- | linux/drivers/media/video/videobuf-core.c | 29 | ||||
-rw-r--r-- | linux/drivers/media/video/videobuf-vmalloc.c | 43 |
2 files changed, 33 insertions, 39 deletions
diff --git a/linux/drivers/media/video/videobuf-core.c b/linux/drivers/media/video/videobuf-core.c index 47af78a06..994dd7ab3 100644 --- a/linux/drivers/media/video/videobuf-core.c +++ b/linux/drivers/media/video/videobuf-core.c @@ -92,25 +92,17 @@ int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, MAGIC_CHECK(vb->magic, MAGIC_BUFFER); MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); - /* This is required to avoid OOPS on some cases, - since mmap_mapper() method should be called before _iolock. - On some cases, the mmap_mapper() is called only after scheduling. - */ - if (vb->memory == V4L2_MEMORY_MMAP) { - wait_event_timeout(vb->done, q->is_mmapped, - msecs_to_jiffies(100)); - if (!q->is_mmapped) { - printk(KERN_ERR - "Error: mmap_mapper() never called!\n"); - return -EINVAL; - } - } - return CALL(q, iolock, q, vb, fbuf); } /* --------------------------------------------------------------------- */ +static int videobuf_mmap_setup_default(struct videobuf_queue *q, + struct videobuf_buffer *vb) +{ + return 0; +} + void videobuf_queue_core_init(struct videobuf_queue *q, struct videobuf_queue_ops *ops, @@ -132,6 +124,9 @@ void videobuf_queue_core_init(struct videobuf_queue *q, q->priv_data = priv; q->int_ops = int_ops; + if (!q->int_ops->mmap_setup) + q->int_ops->mmap_setup = videobuf_mmap_setup_default; + /* All buffer operations are mandatory */ BUG_ON(!q->ops->buf_setup); BUG_ON(!q->ops->buf_prepare); @@ -304,8 +299,6 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) rc = CALL(q, mmap_free, q); - q->is_mmapped = 0; - if (rc < 0) return rc; @@ -357,6 +350,9 @@ static int __videobuf_mmap_setup(struct videobuf_queue *q, switch (memory) { case V4L2_MEMORY_MMAP: q->bufs[i]->boff = bsize * i; + err = q->int_ops->mmap_setup(q, q->bufs[i]); + if (err) + break; break; case V4L2_MEMORY_USERPTR: case V4L2_MEMORY_OVERLAY: @@ -1028,7 +1024,6 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, mutex_lock(&q->vb_lock); retval = CALL(q, mmap_mapper, q, vma); - q->is_mmapped = 1; mutex_unlock(&q->vb_lock); return retval; diff --git a/linux/drivers/media/video/videobuf-vmalloc.c b/linux/drivers/media/video/videobuf-vmalloc.c index 3ce1c92fc..3bc7308af 100644 --- a/linux/drivers/media/video/videobuf-vmalloc.c +++ b/linux/drivers/media/video/videobuf-vmalloc.c @@ -152,21 +152,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, @@ -239,15 +244,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", @@ -315,6 +313,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, |