This source file includes following definitions.
- set_bit
- clear_bit
- change_bit
- test_bit
- ffz
- find_next_zero_bit
- ext2_set_bit
- ext2_clear_bit
- ext2_test_bit
- ext2_find_next_zero_bit
1
2
3
4
5
6
7 #ifndef _SPARC_BITOPS_H
8 #define _SPARC_BITOPS_H
9
10 #include <linux/kernel.h>
11
12 #ifdef __KERNEL__
13 #include <asm/system.h>
14 #endif
15
16 #ifdef __SMP__
17
18 #define SMPVOL volatile
19
20 #else
21
22 #define SMPVOL
23
24 #endif
25
26
27
28
29
30
31
32 extern __inline__ unsigned long set_bit(unsigned long nr, SMPVOL void *addr)
33 {
34 int mask, flags;
35 unsigned long *ADDR = (unsigned long *) addr;
36 unsigned long oldbit;
37
38 ADDR += nr >> 5;
39 mask = 1 << (nr & 31);
40 save_flags(flags); cli();
41 oldbit = (mask & *ADDR);
42 *ADDR |= mask;
43 restore_flags(flags);
44 return oldbit != 0;
45 }
46
47 extern __inline__ unsigned long clear_bit(unsigned long nr, SMPVOL void *addr)
48 {
49 int mask, flags;
50 unsigned long *ADDR = (unsigned long *) addr;
51 unsigned long oldbit;
52
53 ADDR += nr >> 5;
54 mask = 1 << (nr & 31);
55 save_flags(flags); cli();
56 oldbit = (mask & *ADDR);
57 *ADDR &= ~mask;
58 restore_flags(flags);
59 return oldbit != 0;
60 }
61
62 extern __inline__ unsigned long change_bit(unsigned long nr, SMPVOL void *addr)
63 {
64 int mask, flags;
65 unsigned long *ADDR = (unsigned long *) addr;
66 unsigned long oldbit;
67
68 ADDR += nr >> 5;
69 mask = 1 << (nr & 31);
70 save_flags(flags); cli();
71 oldbit = (mask & *ADDR);
72 *ADDR ^= mask;
73 restore_flags(flags);
74 return oldbit != 0;
75 }
76
77
78 extern __inline__ unsigned long test_bit(int nr, const SMPVOL void *addr)
79 {
80 return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
81 }
82
83
84 extern __inline__ unsigned long ffz(unsigned long word)
85 {
86 unsigned long result = 0;
87
88 while(word & 1) {
89 result++;
90 word >>= 1;
91 }
92 return result;
93 }
94
95
96
97
98
99
100 extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
101 {
102 unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
103 unsigned long result = offset & ~31UL;
104 unsigned long tmp;
105
106 if (offset >= size)
107 return size;
108 size -= result;
109 offset &= 31UL;
110 if (offset) {
111 tmp = *(p++);
112 tmp |= ~0UL >> (32-offset);
113 if (size < 32)
114 goto found_first;
115 if (~tmp)
116 goto found_middle;
117 size -= 32;
118 result += 32;
119 }
120 while (size & ~31UL) {
121 if (~(tmp = *(p++)))
122 goto found_middle;
123 result += 32;
124 size -= 32;
125 }
126 if (!size)
127 return result;
128 tmp = *p;
129
130 found_first:
131 tmp |= ~0UL >> size;
132 found_middle:
133 return result + ffz(tmp);
134 }
135
136
137
138
139
140 #define find_first_zero_bit(addr, size) \
141 find_next_zero_bit((addr), (size), 0)
142
143
144
145 extern __inline__ int ext2_set_bit(int nr,void * addr)
146 {
147 int mask, retval, flags;
148 unsigned char *ADDR = (unsigned char *) addr;
149
150 ADDR += nr >> 3;
151 mask = 1 << (nr & 0x07);
152 save_flags(flags); cli();
153 retval = (mask & *ADDR) != 0;
154 *ADDR |= mask;
155 restore_flags(flags);
156 return retval;
157 }
158
159 extern __inline__ int ext2_clear_bit(int nr, void * addr)
160 {
161 int mask, retval, flags;
162 unsigned char *ADDR = (unsigned char *) addr;
163
164 ADDR += nr >> 3;
165 mask = 1 << (nr & 0x07);
166 save_flags(flags); cli();
167 retval = (mask & *ADDR) != 0;
168 *ADDR &= ~mask;
169 restore_flags(flags);
170 return retval;
171 }
172
173 extern __inline__ int ext2_test_bit(int nr, const void * addr)
174 {
175 int mask;
176 const unsigned char *ADDR = (const unsigned char *) addr;
177
178 ADDR += nr >> 3;
179 mask = 1 << (nr & 0x07);
180 return ((mask & *ADDR) != 0);
181 }
182
183 #define ext2_find_first_zero_bit(addr, size) \
184 ext2_find_next_zero_bit((addr), (size), 0)
185
186 extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
187 {
188 unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
189 unsigned long result = offset & ~31UL;
190 unsigned long tmp;
191
192 if (offset >= size)
193 return size;
194 size -= result;
195 offset &= 31UL;
196 if(offset) {
197 tmp = *(p++);
198 tmp |= ~0UL << (32-offset);
199 if(size < 32)
200 goto found_first;
201 if(~tmp)
202 goto found_middle;
203 size -= 32;
204 result += 32;
205 }
206 while(size & ~31UL) {
207 if(~(tmp = *(p++)))
208 goto found_middle;
209 result += 32;
210 size -= 32;
211 }
212 if(!size)
213 return result;
214 tmp = *p;
215
216 found_first:
217 tmp |= ~0UL << size;
218 found_middle:
219 tmp = ((tmp>>24) | ((tmp>>8)&0xff00) | ((tmp<<8)&0xff0000) | (tmp<<24));
220 return result + ffz(tmp);
221 }
222
223 #endif
224