/*
 * sound/oss/audio.c
 *
 * Device file manager for /dev/audio
 */

/*
 * 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.
 */
/*
 * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
 * Thomas Sailer   : moved several static variables into struct audio_operations
 *                   (which is grossly misnamed btw.) because they have the same
 *                   lifetime as the rest in there and dynamic allocation saves
 *                   12k or so
 * Thomas Sailer   : use more logical O_NONBLOCK semantics
 * Daniel Rodriksson: reworked the use of the device specific copy_user
 *                    still generic
 * Horst von Brand:  Add missing #include <linux/string.h>
 * Chris Rankin    : Update the module-usage counter for the coprocessor,
 *                   and decrement the counters again if we cannot open
 *                   the audio device.
 */

#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/kmod.h>

#include "sound_config.h"
#include "ulaw.h"
#include "coproc.h"

#define NEUTRAL8	0x80
#define NEUTRAL16	0x00


static int             dma_ioctl(int dev, unsigned int cmd, void __user *arg);

static int set_format(int dev, int fmt)
{
	if (fmt != AFMT_QUERY)
	{
		audio_devs[dev]->local_conversion = 0;

		if (!(audio_devs[dev]->format_mask & fmt))	/* Not supported */
		{
			if (fmt == AFMT_MU_LAW)
			{
				fmt = AFMT_U8;
				audio_devs[dev]->local_conversion = CNV_MU_LAW;
			}
			else
				fmt = AFMT_U8;	/* This is always supported */
		}
		audio_devs[dev]->audio_format = audio_devs[dev]->d->set_bits(dev, fmt);
		audio_devs[dev]->local_format = fmt;
	}
	else
		return audio_devs[dev]->local_format;

	if (audio_devs[dev]->local_conversion)
		return audio_devs[dev]->local_conversion;
	else 
		return audio_devs[dev]->local_format;
}

int audio_open(int dev, struct file *file)
{
	int ret;
	int bits;
	int dev_type = dev & 0x0f;
	int mode = translate_mode(file);
	const struct audio_driver *driver;
	const struct coproc_operations *coprocessor;

	dev = dev >> 4;

	if (dev_type == SND_DEV_DSP16)
		bits = 16;
	else
		bits = 8;

	if (dev < 0 || dev >= num_audiodevs)
		return -ENXIO;

	driver = audio_devs[dev]->d;

	if (!try_module_get(driver->owner))
		return -ENODEV;

	if ((ret = DMAbuf_open(dev, mode)) < 0)
		goto error_1;

	if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
		if (!try_module_get(coprocessor->owner))
			goto error_2;

		if ((ret = coprocessor->open(coprocessor->devc, COPR_PCM)) < 0) {
			printk(KERN_WARNING "Sound: Can't access coprocessor device\n");
			goto error_3;
		}
	}
	
	audio_devs[dev]->local_conversion = 0;

	if (dev_type == SND_DEV_AUDIO)
		set_format(dev, AFMT_MU_LAW);
	else 
		set_format(dev, bits);

	audio_devs[dev]->audio_mode = AM_NONE;

	return 0;

	/*
	 * Clean-up stack: this is what needs (un)doing if
	 * we can't open the audio device ...
	 */
	error_3:
	module_put(coprocessor->owner);

	error_2:
	DMAbuf_release(dev, mode);

	error_1:
	module_put(driver->owner);

	return ret;
}

static void sync_output(int dev)
{
	int             p, i;
	int             l;
	struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;

	if (dmap->fragment_size <= 0)
		return;
	dmap->flags |= DMA_POST;

	/* Align the write pointer with fragment boundaries */
	
	if ((l = dmap->user_counter % dmap->fragment_size) > 0)
	{
		int len;
		unsigned long offs = dmap->user_counter % dmap->bytes_in_use;

		len = dmap->fragment_size - l;
		memset(dmap->raw_buf + offs, dmap->neutral_byte, len);
		DMAbuf_move_wrpointer(dev, len);
	}
	
	/*
	 * Clean all unused buffer fragments.
	 */

	p = dmap->qtail;
	dmap->flags |= DMA_POST;

	for (i = dmap->qlen + 1; i < dmap->nbufs; i++)
	{
		p = (p + 1) % dmap->nbufs;
		if (((dmap->raw_buf + p * dmap->fragment_size) + dmap->fragment_size) >
			(dmap->raw_buf + dmap->buffsize))
				printk(KERN_ERR "audio: Buffer error 2\n");

		memset(dmap->raw_buf + p * dmap->fragment_size,
			dmap->neutral_byte,
			dmap->fragment_size);
	}

	dmap->flags |= DMA_DIRTY;
}

