Re: [PATCH 11/15] rfkill: add notifier chains support

Previous thread: none

Next thread: [patch 01/18] m68k: Convert access_ok() to an inline function by Geert Uytterhoeven on Sunday, May 18, 2008 - 11:47 am. (1 message)
From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

This patch series contains what is ready so far of my rfkill rework
effort.

Much has been talked about it already, please refer to the thread started
by Message-Id: <1207946244-14525-1-git-send-email-hmh@hmh.eng.br>
(http://thread.gmane.org/gmane.linux.kernel/664500) if you don't understand
what brought this on.

In particular, anyone that still thinks drivers can use the input layer to
send rfkill state change messages around, or that rfkill class and
input-polldev work as a way to have read/write rfkill switches, go read
that thread... Fixing this is about half the reason why this patchset
exists (the other being that thinkpad-acpi needs it, and therefore I need
it as an user and also as a kernel developer).

This series is available as a git branch at:
git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git rfkill

The first two patches are just to sync the pending-merge queue of
thinkpad-acpi to avoid wasting my time with various versions of other
patches because of two patches that will hit mainline very soon.  Do not
pay too much attention to them.

The input layer patch is already approved by Dmitry, but he asked me to
merge it along with the rest of the stuff that needs it.

The full rfkill work is NOT complete.  The userspace interface is lacking a
way to read and write to the global rfkill switch states, in order to let
userspace do all that rfkill-input.c can do (i.e. something like the
private rfkill_switch_all and rfkill_epo).  I do have some patches that do
it, but I am not happy with them.  I will send them later, please comment
on this "supposedly to be ready for merging" patch set first.

As it stands, I'd like to know if the patches in this series are acceptable
to go upstream.  They do NOT break anything further in the kernel, but they
don't fix any drivers by themselves either (the drivers, like b43, need to
be fixed to use the rfkill class properly).

If you need a 2.6.23 (might also work on 2.6.24 and 2.6.25) backport of
this series, OR if you ...
From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

The less tested codepaths for LED handling, used on ThinkPads 570, 600e/x,
770e, 770x, A21e, A2xm/p, T20-22, X20 and maybe a few others, would write
data to kernel memory it had no business touching, for leds number 3 and
above.  If one is lucky, that illegal write would cause an OOPS, but
chances are it would silently corrupt a byte.

The problem was introduced in commit af116101, "ACPI: thinkpad-acpi: add
sysfs led class support to thinkpad leds (v3.2)".

Fix the bug by refactoring the entire code to be far more obvious on what
it wants to do.  Also do some defensive "constification".

Issue reported by Karol Lewandowski <lmctlx@gmail.com> (he's an lucky guy
and got an OOPS instead of silent corruption :-) ).

Root cause of the OOPS identified by Adrian Bunk <bunk@kernel.org>.
Thanks, Adrian!

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Tested-by: Karol Lewandowski <lmctlx@gmail.com>
Cc: Adrian Bunk <bunk@kernel.org>
---
 drivers/misc/thinkpad_acpi.c |   55 +++++++++++++++++++++--------------------
 1 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 3c53668..5a560d9 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -3853,7 +3853,7 @@ static const char const *tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
 	"tpacpi::standby",
 };
 
-static int led_get_status(unsigned int led)
+static int led_get_status(const unsigned int led)
 {
 	int status;
 	enum led_status_t led_s;
@@ -3877,41 +3877,42 @@ static int led_get_status(unsigned int led)
 	/* not reached */
 }
 
