aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/core.h5
-rw-r--r--sound/core/sound.c72
-rw-r--r--sound/core/sound_oss.c64
3 files changed, 49 insertions, 92 deletions
diff --git a/include/sound/core.h b/include/sound/core.h
index f557c8ac450e..67b0a7e764e7 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -183,9 +183,8 @@ static inline int snd_power_wait(struct snd_card *card, unsigned int state, stru
183#endif /* CONFIG_PM */ 183#endif /* CONFIG_PM */
184 184
185struct snd_minor { 185struct snd_minor {
186 struct list_head list; /* list of all minors per card */
187 int number; /* minor number */
188 int type; /* SNDRV_DEVICE_TYPE_XXX */ 186 int type; /* SNDRV_DEVICE_TYPE_XXX */
187 int card; /* card number */
189 int device; /* device number */ 188 int device; /* device number */
190 struct file_operations *f_ops; /* file operations */ 189 struct file_operations *f_ops; /* file operations */
191 char name[0]; /* device name (keep at the end of 190 char name[0]; /* device name (keep at the end of
@@ -217,11 +216,9 @@ int snd_minor_info_done(void);
217#ifdef CONFIG_SND_OSSEMUL 216#ifdef CONFIG_SND_OSSEMUL
218int snd_minor_info_oss_init(void); 217int snd_minor_info_oss_init(void);
219int snd_minor_info_oss_done(void); 218int snd_minor_info_oss_done(void);
220int snd_oss_init_module(void);
221#else 219#else
222#define snd_minor_info_oss_init() /*NOP*/ 220#define snd_minor_info_oss_init() /*NOP*/
223#define snd_minor_info_oss_done() /*NOP*/ 221#define snd_minor_info_oss_done() /*NOP*/
224#define snd_oss_init_module() 0
225#endif 222#endif
226 223
227/* memory.c */ 224/* memory.c */
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 798c24c2de20..a509f49fa0b4 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -59,7 +59,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
59 */ 59 */
60int snd_ecards_limit; 60int snd_ecards_limit;
61 61
62static struct list_head snd_minors_hash[SNDRV_CARDS]; 62static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
63 63
64static DECLARE_MUTEX(sound_mutex); 64static DECLARE_MUTEX(sound_mutex);
65 65
@@ -107,19 +107,6 @@ static void snd_request_other(int minor)
107 107
108#endif /* request_module support */ 108#endif /* request_module support */
109 109
110static struct snd_minor *snd_minor_search(int minor)
111{
112 struct list_head *list;
113 struct snd_minor *mptr;
114
115 list_for_each(list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]) {
116 mptr = list_entry(list, struct snd_minor, list);
117 if (mptr->number == minor)
118 return mptr;
119 }
120 return NULL;
121}
122
123static int snd_open(struct inode *inode, struct file *file) 110static int snd_open(struct inode *inode, struct file *file)
124{ 111{
125 int minor = iminor(inode); 112 int minor = iminor(inode);
@@ -139,11 +126,11 @@ static int snd_open(struct inode *inode, struct file *file)
139 } 126 }
140 } else { 127 } else {
141#ifdef CONFIG_KMOD 128#ifdef CONFIG_KMOD
142 if ((mptr = snd_minor_search(minor)) == NULL) 129 if ((mptr = snd_minors[minor]) == NULL)
143 snd_request_other(minor); 130 snd_request_other(minor);
144#endif 131#endif
145 } 132 }
146 if (mptr == NULL && (mptr = snd_minor_search(minor)) == NULL) 133 if (mptr == NULL && (mptr = snd_minors[minor]) == NULL)
147 return -ENODEV; 134 return -ENODEV;
148 old_fops = file->f_op; 135 old_fops = file->f_op;
149 file->f_op = fops_get(mptr->f_ops); 136 file->f_op = fops_get(mptr->f_ops);
@@ -213,22 +200,22 @@ int snd_register_device(int type, struct snd_card *card, int dev,
213 if (minor < 0) 200 if (minor < 0)
214 return minor; 201 return minor;
215 snd_assert(name, return -EINVAL); 202 snd_assert(name, return -EINVAL);
216 preg = kzalloc(sizeof(struct snd_minor) + strlen(name) + 1, GFP_KERNEL); 203 preg = kmalloc(sizeof(struct snd_minor) + strlen(name) + 1, GFP_KERNEL);
217 if (preg == NULL) 204 if (preg == NULL)
218 return -ENOMEM; 205 return -ENOMEM;
219 preg->number = minor;
220 preg->type = type; 206 preg->type = type;
207 preg->card = card ? card->number : -1;
221 preg->device = dev; 208 preg->device = dev;
222 preg->f_ops = f_ops; 209 preg->f_ops = f_ops;
223 strcpy(preg->name, name); 210 strcpy(preg->name, name);
224 down(&sound_mutex); 211 down(&sound_mutex);
225 if (snd_minor_search(minor)) { 212 if (snd_minors[minor]) {
226 up(&sound_mutex); 213 up(&sound_mutex);
227 kfree(preg); 214 kfree(preg);
228 return -EBUSY; 215 return -EBUSY;
229 } 216 }
230 list_add_tail(&preg->list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]); 217 snd_minors[minor] = preg;
231 if (strncmp(name, "controlC", 8) || card->number >= cards_limit) 218 if (type != SNDRV_DEVICE_TYPE_CONTROL || preg->card >= cards_limit)
232 devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name); 219 devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
233 if (card) 220 if (card)
234 device = card->dev; 221 device = card->dev;
@@ -257,16 +244,17 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
257 if (minor < 0) 244 if (minor < 0)
258 return minor; 245 return minor;
259 down(&sound_mutex); 246 down(&sound_mutex);
260 if ((mptr = snd_minor_search(minor)) == NULL) { 247 if ((mptr = snd_minors[minor]) == NULL) {
261 up(&sound_mutex); 248 up(&sound_mutex);
262 return -EINVAL; 249 return -EINVAL;
263 } 250 }
264 251
265 if (strncmp(mptr->name, "controlC", 8) || card->number >= cards_limit) /* created in sound.c */ 252 if (mptr->type != SNDRV_DEVICE_TYPE_CONTROL ||
253 mptr->card >= cards_limit) /* created in sound.c */
266 devfs_remove("snd/%s", mptr->name); 254 devfs_remove("snd/%s", mptr->name);
267 class_device_destroy(sound_class, MKDEV(major, minor)); 255 class_device_destroy(sound_class, MKDEV(major, minor));
268 256
269 list_del(&mptr->list); 257 snd_minors[minor] = NULL;
270 up(&sound_mutex); 258 up(&sound_mutex);
271 kfree(mptr); 259 kfree(mptr);
272 return 0; 260 return 0;
@@ -302,23 +290,25 @@ static const char *snd_device_type_name(int type)
302 290
303static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 291static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
304{ 292{
305 int card, device; 293 int minor;
306 struct list_head *list;
307 struct snd_minor *mptr; 294 struct snd_minor *mptr;
308 295
309 down(&sound_mutex); 296 down(&sound_mutex);
310 for (card = 0; card < SNDRV_CARDS; card++) { 297 for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) {
311 list_for_each(list, &snd_minors_hash[card]) { 298 if (!(mptr = snd_minors[minor]))
312 mptr = list_entry(list, struct snd_minor, list); 299 continue;
313 if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_GLOBAL) { 300 if (mptr->card >= 0) {
314 if ((device = mptr->device) >= 0) 301 if (mptr->device >= 0)
315 snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, snd_device_type_name(mptr->type)); 302 snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n",
316 else 303 minor, mptr->card, mptr->device,
317 snd_iprintf(buffer, "%3i: [%i] : %s\n", mptr->number, card, snd_device_type_name(mptr->type)); 304 snd_device_type_name(mptr->type));
318 } else { 305 else
319 snd_iprintf(buffer, "%3i: : %s\n", mptr->number, snd_device_type_name(mptr->type)); 306 snd_iprintf(buffer, "%3i: [%i] : %s\n",
320 } 307 minor, mptr->card,
321 } 308 snd_device_type_name(mptr->type));
309 } else
310 snd_iprintf(buffer, "%3i: : %s\n", minor,
311 snd_device_type_name(mptr->type));
322 } 312 }
323 up(&sound_mutex); 313 up(&sound_mutex);
324} 314}
@@ -354,15 +344,9 @@ int __exit snd_minor_info_done(void)
354static int __init alsa_sound_init(void) 344static int __init alsa_sound_init(void)
355{ 345{
356 short controlnum; 346 short controlnum;
357 int err;
358 int card;
359 347
360 snd_major = major; 348 snd_major = major;
361 snd_ecards_limit = cards_limit; 349 snd_ecards_limit = cards_limit;
362 for (card = 0; card < SNDRV_CARDS; card++)
363 INIT_LIST_HEAD(&snd_minors_hash[card]);
364 if ((err = snd_oss_init_module()) < 0)
365 return err;
366 devfs_mk_dir("snd"); 350 devfs_mk_dir("snd");
367 if (register_chrdev(major, "alsa", &snd_fops)) { 351 if (register_chrdev(major, "alsa", &snd_fops)) {
368 snd_printk(KERN_ERR "unable to register native major device number %d\n", major); 352 snd_printk(KERN_ERR "unable to register native major device number %d\n", major);
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 4d189ffaa764..afbfd8df1298 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -35,25 +35,12 @@
35#include <sound/info.h> 35#include <sound/info.h>
36#include <linux/sound.h> 36#include <linux/sound.h>
37 37
38#define SNDRV_OS_MINORS 256 38#define SNDRV_OSS_MINORS 128
39 39
40static struct list_head snd_oss_minors_hash[SNDRV_CARDS]; 40static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
41 41
42static DECLARE_MUTEX(sound_oss_mutex); 42static DECLARE_MUTEX(sound_oss_mutex);
43 43
44static struct snd_minor *snd_oss_minor_search(int minor)
45{
46 struct list_head *list;
47 struct snd_minor *mptr;
48
49 list_for_each(list, &snd_oss_minors_hash[SNDRV_MINOR_OSS_CARD(minor)]) {
50 mptr = list_entry(list, struct snd_minor, list);
51 if (mptr->number == minor)
52 return mptr;
53 }
54 return NULL;
55}
56
57static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) 44static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
58{ 45{
59 int minor; 46 int minor;
@@ -86,7 +73,7 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
86 default: 73 default:
87 return -EINVAL; 74 return -EINVAL;
88 } 75 }
89 snd_assert(minor >= 0 && minor < SNDRV_OS_MINORS, return -EINVAL); 76 snd_assert(minor >= 0 && minor < SNDRV_OSS_MINORS, return -EINVAL);
90 return minor; 77 return minor;
91} 78}
92 79
@@ -103,15 +90,15 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
103 90
104 if (minor < 0) 91 if (minor < 0)
105 return minor; 92 return minor;
106 preg = kzalloc(sizeof(struct snd_minor), GFP_KERNEL); 93 preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL);
107 if (preg == NULL) 94 if (preg == NULL)
108 return -ENOMEM; 95 return -ENOMEM;
109 preg->number = minor;
110 preg->type = type; 96 preg->type = type;
97 preg->card = card ? card->number : -1;
111 preg->device = dev; 98 preg->device = dev;
112 preg->f_ops = f_ops; 99 preg->f_ops = f_ops;
113 down(&sound_oss_mutex); 100 down(&sound_oss_mutex);
114 list_add_tail(&preg->list, &snd_oss_minors_hash[cidx]); 101 snd_oss_minors[minor] = preg;
115 minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); 102 minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
116 switch (minor_unit) { 103 switch (minor_unit) {
117 case SNDRV_MINOR_OSS_PCM: 104 case SNDRV_MINOR_OSS_PCM:
@@ -143,7 +130,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
143 unregister_sound_special(register2); 130 unregister_sound_special(register2);
144 if (register1 >= 0) 131 if (register1 >= 0)
145 unregister_sound_special(register1); 132 unregister_sound_special(register1);
146 list_del(&preg->list); 133 snd_oss_minors[minor] = NULL;
147 up(&sound_oss_mutex); 134 up(&sound_oss_mutex);
148 kfree(preg); 135 kfree(preg);
149 return -EBUSY; 136 return -EBUSY;
@@ -159,7 +146,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
159 if (minor < 0) 146 if (minor < 0)
160 return minor; 147 return minor;
161 down(&sound_oss_mutex); 148 down(&sound_oss_mutex);
162 mptr = snd_oss_minor_search(minor); 149 mptr = snd_oss_minors[minor];
163 if (mptr == NULL) { 150 if (mptr == NULL) {
164 up(&sound_oss_mutex); 151 up(&sound_oss_mutex);
165 return -ENOENT; 152 return -ENOENT;
@@ -178,7 +165,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
178 } 165 }
179 if (track2 >= 0) 166 if (track2 >= 0)
180 unregister_sound_special(track2); 167 unregister_sound_special(track2);
181 list_del(&mptr->list); 168 snd_oss_minors[minor] = NULL;
182 up(&sound_oss_mutex); 169 up(&sound_oss_mutex);
183 kfree(mptr); 170 kfree(mptr);
184 return 0; 171 return 0;
@@ -214,22 +201,20 @@ static const char *snd_oss_device_type_name(int type)
214static void snd_minor_info_oss_read(struct snd_info_entry *entry, 201static void snd_minor_info_oss_read(struct snd_info_entry *entry,
215 struct snd_info_buffer *buffer) 202 struct snd_info_buffer *buffer)
216{ 203{
217 int card, dev; 204 int minor;
218 struct list_head *list;
219 struct snd_minor *mptr; 205 struct snd_minor *mptr;
220 206
221 down(&sound_oss_mutex); 207 down(&sound_oss_mutex);
222 for (card = 0; card < SNDRV_CARDS; card++) { 208 for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) {
223 list_for_each(list, &snd_oss_minors_hash[card]) { 209 if (!(mptr = snd_oss_minors[minor]))
224 mptr = list_entry(list, struct snd_minor, list); 210 continue;
225 dev = SNDRV_MINOR_OSS_DEVICE(mptr->number); 211 if (mptr->card >= 0)
226 if (dev != SNDRV_MINOR_OSS_SNDSTAT && 212 snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", minor,
227 dev != SNDRV_MINOR_OSS_SEQUENCER && 213 mptr->card, mptr->device,
228 dev != SNDRV_MINOR_OSS_MUSIC) 214 snd_oss_device_type_name(mptr->type));
229 snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, dev, snd_oss_device_type_name(mptr->type)); 215 else
230 else 216 snd_iprintf(buffer, "%3i: : %s\n", minor,
231 snd_iprintf(buffer, "%3i: : %s\n", mptr->number, snd_oss_device_type_name(mptr->type)); 217 snd_oss_device_type_name(mptr->type));
232 }
233 } 218 }
234 up(&sound_oss_mutex); 219 up(&sound_oss_mutex);
235} 220}
@@ -264,13 +249,4 @@ int __exit snd_minor_info_oss_done(void)
264 return 0; 249 return 0;
265} 250}
266 251
267int __init snd_oss_init_module(void)
268{
269 int card;
270
271 for (card = 0; card < SNDRV_CARDS; card++)
272 INIT_LIST_HEAD(&snd_oss_minors_hash[card]);
273 return 0;
274}
275
276#endif /* CONFIG_SND_OSSEMUL */ 252#endif /* CONFIG_SND_OSSEMUL */