From e7df2a3ae569ed6d178510f58b22308edac7a4c7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 9 Mar 2012 17:41:53 +0100 Subject: ALSA: core - Refactor card id string creation code The code to handle the card id string is fairly messy, so here is a tidy up. Signed-off-by: Takashi Iwai --- sound/core/init.c | 169 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 69 deletions(-) (limited to 'sound/core/init.c') diff --git a/sound/core/init.c b/sound/core/init.c index 3ac49b1b7cb..068cf08d3ff 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -480,74 +480,104 @@ int snd_card_free(struct snd_card *card) EXPORT_SYMBOL(snd_card_free); -static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid) +/* retrieve the last word of shortname or longname */ +static const char *retrieve_id_from_card_name(const char *name) { - int i, len, idx_flag = 0, loops = SNDRV_CARDS; - const char *spos, *src; - char *id; - - if (nid == NULL) { - id = card->shortname; - spos = src = id; - while (*id != '\0') { - if (*id == ' ') - spos = id + 1; - id++; - } - } else { - spos = src = nid; + const char *spos = name; + + while (*name) { + if (isspace(*name) && isalnum(name[1])) + spos = name + 1; + name++; } - id = card->id; - while (*spos != '\0' && !isalnum(*spos)) - spos++; - if (isdigit(*spos)) - *id++ = isalpha(src[0]) ? src[0] : 'D'; - while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) { - if (isalnum(*spos)) - *id++ = *spos; - spos++; + return spos; +} + +/* return true if the given id string doesn't conflict any other card ids */ +static bool card_id_ok(struct snd_card *card, const char *id) +{ + int i; + if (!snd_info_check_reserved_words(id)) + return false; + for (i = 0; i < snd_ecards_limit; i++) { + if (snd_cards[i] && snd_cards[i] != card && + !strcmp(snd_cards[i]->id, id)) + return false; } - *id = '\0'; + return true; +} - id = card->id; +/* copy to card->id only with valid letters from nid */ +static void copy_valid_id_string(struct snd_card *card, const char *src, + const char *nid) +{ + char *id = card->id; + + while (*nid && !isalnum(*nid)) + nid++; + if (isdigit(*nid)) + *id++ = isalpha(*src) ? *src : 'D'; + while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) { + if (isalnum(*nid)) + *id++ = *nid; + nid++; + } + *id = 0; +} + +/* Set card->id from the given string + * If the string conflicts with other ids, add a suffix to make it unique. + */ +static void snd_card_set_id_no_lock(struct snd_card *card, const char *src, + const char *nid) +{ + int len, loops; + bool with_suffix; + bool is_default = false; + char *id; - if (*id == '\0') + copy_valid_id_string(card, src, nid); + id = card->id; + + again: + /* use "Default" for obviously invalid strings + * ("card" conflicts with proc directories) + */ + if (!*id || !strncmp(id, "card", 4)) { strcpy(id, "Default"); + is_default = true; + } - while (1) { - if (loops-- == 0) { - 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; - for (i = 0; i < snd_ecards_limit; i++) { - if (snd_cards[i] && !strcmp(snd_cards[i]->id, id)) - goto __change; - } - break; + with_suffix = false; + for (loops = 0; loops < SNDRV_CARDS; loops++) { + if (card_id_ok(card, id)) + return; /* OK */ - __change: len = strlen(id); - if (idx_flag) { - if (id[len-1] != '9') - id[len-1]++; - else - id[len-1] = 'A'; - } else if ((size_t)len <= sizeof(card->id) - 3) { - strcat(id, "_1"); - idx_flag++; + if (!with_suffix) { + /* add the "_X" suffix */ + char *spos = id + len; + if (len > sizeof(card->id) - 3) + spos = id + sizeof(card->id) - 3; + strcpy(spos, "_1"); + with_suffix = true; } else { - spos = id + len - 2; - if ((size_t)len <= sizeof(card->id) - 2) - spos++; - *(char *)spos++ = '_'; - *(char *)spos++ = '1'; - *(char *)spos++ = '\0'; - idx_flag++; + /* modify the existing suffix */ + if (id[len - 1] != '9') + id[len - 1]++; + else + id[len - 1] = 'A'; } } + /* fallback to the default id */ + if (!is_default) { + *id = 0; + goto again; + } + /* last resort... */ + snd_printk(KERN_ERR "unable to set card id (%s)\n", id); + if (card->proc_root->name) + strcpy(card->id, card->proc_root->name); } /** @@ -564,7 +594,7 @@ void snd_card_set_id(struct snd_card *card, const char *nid) if (card->id[0] != '\0') return; mutex_lock(&snd_card_mutex); - snd_card_set_id_no_lock(card, nid); + snd_card_set_id_no_lock(card, nid, nid); mutex_unlock(&snd_card_mutex); } EXPORT_SYMBOL(snd_card_set_id); @@ -596,22 +626,12 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr, memcpy(buf1, buf, copy); buf1[copy] = '\0'; mutex_lock(&snd_card_mutex); - if (!snd_info_check_reserved_words(buf1)) { - __exist: + if (!card_id_ok(NULL, buf1)) { mutex_unlock(&snd_card_mutex); return -EEXIST; } - for (idx = 0; idx < snd_ecards_limit; idx++) { - if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) { - if (card == snd_cards[idx]) - goto __ok; - else - goto __exist; - } - } strcpy(card->id, buf1); snd_info_card_id_change(card); -__ok: mutex_unlock(&snd_card_mutex); return count; @@ -665,7 +685,18 @@ int snd_card_register(struct snd_card *card) mutex_unlock(&snd_card_mutex); return 0; } - snd_card_set_id_no_lock(card, card->id[0] == '\0' ? NULL : card->id); + if (*card->id) { + /* make a unique id name from the given string */ + char tmpid[sizeof(card->id)]; + memcpy(tmpid, card->id, sizeof(card->id)); + snd_card_set_id_no_lock(card, tmpid, tmpid); + } else { + /* create an id from either shortname or longname */ + const char *src; + src = *card->shortname ? card->shortname : card->longname; + snd_card_set_id_no_lock(card, src, + retrieve_id_from_card_name(src)); + } snd_cards[card->number] = card; mutex_unlock(&snd_card_mutex); init_info_for_card(card); -- cgit v1.2.3-70-g09d2 From 51990e825431089747f8896244b5c17d3a6423f1 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 22 Jan 2012 11:23:42 -0500 Subject: device.h: cleanup users outside of linux/include (C files) For files that are actively using linux/device.h, make sure that they call it out. This will allow us to clean up some of the implicit uses of linux/device.h within include/* without introducing build regressions. Yes, this was created by "cheating" -- i.e. the headers were cleaned up, and then the fallout was found and fixed, and then the two commits were reordered. This ensures we don't introduce build regressions into the git history. Signed-off-by: Paul Gortmaker --- drivers/base/power/clock_ops.c | 1 + drivers/base/power/common.c | 1 + drivers/base/power/opp.c | 1 + drivers/base/regmap/regcache-lzo.c | 1 + drivers/base/regmap/regcache-rbtree.c | 1 + drivers/base/regmap/regcache.c | 1 + drivers/base/regmap/regmap-debugfs.c | 1 + drivers/base/regmap/regmap-irq.c | 1 + drivers/base/regmap/regmap.c | 1 + drivers/edac/edac_stub.c | 1 + drivers/edac/mce_amd_inj.c | 1 + drivers/mfd/wm8994-regmap.c | 1 + drivers/power/apm_power.c | 1 + drivers/power/power_supply.h | 4 ++++ drivers/power/power_supply_leds.c | 1 + drivers/power/power_supply_sysfs.c | 1 + net/rfkill/core.c | 1 + sound/core/init.c | 1 + sound/core/pcm.c | 1 + sound/core/seq/seq.c | 1 + sound/core/timer.c | 1 + 21 files changed, 24 insertions(+) (limited to 'sound/core/init.c') diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 428e55e012d..869d7ff2227 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index 4af7c1cbf90..a14085cc613 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 95706fa24c7..ac993eafec8 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regcache-lzo.c index b7d16143ede..51f6f28dadf 100644 --- a/drivers/base/regmap/regcache-lzo.c +++ b/drivers/base/regmap/regcache-lzo.c @@ -11,6 +11,7 @@ */ #include +#include #include #include "internal.h" diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 32620c4f168..b487c29a67d 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 1ead66186b7..214f704c34d 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 6f397476e27..8c90a83ae24 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "internal.h" diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 428836fc583..1befaa7a31c 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index be10a4ff660..87f9e1129ae 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include diff --git a/drivers/edac/edac_stub.c b/drivers/edac/edac_stub.c index 670c4481453..6c86f6e5455 100644 --- a/drivers/edac/edac_stub.c +++ b/drivers/edac/edac_stub.c @@ -15,6 +15,7 @@ #include #include #include +#include #include int edac_op_state = EDAC_OPSTATE_INVAL; diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c index 885e8ad8fdc..66b5151c108 100644 --- a/drivers/edac/mce_amd_inj.c +++ b/drivers/edac/mce_amd_inj.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c index c598ae69b8f..0c0a215f3fd 100644 --- a/drivers/mfd/wm8994-regmap.c +++ b/drivers/mfd/wm8994-regmap.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "wm8994.h" diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c index 8a612dec913..39763015b36 100644 --- a/drivers/power/apm_power.c +++ b/drivers/power/apm_power.c @@ -10,6 +10,7 @@ */ #include +#include #include #include diff --git a/drivers/power/power_supply.h b/drivers/power/power_supply.h index 018de2b2699..cc439fd89d8 100644 --- a/drivers/power/power_supply.h +++ b/drivers/power/power_supply.h @@ -10,6 +10,10 @@ * You may use this code as per GPL version 2 */ +struct device; +struct device_type; +struct power_supply; + #ifdef CONFIG_SYSFS extern void power_supply_init_attrs(struct device_type *dev_type); diff --git a/drivers/power/power_supply_leds.c b/drivers/power/power_supply_leds.c index da25eb94e5c..995f966ed5b 100644 --- a/drivers/power/power_supply_leds.c +++ b/drivers/power/power_supply_leds.c @@ -11,6 +11,7 @@ */ #include +#include #include #include diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index b52b57ca308..4368e7d6131 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 354760ebbbd..f974961754c 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/sound/core/init.c b/sound/core/init.c index 3ac49b1b7cb..995fc5d4b1a 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 8928ca871c2..1888a90bd5b 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index 9d8379aedf4..71211056108 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/sound/core/timer.c b/sound/core/timer.c index 8e7561dfc5f..6ddcf06f52f 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3-70-g09d2