1 /* 2 * sound/oss/dev_table.c 3 * 4 * Device call tables. 5 * 6 * 7 * Copyright (C) by Hannu Savolainen 1993-1997 8 * 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 11 * for more info. 12 */ 13 14 #include <linux/init.h> 15 16 #include "sound_config.h" 17 18 struct audio_operations *audio_devs[MAX_AUDIO_DEV]; 19 EXPORT_SYMBOL(audio_devs); 20 21 int num_audiodevs; 22 EXPORT_SYMBOL(num_audiodevs); 23 24 struct mixer_operations *mixer_devs[MAX_MIXER_DEV]; 25 EXPORT_SYMBOL(mixer_devs); 26 27 int num_mixers; 28 EXPORT_SYMBOL(num_mixers); 29 30 struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV]; 31 EXPORT_SYMBOL(synth_devs); 32 33 int num_synths; 34 35 struct midi_operations *midi_devs[MAX_MIDI_DEV]; 36 EXPORT_SYMBOL(midi_devs); 37 38 int num_midis; 39 EXPORT_SYMBOL(num_midis); 40 41 struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = { 42 &default_sound_timer, NULL 43 }; 44 EXPORT_SYMBOL(sound_timer_devs); 45 46 int num_sound_timers = 1; 47 48 49 static int sound_alloc_audiodev(void); 50 51 int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver, 52 int driver_size, int flags, unsigned int format_mask, 53 void *devc, int dma1, int dma2) 54 { 55 struct audio_driver *d; 56 struct audio_operations *op; 57 int num; 58 59 if (vers != AUDIO_DRIVER_VERSION || driver_size > sizeof(struct audio_driver)) { 60 printk(KERN_ERR "Sound: Incompatible audio driver for %s\n", name); 61 return -(EINVAL); 62 } 63 num = sound_alloc_audiodev(); 64 65 if (num == -1) { 66 printk(KERN_ERR "sound: Too many audio drivers\n"); 67 return -(EBUSY); 68 } 69 d = (struct audio_driver *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_driver))); 70 sound_nblocks++; 71 if (sound_nblocks >= MAX_MEM_BLOCKS) 72 sound_nblocks = MAX_MEM_BLOCKS - 1; 73 74 op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct audio_operations))); 75 sound_nblocks++; 76 if (sound_nblocks >= MAX_MEM_BLOCKS) 77 sound_nblocks = MAX_MEM_BLOCKS - 1; 78 79 if (d == NULL || op == NULL) { 80 printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name); 81 sound_unload_audiodev(num); 82 return -(ENOMEM); 83 } 84 init_waitqueue_head(&op->in_sleeper); 85 init_waitqueue_head(&op->out_sleeper); 86 init_waitqueue_head(&op->poll_sleeper); 87 if (driver_size < sizeof(struct audio_driver)) 88 memset((char *) d, 0, sizeof(struct audio_driver)); 89 90 memcpy((char *) d, (char *) driver, driver_size); 91 92 op->d = d; 93 strlcpy(op->name, name, sizeof(op->name)); 94 op->flags = flags; 95 op->format_mask = format_mask; 96 op->devc = devc; 97 98 /* 99 * Hardcoded defaults 100 */ 101 audio_devs[num] = op; 102 103 DMAbuf_init(num, dma1, dma2); 104 105 audio_init_devices(); 106 return num; 107 } 108 EXPORT_SYMBOL(sound_install_audiodrv); 109 110 int sound_install_mixer(int vers, char *name, struct mixer_operations *driver, 111 int driver_size, void *devc) 112 { 113 struct mixer_operations *op; 114 115 int n = sound_alloc_mixerdev(); 116 117 if (n == -1) { 118 printk(KERN_ERR "Sound: Too many mixer drivers\n"); 119 return -EBUSY; 120 } 121 if (vers != MIXER_DRIVER_VERSION || 122 driver_size > sizeof(struct mixer_operations)) { 123 printk(KERN_ERR "Sound: Incompatible mixer driver for %s\n", name); 124 return -EINVAL; 125 } 126 127 /* FIXME: This leaks a mixer_operations struct every time its called 128 until you unload sound! */ 129 130 op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct mixer_operations))); 131 sound_nblocks++; 132 if (sound_nblocks >= MAX_MEM_BLOCKS) 133 sound_nblocks = MAX_MEM_BLOCKS - 1; 134 135 if (op == NULL) { 136 printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name); 137 return -ENOMEM; 138 } 139 memcpy((char *) op, (char *) driver, driver_size); 140 141 strlcpy(op->name, name, sizeof(op->name)); 142 op->devc = devc; 143 144 mixer_devs[n] = op; 145 return n; 146 } 147 EXPORT_SYMBOL(sound_install_mixer); 148 149 void sound_unload_audiodev(int dev) 150 { 151 if (dev != -1) { 152 DMAbuf_deinit(dev); 153 audio_devs[dev] = NULL; 154 unregister_sound_dsp((dev<<4)+3); 155 } 156 } 157 EXPORT_SYMBOL(sound_unload_audiodev); 158 159 static int sound_alloc_audiodev(void) 160 { 161 int i = register_sound_dsp(&oss_sound_fops, -1); 162 if(i==-1) 163 return i; 164 i>>=4; 165 if(i>=num_audiodevs) 166 num_audiodevs = i + 1; 167 return i; 168 } 169 170 int sound_alloc_mididev(void) 171 { 172 int i = register_sound_midi(&oss_sound_fops, -1); 173 if(i==-1) 174 return i; 175 i>>=4; 176 if(i>=num_midis) 177 num_midis = i + 1; 178 return i; 179 } 180 EXPORT_SYMBOL(sound_alloc_mididev); 181 182 int sound_alloc_synthdev(void) 183 { 184 int i; 185 186 for (i = 0; i < MAX_SYNTH_DEV; i++) { 187 if (synth_devs[i] == NULL) { 188 if (i >= num_synths) 189 num_synths++; 190 return i; 191 } 192 } 193 return -1; 194 } 195 EXPORT_SYMBOL(sound_alloc_synthdev); 196 197 int sound_alloc_mixerdev(void) 198 { 199 int i = register_sound_mixer(&oss_sound_fops, -1); 200 if(i==-1) 201 return -1; 202 i>>=4; 203 if(i>=num_mixers) 204 num_mixers = i + 1; 205 return i; 206 } 207 EXPORT_SYMBOL(sound_alloc_mixerdev); 208 209 int sound_alloc_timerdev(void) 210 { 211 int i; 212 213 for (i = 0; i < MAX_TIMER_DEV; i++) { 214 if (sound_timer_devs[i] == NULL) { 215 if (i >= num_sound_timers) 216 num_sound_timers++; 217 return i; 218 } 219 } 220 return -1; 221 } 222 EXPORT_SYMBOL(sound_alloc_timerdev); 223 224 void sound_unload_mixerdev(int dev) 225 { 226 if (dev != -1) { 227 mixer_devs[dev] = NULL; 228 unregister_sound_mixer(dev<<4); 229 num_mixers--; 230 } 231 } 232 EXPORT_SYMBOL(sound_unload_mixerdev); 233 234 void sound_unload_mididev(int dev) 235 { 236 if (dev != -1) { 237 midi_devs[dev] = NULL; 238 unregister_sound_midi((dev<<4)+2); 239 } 240 } 241 EXPORT_SYMBOL(sound_unload_mididev); 242 243 void sound_unload_synthdev(int dev) 244 { 245 if (dev != -1) 246 synth_devs[dev] = NULL; 247 } 248 EXPORT_SYMBOL(sound_unload_synthdev); 249 250 void sound_unload_timerdev(int dev) 251 { 252 if (dev != -1) 253 sound_timer_devs[dev] = NULL; 254 } 255 EXPORT_SYMBOL(sound_unload_timerdev); 256 257
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.