diff options
Diffstat (limited to 'include')
25 files changed, 269 insertions, 52 deletions
diff --git a/include/asm-alpha/scatterlist.h b/include/asm-alpha/scatterlist.h index 917365405e83..440747ca6349 100644 --- a/include/asm-alpha/scatterlist.h +++ b/include/asm-alpha/scatterlist.h | |||
| @@ -5,7 +5,10 @@ | |||
| 5 | #include <asm/types.h> | 5 | #include <asm/types.h> |
| 6 | 6 | ||
| 7 | struct scatterlist { | 7 | struct scatterlist { |
| 8 | struct page *page; | 8 | #ifdef CONFIG_DEBUG_SG |
| 9 | unsigned long sg_magic; | ||
| 10 | #endif | ||
| 11 | unsigned long page_link; | ||
| 9 | unsigned int offset; | 12 | unsigned int offset; |
| 10 | 13 | ||
| 11 | unsigned int length; | 14 | unsigned int length; |
diff --git a/include/asm-arm/scatterlist.h b/include/asm-arm/scatterlist.h index de2f65eb42ed..ca0a37d03400 100644 --- a/include/asm-arm/scatterlist.h +++ b/include/asm-arm/scatterlist.h | |||
| @@ -5,7 +5,10 @@ | |||
| 5 | #include <asm/types.h> | 5 | #include <asm/types.h> |
| 6 | 6 | ||
| 7 | struct scatterlist { | 7 | struct scatterlist { |
| 8 | struct page *page; /* buffer page */ | 8 | #ifdef CONFIG_DEBUG_SG |
| 9 | unsigned long sg_magic; | ||
| 10 | #endif | ||
| 11 | unsigned long page_link; | ||
| 9 | unsigned int offset; /* buffer offset */ | 12 | unsigned int offset; /* buffer offset */ |
| 10 | dma_addr_t dma_address; /* dma address */ | 13 | dma_addr_t dma_address; /* dma address */ |
| 11 | unsigned int length; /* length */ | 14 | unsigned int length; /* length */ |
diff --git a/include/asm-avr32/scatterlist.h b/include/asm-avr32/scatterlist.h index c6d5ce3b3a25..377320e3bd17 100644 --- a/include/asm-avr32/scatterlist.h +++ b/include/asm-avr32/scatterlist.h | |||
| @@ -4,7 +4,10 @@ | |||
| 4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
| 5 | 5 | ||
| 6 | struct scatterlist { | 6 | struct scatterlist { |
| 7 | struct page *page; | 7 | #ifdef CONFIG_DEBUG_SG |
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 10 | unsigned long page_link; | ||
| 8 | unsigned int offset; | 11 | unsigned int offset; |
| 9 | dma_addr_t dma_address; | 12 | dma_addr_t dma_address; |
| 10 | unsigned int length; | 13 | unsigned int length; |
diff --git a/include/asm-blackfin/scatterlist.h b/include/asm-blackfin/scatterlist.h index 60e07b92044c..32128d53469b 100644 --- a/include/asm-blackfin/scatterlist.h +++ b/include/asm-blackfin/scatterlist.h | |||
| @@ -4,7 +4,10 @@ | |||
| 4 | #include <linux/mm.h> | 4 | #include <linux/mm.h> |
| 5 | 5 | ||
| 6 | struct scatterlist { | 6 | struct scatterlist { |
| 7 | struct page *page; | 7 | #ifdef CONFIG_DEBUG_SG |
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 10 | unsigned long page_link; | ||
| 8 | unsigned int offset; | 11 | unsigned int offset; |
| 9 | dma_addr_t dma_address; | 12 | dma_addr_t dma_address; |
| 10 | unsigned int length; | 13 | unsigned int length; |
diff --git a/include/asm-cris/scatterlist.h b/include/asm-cris/scatterlist.h index 4bdc44c4ac3d..faff53ad1f96 100644 --- a/include/asm-cris/scatterlist.h +++ b/include/asm-cris/scatterlist.h | |||
| @@ -2,11 +2,14 @@ | |||
| 2 | #define __ASM_CRIS_SCATTERLIST_H | 2 | #define __ASM_CRIS_SCATTERLIST_H |
| 3 | 3 | ||
| 4 | struct scatterlist { | 4 | struct scatterlist { |
| 5 | #ifdef CONFIG_DEBUG_SG | ||
| 6 | unsigned long sg_magic; | ||
| 7 | #endif | ||
| 5 | char * address; /* Location data is to be transferred to */ | 8 | char * address; /* Location data is to be transferred to */ |
| 6 | unsigned int length; | 9 | unsigned int length; |
| 7 | 10 | ||
| 8 | /* The following is i386 highmem junk - not used by us */ | 11 | /* The following is i386 highmem junk - not used by us */ |
| 9 | struct page * page; /* Location for highmem page, if any */ | 12 | unsigned long page_link; |
| 10 | unsigned int offset;/* for highmem, page offset */ | 13 | unsigned int offset;/* for highmem, page offset */ |
| 11 | 14 | ||
| 12 | }; | 15 | }; |
diff --git a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h index 8e827fa853f1..f7da007b763c 100644 --- a/include/asm-frv/scatterlist.h +++ b/include/asm-frv/scatterlist.h | |||
| @@ -22,7 +22,10 @@ | |||
| 22 | * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens | 22 | * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens |
| 23 | */ | 23 | */ |
| 24 | struct scatterlist { | 24 | struct scatterlist { |
| 25 | struct page *page; /* Location for highmem page, if any */ | 25 | #ifdef CONFIG_DEBUG_SG |
| 26 | unsigned long sg_magic; | ||
| 27 | #endif | ||
| 28 | unsigned long page_link; | ||
| 26 | unsigned int offset; /* for highmem, page offset */ | 29 | unsigned int offset; /* for highmem, page offset */ |
| 27 | 30 | ||
| 28 | dma_addr_t dma_address; | 31 | dma_addr_t dma_address; |
diff --git a/include/asm-h8300/scatterlist.h b/include/asm-h8300/scatterlist.h index 985fdf54eaca..d3ecdd87ac90 100644 --- a/include/asm-h8300/scatterlist.h +++ b/include/asm-h8300/scatterlist.h | |||
| @@ -4,7 +4,10 @@ | |||
| 4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
| 5 | 5 | ||
| 6 | struct scatterlist { | 6 | struct scatterlist { |
| 7 | struct page *page; | 7 | #ifdef CONFIG_DEBUG_SG |
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 10 | unsigned long page_link; | ||
| 8 | unsigned int offset; | 11 | unsigned int offset; |
| 9 | dma_addr_t dma_address; | 12 | dma_addr_t dma_address; |
| 10 | unsigned int length; | 13 | unsigned int length; |
diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h index 7d5234d50312..d6f57874041d 100644 --- a/include/asm-ia64/scatterlist.h +++ b/include/asm-ia64/scatterlist.h | |||
| @@ -9,7 +9,10 @@ | |||
| 9 | #include <asm/types.h> | 9 | #include <asm/types.h> |
| 10 | 10 | ||
| 11 | struct scatterlist { | 11 | struct scatterlist { |
| 12 | struct page *page; | 12 | #ifdef CONFIG_DEBUG_SG |
| 13 | unsigned long sg_magic; | ||
| 14 | #endif | ||
| 15 | unsigned long page_link; | ||
| 13 | unsigned int offset; | 16 | unsigned int offset; |
| 14 | unsigned int length; /* buffer length */ | 17 | unsigned int length; /* buffer length */ |
| 15 | 18 | ||
diff --git a/include/asm-m32r/scatterlist.h b/include/asm-m32r/scatterlist.h index 352415ff5eb9..1ed372c73d0b 100644 --- a/include/asm-m32r/scatterlist.h +++ b/include/asm-m32r/scatterlist.h | |||
| @@ -4,9 +4,12 @@ | |||
| 4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
| 5 | 5 | ||
| 6 | struct scatterlist { | 6 | struct scatterlist { |
| 7 | #ifdef CONFIG_DEBUG_SG | ||
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 7 | char * address; /* Location data is to be transferred to, NULL for | 10 | char * address; /* Location data is to be transferred to, NULL for |
| 8 | * highmem page */ | 11 | * highmem page */ |
| 9 | struct page * page; /* Location for highmem page, if any */ | 12 | unsigned long page_link; |
| 10 | unsigned int offset;/* for highmem, page offset */ | 13 | unsigned int offset;/* for highmem, page offset */ |
| 11 | 14 | ||
| 12 | dma_addr_t dma_address; | 15 | dma_addr_t dma_address; |
diff --git a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h index 24887a2d9c7b..d3a7a0edfeca 100644 --- a/include/asm-m68k/scatterlist.h +++ b/include/asm-m68k/scatterlist.h | |||
| @@ -4,7 +4,10 @@ | |||
| 4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 5 | 5 | ||
| 6 | struct scatterlist { | 6 | struct scatterlist { |
| 7 | struct page *page; | 7 | #ifdef CONFIG_DEBUG_SG |
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 10 | unsigned long page_link; | ||
| 8 | unsigned int offset; | 11 | unsigned int offset; |
| 9 | unsigned int length; | 12 | unsigned int length; |
| 10 | 13 | ||
diff --git a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h index 4da79d3d3f34..10942840e88f 100644 --- a/include/asm-m68knommu/scatterlist.h +++ b/include/asm-m68knommu/scatterlist.h | |||
| @@ -5,7 +5,10 @@ | |||
| 5 | #include <asm/types.h> | 5 | #include <asm/types.h> |
| 6 | 6 | ||
| 7 | struct scatterlist { | 7 | struct scatterlist { |
| 8 | struct page *page; | 8 | #ifdef CONFIG_DEBUG_SG |
| 9 | unsigned long sg_magic; | ||
| 10 | #endif | ||
| 11 | unsigned long page_link; | ||
| 9 | unsigned int offset; | 12 | unsigned int offset; |
| 10 | dma_addr_t dma_address; | 13 | dma_addr_t dma_address; |
| 11 | unsigned int length; | 14 | unsigned int length; |
diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h index 7af104c95b20..83d69fe17c9f 100644 --- a/include/asm-mips/scatterlist.h +++ b/include/asm-mips/scatterlist.h | |||
| @@ -4,7 +4,10 @@ | |||
| 4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
| 5 | 5 | ||
| 6 | struct scatterlist { | 6 | struct scatterlist { |
| 7 | struct page * page; | 7 | #ifdef CONFIG_DEBUG_SG |
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 10 | unsigned long page_link; | ||
| 8 | unsigned int offset; | 11 | unsigned int offset; |
| 9 | dma_addr_t dma_address; | 12 | dma_addr_t dma_address; |
| 10 | unsigned int length; | 13 | unsigned int length; |
diff --git a/include/asm-parisc/scatterlist.h b/include/asm-parisc/scatterlist.h index e7211c748446..cd3cfdf82289 100644 --- a/include/asm-parisc/scatterlist.h +++ b/include/asm-parisc/scatterlist.h | |||
| @@ -5,7 +5,10 @@ | |||
| 5 | #include <asm/types.h> | 5 | #include <asm/types.h> |
| 6 | 6 | ||
| 7 | struct scatterlist { | 7 | struct scatterlist { |
| 8 | struct page *page; | 8 | #ifdef CONFIG_DEBUG_SG |
| 9 | unsigned long sg_magic; | ||
| 10 | #endif | ||
| 11 | unsigned long page_link; | ||
| 9 | unsigned int offset; | 12 | unsigned int offset; |
| 10 | 13 | ||
| 11 | unsigned int length; | 14 | unsigned int length; |
diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h index b075f619c3b7..fcf7d55afe45 100644 --- a/include/asm-powerpc/scatterlist.h +++ b/include/asm-powerpc/scatterlist.h | |||
| @@ -14,7 +14,10 @@ | |||
| 14 | #include <asm/dma.h> | 14 | #include <asm/dma.h> |
| 15 | 15 | ||
| 16 | struct scatterlist { | 16 | struct scatterlist { |
| 17 | struct page *page; | 17 | #ifdef CONFIG_DEBUG_SG |
| 18 | unsigned long sg_magic; | ||
| 19 | #endif | ||
| 20 | unsigned long page_link; | ||
| 18 | unsigned int offset; | 21 | unsigned int offset; |
| 19 | unsigned int length; | 22 | unsigned int length; |
| 20 | 23 | ||
diff --git a/include/asm-s390/scatterlist.h b/include/asm-s390/scatterlist.h index a43b3afc5e2d..29ec8e28c8df 100644 --- a/include/asm-s390/scatterlist.h +++ b/include/asm-s390/scatterlist.h | |||
| @@ -2,7 +2,10 @@ | |||
| 2 | #define _ASMS390_SCATTERLIST_H | 2 | #define _ASMS390_SCATTERLIST_H |
| 3 | 3 | ||
| 4 | struct scatterlist { | 4 | struct scatterlist { |
| 5 | struct page *page; | 5 | #ifdef CONFIG_DEBUG_SG |
| 6 | unsigned long sg_magic; | ||
| 7 | #endif | ||
| 8 | unsigned long page_link; | ||
| 6 | unsigned int offset; | 9 | unsigned int offset; |
| 7 | unsigned int length; | 10 | unsigned int length; |
| 8 | }; | 11 | }; |
diff --git a/include/asm-sh/scatterlist.h b/include/asm-sh/scatterlist.h index b9ae53c38365..a7d0d1856a99 100644 --- a/include/asm-sh/scatterlist.h +++ b/include/asm-sh/scatterlist.h | |||
| @@ -4,7 +4,10 @@ | |||
| 4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
| 5 | 5 | ||
| 6 | struct scatterlist { | 6 | struct scatterlist { |
| 7 | struct page * page; /* Location for highmem page, if any */ | 7 | #ifdef CONFIG_DEBUG_SG |
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 10 | unsigned long page_link; | ||
| 8 | unsigned int offset;/* for highmem, page offset */ | 11 | unsigned int offset;/* for highmem, page offset */ |
| 9 | dma_addr_t dma_address; | 12 | dma_addr_t dma_address; |
| 10 | unsigned int length; | 13 | unsigned int length; |
diff --git a/include/asm-sh64/scatterlist.h b/include/asm-sh64/scatterlist.h index 1c723f2d7a95..5109251970e7 100644 --- a/include/asm-sh64/scatterlist.h +++ b/include/asm-sh64/scatterlist.h | |||
| @@ -14,7 +14,10 @@ | |||
| 14 | #include <asm/types.h> | 14 | #include <asm/types.h> |
| 15 | 15 | ||
| 16 | struct scatterlist { | 16 | struct scatterlist { |
| 17 | struct page * page; /* Location for highmem page, if any */ | 17 | #ifdef CONFIG_DEBUG_SG |
| 18 | unsigned long sg_magic; | ||
| 19 | #endif | ||
| 20 | unsigned long page_link; | ||
| 18 | unsigned int offset;/* for highmem, page offset */ | 21 | unsigned int offset;/* for highmem, page offset */ |
| 19 | dma_addr_t dma_address; | 22 | dma_addr_t dma_address; |
| 20 | unsigned int length; | 23 | unsigned int length; |
diff --git a/include/asm-sparc/scatterlist.h b/include/asm-sparc/scatterlist.h index 4055af90ad7e..e08d3d775b08 100644 --- a/include/asm-sparc/scatterlist.h +++ b/include/asm-sparc/scatterlist.h | |||
| @@ -5,7 +5,10 @@ | |||
| 5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
| 6 | 6 | ||
| 7 | struct scatterlist { | 7 | struct scatterlist { |
| 8 | struct page *page; | 8 | #ifdef CONFIG_DEBUG_SG |
| 9 | unsigned long sg_magic; | ||
| 10 | #endif | ||
| 11 | unsigned long page_link; | ||
| 9 | unsigned int offset; | 12 | unsigned int offset; |
| 10 | 13 | ||
| 11 | unsigned int length; | 14 | unsigned int length; |
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h index 703c5bbe6c8c..6df23f070b1a 100644 --- a/include/asm-sparc64/scatterlist.h +++ b/include/asm-sparc64/scatterlist.h | |||
| @@ -6,7 +6,10 @@ | |||
| 6 | #include <asm/types.h> | 6 | #include <asm/types.h> |
| 7 | 7 | ||
| 8 | struct scatterlist { | 8 | struct scatterlist { |
| 9 | struct page *page; | 9 | #ifdef CONFIG_DEBUG_SG |
| 10 | unsigned long sg_magic; | ||
| 11 | #endif | ||
| 12 | unsigned long page_link; | ||
| 10 | unsigned int offset; | 13 | unsigned int offset; |
| 11 | 14 | ||
| 12 | unsigned int length; | 15 | unsigned int length; |
diff --git a/include/asm-v850/scatterlist.h b/include/asm-v850/scatterlist.h index 56f402920db9..02d27b3fb061 100644 --- a/include/asm-v850/scatterlist.h +++ b/include/asm-v850/scatterlist.h | |||
| @@ -17,7 +17,10 @@ | |||
| 17 | #include <asm/types.h> | 17 | #include <asm/types.h> |
| 18 | 18 | ||
| 19 | struct scatterlist { | 19 | struct scatterlist { |
| 20 | struct page *page; | 20 | #ifdef CONFIG_DEBUG_SG |
| 21 | unsigned long sg_magic; | ||
| 22 | #endif | ||
| 23 | unsigned long page_link; | ||
| 21 | unsigned offset; | 24 | unsigned offset; |
| 22 | dma_addr_t dma_address; | 25 | dma_addr_t dma_address; |
| 23 | unsigned length; | 26 | unsigned length; |
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h index 6a2d26cb5da6..55f01bd9e556 100644 --- a/include/asm-x86/dma-mapping_32.h +++ b/include/asm-x86/dma-mapping_32.h | |||
| @@ -45,9 +45,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, | |||
| 45 | WARN_ON(nents == 0 || sglist[0].length == 0); | 45 | WARN_ON(nents == 0 || sglist[0].length == 0); |
| 46 | 46 | ||
| 47 | for_each_sg(sglist, sg, nents, i) { | 47 | for_each_sg(sglist, sg, nents, i) { |
| 48 | BUG_ON(!sg->page); | 48 | BUG_ON(!sg_page(sg)); |
| 49 | 49 | ||
| 50 | sg->dma_address = page_to_phys(sg->page) + sg->offset; | 50 | sg->dma_address = sg_phys(sg); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | flush_write_buffers(); | 53 | flush_write_buffers(); |
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h index bd5164aa8f63..0e7d997a34be 100644 --- a/include/asm-x86/scatterlist_32.h +++ b/include/asm-x86/scatterlist_32.h | |||
| @@ -4,7 +4,10 @@ | |||
| 4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
| 5 | 5 | ||
| 6 | struct scatterlist { | 6 | struct scatterlist { |
| 7 | struct page *page; | 7 | #ifdef CONFIG_DEBUG_SG |
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 10 | unsigned long page_link; | ||
| 8 | unsigned int offset; | 11 | unsigned int offset; |
| 9 | dma_addr_t dma_address; | 12 | dma_addr_t dma_address; |
| 10 | unsigned int length; | 13 | unsigned int length; |
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h index ef3986ba4b79..1847c72befeb 100644 --- a/include/asm-x86/scatterlist_64.h +++ b/include/asm-x86/scatterlist_64.h | |||
| @@ -4,7 +4,10 @@ | |||
| 4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
| 5 | 5 | ||
| 6 | struct scatterlist { | 6 | struct scatterlist { |
| 7 | struct page *page; | 7 | #ifdef CONFIG_DEBUG_SG |
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 10 | unsigned long page_link; | ||
| 8 | unsigned int offset; | 11 | unsigned int offset; |
| 9 | unsigned int length; | 12 | unsigned int length; |
| 10 | dma_addr_t dma_address; | 13 | dma_addr_t dma_address; |
diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h index ca337a294290..810080bb0a2b 100644 --- a/include/asm-xtensa/scatterlist.h +++ b/include/asm-xtensa/scatterlist.h | |||
| @@ -14,7 +14,10 @@ | |||
| 14 | #include <asm/types.h> | 14 | #include <asm/types.h> |
| 15 | 15 | ||
| 16 | struct scatterlist { | 16 | struct scatterlist { |
| 17 | struct page *page; | 17 | #ifdef CONFIG_DEBUG_SG |
| 18 | unsigned long sg_magic; | ||
| 19 | #endif | ||
| 20 | unsigned long page_link; | ||
| 18 | unsigned int offset; | 21 | unsigned int offset; |
| 19 | dma_addr_t dma_address; | 22 | dma_addr_t dma_address; |
| 20 | unsigned int length; | 23 | unsigned int length; |
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 2dc7464cce52..42daf5e15265 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h | |||
| @@ -4,47 +4,95 @@ | |||
| 4 | #include <asm/scatterlist.h> | 4 | #include <asm/scatterlist.h> |
| 5 | #include <linux/mm.h> | 5 | #include <linux/mm.h> |
| 6 | #include <linux/string.h> | 6 | #include <linux/string.h> |
| 7 | #include <asm/io.h> | ||
| 7 | 8 | ||
| 9 | /* | ||
| 10 | * Notes on SG table design. | ||
| 11 | * | ||
| 12 | * Architectures must provide an unsigned long page_link field in the | ||
| 13 | * scatterlist struct. We use that to place the page pointer AND encode | ||
| 14 | * information about the sg table as well. The two lower bits are reserved | ||
| 15 | * for this information. | ||
| 16 | * | ||
| 17 | * If bit 0 is set, then the page_link contains a pointer to the next sg | ||
| 18 | * table list. Otherwise the next entry is at sg + 1. | ||
| 19 | * | ||
| 20 | * If bit 1 is set, then this sg entry is the last element in a list. | ||
| 21 | * | ||
| 22 | * See sg_next(). | ||
| 23 | * | ||
| 24 | */ | ||
| 25 | |||
| 26 | #define SG_MAGIC 0x87654321 | ||
| 27 | |||
| 28 | /** | ||
| 29 | * sg_set_page - Set sg entry to point at given page | ||
| 30 | * @sg: SG entry | ||
| 31 | * @page: The page | ||
| 32 | * | ||
| 33 | * Description: | ||
| 34 | * Use this function to set an sg entry pointing at a page, never assign | ||
| 35 | * the page directly. We encode sg table information in the lower bits | ||
| 36 | * of the page pointer. See sg_page() for looking up the page belonging | ||
| 37 | * to an sg entry. | ||
| 38 | * | ||
| 39 | **/ | ||
| 40 | static inline void sg_set_page(struct scatterlist *sg, struct page *page) | ||
| 41 | { | ||
| 42 | unsigned long page_link = sg->page_link & 0x3; | ||
| 43 | |||
| 44 | #ifdef CONFIG_DEBUG_SG | ||
| 45 | BUG_ON(sg->sg_magic != SG_MAGIC); | ||
| 46 | #endif | ||
| 47 | sg->page_link = page_link | (unsigned long) page; | ||
| 48 | } | ||
| 49 | |||
| 50 | #define sg_page(sg) ((struct page *) ((sg)->page_link & ~0x3)) | ||
| 51 | |||
| 52 | /** | ||
| 53 | * sg_set_buf - Set sg entry to point at given data | ||
| 54 | * @sg: SG entry | ||
| 55 | * @buf: Data | ||
| 56 | * @buflen: Data length | ||
| 57 | * | ||
| 58 | **/ | ||
| 8 | static inline void sg_set_buf(struct scatterlist *sg, const void *buf, | 59 | static inline void sg_set_buf(struct scatterlist *sg, const void *buf, |
| 9 | unsigned int buflen) | 60 | unsigned int buflen) |
| 10 | { | 61 | { |
| 11 | sg->page = virt_to_page(buf); | 62 | sg_set_page(sg, virt_to_page(buf)); |
| 12 | sg->offset = offset_in_page(buf); | 63 | sg->offset = offset_in_page(buf); |
| 13 | sg->length = buflen; | 64 | sg->length = buflen; |
| 14 | } | 65 | } |
| 15 | 66 | ||
| 16 | static inline void sg_init_one(struct scatterlist *sg, const void *buf, | ||
| 17 | unsigned int buflen) | ||
| 18 | { | ||
| 19 | memset(sg, 0, sizeof(*sg)); | ||
| 20 | sg_set_buf(sg, buf, buflen); | ||
| 21 | } | ||
| 22 | |||
| 23 | /* | 67 | /* |
| 24 | * We overload the LSB of the page pointer to indicate whether it's | 68 | * We overload the LSB of the page pointer to indicate whether it's |
| 25 | * a valid sg entry, or whether it points to the start of a new scatterlist. | 69 | * a valid sg entry, or whether it points to the start of a new scatterlist. |
| 26 | * Those low bits are there for everyone! (thanks mason :-) | 70 | * Those low bits are there for everyone! (thanks mason :-) |
| 27 | */ | 71 | */ |
| 28 | #define sg_is_chain(sg) ((unsigned long) (sg)->page & 0x01) | 72 | #define sg_is_chain(sg) ((sg)->page_link & 0x01) |
| 73 | #define sg_is_last(sg) ((sg)->page_link & 0x02) | ||
| 29 | #define sg_chain_ptr(sg) \ | 74 | #define sg_chain_ptr(sg) \ |
| 30 | ((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01)) | 75 | ((struct scatterlist *) ((sg)->page_link & ~0x03)) |
| 31 | 76 | ||
| 32 | /** | 77 | /** |
| 33 | * sg_next - return the next scatterlist entry in a list | 78 | * sg_next - return the next scatterlist entry in a list |
| 34 | * @sg: The current sg entry | 79 | * @sg: The current sg entry |
| 35 | * | 80 | * |
| 36 | * Usually the next entry will be @sg@ + 1, but if this sg element is part | 81 | * Description: |
| 37 | * of a chained scatterlist, it could jump to the start of a new | 82 | * Usually the next entry will be @sg@ + 1, but if this sg element is part |
| 38 | * scatterlist array. | 83 | * of a chained scatterlist, it could jump to the start of a new |
| 39 | * | 84 | * scatterlist array. |
| 40 | * Note that the caller must ensure that there are further entries after | ||
| 41 | * the current entry, this function will NOT return NULL for an end-of-list. | ||
| 42 | * | 85 | * |
| 43 | */ | 86 | **/ |
| 44 | static inline struct scatterlist *sg_next(struct scatterlist *sg) | 87 | static inline struct scatterlist *sg_next(struct scatterlist *sg) |
| 45 | { | 88 | { |
| 46 | sg++; | 89 | #ifdef CONFIG_DEBUG_SG |
| 90 | BUG_ON(sg->sg_magic != SG_MAGIC); | ||
| 91 | #endif | ||
| 92 | if (sg_is_last(sg)) | ||
| 93 | return NULL; | ||
| 47 | 94 | ||
| 95 | sg++; | ||
| 48 | if (unlikely(sg_is_chain(sg))) | 96 | if (unlikely(sg_is_chain(sg))) |
| 49 | sg = sg_chain_ptr(sg); | 97 | sg = sg_chain_ptr(sg); |
| 50 | 98 | ||
| @@ -62,14 +110,15 @@ static inline struct scatterlist *sg_next(struct scatterlist *sg) | |||
| 62 | * @sgl: First entry in the scatterlist | 110 | * @sgl: First entry in the scatterlist |
| 63 | * @nents: Number of entries in the scatterlist | 111 | * @nents: Number of entries in the scatterlist |
| 64 | * | 112 | * |
| 65 | * Should only be used casually, it (currently) scan the entire list | 113 | * Description: |
| 66 | * to get the last entry. | 114 | * Should only be used casually, it (currently) scan the entire list |
| 115 | * to get the last entry. | ||
| 67 | * | 116 | * |
| 68 | * Note that the @sgl@ pointer passed in need not be the first one, | 117 | * Note that the @sgl@ pointer passed in need not be the first one, |
| 69 | * the important bit is that @nents@ denotes the number of entries that | 118 | * the important bit is that @nents@ denotes the number of entries that |
| 70 | * exist from @sgl@. | 119 | * exist from @sgl@. |
| 71 | * | 120 | * |
| 72 | */ | 121 | **/ |
| 73 | static inline struct scatterlist *sg_last(struct scatterlist *sgl, | 122 | static inline struct scatterlist *sg_last(struct scatterlist *sgl, |
| 74 | unsigned int nents) | 123 | unsigned int nents) |
| 75 | { | 124 | { |
| @@ -83,6 +132,10 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl, | |||
| 83 | ret = sg; | 132 | ret = sg; |
| 84 | 133 | ||
| 85 | #endif | 134 | #endif |
| 135 | #ifdef CONFIG_DEBUG_SG | ||
| 136 | BUG_ON(sgl[0].sg_magic != SG_MAGIC); | ||
| 137 | BUG_ON(!sg_is_last(ret)); | ||
| 138 | #endif | ||
| 86 | return ret; | 139 | return ret; |
| 87 | } | 140 | } |
| 88 | 141 | ||
| @@ -92,16 +145,111 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl, | |||
| 92 | * @prv_nents: Number of entries in prv | 145 | * @prv_nents: Number of entries in prv |
| 93 | * @sgl: Second scatterlist | 146 | * @sgl: Second scatterlist |
| 94 | * | 147 | * |
| 95 | * Links @prv@ and @sgl@ together, to form a longer scatterlist. | 148 | * Description: |
| 149 | * Links @prv@ and @sgl@ together, to form a longer scatterlist. | ||
| 96 | * | 150 | * |
| 97 | */ | 151 | **/ |
| 98 | static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents, | 152 | static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents, |
| 99 | struct scatterlist *sgl) | 153 | struct scatterlist *sgl) |
| 100 | { | 154 | { |
| 101 | #ifndef ARCH_HAS_SG_CHAIN | 155 | #ifndef ARCH_HAS_SG_CHAIN |
| 102 | BUG(); | 156 | BUG(); |
| 103 | #endif | 157 | #endif |
| 104 | prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01); | 158 | prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01; |
| 159 | } | ||
| 160 | |||
| 161 | /** | ||
| 162 | * sg_mark_end - Mark the end of the scatterlist | ||
| 163 | * @sgl: Scatterlist | ||
| 164 | * @nents: Number of entries in sgl | ||
| 165 | * | ||
| 166 | * Description: | ||
| 167 | * Marks the last entry as the termination point for sg_next() | ||
| 168 | * | ||
| 169 | **/ | ||
| 170 | static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents) | ||
| 171 | { | ||
| 172 | sgl[nents - 1].page_link = 0x02; | ||
| 173 | } | ||
| 174 | |||
| 175 | static inline void __sg_mark_end(struct scatterlist *sg) | ||
| 176 | { | ||
| 177 | sg->page_link |= 0x02; | ||
| 178 | } | ||
| 179 | |||
| 180 | /** | ||
| 181 | * sg_init_one - Initialize a single entry sg list | ||
| 182 | * @sg: SG entry | ||
| 183 | * @buf: Virtual address for IO | ||
| 184 | * @buflen: IO length | ||
| 185 | * | ||
| 186 | * Notes: | ||
| 187 | * This should not be used on a single entry that is part of a larger | ||
| 188 | * table. Use sg_init_table() for that. | ||
| 189 | * | ||
| 190 | **/ | ||
| 191 | static inline void sg_init_one(struct scatterlist *sg, const void *buf, | ||
| 192 | unsigned int buflen) | ||
| 193 | { | ||
| 194 | memset(sg, 0, sizeof(*sg)); | ||
| 195 | #ifdef CONFIG_DEBUG_SG | ||
| 196 | sg->sg_magic = SG_MAGIC; | ||
| 197 | #endif | ||
| 198 | sg_mark_end(sg, 1); | ||
| 199 | sg_set_buf(sg, buf, buflen); | ||
| 200 | } | ||
| 201 | |||
| 202 | /** | ||
| 203 | * sg_init_table - Initialize SG table | ||
| 204 | * @sgl: The SG table | ||
| 205 | * @nents: Number of entries in table | ||
| 206 | * | ||
| 207 | * Notes: | ||
| 208 | * If this is part of a chained sg table, sg_mark_end() should be | ||
| 209 | * used only on the last table part. | ||
| 210 | * | ||
| 211 | **/ | ||
| 212 | static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents) | ||
| 213 | { | ||
| 214 | memset(sgl, 0, sizeof(*sgl) * nents); | ||
| 215 | sg_mark_end(sgl, nents); | ||
| 216 | #ifdef CONFIG_DEBUG_SG | ||
| 217 | { | ||
| 218 | int i; | ||
| 219 | for (i = 0; i < nents; i++) | ||
| 220 | sgl[i].sg_magic = SG_MAGIC; | ||
| 221 | } | ||
| 222 | #endif | ||
| 223 | } | ||
| 224 | |||
| 225 | /** | ||
| 226 | * sg_phys - Return physical address of an sg entry | ||
| 227 | * @sg: SG entry | ||
| 228 | * | ||
| 229 | * Description: | ||
| 230 | * This calls page_to_phys() on the page in this sg entry, and adds the | ||
| 231 | * sg offset. The caller must know that it is legal to call page_to_phys() | ||
| 232 | * on the sg page. | ||
| 233 | * | ||
| 234 | **/ | ||
| 235 | static inline unsigned long sg_phys(struct scatterlist *sg) | ||
| 236 | { | ||
| 237 | return page_to_phys(sg_page(sg)) + sg->offset; | ||
| 238 | } | ||
| 239 | |||
| 240 | /** | ||
| 241 | * sg_virt - Return virtual address of an sg entry | ||
| 242 | * @sg: SG entry | ||
| 243 | * | ||
| 244 | * Description: | ||
| 245 | * This calls page_address() on the page in this sg entry, and adds the | ||
| 246 | * sg offset. The caller must know that the sg page has a valid virtual | ||
| 247 | * mapping. | ||
| 248 | * | ||
| 249 | **/ | ||
| 250 | static inline void *sg_virt(struct scatterlist *sg) | ||
| 251 | { | ||
| 252 | return page_address(sg_page(sg)) + sg->offset; | ||
| 105 | } | 253 | } |
| 106 | 254 | ||
| 107 | #endif /* _LINUX_SCATTERLIST_H */ | 255 | #endif /* _LINUX_SCATTERLIST_H */ |
