1/* 2 * sound/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#define _DEV_TABLE_C_ 17#include "sound_config.h" 18 19int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver, 20 int driver_size, int flags, unsigned int format_mask, 21 void *devc, int dma1, int dma2) 22{ 23 struct audio_driver *d; 24 struct audio_operations *op; 25 int l, num; 26 27 if (vers != AUDIO_DRIVER_VERSION || driver_size > sizeof(struct audio_driver)) { 28 printk(KERN_ERR "Sound: Incompatible audio driver for %s\n", name); 29 return -(EINVAL); 30 } 31 num = sound_alloc_audiodev(); 32 33 if (num == -1) { 34 printk(KERN_ERR "sound: Too many audio drivers\n"); 35 return -(EBUSY); 36 } 37 d = (struct audio_driver *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_driver))); 38 39 if (sound_nblocks < 1024) 40 sound_nblocks++; 41 42 op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_operations))); 43 44 if (sound_nblocks < 1024) 45 sound_nblocks++; 46 if (d == NULL || op == NULL) { 47 printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name); 48 sound_unload_audiodev(num); 49 return -(ENOMEM); 50 } 51 memset((char *) op, 0, sizeof(struct audio_operations)); 52 init_waitqueue_head(&op->in_sleeper); 53 init_waitqueue_head(&op->out_sleeper); 54 init_waitqueue_head(&op->poll_sleeper); 55 if (driver_size < sizeof(struct audio_driver)) 56 memset((char *) d, 0, sizeof(struct audio_driver)); 57 58 memcpy((char *) d, (char *) driver, driver_size); 59 60 op->d = d; 61 l = strlen(name) + 1; 62 if (l > sizeof(op->name)) 63 l = sizeof(op->name); 64 strncpy(op->name, name, l); 65 op->name[l - 1] = 0; 66 op->flags = flags; 67 op->format_mask = format_mask; 68 op->devc = devc; 69 70 /* 71 * Hardcoded defaults 72 */ 73 audio_devs[num] = op; 74 75 DMAbuf_init(num, dma1, dma2); 76 77 audio_init_devices(); 78 return num; 79} 80 81int sound_install_mixer(int vers, char *name, struct mixer_operations *driver, 82 int driver_size, void *devc) 83{ 84 struct mixer_operations *op; 85 int l; 86 87 int n = sound_alloc_mixerdev(); 88 89 if (n == -1) { 90 printk(KERN_ERR "Sound: Too many mixer drivers\n"); 91 return -EBUSY; 92 } 93 if (vers != MIXER_DRIVER_VERSION || 94 driver_size > sizeof(struct mixer_operations)) { 95 printk(KERN_ERR "Sound: Incompatible mixer driver for %s\n", name); 96 return -EINVAL; 97 } 98 99 100 op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations))); 101 102 if (sound_nblocks < 1024) 103 sound_nblocks++; 104 if (op == NULL) { 105 printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name); 106 return -ENOMEM; 107 } 108 memset((char *) op, 0, sizeof(struct mixer_operations)); 109 memcpy((char *) op, (char *) driver, driver_size); 110 111 l = strlen(name) + 1; 112 if (l > sizeof(op->name)) 113 l = sizeof(op->name); 114 strncpy(op->name, name, l); 115 op->name[l - 1] = 0; 116 op->devc = devc; 117 118 mixer_devs[n] = op; 119 return n; 120} 121 122void sound_unload_audiodev(int dev) 123{ 124 if (dev != -1) { 125 DMAbuf_deinit(dev); 126 audio_devs[dev] = NULL; 127 unregister_sound_dsp((dev<<4)+3); 128 } 129} 130 131int sound_alloc_audiodev(void) 132{ 133 int i = register_sound_dsp(&oss_sound_fops, -1); 134 if(i==-1) 135 return i; 136 i>>=4; 137 if(i>=num_audiodevs) 138 num_audiodevs = i + 1; 139 return i; 140} 141 142int sound_alloc_mididev(void) 143{ 144 int i = register_sound_midi(&oss_sound_fops, -1); 145 if(i==-1) 146 return i; 147 i>>=4; 148 if(i>=num_midis) 149 num_midis = i + 1; 150 return i; 151} 152 153int sound_alloc_synthdev(void) 154{ 155 int i; 156 157 for (i = 0; i < MAX_SYNTH_DEV; i++) { 158 if (synth_devs[i] == NULL) { 159 if (i >= num_synths) 160 num_synths++; 161 return i; 162 } 163 } 164 return -1; 165} 166 167int sound_alloc_mixerdev(void) 168{ 169 int i = register_sound_mixer(&oss_sound_fops, -1); 170 if(i==-1) 171 return -1; 172 i>>=4; 173 if(i>=num_mixers) 174 num_mixers = i + 1; 175 return i; 176} 177 178int sound_alloc_timerdev(void) 179{ 180 int i; 181 182 for (i = 0; i < MAX_TIMER_DEV; i++) { 183 if (sound_timer_devs[i] == NULL) { 184 if (i >= num_sound_timers) 185 num_sound_timers++; 186 return i; 187 } 188 } 189 return -1; 190} 191 192void sound_unload_mixerdev(int dev) 193{ 194 if (dev != -1) { 195 mixer_devs[dev] = NULL; 196 unregister_sound_mixer(dev<<4); 197 num_mixers--; 198 } 199} 200 201void sound_unload_mididev(int dev) 202{ 203 if (dev != -1) { 204 midi_devs[dev] = NULL; 205 unregister_sound_midi((dev<<4)+2); 206 } 207} 208 209void sound_unload_synthdev(int dev) 210{ 211 if (dev != -1) 212 synth_devs[dev] = NULL; 213} 214 215void sound_unload_timerdev(int dev) 216{ 217 if (dev != -1) 218 sound_timer_devs[dev] = NULL; 219} 220