]> Git Repo - u-boot.git/blobdiff - env/flags.c
Merge patch series "spi-nor: Add parallel and stacked memories support"
[u-boot.git] / env / flags.c
index 418d6cc7425a5689164b0d99fa250e3d4d2c9fa2..233fd460d84215224e1934e5c34085a4b50a58d8 100644 (file)
@@ -8,9 +8,9 @@
 #include <linux/string.h>
 #include <linux/ctype.h>
 
+#include <stdio.h>
 #ifdef USE_HOSTCC /* Eliminate "ANSI does not permit..." warnings */
 #include <stdint.h>
-#include <stdio.h>
 #include "fw_env_private.h"
 #include "fw_env.h"
 #include <env_attr.h>
 #define env_get fw_getenv
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 #else
-#include <common.h>
+#include <linux/kernel.h>
 #include <env_internal.h>
 #endif
 
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
 #define ENV_FLAGS_NET_VARTYPE_REPS "im"
 #else
 #define ENV_FLAGS_NET_VARTYPE_REPS ""
 #endif
 
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+#define ENV_FLAGS_WRITEABLE_VARACCESS_REPS "w"
+#else
+#define ENV_FLAGS_WRITEABLE_VARACCESS_REPS ""
+#endif
+
 static const char env_flags_vartype_rep[] = "sdxb" ENV_FLAGS_NET_VARTYPE_REPS;
-static const char env_flags_varaccess_rep[] = "aroc";
+static const char env_flags_varaccess_rep[] =
+       "aroc" ENV_FLAGS_WRITEABLE_VARACCESS_REPS;
 static const int env_flags_varaccess_mask[] = {
        0,
        ENV_FLAGS_VARACCESS_PREVENT_DELETE |
@@ -38,7 +45,11 @@ static const int env_flags_varaccess_mask[] = {
        ENV_FLAGS_VARACCESS_PREVENT_DELETE |
                ENV_FLAGS_VARACCESS_PREVENT_OVERWR,
        ENV_FLAGS_VARACCESS_PREVENT_DELETE |
-               ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR};
+               ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR,
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+       ENV_FLAGS_VARACCESS_WRITEABLE,
+#endif
+       };
 
 #ifdef CONFIG_CMD_ENV_FLAGS
 static const char * const env_flags_vartype_names[] = {
@@ -46,7 +57,7 @@ static const char * const env_flags_vartype_names[] = {
        "decimal",
        "hexadecimal",
        "boolean",
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
        "IP address",
        "MAC address",
 #endif
@@ -56,6 +67,9 @@ static const char * const env_flags_varaccess_names[] = {
        "read-only",
        "write-once",
        "change-default",
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+       "writeable",
+#endif
 };
 
 /*
@@ -130,21 +144,25 @@ enum env_flags_vartype env_flags_parse_vartype(const char *flags)
  */
 enum env_flags_varaccess env_flags_parse_varaccess(const char *flags)
 {
+       enum env_flags_varaccess va_default = env_flags_varaccess_any;
+       enum env_flags_varaccess va;
        char *access;
 
        if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
-               return env_flags_varaccess_any;
+               return va_default;
 
        access = strchr(env_flags_varaccess_rep,
                flags[ENV_FLAGS_VARACCESS_LOC]);
 
-       if (access != NULL)
-               return (enum env_flags_varaccess)
+       if (access != NULL) {
+               va = (enum env_flags_varaccess)
                        (access - &env_flags_varaccess_rep[0]);
+               return va;
+       }
 
        printf("## Warning: Unknown environment variable access method '%c'\n",
                flags[ENV_FLAGS_VARACCESS_LOC]);
-       return env_flags_varaccess_any;
+       return va_default;
 }
 
 /*
@@ -152,17 +170,21 @@ enum env_flags_varaccess env_flags_parse_varaccess(const char *flags)
  */
 enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags)
 {
+       enum env_flags_varaccess va_default = env_flags_varaccess_any;
+       enum env_flags_varaccess va;
        int i;
 
        for (i = 0; i < ARRAY_SIZE(env_flags_varaccess_mask); i++)
                if (env_flags_varaccess_mask[i] ==
-                   (binflags & ENV_FLAGS_VARACCESS_BIN_MASK))
-                       return (enum env_flags_varaccess)i;
+                   (binflags & ENV_FLAGS_VARACCESS_BIN_MASK)) {
+                       va = (enum env_flags_varaccess)i;
+                       return va;
+       }
 
        printf("Warning: Non-standard access flags. (0x%x)\n",
                binflags & ENV_FLAGS_VARACCESS_BIN_MASK);
 
-       return env_flags_varaccess_any;
+       return va_default;
 }
 
 static inline int is_hex_prefix(const char *value)
