9p: VFS switches for 9p2000.L: protocol and client changes
[safe/jmp/linux-2.6] / net / wimax / stack.c
index a0ee76b..ee99e7d 100644 (file)
@@ -51,6 +51,7 @@
  *   wimax_rfkill_rm()
  */
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <net/genetlink.h>
 #include <linux/netdevice.h>
 #include <linux/wimax.h>
 #define D_SUBMODULE stack
 #include "debug-levels.h"
 
+static char wimax_debug_params[128];
+module_param_string(debug, wimax_debug_params, sizeof(wimax_debug_params),
+                   0644);
+MODULE_PARM_DESC(debug,
+                "String of space-separated NAME:VALUE pairs, where NAMEs "
+                "are the different debug submodules and VALUE are the "
+                "initial debug value to set.");
+
 /*
  * Authoritative source for the RE_STATE_CHANGE attribute policy
  *
@@ -67,8 +76,7 @@
  * close to where the data is generated.
  */
 /*
-static const
-struct nla_policy wimax_gnl_re_status_change[WIMAX_GNL_ATTR_MAX + 1] = {
+static const struct nla_policy wimax_gnl_re_status_change[WIMAX_GNL_ATTR_MAX + 1] = {
        [WIMAX_GNL_STCH_STATE_OLD] = { .type = NLA_U8 },
        [WIMAX_GNL_STCH_STATE_NEW] = { .type = NLA_U8 },
 };
@@ -307,12 +315,11 @@ void __wimax_state_change(struct wimax_dev *wimax_dev, enum wimax_st new_state)
                BUG();
        }
        __wimax_state_set(wimax_dev, new_state);
-       if (stch_skb)
+       if (!IS_ERR(stch_skb))
                wimax_gnl_re_state_change_send(wimax_dev, stch_skb, header);
 out:
        d_fnend(3, dev, "(wimax_dev %p new_state %u [old %u]) = void\n",
                wimax_dev, new_state, old_state);
-       return;
 }
 
 
@@ -338,10 +345,22 @@ out:
  */
 void wimax_state_change(struct wimax_dev *wimax_dev, enum wimax_st new_state)
 {
+       /*
+        * A driver cannot take the wimax_dev out of the
+        * __WIMAX_ST_NULL state unless by calling wimax_dev_add(). If
+        * the wimax_dev's state is still NULL, we ignore any request
+        * to change its state because it means it hasn't been yet
+        * registered.
+        *
+        * There is no need to complain about it, as routines that
+        * call this might be shared from different code paths that
+        * are called before or after wimax_dev_add() has done its
+        * job.
+        */
        mutex_lock(&wimax_dev->mutex);
-       __wimax_state_change(wimax_dev, new_state);
+       if (wimax_dev->state > __WIMAX_ST_NULL)
+               __wimax_state_change(wimax_dev, new_state);
        mutex_unlock(&wimax_dev->mutex);
-       return;
 }
 EXPORT_SYMBOL_GPL(wimax_state_change);
 
@@ -376,7 +395,7 @@ EXPORT_SYMBOL_GPL(wimax_state_get);
 void wimax_dev_init(struct wimax_dev *wimax_dev)
 {
        INIT_LIST_HEAD(&wimax_dev->id_table_node);
-       __wimax_state_set(wimax_dev, WIMAX_ST_UNINITIALIZED);
+       __wimax_state_set(wimax_dev, __WIMAX_ST_NULL);
        mutex_init(&wimax_dev->mutex);
        mutex_init(&wimax_dev->mutex_reset);
 }
@@ -389,13 +408,15 @@ EXPORT_SYMBOL_GPL(wimax_dev_init);
 extern struct genl_ops
        wimax_gnl_msg_from_user,
        wimax_gnl_reset,
-       wimax_gnl_rfkill;
+       wimax_gnl_rfkill,
+       wimax_gnl_state_get;
 
 static
 struct genl_ops *wimax_gnl_ops[] = {
        &wimax_gnl_msg_from_user,
        &wimax_gnl_reset,
        &wimax_gnl_rfkill,
+       &wimax_gnl_state_get,
 };
 
 
@@ -520,6 +541,7 @@ struct d_level D_LEVEL[] = {
        D_SUBMODULE_DEFINE(op_msg),
        D_SUBMODULE_DEFINE(op_reset),
        D_SUBMODULE_DEFINE(op_rfkill),
+       D_SUBMODULE_DEFINE(op_state_get),
        D_SUBMODULE_DEFINE(stack),
 };
 size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
@@ -546,6 +568,9 @@ int __init wimax_subsys_init(void)
        int result, cnt;
 
        d_fnstart(4, NULL, "()\n");
+       d_parse_params(D_LEVEL, D_LEVEL_SIZE, wimax_debug_params,
+                      "wimax.debug");
+
        snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name),
                 "WiMAX");
        result = genl_register_family(&wimax_gnl_family);