Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *  linux/sound/oss/dmasound/dmasound_core.c
0003  *
0004  *
0005  *  OSS/Free compatible Atari TT/Falcon and Amiga DMA sound driver for
0006  *  Linux/m68k
0007  *  Extended to support Power Macintosh for Linux/ppc by Paul Mackerras
0008  *
0009  *  (c) 1995 by Michael Schlueter & Michael Marte
0010  *
0011  *  Michael Schlueter (michael@duck.syd.de) did the basic structure of the VFS
0012  *  interface and the u-law to signed byte conversion.
0013  *
0014  *  Michael Marte (marte@informatik.uni-muenchen.de) did the sound queue,
0015  *  /dev/mixer, /dev/sndstat and complemented the VFS interface. He would like
0016  *  to thank:
0017  *    - Michael Schlueter for initial ideas and documentation on the MFP and
0018  *  the DMA sound hardware.
0019  *    - Therapy? for their CD 'Troublegum' which really made me rock.
0020  *
0021  *  /dev/sndstat is based on code by Hannu Savolainen, the author of the
0022  *  VoxWare family of drivers.
0023  *
0024  *  This file is subject to the terms and conditions of the GNU General Public
0025  *  License.  See the file COPYING in the main directory of this archive
0026  *  for more details.
0027  *
0028  *  History:
0029  *
0030  *  1995/8/25   First release
0031  *
0032  *  1995/9/02   Roman Hodek:
0033  *            - Fixed atari_stram_alloc() call, the timer
0034  *              programming and several race conditions
0035  *  1995/9/14   Roman Hodek:
0036  *            - After some discussion with Michael Schlueter,
0037  *              revised the interrupt disabling
0038  *            - Slightly speeded up U8->S8 translation by using
0039  *              long operations where possible
0040  *            - Added 4:3 interpolation for /dev/audio
0041  *
0042  *  1995/9/20   Torsten Scherer:
0043  *            - Fixed a bug in sq_write and changed /dev/audio
0044  *              converting to play at 12517Hz instead of 6258Hz.
0045  *
0046  *  1995/9/23   Torsten Scherer:
0047  *            - Changed sq_interrupt() and sq_play() to pre-program
0048  *              the DMA for another frame while there's still one
0049  *              running. This allows the IRQ response to be
0050  *              arbitrarily delayed and playing will still continue.
0051  *
0052  *  1995/10/14  Guenther Kelleter, Torsten Scherer:
0053  *            - Better support for Falcon audio (the Falcon doesn't
0054  *              raise an IRQ at the end of a frame, but at the
0055  *              beginning instead!). uses 'if (codec_dma)' in lots
0056  *              of places to simply switch between Falcon and TT
0057  *              code.
0058  *
0059  *  1995/11/06  Torsten Scherer:
0060  *            - Started introducing a hardware abstraction scheme
0061  *              (may perhaps also serve for Amigas?)
0062  *            - Can now play samples at almost all frequencies by
0063  *              means of a more generalized expand routine
0064  *            - Takes a good deal of care to cut data only at
0065  *              sample sizes
0066  *            - Buffer size is now a kernel runtime option
0067  *            - Implemented fsync() & several minor improvements
0068  *          Guenther Kelleter:
0069  *            - Useful hints and bug fixes
0070  *            - Cross-checked it for Falcons
0071  *
0072  *  1996/3/9    Geert Uytterhoeven:
0073  *            - Support added for Amiga, A-law, 16-bit little
0074  *              endian.
0075  *            - Unification to drivers/sound/dmasound.c.
0076  *
0077  *  1996/4/6    Martin Mitchell:
0078  *            - Updated to 1.3 kernel.
0079  *
0080  *  1996/6/13       Topi Kanerva:
0081  *            - Fixed things that were broken (mainly the amiga
0082  *              14-bit routines)
0083  *            - /dev/sndstat shows now the real hardware frequency
0084  *            - The lowpass filter is disabled by default now
0085  *
0086  *  1996/9/25   Geert Uytterhoeven:
0087  *            - Modularization
0088  *
0089  *  1998/6/10   Andreas Schwab:
0090  *            - Converted to use sound_core
0091  *
0092  *  1999/12/28  Richard Zidlicky:
0093  *            - Added support for Q40
0094  *
0095  *  2000/2/27   Geert Uytterhoeven:
0096  *            - Clean up and split the code into 4 parts:
0097  *                o dmasound_core: machine-independent code
0098  *                o dmasound_atari: Atari TT and Falcon support
0099  *                o dmasound_awacs: Apple PowerMac support
0100  *                o dmasound_paula: Amiga support
0101  *
0102  *  2000/3/25   Geert Uytterhoeven:
0103  *            - Integration of dmasound_q40
0104  *            - Small clean ups
0105  *
0106  *  2001/01/26 [1.0] Iain Sandoe
0107  *            - make /dev/sndstat show revision & edition info.
0108  *            - since dmasound.mach.sq_setup() can fail on pmac
0109  *              its type has been changed to int and the returns
0110  *              are checked.
0111  *         [1.1]  - stop missing translations from being called.
0112  *  2001/02/08 [1.2]  - remove unused translation tables & move machine-
0113  *              specific tables to low-level.
0114  *            - return correct info. for SNDCTL_DSP_GETFMTS.
0115  *         [1.3]  - implement SNDCTL_DSP_GETCAPS fully.
0116  *         [1.4]  - make /dev/sndstat text length usage deterministic.
0117  *            - make /dev/sndstat call to low-level
0118  *              dmasound.mach.state_info() pass max space to ll driver.
0119  *            - tidy startup banners and output info.
0120  *         [1.5]  - tidy up a little (removed some unused #defines in
0121  *              dmasound.h)
0122  *            - fix up HAS_RECORD conditionalisation.
0123  *            - add record code in places it is missing...
0124  *            - change buf-sizes to bytes to allow < 1kb for pmac
0125  *              if user param entry is < 256 the value is taken to
0126  *              be in kb > 256 is taken to be in bytes.
0127  *            - make default buff/frag params conditional on
0128  *              machine to allow smaller values for pmac.
0129  *            - made the ioctls, read & write comply with the OSS
0130  *              rules on setting params.
0131  *            - added parsing of _setup() params for record.
0132  *  2001/04/04 [1.6]  - fix bug where sample rates higher than maximum were
0133  *              being reported as OK.
0134  *            - fix open() to return -EBUSY as per OSS doc. when
0135  *              audio is in use - this is independent of O_NOBLOCK.
0136  *            - fix bug where SNDCTL_DSP_POST was blocking.
0137  */
0138 
0139  /* Record capability notes 30/01/2001:
0140   * At present these observations apply only to pmac LL driver (the only one
0141   * that can do record, at present).  However, if other LL drivers for machines
0142   * with record are added they may apply.
0143   *
0144   * The fragment parameters for the record and play channels are separate.
0145   * However, if the driver is opened O_RDWR there is no way (in the current OSS
0146   * API) to specify their values independently for the record and playback
0147   * channels.  Since the only common factor between the input & output is the
0148   * sample rate (on pmac) it should be possible to open /dev/dspX O_WRONLY and
0149   * /dev/dspY O_RDONLY.  The input & output channels could then have different
0150   * characteristics (other than the first that sets sample rate claiming the
0151   * right to set it for ever).  As it stands, the format, channels, number of
0152   * bits & sample rate are assumed to be common.  In the future perhaps these
0153   * should be the responsibility of the LL driver - and then if a card really
0154   * does not share items between record & playback they can be specified
0155   * separately.
0156 */
0157 
0158 /* Thread-safeness of shared_resources notes: 31/01/2001
0159  * If the user opens O_RDWR and then splits record & play between two threads
0160  * both of which inherit the fd - and then starts changing things from both
0161  * - we will have difficulty telling.
0162  *
0163  * It's bad application coding - but ...
0164  * TODO: think about how to sort this out... without bogging everything down in
0165  * semaphores.
0166  *
0167  * Similarly, the OSS spec says "all changes to parameters must be between
0168  * open() and the first read() or write(). - and a bit later on (by
0169  * implication) "between SNDCTL_DSP_RESET and the first read() or write() after
0170  * it".  If the app is multi-threaded and this rule is broken between threads
0171  * we will have trouble spotting it - and the fault will be rather obscure :-(
0172  *
0173  * We will try and put out at least a kmsg if we see it happen... but I think
0174  * it will be quite hard to trap it with an -EXXX return... because we can't
0175  * see the fault until after the damage is done.
0176 */
0177 
0178 #include <linux/module.h>
0179 #include <linux/slab.h>
0180 #include <linux/sound.h>
0181 #include <linux/init.h>
0182 #include <linux/soundcard.h>
0183 #include <linux/poll.h>
0184 #include <linux/mutex.h>
0185 #include <linux/sched/signal.h>
0186 
0187 #include <linux/uaccess.h>
0188 
0189 #include "dmasound.h"
0190 
0191 #define DMASOUND_CORE_REVISION 1
0192 #define DMASOUND_CORE_EDITION 6
0193 
0194     /*
0195      *  Declarations
0196      */
0197 
0198 static DEFINE_MUTEX(dmasound_core_mutex);
0199 int dmasound_catchRadius = 0;
0200 module_param(dmasound_catchRadius, int, 0);
0201 
0202 static unsigned int numWriteBufs = DEFAULT_N_BUFFERS;
0203 module_param(numWriteBufs, int, 0);
0204 static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ;  /* in bytes */
0205 module_param(writeBufSize, int, 0);
0206 
0207 MODULE_LICENSE("GPL");
0208 
0209 static int sq_unit = -1;
0210 static int mixer_unit = -1;
0211 static int state_unit = -1;
0212 static int irq_installed;
0213 
0214 /* control over who can modify resources shared between play/record */
0215 static fmode_t shared_resource_owner;
0216 static int shared_resources_initialised;
0217 
0218     /*
0219      *  Mid level stuff
0220      */
0221 
0222 struct sound_settings dmasound = {
0223     .lock = __SPIN_LOCK_UNLOCKED(dmasound.lock)
0224 };
0225 
0226 static inline void sound_silence(void)
0227 {
0228     dmasound.mach.silence(); /* _MUST_ stop DMA */
0229 }
0230 
0231 static inline int sound_set_format(int format)
0232 {
0233     return dmasound.mach.setFormat(format);
0234 }
0235 
0236 
0237 static int sound_set_speed(int speed)
0238 {
0239     if (speed < 0)
0240         return dmasound.soft.speed;
0241 
0242     /* trap out-of-range speed settings.
0243        at present we allow (arbitrarily) low rates - using soft
0244        up-conversion - but we can't allow > max because there is
0245        no soft down-conversion.
0246     */
0247     if (dmasound.mach.max_dsp_speed &&
0248        (speed > dmasound.mach.max_dsp_speed))
0249         speed = dmasound.mach.max_dsp_speed ;
0250 
0251     dmasound.soft.speed = speed;
0252 
0253     if (dmasound.minDev == SND_DEV_DSP)
0254         dmasound.dsp.speed = dmasound.soft.speed;
0255 
0256     return dmasound.soft.speed;
0257 }
0258 
0259 static int sound_set_stereo(int stereo)
0260 {
0261     if (stereo < 0)
0262         return dmasound.soft.stereo;
0263 
0264     stereo = !!stereo;    /* should be 0 or 1 now */
0265 
0266     dmasound.soft.stereo = stereo;
0267     if (dmasound.minDev == SND_DEV_DSP)
0268         dmasound.dsp.stereo = stereo;
0269 
0270     return stereo;
0271 }
0272 
0273 static ssize_t sound_copy_translate(TRANS *trans, const u_char __user *userPtr,
0274                     size_t userCount, u_char frame[],
0275                     ssize_t *frameUsed, ssize_t frameLeft)
0276 {
0277     ssize_t (*ct_func)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
0278 
0279     switch (dmasound.soft.format) {
0280         case AFMT_MU_LAW:
0281         ct_func = trans->ct_ulaw;
0282         break;
0283         case AFMT_A_LAW:
0284         ct_func = trans->ct_alaw;
0285         break;
0286         case AFMT_S8:
0287         ct_func = trans->ct_s8;
0288         break;
0289         case AFMT_U8:
0290         ct_func = trans->ct_u8;
0291         break;
0292         case AFMT_S16_BE:
0293         ct_func = trans->ct_s16be;
0294         break;
0295         case AFMT_U16_BE:
0296         ct_func = trans->ct_u16be;
0297         break;
0298         case AFMT_S16_LE:
0299         ct_func = trans->ct_s16le;
0300         break;
0301         case AFMT_U16_LE:
0302         ct_func = trans->ct_u16le;
0303         break;
0304         default:
0305         return 0;
0306     }
0307     /* if the user has requested a non-existent translation don't try
0308        to call it but just return 0 bytes moved
0309     */
0310     if (ct_func)
0311         return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
0312     return 0;
0313 }
0314 
0315     /*
0316      *  /dev/mixer abstraction
0317      */
0318 
0319 static struct {
0320     int busy;
0321     int modify_counter;
0322 } mixer;
0323 
0324 static int mixer_open(struct inode *inode, struct file *file)
0325 {
0326     mutex_lock(&dmasound_core_mutex);
0327     if (!try_module_get(dmasound.mach.owner)) {
0328         mutex_unlock(&dmasound_core_mutex);
0329         return -ENODEV;
0330     }
0331     mixer.busy = 1;
0332     mutex_unlock(&dmasound_core_mutex);
0333     return 0;
0334 }
0335 
0336 static int mixer_release(struct inode *inode, struct file *file)
0337 {
0338     mutex_lock(&dmasound_core_mutex);
0339     mixer.busy = 0;
0340     module_put(dmasound.mach.owner);
0341     mutex_unlock(&dmasound_core_mutex);
0342     return 0;
0343 }
0344 
0345 static int mixer_ioctl(struct file *file, u_int cmd, u_long arg)
0346 {
0347     if (_SIOC_DIR(cmd) & _SIOC_WRITE)
0348         mixer.modify_counter++;
0349     switch (cmd) {
0350         case OSS_GETVERSION:
0351         return IOCTL_OUT(arg, SOUND_VERSION);
0352         case SOUND_MIXER_INFO:
0353         {
0354             mixer_info info;
0355             memset(&info, 0, sizeof(info));
0356             strscpy(info.id, dmasound.mach.name2, sizeof(info.id));
0357             strscpy(info.name, dmasound.mach.name2, sizeof(info.name));
0358             info.modify_counter = mixer.modify_counter;
0359             if (copy_to_user((void __user *)arg, &info, sizeof(info)))
0360                 return -EFAULT;
0361             return 0;
0362         }
0363     }
0364     if (dmasound.mach.mixer_ioctl)
0365         return dmasound.mach.mixer_ioctl(cmd, arg);
0366     return -EINVAL;
0367 }
0368 
0369 static long mixer_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
0370 {
0371     int ret;
0372 
0373     mutex_lock(&dmasound_core_mutex);
0374     ret = mixer_ioctl(file, cmd, arg);
0375     mutex_unlock(&dmasound_core_mutex);
0376 
0377     return ret;
0378 }
0379 
0380 static const struct file_operations mixer_fops =
0381 {
0382     .owner      = THIS_MODULE,
0383     .llseek     = no_llseek,
0384     .unlocked_ioctl = mixer_unlocked_ioctl,
0385     .compat_ioctl   = compat_ptr_ioctl,
0386     .open       = mixer_open,
0387     .release    = mixer_release,
0388 };
0389 
0390 static void mixer_init(void)
0391 {
0392     mixer_unit = register_sound_mixer(&mixer_fops, -1);
0393     if (mixer_unit < 0)
0394         return;
0395 
0396     mixer.busy = 0;
0397     dmasound.treble = 0;
0398     dmasound.bass = 0;
0399     if (dmasound.mach.mixer_init)
0400         dmasound.mach.mixer_init();
0401 }
0402 
0403 
0404     /*
0405      *  Sound queue stuff, the heart of the driver
0406      */
0407 
0408 struct sound_queue dmasound_write_sq;
0409 static void sq_reset_output(void) ;
0410 
0411 static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
0412 {
0413     int i;
0414 
0415     if (sq->buffers)
0416         return 0;
0417     sq->numBufs = num;
0418     sq->bufSize = size;
0419     sq->buffers = kmalloc_array (num, sizeof(char *), GFP_KERNEL);
0420     if (!sq->buffers)
0421         return -ENOMEM;
0422     for (i = 0; i < num; i++) {
0423         sq->buffers[i] = dmasound.mach.dma_alloc(size, GFP_KERNEL);
0424         if (!sq->buffers[i]) {
0425             while (i--)
0426                 dmasound.mach.dma_free(sq->buffers[i], size);
0427             kfree(sq->buffers);
0428             sq->buffers = NULL;
0429             return -ENOMEM;
0430         }
0431     }
0432     return 0;
0433 }
0434 
0435 static void sq_release_buffers(struct sound_queue *sq)
0436 {
0437     int i;
0438 
0439     if (sq->buffers) {
0440         for (i = 0; i < sq->numBufs; i++)
0441             dmasound.mach.dma_free(sq->buffers[i], sq->bufSize);
0442         kfree(sq->buffers);
0443         sq->buffers = NULL;
0444     }
0445 }
0446 
0447 
0448 static int sq_setup(struct sound_queue *sq)
0449 {
0450     int (*setup_func)(void) = NULL;
0451     int hard_frame ;
0452 
0453     if (sq->locked) { /* are we already set? - and not changeable */
0454 #ifdef DEBUG_DMASOUND
0455 printk("dmasound_core: tried to sq_setup a locked queue\n") ;
0456 #endif
0457         return -EINVAL ;
0458     }
0459     sq->locked = 1 ; /* don't think we have a race prob. here _check_ */
0460 
0461     /* make sure that the parameters are set up
0462        This should have been done already...
0463     */
0464 
0465     dmasound.mach.init();
0466 
0467     /* OK.  If the user has set fragment parameters explicitly, then we
0468        should leave them alone... as long as they are valid.
0469        Invalid user fragment params can occur if we allow the whole buffer
0470        to be used when the user requests the fragments sizes (with no soft
0471        x-lation) and then the user subsequently sets a soft x-lation that
0472        requires increased internal buffering.
0473 
0474        Othwerwise (if the user did not set them) OSS says that we should
0475        select frag params on the basis of 0.5 s output & 0.1 s input
0476        latency. (TODO.  For now we will copy in the defaults.)
0477     */
0478 
0479     if (sq->user_frags <= 0) {
0480         sq->max_count = sq->numBufs ;
0481         sq->max_active = sq->numBufs ;
0482         sq->block_size = sq->bufSize;
0483         /* set up the user info */
0484         sq->user_frags = sq->numBufs ;
0485         sq->user_frag_size = sq->bufSize ;
0486         sq->user_frag_size *=
0487             (dmasound.soft.size * (dmasound.soft.stereo+1) ) ;
0488         sq->user_frag_size /=
0489             (dmasound.hard.size * (dmasound.hard.stereo+1) ) ;
0490     } else {
0491         /* work out requested block size */
0492         sq->block_size = sq->user_frag_size ;
0493         sq->block_size *=
0494             (dmasound.hard.size * (dmasound.hard.stereo+1) ) ;
0495         sq->block_size /=
0496             (dmasound.soft.size * (dmasound.soft.stereo+1) ) ;
0497         /* the user wants to write frag-size chunks */
0498         sq->block_size *= dmasound.hard.speed ;
0499         sq->block_size /= dmasound.soft.speed ;
0500         /* this only works for size values which are powers of 2 */
0501         hard_frame =
0502             (dmasound.hard.size * (dmasound.hard.stereo+1))/8 ;
0503         sq->block_size +=  (hard_frame - 1) ;
0504         sq->block_size &= ~(hard_frame - 1) ; /* make sure we are aligned */
0505         /* let's just check for obvious mistakes */
0506         if ( sq->block_size <= 0 || sq->block_size > sq->bufSize) {
0507 #ifdef DEBUG_DMASOUND
0508 printk("dmasound_core: invalid frag size (user set %d)\n", sq->user_frag_size) ;
0509 #endif
0510             sq->block_size = sq->bufSize ;
0511         }
0512         if ( sq->user_frags <= sq->numBufs ) {
0513             sq->max_count = sq->user_frags ;
0514             /* if user has set max_active - then use it */
0515             sq->max_active = (sq->max_active <= sq->max_count) ?
0516                 sq->max_active : sq->max_count ;
0517         } else {
0518 #ifdef DEBUG_DMASOUND
0519 printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ;
0520 #endif
0521             sq->max_count =
0522             sq->max_active = sq->numBufs ;
0523         }
0524     }
0525     sq->front = sq->count = sq->rear_size = 0;
0526     sq->syncing = 0;
0527     sq->active = 0;
0528 
0529     if (sq == &write_sq) {
0530         sq->rear = -1;
0531         setup_func = dmasound.mach.write_sq_setup;
0532     }
0533     if (setup_func)
0534         return setup_func();
0535     return 0 ;
0536 }
0537 
0538 static inline void sq_play(void)
0539 {
0540     dmasound.mach.play();
0541 }
0542 
0543 static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft,
0544             loff_t *ppos)
0545 {
0546     ssize_t uWritten = 0;
0547     u_char *dest;
0548     ssize_t uUsed = 0, bUsed, bLeft;
0549     unsigned long flags ;
0550 
0551     /* ++TeSche: Is something like this necessary?
0552      * Hey, that's an honest question! Or does any other part of the
0553      * filesystem already checks this situation? I really don't know.
0554      */
0555     if (uLeft == 0)
0556         return 0;
0557 
0558     /* implement any changes we have made to the soft/hard params.
0559        this is not satisfactory really, all we have done up to now is to
0560        say what we would like - there hasn't been any real checking of capability
0561     */
0562 
0563     if (shared_resources_initialised == 0) {
0564         dmasound.mach.init() ;
0565         shared_resources_initialised = 1 ;
0566     }
0567 
0568     /* set up the sq if it is not already done. This may seem a dumb place
0569        to do it - but it is what OSS requires.  It means that write() can
0570        return memory allocation errors.  To avoid this possibility use the
0571        GETBLKSIZE or GETOSPACE ioctls (after you've fiddled with all the
0572        params you want to change) - these ioctls also force the setup.
0573     */
0574 
0575     if (write_sq.locked == 0) {
0576         if ((uWritten = sq_setup(&write_sq)) < 0) return uWritten ;
0577         uWritten = 0 ;
0578     }
0579 
0580 /* FIXME: I think that this may be the wrong behaviour when we get strapped
0581     for time and the cpu is close to being (or actually) behind in sending data.
0582     - because we've lost the time that the N samples, already in the buffer,
0583     would have given us to get here with the next lot from the user.
0584 */
0585     /* The interrupt doesn't start to play the last, incomplete frame.
0586      * Thus we can append to it without disabling the interrupts! (Note
0587      * also that write_sq.rear isn't affected by the interrupt.)
0588      */
0589 
0590     /* as of 1.6 this behaviour changes if SNDCTL_DSP_POST has been issued:
0591        this will mimic the behaviour of syncing and allow the sq_play() to
0592        queue a partial fragment.  Since sq_play() may/will be called from
0593        the IRQ handler - at least on Pmac we have to deal with it.
0594        The strategy - possibly not optimum - is to kill _POST status if we
0595        get here.  This seems, at least, reasonable - in the sense that POST
0596        is supposed to indicate that we might not write before the queue
0597        is drained - and if we get here in time then it does not apply.
0598     */
0599 
0600     spin_lock_irqsave(&dmasound.lock, flags);
0601     write_sq.syncing &= ~2 ; /* take out POST status */
0602     spin_unlock_irqrestore(&dmasound.lock, flags);
0603 
0604     if (write_sq.count > 0 &&
0605         (bLeft = write_sq.block_size-write_sq.rear_size) > 0) {
0606         dest = write_sq.buffers[write_sq.rear];
0607         bUsed = write_sq.rear_size;
0608         uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
0609                          dest, &bUsed, bLeft);
0610         if (uUsed <= 0)
0611             return uUsed;
0612         src += uUsed;
0613         uWritten += uUsed;
0614         uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ; /* paranoia */
0615         write_sq.rear_size = bUsed;
0616     }
0617 
0618     while (uLeft) {
0619         DEFINE_WAIT(wait);
0620 
0621         while (write_sq.count >= write_sq.max_active) {
0622             prepare_to_wait(&write_sq.action_queue, &wait, TASK_INTERRUPTIBLE);
0623             sq_play();
0624             if (write_sq.non_blocking) {
0625                 finish_wait(&write_sq.action_queue, &wait);
0626                 return uWritten > 0 ? uWritten : -EAGAIN;
0627             }
0628             if (write_sq.count < write_sq.max_active)
0629                 break;
0630 
0631             schedule_timeout(HZ);
0632             if (signal_pending(current)) {
0633                 finish_wait(&write_sq.action_queue, &wait);
0634                 return uWritten > 0 ? uWritten : -EINTR;
0635             }
0636         }
0637 
0638         finish_wait(&write_sq.action_queue, &wait);
0639 
0640         /* Here, we can avoid disabling the interrupt by first
0641          * copying and translating the data, and then updating
0642          * the write_sq variables. Until this is done, the interrupt
0643          * won't see the new frame and we can work on it
0644          * undisturbed.
0645          */
0646 
0647         dest = write_sq.buffers[(write_sq.rear+1) % write_sq.max_count];
0648         bUsed = 0;
0649         bLeft = write_sq.block_size;
0650         uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
0651                          dest, &bUsed, bLeft);
0652         if (uUsed <= 0)
0653             break;
0654         src += uUsed;
0655         uWritten += uUsed;
0656         uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ; /* paranoia */
0657         if (bUsed) {
0658             write_sq.rear = (write_sq.rear+1) % write_sq.max_count;
0659             write_sq.rear_size = bUsed;
0660             write_sq.count++;
0661         }
0662     } /* uUsed may have been 0 */
0663 
0664     sq_play();
0665 
0666     return uUsed < 0? uUsed: uWritten;
0667 }
0668 
0669 static __poll_t sq_poll(struct file *file, struct poll_table_struct *wait)
0670 {
0671     __poll_t mask = 0;
0672     int retVal;
0673     
0674     if (write_sq.locked == 0) {
0675         if ((retVal = sq_setup(&write_sq)) < 0)
0676             return retVal;
0677         return 0;
0678     }
0679     if (file->f_mode & FMODE_WRITE )
0680         poll_wait(file, &write_sq.action_queue, wait);
0681     if (file->f_mode & FMODE_WRITE)
0682         if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0)
0683             mask |= EPOLLOUT | EPOLLWRNORM;
0684     return mask;
0685 
0686 }
0687 
0688 static inline void sq_init_waitqueue(struct sound_queue *sq)
0689 {
0690     init_waitqueue_head(&sq->action_queue);
0691     init_waitqueue_head(&sq->open_queue);
0692     init_waitqueue_head(&sq->sync_queue);
0693     sq->busy = 0;
0694 }
0695 
0696 #if 0 /* blocking open() */
0697 static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
0698                   fmode_t mode)
0699 {
0700     if (file->f_mode & mode) {
0701         sq->busy = 0; /* CHECK: IS THIS OK??? */
0702         WAKE_UP(sq->open_queue);
0703     }
0704 }
0705 #endif
0706 
0707 static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode,
0708             int numbufs, int bufsize)
0709 {
0710     int rc = 0;
0711 
0712     if (file->f_mode & mode) {
0713         if (sq->busy) {
0714 #if 0 /* blocking open() */
0715             rc = -EBUSY;
0716             if (file->f_flags & O_NONBLOCK)
0717                 return rc;
0718             rc = -EINTR;
0719             if (wait_event_interruptible(sq->open_queue, !sq->busy))
0720                 return rc;
0721             rc = 0;
0722 #else
0723             /* OSS manual says we will return EBUSY regardless
0724                of O_NOBLOCK.
0725             */
0726             return -EBUSY ;
0727 #endif
0728         }
0729         sq->busy = 1; /* Let's play spot-the-race-condition */
0730 
0731         /* allocate the default number & size of buffers.
0732            (i.e. specified in _setup() or as module params)
0733            can't be changed at the moment - but _could_ be perhaps
0734            in the setfragments ioctl.
0735         */
0736         if (( rc = sq_allocate_buffers(sq, numbufs, bufsize))) {
0737 #if 0 /* blocking open() */
0738             sq_wake_up(sq, file, mode);
0739 #else
0740             sq->busy = 0 ;
0741 #endif
0742             return rc;
0743         }
0744 
0745         sq->non_blocking = file->f_flags & O_NONBLOCK;
0746     }
0747     return rc;
0748 }
0749 
0750 #define write_sq_init_waitqueue()   sq_init_waitqueue(&write_sq)
0751 #if 0 /* blocking open() */
0752 #define write_sq_wake_up(file)      sq_wake_up(&write_sq, file, FMODE_WRITE)
0753 #endif
0754 #define write_sq_release_buffers()  sq_release_buffers(&write_sq)
0755 #define write_sq_open(file) \
0756     sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
0757 
0758 static int sq_open(struct inode *inode, struct file *file)
0759 {
0760     int rc;
0761 
0762     mutex_lock(&dmasound_core_mutex);
0763     if (!try_module_get(dmasound.mach.owner)) {
0764         mutex_unlock(&dmasound_core_mutex);
0765         return -ENODEV;
0766     }
0767 
0768     rc = write_sq_open(file); /* checks the f_mode */
0769     if (rc)
0770         goto out;
0771     if (file->f_mode & FMODE_READ) {
0772         /* TODO: if O_RDWR, release any resources grabbed by write part */
0773         rc = -ENXIO ; /* I think this is what is required by open(2) */
0774         goto out;
0775     }
0776 
0777     if (dmasound.mach.sq_open)
0778         dmasound.mach.sq_open(file->f_mode);
0779 
0780     /* CHECK whether this is sensible - in the case that dsp0 could be opened
0781       O_RDONLY and dsp1 could be opened O_WRONLY
0782     */
0783 
0784     dmasound.minDev = iminor(inode) & 0x0f;
0785 
0786     /* OK. - we should make some attempt at consistency. At least the H'ware
0787        options should be set with a valid mode.  We will make it that the LL
0788        driver must supply defaults for hard & soft params.
0789     */
0790 
0791     if (shared_resource_owner == 0) {
0792         /* you can make this AFMT_U8/mono/8K if you want to mimic old
0793            OSS behaviour - while we still have soft translations ;-) */
0794         dmasound.soft = dmasound.mach.default_soft ;
0795         dmasound.dsp = dmasound.mach.default_soft ;
0796         dmasound.hard = dmasound.mach.default_hard ;
0797     }
0798 
0799 #ifndef DMASOUND_STRICT_OSS_COMPLIANCE
0800     /* none of the current LL drivers can actually do this "native" at the moment
0801        OSS does not really require us to supply /dev/audio if we can't do it.
0802     */
0803     if (dmasound.minDev == SND_DEV_AUDIO) {
0804         sound_set_speed(8000);
0805         sound_set_stereo(0);
0806         sound_set_format(AFMT_MU_LAW);
0807     }
0808 #endif
0809     mutex_unlock(&dmasound_core_mutex);
0810     return 0;
0811  out:
0812     module_put(dmasound.mach.owner);
0813     mutex_unlock(&dmasound_core_mutex);
0814     return rc;
0815 }
0816 
0817 static void sq_reset_output(void)
0818 {
0819     sound_silence(); /* this _must_ stop DMA, we might be about to lose the buffers */
0820     write_sq.active = 0;
0821     write_sq.count = 0;
0822     write_sq.rear_size = 0;
0823     /* write_sq.front = (write_sq.rear+1) % write_sq.max_count;*/
0824     write_sq.front = 0 ;
0825     write_sq.rear = -1 ; /* same as for set-up */
0826 
0827     /* OK - we can unlock the parameters and fragment settings */
0828     write_sq.locked = 0 ;
0829     write_sq.user_frags = 0 ;
0830     write_sq.user_frag_size = 0 ;
0831 }
0832 
0833 static void sq_reset(void)
0834 {
0835     sq_reset_output() ;
0836     /* we could consider resetting the shared_resources_owner here... but I
0837        think it is probably still rather non-obvious to application writer
0838     */
0839 
0840     /* we release everything else though */
0841     shared_resources_initialised = 0 ;
0842 }
0843 
0844 static int sq_fsync(void)
0845 {
0846     int rc = 0;
0847     int timeout = 5;
0848 
0849     write_sq.syncing |= 1;
0850     sq_play();  /* there may be an incomplete frame waiting */
0851 
0852     while (write_sq.active) {
0853         wait_event_interruptible_timeout(write_sq.sync_queue,
0854                          !write_sq.active, HZ);
0855         if (signal_pending(current)) {
0856             /* While waiting for audio output to drain, an
0857              * interrupt occurred.  Stop audio output immediately
0858              * and clear the queue. */
0859             sq_reset_output();
0860             rc = -EINTR;
0861             break;
0862         }
0863         if (!--timeout) {
0864             printk(KERN_WARNING "dmasound: Timeout draining output\n");
0865             sq_reset_output();
0866             rc = -EIO;
0867             break;
0868         }
0869     }
0870 
0871     /* flag no sync regardless of whether we had a DSP_POST or not */
0872     write_sq.syncing = 0 ;
0873     return rc;
0874 }
0875 
0876 static int sq_release(struct inode *inode, struct file *file)
0877 {
0878     int rc = 0;
0879 
0880     mutex_lock(&dmasound_core_mutex);
0881 
0882     if (file->f_mode & FMODE_WRITE) {
0883         if (write_sq.busy)
0884             rc = sq_fsync();
0885 
0886         sq_reset_output() ; /* make sure dma is stopped and all is quiet */
0887         write_sq_release_buffers();
0888         write_sq.busy = 0;
0889     }
0890 
0891     if (file->f_mode & shared_resource_owner) { /* it's us that has them */
0892         shared_resource_owner = 0 ;
0893         shared_resources_initialised = 0 ;
0894         dmasound.hard = dmasound.mach.default_hard ;
0895     }
0896 
0897     module_put(dmasound.mach.owner);
0898 
0899 #if 0 /* blocking open() */
0900     /* Wake up a process waiting for the queue being released.
0901      * Note: There may be several processes waiting for a call
0902      * to open() returning. */
0903 
0904     /* Iain: hmm I don't understand this next comment ... */
0905     /* There is probably a DOS atack here. They change the mode flag. */
0906     /* XXX add check here,*/
0907     read_sq_wake_up(file); /* checks f_mode */
0908     write_sq_wake_up(file); /* checks f_mode */
0909 #endif /* blocking open() */
0910 
0911     mutex_unlock(&dmasound_core_mutex);
0912 
0913     return rc;
0914 }
0915 
0916 /* here we see if we have a right to modify format, channels, size and so on
0917    if no-one else has claimed it already then we do...
0918 
0919    TODO: We might change this to mask O_RDWR such that only one or the other channel
0920    is the owner - if we have problems.
0921 */
0922 
0923 static int shared_resources_are_mine(fmode_t md)
0924 {
0925     if (shared_resource_owner)
0926         return (shared_resource_owner & md) != 0;
0927     else {
0928         shared_resource_owner = md ;
0929         return 1 ;
0930     }
0931 }
0932 
0933 /* if either queue is locked we must deny the right to change shared params
0934 */
0935 
0936 static int queues_are_quiescent(void)
0937 {
0938     if (write_sq.locked)
0939         return 0 ;
0940     return 1 ;
0941 }
0942 
0943 /* check and set a queue's fragments per user's wishes...
0944    we will check against the pre-defined literals and the actual sizes.
0945    This is a bit fraught - because soft translations can mess with our
0946    buffer requirements *after* this call - OSS says "call setfrags first"
0947 */
0948 
0949 /* It is possible to replace all the -EINVAL returns with an override that
0950    just puts the allowable value in.  This may be what many OSS apps require
0951 */
0952 
0953 static int set_queue_frags(struct sound_queue *sq, int bufs, int size)
0954 {
0955     if (sq->locked) {
0956 #ifdef DEBUG_DMASOUND
0957 printk("dmasound_core: tried to set_queue_frags on a locked queue\n") ;
0958 #endif
0959         return -EINVAL ;
0960     }
0961 
0962     if ((size < MIN_FRAG_SIZE) || (size > MAX_FRAG_SIZE))
0963         return -EINVAL ;
0964     size = (1<<size) ; /* now in bytes */
0965     if (size > sq->bufSize)
0966         return -EINVAL ; /* this might still not work */
0967 
0968     if (bufs <= 0)
0969         return -EINVAL ;
0970     if (bufs > sq->numBufs) /* the user is allowed say "don't care" with 0x7fff */
0971         bufs = sq->numBufs ;
0972 
0973     /* there is, currently, no way to specify max_active separately
0974        from max_count.  This could be a LL driver issue - I guess
0975        if there is a requirement for these values to be different then
0976       we will have to pass that info. up to this level.
0977     */
0978     sq->user_frags =
0979     sq->max_active = bufs ;
0980     sq->user_frag_size = size ;
0981 
0982     return 0 ;
0983 }
0984 
0985 static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
0986 {
0987     int val, result;
0988     u_long fmt;
0989     int data;
0990     int size, nbufs;
0991     audio_buf_info info;
0992 
0993     switch (cmd) {
0994     case SNDCTL_DSP_RESET:
0995         sq_reset();
0996         return 0;
0997     case SNDCTL_DSP_GETFMTS:
0998         fmt = dmasound.mach.hardware_afmts ; /* this is what OSS says.. */
0999         return IOCTL_OUT(arg, fmt);
1000     case SNDCTL_DSP_GETBLKSIZE:
1001         /* this should tell the caller about bytes that the app can
1002            read/write - the app doesn't care about our internal buffers.
1003            We force sq_setup() here as per OSS 1.1 (which should
1004            compute the values necessary).
1005            Since there is no mechanism to specify read/write separately, for
1006            fds opened O_RDWR, the write_sq values will, arbitrarily, overwrite
1007            the read_sq ones.
1008         */
1009         size = 0 ;
1010         if (file->f_mode & FMODE_WRITE) {
1011             if ( !write_sq.locked )
1012                 sq_setup(&write_sq) ;
1013             size = write_sq.user_frag_size ;
1014         }
1015         return IOCTL_OUT(arg, size);
1016     case SNDCTL_DSP_POST:
1017         /* all we are going to do is to tell the LL that any
1018            partial frags can be queued for output.
1019            The LL will have to clear this flag when last output
1020            is queued.
1021         */
1022         write_sq.syncing |= 0x2 ;
1023         sq_play() ;
1024         return 0 ;
1025     case SNDCTL_DSP_SYNC:
1026         /* This call, effectively, has the same behaviour as SNDCTL_DSP_RESET
1027            except that it waits for output to finish before resetting
1028            everything - read, however, is killed immediately.
1029         */
1030         result = 0 ;
1031         if (file->f_mode & FMODE_WRITE) {
1032             result = sq_fsync();
1033             sq_reset_output() ;
1034         }
1035         /* if we are the shared resource owner then release them */
1036         if (file->f_mode & shared_resource_owner)
1037             shared_resources_initialised = 0 ;
1038         return result ;
1039     case SOUND_PCM_READ_RATE:
1040         return IOCTL_OUT(arg, dmasound.soft.speed);
1041     case SNDCTL_DSP_SPEED:
1042         /* changing this on the fly will have weird effects on the sound.
1043            Where there are rate conversions implemented in soft form - it
1044            will cause the _ctx_xxx() functions to be substituted.
1045            However, there doesn't appear to be any reason to dis-allow it from
1046            a driver pov.
1047         */
1048         if (shared_resources_are_mine(file->f_mode)) {
1049             IOCTL_IN(arg, data);
1050             data = sound_set_speed(data) ;
1051             shared_resources_initialised = 0 ;
1052             return IOCTL_OUT(arg, data);
1053         } else
1054             return -EINVAL ;
1055         break ;
1056     /* OSS says these next 4 actions are undefined when the device is
1057        busy/active - we will just return -EINVAL.
1058        To be allowed to change one - (a) you have to own the right
1059         (b) the queue(s) must be quiescent
1060     */
1061     case SNDCTL_DSP_STEREO:
1062         if (shared_resources_are_mine(file->f_mode) &&
1063             queues_are_quiescent()) {
1064             IOCTL_IN(arg, data);
1065             shared_resources_initialised = 0 ;
1066             return IOCTL_OUT(arg, sound_set_stereo(data));
1067         } else
1068             return -EINVAL ;
1069         break ;
1070     case SOUND_PCM_WRITE_CHANNELS:
1071         if (shared_resources_are_mine(file->f_mode) &&
1072             queues_are_quiescent()) {
1073             IOCTL_IN(arg, data);
1074             /* the user might ask for 20 channels, we will return 1 or 2 */
1075             shared_resources_initialised = 0 ;
1076             return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
1077         } else
1078             return -EINVAL ;
1079         break ;
1080     case SNDCTL_DSP_SETFMT:
1081         if (shared_resources_are_mine(file->f_mode) &&
1082             queues_are_quiescent()) {
1083                 int format;
1084             IOCTL_IN(arg, data);
1085             shared_resources_initialised = 0 ;
1086             format = sound_set_format(data);
1087             result = IOCTL_OUT(arg, format);
1088             if (result < 0)
1089                 return result;
1090             if (format != data && data != AFMT_QUERY)
1091                 return -EINVAL;
1092             return 0;
1093         } else
1094             return -EINVAL ;
1095     case SNDCTL_DSP_SUBDIVIDE:
1096         return -EINVAL ;
1097     case SNDCTL_DSP_SETFRAGMENT:
1098         /* we can do this independently for the two queues - with the
1099            proviso that for fds opened O_RDWR we cannot separate the
1100            actions and both queues will be set per the last call.
1101            NOTE: this does *NOT* actually set the queue up - merely
1102            registers our intentions.
1103         */
1104         IOCTL_IN(arg, data);
1105         result = 0 ;
1106         nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */
1107         size = data & 0xffff;
1108         if (file->f_mode & FMODE_WRITE) {
1109             result = set_queue_frags(&write_sq, nbufs, size) ;
1110             if (result)
1111                 return result ;
1112         }
1113         /* NOTE: this return value is irrelevant - OSS specifically says that
1114            the value is 'random' and that the user _must_ check the actual
1115            frags values using SNDCTL_DSP_GETBLKSIZE or similar */
1116         return IOCTL_OUT(arg, data);
1117     case SNDCTL_DSP_GETOSPACE:
1118         /*
1119         */
1120         if (file->f_mode & FMODE_WRITE) {
1121             if ( !write_sq.locked )
1122                 sq_setup(&write_sq) ;
1123             info.fragments = write_sq.max_active - write_sq.count;
1124             info.fragstotal = write_sq.max_active;
1125             info.fragsize = write_sq.user_frag_size;
1126             info.bytes = info.fragments * info.fragsize;
1127             if (copy_to_user((void __user *)arg, &info, sizeof(info)))
1128                 return -EFAULT;
1129             return 0;
1130         } else
1131             return -EINVAL ;
1132         break ;
1133     case SNDCTL_DSP_GETCAPS:
1134         val = dmasound.mach.capabilities & 0xffffff00;
1135         return IOCTL_OUT(arg,val);
1136 
1137     default:
1138         return mixer_ioctl(file, cmd, arg);
1139     }
1140     return -EINVAL;
1141 }
1142 
1143 static long sq_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
1144 {
1145     int ret;
1146 
1147     mutex_lock(&dmasound_core_mutex);
1148     ret = sq_ioctl(file, cmd, arg);
1149     mutex_unlock(&dmasound_core_mutex);
1150 
1151     return ret;
1152 }
1153 
1154 static const struct file_operations sq_fops =
1155 {
1156     .owner      = THIS_MODULE,
1157     .llseek     = no_llseek,
1158     .write      = sq_write,
1159     .poll       = sq_poll,
1160     .unlocked_ioctl = sq_unlocked_ioctl,
1161     .compat_ioctl   = compat_ptr_ioctl,
1162     .open       = sq_open,
1163     .release    = sq_release,
1164 };
1165 
1166 static int sq_init(void)
1167 {
1168     const struct file_operations *fops = &sq_fops;
1169 
1170     sq_unit = register_sound_dsp(fops, -1);
1171     if (sq_unit < 0) {
1172         printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
1173         return sq_unit ;
1174     }
1175 
1176     write_sq_init_waitqueue();
1177 
1178     /* These parameters will be restored for every clean open()
1179      * in the case of multiple open()s (e.g. dsp0 & dsp1) they
1180      * will be set so long as the shared resources have no owner.
1181      */
1182 
1183     if (shared_resource_owner == 0) {
1184         dmasound.soft = dmasound.mach.default_soft ;
1185         dmasound.hard = dmasound.mach.default_hard ;
1186         dmasound.dsp = dmasound.mach.default_soft ;
1187         shared_resources_initialised = 0 ;
1188     }
1189     return 0 ;
1190 }
1191 
1192 
1193     /*
1194      *  /dev/sndstat
1195      */
1196 
1197 /* we allow more space for record-enabled because there are extra output lines.
1198    the number here must include the amount we are prepared to give to the low-level
1199    driver.
1200 */
1201 
1202 #define STAT_BUFF_LEN 768
1203 
1204 /* this is how much space we will allow the low-level driver to use
1205    in the stat buffer.  Currently, 2 * (80 character line + <NL>).
1206    We do not police this (it is up to the ll driver to be honest).
1207 */
1208 
1209 #define LOW_LEVEL_STAT_ALLOC 162
1210 
1211 static struct {
1212     int busy;
1213     char buf[STAT_BUFF_LEN];    /* state.buf should not overflow! */
1214     int len, ptr;
1215 } state;
1216 
1217 /* publish this function for use by low-level code, if required */
1218 
1219 static char *get_afmt_string(int afmt)
1220 {
1221         switch(afmt) {
1222             case AFMT_MU_LAW:
1223                 return "mu-law";
1224             case AFMT_A_LAW:
1225                 return "A-law";
1226             case AFMT_U8:
1227                 return "unsigned 8 bit";
1228             case AFMT_S8:
1229                 return "signed 8 bit";
1230             case AFMT_S16_BE:
1231                 return "signed 16 bit BE";
1232             case AFMT_U16_BE:
1233                 return "unsigned 16 bit BE";
1234             case AFMT_S16_LE:
1235                 return "signed 16 bit LE";
1236             case AFMT_U16_LE:
1237                 return "unsigned 16 bit LE";
1238         case 0:
1239         return "format not set" ;
1240             default:
1241                 break ;
1242         }
1243         return "ERROR: Unsupported AFMT_XXXX code" ;
1244 }
1245 
1246 static int state_open(struct inode *inode, struct file *file)
1247 {
1248     char *buffer = state.buf;
1249     int len = 0;
1250     int ret;
1251 
1252     mutex_lock(&dmasound_core_mutex);
1253     ret = -EBUSY;
1254     if (state.busy)
1255         goto out;
1256 
1257     ret = -ENODEV;
1258     if (!try_module_get(dmasound.mach.owner))
1259         goto out;
1260 
1261     state.ptr = 0;
1262     state.busy = 1;
1263 
1264     len += sprintf(buffer+len, "%sDMA sound driver rev %03d :\n",
1265         dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +
1266         ((dmasound.mach.version>>8) & 0x0f));
1267     len += sprintf(buffer+len,
1268         "Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
1269         DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,
1270         (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
1271 
1272     /* call the low-level module to fill in any stat info. that it has
1273        if present.  Maximum buffer usage is specified.
1274     */
1275 
1276     if (dmasound.mach.state_info)
1277         len += dmasound.mach.state_info(buffer+len,
1278             (size_t) LOW_LEVEL_STAT_ALLOC) ;
1279 
1280     /* make usage of the state buffer as deterministic as poss.
1281        exceptional conditions could cause overrun - and this is flagged as
1282        a kernel error.
1283     */
1284 
1285     /* formats and settings */
1286 
1287     len += sprintf(buffer+len,"\t\t === Formats & settings ===\n") ;
1288     len += sprintf(buffer+len,"Parameter %20s%20s\n","soft","hard") ;
1289     len += sprintf(buffer+len,"Format   :%20s%20s\n",
1290         get_afmt_string(dmasound.soft.format),
1291         get_afmt_string(dmasound.hard.format));
1292 
1293     len += sprintf(buffer+len,"Samp Rate:%14d s/sec%14d s/sec\n",
1294                dmasound.soft.speed, dmasound.hard.speed);
1295 
1296     len += sprintf(buffer+len,"Channels :%20s%20s\n",
1297                dmasound.soft.stereo ? "stereo" : "mono",
1298                dmasound.hard.stereo ? "stereo" : "mono" );
1299 
1300     /* sound queue status */
1301 
1302     len += sprintf(buffer+len,"\t\t === Sound Queue status ===\n");
1303     len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;
1304     len += sprintf(buffer+len,"%9s:%8d%6d\n",
1305         "write", write_sq.numBufs, write_sq.bufSize) ;
1306     len += sprintf(buffer+len,
1307         "Current  : MaxFrg FragSiz MaxAct Frnt Rear "
1308         "Cnt RrSize A B S L  xruns\n") ;
1309     len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
1310         "write", write_sq.max_count, write_sq.block_size,
1311         write_sq.max_active, write_sq.front, write_sq.rear,
1312         write_sq.count, write_sq.rear_size, write_sq.active,
1313         write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;
1314 #ifdef DEBUG_DMASOUND
1315 printk("dmasound: stat buffer used %d bytes\n", len) ;
1316 #endif
1317 
1318     if (len >= STAT_BUFF_LEN)
1319         printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n");
1320 
1321     state.len = len;
1322     ret = 0;
1323 out:
1324     mutex_unlock(&dmasound_core_mutex);
1325     return ret;
1326 }
1327 
1328 static int state_release(struct inode *inode, struct file *file)
1329 {
1330     mutex_lock(&dmasound_core_mutex);
1331     state.busy = 0;
1332     module_put(dmasound.mach.owner);
1333     mutex_unlock(&dmasound_core_mutex);
1334     return 0;
1335 }
1336 
1337 static ssize_t state_read(struct file *file, char __user *buf, size_t count,
1338               loff_t *ppos)
1339 {
1340     int n = state.len - state.ptr;
1341     if (n > count)
1342         n = count;
1343     if (n <= 0)
1344         return 0;
1345     if (copy_to_user(buf, &state.buf[state.ptr], n))
1346         return -EFAULT;
1347     state.ptr += n;
1348     return n;
1349 }
1350 
1351 static const struct file_operations state_fops = {
1352     .owner      = THIS_MODULE,
1353     .llseek     = no_llseek,
1354     .read       = state_read,
1355     .open       = state_open,
1356     .release    = state_release,
1357 };
1358 
1359 static int state_init(void)
1360 {
1361     state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
1362     if (state_unit < 0)
1363         return state_unit ;
1364     state.busy = 0;
1365     return 0 ;
1366 }
1367 
1368 
1369     /*
1370      *  Config & Setup
1371      *
1372      *  This function is called by _one_ chipset-specific driver
1373      */
1374 
1375 int dmasound_init(void)
1376 {
1377     int res ;
1378 
1379     if (irq_installed)
1380         return -EBUSY;
1381 
1382     /* Set up sound queue, /dev/audio and /dev/dsp. */
1383 
1384     /* Set default settings. */
1385     if ((res = sq_init()) < 0)
1386         return res ;
1387 
1388     /* Set up /dev/sndstat. */
1389     if ((res = state_init()) < 0)
1390         return res ;
1391 
1392     /* Set up /dev/mixer. */
1393     mixer_init();
1394 
1395     if (!dmasound.mach.irqinit()) {
1396         printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
1397         return -ENODEV;
1398     }
1399     irq_installed = 1;
1400 
1401     printk(KERN_INFO "%s DMA sound driver rev %03d installed\n",
1402         dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +
1403         ((dmasound.mach.version>>8) & 0x0f));
1404     printk(KERN_INFO
1405         "Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
1406         DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,
1407         (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
1408     printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
1409         numWriteBufs, writeBufSize) ;
1410     return 0;
1411 }
1412 
1413 void dmasound_deinit(void)
1414 {
1415     if (irq_installed) {
1416         sound_silence();
1417         dmasound.mach.irqcleanup();
1418         irq_installed = 0;
1419     }
1420 
1421     write_sq_release_buffers();
1422 
1423     if (mixer_unit >= 0)
1424         unregister_sound_mixer(mixer_unit);
1425     if (state_unit >= 0)
1426         unregister_sound_special(state_unit);
1427     if (sq_unit >= 0)
1428         unregister_sound_dsp(sq_unit);
1429 }
1430 
1431 static int __maybe_unused dmasound_setup(char *str)
1432 {
1433     int ints[6], size;
1434 
1435     str = get_options(str, ARRAY_SIZE(ints), ints);
1436 
1437     /* check the bootstrap parameter for "dmasound=" */
1438 
1439     /* FIXME: other than in the most naive of cases there is no sense in these
1440      *    buffers being other than powers of two.  This is not checked yet.
1441      */
1442 
1443     switch (ints[0]) {
1444     case 3:
1445         if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
1446             printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
1447         else
1448             catchRadius = ints[3];
1449         fallthrough;
1450     case 2:
1451         if (ints[1] < MIN_BUFFERS)
1452             printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
1453         else
1454             numWriteBufs = ints[1];
1455         fallthrough;
1456     case 1:
1457         if ((size = ints[2]) < 256) /* check for small buffer specs */
1458             size <<= 10 ;
1459                 if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
1460                         printk("dmasound_setup: invalid write buffer size, using default = %d\n", writeBufSize);
1461                 else
1462                         writeBufSize = size;
1463     case 0:
1464         break;
1465     default:
1466         printk("dmasound_setup: invalid number of arguments\n");
1467         return 0;
1468     }
1469     return 1;
1470 }
1471 
1472 __setup("dmasound=", dmasound_setup);
1473 
1474     /*
1475      *  Conversion tables
1476      */
1477 
1478 #ifdef HAS_8BIT_TABLES
1479 /* 8 bit mu-law */
1480 
1481 char dmasound_ulaw2dma8[] = {
1482     -126,   -122,   -118,   -114,   -110,   -106,   -102,   -98,
1483     -94,    -90,    -86,    -82,    -78,    -74,    -70,    -66,
1484     -63,    -61,    -59,    -57,    -55,    -53,    -51,    -49,
1485     -47,    -45,    -43,    -41,    -39,    -37,    -35,    -33,
1486     -31,    -30,    -29,    -28,    -27,    -26,    -25,    -24,
1487     -23,    -22,    -21,    -20,    -19,    -18,    -17,    -16,
1488     -16,    -15,    -15,    -14,    -14,    -13,    -13,    -12,
1489     -12,    -11,    -11,    -10,    -10,    -9, -9, -8,
1490     -8, -8, -7, -7, -7, -7, -6, -6,
1491     -6, -6, -5, -5, -5, -5, -4, -4,
1492     -4, -4, -4, -4, -3, -3, -3, -3,
1493     -3, -3, -3, -3, -2, -2, -2, -2,
1494     -2, -2, -2, -2, -2, -2, -2, -2,
1495     -1, -1, -1, -1, -1, -1, -1, -1,
1496     -1, -1, -1, -1, -1, -1, -1, -1,
1497     -1, -1, -1, -1, -1, -1, -1, 0,
1498     125,    121,    117,    113,    109,    105,    101,    97,
1499     93, 89, 85, 81, 77, 73, 69, 65,
1500     62, 60, 58, 56, 54, 52, 50, 48,
1501     46, 44, 42, 40, 38, 36, 34, 32,
1502     30, 29, 28, 27, 26, 25, 24, 23,
1503     22, 21, 20, 19, 18, 17, 16, 15,
1504     15, 14, 14, 13, 13, 12, 12, 11,
1505     11, 10, 10, 9,  9,  8,  8,  7,
1506     7,  7,  6,  6,  6,  6,  5,  5,
1507     5,  5,  4,  4,  4,  4,  3,  3,
1508     3,  3,  3,  3,  2,  2,  2,  2,
1509     2,  2,  2,  2,  1,  1,  1,  1,
1510     1,  1,  1,  1,  1,  1,  1,  1,
1511     0,  0,  0,  0,  0,  0,  0,  0,
1512     0,  0,  0,  0,  0,  0,  0,  0,
1513     0,  0,  0,  0,  0,  0,  0,  0
1514 };
1515 
1516 /* 8 bit A-law */
1517 
1518 char dmasound_alaw2dma8[] = {
1519     -22,    -21,    -24,    -23,    -18,    -17,    -20,    -19,
1520     -30,    -29,    -32,    -31,    -26,    -25,    -28,    -27,
1521     -11,    -11,    -12,    -12,    -9, -9, -10,    -10,
1522     -15,    -15,    -16,    -16,    -13,    -13,    -14,    -14,
1523     -86,    -82,    -94,    -90,    -70,    -66,    -78,    -74,
1524     -118,   -114,   -126,   -122,   -102,   -98,    -110,   -106,
1525     -43,    -41,    -47,    -45,    -35,    -33,    -39,    -37,
1526     -59,    -57,    -63,    -61,    -51,    -49,    -55,    -53,
1527     -2, -2, -2, -2, -2, -2, -2, -2,
1528     -2, -2, -2, -2, -2, -2, -2, -2,
1529     -1, -1, -1, -1, -1, -1, -1, -1,
1530     -1, -1, -1, -1, -1, -1, -1, -1,
1531     -6, -6, -6, -6, -5, -5, -5, -5,
1532     -8, -8, -8, -8, -7, -7, -7, -7,
1533     -3, -3, -3, -3, -3, -3, -3, -3,
1534     -4, -4, -4, -4, -4, -4, -4, -4,
1535     21, 20, 23, 22, 17, 16, 19, 18,
1536     29, 28, 31, 30, 25, 24, 27, 26,
1537     10, 10, 11, 11, 8,  8,  9,  9,
1538     14, 14, 15, 15, 12, 12, 13, 13,
1539     86, 82, 94, 90, 70, 66, 78, 74,
1540     118,    114,    126,    122,    102,    98, 110,    106,
1541     43, 41, 47, 45, 35, 33, 39, 37,
1542     59, 57, 63, 61, 51, 49, 55, 53,
1543     1,  1,  1,  1,  1,  1,  1,  1,
1544     1,  1,  1,  1,  1,  1,  1,  1,
1545     0,  0,  0,  0,  0,  0,  0,  0,
1546     0,  0,  0,  0,  0,  0,  0,  0,
1547     5,  5,  5,  5,  4,  4,  4,  4,
1548     7,  7,  7,  7,  6,  6,  6,  6,
1549     2,  2,  2,  2,  2,  2,  2,  2,
1550     3,  3,  3,  3,  3,  3,  3,  3
1551 };
1552 #endif /* HAS_8BIT_TABLES */
1553 
1554     /*
1555      *  Visible symbols for modules
1556      */
1557 
1558 EXPORT_SYMBOL(dmasound);
1559 EXPORT_SYMBOL(dmasound_init);
1560 EXPORT_SYMBOL(dmasound_deinit);
1561 EXPORT_SYMBOL(dmasound_write_sq);
1562 EXPORT_SYMBOL(dmasound_catchRadius);
1563 #ifdef HAS_8BIT_TABLES
1564 EXPORT_SYMBOL(dmasound_ulaw2dma8);
1565 EXPORT_SYMBOL(dmasound_alaw2dma8);
1566 #endif