diff options
author | Akinobu Mita <mita@miraclelinux.com> | 2006-03-26 04:39:30 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-26 11:57:13 -0500 |
commit | 3c9ee7ef87414cba80dbdf433d3547bb20055ef7 (patch) | |
tree | 33ba680da1c758bbee02979589600eda2d1f03ac | |
parent | d2d7cdcf6e6d2a3db9885316d075940f12324413 (diff) |
[PATCH] bitops: mips: use generic bitops
- remove __{,test_and_}{set,clear,change}_bit() and test_bit()
- unless defined(CONFIG_CPU_MIPS32) or defined(CONFIG_CPU_MIPS64)
- remove __ffs()
- remove ffs()
- remove ffz()
- remove fls()
- remove fls64()
- remove find_{next,first}{,_zero}_bit()
- remove sched_find_first_bit()
- remove generic_hweight64()
- remove generic_hweight{32,16,8}()
- remove ext2_{set,clear,test,find_first_zero,find_next_zero}_bit()
- remove ext2_{set,clear}_bit_atomic()
- remove minix_{test,set,test_and_clear,test,find_first_zero}_bit()
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/mips/Kconfig | 8 | ||||
-rw-r--r-- | include/asm-mips/bitops.h | 465 |
2 files changed, 24 insertions, 449 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index ac2012f033d6..5080ea1799a4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -801,6 +801,14 @@ config RWSEM_GENERIC_SPINLOCK | |||
801 | config RWSEM_XCHGADD_ALGORITHM | 801 | config RWSEM_XCHGADD_ALGORITHM |
802 | bool | 802 | bool |
803 | 803 | ||
804 | config GENERIC_FIND_NEXT_BIT | ||
805 | bool | ||
806 | default y | ||
807 | |||
808 | config GENERIC_HWEIGHT | ||
809 | bool | ||
810 | default y | ||
811 | |||
804 | config GENERIC_CALIBRATE_DELAY | 812 | config GENERIC_CALIBRATE_DELAY |
805 | bool | 813 | bool |
806 | default y | 814 | default y |
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 0e83abc829d4..a1728f8c0705 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h | |||
@@ -105,22 +105,6 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * __set_bit - Set a bit in memory | ||
109 | * @nr: the bit to set | ||
110 | * @addr: the address to start counting from | ||
111 | * | ||
112 | * Unlike set_bit(), this function is non-atomic and may be reordered. | ||
113 | * If it's called on the same region of memory simultaneously, the effect | ||
114 | * may be that only one operation succeeds. | ||
115 | */ | ||
116 | static inline void __set_bit(unsigned long nr, volatile unsigned long * addr) | ||
117 | { | ||
118 | unsigned long * m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | ||
119 | |||
120 | *m |= 1UL << (nr & SZLONG_MASK); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * clear_bit - Clears a bit in memory | 108 | * clear_bit - Clears a bit in memory |
125 | * @nr: Bit to clear | 109 | * @nr: Bit to clear |
126 | * @addr: Address to start counting from | 110 | * @addr: Address to start counting from |
@@ -169,22 +153,6 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
169 | } | 153 | } |
170 | 154 | ||
171 | /* | 155 | /* |
172 | * __clear_bit - Clears a bit in memory | ||
173 | * @nr: Bit to clear | ||
174 | * @addr: Address to start counting from | ||
175 | * | ||
176 | * Unlike clear_bit(), this function is non-atomic and may be reordered. | ||
177 | * If it's called on the same region of memory simultaneously, the effect | ||
178 | * may be that only one operation succeeds. | ||
179 | */ | ||
180 | static inline void __clear_bit(unsigned long nr, volatile unsigned long * addr) | ||
181 | { | ||
182 | unsigned long * m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | ||
183 | |||
184 | *m &= ~(1UL << (nr & SZLONG_MASK)); | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * change_bit - Toggle a bit in memory | 156 | * change_bit - Toggle a bit in memory |
189 | * @nr: Bit to change | 157 | * @nr: Bit to change |
190 | * @addr: Address to start counting from | 158 | * @addr: Address to start counting from |
@@ -235,22 +203,6 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
235 | } | 203 | } |
236 | 204 | ||
237 | /* | 205 | /* |
238 | * __change_bit - Toggle a bit in memory | ||
239 | * @nr: the bit to change | ||
240 | * @addr: the address to start counting from | ||
241 | * | ||
242 | * Unlike change_bit(), this function is non-atomic and may be reordered. | ||
243 | * If it's called on the same region of memory simultaneously, the effect | ||
244 | * may be that only one operation succeeds. | ||
245 | */ | ||
246 | static inline void __change_bit(unsigned long nr, volatile unsigned long * addr) | ||
247 | { | ||
248 | unsigned long * m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | ||
249 | |||
250 | *m ^= 1UL << (nr & SZLONG_MASK); | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * test_and_set_bit - Set a bit and return its old value | 206 | * test_and_set_bit - Set a bit and return its old value |
255 | * @nr: Bit to set | 207 | * @nr: Bit to set |
256 | * @addr: Address to count from | 208 | * @addr: Address to count from |
@@ -321,30 +273,6 @@ static inline int test_and_set_bit(unsigned long nr, | |||
321 | } | 273 | } |
322 | 274 | ||
323 | /* | 275 | /* |
324 | * __test_and_set_bit - Set a bit and return its old value | ||
325 | * @nr: Bit to set | ||
326 | * @addr: Address to count from | ||
327 | * | ||
328 | * This operation is non-atomic and can be reordered. | ||
329 | * If two examples of this operation race, one can appear to succeed | ||
330 | * but actually fail. You must protect multiple accesses with a lock. | ||
331 | */ | ||
332 | static inline int __test_and_set_bit(unsigned long nr, | ||
333 | volatile unsigned long *addr) | ||
334 | { | ||
335 | volatile unsigned long *a = addr; | ||
336 | unsigned long mask; | ||
337 | int retval; | ||
338 | |||
339 | a += nr >> SZLONG_LOG; | ||
340 | mask = 1UL << (nr & SZLONG_MASK); | ||
341 | retval = (mask & *a) != 0; | ||
342 | *a |= mask; | ||
343 | |||
344 | return retval; | ||
345 | } | ||
346 | |||
347 | /* | ||
348 | * test_and_clear_bit - Clear a bit and return its old value | 276 | * test_and_clear_bit - Clear a bit and return its old value |
349 | * @nr: Bit to clear | 277 | * @nr: Bit to clear |
350 | * @addr: Address to count from | 278 | * @addr: Address to count from |
@@ -417,30 +345,6 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
417 | } | 345 | } |
418 | 346 | ||
419 | /* | 347 | /* |
420 | * __test_and_clear_bit - Clear a bit and return its old value | ||
421 | * @nr: Bit to clear | ||
422 | * @addr: Address to count from | ||
423 | * | ||
424 | * This operation is non-atomic and can be reordered. | ||
425 | * If two examples of this operation race, one can appear to succeed | ||
426 | * but actually fail. You must protect multiple accesses with a lock. | ||
427 | */ | ||
428 | static inline int __test_and_clear_bit(unsigned long nr, | ||
429 | volatile unsigned long * addr) | ||
430 | { | ||
431 | volatile unsigned long *a = addr; | ||
432 | unsigned long mask; | ||
433 | int retval; | ||
434 | |||
435 | a += (nr >> SZLONG_LOG); | ||
436 | mask = 1UL << (nr & SZLONG_MASK); | ||
437 | retval = ((mask & *a) != 0); | ||
438 | *a &= ~mask; | ||
439 | |||
440 | return retval; | ||
441 | } | ||
442 | |||
443 | /* | ||
444 | * test_and_change_bit - Change a bit and return its old value | 348 | * test_and_change_bit - Change a bit and return its old value |
445 | * @nr: Bit to change | 349 | * @nr: Bit to change |
446 | * @addr: Address to count from | 350 | * @addr: Address to count from |
@@ -509,43 +413,11 @@ static inline int test_and_change_bit(unsigned long nr, | |||
509 | } | 413 | } |
510 | } | 414 | } |
511 | 415 | ||
512 | /* | ||
513 | * __test_and_change_bit - Change a bit and return its old value | ||
514 | * @nr: Bit to change | ||
515 | * @addr: Address to count from | ||
516 | * | ||
517 | * This operation is non-atomic and can be reordered. | ||
518 | * If two examples of this operation race, one can appear to succeed | ||
519 | * but actually fail. You must protect multiple accesses with a lock. | ||
520 | */ | ||
521 | static inline int __test_and_change_bit(unsigned long nr, | ||
522 | volatile unsigned long *addr) | ||
523 | { | ||
524 | volatile unsigned long *a = addr; | ||
525 | unsigned long mask; | ||
526 | int retval; | ||
527 | |||
528 | a += (nr >> SZLONG_LOG); | ||
529 | mask = 1UL << (nr & SZLONG_MASK); | ||
530 | retval = ((mask & *a) != 0); | ||
531 | *a ^= mask; | ||
532 | |||
533 | return retval; | ||
534 | } | ||
535 | |||
536 | #undef __bi_flags | 416 | #undef __bi_flags |
537 | #undef __bi_local_irq_save | 417 | #undef __bi_local_irq_save |
538 | #undef __bi_local_irq_restore | 418 | #undef __bi_local_irq_restore |
539 | 419 | ||
540 | /* | 420 | #include <asm-generic/bitops/non-atomic.h> |
541 | * test_bit - Determine whether a bit is set | ||
542 | * @nr: bit number to test | ||
543 | * @addr: Address to start counting from | ||
544 | */ | ||
545 | static inline int test_bit(unsigned long nr, const volatile unsigned long *addr) | ||
546 | { | ||
547 | return 1UL & (addr[nr >> SZLONG_LOG] >> (nr & SZLONG_MASK)); | ||
548 | } | ||
549 | 421 | ||
550 | /* | 422 | /* |
551 | * Return the bit position (0..63) of the most significant 1 bit in a word | 423 | * Return the bit position (0..63) of the most significant 1 bit in a word |
@@ -580,6 +452,8 @@ static inline int __ilog2(unsigned long x) | |||
580 | return 63 - lz; | 452 | return 63 - lz; |
581 | } | 453 | } |
582 | 454 | ||
455 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
456 | |||
583 | /* | 457 | /* |
584 | * __ffs - find first bit in word. | 458 | * __ffs - find first bit in word. |
585 | * @word: The word to search | 459 | * @word: The word to search |
@@ -589,31 +463,7 @@ static inline int __ilog2(unsigned long x) | |||
589 | */ | 463 | */ |
590 | static inline unsigned long __ffs(unsigned long word) | 464 | static inline unsigned long __ffs(unsigned long word) |
591 | { | 465 | { |
592 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
593 | return __ilog2(word & -word); | 466 | return __ilog2(word & -word); |
594 | #else | ||
595 | int b = 0, s; | ||
596 | |||
597 | #ifdef CONFIG_32BIT | ||
598 | s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s; | ||
599 | s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s; | ||
600 | s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s; | ||
601 | s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s; | ||
602 | s = 1; if (word << 31 != 0) s = 0; b += s; | ||
603 | |||
604 | return b; | ||
605 | #endif | ||
606 | #ifdef CONFIG_64BIT | ||
607 | s = 32; if (word << 32 != 0) s = 0; b += s; word >>= s; | ||
608 | s = 16; if (word << 48 != 0) s = 0; b += s; word >>= s; | ||
609 | s = 8; if (word << 56 != 0) s = 0; b += s; word >>= s; | ||
610 | s = 4; if (word << 60 != 0) s = 0; b += s; word >>= s; | ||
611 | s = 2; if (word << 62 != 0) s = 0; b += s; word >>= s; | ||
612 | s = 1; if (word << 63 != 0) s = 0; b += s; | ||
613 | |||
614 | return b; | ||
615 | #endif | ||
616 | #endif | ||
617 | } | 467 | } |
618 | 468 | ||
619 | /* | 469 | /* |
@@ -652,321 +502,38 @@ static inline unsigned long ffz(unsigned long word) | |||
652 | */ | 502 | */ |
653 | static inline unsigned long fls(unsigned long word) | 503 | static inline unsigned long fls(unsigned long word) |
654 | { | 504 | { |
655 | #ifdef CONFIG_32BIT | ||
656 | #ifdef CONFIG_CPU_MIPS32 | 505 | #ifdef CONFIG_CPU_MIPS32 |
657 | __asm__ ("clz %0, %1" : "=r" (word) : "r" (word)); | 506 | __asm__ ("clz %0, %1" : "=r" (word) : "r" (word)); |
658 | 507 | ||
659 | return 32 - word; | 508 | return 32 - word; |
660 | #else | ||
661 | { | ||
662 | int r = 32, s; | ||
663 | |||
664 | if (word == 0) | ||
665 | return 0; | ||
666 | |||
667 | s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s; | ||
668 | s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s; | ||
669 | s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s; | ||
670 | s = 2; if ((word & 0xc0000000)) s = 0; r -= s; word <<= s; | ||
671 | s = 1; if ((word & 0x80000000)) s = 0; r -= s; | ||
672 | |||
673 | return r; | ||
674 | } | ||
675 | #endif | 509 | #endif |
676 | #endif /* CONFIG_32BIT */ | ||
677 | 510 | ||
678 | #ifdef CONFIG_64BIT | ||
679 | #ifdef CONFIG_CPU_MIPS64 | 511 | #ifdef CONFIG_CPU_MIPS64 |
680 | |||
681 | __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word)); | 512 | __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word)); |
682 | 513 | ||
683 | return 64 - word; | 514 | return 64 - word; |
684 | #else | ||
685 | { | ||
686 | int r = 64, s; | ||
687 | |||
688 | if (word == 0) | ||
689 | return 0; | ||
690 | |||
691 | s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s; | ||
692 | s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s; | ||
693 | s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s; | ||
694 | s = 4; if ((word & 0xf000000000000000UL)) s = 0; r -= s; word <<= s; | ||
695 | s = 2; if ((word & 0xc000000000000000UL)) s = 0; r -= s; word <<= s; | ||
696 | s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s; | ||
697 | |||
698 | return r; | ||
699 | } | ||
700 | #endif | 515 | #endif |
701 | #endif /* CONFIG_64BIT */ | ||
702 | } | 516 | } |
703 | 517 | ||
704 | #define fls64(x) generic_fls64(x) | 518 | #else |
705 | |||
706 | /* | ||
707 | * find_next_zero_bit - find the first zero bit in a memory region | ||
708 | * @addr: The address to base the search on | ||
709 | * @offset: The bitnumber to start searching at | ||
710 | * @size: The maximum size to search | ||
711 | */ | ||
712 | static inline unsigned long find_next_zero_bit(const unsigned long *addr, | ||
713 | unsigned long size, unsigned long offset) | ||
714 | { | ||
715 | const unsigned long *p = addr + (offset >> SZLONG_LOG); | ||
716 | unsigned long result = offset & ~SZLONG_MASK; | ||
717 | unsigned long tmp; | ||
718 | |||
719 | if (offset >= size) | ||
720 | return size; | ||
721 | size -= result; | ||
722 | offset &= SZLONG_MASK; | ||
723 | if (offset) { | ||
724 | tmp = *(p++); | ||
725 | tmp |= ~0UL >> (_MIPS_SZLONG-offset); | ||
726 | if (size < _MIPS_SZLONG) | ||
727 | goto found_first; | ||
728 | if (~tmp) | ||
729 | goto found_middle; | ||
730 | size -= _MIPS_SZLONG; | ||
731 | result += _MIPS_SZLONG; | ||
732 | } | ||
733 | while (size & ~SZLONG_MASK) { | ||
734 | if (~(tmp = *(p++))) | ||
735 | goto found_middle; | ||
736 | result += _MIPS_SZLONG; | ||
737 | size -= _MIPS_SZLONG; | ||
738 | } | ||
739 | if (!size) | ||
740 | return result; | ||
741 | tmp = *p; | ||
742 | |||
743 | found_first: | ||
744 | tmp |= ~0UL << size; | ||
745 | if (tmp == ~0UL) /* Are any bits zero? */ | ||
746 | return result + size; /* Nope. */ | ||
747 | found_middle: | ||
748 | return result + ffz(tmp); | ||
749 | } | ||
750 | 519 | ||
751 | #define find_first_zero_bit(addr, size) \ | 520 | #include <asm-generic/bitops/__ffs.h> |
752 | find_next_zero_bit((addr), (size), 0) | 521 | #include <asm-generic/bitops/ffs.h> |
522 | #include <asm-generic/bitops/ffz.h> | ||
523 | #include <asm-generic/bitops/fls.h> | ||
753 | 524 | ||
754 | /* | 525 | #endif /*defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) */ |
755 | * find_next_bit - find the next set bit in a memory region | ||
756 | * @addr: The address to base the search on | ||
757 | * @offset: The bitnumber to start searching at | ||
758 | * @size: The maximum size to search | ||
759 | */ | ||
760 | static inline unsigned long find_next_bit(const unsigned long *addr, | ||
761 | unsigned long size, unsigned long offset) | ||
762 | { | ||
763 | const unsigned long *p = addr + (offset >> SZLONG_LOG); | ||
764 | unsigned long result = offset & ~SZLONG_MASK; | ||
765 | unsigned long tmp; | ||
766 | |||
767 | if (offset >= size) | ||
768 | return size; | ||
769 | size -= result; | ||
770 | offset &= SZLONG_MASK; | ||
771 | if (offset) { | ||
772 | tmp = *(p++); | ||
773 | tmp &= ~0UL << offset; | ||
774 | if (size < _MIPS_SZLONG) | ||
775 | goto found_first; | ||
776 | if (tmp) | ||
777 | goto found_middle; | ||
778 | size -= _MIPS_SZLONG; | ||
779 | result += _MIPS_SZLONG; | ||
780 | } | ||
781 | while (size & ~SZLONG_MASK) { | ||
782 | if ((tmp = *(p++))) | ||
783 | goto found_middle; | ||
784 | result += _MIPS_SZLONG; | ||
785 | size -= _MIPS_SZLONG; | ||
786 | } | ||
787 | if (!size) | ||
788 | return result; | ||
789 | tmp = *p; | ||
790 | |||
791 | found_first: | ||
792 | tmp &= ~0UL >> (_MIPS_SZLONG - size); | ||
793 | if (tmp == 0UL) /* Are any bits set? */ | ||
794 | return result + size; /* Nope. */ | ||
795 | found_middle: | ||
796 | return result + __ffs(tmp); | ||
797 | } | ||
798 | 526 | ||
799 | /* | 527 | #include <asm-generic/bitops/fls64.h> |
800 | * find_first_bit - find the first set bit in a memory region | 528 | #include <asm-generic/bitops/find.h> |
801 | * @addr: The address to start the search at | ||
802 | * @size: The maximum size to search | ||
803 | * | ||
804 | * Returns the bit-number of the first set bit, not the number of the byte | ||
805 | * containing a bit. | ||
806 | */ | ||
807 | #define find_first_bit(addr, size) \ | ||
808 | find_next_bit((addr), (size), 0) | ||
809 | 529 | ||
810 | #ifdef __KERNEL__ | 530 | #ifdef __KERNEL__ |
811 | 531 | ||
812 | /* | 532 | #include <asm-generic/bitops/sched.h> |
813 | * Every architecture must define this function. It's the fastest | 533 | #include <asm-generic/bitops/hweight.h> |
814 | * way of searching a 140-bit bitmap where the first 100 bits are | 534 | #include <asm-generic/bitops/ext2-non-atomic.h> |
815 | * unlikely to be set. It's guaranteed that at least one of the 140 | 535 | #include <asm-generic/bitops/ext2-atomic.h> |
816 | * bits is cleared. | 536 | #include <asm-generic/bitops/minix.h> |
817 | */ | ||
818 | static inline int sched_find_first_bit(const unsigned long *b) | ||
819 | { | ||
820 | #ifdef CONFIG_32BIT | ||
821 | if (unlikely(b[0])) | ||
822 | return __ffs(b[0]); | ||
823 | if (unlikely(b[1])) | ||
824 | return __ffs(b[1]) + 32; | ||
825 | if (unlikely(b[2])) | ||
826 | return __ffs(b[2]) + 64; | ||
827 | if (b[3]) | ||
828 | return __ffs(b[3]) + 96; | ||
829 | return __ffs(b[4]) + 128; | ||
830 | #endif | ||
831 | #ifdef CONFIG_64BIT | ||
832 | if (unlikely(b[0])) | ||
833 | return __ffs(b[0]); | ||
834 | if (unlikely(b[1])) | ||
835 | return __ffs(b[1]) + 64; | ||
836 | return __ffs(b[2]) + 128; | ||
837 | #endif | ||
838 | } | ||
839 | |||
840 | /* | ||
841 | * hweightN - returns the hamming weight of a N-bit word | ||
842 | * @x: the word to weigh | ||
843 | * | ||
844 | * The Hamming Weight of a number is the total number of bits set in it. | ||
845 | */ | ||
846 | |||
847 | #define hweight64(x) generic_hweight64(x) | ||
848 | #define hweight32(x) generic_hweight32(x) | ||
849 | #define hweight16(x) generic_hweight16(x) | ||
850 | #define hweight8(x) generic_hweight8(x) | ||
851 | |||
852 | static inline int __test_and_set_le_bit(unsigned long nr, unsigned long *addr) | ||
853 | { | ||
854 | unsigned char *ADDR = (unsigned char *) addr; | ||
855 | int mask, retval; | ||
856 | |||
857 | ADDR += nr >> 3; | ||
858 | mask = 1 << (nr & 0x07); | ||
859 | retval = (mask & *ADDR) != 0; | ||
860 | *ADDR |= mask; | ||
861 | |||
862 | return retval; | ||
863 | } | ||
864 | |||
865 | static inline int __test_and_clear_le_bit(unsigned long nr, unsigned long *addr) | ||
866 | { | ||
867 | unsigned char *ADDR = (unsigned char *) addr; | ||
868 | int mask, retval; | ||
869 | |||
870 | ADDR += nr >> 3; | ||
871 | mask = 1 << (nr & 0x07); | ||
872 | retval = (mask & *ADDR) != 0; | ||
873 | *ADDR &= ~mask; | ||
874 | |||
875 | return retval; | ||
876 | } | ||
877 | |||
878 | static inline int test_le_bit(unsigned long nr, const unsigned long * addr) | ||
879 | { | ||
880 | const unsigned char *ADDR = (const unsigned char *) addr; | ||
881 | int mask; | ||
882 | |||
883 | ADDR += nr >> 3; | ||
884 | mask = 1 << (nr & 0x07); | ||
885 | |||
886 | return ((mask & *ADDR) != 0); | ||
887 | } | ||
888 | |||
889 | static inline unsigned long find_next_zero_le_bit(unsigned long *addr, | ||
890 | unsigned long size, unsigned long offset) | ||
891 | { | ||
892 | unsigned long *p = ((unsigned long *) addr) + (offset >> SZLONG_LOG); | ||
893 | unsigned long result = offset & ~SZLONG_MASK; | ||
894 | unsigned long tmp; | ||
895 | |||
896 | if (offset >= size) | ||
897 | return size; | ||
898 | size -= result; | ||
899 | offset &= SZLONG_MASK; | ||
900 | if (offset) { | ||
901 | tmp = cpu_to_lelongp(p++); | ||
902 | tmp |= ~0UL >> (_MIPS_SZLONG-offset); /* bug or feature ? */ | ||
903 | if (size < _MIPS_SZLONG) | ||
904 | goto found_first; | ||
905 | if (~tmp) | ||
906 | goto found_middle; | ||
907 | size -= _MIPS_SZLONG; | ||
908 | result += _MIPS_SZLONG; | ||
909 | } | ||
910 | while (size & ~SZLONG_MASK) { | ||
911 | if (~(tmp = cpu_to_lelongp(p++))) | ||
912 | goto found_middle; | ||
913 | result += _MIPS_SZLONG; | ||
914 | size -= _MIPS_SZLONG; | ||
915 | } | ||
916 | if (!size) | ||
917 | return result; | ||
918 | tmp = cpu_to_lelongp(p); | ||
919 | |||
920 | found_first: | ||
921 | tmp |= ~0UL << size; | ||
922 | if (tmp == ~0UL) /* Are any bits zero? */ | ||
923 | return result + size; /* Nope. */ | ||
924 | |||
925 | found_middle: | ||
926 | return result + ffz(tmp); | ||
927 | } | ||
928 | |||
929 | #define find_first_zero_le_bit(addr, size) \ | ||
930 | find_next_zero_le_bit((addr), (size), 0) | ||
931 | |||
932 | #define ext2_set_bit(nr,addr) \ | ||
933 | __test_and_set_le_bit((nr),(unsigned long*)addr) | ||
934 | #define ext2_clear_bit(nr, addr) \ | ||
935 | __test_and_clear_le_bit((nr),(unsigned long*)addr) | ||
936 | #define ext2_set_bit_atomic(lock, nr, addr) \ | ||
937 | ({ \ | ||
938 | int ret; \ | ||
939 | spin_lock(lock); \ | ||
940 | ret = ext2_set_bit((nr), (addr)); \ | ||
941 | spin_unlock(lock); \ | ||
942 | ret; \ | ||
943 | }) | ||
944 | |||
945 | #define ext2_clear_bit_atomic(lock, nr, addr) \ | ||
946 | ({ \ | ||
947 | int ret; \ | ||
948 | spin_lock(lock); \ | ||
949 | ret = ext2_clear_bit((nr), (addr)); \ | ||
950 | spin_unlock(lock); \ | ||
951 | ret; \ | ||
952 | }) | ||
953 | #define ext2_test_bit(nr, addr) test_le_bit((nr),(unsigned long*)addr) | ||
954 | #define ext2_find_first_zero_bit(addr, size) \ | ||
955 | find_first_zero_le_bit((unsigned long*)addr, size) | ||
956 | #define ext2_find_next_zero_bit(addr, size, off) \ | ||
957 | find_next_zero_le_bit((unsigned long*)addr, size, off) | ||
958 | |||
959 | /* | ||
960 | * Bitmap functions for the minix filesystem. | ||
961 | * | ||
962 | * FIXME: These assume that Minix uses the native byte/bitorder. | ||
963 | * This limits the Minix filesystem's value for data exchange very much. | ||
964 | */ | ||
965 | #define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr) | ||
966 | #define minix_set_bit(nr,addr) __set_bit(nr,addr) | ||
967 | #define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr) | ||
968 | #define minix_test_bit(nr,addr) test_bit(nr,addr) | ||
969 | #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) | ||
970 | 537 | ||
971 | #endif /* __KERNEL__ */ | 538 | #endif /* __KERNEL__ */ |
972 | 539 | ||