OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [sound/] [dmasound/] [dmasound_core.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.