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/sound/oss/gus_midi.c b/sound/oss/gus_midi.c
new file mode 100644
index 0000000..b48f57c
--- /dev/null
+++ b/sound/oss/gus_midi.c
@@ -0,0 +1,256 @@
+/*
+ * sound/gus2_midi.c
+ *
+ * The low level driver for the GUS Midi Interface.
+ *
+ *
+ * Copyright (C) by Hannu Savolainen 1993-1997
+ *
+ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * Version 2 (June 1991). See the "COPYING" file distributed with this software
+ * for more info.
+ *
+ * Changes:
+ * 11-10-2000	Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
+ *		Added __init to gus_midi_init()
+ */
+
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include "sound_config.h"
+
+#include "gus.h"
+#include "gus_hw.h"
+
+static int      midi_busy, input_opened;
+static int      my_dev;
+static int      output_used;
+static volatile unsigned char gus_midi_control;
+static void     (*midi_input_intr) (int dev, unsigned char data);
+
+static unsigned char tmp_queue[256];
+extern int      gus_pnp_flag;
+static volatile int qlen;
+static volatile unsigned char qhead, qtail;
+extern int      gus_base, gus_irq, gus_dma;
+extern int     *gus_osp;
+extern spinlock_t gus_lock;
+
+static int GUS_MIDI_STATUS(void)
+{
+	return inb(u_MidiStatus);
+}
+
+static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev))
+{
+	if (midi_busy)
+	{
+/*		printk("GUS: Midi busy\n");*/
+		return -EBUSY;
+	}
+	outb((MIDI_RESET), u_MidiControl);
+	gus_delay();
+
+	gus_midi_control = 0;
+	input_opened = 0;
+
+	if (mode == OPEN_READ || mode == OPEN_READWRITE)
+		if (!gus_pnp_flag)
+		{
+			gus_midi_control |= MIDI_ENABLE_RCV;
+			input_opened = 1;
+		}
+	outb((gus_midi_control), u_MidiControl);	/* Enable */
+
+	midi_busy = 1;
+	qlen = qhead = qtail = output_used = 0;
+	midi_input_intr = input;
+
+	return 0;
+}
+
+static int dump_to_midi(unsigned char midi_byte)
+{
+	unsigned long   flags;
+	int             ok = 0;
+
+	output_used = 1;
+
+	spin_lock_irqsave(&gus_lock, flags);
+
+	if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
+	{
+		ok = 1;
+		outb((midi_byte), u_MidiData);
+	}
+	else
+	{
+		/*
+		 * Enable Midi xmit interrupts (again)
+		 */
+		gus_midi_control |= MIDI_ENABLE_XMIT;
+		outb((gus_midi_control), u_MidiControl);
+	}
+
+	spin_unlock_irqrestore(&gus_lock,flags);
+	return ok;
+}
+
+static void gus_midi_close(int dev)
+{
+	/*
+	 * Reset FIFO pointers, disable intrs
+	 */
+
+	outb((MIDI_RESET), u_MidiControl);
+	midi_busy = 0;
+}
+
+static int gus_midi_out(int dev, unsigned char midi_byte)
+{
+	unsigned long   flags;
+
+	/*
+	 * Drain the local queue first
+	 */
+	spin_lock_irqsave(&gus_lock, flags);
+
+	while (qlen && dump_to_midi(tmp_queue[qhead]))
+	{
+		qlen--;
+		qhead++;
+	}
+	spin_unlock_irqrestore(&gus_lock,flags);
+
+	/*
+	 *	Output the byte if the local queue is empty.
+	 */
+
+	if (!qlen)
+		if (dump_to_midi(midi_byte))
+			return 1;	/*
+					 * OK
+					 */
+
+	/*
+	 *	Put to the local queue
+	 */
+
+	if (qlen >= 256)
+		return 0;	/*
+				 * Local queue full
+				 */
+	spin_lock_irqsave(&gus_lock, flags);
+
+	tmp_queue[qtail] = midi_byte;
+	qlen++;
+	qtail++;
+
+	spin_unlock_irqrestore(&gus_lock,flags);
+	return 1;
+}
+
+static int gus_midi_start_read(int dev)
+{
+	return 0;
+}
+
+static int gus_midi_end_read(int dev)
+{
+	return 0;
+}
+
+static void gus_midi_kick(int dev)
+{
+}
+
+static int gus_midi_buffer_status(int dev)
+{
+	unsigned long   flags;
+
+	if (!output_used)
+		return 0;
+
+	spin_lock_irqsave(&gus_lock, flags);
+
+	if (qlen && dump_to_midi(tmp_queue[qhead]))
+	{
+		qlen--;
+		qhead++;
+	}
+	spin_unlock_irqrestore(&gus_lock,flags);
+	return (qlen > 0) || !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
+}
+
+#define MIDI_SYNTH_NAME	"Gravis Ultrasound Midi"
+#define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
+#include "midi_synth.h"
+
+static struct midi_operations gus_midi_operations =
+{
+	.owner		= THIS_MODULE,
+	.info		= {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
+	.converter	= &std_midi_synth,
+	.in_info	= {0},
+	.open		= gus_midi_open,
+	.close		= gus_midi_close,
+	.outputc	= gus_midi_out,
+	.start_read	= gus_midi_start_read,
+	.end_read	= gus_midi_end_read,
+	.kick		= gus_midi_kick,
+	.buffer_status	= gus_midi_buffer_status,
+};
+
+void __init gus_midi_init(struct address_info *hw_config)
+{
+	int dev = sound_alloc_mididev();
+
+	if (dev == -1)
+	{
+		printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
+		return;
+	}
+	outb((MIDI_RESET), u_MidiControl);
+
+	std_midi_synth.midi_dev = my_dev = dev;
+	hw_config->slots[2] = dev;
+	midi_devs[dev] = &gus_midi_operations;
+	sequencer_init();
+	return;
+}
+
+void gus_midi_interrupt(int dummy)
+{
+	volatile unsigned char stat, data;
+	int timeout = 10;
+
+	spin_lock(&gus_lock);
+
+	while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
+	{
+		if (stat & MIDI_RCV_FULL)
+		{
+			data = inb(u_MidiData);
+			if (input_opened)
+				midi_input_intr(my_dev, data);
+		}
+		if (stat & MIDI_XMIT_EMPTY)
+		{
+			while (qlen && dump_to_midi(tmp_queue[qhead]))
+			{
+				qlen--;
+				qhead++;
+			}
+			if (!qlen)
+			{
+			      /*
+			       * Disable Midi output interrupts, since no data in the buffer
+			       */
+			      gus_midi_control &= ~MIDI_ENABLE_XMIT;
+			      outb((gus_midi_control), u_MidiControl);
+			      outb((gus_midi_control), u_MidiControl);
+			}
+		}
+	}
+	spin_unlock(&gus_lock);
+}