~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/oss/dmasound/dmasound_core.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/sound/oss/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/mutex.h>
185 #include <linux/sched/signal.h>
186 
187 #include <linux/uaccess.h>
188 
189 #include "dmasound.h"
190 
191 #define DMASOUND_CORE_REVISION 1
192 #define DMASOUND_CORE_EDITION 6
193 
194     /*
195      *  Declarations
196      */
197 
198 static DEFINE_MUTEX(dmasound_core_mutex);
199 int dmasound_catchRadius = 0;
200 module_param(dmasound_catchRadius, int, 0);
201 
202 static unsigned int numWriteBufs = DEFAULT_N_BUFFERS;
203 module_param(numWriteBufs, int, 0);
204 static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ;  /* in bytes */
205 module_param(writeBufSize, int, 0);
206 
207 MODULE_DESCRIPTION("Atari/Amiga/Q40 core DMA sound driver");
208 MODULE_LICENSE("GPL");
209 
210 static int sq_unit = -1;
211 static int mixer_unit = -1;
212 static int state_unit = -1;
213 static int irq_installed;
214 
215 /* control over who can modify resources shared between play/record */
216 static fmode_t shared_resource_owner;
217 static int shared_resources_initialised;
218 
219     /*
220      *  Mid level stuff
221      */
222 
223 struct sound_settings dmasound = {
224         .lock = __SPIN_LOCK_UNLOCKED(dmasound.lock)
225 };
226 
227 static inline void sound_silence(void)
228 {
229         dmasound.mach.silence(); /* _MUST_ stop DMA */
230 }
231 
232 static inline int sound_set_format(int format)
233 {
234         return dmasound.mach.setFormat(format);
235 }
236 
237 
238 static int sound_set_speed(int speed)
239 {
240         if (speed < 0)
241                 return dmasound.soft.speed;
242 
243         /* trap out-of-range speed settings.
244            at present we allow (arbitrarily) low rates - using soft
245            up-conversion - but we can't allow > max because there is
246            no soft down-conversion.
247         */
248         if (dmasound.mach.max_dsp_speed &&
249            (speed > dmasound.mach.max_dsp_speed))
250                 speed = dmasound.mach.max_dsp_speed ;
251 
252         dmasound.soft.speed = speed;
253 
254         if (dmasound.minDev == SND_DEV_DSP)
255                 dmasound.dsp.speed = dmasound.soft.speed;
256 
257         return dmasound.soft.speed;
258 }
259 
260 static int sound_set_stereo(int stereo)
261 {
262         if (stereo < 0)
263                 return dmasound.soft.stereo;
264 
265         stereo = !!stereo;    /* should be 0 or 1 now */
266 
267         dmasound.soft.stereo = stereo;
268         if (dmasound.minDev == SND_DEV_DSP)
269                 dmasound.dsp.stereo = stereo;
270 
271         return stereo;
272 }
273 
274 static ssize_t sound_copy_translate(TRANS *trans, const u_char __user *userPtr,
275                                     size_t userCount, u_char frame[],
276                                     ssize_t *frameUsed, ssize_t frameLeft)
277 {
278         ssize_t (*ct_func)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
279 
280         switch (dmasound.soft.format) {
281             case AFMT_MU_LAW:
282                 ct_func = trans->ct_ulaw;
283                 break;
284             case AFMT_A_LAW:
285                 ct_func = trans->ct_alaw;
286                 break;
287             case AFMT_S8:
288                 ct_func = trans->ct_s8;
289                 break;
290             case AFMT_U8:
291                 ct_func = trans->ct_u8;
292                 break;
293             case AFMT_S16_BE:
294                 ct_func = trans->ct_s16be;
295                 break;
296             case AFMT_U16_BE:
297                 ct_func = trans->ct_u16be;
298                 break;
299             case AFMT_S16_LE:
300                 ct_func = trans->ct_s16le;
301                 break;
302             case AFMT_U16_LE:
303                 ct_func = trans->ct_u16le;
304                 break;
305             default:
306                 return 0;
307         }
308         /* if the user has requested a non-existent translation don't try
309            to call it but just return 0 bytes moved
310         */
311         if (ct_func)
312                 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
313         return 0;
314 }
315 
316     /*
317      *  /dev/mixer abstraction
318      */
319 
320 static struct {
321     int busy;
322     int modify_counter;
323 } mixer;
324 
325 static int mixer_open(struct inode *inode, struct file *file)
326 {
327         mutex_lock(&dmasound_core_mutex);
328         if (!try_module_get(dmasound.mach.owner)) {
329                 mutex_unlock(&dmasound_core_mutex);
330                 return -ENODEV;
331         }
332         mixer.busy = 1;
333         mutex_unlock(&dmasound_core_mutex);
334         return 0;
335 }
336 
337 static int mixer_release(struct inode *inode, struct file *file)
338 {
339         mutex_lock(&dmasound_core_mutex);
340         mixer.busy = 0;
341         module_put(dmasound.mach.owner);
342         mutex_unlock(&dmasound_core_mutex);
343         return 0;
344 }
345 
346 static int mixer_ioctl(struct file *file, u_int cmd, u_long arg)
347 {
348         if (_SIOC_DIR(cmd) & _SIOC_WRITE)
349             mixer.modify_counter++;
350         switch (cmd) {
351             case OSS_GETVERSION:
352                 return IOCTL_OUT(arg, SOUND_VERSION);
353             case SOUND_MIXER_INFO:
354                 {
355                     mixer_info info;
356                     memset(&info, 0, sizeof(info));
357                     strscpy(info.id, dmasound.mach.name2, sizeof(info.id));
358                     strscpy(info.name, dmasound.mach.name2, sizeof(info.name));
359                     info.modify_counter = mixer.modify_counter;
360                     if (copy_to_user((void __user *)arg, &info, sizeof(info)))
361                             return -EFAULT;
362                     return 0;
363                 }
364         }
365         if (dmasound.mach.mixer_ioctl)
366             return dmasound.mach.mixer_ioctl(cmd, arg);
367         return -EINVAL;
368 }
369 
370 static long mixer_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
371 {
372         int ret;
373 
374         mutex_lock(&dmasound_core_mutex);
375         ret = mixer_ioctl(file, cmd, arg);
376         mutex_unlock(&dmasound_core_mutex);
377 
378         return ret;
379 }
380 
381 static const struct file_operations mixer_fops =
382 {
383         .owner          = THIS_MODULE,
384         .llseek         = no_llseek,
385         .unlocked_ioctl = mixer_unlocked_ioctl,
386         .compat_ioctl   = compat_ptr_ioctl,
387         .open           = mixer_open,
388         .release        = mixer_release,
389 };
390 
391 static void mixer_init(void)
392 {
393         mixer_unit = register_sound_mixer(&mixer_fops, -1);
394         if (mixer_unit < 0)
395                 return;
396 
397         mixer.busy = 0;
398         dmasound.treble = 0;
399         dmasound.bass = 0;
400         if (dmasound.mach.mixer_init)
401             dmasound.mach.mixer_init();
402 }
403 
404 
405     /*
406      *  Sound queue stuff, the heart of the driver
407      */
408 
409 struct sound_queue dmasound_write_sq;
410 static void sq_reset_output(void) ;
411 
412 static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
413 {
414         int i;
415 
416         if (sq->buffers)
417                 return 0;
418         sq->numBufs = num;
419         sq->bufSize = size;
420         sq->buffers = kmalloc_array (num, sizeof(char *), GFP_KERNEL);
421         if (!sq->buffers)
422                 return -ENOMEM;
423         for (i = 0; i < num; i++) {
424                 sq->buffers[i] = dmasound.mach.dma_alloc(size, GFP_KERNEL);
425                 if (!sq->buffers[i]) {
426                         while (i--)
427                                 dmasound.mach.dma_free(sq->buffers[i], size);
428                         kfree(sq->buffers);
429                         sq->buffers = NULL;
430                         return -ENOMEM;
431                 }
432         }
433         return 0;
434 }
435 
436 static void sq_release_buffers(struct sound_queue *sq)
437 {
438         int i;
439 
440         if (sq->buffers) {
441                 for (i = 0; i < sq->numBufs; i++)
442                         dmasound.mach.dma_free(sq->buffers[i], sq->bufSize);
443                 kfree(sq->buffers);
444                 sq->buffers = NULL;
445         }
446 }
447 
448 
449 static int sq_setup(struct sound_queue *sq)
450 {
451         int (*setup_func)(void) = NULL;
452         int hard_frame ;
453 
454         if (sq->locked) { /* are we already set? - and not changeable */
455 #ifdef DEBUG_DMASOUND
456 printk("dmasound_core: tried to sq_setup a locked queue\n") ;
457 #endif
458                 return -EINVAL ;
459         }
460         sq->locked = 1 ; /* don't think we have a race prob. here _check_ */
461 
462         /* make sure that the parameters are set up
463            This should have been done already...
464         */
465 
466         dmasound.mach.init();
467 
468         /* OK.  If the user has set fragment parameters explicitly, then we
469            should leave them alone... as long as they are valid.
470            Invalid user fragment params can occur if we allow the whole buffer
471            to be used when the user requests the fragments sizes (with no soft
472            x-lation) and then the user subsequently sets a soft x-lation that
473            requires increased internal buffering.
474 
475            Othwerwise (if the user did not set them) OSS says that we should
476            select frag params on the basis of 0.5 s output & 0.1 s input
477            latency. (TODO.  For now we will copy in the defaults.)
478         */
479 
480         if (sq->user_frags <= 0) {
481                 sq->max_count = sq->numBufs ;
482                 sq->max_active = sq->numBufs ;
483                 sq->block_size = sq->bufSize;
484                 /* set up the user info */
485                 sq->user_frags = sq->numBufs ;
486                 sq->user_frag_size = sq->bufSize ;
487                 sq->user_frag_size *=
488                         (dmasound.soft.size * (dmasound.soft.stereo+1) ) ;
489                 sq->user_frag_size /=
490                         (dmasound.hard.size * (dmasound.hard.stereo+1) ) ;
491         } else {
492                 /* work out requested block size */
493                 sq->block_size = sq->user_frag_size ;
494                 sq->block_size *=
495                         (dmasound.hard.size * (dmasound.hard.stereo+1) ) ;
496                 sq->block_size /=
497                         (dmasound.soft.size * (dmasound.soft.stereo+1) ) ;
498                 /* the user wants to write frag-size chunks */
499                 sq->block_size *= dmasound.hard.speed ;
500                 sq->block_size /= dmasound.soft.speed ;
501                 /* this only works for size values which are powers of 2 */
502                 hard_frame =
503                         (dmasound.hard.size * (dmasound.hard.stereo+1))/8 ;
504                 sq->block_size +=  (hard_frame - 1) ;
505                 sq->block_size &= ~(hard_frame - 1) ; /* make sure we are aligned */
506                 /* let's just check for obvious mistakes */
507                 if ( sq->block_size <= 0 || sq->block_size > sq->bufSize) {
508 #ifdef DEBUG_DMASOUND
509 printk("dmasound_core: invalid frag size (user set %d)\n", sq->user_frag_size) ;
510 #endif
511                         sq->block_size = sq->bufSize ;
512                 }
513                 if ( sq->user_frags <= sq->numBufs ) {
514                         sq->max_count = sq->user_frags ;
515                         /* if user has set max_active - then use it */
516                         sq->max_active = (sq->max_active <= sq->max_count) ?
517                                 sq->max_active : sq->max_count ;
518                 } else {
519 #ifdef DEBUG_DMASOUND
520 printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ;
521 #endif
522                         sq->max_count =
523                         sq->max_active = sq->numBufs ;
524                 }
525         }
526         sq->front = sq->count = sq->rear_size = 0;
527         sq->syncing = 0;
528         sq->active = 0;
529 
530         if (sq == &write_sq) {
531             sq->rear = -1;
532             setup_func = dmasound.mach.write_sq_setup;
533         }
534         if (setup_func)
535             return setup_func();
536         return 0 ;
537 }
538 
539 static inline void sq_play(void)
540 {
541         dmasound.mach.play();
542 }
543 
544 static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft,
545                         loff_t *ppos)
546 {
547         ssize_t uWritten = 0;
548         u_char *dest;
549         ssize_t uUsed = 0, bUsed, bLeft;
550         unsigned long flags ;
551 
552         /* ++TeSche: Is something like this necessary?
553          * Hey, that's an honest question! Or does any other part of the
554          * filesystem already checks this situation? I really don't know.
555          */
556         if (uLeft == 0)
557                 return 0;
558 
559         /* implement any changes we have made to the soft/hard params.
560            this is not satisfactory really, all we have done up to now is to
561            say what we would like - there hasn't been any real checking of capability
562         */
563 
564         if (shared_resources_initialised == 0) {
565                 dmasound.mach.init() ;
566                 shared_resources_initialised = 1 ;
567         }
568 
569         /* set up the sq if it is not already done. This may seem a dumb place
570            to do it - but it is what OSS requires.  It means that write() can
571            return memory allocation errors.  To avoid this possibility use the
572            GETBLKSIZE or GETOSPACE ioctls (after you've fiddled with all the
573            params you want to change) - these ioctls also force the setup.
574         */
575 
576         if (write_sq.locked == 0) {
577                 if ((uWritten = sq_setup(&write_sq)) < 0) return uWritten ;
578                 uWritten = 0 ;
579         }
580 
581 /* FIXME: I think that this may be the wrong behaviour when we get strapped
582         for time and the cpu is close to being (or actually) behind in sending data.
583         - because we've lost the time that the N samples, already in the buffer,
584         would have given us to get here with the next lot from the user.
585 */
586         /* The interrupt doesn't start to play the last, incomplete frame.
587          * Thus we can append to it without disabling the interrupts! (Note
588          * also that write_sq.rear isn't affected by the interrupt.)
589          */
590 
591         /* as of 1.6 this behaviour changes if SNDCTL_DSP_POST has been issued:
592            this will mimic the behaviour of syncing and allow the sq_play() to
593            queue a partial fragment.  Since sq_play() may/will be called from
594            the IRQ handler - at least on Pmac we have to deal with it.
595            The strategy - possibly not optimum - is to kill _POST status if we
596            get here.  This seems, at least, reasonable - in the sense that POST
597            is supposed to indicate that we might not write before the queue
598            is drained - and if we get here in time then it does not apply.
599         */
600 
601         spin_lock_irqsave(&dmasound.lock, flags);
602         write_sq.syncing &= ~2 ; /* take out POST status */
603         spin_unlock_irqrestore(&dmasound.lock, flags);
604 
605         if (write_sq.count > 0 &&
606             (bLeft = write_sq.block_size-write_sq.rear_size) > 0) {
607                 dest = write_sq.buffers[write_sq.rear];
608                 bUsed = write_sq.rear_size;
609                 uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
610                                              dest, &bUsed, bLeft);
611                 if (uUsed <= 0)
612                         return uUsed;
613                 src += uUsed;
614                 uWritten += uUsed;
615                 uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ; /* paranoia */
616                 write_sq.rear_size = bUsed;
617         }
618 
619         while (uLeft) {
620                 DEFINE_WAIT(wait);
621 
622                 while (write_sq.count >= write_sq.max_active) {
623                         prepare_to_wait(&write_sq.action_queue, &wait, TASK_INTERRUPTIBLE);
624                         sq_play();
625                         if (write_sq.non_blocking) {
626                                 finish_wait(&write_sq.action_queue, &wait);
627                                 return uWritten > 0 ? uWritten : -EAGAIN;
628                         }
629                         if (write_sq.count < write_sq.max_active)
630                                 break;
631 
632                         schedule_timeout(HZ);
633                         if (signal_pending(current)) {
634                                 finish_wait(&write_sq.action_queue, &wait);
635                                 return uWritten > 0 ? uWritten : -EINTR;
636                         }
637                 }
638 
639                 finish_wait(&write_sq.action_queue, &wait);
640 
641                 /* Here, we can avoid disabling the interrupt by first
642                  * copying and translating the data, and then updating
643                  * the write_sq variables. Until this is done, the interrupt
644                  * won't see the new frame and we can work on it
645                  * undisturbed.
646                  */
647 
648                 dest = write_sq.buffers[(write_sq.rear+1) % write_sq.max_count];
649                 bUsed = 0;
650                 bLeft = write_sq.block_size;
651                 uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
652                                              dest, &bUsed, bLeft);
653                 if (uUsed <= 0)
654                         break;
655                 src += uUsed;
656                 uWritten += uUsed;
657                 uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ; /* paranoia */
658                 if (bUsed) {
659                         write_sq.rear = (write_sq.rear+1) % write_sq.max_count;
660                         write_sq.rear_size = bUsed;
661                         write_sq.count++;
662                 }
663         } /* uUsed may have been 0 */
664 
665         sq_play();
666 
667         return uUsed < 0? uUsed: uWritten;
668 }
669 
670 static __poll_t sq_poll(struct file *file, struct poll_table_struct *wait)
671 {
672         __poll_t mask = 0;
673         int retVal;
674         
675         if (write_sq.locked == 0) {
676                 if ((retVal = sq_setup(&write_sq)) < 0)
677                         return retVal;
678                 return 0;
679         }
680         if (file->f_mode & FMODE_WRITE )
681                 poll_wait(file, &write_sq.action_queue, wait);
682         if (file->f_mode & FMODE_WRITE)
683                 if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0)
684                         mask |= EPOLLOUT | EPOLLWRNORM;
685         return mask;
686 
687 }
688 
689 static inline void sq_init_waitqueue(struct sound_queue *sq)
690 {
691         init_waitqueue_head(&sq->action_queue);
692         init_waitqueue_head(&sq->open_queue);
693         init_waitqueue_head(&sq->sync_queue);
694         sq->busy = 0;
695 }
696 
697 #if 0 /* blocking open() */
698 static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
699                               fmode_t mode)
700 {
701         if (file->f_mode & mode) {
702                 sq->busy = 0; /* CHECK: IS THIS OK??? */
703                 WAKE_UP(sq->open_queue);
704         }
705 }
706 #endif
707 
708 static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode,
709                     int numbufs, int bufsize)
710 {
711         int rc = 0;
712 
713         if (file->f_mode & mode) {
714                 if (sq->busy) {
715 #if 0 /* blocking open() */
716                         rc = -EBUSY;
717                         if (file->f_flags & O_NONBLOCK)
718                                 return rc;
719                         rc = -EINTR;
720                         if (wait_event_interruptible(sq->open_queue, !sq->busy))
721                                 return rc;
722                         rc = 0;
723 #else
724                         /* OSS manual says we will return EBUSY regardless
725                            of O_NOBLOCK.
726                         */
727                         return -EBUSY ;
728 #endif
729                 }
730                 sq->busy = 1; /* Let's play spot-the-race-condition */
731 
732                 /* allocate the default number & size of buffers.
733                    (i.e. specified in _setup() or as module params)
734                    can't be changed at the moment - but _could_ be perhaps
735                    in the setfragments ioctl.
736                 */
737                 if (( rc = sq_allocate_buffers(sq, numbufs, bufsize))) {
738 #if 0 /* blocking open() */
739                         sq_wake_up(sq, file, mode);
740 #else
741                         sq->busy = 0 ;
742 #endif
743                         return rc;
744                 }
745 
746                 sq->non_blocking = file->f_flags & O_NONBLOCK;
747         }
748         return rc;
749 }
750 
751 #define write_sq_init_waitqueue()       sq_init_waitqueue(&write_sq)
752 #if 0 /* blocking open() */
753 #define write_sq_wake_up(file)          sq_wake_up(&write_sq, file, FMODE_WRITE)
754 #endif
755 #define write_sq_release_buffers()      sq_release_buffers(&write_sq)
756 #define write_sq_open(file)     \
757         sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
758 
759 static int sq_open(struct inode *inode, struct file *file)
760 {
761         int rc;
762 
763         mutex_lock(&dmasound_core_mutex);
764         if (!try_module_get(dmasound.mach.owner)) {
765                 mutex_unlock(&dmasound_core_mutex);
766                 return -ENODEV;
767         }
768 
769         rc = write_sq_open(file); /* checks the f_mode */
770         if (rc)
771                 goto out;
772         if (file->f_mode & FMODE_READ) {
773                 /* TODO: if O_RDWR, release any resources grabbed by write part */
774                 rc = -ENXIO ; /* I think this is what is required by open(2) */
775                 goto out;
776         }
777 
778         if (dmasound.mach.sq_open)
779             dmasound.mach.sq_open(file->f_mode);
780 
781         /* CHECK whether this is sensible - in the case that dsp0 could be opened
782           O_RDONLY and dsp1 could be opened O_WRONLY
783         */
784 
785         dmasound.minDev = iminor(inode) & 0x0f;
786 
787         /* OK. - we should make some attempt at consistency. At least the H'ware
788            options should be set with a valid mode.  We will make it that the LL
789            driver must supply defaults for hard & soft params.
790         */
791 
792         if (shared_resource_owner == 0) {
793                 /* you can make this AFMT_U8/mono/8K if you want to mimic old
794                    OSS behaviour - while we still have soft translations ;-) */
795                 dmasound.soft = dmasound.mach.default_soft ;
796                 dmasound.dsp = dmasound.mach.default_soft ;
797                 dmasound.hard = dmasound.mach.default_hard ;
798         }
799 
800 #ifndef DMASOUND_STRICT_OSS_COMPLIANCE
801         /* none of the current LL drivers can actually do this "native" at the moment
802            OSS does not really require us to supply /dev/audio if we can't do it.
803         */
804         if (dmasound.minDev == SND_DEV_AUDIO) {
805                 sound_set_speed(8000);
806                 sound_set_stereo(0);
807                 sound_set_format(AFMT_MU_LAW);
808         }
809 #endif
810         mutex_unlock(&dmasound_core_mutex);
811         return 0;
812  out:
813         module_put(dmasound.mach.owner);
814         mutex_unlock(&dmasound_core_mutex);
815         return rc;
816 }
817 
818 static void sq_reset_output(void)
819 {
820         sound_silence(); /* this _must_ stop DMA, we might be about to lose the buffers */
821         write_sq.active = 0;
822         write_sq.count = 0;
823         write_sq.rear_size = 0;
824         /* write_sq.front = (write_sq.rear+1) % write_sq.max_count;*/
825         write_sq.front = 0 ;
826         write_sq.rear = -1 ; /* same as for set-up */
827 
828         /* OK - we can unlock the parameters and fragment settings */
829         write_sq.locked = 0 ;
830         write_sq.user_frags = 0 ;
831         write_sq.user_frag_size = 0 ;
832 }
833 
834 static void sq_reset(void)
835 {
836         sq_reset_output() ;
837         /* we could consider resetting the shared_resources_owner here... but I
838            think it is probably still rather non-obvious to application writer
839         */
840 
841         /* we release everything else though */
842         shared_resources_initialised = 0 ;
843 }
844 
845 static int sq_fsync(void)
846 {
847         int rc = 0;
848         int timeout = 5;
849 
850         write_sq.syncing |= 1;
851         sq_play();      /* there may be an incomplete frame waiting */
852 
853         while (write_sq.active) {
854                 wait_event_interruptible_timeout(write_sq.sync_queue,
855                                                  !write_sq.active, HZ);
856                 if (signal_pending(current)) {
857                         /* While waiting for audio output to drain, an
858                          * interrupt occurred.  Stop audio output immediately
859                          * and clear the queue. */
860                         sq_reset_output();
861                         rc = -EINTR;
862                         break;
863                 }
864                 if (!--timeout) {
865                         printk(KERN_WARNING "dmasound: Timeout draining output\n");
866                         sq_reset_output();
867                         rc = -EIO;
868                         break;
869                 }
870         }
871 
872         /* flag no sync regardless of whether we had a DSP_POST or not */
873         write_sq.syncing = 0 ;
874         return rc;
875 }
876 
877 static int sq_release(struct inode *inode, struct file *file)
878 {
879         int rc = 0;
880 
881         mutex_lock(&dmasound_core_mutex);
882 
883         if (file->f_mode & FMODE_WRITE) {
884                 if (write_sq.busy)
885                         rc = sq_fsync();
886 
887                 sq_reset_output() ; /* make sure dma is stopped and all is quiet */
888                 write_sq_release_buffers();
889                 write_sq.busy = 0;
890         }
891 
892         if (file->f_mode & shared_resource_owner) { /* it's us that has them */
893                 shared_resource_owner = 0 ;
894                 shared_resources_initialised = 0 ;
895                 dmasound.hard = dmasound.mach.default_hard ;
896         }
897 
898         module_put(dmasound.mach.owner);
899 
900 #if 0 /* blocking open() */
901         /* Wake up a process waiting for the queue being released.
902          * Note: There may be several processes waiting for a call
903          * to open() returning. */
904 
905         /* Iain: hmm I don't understand this next comment ... */
906         /* There is probably a DOS atack here. They change the mode flag. */
907         /* XXX add check here,*/
908         read_sq_wake_up(file); /* checks f_mode */
909         write_sq_wake_up(file); /* checks f_mode */
910 #endif /* blocking open() */
911 
912         mutex_unlock(&dmasound_core_mutex);
913 
914         return rc;
915 }
916 
917 /* here we see if we have a right to modify format, channels, size and so on
918    if no-one else has claimed it already then we do...
919 
920    TODO: We might change this to mask O_RDWR such that only one or the other channel
921    is the owner - if we have problems.
922 */
923 
924 static int shared_resources_are_mine(fmode_t md)
925 {
926         if (shared_resource_owner)
927                 return (shared_resource_owner & md) != 0;
928         else {
929                 shared_resource_owner = md ;
930                 return 1 ;
931         }
932 }
933 
934 /* if either queue is locked we must deny the right to change shared params
935 */
936 
937 static int queues_are_quiescent(void)
938 {
939         if (write_sq.locked)
940                 return 0 ;
941         return 1 ;
942 }
943 
944 /* check and set a queue's fragments per user's wishes...
945    we will check against the pre-defined literals and the actual sizes.
946    This is a bit fraught - because soft translations can mess with our
947    buffer requirements *after* this call - OSS says "call setfrags first"
948 */
949 
950 /* It is possible to replace all the -EINVAL returns with an override that
951    just puts the allowable value in.  This may be what many OSS apps require
952 */
953 
954 static int set_queue_frags(struct sound_queue *sq, int bufs, int size)
955 {
956         if (sq->locked) {
957 #ifdef DEBUG_DMASOUND
958 printk("dmasound_core: tried to set_queue_frags on a locked queue\n") ;
959 #endif
960                 return -EINVAL ;
961         }
962 
963         if ((size < MIN_FRAG_SIZE) || (size > MAX_FRAG_SIZE))
964                 return -EINVAL ;
965         size = (1<<size) ; /* now in bytes */
966         if (size > sq->bufSize)
967                 return -EINVAL ; /* this might still not work */
968 
969         if (bufs <= 0)
970                 return -EINVAL ;
971         if (bufs > sq->numBufs) /* the user is allowed say "don't care" with 0x7fff */
972                 bufs = sq->numBufs ;
973 
974         /* there is, currently, no way to specify max_active separately
975            from max_count.  This could be a LL driver issue - I guess
976            if there is a requirement for these values to be different then
977           we will have to pass that info. up to this level.
978         */
979         sq->user_frags =
980         sq->max_active = bufs ;
981         sq->user_frag_size = size ;
982 
983         return 0 ;
984 }
985 
986 static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
987 {
988         int val, result;
989         u_long fmt;
990         int data;
991         int size, nbufs;
992         audio_buf_info info;
993 
994         switch (cmd) {
995         case SNDCTL_DSP_RESET:
996                 sq_reset();
997                 return 0;
998         case SNDCTL_DSP_GETFMTS:
999                 fmt = dmasound.mach.hardware_afmts ; /* this is what OSS says.. */
1000                 return IOCTL_OUT(arg, fmt);
1001         case SNDCTL_DSP_GETBLKSIZE:
1002                 /* this should tell the caller about bytes that the app can
1003                    read/write - the app doesn't care about our internal buffers.
1004                    We force sq_setup() here as per OSS 1.1 (which should
1005                    compute the values necessary).
1006                    Since there is no mechanism to specify read/write separately, for
1007                    fds opened O_RDWR, the write_sq values will, arbitrarily, overwrite
1008                    the read_sq ones.
1009                 */
1010                 size = 0 ;
1011                 if (file->f_mode & FMODE_WRITE) {
1012                         if ( !write_sq.locked )
1013                                 sq_setup(&write_sq) ;
1014                         size = write_sq.user_frag_size ;
1015                 }
1016                 return IOCTL_OUT(arg, size);
1017         case SNDCTL_DSP_POST:
1018                 /* all we are going to do is to tell the LL that any
1019                    partial frags can be queued for output.
1020                    The LL will have to clear this flag when last output
1021                    is queued.
1022                 */
1023                 write_sq.syncing |= 0x2 ;
1024                 sq_play() ;
1025                 return 0 ;
1026         case SNDCTL_DSP_SYNC:
1027                 /* This call, effectively, has the same behaviour as SNDCTL_DSP_RESET
1028                    except that it waits for output to finish before resetting
1029                    everything - read, however, is killed immediately.
1030                 */
1031                 result = 0 ;
1032                 if (file->f_mode & FMODE_WRITE) {
1033                         result = sq_fsync();
1034                         sq_reset_output() ;
1035                 }
1036                 /* if we are the shared resource owner then release them */
1037                 if (file->f_mode & shared_resource_owner)
1038                         shared_resources_initialised = 0 ;
1039                 return result ;
1040         case SOUND_PCM_READ_RATE:
1041                 return IOCTL_OUT(arg, dmasound.soft.speed);
1042         case SNDCTL_DSP_SPEED:
1043                 /* changing this on the fly will have weird effects on the sound.
1044                    Where there are rate conversions implemented in soft form - it
1045                    will cause the _ctx_xxx() functions to be substituted.
1046                    However, there doesn't appear to be any reason to dis-allow it from
1047                    a driver pov.
1048                 */
1049                 if (shared_resources_are_mine(file->f_mode)) {
1050                         IOCTL_IN(arg, data);
1051                         data = sound_set_speed(data) ;
1052                         shared_resources_initialised = 0 ;
1053                         return IOCTL_OUT(arg, data);
1054                 } else
1055                         return -EINVAL ;
1056                 break ;
1057         /* OSS says these next 4 actions are undefined when the device is
1058            busy/active - we will just return -EINVAL.
1059            To be allowed to change one - (a) you have to own the right
1060             (b) the queue(s) must be quiescent
1061         */
1062         case SNDCTL_DSP_STEREO:
1063                 if (shared_resources_are_mine(file->f_mode) &&
1064                     queues_are_quiescent()) {
1065                         IOCTL_IN(arg, data);
1066                         shared_resources_initialised = 0 ;
1067                         return IOCTL_OUT(arg, sound_set_stereo(data));
1068                 } else
1069                         return -EINVAL ;
1070                 break ;
1071         case SOUND_PCM_WRITE_CHANNELS:
1072                 if (shared_resources_are_mine(file->f_mode) &&
1073                     queues_are_quiescent()) {
1074                         IOCTL_IN(arg, data);
1075                         /* the user might ask for 20 channels, we will return 1 or 2 */
1076                         shared_resources_initialised = 0 ;
1077                         return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
1078                 } else
1079                         return -EINVAL ;
1080                 break ;
1081         case SNDCTL_DSP_SETFMT:
1082                 if (shared_resources_are_mine(file->f_mode) &&
1083                     queues_are_quiescent()) {
1084                         int format;
1085                         IOCTL_IN(arg, data);
1086                         shared_resources_initialised = 0 ;
1087                         format = sound_set_format(data);
1088                         result = IOCTL_OUT(arg, format);
1089                         if (result < 0)
1090                                 return result;
1091                         if (format != data && data != AFMT_QUERY)
1092                                 return -EINVAL;
1093                         return 0;
1094                 } else
1095                         return -EINVAL ;
1096         case SNDCTL_DSP_SUBDIVIDE:
1097                 return -EINVAL ;
1098         case SNDCTL_DSP_SETFRAGMENT:
1099                 /* we can do this independently for the two queues - with the
1100                    proviso that for fds opened O_RDWR we cannot separate the
1101                    actions and both queues will be set per the last call.
1102                    NOTE: this does *NOT* actually set the queue up - merely
1103                    registers our intentions.
1104                 */
1105                 IOCTL_IN(arg, data);
1106                 result = 0 ;
1107                 nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */
1108                 size = data & 0xffff;
1109                 if (file->f_mode & FMODE_WRITE) {
1110                         result = set_queue_frags(&write_sq, nbufs, size) ;
1111                         if (result)
1112                                 return result ;
1113                 }
1114                 /* NOTE: this return value is irrelevant - OSS specifically says that
1115                    the value is 'random' and that the user _must_ check the actual
1116                    frags values using SNDCTL_DSP_GETBLKSIZE or similar */
1117                 return IOCTL_OUT(arg, data);
1118         case SNDCTL_DSP_GETOSPACE:
1119                 /*
1120                 */
1121                 if (file->f_mode & FMODE_WRITE) {
1122                         if ( !write_sq.locked )
1123                                 sq_setup(&write_sq) ;
1124                         info.fragments = write_sq.max_active - write_sq.count;
1125                         info.fragstotal = write_sq.max_active;
1126                         info.fragsize = write_sq.user_frag_size;
1127                         info.bytes = info.fragments * info.fragsize;
1128                         if (copy_to_user((void __user *)arg, &info, sizeof(info)))
1129                                 return -EFAULT;
1130                         return 0;
1131                 } else
1132                         return -EINVAL ;
1133                 break ;
1134         case SNDCTL_DSP_GETCAPS:
1135                 val = dmasound.mach.capabilities & 0xffffff00;
1136                 return IOCTL_OUT(arg,val);
1137 
1138         default:
1139                 return mixer_ioctl(file, cmd, arg);
1140         }
1141         return -EINVAL;
1142 }
1143 
1144 static long sq_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
1145 {
1146         int ret;
1147 
1148         mutex_lock(&dmasound_core_mutex);
1149         ret = sq_ioctl(file, cmd, arg);
1150         mutex_unlock(&dmasound_core_mutex);
1151 
1152         return ret;
1153 }
1154 
1155 static const struct file_operations sq_fops =
1156 {
1157         .owner          = THIS_MODULE,
1158         .llseek         = no_llseek,
1159         .write          = sq_write,
1160         .poll           = sq_poll,
1161         .unlocked_ioctl = sq_unlocked_ioctl,
1162         .compat_ioctl   = compat_ptr_ioctl,
1163         .open           = sq_open,
1164         .release        = sq_release,
1165 };
1166 
1167 static int sq_init(void)
1168 {
1169         const struct file_operations *fops = &sq_fops;
1170 
1171         sq_unit = register_sound_dsp(fops, -1);
1172         if (sq_unit < 0) {
1173                 printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
1174                 return sq_unit ;
1175         }
1176 
1177         write_sq_init_waitqueue();
1178 
1179         /* These parameters will be restored for every clean open()
1180          * in the case of multiple open()s (e.g. dsp0 & dsp1) they
1181          * will be set so long as the shared resources have no owner.
1182          */
1183 
1184         if (shared_resource_owner == 0) {
1185                 dmasound.soft = dmasound.mach.default_soft ;
1186                 dmasound.hard = dmasound.mach.default_hard ;
1187                 dmasound.dsp = dmasound.mach.default_soft ;
1188                 shared_resources_initialised = 0 ;
1189         }
1190         return 0 ;
1191 }
1192 
1193 
1194     /*
1195      *  /dev/sndstat
1196      */
1197 
1198 /* we allow more space for record-enabled because there are extra output lines.
1199    the number here must include the amount we are prepared to give to the low-level
1200    driver.
1201 */
1202 
1203 #define STAT_BUFF_LEN 768
1204 
1205 /* this is how much space we will allow the low-level driver to use
1206    in the stat buffer.  Currently, 2 * (80 character line + <NL>).
1207    We do not police this (it is up to the ll driver to be honest).
1208 */
1209 
1210 #define LOW_LEVEL_STAT_ALLOC 162
1211 
1212 static struct {
1213     int busy;
1214     char buf[STAT_BUFF_LEN];    /* state.buf should not overflow! */
1215     int len, ptr;
1216 } state;
1217 
1218 /* publish this function for use by low-level code, if required */
1219 
1220 static char *get_afmt_string(int afmt)
1221 {
1222         switch(afmt) {
1223             case AFMT_MU_LAW:
1224                 return "mu-law";
1225             case AFMT_A_LAW:
1226                 return "A-law";
1227             case AFMT_U8:
1228                 return "unsigned 8 bit";
1229             case AFMT_S8:
1230                 return "signed 8 bit";
1231             case AFMT_S16_BE:
1232                 return "signed 16 bit BE";
1233             case AFMT_U16_BE:
1234                 return "unsigned 16 bit BE";
1235             case AFMT_S16_LE:
1236                 return "signed 16 bit LE";
1237             case AFMT_U16_LE:
1238                 return "unsigned 16 bit LE";
1239             case 0:
1240                 return "format not set" ;
1241             default:
1242                 break ;
1243         }
1244         return "ERROR: Unsupported AFMT_XXXX code" ;
1245 }
1246 
1247 static int state_open(struct inode *inode, struct file *file)
1248 {
1249         char *buffer = state.buf;
1250         int len = 0;
1251         int ret;
1252 
1253         mutex_lock(&dmasound_core_mutex);
1254         ret = -EBUSY;
1255         if (state.busy)
1256                 goto out;
1257 
1258         ret = -ENODEV;
1259         if (!try_module_get(dmasound.mach.owner))
1260                 goto out;
1261 
1262         state.ptr = 0;
1263         state.busy = 1;
1264 
1265         len += sprintf(buffer+len, "%sDMA sound driver rev %03d :\n",
1266                 dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +
1267                 ((dmasound.mach.version>>8) & 0x0f));
1268         len += sprintf(buffer+len,
1269                 "Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
1270                 DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,
1271                 (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
1272 
1273         /* call the low-level module to fill in any stat info. that it has
1274            if present.  Maximum buffer usage is specified.
1275         */
1276 
1277         if (dmasound.mach.state_info)
1278                 len += dmasound.mach.state_info(buffer+len,
1279                         (size_t) LOW_LEVEL_STAT_ALLOC) ;
1280 
1281         /* make usage of the state buffer as deterministic as poss.
1282            exceptional conditions could cause overrun - and this is flagged as
1283            a kernel error.
1284         */
1285 
1286         /* formats and settings */
1287 
1288         len += sprintf(buffer+len,"\t\t === Formats & settings ===\n") ;
1289         len += sprintf(buffer+len,"Parameter %20s%20s\n","soft","hard") ;
1290         len += sprintf(buffer+len,"Format   :%20s%20s\n",
1291                 get_afmt_string(dmasound.soft.format),
1292                 get_afmt_string(dmasound.hard.format));
1293 
1294         len += sprintf(buffer+len,"Samp Rate:%14d s/sec%14d s/sec\n",
1295                        dmasound.soft.speed, dmasound.hard.speed);
1296 
1297         len += sprintf(buffer+len,"Channels :%20s%20s\n",
1298                        dmasound.soft.stereo ? "stereo" : "mono",
1299                        dmasound.hard.stereo ? "stereo" : "mono" );
1300 
1301         /* sound queue status */
1302 
1303         len += sprintf(buffer+len,"\t\t === Sound Queue status ===\n");
1304         len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;
1305         len += sprintf(buffer+len,"%9s:%8d%6d\n",
1306                 "write", write_sq.numBufs, write_sq.bufSize) ;
1307         len += sprintf(buffer+len,
1308                 "Current  : MaxFrg FragSiz MaxAct Frnt Rear "
1309                 "Cnt RrSize A B S L  xruns\n") ;
1310         len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
1311                 "write", write_sq.max_count, write_sq.block_size,
1312                 write_sq.max_active, write_sq.front, write_sq.rear,
1313                 write_sq.count, write_sq.rear_size, write_sq.active,
1314                 write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;
1315 #ifdef DEBUG_DMASOUND
1316 printk("dmasound: stat buffer used %d bytes\n", len) ;
1317 #endif
1318 
1319         if (len >= STAT_BUFF_LEN)
1320                 printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n");
1321 
1322         state.len = len;
1323         ret = 0;
1324 out:
1325         mutex_unlock(&dmasound_core_mutex);
1326         return ret;
1327 }
1328 
1329 static int state_release(struct inode *inode, struct file *file)
1330 {
1331         mutex_lock(&dmasound_core_mutex);
1332         state.busy = 0;
1333         module_put(dmasound.mach.owner);
1334         mutex_unlock(&dmasound_core_mutex);
1335         return 0;
1336 }
1337 
1338 static ssize_t state_read(struct file *file, char __user *buf, size_t count,
1339                           loff_t *ppos)
1340 {
1341         int n = state.len - state.ptr;
1342         if (n > count)
1343                 n = count;
1344         if (n <= 0)
1345                 return 0;
1346         if (copy_to_user(buf, &state.buf[state.ptr], n))
1347                 return -EFAULT;
1348         state.ptr += n;
1349         return n;
1350 }
1351 
1352 static const struct file_operations state_fops = {
1353         .owner          = THIS_MODULE,
1354         .llseek         = no_llseek,
1355         .read           = state_read,
1356         .open           = state_open,
1357         .release        = state_release,
1358 };
1359 
1360 static int state_init(void)
1361 {
1362         state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
1363         if (state_unit < 0)
1364                 return state_unit ;
1365         state.busy = 0;
1366         return 0 ;
1367 }
1368 
1369 
1370     /*
1371      *  Config & Setup
1372      *
1373      *  This function is called by _one_ chipset-specific driver
1374      */
1375 
1376 int dmasound_init(void)
1377 {
1378         int res ;
1379 
1380         if (irq_installed)
1381                 return -EBUSY;
1382 
1383         /* Set up sound queue, /dev/audio and /dev/dsp. */
1384 
1385         /* Set default settings. */
1386         if ((res = sq_init()) < 0)
1387                 return res ;
1388 
1389         /* Set up /dev/sndstat. */
1390         if ((res = state_init()) < 0)
1391                 return res ;
1392 
1393         /* Set up /dev/mixer. */
1394         mixer_init();
1395 
1396         if (!dmasound.mach.irqinit()) {
1397                 printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
1398                 return -ENODEV;
1399         }
1400         irq_installed = 1;
1401 
1402         printk(KERN_INFO "%s DMA sound driver rev %03d installed\n",
1403                 dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +
1404                 ((dmasound.mach.version>>8) & 0x0f));
1405         printk(KERN_INFO
1406                 "Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
1407                 DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,
1408                 (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
1409         printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
1410                 numWriteBufs, writeBufSize) ;
1411         return 0;
1412 }
1413 
1414 void dmasound_deinit(void)
1415 {
1416         if (irq_installed) {
1417                 sound_silence();
1418                 dmasound.mach.irqcleanup();
1419                 irq_installed = 0;
1420         }
1421 
1422         write_sq_release_buffers();
1423 
1424         if (mixer_unit >= 0)
1425                 unregister_sound_mixer(mixer_unit);
1426         if (state_unit >= 0)
1427                 unregister_sound_special(state_unit);
1428         if (sq_unit >= 0)
1429                 unregister_sound_dsp(sq_unit);
1430 }
1431 
1432 static int __maybe_unused dmasound_setup(char *str)
1433 {
1434         int ints[6], size;
1435 
1436         str = get_options(str, ARRAY_SIZE(ints), ints);
1437 
1438         /* check the bootstrap parameter for "dmasound=" */
1439 
1440         /* FIXME: other than in the most naive of cases there is no sense in these
1441          *        buffers being other than powers of two.  This is not checked yet.
1442          */
1443 
1444         switch (ints[0]) {
1445         case 3:
1446                 if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
1447                         printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
1448                 else
1449                         catchRadius = ints[3];
1450                 fallthrough;
1451         case 2:
1452                 if (ints[1] < MIN_BUFFERS)
1453                         printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
1454                 else
1455                         numWriteBufs = ints[1];
1456                 fallthrough;
1457         case 1:
1458                 if ((size = ints[2]) < 256) /* check for small buffer specs */
1459                         size <<= 10 ;
1460                 if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
1461                         printk("dmasound_setup: invalid write buffer size, using default = %d\n", writeBufSize);
1462                 else
1463                         writeBufSize = size;
1464         case 0:
1465                 break;
1466         default:
1467                 printk("dmasound_setup: invalid number of arguments\n");
1468                 return 0;
1469         }
1470         return 1;
1471 }
1472 
1473 __setup("dmasound=", dmasound_setup);
1474 
1475     /*
1476      *  Conversion tables
1477      */
1478 
1479 #ifdef HAS_8BIT_TABLES
1480 /* 8 bit mu-law */
1481 
1482 char dmasound_ulaw2dma8[] = {
1483         -126,   -122,   -118,   -114,   -110,   -106,   -102,   -98,
1484         -94,    -90,    -86,    -82,    -78,    -74,    -70,    -66,
1485         -63,    -61,    -59,    -57,    -55,    -53,    -51,    -49,
1486         -47,    -45,    -43,    -41,    -39,    -37,    -35,    -33,
1487         -31,    -30,    -29,    -28,    -27,    -26,    -25,    -24,
1488         -23,    -22,    -21,    -20,    -19,    -18,    -17,    -16,
1489         -16,    -15,    -15,    -14,    -14,    -13,    -13,    -12,
1490         -12,    -11,    -11,    -10,    -10,    -9,     -9,     -8,
1491         -8,     -8,     -7,     -7,     -7,     -7,     -6,     -6,
1492         -6,     -6,     -5,     -5,     -5,     -5,     -4,     -4,
1493         -4,     -4,     -4,     -4,     -3,     -3,     -3,     -3,
1494         -3,     -3,     -3,     -3,     -2,     -2,     -2,     -2,
1495         -2,     -2,     -2,     -2,     -2,     -2,     -2,     -2,
1496         -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
1497         -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
1498         -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,
1499         125,    121,    117,    113,    109,    105,    101,    97,
1500         93,     89,     85,     81,     77,     73,     69,     65,
1501         62,     60,     58,     56,     54,     52,     50,     48,
1502         46,     44,     42,     40,     38,     36,     34,     32,
1503         30,     29,     28,     27,     26,     25,     24,     23,
1504         22,     21,     20,     19,     18,     17,     16,     15,
1505         15,     14,     14,     13,     13,     12,     12,     11,
1506         11,     10,     10,     9,      9,      8,      8,      7,
1507         7,      7,      6,      6,      6,      6,      5,      5,
1508         5,      5,      4,      4,      4,      4,      3,      3,
1509         3,      3,      3,      3,      2,      2,      2,      2,
1510         2,      2,      2,      2,      1,      1,      1,      1,
1511         1,      1,      1,      1,      1,      1,      1,      1,
1512         0,      0,      0,      0,      0,      0,      0,      0,
1513         0,      0,      0,      0,      0,      0,      0,      0,
1514         0,      0,      0,      0,      0,      0,      0,      0
1515 };
1516 
1517 /* 8 bit A-law */
1518 
1519 char dmasound_alaw2dma8[] = {
1520         -22,    -21,    -24,    -23,    -18,    -17,    -20,    -19,
1521         -30,    -29,    -32,    -31,    -26,    -25,    -28,    -27,
1522         -11,    -11,    -12,    -12,    -9,     -9,     -10,    -10,
1523         -15,    -15,    -16,    -16,    -13,    -13,    -14,    -14,
1524         -86,    -82,    -94,    -90,    -70,    -66,    -78,    -74,
1525         -118,   -114,   -126,   -122,   -102,   -98,    -110,   -106,
1526         -43,    -41,    -47,    -45,    -35,    -33,    -39,    -37,
1527         -59,    -57,    -63,    -61,    -51,    -49,    -55,    -53,
1528         -2,     -2,     -2,     -2,     -2,     -2,     -2,     -2,
1529         -2,     -2,     -2,     -2,     -2,     -2,     -2,     -2,
1530         -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
1531         -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
1532         -6,     -6,     -6,     -6,     -5,     -5,     -5,     -5,
1533         -8,     -8,     -8,     -8,     -7,     -7,     -7,     -7,
1534         -3,     -3,     -3,     -3,     -3,     -3,     -3,     -3,
1535         -4,     -4,     -4,     -4,     -4,     -4,     -4,     -4,
1536         21,     20,     23,     22,     17,     16,     19,     18,
1537         29,     28,     31,     30,     25,     24,     27,     26,
1538         10,     10,     11,     11,     8,      8,      9,      9,
1539         14,     14,     15,     15,     12,     12,     13,     13,
1540         86,     82,     94,     90,     70,     66,     78,     74,
1541         118,    114,    126,    122,    102,    98,     110,    106,
1542         43,     41,     47,     45,     35,     33,     39,     37,
1543         59,     57,     63,     61,     51,     49,     55,     53,
1544         1,      1,      1,      1,      1,      1,      1,      1,
1545         1,      1,      1,      1,      1,      1,      1,      1,
1546         0,      0,      0,      0,      0,      0,      0,      0,
1547         0,      0,      0,      0,      0,      0,      0,      0,
1548         5,      5,      5,      5,      4,      4,      4,      4,
1549         7,      7,      7,      7,      6,      6,      6,      6,
1550         2,      2,      2,      2,      2,      2,      2,      2,
1551         3,      3,      3,      3,      3,      3,      3,      3
1552 };
1553 #endif /* HAS_8BIT_TABLES */
1554 
1555     /*
1556      *  Visible symbols for modules
1557      */
1558 
1559 EXPORT_SYMBOL(dmasound);
1560 EXPORT_SYMBOL(dmasound_init);
1561 EXPORT_SYMBOL(dmasound_deinit);
1562 EXPORT_SYMBOL(dmasound_write_sq);
1563 EXPORT_SYMBOL(dmasound_catchRadius);
1564 #ifdef HAS_8BIT_TABLES
1565 EXPORT_SYMBOL(dmasound_ulaw2dma8);
1566 EXPORT_SYMBOL(dmasound_alaw2dma8);
1567 #endif
1568 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php