aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-05-27 11:59:24 -0400
committerTakashi Iwai <tiwai@suse.de>2008-05-28 09:14:32 -0400
commita93bbaa77ea61c6bad684263a65f812b31bf9791 (patch)
tree46dda28fb9a4696722ae85946dc18434b9ff7cc9 /sound/core
parentf9423e7a94eb2dfef3503dde76d17eaf342ab962 (diff)
[ALSA] Improve the slots option handling
Fix and improve the slots option handling. The sound core tries to find the slot with the given module name first and assign if it's still available. If all pre-given slots are unavailable, then try to find another free slot. Also, when a module name begins with '!', it means the negative match: the slot will be given for any modules but that one. Signed-off-by: Takashi Iwai <tiwai@suse.de>
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;