This source file includes following definitions.
- snd_ioctl_return
- sound_read
- sound_write
- sound_lseek
- sound_open
- sound_release
- sound_ioctl
- sound_select
- soundcard_init
- free_all_irqs
- init_module
- cleanup_module
- tenmicrosec
- snd_set_irq_handler
- snd_release_irq
- request_sound_timer
- sound_stop_timer
- valid_dma_page
- add_to_dma_list
- module_sound_mem_init
- module_sound_mem_release
- sound_mem_init
- soundcard_init
- sound_mem_init
- module_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
32
33 #include "sound_config.h"
34
35 #ifdef CONFIGURE_SOUNDCARD
36
37 #include <linux/major.h>
38
39 static int soundcards_installed = 0;
40
41
42 static int soundcard_configured = 0;
43
44 static struct fileinfo files[SND_NDEVS];
45
46 int
47 snd_ioctl_return (int *addr, int value)
48 {
49 if (value < 0)
50 return value;
51
52 PUT_WORD_TO_USER (addr, 0, value);
53 return 0;
54 }
55
56 static int
57 sound_read (struct inode *inode, struct file *file, char *buf, int count)
58 {
59 int dev;
60
61 dev = MINOR(inode->i_rdev);
62
63 return sound_read_sw (dev, &files[dev], buf, count);
64 }
65
66 static int
67 sound_write (struct inode *inode, struct file *file, const char *buf, int count)
68 {
69 int dev;
70
71 #ifdef MODULE
72 int err;
73
74 #endif
75
76 dev = MINOR(inode->i_rdev);
77
78 return sound_write_sw (dev, &files[dev], buf, count);
79 }
80
81 static int
82 sound_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
83 {
84 return RET_ERROR (EPERM);
85 }
86
87 static int
88 sound_open (struct inode *inode, struct file *file)
89 {
90 int dev, retval;
91 struct fileinfo tmp_file;
92
93 dev = MINOR(inode->i_rdev);
94
95 if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
96 {
97 printk ("SoundCard Error: The soundcard system has not been configured\n");
98 return RET_ERROR (ENXIO);
99 }
100
101 tmp_file.mode = 0;
102 tmp_file.filp = file;
103
104 if ((file->f_flags & O_ACCMODE) == O_RDWR)
105 tmp_file.mode = OPEN_READWRITE;
106 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
107 tmp_file.mode = OPEN_READ;
108 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
109 tmp_file.mode = OPEN_WRITE;
110
111 if ((retval = sound_open_sw (dev, &tmp_file)) < 0)
112 return retval;
113
114 #ifdef MODULE
115 MOD_INC_USE_COUNT;
116 #endif
117
118 memcpy ((char *) &files[dev], (char *) &tmp_file, sizeof (tmp_file));
119 return retval;
120 }
121
122 static void
123 sound_release (struct inode *inode, struct file *file)
124 {
125 int dev;
126
127 dev = MINOR(inode->i_rdev);
128
129 sound_release_sw (dev, &files[dev]);
130 #ifdef MODULE
131 MOD_DEC_USE_COUNT;
132 #endif
133 }
134
135 static int
136 sound_ioctl (struct inode *inode, struct file *file,
137 unsigned int cmd, unsigned long arg)
138 {
139 int dev;
140
141 dev = MINOR(inode->i_rdev);
142
143 if (cmd & IOC_INOUT)
144 {
145
146
147
148 int len, err;
149
150 len = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
151
152 if (cmd & IOC_IN)
153 {
154 if ((err = verify_area (VERIFY_READ, (void *) arg, len)) < 0)
155 return err;
156 }
157
158 if (cmd & IOC_OUT)
159 {
160 if ((err = verify_area (VERIFY_WRITE, (void *) arg, len)) < 0)
161 return err;
162 }
163
164 }
165
166 return sound_ioctl_sw (dev, &files[dev], cmd, arg);
167 }
168
169 static int
170 sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
171 {
172 int dev;
173
174 dev = MINOR(inode->i_rdev);
175
176 DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
177
178 switch (dev & 0x0f)
179 {
180 #ifndef EXCLUDE_SEQUENCER
181 case SND_DEV_SEQ:
182 case SND_DEV_SEQ2:
183 return sequencer_select (dev, &files[dev], sel_type, wait);
184 break;
185 #endif
186
187 #ifndef EXCLUDE_MIDI
188 case SND_DEV_MIDIN:
189 return MIDIbuf_select (dev, &files[dev], sel_type, wait);
190 break;
191 #endif
192
193 #ifndef EXCLUDE_AUDIO
194 case SND_DEV_DSP:
195 case SND_DEV_DSP16:
196 case SND_DEV_AUDIO:
197 return audio_select (dev, &files[dev], sel_type, wait);
198 break;
199 #endif
200
201 default:
202 return 0;
203 }
204
205 return 0;
206 }
207
208 static struct file_operations sound_fops =
209 {
210 sound_lseek,
211 sound_read,
212 sound_write,
213 NULL,
214 sound_select,
215 sound_ioctl,
216 NULL,
217 sound_open,
218 sound_release
219 };
220
221 long
222 soundcard_init (long mem_start)
223 {
224 #ifndef MODULE
225 register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
226 #endif
227
228 soundcard_configured = 1;
229
230 mem_start = sndtable_init (mem_start);
231
232
233 if (!(soundcards_installed = sndtable_get_cardcount ()))
234 return mem_start;
235
236 #ifndef EXCLUDE_AUDIO
237 if (num_audiodevs)
238 {
239 mem_start = DMAbuf_init (mem_start);
240 mem_start = audio_init (mem_start);
241 }
242 #endif
243
244 #ifndef EXCLUDE_MIDI
245 if (num_midis)
246 mem_start = MIDIbuf_init (mem_start);
247 #endif
248
249 #ifndef EXCLUDE_SEQUENCER
250 if (num_midis + num_synths)
251 mem_start = sequencer_init (mem_start);
252 #endif
253
254 return mem_start;
255 }
256
257 #ifdef MODULE
258 static unsigned long irqs = 0;
259 void snd_release_irq (int);
260 static int module_sound_mem_init (void);
261 static void module_sound_mem_release (void);
262
263 static void
264 free_all_irqs (void)
265 {
266 int i;
267
268 for (i = 0; i < 31; i++)
269 if (irqs & (1ul << i))
270 snd_release_irq (i);
271 irqs = 0;
272 }
273
274 char kernel_version[] = UTS_RELEASE;
275
276 static long memory_pool = 0;
277 static int memsize = 70 * 1024;
278 static int debugmem = 0;
279
280 int
281 init_module (void)
282 {
283 long lastbyte;
284 int err;
285
286 printk ("sound: made modular by Peter Trattler (peter@sbox.tu-graz.ac.at)\n");
287 err = register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
288 if (err)
289 {
290 printk ("sound: driver already loaded/included in kernel\n");
291 return err;
292 }
293 memory_pool = (long) kmalloc (memsize, GFP_KERNEL);
294 if (memory_pool == 0l)
295 {
296 unregister_chrdev (SOUND_MAJOR, "sound");
297 return -ENOMEM;
298 }
299 lastbyte = soundcard_init (memory_pool);
300 if (lastbyte > memory_pool + memsize)
301 {
302 printk ("sound: Not enough memory; use : 'insmod sound.o memsize=%ld'\n",
303 lastbyte - memory_pool);
304 kfree ((void *) memory_pool);
305 unregister_chrdev (SOUND_MAJOR, "sound");
306 free_all_irqs ();
307 return -ENOMEM;
308 }
309 err = module_sound_mem_init ();
310 if (err)
311 {
312 module_sound_mem_release ();
313 kfree ((void *) memory_pool);
314 unregister_chrdev (SOUND_MAJOR, "sound");
315 free_all_irqs ();
316 return err;
317 }
318 if (lastbyte < memory_pool + memsize)
319 printk ("sound: (Suggestion) too much memory; use : 'insmod sound.o memsize=%ld'\n",
320 lastbyte - memory_pool);
321 return 0;
322 }
323
324 void
325 cleanup_module (void)
326 {
327 if (MOD_IN_USE)
328 printk ("sound: module busy -- remove delayed\n");
329 else
330 {
331 kfree ((void *) memory_pool);
332 unregister_chrdev (SOUND_MAJOR, "sound");
333 free_all_irqs ();
334 module_sound_mem_release ();
335 }
336 }
337
338 #endif
339
340 void
341 tenmicrosec (void)
342 {
343 int i;
344
345 for (i = 0; i < 16; i++)
346 inb (0x80);
347 }
348
349 int
350 snd_set_irq_handler (int interrupt_level, INT_HANDLER_PROTO (), char *name)
351 {
352 int retcode;
353
354 retcode = request_irq (interrupt_level, hndlr, SA_INTERRUPT, name);
355 if (retcode < 0)
356 {
357 printk ("Sound: IRQ%d already in use\n", interrupt_level);
358 }
359 #ifdef MODULE
360 else
361 irqs |= (1ul << interrupt_level);
362 #endif
363
364 return retcode;
365 }
366
367 void
368 snd_release_irq (int vect)
369 {
370 #ifdef MODULE
371 irqs &= ~(1ul << vect);
372 #endif
373 free_irq (vect);
374 }
375
376 #ifndef EXCLUDE_SEQUENCER
377 void
378 request_sound_timer (int count)
379 {
380 extern unsigned long seq_time;
381
382 #if 1
383 if (count < 0)
384 count = jiffies + (-count);
385 else
386 count += seq_time;
387 timer_table[SOUND_TIMER].fn = sequencer_timer;
388 timer_table[SOUND_TIMER].expires = count;
389 timer_active |= 1 << SOUND_TIMER;
390 #endif
391 }
392
393 #endif
394
395 void
396 sound_stop_timer (void)
397 {
398 #if 1
399 timer_table[SOUND_TIMER].expires = 0;
400 timer_active &= ~(1 << SOUND_TIMER);
401 #endif
402 }
403
404 #ifndef EXCLUDE_AUDIO
405 static int
406 valid_dma_page (unsigned long addr, unsigned long dev_buffsize, unsigned long dma_pagesize)
407 {
408 if (((addr & (dma_pagesize - 1)) + dev_buffsize) <= dma_pagesize)
409 return 1;
410 else
411 return 0;
412 }
413
414 #ifdef MODULE
415
416 #ifdef KMALLOC_DMA_BROKEN
417 #define KMALLOC_MEM_REGIONS 20
418
419 static char *dma_list[KMALLOC_MEM_REGIONS];
420 static int dma_last = 0;
421 inline void
422 add_to_dma_list (char *adr)
423 {
424 dma_list[dma_last++] = adr;
425 }
426
427 #endif
428
429 static int
430 module_sound_mem_init (void)
431 {
432 int dev, ret = 0;
433 unsigned long dma_pagesize;
434 char *start_addr, *end_addr;
435 int order, size;
436 struct dma_buffparms *dmap;
437
438 for (dev = 0; dev < num_audiodevs; dev++)
439 if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
440 {
441 dmap = audio_devs[dev]->dmap;
442 if (audio_devs[dev]->flags & DMA_AUTOMODE)
443 audio_devs[dev]->buffcount = 1;
444
445 if (audio_devs[dev]->dmachan > 3)
446 dma_pagesize = 131072;
447 else
448 dma_pagesize = 65536;
449 if (debugmem)
450 printk ("sound: dma-page-size %lu\n", dma_pagesize);
451
452
453 if (audio_devs[dev]->buffsize > dma_pagesize)
454 audio_devs[dev]->buffsize = dma_pagesize;
455 audio_devs[dev]->buffsize &= 0xfffff000;
456 if (audio_devs[dev]->buffsize < 4096)
457 audio_devs[dev]->buffsize = 4096;
458 if (debugmem)
459 printk ("sound: buffsize %lu\n", audio_devs[dev]->buffsize);
460
461 for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount;
462 dmap->raw_count++)
463 {
464 #ifdef KMALLOC_DMA_BROKEN
465 start_addr = kmalloc (audio_devs[dev]->buffsize, GFP_KERNEL);
466 if (start_addr)
467 {
468 if (debugmem)
469 printk ("sound: trying 0x%lx for DMA\n", (long) start_addr);
470 if (valid_dma_page ((unsigned long) start_addr,
471 audio_devs[dev]->buffsize,
472 dma_pagesize))
473 add_to_dma_list (start_addr);
474 else
475 {
476 kfree (start_addr);
477 start_addr = kmalloc (audio_devs[dev]->buffsize * 2,
478 GFP_KERNEL);
479 if (start_addr)
480 {
481 if (debugmem)
482 printk ("sound: failed; trying 0x%lx aligned to",
483 (long) start_addr);
484 add_to_dma_list (start_addr);
485
486 start_addr = (char *) (((long) start_addr
487 + dma_pagesize - 1)
488 & ~(dma_pagesize - 1));
489 if (debugmem)
490 printk (" 0x%lx\n", (long) start_addr);
491 }
492 }
493 }
494 #else
495 for (order = 0, size = PAGE_SIZE;
496 size < audio_devs[dev]->buffsize;
497 order++, size <<= 1);
498 start_addr = (char *) __get_free_pages(GFP_KERNEL, order, MAX_DMA_ADDRESS);
499 #endif
500 if (start_addr == NULL)
501 ret = -ENOMEM;
502
503
504
505 else
506 {
507
508 end_addr = start_addr + audio_devs[dev]->buffsize - 1;
509 if (debugmem)
510 printk ("sound: start 0x%lx, end 0x%lx\n",
511 (long) start_addr, (long) end_addr);
512
513 if (((long) start_addr & ~(dma_pagesize - 1))
514 != ((long) end_addr & ~(dma_pagesize - 1))
515 || end_addr >= (char *) (16 * 1024 * 1024))
516 {
517 printk (
518 "sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
519 (long) start_addr,
520 audio_devs[dev]->buffsize);
521 ret = -EFAULT;
522 }
523 }
524 dmap->raw_buf[dmap->raw_count] = start_addr;
525 dmap->raw_buf_phys[dmap->raw_count] = (unsigned long) start_addr;
526 }
527 }
528 return ret;
529 }
530
531 static void
532 module_sound_mem_release (void)
533 {
534 #ifdef KMALLOC_DMA_BROKEN
535 int i;
536
537 for (i = 0; i < dma_last; i++)
538 {
539 if (debugmem)
540 printk ("sound: freeing 0x%lx\n", (long) dma_list[i]);
541 kfree (dma_list[i]);
542 }
543 #else
544 int dev, i;
545 int order, size;
546
547 for (dev = 0; dev < num_audiodevs; dev++) {
548 for (order = 0, size = PAGE_SIZE;
549 size < audio_devs[dev]->buffsize;
550 order++, size <<= 1);
551 if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
552 {
553 for (i = 0; i < audio_devs[dev]->buffcount; i++)
554 if (audio_devs[dev]->dmap->raw_buf[i])
555 {
556 if (debugmem)
557 printk ("sound: freeing 0x%lx\n",
558 (long) (audio_devs[dev]->dmap->raw_buf[i]));
559 free_pages((unsigned long) audio_devs[dev]->dmap->raw_buf[i],
560 order);
561 }
562 }
563 }
564 #endif
565 }
566
567 #else
568
569 void
570 sound_mem_init (void)
571 {
572 int i, dev;
573 unsigned long start_addr, end_addr, mem_ptr, dma_pagesize;
574 struct dma_buffparms *dmap;
575
576 mem_ptr = high_memory;
577
578
579
580 if (mem_ptr > (16 * 1024 * 1024))
581 mem_ptr = 16 * 1024 * 1024;
582
583 for (dev = 0; dev < num_audiodevs; dev++)
584 if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
585 {
586 dmap = audio_devs[dev]->dmap;
587
588 if (audio_devs[dev]->flags & DMA_AUTOMODE)
589 audio_devs[dev]->buffcount = 1;
590
591 if (audio_devs[dev]->dmachan > 3 && audio_devs[dev]->buffsize > 65536)
592 dma_pagesize = 131072;
593 else
594 dma_pagesize = 65536;
595
596
597
598 if (audio_devs[dev]->buffsize > dma_pagesize)
599 audio_devs[dev]->buffsize = dma_pagesize;
600 audio_devs[dev]->buffsize &= 0xfffff000;
601 if (audio_devs[dev]->buffsize < 4096)
602 audio_devs[dev]->buffsize = 4096;
603
604
605
606 for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount; dmap->raw_count++)
607 {
608 start_addr = mem_ptr - audio_devs[dev]->buffsize;
609 if (!valid_dma_page (start_addr, audio_devs[dev]->buffsize, dma_pagesize))
610 start_addr &= ~(dma_pagesize - 1);
611
612
613 end_addr = start_addr + audio_devs[dev]->buffsize - 1;
614
615 dmap->raw_buf[dmap->raw_count] = (char *) start_addr;
616 dmap->raw_buf_phys[dmap->raw_count] = start_addr;
617 mem_ptr = start_addr;
618
619 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
620 {
621 if (mem_map[i].reserved || mem_map[i].count)
622 panic ("sound_mem_init: Page not free (driver incompatible with kernel).\n");
623
624 mem_map[i].reserved = 1;
625 }
626 }
627 }
628 }
629
630 #endif
631
632 #endif
633
634 #else
635
636 long
637 soundcard_init (long mem_start)
638 {
639 return mem_start;
640 }
641
642 #endif
643
644 #if !defined(CONFIGURE_SOUNDCARD) || defined(EXCLUDE_AUDIO)
645 void
646 sound_mem_init (void)
647 {
648
649 }
650
651 #ifdef MODULE
652 static int
653 module_sound_mem_init (void)
654 {
655 return 0;
656 }
657
658 #endif
659
660 #endif