X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=include%2Flinux%2Fscatterlist.h;h=45712317138973ad8147ed0567c30bb4d62da55a;hb=7f1495745347bc2cb9cc4f50d0a889caeb71f1f1;hp=c6136e8a7f58fcb561ffc042b501e7a9f554c1a1;hpb=18dabf473e15850c0dbc8ff13ac1e2806d542c15;p=pandora-kernel.git diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index c6136e8a7f58..457123171389 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -1,6 +1,7 @@ #ifndef _LINUX_SCATTERLIST_H #define _LINUX_SCATTERLIST_H +#include #include #include #include @@ -23,10 +24,39 @@ * */ +#define SG_MAGIC 0x87654321 + +/** + * sg_assign_page - Assign a given page to an SG entry + * @sg: SG entry + * @page: The page + * + * Description: + * Assign page to sg entry. Also see sg_set_page(), the most commonly used + * variant. + * + **/ +static inline void sg_assign_page(struct scatterlist *sg, struct page *page) +{ + unsigned long page_link = sg->page_link & 0x3; + + /* + * In order for the low bit stealing approach to work, pages + * must be aligned at a 32-bit boundary as a minimum. + */ + BUG_ON((unsigned long) page & 0x03); +#ifdef CONFIG_DEBUG_SG + BUG_ON(sg->sg_magic != SG_MAGIC); +#endif + sg->page_link = page_link | (unsigned long) page; +} + /** * sg_set_page - Set sg entry to point at given page * @sg: SG entry * @page: The page + * @len: Length of data + * @offset: Offset into page * * Description: * Use this function to set an sg entry pointing at a page, never assign @@ -35,11 +65,12 @@ * to an sg entry. * **/ -static inline void sg_set_page(struct scatterlist *sg, struct page *page) +static inline void sg_set_page(struct scatterlist *sg, struct page *page, + unsigned int len, unsigned int offset) { - unsigned long page_link = sg->page_link & 0x3; - - sg->page_link = page_link | (unsigned long) page; + sg_assign_page(sg, page); + sg->offset = offset; + sg->length = len; } #define sg_page(sg) ((struct page *) ((sg)->page_link & ~0x3)) @@ -54,9 +85,7 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page) static inline void sg_set_buf(struct scatterlist *sg, const void *buf, unsigned int buflen) { - sg_set_page(sg, virt_to_page(buf)); - sg->offset = offset_in_page(buf); - sg->length = buflen; + sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); } /* @@ -81,6 +110,9 @@ static inline void sg_set_buf(struct scatterlist *sg, const void *buf, **/ static inline struct scatterlist *sg_next(struct scatterlist *sg) { +#ifdef CONFIG_DEBUG_SG + BUG_ON(sg->sg_magic != SG_MAGIC); +#endif if (sg_is_last(sg)) return NULL; @@ -123,6 +155,10 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl, for_each_sg(sgl, sg, nents, i) ret = sg; +#endif +#ifdef CONFIG_DEBUG_SG + BUG_ON(sgl[0].sg_magic != SG_MAGIC); + BUG_ON(!sg_is_last(ret)); #endif return ret; } @@ -180,6 +216,9 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf, unsigned int buflen) { memset(sg, 0, sizeof(*sg)); +#ifdef CONFIG_DEBUG_SG + sg->sg_magic = SG_MAGIC; +#endif sg_mark_end(sg, 1); sg_set_buf(sg, buf, buflen); } @@ -198,6 +237,13 @@ static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents) { memset(sgl, 0, sizeof(*sgl) * nents); sg_mark_end(sgl, nents); +#ifdef CONFIG_DEBUG_SG + { + int i; + for (i = 0; i < nents; i++) + sgl[i].sg_magic = SG_MAGIC; + } +#endif } /** @@ -210,7 +256,7 @@ static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents) * on the sg page. * **/ -static inline unsigned long sg_phys(struct scatterlist *sg) +static inline dma_addr_t sg_phys(struct scatterlist *sg) { return page_to_phys(sg_page(sg)) + sg->offset; }