aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt4
-rw-r--r--sound/core/init.c67
2 files changed, 44 insertions, 27 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index f48939e97aba..529073dea196 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -2271,6 +2271,10 @@ case above again, the first two slots are already reserved. If any
2271other driver (e.g. snd-usb-audio) is loaded before snd-interwave or 2271other driver (e.g. snd-usb-audio) is loaded before snd-interwave or
2272snd-ens1371, it will be assigned to the third or later slot. 2272snd-ens1371, it will be assigned to the third or later slot.
2273 2273
2274When a module name is given with '!', the slot will be given for any
2275modules but that name. For example, "slots=!snd-pcsp" will reserve
2276the first slot for any modules but snd-pcsp.
2277
2274 2278
2275ALSA PCM devices to OSS devices mapping 2279ALSA PCM devices to OSS devices mapping
2276======================================= 2280=======================================
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;