1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <linux/bitops.h>
20#include <linux/bitmap.h>
21#include <linux/export.h>
22#include <linux/kernel.h>
23#include <linux/minmax.h>
24
25#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \
26 !defined(find_next_and_bit)
27
28
29
30
31
32
33
34
35static inline unsigned long _find_next_bit(const unsigned long *addr1,
36 const unsigned long *addr2, unsigned long nbits,
37 unsigned long start, unsigned long invert)
38{
39 unsigned long tmp;
40
41 if (unlikely(start >= nbits))
42 return nbits;
43
44 tmp = addr1[start / BITS_PER_LONG];
45 if (addr2)
46 tmp &= addr2[start / BITS_PER_LONG];
47 tmp ^= invert;
48
49
50 tmp &= BITMAP_FIRST_WORD_MASK(start);
51 start = round_down(start, BITS_PER_LONG);
52
53 while (!tmp) {
54 start += BITS_PER_LONG;
55 if (start >= nbits)
56 return nbits;
57
58 tmp = addr1[start / BITS_PER_LONG];
59 if (addr2)
60 tmp &= addr2[start / BITS_PER_LONG];
61 tmp ^= invert;
62 }
63
64 return min(start + __ffs(tmp), nbits);
65}
66#endif
67
68#ifndef find_next_bit
69
70
71
72unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
73 unsigned long offset)
74{
75 return _find_next_bit(addr, NULL, size, offset, 0UL);
76}
77EXPORT_SYMBOL(find_next_bit);
78#endif
79
80#ifndef find_next_zero_bit
81unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
82 unsigned long offset)
83{
84 return _find_next_bit(addr, NULL, size, offset, ~0UL);
85}
86EXPORT_SYMBOL(find_next_zero_bit);
87#endif
88
89#if !defined(find_next_and_bit)
90unsigned long find_next_and_bit(const unsigned long *addr1,
91 const unsigned long *addr2, unsigned long size,
92 unsigned long offset)
93{
94 return _find_next_bit(addr1, addr2, size, offset, 0UL);
95}
96EXPORT_SYMBOL(find_next_and_bit);
97#endif
98
99#ifndef find_first_bit
100
101
102
103unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
104{
105 unsigned long idx;
106
107 for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
108 if (addr[idx])
109 return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size);
110 }
111
112 return size;
113}
114EXPORT_SYMBOL(find_first_bit);
115#endif
116
117#ifndef find_first_zero_bit
118
119
120
121unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
122{
123 unsigned long idx;
124
125 for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
126 if (addr[idx] != ~0UL)
127 return min(idx * BITS_PER_LONG + ffz(addr[idx]), size);
128 }
129
130 return size;
131}
132EXPORT_SYMBOL(find_first_zero_bit);
133#endif
134
135#ifndef find_last_bit
136unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
137{
138 if (size) {
139 unsigned long val = BITMAP_LAST_WORD_MASK(size);
140 unsigned long idx = (size-1) / BITS_PER_LONG;
141
142 do {
143 val &= addr[idx];
144 if (val)
145 return idx * BITS_PER_LONG + __fls(val);
146
147 val = ~0ul;
148 } while (idx--);
149 }
150 return size;
151}
152EXPORT_SYMBOL(find_last_bit);
153#endif
154
155#ifdef __BIG_ENDIAN
156
157#if !defined(find_next_bit_le) || !defined(find_next_zero_bit_le)
158static inline unsigned long _find_next_bit_le(const unsigned long *addr1,
159 const unsigned long *addr2, unsigned long nbits,
160 unsigned long start, unsigned long invert)
161{
162 unsigned long tmp;
163
164 if (unlikely(start >= nbits))
165 return nbits;
166
167 tmp = addr1[start / BITS_PER_LONG];
168 if (addr2)
169 tmp &= addr2[start / BITS_PER_LONG];
170 tmp ^= invert;
171
172
173 tmp &= swab(BITMAP_FIRST_WORD_MASK(start));
174 start = round_down(start, BITS_PER_LONG);
175
176 while (!tmp) {
177 start += BITS_PER_LONG;
178 if (start >= nbits)
179 return nbits;
180
181 tmp = addr1[start / BITS_PER_LONG];
182 if (addr2)
183 tmp &= addr2[start / BITS_PER_LONG];
184 tmp ^= invert;
185 }
186
187 return min(start + __ffs(swab(tmp)), nbits);
188}
189#endif
190
191#ifndef find_next_zero_bit_le
192unsigned long find_next_zero_bit_le(const void *addr, unsigned
193 long size, unsigned long offset)
194{
195 return _find_next_bit_le(addr, NULL, size, offset, ~0UL);
196}
197EXPORT_SYMBOL(find_next_zero_bit_le);
198#endif
199
200#ifndef find_next_bit_le
201unsigned long find_next_bit_le(const void *addr, unsigned
202 long size, unsigned long offset)
203{
204 return _find_next_bit_le(addr, NULL, size, offset, 0UL);
205}
206EXPORT_SYMBOL(find_next_bit_le);
207#endif
208
209#endif
210
211unsigned long find_next_clump8(unsigned long *clump, const unsigned long *addr,
212 unsigned long size, unsigned long offset)
213{
214 offset = find_next_bit(addr, size, offset);
215 if (offset == size)
216 return size;
217
218 offset = round_down(offset, 8);
219 *clump = bitmap_get_value8(addr, offset);
220
221 return offset;
222}
223EXPORT_SYMBOL(find_next_clump8);
224