Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/s390/kernel/semaphore.c b/arch/s390/kernel/semaphore.c
new file mode 100644
index 0000000..8dfb690
--- /dev/null
+++ b/arch/s390/kernel/semaphore.c
@@ -0,0 +1,108 @@
+/*
+ *  linux/arch/s390/kernel/semaphore.c
+ *
+ *  S390 version
+ *    Copyright (C) 1998-2000 IBM Corporation
+ *    Author(s): Martin Schwidefsky
+ *
+ *  Derived from "linux/arch/i386/kernel/semaphore.c
+ *    Copyright (C) 1999, Linus Torvalds
+ *
+ */
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <asm/semaphore.h>
+
+/*
+ * Atomically update sem->count. Equivalent to:
+ *   old_val = sem->count.counter;
+ *   new_val = ((old_val >= 0) ? old_val : 0) + incr;
+ *   sem->count.counter = new_val;
+ *   return old_val;
+ */
+static inline int __sem_update_count(struct semaphore *sem, int incr)
+{
+	int old_val, new_val;
+
+        __asm__ __volatile__("   l     %0,0(%3)\n"
+                             "0: ltr   %1,%0\n"
+			     "   jhe   1f\n"
+			     "   lhi   %1,0\n"
+			     "1: ar    %1,%4\n"
+                             "   cs    %0,%1,0(%3)\n"
+                             "   jl    0b\n"
+                             : "=&d" (old_val), "=&d" (new_val),
+			       "=m" (sem->count)
+			     : "a" (&sem->count), "d" (incr), "m" (sem->count)
+			     : "cc" );
+	return old_val;
+}
+
+/*
+ * The inline function up() incremented count but the result
+ * was <= 0. This indicates that some process is waiting on
+ * the semaphore. The semaphore is free and we'll wake the
+ * first sleeping process, so we set count to 1 unless some
+ * other cpu has called up in the meantime in which case
+ * we just increment count by 1.
+ */
+void __up(struct semaphore *sem)
+{
+	__sem_update_count(sem, 1);
+	wake_up(&sem->wait);
+}
+
+/*
+ * The inline function down() decremented count and the result
+ * was < 0. The wait loop will atomically test and update the
+ * semaphore counter following the rules:
+ *   count > 0: decrement count, wake up queue and exit.
+ *   count <= 0: set count to -1, go to sleep.
+ */
+void __sched __down(struct semaphore * sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	__set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+	add_wait_queue_exclusive(&sem->wait, &wait);
+	while (__sem_update_count(sem, -1) <= 0) {
+		schedule();
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+	}
+	remove_wait_queue(&sem->wait, &wait);
+	__set_task_state(tsk, TASK_RUNNING);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Same as __down() with an additional test for signals.
+ * If a signal is pending the count is updated as follows:
+ *   count > 0: wake up queue and exit.
+ *   count <= 0: set count to 0, wake up queue and exit.
+ */
+int __sched __down_interruptible(struct semaphore * sem)
+{
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	__set_task_state(tsk, TASK_INTERRUPTIBLE);
+	add_wait_queue_exclusive(&sem->wait, &wait);
+	while (__sem_update_count(sem, -1) <= 0) {
+		if (signal_pending(current)) {
+			__sem_update_count(sem, 0);
+			retval = -EINTR;
+			break;
+		}
+		schedule();
+		set_task_state(tsk, TASK_INTERRUPTIBLE);
+	}
+	remove_wait_queue(&sem->wait, &wait);
+	__set_task_state(tsk, TASK_RUNNING);
+	wake_up(&sem->wait);
+	return retval;
+}
+