Commit 0552daac authored by Marek Szyprowski's avatar Marek Szyprowski

drm: prime: use sgtable iterators in drm_prime_sg_to_page_addr_arrays()

Replace the current hand-crafted code for extracting pages and DMA
addresses from the given scatterlist by the much more robust
code based on the generic scatterlist iterators and recently
introduced sg_table-based wrappers. The resulting code is simple and
easy to understand, so the comment describing the old code is no
longer needed.
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: default avatarAndrzej Hajda <a.hajda@samsung.com>
Reviewed-by: default avatarRobin Murphy <robin.murphy@arm.com>
parent d46e7ae2
...@@ -990,45 +990,26 @@ EXPORT_SYMBOL(drm_gem_prime_import); ...@@ -990,45 +990,26 @@ EXPORT_SYMBOL(drm_gem_prime_import);
int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
dma_addr_t *addrs, int max_entries) dma_addr_t *addrs, int max_entries)
{ {
unsigned count; struct sg_dma_page_iter dma_iter;
struct scatterlist *sg; struct sg_page_iter page_iter;
struct page *page; struct page **p = pages;
u32 page_len, page_index; dma_addr_t *a = addrs;
dma_addr_t addr;
u32 dma_len, dma_index; if (pages) {
for_each_sgtable_page(sgt, &page_iter, 0) {
/* if (WARN_ON(p - pages >= max_entries))
* Scatterlist elements contains both pages and DMA addresses, but
* one shoud not assume 1:1 relation between them. The sg->length is
* the size of the physical memory chunk described by the sg->page,
* while sg_dma_len(sg) is the size of the DMA (IO virtual) chunk
* described by the sg_dma_address(sg).
*/
page_index = 0;
dma_index = 0;
for_each_sg(sgt->sgl, sg, sgt->nents, count) {
page_len = sg->length;
page = sg_page(sg);
dma_len = sg_dma_len(sg);
addr = sg_dma_address(sg);
while (pages && page_len > 0) {
if (WARN_ON(page_index >= max_entries))
return -1; return -1;
pages[page_index] = page; *p++ = sg_page_iter_page(&page_iter);
page++; }
page_len -= PAGE_SIZE;
page_index++;
} }
while (addrs && dma_len > 0) { if (addrs) {
if (WARN_ON(dma_index >= max_entries)) for_each_sgtable_dma_page(sgt, &dma_iter, 0) {
if (WARN_ON(a - addrs >= max_entries))
return -1; return -1;
addrs[dma_index] = addr; *a++ = sg_page_iter_dma_address(&dma_iter);
addr += PAGE_SIZE;
dma_len -= PAGE_SIZE;
dma_index++;
} }
} }
return 0; return 0;
} }
EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays); EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment