[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>
This commit is contained in:
Родитель
f9423e7a94
Коммит
a93bbaa77e
|
@ -2271,6 +2271,10 @@ case above again, the first two slots are already reserved. If any
|
||||||
other driver (e.g. snd-usb-audio) is loaded before snd-interwave or
|
other driver (e.g. snd-usb-audio) is loaded before snd-interwave or
|
||||||
snd-ens1371, it will be assigned to the third or later slot.
|
snd-ens1371, it will be assigned to the third or later slot.
|
||||||
|
|
||||||
|
When a module name is given with '!', the slot will be given for any
|
||||||
|
modules but that name. For example, "slots=!snd-pcsp" will reserve
|
||||||
|
the first slot for any modules but snd-pcsp.
|
||||||
|
|
||||||
|
|
||||||
ALSA PCM devices to OSS devices mapping
|
ALSA PCM devices to OSS devices mapping
|
||||||
=======================================
|
=======================================
|
||||||
|
|
|
@ -46,17 +46,24 @@ static char *slots[SNDRV_CARDS];
|
||||||
module_param_array(slots, charp, NULL, 0444);
|
module_param_array(slots, charp, NULL, 0444);
|
||||||
MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
|
MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
|
||||||
|
|
||||||
/* return non-zero if the given index is already reserved for another
|
/* return non-zero if the given index is reserved for the given
|
||||||
* module via slots option
|
* module via slots option
|
||||||
*/
|
*/
|
||||||
static int module_slot_mismatch(struct module *module, int idx)
|
static int module_slot_match(struct module *module, int idx)
|
||||||
{
|
{
|
||||||
|
int match = 1;
|
||||||
#ifdef MODULE
|
#ifdef MODULE
|
||||||
char *s1, *s2;
|
const char *s1, *s2;
|
||||||
|
|
||||||
if (!module || !module->name || !slots[idx])
|
if (!module || !module->name || !slots[idx])
|
||||||
return 0;
|
return 0;
|
||||||
s1 = slots[idx];
|
|
||||||
s2 = module->name;
|
s1 = module->name;
|
||||||
|
s2 = slots[idx];
|
||||||
|
if (*s2 == '!') {
|
||||||
|
match = 0; /* negative match */
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
/* compare module name strings
|
/* compare module name strings
|
||||||
* hyphens are handled as equivalent with underscore
|
* hyphens are handled as equivalent with underscore
|
||||||
*/
|
*/
|
||||||
|
@ -68,12 +75,12 @@ static int module_slot_mismatch(struct module *module, int idx)
|
||||||
if (c2 == '-')
|
if (c2 == '-')
|
||||||
c2 = '_';
|
c2 = '_';
|
||||||
if (c1 != c2)
|
if (c1 != c2)
|
||||||
return 1;
|
return !match;
|
||||||
if (!c1)
|
if (!c1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* MODULE */
|
||||||
return 0;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
|
#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,
|
||||||
struct module *module, int extra_size)
|
struct module *module, int extra_size)
|
||||||
{
|
{
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
int err;
|
int err, idx2;
|
||||||
|
|
||||||
if (extra_size < 0)
|
if (extra_size < 0)
|
||||||
extra_size = 0;
|
extra_size = 0;
|
||||||
|
@ -144,35 +151,41 @@ struct snd_card *snd_card_new(int idx, const char *xid,
|
||||||
err = 0;
|
err = 0;
|
||||||
mutex_lock(&snd_card_mutex);
|
mutex_lock(&snd_card_mutex);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
int idx2;
|
|
||||||
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
|
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
|
||||||
/* idx == -1 == 0xffff means: take any free slot */
|
/* idx == -1 == 0xffff means: take any free slot */
|
||||||
if (~snd_cards_lock & idx & 1<<idx2) {
|
if (~snd_cards_lock & idx & 1<<idx2) {
|
||||||
if (module_slot_mismatch(module, idx2))
|
if (module_slot_match(module, idx2)) {
|
||||||
continue;
|
idx = idx2;
|
||||||
idx = idx2;
|
break;
|
||||||
if (idx >= snd_ecards_limit)
|
}
|
||||||
snd_ecards_limit = idx + 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (idx < snd_ecards_limit) {
|
|
||||||
if (snd_cards_lock & (1 << idx))
|
|
||||||
err = -EBUSY; /* invalid */
|
|
||||||
} else {
|
|
||||||
if (idx < SNDRV_CARDS)
|
|
||||||
snd_ecards_limit = idx + 1; /* increase the limit */
|
|
||||||
else
|
|
||||||
err = -ENODEV;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (idx < 0 || err < 0) {
|
if (idx < 0) {
|
||||||
|
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
|
||||||
|
/* idx == -1 == 0xffff means: take any free slot */
|
||||||
|
if (~snd_cards_lock & idx & 1<<idx2) {
|
||||||
|
if (!slots[idx2] || !*slots[idx2]) {
|
||||||
|
idx = idx2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (idx < 0)
|
||||||
|
err = -ENODEV;
|
||||||
|
else if (idx < snd_ecards_limit) {
|
||||||
|
if (snd_cards_lock & (1 << idx))
|
||||||
|
err = -EBUSY; /* invalid */
|
||||||
|
} else if (idx >= SNDRV_CARDS)
|
||||||
|
err = -ENODEV;
|
||||||
|
if (err < 0) {
|
||||||
mutex_unlock(&snd_card_mutex);
|
mutex_unlock(&snd_card_mutex);
|
||||||
snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n",
|
snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n",
|
||||||
idx, snd_ecards_limit - 1, err);
|
idx, snd_ecards_limit - 1, err);
|
||||||
goto __error;
|
goto __error;
|
||||||
}
|
}
|
||||||
snd_cards_lock |= 1 << idx; /* lock it */
|
snd_cards_lock |= 1 << idx; /* lock it */
|
||||||
|
if (idx >= snd_ecards_limit)
|
||||||
|
snd_ecards_limit = idx + 1; /* increase the limit */
|
||||||
mutex_unlock(&snd_card_mutex);
|
mutex_unlock(&snd_card_mutex);
|
||||||
card->number = idx;
|
card->number = idx;
|
||||||
card->module = module;
|
card->module = module;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче