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/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c
new file mode 100644
index 0000000..4df668eb3
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_patch.c
@@ -0,0 +1,223 @@
+/*
+ *  Patch transfer callback for Emu10k1
+ *
+ *  Copyright (C) 2000 Takashi iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+/*
+ * All the code for loading in a patch.  There is very little that is
+ * chip specific here.  Just the actual writing to the board.
+ */
+
+#include "emu10k1_synth_local.h"
+
+/*
+ */
+#define BLANK_LOOP_START	4
+#define BLANK_LOOP_END		8
+#define BLANK_LOOP_SIZE		12
+#define BLANK_HEAD_SIZE		32
+
+/*
+ * allocate a sample block and copy data from userspace
+ */
+int
+snd_emu10k1_sample_new(snd_emux_t *rec, snd_sf_sample_t *sp,
+		       snd_util_memhdr_t *hdr, const void __user *data, long count)
+{
+	int offset;
+	int truesize, size, loopsize, blocksize;
+	int loopend, sampleend;
+	unsigned int start_addr;
+	emu10k1_t *emu;
+
+	emu = rec->hw;
+	snd_assert(sp != NULL, return -EINVAL);
+	snd_assert(hdr != NULL, return -EINVAL);
+
+	if (sp->v.size == 0) {
+		snd_printd("emu: rom font for sample %d\n", sp->v.sample);
+		return 0;
+	}
+
+	/* recalculate address offset */
+	sp->v.end -= sp->v.start;
+	sp->v.loopstart -= sp->v.start;
+	sp->v.loopend -= sp->v.start;
+	sp->v.start = 0;
+
+	/* some samples have invalid data.  the addresses are corrected in voice info */
+	sampleend = sp->v.end;
+	if (sampleend > sp->v.size)
+		sampleend = sp->v.size;
+	loopend = sp->v.loopend;
+	if (loopend > sampleend)
+		loopend = sampleend;
+
+	/* be sure loop points start < end */
+	if (sp->v.loopstart >= sp->v.loopend) {
+		int tmp = sp->v.loopstart;
+		sp->v.loopstart = sp->v.loopend;
+		sp->v.loopend = tmp;
+	}
+
+	/* compute true data size to be loaded */
+	truesize = sp->v.size + BLANK_HEAD_SIZE;
+	loopsize = 0;
+#if 0 /* not supported */
+	if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP))
+		loopsize = sp->v.loopend - sp->v.loopstart;
+	truesize += loopsize;
+#endif
+	if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK)
+		truesize += BLANK_LOOP_SIZE;
+
+	/* try to allocate a memory block */
+	blocksize = truesize;
+	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
+		blocksize *= 2;
+	sp->block = snd_emu10k1_synth_alloc(emu, blocksize);
+	if (sp->block == NULL) {
+		snd_printd("emu10k1: synth malloc failed (size=%d)\n", blocksize);
+		/* not ENOMEM (for compatibility with OSS) */
+		return -ENOSPC;
+	}
+	/* set the total size */
+	sp->v.truesize = blocksize;
+
+	/* write blank samples at head */
+	offset = 0;
+	size = BLANK_HEAD_SIZE;
+	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
+		size *= 2;
+	snd_assert(offset + size <= blocksize, return -EINVAL);
+	snd_emu10k1_synth_bzero(emu, sp->block, offset, size);
+	offset += size;
+
+	/* copy start->loopend */
+	size = loopend;
+	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
+		size *= 2;
+	snd_assert(offset + size <= blocksize, return -EINVAL);
+	if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
+		snd_emu10k1_synth_free(emu, sp->block);
+		sp->block = NULL;
+		return -EFAULT;
+	}
+	offset += size;
+	data += size;
+
+#if 0 /* not suppported yet */
+	/* handle reverse (or bidirectional) loop */
+	if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
+		/* copy loop in reverse */
+		if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
+			int woffset;
+			unsigned short *wblock = (unsigned short*)block;
+			woffset = offset / 2;
+			snd_assert(offset + loopsize*2 <= blocksize, return -EINVAL);
+			for (i = 0; i < loopsize; i++)
+				wblock[woffset + i] = wblock[woffset - i -1];
+			offset += loopsize * 2;
+		} else {
+			snd_assert(offset + loopsize <= blocksize, return -EINVAL);
+			for (i = 0; i < loopsize; i++)
+				block[offset + i] = block[offset - i -1];
+			offset += loopsize;
+		}
+
+		/* modify loop pointers */
+		if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_BIDIR_LOOP) {
+			sp->v.loopend += loopsize;
+		} else {
+			sp->v.loopstart += loopsize;
+			sp->v.loopend += loopsize;
+		}
+		/* add sample pointer */
+		sp->v.end += loopsize;
+	}
+#endif
+
+	/* loopend -> sample end */
+	size = sp->v.size - loopend;
+	snd_assert(size >= 0, return -EINVAL);
+	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
+		size *= 2;
+	if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
+		snd_emu10k1_synth_free(emu, sp->block);
+		sp->block = NULL;
+		return -EFAULT;
+	}
+	offset += size;
+
+	/* clear rest of samples (if any) */
+	if (offset < blocksize)
+		snd_emu10k1_synth_bzero(emu, sp->block, offset, blocksize - offset);
+
+	if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
+		/* if no blank loop is attached in the sample, add it */
+		if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
+			sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
+			sp->v.loopend = sp->v.end + BLANK_LOOP_END;
+		}
+	}
+
+#if 0 /* not supported yet */
+	if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) {
+		/* unsigned -> signed */
+		if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
+			unsigned short *wblock = (unsigned short*)block;
+			for (i = 0; i < truesize; i++)
+				wblock[i] ^= 0x8000;
+		} else {
+			for (i = 0; i < truesize; i++)
+				block[i] ^= 0x80;
+		}
+	}
+#endif
+
+	/* recalculate offset */
+	start_addr = BLANK_HEAD_SIZE * 2;
+	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
+		start_addr >>= 1;
+	sp->v.start += start_addr;
+	sp->v.end += start_addr;
+	sp->v.loopstart += start_addr;
+	sp->v.loopend += start_addr;
+
+	return 0;
+}
+
+/*
+ * free a sample block
+ */
+int
+snd_emu10k1_sample_free(snd_emux_t *rec, snd_sf_sample_t *sp,
+			snd_util_memhdr_t *hdr)
+{
+	emu10k1_t *emu;
+
+	emu = rec->hw;
+	snd_assert(sp != NULL, return -EINVAL);
+	snd_assert(hdr != NULL, return -EINVAL);
+
+	if (sp->block) {
+		snd_emu10k1_synth_free(emu, sp->block);
+		sp->block = NULL;
+	}
+	return 0;
+}
+