diff options
Diffstat (limited to 'net/batman-adv/bat_sysfs.c')
-rw-r--r-- | net/batman-adv/bat_sysfs.c | 102 |
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) | 31 | static 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 | |||
37 | static 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 | |||
47 | static char *uev_action_str[] = { | ||
48 | "add", | ||
49 | "del", | ||
50 | "change" | ||
51 | }; | ||
52 | |||
53 | static 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 | ||
97 | static int store_bool_attr(char *buff, size_t count, | 119 | static 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 | ||
149 | static int store_uint_attr(char *buff, size_t count, | 170 | static 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 | ||
186 | static inline ssize_t __store_uint_attr(char *buff, size_t count, | 207 | static 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, | |||
368 | static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, | 389 | static 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 |
371 | BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL); | 392 | BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 7, NULL); |
372 | #endif | 393 | #endif |
373 | 394 | ||
374 | static struct bat_attribute *mesh_attrs[] = { | 395 | static 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 | |||
619 | int 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); | ||
660 | out: | ||
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 | } | ||