Commit 6983b7240cd229787c3ee00e663ea94ea649d96a
Committed by
Jaroslav Kysela
1 parent
2af677fc88
Exists in
master
and in
7 other branches
[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>
Showing 3 changed files with 49 additions and 92 deletions Side-by-side Diff
include/sound/core.h
... | ... | @@ -183,9 +183,8 @@ |
183 | 183 | #endif /* CONFIG_PM */ |
184 | 184 | |
185 | 185 | struct snd_minor { |
186 | - struct list_head list; /* list of all minors per card */ | |
187 | - int number; /* minor number */ | |
188 | 186 | int type; /* SNDRV_DEVICE_TYPE_XXX */ |
187 | + int card; /* card number */ | |
189 | 188 | int device; /* device number */ |
190 | 189 | struct file_operations *f_ops; /* file operations */ |
191 | 190 | char name[0]; /* device name (keep at the end of |
192 | 191 | |
... | ... | @@ -217,11 +216,9 @@ |
217 | 216 | #ifdef CONFIG_SND_OSSEMUL |
218 | 217 | int snd_minor_info_oss_init(void); |
219 | 218 | int snd_minor_info_oss_done(void); |
220 | -int snd_oss_init_module(void); | |
221 | 219 | #else |
222 | 220 | #define snd_minor_info_oss_init() /*NOP*/ |
223 | 221 | #define snd_minor_info_oss_done() /*NOP*/ |
224 | -#define snd_oss_init_module() 0 | |
225 | 222 | #endif |
226 | 223 | |
227 | 224 | /* memory.c */ |
sound/core/sound.c
... | ... | @@ -59,7 +59,7 @@ |
59 | 59 | */ |
60 | 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 | 64 | static DECLARE_MUTEX(sound_mutex); |
65 | 65 | |
... | ... | @@ -107,19 +107,6 @@ |
107 | 107 | |
108 | 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 | 110 | static int snd_open(struct inode *inode, struct file *file) |
124 | 111 | { |
125 | 112 | int minor = iminor(inode); |
126 | 113 | |
... | ... | @@ -139,11 +126,11 @@ |
139 | 126 | } |
140 | 127 | } else { |
141 | 128 | #ifdef CONFIG_KMOD |
142 | - if ((mptr = snd_minor_search(minor)) == NULL) | |
129 | + if ((mptr = snd_minors[minor]) == NULL) | |
143 | 130 | snd_request_other(minor); |
144 | 131 | #endif |
145 | 132 | } |
146 | - if (mptr == NULL && (mptr = snd_minor_search(minor)) == NULL) | |
133 | + if (mptr == NULL && (mptr = snd_minors[minor]) == NULL) | |
147 | 134 | return -ENODEV; |
148 | 135 | old_fops = file->f_op; |
149 | 136 | file->f_op = fops_get(mptr->f_ops); |
150 | 137 | |
151 | 138 | |
152 | 139 | |
153 | 140 | |
... | ... | @@ -213,22 +200,22 @@ |
213 | 200 | if (minor < 0) |
214 | 201 | return minor; |
215 | 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 | 204 | if (preg == NULL) |
218 | 205 | return -ENOMEM; |
219 | - preg->number = minor; | |
220 | 206 | preg->type = type; |
207 | + preg->card = card ? card->number : -1; | |
221 | 208 | preg->device = dev; |
222 | 209 | preg->f_ops = f_ops; |
223 | 210 | strcpy(preg->name, name); |
224 | 211 | down(&sound_mutex); |
225 | - if (snd_minor_search(minor)) { | |
212 | + if (snd_minors[minor]) { | |
226 | 213 | up(&sound_mutex); |
227 | 214 | kfree(preg); |
228 | 215 | return -EBUSY; |
229 | 216 | } |
230 | - list_add_tail(&preg->list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]); | |
231 | - if (strncmp(name, "controlC", 8) || card->number >= cards_limit) | |
217 | + snd_minors[minor] = preg; | |
218 | + if (type != SNDRV_DEVICE_TYPE_CONTROL || preg->card >= cards_limit) | |
232 | 219 | devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name); |
233 | 220 | if (card) |
234 | 221 | device = card->dev; |
235 | 222 | |
236 | 223 | |
... | ... | @@ -257,16 +244,17 @@ |
257 | 244 | if (minor < 0) |
258 | 245 | return minor; |
259 | 246 | down(&sound_mutex); |
260 | - if ((mptr = snd_minor_search(minor)) == NULL) { | |
247 | + if ((mptr = snd_minors[minor]) == NULL) { | |
261 | 248 | up(&sound_mutex); |
262 | 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 | 254 | devfs_remove("snd/%s", mptr->name); |
267 | 255 | class_device_destroy(sound_class, MKDEV(major, minor)); |
268 | 256 | |
269 | - list_del(&mptr->list); | |
257 | + snd_minors[minor] = NULL; | |
270 | 258 | up(&sound_mutex); |
271 | 259 | kfree(mptr); |
272 | 260 | return 0; |
273 | 261 | |
... | ... | @@ -302,23 +290,25 @@ |
302 | 290 | |
303 | 291 | static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) |
304 | 292 | { |
305 | - int card, device; | |
306 | - struct list_head *list; | |
293 | + int minor; | |
307 | 294 | struct snd_minor *mptr; |
308 | 295 | |
309 | 296 | down(&sound_mutex); |
310 | - for (card = 0; card < SNDRV_CARDS; card++) { | |
311 | - list_for_each(list, &snd_minors_hash[card]) { | |
312 | - mptr = list_entry(list, struct snd_minor, list); | |
313 | - if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_GLOBAL) { | |
314 | - if ((device = mptr->device) >= 0) | |
315 | - snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, snd_device_type_name(mptr->type)); | |
316 | - else | |
317 | - snd_iprintf(buffer, "%3i: [%i] : %s\n", mptr->number, card, snd_device_type_name(mptr->type)); | |
318 | - } else { | |
319 | - snd_iprintf(buffer, "%3i: : %s\n", mptr->number, snd_device_type_name(mptr->type)); | |
320 | - } | |
321 | - } | |
297 | + for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) { | |
298 | + if (!(mptr = snd_minors[minor])) | |
299 | + continue; | |
300 | + if (mptr->card >= 0) { | |
301 | + if (mptr->device >= 0) | |
302 | + snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", | |
303 | + minor, mptr->card, mptr->device, | |
304 | + snd_device_type_name(mptr->type)); | |
305 | + else | |
306 | + snd_iprintf(buffer, "%3i: [%i] : %s\n", | |
307 | + minor, mptr->card, | |
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 | 313 | up(&sound_mutex); |
324 | 314 | } |
325 | 315 | |
... | ... | @@ -354,15 +344,9 @@ |
354 | 344 | static int __init alsa_sound_init(void) |
355 | 345 | { |
356 | 346 | short controlnum; |
357 | - int err; | |
358 | - int card; | |
359 | 347 | |
360 | 348 | snd_major = major; |
361 | 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 | 350 | devfs_mk_dir("snd"); |
367 | 351 | if (register_chrdev(major, "alsa", &snd_fops)) { |
368 | 352 | snd_printk(KERN_ERR "unable to register native major device number %d\n", major); |
sound/core/sound_oss.c
... | ... | @@ -35,25 +35,12 @@ |
35 | 35 | #include <sound/info.h> |
36 | 36 | #include <linux/sound.h> |
37 | 37 | |
38 | -#define SNDRV_OS_MINORS 256 | |
38 | +#define SNDRV_OSS_MINORS 128 | |
39 | 39 | |
40 | -static struct list_head snd_oss_minors_hash[SNDRV_CARDS]; | |
40 | +static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; | |
41 | 41 | |
42 | 42 | static DECLARE_MUTEX(sound_oss_mutex); |
43 | 43 | |
44 | -static 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 | - | |
57 | 44 | static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) |
58 | 45 | { |
59 | 46 | int minor; |
... | ... | @@ -86,7 +73,7 @@ |
86 | 73 | default: |
87 | 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 | 77 | return minor; |
91 | 78 | } |
92 | 79 | |
93 | 80 | |
94 | 81 | |
95 | 82 | |
... | ... | @@ -103,15 +90,15 @@ |
103 | 90 | |
104 | 91 | if (minor < 0) |
105 | 92 | return minor; |
106 | - preg = kzalloc(sizeof(struct snd_minor), GFP_KERNEL); | |
93 | + preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL); | |
107 | 94 | if (preg == NULL) |
108 | 95 | return -ENOMEM; |
109 | - preg->number = minor; | |
110 | 96 | preg->type = type; |
97 | + preg->card = card ? card->number : -1; | |
111 | 98 | preg->device = dev; |
112 | 99 | preg->f_ops = f_ops; |
113 | 100 | down(&sound_oss_mutex); |
114 | - list_add_tail(&preg->list, &snd_oss_minors_hash[cidx]); | |
101 | + snd_oss_minors[minor] = preg; | |
115 | 102 | minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); |
116 | 103 | switch (minor_unit) { |
117 | 104 | case SNDRV_MINOR_OSS_PCM: |
... | ... | @@ -143,7 +130,7 @@ |
143 | 130 | unregister_sound_special(register2); |
144 | 131 | if (register1 >= 0) |
145 | 132 | unregister_sound_special(register1); |
146 | - list_del(&preg->list); | |
133 | + snd_oss_minors[minor] = NULL; | |
147 | 134 | up(&sound_oss_mutex); |
148 | 135 | kfree(preg); |
149 | 136 | return -EBUSY; |
... | ... | @@ -159,7 +146,7 @@ |
159 | 146 | if (minor < 0) |
160 | 147 | return minor; |
161 | 148 | down(&sound_oss_mutex); |
162 | - mptr = snd_oss_minor_search(minor); | |
149 | + mptr = snd_oss_minors[minor]; | |
163 | 150 | if (mptr == NULL) { |
164 | 151 | up(&sound_oss_mutex); |
165 | 152 | return -ENOENT; |
... | ... | @@ -178,7 +165,7 @@ |
178 | 165 | } |
179 | 166 | if (track2 >= 0) |
180 | 167 | unregister_sound_special(track2); |
181 | - list_del(&mptr->list); | |
168 | + snd_oss_minors[minor] = NULL; | |
182 | 169 | up(&sound_oss_mutex); |
183 | 170 | kfree(mptr); |
184 | 171 | return 0; |
185 | 172 | |
... | ... | @@ -214,22 +201,20 @@ |
214 | 201 | static void snd_minor_info_oss_read(struct snd_info_entry *entry, |
215 | 202 | struct snd_info_buffer *buffer) |
216 | 203 | { |
217 | - int card, dev; | |
218 | - struct list_head *list; | |
204 | + int minor; | |
219 | 205 | struct snd_minor *mptr; |
220 | 206 | |
221 | 207 | down(&sound_oss_mutex); |
222 | - for (card = 0; card < SNDRV_CARDS; card++) { | |
223 | - list_for_each(list, &snd_oss_minors_hash[card]) { | |
224 | - mptr = list_entry(list, struct snd_minor, list); | |
225 | - dev = SNDRV_MINOR_OSS_DEVICE(mptr->number); | |
226 | - if (dev != SNDRV_MINOR_OSS_SNDSTAT && | |
227 | - dev != SNDRV_MINOR_OSS_SEQUENCER && | |
228 | - dev != SNDRV_MINOR_OSS_MUSIC) | |
229 | - snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, dev, snd_oss_device_type_name(mptr->type)); | |
230 | - else | |
231 | - snd_iprintf(buffer, "%3i: : %s\n", mptr->number, snd_oss_device_type_name(mptr->type)); | |
232 | - } | |
208 | + for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) { | |
209 | + if (!(mptr = snd_oss_minors[minor])) | |
210 | + continue; | |
211 | + if (mptr->card >= 0) | |
212 | + snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", minor, | |
213 | + mptr->card, mptr->device, | |
214 | + snd_oss_device_type_name(mptr->type)); | |
215 | + else | |
216 | + snd_iprintf(buffer, "%3i: : %s\n", minor, | |
217 | + snd_oss_device_type_name(mptr->type)); | |
233 | 218 | } |
234 | 219 | up(&sound_oss_mutex); |
235 | 220 | } |
... | ... | @@ -261,15 +246,6 @@ |
261 | 246 | if (snd_minor_info_oss_entry) |
262 | 247 | snd_info_unregister(snd_minor_info_oss_entry); |
263 | 248 | #endif |
264 | - return 0; | |
265 | -} | |
266 | - | |
267 | -int __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 | 249 | return 0; |
274 | 250 | } |
275 | 251 |