#define __PA_LDCW_ALIGNMENT 16 #define __ldcw_align(a) ({ \ unsigned long __ret = (unsigned long) a; \ __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \ (volatile unsigned int *) __ret; \ }) #define __ldcw(a) ({ \ unsigned __ret; \ __asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \ __ret; \ }) typedef struct { volatile unsigned int lock[4]; } spinlock_t; struct semaphore { spinlock_t sentry; int count; }; struct loop_device { struct loop_func_table *lo_encryption; struct semaphore lo_ctl_mutex; }; static int max_loop = 8; static struct loop_device *loop_dev; void __down (struct semaphore *sem); void __up (struct semaphore *sem); static inline void _raw_spin_lock (spinlock_t * x) { volatile unsigned int *a = __ldcw_align(x); while (__ldcw(a) == 0) while (*a == 0); } static inline void _raw_spin_unlock (spinlock_t * x) { volatile unsigned int *a = __ldcw_align(x); *a = 1; } inline void down (struct semaphore *sem) { _raw_spin_lock (&sem->sentry); if (sem->count > 0) { sem->count--; } else { __down (sem); } _raw_spin_unlock (&sem->sentry); } inline void up (struct semaphore *sem) { _raw_spin_lock (&sem->sentry); if (sem->count < 0) { __up (sem); } else { sem->count++; } _raw_spin_unlock (&sem->sentry); } int loop_unregister_transfer (int number) { struct loop_device *lo = &loop_dev[0]; for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) { down (&lo->lo_ctl_mutex); if (lo->lo_encryption == 0) loop_release_xfer (lo); up (&lo->lo_ctl_mutex); } return 0; }