From: Lad, Prabhakar Date: Fri, 22 Jun 2012 09:19:28 +0000 (-0300) Subject: [media] videobuf-dma-contig: restore buffer mapping for uncached bufers X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=4099040eaaa4fe543c4e915b8cab51b1d843edee;p=linux-beck.git [media] videobuf-dma-contig: restore buffer mapping for uncached bufers 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 Signed-off-by: Hadli, Manjunath Acked-by: Federico Vaga Acked-by: Hans Verkuil Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 9b9a06fdd0f0..f68284655f20 100644 --- 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 videobuf_queue *q, 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;