[PATCH] drm: exynos: fix for mapping of dma buffers

2012-11-06 Thread Inki Dae
Applied.

Thanks,
Inki Dae


2012/11/6 Rahul Sharma 

> This patch fixes the problem of mapping contigous and non contigous dma
> buffers.
>
> Currently page struct is calculated from the buf->dma_addr which is not the
> physical address. It is replaced by buf->pages which points to the page
> struct
> of the first page of contigous memory chunk. This gives the correct page
> frame
> number for mapping.
>
> Non-contigous dma buffers are described using SG table and SG lists. Each
> valid SG List is pointing to a single page or group of pages which are
> physically contigous. Current implementation just maps the first page of
> each
> SG List and leave the other pages unmapped, leading to a crash. Given
> solution
> finds the page struct for the faulting page through parsing SG table and
> map it.
>
> Signed-off-by: Rahul Sharma 
> ---
>  drivers/gpu/drm/exynos/exynos_drm_gem.c |   28
> +---
>  1 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> index 8cb6824..50d73f1 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> @@ -95,15 +95,37 @@ static int exynos_drm_gem_map_buf(struct
> drm_gem_object *obj,
>  {
> struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
> struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
> +   struct scatterlist *sgl;
> unsigned long pfn;
> +   int i;
>
> if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
> +   if (!buf->sgt)
> +   return -EINTR;
> +
> +   sgl = buf->sgt->sgl;
> +   for_each_sg(buf->sgt->sgl, sgl, buf->sgt->nents, i) {
> +   if (!sgl) {
> +   DRM_ERROR("invalid SG table\n");
> +   return -EINTR;
> +   }
> +   if (page_offset < (sgl->length >> PAGE_SHIFT))
> +   break;
> +   page_offset -=  (sgl->length >> PAGE_SHIFT);
> +   }
> +
> +   if (i >= buf->sgt->nents) {
> +   DRM_ERROR("invalid page offset\n");
> +   return -EINVAL;
> +   }
> +
> +   pfn = __phys_to_pfn(sg_phys(sgl)) + page_offset;
> +   } else {
> if (!buf->pages)
> return -EINTR;
>
> -   pfn = page_to_pfn(buf->pages[page_offset++]);
> -   } else
> -   pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset;
> +   pfn = page_to_pfn(buf->pages[0]) + page_offset;
> +   }
>
> return vm_insert_mixed(vma, f_vaddr, pfn);
>  }
> --
> 1.7.0.4
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
-- next part --
An HTML attachment was scrubbed...
URL: 



[PATCH] drm: exynos: fix for mapping of dma buffers

2012-11-05 Thread Rahul Sharma
This patch fixes the problem of mapping contigous and non contigous dma buffers.

Currently page struct is calculated from the buf->dma_addr which is not the
physical address. It is replaced by buf->pages which points to the page struct
of the first page of contigous memory chunk. This gives the correct page frame
number for mapping.

Non-contigous dma buffers are described using SG table and SG lists. Each
valid SG List is pointing to a single page or group of pages which are
physically contigous. Current implementation just maps the first page of each
SG List and leave the other pages unmapped, leading to a crash. Given solution
finds the page struct for the faulting page through parsing SG table and map it.

Signed-off-by: Rahul Sharma 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c |   28 +---
 1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 8cb6824..50d73f1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -95,15 +95,37 @@ static int exynos_drm_gem_map_buf(struct drm_gem_object 
*obj,
 {
struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
+   struct scatterlist *sgl;
unsigned long pfn;
+   int i;

if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
+   if (!buf->sgt)
+   return -EINTR;
+
+   sgl = buf->sgt->sgl;
+   for_each_sg(buf->sgt->sgl, sgl, buf->sgt->nents, i) {
+   if (!sgl) {
+   DRM_ERROR("invalid SG table\n");
+   return -EINTR;
+   }
+   if (page_offset < (sgl->length >> PAGE_SHIFT))
+   break;
+   page_offset -=  (sgl->length >> PAGE_SHIFT);
+   }
+
+   if (i >= buf->sgt->nents) {
+   DRM_ERROR("invalid page offset\n");
+   return -EINVAL;
+   }
+
+   pfn = __phys_to_pfn(sg_phys(sgl)) + page_offset;
+   } else {
if (!buf->pages)
return -EINTR;

-   pfn = page_to_pfn(buf->pages[page_offset++]);
-   } else
-   pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset;
+   pfn = page_to_pfn(buf->pages[0]) + page_offset;
+   }

return vm_insert_mixed(vma, f_vaddr, pfn);
 }
-- 
1.7.0.4



[PATCH] drm: exynos: fix for mapping of dma buffers

2012-11-05 Thread Rahul Sharma
This patch fixes the problem of mapping contigous and non contigous dma buffers.

Currently page struct is calculated from the buf-dma_addr which is not the
physical address. It is replaced by buf-pages which points to the page struct
of the first page of contigous memory chunk. This gives the correct page frame
number for mapping.

