Commit 6983b7240cd229787c3ee00e663ea94ea649d96a

Authored by Clemens Ladisch
Committed by Jaroslav Kysela
1 parent 2af677fc88

[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 */
... ... @@ -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