Add a helper to walk through a scatter list a page at a time. Needed by upcoming patches fixing the scatter list walking logic in the i915 driver. Signed-off-by: Imre Deak <imre.deak at intel.com> --- include/drm/drmP.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fad21c9..0c0c213 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1578,6 +1578,50 @@ extern int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, extern int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request); extern int drm_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv); +struct drm_sg_iter { + struct scatterlist *sg; + int sg_offset; + struct page *page; +}; + +static inline int +__drm_sg_iter_seek(struct drm_sg_iter *iter) +{ + while (iter->sg && iter->sg_offset >= iter->sg->length) { + iter->sg_offset -= iter->sg->length; + iter->sg = sg_next(iter->sg); + } + + return iter->sg ? 0 : -1; +} + +static inline struct page * +drm_sg_iter_next(struct drm_sg_iter *iter) +{ + struct page *page; + + if (__drm_sg_iter_seek(iter)) + return NULL; + + page = nth_page(sg_page(iter->sg), iter->sg_offset >> PAGE_SHIFT); + iter->sg_offset = (iter->sg_offset + PAGE_SIZE) & PAGE_MASK; + + return page; +} + +static inline struct page * +drm_sg_iter_start(struct drm_sg_iter *iter, struct scatterlist *sg, + unsigned long offset) +{ + iter->sg = sg; + iter->sg_offset = offset; + + return drm_sg_iter_next(iter); +} + +#define drm_for_each_sg_page(iter, sg, pgoffset) \ + for ((iter)->page = drm_sg_iter_start((iter), (sg), (pgoffset));\ + (iter)->page; (iter)->page = drm_sg_iter_next(iter)) /* ATI PCIGART support (ati_pcigart.h) */ extern int drm_ati_pcigart_init(struct drm_device *dev, -- 1.7.10.4