-static int led_set_status(unsigned int led, enum led_status_t ledstatus)
+static int led_set_status(const unsigned int led,
+			  const enum led_status_t ledstatus)
 {
 	/* off, on, blink. Index is led_status_t */
-	static const int const led_sled_arg1[] = { 0, 1, 3 };
-	static const int const led_exp_hlbl[] = { 0, 0, 1 };	/* led# * */
-	static const int const led_exp_hlcl[] = { 0, 1, ...
From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

The SW_RADIO code for EV_SW events has a name that is not descriptive
enough of its intended function, and could induce someone to think
KEY_RADIO is its EV_KEY counterpart, which is false.

Rename it to SW_RFKILL_ALL, and document what this event is for.  Keep
the old name around, to avoid userspace ABI breaks.

The SW_RFKILL_ALL event is meant to be used by rfkill master switches.  It
is not bound to a particular radio switch type, and usually applies to all
types.  It is semantically tied to master rfkill switches that enable or
disable every radio in a system.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
---
 Documentation/laptops/thinkpad-acpi.txt |    2 +-
 drivers/misc/thinkpad_acpi.c            |    4 ++--
 include/linux/input.h                   |    4 +++-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 01c6c3d..64b3f14 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -503,7 +503,7 @@ generate input device EV_KEY events.
 In addition to the EV_KEY events, thinkpad-acpi may also issue EV_SW
 events for switches:
 
-SW_RADIO	T60 and later hardare rfkill rocker switch
+SW_RFKILL_ALL	T60 and later hardare rfkill rocker switch
 SW_TABLET_MODE	Tablet ThinkPads HKEY events 0x5009 and 0x500A
 
 Non hot-key ACPI HKEY event map:
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 5a560d9..084a8f9 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1293,7 +1293,7 @@ static void tpacpi_input_send_radiosw(void)
 		mutex_lock(&tpacpi_inputdev_send_mutex);
 
 		input_report_switch(tpacpi_inputdev,
-				    SW_RADIO, !!wlsw);
+				    SW_RFKILL_ALL, !!wlsw);
 		input_sync(tpacpi_inputdev);
 
 		mutex_unlock(&tpacpi_inputdev_send_mutex);
@@ -2231,7 +2231,7 @@ static ...
From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

rfkill really should have been named rfswitch.  As it is, one can get
confused whether RFKILL_STATE_ON means the KILL switch is on (and
therefore, the radio is being *blocked* from operating), or whether it
means the RADIO rf output is on.

Clearly state that RFKILL_STATE_ON means the radio is *unblocked* from
operating (i.e. there is no rf killing going on).

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Cc: John W. Linville <linville@tuxdriver.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
---
 Documentation/rfkill.txt |    7 +++++++
 include/linux/rfkill.h   |    6 +++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt
index a83ff23..ec75d6d 100644
--- a/Documentation/rfkill.txt
+++ b/Documentation/rfkill.txt
@@ -8,6 +8,13 @@ rfkill - RF switch subsystem support
 ===============================================================================
 1: Implementation details
 
+The rfkill switch subsystem exists to add a generic interface to circuitry that
+can enable or disable the RF output of a radio *transmitter* of any type.
+
+When a rfkill switch is in the RFKILL_STATE_ON, the radio transmitter is
+*enabled*.  When the rfkill switch is in the RFKILL_STATE_OFF, the radio
+transmitter is *disabled*.
+
 The rfkill switch subsystem offers support for keys often found on laptops
 to enable wireless devices like WiFi and Bluetooth.
 
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index e3ab21d..ca89ae1 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -44,8 +44,8 @@ enum rfkill_type {
 };
 
 enum rfkill_state {
-	RFKILL_STATE_OFF	= 0,
-	RFKILL_STATE_ON		= 1,
+	RFKILL_STATE_OFF	= 0,	/* Radio output blocked */
+	RFKILL_STATE_ON		= 1,	/* Radio output active */
 };
 
 /**
@@ -53,7 +53,7 @@ enum rfkill_state {
  * @name: Name of the switch.
  * @type: Radio type which the button controls, the value stored
  *	here should ...
From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:08 am

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

Fix a minor typo in an exported function documentation

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Cc: John W. Linville <linville@tuxdriver.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
---
 net/rfkill/rfkill.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 4e10a95..f95081a 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -412,7 +412,7 @@ int rfkill_register(struct rfkill *rfkill)
 EXPORT_SYMBOL(rfkill_register);
 
 /**
- * rfkill_unregister - Uegister a rfkill structure.
+ * rfkill_unregister - Unregister a rfkill structure.
  * @rfkill: rfkill structure to be unregistered
  *
  * This function should be called by the network driver during device
-- 
1.5.5.1

--

From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:08 am

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

Rework some subdriver init and exit handlers, in order to fix some
initialization error paths that were missing, or broken.

Hitting those bugs should be extremely rare in the real world, but should
that happen, thinkpad-acpi would fail to dealocate some resources and a
reboot might well be needed to be able to load the driver again.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
 drivers/misc/thinkpad_acpi.c |  435 ++++++++++++++++++++++--------------------
 1 files changed, 229 insertions(+), 206 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 3f28f6e..3c53668 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1921,6 +1921,29 @@ static struct attribute *hotkey_mask_attributes[] __initdata = {
 	&dev_attr_hotkey_wakeup_hotunplug_complete.attr,
 };
 
+static void hotkey_exit(void)
+{
+#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
+	hotkey_poll_stop_sync();
+#endif
+
+	if (hotkey_dev_attributes)
+		delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
+
+	kfree(hotkey_keycode_map);
+
+	if (tp_features.hotkey) {
+		dbg_printk(TPACPI_DBG_EXIT,
+			   "restoring original hot key mask\n");
+		/* no short-circuit boolean operator below! */
+		if ((hotkey_mask_set(hotkey_orig_mask) |
+		     hotkey_status_set(hotkey_orig_status)) != 0)
+			printk(TPACPI_ERR
+			       "failed to restore hot key mask "
+			       "to BIOS defaults\n");
+	}
+}
+
 static int __init hotkey_init(struct ibm_init_struct *iibm)
 {
 	/* Requirements for changing the default keymaps:
@@ -2060,226 +2083,220 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 	vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
 		str_supported(tp_features.hotkey));
 
-	if (tp_features.hotkey) {
-		hotkey_dev_attributes = create_attr_set(13, NULL);
-		if (!hotkey_dev_attributes)
-			return -ENOMEM;
-		res = ...
From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

Teach rfkill-input how to handle SW_RFKILL_ALL events (new name for the
SW_RADIO event).

SW_RFKILL_ALL is an absolute enable-or-disable command that is tied to all
radios in a system.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
---
 net/rfkill/rfkill-input.c |   45 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index e4b051d..9d6c925 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -55,6 +55,22 @@ static void rfkill_task_handler(struct work_struct *work)
 	mutex_unlock(&task->mutex);
 }
 
+static void rfkill_schedule_set(struct rfkill_task *task,
+				enum rfkill_state desired_state)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&task->lock, flags);
+
+	if (time_after(jiffies, task->last + msecs_to_jiffies(200))) {
+		task->desired_state = desired_state;
+		task->last = jiffies;
+		schedule_work(&task->work);
+	}
+
+	spin_unlock_irqrestore(&task->lock, flags);
+}
+
 static void rfkill_schedule_toggle(struct rfkill_task *task)
 {
 	unsigned long flags;
@@ -87,9 +103,9 @@ static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
 static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
 
 static void rfkill_event(struct input_handle *handle, unsigned int type,
-			unsigned int code, int down)
+			unsigned int code, int data)
 {
-	if (type == EV_KEY && down == 1) {
+	if (type == EV_KEY && data == 1) {
 		switch (code) {
 		case KEY_WLAN:
 			rfkill_schedule_toggle(&rfkill_wlan);
@@ -106,6 +122,26 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
 		default:
 			break;
 		}
+	} else if (type == EV_SW) {
+		switch (code) {
+		case SW_RFKILL_ALL:
+			/* EVERY radio type. data != 0 means radios ON */
+			rfkill_schedule_set(&rfkill_wimax,
+					    (data)? RFKILL_STATE_ON:
+						    ...
From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:08 am

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

Currently, radios are always enabled when their rfkill interface is
registered.  This is not optimal, the safest state for a radio is to be
offline unless the user turns it on.

Add a module parameter that causes all radios to be disabled when their
rfkill interface is registered.  The module default is not changed so
unless the parameter is used, radios will still be forced to their enabled
state when they are registered.

The new rfkill module parameter is called "default_state".

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 net/rfkill/rfkill.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index f95081a..3edc585 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -39,6 +39,11 @@ MODULE_LICENSE("GPL");
 static LIST_HEAD(rfkill_list);	/* list of registered rf switches */
 static DEFINE_MUTEX(rfkill_mutex);
 
+static unsigned int rfkill_default_state = RFKILL_STATE_ON;
+module_param_named(default_state, rfkill_default_state, uint, 0444);
+MODULE_PARM_DESC(default_state,
+		 "Default initial state for all radio types, 0 = radio off");
+
 static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX];
 
 
@@ -436,8 +441,12 @@ static int __init rfkill_init(void)
 	int error;
 	int i;
 
+	if (rfkill_default_state != RFKILL_STATE_OFF &&
+	    rfkill_default_state != RFKILL_STATE_ON)
+		return -EINVAL;
+
 	for (i = 0; i < ARRAY_SIZE(rfkill_states); i++)
-		rfkill_states[i] = RFKILL_STATE_ON;
+		rfkill_states[i] = rfkill_default_state;
 
 	error = class_register(&rfkill_class);
 	if (error) {
-- 
1.5.5.1

--

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:48 am

We will need access to the rfkill switch type in string format for more
than just sysfs.  Therefore, move it to a generic helper.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
---
 net/rfkill/rfkill.c |   33 +++++++++++++++------------------
 1 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 251defe..4ed8d19 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -220,34 +220,31 @@ static ssize_t rfkill_name_show(struct device *dev,
 	return sprintf(buf, "%s\n", rfkill->name);
 }
 
-static ssize_t rfkill_type_show(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
+static const char const *rfkill_get_type_str(enum rfkill_type type)
 {
-	struct rfkill *rfkill = to_rfkill(dev);
-	const char *type;
-
-	switch (rfkill->type) {
+	switch (type) {
 	case RFKILL_TYPE_WLAN:
-		type = "wlan";
-		break;
+		return "wlan";
 	case RFKILL_TYPE_BLUETOOTH:
-		type = "bluetooth";
-		break;
+		return "bluetooth";
 	case RFKILL_TYPE_UWB:
-		type = "ultrawideband";
-		break;
+		return "ultrawideband";
 	case RFKILL_TYPE_WIMAX:
-		type = "wimax";
-		break;
+		return "wimax";
 	case RFKILL_TYPE_WWAN:
-		type = "wwan";
-		break;
+		return "wwan";
 	default:
 		BUG();
 	}
+}
+
+static ssize_t rfkill_type_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct rfkill *rfkill = to_rfkill(dev);
 
-	return sprintf(buf, "%s\n", type);
+	return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
 }
 
 static ssize_t rfkill_state_show(struct device *dev,
-- 
1.5.5.1

--

From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:09 am

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:48 am

Use the notification chains to also send uevents, so that userspace can be
notified of state changes of every rfkill switch.

Userspace should use these events for OSD/status report applications and
rfkill GUI frontends.  HAL might want to broadcast them over DBUS, for
example.  It might be also useful for userspace implementations of
rfkill-input, or to use HAL as the platform driver which promotes rfkill
switch change events into input events (to synchronize all other switches)
when necessary for platforms that lack a convenient platform-specific
kernel module to do it.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
---
 net/rfkill/rfkill.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 4ed8d19..ba25bde 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -382,12 +382,51 @@ static int rfkill_resume(struct device *dev)
 #define rfkill_resume NULL
 #endif
 
+static int rfkill_blocking_uevent_notifier(struct notifier_block *nb,
+					unsigned long eventid,
+					void *data)
+{
+	struct rfkill *rfkill = (struct rfkill *)data;
+
+	switch (eventid) {
+	case RFKILL_STATE_CHANGED:
+		kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block rfkill_blocking_uevent_nb = {
+	.notifier_call	= rfkill_blocking_uevent_notifier,
+	.priority	= 0,
+};
+
+static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	struct rfkill *rfkill = to_rfkill(dev);
+	int error;
+
+	error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);
+	if (error)
+		return error;
+	error = add_uevent_var(env, "RFKILL_TYPE=%s",
+				rfkill_get_type_str(rfkill->type));
+	if (error)
+		return error;
+	error = add_uevent_var(env, "RFKILL_STATE=%u", rfkill->state);
+	return ...
From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:09 am

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

Unfortunately, instead of adding a generic Wireless WAN type, a technology-
specific type (WiMAX) was added.  That's useless for other WWAN devices,
such as EDGE, UMTS, X-RTT and other such radios.

Add a WWAN rfkill type for generic wireless WAN devices.  No keys are added
as most devices really want to use KEY_WLAN for WWAN control (in a cycle of
none, WLAN, WWAN, WLAN+WWAN) and need no specific keycode added.

Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Cc: Iñaky Pérez-González <inaky.perez-gonzalez@intel.com>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Cc: John W. Linville <linville@tuxdriver.com>
Cc: David S. Miller <davem@davemloft.net>
---
 include/linux/rfkill.h    |    2 ++
 net/rfkill/rfkill-input.c |    4 ++++
 net/rfkill/rfkill.c       |    3 +++
 3 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 844e961..c0cab7d 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -34,12 +34,14 @@
  * RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
  * RFKILL_TYPE_UWB: switch is on a ultra wideband device.
  * RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
+ * RFKILL_TYPE_WWAN: switch is on a wireless WAN device.
  */
 enum rfkill_type {
 	RFKILL_TYPE_WLAN ,
 	RFKILL_TYPE_BLUETOOTH,
 	RFKILL_TYPE_UWB,
 	RFKILL_TYPE_WIMAX,
+	RFKILL_TYPE_WWAN,
 	RFKILL_TYPE_MAX,
 };
 
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index 9d6c925..29c13d3 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -101,6 +101,7 @@ static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN);
 static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH);
 static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
 static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
+static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN);
 
 static void rfkill_event(struct input_handle *handle, unsigned int type,
 			unsigned int code, int data)
@@ -126,6 +127,9 @@ ...
From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:08 am

If WiMAX is a subset of the WWAN technology, shouldn't we replace WiMAX completely
in rfkill? Otherwise people might get ideas and add the other technologies seperately as well. ;)

Other then that, the addition of WWAN is fine with me. :)



