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
- sound_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 sound[20] =
393 {0};
394
395 int
396 init_module (void)
397 {
398 int err;
399 int ints[21];
400 int i;
401
402 if (connect_wrapper (WRAPPER_VERSION) < 0)
403 {
404 printk ("Sound: Incompatible kernel (wrapper) version\n");
405 return -EINVAL;
406 }
407
408
409
410
411 i = 0;
412 while (i < 20 && sound[i])
413 ints[i + 1] = sound[i++];
414 ints[0] = i;
415
416 if (i)
417 sound_setup ("sound=", ints);
418
419 err = module_register_chrdev (sound_major, "sound", &sound_fops);
420 if (err)
421 {
422 printk ("sound: driver already loaded/included in kernel\n");
423 return err;
424 }
425
426 chrdev_registered = 1;
427 soundcard_init ();
428
429 if (sound_num_blocks >= 1024)
430 printk ("Sound warning: Deallocation table was too small.\n");
431
432 return 0;
433 }
434
435 #ifdef MODULE
436
437
438 void
439 cleanup_module (void)
440 {
441 int i;
442
443 if (MOD_IN_USE)
444 {
445 return;
446 }
447
448 if (chrdev_registered)
449 module_unregister_chrdev (sound_major, "sound");
450
451 #ifdef CONFIG_SEQUENCER
452 sound_stop_timer ();
453 #endif
454 sound_unload_drivers ();
455
456 for (i = 0; i < sound_num_blocks; i++)
457 kfree (sound_mem_blocks[i]);
458
459 free_all_irqs ();
460
461 for (i = 0; i < 8; i++)
462 if (dma_alloc_map[i] != DMA_MAP_UNAVAIL)
463 {
464 printk ("Sound: Hmm, DMA%d was left allocated - fixed\n", i);
465 sound_free_dma (i);
466 }
467
468 }
469 #endif
470
471 void
472 tenmicrosec (int *osp)
473 {
474 int i;
475
476 for (i = 0; i < 16; i++)
477 inb (0x80);
478 }
479
480 int
481 snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, void *, struct pt_regs *), char *name, int *osp)
482 {
483 int retcode;
484
485 retcode = request_irq (interrupt_level, hndlr, 0 , name, NULL);
486 if (retcode < 0)
487 {
488 printk ("Sound: IRQ%d already in use\n", interrupt_level);
489 }
490 else
491 irqs |= (1ul << interrupt_level);
492
493 return retcode;
494 }
495
496 void
497 snd_release_irq (int vect)
498 {
499 if (!(irqs & (1ul << vect)))
500 return;
501
502 irqs &= ~(1ul << vect);
503 free_irq (vect, NULL);
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 debugmem = 0;
607
608 static int dma_buffsize = DSP_BUFFSIZE;
609
610 int
611 sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan)
612 {
613 char *start_addr, *end_addr;
614 int i, dma_pagesize;
615
616 dmap->mapping_flags &= ~DMA_MAP_MAPPED;
617
618 if (dmap->raw_buf != NULL)
619 return 0;
620
621 if (dma_buffsize < 4096)
622 dma_buffsize = 4096;
623
624 if (chan < 4)
625 dma_pagesize = 64 * 1024;
626 else
627 dma_pagesize = 128 * 1024;
628
629 dmap->raw_buf = NULL;
630
631 if (debugmem)
632 printk ("sound: buffsize[%d] = %lu\n", dev, audio_devs[dev]->buffsize);
633
634 audio_devs[dev]->buffsize = dma_buffsize;
635
636 if (audio_devs[dev]->buffsize > dma_pagesize)
637 audio_devs[dev]->buffsize = dma_pagesize;
638
639 start_addr = NULL;
640
641
642
643
644
645
646 while (start_addr == NULL && audio_devs[dev]->buffsize > PAGE_SIZE)
647 {
648 int sz, size;
649
650 for (sz = 0, size = PAGE_SIZE;
651 size < audio_devs[dev]->buffsize;
652 sz++, size <<= 1);
653
654 audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
655
656 if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
657 audio_devs[dev]->buffsize /= 2;
658 }
659
660 if (start_addr == NULL)
661 {
662 printk ("Sound error: Couldn't allocate DMA buffer\n");
663 return -ENOMEM;
664 }
665 else
666 {
667
668 end_addr = start_addr + audio_devs[dev]->buffsize - 1;
669
670 if (debugmem)
671 printk ("sound: start 0x%lx, end 0x%lx\n",
672 (long) start_addr, (long) end_addr);
673
674
675
676 if (((long) start_addr & ~(dma_pagesize - 1))
677 != ((long) end_addr & ~(dma_pagesize - 1))
678 || end_addr >= (char *) (MAX_DMA_ADDRESS))
679 {
680 printk (
681 "sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
682 (long) start_addr,
683 audio_devs[dev]->buffsize);
684 return -EFAULT;
685 }
686 }
687 dmap->raw_buf = start_addr;
688 dmap->raw_buf_phys = virt_to_bus (start_addr);
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 sound_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 #endif
736
737 void
738 conf_printf (char *name, struct address_info *hw_config)
739 {
740 if (!trace_init)
741 return;
742
743 printk ("<%s> at 0x%03x", name, hw_config->io_base);
744
745 if (hw_config->irq)
746 printk (" irq %d", (hw_config->irq > 0) ? hw_config->irq : -hw_config->irq);
747
748 if (hw_config->dma != -1 || hw_config->dma2 != -1)
749 {
750 printk (" dma %d", hw_config->dma);
751 if (hw_config->dma2 != -1)
752 printk (",%d", hw_config->dma2);
753 }
754
755 printk ("\n");
756 }
757
758 void
759 conf_printf2 (char *name, int base, int irq, int dma, int dma2)
760 {
761 if (!trace_init)
762 return;
763
764 printk ("<%s> at 0x%03x", name, base);
765
766 if (irq)
767 printk (" irq %d", (irq > 0) ? irq : -irq);
768
769 if (dma != -1 || dma2 != -1)
770 {
771 printk (" dma %d", dma);
772 if (dma2 != -1)
773 printk (",%d", dma2);
774 }
775
776 printk ("\n");
777 }