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