On Tue, May 22, 2012 at 8:49 AM, Dave Airlie <airlied at gmail.com> wrote: > From: Dave Airlie <airlied at redhat.com> > > the ttm drivers need this currently, in order to get fault handling > working and efficient. > > It also allows addrs to be NULL for devices like udl. > > Signed-off-by: Dave Airlie <airlied at redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com> > --- > ?drivers/gpu/drm/drm_prime.c | ? 36 ++++++++++++++++++++++++++++++++++++ > ?include/drm/drmP.h ? ? ? ? ?| ? ?2 ++ > ?2 files changed, 38 insertions(+), 0 deletions(-) > > diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c > index 1bdf2b5..20dbf2c 100644 > --- a/drivers/gpu/drm/drm_prime.c > +++ b/drivers/gpu/drm/drm_prime.c > @@ -227,6 +227,42 @@ out: > ?} > ?EXPORT_SYMBOL(drm_prime_pages_to_sg); > > +/* export an sg table into an array of pages and addresses > + ? this is currently required by the TTM driver in order to do correct fault > + ? handling */ > +int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page > **pages, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?dma_addr_t *addrs, int max_pages) > +{ > + ? ? ? unsigned count; > + ? ? ? struct scatterlist *sg; > + ? ? ? struct page *page; > + ? ? ? u32 len, offset; > + ? ? ? int pg_index; > + ? ? ? dma_addr_t addr; > + > + ? ? ? pg_index = 0; > + ? ? ? for_each_sg(sgt->sgl, sg, sgt->nents, count) { > + ? ? ? ? ? ? ? len = sg->length; > + ? ? ? ? ? ? ? offset = sg->offset; > + ? ? ? ? ? ? ? page = sg_page(sg); > + ? ? ? ? ? ? ? addr = sg_dma_address(sg); > + > + ? ? ? ? ? ? ? while (len > 0) { > + ? ? ? ? ? ? ? ? ? ? ? if (WARN_ON(pg_index >= max_pages)) > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return -1; > + ? ? ? ? ? ? ? ? ? ? ? pages[pg_index] = page; > + ? ? ? ? ? ? ? ? ? ? ? if (addrs) > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? addrs[pg_index] = addr; > + > + ? ? ? ? ? ? ? ? ? ? ? page++; > + ? ? ? ? ? ? ? ? ? ? ? addr += PAGE_SIZE; > + ? ? ? ? ? ? ? ? ? ? ? len -= PAGE_SIZE; > + ? ? ? ? ? ? ? ? ? ? ? pg_index++; > + ? ? ? ? ? ? ? } > + ? ? ? } > + ? ? ? return 0; > +} > +EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays); > ?/* helper function to cleanup a GEM/prime object */ > ?void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) > ?{ > diff --git a/include/drm/drmP.h b/include/drm/drmP.h > index 15d9179..31ad880 100644 > --- a/include/drm/drmP.h > +++ b/include/drm/drmP.h > @@ -1558,6 +1558,8 @@ extern int drm_prime_handle_to_fd_ioctl(struct > drm_device *dev, void *data, > ?extern int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct drm_file *file_priv); > > +extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct > page **pages, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dma_addr_t *addrs, int max_pages); > ?extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int > nr_pages); > ?extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct > sg_table *sg); > > -- > 1.7.6 > > _______________________________________________ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel