1 /*
2  *  linux/drivers/sound/dmasound/dmasound_core.c
3  *
4  *
5  *  OSS/Free compatible Atari TT/Falcon and Amiga DMA sound driver for
6  *  Linux/m68k
7  *  Extended to support Power Macintosh for Linux/ppc by Paul Mackerras
8  *
9  *  (c) 1995 by Michael Schlueter & Michael Marte
10  *
11  *  Michael Schlueter (michael@duck.syd.de) did the basic structure of the VFS
12  *  interface and the u-law to signed byte conversion.
13  *
14  *  Michael Marte (marte@informatik.uni-muenchen.de) did the sound queue,
15  *  /dev/mixer, /dev/sndstat and complemented the VFS interface. He would like
16  *  to thank:
17  *    - Michael Schlueter for initial ideas and documentation on the MFP and
18  *	the DMA sound hardware.
19  *    - Therapy? for their CD 'Troublegum' which really made me rock.
20  *
21  *  /dev/sndstat is based on code by Hannu Savolainen, the author of the
22  *  VoxWare family of drivers.
23  *
24  *  This file is subject to the terms and conditions of the GNU General Public
25  *  License.  See the file COPYING in the main directory of this archive
26  *  for more details.
27  *
28  *  History:
29  *
30  *	1995/8/25	First release
31  *
32  *	1995/9/02	Roman Hodek:
33  *			  - Fixed atari_stram_alloc() call, the timer
34  *			    programming and several race conditions
35  *	1995/9/14	Roman Hodek:
36  *			  - After some discussion with Michael Schlueter,
37  *			    revised the interrupt disabling
38  *			  - Slightly speeded up U8->S8 translation by using
39  *			    long operations where possible
40  *			  - Added 4:3 interpolation for /dev/audio
41  *
42  *	1995/9/20	Torsten Scherer:
43  *			  - Fixed a bug in sq_write and changed /dev/audio
44  *			    converting to play at 12517Hz instead of 6258Hz.
45  *
46  *	1995/9/23	Torsten Scherer:
47  *			  - Changed sq_interrupt() and sq_play() to pre-program
48  *			    the DMA for another frame while there's still one
49  *			    running. This allows the IRQ response to be
50  *			    arbitrarily delayed and playing will still continue.
51  *
52  *	1995/10/14	Guenther Kelleter, Torsten Scherer:
53  *			  - Better support for Falcon audio (the Falcon doesn't
54  *			    raise an IRQ at the end of a frame, but at the
55  *			    beginning instead!). uses 'if (codec_dma)' in lots
56  *			    of places to simply switch between Falcon and TT
57  *			    code.
58  *
59  *	1995/11/06	Torsten Scherer:
60  *			  - Started introducing a hardware abstraction scheme
61  *			    (may perhaps also serve for Amigas?)
62  *			  - Can now play samples at almost all frequencies by
63  *			    means of a more generalized expand routine
64  *			  - Takes a good deal of care to cut data only at
65  *			    sample sizes
66  *			  - Buffer size is now a kernel runtime option
67  *			  - Implemented fsync() & several minor improvements
68  *			Guenther Kelleter:
69  *			  - Useful hints and bug fixes
70  *			  - Cross-checked it for Falcons
71  *
72  *	1996/3/9	Geert Uytterhoeven:
73  *			  - Support added for Amiga, A-law, 16-bit little
74  *			    endian.
75  *			  - Unification to drivers/sound/dmasound.c.
76  *
77  *	1996/4/6	Martin Mitchell:
78  *			  - Updated to 1.3 kernel.
79  *
80  *	1996/6/13       Topi Kanerva:
81  *			  - Fixed things that were broken (mainly the amiga
82  *			    14-bit routines)
83  *			  - /dev/sndstat shows now the real hardware frequency
84  *			  - The lowpass filter is disabled by default now
85  *
86  *	1996/9/25	Geert Uytterhoeven:
87  *			  - Modularization
88  *
89  *	1998/6/10	Andreas Schwab:
90  *			  - Converted to use sound_core
91  *
92  *	1999/12/28	Richard Zidlicky:
93  *			  - Added support for Q40
94  *
95  *	2000/2/27	Geert Uytterhoeven:
96  *			  - Clean up and split the code into 4 parts:
97  *			      o dmasound_core: machine-independent code
98  *			      o dmasound_atari: Atari TT and Falcon support
99  *			      o dmasound_awacs: Apple PowerMac support
100  *			      o dmasound_paula: Amiga support
101  *
102  *	2000/3/25	Geert Uytterhoeven:
103  *			  - Integration of dmasound_q40
104  *			  - Small clean ups
105  *
106  *	2001/01/26 [1.0] Iain Sandoe
107  *			  - make /dev/sndstat show revision & edition info.
108  *			  - since dmasound.mach.sq_setup() can fail on pmac
109  *			    its type has been changed to int and the returns
110  *			    are checked.
111  *		   [1.1]  - stop missing translations from being called.
112  *	2001/02/08 [1.2]  - remove unused translation tables & move machine-
113  *			    specific tables to low-level.
114  *			  - return correct info. for SNDCTL_DSP_GETFMTS.
115  *		   [1.3]  - implement SNDCTL_DSP_GETCAPS fully.
116  *		   [1.4]  - make /dev/sndstat text length usage deterministic.
117  *			  - make /dev/sndstat call to low-level
118  *			    dmasound.mach.state_info() pass max space to ll driver.
119  *			  - tidy startup banners and output info.
120  *		   [1.5]  - tidy up a little (removed some unused #defines in
121  *			    dmasound.h)
122  *			  - fix up HAS_RECORD conditionalisation.
123  *			  - add record code in places it is missing...
124  *			  - change buf-sizes to bytes to allow < 1kb for pmac
125  *			    if user param entry is < 256 the value is taken to
126  *			    be in kb > 256 is taken to be in bytes.
127  *			  - make default buff/frag params conditional on
128  *			    machine to allow smaller values for pmac.
129  *			  - made the ioctls, read & write comply with the OSS
130  *			    rules on setting params.
131  *			  - added parsing of _setup() params for record.
132  *	2001/04/04 [1.6]  - fix bug where sample rates higher than maximum were
133  *			    being reported as OK.
134  *			  - fix open() to return -EBUSY as per OSS doc. when
135  *			    audio is in use - this is independent of O_NOBLOCK.
136  *			  - fix bug where SNDCTL_DSP_POST was blocking.
137  */
138 
139  /* Record capability notes 30/01/2001:
140   * At present these observations apply only to pmac LL driver (the only one
141   * that can do record, at present).  However, if other LL drivers for machines
142   * with record are added they may apply.
143   *
144   * The fragment parameters for the record and play channels are separate.
145   * However, if the driver is opened O_RDWR there is no way (in the current OSS
146   * API) to specify their values independently for the record and playback
147   * channels.  Since the only common factor between the input & output is the
148   * sample rate (on pmac) it should be possible to open /dev/dspX O_WRONLY and
149   * /dev/dspY O_RDONLY.  The input & output channels could then have different
150   * characteristics (other than the first that sets sample rate claiming the
151   * right to set it for ever).  As it stands, the format, channels, number of
152   * bits & sample rate are assumed to be common.  In the future perhaps these
153   * should be the responsibility of the LL driver - and then if a card really
154   * does not share items between record & playback they can be specified
155   * separately.
156 */
157 
158 /* Thread-safeness of shared_resources notes: 31/01/2001
159  * If the user opens O_RDWR and then splits record & play between two threads
160  * both of which inherit the fd - and then starts changing things from both
161  * - we will have difficulty telling.
162  *
163  * It's bad application coding - but ...
164  * TODO: think about how to sort this out... without bogging everything down in
165  * semaphores.
166  *
167  * Similarly, the OSS spec says "all changes to parameters must be between
168  * open() and the first read() or write(). - and a bit later on (by
169  * implication) "between SNDCTL_DSP_RESET and the first read() or write() after
170  * it".  If the app is multi-threaded and this rule is broken between threads
171  * we will have trouble spotting it - and the fault will be rather obscure :-(
172  *
173  * We will try and put out at least a kmsg if we see it happen... but I think
174  * it will be quite hard to trap it with an -EXXX return... because we can't
175  * see the fault until after the damage is done.
176 */
177 
178 #include <linux/module.h>
179 #include <linux/slab.h>
180 #include <linux/sound.h>
181 #include <linux/init.h>
182 #include <linux/soundcard.h>
183 #include <linux/poll.h>
184 #include <linux/smp_lock.h>
185 
186 #include <asm/uaccess.h>
187 
188 #include "dmasound.h"
189 
190 #define DMASOUND_CORE_REVISION 1
191 #define DMASOUND_CORE_EDITION 6
192 
193     /*
194      *  Declarations
195      */
196 
197 int dmasound_catchRadius = 0;
198 MODULE_PARM(dmasound_catchRadius, "i");
199 
200 static unsigned int numWriteBufs = DEFAULT_N_BUFFERS;
201 MODULE_PARM(numWriteBufs, "i");
202 static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ;	/* in bytes */
203 MODULE_PARM(writeBufSize, "i");
204 
205 #ifdef HAS_RECORD
206 static unsigned int numReadBufs = DEFAULT_N_BUFFERS;
207 MODULE_PARM(numReadBufs, "i");
208 static unsigned int readBufSize = DEFAULT_BUFF_SIZE;	/* in bytes */
209 MODULE_PARM(readBufSize, "i");
210 #endif
211 
212 MODULE_LICENSE("GPL");
213 
214 #ifdef MODULE
215 static int sq_unit = -1;
216 static int mixer_unit = -1;
217 static int state_unit = -1;
218 static int irq_installed = 0;
219 #endif /* MODULE */
220 
221 /* control over who can modify resources shared between play/record */
222 static mode_t shared_resource_owner = 0 ;
223 static int shared_resources_initialised = 0 ;
224 
225     /*
226      *  Mid level stuff
227      */
228 
229 struct sound_settings dmasound;
230 
sound_silence(void)231 static inline void sound_silence(void)
232 {
233 	dmasound.mach.silence(); /* _MUST_ stop DMA */
234 }
235 
sound_set_format(int format)236 static inline int sound_set_format(int format)
237 {
238 	return dmasound.mach.setFormat(format);
239 }
240 
sound_set_speed(int speed)241 static int sound_set_speed(int speed)
242 {
243 	if (speed < 0)
244 		return dmasound.soft.speed;
245 
246 	/* trap out-of-range speed settings.
247 	   at present we allow (arbitrarily) low rates - using soft
248 	   up-conversion - but we can't allow > max because there is
249 	   no soft down-conversion.
250 	*/
251 	if (dmasound.mach.max_dsp_speed &&
252 	   (speed > dmasound.mach.max_dsp_speed))
253 		speed = dmasound.mach.max_dsp_speed ;
254 
255 	dmasound.soft.speed = speed;
256 
257 	if (dmasound.minDev == SND_DEV_DSP)
258 		dmasound.dsp.speed = dmasound.soft.speed;
259 
260 	return dmasound.soft.speed;
261 }
262 
sound_set_stereo(int stereo)263 static int sound_set_stereo(int stereo)
264 {
265 	if (stereo < 0)
266 		return dmasound.soft.stereo;
267 
268 	stereo = !!stereo;    /* should be 0 or 1 now */
269 
270 	dmasound.soft.stereo = stereo;
271 	if (dmasound.minDev == SND_DEV_DSP)
272 		dmasound.dsp.stereo = stereo;
273 
274 	return stereo;
275 }
276 
sound_copy_translate(TRANS * trans,const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)277 static ssize_t sound_copy_translate(TRANS *trans, const u_char *userPtr,
278 				    size_t userCount, u_char frame[],
279 				    ssize_t *frameUsed, ssize_t frameLeft)
280 {
281 	ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
282 
283 	switch (dmasound.soft.format) {
284 	    case AFMT_MU_LAW:
285 		ct_func = trans->ct_ulaw;
286 		break;
287 	    case AFMT_A_LAW:
288 		ct_func = trans->ct_alaw;
289 		break;
290 	    case AFMT_S8:
291 		ct_func = trans->ct_s8;
292 		break;
293 	    case AFMT_U8:
294 		ct_func = trans->ct_u8;
295 		break;
296 	    case AFMT_S16_BE:
297 		ct_func = trans->ct_s16be;
298 		break;
299 	    case AFMT_U16_BE:
300 		ct_func = trans->ct_u16be;
301 		break;
302 	    case AFMT_S16_LE:
303 		ct_func = trans->ct_s16le;
304 		break;
305 	    case AFMT_U16_LE:
306 		ct_func = trans->ct_u16le;
307 		break;
308 	    default:
309 		return 0;
310 	}
311 	/* if the user has requested a non-existent translation don't try
312 	   to call it but just return 0 bytes moved
313 	*/
314 	if (ct_func)
315 		return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
316 	return 0;
317 }
318 
319     /*
320      *  /dev/mixer abstraction
321      */
322 
323 static struct {
324     int busy;
325     int modify_counter;
326 } mixer;
327 
mixer_open(struct inode * inode,struct file * file)328 static int mixer_open(struct inode *inode, struct file *file)
329 {
330 	dmasound.mach.open();
331 	mixer.busy = 1;
332 	return 0;
333 }
334 
mixer_release(struct inode * inode,struct file * file)335 static int mixer_release(struct inode *inode, struct file *file)
336 {
337 	lock_kernel();
338 	mixer.busy = 0;
339 	dmasound.mach.release();
340 	unlock_kernel();
341 	return 0;
342 }
mixer_ioctl(struct inode * inode,struct file * file,u_int cmd,u_long arg)343 static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
344 		       u_long arg)
345 {
346 	if (_SIOC_DIR(cmd) & _SIOC_WRITE)
347 	    mixer.modify_counter++;
348 	switch (cmd) {
349 	    case OSS_GETVERSION:
350 		return IOCTL_OUT(arg, SOUND_VERSION);
351 	    case SOUND_MIXER_INFO:
352 		{
353 		    mixer_info info;
354 		    strncpy(info.id, dmasound.mach.name2, sizeof(info.id));
355 		    strncpy(info.name, dmasound.mach.name2, sizeof(info.name));
356 		    info.name[sizeof(info.name)-1] = 0;
357 		    info.modify_counter = mixer.modify_counter;
358 		    if (copy_to_user((int *)arg, &info, sizeof(info)))
359 			    return -EFAULT;
360 		    return 0;
361 		}
362 	}
363 	if (dmasound.mach.mixer_ioctl)
364 	    return dmasound.mach.mixer_ioctl(cmd, arg);
365 	return -EINVAL;
366 }
367 
368 static struct file_operations mixer_fops =
369 {
370 	owner:		THIS_MODULE,
371 	llseek:		no_llseek,
372 	ioctl:		mixer_ioctl,
373 	open:		mixer_open,
374 	release:	mixer_release,
375 };
376 
mixer_init(void)377 static void mixer_init(void)
378 {
379 #ifndef MODULE
380 	int mixer_unit;
381 #endif
382 	mixer_unit = register_sound_mixer(&mixer_fops, -1);
383 	if (mixer_unit < 0)
384 		return;
385 
386 	mixer.busy = 0;
387 	dmasound.treble = 0;
388 	dmasound.bass = 0;
389 	if (dmasound.mach.mixer_init)
390 	    dmasound.mach.mixer_init();
391 }
392 
393 
394     /*
395      *  Sound queue stuff, the heart of the driver
396      */
397 
398 struct sound_queue dmasound_write_sq;
399 static void sq_reset_output(void) ;
400 #ifdef HAS_RECORD
401 struct sound_queue dmasound_read_sq;
402 static void sq_reset_input(void) ;
403 #endif
404 
sq_allocate_buffers(struct sound_queue * sq,int num,int size)405 static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
406 {
407 	int i;
408 
409 	if (sq->buffers)
410 		return 0;
411 	sq->numBufs = num;
412 	sq->bufSize = size;
413 	sq->buffers = kmalloc (num * sizeof(char *), GFP_KERNEL);
414 	if (!sq->buffers)
415 		return -ENOMEM;
416 	for (i = 0; i < num; i++) {
417 		sq->buffers[i] = dmasound.mach.dma_alloc(size, GFP_KERNEL);
418 		if (!sq->buffers[i]) {
419 			while (i--)
420 				dmasound.mach.dma_free(sq->buffers[i], size);
421 			kfree(sq->buffers);
422 			sq->buffers = 0;
423 			return -ENOMEM;
424 		}
425 	}
426 	return 0;
427 }
428 
sq_release_buffers(struct sound_queue * sq)429 static void sq_release_buffers(struct sound_queue *sq)
430 {
431 	int i;
432 
433 	if (sq->buffers) {
434 		for (i = 0; i < sq->numBufs; i++)
435 			dmasound.mach.dma_free(sq->buffers[i], sq->bufSize);
436 		kfree(sq->buffers);
437 		sq->buffers = NULL;
438 	}
439 }
440 
441 
sq_setup(struct sound_queue * sq)442 static int sq_setup(struct sound_queue *sq)
443 {
444 	int (*setup_func)(void) = 0;
445 	int hard_frame ;
446 
447 	if (sq->locked) { /* are we already set? - and not changeable */
448 #ifdef DEBUG_DMASOUND
449 printk("dmasound_core: tried to sq_setup a locked queue\n") ;
450 #endif
451 		return -EINVAL ;
452 	}
453 	sq->locked = 1 ; /* don't think we have a race prob. here _check_ */
454 
455 	/* make sure that the parameters are set up
456 	   This should have been done already...
457 	*/
458 
459 	dmasound.mach.init();
460 
461 	/* OK.  If the user has set fragment parameters explicitly, then we
462 	   should leave them alone... as long as they are valid.
463 	   Invalid user fragment params can occur if we allow the whole buffer
464 	   to be used when the user requests the fragments sizes (with no soft
465 	   x-lation) and then the user subsequently sets a soft x-lation that
466 	   requires increased internal buffering.
467 
468 	   Othwerwise (if the user did not set them) OSS says that we should
469 	   select frag params on the basis of 0.5 s output & 0.1 s input
470 	   latency. (TODO.  For now we will copy in the defaults.)
471 	*/
472 
473 	if (sq->user_frags <= 0) {
474 		sq->max_count = sq->numBufs ;
475 		sq->max_active = sq->numBufs ;
476 		sq->block_size = sq->bufSize;
477 		/* set up the user info */
478 		sq->user_frags = sq->numBufs ;
479 		sq->user_frag_size = sq->bufSize ;
480 		sq->user_frag_size *=
481 			(dmasound.soft.size * (dmasound.soft.stereo+1) ) ;
482 		sq->user_frag_size /=
483 			(dmasound.hard.size * (dmasound.hard.stereo+1) ) ;
484 	} else {
485 		/* work out requested block size */
486 		sq->block_size = sq->user_frag_size ;
487 		sq->block_size *=
488 			(dmasound.hard.size * (dmasound.hard.stereo+1) ) ;
489 		sq->block_size /=
490 			(dmasound.soft.size * (dmasound.soft.stereo+1) ) ;
491 		/* the user wants to write frag-size chunks */
492 		sq->block_size *= dmasound.hard.speed ;
493 		sq->block_size /= dmasound.soft.speed ;
494 		/* this only works for size values which are powers of 2 */
495 		hard_frame =
496 			(dmasound.hard.size * (dmasound.hard.stereo+1))/8 ;
497 		sq->block_size +=  (hard_frame - 1) ;
498 		sq->block_size &= ~(hard_frame - 1) ; /* make sure we are aligned */
499 		/* let's just check for obvious mistakes */
500 		if ( sq->block_size <= 0 || sq->block_size > sq->bufSize) {
501 #ifdef DEBUG_DMASOUND
502 printk("dmasound_core: invalid frag size (user set %d)\n", sq->user_frag_size) ;
503 #endif
504 			sq->block_size = sq->bufSize ;
505 		}
506 		if ( sq->user_frags <= sq->numBufs ) {
507 			sq->max_count = sq->user_frags ;
508 			/* if user has set max_active - then use it */
509 			sq->max_active = (sq->max_active <= sq->max_count) ?
510 				sq->max_active : sq->max_count ;
511 		} else {
512 #ifdef DEBUG_DMASOUND
513 printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ;
514 #endif
515 			sq->max_count =
516 			sq->max_active = sq->numBufs ;
517 		}
518 	}
519 	sq->front = sq->count = sq->rear_size = 0;
520 	sq->syncing = 0;
521 	sq->active = 0;
522 
523 	if (sq == &write_sq) {
524 	    sq->rear = -1;
525 	    setup_func = dmasound.mach.write_sq_setup;
526 	}
527 #ifdef HAS_RECORD
528 	else {
529 	    sq->rear = 0;
530 	    setup_func = dmasound.mach.read_sq_setup;
531 	}
532 #endif
533 	if (setup_func)
534 	    return setup_func();
535 	return 0 ;
536 }
537 
sq_play(void)538 static inline void sq_play(void)
539 {
540 	dmasound.mach.play();
541 }
542 
sq_write(struct file * file,const char * src,size_t uLeft,loff_t * ppos)543 static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
544 			loff_t *ppos)
545 {
546 	ssize_t uWritten = 0;
547 	u_char *dest;
548 	ssize_t uUsed = 0, bUsed, bLeft;
549 	unsigned long flags ;
550 
551 	/* ++TeSche: Is something like this necessary?
552 	 * Hey, that's an honest question! Or does any other part of the
553 	 * filesystem already checks this situation? I really don't know.
554 	 */
555 	if (uLeft == 0)
556 		return 0;
557 
558 	/* implement any changes we have made to the soft/hard params.
559 	   this is not satisfactory really, all we have done up to now is to
560 	   say what we would like - there hasn't been any real checking of capability
561 	*/
562 
563 	if (shared_resources_initialised == 0) {
564 		dmasound.mach.init() ;
565 		shared_resources_initialised = 1 ;
566 	}
567 
568 	/* set up the sq if it is not already done. This may seem a dumb place
569 	   to do it - but it is what OSS requires.  It means that write() can
570 	   return memory allocation errors.  To avoid this possibility use the
571 	   GETBLKSIZE or GETOSPACE ioctls (after you've fiddled with all the
572 	   params you want to change) - these ioctls also force the setup.
573 	*/
574 
575 	if (write_sq.locked == 0) {
576 		if ((uWritten = sq_setup(&write_sq)) < 0) return uWritten ;
577 		uWritten = 0 ;
578 	}
579 
580 /* FIXME: I think that this may be the wrong behaviour when we get strapped
581 	for time and the cpu is close to being (or actually) behind in sending data.
582 	- because we've lost the time that the N samples, already in the buffer,
583 	would have given us to get here with the next lot from the user.
584 */
585 	/* The interrupt doesn't start to play the last, incomplete frame.
586 	 * Thus we can append to it without disabling the interrupts! (Note
587 	 * also that write_sq.rear isn't affected by the interrupt.)
588 	 */
589 
590 	/* as of 1.6 this behaviour changes if SNDCTL_DSP_POST has been issued:
591 	   this will mimic the behaviour of syncing and allow the sq_play() to
592 	   queue a partial fragment.  Since sq_play() may/will be called from
593 	   the IRQ handler - at least on Pmac we have to deal with it.
594 	   The strategy - possibly not optimum - is to kill _POST status if we
595 	   get here.  This seems, at least, reasonable - in the sense that POST
596 	   is supposed to indicate that we might not write before the queue
597 	   is drained - and if we get here in time then it does not apply.
598 	*/
599 
600 	save_flags(flags) ; cli() ;
601 	write_sq.syncing &= ~2 ; /* take out POST status */
602 	restore_flags(flags) ;
603 
604 	if (write_sq.count > 0 &&
605 	    (bLeft = write_sq.block_size-write_sq.rear_size) > 0) {
606 		dest = write_sq.buffers[write_sq.rear];
607 		bUsed = write_sq.rear_size;
608 		uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
609 					     dest, &bUsed, bLeft);
610 		if (uUsed <= 0)
611 			return uUsed;
612 		src += uUsed;
613 		uWritten += uUsed;
614 		uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ; /* paranoia */
615 		write_sq.rear_size = bUsed;
616 	}
617 
618 	while (uLeft) {
619 		while (write_sq.count >= write_sq.max_active) {
620 			sq_play();
621 			if (write_sq.open_mode & O_NONBLOCK)
622 				return uWritten > 0 ? uWritten : -EAGAIN;
623 			SLEEP(write_sq.action_queue);
624 			if (signal_pending(current))
625 				return uWritten > 0 ? uWritten : -EINTR;
626 		}
627 
628 		/* Here, we can avoid disabling the interrupt by first
629 		 * copying and translating the data, and then updating
630 		 * the write_sq variables. Until this is done, the interrupt
631 		 * won't see the new frame and we can work on it
632 		 * undisturbed.
633 		 */
634 
635 		dest = write_sq.buffers[(write_sq.rear+1) % write_sq.max_count];
636 		bUsed = 0;
637 		bLeft = write_sq.block_size;
638 		uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
639 					     dest, &bUsed, bLeft);
640 		if (uUsed <= 0)
641 			break;
642 		src += uUsed;
643 		uWritten += uUsed;
644 		uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ; /* paranoia */
645 		if (bUsed) {
646 			write_sq.rear = (write_sq.rear+1) % write_sq.max_count;
647 			write_sq.rear_size = bUsed;
648 			write_sq.count++;
649 		}
650 	} /* uUsed may have been 0 */
651 
652 	sq_play();
653 
654 	return uUsed < 0? uUsed: uWritten;
655 }
656 
sq_poll(struct file * file,struct poll_table_struct * wait)657 static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
658 {
659 	unsigned int mask = 0;
660 	int retVal;
661 
662 	if (write_sq.locked == 0) {
663 		if ((retVal = sq_setup(&write_sq)) < 0)
664 			return retVal;
665 		return 0;
666 	}
667 	if (file->f_mode & FMODE_WRITE )
668 		poll_wait(file, &write_sq.action_queue, wait);
669 #ifdef HAS_RECORD
670 	if (file->f_mode & FMODE_READ)
671 		poll_wait(file, &read_sq.action_queue, wait);
672 	if (file->f_mode & FMODE_READ)
673 		if (read_sq.block_size - read_sq.rear_size > 0)
674 			mask |= POLLIN | POLLRDNORM;
675 #endif
676 	if (file->f_mode & FMODE_WRITE)
677 		if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0)
678 			mask |= POLLOUT | POLLWRNORM;
679 	return mask;
680 
681 }
682 
683 #ifdef HAS_RECORD
684     /*
685      *  Here is how the values are used for reading.
686      *  The value 'active' simply indicates the DMA is running.  This is done
687      *  so the driver semantics are DMA starts when the first read is posted.
688      *  The value 'front' indicates the buffer we should next send to the user.
689      *  The value 'rear' indicates the buffer the DMA is currently filling.
690      *  When 'front' == 'rear' the buffer "ring" is empty (we always have an
691      *  empty available).  The 'rear_size' is used to track partial offsets
692      *  into the buffer we are currently returning to the user.
693 
694      *  This level (> [1.5]) doesn't care what strategy the LL driver uses with
695      *  DMA on over-run.  It can leave it running (and keep active == 1) or it
696      *  can kill it and set active == 0 in which case this routine will spot
697      *  it and restart the DMA.
698      */
699 
sq_read(struct file * file,char * dst,size_t uLeft,loff_t * ppos)700 static ssize_t sq_read(struct file *file, char *dst, size_t uLeft,
701 		       loff_t *ppos)
702 {
703 
704 	ssize_t	uRead, bLeft, bUsed, uUsed;
705 
706 	if (uLeft == 0)
707 		return 0;
708 
709 	/* cater for the compatibility mode - record compiled in but no LL */
710 	if (dmasound.mach.record == NULL)
711 		return -EINVAL ;
712 
713 	/* see comment in sq_write()
714 	*/
715 
716 	if( shared_resources_initialised == 0) {
717 		dmasound.mach.init() ;
718 		shared_resources_initialised = 1 ;
719 	}
720 
721 	/* set up the sq if it is not already done. see comments in sq_write().
722 	*/
723 
724 	if (read_sq.locked == 0) {
725 		if ((uRead = sq_setup(&read_sq)) < 0)
726 			return uRead ;
727 	}
728 
729 	uRead = 0;
730 
731 	/* Move what the user requests, depending upon other options.
732 	*/
733 	while (uLeft > 0) {
734 
735 		/* we happened to get behind and the LL driver killed DMA
736 		   then we should set it going again.  This also sets it
737 		   going the first time through.
738 		*/
739 		if ( !read_sq.active )
740 			dmasound.mach.record();
741 
742 		/* When front == rear, the DMA is not done yet.
743 		*/
744 		while (read_sq.front == read_sq.rear) {
745 			if (read_sq.open_mode & O_NONBLOCK) {
746 			       return uRead > 0 ? uRead : -EAGAIN;
747 			}
748 			SLEEP(read_sq.action_queue);
749 			if (signal_pending(current))
750 				return uRead > 0 ? uRead : -EINTR;
751 		}
752 
753 		/* The amount we move is either what is left in the
754 		 * current buffer or what the user wants.
755 		 */
756 		bLeft = read_sq.block_size - read_sq.rear_size;
757 		bUsed = read_sq.rear_size;
758 		uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft,
759 					     read_sq.buffers[read_sq.front],
760 					     &bUsed, bLeft);
761 		if (uUsed <= 0)
762 			return uUsed;
763 		dst += uUsed;
764 		uRead += uUsed;
765 		uLeft -= uUsed;
766 		read_sq.rear_size += bUsed;
767 		if (read_sq.rear_size >= read_sq.block_size) {
768 			read_sq.rear_size = 0;
769 			read_sq.front++;
770 			if (read_sq.front >= read_sq.max_active)
771 				read_sq.front = 0;
772 		}
773 	}
774 	return uRead;
775 }
776 #endif /* HAS_RECORD */
777 
sq_init_waitqueue(struct sound_queue * sq)778 static inline void sq_init_waitqueue(struct sound_queue *sq)
779 {
780 	init_waitqueue_head(&sq->action_queue);
781 	init_waitqueue_head(&sq->open_queue);
782 	init_waitqueue_head(&sq->sync_queue);
783 	sq->busy = 0;
784 }
785 
786 #if 0 /* blocking open() */
787 static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
788 			      mode_t mode)
789 {
790 	if (file->f_mode & mode) {
791 		sq->busy = 0; /* CHECK: IS THIS OK??? */
792 		WAKE_UP(sq->open_queue);
793 	}
794 }
795 #endif
796 
sq_open2(struct sound_queue * sq,struct file * file,mode_t mode,int numbufs,int bufsize)797 static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
798 		    int numbufs, int bufsize)
799 {
800 	int rc = 0;
801 
802 	if (file->f_mode & mode) {
803 		if (sq->busy) {
804 #if 0 /* blocking open() */
805 			rc = -EBUSY;
806 			if (file->f_flags & O_NONBLOCK)
807 				return rc;
808 			rc = -EINTR;
809 			while (sq->busy) {
810 				SLEEP(sq->open_queue);
811 				if (signal_pending(current))
812 					return rc;
813 			}
814 			rc = 0;
815 #else
816 			/* OSS manual says we will return EBUSY regardless
817 			   of O_NOBLOCK.
818 			*/
819 			return -EBUSY ;
820 #endif
821 		}
822 		sq->busy = 1; /* Let's play spot-the-race-condition */
823 
824 		/* allocate the default number & size of buffers.
825 		   (i.e. specified in _setup() or as module params)
826 		   can't be changed at the moment - but _could_ be perhaps
827 		   in the setfragments ioctl.
828 		*/
829 		if (( rc = sq_allocate_buffers(sq, numbufs, bufsize))) {
830 #if 0 /* blocking open() */
831 			sq_wake_up(sq, file, mode);
832 #else
833 			sq->busy = 0 ;
834 #endif
835 			return rc;
836 		}
837 
838 		sq->open_mode = file->f_mode;
839 	}
840 	return rc;
841 }
842 
843 #define write_sq_init_waitqueue()	sq_init_waitqueue(&write_sq)
844 #if 0 /* blocking open() */
845 #define write_sq_wake_up(file)		sq_wake_up(&write_sq, file, FMODE_WRITE)
846 #endif
847 #define write_sq_release_buffers()	sq_release_buffers(&write_sq)
848 #define write_sq_open(file)	\
849 	sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
850 
851 #ifdef HAS_RECORD
852 #define read_sq_init_waitqueue()	sq_init_waitqueue(&read_sq)
853 #if 0 /* blocking open() */
854 #define read_sq_wake_up(file)		sq_wake_up(&read_sq, file, FMODE_READ)
855 #endif
856 #define read_sq_release_buffers()	sq_release_buffers(&read_sq)
857 #define read_sq_open(file)	\
858 	sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize )
859 #else
860 #define read_sq_init_waitqueue()	do {} while (0)
861 #if 0 /* blocking open() */
862 #define read_sq_wake_up(file)		do {} while (0)
863 #endif
864 #define read_sq_release_buffers()	do {} while (0)
865 #define sq_reset_input()		do {} while (0)
866 #endif
867 
sq_open(struct inode * inode,struct file * file)868 static int sq_open(struct inode *inode, struct file *file)
869 {
870 	int rc;
871 
872 	dmasound.mach.open();
873 
874 	if ((rc = write_sq_open(file))) { /* checks the f_mode */
875 		dmasound.mach.release();
876 		return rc;
877 	}
878 #ifdef HAS_RECORD
879 	if (dmasound.mach.record) {
880 		if ((rc = read_sq_open(file))) { /* checks the f_mode */
881 			dmasound.mach.release();
882 			return rc;
883 		}
884 	} else { /* no record function installed; in compat mode */
885 		if (file->f_mode & FMODE_READ) {
886 			/* TODO: if O_RDWR, release any resources grabbed by write part */
887 			dmasound.mach.release() ;
888 			/* I think this is what is required by open(2) */
889 			return -ENXIO ;
890 		}
891 	}
892 #else /* !HAS_RECORD */
893 	if (file->f_mode & FMODE_READ) {
894 		/* TODO: if O_RDWR, release any resources grabbed by write part */
895 		dmasound.mach.release() ;
896 		return -ENXIO ; /* I think this is what is required by open(2) */
897 	}
898 #endif /* HAS_RECORD */
899 
900 	if (dmasound.mach.sq_open)
901 	    dmasound.mach.sq_open(file->f_mode);
902 
903 	/* CHECK whether this is sensible - in the case that dsp0 could be opened
904 	  O_RDONLY and dsp1 could be opened O_WRONLY
905 	*/
906 
907 	dmasound.minDev = MINOR(inode->i_rdev) & 0x0f;
908 
909 	/* OK. - we should make some attempt at consistency. At least the H'ware
910 	   options should be set with a valid mode.  We will make it that the LL
911 	   driver must supply defaults for hard & soft params.
912 	*/
913 
914 	if (shared_resource_owner == 0) {
915 		/* you can make this AFMT_U8/mono/8K if you want to mimic old
916 		   OSS behaviour - while we still have soft translations ;-) */
917 		dmasound.soft = dmasound.mach.default_soft ;
918 		dmasound.dsp = dmasound.mach.default_soft ;
919 		dmasound.hard = dmasound.mach.default_hard ;
920 	}
921 
922 #ifndef DMASOUND_STRICT_OSS_COMPLIANCE
923 	/* none of the current LL drivers can actually do this "native" at the moment
924 	   OSS does not really require us to supply /dev/audio if we can't do it.
925 	*/
926 	if (dmasound.minDev == SND_DEV_AUDIO) {
927 		sound_set_speed(8000);
928 		sound_set_stereo(0);
929 		sound_set_format(AFMT_MU_LAW);
930 	}
931 #endif
932 
933 	return 0;
934 }
935 
sq_reset_output(void)936 static void sq_reset_output(void)
937 {
938 	sound_silence(); /* this _must_ stop DMA, we might be about to lose the buffers */
939 	write_sq.active = 0;
940 	write_sq.count = 0;
941 	write_sq.rear_size = 0;
942 	/* write_sq.front = (write_sq.rear+1) % write_sq.max_count;*/
943 	write_sq.front = 0 ;
944 	write_sq.rear = -1 ; /* same as for set-up */
945 
946 	/* OK - we can unlock the parameters and fragment settings */
947 	write_sq.locked = 0 ;
948 	write_sq.user_frags = 0 ;
949 	write_sq.user_frag_size = 0 ;
950 }
951 
952 #ifdef HAS_RECORD
953 
sq_reset_input(void)954 static void sq_reset_input(void)
955 {
956 	if (dmasound.mach.record && read_sq.active) {
957 		if (dmasound.mach.abort_read) { /* this routine must really be present */
958 			read_sq.syncing = 1 ;
959 			/* this can use the read_sq.sync_queue to sleep if
960 			   necessary - it should not return until DMA
961 			   is really stopped - because we might deallocate
962 			   the buffers as the next action...
963 			*/
964 			dmasound.mach.abort_read() ;
965 		} else {
966 			printk(KERN_ERR
967 			"dmasound_core: %s has no abort_read()!! all bets are off\n",
968 				dmasound.mach.name) ;
969 		}
970 	}
971 	read_sq.syncing =
972 	read_sq.active =
973 	read_sq.front =
974 	read_sq.count =
975 	read_sq.rear = 0 ;
976 
977 	/* OK - we can unlock the parameters and fragment settings */
978 	read_sq.locked = 0 ;
979 	read_sq.user_frags = 0 ;
980 	read_sq.user_frag_size = 0 ;
981 }
982 
983 #endif
984 
sq_reset(void)985 static void sq_reset(void)
986 {
987 	sq_reset_output() ;
988 	sq_reset_input() ;
989 	/* we could consider resetting the shared_resources_owner here... but I
990 	   think it is probably still rather non-obvious to application writer
991 	*/
992 
993 	/* we release everything else though */
994 	shared_resources_initialised = 0 ;
995 }
996 
sq_fsync(struct file * filp,struct dentry * dentry)997 static int sq_fsync(struct file *filp, struct dentry *dentry)
998 {
999 	int rc = 0;
1000 
1001 	write_sq.syncing |= 1;
1002 	sq_play();	/* there may be an incomplete frame waiting */
1003 
1004 	while (write_sq.active) {
1005 		SLEEP(write_sq.sync_queue);
1006 		if (signal_pending(current)) {
1007 			/* While waiting for audio output to drain, an
1008 			 * interrupt occurred.  Stop audio output immediately
1009 			 * and clear the queue. */
1010 			sq_reset_output();
1011 			rc = -EINTR;
1012 			break;
1013 		}
1014 	}
1015 
1016 	/* flag no sync regardless of whether we had a DSP_POST or not */
1017 	write_sq.syncing = 0 ;
1018 	return rc;
1019 }
1020 
sq_release(struct inode * inode,struct file * file)1021 static int sq_release(struct inode *inode, struct file *file)
1022 {
1023 	int rc = 0;
1024 
1025 	lock_kernel();
1026 
1027 #ifdef HAS_RECORD
1028 	/* probably best to do the read side first - so that time taken to do it
1029 	   overlaps with playing any remaining output samples.
1030 	*/
1031 	if (file->f_mode & FMODE_READ) {
1032 		sq_reset_input() ; /* make sure dma is stopped and all is quiet */
1033 		read_sq_release_buffers();
1034 		read_sq.busy = 0;
1035 	}
1036 #endif
1037 
1038 	if (file->f_mode & FMODE_WRITE) {
1039 		if (write_sq.busy)
1040 			rc = sq_fsync(file, file->f_dentry);
1041 
1042 		sq_reset_output() ; /* make sure dma is stopped and all is quiet */
1043 		write_sq_release_buffers();
1044 		write_sq.busy = 0;
1045 	}
1046 
1047 	if (file->f_mode & shared_resource_owner) { /* it's us that has them */
1048 		shared_resource_owner = 0 ;
1049 		shared_resources_initialised = 0 ;
1050 		dmasound.hard = dmasound.mach.default_hard ;
1051 	}
1052 
1053 	dmasound.mach.release();
1054 
1055 #if 0 /* blocking open() */
1056 	/* Wake up a process waiting for the queue being released.
1057 	 * Note: There may be several processes waiting for a call
1058 	 * to open() returning. */
1059 
1060 	/* Iain: hmm I don't understand this next comment ... */
1061 	/* There is probably a DOS atack here. They change the mode flag. */
1062 	/* XXX add check here,*/
1063 	read_sq_wake_up(file); /* checks f_mode */
1064 	write_sq_wake_up(file); /* checks f_mode */
1065 #endif /* blocking open() */
1066 
1067 	unlock_kernel();
1068 
1069 	return rc;
1070 }
1071 
1072 /* here we see if we have a right to modify format, channels, size and so on
1073    if no-one else has claimed it already then we do...
1074 
1075    TODO: We might change this to mask O_RDWR such that only one or the other channel
1076    is the owner - if we have problems.
1077 */
1078 
shared_resources_are_mine(mode_t md)1079 static int shared_resources_are_mine(mode_t md)
1080 {
1081 	if (shared_resource_owner)
1082 		return (shared_resource_owner & md ) ;
1083 	else {
1084 		shared_resource_owner = md ;
1085 		return 1 ;
1086 	}
1087 }
1088 
1089 /* if either queue is locked we must deny the right to change shared params
1090 */
1091 
queues_are_quiescent(void)1092 static int queues_are_quiescent(void)
1093 {
1094 #ifdef HAS_RECORD
1095 	if (dmasound.mach.record)
1096 		if (read_sq.locked)
1097 			return 0 ;
1098 #endif
1099 	if (write_sq.locked)
1100 		return 0 ;
1101 	return 1 ;
1102 }
1103 
1104 /* check and set a queue's fragments per user's wishes...
1105    we will check against the pre-defined literals and the actual sizes.
1106    This is a bit fraught - because soft translations can mess with our
1107    buffer requirements *after* this call - OSS says "call setfrags first"
1108 */
1109 
1110 /* It is possible to replace all the -EINVAL returns with an override that
1111    just puts the allowable value in.  This may be what many OSS apps require
1112 */
1113 
set_queue_frags(struct sound_queue * sq,int bufs,int size)1114 static int set_queue_frags(struct sound_queue *sq, int bufs, int size)
1115 {
1116 	if (sq->locked) {
1117 #ifdef DEBUG_DMASOUND
1118 printk("dmasound_core: tried to set_queue_frags on a locked queue\n") ;
1119 #endif
1120 		return -EINVAL ;
1121 	}
1122 
1123 	if ((size < MIN_FRAG_SIZE) || (size > MAX_FRAG_SIZE))
1124 		return -EINVAL ;
1125 	size = (1<<size) ; /* now in bytes */
1126 	if (size > sq->bufSize)
1127 		return -EINVAL ; /* this might still not work */
1128 
1129 	if (bufs <= 0)
1130 		return -EINVAL ;
1131 	if (bufs > sq->numBufs) /* the user is allowed say "don't care" with 0x7fff */
1132 		bufs = sq->numBufs ;
1133 
1134 	/* there is, currently, no way to specify max_active separately
1135 	   from max_count.  This could be a LL driver issue - I guess
1136 	   if there is a requirement for these values to be different then
1137 	  we will have to pass that info. up to this level.
1138 	*/
1139 	sq->user_frags =
1140 	sq->max_active = bufs ;
1141 	sq->user_frag_size = size ;
1142 
1143 	return 0 ;
1144 }
1145 
sq_ioctl(struct inode * inode,struct file * file,u_int cmd,u_long arg)1146 static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
1147 		    u_long arg)
1148 {
1149 	int val, result;
1150 	u_long fmt;
1151 	int data;
1152 	int size, nbufs;
1153 	audio_buf_info info;
1154 
1155 	switch (cmd) {
1156 	case SNDCTL_DSP_RESET:
1157 		sq_reset();
1158 		return 0;
1159 		break ;
1160 	case SNDCTL_DSP_GETFMTS:
1161 		fmt = dmasound.mach.hardware_afmts ; /* this is what OSS says.. */
1162 		return IOCTL_OUT(arg, fmt);
1163 		break ;
1164 	case SNDCTL_DSP_GETBLKSIZE:
1165 		/* this should tell the caller about bytes that the app can
1166 		   read/write - the app doesn't care about our internal buffers.
1167 		   We force sq_setup() here as per OSS 1.1 (which should
1168 		   compute the values necessary).
1169 		   Since there is no mechanism to specify read/write separately, for
1170 		   fds opened O_RDWR, the write_sq values will, arbitrarily, overwrite
1171 		   the read_sq ones.
1172 		*/
1173 		size = 0 ;
1174 #ifdef HAS_RECORD
1175 		if (dmasound.mach.record && (file->f_mode & FMODE_READ)) {
1176 			if ( !read_sq.locked )
1177 				sq_setup(&read_sq) ; /* set params */
1178 			size = read_sq.user_frag_size ;
1179 		}
1180 #endif
1181 		if (file->f_mode & FMODE_WRITE) {
1182 			if ( !write_sq.locked )
1183 				sq_setup(&write_sq) ;
1184 			size = write_sq.user_frag_size ;
1185 		}
1186 		return IOCTL_OUT(arg, size);
1187 		break ;
1188 	case SNDCTL_DSP_POST:
1189 		/* all we are going to do is to tell the LL that any
1190 		   partial frags can be queued for output.
1191 		   The LL will have to clear this flag when last output
1192 		   is queued.
1193 		*/
1194 		write_sq.syncing |= 0x2 ;
1195 		sq_play() ;
1196 		return 0 ;
1197 	case SNDCTL_DSP_SYNC:
1198 		/* This call, effectively, has the same behaviour as SNDCTL_DSP_RESET
1199 		   except that it waits for output to finish before resetting
1200 		   everything - read, however, is killed imediately.
1201 		*/
1202 		result = 0 ;
1203 		if ((file->f_mode & FMODE_READ) && dmasound.mach.record)
1204 			sq_reset_input() ;
1205 		if (file->f_mode & FMODE_WRITE) {
1206 			result = sq_fsync(file, file->f_dentry);
1207 			sq_reset_output() ;
1208 		}
1209 		/* if we are the shared resource owner then release them */
1210 		if (file->f_mode & shared_resource_owner)
1211 			shared_resources_initialised = 0 ;
1212 		return result ;
1213 		break ;
1214 	case SOUND_PCM_READ_RATE:
1215 		return IOCTL_OUT(arg, dmasound.soft.speed);
1216 	case SNDCTL_DSP_SPEED:
1217 		/* Changing this on the fly will have weird effects on the sound.
1218 		   Where there are rate conversions implemented in soft form - it
1219 		   will cause the _ctx_xxx() functions to be substituted.
1220 		   However, there doesn't appear to be any reason to dis-allow it from
1221 		   a driver pov.
1222 		*/
1223 		if (shared_resources_are_mine(file->f_mode)) {
1224 			IOCTL_IN(arg, data);
1225 			data = sound_set_speed(data) ;
1226 			shared_resources_initialised = 0 ;
1227 			return IOCTL_OUT(arg, data);
1228 		} else
1229 			return -EINVAL ;
1230 		break ;
1231 	/* OSS says these next 4 actions are undefined when the device is
1232 	   busy/active - we will just return -EINVAL.
1233 	   To be allowed to change one - (a) you have to own the right
1234 	    (b) the queue(s) must be quiescent
1235 	*/
1236 	case SNDCTL_DSP_STEREO:
1237 		if (shared_resources_are_mine(file->f_mode) &&
1238 		    queues_are_quiescent()) {
1239 			IOCTL_IN(arg, data);
1240 			shared_resources_initialised = 0 ;
1241 			return IOCTL_OUT(arg, sound_set_stereo(data));
1242 		} else
1243 			return -EINVAL ;
1244 		break ;
1245 	case SOUND_PCM_WRITE_CHANNELS:
1246 		if (shared_resources_are_mine(file->f_mode) &&
1247 		    queues_are_quiescent()) {
1248 			IOCTL_IN(arg, data);
1249 			/* the user might ask for 20 channels, we will return 1 or 2 */
1250 			shared_resources_initialised = 0 ;
1251 			return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
1252 		} else
1253 			return -EINVAL ;
1254 		break ;
1255 	case SOUND_PCM_READ_CHANNELS:
1256 		return IOCTL_OUT(arg, dmasound.soft.stereo+1);
1257 	case SNDCTL_DSP_SETFMT:
1258 		if (shared_resources_are_mine(file->f_mode) &&
1259 		    queues_are_quiescent()) {
1260 		    	int format;
1261 			IOCTL_IN(arg, data);
1262 			shared_resources_initialised = 0 ;
1263 			format = sound_set_format(data);
1264 			result = IOCTL_OUT(arg, format);
1265 			if (result < 0)
1266 				return result;
1267 			return 0;
1268 		} else
1269 			return -EINVAL ;
1270 		break ;
1271 	case SNDCTL_DSP_SUBDIVIDE:
1272 		return -EINVAL ;
1273 		break;
1274 	case SNDCTL_DSP_SETFRAGMENT:
1275 		/* we can do this independently for the two queues - with the
1276 		   proviso that for fds opened O_RDWR we cannot separate the
1277 		   actions and both queues will be set per the last call.
1278 		   NOTE: this does *NOT* actually set the queue up - merely
1279 		   registers our intentions.
1280 		*/
1281 		IOCTL_IN(arg, data);
1282 		result = 0 ;
1283 		nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */
1284 		size = data & 0xffff;
1285 #ifdef HAS_RECORD
1286 		if ((file->f_mode & FMODE_READ) && dmasound.mach.record) {
1287 			result = set_queue_frags(&read_sq, nbufs, size) ;
1288 			if (result)
1289 				return result ;
1290 		}
1291 #endif
1292 		if (file->f_mode & FMODE_WRITE) {
1293 			result = set_queue_frags(&write_sq, nbufs, size) ;
1294 			if (result)
1295 				return result ;
1296 		}
1297 		/* NOTE: this return value is irrelevant - OSS specifically says that
1298 		   the value is 'random' and that the user _must_ check the actual
1299 		   frags values using SNDCTL_DSP_GETBLKSIZE or similar */
1300 		return IOCTL_OUT(arg, data);
1301 		break ;
1302 	case SNDCTL_DSP_GETOSPACE:
1303 		/*
1304 		*/
1305 		if (file->f_mode & FMODE_WRITE) {
1306 			if ( !write_sq.locked )
1307 				sq_setup(&write_sq) ;
1308 			info.fragments = write_sq.max_active - write_sq.count;
1309 			info.fragstotal = write_sq.max_active;
1310 			info.fragsize = write_sq.user_frag_size;
1311 			info.bytes = info.fragments * info.fragsize;
1312 			if (copy_to_user((void *)arg, &info, sizeof(info)))
1313 				return -EFAULT;
1314 			return 0;
1315 		} else
1316 			return -EINVAL ;
1317 		break ;
1318 	case SNDCTL_DSP_GETCAPS:
1319 		val = dmasound.mach.capabilities & 0xffffff00;
1320 		return IOCTL_OUT(arg,val);
1321 
1322 	default:
1323 		return mixer_ioctl(inode, file, cmd, arg);
1324 	}
1325 	return -EINVAL;
1326 }
1327 
1328 static struct file_operations sq_fops =
1329 {
1330 	owner:		THIS_MODULE,
1331 	llseek:		no_llseek,
1332 	write:		sq_write,
1333 	poll:		sq_poll,
1334 	ioctl:		sq_ioctl,
1335 	open:		sq_open,
1336 	release:	sq_release,
1337 #ifdef HAS_RECORD
1338 	read:		NULL	/* default to no read for compat mode */
1339 #endif
1340 };
1341 
sq_init(void)1342 static int sq_init(void)
1343 {
1344 #ifndef MODULE
1345 	int sq_unit;
1346 #endif
1347 
1348 #ifdef HAS_RECORD
1349 	if (dmasound.mach.record)
1350 		sq_fops.read = sq_read ;
1351 #endif
1352 	sq_unit = register_sound_dsp(&sq_fops, -1);
1353 	if (sq_unit < 0) {
1354 		printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
1355 		return sq_unit ;
1356 	}
1357 
1358 	write_sq_init_waitqueue();
1359 	read_sq_init_waitqueue();
1360 
1361 	/* These parameters will be restored for every clean open()
1362 	 * in the case of multiple open()s (e.g. dsp0 & dsp1) they
1363 	 * will be set so long as the shared resources have no owner.
1364 	 */
1365 
1366 	if (shared_resource_owner == 0) {
1367 		dmasound.soft = dmasound.mach.default_soft ;
1368 		dmasound.hard = dmasound.mach.default_hard ;
1369 		dmasound.dsp = dmasound.mach.default_soft ;
1370 		shared_resources_initialised = 0 ;
1371 	}
1372 	return 0 ;
1373 }
1374 
1375 
1376     /*
1377      *  /dev/sndstat
1378      */
1379 
1380 /* we allow more space for record-enabled because there are extra output lines.
1381    the number here must include the amount we are prepared to give to the low-level
1382    driver.
1383 */
1384 
1385 #ifdef HAS_RECORD
1386 #define STAT_BUFF_LEN 1024
1387 #else
1388 #define STAT_BUFF_LEN 768
1389 #endif
1390 
1391 /* this is how much space we will allow the low-level driver to use
1392    in the stat buffer.  Currently, 2 * (80 character line + <NL>).
1393    We do not police this (it is up to the ll driver to be honest).
1394 */
1395 
1396 #define LOW_LEVEL_STAT_ALLOC 162
1397 
1398 static struct {
1399     int busy;
1400     char buf[STAT_BUFF_LEN];	/* state.buf should not overflow! */
1401     int len, ptr;
1402 } state;
1403 
1404 /* publish this function for use by low-level code, if required */
1405 
get_afmt_string(int afmt)1406 char *get_afmt_string(int afmt)
1407 {
1408         switch(afmt) {
1409             case AFMT_MU_LAW:
1410                 return "mu-law";
1411                 break;
1412             case AFMT_A_LAW:
1413                 return "A-law";
1414                 break;
1415             case AFMT_U8:
1416                 return "unsigned 8 bit";
1417                 break;
1418             case AFMT_S8:
1419                 return "signed 8 bit";
1420                 break;
1421             case AFMT_S16_BE:
1422                 return "signed 16 bit BE";
1423                 break;
1424             case AFMT_U16_BE:
1425                 return "unsigned 16 bit BE";
1426                 break;
1427             case AFMT_S16_LE:
1428                 return "signed 16 bit LE";
1429                 break;
1430             case AFMT_U16_LE:
1431                 return "unsigned 16 bit LE";
1432                 break;
1433 	    case 0:
1434 		return "format not set" ;
1435 		break ;
1436             default:
1437                 break ;
1438         }
1439         return "ERROR: Unsupported AFMT_XXXX code" ;
1440 }
1441 
state_open(struct inode * inode,struct file * file)1442 static int state_open(struct inode *inode, struct file *file)
1443 {
1444 	char *buffer = state.buf;
1445 	int len = 0;
1446 
1447 	if (state.busy)
1448 		return -EBUSY;
1449 
1450 	dmasound.mach.open();
1451 	state.ptr = 0;
1452 	state.busy = 1;
1453 
1454 	len += sprintf(buffer+len, "%sDMA sound driver rev %03d :\n",
1455 		dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +
1456 		((dmasound.mach.version>>8) & 0x0f));
1457 	len += sprintf(buffer+len,
1458 		"Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
1459 		DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,
1460 		(dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
1461 
1462 	/* call the low-level module to fill in any stat info. that it has
1463 	   if present.  Maximum buffer usage is specified.
1464 	*/
1465 
1466 	if (dmasound.mach.state_info)
1467 		len += dmasound.mach.state_info(buffer+len,
1468 			(size_t) LOW_LEVEL_STAT_ALLOC) ;
1469 
1470 	/* make usage of the state buffer as deterministic as poss.
1471 	   exceptional conditions could cause overrun - and this is flagged as
1472 	   a kernel error.
1473 	*/
1474 
1475 	/* formats and settings */
1476 
1477 	len += sprintf(buffer+len,"\t\t === Formats & settings ===\n") ;
1478 	len += sprintf(buffer+len,"Parameter %20s%20s\n","soft","hard") ;
1479 	len += sprintf(buffer+len,"Format   :%20s%20s\n",
1480 		get_afmt_string(dmasound.soft.format),
1481 		get_afmt_string(dmasound.hard.format));
1482 
1483 	len += sprintf(buffer+len,"Samp Rate:%14d s/sec%14d s/sec\n",
1484 		       dmasound.soft.speed, dmasound.hard.speed);
1485 
1486 	len += sprintf(buffer+len,"Channels :%20s%20s\n",
1487 		       dmasound.soft.stereo ? "stereo" : "mono",
1488 		       dmasound.hard.stereo ? "stereo" : "mono" );
1489 
1490 	/* sound queue status */
1491 
1492 	len += sprintf(buffer+len,"\t\t === Sound Queue status ===\n");
1493 	len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;
1494 	len += sprintf(buffer+len,"%9s:%8d%6d\n",
1495 		"write", write_sq.numBufs, write_sq.bufSize) ;
1496 #ifdef HAS_RECORD
1497 	if (dmasound.mach.record)
1498 		len += sprintf(buffer+len,"%9s:%8d%6d\n",
1499 			"read", read_sq.numBufs, read_sq.bufSize) ;
1500 #endif
1501 	len += sprintf(buffer+len,
1502 		"Current  : MaxFrg FragSiz MaxAct Frnt Rear "
1503 		"Cnt RrSize A B S L  xruns\n") ;
1504 	len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
1505 		"write", write_sq.max_count, write_sq.block_size,
1506 		write_sq.max_active, write_sq.front, write_sq.rear,
1507 		write_sq.count, write_sq.rear_size, write_sq.active,
1508 		write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;
1509 #ifdef HAS_RECORD
1510 	if (dmasound.mach.record)
1511 		len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
1512 			"read", read_sq.max_count, read_sq.block_size,
1513 			read_sq.max_active, read_sq.front, read_sq.rear,
1514 			read_sq.count, read_sq.rear_size, read_sq.active,
1515 			read_sq.busy, read_sq.syncing, read_sq.locked, read_sq.xruns) ;
1516 #endif
1517 #ifdef DEBUG_DMASOUND
1518 printk("dmasound: stat buffer used %d bytes\n", len) ;
1519 #endif
1520 
1521 	if (len >= STAT_BUFF_LEN)
1522 		printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n");
1523 
1524 	state.len = len;
1525 	return 0;
1526 }
1527 
state_release(struct inode * inode,struct file * file)1528 static int state_release(struct inode *inode, struct file *file)
1529 {
1530 	lock_kernel();
1531 	state.busy = 0;
1532 	dmasound.mach.release();
1533 	unlock_kernel();
1534 	return 0;
1535 }
1536 
state_read(struct file * file,char * buf,size_t count,loff_t * ppos)1537 static ssize_t state_read(struct file *file, char *buf, size_t count,
1538 			  loff_t *ppos)
1539 {
1540 	int n = state.len - state.ptr;
1541 	if (n > count)
1542 		n = count;
1543 	if (n <= 0)
1544 		return 0;
1545 	if (copy_to_user(buf, &state.buf[state.ptr], n))
1546 		return -EFAULT;
1547 	state.ptr += n;
1548 	return n;
1549 }
1550 
1551 static struct file_operations state_fops = {
1552 	owner:		THIS_MODULE,
1553 	llseek:		no_llseek,
1554 	read:		state_read,
1555 	open:		state_open,
1556 	release:	state_release,
1557 };
1558 
state_init(void)1559 static int state_init(void)
1560 {
1561 #ifndef MODULE
1562 	int state_unit;
1563 #endif
1564 	state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
1565 	if (state_unit < 0)
1566 		return state_unit ;
1567 	state.busy = 0;
1568 	return 0 ;
1569 }
1570 
1571 
1572     /*
1573      *  Config & Setup
1574      *
1575      *  This function is called by _one_ chipset-specific driver
1576      */
1577 
dmasound_init(void)1578 int dmasound_init(void)
1579 {
1580 	int res ;
1581 #ifdef MODULE
1582 	if (irq_installed)
1583 		return -EBUSY;
1584 #endif
1585 
1586 	/* Set up sound queue, /dev/audio and /dev/dsp. */
1587 
1588 	/* Set default settings. */
1589 	if ((res = sq_init()) < 0)
1590 		return res ;
1591 
1592 	/* Set up /dev/sndstat. */
1593 	if ((res = state_init()) < 0)
1594 		return res ;
1595 
1596 	/* Set up /dev/mixer. */
1597 	mixer_init();
1598 
1599 	if (!dmasound.mach.irqinit()) {
1600 		printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
1601 		return -ENODEV;
1602 	}
1603 #ifdef MODULE
1604 	irq_installed = 1;
1605 #endif
1606 
1607 	printk(KERN_INFO "%s DMA sound driver rev %03d installed\n",
1608 		dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +
1609 		((dmasound.mach.version>>8) & 0x0f));
1610 	printk(KERN_INFO
1611 		"Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
1612 		DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,
1613 		(dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
1614 	printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
1615 		numWriteBufs, writeBufSize) ;
1616 #ifdef HAS_RECORD
1617 	if (dmasound.mach.record)
1618 		printk(KERN_INFO
1619 			"Read  will use %4d fragments of %7d bytes as default\n",
1620 			numReadBufs, readBufSize) ;
1621 #endif
1622 
1623 	return 0;
1624 }
1625 
1626 #ifdef MODULE
1627 
dmasound_deinit(void)1628 void dmasound_deinit(void)
1629 {
1630 	if (irq_installed) {
1631 		sound_silence();
1632 		dmasound.mach.irqcleanup();
1633 		irq_installed = 0;
1634 	}
1635 
1636 	write_sq_release_buffers();
1637 	read_sq_release_buffers();
1638 
1639 	if (mixer_unit >= 0)
1640 		unregister_sound_mixer(mixer_unit);
1641 	if (state_unit >= 0)
1642 		unregister_sound_special(state_unit);
1643 	if (sq_unit >= 0)
1644 		unregister_sound_dsp(sq_unit);
1645 }
1646 
1647 #else /* !MODULE */
1648 
dmasound_setup(char * str)1649 static int dmasound_setup(char *str)
1650 {
1651 	int ints[6], size;
1652 
1653 	str = get_options(str, ARRAY_SIZE(ints), ints);
1654 
1655 	/* check the bootstrap parameter for "dmasound=" */
1656 
1657 	/* FIXME: other than in the most naive of cases there is no sense in these
1658 	 *	  buffers being other than powers of two.  This is not checked yet.
1659 	 */
1660 
1661 	switch (ints[0]) {
1662 #ifdef HAS_RECORD
1663         case 5:
1664                 if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS))
1665                         printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
1666                 else
1667                         catchRadius = ints[5];
1668                 /* fall through */
1669         case 4:
1670                 if (ints[4] < MIN_BUFFERS)
1671                         printk("dmasound_setup: invalid number of read buffers, using default = %d\n",
1672                                  numReadBufs);
1673                 else
1674                         numReadBufs = ints[4];
1675                 /* fall through */
1676         case 3:
1677 		if ((size = ints[3]) < 256)  /* check for small buffer specs */
1678 			size <<= 10 ;
1679                 if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
1680                         printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize);
1681                 else
1682                         readBufSize = size;
1683                 /* fall through */
1684 #else
1685 	case 3:
1686 		if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
1687 			printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
1688 		else
1689 			catchRadius = ints[3];
1690 		/* fall through */
1691 #endif
1692 	case 2:
1693 		if (ints[1] < MIN_BUFFERS)
1694 			printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
1695 		else
1696 			numWriteBufs = ints[1];
1697 		/* fall through */
1698 	case 1:
1699 		if ((size = ints[2]) < 256) /* check for small buffer specs */
1700 			size <<= 10 ;
1701                 if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
1702                         printk("dmasound_setup: invalid write buffer size, using default = %d\n", writeBufSize);
1703                 else
1704                         writeBufSize = size;
1705 	case 0:
1706 		break;
1707 	default:
1708 		printk("dmasound_setup: invalid number of arguments\n");
1709 		return 0;
1710 	}
1711 	return 1;
1712 }
1713 
1714 __setup("dmasound=", dmasound_setup);
1715 
1716 #endif /* !MODULE */
1717 
1718     /*
1719      *  Conversion tables
1720      */
1721 
1722 #ifdef HAS_8BIT_TABLES
1723 /* 8 bit mu-law */
1724 
1725 char dmasound_ulaw2dma8[] = {
1726 	-126,	-122,	-118,	-114,	-110,	-106,	-102,	-98,
1727 	-94,	-90,	-86,	-82,	-78,	-74,	-70,	-66,
1728 	-63,	-61,	-59,	-57,	-55,	-53,	-51,	-49,
1729 	-47,	-45,	-43,	-41,	-39,	-37,	-35,	-33,
1730 	-31,	-30,	-29,	-28,	-27,	-26,	-25,	-24,
1731 	-23,	-22,	-21,	-20,	-19,	-18,	-17,	-16,
1732 	-16,	-15,	-15,	-14,	-14,	-13,	-13,	-12,
1733 	-12,	-11,	-11,	-10,	-10,	-9,	-9,	-8,
1734 	-8,	-8,	-7,	-7,	-7,	-7,	-6,	-6,
1735 	-6,	-6,	-5,	-5,	-5,	-5,	-4,	-4,
1736 	-4,	-4,	-4,	-4,	-3,	-3,	-3,	-3,
1737 	-3,	-3,	-3,	-3,	-2,	-2,	-2,	-2,
1738 	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,
1739 	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
1740 	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
1741 	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,
1742 	125,	121,	117,	113,	109,	105,	101,	97,
1743 	93,	89,	85,	81,	77,	73,	69,	65,
1744 	62,	60,	58,	56,	54,	52,	50,	48,
1745 	46,	44,	42,	40,	38,	36,	34,	32,
1746 	30,	29,	28,	27,	26,	25,	24,	23,
1747 	22,	21,	20,	19,	18,	17,	16,	15,
1748 	15,	14,	14,	13,	13,	12,	12,	11,
1749 	11,	10,	10,	9,	9,	8,	8,	7,
1750 	7,	7,	6,	6,	6,	6,	5,	5,
1751 	5,	5,	4,	4,	4,	4,	3,	3,
1752 	3,	3,	3,	3,	2,	2,	2,	2,
1753 	2,	2,	2,	2,	1,	1,	1,	1,
1754 	1,	1,	1,	1,	1,	1,	1,	1,
1755 	0,	0,	0,	0,	0,	0,	0,	0,
1756 	0,	0,	0,	0,	0,	0,	0,	0,
1757 	0,	0,	0,	0,	0,	0,	0,	0
1758 };
1759 
1760 /* 8 bit A-law */
1761 
1762 char dmasound_alaw2dma8[] = {
1763 	-22,	-21,	-24,	-23,	-18,	-17,	-20,	-19,
1764 	-30,	-29,	-32,	-31,	-26,	-25,	-28,	-27,
1765 	-11,	-11,	-12,	-12,	-9,	-9,	-10,	-10,
1766 	-15,	-15,	-16,	-16,	-13,	-13,	-14,	-14,
1767 	-86,	-82,	-94,	-90,	-70,	-66,	-78,	-74,
1768 	-118,	-114,	-126,	-122,	-102,	-98,	-110,	-106,
1769 	-43,	-41,	-47,	-45,	-35,	-33,	-39,	-37,
1770 	-59,	-57,	-63,	-61,	-51,	-49,	-55,	-53,
1771 	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,
1772 	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,
1773 	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
1774 	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
1775 	-6,	-6,	-6,	-6,	-5,	-5,	-5,	-5,
1776 	-8,	-8,	-8,	-8,	-7,	-7,	-7,	-7,
1777 	-3,	-3,	-3,	-3,	-3,	-3,	-3,	-3,
1778 	-4,	-4,	-4,	-4,	-4,	-4,	-4,	-4,
1779 	21,	20,	23,	22,	17,	16,	19,	18,
1780 	29,	28,	31,	30,	25,	24,	27,	26,
1781 	10,	10,	11,	11,	8,	8,	9,	9,
1782 	14,	14,	15,	15,	12,	12,	13,	13,
1783 	86,	82,	94,	90,	70,	66,	78,	74,
1784 	118,	114,	126,	122,	102,	98,	110,	106,
1785 	43,	41,	47,	45,	35,	33,	39,	37,
1786 	59,	57,	63,	61,	51,	49,	55,	53,
1787 	1,	1,	1,	1,	1,	1,	1,	1,
1788 	1,	1,	1,	1,	1,	1,	1,	1,
1789 	0,	0,	0,	0,	0,	0,	0,	0,
1790 	0,	0,	0,	0,	0,	0,	0,	0,
1791 	5,	5,	5,	5,	4,	4,	4,	4,
1792 	7,	7,	7,	7,	6,	6,	6,	6,
1793 	2,	2,	2,	2,	2,	2,	2,	2,
1794 	3,	3,	3,	3,	3,	3,	3,	3
1795 };
1796 #endif /* HAS_8BIT_TABLES */
1797 
1798     /*
1799      *  Visible symbols for modules
1800      */
1801 
1802 EXPORT_SYMBOL(dmasound);
1803 EXPORT_SYMBOL(dmasound_init);
1804 #ifdef MODULE
1805 EXPORT_SYMBOL(dmasound_deinit);
1806 #endif
1807 EXPORT_SYMBOL(dmasound_write_sq);
1808 #ifdef HAS_RECORD
1809 EXPORT_SYMBOL(dmasound_read_sq);
1810 #endif
1811 EXPORT_SYMBOL(dmasound_catchRadius);
1812 #ifdef HAS_8BIT_TABLES
1813 EXPORT_SYMBOL(dmasound_ulaw2dma8);
1814 EXPORT_SYMBOL(dmasound_alaw2dma8);
1815 #endif
1816 EXPORT_SYMBOL(get_afmt_string) ;
1817