From 7c7335877105364f7f5181e80ff34206b54be81f Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 7 Mar 2011 13:22:50 +0100 Subject: ALSA: control: fix numid conflict check for new controls The purpose of the snd_ctl_hole_check() function is to find conflicts between the numerical IDs of the new control and those of any existing controls. However, it would fail to detect an existing control whose count is smaller than the new control's count and whose interval of IDs is entirely contained in the interval of the new control's IDs. To fix this, use the correct formula to detect overlapping intervals, which happens to simplify the condition. This problem was not encountered so far because ALSA does not yet allow drivers to allocate specific control IDs. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/core/control.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'sound/core/control.c') diff --git a/sound/core/control.c b/sound/core/control.c index 9ce00ed20fba..d1b5ce818a4f 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -285,10 +285,8 @@ static unsigned int snd_ctl_hole_check(struct snd_card *card, struct snd_kcontrol *kctl; list_for_each_entry(kctl, &card->controls, list) { - if ((kctl->id.numid <= card->last_numid && - kctl->id.numid + kctl->count > card->last_numid) || - (kctl->id.numid <= card->last_numid + count - 1 && - kctl->id.numid + kctl->count > card->last_numid + count - 1)) + if (kctl->id.numid < card->last_numid + 1 + count && + kctl->id.numid + kctl->count > card->last_numid + 1) return card->last_numid = kctl->id.numid + kctl->count - 1; } return card->last_numid; -- cgit v1.2.3 From 0e82e5fa97614c9ca3efca5f8dca69dffd1c0ec0 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 7 Mar 2011 13:24:30 +0100 Subject: ALSA: control: clean up snd_ctl_hole_check() The return value of snd_ctl_hole_check() is used only to detect whether to continue the loop in snd_ctl_find_hole() or not, so we can simplify the code by changing this return type to a boolean. Also rename this function to better show what it actually does. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/core/control.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'sound/core/control.c') diff --git a/sound/core/control.c b/sound/core/control.c index d1b5ce818a4f..dc4afa6f99b1 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -279,31 +279,31 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol) EXPORT_SYMBOL(snd_ctl_free_one); -static unsigned int snd_ctl_hole_check(struct snd_card *card, - unsigned int count) +static bool snd_ctl_remove_numid_conflict(struct snd_card *card, + unsigned int count) { struct snd_kcontrol *kctl; list_for_each_entry(kctl, &card->controls, list) { if (kctl->id.numid < card->last_numid + 1 + count && - kctl->id.numid + kctl->count > card->last_numid + 1) - return card->last_numid = kctl->id.numid + kctl->count - 1; + kctl->id.numid + kctl->count > card->last_numid + 1) { + card->last_numid = kctl->id.numid + kctl->count - 1; + return true; + } } - return card->last_numid; + return false; } static int snd_ctl_find_hole(struct snd_card *card, unsigned int count) { - unsigned int last_numid, iter = 100000; + unsigned int iter = 100000; - last_numid = card->last_numid; - while (last_numid != snd_ctl_hole_check(card, count)) { + while (snd_ctl_remove_numid_conflict(card, count)) { if (--iter == 0) { /* this situation is very unlikely */ snd_printk(KERN_ERR "unable to allocate new control numid\n"); return -ENOMEM; } - last_numid = card->last_numid; } return 0; } -- cgit v1.2.3