void audio_release(int dev, struct file *file)
{
	const struct coproc_operations *coprocessor;
	int mode = translate_mode(file);

	dev = dev >> 4;

	/*
	 * We do this in DMAbuf_release(). Why are we doing it
	 * here? Why don't we test the file mode before setting
	 * both flags? DMAbuf_release() does.
	 * ...pester...pester...pester...
	 */
	audio_devs[dev]->dmap_out->closing = 1;
	audio_devs[dev]->dmap_in->closing = 1;

	/*
	 * We need to make sure we allocated the dmap_out buffer
	 * before we go mucking around with it in sync_output().
	 */
	if (mode & OPEN_WRITE)
		sync_output(dev);

	if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
		coprocessor->close(coprocessor->devc, COPR_PCM);
		module_put(coprocessor->owner);
	}
	DMAbuf_release(dev, mode);

	module_put(audio_devs[dev]->d->owner);
}

static void translate_bytes(const unsigned char *table, unsigned char *buff, int n)
{
	unsigned long   i;

	if (n <= 0)
		return;

	for (i = 0; i < n; ++i)
		buff[i] = table[buff[i]];
}

int audio_write(int dev, struct file *file, const char __user *buf, int count)
{
	int c, p, l, buf_size, used, returned;
	int err;
	char *dma_buf;

	dev = dev >> 4;

	p = 0;
	c = count;
	
	if(count < 0)
		return -EINVAL;

	if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
		return -EPERM;

	if (audio_devs[dev]->flags & DMA_DUPLEX)
		audio_devs[dev]->audio_mode |= AM_WRITE;
	else
		audio_devs[dev]->audio_mode = AM_WRITE;

	if (!count)		/* Flush output */
	{
		  sync_output(dev);
		  return 0;
	}
	
	while (c)
	{
		if ((err = DMAbuf_getwrbuffer(dev, &dma_buf, &buf_size, !!(file->f_flags & O_NONBLOCK))) < 0)
		{
			    /* Handle nonblocking mode */
			if ((file->f_flags & O_NONBLOCK) && err == -EAGAIN)
				return p? p : -EAGAIN;	/* No more space. Return # of accepted bytes */
			return err;
		}
		l = c;

		if (l > buf_size)
			l = buf_size;

		returned = l;
		used = l;
		if (!audio_devs[dev]->d->copy_user)
		{
			if ((dma_buf + l) >
				(audio_devs[dev]->dmap_out->raw_buf + audio_devs[dev]->dmap_out->buffsize))
			{
				printk(KERN_ERR "audio: Buffer error 3 (%lx,%d), (%lx, %d)\n", (long) dma_buf, l, (long) audio_devs[dev]->dmap_out->raw_buf, (int) audio_devs[dev]->dmap_out->buffsize);
				return -EDOM;
			}
			if (dma_buf < audio_devs[dev]->dmap_out->raw_buf)
			{
				printk(KERN_ERR "audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf, (long) audio_devs[dev]->dmap_out->raw_buf);
				return -EDOM;
			}
			if(copy_from_user(dma_buf, &(buf)[p], l))
				return -EFAULT;
		} 
		else audio_devs[dev]->d->copy_user (dev,
						dma_buf, 0,
						buf, p,
						c, buf_size,
						&used, &returned,
						l);
		l = returned;

		if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
		{
			translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
		}
		c -= used;
		p += used;
		DMAbuf_move_wrpointer(dev, l);

	}

	return count;
}

int audio_read(int dev, struct file *file, char __user *buf, int count)
{
	int             c, p, l;
	char           *dmabuf;
	int             buf_no;

	dev = dev >> 4;
	p = 0;
	c = count;

	if (!(audio_devs[dev]->open_mode & OPEN_READ))
		return -EPERM;

	if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
		sync_output(dev);

	if (audio_devs[dev]->flags & DMA_DUPLEX)
		audio_devs[dev]->audio_mode |= AM_READ;
	else
		audio_devs[dev]->audio_mode = AM_READ;

	while(c)
	{
		if ((buf_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l, !!(file->f_flags & O_NONBLOCK))) < 0)
		{
			/*
			 *	Nonblocking mode handling. Return current # of bytes
			 */

			if (p > 0) 		/* Avoid throwing away data */
				return p;	/* Return it instead */

			if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN)
				return -EAGAIN;

			return buf_no;
		}
		if (l > c)
			l = c;

		/*
		 * Insert any local processing here.
		 */

		if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
		{
			translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l);
		}
		
		{
			char           *fixit = dmabuf;

			if(copy_to_user(&(buf)[p], fixit, l))
				return -EFAULT;
		};

		DMAbuf_rmchars(dev, buf_no, l);

		p += l;
		c -= l;
	}

	return count - c;
}

