Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/oss/dev_table.c
10814 views
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
258