/*
 * 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);
}
