This source file includes following definitions.
- put_status
- init_status
- read_status
- snd_ioctl_return
- sound_read
- sound_write
- sound_lseek
- sound_open
- sound_release
- sound_ioctl
- sound_select
- soundcard_init
- tenmicrosec
- snd_set_irq_handler
- snd_release_irq
- request_sound_timer
- sound_stop_timer
- valid_dma_page
- sound_mem_init
- soundcard_init
- sound_mem_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #include "sound_config.h"
32
33 #ifdef CONFIGURE_SOUNDCARD
34
35 #include <linux/major.h>
36
37 struct sbc_device
38 {
39 int usecount;
40 };
41
42 static struct sbc_device sbc_devices[SND_NDEVS];
43 extern long seq_time;
44
45 static int in_use = 0;
46
47 static int soundcards_installed = 0;
48
49 static int soundcard_configured = 0;
50
51 static struct fileinfo files[SND_NDEVS];
52
53 extern char *snd_raw_buf[MAX_DSP_DEV][DSP_BUFFCOUNT];
54 extern unsigned long snd_raw_buf_phys[MAX_DSP_DEV][DSP_BUFFCOUNT];
55 extern int snd_raw_count[MAX_DSP_DEV];
56
57
58
59
60 static char *status_buf = NULL;
61 static int status_len, status_ptr;
62 static int status_busy = 0;
63
64 static int
65 put_status (char *s)
66 {
67 int l = strlen (s);
68
69 if (status_len + l >= 4000)
70 return 0;
71
72 memcpy (&status_buf[status_len], s, l);
73 status_len += l;
74
75 return 1;
76 }
77
78 static void
79 init_status (void)
80 {
81
82
83
84
85
86 char tmp_buf[256];
87 int i;
88
89 status_ptr = 0;
90
91 put_status ("Sound Driver:" SOUND_VERSION_STRING
92 " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY "@"
93 SOUND_CONFIG_HOST "." SOUND_CONFIG_DOMAIN ")"
94 "\n");
95
96 sprintf (tmp_buf, "Config options: 0x%08x\n\n", SELECTED_SOUND_OPTIONS);
97 if (!put_status (tmp_buf))
98 return;
99
100 sprintf (tmp_buf, "Major number: %d\n", SOUND_MAJOR);
101 if (!put_status (tmp_buf))
102 return;
103
104 if (!put_status ("HW config: \n"))
105 return;
106
107 for (i = 0; i < (num_sound_drivers - 1); i++)
108 {
109 if (!supported_drivers[i].enabled)
110 if (!put_status ("("))
111 return;
112
113 sprintf (tmp_buf, "Type %02x: %s",
114 supported_drivers[i].card_type,
115 supported_drivers[i].name);
116 if (!put_status (tmp_buf))
117 return;
118
119 sprintf (tmp_buf, " at 0x%03x irq %d drq %d",
120 supported_drivers[i].config.io_base,
121 supported_drivers[i].config.irq,
122 supported_drivers[i].config.dma);
123 if (!put_status (tmp_buf))
124 return;
125
126 if (!supported_drivers[i].enabled)
127 if (!put_status (")"))
128 return;
129
130 if (!put_status ("\n"))
131 return;
132 }
133
134 if (!put_status ("\nPCM devices:\n"))
135 return;
136
137 for (i = 0; i < num_dspdevs; i++)
138 {
139 sprintf (tmp_buf, "%02d: %s\n", i, dsp_devs[i]->name);
140 if (!put_status (tmp_buf))
141 return;
142 }
143
144 if (!put_status ("\nSynth devices:\n"))
145 return;
146
147 for (i = 0; i < num_synths; i++)
148 {
149 sprintf (tmp_buf, "%02d: %s\n", i, synth_devs[i]->info->name);
150 if (!put_status (tmp_buf))
151 return;
152 }
153
154 if (!put_status ("\nMidi devices:\n"))
155 return;
156
157 for (i = 0; i < num_midis; i++)
158 {
159 sprintf (tmp_buf, "%02d: %s\n", i, midi_devs[i]->info.name);
160 if (!put_status (tmp_buf))
161 return;
162 }
163
164 if (num_mixers)
165 {
166 if (!put_status ("\nMixer(s) installed\n"))
167 return;
168 }
169 else
170 {
171 if (!put_status ("\nNo mixers installed\n"))
172 return;
173 }
174 }
175
176 static int
177 read_status (char *buf, int count)
178 {
179
180
181
182 int l, c;
183
184 l = count;
185 c = status_len - status_ptr;
186
187 if (l > c)
188 l = c;
189 if (l <= 0)
190 return 0;
191
192 memcpy_tofs (buf, &status_buf[status_ptr], l);
193 status_ptr += l;
194
195 return l;
196 }
197
198 int
199 snd_ioctl_return (int *addr, int value)
200 {
201 if (value < 0)
202 return value;
203
204 PUT_WORD_TO_USER (addr, 0, value);
205 return 0;
206 }
207
208 static int
209 sound_read (struct inode *inode, struct file *file, char *buf, int count)
210 {
211 int dev;
212
213 dev = inode->i_rdev;
214 dev = MINOR (dev);
215
216 DEB (printk ("sound_read(dev=%d, count=%d)\n", dev, count));
217
218 switch (dev & 0x0f)
219 {
220 case SND_DEV_STATUS:
221 return read_status (buf, count);
222 break;
223
224 case SND_DEV_DSP:
225 case SND_DEV_DSP16:
226 case SND_DEV_AUDIO:
227 return audio_read (dev, &files[dev], buf, count);
228 break;
229
230 case SND_DEV_SEQ:
231 return sequencer_read (dev, &files[dev], buf, count);
232 break;
233
234 #ifndef EXCLUDE_MPU401
235 case SND_DEV_MIDIN:
236 return MIDIbuf_read (dev, &files[dev], buf, count);
237 #endif
238
239 default:
240 printk ("Sound: Undefined minor device %d\n", dev);
241 }
242
243 return RET_ERROR (EPERM);
244 }
245
246 static int
247 sound_write (struct inode *inode, struct file *file, char *buf, int count)
248 {
249 int dev;
250
251 dev = inode->i_rdev;
252 dev = MINOR (dev);
253
254 DEB (printk ("sound_write(dev=%d, count=%d)\n", dev, count));
255
256 switch (dev & 0x0f)
257 {
258
259 case SND_DEV_SEQ:
260 return sequencer_write (dev, &files[dev], buf, count);
261 break;
262
263 case SND_DEV_DSP:
264 case SND_DEV_DSP16:
265 case SND_DEV_AUDIO:
266 return audio_write (dev, &files[dev], buf, count);
267 break;
268
269 default:
270 return RET_ERROR (EPERM);
271 }
272
273 return count;
274 }
275
276 static int
277 sound_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
278 {
279 return RET_ERROR (EPERM);
280 }
281
282 static int
283 sound_open (struct inode *inode, struct file *file)
284 {
285 int dev, retval;
286
287 dev = inode->i_rdev;
288 dev = MINOR (dev);
289
290 DEB (printk ("sound_open(dev=%d) : usecount=%d\n", dev, sbc_devices[dev].usecount));
291
292 if ((dev >= SND_NDEVS) || (dev < 0))
293 {
294 printk ("Invalid minor device %d\n", dev);
295 return RET_ERROR (ENODEV);
296 }
297
298 if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
299 {
300 printk ("SoundCard Error: The soundcard system has not been configured\n");
301 return RET_ERROR (ENODEV);
302 }
303
304 files[dev].mode = 0;
305
306 if ((file->f_flags & O_ACCMODE) == O_RDWR)
307 files[dev].mode = OPEN_READWRITE;
308 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
309 files[dev].mode = OPEN_READ;
310 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
311 files[dev].mode = OPEN_WRITE;
312
313 switch (dev & 0x0f)
314 {
315 case SND_DEV_STATUS:
316 if (status_busy)
317 return RET_ERROR (EBUSY);
318 status_busy = 1;
319 if ((status_buf = (char *) KERNEL_MALLOC (4000)) == NULL)
320 return RET_ERROR (EIO);
321 status_len = status_ptr = 0;
322 init_status ();
323 break;
324
325 case SND_DEV_CTL:
326 if (!soundcards_installed)
327 if (soundcard_configured)
328 {
329 printk ("Soundcard not installed\n");
330 return RET_ERROR (ENODEV);
331 }
332 break;
333
334 case SND_DEV_SEQ:
335 if ((retval = sequencer_open (dev, &files[dev])) < 0)
336 return retval;
337 break;
338
339 #ifndef EXCLUDE_MPU401
340 case SND_DEV_MIDIN:
341 if ((retval = MIDIbuf_open (dev, &files[dev])) < 0)
342 return retval;
343 break;
344 #endif
345
346 case SND_DEV_DSP:
347 case SND_DEV_DSP16:
348 case SND_DEV_AUDIO:
349 if ((retval = audio_open (dev, &files[dev])) < 0)
350 return retval;
351 break;
352
353 default:
354 printk ("Invalid minor device %d\n", dev);
355 return RET_ERROR (ENODEV);
356 }
357
358 sbc_devices[dev].usecount++;
359 in_use++;
360
361 return 0;
362 }
363
364 static void
365 sound_release (struct inode *inode, struct file *file)
366 {
367 int dev;
368
369 dev = inode->i_rdev;
370 dev = MINOR (dev);
371
372 DEB (printk ("sound_release(dev=%d)\n", dev));
373
374 switch (dev & 0x0f)
375 {
376 case SND_DEV_STATUS:
377 if (status_buf)
378 KERNEL_FREE (status_buf);
379 status_buf = NULL;
380 status_busy = 0;
381 break;
382
383 case SND_DEV_CTL:
384 break;
385
386 case SND_DEV_SEQ:
387 sequencer_release (dev, &files[dev]);
388 break;
389
390 #ifndef EXCLUDE_MPU401
391 case SND_DEV_MIDIN:
392 MIDIbuf_release (dev, &files[dev]);
393 break;
394 #endif
395
396 case SND_DEV_DSP:
397 case SND_DEV_DSP16:
398 case SND_DEV_AUDIO:
399 audio_release (dev, &files[dev]);
400 break;
401
402 default:
403 printk ("Sound error: Releasing unknown device 0x%02x\n", dev);
404 }
405
406 sbc_devices[dev].usecount--;
407 in_use--;
408 }
409
410 static int
411 sound_ioctl (struct inode *inode, struct file *file,
412 unsigned int cmd, unsigned long arg)
413 {
414 int dev;
415
416 dev = inode->i_rdev;
417 dev = MINOR (dev);
418
419 DEB (printk ("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
420
421 switch (dev & 0x0f)
422 {
423
424 case SND_DEV_CTL:
425
426 if (!num_mixers)
427 return RET_ERROR (ENODEV);
428
429 if (dev >= num_mixers)
430 return RET_ERROR (ENODEV);
431
432 return mixer_devs[dev]->ioctl (dev, cmd, arg);
433 break;
434
435 case SND_DEV_SEQ:
436 return sequencer_ioctl (dev, &files[dev], cmd, arg);
437 break;
438
439 case SND_DEV_DSP:
440 case SND_DEV_DSP16:
441 case SND_DEV_AUDIO:
442 return audio_ioctl (dev, &files[dev], cmd, arg);
443 break;
444
445 #ifndef EXCLUDE_MPU401
446 case SND_DEV_MIDIN:
447 return MIDIbuf_ioctl (dev, &files[dev], cmd, arg);
448 break;
449 #endif
450
451 default:
452 return RET_ERROR (EPERM);
453 break;
454 }
455
456 return RET_ERROR (EPERM);
457 }
458
459 static int
460 sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
461 {
462 int dev;
463
464 dev = inode->i_rdev;
465 dev = MINOR (dev);
466
467 DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
468
469 switch (dev & 0x0f)
470 {
471 case SND_DEV_SEQ:
472 return sequencer_select (dev, &files[dev], sel_type, wait);
473 break;
474
475 default:
476 return 0;
477 }
478
479 return 0;
480 }
481
482 static struct file_operations sound_fops =
483 {
484 sound_lseek,
485 sound_read,
486 sound_write,
487 NULL,
488 sound_select,
489 sound_ioctl,
490 NULL,
491 sound_open,
492 sound_release
493 };
494
495 long
496 soundcard_init (long mem_start)
497 {
498 int i;
499
500 register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
501
502 soundcard_configured = 1;
503
504 mem_start = sndtable_init (mem_start);
505
506
507 if (!(soundcards_installed = sndtable_get_cardcount ()))
508 return mem_start;
509
510 if (num_dspdevs)
511 {
512 mem_start = DMAbuf_init (mem_start);
513 mem_start = audio_init (mem_start);
514 }
515
516 #ifndef EXCLUDE_MPU401
517 if (num_midis)
518 mem_start = MIDIbuf_init (mem_start);
519 #endif
520
521 if (num_midis + num_synths)
522 mem_start = sequencer_init (mem_start);
523
524 for (i = 0; i < SND_NDEVS; i++)
525 {
526 sbc_devices[i].usecount = 0;
527 }
528
529 return mem_start;
530 }
531
532 void
533 tenmicrosec (void)
534 {
535 int i;
536
537 for (i = 0; i < 16; i++)
538 inb (0x80);
539 }
540
541 int
542 snd_set_irq_handler (int interrupt_level, void(*hndlr)(int))
543 {
544 int retcode;
545
546 struct sigaction sa;
547
548 sa.sa_handler = hndlr;
549
550 #ifdef SND_SA_INTERRUPT
551 sa.sa_flags = SA_INTERRUPT;
552 #else
553 sa.sa_flags = 0;
554 #endif
555
556 sa.sa_mask = 0;
557 sa.sa_restorer = NULL;
558
559 retcode = irqaction (interrupt_level, &sa);
560
561 if (retcode < 0)
562 {
563 printk ("Sound: IRQ%d already in use\n", interrupt_level);
564 }
565
566 return retcode;
567 }
568
569 void
570 snd_release_irq(int vect)
571 {
572 free_irq(vect);
573 }
574
575 void
576 request_sound_timer (int count)
577 {
578 #ifndef EXCLUDE_SEQUENCER
579 if (count < 0)
580 count = jiffies + (-count);
581 else
582 count += seq_time;
583 timer_table[SOUND_TIMER].fn = sequencer_timer;
584 timer_table[SOUND_TIMER].expires = count;
585 timer_active |= 1 << SOUND_TIMER;
586 #endif
587 }
588
589 void
590 sound_stop_timer (void)
591 {
592 #ifndef EXCLUDE_SEQUENCER
593 timer_table[SOUND_TIMER].expires = 0;
594 timer_active &= ~(1 << SOUND_TIMER);
595 #endif
596 }
597
598 #ifndef EXCLUDE_AUDIO
599 static int
600 valid_dma_page (unsigned long addr, unsigned long dev_buffsize, unsigned long dma_pagesize)
601 {
602 if (((addr & (dma_pagesize - 1)) + dev_buffsize) <= dma_pagesize)
603 return 1;
604 else
605 return 0;
606 }
607
608 void
609 sound_mem_init (void)
610 {
611 int i, dev;
612 unsigned long start_addr, end_addr, mem_ptr, dma_pagesize;
613
614 mem_ptr = high_memory;
615
616
617
618 if (mem_ptr > (16 * 1024 * 1024))
619 mem_ptr = 16 * 1024 * 1024;
620
621 for (dev = 0; dev < num_dspdevs; dev++)
622 if (sound_buffcounts[dev] > 0 && sound_dsp_dmachan[dev] > 0)
623 {
624 if (sound_dma_automode[dev])
625 sound_buffcounts[dev] = 1;
626
627 if (sound_dsp_dmachan[dev] > 3 && sound_buffsizes[dev] > 65536)
628 dma_pagesize = 131072;
629 else
630 dma_pagesize = 65536;
631
632
633
634 if (sound_buffsizes[dev] > dma_pagesize)
635 sound_buffsizes[dev] = dma_pagesize;
636 sound_buffsizes[dev] &= 0xfffff000;
637 if (sound_buffsizes[dev] < 4096)
638 sound_buffsizes[dev] = 4096;
639
640
641
642 for (snd_raw_count[dev] = 0; snd_raw_count[dev] < sound_buffcounts[dev]; snd_raw_count[dev]++)
643 {
644 start_addr = mem_ptr - sound_buffsizes[dev];
645 if (!valid_dma_page (start_addr, sound_buffsizes[dev], dma_pagesize))
646 start_addr &= ~(dma_pagesize - 1);
647
648
649 end_addr = start_addr + sound_buffsizes[dev] - 1;
650
651 snd_raw_buf[dev][snd_raw_count[dev]] = (char *) start_addr;
652 snd_raw_buf_phys[dev][snd_raw_count[dev]] = start_addr;
653 mem_ptr = start_addr;
654
655 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
656 {
657 if (mem_map[i])
658 panic ("sound_mem_init: Page not free (driver incompatible with kernel).\n");
659
660 mem_map[i] = MAP_PAGE_RESERVED;
661 }
662 }
663 }
664 }
665
666 #endif
667
668 #else
669
670 long
671 soundcard_init (long mem_start)
672 {
673 return mem_start;
674 }
675
676 #endif
677
678 #if !defined(CONFIGURE_SOUNDCARD) || defined(EXCLUDE_AUDIO)
679 void
680 sound_mem_init (void)
681 {
682
683 }
684
685 #endif