]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef _LINUX_SCATTERLIST_H |
2 | #define _LINUX_SCATTERLIST_H | |
3 | ||
d32311fe HX |
4 | #include <asm/scatterlist.h> |
5 | #include <linux/mm.h> | |
6 | #include <linux/string.h> | |
18dabf47 JA |
7 | #include <asm/io.h> |
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 | */ | |
1da177e4 | 25 | |
d6ec0842 JA |
26 | #define SG_MAGIC 0x87654321 |
27 | ||
82f66fbe | 28 | /** |
642f1490 JA |
29 | * sg_assign_page - Assign a given page to an SG entry |
30 | * @sg: SG entry | |
31 | * @page: The page | |
82f66fbe JA |
32 | * |
33 | * Description: | |
642f1490 JA |
34 | * Assign page to sg entry. Also see sg_set_page(), the most commonly used |
35 | * variant. | |
82f66fbe JA |
36 | * |
37 | **/ | |
642f1490 | 38 | static inline void sg_assign_page(struct scatterlist *sg, struct page *page) |
82f66fbe | 39 | { |
18dabf47 JA |
40 | unsigned long page_link = sg->page_link & 0x3; |
41 | ||
de26103d JA |
42 | /* |
43 | * In order for the low bit stealing approach to work, pages | |
44 | * must be aligned at a 32-bit boundary as a minimum. | |
45 | */ | |
46 | BUG_ON((unsigned long) page & 0x03); | |
d6ec0842 JA |
47 | #ifdef CONFIG_DEBUG_SG |
48 | BUG_ON(sg->sg_magic != SG_MAGIC); | |
49 | #endif | |
18dabf47 | 50 | sg->page_link = page_link | (unsigned long) page; |
82f66fbe JA |
51 | } |
52 | ||
642f1490 JA |
53 | /** |
54 | * sg_set_page - Set sg entry to point at given page | |
55 | * @sg: SG entry | |
56 | * @page: The page | |
57 | * @len: Length of data | |
58 | * @offset: Offset into page | |
59 | * | |
60 | * Description: | |
61 | * Use this function to set an sg entry pointing at a page, never assign | |
62 | * the page directly. We encode sg table information in the lower bits | |
63 | * of the page pointer. See sg_page() for looking up the page belonging | |
64 | * to an sg entry. | |
65 | * | |
66 | **/ | |
67 | static inline void sg_set_page(struct scatterlist *sg, struct page *page, | |
68 | unsigned int len, unsigned int offset) | |
69 | { | |
70 | sg_assign_page(sg, page); | |
71 | sg->offset = offset; | |
72 | sg->length = len; | |
73 | } | |
74 | ||
18dabf47 | 75 | #define sg_page(sg) ((struct page *) ((sg)->page_link & ~0x3)) |
82f66fbe | 76 | |
18dabf47 JA |
77 | /** |
78 | * sg_set_buf - Set sg entry to point at given data | |
79 | * @sg: SG entry | |
80 | * @buf: Data | |
81 | * @buflen: Data length | |
82 | * | |
83 | **/ | |
03fd9cee | 84 | static inline void sg_set_buf(struct scatterlist *sg, const void *buf, |
d32311fe HX |
85 | unsigned int buflen) |
86 | { | |
642f1490 | 87 | sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); |
1da177e4 LT |
88 | } |
89 | ||
70eb8040 JA |
90 | /* |
91 | * We overload the LSB of the page pointer to indicate whether it's | |
92 | * a valid sg entry, or whether it points to the start of a new scatterlist. | |
93 | * Those low bits are there for everyone! (thanks mason :-) | |
94 | */ | |
18dabf47 JA |
95 | #define sg_is_chain(sg) ((sg)->page_link & 0x01) |
96 | #define sg_is_last(sg) ((sg)->page_link & 0x02) | |
70eb8040 | 97 | #define sg_chain_ptr(sg) \ |
18dabf47 | 98 | ((struct scatterlist *) ((sg)->page_link & ~0x03)) |
70eb8040 JA |
99 | |
100 | /** | |
101 | * sg_next - return the next scatterlist entry in a list | |
102 | * @sg: The current sg entry | |
103 | * | |
18dabf47 JA |
104 | * Description: |
105 | * Usually the next entry will be @sg@ + 1, but if this sg element is part | |
106 | * of a chained scatterlist, it could jump to the start of a new | |
107 | * scatterlist array. | |
70eb8040 | 108 | * |
18dabf47 | 109 | **/ |
70eb8040 JA |
110 | static inline struct scatterlist *sg_next(struct scatterlist *sg) |
111 | { | |
d6ec0842 JA |
112 | #ifdef CONFIG_DEBUG_SG |
113 | BUG_ON(sg->sg_magic != SG_MAGIC); | |
114 | #endif | |
18dabf47 JA |
115 | if (sg_is_last(sg)) |
116 | return NULL; | |
70eb8040 | 117 | |
18dabf47 | 118 | sg++; |
70eb8040 JA |
119 | if (unlikely(sg_is_chain(sg))) |
120 | sg = sg_chain_ptr(sg); | |
121 | ||
122 | return sg; | |
123 | } | |
96b418c9 JA |
124 | |
125 | /* | |
126 | * Loop over each sg element, following the pointer to a new list if necessary | |
127 | */ | |
128 | #define for_each_sg(sglist, sg, nr, __i) \ | |
129 | for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg)) | |
130 | ||
70eb8040 JA |
131 | /** |
132 | * sg_last - return the last scatterlist entry in a list | |
133 | * @sgl: First entry in the scatterlist | |
134 | * @nents: Number of entries in the scatterlist | |
135 | * | |
18dabf47 JA |
136 | * Description: |
137 | * Should only be used casually, it (currently) scan the entire list | |
138 | * to get the last entry. | |
70eb8040 | 139 | * |
18dabf47 JA |
140 | * Note that the @sgl@ pointer passed in need not be the first one, |
141 | * the important bit is that @nents@ denotes the number of entries that | |
142 | * exist from @sgl@. | |
70eb8040 | 143 | * |
18dabf47 | 144 | **/ |
70eb8040 JA |
145 | static inline struct scatterlist *sg_last(struct scatterlist *sgl, |
146 | unsigned int nents) | |
147 | { | |
148 | #ifndef ARCH_HAS_SG_CHAIN | |
149 | struct scatterlist *ret = &sgl[nents - 1]; | |
150 | #else | |
151 | struct scatterlist *sg, *ret = NULL; | |
152 | int i; | |
153 | ||
154 | for_each_sg(sgl, sg, nents, i) | |
155 | ret = sg; | |
156 | ||
d6ec0842 JA |
157 | #endif |
158 | #ifdef CONFIG_DEBUG_SG | |
159 | BUG_ON(sgl[0].sg_magic != SG_MAGIC); | |
160 | BUG_ON(!sg_is_last(ret)); | |
70eb8040 JA |
161 | #endif |
162 | return ret; | |
163 | } | |
164 | ||
165 | /** | |
166 | * sg_chain - Chain two sglists together | |
167 | * @prv: First scatterlist | |
168 | * @prv_nents: Number of entries in prv | |
169 | * @sgl: Second scatterlist | |
170 | * | |
18dabf47 JA |
171 | * Description: |
172 | * Links @prv@ and @sgl@ together, to form a longer scatterlist. | |
70eb8040 | 173 | * |
18dabf47 | 174 | **/ |
70eb8040 JA |
175 | static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents, |
176 | struct scatterlist *sgl) | |
177 | { | |
178 | #ifndef ARCH_HAS_SG_CHAIN | |
179 | BUG(); | |
180 | #endif | |
18dabf47 | 181 | prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01; |
70eb8040 JA |
182 | } |
183 | ||
82f66fbe JA |
184 | /** |
185 | * sg_mark_end - Mark the end of the scatterlist | |
186 | * @sgl: Scatterlist | |
187 | * @nents: Number of entries in sgl | |
188 | * | |
189 | * Description: | |
190 | * Marks the last entry as the termination point for sg_next() | |
191 | * | |
192 | **/ | |
193 | static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents) | |
194 | { | |
18dabf47 | 195 | sgl[nents - 1].page_link = 0x02; |
82f66fbe JA |
196 | } |
197 | ||
198 | static inline void __sg_mark_end(struct scatterlist *sg) | |
199 | { | |
18dabf47 | 200 | sg->page_link |= 0x02; |
82f66fbe JA |
201 | } |
202 | ||
82f66fbe JA |
203 | /** |
204 | * sg_init_one - Initialize a single entry sg list | |
205 | * @sg: SG entry | |
206 | * @buf: Virtual address for IO | |
207 | * @buflen: IO length | |
208 | * | |
209 | * Notes: | |
210 | * This should not be used on a single entry that is part of a larger | |
211 | * table. Use sg_init_table() for that. | |
212 | * | |
213 | **/ | |
214 | static inline void sg_init_one(struct scatterlist *sg, const void *buf, | |
215 | unsigned int buflen) | |
216 | { | |
217 | memset(sg, 0, sizeof(*sg)); | |
d6ec0842 JA |
218 | #ifdef CONFIG_DEBUG_SG |
219 | sg->sg_magic = SG_MAGIC; | |
220 | #endif | |
82f66fbe JA |
221 | sg_mark_end(sg, 1); |
222 | sg_set_buf(sg, buf, buflen); | |
223 | } | |
224 | ||
225 | /** | |
226 | * sg_init_table - Initialize SG table | |
227 | * @sgl: The SG table | |
228 | * @nents: Number of entries in table | |
229 | * | |
230 | * Notes: | |
231 | * If this is part of a chained sg table, sg_mark_end() should be | |
232 | * used only on the last table part. | |
233 | * | |
234 | **/ | |
235 | static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents) | |
236 | { | |
237 | memset(sgl, 0, sizeof(*sgl) * nents); | |
238 | sg_mark_end(sgl, nents); | |
d6ec0842 JA |
239 | #ifdef CONFIG_DEBUG_SG |
240 | { | |
241 | int i; | |
242 | for (i = 0; i < nents; i++) | |
243 | sgl[i].sg_magic = SG_MAGIC; | |
244 | } | |
245 | #endif | |
82f66fbe JA |
246 | } |
247 | ||
248 | /** | |
249 | * sg_phys - Return physical address of an sg entry | |
250 | * @sg: SG entry | |
251 | * | |
252 | * Description: | |
253 | * This calls page_to_phys() on the page in this sg entry, and adds the | |
254 | * sg offset. The caller must know that it is legal to call page_to_phys() | |
255 | * on the sg page. | |
256 | * | |
257 | **/ | |
258 | static inline unsigned long sg_phys(struct scatterlist *sg) | |
259 | { | |
260 | return page_to_phys(sg_page(sg)) + sg->offset; | |
261 | } | |
262 | ||
263 | /** | |
264 | * sg_virt - Return virtual address of an sg entry | |
18dabf47 | 265 | * @sg: SG entry |
82f66fbe JA |
266 | * |
267 | * Description: | |
268 | * This calls page_address() on the page in this sg entry, and adds the | |
269 | * sg offset. The caller must know that the sg page has a valid virtual | |
270 | * mapping. | |
271 | * | |
272 | **/ | |
273 | static inline void *sg_virt(struct scatterlist *sg) | |
274 | { | |
275 | return page_address(sg_page(sg)) + sg->offset; | |
276 | } | |
277 | ||
1da177e4 | 278 | #endif /* _LINUX_SCATTERLIST_H */ |