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
38 static int is_unloading = 0;
39
40
41
42
43 caddr_t sound_mem_blocks[1024];
44 int sound_num_blocks = 0;
45
46 static int soundcard_configured = 0;
47
48 static struct fileinfo files[SND_NDEVS];
49
50 static char dma_alloc_map[8] =
51 {0};
52
53 #define DMA_MAP_UNAVAIL 0
54 #define DMA_MAP_FREE 1
55 #define DMA_MAP_BUSY 2
56
57 int
58 snd_ioctl_return (int *addr, int value)
59 {
60 if (value < 0)
61 return value;
62
63 put_fs_long (value, (long *) &((addr)[0]));
64 return 0;
65 }
66
67 static int
68 sound_read (inode_handle * inode, file_handle * file, char *buf, int count)
69 {
70 int dev;
71
72 dev = inode_get_rdev (inode);
73 dev = MINOR (dev);
74 files[dev].flags = file_get_flags (file);
75
76 return sound_read_sw (dev, &files[dev], buf, count);
77 }
78
79 static int
80 sound_write (inode_handle * inode, file_handle * file, const char *buf, int count)
81 {
82 int dev;
83
84 dev = inode_get_rdev (inode);
85 dev = MINOR (dev);
86 files[dev].flags = file_get_flags (file);
87
88 return sound_write_sw (dev, &files[dev], buf, count);
89 }
90
91 static int
92 sound_lseek (inode_handle * inode, file_handle * file, off_t offset, int orig)
93 {
94 return -EPERM;
95 }
96
97 static int
98 sound_open (inode_handle * inode, file_handle * file)
99 {
100 int dev, retval;
101 struct fileinfo tmp_file;
102
103 if (is_unloading)
104 {
105 printk ("Sound: Driver partially removed. Can't open device\n");
106 return -EBUSY;
107 }
108
109 dev = inode_get_rdev (inode);
110 dev = MINOR (dev);
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 = inode_get_rdev (inode);
145 dev = MINOR (dev);
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 = inode_get_rdev (inode);
161 dev = MINOR (dev);
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 = inode_get_rdev (inode);
198 dev = MINOR (dev);
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 = inode_get_rdev (inode);
241 dev = MINOR (dev);
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
349 if (sndtable_get_cardcount () == 0)
350 return;
351
352 #ifdef CONFIG_AUDIO
353 if (num_audiodevs)
354 {
355 DMAbuf_init (0);
356 audio_init (0);
357 }
358 #endif
359
360 #ifdef CONFIG_MIDI
361 if (num_midis)
362 MIDIbuf_init (0);
363 #endif
364
365 #ifdef CONFIG_SEQUENCER
366 if (num_midis + num_synths)
367 sequencer_init (0);
368 #endif
369
370 }
371
372 static unsigned int irqs = 0;
373
374 #ifdef MODULE
375 static void
376 free_all_irqs (void)
377 {
378 int i;
379
380 for (i = 0; i < 31; i++)
381 if (irqs & (1ul << i))
382 {
383 printk ("Sound warning: IRQ%d was left allocated. Fixed.\n", i);
384 snd_release_irq (i);
385 }
386 irqs = 0;
387 }
388
389 char kernel_version[] = UTS_RELEASE;
390
391 #endif
392
393 static int debugmem = 0;
394
395 static int sound[20] =
396 {0};
397
398 int
399 init_module (void)
400 {
401 int err;
402 int ints[21];
403 int i;
404
405 if (connect_wrapper (WRAPPER_VERSION) < 0)
406 {
407 printk ("Sound: Incompatible kernel (wrapper) version\n");
408 return -EINVAL;
409 }
410
411
412
413
414 i = 0;
415 while (i < 20 && sound[i])
416 ints[i + 1] = sound[i++];
417 ints[0] = i;
418
419 if (i)
420 sound_setup ("sound=", ints);
421
422 err = module_register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
423 if (err)
424 {
425 printk ("sound: driver already loaded/included in kernel\n");
426 return err;
427 }
428
429 chrdev_registered = 1;
430 soundcard_init ();
431
432 if (sound_num_blocks >= 1024)
433 printk ("Sound warning: Deallocation table was too small.\n");
434
435 return 0;
436 }
437
438 #ifdef MODULE
439
440
441 void
442 cleanup_module (void)
443 {
444 if (MOD_IN_USE)
445 printk ("sound: module busy -- remove delayed\n");
446 else
447 {
448 int i;
449
450 if (chrdev_registered)
451 module_unregister_chrdev (SOUND_MAJOR, "sound");
452
453 #ifdef CONFIG_SEQUENCER
454 sound_stop_timer ();
455 #endif
456 sound_unload_drivers ();
457
458 for (i = 0; i < sound_num_blocks; i++)
459 kfree (sound_mem_blocks[i]);
460
461 free_all_irqs ();
462
463 for (i = 0; i < 8; i++)
464 if (dma_alloc_map[i] != DMA_MAP_UNAVAIL)
465 {
466 printk ("Sound: Hmm, DMA%d was left allocated\n", i);
467 sound_free_dma (i);
468 }
469
470 }
471 }
472 #endif
473
474 void
475 tenmicrosec (int *osp)
476 {
477 int i;
478
479 for (i = 0; i < 16; i++)
480 inb (0x80);
481 }
482
483 int
484 snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, struct pt_regs *), char *name, int *osp)
485 {
486 int retcode;
487
488 retcode = request_irq (interrupt_level, hndlr, 0 , name);
489 if (retcode < 0)
490 {
491 printk ("Sound: IRQ%d already in use\n", interrupt_level);
492 }
493 else
494 irqs |= (1ul << interrupt_level);
495
496 return retcode;
497 }
498
499 void
500 snd_release_irq (int vect)
501 {
502 irqs &= ~(1ul << vect);
503 free_irq (vect);
504 }
505
506 int
507 sound_alloc_dma (int chn, char *deviceID)
508 {
509 int err;
510
511 if ((err = request_dma (chn, deviceID)) != 0)
512 return err;
513
514 dma_alloc_map[chn] = DMA_MAP_FREE;
515
516 return 0;
517 }
518
519 int
520 sound_open_dma (int chn, char *deviceID)
521 {
522 unsigned long flags;
523
524 save_flags (flags);
525 cli ();
526
527 if (dma_alloc_map[chn] != DMA_MAP_FREE)
528 {
529 printk ("sound_open_dma: DMA channel %d busy or not allocated\n", chn);
530 restore_flags (flags);
531 return 1;
532 }
533
534 dma_alloc_map[chn] = DMA_MAP_BUSY;
535 restore_flags (flags);
536 return 0;
537 }
538
539 void
540 sound_free_dma (int chn)
541 {
542 if (dma_alloc_map[chn] != DMA_MAP_FREE)
543 {
544
545 return;
546 }
547 free_dma (chn);
548 dma_alloc_map[chn] = DMA_MAP_UNAVAIL;
549 }
550
551 void
552 sound_close_dma (int chn)
553 {
554 unsigned long flags;
555
556 save_flags (flags);
557 cli ();
558
559 if (dma_alloc_map[chn] != DMA_MAP_BUSY)
560 {
561 printk ("sound_close_dma: Bad access to DMA channel %d\n", chn);
562 restore_flags (flags);
563 return;
564 }
565 dma_alloc_map[chn] = DMA_MAP_FREE;
566 restore_flags (flags);
567 }
568
569 #ifdef CONFIG_SEQUENCER
570
571
572 static struct timer_list seq_timer =
573 {NULL, NULL, 0, 0, sequencer_timer};
574
575 void
576 request_sound_timer (int count)
577 {
578 extern unsigned long seq_time;
579
580 if (count < 0)
581 count = jiffies + (-count);
582 else
583 count += seq_time;
584
585 ;
586
587 {
588 seq_timer.expires = ((count - jiffies)) + jiffies;
589 add_timer (&seq_timer);
590 };
591 }
592
593 void
594 sound_stop_timer (void)
595 {
596 del_timer (&seq_timer);;
597 }
598 #endif
599
600 #ifdef CONFIG_AUDIO
601
602 #ifdef KMALLOC_DMA_BROKEN
603 fatal_error__This_version_is_not_compatible_with_this_kernel;
604 #endif
605
606 static int dma_buffsize = DSP_BUFFSIZE;
607
608 int
609 sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan)
610 {
611 char *start_addr, *end_addr;
612 int i, dma_pagesize;
613
614 dmap->mapping_flags &= ~DMA_MAP_MAPPED;
615
616 if (dmap->raw_buf != NULL)
617 return 0;
618
619 if (dma_buffsize < 4096)
620 dma_buffsize = 4096;
621
622 if (chan < 4)
623 dma_pagesize = 64 * 1024;
624 else
625 dma_pagesize = 128 * 1024;
626
627 dmap->raw_buf = NULL;
628
629 if (debugmem)
630 printk ("sound: buffsize%d %lu\n", dev, audio_devs[dev]->buffsize);
631
632 audio_devs[dev]->buffsize = dma_buffsize;
633
634 if (audio_devs[dev]->buffsize > dma_pagesize)
635 audio_devs[dev]->buffsize = dma_pagesize;
636
637 start_addr = NULL;
638
639
640
641
642
643
644 while (start_addr == NULL && audio_devs[dev]->buffsize > PAGE_SIZE)
645 {
646 int sz, size;
647
648 for (sz = 0, size = PAGE_SIZE;
649 size < audio_devs[dev]->buffsize;
650 sz++, size <<= 1);
651
652 audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
653
654 if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
655 audio_devs[dev]->buffsize /= 2;
656 }
657
658 if (start_addr == NULL)
659 {
660 printk ("Sound error: Couldn't allocate DMA buffer\n");
661 return -ENOMEM;
662 }
663 else
664 {
665
666 end_addr = start_addr + audio_devs[dev]->buffsize - 1;
667
668 if (debugmem)
669 printk ("sound: start 0x%lx, end 0x%lx\n",
670 (long) start_addr, (long) end_addr);
671
672
673
674 if (((long) start_addr & ~(dma_pagesize - 1))
675 != ((long) end_addr & ~(dma_pagesize - 1))
676 || end_addr >= (char *) (MAX_DMA_ADDRESS))
677 {
678 printk (
679 "sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
680 (long) start_addr,
681 audio_devs[dev]->buffsize);
682 return -EFAULT;
683 }
684 }
685 dmap->raw_buf = start_addr;
686 dmap->raw_buf_phys = virt_to_bus (start_addr);
687
688 memset (dmap->raw_buf, 0x00, audio_devs[dev]->buffsize);
689
690 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
691 {
692 mem_map_reserve (i);
693 }
694
695 return 0;
696 }
697
698 void
699 sound_free_dmap (int dev, struct dma_buffparms *dmap)
700 {
701 if (dmap->raw_buf == NULL)
702 return;
703
704 if (dmap->mapping_flags & DMA_MAP_MAPPED)
705 return;
706
707 {
708 int sz, size, i;
709 unsigned long start_addr, end_addr;
710
711 for (sz = 0, size = PAGE_SIZE;
712 size < audio_devs[dev]->buffsize;
713 sz++, size <<= 1);
714
715 start_addr = (unsigned long) dmap->raw_buf;
716 end_addr = start_addr + audio_devs[dev]->buffsize;
717
718 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
719 {
720 mem_map_unreserve (i);
721 }
722
723 free_pages ((unsigned long) dmap->raw_buf, sz);
724 }
725 dmap->raw_buf = NULL;
726 }
727
728 int
729 soud_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc * info)
730 {
731 printk ("Entered sound_map_buffer()\n");
732 printk ("Exited sound_map_buffer()\n");
733 return -EINVAL;
734 }
735
736 void
737 conf_printf (char *name, struct address_info *hw_config)
738 {
739 if (!trace_init)
740 return;
741
742 printk ("<%s> at 0x%03x", name, hw_config->io_base);
743
744 if (hw_config->irq)
745 printk (" irq %d", hw_config->irq);
746
747 if (hw_config->dma != -1 || hw_config->dma2 != -1)
748 {
749 printk (" dma %d", hw_config->dma);
750 if (hw_config->dma2 != -1)
751 printk (",%d", hw_config->dma2);
752 }
753
754 printk ("\n");
755 }
756
757 void
758 conf_printf2 (char *name, int base, int irq, int dma, int dma2)
759 {
760 if (!trace_init)
761 return;
762
763 printk ("<%s> at 0x%03x", name, base);
764
765 if (irq)
766 printk (" irq %d", irq);
767
768 if (dma != -1 || dma2 != -1)
769 {
770 printk (" dma %d", dma);
771 if (dma2 != -1)
772 printk (",%d", dma2);
773 }
774
775 printk ("\n");
776 }
777 #endif