aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/bat_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/bat_sysfs.c')
-rw-r--r--net/batman-adv/bat_sysfs.c102
1 files changed, 90 insertions, 12 deletions
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c
index 497a0700cc3c..cd15deba60a1 100644
--- a/net/batman-adv/bat_sysfs.c
+++ b/net/batman-adv/bat_sysfs.c
@@ -28,9 +28,31 @@
28#include "gateway_client.h" 28#include "gateway_client.h"
29#include "vis.h" 29#include "vis.h"
30 30
31#define to_dev(obj) container_of(obj, struct device, kobj) 31static struct net_device *kobj_to_netdev(struct kobject *obj)
32#define kobj_to_netdev(obj) to_net_dev(to_dev(obj->parent)) 32{
33#define kobj_to_batpriv(obj) netdev_priv(kobj_to_netdev(obj)) 33 struct device *dev = container_of(obj->parent, struct device, kobj);
34 return to_net_dev(dev);
35}
36
37static struct bat_priv *kobj_to_batpriv(struct kobject *obj)
38{
39 struct net_device *net_dev = kobj_to_netdev(obj);
40 return netdev_priv(net_dev);
41}
42
43#define UEV_TYPE_VAR "BATTYPE="
44#define UEV_ACTION_VAR "BATACTION="
45#define UEV_DATA_VAR "BATDATA="
46
47static char *uev_action_str[] = {
48 "add",
49 "del",
50 "change"
51};
52
53static char *uev_type_str[] = {
54 "gw"
55};
34 56
35/* Use this, if you have customized show and store functions */ 57/* Use this, if you have customized show and store functions */
36#define BAT_ATTR(_name, _mode, _show, _store) \ 58#define BAT_ATTR(_name, _mode, _show, _store) \
@@ -96,7 +118,7 @@ ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \
96 118
97static int store_bool_attr(char *buff, size_t count, 119static int store_bool_attr(char *buff, size_t count,
98 struct net_device *net_dev, 120 struct net_device *net_dev,
99 char *attr_name, atomic_t *attr) 121 const char *attr_name, atomic_t *attr)
100{ 122{
101 int enabled = -1; 123 int enabled = -1;
102 124
@@ -138,16 +160,15 @@ static inline ssize_t __store_bool_attr(char *buff, size_t count,
138{ 160{
139 int ret; 161 int ret;
140 162
141 ret = store_bool_attr(buff, count, net_dev, (char *)attr->name, 163 ret = store_bool_attr(buff, count, net_dev, attr->name, attr_store);
142 attr_store);
143 if (post_func && ret) 164 if (post_func && ret)
144 post_func(net_dev); 165 post_func(net_dev);
145 166
146 return ret; 167 return ret;
147} 168}
148 169
149static int store_uint_attr(char *buff, size_t count, 170static int store_uint_attr(const char *buff, size_t count,
150 struct net_device *net_dev, char *attr_name, 171 struct net_device *net_dev, const char *attr_name,
151 unsigned int min, unsigned int max, atomic_t *attr) 172 unsigned int min, unsigned int max, atomic_t *attr)
152{ 173{
153 unsigned long uint_val; 174 unsigned long uint_val;
@@ -183,15 +204,15 @@ static int store_uint_attr(char *buff, size_t count,
183 return count; 204 return count;
184} 205}
185 206
186static inline ssize_t __store_uint_attr(char *buff, size_t count, 207static inline ssize_t __store_uint_attr(const char *buff, size_t count,
187 int min, int max, 208 int min, int max,
188 void (*post_func)(struct net_device *), 209 void (*post_func)(struct net_device *),
189 struct attribute *attr, 210 const struct attribute *attr,
190 atomic_t *attr_store, struct net_device *net_dev) 211 atomic_t *attr_store, struct net_device *net_dev)
191{ 212{
192 int ret; 213 int ret;
193 214
194 ret = store_uint_attr(buff, count, net_dev, (char *)attr->name, 215 ret = store_uint_attr(buff, count, net_dev, attr->name,
195 min, max, attr_store); 216 min, max, attr_store);
196 if (post_func && ret) 217 if (post_func && ret)
197 post_func(net_dev); 218 post_func(net_dev);
@@ -368,7 +389,7 @@ BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
368static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, 389static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth,
369 store_gw_bwidth); 390 store_gw_bwidth);
370#ifdef CONFIG_BATMAN_ADV_DEBUG 391#ifdef CONFIG_BATMAN_ADV_DEBUG
371BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL); 392BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 7, NULL);
372#endif 393#endif
373 394
374static struct bat_attribute *mesh_attrs[] = { 395static struct bat_attribute *mesh_attrs[] = {
@@ -594,3 +615,60 @@ void sysfs_del_hardif(struct kobject **hardif_obj)
594 kobject_put(*hardif_obj); 615 kobject_put(*hardif_obj);
595 *hardif_obj = NULL; 616 *hardif_obj = NULL;
596} 617}
618
619int throw_uevent(struct bat_priv *bat_priv, enum uev_type type,
620 enum uev_action action, const char *data)
621{
622 int ret = -1;
623 struct hard_iface *primary_if = NULL;
624 struct kobject *bat_kobj;
625 char *uevent_env[4] = { NULL, NULL, NULL, NULL };
626
627 primary_if = primary_if_get_selected(bat_priv);
628 if (!primary_if)
629 goto out;
630
631 bat_kobj = &primary_if->soft_iface->dev.kobj;
632
633 uevent_env[0] = kmalloc(strlen(UEV_TYPE_VAR) +
634 strlen(uev_type_str[type]) + 1,
635 GFP_ATOMIC);
636 if (!uevent_env[0])
637 goto out;
638
639 sprintf(uevent_env[0], "%s%s", UEV_TYPE_VAR, uev_type_str[type]);
640
641 uevent_env[1] = kmalloc(strlen(UEV_ACTION_VAR) +
642 strlen(uev_action_str[action]) + 1,
643 GFP_ATOMIC);
644 if (!uevent_env[1])
645 goto out;
646
647 sprintf(uevent_env[1], "%s%s", UEV_ACTION_VAR, uev_action_str[action]);
648
649 /* If the event is DEL, ignore the data field */
650 if (action != UEV_DEL) {
651 uevent_env[2] = kmalloc(strlen(UEV_DATA_VAR) +
652 strlen(data) + 1, GFP_ATOMIC);
653 if (!uevent_env[2])
654 goto out;
655
656 sprintf(uevent_env[2], "%s%s", UEV_DATA_VAR, data);
657 }
658
659 ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env);
660out:
661 kfree(uevent_env[0]);
662 kfree(uevent_env[1]);
663 kfree(uevent_env[2]);
664
665 if (primary_if)
666 hardif_free_ref(primary_if);
667
668 if (ret)
669 bat_dbg(DBG_BATMAN, bat_priv, "Impossible to send "
670 "uevent for (%s,%s,%s) event (err: %d)\n",
671 uev_type_str[type], uev_action_str[action],
672 (action == UEV_DEL ? "NULL" : data), ret);
673 return ret;
674}