/* Copyright (C) by Paul Barton-Davis 1998-1999
 *
 * Some portions of this file are taken from work that is
 * copyright (C) by Hannu Savolainen 1993-1996
 *
 * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
 * for more info.  
 */

/*  
 * An ALSA lowlevel driver for Turtle Beach ICS2115 wavetable synth
 *                                             (Maui, Tropez, Tropez Plus)
 *
 * This driver supports the onboard wavetable synthesizer (an ICS2115),
 * including patch, sample and program loading and unloading, conversion
 * of GUS patches during loading, and full user-level access to all
 * WaveFront commands. It tries to provide semi-intelligent patch and
 * sample management as well.
 *
 */

#include <sound/driver.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/snd_wavefront.h>
#include <sound/initval.h>

static int wf_raw = 0; /* we normally check for "raw state" to firmware
			  loading. if non-zero, then during driver loading, the
			  state of the board is ignored, and we reset the
			  board and load the firmware anyway.
		       */
		   
static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
			  whatever state it is when the driver is loaded.
			  The default is to download the microprogram and
			  associated coefficients to set it up for "default"
			  operation, whatever that means.
		       */

static int debug_default = 0;  /* you can set this to control debugging
				  during driver loading. it takes any combination
				  of the WF_DEBUG_* flags defined in
				  wavefront.h
			       */

/* XXX this needs to be made firmware and hardware version dependent */

static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
						    version of the WaveFront OS
						 */

static int wait_usecs = 150; /* This magic number seems to give pretty optimal
				throughput based on my limited experimentation.
				If you want to play around with it and find a better
				value, be my guest. Remember, the idea is to
				get a number that causes us to just busy wait
				for as many WaveFront commands as possible, without
				coming up with a number so large that we hog the
				whole CPU.

				Specifically, with this number, out of about 134,000
				status waits, only about 250 result in a sleep.
			    */

static int sleep_interval = 100;   /* HZ/sleep_interval seconds per sleep */
static int sleep_tries = 50;       /* number of times we'll try to sleep */

static int reset_time = 2;        /* hundreths of a second we wait after a HW
				     reset for the expected interrupt.
				  */

static int ramcheck_time = 20;    /* time in seconds to wait while ROM code
				     checks on-board RAM.
				  */

static int osrun_time = 10;       /* time in seconds we wait for the OS to
				     start running.
				  */
module_param(wf_raw, int, 0444);
MODULE_PARM_DESC(wf_raw, "if non-zero, assume that we need to boot the OS");
module_param(fx_raw, int, 0444);
MODULE_PARM_DESC(fx_raw, "if non-zero, assume that the FX process needs help");
module_param(debug_default, int, 0444);
MODULE_PARM_DESC(debug_default, "debug parameters for card initialization");
module_param(wait_usecs, int, 0444);
MODULE_PARM_DESC(wait_usecs, "how long to wait without sleeping, usecs");
module_param(sleep_interval, int, 0444);
MODULE_PARM_DESC(sleep_interval, "how long to sleep when waiting for reply");
module_param(sleep_tries, int, 0444);
MODULE_PARM_DESC(sleep_tries, "how many times to try sleeping during a wait");
module_param(ospath, charp, 0444);
MODULE_PARM_DESC(ospath, "full pathname to processed ICS2115 OS firmware");
module_param(reset_time, int, 0444);
MODULE_PARM_DESC(reset_time, "how long to wait for a reset to take effect");
module_param(ramcheck_time, int, 0444);
MODULE_PARM_DESC(ramcheck_time, "how many seconds to wait for the RAM test");
module_param(osrun_time, int, 0444);
MODULE_PARM_DESC(osrun_time, "how many seconds to wait for the ICS2115 OS");

/* if WF_DEBUG not defined, no run-time debugging messages will
   be available via the debug flag setting. Given the current
   beta state of the driver, this will remain set until a future 
   version.
*/

#define WF_DEBUG 1

#ifdef WF_DEBUG

#if defined(NEW_MACRO_VARARGS) || __GNUC__ >= 3
#define DPRINT(cond, ...) \
       if ((dev->debug & (cond)) == (cond)) { \
	     snd_printk (__VA_ARGS__); \
       }
#else
#define DPRINT(cond, args...) \
       if ((dev->debug & (cond)) == (cond)) { \
	     snd_printk (args); \
       }
#endif
#else
#define DPRINT(cond, args...)
#endif /* WF_DEBUG */

#define LOGNAME "WaveFront: "

/* bitmasks for WaveFront status port value */

#define STAT_RINTR_ENABLED	0x01
#define STAT_CAN_READ		0x02
#define STAT_INTR_READ		0x04
#define STAT_WINTR_ENABLED	0x10
#define STAT_CAN_WRITE		0x20
#define STAT_INTR_WRITE		0x40

static int wavefront_delete_sample (snd_wavefront_t *, int sampnum);
static int wavefront_find_free_sample (snd_wavefront_t *);

typedef struct {
	int cmd;
	char *action;
	unsigned int read_cnt;
	unsigned int write_cnt;
	int need_ack;
} wavefront_command;

static struct {
	int errno;
	const char *errstr;
} wavefront_errors[] = {
	{ 0x01, "Bad sample number" },
	{ 0x02, "Out of sample memory" },
	{ 0x03, "Bad patch number" },
	{ 0x04, "Error in number of voices" },
	{ 0x06, "Sample load already in progress" },
	{ 0x0B, "No sample load request pending" },
	{ 0x0E, "Bad MIDI channel number" },
	{ 0x10, "Download Record Error" },
	{ 0x80, "Success" },
	{ 0x0 }
};

#define NEEDS_ACK 1

static wavefront_command wavefront_commands[] = {
	{ WFC_SET_SYNTHVOL, "set synthesizer volume", 0, 1, NEEDS_ACK },
	{ WFC_GET_SYNTHVOL, "get synthesizer volume", 1, 0, 0},
	{ WFC_SET_NVOICES, "set number of voices", 0, 1, NEEDS_ACK },
	{ WFC_GET_NVOICES, "get number of voices", 1, 0, 0 },
	{ WFC_SET_TUNING, "set synthesizer tuning", 0, 2, NEEDS_ACK },
	{ WFC_GET_TUNING, "get synthesizer tuning", 2, 0, 0 },
	{ WFC_DISABLE_CHANNEL, "disable synth channel", 0, 1, NEEDS_ACK },
	{ WFC_ENABLE_CHANNEL, "enable synth channel", 0, 1, NEEDS_ACK },
	{ WFC_GET_CHANNEL_STATUS, "get synth channel status", 3, 0, 0 },
	{ WFC_MISYNTH_OFF, "disable midi-in to synth", 0, 0, NEEDS_ACK },
	{ WFC_MISYNTH_ON, "enable midi-in to synth", 0, 0, NEEDS_ACK },
	{ WFC_VMIDI_ON, "enable virtual midi mode", 0, 0, NEEDS_ACK },
	{ WFC_VMIDI_OFF, "disable virtual midi mode", 0, 0, NEEDS_ACK },
	{ WFC_MIDI_STATUS, "report midi status", 1, 0, 0 },
	{ WFC_FIRMWARE_VERSION, "report firmware version", 2, 0, 0 },
	{ WFC_HARDWARE_VERSION, "report hardware version", 2, 0, 0 },
	{ WFC_GET_NSAMPLES, "report number of samples", 2, 0, 0 },
	{ WFC_INSTOUT_LEVELS, "report instantaneous output levels", 7, 0, 0 },
	{ WFC_PEAKOUT_LEVELS, "report peak output levels", 7, 0, 0 },
	{ WFC_DOWNLOAD_SAMPLE, "download sample",
	  0, WF_SAMPLE_BYTES, NEEDS_ACK },
	{ WFC_DOWNLOAD_BLOCK, "download block", 0, 0, NEEDS_ACK},
	{ WFC_DOWNLOAD_SAMPLE_HEADER, "download sample header",
	  0, WF_SAMPLE_HDR_BYTES, NEEDS_ACK },
	{ WFC_UPLOAD_SAMPLE_HEADER, "upload sample header", 13, 2, 0 },

	/* This command requires a variable number of bytes to be written.
	   There is a hack in snd_wavefront_cmd() to support this. The actual
	   count is passed in as the read buffer ptr, cast appropriately.
	   Ugh.
	*/

	{ WFC_DOWNLOAD_MULTISAMPLE, "download multisample", 0, 0, NEEDS_ACK },

	/* This one is a hack as well. We just read the first byte of the
	   response, don't fetch an ACK, and leave the rest to the 
	   calling function. Ugly, ugly, ugly.
	*/

	{ WFC_UPLOAD_MULTISAMPLE, "upload multisample", 2, 1, 0 },
	{ WFC_DOWNLOAD_SAMPLE_ALIAS, "download sample alias",
	  0, WF_ALIAS_BYTES, NEEDS_ACK },
	{ WFC_UPLOAD_SAMPLE_ALIAS, "upload sample alias", WF_ALIAS_BYTES, 2, 0},
	{ WFC_DELETE_SAMPLE, "delete sample", 0, 2, NEEDS_ACK },
	{ WFC_IDENTIFY_SAMPLE_TYPE, "identify sample type", 5, 2, 0 },
	{ WFC_UPLOAD_SAMPLE_PARAMS, "upload sample parameters" },
	{ WFC_REPORT_FREE_MEMORY, "report free memory", 4, 0, 0 },
	{ WFC_DOWNLOAD_PATCH, "download patch", 0, 134, NEEDS_ACK },
	{ WFC_UPLOAD_PATCH, "upload patch", 132, 2, 0 },
	{ WFC_DOWNLOAD_PROGRAM, "download program", 0, 33, NEEDS_ACK },
	{ WFC_UPLOAD_PROGRAM, "upload program", 32, 1, 0 },
	{ WFC_DOWNLOAD_EDRUM_PROGRAM, "download enhanced drum program", 0, 9,
	  NEEDS_ACK},
	{ WFC_UPLOAD_EDRUM_PROGRAM, "upload enhanced drum program", 8, 1, 0},
	{ WFC_SET_EDRUM_CHANNEL, "set enhanced drum program channel",
	  0, 1, NEEDS_ACK },
	{ WFC_DISABLE_DRUM_PROGRAM, "disable drum program", 0, 1, NEEDS_ACK },
	{ WFC_REPORT_CHANNEL_PROGRAMS, "report channel program numbers",
	  32, 0, 0 },
	{ WFC_NOOP, "the no-op command", 0, 0, NEEDS_ACK },
	{ 0x00 }
};

