# HG changeset patch
# User Jimi Xenidis <[EMAIL PROTECTED]>
# Node ID 8f36901a3c1599e6c326b1a6f6b017dd5f285b0a
# Parent  6e08c342cb81ecd9f6617ba22e7399b980549652
[POWERPC] Add _Xen_Only_ __synch_cmpxchg_u16() for grant table ops

ewww, Ewww, EWWWW!

Signed-off-by: Jimi Xenidis <[EMAIL PROTECTED]>
---
 include/asm-powerpc/xen/asm/synch_bitops.h |   53 ++++++++++++++++++++++++++++-
 1 files changed, 52 insertions(+), 1 deletion(-)

diff -r 6e08c342cb81 -r 8f36901a3c15 include/asm-powerpc/xen/asm/synch_bitops.h
--- a/include/asm-powerpc/xen/asm/synch_bitops.h        Fri Aug 11 12:40:56 
2006 -0400
+++ b/include/asm-powerpc/xen/asm/synch_bitops.h        Fri Aug 11 12:49:08 
2006 -0400
@@ -9,7 +9,6 @@
 
 #define synch_change_bit(a,b) change_bit(a,b)
 #define synch_clear_bit(a,b) clear_bit(a,b)
-#define synch_cmpxchg(ptr,o,n) cmpxchg(ptr,o,n)
 #define synch_const_test_bit(a,b) const_test_bit(a,b) 
 #define synch_set_bit(a,b) set_bit(a,b)
 #define synch_test_and_set_bit(a,b) test_and_set_bit(a,b)
@@ -17,6 +16,58 @@
 #define synch_test_and_clear_bit(a,b) test_and_clear_bit(a,b)
 #define synch_test_bit(a,b) test_bit(a,b)
 
+static __inline__ unsigned long
+__synch_cmpxchg_u16(volatile unsigned short *p, unsigned long old, unsigned 
long new)
+{
+       int idx;
+       volatile unsigned int *xp = (unsigned int *)((ulong)p & 0x3);
+       union {
+               unsigned int word;
+               struct {
+                       unsigned short s[2];
+               }s;
+       } xold, xnew;
+
+       xold.word = *xp;
+       xnew.word = xold.word;
+       idx = ((ulong)p >> 1) & 0x1;
+       xold.s.s[idx] = old;
+       xnew.s.s[idx] = new;
+
+       return __cmpxchg_u32(xp, xold.word, xnew.word);
+}
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid xchg().
+ */
+extern void __synch_cmpxchg_called_with_bad_pointer(void);
+static __inline__ unsigned long
+__synch_cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
+              unsigned int size)
+{
+       switch (size) {
+       case 2:
+               return __synch_cmpxchg_u16(ptr, old, new);
+       case 4:
+               return __cmpxchg_u32(ptr, old, new);
+#ifdef CONFIG_PPC64
+       case 8:
+               return __cmpxchg_u64(ptr, old, new);
+#endif
+       }
+       __synch_cmpxchg_called_with_bad_pointer();
+       return old;
+}
+
+#define synch_cmpxchg(ptr,o,n)                                          \
+  ({                                                                    \
+     __typeof__(*(ptr)) _o_ = (o);                                      \
+     __typeof__(*(ptr)) _n_ = (n);                                      \
+     (__typeof__(*(ptr))) __synch_cmpxchg((ptr), (unsigned long)_o_,           
 \
+                                   (unsigned long)_n_, sizeof(*(ptr))); \
+  })
+
 #else
 #error "this only works for CONFIG_SMP"
 #endif

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to