Put the sound stuff in alpabetic order.
[unix-history] / sys / i386 / isa / sound / dmabuf.c
CommitLineData
1b261ae5
JH
1/*
2 * linux/kernel/chr_drv/sound/dmabuf.c
3 *
4 * The DMA buffer manager for digitized voice applications
5 *
6 * (C) 1992 Hannu Savolainen (hsavolai@cs.helsinki.fi) See COPYING for further
7 * details. Should be distributed with this file.
8 */
9
10#include "sound_config.h"
11
12#ifdef CONFIGURE_SOUNDCARD
13
14#include "sound_calls.h"
15
16#if !defined(EXCLUDE_AUDIO) || !defined(EXCLUDE_GUS)
17
18#define MAX_SUB_BUFFERS 16
19
20/*
21 * The DSP channel can be used either for input or output. Variable
22 * 'dma_mode' will be set when the program calls read or write first time
23 * after open. Current version doesn't support mode changes without closing
24 * and reopening the device. Support for this feature may be implemented in a
25 * future version of this driver.
26 */
27
28#define DMODE_NONE 0
29#define DMODE_OUTPUT 1
30#define DMODE_INPUT 2
31#define DMODE_INIT 3
32
33DEFINE_WAIT_QUEUES (dev_sleeper[MAX_DSP_DEV], dev_sleep_flag[MAX_DSP_DEV]);
34
35static int dma_mode[MAX_DSP_DEV] =
36{0}; /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
37
38static volatile int dmabuf_interrupted[MAX_DSP_DEV] =
39{0};
40
41#ifdef ISC
42/* I don't like this. */
43#undef INTERRUPTIBLE_SLEEP_ON
44#define INTERRUPTIBLE_SLEEP_ON(A,F) { \
45 A = F = 1; \
46 if (sleep(&(A), (PZERO + 5) | PCATCH)) { \
47 A = F = 0; \
48 dmabuf_interrupted[dev] = 1; \
49 dev_busy[dev] = 0; \
50 dma_reset(dev); \
51 dmabuf_interrupted[dev] = 0; \
52 /* longjmp(u.u_qsav, 1); Where it goes??? */ \
53 } \
54 }
55#endif
56
57/*
58 * Pointers to raw buffers
59 */
60
61char *snd_raw_buf[MAX_DSP_DEV][DSP_BUFFCOUNT];
62unsigned long snd_raw_buf_phys[MAX_DSP_DEV][DSP_BUFFCOUNT];
63int snd_raw_count[MAX_DSP_DEV];
64
65/*
66 * Device state tables
67 */
68
69static int dev_busy[MAX_DSP_DEV];
70static int dev_active[MAX_DSP_DEV];
71static int dev_qlen[MAX_DSP_DEV];
72static int dev_qhead[MAX_DSP_DEV];
73static int dev_qtail[MAX_DSP_DEV];
74static int dev_underrun[MAX_DSP_DEV];
75static int bufferalloc_done[MAX_DSP_DEV] =
76{0};
77
78/*
79 * Logical buffers for each devices
80 */
81
82static int dev_nbufs[MAX_DSP_DEV]; /* # of logical buffers ( >=
83 * sound_buffcounts[dev] */
84static int dev_counts[MAX_DSP_DEV][MAX_SUB_BUFFERS];
85static unsigned long dev_buf_phys[MAX_DSP_DEV][MAX_SUB_BUFFERS];
86static char *dev_buf[MAX_DSP_DEV][MAX_SUB_BUFFERS];
87static int dev_buffsize[MAX_DSP_DEV];
88
89static void
90reorganize_buffers (int dev)
91{
92 /*
93 * This routine breaks the physical device buffers to logical ones.
94 */
95
96 unsigned long i, p, n;
97 unsigned long sr, nc, sz, bsz;
98
99 sr = dsp_devs[dev]->ioctl (dev, SOUND_PCM_READ_RATE, 0, 1);
100 nc = dsp_devs[dev]->ioctl (dev, SOUND_PCM_READ_CHANNELS, 0, 1);
101 sz = dsp_devs[dev]->ioctl (dev, SOUND_PCM_READ_BITS, 0, 1);
102
103 if (sr < 1 || nc < 1 || sz < 1)
104 {
105 printk ("SOUND: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);
106 sr = DSP_DEFAULT_SPEED;
107 nc = 1;
108 sz = 8;
109 }
110
111 sz /= 8; /* Convert # of bits -> # of bytes */
112
113 sz = sr * nc * sz;
114
115 /*
116 * Compute a buffer size not exeeding 1 second.
117 */
118
119 bsz = sound_buffsizes[dev];
120
121 while (bsz > sz)
122 bsz >>= 1; /* Divide by 2 */
123
124 if (sound_buffcounts[dev] == 1 && bsz == sound_buffsizes[dev])
125 bsz >>= 1; /* Need at least 2 buffers */
126
127 dev_buffsize[dev] = bsz;
128 n = 0;
129
130 /*
131 * Now computing addresses for the logical buffers
132 */
133
134 for (i = 0; i < snd_raw_count[dev]; i++)
135 {
136 p = 0;
137
138 while ((p + bsz) <= sound_buffsizes[dev])
139 {
140 dev_buf[dev][n] = snd_raw_buf[dev][i] + p;
141 dev_buf_phys[dev][n] = snd_raw_buf_phys[dev][i] + p;
142 p += bsz;
143 n++;
144 }
145 }
146
147 dev_nbufs[dev] = n;
148
149 for (i = 0; i < dev_nbufs[dev]; i++)
150 {
151 dev_counts[dev][i] = 0;
152 }
153
154 bufferalloc_done[dev] = 1;
155}
156
157int
158DMAbuf_open (int dev, int mode)
159{
160 int retval;
161
162 if (dev >= num_dspdevs)
163 {
164 printk ("PCM device %d not installed.\n", dev);
165 return RET_ERROR (ENXIO);
166 }
167
168 if (dev_busy[dev])
169 return RET_ERROR (EBUSY);
170
171 if (!dsp_devs[dev])
172 {
173 printk ("DSP device %d not initialized\n", dev);
174 return RET_ERROR (ENXIO);
175 }
176
177 if (sound_buffcounts[dev] <= 0)
178 return RET_ERROR (ENOSPC); /* Memory allocation failed during boot */
179
180 if ((retval = dsp_devs[dev]->open (dev, mode)) < 0)
181 return retval;
182
183 dev_underrun[dev] = 0;
184
185 dev_busy[dev] = 1;
186
187 reorganize_buffers (dev);
188 bufferalloc_done[dev] = 0;
189
190 dev_qlen[dev] = dev_qtail[dev] = dev_qhead[dev] = 0;
191
192 return 0;
193}
194
195static void
196dma_reset (int dev)
197{
198 dsp_devs[dev]->reset (dev);
199
200 dev_qlen[dev] = 0;
201 dev_qhead[dev] = 0;
202 dev_qtail[dev] = 0;
203 dev_active[dev] = 0;
204}
205
206static int
207dma_sync (int dev)
208{
209 unsigned long flags;
210 unsigned long time;
211 int timed_out;
212
213 if (dma_mode[dev] == DMODE_OUTPUT)
214 {
215 DISABLE_INTR (flags);
216
217 timed_out = 0;
218 time = GET_TIME ();
219
220 while ((!(PROCESS_ABORTING || dmabuf_interrupted[dev]) && !timed_out)
221 && dev_qlen[dev])
222 {
223 REQUEST_TIMEOUT (10 * HZ, dev_sleeper[dev]);
224 INTERRUPTIBLE_SLEEP_ON (dev_sleeper[dev], dev_sleep_flag[dev]);
225 if ((GET_TIME () - time) > (10 * HZ))
226 timed_out = 1;
227 }
228 RESTORE_INTR (flags);
229
230 /*
231 * Some devices such as GUS have huge amount of on board RAM for the
232 * audio data. We have to wait util the device has finished playing.
233 */
234
235 DISABLE_INTR (flags);
236 if (dsp_devs[dev]->has_output_drained) /* Device has hidden buffers */
237 {
238 while (!(PROCESS_ABORTING || dmabuf_interrupted[dev])
239 && !dsp_devs[dev]->has_output_drained (dev))
240 {
241 REQUEST_TIMEOUT (HZ / 4, dev_sleeper[dev]);
242 INTERRUPTIBLE_SLEEP_ON (dev_sleeper[dev], dev_sleep_flag[dev]);
243 }
244 }
245 RESTORE_INTR (flags);
246 }
247 return dev_qlen[dev];
248}
249
250int
251DMAbuf_release (int dev, int mode)
252{
253
254 if (!(PROCESS_ABORTING || dmabuf_interrupted[dev])
255 && (dma_mode[dev] == DMODE_OUTPUT))
256 {
257 dma_sync (dev);
258 }
259
260 dma_reset (dev);
261
262 if (!dev_active[dev])
263 dsp_devs[dev]->close (dev);
264
265 dma_mode[dev] = DMODE_NONE;
266 dev_busy[dev] = 0;
267
268 return 0;
269}
270
271int
272DMAbuf_getrdbuffer (int dev, char **buf, int *len)
273{
274 unsigned long flags;
275
276 if (!bufferalloc_done[dev])
277 reorganize_buffers (dev);
278
279 if (!dma_mode[dev])
280 {
281 int err;
282
283 if ((err = dsp_devs[dev]->prepare_for_input (dev,
284 dev_buffsize[dev], dev_nbufs[dev])) < 0)
285 return err;
286 dma_mode[dev] = DMODE_INPUT;
287 }
288
289 if (dma_mode[dev] != DMODE_INPUT)
290 return RET_ERROR (EBUSY); /* Can't change mode on fly */
291
292 DISABLE_INTR (flags);
293 if (!dev_qlen[dev])
294 {
295 if (!dev_active[dev])
296 {
297 dsp_devs[dev]->start_input (dev, dev_buf_phys[dev][dev_qtail[dev]], dev_buffsize[dev], 0);
298 dev_active[dev] = 1;
299 }
300
301 /* Wait for the next block */
302#ifdef CRYPTO
303 REQUEST_TIMEOUT (60 * HZ, dev_sleeper[dev]);
304#else
305 REQUEST_TIMEOUT (10 * HZ, dev_sleeper[dev]);
306#endif
307 INTERRUPTIBLE_SLEEP_ON (dev_sleeper[dev], dev_sleep_flag[dev]);
308 }
309 RESTORE_INTR (flags);
310
311 if (!dev_qlen[dev])
312 return RET_ERROR (EINTR);
313
314 *buf = &dev_buf[dev][dev_qhead[dev]][dev_counts[dev][dev_qhead[dev]]];
315 *len = dev_buffsize[dev] - dev_counts[dev][dev_qhead[dev]];
316
317 return dev_qhead[dev];
318}
319
320int
321DMAbuf_rmchars (int dev, int buff_no, int c)
322{
323 int p = dev_counts[dev][dev_qhead[dev]] + c;
324
325 if (p >= dev_buffsize[dev])
326 { /* This buffer is now empty */
327 dev_counts[dev][dev_qhead[dev]] = 0;
328 dev_qlen[dev]--;
329 dev_qhead[dev] = (dev_qhead[dev] + 1) % dev_nbufs[dev];
330 }
331 else
332 dev_counts[dev][dev_qhead[dev]] = p;
333
334 return 0;
335}
336
337int
338DMAbuf_read (int dev, snd_rw_buf * user_buf, int count)
339{
340 char *dmabuf;
341 int buff_no, c, err;
342
343 /*
344 * This routine returns at most 'count' bytes from the dsp input buffers.
345 * Returns negative value if there is an error.
346 */
347
348 if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &c)) < 0)
349 return buff_no;
350
351 if (c > count)
352 c = count;
353
354 COPY_TO_USER (user_buf, 0, dmabuf, c);
355
356 if ((err = DMAbuf_rmchars (dev, buff_no, c)) < 0)
357 return err;
358 return c;
359
360}
361
362int
363DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
364{
365 switch (cmd)
366 {
367 case SNDCTL_DSP_RESET:
368 dma_reset (dev);
369 return 0;
370 break;
371
372 case SNDCTL_DSP_SYNC:
373 dma_sync (dev);
374 return 0;
375 break;
376
377 case SNDCTL_DSP_GETBLKSIZE:
378 if (!bufferalloc_done[dev])
379 reorganize_buffers (dev);
380
381 return IOCTL_OUT (arg, dev_buffsize[dev]);
382 break;
383
384 default:
385 return dsp_devs[dev]->ioctl (dev, cmd, arg, local);
386 }
387
388 return RET_ERROR (EIO);
389}
390
391int
392DMAbuf_getwrbuffer (int dev, char **buf, int *size)
393{
394 unsigned long flags;
395
396 if (!bufferalloc_done[dev])
397 reorganize_buffers (dev);
398
399 if (!dma_mode[dev])
400 {
401 int err;
402
403 dma_mode[dev] = DMODE_OUTPUT;
404 if ((err = dsp_devs[dev]->prepare_for_output (dev,
405 dev_buffsize[dev], dev_nbufs[dev])) < 0)
406 return err;
407 }
408
409 if (dma_mode[dev] != DMODE_OUTPUT)
410 return RET_ERROR (EBUSY); /* Can't change mode on fly */
411
412 DISABLE_INTR (flags);
413 if (dev_qlen[dev] == dev_nbufs[dev])
414 {
415 if (!dev_active[dev])
416 {
417 printk ("Soundcard warning: DMA not activated %d/%d\n",
418 dev_qlen[dev], dev_nbufs[dev]);
419 return RET_ERROR (EIO);
420 }
421
422 /* Wait for free space */
423 REQUEST_TIMEOUT (60 * HZ, dev_sleeper[dev]); /* Overestimated timeout */
424 INTERRUPTIBLE_SLEEP_ON (dev_sleeper[dev], dev_sleep_flag[dev]);
425 }
426 RESTORE_INTR (flags);
427
428 if (dev_qlen[dev] == dev_nbufs[dev])
429 return RET_ERROR (EIO); /* We have got signal (?) */
430
431 *buf = dev_buf[dev][dev_qtail[dev]];
432 *size = dev_buffsize[dev];
433 dev_counts[dev][dev_qtail[dev]] = 0;
434
435 return dev_qtail[dev];
436}
437
438int
439DMAbuf_start_output (int dev, int buff_no, int l)
440{
441 if (buff_no != dev_qtail[dev])
442 printk ("Soundcard warning: DMA buffers out of sync %d != %d\n", buff_no, dev_qtail[dev]);
443
444 dev_qlen[dev]++;
445
446 dev_counts[dev][dev_qtail[dev]] = l;
447
448 dev_qtail[dev] = (dev_qtail[dev] + 1) % dev_nbufs[dev];
449
450 if (!dev_active[dev])
451 {
452 dev_active[dev] = 1;
453 dsp_devs[dev]->output_block (dev, dev_buf_phys[dev][dev_qhead[dev]], dev_counts[dev][dev_qhead[dev]], 0);
454 }
455
456 return 0;
457}
458
459int
460DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
461{
462 int chan = sound_dsp_dmachan[dev];
463 unsigned long flags;
464
465 /*
466 * This function is not as portable as it should be.
467 */
468
469 /*
470 * The count must be one less than the actual size. This is handled by
471 * set_dma_addr()
472 */
473
474 if (sound_dma_automode[dev])
475 { /* Auto restart mode. Transfer the whole
476 * buffer */
477#ifdef linux
478 DISABLE_INTR (flags);
479 disable_dma (chan);
480 clear_dma_ff (chan);
481 set_dma_mode (chan, dma_mode | DMA_AUTOINIT);
482 set_dma_addr (chan, snd_raw_buf_phys[dev][0]);
483 set_dma_count (chan, sound_buffsizes[dev]);
484 enable_dma (chan);
485 RESTORE_INTR (flags);
486#else
487
488#ifdef __386BSD__
489 printk ("sound: Invalid DMA mode for device %d\n", dev);
490
491 isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
492 snd_raw_buf_phys[dev][0],
493 sound_buffsizes[dev],
494 chan);
495#else
496#ifdef ISC
497 printk ("sound: Invalid DMA mode for device %d\n", dev);
498 dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode) | DMAMODE_AUTO,
499 snd_raw_buf_phys[dev][0], count - 1);
500 dma_enable (chan);
501#else
502# error This routine is not valid for this OS.
503#endif
504#endif
505
506#endif
507 }
508 else
509 {
510#ifdef linux
511 DISABLE_INTR (flags);
512 disable_dma (chan);
513 clear_dma_ff (chan);
514 set_dma_mode (chan, dma_mode);
515 set_dma_addr (chan, physaddr);
516 set_dma_count (chan, count);
517 enable_dma (chan);
518 RESTORE_INTR (flags);
519#else
520#ifdef __386BSD__
521 isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
522 physaddr,
523 count,
524 chan);
525#else
526
527#ifdef ISC
528 dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode),
529 physaddr, count - 1);
530 dma_enable (chan);
531#else
532# error This routine is not valid for this OS.
533#endif /* !ISC */
534#endif
535
536#endif
537 }
538
539 return count;
540}
541
542long
543DMAbuf_init (long mem_start)
544{
545 int i;
546
547 /*
548 * In this version the DMA buffer allocation is done by sound_mem_init()
549 * which is called by init/main.c
550 */
551
552 for (i = 0; i < MAX_DSP_DEV; i++)
553 {
554 dev_qlen[i] = 0;
555 dev_qhead[i] = 0;
556 dev_qtail[i] = 0;
557 dev_active[i] = 0;
558 dev_busy[i] = 0;
559 bufferalloc_done[i] = 0;
560 }
561
562 return mem_start;
563}
564
565void
566DMAbuf_outputintr (int dev)
567{
568 unsigned long flags;
569
570 dev_active[dev] = 0;
571 dev_qlen[dev]--;
572 dev_qhead[dev] = (dev_qhead[dev] + 1) % dev_nbufs[dev];
573
574 if (dev_qlen[dev])
575 {
576 dsp_devs[dev]->output_block (dev, dev_buf_phys[dev][dev_qhead[dev]], dev_counts[dev][dev_qhead[dev]], 1);
577 dev_active[dev] = 1;
578 }
579 else
580 {
581 if (dev_busy[dev])
582 {
583 dev_underrun[dev]++;
584 dsp_devs[dev]->halt_xfer (dev);
585 }
586 else
587 { /* Device has been closed */
588 dsp_devs[dev]->close (dev);
589 }
590 }
591
592 DISABLE_INTR (flags);
593 if (dev_sleep_flag[dev])
594 {
595 dev_sleep_flag[dev] = 0;
596 WAKE_UP (dev_sleeper[dev]);
597 }
598 RESTORE_INTR (flags);
599}
600
601void
602DMAbuf_inputintr (int dev)
603{
604 unsigned long flags;
605
606 dev_active[dev] = 0;
607 if (!dev_busy[dev])
608 {
609 dsp_devs[dev]->close (dev);
610 }
611 else if (dev_qlen[dev] == (dev_nbufs[dev] - 1))
612 {
613 dev_underrun[dev]++;
614 dsp_devs[dev]->halt_xfer (dev);
615 }
616 else
617 {
618 dev_qlen[dev]++;
619 dev_qtail[dev] = (dev_qtail[dev] + 1) % dev_nbufs[dev];
620
621 dsp_devs[dev]->start_input (dev, dev_buf_phys[dev][dev_qtail[dev]], dev_buffsize[dev], 1);
622 dev_active[dev] = 1;
623 }
624
625 DISABLE_INTR (flags);
626 if (dev_sleep_flag[dev])
627 {
628 dev_sleep_flag[dev] = 0;
629 WAKE_UP (dev_sleeper[dev]);
630 }
631 RESTORE_INTR (flags);
632}
633
634int
635DMAbuf_open_dma (int dev)
636{
637 unsigned long flags;
638 int chan = sound_dsp_dmachan[dev];
639
640 if (ALLOC_DMA_CHN (chan))
641 {
642 printk ("Unable to grab DMA%d for the audio driver\n", chan);
643 return 0;
644 }
645
646 DISABLE_INTR (flags);
647#ifdef linux
648 disable_dma (chan);
649 clear_dma_ff (chan);
650#endif
651 RESTORE_INTR (flags);
652
653 return 1;
654}
655
656void
657DMAbuf_close_dma (int dev)
658{
659 int chan = sound_dsp_dmachan[dev];
660
661 DMAbuf_reset_dma (chan);
662 RELEASE_DMA_CHN (chan);
663}
664
665void
666DMAbuf_reset_dma (int chan)
667{
668}
669
670/*
671 * The sound_mem_init() is called by mem_init() immediately after mem_map is
672 * initialized and before free_page_list is created.
673 *
674 * This routine allocates DMA buffers at the end of available physical memory (
675 * <16M) and marks pages reserved at mem_map.
676 */
677
678#else
679/* Stub versions if audio services not included */
680
681int
682DMAbuf_open (int dev, int mode)
683{
684 return RET_ERROR (ENXIO);
685}
686
687int
688DMAbuf_release (int dev, int mode)
689{
690 return 0;
691}
692
693int
694DMAbuf_read (int dev, snd_rw_buf * user_buf, int count)
695{
696 return RET_ERROR (EIO);
697}
698
699int
700DMAbuf_getwrbuffer (int dev, char **buf, int *size)
701{
702 return RET_ERROR (EIO);
703}
704
705int
706DMAbuf_getrdbuffer (int dev, char **buf, int *len)
707{
708 return RET_ERROR (EIO);
709}
710
711int
712DMAbuf_rmchars (int dev, int buff_no, int c)
713{
714 return RET_ERROR (EIO);
715}
716
717int
718DMAbuf_start_output (int dev, int buff_no, int l)
719{
720 return RET_ERROR (EIO);
721}
722
723int
724DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
725{
726 return RET_ERROR (EIO);
727}
728
729long
730DMAbuf_init (long mem_start)
731{
732 return mem_start;
733}
734
735int
736DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
737{
738 return RET_ERROR (EIO);
739}
740
741int
742DMAbuf_open_dma (int chan)
743{
744 return RET_ERROR (ENXIO);
745}
746
747void
748DMAbuf_close_dma (int chan)
749{
750 return;
751}
752
753void
754DMAbuf_reset_dma (int chan)
755{
756 return;
757}
758
759void
760DMAbuf_inputintr (int dev)
761{
762 return;
763}
764
765void
766DMAbuf_outputintr (int dev)
767{
768 return;
769}
770
771#endif
772
773#endif