static const char *
wavefront_errorstr (int errnum)

{
	int i;

	for (i = 0; wavefront_errors[i].errstr; i++) {
		if (wavefront_errors[i].errno == errnum) {
			return wavefront_errors[i].errstr;
		}
	}

	return "Unknown WaveFront error";
}

static wavefront_command *
wavefront_get_command (int cmd) 

{
	int i;

	for (i = 0; wavefront_commands[i].cmd != 0; i++) {
		if (cmd == wavefront_commands[i].cmd) {
			return &wavefront_commands[i];
		}
	}

	return (wavefront_command *) 0;
}

static inline int
wavefront_status (snd_wavefront_t *dev) 

{
	return inb (dev->status_port);
}

static int
wavefront_sleep (int limit)

{
	set_current_state(TASK_INTERRUPTIBLE);
	schedule_timeout(limit);

	return signal_pending(current);
}

static int
wavefront_wait (snd_wavefront_t *dev, int mask)

{
	int             i;

	/* Spin for a short period of time, because >99% of all
	   requests to the WaveFront can be serviced inline like this.
	*/

	for (i = 0; i < wait_usecs; i += 5) {
		if (wavefront_status (dev) & mask) {
			return 1;
		}
		udelay(5);
	}

	for (i = 0; i < sleep_tries; i++) {

		if (wavefront_status (dev) & mask) {
			return 1;
		}

		if (wavefront_sleep (HZ/sleep_interval)) {
			return (0);
		}
	}

	return (0);
}

static int
wavefront_read (snd_wavefront_t *dev)

{
	if (wavefront_wait (dev, STAT_CAN_READ))
		return inb (dev->data_port);

	DPRINT (WF_DEBUG_DATA, "read timeout.\n");

	return -1;
}

static int
wavefront_write (snd_wavefront_t *dev, unsigned char data)

{
	if (wavefront_wait (dev, STAT_CAN_WRITE)) {
		outb (data, dev->data_port);
		return 0;
	}

	DPRINT (WF_DEBUG_DATA, "write timeout.\n");

	return -1;
}

int
snd_wavefront_cmd (snd_wavefront_t *dev, 
		   int cmd, unsigned char *rbuf, unsigned char *wbuf)

{
	int ack;
	unsigned int i;
	int c;
	wavefront_command *wfcmd;

	if ((wfcmd = wavefront_get_command (cmd)) == (wavefront_command *) 0) {
		snd_printk ("command 0x%x not supported.\n",
			cmd);
		return 1;
	}

	/* Hack to handle the one variable-size write command. See
	   wavefront_send_multisample() for the other half of this
	   gross and ugly strategy.
	*/

	if (cmd == WFC_DOWNLOAD_MULTISAMPLE) {
		wfcmd->write_cnt = (unsigned long) rbuf;
		rbuf = NULL;
	}

	DPRINT (WF_DEBUG_CMD, "0x%x [%s] (%d,%d,%d)\n",
			       cmd, wfcmd->action, wfcmd->read_cnt,
			       wfcmd->write_cnt, wfcmd->need_ack);
    
	if (wavefront_write (dev, cmd)) { 
		DPRINT ((WF_DEBUG_IO|WF_DEBUG_CMD), "cannot request "
						     "0x%x [%s].\n",
						     cmd, wfcmd->action);
		return 1;
	} 

	if (wfcmd->write_cnt > 0) {
		DPRINT (WF_DEBUG_DATA, "writing %d bytes "
					"for 0x%x\n",
					wfcmd->write_cnt, cmd);

		for (i = 0; i < wfcmd->write_cnt; i++) {
			if (wavefront_write (dev, wbuf[i])) {
				DPRINT (WF_DEBUG_IO, "bad write for byte "
						      "%d of 0x%x [%s].\n",
						      i, cmd, wfcmd->action);
				return 1;
			}

			DPRINT (WF_DEBUG_DATA, "write[%d] = 0x%x\n",
						i, wbuf[i]);
		}
	}

	if (wfcmd->read_cnt > 0) {
		DPRINT (WF_DEBUG_DATA, "reading %d ints "
					"for 0x%x\n",
					wfcmd->read_cnt, cmd);

		for (i = 0; i < wfcmd->read_cnt; i++) {

			if ((c = wavefront_read (dev)) == -1) {
				DPRINT (WF_DEBUG_IO, "bad read for byte "
						      "%d of 0x%x [%s].\n",
						      i, cmd, wfcmd->action);
				return 1;
			}

			/* Now handle errors. Lots of special cases here */
	    
			if (c == 0xff) { 
				if ((c = wavefront_read (dev)) == -1) {
					DPRINT (WF_DEBUG_IO, "bad read for "
							      "error byte at "
							      "read byte %d "
							      "of 0x%x [%s].\n",
							      i, cmd,
							      wfcmd->action);
					return 1;
				}

				/* Can you believe this madness ? */

				if (c == 1 &&
				    wfcmd->cmd == WFC_IDENTIFY_SAMPLE_TYPE) {
					rbuf[0] = WF_ST_EMPTY;
					return (0);

				} else if (c == 3 &&
					   wfcmd->cmd == WFC_UPLOAD_PATCH) {

					return 3;

				} else if (c == 1 &&
					   wfcmd->cmd == WFC_UPLOAD_PROGRAM) {

					return 1;

				} else {

					DPRINT (WF_DEBUG_IO, "error %d (%s) "
							      "during "
							      "read for byte "
							      "%d of 0x%x "
							      "[%s].\n",
							      c,
							      wavefront_errorstr (c),
							      i, cmd,
							      wfcmd->action);
					return 1;

				}
		
		} else {
				rbuf[i] = c;
			}
			
			DPRINT (WF_DEBUG_DATA, "read[%d] = 0x%x\n",i, rbuf[i]);
		}
	}
	
	if ((wfcmd->read_cnt == 0 && wfcmd->write_cnt == 0) || wfcmd->need_ack) {

		DPRINT (WF_DEBUG_CMD, "reading ACK for 0x%x\n", cmd);

		/* Some commands need an ACK, but return zero instead
		   of the standard value.
		*/
	    
		if ((ack = wavefront_read (dev)) == 0) {
			ack = WF_ACK;
		}
	
		if (ack != WF_ACK) {
			if (ack == -1) {
				DPRINT (WF_DEBUG_IO, "cannot read ack for "
						      "0x%x [%s].\n",
						      cmd, wfcmd->action);
				return 1;
		
			} else {
				int err = -1; /* something unknown */

				if (ack == 0xff) { /* explicit error */
		    
					if ((err = wavefront_read (dev)) == -1) {
						DPRINT (WF_DEBUG_DATA,
							"cannot read err "
							"for 0x%x [%s].\n",
							cmd, wfcmd->action);
					}
				}
				
				DPRINT (WF_DEBUG_IO, "0x%x [%s] "
					"failed (0x%x, 0x%x, %s)\n",
					cmd, wfcmd->action, ack, err,
					wavefront_errorstr (err));
				
				return -err;
			}
		}
		
		DPRINT (WF_DEBUG_DATA, "ack received "
					"for 0x%x [%s]\n",
					cmd, wfcmd->action);
	} else {

		DPRINT (WF_DEBUG_CMD, "0x%x [%s] does not need "
				       "ACK (%d,%d,%d)\n",
				       cmd, wfcmd->action, wfcmd->read_cnt,
				       wfcmd->write_cnt, wfcmd->need_ack);
	}

	return 0;
	
}

