diff options
-rw-r--r-- | include/sound/core.h | 5 | ||||
-rw-r--r-- | sound/core/sound.c | 72 | ||||
-rw-r--r-- | sound/core/sound_oss.c | 64 |
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 | ||
185 | struct snd_minor { | 185 | struct 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 |
218 | int snd_minor_info_oss_init(void); | 217 | int snd_minor_info_oss_init(void); |
219 | int snd_minor_info_oss_done(void); | 218 | int snd_minor_info_oss_done(void); |
220 | int 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 | */ |
60 | int snd_ecards_limit; | 60 | int snd_ecards_limit; |
61 | 61 | ||
62 | static struct list_head snd_minors_hash[SNDRV_CARDS]; | 62 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; |
63 | 63 | ||
64 | static DECLARE_MUTEX(sound_mutex); | 64 | static 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 | ||
110 | static 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 | |||
123 | static int snd_open(struct inode *inode, struct file *file) | 110 | static 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 | ||
303 | static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | 291 | static 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) | |||
354 | static int __init alsa_sound_init(void) | 344 | static 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 | ||
40 | static struct list_head snd_oss_minors_hash[SNDRV_CARDS]; | 40 | static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; |
41 | 41 | ||
42 | static DECLARE_MUTEX(sound_oss_mutex); | 42 | static DECLARE_MUTEX(sound_oss_mutex); |
43 | 43 | ||
44 | static 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 | |||
57 | static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) | 44 | static 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) | |||
214 | static void snd_minor_info_oss_read(struct snd_info_entry *entry, | 201 | static 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 | ||
267 | int __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 */ |