--

From: Henrique de Moraes Holschuh
Date: Tuesday, May 20, 2008 - 6:12 pm

Actually, I have no reason to believe there *isn't* a device with
KEY_WIMAX... but we need the WWAN type before we bother with a WiMax
type :-)

IMO, we should fix the issue by adding a "supertype", i.e., a class.
Use that for generic grouping, and let type be more specific when there
is a reason for it.  Repeat the class as the type to get a "generic"
type, when there is no reason to bother with more specific types.

Stuff like "WiMax", "802.1a", "EDGE", "GRPS", "802.1bg" would be the
type, and class would be "WLAN", "WWAN", etc.

We would only deal with classes on rfkill-input.  Anything else more
specific should be done in userspace instead, disabling rfkill-input.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Inaky Perez-Gonzalez
Date: Tuesday, May 20, 2008 - 8:35 pm

BTW, I just realized this was mistakenly put in your initial patch; 

How would this apply to the case where I want to use the HW key to switch
one off and turn the other one off (say I have both a WiMAX and EDGE
cards in my machine); how could we do it to distinguish which key is which?
I might be missing something.

-- 
Inaky
--

From: Henrique de Moraes Holschuh
Date: Tuesday, May 20, 2008 - 8:42 pm

I don't understand.  Switch one off and turn the other one off?  Isn't
that the same thing?

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Inaky Perez-Gonzalez
Date: Tuesday, May 20, 2008 - 11:48 pm