/***********************************************************************
WaveFront data munging   

Things here are weird. All data written to the board cannot 
have its most significant bit set. Any data item with values 
potentially > 0x7F (127) must be split across multiple bytes.

Sometimes, we need to munge numeric values that are represented on
the x86 side as 8-32 bit values. Sometimes, we need to munge data
that is represented on the x86 side as an array of bytes. The most
efficient approach to handling both cases seems to be to use 2
different functions for munging and 2 for de-munging. This avoids
weird casting and worrying about bit-level offsets.

**********************************************************************/

static unsigned char *
munge_int32 (unsigned int src,
	     unsigned char *dst,
	     unsigned int dst_size)
{
	unsigned int i;

	for (i = 0; i < dst_size; i++) {
		*dst = src & 0x7F;  /* Mask high bit of LSB */
		src = src >> 7;     /* Rotate Right 7 bits  */
	                            /* Note: we leave the upper bits in place */ 

		dst++;
 	};
	return dst;
};

static int 
demunge_int32 (unsigned char* src, int src_size)

{
	int i;
 	int outval = 0;
	
 	for (i = src_size - 1; i >= 0; i--) {
		outval=(outval<<7)+src[i];
	}

	return outval;
};

static 
unsigned char *
munge_buf (unsigned char *src, unsigned char *dst, unsigned int dst_size)

{
	unsigned int i;
	unsigned int last = dst_size / 2;

	for (i = 0; i < last; i++) {
		*dst++ = src[i] & 0x7f;
		*dst++ = src[i] >> 7;
	}
	return dst;
}

static 
unsigned char *
demunge_buf (unsigned char *src, unsigned char *dst, unsigned int src_bytes)

{
	int i;
	unsigned char *end = src + src_bytes;
    
	end = src + src_bytes;

	/* NOTE: src and dst *CAN* point to the same address */

	for (i = 0; src != end; i++) {
		dst[i] = *src++;
		dst[i] |= (*src++)<<7;
	}

	return dst;
}

/***********************************************************************
WaveFront: sample, patch and program management.
***********************************************************************/

static int
wavefront_delete_sample (snd_wavefront_t *dev, int sample_num)

{
	unsigned char wbuf[2];
	int x;

	wbuf[0] = sample_num & 0x7f;
	wbuf[1] = sample_num >> 7;

	if ((x = snd_wavefront_cmd (dev, WFC_DELETE_SAMPLE, NULL, wbuf)) == 0) {
		dev->sample_status[sample_num] = WF_ST_EMPTY;
	}

	return x;
}

static int
wavefront_get_sample_status (snd_wavefront_t *dev, int assume_rom)

{
	int i;
	unsigned char rbuf[32], wbuf[32];
	unsigned int    sc_real, sc_alias, sc_multi;

	/* check sample status */
    
	if (snd_wavefront_cmd (dev, WFC_GET_NSAMPLES, rbuf, wbuf)) {
		snd_printk ("cannot request sample count.\n");
		return -1;
	} 
    
	sc_real = sc_alias = sc_multi = dev->samples_used = 0;
    
	for (i = 0; i < WF_MAX_SAMPLE; i++) {
	
		wbuf[0] = i & 0x7f;
		wbuf[1] = i >> 7;

		if (snd_wavefront_cmd (dev, WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
			snd_printk("cannot identify sample "
				   "type of slot %d\n", i);
			dev->sample_status[i] = WF_ST_EMPTY;
			continue;
		}

		dev->sample_status[i] = (WF_SLOT_FILLED|rbuf[0]);

		if (assume_rom) {
			dev->sample_status[i] |= WF_SLOT_ROM;
		}

		switch (rbuf[0] & WF_ST_MASK) {
		case WF_ST_SAMPLE:
			sc_real++;
			break;
		case WF_ST_MULTISAMPLE:
			sc_multi++;
			break;
		case WF_ST_ALIAS:
			sc_alias++;
			break;
		case WF_ST_EMPTY:
			break;

		default:
			snd_printk ("unknown sample type for "
				    "slot %d (0x%x)\n", 
				    i, rbuf[0]);
		}

		if (rbuf[0] != WF_ST_EMPTY) {
			dev->samples_used++;
		} 
	}

	snd_printk ("%d samples used (%d real, %d aliases, %d multi), "
		    "%d empty\n", dev->samples_used, sc_real, sc_alias, sc_multi,
		    WF_MAX_SAMPLE - dev->samples_used);


	return (0);

}

static int
wavefront_get_patch_status (snd_wavefront_t *dev)

{
	unsigned char patchbuf[WF_PATCH_BYTES];
	unsigned char patchnum[2];
	wavefront_patch *p;
	int i, x, cnt, cnt2;

	for (i = 0; i < WF_MAX_PATCH; i++) {
		patchnum[0] = i & 0x7f;
		patchnum[1] = i >> 7;

		if ((x = snd_wavefront_cmd (dev, WFC_UPLOAD_PATCH, patchbuf,
					patchnum)) == 0) {

			dev->patch_status[i] |= WF_SLOT_FILLED;
			p = (wavefront_patch *) patchbuf;
			dev->sample_status
				[p->sample_number|(p->sample_msb<<7)] |=
				WF_SLOT_USED;
	    
		} else if (x == 3) { /* Bad patch number */
			dev->patch_status[i] = 0;
		} else {
			snd_printk ("upload patch "
				    "error 0x%x\n", x);
			dev->patch_status[i] = 0;
			return 1;
		}
	}

	/* program status has already filled in slot_used bits */

	for (i = 0, cnt = 0, cnt2 = 0; i < WF_MAX_PATCH; i++) {
		if (dev->patch_status[i] & WF_SLOT_FILLED) {
			cnt++;
		}
		if (dev->patch_status[i] & WF_SLOT_USED) {
			cnt2++;
		}
	
	}
	snd_printk ("%d patch slots filled, %d in use\n", cnt, cnt2);

	return (0);
}

static int
wavefront_get_program_status (snd_wavefront_t *dev)

{
	unsigned char progbuf[WF_PROGRAM_BYTES];
	wavefront_program prog;
	unsigned char prognum;
	int i, x, l, cnt;

	for (i = 0; i < WF_MAX_PROGRAM; i++) {
		prognum = i;

		if ((x = snd_wavefront_cmd (dev, WFC_UPLOAD_PROGRAM, progbuf,
					&prognum)) == 0) {

			dev->prog_status[i] |= WF_SLOT_USED;

			demunge_buf (progbuf, (unsigned char *) &prog,
				     WF_PROGRAM_BYTES);

			for (l = 0; l < WF_NUM_LAYERS; l++) {
				if (prog.layer[l].mute) {
					dev->patch_status
						[prog.layer[l].patch_number] |=
						WF_SLOT_USED;
				}
			}
		} else if (x == 1) { /* Bad program number */
			dev->prog_status[i] = 0;
		} else {
			snd_printk ("upload program "
				    "error 0x%x\n", x);
			dev->prog_status[i] = 0;
		}
	}

	for (i = 0, cnt = 0; i < WF_MAX_PROGRAM; i++) {
		if (dev->prog_status[i]) {
			cnt++;
		}
	}

	snd_printk ("%d programs slots in use\n", cnt);

	return (0);
}

static int
wavefront_send_patch (snd_wavefront_t *dev, wavefront_patch_info *header)

{
	unsigned char buf[WF_PATCH_BYTES+2];
	unsigned char *bptr;

	DPRINT (WF_DEBUG_LOAD_PATCH, "downloading patch %d\n",
				      header->number);

	dev->patch_status[header->number] |= WF_SLOT_FILLED;

	bptr = buf;
	bptr = munge_int32 (header->number, buf, 2);
	munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES);
    
	if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_PATCH, NULL, buf)) {
		snd_printk ("download patch failed\n");
		return -(EIO);
	}

	return (0);
}

