diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2017-05-05 11:31:35 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2017-05-05 11:31:35 +0200 |
commit | 8e91536a000c1738e354827d6f72965fa1444985 (patch) | |
tree | cb48104fa7a635e82d2b8b8eed6af6fe671756f2 /lib | |
parent | 30cce0c7414498317a43b2020dc1737b007acf98 (diff) | |
parent | 0071bacb4c7cab21c9fab8540f5aa9922a270a85 (diff) | |
download | barebox-8e91536a000c1738e354827d6f72965fa1444985.tar.gz barebox-8e91536a000c1738e354827d6f72965fa1444985.tar.xz |
Merge branch 'for-next/parameter-types'
Diffstat (limited to 'lib')
-rw-r--r-- | lib/parameter.c | 254 | ||||
-rw-r--r-- | lib/strtox.c | 9 |
2 files changed, 133 insertions, 130 deletions
diff --git a/lib/parameter.c b/lib/parameter.c index 65d6c7c0df..ab36b15591 100644 --- a/lib/parameter.c +++ b/lib/parameter.c @@ -31,6 +31,24 @@ #include <globalvar.h> #include <linux/err.h> +static const char *param_type_string[] = { + [PARAM_TYPE_STRING] = "string", + [PARAM_TYPE_INT32] = "int32", + [PARAM_TYPE_UINT32] = "uint32", + [PARAM_TYPE_INT64] = "int64", + [PARAM_TYPE_UINT64] = "uint64", + [PARAM_TYPE_BOOL] = "bool", + [PARAM_TYPE_ENUM] = "enum", + [PARAM_TYPE_BITMASK] = "bitmask", + [PARAM_TYPE_IPV4] = "ipv4", + [PARAM_TYPE_MAC] = "MAC", +}; + +const char *get_param_type(struct param_d *param) +{ + return param_type_string[param->type]; +} + struct param_d *get_param_by_name(struct device_d *dev, const char *name) { struct param_d *p; @@ -58,7 +76,7 @@ const char *dev_get_param(struct device_d *dev, const char *name) return NULL; } - return param->get(dev, param); + return param->get(param); } /** @@ -89,7 +107,7 @@ int dev_set_param(struct device_d *dev, const char *name, const char *val) return -EACCES; } - ret = param->set(dev, param, val); + ret = param->set(param, val); if (ret) errno = -ret; @@ -107,7 +125,7 @@ int dev_set_param(struct device_d *dev, const char *name, const char *val) * used during deregistration of the parameter to free the alloctated * memory. */ -int dev_param_set_generic(struct device_d *dev, struct param_d *p, +int dev_param_set_generic(struct param_d *p, const char *val) { free(p->value); @@ -119,7 +137,7 @@ int dev_param_set_generic(struct device_d *dev, struct param_d *p, return p->value ? 0 : -ENOMEM; } -static const char *param_get_generic(struct device_d *dev, struct param_d *p) +static const char *param_get_generic(struct param_d *p) { return p->value ? p->value : ""; } @@ -133,8 +151,8 @@ static int compare(struct list_head *a, struct list_head *b) } static int __dev_add_param(struct param_d *param, struct device_d *dev, const char *name, - int (*set)(struct device_d *dev, struct param_d *p, const char *val), - const char *(*get)(struct device_d *dev, struct param_d *p), + int (*set)(struct param_d *p, const char *val), + const char *(*get)(struct param_d *p), unsigned long flags) { if (get_param_by_name(dev, name)) @@ -176,8 +194,8 @@ static int __dev_add_param(struct param_d *param, struct device_d *dev, const ch * not use static arrays when using the generic functions. */ struct param_d *dev_add_param(struct device_d *dev, const char *name, - int (*set)(struct device_d *dev, struct param_d *p, const char *val), - const char *(*get)(struct device_d *dev, struct param_d *param), + int (*set)(struct param_d *p, const char *val), + const char *(*get)(struct param_d *param), unsigned long flags) { struct param_d *param; @@ -200,7 +218,7 @@ struct param_d *dev_add_param(struct device_d *dev, const char *name, * @param name The name of the parameter * @param value The value of the parameter */ -int dev_add_param_fixed(struct device_d *dev, const char *name, const char *value) +struct param_d *dev_add_param_fixed(struct device_d *dev, const char *name, const char *value) { struct param_d *param; int ret; @@ -210,12 +228,12 @@ int dev_add_param_fixed(struct device_d *dev, const char *name, const char *valu ret = __dev_add_param(param, dev, name, NULL, NULL, PARAM_FLAG_RO); if (ret) { free(param); - return ret; + return ERR_PTR(ret); } param->value = strdup(value); - return 0; + return param; } struct param_string { @@ -230,7 +248,7 @@ static inline struct param_string *to_param_string(struct param_d *p) return container_of(p, struct param_string, param); } -static int param_string_set(struct device_d *dev, struct param_d *p, const char *val) +static int param_string_set(struct param_d *p, const char *val) { struct param_string *ps = to_param_string(p); int ret; @@ -255,7 +273,7 @@ static int param_string_set(struct device_d *dev, struct param_d *p, const char return ret; } -static const char *param_string_get(struct device_d *dev, struct param_d *p) +static const char *param_string_get(struct param_d *p) { struct param_string *ps = to_param_string(p); int ret; @@ -284,6 +302,7 @@ struct param_d *dev_add_param_string(struct device_d *dev, const char *name, ps->get = get; p = &ps->param; p->driver_priv = priv; + p->type = PARAM_TYPE_STRING; ret = __dev_add_param(p, dev, name, param_string_set, param_string_get, 0); if (ret) { @@ -296,10 +315,9 @@ struct param_d *dev_add_param_string(struct device_d *dev, const char *name, struct param_int { struct param_d param; - int *value; + void *value; + int dsize; const char *format; -#define PARAM_INT_FLAG_BOOL (1 << 0) - unsigned flags; int (*set)(struct param_d *p, void *priv); int (*get)(struct param_d *p, void *priv); }; @@ -309,21 +327,35 @@ static inline struct param_int *to_param_int(struct param_d *p) return container_of(p, struct param_int, param); } -static int param_int_set(struct device_d *dev, struct param_d *p, const char *val) +static int param_int_set(struct param_d *p, const char *val) { struct param_int *pi = to_param_int(p); - int value_save = *pi->value; + u8 value_save[pi->dsize]; int ret; if (!val) return -EINVAL; - if (pi->flags & PARAM_INT_FLAG_BOOL) { + memcpy(value_save, pi->value, pi->dsize); + + switch (p->type) { + case PARAM_TYPE_BOOL: ret = strtobool(val, pi->value); - if (ret) - return ret; - } else { - *pi->value = simple_strtol(val, NULL, 0); + break; + case PARAM_TYPE_INT32: + *(uint32_t *)pi->value = simple_strtol(val, NULL, 0); + break; + case PARAM_TYPE_UINT32: + *(int32_t *)pi->value = simple_strtoul(val, NULL, 0); + break; + case PARAM_TYPE_INT64: + *(int64_t *)pi->value = simple_strtoll(val, NULL, 0); + break; + case PARAM_TYPE_UINT64: + *(uint64_t *)pi->value = simple_strtoull(val, NULL, 0); + break; + default: + return -EINVAL; } if (!pi->set) @@ -331,12 +363,12 @@ static int param_int_set(struct device_d *dev, struct param_d *p, const char *va ret = pi->set(p, p->driver_priv); if (ret) - *pi->value = value_save; + memcpy(pi->value, value_save, pi->dsize); return ret; } -static const char *param_int_get(struct device_d *dev, struct param_d *p) +static const char *param_int_get(struct param_d *p) { struct param_int *pi = to_param_int(p); int ret; @@ -348,11 +380,28 @@ static const char *param_int_get(struct device_d *dev, struct param_d *p) } free(p->value); - p->value = basprintf(pi->format, *pi->value); + switch (p->type) { + case PARAM_TYPE_BOOL: + case PARAM_TYPE_INT32: + case PARAM_TYPE_UINT32: + p->value = basprintf(pi->format, *(int32_t *)pi->value); + break; + case PARAM_TYPE_INT64: + case PARAM_TYPE_UINT64: + p->value = basprintf(pi->format, *(int64_t *)pi->value); + break; + default: + return NULL; + } return p->value; } +int param_set_readonly(struct param_d *p, void *priv) +{ + return -EROFS; +} + /** * dev_add_param_int - add an integer parameter to a device * @param dev The device @@ -360,6 +409,7 @@ static const char *param_int_get(struct device_d *dev, struct param_d *p) * @param set set function * @param get get function * @param value pointer to the integer containing the value of the parameter + * @param type The variable type * @param format the printf format used to print the value * @param priv user private data, will be passed to get/set * @@ -368,22 +418,51 @@ static const char *param_int_get(struct device_d *dev, struct param_d *p) * The set function can be used as a notifer when the variable is about * to be written. Can also be used to limit the value. */ -struct param_d *dev_add_param_int(struct device_d *dev, const char *name, +struct param_d *__dev_add_param_int(struct device_d *dev, const char *name, int (*set)(struct param_d *p, void *priv), int (*get)(struct param_d *p, void *priv), - int *value, const char *format, void *priv) + void *value, enum param_type type, const char *format, void *priv) { struct param_int *pi; struct param_d *p; - int ret; + int ret, dsize; + + switch (type) { + case PARAM_TYPE_BOOL: + dsize = sizeof(uint32_t); + break; + case PARAM_TYPE_INT32: + dsize = sizeof(int32_t); + break; + case PARAM_TYPE_UINT32: + dsize = sizeof(uint32_t); + break; + case PARAM_TYPE_INT64: + dsize = sizeof(int64_t); + break; + case PARAM_TYPE_UINT64: + dsize = sizeof(uint64_t); + break; + default: + return ERR_PTR(-EINVAL); + } pi = xzalloc(sizeof(*pi)); - pi->value = value; + + if (IS_ERR(set)) { + pi->value = xmemdup(value, dsize); + set = param_set_readonly; + } else { + pi->value = value; + } + + pi->dsize = dsize; pi->format = format; pi->set = set; pi->get = get; p = &pi->param; p->driver_priv = priv; + p->type = type; ret = __dev_add_param(p, dev, name, param_int_set, param_int_get, 0); if (ret) { @@ -408,7 +487,7 @@ static inline struct param_enum *to_param_enum(struct param_d *p) return container_of(p, struct param_enum, param); } -static int param_enum_set(struct device_d *dev, struct param_d *p, const char *val) +static int param_enum_set(struct param_d *p, const char *val) { struct param_enum *pe = to_param_enum(p); int value_save = *pe->value; @@ -436,7 +515,7 @@ static int param_enum_set(struct device_d *dev, struct param_d *p, const char *v return ret; } -static const char *param_enum_get(struct device_d *dev, struct param_d *p) +static const char *param_enum_get(struct param_d *p) { struct param_enum *pe = to_param_enum(p); int ret; @@ -465,7 +544,7 @@ static void param_enum_info(struct param_d *p) if (pe->num_names <= 1) return; - printf(" ("); + printf(" (values: "); for (i = 0; i < pe->num_names; i++) { if (!pe->names[i] || !*pe->names[i]) @@ -493,6 +572,7 @@ struct param_d *dev_add_param_enum(struct device_d *dev, const char *name, pe->num_names = num_names; p = &pe->param; p->driver_priv = priv; + p->type = PARAM_TYPE_ENUM; ret = __dev_add_param(p, dev, name, param_enum_set, param_enum_get, 0); if (ret) { @@ -519,7 +599,7 @@ static inline struct param_bitmask *to_param_bitmask(struct param_d *p) return container_of(p, struct param_bitmask, param); } -static int param_bitmask_set(struct device_d *dev, struct param_d *p, const char *val) +static int param_bitmask_set(struct param_d *p, const char *val) { struct param_bitmask *pb = to_param_bitmask(p); void *value_save; @@ -565,7 +645,7 @@ out: return ret; } -static const char *param_bitmask_get(struct device_d *dev, struct param_d *p) +static const char *param_bitmask_get(struct param_d *p) { struct param_bitmask *pb = to_param_bitmask(p); int ret, bit; @@ -622,6 +702,7 @@ struct param_d *dev_add_param_bitmask(struct device_d *dev, const char *name, pb->num_names = max; p = &pb->param; p->driver_priv = priv; + p->type = PARAM_TYPE_BITMASK; for (i = 0; i < pb->num_names; i++) if (pb->names[i]) @@ -640,95 +721,6 @@ struct param_d *dev_add_param_bitmask(struct device_d *dev, const char *name, return &pb->param; } -/** - * dev_add_param_bool - add an boolean parameter to a device - * @param dev The device - * @param name The name of the parameter - * @param set set function - * @param get get function - * @param value pointer to the integer containing the value of the parameter - * @param priv user private data, will be passed to get/set - * - * The get function can be used as a notifier when the variable is about - * to be read. - * The set function can be used as a notifer when the variable is about - * to be written. Can also be used to limit the value. - */ -struct param_d *dev_add_param_bool(struct device_d *dev, const char *name, - int (*set)(struct param_d *p, void *priv), - int (*get)(struct param_d *p, void *priv), - int *value, void *priv) -{ - struct param_int *pi; - struct param_d *p; - - p = dev_add_param_int(dev, name, set, get, value, "%d", priv); - if (IS_ERR(p)) - return p; - - pi = to_param_int(p); - pi->flags |= PARAM_INT_FLAG_BOOL; - - return p; -} - -struct param_int_ro { - struct param_d param; - char *value; -}; - -/** - * dev_add_param_int_ro - add a read only integer parameter to a device - * @param dev The device - * @param name The name of the parameter - * @param value The value of the parameter - * @param format the printf format used to print the value - */ -struct param_d *dev_add_param_int_ro(struct device_d *dev, const char *name, - int value, const char *format) -{ - struct param_int *piro; - int ret; - - piro = xzalloc(sizeof(*piro)); - - ret = __dev_add_param(&piro->param, dev, name, NULL, NULL, PARAM_FLAG_RO); - if (ret) { - free(piro); - return ERR_PTR(ret); - } - - piro->param.value = basprintf(format, value); - - return &piro->param; -} - -/** - * dev_add_param_llint_ro - add a read only long long parameter to a device - * @param dev The device - * @param name The name of the parameter - * @param value The value of the parameter - * @param format the printf format used to print the value - */ -struct param_d *dev_add_param_llint_ro(struct device_d *dev, const char *name, - long long value, const char *format) -{ - struct param_int *piro; - int ret; - - piro = xzalloc(sizeof(*piro)); - - ret = __dev_add_param(&piro->param, dev, name, NULL, NULL, PARAM_FLAG_RO); - if (ret) { - free(piro); - return ERR_PTR(ret); - } - - piro->param.value = basprintf(format, value); - - return &piro->param; -} - struct param_ip { struct param_d param; IPaddr_t *ip; @@ -742,7 +734,7 @@ static inline struct param_ip *to_param_ip(struct param_d *p) return container_of(p, struct param_ip, param); } -static int param_ip_set(struct device_d *dev, struct param_d *p, const char *val) +static int param_ip_set(struct param_d *p, const char *val) { struct param_ip *pi = to_param_ip(p); IPaddr_t ip_save = *pi->ip; @@ -765,7 +757,7 @@ static int param_ip_set(struct device_d *dev, struct param_d *p, const char *val return ret; } -static const char *param_ip_get(struct device_d *dev, struct param_d *p) +static const char *param_ip_get(struct param_d *p) { struct param_ip *pi = to_param_ip(p); int ret; @@ -795,6 +787,7 @@ struct param_d *dev_add_param_ip(struct device_d *dev, const char *name, pi->set = set; pi->get = get; pi->param.driver_priv = priv; + pi->param.type = PARAM_TYPE_IPV4; ret = __dev_add_param(&pi->param, dev, name, param_ip_set, param_ip_get, 0); @@ -823,7 +816,7 @@ static inline struct param_mac *to_param_mac(struct param_d *p) return container_of(p, struct param_mac, param); } -static int param_mac_set(struct device_d *dev, struct param_d *p, const char *val) +static int param_mac_set(struct param_d *p, const char *val) { struct param_mac *pm = to_param_mac(p); char mac_save[6]; @@ -852,7 +845,7 @@ out: return ret; } -static const char *param_mac_get(struct device_d *dev, struct param_d *p) +static const char *param_mac_get(struct param_d *p) { struct param_mac *pm = to_param_mac(p); int ret; @@ -882,6 +875,7 @@ struct param_d *dev_add_param_mac(struct device_d *dev, const char *name, pm->get = get; pm->param.driver_priv = priv; pm->param.value = pm->mac_str; + pm->param.type = PARAM_TYPE_MAC; ret = __dev_add_param(&pm->param, dev, name, param_mac_set, param_mac_get, 0); @@ -900,7 +894,7 @@ struct param_d *dev_add_param_mac(struct device_d *dev, const char *name, */ void dev_remove_param(struct param_d *p) { - p->set(p->dev, p, NULL); + p->set(p, NULL); list_del(&p->list); free(p->name); free(p); @@ -916,7 +910,7 @@ void dev_remove_parameters(struct device_d *dev) struct param_d *p, *n; list_for_each_entry_safe(p, n, &dev->parameters, list) { - p->set(dev, p, NULL); + p->set(p, NULL); list_del(&p->list); free(p->name); free(p); diff --git a/lib/strtox.c b/lib/strtox.c index 3bb6b0ef89..4b601a1b39 100644 --- a/lib/strtox.c +++ b/lib/strtox.c @@ -73,3 +73,12 @@ unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int bas return result; } EXPORT_SYMBOL(simple_strtoull); + +long long simple_strtoll(const char *cp, char **endp, unsigned int base) +{ + if (*cp == '-') + return -simple_strtoull(cp + 1, endp, base); + + return simple_strtoull(cp, endp, base); +} +EXPORT_SYMBOL(simple_strtoll); |