aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/sound.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2005-11-20 08:05:49 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:29:15 -0500
commit6983b7240cd229787c3ee00e663ea94ea649d96a (patch)
tree25005b4a0fce5465e70961a5d3fe2d040786f890 /sound/core/sound.c
parent2af677fc884fc6dc79e65c99050ea607ac8bab9b (diff)
[ALSA] dynamic minors (2/6): simplify storage of snd_minor structures
Modules: ALSA Core Store the snd_minor structure pointers in one array instead of using a separate list for each card. This simplifies the mapping from device files to minor struct by removing the need to know about the encoding of the card number in the minor number. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
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 798c24c2de2..a509f49fa0b 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);