This source file includes following definitions.
- snd_ioctl_return
- sound_read
- sound_write
- sound_lseek
- sound_open
- sound_release
- sound_ioctl
- sound_select
- sound_mmap
- soundcard_init
- free_all_irqs
- init_module
- cleanup_module
- tenmicrosec
- snd_set_irq_handler
- snd_release_irq
- sound_alloc_dma
- sound_open_dma
- sound_free_dma
- sound_close_dma
- request_sound_timer
- sound_stop_timer
- sound_alloc_dmap
- sound_free_dmap
- soud_map_buffer
- conf_printf
- conf_printf2
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 #include <linux/config.h>
30
31
32 #include "sound_config.h"
33
34 #include <linux/major.h>
35
36 static int chrdev_registered = 0;
37 static int sound_major = SOUND_MAJOR;
38
39 static int is_unloading = 0;
40
41
42
43
44 caddr_t sound_mem_blocks[1024];
45 int sound_num_blocks = 0;
46
47 static int soundcard_configured = 0;
48
49 static struct fileinfo files[SND_NDEVS];
50
51 static char dma_alloc_map[8] =
52 {0};
53
54 #define DMA_MAP_UNAVAIL 0
55 #define DMA_MAP_FREE 1
56 #define DMA_MAP_BUSY 2
57
58 int
59 snd_ioctl_return (int *addr, int value)
60 {
61 if (value < 0)
62 return value;
63
64 put_fs_long (value, (long *) &((addr)[0]));
65 return 0;
66 }
67
68 static int
69 sound_read (inode_handle * inode, file_handle * file, char *buf, int count)
70 {
71 int dev;
72
73 dev = MINOR (inode_get_rdev (inode));
74
75 files[dev].flags = file_get_flags (file);
76
77 return sound_read_sw (dev, &files[dev], buf, count);
78 }
79
80 static int
81 sound_write (inode_handle * inode, file_handle * file, const char *buf, int count)
82 {
83 int dev;
84
85 dev = MINOR (inode_get_rdev (inode));
86
87 files[dev].flags = file_get_flags (file);
88
89 return sound_write_sw (dev, &files[dev], buf, count);
90 }
91
92 static int
93 sound_lseek (inode_handle * inode, file_handle * file, off_t offset, int orig)
94 {
95 return -EPERM;
96 }
97
98 static int
99 sound_open (inode_handle * inode, file_handle * file)
100 {
101 int dev, retval;
102 struct fileinfo tmp_file;
103
104 if (is_unloading)
105 {
106 printk ("Sound: Driver partially removed. Can't open device\n");
107 return -EBUSY;
108 }
109
110 dev = MINOR (inode_get_rdev (inode));
111
112 if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
113 {
114 printk ("SoundCard Error: The soundcard system has not been configured\n");
115 return -ENXIO;
116 }
117
118 tmp_file.mode = 0;
119 tmp_file.flags = file_get_flags (file);
120
121 if ((tmp_file.flags & O_ACCMODE) == O_RDWR)
122 tmp_file.mode = OPEN_READWRITE;
123 if ((tmp_file.flags & O_ACCMODE) == O_RDONLY)
124 tmp_file.mode = OPEN_READ;
125 if ((tmp_file.flags & O_ACCMODE) == O_WRONLY)
126 tmp_file.mode = OPEN_WRITE;
127
128 if ((retval = sound_open_sw (dev, &tmp_file)) < 0)
129 return retval;
130
131 #ifdef MODULE
132 MOD_INC_USE_COUNT;
133 #endif
134
135 memcpy ((char *) &files[dev], (char *) &tmp_file, sizeof (tmp_file));
136 return retval;
137 }
138
139 static void
140 sound_release (inode_handle * inode, file_handle * file)
141 {
142 int dev;
143
144 dev = MINOR (inode_get_rdev (inode));
145
146 files[dev].flags = file_get_flags (file);
147
148 sound_release_sw (dev, &files[dev]);
149 #ifdef MODULE
150 MOD_DEC_USE_COUNT;
151 #endif
152 }
153
154 static int
155 sound_ioctl (inode_handle * inode, file_handle * file,
156 unsigned int cmd, unsigned long arg)
157 {
158 int dev, err;
159
160 dev = MINOR (inode_get_rdev (inode));
161
162 files[dev].flags = file_get_flags (file);
163
164 if (_IOC_DIR (cmd) != _IOC_NONE)
165 {
166
167
168
169 int len;
170
171 len = _IOC_SIZE (cmd);
172
173 if (_IOC_DIR (cmd) == _IOC_WRITE)
174 {
175 if ((err = verify_area (VERIFY_READ, (void *) arg, len)) < 0)
176 return err;
177 }
178
179 if (_IOC_DIR (cmd) == _IOC_READ)
180 {
181 if ((err = verify_area (VERIFY_WRITE, (void *) arg, len)) < 0)
182 return err;
183 }
184
185 }
186
187 err = sound_ioctl_sw (dev, &files[dev], cmd, (caddr_t) arg);
188
189 return err;
190 }
191
192 static int
193 sound_select (inode_handle * inode, file_handle * file, int sel_type, select_table_handle * wait)
194 {
195 int dev;
196
197 dev = MINOR (inode_get_rdev (inode));
198
199 files[dev].flags = file_get_flags (file);
200
201 DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
202
203 switch (dev & 0x0f)
204 {
205 #ifdef CONFIG_SEQUENCER
206 case SND_DEV_SEQ:
207 case SND_DEV_SEQ2:
208 return sequencer_select (dev, &files[dev], sel_type, wait);
209 break;
210 #endif
211
212 #ifdef CONFIG_MIDI
213 case SND_DEV_MIDIN:
214 return MIDIbuf_select (dev, &files[dev], sel_type, wait);
215 break;
216 #endif
217
218 #ifdef CONFIG_AUDIO
219 case SND_DEV_DSP:
220 case SND_DEV_DSP16:
221 case SND_DEV_AUDIO:
222 return audio_select (dev, &files[dev], sel_type, wait);
223 break;
224 #endif
225
226 default:
227 return 0;
228 }
229
230 return 0;
231 }
232
233 static int
234 sound_mmap (inode_handle * inode, file_handle * file, vm_area_handle * vma)
235 {
236 int dev, dev_class;
237 unsigned long size;
238 struct dma_buffparms *dmap = NULL;
239
240 dev = MINOR (inode_get_rdev (inode));
241
242 files[dev].flags = file_get_flags (file);
243
244 dev_class = dev & 0x0f;
245 dev >>= 4;
246
247 if (dev_class != SND_DEV_DSP && dev_class != SND_DEV_DSP16 && dev_class != SND_DEV_AUDIO)
248 {
249 printk ("Sound: mmap() not supported for other than audio devices\n");
250 return -EINVAL;
251 }
252
253 if ((vma_get_flags (vma) & (VM_READ | VM_WRITE)) == (VM_READ | VM_WRITE))
254 {
255 printk ("Sound: Cannot do read/write mmap()\n");
256 return -EINVAL;
257 }
258
259 if (vma_get_flags (vma) & VM_READ)
260 {
261 dmap = audio_devs[dev]->dmap_in;
262 }
263 else if (vma_get_flags (vma) & VM_WRITE)
264 {
265 dmap = audio_devs[dev]->dmap_out;
266 }
267 else
268 {
269 printk ("Sound: Undefined mmap() access\n");
270 return -EINVAL;
271 }
272
273 if (dmap == NULL)
274 {
275 printk ("Sound: mmap() error. dmap == NULL\n");
276 return -EIO;
277 }
278
279 if (dmap->raw_buf == NULL)
280 {
281 printk ("Sound: mmap() called when raw_buf == NULL\n");
282 return -EIO;
283 }
284
285 if (dmap->mapping_flags)
286 {
287 printk ("Sound: mmap() called twice for the same DMA buffer\n");
288 return -EIO;
289 }
290
291 if (vma_get_offset (vma) != 0)
292 {
293 printk ("Sound: mmap() offset must be 0.\n");
294 return -EINVAL;
295 }
296
297 size = vma_get_end (vma) - vma_get_start (vma);
298
299 if (size != dmap->bytes_in_use)
300 {
301 printk ("Sound: mmap() size = %ld. Should be %d\n",
302 size, dmap->bytes_in_use);
303 }
304
305
306 if (remap_page_range (vma_get_start (vma), dmap->raw_buf_phys,
307 vma_get_end (vma) - vma_get_start (vma),
308 vma_get_page_prot (vma)))
309 return -EAGAIN;
310
311 vma_set_inode (vma, inode);
312 inode_inc_count (inode);
313
314 dmap->mapping_flags |= DMA_MAP_MAPPED;
315
316 memset (dmap->raw_buf,
317 dmap->neutral_byte,
318 dmap->bytes_in_use);
319 return 0;
320 }
321
322 static struct file_operation_handle sound_fops =
323 {
324 sound_lseek,
325 sound_read,
326 sound_write,
327 NULL,
328 sound_select,
329 sound_ioctl,
330 sound_mmap,
331 sound_open,
332 sound_release
333 };
334
335 void
336 soundcard_init (void)
337 {
338 #ifndef MODULE
339 module_register_chrdev (sound_major, "sound", &sound_fops);
340 chrdev_registered = 1;
341 #endif
342
343 soundcard_configured = 1;
344
345 sndtable_init (0);
346
347
348 if (sndtable_get_cardcount () == 0)
349 return;
350
351 #ifdef CONFIG_AUDIO
352 if (num_audiodevs)
353 {
354 DMAbuf_init (0);
355 audio_init (0);
356 }
357 #endif
358
359 #ifdef CONFIG_MIDI
360 if (num_midis)
361 MIDIbuf_init (0);
362 #endif
363
364 #ifdef CONFIG_SEQUENCER
365 if (num_midis + num_synths)
366 sequencer_init (0);
367 #endif
368
369 }
370
371 static unsigned int irqs = 0;
372
373 #ifdef MODULE
374 static void
375 free_all_irqs (void)
376 {
377 int i;
378
379 for (i = 0; i < 31; i++)
380 if (irqs & (1ul << i))
381 {
382 printk ("Sound warning: IRQ%d was left allocated - fixed.\n", i);
383 snd_release_irq (i);
384 }
385 irqs = 0;
386 }
387
388 char kernel_version[] = UTS_RELEASE;
389
390 #endif
391
392 static int debugmem = 0;
393
394 static int sound[20] =
395 {0};
396
397 int
398 init_module (void)
399 {
400 int err;
401 int ints[21];
402 int i;
403
404 if (connect_wrapper (WRAPPER_VERSION) < 0)
405 {
406 printk ("Sound: Incompatible kernel (wrapper) version\n");
407 return -EINVAL;
408 }
409
410
411
412
413 i = 0;
414 while (i < 20 && sound[i])
415 ints[i + 1] = sound[i++];
416 ints[0] = i;
417
418 if (i)
419 sound_setup ("sound=", ints);
420
421 err = module_register_chrdev (sound_major, "sound", &sound_fops);
422 if (err)
423 {
424 printk ("sound: driver already loaded/included in kernel\n");
425 return err;
426 }
427
428 chrdev_registered = 1;
429 soundcard_init ();
430
431 if (sound_num_blocks >= 1024)
432 printk ("Sound warning: Deallocation table was too small.\n");
433
434 return 0;
435 }
436
437 #ifdef MODULE
438
439
440 void
441 cleanup_module (void)
442 {
443 int i;
444
445 if (chrdev_registered)
446 module_unregister_chrdev (sound_major, "sound");
447
448 #ifdef CONFIG_SEQUENCER
449 sound_stop_timer ();
450 #endif
451 sound_unload_drivers ();
452
453 for (i = 0; i < sound_num_blocks; i++)
454 kfree (sound_mem_blocks[i]);
455
456 free_all_irqs ();
457
458 for (i = 0; i < 8; i++)
459 if (dma_alloc_map[i] != DMA_MAP_UNAVAIL)
460 {
461 printk ("Sound: Hmm, DMA%d was left allocated - fixed\n", i);
462 sound_free_dma (i);
463 }
464 }
465 #endif
466
467 void
468 tenmicrosec (int *osp)
469 {
470 int i;
471
472 for (i = 0; i < 16; i++)
473 inb (0x80);
474 }
475
476 int
477 snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, void *, struct pt_regs *), char *name, int *osp)
478 {
479 int retcode;
480
481 retcode = request_irq (interrupt_level, hndlr, 0 , name, NULL);
482 if (retcode < 0)
483 {
484 printk ("Sound: IRQ%d already in use\n", interrupt_level);
485 }
486 else
487 irqs |= (1ul << interrupt_level);
488
489 return retcode;
490 }
491
492 void
493 snd_release_irq (int vect)
494 {
495 if (!(irqs & (1ul << vect)))
496 return;
497
498 irqs &= ~(1ul << vect);
499 free_irq (vect, NULL);
500 }
501
502 int
503 sound_alloc_dma (int chn, char *deviceID)
504 {
505 int err;
506
507 if ((err = request_dma (chn, deviceID)) != 0)
508 return err;
509
510 dma_alloc_map[chn] = DMA_MAP_FREE;
511
512 return 0;
513 }
514
515 int
516 sound_open_dma (int chn, char *deviceID)
517 {
518 unsigned long flags;
519
520 save_flags (flags);
521 cli ();
522
523 if (dma_alloc_map[chn] != DMA_MAP_FREE)
524 {
525 printk ("sound_open_dma: DMA channel %d busy or not allocated\n", chn);
526 restore_flags (flags);
527 return 1;
528 }
529
530 dma_alloc_map[chn] = DMA_MAP_BUSY;
531 restore_flags (flags);
532 return 0;
533 }
534
535 void
536 sound_free_dma (int chn)
537 {
538 if (dma_alloc_map[chn] != DMA_MAP_FREE)
539 {
540
541 return;
542 }
543 free_dma (chn);
544 dma_alloc_map[chn] = DMA_MAP_UNAVAIL;
545 }
546
547 void
548 sound_close_dma (int chn)
549 {
550 unsigned long flags;
551
552 save_flags (flags);
553 cli ();
554
555 if (dma_alloc_map[chn] != DMA_MAP_BUSY)
556 {
557 printk ("sound_close_dma: Bad access to DMA channel %d\n", chn);
558 restore_flags (flags);
559 return;
560 }
561 dma_alloc_map[chn] = DMA_MAP_FREE;
562 restore_flags (flags);
563 }
564
565 #ifdef CONFIG_SEQUENCER
566
567
568 static struct timer_list seq_timer =
569 {NULL, NULL, 0, 0, sequencer_timer};
570
571 void
572 request_sound_timer (int count)
573 {
574 extern unsigned long seq_time;
575
576 if (count < 0)
577 count = jiffies + (-count);
578 else
579 count += seq_time;
580
581 ;
582
583 {
584 seq_timer.expires = ((count - jiffies)) + jiffies;
585 add_timer (&seq_timer);
586 };
587 }
588
589 void
590 sound_stop_timer (void)
591 {
592 del_timer (&seq_timer);;
593 }
594 #endif
595
596 #ifdef CONFIG_AUDIO
597
598 #ifdef KMALLOC_DMA_BROKEN
599 fatal_error__This_version_is_not_compatible_with_this_kernel;
600 #endif
601
602 static int dma_buffsize = DSP_BUFFSIZE;
603
604 int
605 sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan)
606 {
607 char *start_addr, *end_addr;
608 int i, dma_pagesize;
609
610 dmap->mapping_flags &= ~DMA_MAP_MAPPED;
611
612 if (dmap->raw_buf != NULL)
613 return 0;
614
615 if (dma_buffsize < 4096)
616 dma_buffsize = 4096;
617
618 if (chan < 4)
619 dma_pagesize = 64 * 1024;
620 else
621 dma_pagesize = 128 * 1024;
622
623 dmap->raw_buf = NULL;
624
625 if (debugmem)
626 printk ("sound: buffsize[%d] = %lu\n", dev, audio_devs[dev]->buffsize);
627
628 audio_devs[dev]->buffsize = dma_buffsize;
629
630 if (audio_devs[dev]->buffsize > dma_pagesize)
631 audio_devs[dev]->buffsize = dma_pagesize;
632
633 start_addr = NULL;
634
635
636
637
638
639
640 while (start_addr == NULL && audio_devs[dev]->buffsize > PAGE_SIZE)
641 {
642 int sz, size;
643
644 for (sz = 0, size = PAGE_SIZE;
645 size < audio_devs[dev]->buffsize;
646 sz++, size <<= 1);
647
648 audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
649
650 if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, 1)) == NULL)
651 audio_devs[dev]->buffsize /= 2;
652 }
653
654 if (start_addr == NULL)
655 {
656 printk ("Sound error: Couldn't allocate DMA buffer\n");
657 return -ENOMEM;
658 }
659 else
660 {
661
662 end_addr = start_addr + audio_devs[dev]->buffsize - 1;
663
664 if (debugmem)
665 printk ("sound: start 0x%lx, end 0x%lx\n",
666 (long) start_addr, (long) end_addr);
667
668
669
670 if (((long) start_addr & ~(dma_pagesize - 1))
671 != ((long) end_addr & ~(dma_pagesize - 1))
672 || end_addr >= (char *) (MAX_DMA_ADDRESS))
673 {
674 printk (
675 "sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
676 (long) start_addr,
677 audio_devs[dev]->buffsize);
678 return -EFAULT;
679 }
680 }
681 dmap->raw_buf = start_addr;
682 dmap->raw_buf_phys = virt_to_bus (start_addr);
683
684 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
685 {
686 mem_map_reserve (i);
687 }
688
689 return 0;
690 }
691
692 void
693 sound_free_dmap (int dev, struct dma_buffparms *dmap)
694 {
695 if (dmap->raw_buf == NULL)
696 return;
697
698 if (dmap->mapping_flags & DMA_MAP_MAPPED)
699 return;
700
701 {
702 int sz, size, i;
703 unsigned long start_addr, end_addr;
704
705 for (sz = 0, size = PAGE_SIZE;
706 size < audio_devs[dev]->buffsize;
707 sz++, size <<= 1);
708
709 start_addr = (unsigned long) dmap->raw_buf;
710 end_addr = start_addr + audio_devs[dev]->buffsize;
711
712 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
713 {
714 mem_map_unreserve (i);
715 }
716
717 free_pages ((unsigned long) dmap->raw_buf, sz);
718 }
719 dmap->raw_buf = NULL;
720 }
721
722 int
723 soud_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc * info)
724 {
725 printk ("Entered sound_map_buffer()\n");
726 printk ("Exited sound_map_buffer()\n");
727 return -EINVAL;
728 }
729
730 void
731 conf_printf (char *name, struct address_info *hw_config)
732 {
733 if (!trace_init)
734 return;
735
736 printk ("<%s> at 0x%03x", name, hw_config->io_base);
737
738 if (hw_config->irq)
739 printk (" irq %d", (hw_config->irq > 0) ? hw_config->irq : -hw_config->irq);
740
741 if (hw_config->dma != -1 || hw_config->dma2 != -1)
742 {
743 printk (" dma %d", hw_config->dma);
744 if (hw_config->dma2 != -1)
745 printk (",%d", hw_config->dma2);
746 }
747
748 printk ("\n");
749 }
750
751 void
752 conf_printf2 (char *name, int base, int irq, int dma, int dma2)
753 {
754 if (!trace_init)
755 return;
756
757 printk ("<%s> at 0x%03x", name, base);
758
759 if (irq)
760 printk (" irq %d", (irq > 0) ? irq : -irq);
761
762 if (dma != -1 || dma2 != -1)
763 {
764 printk (" dma %d", dma);
765 if (dma2 != -1)
766 printk (",%d", dma2);
767 }
768
769 printk ("\n");
770 }
771 #endif