summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2017-04-07 11:57:08 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2017-04-11 08:33:48 +0200
commitc5d95eb4c72a2639c10d01a801df00b4c34db315 (patch)
tree5b8c0afce59f832d2f102e4114feb3c16ffd98a0 /lib
parentc0511abbd1fa99ee8eff80d5bf207ff5f349cf8a (diff)
downloadbarebox-c5d95eb4c72a2639c10d01a801df00b4c34db315.tar.gz
barebox-c5d95eb4c72a2639c10d01a801df00b4c34db315.tar.xz
param: make parameter functions more consistent
This patch creates a consitent set of device parameter functions. With this we have: dev_add_param_<type><access> "type" is one of: int32, uint32, int64, uint64, string, mac, ipv4, enum, bitmask The improvement here is that we now can exactly specify the width of the int type parameters and also correctly distinguish between signed and unsigned variables which means that a variable no longer ends up with INT_MAX when it's assigned -1. "access" can be empty for regular read/write parameter, "_ro" for readonly parameters which get their value from a variable pointer in the background or "_fixed" for parameters which are set to a fixed value (without a pointer in the background). Some more exotic types are not (yet) implemented, like dev_add_param_ip_ro. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/parameter.c190
1 files changed, 78 insertions, 112 deletions
diff --git a/lib/parameter.c b/lib/parameter.c
index 6456779e71..a21b8fa4a4 100644
--- a/lib/parameter.c
+++ b/lib/parameter.c
@@ -218,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;
@@ -228,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 {
@@ -315,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);
};
@@ -331,18 +330,32 @@ static inline struct param_int *to_param_int(struct param_d *p)
static int param_int_set(struct device_d *dev, 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)
@@ -350,7 +363,7 @@ 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;
}
@@ -367,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
@@ -379,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
*
@@ -387,23 +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 = PARAM_TYPE_INT32;
+ p->type = type;
ret = __dev_add_param(p, dev, name, param_int_set, param_int_get, 0);
if (ret) {
@@ -662,99 +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;
-
- p->type = PARAM_TYPE_BOOL;
-
- 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.type = PARAM_TYPE_INT32;
- 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.type = PARAM_TYPE_INT64;
- piro->param.value = basprintf(format, value);
-
- return &piro->param;
-}
-
struct param_ip {
struct param_d param;
IPaddr_t *ip;