diff options
Diffstat (limited to 'include/linux/scatterlist.h')
-rw-r--r-- | include/linux/scatterlist.h | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 4bd6c06eb28e..2d8bdaef9611 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h | |||
@@ -231,6 +231,41 @@ size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents, | |||
231 | */ | 231 | */ |
232 | #define SG_MAX_SINGLE_ALLOC (PAGE_SIZE / sizeof(struct scatterlist)) | 232 | #define SG_MAX_SINGLE_ALLOC (PAGE_SIZE / sizeof(struct scatterlist)) |
233 | 233 | ||
234 | /* | ||
235 | * sg page iterator | ||
236 | * | ||
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 | ||
239 | * page and @piter->sg_pgoffset to the page's page offset within the sg. The | ||
240 | * iteration will stop either when a maximum number of sg entries was reached | ||
241 | * or a terminating sg (sg_last(sg) == true) was reached. | ||
242 | */ | ||
243 | struct sg_page_iter { | ||
244 | struct page *page; /* current page */ | ||
245 | struct scatterlist *sg; /* sg holding the page */ | ||
246 | unsigned int sg_pgoffset; /* page offset within the sg */ | ||
247 | |||
248 | /* these are internal states, keep away */ | ||
249 | unsigned int __nents; /* remaining sg entries */ | ||
250 | int __pg_advance; /* nr pages to advance at the | ||
251 | * next step */ | ||
252 | }; | ||
253 | |||
254 | bool __sg_page_iter_next(struct sg_page_iter *piter); | ||
255 | void __sg_page_iter_start(struct sg_page_iter *piter, | ||
256 | struct scatterlist *sglist, unsigned int nents, | ||
257 | unsigned long pgoffset); | ||
258 | |||
259 | /** | ||
260 | * for_each_sg_page - iterate over the pages of the given sg list | ||
261 | * @sglist: sglist to iterate over | ||
262 | * @piter: page iterator to hold current page, sg, sg_pgoffset | ||
263 | * @nents: maximum number of sg entries to iterate over | ||
264 | * @pgoffset: starting page offset | ||
265 | */ | ||
266 | #define for_each_sg_page(sglist, piter, nents, pgoffset) \ | ||
267 | for (__sg_page_iter_start((piter), (sglist), (nents), (pgoffset)); \ | ||
268 | __sg_page_iter_next(piter);) | ||
234 | 269 | ||
235 | /* | 270 | /* |
236 | * Mapping sg iterator | 271 | * Mapping sg iterator |
@@ -258,11 +293,11 @@ struct sg_mapping_iter { | |||
258 | void *addr; /* pointer to the mapped area */ | 293 | void *addr; /* pointer to the mapped area */ |
259 | size_t length; /* length of the mapped area */ | 294 | size_t length; /* length of the mapped area */ |
260 | size_t consumed; /* number of consumed bytes */ | 295 | size_t consumed; /* number of consumed bytes */ |
296 | struct sg_page_iter piter; /* page iterator */ | ||
261 | 297 | ||
262 | /* these are internal states, keep away */ | 298 | /* these are internal states, keep away */ |
263 | struct scatterlist *__sg; /* current entry */ | 299 | unsigned int __offset; /* offset within page */ |
264 | unsigned int __nents; /* nr of remaining entries */ | 300 | unsigned int __remaining; /* remaining bytes on page */ |
265 | unsigned int __offset; /* offset within sg */ | ||
266 | unsigned int __flags; | 301 | unsigned int __flags; |
267 | }; | 302 | }; |
268 | 303 | ||