int audio_ioctl(int dev, struct file *file, unsigned int cmd, void __user *arg)
{
	int val, count;
	unsigned long flags;
	struct dma_buffparms *dmap;
	int __user *p = arg;

	dev = dev >> 4;

	if (_IOC_TYPE(cmd) == 'C')	{
		if (audio_devs[dev]->coproc)	/* Coprocessor ioctl */
			return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
		/* else
		        printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
		return -ENXIO;
	}
	else switch (cmd) 
	{
		case SNDCTL_DSP_SYNC:
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return 0;
			if (audio_devs[dev]->dmap_out->fragment_size == 0)
				return 0;
			sync_output(dev);
			DMAbuf_sync(dev);
			DMAbuf_reset(dev);
			return 0;

		case SNDCTL_DSP_POST:
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return 0;
			if (audio_devs[dev]->dmap_out->fragment_size == 0)
				return 0;
			audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
			sync_output(dev);
			dma_ioctl(dev, SNDCTL_DSP_POST, NULL);
			return 0;

		case SNDCTL_DSP_RESET:
			audio_devs[dev]->audio_mode = AM_NONE;
			DMAbuf_reset(dev);
			return 0;

		case SNDCTL_DSP_GETFMTS:
			val = audio_devs[dev]->format_mask | AFMT_MU_LAW;
			break;
	
		case SNDCTL_DSP_SETFMT:
			if (get_user(val, p))
				return -EFAULT;
			val = set_format(dev, val);
			break;

		case SNDCTL_DSP_GETISPACE:
			if (!(audio_devs[dev]->open_mode & OPEN_READ))
				return 0;
  			if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
  				return -EBUSY;
			return dma_ioctl(dev, cmd, arg);

		case SNDCTL_DSP_GETOSPACE:
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return -EPERM;
  			if ((audio_devs[dev]->audio_mode & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
  				return -EBUSY;
			return dma_ioctl(dev, cmd, arg);
		
		case SNDCTL_DSP_NONBLOCK:
			spin_lock(&file->f_lock);
			file->f_flags |= O_NONBLOCK;
			spin_unlock(&file->f_lock);
			return 0;

		case SNDCTL_DSP_GETCAPS:
				val = 1 | DSP_CAP_MMAP;	/* Revision level of this ioctl() */
				if (audio_devs[dev]->flags & DMA_DUPLEX &&
					audio_devs[dev]->open_mode == OPEN_READWRITE)
					val |= DSP_CAP_DUPLEX;
				if (audio_devs[dev]->coproc)
					val |= DSP_CAP_COPROC;
				if (audio_devs[dev]->d->local_qlen)	/* Device has hidden buffers */
					val |= DSP_CAP_BATCH;
				if (audio_devs[dev]->d->trigger)	/* Supports SETTRIGGER */
					val |= DSP_CAP_TRIGGER;
				break;
			
		case SOUND_PCM_WRITE_RATE:
			if (get_user(val, p))
				return -EFAULT;
			val = audio_devs[dev]->d->set_speed(dev, val);
			break;

		case SOUND_PCM_READ_RATE:
			val = audio_devs[dev]->d->set_speed(dev, 0);
			break;
			
		case SNDCTL_DSP_STEREO:
			if (get_user(val, p))
				return -EFAULT;
			if (val > 1 || val < 0)
				return -EINVAL;
			val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
			break;

		case SOUND_PCM_WRITE_CHANNELS:
			if (get_user(val, p))
				return -EFAULT;
			val = audio_devs[dev]->d->set_channels(dev, val);
			break;

		case SOUND_PCM_READ_CHANNELS:
			val = audio_devs[dev]->d->set_channels(dev, 0);
			break;
		
		case SOUND_PCM_READ_BITS:
			val = audio_devs[dev]->d->set_bits(dev, 0);
			break;

		case SNDCTL_DSP_SETDUPLEX:
			if (audio_devs[dev]->open_mode != OPEN_READWRITE)
				return -EPERM;
			return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;

		case SNDCTL_DSP_PROFILE:
			if (get_user(val, p))
				return -EFAULT;
			if (audio_devs[dev]->open_mode & OPEN_WRITE)
				audio_devs[dev]->dmap_out->applic_profile = val;
			if (audio_devs[dev]->open_mode & OPEN_READ)
				audio_devs[dev]->dmap_in->applic_profile = val;
			return 0;
		
		case SNDCTL_DSP_GETODELAY:
			dmap = audio_devs[dev]->dmap_out;
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return -EINVAL;
			if (!(dmap->flags & DMA_ALLOC_DONE))
			{
				val=0;
				break;
			}
		
			spin_lock_irqsave(&dmap->lock,flags);
			/* Compute number of bytes that have been played */
			count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
			if (count < dmap->fragment_size && dmap->qhead != 0)
				count += dmap->bytes_in_use;	/* Pointer wrap not handled yet */
			count += dmap->byte_counter;
		
			/* Subtract current count from the number of bytes written by app */
			count = dmap->user_counter - count;
			if (count < 0)
				count = 0;
			spin_unlock_irqrestore(&dmap->lock,flags);
			val = count;
			break;
		
		default:
			return dma_ioctl(dev, cmd, arg);
	}
	return put_user(val, p);
}

