aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/sound/core.h5
-rw-r--r--sound/core/sound.c72
-rw-r--r--sound/core/sound_oss.c64
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
185struct snd_minor { 185struct 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
218int snd_minor_info_oss_init(void); 217int snd_minor_info_oss_init(void);
219int snd_minor_info_oss_done(void); 218int snd_minor_info_oss_done(void);
220int 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 */
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);
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
40static struct list_head snd_oss_minors_hash[SNDRV_CARDS]; 40static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
41 41
42static DECLARE_MUTEX(sound_oss_mutex); 42static DECLARE_MUTEX(sound_oss_mutex);
43 43
44static 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
57static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) 44static 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)
214static void snd_minor_info_oss_read(struct snd_info_entry *entry, 201static 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
267int __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 */