diff options
Diffstat (limited to 'sound/core/sound.c')
-rw-r--r-- | sound/core/sound.c | 72 |
1 files changed, 28 insertions, 44 deletions
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); |