static int
wavefront_send_program (snd_wavefront_t *dev, wavefront_patch_info *header)

{
	unsigned char buf[WF_PROGRAM_BYTES+1];
	int i;

	DPRINT (WF_DEBUG_LOAD_PATCH, "downloading program %d\n",
		header->number);

	dev->prog_status[header->number] = WF_SLOT_USED;

	/* XXX need to zero existing SLOT_USED bit for program_status[i]
	   where `i' is the program that's being (potentially) overwritten.
	*/
    
	for (i = 0; i < WF_NUM_LAYERS; i++) {
		if (header->hdr.pr.layer[i].mute) {
			dev->patch_status[header->hdr.pr.layer[i].patch_number] |=
				WF_SLOT_USED;

			/* XXX need to mark SLOT_USED for sample used by
			   patch_number, but this means we have to load it. Ick.
			*/
		}
	}

	buf[0] = header->number;
	munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES);
    
	if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_PROGRAM, NULL, buf)) {
		snd_printk ("download patch failed\n");	
		return -(EIO);
	}

	return (0);
}

static int
wavefront_freemem (snd_wavefront_t *dev)

{
	char rbuf[8];

	if (snd_wavefront_cmd (dev, WFC_REPORT_FREE_MEMORY, rbuf, NULL)) {
		snd_printk ("can't get memory stats.\n");
		return -1;
	} else {
		return demunge_int32 (rbuf, 4);
	}
}

static int
wavefront_send_sample (snd_wavefront_t *dev, 
		       wavefront_patch_info *header,
		       u16 __user *dataptr,
		       int data_is_unsigned)

{
	/* samples are downloaded via a 16-bit wide i/o port
	   (you could think of it as 2 adjacent 8-bit wide ports
	   but its less efficient that way). therefore, all
	   the blocksizes and so forth listed in the documentation,
	   and used conventionally to refer to sample sizes,
	   which are given in 8-bit units (bytes), need to be
	   divided by 2.
        */

	u16 sample_short;
	u32 length;
	u16 __user *data_end = NULL;
	unsigned int i;
	const unsigned int max_blksize = 4096/2;
	unsigned int written;
	unsigned int blocksize;
	int dma_ack;
	int blocknum;
	unsigned char sample_hdr[WF_SAMPLE_HDR_BYTES];
	unsigned char *shptr;
	int skip = 0;
	int initial_skip = 0;

	DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, "
				      "type %d, %d bytes from 0x%lx\n",
				      header->size ? "" : "header ", 
				      header->number, header->subkey,
				      header->size,
				      (unsigned long) header->dataptr);

	if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
		int x;

		if ((x = wavefront_find_free_sample (dev)) < 0) {
			return -ENOMEM;
		}
		snd_printk ("unspecified sample => %d\n", x);
		header->number = x;
	}

	if (header->size) {

		/* XXX it's a debatable point whether or not RDONLY semantics
		   on the ROM samples should cover just the sample data or
		   the sample header. For now, it only covers the sample data,
		   so anyone is free at all times to rewrite sample headers.

		   My reason for this is that we have the sample headers
		   available in the WFB file for General MIDI, and so these
		   can always be reset if needed. The sample data, however,
		   cannot be recovered without a complete reset and firmware
		   reload of the ICS2115, which is a very expensive operation.

		   So, doing things this way allows us to honor the notion of
		   "RESETSAMPLES" reasonably cheaply. Note however, that this
		   is done purely at user level: there is no WFB parser in
		   this driver, and so a complete reset (back to General MIDI,
		   or theoretically some other configuration) is the
		   responsibility of the user level library. 

		   To try to do this in the kernel would be a little
		   crazy: we'd need 158K of kernel space just to hold
		   a copy of the patch/program/sample header data.
		*/

		if (dev->rom_samples_rdonly) {
			if (dev->sample_status[header->number] & WF_SLOT_ROM) {
				snd_printk ("sample slot %d "
					    "write protected\n",
					    header->number);
				return -EACCES;
			}
		}

		wavefront_delete_sample (dev, header->number);
	}

	if (header->size) {
		dev->freemem = wavefront_freemem (dev);

		if (dev->freemem < (int)header->size) {
			snd_printk ("insufficient memory to "
				    "load %d byte sample.\n",
				    header->size);
			return -ENOMEM;
		}
	
	}

	skip = WF_GET_CHANNEL(&header->hdr.s);

	if (skip > 0 && header->hdr.s.SampleResolution != LINEAR_16BIT) {
		snd_printk ("channel selection only "
			    "possible on 16-bit samples");
		return -(EINVAL);
	}

	switch (skip) {
	case 0:
		initial_skip = 0;
		skip = 1;
		break;
	case 1:
		initial_skip = 0;
		skip = 2;
		break;
	case 2:
		initial_skip = 1;
		skip = 2;
		break;
	case 3:
		initial_skip = 2;
		skip = 3;
		break;
	case 4:
		initial_skip = 3;
		skip = 4;
		break;
	case 5:
		initial_skip = 4;
		skip = 5;
		break;
	case 6:
		initial_skip = 5;
		skip = 6;
		break;
	}

	DPRINT (WF_DEBUG_LOAD_PATCH, "channel selection: %d => "
				      "initial skip = %d, skip = %d\n",
				      WF_GET_CHANNEL (&header->hdr.s),
				      initial_skip, skip);
    
	/* Be safe, and zero the "Unused" bits ... */

	WF_SET_CHANNEL(&header->hdr.s, 0);

	/* adjust size for 16 bit samples by dividing by two.  We always
	   send 16 bits per write, even for 8 bit samples, so the length
	   is always half the size of the sample data in bytes.
	*/

	length = header->size / 2;

	/* the data we're sent has not been munged, and in fact, the
	   header we have to send isn't just a munged copy either.
	   so, build the sample header right here.
	*/

	shptr = &sample_hdr[0];

	shptr = munge_int32 (header->number, shptr, 2);

	if (header->size) {
		shptr = munge_int32 (length, shptr, 4);
	}

	/* Yes, a 4 byte result doesn't contain all of the offset bits,
	   but the offset only uses 24 bits.
	*/

	shptr = munge_int32 (*((u32 *) &header->hdr.s.sampleStartOffset),
			     shptr, 4);
	shptr = munge_int32 (*((u32 *) &header->hdr.s.loopStartOffset),
			     shptr, 4);
	shptr = munge_int32 (*((u32 *) &header->hdr.s.loopEndOffset),
			     shptr, 4);
	shptr = munge_int32 (*((u32 *) &header->hdr.s.sampleEndOffset),
			     shptr, 4);
	
	/* This one is truly weird. What kind of weirdo decided that in
	   a system dominated by 16 and 32 bit integers, they would use
	   a just 12 bits ?
	*/
	
	shptr = munge_int32 (header->hdr.s.FrequencyBias, shptr, 3);
	
	/* Why is this nybblified, when the MSB is *always* zero ? 
	   Anyway, we can't take address of bitfield, so make a
	   good-faith guess at where it starts.
	*/
	
	shptr = munge_int32 (*(&header->hdr.s.FrequencyBias+1),
			     shptr, 2);

	if (snd_wavefront_cmd (dev, 
			   header->size ?
			   WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER,
			   NULL, sample_hdr)) {
		snd_printk ("sample %sdownload refused.\n",
			    header->size ? "" : "header ");
		return -(EIO);
	}

	if (header->size == 0) {
		goto sent; /* Sorry. Just had to have one somewhere */
	}
    
	data_end = dataptr + length;

	/* Do any initial skip over an unused channel's data */

	dataptr += initial_skip;
    
	for (written = 0, blocknum = 0;
	     written < length; written += max_blksize, blocknum++) {
	
		if ((length - written) > max_blksize) {
			blocksize = max_blksize;
		} else {
			/* round to nearest 16-byte value */
			blocksize = ((length-written+7)&~0x7);
		}

		if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_BLOCK, NULL, NULL)) {
			snd_printk ("download block "
				    "request refused.\n");
			return -(EIO);
		}

		for (i = 0; i < blocksize; i++) {

			if (dataptr < data_end) {
		
				__get_user (sample_short, dataptr);
				dataptr += skip;
		
				if (data_is_unsigned) { /* GUS ? */

					if (WF_SAMPLE_IS_8BIT(&header->hdr.s)) {
			
						/* 8 bit sample
						 resolution, sign
						 extend both bytes.
						*/
			
						((unsigned char*)
						 &sample_short)[0] += 0x7f;
						((unsigned char*)
						 &sample_short)[1] += 0x7f;
			
					} else {
			
						/* 16 bit sample
						 resolution, sign
						 extend the MSB.
						*/
			
						sample_short += 0x7fff;
					}
				}

			} else {

				/* In padding section of final block:

				   Don't fetch unsupplied data from
				   user space, just continue with
				   whatever the final value was.
				*/
			}
	    
			if (i < blocksize - 1) {
				outw (sample_short, dev->block_port);
			} else {
				outw (sample_short, dev->last_block_port);
			}
		}

		/* Get "DMA page acknowledge", even though its really
		   nothing to do with DMA at all.
		*/
	
		if ((dma_ack = wavefront_read (dev)) != WF_DMA_ACK) {
			if (dma_ack == -1) {
				snd_printk ("upload sample "
					    "DMA ack timeout\n");
				return -(EIO);
			} else {
				snd_printk ("upload sample "
					    "DMA ack error 0x%x\n",
					    dma_ack);
				return -(EIO);
			}
		}
	}

	dev->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE);

	/* Note, label is here because sending the sample header shouldn't
	   alter the sample_status info at all.
	*/

 sent:
	return (0);
}