void audio_init_devices(void)
{
	/*
	 * NOTE! This routine could be called several times during boot.
	 */
}

void reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
{
	/*
	 * This routine breaks the physical device buffers to logical ones.
	 */

	struct audio_operations *dsp_dev = audio_devs[dev];

	unsigned i, n;
	unsigned sr, nc, sz, bsz;

	sr = dsp_dev->d->set_speed(dev, 0);
	nc = dsp_dev->d->set_channels(dev, 0);
	sz = dsp_dev->d->set_bits(dev, 0);

	if (sz == 8)
		dmap->neutral_byte = NEUTRAL8;
	else
		dmap->neutral_byte = NEUTRAL16;

	if (sr < 1 || nc < 1 || sz < 1)
	{
/*		printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/
		sr = DSP_DEFAULT_SPEED;
		nc = 1;
		sz = 8;
	}
	
	sz = sr * nc * sz;

	sz /= 8;		/* #bits -> #bytes */
	dmap->data_rate = sz;

	if (!dmap->needs_reorg)
		return;
	dmap->needs_reorg = 0;

	if (dmap->fragment_size == 0)
	{	
		/* Compute the fragment size using the default algorithm */

		/*
		 * Compute a buffer size for time not exceeding 1 second.
		 * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
		 * of sound (using the current speed, sample size and #channels).
		 */

		bsz = dmap->buffsize;
		while (bsz > sz)
			bsz /= 2;

		if (bsz == dmap->buffsize)
			bsz /= 2;	/* Needs at least 2 buffers */

		/*
		 *    Split the computed fragment to smaller parts. After 3.5a9
		 *      the default subdivision is 4 which should give better
		 *      results when recording.
		 */

		if (dmap->subdivision == 0)	/* Not already set */
		{
			dmap->subdivision = 4;	/* Init to the default value */

			if ((bsz / dmap->subdivision) > 4096)
				dmap->subdivision *= 2;
			if ((bsz / dmap->subdivision) < 4096)
				dmap->subdivision = 1;
		}
		bsz /= dmap->subdivision;

		if (bsz < 16)
			bsz = 16;	/* Just a sanity check */

		dmap->fragment_size = bsz;
	}
	else
	{
		/*
		 * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
		 * the buffer size computation has already been done.
		 */
		if (dmap->fragment_size > (dmap->buffsize / 2))
			dmap->fragment_size = (dmap->buffsize / 2);
		bsz = dmap->fragment_size;
	}

	if (audio_devs[dev]->min_fragment)
		if (bsz < (1 << audio_devs[dev]->min_fragment))
			bsz = 1 << audio_devs[dev]->min_fragment;
	if (audio_devs[dev]->max_fragment)
		if (bsz > (1 << audio_devs[dev]->max_fragment))
			bsz = 1 << audio_devs[dev]->max_fragment;
	bsz &= ~0x07;		/* Force size which is multiple of 8 bytes */
#ifdef OS_DMA_ALIGN_CHECK
	OS_DMA_ALIGN_CHECK(bsz);
#endif

	n = dmap->buffsize / bsz;
	if (n > MAX_SUB_BUFFERS)
		n = MAX_SUB_BUFFERS;
	if (n > dmap->max_fragments)
		n = dmap->max_fragments;

	if (n < 2)
	{
		n = 2;
		bsz /= 2;
	}
	dmap->nbufs = n;
	dmap->bytes_in_use = n * bsz;
	dmap->fragment_size = bsz;
	dmap->max_byte_counter = (dmap->data_rate * 60 * 60) +
			dmap->bytes_in_use;	/* Approximately one hour */

	if (dmap->raw_buf)
	{
		memset(dmap->raw_buf, dmap->neutral_byte, dmap->bytes_in_use);
	}
	
	for (i = 0; i < dmap->nbufs; i++)
	{
		dmap->counts[i] = 0;
	}

	dmap->flags |= DMA_ALLOC_DONE | DMA_EMPTY;
}

static int dma_subdivide(int dev, struct dma_buffparms *dmap, int fact)
{
	if (fact == 0) 
	{
		fact = dmap->subdivision;
		if (fact == 0)
			fact = 1;
		return fact;
	}
	if (dmap->subdivision != 0 || dmap->fragment_size)	/* Too late to change */
		return -EINVAL;

	if (fact > MAX_REALTIME_FACTOR)
		return -EINVAL;

	if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact != 16)
		return -EINVAL;

	dmap->subdivision = fact;
	return fact;
}

