aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/init.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/sound/core/init.c b/sound/core/init.c
index ac0573416130..5c254d498ae0 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -46,17 +46,24 @@ static char *slots[SNDRV_CARDS];
46module_param_array(slots, charp, NULL, 0444); 46module_param_array(slots, charp, NULL, 0444);
47MODULE_PARM_DESC(slots, "Module names assigned to the slots."); 47MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
48 48
49/* return non-zero if the given index is already reserved for another 49/* return non-zero if the given index is reserved for the given
50 * module via slots option 50 * module via slots option
51 */ 51 */
52static int module_slot_mismatch(struct module *module, int idx) 52static int module_slot_match(struct module *module, int idx)
53{ 53{
54 int match = 1;
54#ifdef MODULE 55#ifdef MODULE
55 char *s1, *s2; 56 const char *s1, *s2;
57
56 if (!module || !module->name || !slots[idx]) 58 if (!module || !module->name || !slots[idx])
57 return 0; 59 return 0;
58 s1 = slots[idx]; 60
59 s2 = module->name; 61 s1 = module->name;
62 s2 = slots[idx];
63 if (*s2 == '!') {
64 match = 0; /* negative match */
65 s2++;
66 }
60 /* compare module name strings 67 /* compare module name strings
61 * hyphens are handled as equivalent with underscore 68 * hyphens are handled as equivalent with underscore
62 */ 69 */
@@ -68,12 +75,12 @@ static int module_slot_mismatch(struct module *module, int idx)
68 if (c2 == '-') 75 if (c2 == '-')
69 c2 = '_'; 76 c2 = '_';
70 if (c1 != c2) 77 if (c1 != c2)
71 return 1; 78 return !match;
72 if (!c1) 79 if (!c1)
73 break; 80 break;
74 } 81 }
75#endif 82#endif /* MODULE */
76 return 0; 83 return match;
77} 84}
78 85
79#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 86#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
@@ -129,7 +136,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
129 struct module *module, int extra_size) 136 struct module *module, int extra_size)
130{ 137{
131 struct snd_card *card; 138 struct snd_card *card;
132 int err; 139 int err, idx2;
133 140
134 if (extra_size < 0) 141 if (extra_size < 0)
135 extra_size = 0; 142 extra_size = 0;
@@ -144,35 +151,41 @@ struct snd_card *snd_card_new(int idx, const char *xid,
144 err = 0; 151 err = 0;
145 mutex_lock(&snd_card_mutex); 152 mutex_lock(&snd_card_mutex);
146 if (idx < 0) { 153 if (idx < 0) {
147 int idx2;
148 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 154 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
149 /* idx == -1 == 0xffff means: take any free slot */ 155 /* idx == -1 == 0xffff means: take any free slot */
150 if (~snd_cards_lock & idx & 1<<idx2) { 156 if (~snd_cards_lock & idx & 1<<idx2) {
151 if (module_slot_mismatch(module, idx2)) 157 if (module_slot_match(module, idx2)) {
152 continue; 158 idx = idx2;
153 idx = idx2; 159 break;
154 if (idx >= snd_ecards_limit) 160 }
155 snd_ecards_limit = idx + 1; 161 }
156 break; 162 }
163 if (idx < 0) {
164 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
165 /* idx == -1 == 0xffff means: take any free slot */
166 if (~snd_cards_lock & idx & 1<<idx2) {
167 if (!slots[idx2] || !*slots[idx2]) {
168 idx = idx2;
169 break;
170 }
157 } 171 }
158 } else {
159 if (idx < snd_ecards_limit) {
160 if (snd_cards_lock & (1 << idx))
161 err = -EBUSY; /* invalid */
162 } else {
163 if (idx < SNDRV_CARDS)
164 snd_ecards_limit = idx + 1; /* increase the limit */
165 else
166 err = -ENODEV;
167 }
168 } 172 }
169 if (idx < 0 || err < 0) { 173 if (idx < 0)
174 err = -ENODEV;
175 else if (idx < snd_ecards_limit) {
176 if (snd_cards_lock & (1 << idx))
177 err = -EBUSY; /* invalid */
178 } else if (idx >= SNDRV_CARDS)
179 err = -ENODEV;
180 if (err < 0) {
170 mutex_unlock(&snd_card_mutex); 181 mutex_unlock(&snd_card_mutex);
171 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n", 182 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n",
172 idx, snd_ecards_limit - 1, err); 183 idx, snd_ecards_limit - 1, err);
173 goto __error; 184 goto __error;
174 } 185 }
175 snd_cards_lock |= 1 << idx; /* lock it */ 186 snd_cards_lock |= 1 << idx; /* lock it */
187 if (idx >= snd_ecards_limit)
188 snd_ecards_limit = idx + 1; /* increase the limit */
176 mutex_unlock(&snd_card_mutex); 189 mutex_unlock(&snd_card_mutex);
177 card->number = idx; 190 card->number = idx;
178 card->module = module; 191 card->module = module;