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