patch-2.4.22 linux-2.4.22/include/asm-mips/bitops.h

Next file: linux-2.4.22/include/asm-mips/bootinfo.h
Previous file: linux-2.4.22/include/asm-mips/baget/vic.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/include/asm-mips/bitops.h linux-2.4.22/include/asm-mips/bitops.h
@@ -13,6 +13,14 @@
 #include <linux/types.h>
 #include <asm/byteorder.h>		/* sigh ... */
 
+#if (_MIPS_SZLONG == 32)
+#define SZLONG_LOG 5
+#define SZLONG_MASK 31UL
+#elif (_MIPS_SZLONG == 64)
+#define SZLONG_LOG 6
+#define SZLONG_MASK 63UL 
+#endif
+
 #ifdef __KERNEL__
 
 #include <asm/sgidefs.h>
@@ -28,17 +36,17 @@
  * Only disable interrupt for kernel mode stuff to keep usermode stuff
  * that dares to use kernel include files alive.
  */
-#define __bi_flags unsigned long flags
-#define __bi_cli() __cli()
-#define __bi_save_flags(x) __save_flags(x)
-#define __bi_save_and_cli(x) __save_and_cli(x)
-#define __bi_restore_flags(x) __restore_flags(x)
+#define __bi_flags			unsigned long flags
+#define __bi_cli()			local_irq_disable()
+#define __bi_save_flags(x)		local_save_flags(x)
+#define __bi_local_irq_save(x)		local_irq_save(x)
+#define __bi_local_irq_restore(x)	local_irq_restore(x)
 #else
 #define __bi_flags
 #define __bi_cli()
 #define __bi_save_flags(x)
-#define __bi_save_and_cli(x)
-#define __bi_restore_flags(x)
+#define __bi_local_irq_save(x)
+#define __bi_local_irq_restore(x)
 #endif /* __KERNEL__ */
 
 #ifdef CONFIG_CPU_HAS_LLSC
