OSDN Git Service

ucm: add _fboot / FixedBootSequence
authorJaroslav Kysela <perex@perex.cz>
Fri, 5 Mar 2021 17:50:02 +0000 (18:50 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 11 Mar 2021 08:25:52 +0000 (09:25 +0100)
Actually, the BootSequence is executed only when the driver controls
(identifiers or value types) are changed. It may be handy to have
also a sequence which is executed at _each_ boot without any condition.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
include/use-case.h
src/ucm/main.c
src/ucm/parser.c
src/ucm/ucm_local.h
src/ucm/utils.c

index 2363c3e..13e5e3a 100644 (file)
@@ -418,7 +418,10 @@ int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
  * \return Zero if success, otherwise a negative error code
  *
  * Known identifiers:
+ *   - _fboot                  - execute the fixed boot sequence (value = NULL)
  *   - _boot                   - execute the boot sequence (value = NULL)
+ *                                - only when driver controls identifiers are changed
+ *                                  (otherwise the old control values are restored)
  *   - _defaults               - execute the 'defaults' sequence (value = NULL)
  *   - _verb                   - set current verb = value
  *   - _enadev                 - enable given device = value
index 754b967..8ac99de 100644 (file)
@@ -594,6 +594,8 @@ static int check_empty_configuration(snd_use_case_mgr_t *uc_mgr)
        }
        if (!list_empty(&uc_mgr->verb_list))
                return 0;
+       if (!list_empty(&uc_mgr->fixedboot_list))
+               return 0;
        if (!list_empty(&uc_mgr->boot_list))
                return 0;
        return -ENXIO;
@@ -993,6 +995,7 @@ int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr,
        if (mgr == NULL)
                return -ENOMEM;
        INIT_LIST_HEAD(&mgr->verb_list);
+       INIT_LIST_HEAD(&mgr->fixedboot_list);
        INIT_LIST_HEAD(&mgr->boot_list);
        INIT_LIST_HEAD(&mgr->default_list);
        INIT_LIST_HEAD(&mgr->value_list);
@@ -1886,6 +1889,24 @@ int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
         return err;
 }
 
+static int set_fixedboot_user(snd_use_case_mgr_t *uc_mgr,
+                             const char *value)
+{
+       int err;
+
+       if (value != NULL && *value) {
+               uc_error("error: wrong value for _fboot (%s)", value);
+               return -EINVAL;
+       }
+       err = execute_sequence(uc_mgr, &uc_mgr->fixedboot_list,
+                              &uc_mgr->value_list, NULL, NULL);
+       if (err < 0) {
+               uc_error("Unable to execute force boot sequence");
+               return err;
+       }
+       return err;
+}
+
 static int set_boot_user(snd_use_case_mgr_t *uc_mgr,
                         const char *value)
 {
@@ -2125,7 +2146,9 @@ int snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
        int err = 0;
 
        pthread_mutex_lock(&uc_mgr->mutex);
-       if (strcmp(identifier, "_boot") == 0)
+       if (strcmp(identifier, "_fboot") == 0)
+               err = set_fixedboot_user(uc_mgr, value);
+       else if (strcmp(identifier, "_boot") == 0)
                err = set_boot_user(uc_mgr, value);
        else if (strcmp(identifier, "_defaults") == 0)
                err = set_defaults_user(uc_mgr, value);
index a5be791..55781f8 100644 (file)
@@ -1740,6 +1740,26 @@ __error:
 }
 
 /*
+ * parse controls which should be run only at initial boot (forcefully)
+ */
+static int parse_controls_fixedboot(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
+{
+       int err;
+
+       if (!list_empty(&uc_mgr->fixedboot_list)) {
+               uc_error("FixedBoot list is not empty");
+               return -EINVAL;
+       }
+       err = parse_sequence(uc_mgr, &uc_mgr->fixedboot_list, cfg);
+       if (err < 0) {
+               uc_error("Unable to parse FixedBootSequence");
+               return err;
+       }
+
+       return 0;
+}
+
+/*
  * parse controls which should be run only at initial boot
  */
 static int parse_controls_boot(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
@@ -1891,6 +1911,14 @@ static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
                        continue;
                }
 
+               /* find default control values section (force boot sequence only) */
+               if (strcmp(id, "FixedBootSequence") == 0) {
+                       err = parse_controls_fixedboot(uc_mgr, n);
+                       if (err < 0)
+                               return err;
+                       continue;
+               }
+
                /* find default control values section (first boot only) */
                if (strcmp(id, "BootSequence") == 0) {
                        err = parse_controls_boot(uc_mgr, n);
index f99cd5d..c3e5a07 100644 (file)
@@ -222,6 +222,9 @@ struct snd_use_case_mgr {
        /* use case verb, devices and modifier configs parsed from files */
        struct list_head verb_list;
 
+       /* force boot settings - sequence */
+       struct list_head fixedboot_list;
+
        /* boot settings - sequence */
        struct list_head boot_list;
 
index f1fd8e9..24d0631 100644 (file)
@@ -692,6 +692,7 @@ void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr)
                list_del(&verb->list);
                free(verb);
        }
+       uc_mgr_free_sequence(&uc_mgr->fixedboot_list);
        uc_mgr_free_sequence(&uc_mgr->boot_list);
        uc_mgr_free_sequence(&uc_mgr->default_list);
        uc_mgr_free_value(&uc_mgr->value_list);