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