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);
* 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) {
* 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];
}
_execute_boot:
- if (flags & FLAG_UCM_FBOOT)
+ if (fixed_boot)
restored = true;
if (boot_card_group) {
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;
_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)
#else
-int init_ucm(int flags, int cardno)
+int init_ucm(const char *cfgdir, int flags, int cardno)
{
return -ENXIO;
}
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)) {