From 642f149031d70415d9318b919d50b71e4724adbd Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 24 Oct 2007 11:20:47 +0200 Subject: SG: Change sg_set_page() to take length and offset argument Most drivers need to set length and offset as well, so may as well fold those three lines into one. Add sg_assign_page() for those two locations that only needed to set the page, where the offset/length is set outside of the function context. Signed-off-by: Jens Axboe --- include/linux/scatterlist.h | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index df7ddcee7c4b..809b2ac2e37e 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -26,18 +26,16 @@ #define SG_MAGIC 0x87654321 /** - * sg_set_page - Set sg entry to point at given page - * @sg: SG entry - * @page: The page + * sg_assign_page - Assign a given page to an SG entry + * @sg: SG entry + * @page: The page * * Description: - * Use this function to set an sg entry pointing at a page, never assign - * the page directly. We encode sg table information in the lower bits - * of the page pointer. See sg_page() for looking up the page belonging - * to an sg entry. + * Assign page to sg entry. Also see sg_set_page(), the most commonly used + * variant. * **/ -static inline void sg_set_page(struct scatterlist *sg, struct page *page) +static inline void sg_assign_page(struct scatterlist *sg, struct page *page) { unsigned long page_link = sg->page_link & 0x3; @@ -52,6 +50,28 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page) 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 + * the page directly. We encode sg table information in the lower bits + * of the page pointer. See sg_page() for looking up the page belonging + * to an sg entry. + * + **/ +static inline void sg_set_page(struct scatterlist *sg, struct page *page, + unsigned int len, unsigned int offset) +{ + sg_assign_page(sg, page); + sg->offset = offset; + sg->length = len; +} + #define sg_page(sg) ((struct page *) ((sg)->page_link & ~0x3)) /** @@ -64,9 +84,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)); } /* -- cgit v1.2.2 From 85cdffcde0b6b831a06422413300d0f5c0e608c3 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Thu, 25 Oct 2007 09:55:05 +0200 Subject: fix sg_phys to use dma_addr_t x86_32 CONFIG_HIGHMEM64G with 5GB RAM hung when booting, after issuing some "request_module: runaway loop modprobe binfmt-0000" messages in trying to exec /sbin/init. The binprm buf doesn't see the right ".ELF" header because sg_phys() is providing the wrong physical addresses for high pages: a 32-bit unsigned long is too small in this case, we need to use dma_addr_t. Signed-off-by: Hugh Dickins Signed-off-by: Jens Axboe --- include/linux/scatterlist.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 809b2ac2e37e..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 @@ -255,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; } -- cgit v1.2.2