static int
wavefront_send_alias (snd_wavefront_t *dev, wavefront_patch_info *header)

{
	unsigned char alias_hdr[WF_ALIAS_BYTES];

	DPRINT (WF_DEBUG_LOAD_PATCH, "download alias, %d is "
				      "alias for %d\n",
				      header->number,
				      header->hdr.a.OriginalSample);
    
	munge_int32 (header->number, &alias_hdr[0], 2);
	munge_int32 (header->hdr.a.OriginalSample, &alias_hdr[2], 2);
	munge_int32 (*((unsigned int *)&header->hdr.a.sampleStartOffset),
		     &alias_hdr[4], 4);
	munge_int32 (*((unsigned int *)&header->hdr.a.loopStartOffset),
		     &alias_hdr[8], 4);
	munge_int32 (*((unsigned int *)&header->hdr.a.loopEndOffset),
		     &alias_hdr[12], 4);
	munge_int32 (*((unsigned int *)&header->hdr.a.sampleEndOffset),
		     &alias_hdr[16], 4);
	munge_int32 (header->hdr.a.FrequencyBias, &alias_hdr[20], 3);
	munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2);

	if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_SAMPLE_ALIAS, NULL, alias_hdr)) {
		snd_printk ("download alias failed.\n");
		return -(EIO);
	}

	dev->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS);

	return (0);
}

static int
wavefront_send_multisample (snd_wavefront_t *dev, wavefront_patch_info *header)
{
	int i;
	int num_samples;
	unsigned char *msample_hdr;

	msample_hdr = kmalloc(sizeof(WF_MSAMPLE_BYTES), GFP_KERNEL);
	if (! msample_hdr)
		return -ENOMEM;

	munge_int32 (header->number, &msample_hdr[0], 2);

	/* You'll recall at this point that the "number of samples" value
	   in a wavefront_multisample struct is actually the log2 of the
	   real number of samples.
	*/

	num_samples = (1<<(header->hdr.ms.NumberOfSamples&7));
	msample_hdr[2] = (unsigned char) header->hdr.ms.NumberOfSamples;

	DPRINT (WF_DEBUG_LOAD_PATCH, "multi %d with %d=%d samples\n",
				      header->number,
				      header->hdr.ms.NumberOfSamples,
				      num_samples);

	for (i = 0; i < num_samples; i++) {
		DPRINT(WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA, "sample[%d] = %d\n",
		       i, header->hdr.ms.SampleNumber[i]);
		munge_int32 (header->hdr.ms.SampleNumber[i],
		     &msample_hdr[3+(i*2)], 2);
	}
    
	/* Need a hack here to pass in the number of bytes
	   to be written to the synth. This is ugly, and perhaps
	   one day, I'll fix it.
	*/

	if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_MULTISAMPLE, 
			   (unsigned char *) (long) ((num_samples*2)+3),
			   msample_hdr)) {
		snd_printk ("download of multisample failed.\n");
		kfree(msample_hdr);
		return -(EIO);
	}

	dev->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);

	kfree(msample_hdr);
	return (0);
}

static int
wavefront_fetch_multisample (snd_wavefront_t *dev, 
			     wavefront_patch_info *header)
{
	int i;
	unsigned char log_ns[1];
	unsigned char number[2];
	int num_samples;

	munge_int32 (header->number, number, 2);
    
	if (snd_wavefront_cmd (dev, WFC_UPLOAD_MULTISAMPLE, log_ns, number)) {
		snd_printk ("upload multisample failed.\n");
		return -(EIO);
	}
    
	DPRINT (WF_DEBUG_DATA, "msample %d has %d samples\n",
				header->number, log_ns[0]);

	header->hdr.ms.NumberOfSamples = log_ns[0];

	/* get the number of samples ... */

	num_samples = (1 << log_ns[0]);
    
	for (i = 0; i < num_samples; i++) {
		char d[2];
		int val;
	
		if ((val = wavefront_read (dev)) == -1) {
			snd_printk ("upload multisample failed "
				    "during sample loop.\n");
			return -(EIO);
		}
		d[0] = val;

		if ((val = wavefront_read (dev)) == -1) {
			snd_printk ("upload multisample failed "
				    "during sample loop.\n");
			return -(EIO);
		}
		d[1] = val;
	
		header->hdr.ms.SampleNumber[i] =
			demunge_int32 ((unsigned char *) d, 2);
	
		DPRINT (WF_DEBUG_DATA, "msample sample[%d] = %d\n",
					i, header->hdr.ms.SampleNumber[i]);
	}

	return (0);
}


static int
wavefront_send_drum (snd_wavefront_t *dev, wavefront_patch_info *header)

{
	unsigned char drumbuf[WF_DRUM_BYTES];
	wavefront_drum *drum = &header->hdr.d;
	int i;

	DPRINT (WF_DEBUG_LOAD_PATCH, "downloading edrum for MIDI "
		"note %d, patch = %d\n", 
		header->number, drum->PatchNumber);

	drumbuf[0] = header->number & 0x7f;

	for (i = 0; i < 4; i++) {
		munge_int32 (((unsigned char *)drum)[i], &drumbuf[1+(i*2)], 2);
	}

	if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_EDRUM_PROGRAM, NULL, drumbuf)) {
		snd_printk ("download drum failed.\n");
		return -(EIO);
	}

	return (0);
}

static int 
wavefront_find_free_sample (snd_wavefront_t *dev)

{
	int i;

	for (i = 0; i < WF_MAX_SAMPLE; i++) {
		if (!(dev->sample_status[i] & WF_SLOT_FILLED)) {
			return i;
		}
	}
	snd_printk ("no free sample slots!\n");
	return -1;
}

