Sound card drivers may choose their own way to provide a nice sound card ID, especially when the default behaviour taken by choose_default_name() is not appropriate. ALSA's IDs must be unique, so there is need for some core logic to ensure that.
This patch adds the function snd_card_make_id_unique() to the ALSA core which lowlevel drivers can call to make sure the computed string isn't already taken.
Signed-off-by: Daniel Mack daniel@caiaq.de Cc: Takashi Iwai tiwai@suse.de Cc: Jaroslav Kysela perex@perex.cz --- include/sound/core.h | 1 + sound/core/init.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/include/sound/core.h b/include/sound/core.h index 3dea798..01ea816 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -319,6 +319,7 @@ int snd_card_info_done(void); int snd_component_add(struct snd_card *card, const char *component); int snd_card_file_add(struct snd_card *card, struct file *file); int snd_card_file_remove(struct snd_card *card, struct file *file); +void snd_card_make_id_unique(struct snd_card *card);
#ifndef snd_card_set_dev #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr)) diff --git a/sound/core/init.c b/sound/core/init.c index fd56afe..8503a01 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -547,6 +547,51 @@ static void choose_default_id(struct snd_card *card) } }
+static int +card_id_is_ambiguous(struct snd_card *card, const char *id) +{ + int i; + + for (i = 0; i < snd_ecards_limit; i++) { + /* only run for exisiting cards but not for the + * one in question */ + if (i == card->number || !snd_cards[i]) + continue; + + if (strcmp(snd_cards[i]->id, id) == 0) + return 1; + } + + return 0; +} + +void +snd_card_make_id_unique(struct snd_card *card) +{ + int count = 1; + char id[sizeof(card->id)]; + + if (*card->id == '\0') + return; + + strlcpy(id, card->id, sizeof(id)); + + while (card_id_is_ambiguous(card, id)) { + /* As we need to add some characters to the id, make + * sure there's enough room for it */ + int maxlen = sizeof(card->id) - (2 + (count / 10)); + + if (strlen(card->id) > maxlen) + card->id[maxlen] = '\0'; + + snprintf(id, sizeof(id), "%s_%d", card->id, count); + count++; + } + + strlcpy(card->id, id, sizeof(id)); +} +EXPORT_SYMBOL_GPL(snd_card_make_id_unique); + #ifndef CONFIG_SYSFS_DEPRECATED static ssize_t card_id_show_attr(struct device *dev,