2 * linux/drivers/sound/soundcard.c
4 * Soundcard driver for Linux
7 * Copyright (C) by Hannu Savolainen 1993-1997
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
14 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
15 * integrated sound_switch.c
16 * Stefan Reinauer : integrated /proc/sound (equals to /dev/sndstat,
17 * which should disappear in the near future)
19 #include <linux/config.h>
22 #include "sound_config.h"
23 #include <linux/types.h>
24 #include <linux/errno.h>
25 #include <linux/signal.h>
26 #include <linux/fcntl.h>
27 #include <linux/ctype.h>
28 #include <linux/stddef.h>
29 #include <linux/kerneld.h>
32 #include <asm/segment.h>
33 #include <linux/wait.h>
34 #include <linux/malloc.h>
35 #include <linux/ioport.h>
36 #endif /* __KERNEL__ */
37 #include <linux/delay.h>
38 #include <linux/proc_fs.h>
42 #include "soundmodule.h"
44 #include <linux/major.h>
51 static int chrdev_registered
= 0;
52 static int sound_major
= SOUND_MAJOR
;
54 static int is_unloading
= 0;
57 * Table for permanently allocated memory (used when unloading the module)
59 caddr_t sound_mem_blocks
[1024];
60 int sound_mem_sizes
[1024];
61 int sound_nblocks
= 0;
63 static int soundcard_configured
= 0;
65 static char dma_alloc_map
[8] =
68 #define DMA_MAP_UNAVAIL 0
69 #define DMA_MAP_FREE 1
70 #define DMA_MAP_BUSY 2
73 static int in_use
= 0; /* Total # of open devices */
74 unsigned long seq_time
= 0; /* Time for /dev/sequencer */
77 * Table for configurable mixer volume handling
79 static mixer_vol_table mixer_vols
[MAX_MIXER_DEV
];
80 static int num_mixer_volumes
= 0;
83 int *load_mixer_volumes(char *name
, int *levels
, int present
)
87 for (i
= 0; i
< num_mixer_volumes
; i
++)
88 if (strcmp(name
, mixer_vols
[i
].name
) == 0)
91 mixer_vols
[i
].num
= i
;
92 return mixer_vols
[i
].levels
;
94 if (num_mixer_volumes
>= MAX_MIXER_DEV
)
96 printk("Sound: Too many mixers (%s)\n", name
);
99 n
= num_mixer_volumes
++;
101 strcpy(mixer_vols
[n
].name
, name
);
104 mixer_vols
[n
].num
= n
;
106 mixer_vols
[n
].num
= -1;
108 for (i
= 0; i
< 32; i
++)
109 mixer_vols
[n
].levels
[i
] = levels
[i
];
110 return mixer_vols
[n
].levels
;
113 static int set_mixer_levels(caddr_t arg
)
115 /* mixer_vol_table is 174 bytes, so IMHO no reason to not allocate it on the stack */
118 if (__copy_from_user(&buf
, arg
, sizeof(buf
)))
120 load_mixer_volumes(buf
.name
, buf
.levels
, 0);
121 if (__copy_to_user(arg
, &buf
, sizeof(buf
)))
126 static int get_mixer_levels(caddr_t arg
)
130 if (__get_user(n
, (int *)(&(((mixer_vol_table
*)arg
)->num
))))
132 if (n
< 0 || n
>= num_mixer_volumes
)
134 if (__copy_to_user(arg
, &mixer_vols
[n
], sizeof(mixer_vol_table
)))
139 static int sound_proc_get_info(char *buffer
, char **start
, off_t offset
, int length
, int inout
)
146 #define MODULEPROCSTRING "Driver loaded as a module"
148 #define MODULEPROCSTRING "Driver compiled into kernel"
151 len
= sprintf(buffer
, "OSS/Free:" SOUND_VERSION_STRING
"\n"
152 "Load type: " MODULEPROCSTRING
"\n"
153 "Kernel: %s %s %s %s %s\n"
154 "Config options: %x\n\nInstalled drivers: \n",
155 system_utsname
.sysname
, system_utsname
.nodename
, system_utsname
.release
,
156 system_utsname
.version
, system_utsname
.machine
, SELECTED_SOUND_OPTIONS
);
158 for (i
= 0; (i
< num_sound_drivers
) && (pos
<= offset
+ length
); i
++) {
159 if (!sound_drivers
[i
].card_type
)
161 len
+= sprintf(buffer
+ len
, "Type %d: %s\n",
162 sound_drivers
[i
].card_type
, sound_drivers
[i
].name
);
169 len
+= sprintf(buffer
+ len
, "\nCard config: \n");
171 for (i
= 0; (i
< num_sound_cards
) && (pos
<= offset
+ length
); i
++) {
172 if (!snd_installed_cards
[i
].card_type
)
174 if (!snd_installed_cards
[i
].enabled
)
175 len
+= sprintf(buffer
+ len
, "(");
176 if ((drv
= snd_find_driver(snd_installed_cards
[i
].card_type
)) != -1)
177 len
+= sprintf(buffer
+ len
, "%s", sound_drivers
[drv
].name
);
178 if (snd_installed_cards
[i
].config
.io_base
)
179 len
+= sprintf(buffer
+ len
, " at 0x%x", snd_installed_cards
[i
].config
.io_base
);
180 if (snd_installed_cards
[i
].config
.irq
!= 0)
181 len
+= sprintf(buffer
+ len
, " irq %d", abs(snd_installed_cards
[i
].config
.irq
));
182 if (snd_installed_cards
[i
].config
.dma
!= -1) {
183 len
+= sprintf(buffer
+ len
, " drq %d", snd_installed_cards
[i
].config
.dma
);
184 if (snd_installed_cards
[i
].config
.dma2
!= -1)
185 len
+= sprintf(buffer
+ len
, ",%d", snd_installed_cards
[i
].config
.dma2
);
187 if (!snd_installed_cards
[i
].enabled
)
188 len
+= sprintf(buffer
+ len
, ")");
189 len
+= sprintf(buffer
+ len
, "\n");
197 len
+= sprintf(buffer
+ len
, "\n\n***** Sound driver not started *****\n\n");
199 len
+= sprintf(buffer
+ len
, "\nAudio devices: NOT ENABLED IN CONFIG\n");
201 len
+= sprintf(buffer
+ len
, "\nAudio devices:\n");
202 for (i
= 0; (i
< num_audiodevs
) && (pos
<= offset
+ length
); i
++) {
203 if (audio_devs
[i
] == NULL
)
205 len
+= sprintf(buffer
+ len
, "%d: %s%s\n", i
, audio_devs
[i
]->name
,
206 audio_devs
[i
]->flags
& DMA_DUPLEX
? " (DUPLEX)" : "");
215 #ifndef CONFIG_SEQUENCER
216 len
+= sprintf(buffer
+ len
, "\nSynth devices: NOT ENABLED IN CONFIG\n");
218 len
+= sprintf(buffer
+ len
, "\nSynth devices:\n");
219 for (i
= 0; (i
< num_synths
) && (pos
<= offset
+ length
); i
++) {
220 if (synth_devs
[i
] == NULL
)
222 len
+= sprintf(buffer
+ len
, "%d: %s\n", i
, synth_devs
[i
]->info
->name
);
232 len
+= sprintf(buffer
+ len
, "\nMidi devices: NOT ENABLED IN CONFIG\n");
234 len
+= sprintf(buffer
+ len
, "\nMidi devices:\n");
235 for (i
= 0; (i
< num_midis
) && (pos
<= offset
+ length
); i
++) {
236 if (midi_devs
[i
] == NULL
)
238 len
+= sprintf(buffer
+ len
, "%d: %s\n", i
, midi_devs
[i
]->info
.name
);
247 #ifdef CONFIG_SEQUENCER
248 len
+= sprintf(buffer
+ len
, "\nTimers:\n");
250 for (i
= 0; (i
< num_sound_timers
) && (pos
<= offset
+ length
); i
++) {
251 if (sound_timer_devs
[i
] == NULL
)
253 len
+= sprintf(buffer
+ len
, "%d: %s\n", i
, sound_timer_devs
[i
]->info
.name
);
262 len
+= sprintf(buffer
+ len
, "\nMixers:\n");
263 for (i
= 0; (i
< num_mixers
) && (pos
<= offset
+ length
); i
++) {
264 if (mixer_devs
[i
] == NULL
)
266 len
+= sprintf(buffer
+ len
, "%d: %s\n", i
, mixer_devs
[i
]->name
);
273 *start
= buffer
+ (offset
- begin
);
274 len
-= (offset
- begin
);
280 static struct proc_dir_entry proc_root_sound
= {
281 PROC_SOUND
, 5, "sound",
282 S_IFREG
| S_IRUGO
, 1, 0, 0,
283 0, NULL
, sound_proc_get_info
287 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
290 /* 4K page size but our output routines use some slack for overruns */
291 #define PROC_BLOCK_SIZE (3*1024)
294 * basically copied from fs/proc/generic.c:proc_file_read
295 * should be removed sometime in the future together with /dev/sndstat
296 * (a symlink /dev/sndstat -> /proc/sound will do as well)
298 static ssize_t
sndstat_file_read(struct file
* file
, char * buf
, size_t nbytes
, loff_t
*ppos
)
306 if (!(page
= (char*) __get_free_page(GFP_KERNEL
)))
309 while ((nbytes
> 0) && !eof
)
311 count
= MIN(PROC_BLOCK_SIZE
, nbytes
);
314 n
= sound_proc_get_info(page
, &start
, *ppos
, count
, 0);
320 * For proc files that are less than 4k
322 start
= page
+ *ppos
;
330 break; /* End of file */
337 n
-= copy_to_user(buf
, start
, n
); /* BUG ??? */
344 *ppos
+= n
; /* Move down the file */
349 free_page((unsigned long) page
);
354 static ssize_t
sound_read(struct file
*file
, char *buf
, size_t count
, loff_t
*ppos
)
356 int dev
= MINOR(file
->f_dentry
->d_inode
->i_rdev
);
358 DEB(printk("sound_read(dev=%d, count=%d)\n", dev
, count
));
359 switch (dev
& 0x0f) {
361 return sndstat_file_read(file
, buf
, count
, ppos
);
367 return audio_read(dev
, file
, buf
, count
);
370 #ifdef CONFIG_SEQUENCER
373 return sequencer_read(dev
, file
, buf
, count
);
378 return MIDIbuf_read(dev
, file
, buf
, count
);
386 static ssize_t
sound_write(struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
)
388 int dev
= MINOR(file
->f_dentry
->d_inode
->i_rdev
);
390 DEB(printk("sound_write(dev=%d, count=%d)\n", dev
, count
));
391 switch (dev
& 0x0f) {
392 #ifdef CONFIG_SEQUENCER
395 return sequencer_write(dev
, file
, buf
, count
);
402 return audio_write(dev
, file
, buf
, count
);
407 return MIDIbuf_write(dev
, file
, buf
, count
);
413 static long long sound_lseek(struct file
*file
, long long offset
, int orig
)
418 static int sound_open(struct inode
*inode
, struct file
*file
)
423 /* printk(KERN_ERR "Sound: Driver partially removed. Can't open device\n");*/
426 dev
= MINOR(inode
->i_rdev
);
427 if (!soundcard_configured
&& dev
!= SND_DEV_CTL
&& dev
!= SND_DEV_STATUS
) {
428 /* printk("SoundCard Error: The soundcard system has not been configured\n");*/
431 DEB(printk("sound_open(dev=%d)\n", dev
));
432 if ((dev
>= SND_NDEVS
) || (dev
< 0)) {
433 printk(KERN_ERR
"Invalid minor device %d\n", dev
);
436 switch (dev
& 0x0f) {
442 #ifdef CONFIG_KERNELD
443 if (dev
>= 0 && dev
< MAX_MIXER_DEV
&& mixer_devs
[dev
] == NULL
) {
445 sprintf(modname
, "mixer%d", dev
);
446 request_module(modname
);
449 if (dev
&& (dev
>= num_mixers
|| mixer_devs
[dev
] == NULL
))
453 #ifdef CONFIG_SEQUENCER
456 if ((retval
= sequencer_open(dev
, file
)) < 0)
463 if ((retval
= MIDIbuf_open(dev
, file
)) < 0)
472 if ((retval
= audio_open(dev
, file
)) < 0)
478 printk(KERN_ERR
"Invalid minor device %d\n", dev
);
488 static int sound_release(struct inode
*inode
, struct file
*file
)
490 int dev
= MINOR(inode
->i_rdev
);
492 DEB(printk("sound_release(dev=%d)\n", dev
));
493 switch (dev
& 0x0f) {
498 #ifdef CONFIG_SEQUENCER
501 sequencer_release(dev
, file
);
507 MIDIbuf_release(dev
, file
);
515 audio_release(dev
, file
);
520 printk(KERN_ERR
"Sound error: Releasing unknown device 0x%02x\n", dev
);
529 static int get_mixer_info(int dev
, caddr_t arg
)
533 strncpy(info
.id
, mixer_devs
[dev
]->id
, sizeof(info
.id
));
534 strncpy(info
.name
, mixer_devs
[dev
]->name
, sizeof(info
.name
));
535 info
.name
[sizeof(info
.name
)-1] = 0;
536 info
.modify_counter
= mixer_devs
[dev
]->modify_counter
;
537 if (__copy_to_user(arg
, &info
, sizeof(info
)))
542 static int get_old_mixer_info(int dev
, caddr_t arg
)
544 _old_mixer_info info
;
546 strncpy(info
.id
, mixer_devs
[dev
]->id
, sizeof(info
.id
));
547 strncpy(info
.name
, mixer_devs
[dev
]->name
, sizeof(info
.name
));
548 info
.name
[sizeof(info
.name
)-1] = 0;
549 if (copy_to_user(arg
, &info
, sizeof(info
)))
554 static int sound_mixer_ioctl(int mixdev
, unsigned int cmd
, caddr_t arg
)
556 if (mixdev
< 0 || mixdev
>= MAX_MIXER_DEV
)
558 #ifdef CONFIG_KERNELD
559 /* Try to load the mixer... */
560 if (mixer_devs
[mixdev
] == NULL
) {
562 sprintf(modname
, "mixer%d", mixdev
);
563 request_module(modname
);
565 #endif /* CONFIG_KERNELD */
566 if (mixdev
>= num_mixers
|| !mixer_devs
[mixdev
])
568 if (cmd
== SOUND_MIXER_INFO
)
569 return get_mixer_info(mixdev
, arg
);
570 if (cmd
== SOUND_OLD_MIXER_INFO
)
571 return get_old_mixer_info(mixdev
, arg
);
572 if (_SIOC_DIR(cmd
) & _SIOC_WRITE
)
573 mixer_devs
[mixdev
]->modify_counter
++;
574 if (!mixer_devs
[mixdev
]->ioctl
)
576 return mixer_devs
[mixdev
]->ioctl(mixdev
, cmd
, arg
);
579 static int sound_ioctl(struct inode
*inode
, struct file
*file
,
580 unsigned int cmd
, unsigned long arg
)
582 int err
, len
= 0, dtype
;
583 int dev
= MINOR(inode
->i_rdev
);
585 if (_SIOC_DIR(cmd
) != _SIOC_NONE
&& _SIOC_DIR(cmd
) != 0) {
587 * Have to validate the address given by the process.
589 len
= _SIOC_SIZE(cmd
);
590 if (len
< 1 || len
> 65536 || arg
== 0)
592 if (_SIOC_DIR(cmd
) & _SIOC_WRITE
)
593 if ((err
= verify_area(VERIFY_READ
, (void *)arg
, len
)) < 0)
595 if (_SIOC_DIR(cmd
) & _SIOC_READ
)
596 if ((err
= verify_area(VERIFY_WRITE
, (void *)arg
, len
)) < 0)
599 DEB(printk("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev
, cmd
, arg
));
600 if (cmd
== OSS_GETVERSION
)
601 return __put_user(SOUND_VERSION
, (int *)arg
);
603 if (_IOC_TYPE(cmd
) == 'M' && num_mixers
> 0 && /* Mixer ioctl */
604 (dev
& 0x0f) != SND_DEV_CTL
) {
611 return sound_mixer_ioctl(audio_devs
[dev
>> 4]->mixer_dev
,
616 return sound_mixer_ioctl(dev
>> 4, cmd
, (caddr_t
)arg
);
619 switch (dev
& 0x0f) {
621 if (cmd
== SOUND_MIXER_GETLEVELS
)
622 return get_mixer_levels((caddr_t
)arg
);
623 if (cmd
== SOUND_MIXER_SETLEVELS
)
624 return set_mixer_levels((caddr_t
)arg
);
625 return sound_mixer_ioctl(dev
>> 4, cmd
, (caddr_t
)arg
);
627 #ifdef CONFIG_SEQUENCER
630 return sequencer_ioctl(dev
, file
, cmd
, (caddr_t
)arg
);
637 return audio_ioctl(dev
, file
, cmd
, (caddr_t
)arg
);
643 return MIDIbuf_ioctl(dev
, file
, cmd
, (caddr_t
)arg
);
651 static unsigned int sound_poll(struct file
*file
, poll_table
* wait
)
653 struct inode
*inode
= file
->f_dentry
->d_inode
;
654 int dev
= MINOR(inode
->i_rdev
);
656 DEB(printk("sound_poll(dev=%d)\n", dev
));
657 switch (dev
& 0x0f) {
658 #if defined(CONFIG_SEQUENCER) || defined(MODULE)
661 return sequencer_poll(dev
, file
, wait
);
664 #if defined(CONFIG_MIDI)
666 return MIDIbuf_poll(dev
, file
, wait
);
669 #if defined(CONFIG_AUDIO) || defined(MODULE)
673 return DMAbuf_poll(file
, dev
>> 4, wait
);
679 static int sound_mmap(struct file
*file
, struct vm_area_struct
*vma
)
683 struct dma_buffparms
*dmap
= NULL
;
684 int dev
= MINOR(file
->f_dentry
->d_inode
->i_rdev
);
686 dev_class
= dev
& 0x0f;
689 if (dev_class
!= SND_DEV_DSP
&& dev_class
!= SND_DEV_DSP16
&& dev_class
!= SND_DEV_AUDIO
)
691 /* printk("Sound: mmap() not supported for other than audio devices\n");*/
694 if (vma
->vm_flags
& VM_WRITE
) /* Map write and read/write to the output buf */
695 dmap
= audio_devs
[dev
]->dmap_out
;
696 else if (vma
->vm_flags
& VM_READ
)
697 dmap
= audio_devs
[dev
]->dmap_in
;
700 /* printk("Sound: Undefined mmap() access\n");*/
706 /* printk("Sound: mmap() error. dmap == NULL\n");*/
709 if (dmap
->raw_buf
== NULL
)
711 /* printk("Sound: mmap() called when raw_buf == NULL\n");*/
714 if (dmap
->mapping_flags
)
716 /* printk("Sound: mmap() called twice for the same DMA buffer\n");*/
719 if (vma
->vm_offset
!= 0)
721 /* printk("Sound: mmap() offset must be 0.\n");*/
724 size
= vma
->vm_end
- vma
->vm_start
;
726 if (size
!= dmap
->bytes_in_use
)
728 printk(KERN_WARNING
"Sound: mmap() size = %ld. Should be %d\n", size
, dmap
->bytes_in_use
);
730 if (remap_page_range(vma
->vm_start
, virt_to_phys(dmap
->raw_buf
),
731 vma
->vm_end
- vma
->vm_start
,
738 dmap
->mapping_flags
|= DMA_MAP_MAPPED
;
740 memset(dmap
->raw_buf
,
746 static struct file_operations sound_fops
=
751 NULL
, /* sound_readdir */
767 register_chrdev(sound_major
, "sound", &sound_fops
);
768 chrdev_registered
= 1;
771 soundcard_configured
= 1;
773 sndtable_init(); /* Initialize call tables and detect cards */
777 if (sndtable_get_cardcount() == 0)
778 return; /* No cards detected */
781 #if defined(CONFIG_AUDIO)
782 if (num_audiodevs
|| modular
) /* Audio devices present */
784 audio_init_devices();
791 static unsigned int irqs
= 0;
799 for (i
= 0; i
< 31; i
++)
801 if (irqs
& (1ul << i
))
803 printk(KERN_WARNING
"Sound warning: IRQ%d was left allocated - fixed.\n", i
);
810 char kernel_version
[] = UTS_RELEASE
;
814 static int sound
[20] =
817 int init_module(void)
824 * "sound=" command line handling by Harald Milz.
827 while (i
< 20 && sound
[i
])
828 ints
[i
+ 1] = sound
[i
++];
832 sound_setup("sound=", ints
);
834 err
= register_chrdev(sound_major
, "sound", &sound_fops
);
837 printk(KERN_ERR
"sound: driver already loaded/included in kernel\n");
840 chrdev_registered
= 1;
843 if (sound_nblocks
>= 1024)
844 printk(KERN_ERR
"Sound warning: Deallocation table was too small.\n");
846 if (proc_register(&proc_root
, &proc_root_sound
))
847 printk(KERN_ERR
"sound: registering /proc/sound failed\n");
854 void cleanup_module(void)
862 if (proc_unregister(&proc_root
, PROC_SOUND
))
863 printk(KERN_ERR
"sound: unregistering /proc/sound failed\n");
864 if (chrdev_registered
)
865 unregister_chrdev(sound_major
, "sound");
867 #if defined(CONFIG_SEQUENCER) || defined(MODULE)
871 #ifdef CONFIG_LOWLEVEL_SOUND
873 extern void sound_unload_lowlevel_drivers(void);
875 sound_unload_lowlevel_drivers();
878 sound_unload_drivers();
879 free_all_irqs(); /* If something was left allocated by accident */
882 for (i
= 0; i
< 8; i
++)
884 if (dma_alloc_map
[i
] != DMA_MAP_UNAVAIL
)
886 printk(KERN_ERR
"Sound: Hmm, DMA%d was left allocated - fixed\n", i
);
890 for (i
= 0; i
< sound_nblocks
; i
++)
892 vfree(sound_mem_blocks
[i
]);
898 int snd_set_irq_handler(int interrupt_level
, void (*iproc
) (int, void *, struct pt_regs
*), char *name
, int *osp
)
905 retcode
= request_irq(interrupt_level
, iproc
, 0, name
, NULL
);
909 printk(KERN_ERR
"Sound: IRQ%d already in use\n", interrupt_level
);
912 irqs
|= (1ul << interrupt_level
);
914 restore_flags(flags
);
918 void snd_release_irq(int vect
)
920 if (!(irqs
& (1ul << vect
)))
923 irqs
&= ~(1ul << vect
);
924 free_irq(vect
, NULL
);
927 int sound_alloc_dma(int chn
, char *deviceID
)
931 if ((err
= request_dma(chn
, deviceID
)) != 0)
934 dma_alloc_map
[chn
] = DMA_MAP_FREE
;
939 int sound_open_dma(int chn
, char *deviceID
)
943 if (chn
< 0 || chn
> 7 || chn
== 4)
945 printk(KERN_ERR
"sound_open_dma: Invalid DMA channel %d\n", chn
);
951 if (dma_alloc_map
[chn
] != DMA_MAP_FREE
)
953 printk("sound_open_dma: DMA channel %d busy or not allocated (%d)\n", chn
, dma_alloc_map
[chn
]);
954 restore_flags(flags
);
957 dma_alloc_map
[chn
] = DMA_MAP_BUSY
;
958 restore_flags(flags
);
962 void sound_free_dma(int chn
)
964 if (dma_alloc_map
[chn
] == DMA_MAP_UNAVAIL
)
966 /* printk( "sound_free_dma: Bad access to DMA channel %d\n", chn); */
970 dma_alloc_map
[chn
] = DMA_MAP_UNAVAIL
;
973 void sound_close_dma(int chn
)
980 if (dma_alloc_map
[chn
] != DMA_MAP_BUSY
)
982 printk(KERN_ERR
"sound_close_dma: Bad access to DMA channel %d\n", chn
);
983 restore_flags(flags
);
986 dma_alloc_map
[chn
] = DMA_MAP_FREE
;
987 restore_flags(flags
);
990 #if defined(CONFIG_SEQUENCER) || defined(MODULE)
992 static void do_sequencer_timer(unsigned long dummy
)
998 static struct timer_list seq_timer
=
999 {NULL
, NULL
, 0, 0, do_sequencer_timer
};
1001 void request_sound_timer(int count
)
1003 extern unsigned long seq_time
;
1007 seq_timer
.expires
= (-count
) + jiffies
;
1008 add_timer(&seq_timer
);
1018 seq_timer
.expires
= (count
) + jiffies
;
1019 add_timer(&seq_timer
);
1022 void sound_stop_timer(void)
1024 del_timer(&seq_timer
);;
1028 void conf_printf(char *name
, struct address_info
*hw_config
)
1033 printk("<%s> at 0x%03x", name
, hw_config
->io_base
);
1036 printk(" irq %d", (hw_config
->irq
> 0) ? hw_config
->irq
: -hw_config
->irq
);
1038 if (hw_config
->dma
!= -1 || hw_config
->dma2
!= -1)
1040 printk(" dma %d", hw_config
->dma
);
1041 if (hw_config
->dma2
!= -1)
1042 printk(",%d", hw_config
->dma2
);
1047 void conf_printf2(char *name
, int base
, int irq
, int dma
, int dma2
)
1052 printk("<%s> at 0x%03x", name
, base
);
1055 printk(" irq %d", (irq
> 0) ? irq
: -irq
);
1057 if (dma
!= -1 || dma2
!= -1)
1059 printk(" dma %d", dma
);
1061 printk(",%d", dma2
);
1067 * Module and lock management
1070 struct notifier_block
*sound_locker
=(struct notifier_block
*)0;
1071 static int lock_depth
= 0;
1073 #define SOUND_INC_USE_COUNT do { notifier_call_chain(&sound_locker, 1, 0); lock_depth++; } while(0);
1074 #define SOUND_DEC_USE_COUNT do { notifier_call_chain(&sound_locker, 0, 0); lock_depth--; } while(0);
1077 * When a sound module is registered we need to bring it to the current
1081 void sound_notifier_chain_register(struct notifier_block
*bl
)
1085 notifier_chain_register(&sound_locker
, bl
);
1087 * Normalise the lock count by calling the entry directly. We
1088 * have to call the module as it owns its own use counter
1090 while(ct
<lock_depth
)
1092 bl
->notifier_call(bl
, 1, 0);