diff options
Diffstat (limited to 'net/ieee802154/wpan-class.c')
| -rw-r--r-- | net/ieee802154/wpan-class.c | 75 | 
1 files changed, 68 insertions, 7 deletions
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c index f306604da67..268691256a6 100644 --- a/net/ieee802154/wpan-class.c +++ b/net/ieee802154/wpan-class.c @@ -22,6 +22,8 @@  #include <net/wpan-phy.h> +#include "ieee802154.h" +  #define MASTER_SHOW_COMPLEX(name, format_string, args...)		\  static ssize_t name ## _show(struct device *dev,			\  			    struct device_attribute *attr, char *buf)	\ @@ -30,7 +32,7 @@ static ssize_t name ## _show(struct device *dev,			\  	int ret;							\  									\  	mutex_lock(&phy->pib_lock);					\ -	ret = sprintf(buf, format_string "\n", args);			\ +	ret = snprintf(buf, PAGE_SIZE, format_string "\n", args);	\  	mutex_unlock(&phy->pib_lock);					\  	return ret;							\  } @@ -40,12 +42,30 @@ static ssize_t name ## _show(struct device *dev,			\  MASTER_SHOW(current_channel, "%d");  MASTER_SHOW(current_page, "%d"); -MASTER_SHOW(channels_supported, "%#x");  MASTER_SHOW_COMPLEX(transmit_power, "%d +- %d dB",  	((signed char) (phy->transmit_power << 2)) >> 2,  	(phy->transmit_power >> 6) ? (phy->transmit_power >> 6) * 3 : 1 );  MASTER_SHOW(cca_mode, "%d"); +static ssize_t channels_supported_show(struct device *dev, +			    struct device_attribute *attr, char *buf) +{ +	struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); +	int ret; +	int i, len = 0; + +	mutex_lock(&phy->pib_lock); +	for (i = 0; i < 32; i++) { +		ret = snprintf(buf + len, PAGE_SIZE - len, +				"%#09x\n", phy->channels_supported[i]); +		if (ret < 0) +			break; +		len += ret; +	} +	mutex_unlock(&phy->pib_lock); +	return len; +} +  static struct device_attribute pmib_attrs[] = {  	__ATTR_RO(current_channel),  	__ATTR_RO(current_page), @@ -91,6 +111,31 @@ struct wpan_phy *wpan_phy_find(const char *str)  }  EXPORT_SYMBOL(wpan_phy_find); +struct wpan_phy_iter_data { +	int (*fn)(struct wpan_phy *phy, void *data); +	void *data; +}; + +static int wpan_phy_iter(struct device *dev, void *_data) +{ +	struct wpan_phy_iter_data *wpid = _data; +	struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); +	return wpid->fn(phy, wpid->data); +} + +int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), +		void *data) +{ +	struct wpan_phy_iter_data wpid = { +		.fn = fn, +		.data = data, +	}; + +	return class_for_each_device(&wpan_phy_class, NULL, +			&wpid, wpan_phy_iter); +} +EXPORT_SYMBOL(wpan_phy_for_each); +  static int wpan_phy_idx_valid(int idx)  {  	return idx >= 0; @@ -118,14 +163,15 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size)  	phy->dev.class = &wpan_phy_class; +	phy->current_channel = -1; /* not initialised */ +	phy->current_page = 0; /* for compatibility */ +  	return phy;  }  EXPORT_SYMBOL(wpan_phy_alloc); -int wpan_phy_register(struct device *parent, struct wpan_phy *phy) +int wpan_phy_register(struct wpan_phy *phy)  { -	phy->dev.parent = parent; -  	return device_add(&phy->dev);  }  EXPORT_SYMBOL(wpan_phy_register); @@ -144,16 +190,31 @@ EXPORT_SYMBOL(wpan_phy_free);  static int __init wpan_phy_class_init(void)  { -	return class_register(&wpan_phy_class); +	int rc; +	rc = class_register(&wpan_phy_class); +	if (rc) +		goto err; + +	rc = ieee802154_nl_init(); +	if (rc) +		goto err_nl; + +	return 0; +err_nl: +	class_unregister(&wpan_phy_class); +err: +	return rc;  }  subsys_initcall(wpan_phy_class_init);  static void __exit wpan_phy_class_exit(void)  { +	ieee802154_nl_exit();  	class_unregister(&wpan_phy_class);  }  module_exit(wpan_phy_class_exit); -MODULE_DESCRIPTION("IEEE 802.15.4 device class");  MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("IEEE 802.15.4 configuration interface"); +MODULE_AUTHOR("Dmitry Eremin-Solenikov");  |