static int dma_set_fragment(int dev, struct dma_buffparms *dmap, int fact)
{
	int bytes, count;

	if (fact == 0)
		return -EIO;

	if (dmap->subdivision != 0 ||
	    dmap->fragment_size)	/* Too late to change */
		return -EINVAL;

	bytes = fact & 0xffff;
	count = (fact >> 16) & 0x7fff;

	if (count == 0)
		count = MAX_SUB_BUFFERS;
	else if (count < MAX_SUB_BUFFERS)
		count++;

	if (bytes < 4 || bytes > 17)	/* <16 || > 512k */
		return -EINVAL;

	if (count < 2)
		return -EINVAL;

	if (audio_devs[dev]->min_fragment > 0)
		if (bytes < audio_devs[dev]->min_fragment)
			bytes = audio_devs[dev]->min_fragment;

	if (audio_devs[dev]->max_fragment > 0)
		if (bytes > audio_devs[dev]->max_fragment)
			bytes = audio_devs[dev]->max_fragment;

#ifdef OS_DMA_MINBITS
	if (bytes < OS_DMA_MINBITS)
		bytes = OS_DMA_MINBITS;
#endif

	dmap->fragment_size = (1 << bytes);
	dmap->max_fragments = count;

	if (dmap->fragment_size > dmap->buffsize)
		dmap->fragment_size = dmap->buffsize;

	if (dmap->fragment_size == dmap->buffsize &&
	    audio_devs[dev]->flags & DMA_AUTOMODE)
		dmap->fragment_size /= 2;	/* Needs at least 2 buffers */

	dmap->subdivision = 1;	/* Disable SNDCTL_DSP_SUBDIVIDE */
	return bytes | ((count - 1) << 16);
}

