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