diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2005-11-20 08:05:49 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:29:15 -0500 |
commit | 6983b7240cd229787c3ee00e663ea94ea649d96a (patch) | |
tree | 25005b4a0fce5465e70961a5d3fe2d040786f890 /sound/core/sound.c | |
parent | 2af677fc884fc6dc79e65c99050ea607ac8bab9b (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.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); |