@@ -189,7 +211,7 @@ static void skip_num(int hex, const char *value, const char **end,
                *end = value;
 }
 
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
 int eth_validate_ethaddr_str(const char *addr)
 {
        const char *end;
@@ -222,7 +244,7 @@ static int _env_flags_validate_type(const char *value,
        enum env_flags_vartype type)
 {
        const char *end;
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
        const char *cur;
        int i;
 #endif
@@ -251,7 +273,7 @@ static int _env_flags_validate_type(const char *value,
                if (value[1] != '\0')
                        return -1;
                break;
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
        case env_flags_vartype_ipaddr:
                cur = value;
                for (i = 0; i < 4; i++) {
@@ -326,13 +348,14 @@ enum env_flags_vartype env_flags_get_type(const char *name)
 enum env_flags_varaccess env_flags_get_varaccess(const char *name)
 {
        const char *flags_list = env_get(ENV_FLAGS_VAR);
+       enum env_flags_varaccess va_default = env_flags_varaccess_any;
        char flags[ENV_FLAGS_ATTR_MAX_LEN + 1];
 
        if (env_flags_lookup(flags_list, name, flags))
-               return env_flags_varaccess_any;
+               return va_default;
 
        if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
-               return env_flags_varaccess_any;
+               return va_default;
 
        return env_flags_parse_varaccess(flags);
 }
@@ -426,7 +449,11 @@ void env_flags_init(struct env_entry *var_entry)
        int ret = 1;
 
        if (first_call) {
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+               flags_list = ENV_FLAGS_LIST_STATIC;
+#else
                flags_list = env_get(ENV_FLAGS_VAR);
+#endif
                first_call = 0;
        }
        /* look in the ".flags" and static for a reference to this variable */
@@ -457,7 +484,6 @@ static int set_flags(const char *name, const char *value, void *priv)
 
        e.key   = name;
        e.data  = NULL;
-       e.callback = NULL;
        hsearch_r(e, ENV_FIND, &ep, &env_htab, 0);
 
        /* does the env variable actually exist? */
@@ -524,10 +550,26 @@ int env_flags_validate(const struct env_entry *item, const char *newval,
        }
 
        /* check for access permission */
-#ifndef CONFIG_ENV_ACCESS_IGNORE_FORCE
-       if (flag & H_FORCE)
+#ifdef CONFIG_ENV_WRITEABLE_LIST
+       if (flag & H_DEFAULT)
+               return 0;       /* Default env is always OK */
+
+       /*
+        * External writeable variables can be overwritten by external env,
+        * anything else can not be overwritten by external env.
+        */
+       if ((flag & H_EXTERNAL) &&
+           !(item->flags & ENV_FLAGS_VARACCESS_WRITEABLE))
+               return 1;
+#endif
+
+       if (flag & H_FORCE) {
+#ifdef CONFIG_ENV_ACCESS_IGNORE_FORCE
+               printf("## Error: Can't force access to \"%s\"\n", name);
+#else
                return 0;
 #endif
+       }
        switch (op) {
        case env_op_delete:
                if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_DELETE) {
This page took 0.033538 seconds and 4 git commands to generate.