-EOPERATORISDUMB, sorry; I meant turn one off and the other on. 

-- 
Inaky
--

From: Henrique de Moraes Holschuh
Date: Wednesday, May 21, 2008 - 7:07 am

Then here's what you'd have with (class, type):

EITHER

1. rfkill-input would manipulate based on class for a given input event.
Therefore we would remove KEY_WIMAX from rfkill-input.

OR...

2. rfkill-input would be teached to manipulate for classes (all switches
in a class), and for (class,type) (hunt down all rfkill switches of that given
type and class)...   and it does mean KEY_WIMAX would only affect WiMAX
switches, while WWAN would affect EDGE, GPRS, *WIMAX*, etc.

And if you need anything different, you'd have to do it in userspace as
you want, and disable rfkill-input entirely, or for the switches you
want to override (using user_claim).

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:48 am

The resume handler should reset the wireless transmitter rfkill
state to exactly what it was when the system was suspended.  Do it,
and do it using the normal routines for state change while at it.

The suspend handler should force-switch the transmitter to blocked
state, ignoring caches.  Do it.

Also take an opportunity shot to rfkill_remove_switch() and also
force the transmitter to blocked state there, bypassing caches.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
---
 net/rfkill/rfkill.c |   35 ++++++++++++++++++-----------------
 1 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index c5a79ab..f11220b 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -75,24 +75,25 @@ static void update_rfkill_state(struct rfkill *rfkill)
 }
 
 static int rfkill_toggle_radio(struct rfkill *rfkill,
-				enum rfkill_state state)
+				enum rfkill_state state,
+				int force)
 {
 	int retval = 0;
 	enum rfkill_state oldstate, newstate;
 
 	oldstate = rfkill->state;
 
-	if (rfkill->get_state &&
+	if (rfkill->get_state && !force &&
 	    !rfkill->get_state(rfkill->data, &newstate))
 		rfkill->state = newstate;
 
-	if (state != rfkill->state) {
+	if (force || state != rfkill->state) {
 		retval = rfkill->toggle_radio(rfkill->data, state);
 		if (!retval)
 			rfkill->state = state;
 	}
 
-	if (rfkill->state != oldstate)
+	if (force || rfkill->state != oldstate)
 		rfkill_led_trigger(rfkill, rfkill->state);
 
 	return retval;
@@ -107,7 +108,6 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
  * a specific switch is claimed by userspace in which case it is
  * left alone.
  */
-
 void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
 {
 	struct rfkill *rfkill;
@@ -118,7 +118,7 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
 
 	list_for_each_entry(rfkill, &rfkill_list, node) {
 		if ...
From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:08 am

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:48 am

Add a notifier chain for use by the rfkill class.  This notifier chain
signals the following events (more to be added when needed):

  1. rfkill: rfkill device state has changed

A pointer to the rfkill struct will be passed as a parameter.

The notifier message types have been added to include/linux/rfkill.h
instead of to include/linux/notifier.h in order to avoid the madness of
modifying a header used globally (and that triggers an almost full tree
rebuild every time it is touched) with information that is of interest only
to code that includes the rfkill.h header.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
---
 include/linux/rfkill.h |    7 +++++
 net/rfkill/rfkill.c    |   70 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index c0cab7d..98667be 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -117,4 +117,11 @@ static inline char *rfkill_get_led_name(struct rfkill *rfkill)
 #endif
 }
 
+/* rfkill notification chain */
+#define RFKILL_STATE_CHANGED		0x0001	/* state of a normal rfkill
+						   switch has changed */
+
+int register_rfkill_notifier(struct notifier_block *nb);
+int unregister_rfkill_notifier(struct notifier_block *nb);
+
 #endif /* RFKILL_H */
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index f11220b..251defe 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -46,6 +46,49 @@ MODULE_PARM_DESC(default_state,
 
 static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX];
 
+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 ...
From: Thomas Renninger
Date: Monday, May 19, 2008 - 1:44 am

One must, one must...,         asynchronous
...

   Thomas



--

From: Henrique de Moraes Holschuh
Date: Monday, May 19, 2008 - 6:10 am

Will fix.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:09 am

Besides the spelling comments from Thomas, patch is fine with me. 



--

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:48 am

SW_RFKILL_ALL is the "emergency power-off all radios" input event.  It must
be handled, and must always do the same thing as far as the rfkill system
is concerned: all transmitters are to go *immediately* offline.

For safety, do NOT allow userspace to override EV_SW SW_RFKILL_ALL OFF.  As
long as rfkill-input is loaded, that event will *always* be processed, and
it will *always* force all rfkill switches to disable all wireless
transmitters, regardless of user_claim attribute or anything else.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
---
 net/rfkill/rfkill-input.c |   29 ++++++++++++++---------------
 net/rfkill/rfkill-input.h |    1 +
 net/rfkill/rfkill.c       |   18 ++++++++++++++++++
 3 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index 29c13d3..0fadeed 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -127,21 +127,20 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
 		switch (code) {
 		case SW_RFKILL_ALL:
 			/* EVERY radio type. data != 0 means radios ON */
-			rfkill_schedule_set(&rfkill_wwan,
-					    (data)? RFKILL_STATE_ON:
-						    RFKILL_STATE_OFF);
-			rfkill_schedule_set(&rfkill_wimax,
-					    (data)? RFKILL_STATE_ON:
-						    RFKILL_STATE_OFF);
-			rfkill_schedule_set(&rfkill_uwb,
-					    (data)? RFKILL_STATE_ON:
-						    RFKILL_STATE_OFF);
-			rfkill_schedule_set(&rfkill_bt,
-					    (data)? RFKILL_STATE_ON:
-						    RFKILL_STATE_OFF);
-			rfkill_schedule_set(&rfkill_wlan,
-					    (data)? RFKILL_STATE_ON:
-						    RFKILL_STATE_OFF);
+			/* handle EPO (emergency power off) through shortcut */
+			if (data) {
+				rfkill_schedule_set(&rfkill_wwan,
+						    RFKILL_STATE_ON);
+				rfkill_schedule_set(&rfkill_wimax,
+						    RFKILL_STATE_ON);
+				rfkill_schedule_set(&rfkill_uwb,
+						    ...
From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:09 am

I don't quite agree here. The SW_RFKILL_ALL key is the one send by thinkpad-acpi,
what makes that key so special that is has to be handled differently then a key
that only controls a single radio type?

All keys should have the same rules when it is pressed, so either all keys should


--

From: Henrique de Moraes Holschuh
Date: Thursday, May 22, 2008 - 1:51 pm

Well, first there is no KEY involved, it is a SWITCH :-)  But that's not
the reason it is special.

What makes SW_RFKILL_ALL special, is that it is the kernel view of *The*
RFKill Switch.  SW_RFKILL_ALL is the event you get when the user
manipulates the very *thing* that created the "rfkill switch" term.

You get that event when someone moves that slider switch in the side/top
of a laptop which has to kill all RF output in hardware as far as safety
regulations go.  Therefore, it refers to the only rfkill switch that has
guidelines that say that it must always work, and that it must not be
possible to override it in software.

Too bad that doesn't apply to "removable" radio transmitters, like
PCMCIA and ExpressCard WLAN cards, USB RF transmitters, and so on...
probably, the user is expected to yank them off when he moves the switch
to the "no radios working here!" position.  Well, we can do better.  We
can make it apply to these other radio transmitters, too.

So yes, it *is* special when it is doing its "power DOWN the
transmitters" function.  It is not special at all when it is in the
"allow radios to function if they want to" position, which is why I
special-cased only the "OFF" state.

IMHO, that makes it special enough to implement it in a different way
that is not subject to, e.g., brain damage in userspace.

As for thinkpad-acpi being the only in-tree code issuing that event so
far, well... I have seen laptops from many vendors with that switch, and
it is likely that the firmware of at least some of these laptops let you
know the state of the switch (like the thinkpad firmware does), so I'd
expect more users of SW_RFKILL_ALL to show up soon.  I am just paving
the way.

That, and as an user, I'd really like to be able to implement a
KEY_RFKILL_ALL keycode to use when I don't have a proper SW_RFKILL_ALL

IMO, "kill ALL radios" events are is the only kind of rfkill input event
that have to *always work*, even if something in userspace tried to
configure it not ...
From: Ivo van Doorn
Date: Friday, May 23, 2008 - 7:15 am

So do keys that are pressed that only send the KEY_WLAN, KEY_BLUETOOTH or
KEY_UWB signals. They all indicate the key has been pressed and the radios

That is a valid point, and rfkill is supposed to do that, but making
a difference between RFKILL_ALL and the individual types is wrong
because that won't result in a clearly defined expected behavior for all


Well the definition of "ALL radios" is the part that is the question, when the KEY_WLAN is
pressed it would be "ALL WLAN radios" and should still have the same rules for allowing
or disallowing userspace to overwrite the status.

Ivo
--

From: Henrique de Moraes Holschuh
Date: Tuesday, May 27, 2008 - 7:08 am

Indicate versus enforce.  There is a BIG difference there, and you can see it
even on how it was implemented by the laptop vendor.  The enforcing switch
has hardware behind it to make sure it works.  For the indication keys, you

IMO, the big difference between regular KEY_* and RFKILL_ALL is that
RFKILL_ALL has EPO (emergency power-off) semanthics, while the others don't.

KEY_WLAN is usually easily overriden in firmware and software, vendors often
don't even bother to implement it in firmware, it is just software.  RFKILL_ALL
switches cannot be overriden at all in any hardware worth its weight, and they
work even if the entire system has gone out for lunch and is deadlocked.
That's quite a big difference.

The only reason I don't usually call the hardware rfkill switches "radio EPO
switches" is because they are not big, red, and shaped like a mushroom.  But
they are in fact required to act like one in airline regulations, AFAIK.  And
that certainly matches the good implementations of the hardware rfkill switch
I know of (they wire-kill the radios, not even firmware gets in the way).

So yes, I do feel RFKILL_ALL is different, and it warrants EPO semanthics in
the kernel, while all other rfkill events, such as KEY_WLAN, don't.

I don't feel strongly about not giving EPO semanthics to other rfkill events,

More like through the new read-write/write-only rfkill class, since you have

Not really.  If you are concerned with a type, it is not an emergency situation,
nor is it a "you are entering a no-RF-emission area" situation.  There *IS* a
difference when a human decides to shut down EVERYTHING regardless of type, or
when he just wants the WLAN to stop wasting power but still wants Bluetooth up
so that he can listen to music on his wireless headphones.

And that notion carried over as the UI for circuit switches.  There IS a UI
notion behind "master switches", and it is very different from the notion behind
"sector switches".  And KEY_WLAN would just be a sector switch, with ...
From: Ivo van Doorn
Date: Tuesday, May 27, 2008 - 7:38 am

You just made my 2 laptops very happy because apparently they
don't behave like most keys do. ;)

Laptop 1)
	- Key to control WLAN (Broadcom)
	- Key to control Bluetooth (Broadcom??)
Laptop 2)
	- Key to control WLAN (Intel)

And each key really controls the hardware, without any software required.
Especially for Laptop one it will not be nice to attack RFKILL_ALL to both keys,

True, but the trick is that you don't know exactly when the radio is the emergency
key or not. Perhaps you do know with some hardware like thinkpad, but with my second
laptop for example, it only has 1 kind of radio and that is WLAN it also has 1 key.
When it is pressed, you simply don't know if it is switched off because of the
no-RF area or to powersave.

With my first laptop, the broadcom WLAN driver will register the key, but it doesn't know
if it is alone or if Bluetooth hardware is also present. So it cannot know if it is a master

Such a thing would indeed be nice, as long as you can positively identify a master switch,
but as long as that is not possible/implemented it will only be confusing for driver developers,
userspace developers and the users.

Ivo
--

From: Henrique de Moraes Holschuh
Date: Tuesday, May 27, 2008 - 10:41 am

You don't have a SW_RFKILL_ALL switch :-)   It is the same as my ThinkPad T43,
it does *NOT* have a SW_RFKILL_ALL switch, and it has a wireless config hotkey,
which is handled in firmware.  The firmware can wire-kill the Intel WLAN card,
and it can also unplug(!) the internal Bluetooth device from the internal USB
bus.

You'd typically assign KEY_WLAN or something else to those keys, but NOT a 
(fictitious) KEY_RFKILL_ALL.


Works just like a ThinkPad before you set its hotkey mask to request the firmware

Those keys definately are *NOT* to have *_RFKILL_ALL attached to them by default,

Then you assume it is just a normal key.  If the user wants to promote that
key to the Wireless EPO key, he changes the default assignment of KEY_WLAN to

Correct.

This is *explicitly* documented by the patches.  The broadcomm driver has to assume
it is a slave rfkill device, and NEVER report any input events.  It has no knowledge
of which platform the broadcomm chip was installed into, after all.  OTOH, it *will*
report the status change through the rfkill notify chain and also through the rfkill
uevents, and either a platform module for your laptop, or HAL (in userspace) can
trap those, and issue the relevant input events.

*IF* you get the events only through the broadcomm device, that is. If you get them

We document it *throughoutly*, and add a big fat warning about the misuse of
RFKILL_ALL.   It should be enough.   Will you consider ACKing a new version of
the patchset which documents better the *_RFKILL_ALL events?

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

--

From: Ivo van Doorn
Date: Tuesday, May 27, 2008 - 11:13 am

Ok, with some additional documentation it should be sufficient for now.
We can later see if minor adjustments need to be made based on userspace
implementation (which with he current rfkill implementation is still very limited).

Ivo
--

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:48 am

Rework the documentation so as to make sure driver writers understand
exactly where the boundaries are for input drivers related to rfkill
switches, buttons and keys, and rfkill class drivers.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
---
 Documentation/rfkill.txt |  329 ++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 277 insertions(+), 52 deletions(-)

diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt
index ec75d6d..bf8709c 100644
--- a/Documentation/rfkill.txt
+++ b/Documentation/rfkill.txt
@@ -2,82 +2,299 @@ rfkill - RF switch subsystem support
 ====================================
 
 1 Implementation details
-2 Driver support
-3 Userspace support
+2 Kernel driver guidelines
+3 Kernel API
+4 Userspace support
 
-===============================================================================
-1: Implementation details
+
+INTRODUCTION:
 
 The rfkill switch subsystem exists to add a generic interface to circuitry that
-can enable or disable the RF output of a radio *transmitter* of any type.
+can enable or disable the signal output of a wireless *transmitter* of any
+type.  By far, the most common use is to disable radio-frequency transmitters.
 
-When a rfkill switch is in the RFKILL_STATE_ON, the radio transmitter is
-*enabled*.  When the rfkill switch is in the RFKILL_STATE_OFF, the radio
-transmitter is *disabled*.
+The rfkill switch subsystem offers support for keys and switches often found on
+laptops to enable wireless devices like WiFi and Bluetooth to actually perform
+an action.
 
-The rfkill switch subsystem offers support for keys often found on laptops
-to enable wireless devices like WiFi and Bluetooth.
+The buttons to enable and disable the wireless transmitters are important in
+situations where the user is for example using his laptop on a location where
+radio-frequency transmitters _must_ be disabled (e.g. airplanes).
 ...
From: Randy Dunlap
Date: Monday, May 19, 2008 - 10:51 am

interaction











[snip]


OF AN RKFILL ?
i.e., does one say "R F KILL" or does one say "rifkill" or "rufkill" or


[snip]

---
~Randy
--

From: Henrique de Moraes Holschuh
Date: Monday, May 19, 2008 - 3:04 pm

Will do, for completeness if anything.


Yeah, I somehow lost part of that sentence while editing the file or

I have no idea :(   I'd read it as if I were spelling "R" "F", so I
think it should be an "AN".

Thanks for the corrections.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Elias Oltmanns
Date: Monday, May 19, 2008 - 3:52 pm

Wouldn't that be "changes" as welll?

Regards,

Elias
--

From: Randy Dunlap
Date: Monday, May 19, 2008 - 3:56 pm

Yes.  Thanks.

~Randy


--

From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:09 am

Wasn't it the plan to send the current hardware state as rfkill registration argument,
so we can force drivers to send a valid state to rfkill?

Ivo
--

From: Henrique de Moraes Holschuh
Date: Tuesday, May 20, 2008 - 8:54 am

Yes, but IMHO we should do that in a future patch.  That patch will touch
every rfkill driver, so I'd rather we do that later.  IMHO it is best to get
the most important stuff merged, first...

Then, in that future patch, we change the API, fix all in-tree drivers using
that API, and update the documentation to match the new API.  For now, we
update the documentation to match the current API.

What do you think?

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

--

From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 10:18 am

Sounds good to me. :)

Ivo
--

From: Henrique de Moraes Holschuh
Date: Tuesday, May 20, 2008 - 6:44 pm

I'll take that as an ACK :-)

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Henrique de Moraes Holschuh
Date: Wednesday, May 28, 2008 - 5:45 pm

Rework the documentation so as to make sure driver writers understand
exactly where the boundaries are for input drivers related to rfkill
switches, buttons and keys, and rfkill class drivers.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
---

Ivo,

This version better documents *_RFKILL_ALL.  Is it good enough for an
ACK for patch 14 of 15?

---
 Documentation/rfkill.txt |  358 +++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 305 insertions(+), 53 deletions(-)

diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt
index ec75d6d..4660208 100644
--- a/Documentation/rfkill.txt
+++ b/Documentation/rfkill.txt
@@ -1,83 +1,327 @@
 rfkill - RF switch subsystem support
 ====================================
 
-1 Implementation details
-2 Driver support
-3 Userspace support
+1 Introduction
+2 Implementation details
+3 Kernel driver guidelines
+4 Kernel API
+5 Userspace support
 
-===============================================================================
-1: Implementation details
+
+1. Introduction:
 
 The rfkill switch subsystem exists to add a generic interface to circuitry that
-can enable or disable the RF output of a radio *transmitter* of any type.
+can enable or disable the signal output of a wireless *transmitter* of any
+type.  By far, the most common use is to disable radio-frequency transmitters.
 
-When a rfkill switch is in the RFKILL_STATE_ON, the radio transmitter is
-*enabled*.  When the rfkill switch is in the RFKILL_STATE_OFF, the radio
-transmitter is *disabled*.
+The rfkill switch subsystem offers support for keys and switches often found on
+laptops to enable wireless devices like WiFi and Bluetooth to actually perform
+an action.
 
-The rfkill switch subsystem offers support for keys often found on laptops
-to enable wireless devices like WiFi and Bluetooth.
+The buttons to enable and disable the wireless transmitters ...
From: Ivo van Doorn
Date: Thursday, May 29, 2008 - 6:02 am

Yes, you can put my ack on patch 14.
Thanks for the documentation update. :)



--

From: Henrique de Moraes Holschuh
Date: Thursday, May 29, 2008 - 9:26 am

Then, this entire batch is ready for merging.  Now, if only Len would
come back from wherever he disappeared to, in order to merge the two
thinkpad-acpi patches, I could send it to netdev for merge.

I will at least publish the entire stack as a thinkpad-acpi pre-release
version, to get some testing on the real world with some power users.

I am thinking about how to best handle the global states.  Doing it
through the rfkill class is ready, but the result was *UGLY*.  More on
this later.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Ivo van Doorn
Date: Thursday, May 29, 2008 - 10:19 am

Actually,  I believe the correct merge order would through wireless-dev,

Ivo
--

From: Henrique de Moraes Holschuh
Date: Thursday, May 29, 2008 - 10:22 am

Noted.  At merge time (which will be as soon as the thinkpad-acpi
changes hit mainline), I will send them to you, John, and
linux-wireless.

Unless you want me to send them all right now to linux-wireless to see
if there are any comments?

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Ivo van Doorn
Date: Thursday, May 29, 2008 - 10:40 am

Well why wait with merging it into wireless-dev until thinkpad-acpi is merged?
I don't think there are real dependencies other then the SW_RFKILL_ALL define.
Perhaps you could send the rfkill patches with SW_RADIO instead of SW_RFKILL_ALL
and make the rename after the thinkpad and rfkill series have both been merged.
That would probably be the fastest route for this patch series.

Ivo
--

From: Henrique de Moraes Holschuh
Date: Thursday, May 29, 2008 - 10:46 am

Yeah, but it would be bad for the documentation, and SW_RADIO was
renamed because it was an error-inducer, so I *really* don't want to
attract any more eyes to rfkill WITHOUT getting that error-inducing
define renamed first.

OTOH, I don't want the clashes thinkpad-acpi init changes to cause a
mess for whomever is going to merge rfkill, as even if I submit them
now, the rfkill changes are next- material, while the thinkpad-acpi
changes are merge-them-ASAP material.

I will talk to Andrew Morton and see if he accepts to push the two
thinkpad-acpi changes to Linus ASAP.  Or maybe we will luck out and Len
will show up in 72h, I think he is bound to come back really soon now.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Dmitry Torokhov
Date: Thursday, May 29, 2008 - 11:58 am

I wonder why thinkpad_acpi has to go through Len, it seems to live
in drivers/misc... Does it depend on some other ACPI changes that
are not in mainline/-mm yet? If it not I'd probably bombard Andrew
with it.

Alternatively SW_RFKILL_ALL can be brought in through wireless three
or I can add it to my "for_linus" branch that I want Linus to pull
soon.

-- 
Dmitry
--

From: Henrique de Moraes Holschuh
Date: Thursday, May 29, 2008 - 2:16 pm

No, the patches in question don't depend on anything at all other than
thinkpad-acpi itself.  If there were no thinkpad-acpi patches "in
flight" in need to get to mainline soon, there would be no problem at
all... but at least one of them clashes with the SW_RFKILL_ALL patch.

thinkpad-acpi merges through Len Brown because that's probably the best
subsystem for it to be tied to right now.  It uses various other
subsystems, like the input layer, hwmon, LEDs and rfkill, but it makes
extremely heavy use of the ACPI subsystem to actually *do* something.

But patches to thinkpad-acpi do not HAVE to always go through Len, as

I would be thankful if you could merge the input layer SW_RFKILL_ALL
patch ASAP through your for_linus branch, as that's probably the fastest
way to get the whole rfkill stack in its way to the linux-next tree.

The SW_RFKILL_ALL patch is the only real dependency of the rfkill
patches on anything.  If that gets merged now, I can immediately send
the rfkill stack to wireless-dev AND respin the two thinkpad-acpi
patches that are pending on Len's hands to apply without issues on top
of a tree that already had SW_RADIO renamed.

I will send the SW_RFKILL_ALL patch in a version that applies on top of
Linus git tree to you in a few moments.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Henrique de Moraes Holschuh
Date: Thursday, May 29, 2008 - 2:25 pm

The SW_RADIO code for EV_SW events has a name that is not descriptive
enough of its intended function, and could induce someone to think
KEY_RADIO is its EV_KEY counterpart, which is false.

Rename it to SW_RFKILL_ALL, and document what this event is for.  Keep
the old name around, to avoid userspace ABI breaks.

The SW_RFKILL_ALL event is meant to be used by rfkill master switches.  It
is not bound to a particular radio switch type, and usually applies to all
types.  It is semantically tied to master rfkill switches that enable or
disable every radio in a system.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
---
 Documentation/laptops/thinkpad-acpi.txt |    2 +-
 drivers/misc/thinkpad_acpi.c            |    4 ++--
 include/linux/input.h                   |    4 +++-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 01c6c3d..64b3f14 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -503,7 +503,7 @@ generate input device EV_KEY events.
 In addition to the EV_KEY events, thinkpad-acpi may also issue EV_SW
 events for switches:
 
-SW_RADIO	T60 and later hardare rfkill rocker switch
+SW_RFKILL_ALL	T60 and later hardare rfkill rocker switch
 SW_TABLET_MODE	Tablet ThinkPads HKEY events 0x5009 and 0x500A
 
 Non hot-key ACPI HKEY event map:
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 3f28f6e..a111148 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1293,7 +1293,7 @@ static void tpacpi_input_send_radiosw(void)
 		mutex_lock(&tpacpi_inputdev_send_mutex);
 
 		input_report_switch(tpacpi_inputdev,
-				    SW_RADIO, !!wlsw);
+				    SW_RFKILL_ALL, !!wlsw);
 		input_sync(tpacpi_inputdev);
 
 		mutex_unlock(&tpacpi_inputdev_send_mutex);
@@ -2199,7 +2199,7 @@ static ...
From: Henrique de Moraes Holschuh
Date: Tuesday, June 3, 2008 - 8:11 pm

I have just done this.  The patchset (with a minor fix to address an
issue sparse found) has been sent to linux-wireless and John Linville
for merging.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--

From: Henrique de Moraes Holschuh
Date: Sunday, May 18, 2008 - 11:47 am

Currently, rfkill support for read/write rfkill switches is hacked through
a round-trip over the input layer and rfkill-input to let a driver sync
rfkill->state to hardware changes.

This is buggy and sub-optimal.  It causes real problems.  It is best to
think of the rfkill class as supporting only write-only switches at the
moment.

In order to implement the read/write functionality properly:

Add a get_state() hook that is called by the class every time it needs to
fetch the current state of the switch.  Add a call to this hook every time
the *current* state of the radio plays a role in a decision.

Also add a force_state() method that can be used to forcefully syncronize
the class' idea of the current state of the switch.  This allows for a
faster implementation of the read/write functionality, as a driver which
get events on switch changes can avoid the need for a get_state() hook.

If the get_state() hook is left as NULL, current behaviour is maintained,
so this change is fully backwards compatible with the current rfkill
drivers.

For hardware that issues events when the rfkill state changes, leave
get_state() NULL in the rfkill struct, set the initial state properly
before registering with the rfkill class, and use the force_state() method
in the driver to keep the rfkill interface up-to-date.

get_state() can be called by the class from atomic context. It must not
sleep.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
---
 include/linux/rfkill.h |    5 ++++
 net/rfkill/rfkill.c    |   49 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index ca89ae1..844e961 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -61,6 +61,8 @@ enum rfkill_state {
  * @data: Pointer to the RF button drivers private data which will be
  *	passed along when toggling ...
From: Ivo van Doorn
Date: Tuesday, May 20, 2008 - 3:08 am

Previous thread: none

Next thread: [patch 01/18] m68k: Convert access_ok() to an inline function by Geert Uytterhoeven on Sunday, May 18, 2008 - 11:47 am. (1 message)