Non-contigous dma buffers are described using SG table and SG lists. Each
valid SG List is pointing to a single page or group of pages which are
physically contigous. Current implementation just maps the first page of each
SG List and leave the other pages unmapped, leading to a crash. Given solution
finds the page struct for the faulting page through parsing SG table and map it.

Signed-off-by: Rahul Sharma rahul.sha...@samsung.com
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c |   28 +---
 1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 8cb6824..50d73f1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -95,15 +95,37 @@ static int exynos_drm_gem_map_buf(struct drm_gem_object 
*obj,
 {
struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
struct exynos_drm_gem_buf *buf = exynos_gem_obj-buffer;
+   struct scatterlist *sgl;
unsigned long pfn;
+   int i;
 
if (exynos_gem_obj-flags  EXYNOS_BO_NONCONTIG) {
+   if (!buf-sgt)
+   return -EINTR;
+
+   sgl = buf-sgt-sgl;
+   for_each_sg(buf-sgt-sgl, sgl, buf-sgt-nents, i) {
+   if (!sgl) {
+   DRM_ERROR(invalid SG table\n);
+   return -EINTR;
+   }
+   if (page_offset  (sgl-length  PAGE_SHIFT))
+   break;
+   page_offset -=  (sgl-length  PAGE_SHIFT);
+   }
+
+   if (i = buf-sgt-nents) {
+   DRM_ERROR(invalid page offset\n);
+   return -EINVAL;
+   }
+
+   pfn = __phys_to_pfn(sg_phys(sgl)) + page_offset;
+   } else {
if (!buf-pages)
return -EINTR;
 
-   pfn = page_to_pfn(buf-pages[page_offset++]);
-   } else
-   pfn = (buf-dma_addr  PAGE_SHIFT) + page_offset;
+   pfn = page_to_pfn(buf-pages[0]) + page_offset;
+   }
 
return vm_insert_mixed(vma, f_vaddr, pfn);
 }
-- 
1.7.0.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm: exynos: fix for mapping of dma buffers

2012-11-05 Thread Inki Dae
Applied.

Thanks,
Inki Dae


2012/11/6 Rahul Sharma rahul.sha...@samsung.com

 This patch fixes the problem of mapping contigous and non contigous dma
 buffers.

 Currently page struct is calculated from the buf-dma_addr which is not the
 physical address. It is replaced by buf-pages which points to the page
 struct
 of the first page of contigous memory chunk. This gives the correct page
 frame
 number for mapping.

 Non-contigous dma buffers are described using SG table and SG lists. Each
 valid SG List is pointing to a single page or group of pages which are
 physically contigous. Current implementation just maps the first page of
 each
 SG List and leave the other pages unmapped, leading to a crash. Given
 solution
 finds the page struct for the faulting page through parsing SG table and
 map it.

 Signed-off-by: Rahul Sharma rahul.sha...@samsung.com
 ---
  drivers/gpu/drm/exynos/exynos_drm_gem.c |   28
 +---
  1 files changed, 25 insertions(+), 3 deletions(-)

 diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c
 b/drivers/gpu/drm/exynos/exynos_drm_gem.c
 index 8cb6824..50d73f1 100644
 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
 +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
 @@ -95,15 +95,37 @@ static int exynos_drm_gem_map_buf(struct
 drm_gem_object *obj,
  {
 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
 struct exynos_drm_gem_buf *buf = exynos_gem_obj-buffer;
 +   struct scatterlist *sgl;
 unsigned long pfn;
 +   int i;

 if (exynos_gem_obj-flags  EXYNOS_BO_NONCONTIG) {
 +   if (!buf-sgt)
 +   return -EINTR;
 +
 +   sgl = buf-sgt-sgl;
 +   for_each_sg(buf-sgt-sgl, sgl, buf-sgt-nents, i) {
 +   if (!sgl) {
 +   DRM_ERROR(invalid SG table\n);
 +   return -EINTR;
 +   }
 +   if (page_offset  (sgl-length  PAGE_SHIFT))
 +   break;
 +   page_offset -=  (sgl-length  PAGE_SHIFT);
 +   }
 +
 +   if (i = buf-sgt-nents) {
 +   DRM_ERROR(invalid page offset\n);
 +   return -EINVAL;
 +   }
 +
 +   pfn = __phys_to_pfn(sg_phys(sgl)) + page_offset;
 +   } else {
 if (!buf-pages)
 return -EINTR;

 -   pfn = page_to_pfn(buf-pages[page_offset++]);
 -   } else
 -   pfn = (buf-dma_addr  PAGE_SHIFT) + page_offset;
 +   pfn = page_to_pfn(buf-pages[0]) + page_offset;
 +   }

 return vm_insert_mixed(vma, f_vaddr, pfn);
  }
 --
 1.7.0.4

 ___
 dri-devel mailing list
 dri-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/dri-devel

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel