191 lines
6.2 KiB
Diff
191 lines
6.2 KiB
Diff
From 120568fbb5b2ea5d4359c8e37f6d47d712e14698 Mon Sep 17 00:00:00 2001
|
|
From: Jaroslav Kysela <perex@perex.cz>
|
|
Date: Thu, 1 Jan 2026 17:51:25 +0100
|
|
Subject: [PATCH 1/2] alsactl: add missing call to clean card specific config
|
|
files
|
|
|
|
The card specific configuration files created at runtime must
|
|
be removed before UCM fixed boot sequence in the standard
|
|
restore operation.
|
|
|
|
Fixes: https://github.com/alsa-project/alsa-lib/issues/492
|
|
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
|
---
|
|
alsactl/state.c | 6 ++++++
|
|
1 file changed, 6 insertions(+)
|
|
|
|
diff --git a/alsactl/state.c b/alsactl/state.c
|
|
index 2942f3f..7c6e6d1 100644
|
|
--- a/alsactl/state.c
|
|
+++ b/alsactl/state.c
|
|
@@ -1790,6 +1790,12 @@ int load_state(const char *cfgdir, const char *file,
|
|
finalerr = lock_fd;
|
|
continue;
|
|
}
|
|
+ err = snd_card_clean_cfgdir(cfgdir, iter.card);
|
|
+ if (err < 0) {
|
|
+ initfailed(iter.card, "cfgdir", err);
|
|
+ finalerr = err;
|
|
+ continue;
|
|
+ }
|
|
/* error is ignored */
|
|
err = init_ucm(initflags | FLAG_UCM_FBOOT, iter.card);
|
|
/* return code 1 and 2 -> postpone initialization */
|
|
--
|
|
2.52.0
|
|
|
|
|
|
From 254528c42706524ff82378cf740d07b472cba2cc Mon Sep 17 00:00:00 2001
|
|
From: Jaroslav Kysela <perex@perex.cz>
|
|
Date: Thu, 1 Jan 2026 18:39:38 +0100
|
|
Subject: [PATCH 2/2] alsactl: fix sequence to clean card specific config files
|
|
for UCM
|
|
|
|
For UCM, card-specific config files should be removed only when the fixed
|
|
boot flag is set or if the card is not the primary card in a given card
|
|
group.
|
|
|
|
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
|
---
|
|
alsactl/alsactl.h | 2 +-
|
|
alsactl/init_parse.c | 2 +-
|
|
alsactl/init_ucm.c | 25 ++++++++++++++++++++-----
|
|
alsactl/state.c | 16 +++++++++-------
|
|
4 files changed, 31 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/alsactl/alsactl.h b/alsactl/alsactl.h
|
|
index 2aefb89..9f17284 100644
|
|
--- a/alsactl/alsactl.h
|
|
+++ b/alsactl/alsactl.h
|
|
@@ -68,7 +68,7 @@ int snd_card_iterator_error(struct snd_card_iterator *iter);
|
|
|
|
int load_configuration(const char *file, snd_config_t **top, int *open_failed);
|
|
int init(const char *cfgdir, const char *file, int flags, const char *cardname);
|
|
-int init_ucm(int flags, int cardno);
|
|
+int init_ucm(const char *cfgdir, int flags, int cardno);
|
|
bool validate_boot_time(long long boot_time, long long current_time, long long synctime);
|
|
int read_boot_params(snd_ctl_t *handle, long long *boot_time, long long *sync_time, long long *restore_time, long long *primary_card);
|
|
int write_boot_params(snd_ctl_t *handle, long long boot_time, long long sync_time, long long restore_time, long long primary_card);
|
|
diff --git a/alsactl/init_parse.c b/alsactl/init_parse.c
|
|
index a34cb0e..a437392 100644
|
|
--- a/alsactl/init_parse.c
|
|
+++ b/alsactl/init_parse.c
|
|
@@ -1761,7 +1761,7 @@ int init(const char *cfgdir, const char *filename, int flags, const char *cardna
|
|
lasterr = err;
|
|
continue;
|
|
}
|
|
- err = init_ucm(flags, iter.card);
|
|
+ err = init_ucm(cfgdir, flags, iter.card);
|
|
if (err == 0 || card_state_is_okay(err))
|
|
continue;
|
|
err = init_space(&space, iter.card);
|
|
diff --git a/alsactl/init_ucm.c b/alsactl/init_ucm.c
|
|
index 60967c4..c168427 100644
|
|
--- a/alsactl/init_ucm.c
|
|
+++ b/alsactl/init_ucm.c
|
|
@@ -137,11 +137,17 @@ static int reopen_ucm_manager(snd_use_case_mgr_t **uc_mgr, int cardno, int flags
|
|
* Helper: Execute boot sequences
|
|
* Returns: 0 on success, negative on error
|
|
*/
|
|
-static int execute_boot_sequences(snd_use_case_mgr_t *uc_mgr, int flags, bool fixed_boot)
|
|
+static int execute_boot_sequences(const char *cfgdir, snd_use_case_mgr_t *uc_mgr,
|
|
+ int cardno, int flags, bool fixed_boot)
|
|
{
|
|
int err = 0;
|
|
|
|
if (fixed_boot) {
|
|
+ err = snd_card_clean_cfgdir(cfgdir, cardno);
|
|
+ if (err < 0) {
|
|
+ dbg("ucm clean cfgdir: %d", err);
|
|
+ return err;
|
|
+ }
|
|
err = snd_use_case_set(uc_mgr, "_fboot", NULL);
|
|
dbg("ucm _fboot: %d", err);
|
|
if (err == -ENOENT && (flags & FLAG_UCM_BOOT) != 0) {
|
|
@@ -170,7 +176,7 @@ static int execute_boot_sequences(snd_use_case_mgr_t *uc_mgr, int flags, bool fi
|
|
* Handle also card groups.
|
|
* Returns: 0 = success, 1 = skip this card (e.g. linked or in-sync), negative on error
|
|
*/
|
|
-int init_ucm(int flags, int cardno)
|
|
+int init_ucm(const char *cfgdir, int flags, int cardno)
|
|
{
|
|
snd_use_case_mgr_t *uc_mgr;
|
|
char id[64];
|
|
@@ -268,7 +274,7 @@ int init_ucm(int flags, int cardno)
|
|
}
|
|
|
|
_execute_boot:
|
|
- if (flags & FLAG_UCM_FBOOT)
|
|
+ if (fixed_boot)
|
|
restored = true;
|
|
|
|
if (boot_card_group) {
|
|
@@ -277,7 +283,7 @@ _execute_boot:
|
|
goto _error;
|
|
}
|
|
|
|
- err = execute_boot_sequences(uc_mgr, flags, fixed_boot);
|
|
+ err = execute_boot_sequences(cfgdir, uc_mgr, cardno, flags, fixed_boot);
|
|
if (err < 0)
|
|
goto _error;
|
|
|
|
@@ -286,6 +292,15 @@ _execute_boot:
|
|
_error:
|
|
snd_use_case_mgr_close(uc_mgr);
|
|
_fin:
|
|
+ if (fixed_boot && primary_card >= 0 && primary_card != cardno) {
|
|
+ /* remove card specific configuration files for other cards in group */
|
|
+ int clean_err = snd_card_clean_cfgdir(cfgdir, cardno);
|
|
+ if (clean_err < 0) {
|
|
+ dbg("ucm clean cfgdir: %d", clean_err);
|
|
+ if (err >= 0)
|
|
+ err = clean_err;
|
|
+ }
|
|
+ }
|
|
if (lock_fd >= 0)
|
|
group_state_unlock(lock_fd, groupfile);
|
|
if (ctl)
|
|
@@ -298,7 +313,7 @@ _fin:
|
|
|
|
#else
|
|
|
|
-int init_ucm(int flags, int cardno)
|
|
+int init_ucm(const char *cfgdir, int flags, int cardno)
|
|
{
|
|
return -ENXIO;
|
|
}
|
|
diff --git a/alsactl/state.c b/alsactl/state.c
|
|
index 7c6e6d1..79bd309 100644
|
|
--- a/alsactl/state.c
|
|
+++ b/alsactl/state.c
|
|
@@ -1790,18 +1790,20 @@ int load_state(const char *cfgdir, const char *file,
|
|
finalerr = lock_fd;
|
|
continue;
|
|
}
|
|
- err = snd_card_clean_cfgdir(cfgdir, iter.card);
|
|
- if (err < 0) {
|
|
- initfailed(iter.card, "cfgdir", err);
|
|
- finalerr = err;
|
|
- continue;
|
|
- }
|
|
/* error is ignored */
|
|
- err = init_ucm(initflags | FLAG_UCM_FBOOT, iter.card);
|
|
+ err = init_ucm(cfgdir, initflags | FLAG_UCM_FBOOT, iter.card);
|
|
/* return code 1 and 2 -> postpone initialization */
|
|
if (card_state_is_okay(err)) {
|
|
export_card_state_set(iter.card, err);
|
|
goto unlock_card;
|
|
+ } else if (err < 0) {
|
|
+ /* no UCM - remove card specific configuration */
|
|
+ err = snd_card_clean_cfgdir(cfgdir, iter.card);
|
|
+ if (err < 0) {
|
|
+ initfailed(iter.card, "cfgdir", err);
|
|
+ finalerr = err;
|
|
+ continue;
|
|
+ }
|
|
}
|
|
/* do a check if controls matches state file */
|
|
if (do_init && set_controls(iter.card, config, 0)) {
|
|
--
|
|
2.52.0
|
|
|