172,6 → 172,22 |
} |
|
/** |
* sg_unmark_end - Undo setting the end of the scatterlist |
* @sg: SG entryScatterlist |
* |
* Description: |
* Removes the termination marker from the given entry of the scatterlist. |
* |
**/ |
static inline void sg_unmark_end(struct scatterlist *sg) |
{ |
#ifdef CONFIG_DEBUG_SG |
BUG_ON(sg->sg_magic != SG_MAGIC); |
#endif |
sg->page_link &= ~0x02; |
} |
|
/** |
* sg_phys - Return physical address of an sg entry |
* @sg: SG entry |
* |
231,7 → 247,60 |
*/ |
#define SG_MAX_SINGLE_ALLOC (4*PAGE_SIZE / sizeof(struct scatterlist)) |
|
/* |
* sg page iterator |
* |
* Iterates over sg entries page-by-page. On each successful iteration, |
* you can call sg_page_iter_page(@piter) and sg_page_iter_dma_address(@piter) |
* to get the current page and its dma address. @piter->sg will point to the |
* sg holding this page and @piter->sg_pgoffset to the page's page offset |
* within the sg. The iteration will stop either when a maximum number of sg |
* entries was reached or a terminating sg (sg_last(sg) == true) was reached. |
*/ |
struct sg_page_iter { |
struct scatterlist *sg; /* sg holding the page */ |
unsigned int sg_pgoffset; /* page offset within the sg */ |
|
/* these are internal states, keep away */ |
unsigned int __nents; /* remaining sg entries */ |
int __pg_advance; /* nr pages to advance at the |
* next step */ |
}; |
|
bool __sg_page_iter_next(struct sg_page_iter *piter); |
void __sg_page_iter_start(struct sg_page_iter *piter, |
struct scatterlist *sglist, unsigned int nents, |
unsigned long pgoffset); |
/** |
* sg_page_iter_page - get the current page held by the page iterator |
* @piter: page iterator holding the page |
*/ |
static inline struct page *sg_page_iter_page(struct sg_page_iter *piter) |
{ |
return nth_page(sg_page(piter->sg), piter->sg_pgoffset); |
} |
|
/** |
* sg_page_iter_dma_address - get the dma address of the current page held by |
* the page iterator. |
* @piter: page iterator holding the page |
*/ |
static inline dma_addr_t sg_page_iter_dma_address(struct sg_page_iter *piter) |
{ |
return sg_dma_address(piter->sg) + (piter->sg_pgoffset << PAGE_SHIFT); |
} |
|
/** |
* for_each_sg_page - iterate over the pages of the given sg list |
* @sglist: sglist to iterate over |
* @piter: page iterator to hold current page, sg, sg_pgoffset |
* @nents: maximum number of sg entries to iterate over |
* @pgoffset: starting page offset |
*/ |
#define for_each_sg_page(sglist, piter, nents, pgoffset) \ |
for (__sg_page_iter_start((piter), (sglist), (nents), (pgoffset)); \ |
__sg_page_iter_next(piter);) |
|
/* |
* Mapping sg iterator |
* |
258,11 → 327,11 |
void *addr; /* pointer to the mapped area */ |
size_t length; /* length of the mapped area */ |
size_t consumed; /* number of consumed bytes */ |
struct sg_page_iter piter; /* page iterator */ |
|
/* these are internal states, keep away */ |
struct scatterlist *__sg; /* current entry */ |
unsigned int __nents; /* nr of remaining entries */ |
unsigned int __offset; /* offset within sg */ |
unsigned int __offset; /* offset within page */ |
unsigned int __remaining; /* remaining bytes on page */ |
unsigned int __flags; |
}; |
|