drm: prime: use sgtable iterators in drm_prime_sg_to_page_addr_arrays()
authorMarek Szyprowski <m.szyprowski@samsung.com>
Fri, 8 May 2020 14:05:14 +0000 (16:05 +0200)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Thu, 10 Sep 2020 06:17:48 +0000 (08:17 +0200)
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: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
drivers/gpu/drm/drm_prime.c

index 4ed5ed1..c5e796d 100644 (file)
@@ -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,
                                     dma_addr_t *addrs, int max_entries)
 {
-       unsigned count;
-       struct scatterlist *sg;
-       struct page *page;
-       u32 page_len, page_index;
-       dma_addr_t addr;
-       u32 dma_len, dma_index;
-
-       /*
-        * 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))
+       struct sg_dma_page_iter dma_iter;
+       struct sg_page_iter page_iter;
+       struct page **p = pages;
+       dma_addr_t *a = addrs;
+
+       if (pages) {
+               for_each_sgtable_page(sgt, &page_iter, 0) {
+                       if (WARN_ON(p - pages >= max_entries))
                                return -1;
-                       pages[page_index] = page;
-                       page++;
-                       page_len -= PAGE_SIZE;
-                       page_index++;
+                       *p++ = sg_page_iter_page(&page_iter);
                }
-               while (addrs && dma_len > 0) {
-                       if (WARN_ON(dma_index >= max_entries))
+       }
+       if (addrs) {
+               for_each_sgtable_dma_page(sgt, &dma_iter, 0) {
+                       if (WARN_ON(a - addrs >= max_entries))
                                return -1;
-                       addrs[dma_index] = addr;
-                       addr += PAGE_SIZE;
-                       dma_len -= PAGE_SIZE;
-                       dma_index++;
+                       *a++ = sg_page_iter_dma_address(&dma_iter);
                }
        }
+
        return 0;
 }
 EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays);