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