@@ -58,8 +66,7 @@
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-extern __inline__ void
-set_bit(int nr, volatile void *addr)
+static __inline__ void set_bit(int nr, volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
 	unsigned long temp;
@@ -82,7 +89,7 @@
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-extern __inline__ void __set_bit(int nr, volatile void * addr)
+static __inline__ void __set_bit(int nr, volatile void * addr)
 {
 	unsigned long * m = ((unsigned long *) addr) + (nr >> 5);
 
@@ -99,8 +106,7 @@
  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  * in order to ensure changes are visible on other processors.
  */
-extern __inline__ void
-clear_bit(int nr, volatile void *addr)
+static __inline__ void clear_bit(int nr, volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
 	unsigned long temp;
@@ -123,8 +129,7 @@
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-extern __inline__ void
-change_bit(int nr, volatile void *addr)
+static __inline__ void change_bit(int nr, volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
 	unsigned long temp;
@@ -140,14 +145,14 @@
 
 /*
  * __change_bit - Toggle a bit in memory
- * @nr: the bit to set
+ * @nr: the bit to change
  * @addr: the address to start counting from
  *
  * Unlike change_bit(), this function is non-atomic and may be reordered.
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-extern __inline__ void __change_bit(int nr, volatile void * addr)
+static __inline__ void __change_bit(int nr, volatile void * addr)
 {
 	unsigned long * m = ((unsigned long *) addr) + (nr >> 5);
 
@@ -162,11 +167,11 @@
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-extern __inline__ int
-test_and_set_bit(int nr, volatile void *addr)
+static __inline__ int test_and_set_bit(int nr, volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
-	unsigned long temp, res;
+	unsigned long temp;
+	int res;
 
 	__asm__ __volatile__(
 		".set\tnoreorder\t\t# test_and_set_bit\n"
@@ -195,10 +200,11 @@
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
 {
-	int mask, retval;
-	volatile int *a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
+	int retval;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
@@ -210,14 +216,13 @@
 
 /*
  * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
  * @addr: Address to count from
  *
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-extern __inline__ int
-test_and_clear_bit(int nr, volatile void *addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
 	unsigned long temp, res;
@@ -243,17 +248,17 @@
 
 /*
  * __test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
  * @addr: Address to count from
  *
  * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
 {
-	int	mask, retval;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask, retval;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
@@ -265,14 +270,13 @@
 
 /*
  * test_and_change_bit - Change a bit and return its new value
- * @nr: Bit to set
+ * @nr: Bit to change
  * @addr: Address to count from
  *
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-extern __inline__ int
-test_and_change_bit(int nr, volatile void *addr)
+static __inline__ int test_and_change_bit(int nr, volatile void *addr)
 {
 	unsigned long *m = ((unsigned long *) addr) + (nr >> 5);
 	unsigned long temp, res;
@@ -297,17 +301,18 @@
 
 /*
  * __test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to change
  * @addr: Address to count from
  *
  * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
 {
-	int	mask, retval;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
+	int retval;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
@@ -329,17 +334,17 @@
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-extern __inline__ void set_bit(int nr, volatile void * addr)
+static __inline__ void set_bit(int nr, volatile void * addr)
 {
-	int	mask;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
 	__bi_flags;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_and_cli(flags);
+	__bi_local_irq_save(flags);
 	*a |= mask;
-	__bi_restore_flags(flags);
+	__bi_local_irq_restore(flags);
 }
 
 /*
@@ -351,10 +356,10 @@
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-extern __inline__ void __set_bit(int nr, volatile void * addr)
+static __inline__ void __set_bit(int nr, volatile void * addr)
 {
-	int	mask;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
@@ -371,51 +376,51 @@
  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  * in order to ensure changes are visible on other processors.
  */
-extern __inline__ void clear_bit(int nr, volatile void * addr)
+static __inline__ void clear_bit(int nr, volatile void * addr)
 {
-	int	mask;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
 	__bi_flags;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_and_cli(flags);
+	__bi_local_irq_save(flags);
 	*a &= ~mask;
-	__bi_restore_flags(flags);
+	__bi_local_irq_restore(flags);
 }
 
 /*
  * change_bit - Toggle a bit in memory
- * @nr: Bit to clear
+ * @nr: Bit to change
  * @addr: Address to start counting from
  *
  * change_bit() is atomic and may not be reordered.
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-extern __inline__ void change_bit(int nr, volatile void * addr)
+static __inline__ void change_bit(int nr, volatile void * addr)
 {
-	int	mask;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
 	__bi_flags;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_and_cli(flags);
+	__bi_local_irq_save(flags);
 	*a ^= mask;
-	__bi_restore_flags(flags);
+	__bi_local_irq_restore(flags);
 }
 
 /*
  * __change_bit - Toggle a bit in memory
- * @nr: the bit to set
+ * @nr: the bit to change
  * @addr: the address to start counting from
  *
  * Unlike change_bit(), this function is non-atomic and may be reordered.
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-extern __inline__ void __change_bit(int nr, volatile void * addr)
+static __inline__ void __change_bit(int nr, volatile void * addr)
 {
 	unsigned long * m = ((unsigned long *) addr) + (nr >> 5);
 
@@ -430,18 +435,19 @@
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
 {
-	int	mask, retval;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
+	int retval;
 	__bi_flags;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_and_cli(flags);
+	__bi_local_irq_save(flags);
 	retval = (mask & *a) != 0;
 	*a |= mask;
-	__bi_restore_flags(flags);
+	__bi_local_irq_restore(flags);
 
 	return retval;
 }
@@ -455,10 +461,11 @@
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-extern __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
 {
-	int	mask, retval;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
+	int retval;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
@@ -470,41 +477,43 @@
 
 /*
  * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
  * @addr: Address to count from
  *
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
 {
-	int	mask, retval;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
+	int retval;
 	__bi_flags;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_and_cli(flags);
+	__bi_local_irq_save(flags);
 	retval = (mask & *a) != 0;
 	*a &= ~mask;
-	__bi_restore_flags(flags);
+	__bi_local_irq_restore(flags);
 
 	return retval;
 }
 
 /*
  * __test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
  * @addr: Address to count from
  *
  * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
 {
-	int	mask, retval;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
+	int retval;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
@@ -516,41 +525,42 @@
 
 /*
  * test_and_change_bit - Change a bit and return its new value
- * @nr: Bit to set
+ * @nr: Bit to change
  * @addr: Address to count from
  *
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
 {
-	int	mask, retval;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask, retval;
 	__bi_flags;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	__bi_save_and_cli(flags);
+	__bi_local_irq_save(flags);
 	retval = (mask & *a) != 0;
 	*a ^= mask;
-	__bi_restore_flags(flags);
+	__bi_local_irq_restore(flags);
 
 	return retval;
 }
 
 /*
  * __test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to change
  * @addr: Address to count from
  *
  * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-extern __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
 {
-	int	mask, retval;
-	volatile int	*a = addr;
+	volatile unsigned long *a = addr;
+	unsigned long mask;
+	int retval;
 
 	a += nr >> 5;
 	mask = 1 << (nr & 0x1f);
@@ -563,7 +573,7 @@
 #undef __bi_flags
 #undef __bi_cli
 #undef __bi_save_flags
-#undef __bi_restore_flags
+#undef __bi_local_irq_restore
 
 #endif /* MIPS I */
 
@@ -572,112 +582,11 @@
  * @nr: bit number to test
  * @addr: Address to start counting from
  */
-extern __inline__ int test_bit(int nr, volatile void *addr)
+static inline int test_bit(int nr, volatile void *addr)
 {
-	return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
+	return 1UL & (((const volatile unsigned long *) addr)[nr >> SZLONG_LOG] >> (nr & SZLONG_MASK));
 }
 
-#ifndef __MIPSEB__
-
-/* Little endian versions. */
-
-/*
- * find_first_zero_bit - find the first zero bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
- *
- * Returns the bit-number of the first zero bit, not the number of the byte
- * containing a bit.
- */
-extern __inline__ int find_first_zero_bit (void *addr, unsigned size)
-{
-	unsigned long dummy;
-	int res;
-
-	if (!size)
-		return 0;
-
-	__asm__ (".set\tnoreorder\n\t"
-		".set\tnoat\n"
-		"1:\tsubu\t$1,%6,%0\n\t"
-		"blez\t$1,2f\n\t"
-		"lw\t$1,(%5)\n\t"
-		"addiu\t%5,4\n\t"
-#if (_MIPS_ISA == _MIPS_ISA_MIPS2 ) || (_MIPS_ISA == _MIPS_ISA_MIPS3 ) || \
-    (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5 ) || \
-    (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
-		"beql\t%1,$1,1b\n\t"
-		"addiu\t%0,32\n\t"
-#else
-		"addiu\t%0,32\n\t"
-		"beq\t%1,$1,1b\n\t"
-		"nop\n\t"
-		"subu\t%0,32\n\t"
-#endif
-#ifdef __MIPSEB__
-#error "Fix this for big endian"
-#endif /* __MIPSEB__ */
-		"li\t%1,1\n"
-		"1:\tand\t%2,$1,%1\n\t"
-		"beqz\t%2,2f\n\t"
-		"sll\t%1,%1,1\n\t"
-		"bnez\t%1,1b\n\t"
-		"add\t%0,%0,1\n\t"
-		".set\tat\n\t"
-		".set\treorder\n"
-		"2:"
-		: "=r" (res), "=r" (dummy), "=r" (addr)
-		: "0" ((signed int) 0), "1" ((unsigned int) 0xffffffff),
-		  "2" (addr), "r" (size));
-
-	return res;
-}
-
-/*
- * find_next_zero_bit - find the first zero bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
- */
-extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
-{
-	unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
-	int set = 0, bit = offset & 31, res;
-	unsigned long dummy;
-
-	if (bit) {
-		/*
-		 * Look for zero in first byte
-		 */
-#ifdef __MIPSEB__
-#error "Fix this for big endian byte order"
-#endif
-		__asm__(".set\tnoreorder\n\t"
-			".set\tnoat\n"
-			"1:\tand\t$1,%4,%1\n\t"
-			"beqz\t$1,1f\n\t"
-			"sll\t%1,%1,1\n\t"
-			"bnez\t%1,1b\n\t"
-			"addiu\t%0,1\n\t"
-			".set\tat\n\t"
-			".set\treorder\n"
-			"1:"
-			: "=r" (set), "=r" (dummy)
-			: "0" (0), "1" (1 << bit), "r" (*p));
-		if (set < (32 - bit))
-			return set + offset;
-		set = 32 - bit;
-		p++;
-	}
-	/*
-	 * No zero yet, search remaining full bytes for a zero
-	 */
-	res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr));
-	return offset + set + res;
-}
-
-#endif /* !(__MIPSEB__) */
-
 /*
  * ffz - find first zero in word.
  * @word: The word to search
@@ -701,38 +610,23 @@
 
 #ifdef __KERNEL__
 
-/**
+/*
  * ffs - find first bit set
  * @x: the word to search
  *
- * This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
+ * Undefined if no bit exists, so code should check against 0 first.
  */
 
 #define ffs(x) generic_ffs(x)
 
 /*
- * hweightN - returns the hamming weight of a N-bit word
- * @x: the word to weigh
- *
- * The Hamming Weight of a number is the total number of bits set in it.
- */
-
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
-
-#endif /* __KERNEL__ */
-
-#ifdef __MIPSEB__
-/*
  * find_next_zero_bit - find the first zero bit in a memory region
  * @addr: The address to base the search on
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-extern __inline__ int find_next_zero_bit(void *addr, int size, int offset)
+static inline long find_next_zero_bit(void *addr, unsigned long size,
+	unsigned long offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
 	unsigned long result = offset & ~31UL;
@@ -768,9 +662,8 @@
 	return result + ffz(tmp);
 }
 
-/* Linus sez that gcc can optimize the following correctly, we'll see if this
- * holds on the Sparc as it does for the ALPHA.
- */
+#define find_first_zero_bit(addr, size) \
+	find_next_zero_bit((addr), (size), 0)
 
 #if 0 /* Fool kernel-doc since it doesn't do macros yet */
 /*
@@ -781,121 +674,129 @@
  * Returns the bit-number of the first zero bit, not the number of the byte
  * containing a bit.
  */
-extern int find_first_zero_bit (void *addr, unsigned size);
+static int find_first_zero_bit (void *addr, unsigned size);
 #endif
 
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
 
-#endif /* (__MIPSEB__) */
 
-/* Now for the ext2 filesystem bit operations and helper routines. */
+/*
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
 
-#ifdef __MIPSEB__
-extern __inline__ int ext2_set_bit(int nr, void * addr)
+static __inline__ int __test_and_set_le_bit(int nr, void * addr)
 {
-	int		mask, retval, flags;
 	unsigned char	*ADDR = (unsigned char *) addr;
+	int		mask, retval;
 
 	ADDR += nr >> 3;
 	mask = 1 << (nr & 0x07);
-	save_and_cli(flags);
 	retval = (mask & *ADDR) != 0;
 	*ADDR |= mask;
-	restore_flags(flags);
+
 	return retval;
 }
 
-extern __inline__ int ext2_clear_bit(int nr, void * addr)
+static __inline__ int __test_and_clear_le_bit(int nr, void * addr)
 {
-	int		mask, retval, flags;
 	unsigned char	*ADDR = (unsigned char *) addr;
+	int		mask, retval;
 
 	ADDR += nr >> 3;
 	mask = 1 << (nr & 0x07);
-	save_and_cli(flags);
 	retval = (mask & *ADDR) != 0;
 	*ADDR &= ~mask;
-	restore_flags(flags);
+
 	return retval;
 }
 
-extern __inline__ int ext2_test_bit(int nr, const void * addr)
+static __inline__ int test_le_bit(int nr, const void * addr)
 {
-	int			mask;
 	const unsigned char	*ADDR = (const unsigned char *) addr;
+	int			mask;
 
 	ADDR += nr >> 3;
 	mask = 1 << (nr & 0x07);
+
 	return ((mask & *ADDR) != 0);
 }
 
-#define ext2_find_first_zero_bit(addr, size) \
-        ext2_find_next_zero_bit((addr), (size), 0)
+static inline unsigned long ext2_ffz(unsigned int word)
+{
+	int b = 0, s;
+
+	word = ~word;
+	s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s;
+	s =  8; if (word << 24 != 0) s = 0; b += s; word >>= s;
+	s =  4; if (word << 28 != 0) s = 0; b += s; word >>= s;
+	s =  2; if (word << 30 != 0) s = 0; b += s; word >>= s;
+	s =  1; if (word << 31 != 0) s = 0; b += s;
+
+	return b;
+}
 
-extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+static inline unsigned long find_next_zero_le_bit(void *addr,
+	unsigned long size, unsigned long offset)
 {
-	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
-	unsigned long result = offset & ~31UL;
-	unsigned long tmp;
+	unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
+	unsigned int result = offset & ~31;
+	unsigned int tmp;
 
 	if (offset >= size)
 		return size;
+
 	size -= result;
-	offset &= 31UL;
-	if(offset) {
-		/* We hold the little endian value in tmp, but then the
-		 * shift is illegal. So we could keep a big endian value
-		 * in tmp, like this:
-		 *
-		 * tmp = __swab32(*(p++));
-		 * tmp |= ~0UL >> (32-offset);
-		 *
-		 * but this would decrease preformance, so we change the
-		 * shift:
-		 */
-		tmp = *(p++);
-		tmp |= __swab32(~0UL >> (32-offset));
-		if(size < 32)
+	offset &= 31;
+	if (offset) {
+		tmp = cpu_to_le32p(p++);
+		tmp |= ~0U >> (32-offset); /* bug or feature ? */
+		if (size < 32)
 			goto found_first;
-		if(~tmp)
+		if (tmp != ~0U)
 			goto found_middle;
 		size -= 32;
 		result += 32;
 	}
-	while(size & ~31UL) {
-		if(~(tmp = *(p++)))
+	while (size >= 32) {
+		if ((tmp = cpu_to_le32p(p++)) != ~0U)
 			goto found_middle;
 		result += 32;
 		size -= 32;
 	}
-	if(!size)
+	if (!size)
 		return result;
-	tmp = *p;
 
+	tmp = cpu_to_le32p(p);
 found_first:
-	/* tmp is little endian, so we would have to swab the shift,
-	 * see above. But then we have to swab tmp below for ffz, so
-	 * we might as well do this here.
-	 */
-	return result + ffz(__swab32(tmp) | (~0UL << size));
+	tmp |= ~0 << size;
+	if (tmp == ~0U)			/* Are any bits zero? */
+		return result + size;	/* Nope. */
+
 found_middle:
-	return result + ffz(__swab32(tmp));
+	return result + ext2_ffz(tmp);
 }
-#else /* !(__MIPSEB__) */
 
-/* Native ext2 byte ordering, just collapse using defines. */
-#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
-#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr))
-#define ext2_test_bit(nr, addr) test_bit((nr), (addr))
-#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
-#define ext2_find_next_zero_bit(addr, size, offset) \
-                find_next_zero_bit((addr), (size), (offset))
+#define find_first_zero_le_bit(addr, size) \
+	find_next_zero_le_bit((addr), (size), 0)
 
-#endif /* !(__MIPSEB__) */
+#define ext2_set_bit			__test_and_set_le_bit
+#define ext2_clear_bit			__test_and_clear_le_bit
+#define ext2_test_bit			test_le_bit
+#define ext2_find_first_zero_bit	find_first_zero_le_bit
+#define ext2_find_next_zero_bit		find_next_zero_le_bit
 
 /*
  * Bitmap functions for the minix filesystem.
+ *
  * FIXME: These assume that Minix uses the native byte/bitorder.
  * This limits the Minix filesystem's value for data exchange very much.
  */
@@ -905,4 +806,6 @@
 #define minix_test_bit(nr,addr) test_bit(nr,addr)
 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
 
+#endif /* __KERNEL__ */
+
 #endif /* _ASM_BITOPS_H */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)