aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2008-07-08 07:52:49 -0700
committerLuis R. Rodriguez <lrodriguez@atheros.com>2008-07-08 07:52:49 -0700
commit176301dfb9aa527c030a0fb08b7bc373f91f4d0d (patch)
tree6d4850210c33d75370156a5ee62b50e87ab8b9da
parent66f3fb0fbcfe53d7ba503f3b02afb4ee17a1a569 (diff)
downloadcompat-wireless-2.6-old-176301dfb9aa527c030a0fb08b7bc373f91f4d0d.tar.gz
Add backport of new rkill work, note that old kernels rkill code
won't call notify_rfkill_state_change() so we may want to just replace rfkill code with compat-wireless to get it to work just as well. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
-rw-r--r--compat/compat.c92
-rw-r--r--compat/compat.h6
2 files changed, 98 insertions, 0 deletions
diff --git a/compat/compat.c b/compat/compat.c
index 88ad830..44cca2f 100644
--- a/compat/compat.c
+++ b/compat/compat.c
@@ -640,6 +640,98 @@ int pci_try_set_mwi(struct pci_dev *dev)
EXPORT_SYMBOL(pci_try_set_mwi);
#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
+
+/* rfkill notification chain */
+#define RFKILL_STATE_CHANGED 0x0001 /* state of a normal rfkill
+ switch has changed */
+
+static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
+
+/**
+ * register_rfkill_notifier - Add notifier to rfkill notifier chain
+ * @nb: pointer to the new entry to add to the chain
+ *
+ * See blocking_notifier_chain_register() for return value and further
+ * observations.
+ *
+ * Adds a notifier to the rfkill notifier chain. The chain will be
+ * called with a pointer to the relevant rfkill structure as a parameter,
+ * refer to include/linux/rfkill.h for the possible events.
+ *
+ * Notifiers added to this chain are to always return NOTIFY_DONE. This
+ * chain is a blocking notifier chain: notifiers can sleep.
+ *
+ * Calls to this chain may have been done through a workqueue. One must
+ * assume unordered asynchronous behaviour, there is no way to know if
+ * actions related to the event that generated the notification have been
+ * carried out already.
+ */
+int register_rfkill_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&rfkill_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_rfkill_notifier);
+
+/**
+ * unregister_rfkill_notifier - remove notifier from rfkill notifier chain
+ * @nb: pointer to the entry to remove from the chain
+ *
+ * See blocking_notifier_chain_unregister() for return value and further
+ * observations.
+ *
+ * Removes a notifier from the rfkill notifier chain.
+ */
+int unregister_rfkill_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_rfkill_notifier);
+
+
+static void notify_rfkill_state_change(struct rfkill *rfkill)
+{
+ blocking_notifier_call_chain(&rfkill_notifier_list,
+ RFKILL_STATE_CHANGED,
+ rfkill);
+}
+
+/**
+ * rfkill_force_state - Force the internal rfkill radio state
+ * @rfkill: pointer to the rfkill class to modify.
+ * @state: the current radio state the class should be forced to.
+ *
+ * This function updates the internal state of the radio cached
+ * by the rfkill class. It should be used when the driver gets
+ * a notification by the firmware/hardware of the current *real*
+ * state of the radio rfkill switch.
+ *
+ * It may not be called from an atomic context.
+ */
+int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
+{
+ enum rfkill_state oldstate;
+
+ if (state != RFKILL_STATE_SOFT_BLOCKED &&
+ state != RFKILL_STATE_UNBLOCKED &&
+ state != RFKILL_STATE_HARD_BLOCKED)
+ return -EINVAL;
+
+ mutex_lock(&rfkill->mutex);
+
+ oldstate = rfkill->state;
+ rfkill->state = state;
+
+ if (state != oldstate)
+ notify_rfkill_state_change(rfkill);
+
+ mutex_unlock(&rfkill->mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(rfkill_force_state);
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) */
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) */
diff --git a/compat/compat.h b/compat/compat.h
index 14f9ef7..212c461 100644
--- a/compat/compat.h
+++ b/compat/compat.h
@@ -29,6 +29,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/uaccess.h>
+#include <linux/rfkill.h>
#include <net/arp.h>
#include <net/neighbour.h>
@@ -731,6 +732,11 @@ static inline const char *dev_name(struct device *dev)
/* This one is new */
#define RFKILL_STATE_HARD_BLOCKED 2
+int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state);
+
+int register_rfkill_notifier(struct notifier_block *nb);
+int unregister_rfkill_notifier(struct notifier_block *nb);
+
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) */
#endif /* LINUX_26_COMPAT_H */