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