Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux-2.6-block.git] / net / ieee802154 / wpan-class.c
index f306604da67a747e792ffa318915530e97a5d45b..268691256a6d2b915caeb7a951cce97aed98ecdf 100644 (file)
@@ -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");