From: Jaroslav Kysela Date: Wed, 3 Dec 2025 18:37:01 +0000 (+0100) Subject: alsactl: fix state restore to handle dynamic user control elements X-Git-Tag: v1.2.15~9 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=3f66770aa97d5ee86def5bf1b64f31b67c8b5dd9;p=alsa-utils.git alsactl: fix state restore to handle dynamic user control elements Track user control elements separately and adjust control count difference checking to account for dynamic user elements. Prevents false positives in re-init detection when only user controls have changed. Signed-off-by: Jaroslav Kysela --- diff --git a/alsactl/state.c b/alsactl/state.c index 2ce9b62..ee88d35 100644 --- a/alsactl/state.c +++ b/alsactl/state.c @@ -1511,7 +1511,7 @@ static int set_controls(int card, snd_config_t *top, int doit) snd_ctl_elem_id_t *elem_id; snd_config_t *control; snd_config_iterator_t i, next; - int err, controls1 = -1, controls2 = -1; + int err, controls1 = -1, controls2 = -1, ucontrols = -1, diff; unsigned int idx, count = 0; char name[32], tmpid[16]; const char *id; @@ -1571,7 +1571,7 @@ static int set_controls(int card, snd_config_t *top, int doit) count = snd_ctl_elem_list_get_count(list); dbg("list count: %u", count); if (count == 0) - goto _check; + goto _free; snd_ctl_elem_list_set_offset(list, 0); if (snd_ctl_elem_list_alloc_space(list, count) < 0) { error("No enough memory..."); @@ -1581,13 +1581,15 @@ static int set_controls(int card, snd_config_t *top, int doit) error("Cannot determine controls (2): %s", snd_strerror(err)); goto _free; } - controls2 = 0; - /* skip non-readable elements */ + controls2 = ucontrols = 0; + /* skip non-readable and count user elements */ for (idx = 0; idx < count; ++idx) { snd_ctl_elem_info_clear(elem_info); snd_ctl_elem_list_get_id(list, idx, elem_id); snd_ctl_elem_info_set_id(elem_info, elem_id); if (snd_ctl_elem_info(handle, elem_info) == 0) { + if (snd_ctl_elem_info_is_user(elem_info)) + ucontrols++; if (!snd_ctl_elem_info_is_readable(elem_info)) continue; controls2++; @@ -1596,9 +1598,9 @@ static int set_controls(int card, snd_config_t *top, int doit) /* check if we have additional controls in driver */ /* in this case we should go through init procedure */ - _check: - dbg("controls1=%i controls2=%i", controls1, controls2); - if (controls1 >= 0 && controls1 != controls2) { + diff = controls2 - controls1; + dbg("controls1=%i controls2=%i ucontrols=%i diff=%i", controls1, controls2, ucontrols, diff); + if (controls1 >= 0 && (-diff > ucontrols || diff > ucontrols)) { /* not very informative */ /* but value is used for check only */ err = -EAGAIN;