diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2010-03-28 08:09:05 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:57:54 -0400 |
commit | 0b62b73778554cd47480ea465f0b255cc63b4336 (patch) | |
tree | 880c3c5fc9b9ba75c65902da9dc77e8c97d3967d /drivers/media/video/videobuf-dma-sg.c | |
parent | 37111039c9521c751ce0597c129fe6d45ba72818 (diff) |
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: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/videobuf-dma-sg.c')
-rw-r--r-- | drivers/media/video/videobuf-dma-sg.c | 69 |
1 files changed, 33 insertions, 36 deletions
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 5c55bd392ea..1a7f3d3d2f9 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c | |||
@@ -549,22 +549,15 @@ static int __videobuf_sync(struct videobuf_queue *q, | |||
549 | } | 549 | } |
550 | 550 | ||
551 | static int __videobuf_mmap_mapper(struct videobuf_queue *q, | 551 | static int __videobuf_mmap_mapper(struct videobuf_queue *q, |
552 | struct vm_area_struct *vma) | 552 | struct videobuf_buffer *buf, |
553 | struct vm_area_struct *vma) | ||
553 | { | 554 | { |
554 | struct videobuf_dma_sg_memory *mem; | 555 | struct videobuf_dma_sg_memory *mem = buf->priv; |
555 | struct videobuf_mapping *map; | 556 | struct videobuf_mapping *map; |
556 | unsigned int first, last, size, i; | 557 | unsigned int first, last, size, i; |
557 | int retval; | 558 | int retval; |
558 | 559 | ||
559 | retval = -EINVAL; | 560 | retval = -EINVAL; |
560 | if (!(vma->vm_flags & VM_WRITE)) { | ||
561 | dprintk(1, "mmap app bug: PROT_WRITE please\n"); | ||
562 | goto done; | ||
563 | } | ||
564 | if (!(vma->vm_flags & VM_SHARED)) { | ||
565 | dprintk(1, "mmap app bug: MAP_SHARED please\n"); | ||
566 | goto done; | ||
567 | } | ||
568 | 561 | ||
569 | /* This function maintains backwards compatibility with V4L1 and will | 562 | /* This function maintains backwards compatibility with V4L1 and will |
570 | * map more than one buffer if the vma length is equal to the combined | 563 | * map more than one buffer if the vma length is equal to the combined |
@@ -574,44 +567,48 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, | |||
574 | * TODO: Allow drivers to specify if they support this mode | 567 | * TODO: Allow drivers to specify if they support this mode |
575 | */ | 568 | */ |
576 | 569 | ||
570 | BUG_ON(!mem); | ||
571 | MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); | ||
572 | |||
577 | /* look for first buffer to map */ | 573 | /* look for first buffer to map */ |
578 | for (first = 0; first < VIDEO_MAX_FRAME; first++) { | 574 | for (first = 0; first < VIDEO_MAX_FRAME; first++) { |
579 | if (NULL == q->bufs[first]) | 575 | if (buf == q->bufs[first]) { |
580 | continue; | 576 | size = PAGE_ALIGN(q->bufs[first]->bsize); |
581 | mem = q->bufs[first]->priv; | ||
582 | BUG_ON(!mem); | ||
583 | MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); | ||
584 | |||
585 | if (V4L2_MEMORY_MMAP != q->bufs[first]->memory) | ||
586 | continue; | ||
587 | if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT)) | ||
588 | break; | 577 | break; |
578 | } | ||
589 | } | 579 | } |
580 | |||
581 | /* paranoia, should never happen since buf is always valid. */ | ||
590 | if (VIDEO_MAX_FRAME == first) { | 582 | if (VIDEO_MAX_FRAME == first) { |
591 | dprintk(1, "mmap app bug: offset invalid [offset=0x%lx]\n", | 583 | dprintk(1, "mmap app bug: offset invalid [offset=0x%lx]\n", |
592 | (vma->vm_pgoff << PAGE_SHIFT)); | 584 | (vma->vm_pgoff << PAGE_SHIFT)); |
593 | goto done; | 585 | goto done; |
594 | } | 586 | } |
595 | 587 | ||
596 | /* look for last buffer to map */ | 588 | last = first; |
597 | for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) { | 589 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
598 | if (NULL == q->bufs[last]) | 590 | if (size != (vma->vm_end - vma->vm_start)) { |
599 | continue; | 591 | /* look for last buffer to map */ |
600 | if (V4L2_MEMORY_MMAP != q->bufs[last]->memory) | 592 | for (last = first + 1; last < VIDEO_MAX_FRAME; last++) { |
601 | continue; | 593 | if (NULL == q->bufs[last]) |
602 | if (q->bufs[last]->map) { | 594 | continue; |
603 | retval = -EBUSY; | 595 | if (V4L2_MEMORY_MMAP != q->bufs[last]->memory) |
596 | continue; | ||
597 | if (q->bufs[last]->map) { | ||
598 | retval = -EBUSY; | ||
599 | goto done; | ||
600 | } | ||
601 | size += PAGE_ALIGN(q->bufs[last]->bsize); | ||
602 | if (size == (vma->vm_end - vma->vm_start)) | ||
603 | break; | ||
604 | } | ||
605 | if (VIDEO_MAX_FRAME == last) { | ||
606 | dprintk(1, "mmap app bug: size invalid [size=0x%lx]\n", | ||
607 | (vma->vm_end - vma->vm_start)); | ||
604 | goto done; | 608 | goto done; |
605 | } | 609 | } |
606 | size += PAGE_ALIGN(q->bufs[last]->bsize); | ||
607 | if (size == (vma->vm_end - vma->vm_start)) | ||
608 | break; | ||
609 | } | ||
610 | if (VIDEO_MAX_FRAME == last) { | ||
611 | dprintk(1, "mmap app bug: size invalid [size=0x%lx]\n", | ||
612 | (vma->vm_end - vma->vm_start)); | ||
613 | goto done; | ||
614 | } | 610 | } |
611 | #endif | ||
615 | 612 | ||
616 | /* create mapping + update buffer list */ | 613 | /* create mapping + update buffer list */ |
617 | retval = -ENOMEM; | 614 | retval = -ENOMEM; |