]> git.karo-electronics.de Git - mv-sheeva.git/blob - include/linux/scatterlist.h
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
[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 #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  **/
59 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
60                               unsigned int buflen)
61 {
62         sg_set_page(sg, virt_to_page(buf));
63         sg->offset = offset_in_page(buf);
64         sg->length = buflen;
65 }
66
67 /*
68  * We overload the LSB of the page pointer to indicate whether it's
69  * a valid sg entry, or whether it points to the start of a new scatterlist.
70  * Those low bits are there for everyone! (thanks mason :-)
71  */
72 #define sg_is_chain(sg)         ((sg)->page_link & 0x01)
73 #define sg_is_last(sg)          ((sg)->page_link & 0x02)
74 #define sg_chain_ptr(sg)        \
75         ((struct scatterlist *) ((sg)->page_link & ~0x03))
76
77 /**
78  * sg_next - return the next scatterlist entry in a list
79  * @sg:         The current sg entry
80  *
81  * Description:
82  *   Usually the next entry will be @sg@ + 1, but if this sg element is part
83  *   of a chained scatterlist, it could jump to the start of a new
84  *   scatterlist array.
85  *
86  **/
87 static inline struct scatterlist *sg_next(struct scatterlist *sg)
88 {
89 #ifdef CONFIG_DEBUG_SG
90         BUG_ON(sg->sg_magic != SG_MAGIC);
91 #endif
92         if (sg_is_last(sg))
93                 return NULL;
94
95         sg++;
96         if (unlikely(sg_is_chain(sg)))
97                 sg = sg_chain_ptr(sg);
98
99         return sg;
100 }
101
102 /*
103  * Loop over each sg element, following the pointer to a new list if necessary
104  */
105 #define for_each_sg(sglist, sg, nr, __i)        \
106         for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
107
108 /**
109  * sg_last - return the last scatterlist entry in a list
110  * @sgl:        First entry in the scatterlist
111  * @nents:      Number of entries in the scatterlist
112  *
113  * Description:
114  *   Should only be used casually, it (currently) scan the entire list
115  *   to get the last entry.
116  *
117  *   Note that the @sgl@ pointer passed in need not be the first one,
118  *   the important bit is that @nents@ denotes the number of entries that
119  *   exist from @sgl@.
120  *
121  **/
122 static inline struct scatterlist *sg_last(struct scatterlist *sgl,
123                                           unsigned int nents)
124 {
125 #ifndef ARCH_HAS_SG_CHAIN
126         struct scatterlist *ret = &sgl[nents - 1];
127 #else
128         struct scatterlist *sg, *ret = NULL;
129         int i;
130
131         for_each_sg(sgl, sg, nents, i)
132                 ret = sg;
133
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
139         return ret;
140 }
141
142 /**
143  * sg_chain - Chain two sglists together
144  * @prv:        First scatterlist
145  * @prv_nents:  Number of entries in prv
146  * @sgl:        Second scatterlist
147  *
148  * Description:
149  *   Links @prv@ and @sgl@ together, to form a longer scatterlist.
150  *
151  **/
152 static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
153                             struct scatterlist *sgl)
154 {
155 #ifndef ARCH_HAS_SG_CHAIN
156         BUG();
157 #endif
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;
253 }
254
255 #endif /* _LINUX_SCATTERLIST_H */