#if 0
static int 
wavefront_find_free_patch (snd_wavefront_t *dev)

{
	int i;

	for (i = 0; i < WF_MAX_PATCH; i++) {
		if (!(dev->patch_status[i] & WF_SLOT_FILLED)) {
			return i;
		}
	}
	snd_printk ("no free patch slots!\n");
	return -1;
}
#endif

static int
wavefront_load_patch (snd_wavefront_t *dev, const char __user *addr)
{
	wavefront_patch_info *header;
	int err;
	
	header = kmalloc(sizeof(*header), GFP_KERNEL);
	if (! header)
		return -ENOMEM;

	if (copy_from_user (header, addr, sizeof(wavefront_patch_info) -
			    sizeof(wavefront_any))) {
		snd_printk ("bad address for load patch.\n");
		err = -EFAULT;
		goto __error;
	}

	DPRINT (WF_DEBUG_LOAD_PATCH, "download "
				      "Sample type: %d "
				      "Sample number: %d "
				      "Sample size: %d\n",
				      header->subkey,
				      header->number,
				      header->size);

	switch (header->subkey) {
	case WF_ST_SAMPLE:  /* sample or sample_header, based on patch->size */

		if (copy_from_user (&header->hdr.s, header->hdrptr,
				    sizeof (wavefront_sample))) {
			err = -EFAULT;
			break;
		}

		err = wavefront_send_sample (dev, header, header->dataptr, 0);
		break;

	case WF_ST_MULTISAMPLE:

		if (copy_from_user (&header->hdr.s, header->hdrptr,
				    sizeof (wavefront_multisample))) {
			err = -EFAULT;
			break;
		}

		err = wavefront_send_multisample (dev, header);
		break;

	case WF_ST_ALIAS:

		if (copy_from_user (&header->hdr.a, header->hdrptr,
				    sizeof (wavefront_alias))) {
			err = -EFAULT;
			break;
		}

		err = wavefront_send_alias (dev, header);
		break;

	case WF_ST_DRUM:
		if (copy_from_user (&header->hdr.d, header->hdrptr,
				    sizeof (wavefront_drum))) {
			err = -EFAULT;
			break;
		}

		err = wavefront_send_drum (dev, header);
		break;

	case WF_ST_PATCH:
		if (copy_from_user (&header->hdr.p, header->hdrptr,
				    sizeof (wavefront_patch))) {
			err = -EFAULT;
			break;
		}
		
		err = wavefront_send_patch (dev, header);
		break;

	case WF_ST_PROGRAM:
		if (copy_from_user (&header->hdr.pr, header->hdrptr,
				    sizeof (wavefront_program))) {
			err = -EFAULT;
			break;
		}

		err = wavefront_send_program (dev, header);
		break;

	default:
		snd_printk ("unknown patch type %d.\n",
			    header->subkey);
		err = -EINVAL;
		break;
	}

 __error:
	kfree(header);
	return err;
}

/***********************************************************************
WaveFront: hardware-dependent interface
***********************************************************************/

static void
process_sample_hdr (u8 *buf)

