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 static int soundcards_installed = 0;
40 static int chrdev_registered = 0;
41
42
43
44
45 caddr_t sound_mem_blocks[1024];
46 int sound_num_blocks = 0;
47
48 static int soundcard_configured = 0;
49
50 static struct fileinfo files[SND_NDEVS];
51
52 static char dma_alloc_map[8] =
53 {0};
54
55 #define DMA_MAP_UNAVAIL 0
56 #define DMA_MAP_FREE 1
57 #define DMA_MAP_BUSY 2
58
59 int
60 snd_ioctl_return (int *addr, int value)
61 {
62 if (value < 0)
63 return value;
64
65 put_fs_long (value, (long *) &((addr)[0]));
66 return 0;
67 }
68
69 static int
70 sound_read (struct inode *inode, struct file *file, char *buf, int count)
71 {
72 int dev;
73
74 dev = inode->i_rdev;
75 dev = MINOR (dev);
76
77 return sound_read_sw (dev, &files[dev], buf, count);
78 }
79
80 static int
81 sound_write (struct inode *inode, struct file *file, const char *buf, int count)
82 {
83 int dev;
84
85 dev = inode->i_rdev;
86 dev = MINOR (dev);
87
88 return sound_write_sw (dev, &files[dev], buf, count);
89 }
90
91 static int
92 sound_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
93 {
94 return -EPERM;
95 }
96
97 static int
98 sound_open (struct inode *inode, struct file *file)
99 {
100 int dev, retval;
101 struct fileinfo tmp_file;
102
103 dev = inode->i_rdev;
104 dev = MINOR (dev);
105
106 if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
107 {
108 printk ("SoundCard Error: The soundcard system has not been configured\n");
109 return -ENXIO;
110 }
111
112 tmp_file.mode = 0;
113 tmp_file.filp = file;
114
115 if ((file->f_flags & O_ACCMODE) == O_RDWR)
116 tmp_file.mode = OPEN_READWRITE;
117 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
118 tmp_file.mode = OPEN_READ;
119 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
120 tmp_file.mode = OPEN_WRITE;
121
122 if ((retval = sound_open_sw (dev, &tmp_file)) < 0)
123 return retval;
124
125 #ifdef MODULE
126 MOD_INC_USE_COUNT;
127 #endif
128
129 memcpy ((char *) &files[dev], (char *) &tmp_file, sizeof (tmp_file));
130 return retval;
131 }
132
133 static void
134 sound_release (struct inode *inode, struct file *file)
135 {
136 int dev;
137
138 dev = inode->i_rdev;
139 dev = MINOR (dev);
140
141 sound_release_sw (dev, &files[dev]);
142 #ifdef MODULE
143 MOD_DEC_USE_COUNT;
144 #endif
145 }
146
147 static int
148 sound_ioctl (struct inode *inode, struct file *file,
149 unsigned int cmd, unsigned long arg)
150 {
151 int dev, err;
152
153 dev = inode->i_rdev;
154 dev = MINOR (dev);
155
156 if (cmd == 1)
157 {
158 int i;
159
160 unsigned char *p;
161
162
163 if (!audio_devs[dev >> 4]->dmap_out)
164 return 0;
165 if (!audio_devs[dev >> 4]->dmap_out->raw_buf)
166 return 0;
167
168 p = audio_devs[dev >> 4]->dmap_out->raw_buf;
169
170 for (i = 0; i < 256; i++)
171 printk ("%02x ", p[i]);
172 printk ("\n");
173 return 0;
174 }
175
176 if (cmd & IOC_INOUT)
177 {
178
179
180
181 int len;
182
183 len = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
184
185 if (cmd & IOC_IN)
186 {
187 if ((err = verify_area (VERIFY_READ, (void *) arg, len)) < 0)
188 return err;
189 }
190
191 if (cmd & IOC_OUT)
192 {
193 if ((err = verify_area (VERIFY_WRITE, (void *) arg, len)) < 0)
194 return err;
195 }
196
197 }
198
199 err = sound_ioctl_sw (dev, &files[dev], cmd, (caddr_t) arg);
200
201 return err;
202 }
203
204 static int
205 sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
206 {
207 int dev;
208
209 dev = inode->i_rdev;
210 dev = MINOR (dev);
211
212 DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
213
214 switch (dev & 0x0f)
215 {
216 #ifndef EXCLUDE_SEQUENCER
217 case SND_DEV_SEQ:
218 case SND_DEV_SEQ2:
219 return sequencer_select (dev, &files[dev], sel_type, wait);
220 break;
221 #endif
222
223 #ifndef EXCLUDE_MIDI
224 case SND_DEV_MIDIN:
225 return MIDIbuf_select (dev, &files[dev], sel_type, wait);
226 break;
227 #endif
228
229 #ifndef EXCLUDE_AUDIO
230 case SND_DEV_DSP:
231 case SND_DEV_DSP16:
232 case SND_DEV_AUDIO:
233 return audio_select (dev, &files[dev], sel_type, wait);
234 break;
235 #endif
236
237 default:
238 return 0;
239 }
240
241 return 0;
242 }
243
244 static int
245 sound_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma)
246 {
247 int dev, dev_class;
248 unsigned long size;
249 struct dma_buffparms *dmap = NULL;
250
251 dev = inode->i_rdev;
252 dev = MINOR (dev);
253
254 dev_class = dev & 0x0f;
255 dev >>= 4;
256
257 if (dev_class != SND_DEV_DSP && dev_class != SND_DEV_DSP16 && dev_class != SND_DEV_AUDIO)
258 {
259 printk ("Sound: mmap() not supported for other than audio devices\n");
260 return -EINVAL;
261 }
262
263 if ((vma->vm_flags & (VM_READ | VM_WRITE)) == (VM_READ | VM_WRITE))
264 {
265 printk ("Sound: Cannot do read/write mmap()\n");
266 return -EINVAL;
267 }
268
269 if (vma->vm_flags & VM_READ)
270 {
271 dmap = audio_devs[dev]->dmap_in;
272 }
273 else if (vma->vm_flags & VM_WRITE)
274 {
275 dmap = audio_devs[dev]->dmap_out;
276 }
277 else
278 {
279 printk ("Sound: Undefined mmap() access\n");
280 return -EINVAL;
281 }
282
283 if (dmap == NULL)
284 {
285 printk ("Sound: mmap() error. dmap == NULL\n");
286 return -EIO;
287 }
288
289 if (dmap->raw_buf == NULL)
290 {
291 printk ("Sound: mmap() called when raw_buf == NULL\n");
292 return -EIO;
293 }
294
295 if (dmap->mapping_flags)
296 {
297 printk ("Sound: mmap() called twice for the same DMA buffer\n");
298 return -EIO;
299 }
300
301 if (vma->vm_offset != 0)
302 {
303 printk ("Sound: mmap() offset must be 0.\n");
304 return -EINVAL;
305 }
306
307 size = vma->vm_end - vma->vm_start;
308
309 if (size != dmap->bytes_in_use)
310 {
311 printk ("Sound: mmap() size = %ld. Should be %d\n",
312 size, dmap->bytes_in_use);
313 }
314
315 if (remap_page_range (vma->vm_start, dmap->raw_buf_phys, vma->vm_end - vma->vm_start, vma->vm_page_prot))
316 return -EAGAIN;
317
318
319 vma->vm_inode = inode;
320 inode->i_count++;
321
322 dmap->mapping_flags |= DMA_MAP_MAPPED;
323
324 memset (dmap->raw_buf,
325 dmap->neutral_byte,
326 dmap->bytes_in_use);
327 return 0;
328 }
329
330 static struct file_operations sound_fops =
331 {
332 sound_lseek,
333 sound_read,
334 sound_write,
335 NULL,
336 sound_select,
337 sound_ioctl,
338 sound_mmap,
339 sound_open,
340 sound_release
341 };
342
343 void
344 soundcard_init (void)
345 {
346 #ifndef MODULE
347 register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
348 chrdev_registered = 1;
349 #endif
350
351 soundcard_configured = 1;
352
353 sndtable_init (0);
354
355 if (!(soundcards_installed = sndtable_get_cardcount ()))
356 return;
357
358 #ifndef EXCLUDE_AUDIO
359 if (num_audiodevs)
360 {
361 DMAbuf_init (0);
362 audio_init (0);
363 }
364 #endif
365
366 #ifndef EXCLUDE_MIDI
367 if (num_midis)
368 MIDIbuf_init (0);
369 #endif
370
371 #ifndef EXCLUDE_SEQUENCER
372 if (num_midis + num_synths)
373 sequencer_init (0);
374 #endif
375
376 }
377
378 static unsigned long irqs = 0;
379
380 #ifdef MODULE
381 static void
382 free_all_irqs (void)
383 {
384 int i;
385
386 for (i = 0; i < 31; i++)
387 if (irqs & (1ul << i))
388 {
389 printk ("Sound warning: IRQ%d was left allocated. Fixed.\n", i);
390 snd_release_irq (i);
391 }
392 irqs = 0;
393 }
394
395 char kernel_version[] = UTS_RELEASE;
396
397 #endif
398
399 static int debugmem = 0;
400
401 static int sound[20] =
402 {0};
403
404 int
405 init_module (void)
406 {
407 int err;
408 int ints[21];
409 int i;
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 = 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 void
440 cleanup_module (void)
441 {
442 if (MOD_IN_USE)
443 printk ("sound: module busy -- remove delayed\n");
444 else
445 {
446 int i;
447
448 if (chrdev_registered)
449 unregister_chrdev (SOUND_MAJOR, "sound");
450
451 sound_stop_timer ();
452 sound_unload_drivers ();
453
454 for (i = 0; i < sound_num_blocks; i++)
455 kfree (sound_mem_blocks[i]);
456
457 free_all_irqs ();
458
459 for (i = 0; i < 8; i++)
460 if (dma_alloc_map[i] != DMA_MAP_UNAVAIL)
461 {
462 printk ("Sound: Hmm, DMA%d was left allocated\n", i);
463 sound_free_dma (i);
464 }
465
466 }
467 }
468 #endif
469
470 void
471 tenmicrosec (void)
472 {
473 int i;
474
475 for (i = 0; i < 16; i++)
476 inb (0x80);
477 }
478
479 int
480 snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, struct pt_regs *), char *name, sound_os_info * osp)
481 {
482 int retcode;
483
484 retcode = request_irq (interrupt_level, hndlr, 0 , name);
485 if (retcode < 0)
486 {
487 printk ("Sound: IRQ%d already in use\n", interrupt_level);
488 }
489 else
490 irqs |= (1ul << interrupt_level);
491
492 return retcode;
493 }
494
495 void
496 snd_release_irq (int vect)
497 {
498 irqs &= ~(1ul << vect);
499 free_irq (vect);
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 printk ("sound_free_dma: Bad access to DMA channel %d\n", chn);
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 #ifndef EXCLUDE_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 seq_timer.expires = ((count - jiffies)) + jiffies;
584 add_timer (&seq_timer);
585 };
586 }
587
588 #endif
589
590 void
591 sound_stop_timer (void)
592 {
593 del_timer (&seq_timer);;
594 }
595
596 #ifndef EXCLUDE_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 if (dmap->raw_buf != NULL)
611 return 0;
612
613 if (dma_buffsize < 4096)
614 dma_buffsize = 4096;
615
616 if (chan < 4)
617 dma_pagesize = 64 * 1024;
618 else
619 dma_pagesize = 128 * 1024;
620
621 dmap->raw_buf = NULL;
622
623 if (debugmem)
624 printk ("sound: buffsize%d %lu\n", dev, audio_devs[dev]->buffsize);
625
626 audio_devs[dev]->buffsize = dma_buffsize;
627
628 if (audio_devs[dev]->buffsize > dma_pagesize)
629 audio_devs[dev]->buffsize = dma_pagesize;
630
631 start_addr = NULL;
632
633
634
635
636
637
638 while (start_addr == NULL && audio_devs[dev]->buffsize > PAGE_SIZE)
639 {
640 int sz, size;
641
642 for (sz = 0, size = PAGE_SIZE;
643 size < audio_devs[dev]->buffsize;
644 sz++, size <<= 1);
645
646 audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
647
648 if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
649 audio_devs[dev]->buffsize /= 2;
650 }
651
652 if (start_addr == NULL)
653 {
654 printk ("Sound error: Couldn't allocate DMA buffer\n");
655 return -ENOMEM;
656 }
657 else
658 {
659
660 end_addr = start_addr + audio_devs[dev]->buffsize - 1;
661
662 if (debugmem)
663 printk ("sound: start 0x%lx, end 0x%lx\n",
664 (long) start_addr, (long) end_addr);
665
666
667
668 if (((long) start_addr & ~(dma_pagesize - 1))
669 != ((long) end_addr & ~(dma_pagesize - 1))
670 || end_addr >= (char *) MAX_DMA_ADDRESS)
671 {
672 printk (
673 "sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
674 (long) start_addr,
675 audio_devs[dev]->buffsize);
676 return -EFAULT;
677 }
678 }
679 dmap->raw_buf = start_addr;
680 dmap->raw_buf_phys = virt_to_bus((unsigned long) start_addr);
681
682 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
683 {
684 #ifdef MAP_PAGE_RESERVED
685 mem_map[i] |= MAP_PAGE_RESERVED;
686 #else
687 mem_map[i].reserved = 1;
688 #endif
689 }
690
691 return 0;
692 }
693
694 void
695 sound_free_dmap (int dev, struct dma_buffparms *dmap)
696 {
697 if (dmap->raw_buf == NULL)
698 return;
699 {
700 int sz, size, i;
701 unsigned long start_addr, end_addr;
702
703 for (sz = 0, size = PAGE_SIZE;
704 size < audio_devs[dev]->buffsize;
705 sz++, size <<= 1);
706
707 start_addr = (unsigned long) dmap->raw_buf;
708 end_addr = start_addr + audio_devs[dev]->buffsize;
709
710 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
711 {
712 #ifdef MAP_PAGE_RESERVED
713 mem_map[i] &= ~MAP_PAGE_RESERVED;
714 #else
715 mem_map[i].reserved = 0;
716 #endif
717 }
718 free_pages ((unsigned long) dmap->raw_buf, sz);
719 }
720 dmap->raw_buf = NULL;
721 }
722
723 int
724 soud_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc * info)
725 {
726 printk ("Entered sound_map_buffer()\n");
727 printk ("Exited sound_map_buffer()\n");
728 return -EINVAL;
729 }
730
731 #else
732
733 void
734 soundcard_init (void)
735 {
736 }
737
738 #endif
739
740 #endif