aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2013-03-26 09:14:18 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-27 12:13:44 -0400
commit2db76d7c3c6db93058f983c8240f7c7c25e87ee6 (patch)
treea35f01706b353841b71645da050bc721c9f0467b /include/linux
parent693db1842d864ca2771e881127cdb4d09979758b (diff)
lib/scatterlist: sg_page_iter: support sg lists w/o backing pages
The i915 driver uses sg lists for memory without backing 'struct page' pages, similarly to other IO memory regions, setting only the DMA address for these. It does this, so that it can program the HW MMU tables in a uniform way both for sg lists with and without backing pages. Without a valid page pointer we can't call nth_page to get the current page in __sg_page_iter_next, so add a helper that relevant users can call separately. Also add a helper to get the DMA address of the current page (idea from Daniel). Convert all places in i915, to use the new API. Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/scatterlist.h28
1 files changed, 23 insertions, 5 deletions
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2d8bdaef9611..e96b9546c4c6 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -235,13 +235,13 @@ size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,
235 * sg page iterator 235 * sg page iterator
236 * 236 *
237 * Iterates over sg entries page-by-page. On each successful iteration, 237 * Iterates over sg entries page-by-page. On each successful iteration,
238 * @piter->page points to the current page, @piter->sg to the sg holding this 238 * you can call sg_page_iter_page(@piter) and sg_page_iter_dma_address(@piter)
239 * page and @piter->sg_pgoffset to the page's page offset within the sg. The 239 * to get the current page and its dma address. @piter->sg will point to the
240 * iteration will stop either when a maximum number of sg entries was reached 240 * sg holding this page and @piter->sg_pgoffset to the page's page offset
241 * or a terminating sg (sg_last(sg) == true) was reached. 241 * within the sg. The iteration will stop either when a maximum number of sg
242 * entries was reached or a terminating sg (sg_last(sg) == true) was reached.
242 */ 243 */
243struct sg_page_iter { 244struct sg_page_iter {
244 struct page *page; /* current page */
245 struct scatterlist *sg; /* sg holding the page */ 245 struct scatterlist *sg; /* sg holding the page */
246 unsigned int sg_pgoffset; /* page offset within the sg */ 246 unsigned int sg_pgoffset; /* page offset within the sg */
247 247
@@ -255,6 +255,24 @@ bool __sg_page_iter_next(struct sg_page_iter *piter);
255void __sg_page_iter_start(struct sg_page_iter *piter, 255void __sg_page_iter_start(struct sg_page_iter *piter,
256 struct scatterlist *sglist, unsigned int nents, 256 struct scatterlist *sglist, unsigned int nents,
257 unsigned long pgoffset); 257 unsigned long pgoffset);
258/**
259 * sg_page_iter_page - get the current page held by the page iterator
260 * @piter: page iterator holding the page
261 */
262static inline struct page *sg_page_iter_page(struct sg_page_iter *piter)
263{
264 return nth_page(sg_page(piter->sg), piter->sg_pgoffset);
265}
266
267/**
268 * sg_page_iter_dma_address - get the dma address of the current page held by
269 * the page iterator.
270 * @piter: page iterator holding the page
271 */
272static inline dma_addr_t sg_page_iter_dma_address(struct sg_page_iter *piter)
273{
274 return sg_dma_address(piter->sg) + (piter->sg_pgoffset << PAGE_SHIFT);
275}
258 276
259/** 277/**
260 * for_each_sg_page - iterate over the pages of the given sg list 278 * for_each_sg_page - iterate over the pages of the given sg list