{
	wavefront_sample s;
	u8 *ptr;

	ptr = buf;

	/* The board doesn't send us an exact copy of a "wavefront_sample"
	   in response to an Upload Sample Header command. Instead, we 
	   have to convert the data format back into our data structure,
	   just as in the Download Sample command, where we have to do
	   something very similar in the reverse direction.
	*/

	*((u32 *) &s.sampleStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
	*((u32 *) &s.loopStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
	*((u32 *) &s.loopEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
	*((u32 *) &s.sampleEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
	*((u32 *) &s.FrequencyBias) = demunge_int32 (ptr, 3); ptr += 3;

	s.SampleResolution = *ptr & 0x3;
	s.Loop = *ptr & 0x8;
	s.Bidirectional = *ptr & 0x10;
	s.Reverse = *ptr & 0x40;

	/* Now copy it back to where it came from */

	memcpy (buf, (unsigned char *) &s, sizeof (wavefront_sample));
}

static int
wavefront_synth_control (snd_wavefront_card_t *acard, 
			 wavefront_control *wc)

{
	snd_wavefront_t *dev = &acard->wavefront;
	unsigned char patchnumbuf[2];
	int i;

	DPRINT (WF_DEBUG_CMD, "synth control with "
		"cmd 0x%x\n", wc->cmd);

	/* Pre-handling of or for various commands */

	switch (wc->cmd) {
		
	case WFC_DISABLE_INTERRUPTS:
		snd_printk ("interrupts disabled.\n");
		outb (0x80|0x20, dev->control_port);
		dev->interrupts_are_midi = 1;
		return 0;

	case WFC_ENABLE_INTERRUPTS:
		snd_printk ("interrupts enabled.\n");
		outb (0x80|0x40|0x20, dev->control_port);
		dev->interrupts_are_midi = 1;
		return 0;

	case WFC_INTERRUPT_STATUS:
		wc->rbuf[0] = dev->interrupts_are_midi;
		return 0;

	case WFC_ROMSAMPLES_RDONLY:
		dev->rom_samples_rdonly = wc->wbuf[0];
		wc->status = 0;
		return 0;

	case WFC_IDENTIFY_SLOT_TYPE:
		i = wc->wbuf[0] | (wc->wbuf[1] << 7);
		if (i <0 || i >= WF_MAX_SAMPLE) {
			snd_printk ("invalid slot ID %d\n",
				i);
			wc->status = EINVAL;
			return -EINVAL;
		}
		wc->rbuf[0] = dev->sample_status[i];
		wc->status = 0;
		return 0;

	case WFC_DEBUG_DRIVER:
		dev->debug = wc->wbuf[0];
		snd_printk ("debug = 0x%x\n", dev->debug);
		return 0;

	case WFC_UPLOAD_PATCH:
		munge_int32 (*((u32 *) wc->wbuf), patchnumbuf, 2);
		memcpy (wc->wbuf, patchnumbuf, 2);
		break;

	case WFC_UPLOAD_MULTISAMPLE:
		/* multisamples have to be handled differently, and
		   cannot be dealt with properly by snd_wavefront_cmd() alone.
		*/
		wc->status = wavefront_fetch_multisample
			(dev, (wavefront_patch_info *) wc->rbuf);
		return 0;

	case WFC_UPLOAD_SAMPLE_ALIAS:
		snd_printk ("support for sample alias upload "
			"being considered.\n");
		wc->status = EINVAL;
		return -EINVAL;
	}

	wc->status = snd_wavefront_cmd (dev, wc->cmd, wc->rbuf, wc->wbuf);

	/* Post-handling of certain commands.

	   In particular, if the command was an upload, demunge the data
	   so that the user-level doesn't have to think about it.
	*/

	if (wc->status == 0) {
		switch (wc->cmd) {
			/* intercept any freemem requests so that we know
			   we are always current with the user-level view
			   of things.
			*/

		case WFC_REPORT_FREE_MEMORY:
			dev->freemem = demunge_int32 (wc->rbuf, 4);
			break;

		case WFC_UPLOAD_PATCH:
			demunge_buf (wc->rbuf, wc->rbuf, WF_PATCH_BYTES);
			break;

		case WFC_UPLOAD_PROGRAM:
			demunge_buf (wc->rbuf, wc->rbuf, WF_PROGRAM_BYTES);
			break;

		case WFC_UPLOAD_EDRUM_PROGRAM:
			demunge_buf (wc->rbuf, wc->rbuf, WF_DRUM_BYTES - 1);
			break;

		case WFC_UPLOAD_SAMPLE_HEADER:
			process_sample_hdr (wc->rbuf);
			break;

		case WFC_UPLOAD_SAMPLE_ALIAS:
			snd_printk ("support for "
				    "sample aliases still "
				    "being considered.\n");
			break;

		case WFC_VMIDI_OFF:
			snd_wavefront_midi_disable_virtual (acard);
			break;

		case WFC_VMIDI_ON:
			snd_wavefront_midi_enable_virtual (acard);
			break;
		}
	}

	return 0;
}

int 
snd_wavefront_synth_open (snd_hwdep_t *hw, struct file *file)

{
	if (!try_module_get(hw->card->module))
		return -EFAULT;
	file->private_data = hw;
	return 0;
}

int 
snd_wavefront_synth_release (snd_hwdep_t *hw, struct file *file)

{
	module_put(hw->card->module);
	return 0;
}

int
snd_wavefront_synth_ioctl (snd_hwdep_t *hw, struct file *file,
			   unsigned int cmd, unsigned long arg)

{
	snd_card_t *card;
	snd_wavefront_t *dev;
	snd_wavefront_card_t *acard;
	wavefront_control *wc;
	void __user *argp = (void __user *)arg;
	int err;

	card = (snd_card_t *) hw->card;

	snd_assert(card != NULL, return -ENODEV);

	snd_assert(card->private_data != NULL, return -ENODEV);

	acard = card->private_data;
	dev = &acard->wavefront;
	
	switch (cmd) {
	case WFCTL_LOAD_SPP:
		if (wavefront_load_patch (dev, argp) != 0) {
			return -EIO;
		}
		break;

	case WFCTL_WFCMD:
		wc = kmalloc(sizeof(*wc), GFP_KERNEL);
		if (! wc)
			return -ENOMEM;
		if (copy_from_user (wc, argp, sizeof (*wc)))
			err = -EFAULT;
		else if (wavefront_synth_control (acard, wc) < 0)
			err = -EIO;
		else if (copy_to_user (argp, wc, sizeof (*wc)))
			err = -EFAULT;
		else
			err = 0;
		kfree(wc);
		return err;

	default:
		return -EINVAL;
	}

	return 0;
}


/***********************************************************************/
/*  WaveFront: interface for card-level wavefront module               */
/***********************************************************************/

void
snd_wavefront_internal_interrupt (snd_wavefront_card_t *card)
{
	snd_wavefront_t *dev = &card->wavefront;

	/*
	   Some comments on interrupts. I attempted a version of this
	   driver that used interrupts throughout the code instead of
	   doing busy and/or sleep-waiting. Alas, it appears that once
	   the Motorola firmware is downloaded, the card *never*
	   generates an RX interrupt. These are successfully generated
	   during firmware loading, and after that wavefront_status()
	   reports that an interrupt is pending on the card from time
	   to time, but it never seems to be delivered to this
	   driver. Note also that wavefront_status() continues to
	   report that RX interrupts are enabled, suggesting that I
	   didn't goof up and disable them by mistake.

	   Thus, I stepped back to a prior version of
	   wavefront_wait(), the only place where this really
	   matters. Its sad, but I've looked through the code to check
	   on things, and I really feel certain that the Motorola
	   firmware prevents RX-ready interrupts.
	*/

	if ((wavefront_status(dev) & (STAT_INTR_READ|STAT_INTR_WRITE)) == 0) {
		return;
	}

	spin_lock(&dev->irq_lock);
	dev->irq_ok = 1;
	dev->irq_cnt++;
	spin_unlock(&dev->irq_lock);
	wake_up(&dev->interrupt_sleeper);
}

/* STATUS REGISTER 

0 Host Rx Interrupt Enable (1=Enabled)
1 Host Rx Register Full (1=Full)
2 Host Rx Interrupt Pending (1=Interrupt)
3 Unused
4 Host Tx Interrupt (1=Enabled)
5 Host Tx Register empty (1=Empty)
6 Host Tx Interrupt Pending (1=Interrupt)
7 Unused
*/

static int __init
snd_wavefront_interrupt_bits (int irq)

{
	int bits;

	switch (irq) {
	case 9:
		bits = 0x00;
		break;
	case 5:
		bits = 0x08;
		break;
	case 12:
		bits = 0x10;
		break;
	case 15:
		bits = 0x18;
		break;
	
	default:
		snd_printk ("invalid IRQ %d\n", irq);
		bits = -1;
	}

	return bits;
}

static void __init
wavefront_should_cause_interrupt (snd_wavefront_t *dev, 
				  int val, int port, int timeout)

{
	wait_queue_t wait;

	init_waitqueue_entry(&wait, current);
	spin_lock_irq(&dev->irq_lock);
	add_wait_queue(&dev->interrupt_sleeper, &wait);
	dev->irq_ok = 0;
	outb (val,port);
	spin_unlock_irq(&dev->irq_lock);
	while (1) {
		set_current_state(TASK_INTERRUPTIBLE);
		if ((timeout = schedule_timeout(timeout)) == 0)
			return;
		if (dev->irq_ok)
			return;
	}
}

static int __init
wavefront_reset_to_cleanliness (snd_wavefront_t *dev)

{
	int bits;
	int hwv[2];

	/* IRQ already checked */

	bits = snd_wavefront_interrupt_bits (dev->irq);

	/* try reset of port */

	outb (0x0, dev->control_port); 
  
	/* At this point, the board is in reset, and the H/W initialization
	   register is accessed at the same address as the data port.
     
	   Bit 7 - Enable IRQ Driver	
	   0 - Tri-state the Wave-Board drivers for the PC Bus IRQs
	   1 - Enable IRQ selected by bits 5:3 to be driven onto the PC Bus.
     
	   Bit 6 - MIDI Interface Select

	   0 - Use the MIDI Input from the 26-pin WaveBlaster
	   compatible header as the serial MIDI source
	   1 - Use the MIDI Input from the 9-pin D connector as the
	   serial MIDI source.
     
	   Bits 5:3 - IRQ Selection
	   0 0 0 - IRQ 2/9
	   0 0 1 - IRQ 5
	   0 1 0 - IRQ 12
	   0 1 1 - IRQ 15
	   1 0 0 - Reserved
	   1 0 1 - Reserved
	   1 1 0 - Reserved
	   1 1 1 - Reserved
     
	   Bits 2:1 - Reserved
	   Bit 0 - Disable Boot ROM
	   0 - memory accesses to 03FC30-03FFFFH utilize the internal Boot ROM
	   1 - memory accesses to 03FC30-03FFFFH are directed to external 
	   storage.
     
	*/

	/* configure hardware: IRQ, enable interrupts, 
	   plus external 9-pin MIDI interface selected
	*/

	outb (0x80 | 0x40 | bits, dev->data_port);	
  
	/* CONTROL REGISTER

	   0 Host Rx Interrupt Enable (1=Enabled)      0x1
	   1 Unused                                    0x2
	   2 Unused                                    0x4
	   3 Unused                                    0x8
	   4 Host Tx Interrupt Enable                 0x10
	   5 Mute (0=Mute; 1=Play)                    0x20
	   6 Master Interrupt Enable (1=Enabled)      0x40
	   7 Master Reset (0=Reset; 1=Run)            0x80

	   Take us out of reset, mute output, master + TX + RX interrupts on.
	   
	   We'll get an interrupt presumably to tell us that the TX
	   register is clear.
	*/

	wavefront_should_cause_interrupt(dev, 0x80|0x40|0x10|0x1,
					 dev->control_port,
					 (reset_time*HZ)/100);

	/* Note: data port is now the data port, not the h/w initialization
	   port.
	 */

	if (!dev->irq_ok) {
		snd_printk ("intr not received after h/w un-reset.\n");
		goto gone_bad;
	} 

	/* Note: data port is now the data port, not the h/w initialization
	   port.

	   At this point, only "HW VERSION" or "DOWNLOAD OS" commands
	   will work. So, issue one of them, and wait for TX
	   interrupt. This can take a *long* time after a cold boot,
	   while the ISC ROM does its RAM test. The SDK says up to 4
	   seconds - with 12MB of RAM on a Tropez+, it takes a lot
	   longer than that (~16secs). Note that the card understands
	   the difference between a warm and a cold boot, so
	   subsequent ISC2115 reboots (say, caused by module
	   reloading) will get through this much faster.

	   XXX Interesting question: why is no RX interrupt received first ?
	*/

	wavefront_should_cause_interrupt(dev, WFC_HARDWARE_VERSION, 
					 dev->data_port, ramcheck_time*HZ);

	if (!dev->irq_ok) {
		snd_printk ("post-RAM-check interrupt not received.\n");
		goto gone_bad;
	} 

	if (!wavefront_wait (dev, STAT_CAN_READ)) {
		snd_printk ("no response to HW version cmd.\n");
		goto gone_bad;
	}
	
	if ((hwv[0] = wavefront_read (dev)) == -1) {
		snd_printk ("board not responding correctly.\n");
		goto gone_bad;
	}

	if (hwv[0] == 0xFF) { /* NAK */

		/* Board's RAM test failed. Try to read error code,
		   and tell us about it either way.
		*/
		
		if ((hwv[0] = wavefront_read (dev)) == -1) {
			snd_printk ("on-board RAM test failed "
				    "(bad error code).\n");
		} else {
			snd_printk ("on-board RAM test failed "
				    "(error code: 0x%x).\n",
				hwv[0]);
		}
		goto gone_bad;
	}

	/* We're OK, just get the next byte of the HW version response */

	if ((hwv[1] = wavefront_read (dev)) == -1) {
		snd_printk ("incorrect h/w response.\n");
		goto gone_bad;
	}

	snd_printk ("hardware version %d.%d\n",
		    hwv[0], hwv[1]);

	return 0;


     gone_bad:
	return (1);
}

#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
#include <asm/uaccess.h>


static int __init
wavefront_download_firmware (snd_wavefront_t *dev, char *path)

{
	unsigned char section[WF_SECTION_MAX];
	signed char section_length; /* yes, just a char; max value is WF_SECTION_MAX */
	int section_cnt_downloaded = 0;
	int fd;
	int c;
	int i;
	mm_segment_t fs;

	/* This tries to be a bit cleverer than the stuff Alan Cox did for
	   the generic sound firmware, in that it actually knows
	   something about the structure of the Motorola firmware. In
	   particular, it uses a version that has been stripped of the
	   20K of useless header information, and had section lengths
	   added, making it possible to load the entire OS without any
	   [kv]malloc() activity, since the longest entity we ever read is
	   42 bytes (well, WF_SECTION_MAX) long.
	*/

	fs = get_fs();
	set_fs (get_ds());

	if ((fd = sys_open ((char __user *) path, 0, 0)) < 0) {
		snd_printk ("Unable to load \"%s\".\n",
			path);
		return 1;
	}

	while (1) {
		int x;

		if ((x = sys_read (fd, (char __user *) &section_length, sizeof (section_length))) !=
		    sizeof (section_length)) {
			snd_printk ("firmware read error.\n");
			goto failure;
		}

		if (section_length == 0) {
			break;
		}

		if (section_length < 0 || section_length > WF_SECTION_MAX) {
			snd_printk ("invalid firmware section length %d\n",
				    section_length);
			goto failure;
		}

		if (sys_read (fd, (char __user *) section, section_length) != section_length) {
			snd_printk ("firmware section "
				"read error.\n");
			goto failure;
		}

		/* Send command */
	
		if (wavefront_write (dev, WFC_DOWNLOAD_OS)) {
			goto failure;
		}
	
		for (i = 0; i < section_length; i++) {
			if (wavefront_write (dev, section[i])) {
				goto failure;
			}
		}
	
		/* get ACK */
	
		if (wavefront_wait (dev, STAT_CAN_READ)) {

			if ((c = inb (dev->data_port)) != WF_ACK) {

				snd_printk ("download "
					    "of section #%d not "
					    "acknowledged, ack = 0x%x\n",
					    section_cnt_downloaded + 1, c);
				goto failure;
		
			}

		} else {
			snd_printk ("time out for firmware ACK.\n");
			goto failure;
		}

	}

	sys_close (fd);
	set_fs (fs);
	return 0;

 failure:
	sys_close (fd);
	set_fs (fs);
	snd_printk ("firmware download failed!!!\n");
	return 1;
}


static int __init
wavefront_do_reset (snd_wavefront_t *dev)

{
	char voices[1];

	if (wavefront_reset_to_cleanliness (dev)) {
		snd_printk ("hw reset failed.\n");
		goto gone_bad;
	}

	if (dev->israw) {
		if (wavefront_download_firmware (dev, ospath)) {
			goto gone_bad;
		}

		dev->israw = 0;

		/* Wait for the OS to get running. The protocol for
		   this is non-obvious, and was determined by
		   using port-IO tracing in DOSemu and some
		   experimentation here.
		   
		   Rather than using timed waits, use interrupts creatively.
		*/

		wavefront_should_cause_interrupt (dev, WFC_NOOP,
						  dev->data_port,
						  (osrun_time*HZ));

		if (!dev->irq_ok) {
			snd_printk ("no post-OS interrupt.\n");
			goto gone_bad;
		}
		
		/* Now, do it again ! */
		
		wavefront_should_cause_interrupt (dev, WFC_NOOP,
						  dev->data_port, (10*HZ));
		
		if (!dev->irq_ok) {
			snd_printk ("no post-OS interrupt(2).\n");
			goto gone_bad;
		}

		/* OK, no (RX/TX) interrupts any more, but leave mute
		   in effect. 
		*/
		
		outb (0x80|0x40, dev->control_port); 
	}

	/* SETUPSND.EXE asks for sample memory config here, but since i
	   have no idea how to interpret the result, we'll forget
	   about it.
	*/
	
	if ((dev->freemem = wavefront_freemem (dev)) < 0) {
		goto gone_bad;
	}
		
	snd_printk ("available DRAM %dk\n", dev->freemem / 1024);

	if (wavefront_write (dev, 0xf0) ||
	    wavefront_write (dev, 1) ||
	    (wavefront_read (dev) < 0)) {
		dev->debug = 0;
		snd_printk ("MPU emulation mode not set.\n");
		goto gone_bad;
	}

	voices[0] = 32;

	if (snd_wavefront_cmd (dev, WFC_SET_NVOICES, NULL, voices)) {
		snd_printk ("cannot set number of voices to 32.\n");
		goto gone_bad;
	}


	return 0;

 gone_bad:
	/* reset that sucker so that it doesn't bother us. */

	outb (0x0, dev->control_port);
	dev->interrupts_are_midi = 0;
	return 1;
}

int __init
snd_wavefront_start (snd_wavefront_t *dev)

{
	int samples_are_from_rom;

	/* IMPORTANT: assumes that snd_wavefront_detect() and/or
	   wavefront_reset_to_cleanliness() has already been called 
	*/

	if (dev->israw) {
		samples_are_from_rom = 1;
	} else {
		/* XXX is this always true ? */
		samples_are_from_rom = 0;
	}

	if (dev->israw || fx_raw) {
		if (wavefront_do_reset (dev)) {
			return -1;
		}
	}
	/* Check for FX device, present only on Tropez+ */

	dev->has_fx = (snd_wavefront_fx_detect (dev) == 0);

	if (dev->has_fx && fx_raw) {
		snd_wavefront_fx_start (dev);
	}

	wavefront_get_sample_status (dev, samples_are_from_rom);
	wavefront_get_program_status (dev);
	wavefront_get_patch_status (dev);

	/* Start normal operation: unreset, master interrupt enabled, no mute
	*/

	outb (0x80|0x40|0x20, dev->control_port); 

	return (0);
}

int __init
snd_wavefront_detect (snd_wavefront_card_t *card)

{
	unsigned char   rbuf[4], wbuf[4];
	snd_wavefront_t *dev = &card->wavefront;
	
	/* returns zero if a WaveFront card is successfully detected.
	   negative otherwise.
	*/

	dev->israw = 0;
	dev->has_fx = 0;
	dev->debug = debug_default;
	dev->interrupts_are_midi = 0;
	dev->irq_cnt = 0;
	dev->rom_samples_rdonly = 1;

	if (snd_wavefront_cmd (dev, WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) {

		dev->fw_version[0] = rbuf[0];
		dev->fw_version[1] = rbuf[1];

		snd_printk ("firmware %d.%d already loaded.\n",
			    rbuf[0], rbuf[1]);

		/* check that a command actually works */
      
		if (snd_wavefront_cmd (dev, WFC_HARDWARE_VERSION,
				       rbuf, wbuf) == 0) {
			dev->hw_version[0] = rbuf[0];
			dev->hw_version[1] = rbuf[1];
		} else {
			snd_printk ("not raw, but no "
				    "hardware version!\n");
			return -1;
		}

		if (!wf_raw) {
			return 0;
		} else {
			snd_printk ("reloading firmware as you requested.\n");
			dev->israw = 1;
		}

	} else {

		dev->israw = 1;
		snd_printk ("no response to firmware probe, assume raw.\n");

	}

	return 0;
}
