[PATCH 1/7] drm/prime: introduce sg->pages/addr arrays helper
Dave Airlie
airlied at gmail.com
Tue May 22 05:49:58 PDT 2012
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>
---
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
More information about the dri-devel
mailing list