1/*
2 * sound/audio.c
3 *
4 * Device file manager for /dev/audio
5 */
6
7/*
8 * Copyright (C) by Hannu Savolainen 1993-1997
9 *
10 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
11 * Version 2 (June 1991). See the "COPYING" file distributed with this software
12 * for more info.
13 */
14/*
15 * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
16 * Thomas Sailer   : moved several static variables into struct audio_operations
17 *                   (which is grossly misnamed btw.) because they have the same
18 *                   lifetime as the rest in there and dynamic allocation saves
19 *                   12k or so
20 * Thomas Sailer   : use more logical O_NONBLOCK semantics
21 * Daniel Rodriksson: reworked the use of the device specific copy_user
22 *                    still generic
23 * Horst von Brand:  Add missing #include <linux/string.h>
24 * Chris Rankin    : Update the module-usage counter for the coprocessor,
25 *                   and decrement the counters again if we cannot open
26 *                   the audio device.
27 */
28
29#include <linux/stddef.h>
30#include <linux/string.h>
31#include <linux/kmod.h>
32
33#include "sound_config.h"
34#include "ulaw.h"
35#include "coproc.h"
36
37#define NEUTRAL8	0x80
38#define NEUTRAL16	0x00
39
40
41int             dma_ioctl(int dev, unsigned int cmd, caddr_t arg);
42
43static int set_format(int dev, int fmt)
44{
45	if (fmt != AFMT_QUERY)
46	{
47		audio_devs[dev]->local_conversion = 0;
48
49		if (!(audio_devs[dev]->format_mask & fmt))	/* Not supported */
50		{
51			if (fmt == AFMT_MU_LAW)
52			{
53				fmt = AFMT_U8;
54				audio_devs[dev]->local_conversion = CNV_MU_LAW;
55			}
56			else
57				fmt = AFMT_U8;	/* This is always supported */
58		}
59		audio_devs[dev]->audio_format = audio_devs[dev]->d->set_bits(dev, fmt);
60		audio_devs[dev]->local_format = fmt;
61	}
62	else
63		return audio_devs[dev]->local_format;
64
65	if (audio_devs[dev]->local_conversion)
66		return audio_devs[dev]->local_conversion;
67	else
68		return audio_devs[dev]->local_format;
69}
70
71int audio_open(int dev, struct file *file)
72{
73	int ret;
74	int bits;
75	int dev_type = dev & 0x0f;
76	int mode = translate_mode(file);
77	const struct audio_driver *driver;
78	const struct coproc_operations *coprocessor;
79
80	dev = dev >> 4;
81
82	if (dev_type == SND_DEV_DSP16)
83		bits = 16;
84	else
85		bits = 8;
86
87	if (dev < 0 || dev >= num_audiodevs)
88		return -ENXIO;
89
90	driver = audio_devs[dev]->d;
91	if (driver->owner)
92		__MOD_INC_USE_COUNT(driver->owner);
93
94	if ((ret = DMAbuf_open(dev, mode)) < 0)
95		goto error_1;
96
97	if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
98		if (coprocessor->owner)
99			__MOD_INC_USE_COUNT(coprocessor->owner);
100
101		if ((ret = coprocessor->open(coprocessor->devc, COPR_PCM)) < 0) {
102			printk(KERN_WARNING "Sound: Can't access coprocessor device\n");
103			goto error_2;
104		}
105	}
106
107	audio_devs[dev]->local_conversion = 0;
108
109	if (dev_type == SND_DEV_AUDIO)
110		set_format(dev, AFMT_MU_LAW);
111	else
112		set_format(dev, bits);
113
114	audio_devs[dev]->audio_mode = AM_NONE;
115
116	return 0;
117
118	/*
119	 * Clean-up stack: this is what needs (un)doing if
120	 * we can't open the audio device ...
121	 */
122	error_2:
123	if (coprocessor->owner)
124		__MOD_DEC_USE_COUNT(coprocessor->owner);
125	DMAbuf_release(dev, mode);
126
127	error_1:
128	if (driver->owner)
129		__MOD_DEC_USE_COUNT(driver->owner);
130
131	return ret;
132}
133
134static void sync_output(int dev)
135{
136	int             p, i;
137	int             l;
138	struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
139
140	if (dmap->fragment_size <= 0)
141		return;
142	dmap->flags |= DMA_POST;
143
144	/* Align the write pointer with fragment boundaries */
145
146	if ((l = dmap->user_counter % dmap->fragment_size) > 0)
147	{
148		int len;
149		unsigned long offs = dmap->user_counter % dmap->bytes_in_use;
150
151		len = dmap->fragment_size - l;
152		memset(dmap->raw_buf + offs, dmap->neutral_byte, len);
153		DMAbuf_move_wrpointer(dev, len);
154	}
155
156	/*
157	 * Clean all unused buffer fragments.
158	 */
159
160	p = dmap->qtail;
161	dmap->flags |= DMA_POST;
162
163	for (i = dmap->qlen + 1; i < dmap->nbufs; i++)
164	{
165		p = (p + 1) % dmap->nbufs;
166		if (((dmap->raw_buf + p * dmap->fragment_size) + dmap->fragment_size) >
167			(dmap->raw_buf + dmap->buffsize))
168				printk(KERN_ERR "audio: Buffer error 2\n");
169
170		memset(dmap->raw_buf + p * dmap->fragment_size,
171			dmap->neutral_byte,
172			dmap->fragment_size);
173	}
174
175	dmap->flags |= DMA_DIRTY;
176}
177
178void audio_release(int dev, struct file *file)
179{
180	const struct coproc_operations *coprocessor;
181	int mode = translate_mode(file);
182
183	dev = dev >> 4;
184
185	/*
186	 * We do this in DMAbuf_release(). Why are we doing it
187	 * here? Why don't we test the file mode before setting
188	 * both flags? DMAbuf_release() does.
189	 * ...pester...pester...pester...
190	 */
191	audio_devs[dev]->dmap_out->closing = 1;
192	audio_devs[dev]->dmap_in->closing = 1;
193
194	/*
195	 * We need to make sure we allocated the dmap_out buffer
196	 * before we go mucking around with it in sync_output().
197	 */
198	if (mode & OPEN_WRITE)
199		sync_output(dev);
200
201	if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
202		coprocessor->close(coprocessor->devc, COPR_PCM);
203
204		if (coprocessor->owner)
205			__MOD_DEC_USE_COUNT(coprocessor->owner);
206	}
207	DMAbuf_release(dev, mode);
208
209	if (audio_devs[dev]->d->owner)
210		__MOD_DEC_USE_COUNT (audio_devs[dev]->d->owner);
211}
212
213static void translate_bytes(const unsigned char *table, unsigned char *buff, int n)
214{
215	unsigned long   i;
216
217	if (n <= 0)
218		return;
219
220	for (i = 0; i < n; ++i)
221		buff[i] = table[buff[i]];
222}
223
224int audio_write(int dev, struct file *file, const char *buf, int count)
225{
226	int c, p, l, buf_size, used, returned;
227	int err;
228	char *dma_buf;
229
230	dev = dev >> 4;
231
232	p = 0;
233	c = count;
234
235	if(count < 0)
236		return -EINVAL;
237
238	if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
239		return -EPERM;
240
241	if (audio_devs[dev]->flags & DMA_DUPLEX)
242		audio_devs[dev]->audio_mode |= AM_WRITE;
243	else
244		audio_devs[dev]->audio_mode = AM_WRITE;
245
246	if (!count)		/* Flush output */
247	{
248		  sync_output(dev);
249		  return 0;
250	}
251
252	while (c)
253	{
254		if ((err = DMAbuf_getwrbuffer(dev, &dma_buf, &buf_size, !!(file->f_flags & O_NONBLOCK))) < 0)
255		{
256			    /* Handle nonblocking mode */
257			if ((file->f_flags & O_NONBLOCK) && err == -EAGAIN)
258				return p? p : -EAGAIN;	/* No more space. Return # of accepted bytes */
259			return err;
260		}
261		l = c;
262
263		if (l > buf_size)
264			l = buf_size;
265
266		returned = l;
267		used = l;
268		if (!audio_devs[dev]->d->copy_user)
269		{
270			if ((dma_buf + l) >
271				(audio_devs[dev]->dmap_out->raw_buf + audio_devs[dev]->dmap_out->buffsize))
272			{
273				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);
274				return -EDOM;
275			}
276			if (dma_buf < audio_devs[dev]->dmap_out->raw_buf)
277			{
278				printk(KERN_ERR "audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf, (long) audio_devs[dev]->dmap_out->raw_buf);
279				return -EDOM;
280			}
281			if(copy_from_user(dma_buf, &(buf)[p], l))
282				return -EFAULT;
283		}
284		else audio_devs[dev]->d->copy_user (dev,
285						dma_buf, 0,
286						buf, p,
287						c, buf_size,
288						&used, &returned,
289						l);
290		l = returned;
291
292		if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
293		{
294			/*
295			 * This just allows interrupts while the conversion is running
296			 */
297			sti();
298			translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
299		}
300		c -= used;
301		p += used;
302		DMAbuf_move_wrpointer(dev, l);
303
304	}
305
306	return count;
307}
308
309int audio_read(int dev, struct file *file, char *buf, int count)
310{
311	int             c, p, l;
312	char           *dmabuf;
313	int             buf_no;
314
315	dev = dev >> 4;
316	p = 0;
317	c = count;
318
319	if (!(audio_devs[dev]->open_mode & OPEN_READ))
320		return -EPERM;
321
322	if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
323		sync_output(dev);
324
325	if (audio_devs[dev]->flags & DMA_DUPLEX)
326		audio_devs[dev]->audio_mode |= AM_READ;
327	else
328		audio_devs[dev]->audio_mode = AM_READ;
329
330	while(c)
331	{
332		if ((buf_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l, !!(file->f_flags & O_NONBLOCK))) < 0)
333		{
334			/*
335			 *	Nonblocking mode handling. Return current # of bytes
336			 */
337
338			if (p > 0) 		/* Avoid throwing away data */
339				return p;	/* Return it instead */
340
341			if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN)
342				return -EAGAIN;
343
344			return buf_no;
345		}
346		if (l > c)
347			l = c;
348
349		/*
350		 * Insert any local processing here.
351		 */
352
353		if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
354		{
355			/*
356			 * This just allows interrupts while the conversion is running
357			 */
358			sti();
359
360			translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l);
361		}
362
363		{
364			char           *fixit = dmabuf;
365
366			if(copy_to_user(&(buf)[p], fixit, l))
367				return -EFAULT;
368		};
369
370		DMAbuf_rmchars(dev, buf_no, l);
371
372		p += l;
373		c -= l;
374	}
375
376	return count - c;
377}
378
379int audio_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
380{
381	int val, count;
382	unsigned long flags;
383	struct dma_buffparms *dmap;
384
385	dev = dev >> 4;
386
387	if (_IOC_TYPE(cmd) == 'C')	{
388		if (audio_devs[dev]->coproc)	/* Coprocessor ioctl */
389			return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
390		/* else
391		        printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
392		return -ENXIO;
393	}
394	else switch (cmd)
395	{
396		case SNDCTL_DSP_SYNC:
397			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
398				return 0;
399			if (audio_devs[dev]->dmap_out->fragment_size == 0)
400				return 0;
401			sync_output(dev);
402			DMAbuf_sync(dev);
403			DMAbuf_reset(dev);
404			return 0;
405
406		case SNDCTL_DSP_POST:
407			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
408				return 0;
409			if (audio_devs[dev]->dmap_out->fragment_size == 0)
410				return 0;
411			audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
412			sync_output(dev);
413			dma_ioctl(dev, SNDCTL_DSP_POST, (caddr_t) 0);
414			return 0;
415
416		case SNDCTL_DSP_RESET:
417			audio_devs[dev]->audio_mode = AM_NONE;
418			DMAbuf_reset(dev);
419			return 0;
420
421		case SNDCTL_DSP_GETFMTS:
422			val = audio_devs[dev]->format_mask | AFMT_MU_LAW;
423			break;
424
425		case SNDCTL_DSP_SETFMT:
426			if (get_user(val, (int *)arg))
427				return -EFAULT;
428			val = set_format(dev, val);
429			break;
430
431		case SNDCTL_DSP_GETISPACE:
432			if (!(audio_devs[dev]->open_mode & OPEN_READ))
433				return 0;
434  			if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
435  				return -EBUSY;
436			return dma_ioctl(dev, cmd, arg);
437
438		case SNDCTL_DSP_GETOSPACE:
439			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
440				return -EPERM;
441  			if ((audio_devs[dev]->audio_mode & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
442  				return -EBUSY;
443			return dma_ioctl(dev, cmd, arg);
444
445		case SNDCTL_DSP_NONBLOCK:
446			file->f_flags |= O_NONBLOCK;
447			return 0;
448
449		case SNDCTL_DSP_GETCAPS:
450				val = 1 | DSP_CAP_MMAP;	/* Revision level of this ioctl() */
451				if (audio_devs[dev]->flags & DMA_DUPLEX &&
452					audio_devs[dev]->open_mode == OPEN_READWRITE)
453					val |= DSP_CAP_DUPLEX;
454				if (audio_devs[dev]->coproc)
455					val |= DSP_CAP_COPROC;
456				if (audio_devs[dev]->d->local_qlen)	/* Device has hidden buffers */
457					val |= DSP_CAP_BATCH;
458				if (audio_devs[dev]->d->trigger)	/* Supports SETTRIGGER */
459					val |= DSP_CAP_TRIGGER;
460				break;
461
462		case SOUND_PCM_WRITE_RATE:
463			if (get_user(val, (int *)arg))
464				return -EFAULT;
465			val = audio_devs[dev]->d->set_speed(dev, val);
466			break;
467
468		case SOUND_PCM_READ_RATE:
469			val = audio_devs[dev]->d->set_speed(dev, 0);
470			break;
471
472		case SNDCTL_DSP_STEREO:
473			if (get_user(val, (int *)arg))
474				return -EFAULT;
475			if (val > 1 || val < 0)
476				return -EINVAL;
477			val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
478			break;
479
480		case SOUND_PCM_WRITE_CHANNELS:
481			if (get_user(val, (int *)arg))
482				return -EFAULT;
483			val = audio_devs[dev]->d->set_channels(dev, val);
484			break;
485
486		case SOUND_PCM_READ_CHANNELS:
487			val = audio_devs[dev]->d->set_channels(dev, 0);
488			break;
489
490		case SOUND_PCM_READ_BITS:
491			val = audio_devs[dev]->d->set_bits(dev, 0);
492			break;
493
494		case SNDCTL_DSP_SETDUPLEX:
495			if (audio_devs[dev]->open_mode != OPEN_READWRITE)
496				return -EPERM;
497			return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;
498
499		case SNDCTL_DSP_PROFILE:
500			if (get_user(val, (int *)arg))
501				return -EFAULT;
502			if (audio_devs[dev]->open_mode & OPEN_WRITE)
503				audio_devs[dev]->dmap_out->applic_profile = val;
504			if (audio_devs[dev]->open_mode & OPEN_READ)
505				audio_devs[dev]->dmap_in->applic_profile = val;
506			return 0;
507
508		case SNDCTL_DSP_GETODELAY:
509			dmap = audio_devs[dev]->dmap_out;
510			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
511				return -EINVAL;
512			if (!(dmap->flags & DMA_ALLOC_DONE))
513			{
514				val=0;
515				break;
516			}
517
518			save_flags (flags);
519			cli();
520			/* Compute number of bytes that have been played */
521			count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
522			if (count < dmap->fragment_size && dmap->qhead != 0)
523				count += dmap->bytes_in_use;	/* Pointer wrap not handled yet */
524			count += dmap->byte_counter;
525
526			/* Substract current count from the number of bytes written by app */
527			count = dmap->user_counter - count;
528			if (count < 0)
529				count = 0;
530			restore_flags (flags);
531			val = count;
532			break;
533
534		default:
535			return dma_ioctl(dev, cmd, arg);
536	}
537	return put_user(val, (int *)arg);
538}
539
540void audio_init_devices(void)
541{
542	/*
543	 * NOTE! This routine could be called several times during boot.
544	 */
545}
546
547void reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
548{
549	/*
550	 * This routine breaks the physical device buffers to logical ones.
551	 */
552
553	struct audio_operations *dsp_dev = audio_devs[dev];
554
555	unsigned i, n;
556	unsigned sr, nc, sz, bsz;
557
558	sr = dsp_dev->d->set_speed(dev, 0);
559	nc = dsp_dev->d->set_channels(dev, 0);
560	sz = dsp_dev->d->set_bits(dev, 0);
561
562	if (sz == 8)
563		dmap->neutral_byte = NEUTRAL8;
564	else
565		dmap->neutral_byte = NEUTRAL16;
566
567	if (sr < 1 || nc < 1 || sz < 1)
568	{
569/*		printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/
570		sr = DSP_DEFAULT_SPEED;
571		nc = 1;
572		sz = 8;
573	}
574
575	sz = sr * nc * sz;
576
577	sz /= 8;		/* #bits -> #bytes */
578	dmap->data_rate = sz;
579
580	if (!dmap->needs_reorg)
581		return;
582	dmap->needs_reorg = 0;
583
584	if (dmap->fragment_size == 0)
585	{
586		/* Compute the fragment size using the default algorithm */
587
588		/*
589		 * Compute a buffer size for time not exceeding 1 second.
590		 * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
591		 * of sound (using the current speed, sample size and #channels).
592		 */
593
594		bsz = dmap->buffsize;
595		while (bsz > sz)
596			bsz /= 2;
597
598		if (bsz == dmap->buffsize)
599			bsz /= 2;	/* Needs at least 2 buffers */
600
601		/*
602		 *    Split the computed fragment to smaller parts. After 3.5a9
603		 *      the default subdivision is 4 which should give better
604		 *      results when recording.
605		 */
606
607		if (dmap->subdivision == 0)	/* Not already set */
608		{
609			dmap->subdivision = 4;	/* Init to the default value */
610
611			if ((bsz / dmap->subdivision) > 4096)
612				dmap->subdivision *= 2;
613			if ((bsz / dmap->subdivision) < 4096)
614				dmap->subdivision = 1;
615		}
616		bsz /= dmap->subdivision;
617
618		if (bsz < 16)
619			bsz = 16;	/* Just a sanity check */
620
621		dmap->fragment_size = bsz;
622	}
623	else
624	{
625		/*
626		 * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
627		 * the buffer size computation has already been done.
628		 */
629		if (dmap->fragment_size > (dmap->buffsize / 2))
630			dmap->fragment_size = (dmap->buffsize / 2);
631		bsz = dmap->fragment_size;
632	}
633
634	if (audio_devs[dev]->min_fragment)
635		if (bsz < (1 << audio_devs[dev]->min_fragment))
636			bsz = 1 << audio_devs[dev]->min_fragment;
637	if (audio_devs[dev]->max_fragment)
638		if (bsz > (1 << audio_devs[dev]->max_fragment))
639			bsz = 1 << audio_devs[dev]->max_fragment;
640	bsz &= ~0x07;		/* Force size which is multiple of 8 bytes */
641#ifdef OS_DMA_ALIGN_CHECK
642	OS_DMA_ALIGN_CHECK(bsz);
643#endif
644
645	n = dmap->buffsize / bsz;
646	if (n > MAX_SUB_BUFFERS)
647		n = MAX_SUB_BUFFERS;
648	if (n > dmap->max_fragments)
649		n = dmap->max_fragments;
650
651	if (n < 2)
652	{
653		n = 2;
654		bsz /= 2;
655	}
656	dmap->nbufs = n;
657	dmap->bytes_in_use = n * bsz;
658	dmap->fragment_size = bsz;
659	dmap->max_byte_counter = (dmap->data_rate * 60 * 60) +
660			dmap->bytes_in_use;	/* Approximately one hour */
661
662	if (dmap->raw_buf)
663	{
664		memset(dmap->raw_buf, dmap->neutral_byte, dmap->bytes_in_use);
665	}
666
667	for (i = 0; i < dmap->nbufs; i++)
668	{
669		dmap->counts[i] = 0;
670	}
671
672	dmap->flags |= DMA_ALLOC_DONE | DMA_EMPTY;
673}
674
675static int dma_subdivide(int dev, struct dma_buffparms *dmap, int fact)
676{
677	if (fact == 0)
678	{
679		fact = dmap->subdivision;
680		if (fact == 0)
681			fact = 1;
682		return fact;
683	}
684	if (dmap->subdivision != 0 || dmap->fragment_size)	/* Too late to change */
685		return -EINVAL;
686
687	if (fact > MAX_REALTIME_FACTOR)
688		return -EINVAL;
689
690	if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact != 16)
691		return -EINVAL;
692
693	dmap->subdivision = fact;
694	return fact;
695}
696
697static int dma_set_fragment(int dev, struct dma_buffparms *dmap, int fact)
698{
699	int bytes, count;
700
701	if (fact == 0)
702		return -EIO;
703
704	if (dmap->subdivision != 0 ||
705	    dmap->fragment_size)	/* Too late to change */
706		return -EINVAL;
707
708	bytes = fact & 0xffff;
709	count = (fact >> 16) & 0x7fff;
710
711	if (count == 0)
712		count = MAX_SUB_BUFFERS;
713	else if (count < MAX_SUB_BUFFERS)
714		count++;
715
716	if (bytes < 4 || bytes > 17)	/* <16 || > 512k */
717		return -EINVAL;
718
719	if (count < 2)
720		return -EINVAL;
721
722	if (audio_devs[dev]->min_fragment > 0)
723		if (bytes < audio_devs[dev]->min_fragment)
724			bytes = audio_devs[dev]->min_fragment;
725
726	if (audio_devs[dev]->max_fragment > 0)
727		if (bytes > audio_devs[dev]->max_fragment)
728			bytes = audio_devs[dev]->max_fragment;
729
730#ifdef OS_DMA_MINBITS
731	if (bytes < OS_DMA_MINBITS)
732		bytes = OS_DMA_MINBITS;
733#endif
734
735	dmap->fragment_size = (1 << bytes);
736	dmap->max_fragments = count;
737
738	if (dmap->fragment_size > dmap->buffsize)
739		dmap->fragment_size = dmap->buffsize;
740
741	if (dmap->fragment_size == dmap->buffsize &&
742	    audio_devs[dev]->flags & DMA_AUTOMODE)
743		dmap->fragment_size /= 2;	/* Needs at least 2 buffers */
744
745	dmap->subdivision = 1;	/* Disable SNDCTL_DSP_SUBDIVIDE */
746	return bytes | ((count - 1) << 16);
747}
748
749int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
750{
751	struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out;
752	struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in;
753	struct dma_buffparms *dmap;
754	audio_buf_info info;
755	count_info cinfo;
756	int fact, ret, changed, bits, count, err;
757	unsigned long flags;
758
759	switch (cmd)
760	{
761		case SNDCTL_DSP_SUBDIVIDE:
762			ret = 0;
763			if (get_user(fact, (int *)arg))
764				return -EFAULT;
765			if (audio_devs[dev]->open_mode & OPEN_WRITE)
766				ret = dma_subdivide(dev, dmap_out, fact);
767			if (ret < 0)
768				return ret;
769			if (audio_devs[dev]->open_mode != OPEN_WRITE ||
770				(audio_devs[dev]->flags & DMA_DUPLEX &&
771					audio_devs[dev]->open_mode & OPEN_READ))
772				ret = dma_subdivide(dev, dmap_in, fact);
773			if (ret < 0)
774				return ret;
775			break;
776
777		case SNDCTL_DSP_GETISPACE:
778		case SNDCTL_DSP_GETOSPACE:
779			dmap = dmap_out;
780			if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
781				return -EINVAL;
782			if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
783				return -EINVAL;
784			if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
785				dmap = dmap_in;
786			if (dmap->mapping_flags & DMA_MAP_MAPPED)
787				return -EINVAL;
788			if (!(dmap->flags & DMA_ALLOC_DONE))
789				reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
790			info.fragstotal = dmap->nbufs;
791			if (cmd == SNDCTL_DSP_GETISPACE)
792				info.fragments = dmap->qlen;
793			else
794			{
795				if (!DMAbuf_space_in_queue(dev))
796					info.fragments = 0;
797				else
798				{
799					info.fragments = DMAbuf_space_in_queue(dev);
800					if (audio_devs[dev]->d->local_qlen)
801					{
802						int tmp = audio_devs[dev]->d->local_qlen(dev);
803						if (tmp && info.fragments)
804							tmp--;	/*
805								 * This buffer has been counted twice
806								 */
807						info.fragments -= tmp;
808					}
809				}
810			}
811			if (info.fragments < 0)
812				info.fragments = 0;
813			else if (info.fragments > dmap->nbufs)
814				info.fragments = dmap->nbufs;
815
816			info.fragsize = dmap->fragment_size;
817			info.bytes = info.fragments * dmap->fragment_size;
818
819			if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
820				info.bytes -= dmap->counts[dmap->qhead];
821			else
822			{
823				info.fragments = info.bytes / dmap->fragment_size;
824				info.bytes -= dmap->user_counter % dmap->fragment_size;
825			}
826			if (copy_to_user(arg, &info, sizeof(info)))
827				return -EFAULT;
828			return 0;
829
830		case SNDCTL_DSP_SETTRIGGER:
831			if (get_user(bits, (int *)arg))
832				return -EFAULT;
833			bits &= audio_devs[dev]->open_mode;
834			if (audio_devs[dev]->d->trigger == NULL)
835				return -EINVAL;
836			if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
837				(bits & PCM_ENABLE_OUTPUT))
838				return -EINVAL;
839			save_flags(flags);
840			cli();
841			changed = audio_devs[dev]->enable_bits ^ bits;
842			if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go)
843			{
844				reorganize_buffers(dev, dmap_in, 1);
845				if ((err = audio_devs[dev]->d->prepare_for_input(dev,
846					     dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
847					restore_flags(flags);
848					return -err;
849				}
850				dmap_in->dma_mode = DMODE_INPUT;
851				audio_devs[dev]->enable_bits = bits;
852				DMAbuf_activate_recording(dev, dmap_in);
853			}
854			if ((changed & bits) & PCM_ENABLE_OUTPUT &&
855			    (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
856			    audio_devs[dev]->go)
857			{
858				if (!(dmap_out->flags & DMA_ALLOC_DONE))
859					reorganize_buffers(dev, dmap_out, 0);
860				dmap_out->dma_mode = DMODE_OUTPUT;
861				audio_devs[dev]->enable_bits = bits;
862				dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
863				DMAbuf_launch_output(dev, dmap_out);
864			}
865			audio_devs[dev]->enable_bits = bits;
866			restore_flags(flags);
867			/* Falls through... */
868
869		case SNDCTL_DSP_GETTRIGGER:
870			ret = audio_devs[dev]->enable_bits;
871			break;
872
873		case SNDCTL_DSP_SETSYNCRO:
874			if (!audio_devs[dev]->d->trigger)
875				return -EINVAL;
876			audio_devs[dev]->d->trigger(dev, 0);
877			audio_devs[dev]->go = 0;
878			return 0;
879
880		case SNDCTL_DSP_GETIPTR:
881			if (!(audio_devs[dev]->open_mode & OPEN_READ))
882				return -EINVAL;
883			save_flags(flags);
884			cli();
885			cinfo.bytes = dmap_in->byte_counter;
886			cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
887			if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
888				cinfo.bytes += dmap_in->bytes_in_use;	/* Pointer wrap not handled yet */
889			cinfo.blocks = dmap_in->qlen;
890			cinfo.bytes += cinfo.ptr;
891			if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
892				dmap_in->qlen = 0;	/* Reset interrupt counter */
893			restore_flags(flags);
894			if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
895				return -EFAULT;
896			return 0;
897
898		case SNDCTL_DSP_GETOPTR:
899			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
900				return -EINVAL;
901
902			save_flags(flags);
903			cli();
904			cinfo.bytes = dmap_out->byte_counter;
905			cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
906			if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
907				cinfo.bytes += dmap_out->bytes_in_use;	/* Pointer wrap not handled yet */
908			cinfo.blocks = dmap_out->qlen;
909			cinfo.bytes += cinfo.ptr;
910			if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
911				dmap_out->qlen = 0;	/* Reset interrupt counter */
912			restore_flags(flags);
913			if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
914				return -EFAULT;
915			return 0;
916
917		case SNDCTL_DSP_GETODELAY:
918			if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
919				return -EINVAL;
920			if (!(dmap_out->flags & DMA_ALLOC_DONE))
921			{
922				ret=0;
923				break;
924			}
925			save_flags(flags);
926			cli();
927			/* Compute number of bytes that have been played */
928			count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
929			if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
930				count += dmap_out->bytes_in_use;	/* Pointer wrap not handled yet */
931			count += dmap_out->byte_counter;
932			/* Substract current count from the number of bytes written by app */
933			count = dmap_out->user_counter - count;
934			if (count < 0)
935				count = 0;
936			restore_flags (flags);
937			ret = count;
938			break;
939
940		case SNDCTL_DSP_POST:
941			if (audio_devs[dev]->dmap_out->qlen > 0)
942				if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
943					DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
944			return 0;
945
946		case SNDCTL_DSP_GETBLKSIZE:
947			dmap = dmap_out;
948			if (audio_devs[dev]->open_mode & OPEN_WRITE)
949				reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
950			if (audio_devs[dev]->open_mode == OPEN_READ ||
951			    (audio_devs[dev]->flags & DMA_DUPLEX &&
952			     audio_devs[dev]->open_mode & OPEN_READ))
953				reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
954			if (audio_devs[dev]->open_mode == OPEN_READ)
955				dmap = dmap_in;
956			ret = dmap->fragment_size;
957			break;
958
959		case SNDCTL_DSP_SETFRAGMENT:
960			ret = 0;
961			if (get_user(fact, (int *)arg))
962				return -EFAULT;
963			if (audio_devs[dev]->open_mode & OPEN_WRITE)
964				ret = dma_set_fragment(dev, dmap_out, fact);
965			if (ret < 0)
966				return ret;
967			if (audio_devs[dev]->open_mode == OPEN_READ ||
968			    (audio_devs[dev]->flags & DMA_DUPLEX &&
969			     audio_devs[dev]->open_mode & OPEN_READ))
970				ret = dma_set_fragment(dev, dmap_in, fact);
971			if (ret < 0)
972				return ret;
973			if (!arg) /* don't know what this is good for, but preserve old semantics */
974				return 0;
975			break;
976
977		default:
978			if (!audio_devs[dev]->d->ioctl)
979				return -EINVAL;
980			return audio_devs[dev]->d->ioctl(dev, cmd, arg);
981	}
982	return put_user(ret, (int *)arg);
983}
984