aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/sound.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/sound.c')
-rw-r--r--sound/core/sound.c72
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 */
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);