Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / include / asm-s390 / bitops.h
index 0ddcdba..ca092ff 100644 (file)
@@ -12,9 +12,7 @@
  *    Copyright (C) 1992, Linus Torvalds
  *
  */
-
-#ifdef __KERNEL__
-
+#include <linux/config.h>
 #include <linux/compiler.h>
 
 /*
  * with operation of the form "set_bit(bitnr, flags)".
  */
 
+/* set ALIGN_CS to 1 if the SMP safe bit operations should
+ * align the address to 4 byte boundary. It seems to work
+ * without the alignment. 
+ */
+#ifdef __KERNEL__
+#define ALIGN_CS 0
+#else
+#define ALIGN_CS 1
+#ifndef CONFIG_SMP
+#error "bitops won't work without CONFIG_SMP"
+#endif
+#endif
+
 /* bitmap tables from arch/S390/kernel/bitmap.S */
 extern const char _oi_bitmap[];
 extern const char _ni_bitmap[];
@@ -111,6 +122,10 @@ static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
         unsigned long addr, old, new, mask;
 
        addr = (unsigned long) ptr;
+#if ALIGN_CS == 1
+       nr += (addr & __BITOPS_ALIGN) << 3;    /* add alignment to bit number */
+       addr ^= addr & __BITOPS_ALIGN;         /* align address to 8 */
+#endif
        /* calculate address for CS */
        addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
        /* make OR mask */
@@ -127,6 +142,10 @@ static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
         unsigned long addr, old, new, mask;
 
        addr = (unsigned long) ptr;
+#if ALIGN_CS == 1
+       nr += (addr & __BITOPS_ALIGN) << 3;    /* add alignment to bit number */
+       addr ^= addr & __BITOPS_ALIGN;         /* align address to 8 */
+#endif
        /* calculate address for CS */
        addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
        /* make AND mask */
@@ -143,6 +162,10 @@ static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
         unsigned long addr, old, new, mask;
 
        addr = (unsigned long) ptr;
+#if ALIGN_CS == 1
+       nr += (addr & __BITOPS_ALIGN) << 3;    /* add alignment to bit number */
+       addr ^= addr & __BITOPS_ALIGN;         /* align address to 8 */
+#endif
        /* calculate address for CS */
        addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
        /* make XOR mask */
@@ -160,6 +183,10 @@ test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
         unsigned long addr, old, new, mask;
 
        addr = (unsigned long) ptr;
+#if ALIGN_CS == 1
+       nr += (addr & __BITOPS_ALIGN) << 3;    /* add alignment to bit number */
+       addr ^= addr & __BITOPS_ALIGN;         /* align address to 8 */
+#endif
        /* calculate address for CS */
        addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
        /* make OR/test mask */
@@ -179,6 +206,10 @@ test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
         unsigned long addr, old, new, mask;
 
        addr = (unsigned long) ptr;
+#if ALIGN_CS == 1
+       nr += (addr & __BITOPS_ALIGN) << 3;    /* add alignment to bit number */
+       addr ^= addr & __BITOPS_ALIGN;         /* align address to 8 */
+#endif
        /* calculate address for CS */
        addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
        /* make AND/test mask */
@@ -198,6 +229,10 @@ test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
         unsigned long addr, old, new, mask;
 
        addr = (unsigned long) ptr;
+#if ALIGN_CS == 1
+       nr += (addr & __BITOPS_ALIGN) << 3;  /* add alignment to bit number */
+       addr ^= addr & __BITOPS_ALIGN;       /* align address to 8 */
+#endif
        /* calculate address for CS */
        addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3;
        /* make XOR/test mask */
@@ -800,6 +835,8 @@ static inline int sched_find_first_bit(unsigned long *b)
 
 #include <asm-generic/bitops/hweight.h>
 
+#ifdef __KERNEL__
+
 /*
  * ATTENTION: intel byte ordering convention for ext2 and minix !!
  * bit 0 is the LSB of addr; bit 31 is the MSB of addr;