summaryrefslogtreecommitdiffstats
path: root/lib/parameter.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/parameter.c')
-rw-r--r--lib/parameter.c267
1 files changed, 191 insertions, 76 deletions
diff --git a/lib/parameter.c b/lib/parameter.c
index fdbb2e71d1..c587d10eab 100644
--- a/lib/parameter.c
+++ b/lib/parameter.c
@@ -3,9 +3,6 @@
*
* Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
@@ -30,6 +27,8 @@
#include <string.h>
#include <globalvar.h>
#include <linux/err.h>
+#include <file-list.h>
+#include <stringlist.h>
static const char *param_type_string[] = {
[PARAM_TYPE_STRING] = "string",
@@ -42,6 +41,7 @@ static const char *param_type_string[] = {
[PARAM_TYPE_BITMASK] = "bitmask",
[PARAM_TYPE_IPV4] = "ipv4",
[PARAM_TYPE_MAC] = "MAC",
+ [PARAM_TYPE_FILE_LIST] = "file-list",
};
const char *get_param_type(struct param_d *param)
@@ -49,7 +49,7 @@ 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 *get_param_by_name(struct device *dev, const char *name)
{
struct param_d *p;
@@ -67,7 +67,7 @@ struct param_d *get_param_by_name(struct device_d *dev, const char *name)
* @param name The name of the parameter
* @return The value
*/
-const char *dev_get_param(struct device_d *dev, const char *name)
+const char *dev_get_param(struct device *dev, const char *name)
{
struct param_d *param = get_param_by_name(dev, name);
@@ -85,33 +85,27 @@ const char *dev_get_param(struct device_d *dev, const char *name)
* @param name The name of the parameter
* @param val The new value of the parameter
*/
-int dev_set_param(struct device_d *dev, const char *name, const char *val)
+int dev_set_param(struct device *dev, const char *name, const char *val)
{
struct param_d *param;
int ret;
- if (!dev) {
- errno = ENODEV;
- return -ENODEV;
- }
+ if (!dev)
+ return errno_set(-ENODEV);
param = get_param_by_name(dev, name);
- if (!param) {
- errno = EINVAL;
- return -EINVAL;
- }
+ if (!param)
+ return errno_set(-EINVAL);
- if (param->flags & PARAM_FLAG_RO) {
- errno = EACCES;
- return -EACCES;
- }
+ if (param->flags & PARAM_FLAG_RO)
+ return errno_set(-EACCES);
ret = param->set(dev, param, val);
if (ret)
- errno = -ret;
+ return errno_set(ret);
- return ret;
+ return 0;
}
/**
@@ -125,8 +119,8 @@ 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,
- const char *val)
+int dev_param_set_generic(struct device *dev, struct param_d *p,
+ const char *val)
{
free(p->value);
if (!val) {
@@ -137,7 +131,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 device *dev, struct param_d *p)
{
return p->value ? p->value : "";
}
@@ -150,10 +144,11 @@ static int compare(struct list_head *a, struct list_head *b)
return strcmp(na, nb);
}
-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),
- unsigned long flags)
+static int __dev_add_param(struct param_d *param, struct device *dev,
+ const char *name,
+ int (*set)(struct device *dev, struct param_d *p, const char *val),
+ const char *(*get)(struct device *dev, struct param_d *p),
+ unsigned long flags)
{
if (get_param_by_name(dev, name))
return -EEXIST;
@@ -193,10 +188,10 @@ static int __dev_add_param(struct param_d *param, struct device_d *dev, const ch
* expect the parameter value to be a string which can be freed with free(). Do
* 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),
- unsigned long flags)
+struct param_d *dev_add_param(struct device *dev, const char *name,
+ int (*set)(struct device *dev, struct param_d *p, const char *val),
+ const char *(*get)(struct device *dev, struct param_d *param),
+ unsigned long flags)
{
struct param_d *param;
int ret;
@@ -218,7 +213,8 @@ 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
*/
-struct param_d *dev_add_param_fixed(struct device_d *dev, const char *name, const char *value)
+struct param_d *dev_add_param_fixed(struct device *dev, const char *name,
+ const char *value)
{
struct param_d *param;
int ret;
@@ -248,7 +244,8 @@ 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 device *dev, struct param_d *p,
+ const char *val)
{
struct param_string *ps = to_param_string(p);
int ret;
@@ -258,12 +255,14 @@ static int param_string_set(struct device_d *dev, struct param_d *p, const char
if (!val)
val = "";
- value_new = xstrdup(val);
- value_new = strim(value_new);
+ value_new = xstrdup(skip_spaces(val));
+ strim(value_new);
*ps->value = value_new;
- if (!ps->set)
+ if (!ps->set) {
+ free(value_save);
return 0;
+ }
ret = ps->set(p, p->driver_priv);
if (ret) {
@@ -276,7 +275,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 device *dev, struct param_d *p)
{
struct param_string *ps = to_param_string(p);
int ret;
@@ -290,10 +289,10 @@ static const char *param_string_get(struct device_d *dev, struct param_d *p)
return *ps->value;
}
-struct param_d *dev_add_param_string(struct device_d *dev, const char *name,
- int (*set)(struct param_d *p, void *priv),
- int (*get)(struct param_d *p, void *priv),
- char **value, void *priv)
+struct param_d *dev_add_param_string(struct device *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ char **value, void *priv)
{
struct param_string *ps;
struct param_d *p;
@@ -330,7 +329,8 @@ 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 device *dev, struct param_d *p,
+ const char *val)
{
struct param_int *pi = to_param_int(p);
u8 value_save[pi->dsize];
@@ -371,7 +371,7 @@ static int param_int_set(struct device_d *dev, struct param_d *p, const char *va
return ret;
}
-static const char *param_int_get(struct device_d *dev, struct param_d *p)
+static const char *param_int_get(struct device *dev, struct param_d *p)
{
struct param_int *pi = to_param_int(p);
int ret;
@@ -421,10 +421,11 @@ int param_set_readonly(struct param_d *p, void *priv)
* 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,
- int (*set)(struct param_d *p, void *priv),
- int (*get)(struct param_d *p, void *priv),
- void *value, enum param_type type, const char *format, void *priv)
+struct param_d *__dev_add_param_int(struct device *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ void *value, enum param_type type,
+ const char *format, void *priv)
{
struct param_int *pi;
struct param_d *p;
@@ -490,7 +491,8 @@ 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 device *dev, struct param_d *p,
+ const char *val)
{
struct param_enum *pe = to_param_enum(p);
int value_save = *pe->value;
@@ -518,7 +520,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 device *dev, struct param_d *p)
{
struct param_enum *pe = to_param_enum(p);
int ret;
@@ -557,10 +559,11 @@ static void param_enum_info(struct param_d *p)
}
}
-struct param_d *dev_add_param_enum(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 * const *names, int num_names, void *priv)
+struct param_d *dev_add_param_enum(struct device *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ int *value, const char * const *names,
+ int num_names, void *priv)
{
struct param_enum *pe;
struct param_d *p;
@@ -588,6 +591,29 @@ struct param_d *dev_add_param_enum(struct device_d *dev, const char *name,
return &pe->param;
}
+static const char *const tristate_names[] = {
+ [PARAM_TRISTATE_UNKNOWN] = "unknown",
+ [PARAM_TRISTATE_TRUE] = "1",
+ [PARAM_TRISTATE_FALSE] = "0",
+};
+
+struct param_d *dev_add_param_tristate(struct device *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ int *value, void *priv)
+{
+ return dev_add_param_enum(dev, name, set, get, value, tristate_names,
+ ARRAY_SIZE(tristate_names), priv);
+}
+
+struct param_d *dev_add_param_tristate_ro(struct device *dev,
+ const char *name,
+ int *value)
+{
+ return dev_add_param_enum_ro(dev, name, value, tristate_names,
+ ARRAY_SIZE(tristate_names));
+}
+
struct param_bitmask {
struct param_d param;
unsigned long *value;
@@ -602,7 +628,8 @@ 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 device *dev, struct param_d *p,
+ const char *val)
{
struct param_bitmask *pb = to_param_bitmask(p);
void *value_save;
@@ -648,7 +675,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 device *dev, struct param_d *p)
{
struct param_bitmask *pb = to_param_bitmask(p);
int ret, bit;
@@ -687,10 +714,12 @@ static void param_bitmask_info(struct param_d *p)
}
}
-struct param_d *dev_add_param_bitmask(struct device_d *dev, const char *name,
- int (*set)(struct param_d *p, void *priv),
- int (*get)(struct param_d *p, void *priv),
- unsigned long *value, const char * const *names, int max, void *priv)
+struct param_d *dev_add_param_bitmask(struct device *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ unsigned long *value,
+ const char * const *names, int max,
+ void *priv)
{
struct param_bitmask *pb;
struct param_d *p;
@@ -727,7 +756,6 @@ struct param_d *dev_add_param_bitmask(struct device_d *dev, const char *name,
struct param_ip {
struct param_d param;
IPaddr_t *ip;
- const char *format;
int (*set)(struct param_d *p, void *priv);
int (*get)(struct param_d *p, void *priv);
};
@@ -737,7 +765,8 @@ 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 device *dev, struct param_d *p,
+ const char *val)
{
struct param_ip *pi = to_param_ip(p);
IPaddr_t ip_save = *pi->ip;
@@ -760,7 +789,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 device *dev, struct param_d *p)
{
struct param_ip *pi = to_param_ip(p);
int ret;
@@ -777,10 +806,10 @@ static const char *param_ip_get(struct device_d *dev, struct param_d *p)
return p->value;
}
-struct param_d *dev_add_param_ip(struct device_d *dev, const char *name,
- int (*set)(struct param_d *p, void *priv),
- int (*get)(struct param_d *p, void *priv),
- IPaddr_t *ip, void *priv)
+struct param_d *dev_add_param_ip(struct device *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ IPaddr_t *ip, void *priv)
{
struct param_ip *pi;
int ret;
@@ -806,20 +835,19 @@ struct param_mac {
struct param_d param;
char *mac;
u8 mac_str[sizeof("xx:xx:xx:xx:xx:xx")];
- const char *format;
int (*set)(struct param_d *p, void *priv);
int (*get)(struct param_d *p, void *priv);
};
int string_to_ethaddr(const char *str, u8 enetaddr[6]);
-void ethaddr_to_string(const u8 enetaddr[6], char *str);
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 device *dev, struct param_d *p,
+ const char *val)
{
struct param_mac *pm = to_param_mac(p);
char mac_save[6];
@@ -848,7 +876,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 device *dev, struct param_d *p)
{
struct param_mac *pm = to_param_mac(p);
int ret;
@@ -859,15 +887,15 @@ static const char *param_mac_get(struct device_d *dev, struct param_d *p)
return NULL;
}
- ethaddr_to_string(pm->mac, p->value);
+ sprintf(p->value, "%pM", pm->mac);
return p->value;
}
-struct param_d *dev_add_param_mac(struct device_d *dev, const char *name,
- int (*set)(struct param_d *p, void *priv),
- int (*get)(struct param_d *p, void *priv),
- u8 *mac, void *priv)
+struct param_d *dev_add_param_mac(struct device *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ u8 *mac, void *priv)
{
struct param_mac *pm;
int ret;
@@ -890,6 +918,93 @@ struct param_d *dev_add_param_mac(struct device_d *dev, const char *name,
return &pm->param;
}
+struct param_file_list {
+ struct param_d param;
+ struct file_list **file_list;
+ char *file_list_str;
+ int (*set)(struct param_d *p, void *priv);
+ int (*get)(struct param_d *p, void *priv);
+};
+
+static inline struct param_file_list *to_param_file_list(struct param_d *p)
+{
+ return container_of(p, struct param_file_list, param);
+}
+
+static int param_file_list_set(struct device *dev, struct param_d *p,
+ const char *val)
+{
+ struct param_file_list *pfl = to_param_file_list(p);
+ struct file_list *file_list_save = *pfl->file_list;
+ int ret;
+
+ if (!val)
+ val = "";
+
+ *pfl->file_list = file_list_parse(val);
+ if (IS_ERR(*pfl->file_list)) {
+ ret = PTR_ERR(*pfl->file_list);
+ goto out;
+ }
+
+ if (pfl->set) {
+ ret = pfl->set(p, p->driver_priv);
+ if (ret) {
+ file_list_free(*pfl->file_list);
+ goto out;
+ }
+ }
+
+ return 0;
+out:
+ *pfl->file_list = file_list_save;
+
+ return ret;
+}
+
+static const char *param_file_list_get(struct device *dev, struct param_d *p)
+{
+ struct param_file_list *pfl = to_param_file_list(p);
+ int ret;
+
+ if (pfl->get) {
+ ret = pfl->get(p, p->driver_priv);
+ if (ret)
+ return NULL;
+ }
+
+ free(p->value);
+ p->value = file_list_to_str(*pfl->file_list);
+ return p->value;
+}
+
+struct param_d *dev_add_param_file_list(struct device *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ struct file_list **file_list,
+ void *priv)
+{
+ struct param_file_list *pfl;
+ int ret;
+
+ pfl = xzalloc(sizeof(*pfl));
+ pfl->file_list = file_list;
+ pfl->set = set;
+ pfl->get = get;
+ pfl->param.driver_priv = priv;
+ pfl->param.type = PARAM_TYPE_FILE_LIST;
+
+ ret = __dev_add_param(&pfl->param, dev, name,
+ param_file_list_set, param_file_list_get, 0);
+ if (ret) {
+ free(pfl);
+ return ERR_PTR(ret);
+ }
+
+ return &pfl->param;
+}
+
+
/**
* dev_remove_param - remove a parameter from a device and free its
* memory
@@ -908,7 +1023,7 @@ void dev_remove_param(struct param_d *p)
* memory
* @param dev The device
*/
-void dev_remove_parameters(struct device_d *dev)
+void dev_remove_parameters(struct device *dev)
{
struct param_d *p, *n;