Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
8bb4d9c
Documentation
arch
block
crypto
drivers
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
aoa
arm
atmel
core
oss
seq
Kconfig
Makefile
compress_offload.c
control.c
control_compat.c
ctljack.c
device.c
hrtimer.c
hwdep.c
hwdep_compat.c
info.c
info_oss.c
init.c
isadma.c
jack.c
memalloc.c
memory.c
misc.c
pcm.c
pcm_compat.c
pcm_lib.c
pcm_memory.c
pcm_misc.c
pcm_native.c
pcm_timer.c
rawmidi.c
rawmidi_compat.c
rtctimer.c
sgbuf.c
sound.c
sound_oss.c
timer.c
timer_compat.c
vmaster.c
drivers
firewire
i2c
isa
mips
oss
parisc
pci
pcmcia
ppc
sh
soc
sparc
spi
synth
usb
Kconfig
Makefile
ac97_bus.c
last.c
sound_core.c
sound_firmware.c
tools
usr
virt
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
sound
/
core
/
sound_oss.c
Blame
Blame
Latest commit
History
History
285 lines (257 loc) · 7.56 KB
Breadcrumbs
linux
/
sound
/
core
/
sound_oss.c
Top
File metadata and controls
Code
Blame
285 lines (257 loc) · 7.56 KB
Raw
/* * Advanced Linux Sound Architecture * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifdef CONFIG_SND_OSSEMUL #if !defined(CONFIG_SOUND) && !(defined(MODULE) && defined(CONFIG_SOUND_MODULE)) #error "Enable the OSS soundcore multiplexer (CONFIG_SOUND) in the kernel." #endif #include <linux/init.h> #include <linux/export.h> #include <linux/slab.h> #include <linux/time.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/info.h> #include <linux/sound.h> #include <linux/mutex.h> #define SNDRV_OSS_MINORS 256 static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; static DEFINE_MUTEX(sound_oss_mutex); /* NOTE: This function increments the refcount of the associated card like * snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately */ void *snd_lookup_oss_minor_data(unsigned int minor, int type) { struct snd_minor *mreg; void *private_data; if (minor >= ARRAY_SIZE(snd_oss_minors)) return NULL; mutex_lock(&sound_oss_mutex); mreg = snd_oss_minors[minor]; if (mreg && mreg->type == type) { private_data = mreg->private_data; if (private_data && mreg->card_ptr) atomic_inc(&mreg->card_ptr->refcount); } else private_data = NULL; mutex_unlock(&sound_oss_mutex); return private_data; } EXPORT_SYMBOL(snd_lookup_oss_minor_data); static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) { int minor; switch (type) { case SNDRV_OSS_DEVICE_TYPE_MIXER: if (snd_BUG_ON(!card || dev < 0 || dev > 1)) return -EINVAL; minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIXER1 : SNDRV_MINOR_OSS_MIXER)); break; case SNDRV_OSS_DEVICE_TYPE_SEQUENCER: minor = SNDRV_MINOR_OSS_SEQUENCER; break; case SNDRV_OSS_DEVICE_TYPE_MUSIC: minor = SNDRV_MINOR_OSS_MUSIC; break; case SNDRV_OSS_DEVICE_TYPE_PCM: if (snd_BUG_ON(!card || dev < 0 || dev > 1)) return -EINVAL; minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_PCM1 : SNDRV_MINOR_OSS_PCM)); break; case SNDRV_OSS_DEVICE_TYPE_MIDI: if (snd_BUG_ON(!card || dev < 0 || dev > 1)) return -EINVAL; minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIDI1 : SNDRV_MINOR_OSS_MIDI)); break; case SNDRV_OSS_DEVICE_TYPE_DMFM: minor = SNDRV_MINOR_OSS(card->number, SNDRV_MINOR_OSS_DMFM); break; case SNDRV_OSS_DEVICE_TYPE_SNDSTAT: minor = SNDRV_MINOR_OSS_SNDSTAT; break; default: return -EINVAL; } if (minor < 0 || minor >= SNDRV_OSS_MINORS) return -EINVAL; return minor; } int snd_register_oss_device(int type, struct snd_card *card, int dev, const struct file_operations *f_ops, void *private_data, const char *name) { int minor = snd_oss_kernel_minor(type, card, dev); int minor_unit; struct snd_minor *preg; int cidx = SNDRV_MINOR_OSS_CARD(minor); int track2 = -1; int register1 = -1, register2 = -1; struct device *carddev = snd_card_get_device_link(card); if (card && card->number >= SNDRV_MINOR_OSS_DEVICES) return 0; /* ignore silently */ if (minor < 0) return minor; preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL); if (preg == NULL) return -ENOMEM; preg->type = type; preg->card = card ? card->number : -1; preg->device = dev; preg->f_ops = f_ops; preg->private_data = private_data; preg->card_ptr = card; mutex_lock(&sound_oss_mutex); snd_oss_minors[minor] = preg; minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); switch (minor_unit) { case SNDRV_MINOR_OSS_PCM: track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO); break; case SNDRV_MINOR_OSS_MIDI: track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI); break; case SNDRV_MINOR_OSS_MIDI1: track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1); break; } register1 = register_sound_special_device(f_ops, minor, carddev); if (register1 != minor) goto __end; if (track2 >= 0) { register2 = register_sound_special_device(f_ops, track2, carddev); if (register2 != track2) goto __end; snd_oss_minors[track2] = preg; } mutex_unlock(&sound_oss_mutex); return 0; __end: if (register2 >= 0) unregister_sound_special(register2); if (register1 >= 0) unregister_sound_special(register1); snd_oss_minors[minor] = NULL; mutex_unlock(&sound_oss_mutex); kfree(preg); return -EBUSY; } EXPORT_SYMBOL(snd_register_oss_device); int snd_unregister_oss_device(int type, struct snd_card *card, int dev) { int minor = snd_oss_kernel_minor(type, card, dev); int cidx = SNDRV_MINOR_OSS_CARD(minor); int track2 = -1; struct snd_minor *mptr; if (card && card->number >= SNDRV_MINOR_OSS_DEVICES) return 0; if (minor < 0) return minor; mutex_lock(&sound_oss_mutex); mptr = snd_oss_minors[minor]; if (mptr == NULL) { mutex_unlock(&sound_oss_mutex); return -ENOENT; } unregister_sound_special(minor); switch (SNDRV_MINOR_OSS_DEVICE(minor)) { case SNDRV_MINOR_OSS_PCM: track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO); break; case SNDRV_MINOR_OSS_MIDI: track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI); break; case SNDRV_MINOR_OSS_MIDI1: track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1); break; } if (track2 >= 0) { unregister_sound_special(track2); snd_oss_minors[track2] = NULL; } snd_oss_minors[minor] = NULL; mutex_unlock(&sound_oss_mutex); kfree(mptr); return 0; } EXPORT_SYMBOL(snd_unregister_oss_device); /* * INFO PART */ #ifdef CONFIG_PROC_FS static struct snd_info_entry *snd_minor_info_oss_entry; static const char *snd_oss_device_type_name(int type) { switch (type) { case SNDRV_OSS_DEVICE_TYPE_MIXER: return "mixer"; case SNDRV_OSS_DEVICE_TYPE_SEQUENCER: case SNDRV_OSS_DEVICE_TYPE_MUSIC: return "sequencer"; case SNDRV_OSS_DEVICE_TYPE_PCM: return "digital audio"; case SNDRV_OSS_DEVICE_TYPE_MIDI: return "raw midi"; case SNDRV_OSS_DEVICE_TYPE_DMFM: return "hardware dependent"; default: return "?"; } } static void snd_minor_info_oss_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { int minor; struct snd_minor *mptr; mutex_lock(&sound_oss_mutex); for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) { if (!(mptr = snd_oss_minors[minor])) continue; if (mptr->card >= 0) snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", minor, mptr->card, mptr->device, snd_oss_device_type_name(mptr->type)); else snd_iprintf(buffer, "%3i: : %s\n", minor, snd_oss_device_type_name(mptr->type)); } mutex_unlock(&sound_oss_mutex); } int __init snd_minor_info_oss_init(void) { struct snd_info_entry *entry; entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root); if (entry) { entry->c.text.read = snd_minor_info_oss_read; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); entry = NULL; } } snd_minor_info_oss_entry = entry; return 0; } int __exit snd_minor_info_oss_done(void) { snd_info_free_entry(snd_minor_info_oss_entry); return 0; } #endif /* CONFIG_PROC_FS */ #endif /* CONFIG_SND_OSSEMUL */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
You can’t perform that action at this time.