static int dma_ioctl(int dev, unsigned int cmd, void __user *arg)
{
	struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out;
	struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in;
	struct dma_buffparms *dmap;
	audio_buf_info info;
	count_info cinfo;
	int fact, ret, changed, bits, count, err;
	unsigned long flags;

	switch (cmd) 
	{
		case SNDCTL_DSP_SUBDIVIDE:
			ret = 0;
			if (get_user(fact, (int __user *)arg))
				return -EFAULT;
			if (audio_devs[dev]->open_mode & OPEN_WRITE)
				ret = dma_subdivide(dev, dmap_out, fact);
			if (ret < 0)
				return ret;
			if (audio_devs[dev]->open_mode != OPEN_WRITE ||
				(audio_devs[dev]->flags & DMA_DUPLEX &&
					audio_devs[dev]->open_mode & OPEN_READ))
				ret = dma_subdivide(dev, dmap_in, fact);
			if (ret < 0)
				return ret;
			break;

		case SNDCTL_DSP_GETISPACE:
		case SNDCTL_DSP_GETOSPACE:
			dmap = dmap_out;
			if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
				return -EINVAL;
			if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
				return -EINVAL;
			if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
				dmap = dmap_in;
			if (dmap->mapping_flags & DMA_MAP_MAPPED)
				return -EINVAL;
			if (!(dmap->flags & DMA_ALLOC_DONE))
				reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
			info.fragstotal = dmap->nbufs;
			if (cmd == SNDCTL_DSP_GETISPACE)
				info.fragments = dmap->qlen;
			else 
			{
				if (!DMAbuf_space_in_queue(dev))
					info.fragments = 0;
				else
				{
					info.fragments = DMAbuf_space_in_queue(dev);
					if (audio_devs[dev]->d->local_qlen) 
					{
						int tmp = audio_devs[dev]->d->local_qlen(dev);
						if (tmp && info.fragments)
							tmp--;	/*
								 * This buffer has been counted twice
								 */
						info.fragments -= tmp;
					}
				}
			}
			if (info.fragments < 0)
				info.fragments = 0;
			else if (info.fragments > dmap->nbufs)
				info.fragments = dmap->nbufs;

			info.fragsize = dmap->fragment_size;
			info.bytes = info.fragments * dmap->fragment_size;

			if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
				info.bytes -= dmap->counts[dmap->qhead];
			else 
			{
				info.fragments = info.bytes / dmap->fragment_size;
				info.bytes -= dmap->user_counter % dmap->fragment_size;
			}
			if (copy_to_user(arg, &info, sizeof(info)))
				return -EFAULT;
			return 0;

		case SNDCTL_DSP_SETTRIGGER:
			if (get_user(bits, (int __user *)arg))
				return -EFAULT;
			bits &= audio_devs[dev]->open_mode;
			if (audio_devs[dev]->d->trigger == NULL)
				return -EINVAL;
			if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
				(bits & PCM_ENABLE_OUTPUT))
				return -EINVAL;

			if (bits & PCM_ENABLE_INPUT)
			{
				spin_lock_irqsave(&dmap_in->lock,flags);
				changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_INPUT;
				if (changed && audio_devs[dev]->go) 
				{
					reorganize_buffers(dev, dmap_in, 1);
					if ((err = audio_devs[dev]->d->prepare_for_input(dev,
						     dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
						spin_unlock_irqrestore(&dmap_in->lock,flags);
						return err;
					}
					dmap_in->dma_mode = DMODE_INPUT;
					audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT;
					DMAbuf_activate_recording(dev, dmap_in);
				} else
					audio_devs[dev]->enable_bits &= ~PCM_ENABLE_INPUT;
				spin_unlock_irqrestore(&dmap_in->lock,flags);
			}
			if (bits & PCM_ENABLE_OUTPUT)
			{
				spin_lock_irqsave(&dmap_out->lock,flags);
				changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_OUTPUT;
				if (changed &&
				    (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
				    audio_devs[dev]->go) 
				{
					if (!(dmap_out->flags & DMA_ALLOC_DONE))
						reorganize_buffers(dev, dmap_out, 0);
					dmap_out->dma_mode = DMODE_OUTPUT;
					audio_devs[dev]->enable_bits |= PCM_ENABLE_OUTPUT;
					dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
					DMAbuf_launch_output(dev, dmap_out);
				} else
					audio_devs[dev]->enable_bits &= ~PCM_ENABLE_OUTPUT;
				spin_unlock_irqrestore(&dmap_out->lock,flags);
			}
#if 0
			if (changed && audio_devs[dev]->d->trigger)
				audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
#endif				
			/* Falls through... */

		case SNDCTL_DSP_GETTRIGGER:
			ret = audio_devs[dev]->enable_bits;
			break;

		case SNDCTL_DSP_SETSYNCRO:
			if (!audio_devs[dev]->d->trigger)
				return -EINVAL;
			audio_devs[dev]->d->trigger(dev, 0);
			audio_devs[dev]->go = 0;
			return 0;

		case SNDCTL_DSP_GETIPTR:
			if (!(audio_devs[dev]->open_mode & OPEN_READ))
				return -EINVAL;
			spin_lock_irqsave(&dmap_in->lock,flags);
			cinfo.bytes = dmap_in->byte_counter;
			cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
			if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
				cinfo.bytes += dmap_in->bytes_in_use;	/* Pointer wrap not handled yet */
			cinfo.blocks = dmap_in->qlen;
			cinfo.bytes += cinfo.ptr;
			if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
				dmap_in->qlen = 0;	/* Reset interrupt counter */
			spin_unlock_irqrestore(&dmap_in->lock,flags);
			if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
				return -EFAULT;
			return 0;

		case SNDCTL_DSP_GETOPTR:
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return -EINVAL;

			spin_lock_irqsave(&dmap_out->lock,flags);
			cinfo.bytes = dmap_out->byte_counter;
			cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
			if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
				cinfo.bytes += dmap_out->bytes_in_use;	/* Pointer wrap not handled yet */
			cinfo.blocks = dmap_out->qlen;
			cinfo.bytes += cinfo.ptr;
			if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
				dmap_out->qlen = 0;	/* Reset interrupt counter */
			spin_unlock_irqrestore(&dmap_out->lock,flags);
			if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
				return -EFAULT;
			return 0;

		case SNDCTL_DSP_GETODELAY:
			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
				return -EINVAL;
			if (!(dmap_out->flags & DMA_ALLOC_DONE))
			{
				ret=0;
				break;
			}
			spin_lock_irqsave(&dmap_out->lock,flags);
			/* Compute number of bytes that have been played */
			count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
			if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
				count += dmap_out->bytes_in_use;	/* Pointer wrap not handled yet */
			count += dmap_out->byte_counter;
			/* Subtract current count from the number of bytes written by app */
			count = dmap_out->user_counter - count;
			if (count < 0)
				count = 0;
			spin_unlock_irqrestore(&dmap_out->lock,flags);
			ret = count;
			break;

		case SNDCTL_DSP_POST:
			if (audio_devs[dev]->dmap_out->qlen > 0)
				if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
					DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
			return 0;

		case SNDCTL_DSP_GETBLKSIZE:
			dmap = dmap_out;
			if (audio_devs[dev]->open_mode & OPEN_WRITE)
				reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
			if (audio_devs[dev]->open_mode == OPEN_READ ||
			    (audio_devs[dev]->flags & DMA_DUPLEX &&
			     audio_devs[dev]->open_mode & OPEN_READ))
				reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
			if (audio_devs[dev]->open_mode == OPEN_READ)
				dmap = dmap_in;
			ret = dmap->fragment_size;
			break;

		case SNDCTL_DSP_SETFRAGMENT:
			ret = 0;
			if (get_user(fact, (int __user *)arg))
				return -EFAULT;
			if (audio_devs[dev]->open_mode & OPEN_WRITE)
				ret = dma_set_fragment(dev, dmap_out, fact);
			if (ret < 0)
				return ret;
			if (audio_devs[dev]->open_mode == OPEN_READ ||
			    (audio_devs[dev]->flags & DMA_DUPLEX &&
			     audio_devs[dev]->open_mode & OPEN_READ))
				ret = dma_set_fragment(dev, dmap_in, fact);
			if (ret < 0)
				return ret;
			if (!arg) /* don't know what this is good for, but preserve old semantics */
				return 0;
			break;

		default:
			if (!audio_devs[dev]->d->ioctl)
				return -EINVAL;
			return audio_devs[dev]->d->ioctl(dev, cmd, arg);
	}
	return put_user(ret, (int __user *)arg);
}
