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