summaryrefslogtreecommitdiffstats
path: root/common/globalvar.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/globalvar.c')
-rw-r--r--common/globalvar.c167
1 files changed, 131 insertions, 36 deletions
diff --git a/common/globalvar.c b/common/globalvar.c
index c87f2c9339..a83529f98f 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
#include <common.h>
#include <malloc.h>
#include <globalvar.h>
@@ -14,12 +16,12 @@
static int nv_dirty;
-struct device_d global_device = {
+struct device global_device = {
.name = "global",
.id = DEVICE_ID_SINGLE,
};
-struct device_d nv_device = {
+struct device nv_device = {
.name = "nv",
.id = DEVICE_ID_SINGLE,
};
@@ -99,7 +101,7 @@ static int nv_save(const char *name, const char *val)
* This function initializes a newly created device parameter from the corresponding
* nv.dev.<devname>.<paramname> variable.
*/
-void dev_param_init_from_nv(struct device_d *dev, const char *name)
+void dev_param_init_from_nv(struct device *dev, const char *name)
{
char *nvname;
const char *val;
@@ -128,19 +130,19 @@ void dev_param_init_from_nv(struct device_d *dev, const char *name)
/**
* nvvar_device_dispatch - dispatch dev.<dev>.<param> name into device and parameter name
* @name: The incoming name in the form dev.<dev>.<param>
- * @dev: The returned device_d * belonging to <dev>
+ * @dev: The returned device * belonging to <dev>
* @pname: the parameter name
*
- * Given a dev.<dev>.<param> string this function finds the device_d * belonging to
+ * Given a dev.<dev>.<param> string this function finds the device * belonging to
* <dev> and the parameter name from <param>.
*
* Return: When incoming string does not belong to the device namespace (does not begin
* with "dev." this function returns 0. A value > 0 is returned when the incoming string
- * is in the device namespace and the string can be dispatched into a device_d * and a
+ * is in the device namespace and the string can be dispatched into a device * and a
* parameter name. A negative error code is returned when the incoming string belongs to
* the device namespace, but cannot be dispatched.
*/
-static int nvvar_device_dispatch(const char *name, struct device_d **dev,
+static int nvvar_device_dispatch(const char *name, struct device **dev,
const char **pname)
{
char *devname;
@@ -175,20 +177,17 @@ static int nvvar_device_dispatch(const char *name, struct device_d **dev,
return 1;
}
-static int nv_set(struct device_d *dev, struct param_d *p, const char *name, const char *val)
+static int nv_set(struct device *dev, struct param_d *p, const char *name,
+ const char *val)
{
int ret;
- if (!val) {
- if (p)
- free(p->value);
- return 0;
+ if (val) {
+ ret = dev_set_param(&global_device, name, val);
+ if (ret)
+ return ret;
}
- ret = dev_set_param(&global_device, name, val);
- if (ret)
- return ret;
-
if (p) {
free(p->value);
p->value = xstrdup(val);
@@ -197,12 +196,13 @@ static int nv_set(struct device_d *dev, struct param_d *p, const char *name, con
return 0;
}
-static const char *nv_param_get(struct device_d *dev, struct param_d *p)
+static const char *nv_param_get(struct device *dev, struct param_d *p)
{
return p->value ? p->value : "";
}
-static int nv_param_set(struct device_d *dev, struct param_d *p, const char *val)
+static int nv_param_set(struct device *dev, struct param_d *p,
+ const char *val)
{
int ret;
@@ -216,7 +216,7 @@ static int nv_param_set(struct device_d *dev, struct param_d *p, const char *val
static int __nvvar_add(const char *name, const char *value)
{
struct param_d *p;
- struct device_d *dev = NULL;
+ struct device *dev = NULL;
const char *pname;
int ret;
@@ -293,6 +293,53 @@ int nvvar_remove(const char *name)
return ret;
}
+struct globalvar_deprecated {
+ char *newname;
+ char *oldname;
+ struct list_head list;
+};
+
+static LIST_HEAD(globalvar_deprecated_list);
+
+/*
+ * globalvar_alias_deprecated - add an alias
+ *
+ * @oldname: The old name for the variable
+ * @newname: The new name for the variable
+ *
+ * This function is a helper for globalvars that are renamed from one
+ * release to another. when a variable @oldname is found in the persistent
+ * environment a warning is issued and its value is written to @newname.
+ *
+ * Note that when both @oldname and @newname contain values then the values
+ * existing in @newname are overwritten.
+ */
+void globalvar_alias_deprecated(const char *oldname, const char *newname)
+{
+ struct globalvar_deprecated *gd;
+
+ gd = xzalloc(sizeof(*gd));
+ gd->newname = xstrdup(newname);
+ gd->oldname = xstrdup(oldname);
+ list_add_tail(&gd->list, &globalvar_deprecated_list);
+}
+
+static const char *globalvar_new_name(const char *oldname)
+{
+ struct globalvar_deprecated *gd;
+
+ list_for_each_entry(gd, &globalvar_deprecated_list, list) {
+ if (!strcmp(oldname, gd->oldname)) {
+ pr_warn("nv.%s is deprecated, converting to nv.%s\n", oldname,
+ gd->newname);
+ nv_dirty = 1;
+ return gd->newname;
+ }
+ }
+
+ return oldname;
+}
+
int nvvar_load(void)
{
char *val;
@@ -308,6 +355,8 @@ int nvvar_load(void)
return -ENOENT;
while ((d = readdir(dir))) {
+ const char *n;
+
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
@@ -316,10 +365,11 @@ int nvvar_load(void)
pr_debug("%s: Setting \"%s\" to \"%s\"\n",
__func__, d->d_name, val);
- ret = __nvvar_add(d->d_name, val);
+ n = globalvar_new_name(d->d_name);
+ ret = __nvvar_add(n, val);
if (ret)
pr_err("failed to create nv variable %s: %s\n",
- d->d_name, strerror(-ret));
+ n, strerror(-ret));
}
closedir(dir);
@@ -327,7 +377,7 @@ int nvvar_load(void)
return 0;
}
-static void device_param_print(struct device_d *dev)
+static void device_param_print(struct device *dev)
{
struct param_d *param;
@@ -399,9 +449,15 @@ void globalvar_set_match(const char *match, const char *val)
}
}
-static int globalvar_simple_set(struct device_d *dev, struct param_d *p, const char *val)
+void globalvar_set(const char *name, const char *val)
+{
+ dev_set_param(&global_device, name, val);
+}
+
+static int globalvar_simple_set(struct device *dev, struct param_d *p,
+ const char *val)
{
- struct device_d *rdev;
+ struct device *rdev;
const char *pname = NULL;
int ret;
@@ -514,7 +570,8 @@ int globalvar_add_simple_int(const char *name, int *value,
return 0;
}
-int globalvar_add_simple_bool(const char *name, int *value)
+int globalvar_add_simple_uint64(const char *name, u64 *value,
+ const char *format)
{
struct param_d *p;
int ret;
@@ -523,8 +580,30 @@ int globalvar_add_simple_bool(const char *name, int *value)
if (ret)
return ret;
- p = dev_add_param_bool(&global_device, name, NULL, NULL,
- value, NULL);
+ p = dev_add_param_uint64(&global_device, name, NULL, NULL,
+ value, format, NULL);
+
+ if (IS_ERR(p))
+ return PTR_ERR(p);
+
+ globalvar_nv_sync(name);
+
+ return 0;
+}
+
+int globalvar_add_bool(const char *name,
+ int (*set)(struct param_d *, void *),
+ int *value, void *priv)
+{
+ struct param_d *p;
+ int ret;
+
+ ret = globalvar_remove_unqualified(name);
+ if (ret)
+ return ret;
+
+ p = dev_add_param_bool(&global_device, name, set, NULL,
+ value, priv);
if (IS_ERR(p))
return PTR_ERR(p);
@@ -563,10 +642,7 @@ int globalvar_add_simple_bitmask(const char *name, unsigned long *value,
p = dev_add_param_bitmask(&global_device, name, NULL, NULL,
value, names, max, NULL);
- if (IS_ERR(p))
- return PTR_ERR(p);
-
- return 0;
+ return PTR_ERR_OR_ZERO(p);
}
int globalvar_add_simple_ip(const char *name, IPaddr_t *ip)
@@ -591,6 +667,8 @@ int globalvar_add_simple_ip(const char *name, IPaddr_t *ip)
static int globalvar_init(void)
{
+ const char *endianness;
+
register_device(&global_device);
if (IS_ENABLED(CONFIG_NVVAR))
@@ -598,11 +676,27 @@ static int globalvar_init(void)
globalvar_add_simple("version", UTS_RELEASE);
+ if (strlen(buildsystem_version_string) > 0)
+ globalvar_add_simple("buildsystem.version", buildsystem_version_string);
+
+#ifdef __BIG_ENDIAN
+ endianness = "big";
+#elif defined(__LITTLE_ENDIAN)
+ endianness = "little";
+#else
+#error "could not determine byte order"
+#endif
+
+ globalvar_add_simple("endianness", endianness);
+
return 0;
}
pure_initcall(globalvar_init);
-BAREBOX_MAGICVAR_NAMED(global_version, global.version, "The barebox version");
+BAREBOX_MAGICVAR(global.version, "The barebox version");
+BAREBOX_MAGICVAR(global.buildsystem.version,
+ "version of buildsystem barebox was built with");
+BAREBOX_MAGICVAR(global.endianness, "The barebox endianness");
/**
* nvvar_save - save NV variables to persistent environment
@@ -614,7 +708,7 @@ int nvvar_save(void)
{
struct param_d *param;
const char *env = default_environment_path_get();
- int ret;
+ int ret = 0;
#define TMPDIR "/.env.tmp"
if (!nv_dirty || !env)
return 0;
@@ -653,8 +747,9 @@ static void nv_exit(void)
}
predevshutdown_exitcall(nv_exit);
-static int nv_global_param_complete(struct device_d *dev, struct string_list *sl,
- char *instr, int eval)
+static int nv_global_param_complete(struct device *dev,
+ struct string_list *sl,
+ char *instr, int eval)
{
struct param_d *param;
int len;
@@ -675,7 +770,7 @@ static int nv_global_param_complete(struct device_d *dev, struct string_list *sl
int nv_complete(struct string_list *sl, char *instr)
{
- struct device_d *dev;
+ struct device *dev;
struct param_d *param;
char *str;
int len;