Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/oss/audio.c
10814 views
1
/*
2
* sound/oss/audio.c
3
*
4
* Device file manager for /dev/audio
5
*/
6
7
/*
8
* Copyright (C) by Hannu Savolainen 1993-1997
9
*
10
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
11
* Version 2 (June 1991). See the "COPYING" file distributed with this software
12
* for more info.
13
*/
14
/*
15
* Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
16
* Thomas Sailer : moved several static variables into struct audio_operations
17
* (which is grossly misnamed btw.) because they have the same
18
* lifetime as the rest in there and dynamic allocation saves
19
* 12k or so
20
* Thomas Sailer : use more logical O_NONBLOCK semantics
21
* Daniel Rodriksson: reworked the use of the device specific copy_user
22
* still generic
23
* Horst von Brand: Add missing #include <linux/string.h>
24
* Chris Rankin : Update the module-usage counter for the coprocessor,
25
* and decrement the counters again if we cannot open
26
* the audio device.
27
*/
28
29
#include <linux/stddef.h>
30
#include <linux/string.h>
31
#include <linux/kmod.h>
32
33
#include "sound_config.h"
34
#include "ulaw.h"
35
#include "coproc.h"
36
37
#define NEUTRAL8 0x80
38
#define NEUTRAL16 0x00
39
40
41
static int dma_ioctl(int dev, unsigned int cmd, void __user *arg);
42
43
static int set_format(int dev, int fmt)
44
{
45
if (fmt != AFMT_QUERY)
46
{
47
audio_devs[dev]->local_conversion = 0;
48
49
if (!(audio_devs[dev]->format_mask & fmt)) /* Not supported */
50
{
51
if (fmt == AFMT_MU_LAW)
52
{
53
fmt = AFMT_U8;
54
audio_devs[dev]->local_conversion = CNV_MU_LAW;
55
}
56
else
57
fmt = AFMT_U8; /* This is always supported */
58
}
59
audio_devs[dev]->audio_format = audio_devs[dev]->d->set_bits(dev, fmt);
60
audio_devs[dev]->local_format = fmt;
61
}
62
else
63
return audio_devs[dev]->local_format;
64
65
if (audio_devs[dev]->local_conversion)
66
return audio_devs[dev]->local_conversion;
67
else
68
return audio_devs[dev]->local_format;
69
}
70
71
int audio_open(int dev, struct file *file)
72
{
73
int ret;
74
int bits;
75
int dev_type = dev & 0x0f;
76
int mode = translate_mode(file);
77
const struct audio_driver *driver;
78
const struct coproc_operations *coprocessor;
79
80
dev = dev >> 4;
81
82
if (dev_type == SND_DEV_DSP16)
83
bits = 16;
84
else
85
bits = 8;
86
87
if (dev < 0 || dev >= num_audiodevs)
88
return -ENXIO;
89
90
driver = audio_devs[dev]->d;
91
92
if (!try_module_get(driver->owner))
93
return -ENODEV;
94
95
if ((ret = DMAbuf_open(dev, mode)) < 0)
96
goto error_1;
97
98
if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
99
if (!try_module_get(coprocessor->owner))
100
goto error_2;
101
102
if ((ret = coprocessor->open(coprocessor->devc, COPR_PCM)) < 0) {
103
printk(KERN_WARNING "Sound: Can't access coprocessor device\n");
104
goto error_3;
105
}
106
}
107
108
audio_devs[dev]->local_conversion = 0;
109
110
if (dev_type == SND_DEV_AUDIO)
111
set_format(dev, AFMT_MU_LAW);
112
else
113
set_format(dev, bits);
114
115
audio_devs[dev]->audio_mode = AM_NONE;
116
117
return 0;
118
119
/*
120
* Clean-up stack: this is what needs (un)doing if
121
* we can't open the audio device ...
122
*/
123
error_3:
124
module_put(coprocessor->owner);
125
126
error_2:
127
DMAbuf_release(dev, mode);
128
129
error_1:
130
module_put(driver->owner);
131
132
return ret;
133
}
134
135
static void sync_output(int dev)
136
{
137
int p, i;
138
int l;
139
struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
140
141
if (dmap->fragment_size <= 0)
142
return;
143
dmap->flags |= DMA_POST;
144
145
/* Align the write pointer with fragment boundaries */
146
147
if ((l = dmap->user_counter % dmap->fragment_size) > 0)
148
{
149
int len;
150
unsigned long offs = dmap->user_counter % dmap->bytes_in_use;
151
152
len = dmap->fragment_size - l;
153
memset(dmap->raw_buf + offs, dmap->neutral_byte, len);
154
DMAbuf_move_wrpointer(dev, len);
155
}
156
157
/*
158
* Clean all unused buffer fragments.
159
*/
160
161
p = dmap->qtail;
162
dmap->flags |= DMA_POST;
163
164
for (i = dmap->qlen + 1; i < dmap->nbufs; i++)
165
{
166
p = (p + 1) % dmap->nbufs;
167
if (((dmap->raw_buf + p * dmap->fragment_size) + dmap->fragment_size) >
168
(dmap->raw_buf + dmap->buffsize))
169
printk(KERN_ERR "audio: Buffer error 2\n");
170
171
memset(dmap->raw_buf + p * dmap->fragment_size,
172
dmap->neutral_byte,
173
dmap->fragment_size);
174
}
175
176
dmap->flags |= DMA_DIRTY;
177
}
178
179
void audio_release(int dev, struct file *file)
180
{
181
const struct coproc_operations *coprocessor;
182
int mode = translate_mode(file);
183
184
dev = dev >> 4;
185
186
/*
187
* We do this in DMAbuf_release(). Why are we doing it
188
* here? Why don't we test the file mode before setting
189
* both flags? DMAbuf_release() does.
190
* ...pester...pester...pester...
191
*/
192
audio_devs[dev]->dmap_out->closing = 1;
193
audio_devs[dev]->dmap_in->closing = 1;
194
195
/*
196
* We need to make sure we allocated the dmap_out buffer
197
* before we go mucking around with it in sync_output().
198
*/
199
if (mode & OPEN_WRITE)
200
sync_output(dev);
201
202
if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
203
coprocessor->close(coprocessor->devc, COPR_PCM);
204
module_put(coprocessor->owner);
205
}
206
DMAbuf_release(dev, mode);
207
208
module_put(audio_devs[dev]->d->owner);
209
}
210
211
static void translate_bytes(const unsigned char *table, unsigned char *buff, int n)
212
{
213
unsigned long i;
214
215
if (n <= 0)
216
return;
217
218
for (i = 0; i < n; ++i)
219
buff[i] = table[buff[i]];
220
}
221
222
int audio_write(int dev, struct file *file, const char __user *buf, int count)
223
{
224
int c, p, l, buf_size, used, returned;
225
int err;
226
char *dma_buf;
227
228
dev = dev >> 4;
229
230
p = 0;
231
c = count;
232
233
if(count < 0)
234
return -EINVAL;
235
236
if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
237
return -EPERM;
238
239
if (audio_devs[dev]->flags & DMA_DUPLEX)
240
audio_devs[dev]->audio_mode |= AM_WRITE;
241
else
242
audio_devs[dev]->audio_mode = AM_WRITE;
243
244
if (!count) /* Flush output */
245
{
246
sync_output(dev);
247
return 0;
248
}
249
250
while (c)
251
{
252
if ((err = DMAbuf_getwrbuffer(dev, &dma_buf, &buf_size, !!(file->f_flags & O_NONBLOCK))) < 0)
253
{
254
/* Handle nonblocking mode */
255
if ((file->f_flags & O_NONBLOCK) && err == -EAGAIN)
256
return p? p : -EAGAIN; /* No more space. Return # of accepted bytes */
257
return err;
258
}
259
l = c;
260
261
if (l > buf_size)
262
l = buf_size;
263
264
returned = l;
265
used = l;
266
if (!audio_devs[dev]->d->copy_user)
267
{
268
if ((dma_buf + l) >
269
(audio_devs[dev]->dmap_out->raw_buf + audio_devs[dev]->dmap_out->buffsize))
270
{
271
printk(KERN_ERR "audio: Buffer error 3 (%lx,%d), (%lx, %d)\n", (long) dma_buf, l, (long) audio_devs[dev]->dmap_out->raw_buf, (int) audio_devs[dev]->dmap_out->buffsize);
272
return -EDOM;
273
}
274
if (dma_buf < audio_devs[dev]->dmap_out->raw_buf)
275
{
276
printk(KERN_ERR "audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf, (long) audio_devs[dev]->dmap_out->raw_buf);
277
return -EDOM;
278
}
279
if(copy_from_user(dma_buf, &(buf)[p], l))
280
return -EFAULT;
281
}
282
else audio_devs[dev]->d->copy_user (dev,
283
dma_buf, 0,
284
buf, p,
285
c, buf_size,
286
&used, &returned,
287
l);
288
l = returned;
289
290
if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
291
{
292
translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
293
}
294
c -= used;
295
p += used;
296
DMAbuf_move_wrpointer(dev, l);
297
298
}
299
300
return count;
301
}
302
303
int audio_read(int dev, struct file *file, char __user *buf, int count)
304
{
305
int c, p, l;
306
char *dmabuf;
307
int buf_no;
308
309
dev = dev >> 4;
310
p = 0;
311
c = count;
312
313
if (!(audio_devs[dev]->open_mode & OPEN_READ))
314
return -EPERM;
315
316
if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
317
sync_output(dev);
318
319
if (audio_devs[dev]->flags & DMA_DUPLEX)
320
audio_devs[dev]->audio_mode |= AM_READ;
321
else
322
audio_devs[dev]->audio_mode = AM_READ;
323
324
while(c)
325
{
326
if ((buf_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l, !!(file->f_flags & O_NONBLOCK))) < 0)
327
{
328
/*
329
* Nonblocking mode handling. Return current # of bytes
330
*/
331
332
if (p > 0) /* Avoid throwing away data */
333
return p; /* Return it instead */
334
335
if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN)
336
return -EAGAIN;
337
338
return buf_no;
339
}
340
if (l > c)
341
l = c;
342
343
/*
344
* Insert any local processing here.
345
*/
346
347
if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
348
{
349
translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l);
350
}
351
352
{
353
char *fixit = dmabuf;
354
355
if(copy_to_user(&(buf)[p], fixit, l))
356
return -EFAULT;
357
};
358
359
DMAbuf_rmchars(dev, buf_no, l);
360
361
p += l;
362
c -= l;
363
}
364
365
return count - c;
366
}
367
368
int audio_ioctl(int dev, struct file *file, unsigned int cmd, void __user *arg)
369
{
370
int val, count;
371
unsigned long flags;
372
struct dma_buffparms *dmap;
373
int __user *p = arg;
374
375
dev = dev >> 4;
376
377
if (_IOC_TYPE(cmd) == 'C') {
378
if (audio_devs[dev]->coproc) /* Coprocessor ioctl */
379
return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
380
/* else
381
printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
382
return -ENXIO;
383
}
384
else switch (cmd)
385
{
386
case SNDCTL_DSP_SYNC:
387
if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
388
return 0;
389
if (audio_devs[dev]->dmap_out->fragment_size == 0)
390
return 0;
391
sync_output(dev);
392
DMAbuf_sync(dev);
393
DMAbuf_reset(dev);
394
return 0;
395
396
case SNDCTL_DSP_POST:
397
if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
398
return 0;
399
if (audio_devs[dev]->dmap_out->fragment_size == 0)
400
return 0;
401
audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
402
sync_output(dev);
403
dma_ioctl(dev, SNDCTL_DSP_POST, NULL);
404
return 0;
405
406
case SNDCTL_DSP_RESET:
407
audio_devs[dev]->audio_mode = AM_NONE;
408
DMAbuf_reset(dev);
409
return 0;
410
411
case SNDCTL_DSP_GETFMTS:
412
val = audio_devs[dev]->format_mask | AFMT_MU_LAW;
413
break;
414
415
case SNDCTL_DSP_SETFMT:
416
if (get_user(val, p))
417
return -EFAULT;
418
val = set_format(dev, val);
419
break;
420
421
case SNDCTL_DSP_GETISPACE:
422
if (!(audio_devs[dev]->open_mode & OPEN_READ))
423
return 0;
424
if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
425
return -EBUSY;
426
return dma_ioctl(dev, cmd, arg);
427
428
case SNDCTL_DSP_GETOSPACE:
429
if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
430
return -EPERM;
431
if ((audio_devs[dev]->audio_mode & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
432
return -EBUSY;
433
return dma_ioctl(dev, cmd, arg);
434
435
case SNDCTL_DSP_NONBLOCK:
436
spin_lock(&file->f_lock);
437
file->f_flags |= O_NONBLOCK;
438
spin_unlock(&file->f_lock);
439
return 0;
440
441
case SNDCTL_DSP_GETCAPS:
442
val = 1 | DSP_CAP_MMAP; /* Revision level of this ioctl() */
443
if (audio_devs[dev]->flags & DMA_DUPLEX &&
444
audio_devs[dev]->open_mode == OPEN_READWRITE)
445
val |= DSP_CAP_DUPLEX;
446
if (audio_devs[dev]->coproc)
447
val |= DSP_CAP_COPROC;
448
if (audio_devs[dev]->d->local_qlen) /* Device has hidden buffers */
449
val |= DSP_CAP_BATCH;
450
if (audio_devs[dev]->d->trigger) /* Supports SETTRIGGER */
451
val |= DSP_CAP_TRIGGER;
452
break;
453
454
case SOUND_PCM_WRITE_RATE:
455
if (get_user(val, p))
456
return -EFAULT;
457
val = audio_devs[dev]->d->set_speed(dev, val);
458
break;
459
460
case SOUND_PCM_READ_RATE:
461
val = audio_devs[dev]->d->set_speed(dev, 0);
462
break;
463
464
case SNDCTL_DSP_STEREO:
465
if (get_user(val, p))
466
return -EFAULT;
467
if (val > 1 || val < 0)
468
return -EINVAL;
469
val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
470
break;
471
472
case SOUND_PCM_WRITE_CHANNELS:
473
if (get_user(val, p))
474
return -EFAULT;
475
val = audio_devs[dev]->d->set_channels(dev, val);
476
break;
477
478
case SOUND_PCM_READ_CHANNELS:
479
val = audio_devs[dev]->d->set_channels(dev, 0);
480
break;
481
482
case SOUND_PCM_READ_BITS:
483
val = audio_devs[dev]->d->set_bits(dev, 0);
484
break;
485
486
case SNDCTL_DSP_SETDUPLEX:
487
if (audio_devs[dev]->open_mode != OPEN_READWRITE)
488
return -EPERM;
489
return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;
490
491
case SNDCTL_DSP_PROFILE:
492
if (get_user(val, p))
493
return -EFAULT;
494
if (audio_devs[dev]->open_mode & OPEN_WRITE)
495
audio_devs[dev]->dmap_out->applic_profile = val;
496
if (audio_devs[dev]->open_mode & OPEN_READ)
497
audio_devs[dev]->dmap_in->applic_profile = val;
498
return 0;
499
500
case SNDCTL_DSP_GETODELAY:
501
dmap = audio_devs[dev]->dmap_out;
502
if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
503
return -EINVAL;
504
if (!(dmap->flags & DMA_ALLOC_DONE))
505
{
506
val=0;
507
break;
508
}
509
510
spin_lock_irqsave(&dmap->lock,flags);
511
/* Compute number of bytes that have been played */
512
count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
513
if (count < dmap->fragment_size && dmap->qhead != 0)
514
count += dmap->bytes_in_use; /* Pointer wrap not handled yet */
515
count += dmap->byte_counter;
516
517
/* Subtract current count from the number of bytes written by app */
518
count = dmap->user_counter - count;
519
if (count < 0)
520
count = 0;
521
spin_unlock_irqrestore(&dmap->lock,flags);
522
val = count;
523
break;
524
525
default:
526
return dma_ioctl(dev, cmd, arg);
527
}
528
return put_user(val, p);
529
}
530
531
void audio_init_devices(void)
532
{
533
/*
534
* NOTE! This routine could be called several times during boot.
535
*/
536
}
537
538
void reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
539
{
540
/*
541
* This routine breaks the physical device buffers to logical ones.
542
*/
543
544
struct audio_operations *dsp_dev = audio_devs[dev];
545
546
unsigned i, n;
547
unsigned sr, nc, sz, bsz;
548
549
sr = dsp_dev->d->set_speed(dev, 0);
550
nc = dsp_dev->d->set_channels(dev, 0);
551
sz = dsp_dev->d->set_bits(dev, 0);
552
553
if (sz == 8)
554
dmap->neutral_byte = NEUTRAL8;
555
else
556
dmap->neutral_byte = NEUTRAL16;
557
558
if (sr < 1 || nc < 1 || sz < 1)
559
{
560
/* printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/
561
sr = DSP_DEFAULT_SPEED;
562
nc = 1;
563
sz = 8;
564
}
565
566
sz = sr * nc * sz;
567
568
sz /= 8; /* #bits -> #bytes */
569
dmap->data_rate = sz;
570
571
if (!dmap->needs_reorg)
572
return;
573
dmap->needs_reorg = 0;
574
575
if (dmap->fragment_size == 0)
576
{
577
/* Compute the fragment size using the default algorithm */
578
579
/*
580
* Compute a buffer size for time not exceeding 1 second.
581
* Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
582
* of sound (using the current speed, sample size and #channels).
583
*/
584
585
bsz = dmap->buffsize;
586
while (bsz > sz)
587
bsz /= 2;
588
589
if (bsz == dmap->buffsize)
590
bsz /= 2; /* Needs at least 2 buffers */
591
592
/*
593
* Split the computed fragment to smaller parts. After 3.5a9
594
* the default subdivision is 4 which should give better
595
* results when recording.
596
*/
597
598
if (dmap->subdivision == 0) /* Not already set */
599
{
600
dmap->subdivision = 4; /* Init to the default value */
601
602
if ((bsz / dmap->subdivision) > 4096)
603
dmap->subdivision *= 2;
604
if ((bsz / dmap->subdivision) < 4096)
605
dmap->subdivision = 1;
606
}
607
bsz /= dmap->subdivision;
608
609
if (bsz < 16)
610
bsz = 16; /* Just a sanity check */
611
612
dmap->fragment_size = bsz;
613
}
614
else
615
{
616
/*
617
* The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
618
* the buffer size computation has already been done.
619
*/
620
if (dmap->fragment_size > (dmap->buffsize / 2))
621
dmap->fragment_size = (dmap->buffsize / 2);
622
bsz = dmap->fragment_size;
623
}
624
625
if (audio_devs[dev]->min_fragment)
626
if (bsz < (1 << audio_devs[dev]->min_fragment))
627
bsz = 1 << audio_devs[dev]->min_fragment;
628
if (audio_devs[dev]->max_fragment)
629
if (bsz > (1 << audio_devs[dev]->max_fragment))
630
bsz = 1 << audio_devs[dev]->max_fragment;
631
bsz &= ~0x07; /* Force size which is multiple of 8 bytes */
632
#ifdef OS_DMA_ALIGN_CHECK
633
OS_DMA_ALIGN_CHECK(bsz);
634
#endif
635
636
n = dmap->buffsize / bsz;
637
if (n > MAX_SUB_BUFFERS)
638
n = MAX_SUB_BUFFERS;
639
if (n > dmap->max_fragments)
640
n = dmap->max_fragments;
641
642
if (n < 2)
643
{
644
n = 2;
645
bsz /= 2;
646
}
647
dmap->nbufs = n;
648
dmap->bytes_in_use = n * bsz;
649
dmap->fragment_size = bsz;
650
dmap->max_byte_counter = (dmap->data_rate * 60 * 60) +
651
dmap->bytes_in_use; /* Approximately one hour */
652
653
if (dmap->raw_buf)
654
{
655
memset(dmap->raw_buf, dmap->neutral_byte, dmap->bytes_in_use);
656
}
657
658
for (i = 0; i < dmap->nbufs; i++)
659
{
660
dmap->counts[i] = 0;
661
}
662
663
dmap->flags |= DMA_ALLOC_DONE | DMA_EMPTY;
664
}
665
666
static int dma_subdivide(int dev, struct dma_buffparms *dmap, int fact)
667
{
668
if (fact == 0)
669
{
670
fact = dmap->subdivision;
671
if (fact == 0)
672
fact = 1;
673
return fact;
674
}
675
if (dmap->subdivision != 0 || dmap->fragment_size) /* Too late to change */
676
return -EINVAL;
677
678
if (fact > MAX_REALTIME_FACTOR)
679
return -EINVAL;
680
681
if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact != 16)
682
return -EINVAL;
683
684
dmap->subdivision = fact;
685
return fact;
686
}
687
688
static int dma_set_fragment(int dev, struct dma_buffparms *dmap, int fact)
689
{
690
int bytes, count;
691
692
if (fact == 0)
693
return -EIO;
694
695
if (dmap->subdivision != 0 ||
696
dmap->fragment_size) /* Too late to change */
697
return -EINVAL;
698
699
bytes = fact & 0xffff;
700
count = (fact >> 16) & 0x7fff;
701
702
if (count == 0)
703
count = MAX_SUB_BUFFERS;
704
else if (count < MAX_SUB_BUFFERS)
705
count++;
706
707
if (bytes < 4 || bytes > 17) /* <16 || > 512k */
708
return -EINVAL;
709
710
if (count < 2)
711
return -EINVAL;
712
713
if (audio_devs[dev]->min_fragment > 0)
714
if (bytes < audio_devs[dev]->min_fragment)
715
bytes = audio_devs[dev]->min_fragment;
716
717
if (audio_devs[dev]->max_fragment > 0)
718
if (bytes > audio_devs[dev]->max_fragment)
719
bytes = audio_devs[dev]->max_fragment;
720
721
#ifdef OS_DMA_MINBITS
722
if (bytes < OS_DMA_MINBITS)
723
bytes = OS_DMA_MINBITS;
724
#endif
725
726
dmap->fragment_size = (1 << bytes);
727
dmap->max_fragments = count;
728
729
if (dmap->fragment_size > dmap->buffsize)
730
dmap->fragment_size = dmap->buffsize;
731
732
if (dmap->fragment_size == dmap->buffsize &&
733
audio_devs[dev]->flags & DMA_AUTOMODE)
734
dmap->fragment_size /= 2; /* Needs at least 2 buffers */
735
736
dmap->subdivision = 1; /* Disable SNDCTL_DSP_SUBDIVIDE */
737
return bytes | ((count - 1) << 16);
738
}
739
740
static int dma_ioctl(int dev, unsigned int cmd, void __user *arg)
741
{
742
struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out;
743
struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in;
744
struct dma_buffparms *dmap;
745
audio_buf_info info;
746
count_info cinfo;
747
int fact, ret, changed, bits, count, err;
748
unsigned long flags;
749
750
switch (cmd)
751
{
752
case SNDCTL_DSP_SUBDIVIDE:
753
ret = 0;
754
if (get_user(fact, (int __user *)arg))
755
return -EFAULT;
756
if (audio_devs[dev]->open_mode & OPEN_WRITE)
757
ret = dma_subdivide(dev, dmap_out, fact);
758
if (ret < 0)
759
return ret;
760
if (audio_devs[dev]->open_mode != OPEN_WRITE ||
761
(audio_devs[dev]->flags & DMA_DUPLEX &&
762
audio_devs[dev]->open_mode & OPEN_READ))
763
ret = dma_subdivide(dev, dmap_in, fact);
764
if (ret < 0)
765
return ret;
766
break;
767
768
case SNDCTL_DSP_GETISPACE:
769
case SNDCTL_DSP_GETOSPACE:
770
dmap = dmap_out;
771
if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
772
return -EINVAL;
773
if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
774
return -EINVAL;
775
if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
776
dmap = dmap_in;
777
if (dmap->mapping_flags & DMA_MAP_MAPPED)
778
return -EINVAL;
779
if (!(dmap->flags & DMA_ALLOC_DONE))
780
reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
781
info.fragstotal = dmap->nbufs;
782
if (cmd == SNDCTL_DSP_GETISPACE)
783
info.fragments = dmap->qlen;
784
else
785
{
786
if (!DMAbuf_space_in_queue(dev))
787
info.fragments = 0;
788
else
789
{
790
info.fragments = DMAbuf_space_in_queue(dev);
791
if (audio_devs[dev]->d->local_qlen)
792
{
793
int tmp = audio_devs[dev]->d->local_qlen(dev);
794
if (tmp && info.fragments)
795
tmp--; /*
796
* This buffer has been counted twice
797
*/
798
info.fragments -= tmp;
799
}
800
}
801
}
802
if (info.fragments < 0)
803
info.fragments = 0;
804
else if (info.fragments > dmap->nbufs)
805
info.fragments = dmap->nbufs;
806
807
info.fragsize = dmap->fragment_size;
808
info.bytes = info.fragments * dmap->fragment_size;
809
810
if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
811
info.bytes -= dmap->counts[dmap->qhead];
812
else
813
{
814
info.fragments = info.bytes / dmap->fragment_size;
815
info.bytes -= dmap->user_counter % dmap->fragment_size;
816
}
817
if (copy_to_user(arg, &info, sizeof(info)))
818
return -EFAULT;
819
return 0;
820
821
case SNDCTL_DSP_SETTRIGGER:
822
if (get_user(bits, (int __user *)arg))
823
return -EFAULT;
824
bits &= audio_devs[dev]->open_mode;
825
if (audio_devs[dev]->d->trigger == NULL)
826
return -EINVAL;
827
if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
828
(bits & PCM_ENABLE_OUTPUT))
829
return -EINVAL;
830
831
if (bits & PCM_ENABLE_INPUT)
832
{
833
spin_lock_irqsave(&dmap_in->lock,flags);
834
changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_INPUT;
835
if (changed && audio_devs[dev]->go)
836
{
837
reorganize_buffers(dev, dmap_in, 1);
838
if ((err = audio_devs[dev]->d->prepare_for_input(dev,
839
dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
840
spin_unlock_irqrestore(&dmap_in->lock,flags);
841
return err;
842
}
843
dmap_in->dma_mode = DMODE_INPUT;
844
audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT;
845
DMAbuf_activate_recording(dev, dmap_in);
846
} else
847
audio_devs[dev]->enable_bits &= ~PCM_ENABLE_INPUT;
848
spin_unlock_irqrestore(&dmap_in->lock,flags);
849
}
850
if (bits & PCM_ENABLE_OUTPUT)
851
{
852
spin_lock_irqsave(&dmap_out->lock,flags);
853
changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_OUTPUT;
854
if (changed &&
855
(dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
856
audio_devs[dev]->go)
857
{
858
if (!(dmap_out->flags & DMA_ALLOC_DONE))
859
reorganize_buffers(dev, dmap_out, 0);
860
dmap_out->dma_mode = DMODE_OUTPUT;
861
audio_devs[dev]->enable_bits |= PCM_ENABLE_OUTPUT;
862
dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
863
DMAbuf_launch_output(dev, dmap_out);
864
} else
865
audio_devs[dev]->enable_bits &= ~PCM_ENABLE_OUTPUT;
866
spin_unlock_irqrestore(&dmap_out->lock,flags);
867
}
868
#if 0
869
if (changed && audio_devs[dev]->d->trigger)
870
audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
871
#endif
872
/* Falls through... */
873
874
case SNDCTL_DSP_GETTRIGGER:
875
ret = audio_devs[dev]->enable_bits;
876
break;
877
878
case SNDCTL_DSP_SETSYNCRO:
879
if (!audio_devs[dev]->d->trigger)
880
return -EINVAL;
881
audio_devs[dev]->d->trigger(dev, 0);
882
audio_devs[dev]->go = 0;
883
return 0;
884
885
case SNDCTL_DSP_GETIPTR:
886
if (!(audio_devs[dev]->open_mode & OPEN_READ))
887
return -EINVAL;
888
spin_lock_irqsave(&dmap_in->lock,flags);
889
cinfo.bytes = dmap_in->byte_counter;
890
cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
891
if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
892
cinfo.bytes += dmap_in->bytes_in_use; /* Pointer wrap not handled yet */
893
cinfo.blocks = dmap_in->qlen;
894
cinfo.bytes += cinfo.ptr;
895
if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
896
dmap_in->qlen = 0; /* Reset interrupt counter */
897
spin_unlock_irqrestore(&dmap_in->lock,flags);
898
if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
899
return -EFAULT;
900
return 0;
901
902
case SNDCTL_DSP_GETOPTR:
903
if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
904
return -EINVAL;
905
906
spin_lock_irqsave(&dmap_out->lock,flags);
907
cinfo.bytes = dmap_out->byte_counter;
908
cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
909
if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
910
cinfo.bytes += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
911
cinfo.blocks = dmap_out->qlen;
912
cinfo.bytes += cinfo.ptr;
913
if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
914
dmap_out->qlen = 0; /* Reset interrupt counter */
915
spin_unlock_irqrestore(&dmap_out->lock,flags);
916
if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
917
return -EFAULT;
918
return 0;
919
920
case SNDCTL_DSP_GETODELAY:
921
if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
922
return -EINVAL;
923
if (!(dmap_out->flags & DMA_ALLOC_DONE))
924
{
925
ret=0;
926
break;
927
}
928
spin_lock_irqsave(&dmap_out->lock,flags);
929
/* Compute number of bytes that have been played */
930
count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
931
if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
932
count += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
933
count += dmap_out->byte_counter;
934
/* Subtract current count from the number of bytes written by app */
935
count = dmap_out->user_counter - count;
936
if (count < 0)
937
count = 0;
938
spin_unlock_irqrestore(&dmap_out->lock,flags);
939
ret = count;
940
break;
941
942
case SNDCTL_DSP_POST:
943
if (audio_devs[dev]->dmap_out->qlen > 0)
944
if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
945
DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
946
return 0;
947
948
case SNDCTL_DSP_GETBLKSIZE:
949
dmap = dmap_out;
950
if (audio_devs[dev]->open_mode & OPEN_WRITE)
951
reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
952
if (audio_devs[dev]->open_mode == OPEN_READ ||
953
(audio_devs[dev]->flags & DMA_DUPLEX &&
954
audio_devs[dev]->open_mode & OPEN_READ))
955
reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
956
if (audio_devs[dev]->open_mode == OPEN_READ)
957
dmap = dmap_in;
958
ret = dmap->fragment_size;
959
break;
960
961
case SNDCTL_DSP_SETFRAGMENT:
962
ret = 0;
963
if (get_user(fact, (int __user *)arg))
964
return -EFAULT;
965
if (audio_devs[dev]->open_mode & OPEN_WRITE)
966
ret = dma_set_fragment(dev, dmap_out, fact);
967
if (ret < 0)
968
return ret;
969
if (audio_devs[dev]->open_mode == OPEN_READ ||
970
(audio_devs[dev]->flags & DMA_DUPLEX &&
971
audio_devs[dev]->open_mode & OPEN_READ))
972
ret = dma_set_fragment(dev, dmap_in, fact);
973
if (ret < 0)
974
return ret;
975
if (!arg) /* don't know what this is good for, but preserve old semantics */
976
return 0;
977
break;
978
979
default:
980
if (!audio_devs[dev]->d->ioctl)
981
return -EINVAL;
982
return audio_devs[dev]->d->ioctl(dev, cmd, arg);
983
}
984
return put_user(ret, (int __user *)arg);
985
}
986
987