diff options
Diffstat (limited to 'common/globalvar.c')
-rw-r--r-- | common/globalvar.c | 167 |
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; |