diff options
author | Jaroslav Kysela <perex@perex.cz> | 2009-06-02 12:02:38 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-06-02 12:47:46 +0200 |
commit | 10a8ebbb08c4b08292598947bbe534e04d6ee705 (patch) | |
tree | 520419b15c64e249106d7642004c898d6d75ba63 | |
parent | 3218911f839b6c85acbf872ad264ea69aa4d89ad (diff) | |
download | linux-10a8ebbb08c4b08292598947bbe534e04d6ee705.tar.bz2 |
ALSA: Core - add snd_card_set_id() function
Introduce snd_card_set_id() function to allow lowlevel drivers to set
default identification name for card slot. The function checks also
for identification name collisions and tries to create unique name.
Also, the snd_card_create() function is simplified, because this new
function is used. As bonus, proper name collision checks are evaluated
at the card create time.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | include/sound/core.h | 1 | ||||
-rw-r--r-- | sound/core/init.c | 62 |
2 files changed, 40 insertions, 23 deletions
diff --git a/include/sound/core.h b/include/sound/core.h index 3dea79829acc..0e8ae10155ab 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -313,6 +313,7 @@ struct snd_card *snd_card_new(int idx, const char *id, int snd_card_disconnect(struct snd_card *card); int snd_card_free(struct snd_card *card); int snd_card_free_when_closed(struct snd_card *card); +void snd_card_set_id(struct snd_card *card, const char *id); int snd_card_register(struct snd_card *card); int snd_card_info_init(void); int snd_card_info_done(void); diff --git a/sound/core/init.c b/sound/core/init.c index fd56afe846ed..6557dd85e191 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -152,15 +152,8 @@ int snd_card_create(int idx, const char *xid, card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL); if (!card) return -ENOMEM; - if (xid) { - if (!snd_info_check_reserved_words(xid)) { - snd_printk(KERN_ERR - "given id string '%s' is reserved.\n", xid); - err = -EBUSY; - goto __error; - } - strlcpy(card->id, xid, sizeof(card->id)); - } + if (xid) + snd_card_set_id(card, xid); err = 0; mutex_lock(&snd_card_mutex); if (idx < 0) { @@ -483,22 +476,39 @@ int snd_card_free(struct snd_card *card) EXPORT_SYMBOL(snd_card_free); -static void choose_default_id(struct snd_card *card) +/** + * snd_card_set_id - set card identification name + * @card: soundcard structure + * @nid: new identification string + * + * This function sets the card identification and checks for name + * collisions. + */ +void snd_card_set_id(struct snd_card *card, const char *nid) { int i, len, idx_flag = 0, loops = SNDRV_CARDS; - char *id, *spos; + const char *spos, *src; + char *id; - id = spos = card->shortname; - while (*id != '\0') { - if (*id == ' ') - spos = id + 1; - id++; + /* check if user specified own card->id */ + if (card->id[0] != '\0') + return; + if (nid == NULL) { + id = card->shortname; + spos = src = id; + while (*id != '\0') { + if (*id == ' ') + spos = id + 1; + id++; + } + } else { + spos = src = nid; } id = card->id; while (*spos != '\0' && !isalnum(*spos)) spos++; if (isdigit(*spos)) - *id++ = isalpha(card->shortname[0]) ? card->shortname[0] : 'D'; + *id++ = isalpha(src[0]) ? src[0] : 'D'; while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) { if (isalnum(*spos)) *id++ = *spos; @@ -513,16 +523,20 @@ static void choose_default_id(struct snd_card *card) while (1) { if (loops-- == 0) { - snd_printk(KERN_ERR "unable to choose default card id (%s)\n", id); + snd_printk(KERN_ERR "unable to set card id (%s)\n", id); strcpy(card->id, card->proc_root->name); return; } if (!snd_info_check_reserved_words(id)) goto __change; + mutex_lock(&snd_card_mutex); for (i = 0; i < snd_ecards_limit; i++) { - if (snd_cards[i] && !strcmp(snd_cards[i]->id, id)) + if (snd_cards[i] && !strcmp(snd_cards[i]->id, id)) { + mutex_unlock(&snd_card_mutex); goto __change; + } } + mutex_unlock(&snd_card_mutex); break; __change: @@ -539,14 +553,16 @@ static void choose_default_id(struct snd_card *card) spos = id + len - 2; if ((size_t)len <= sizeof(card->id) - 2) spos++; - *spos++ = '_'; - *spos++ = '1'; - *spos++ = '\0'; + *(char *)spos++ = '_'; + *(char *)spos++ = '1'; + *(char *)spos++ = '\0'; idx_flag++; } } } +EXPORT_SYMBOL(snd_card_set_id); + #ifndef CONFIG_SYSFS_DEPRECATED static ssize_t card_id_show_attr(struct device *dev, @@ -641,7 +657,7 @@ int snd_card_register(struct snd_card *card) return 0; } if (card->id[0] == '\0') - choose_default_id(card); + snd_card_set_id(card, NULL); snd_cards[card->number] = card; mutex_unlock(&snd_card_mutex); init_info_for_card(card); |