| From 4099040eaaa4fe543c4e915b8cab51b1d843edee Mon Sep 17 00:00:00 2001 |
| From: "Lad, Prabhakar" <prabhakar.lad@ti.com> |
| Date: Fri, 22 Jun 2012 06:19:28 -0300 |
| Subject: media: videobuf-dma-contig: restore buffer mapping for uncached bufers |
| |
| From: "Lad, Prabhakar" <prabhakar.lad@ti.com> |
| |
| commit 4099040eaaa4fe543c4e915b8cab51b1d843edee upstream. |
| |
| from commit a8f3c203e19b702fa5e8e83a9b6fb3c5a6d1cce4 |
| restore the mapping scheme for uncached buffers, |
| which was changed in a common scheme for cached and uncached. |
| This apparently was wrong, and was probably intended only for cached buffers. |
| the fix fixes the crash observed while mapping uncached buffers. |
| |
| Signed-off-by: Lad, Prabhakar <prabhakar.lad@ti.com> |
| Signed-off-by: Hadli, Manjunath <manjunath.hadli@ti.com> |
| Acked-by: Federico Vaga <federico.vaga@gmail.com> |
| Acked-by: Hans Verkuil <hans.verkuil@cisco.com> |
| Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/media/video/videobuf-dma-contig.c | 53 ++++++++++++++++++------------ |
| 1 file changed, 32 insertions(+), 21 deletions(-) |
| |
| --- a/drivers/media/video/videobuf-dma-contig.c |
| +++ b/drivers/media/video/videobuf-dma-contig.c |
| @@ -359,32 +359,43 @@ static int __videobuf_mmap_mapper(struct |
| size = vma->vm_end - vma->vm_start; |
| size = (size < mem->size) ? size : mem->size; |
| |
| - if (!mem->cached) |
| + if (!mem->cached) { |
| vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| - |
| - pos = (unsigned long)mem->vaddr; |
| - |
| - while (size > 0) { |
| - page = virt_to_page((void *)pos); |
| - if (NULL == page) { |
| - dev_err(q->dev, "mmap: virt_to_page failed\n"); |
| - __videobuf_dc_free(q->dev, mem); |
| - goto error; |
| - } |
| - retval = vm_insert_page(vma, start, page); |
| + retval = remap_pfn_range(vma, vma->vm_start, |
| + mem->dma_handle >> PAGE_SHIFT, |
| + size, vma->vm_page_prot); |
| if (retval) { |
| - dev_err(q->dev, "mmap: insert failed with error %d\n", |
| - retval); |
| - __videobuf_dc_free(q->dev, mem); |
| + dev_err(q->dev, "mmap: remap failed with error %d. ", |
| + retval); |
| + dma_free_coherent(q->dev, mem->size, |
| + mem->vaddr, mem->dma_handle); |
| goto error; |
| } |
| - start += PAGE_SIZE; |
| - pos += PAGE_SIZE; |
| + } else { |
| + pos = (unsigned long)mem->vaddr; |
| + |
| + while (size > 0) { |
| + page = virt_to_page((void *)pos); |
| + if (NULL == page) { |
| + dev_err(q->dev, "mmap: virt_to_page failed\n"); |
| + __videobuf_dc_free(q->dev, mem); |
| + goto error; |
| + } |
| + retval = vm_insert_page(vma, start, page); |
| + if (retval) { |
| + dev_err(q->dev, "mmap: insert failed with error %d\n", |
| + retval); |
| + __videobuf_dc_free(q->dev, mem); |
| + goto error; |
| + } |
| + start += PAGE_SIZE; |
| + pos += PAGE_SIZE; |
| |
| - if (size > PAGE_SIZE) |
| - size -= PAGE_SIZE; |
| - else |
| - size = 0; |
| + if (size > PAGE_SIZE) |
| + size -= PAGE_SIZE; |
| + else |
| + size = 0; |
| + } |
| } |
| |
| vma->vm_ops = &videobuf_vm_ops; |