Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dev_table.c
Go to the documentation of this file.
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 
19 EXPORT_SYMBOL(audio_devs);
20 
23 
25 EXPORT_SYMBOL(mixer_devs);
26 
29 
31 EXPORT_SYMBOL(synth_devs);
32 
34 
36 EXPORT_SYMBOL(midi_devs);
37 
40 
43 };
44 EXPORT_SYMBOL(sound_timer_devs);
45 
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++;
73 
74  op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct audio_operations)));
75  sound_nblocks++;
78 
79  if (d == NULL || op == NULL) {
80  printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name);
82  return -(ENOMEM);
83  }
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;
96  op->devc = devc;
97 
98  /*
99  * Hardcoded defaults
100  */
101  audio_devs[num] = op;
102 
103  DMAbuf_init(num, dma1, dma2);
104 
106  return num;
107 }
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++;
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 }
148 
150 {
151  if (dev != -1) {
152  DMAbuf_deinit(dev);
153  audio_devs[dev] = NULL;
154  unregister_sound_dsp((dev<<4)+3);
155  }
156 }
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 
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 }
181 
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 }
196 
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 }
208 
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)
217  return i;
218  }
219  }
220  return -1;
221 }
223 
225 {
226  if (dev != -1) {
227  mixer_devs[dev] = NULL;
228  unregister_sound_mixer(dev<<4);
229  num_mixers--;
230  }
231 }
233 
235 {
236  if (dev != -1) {
237  midi_devs[dev] = NULL;
238  unregister_sound_midi((dev<<4)+2);
239  }
240 }
242 
244 {
245  if (dev != -1)
246  synth_devs[dev] = NULL;
247 }
249 
251 {
252  if (dev != -1)
253  sound_timer_devs[dev] = NULL;
254 }
256