linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] rfkill class rework
@ 2008-05-18 18:47 Henrique de Moraes Holschuh
  2008-05-18 18:47 ` [PATCH 01/15] ACPI: thinkpad-acpi: fix initialization error paths Henrique de Moraes Holschuh
                   ` (14 more replies)
  0 siblings, 15 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ivo van Doorn, Thomas Renninger


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 want to play with a modified thinkpad-acpi that uses
these rfkill changes, please look at:
git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git devel

Comments are appreciated.  The sooner this set of rfkill changes can begin
the merge process, the better.  I'd *really* like to see them merged in
mainline during the 2.6.27 merge window (so that I can do the same with the
rfkill support in thinkpad-acpi).

-- 
  "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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 01/15] ACPI: thinkpad-acpi: fix initialization error paths
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
@ 2008-05-18 18:47 ` Henrique de Moraes Holschuh
  2008-05-18 18:47 ` [PATCH 02/15] ACPI: thinkpad-acpi: fix LED handling on older ThinkPads Henrique de Moraes Holschuh
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh

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 = add_many_to_attr_set(hotkey_dev_attributes,
-				hotkey_attributes,
-				ARRAY_SIZE(hotkey_attributes));
-		if (res)
-			return res;
+	if (!tp_features.hotkey)
+		return 1;
 
-		/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
-		   A30, R30, R31, T20-22, X20-21, X22-24.  Detected by checking
-		   for HKEY interface version 0x100 */
-		if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
-			if ((hkeyv >> 8) != 1) {
-				printk(TPACPI_ERR "unknown version of the "
-				       "HKEY interface: 0x%x\n", hkeyv);
-				printk(TPACPI_ERR "please report this to %s\n",
-				       TPACPI_MAIL);
-			} else {
-				/*
-				 * MHKV 0x100 in A31, R40, R40e,
-				 * T4x, X31, and later
-				 */
-				tp_features.hotkey_mask = 1;
-			}
+	hotkey_dev_attributes = create_attr_set(13, NULL);
+	if (!hotkey_dev_attributes)
+		return -ENOMEM;
+	res = add_many_to_attr_set(hotkey_dev_attributes,
+			hotkey_attributes,
+			ARRAY_SIZE(hotkey_attributes));
+	if (res)
+		goto err_exit;
+
+	/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
+	   A30, R30, R31, T20-22, X20-21, X22-24.  Detected by checking
+	   for HKEY interface version 0x100 */
+	if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
+		if ((hkeyv >> 8) != 1) {
+			printk(TPACPI_ERR "unknown version of the "
+			       "HKEY interface: 0x%x\n", hkeyv);
+			printk(TPACPI_ERR "please report this to %s\n",
+			       TPACPI_MAIL);
+		} else {
+			/*
+			 * MHKV 0x100 in A31, R40, R40e,
+			 * T4x, X31, and later
+			 */
+			tp_features.hotkey_mask = 1;
 		}
+	}
 
-		vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
-			str_supported(tp_features.hotkey_mask));
+	vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
+		str_supported(tp_features.hotkey_mask));
 
-		if (tp_features.hotkey_mask) {
-			if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
-					"MHKA", "qd")) {
-				printk(TPACPI_ERR
-				       "missing MHKA handler, "
-				       "please report this to %s\n",
-				       TPACPI_MAIL);
-				/* FN+F12, FN+F4, FN+F3 */
-				hotkey_all_mask = 0x080cU;
-			}
+	if (tp_features.hotkey_mask) {
+		if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
+				"MHKA", "qd")) {
+			printk(TPACPI_ERR
+			       "missing MHKA handler, "
+			       "please report this to %s\n",
+			       TPACPI_MAIL);
+			/* FN+F12, FN+F4, FN+F3 */
+			hotkey_all_mask = 0x080cU;
 		}
+	}
 
-		/* hotkey_source_mask *must* be zero for
-		 * the first hotkey_mask_get */
-		res = hotkey_status_get(&hotkey_orig_status);
-		if (!res && tp_features.hotkey_mask) {
-			res = hotkey_mask_get();
-			hotkey_orig_mask = hotkey_mask;
-			if (!res) {
-				res = add_many_to_attr_set(
-					hotkey_dev_attributes,
-					hotkey_mask_attributes,
-					ARRAY_SIZE(hotkey_mask_attributes));
-			}
-		}
+	/* hotkey_source_mask *must* be zero for
+	 * the first hotkey_mask_get */
+	res = hotkey_status_get(&hotkey_orig_status);
+	if (res)
+		goto err_exit;
+
+	if (tp_features.hotkey_mask) {
+		res = hotkey_mask_get();
+		if (res)
+			goto err_exit;
+
+		hotkey_orig_mask = hotkey_mask;
+		res = add_many_to_attr_set(
+				hotkey_dev_attributes,
+				hotkey_mask_attributes,
+				ARRAY_SIZE(hotkey_mask_attributes));
+		if (res)
+			goto err_exit;
+	}
 
 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
-		if (tp_features.hotkey_mask) {
-			hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
-						& ~hotkey_all_mask;
-		} else {
-			hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
-		}
+	if (tp_features.hotkey_mask) {
+		hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
+					& ~hotkey_all_mask;
+	} else {
+		hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
+	}
 
-		vdbg_printk(TPACPI_DBG_INIT,
-			    "hotkey source mask 0x%08x, polling freq %d\n",
-			    hotkey_source_mask, hotkey_poll_freq);
+	vdbg_printk(TPACPI_DBG_INIT,
+		    "hotkey source mask 0x%08x, polling freq %d\n",
+		    hotkey_source_mask, hotkey_poll_freq);
 #endif
 
-		/* Not all thinkpads have a hardware radio switch */
-		if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
-			tp_features.hotkey_wlsw = 1;
-			printk(TPACPI_INFO
-				"radio switch found; radios are %s\n",
-				enabled(status, 0));
-			res = add_to_attr_set(hotkey_dev_attributes,
-					&dev_attr_hotkey_radio_sw.attr);
-		}
+	/* Not all thinkpads have a hardware radio switch */
+	if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
+		tp_features.hotkey_wlsw = 1;
+		printk(TPACPI_INFO
+			"radio switch found; radios are %s\n",
+			enabled(status, 0));
+		res = add_to_attr_set(hotkey_dev_attributes,
+				&dev_attr_hotkey_radio_sw.attr);
+	}
 
-		/* For X41t, X60t, X61t Tablets... */
-		if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
-			tp_features.hotkey_tablet = 1;
-			printk(TPACPI_INFO
-				"possible tablet mode switch found; "
-				"ThinkPad in %s mode\n",
-				(status & TP_HOTKEY_TABLET_MASK)?
-					"tablet" : "laptop");
-			res = add_to_attr_set(hotkey_dev_attributes,
-					&dev_attr_hotkey_tablet_mode.attr);
-		}
+	/* For X41t, X60t, X61t Tablets... */
+	if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
+		tp_features.hotkey_tablet = 1;
+		printk(TPACPI_INFO
+			"possible tablet mode switch found; "
+			"ThinkPad in %s mode\n",
+			(status & TP_HOTKEY_TABLET_MASK)?
+				"tablet" : "laptop");
+		res = add_to_attr_set(hotkey_dev_attributes,
+				&dev_attr_hotkey_tablet_mode.attr);
+	}
 
-		if (!res)
-			res = register_attr_set_with_sysfs(
-					hotkey_dev_attributes,
-					&tpacpi_pdev->dev.kobj);
-		if (res)
-			return res;
+	if (!res)
+		res = register_attr_set_with_sysfs(
+				hotkey_dev_attributes,
+				&tpacpi_pdev->dev.kobj);
+	if (res)
+		goto err_exit;
 
-		/* Set up key map */
+	/* Set up key map */
 
-		hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
-						GFP_KERNEL);
-		if (!hotkey_keycode_map) {
-			printk(TPACPI_ERR
-				"failed to allocate memory for key map\n");
-			return -ENOMEM;
-		}
+	hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
+					GFP_KERNEL);
+	if (!hotkey_keycode_map) {
+		printk(TPACPI_ERR
+			"failed to allocate memory for key map\n");
+		res = -ENOMEM;
+		goto err_exit;
+	}
 
-		if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
-			dbg_printk(TPACPI_DBG_INIT,
-				   "using Lenovo default hot key map\n");
-			memcpy(hotkey_keycode_map, &lenovo_keycode_map,
-				TPACPI_HOTKEY_MAP_SIZE);
+	if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
+		dbg_printk(TPACPI_DBG_INIT,
+			   "using Lenovo default hot key map\n");
+		memcpy(hotkey_keycode_map, &lenovo_keycode_map,
+			TPACPI_HOTKEY_MAP_SIZE);
+	} else {
+		dbg_printk(TPACPI_DBG_INIT,
+			   "using IBM default hot key map\n");
+		memcpy(hotkey_keycode_map, &ibm_keycode_map,
+			TPACPI_HOTKEY_MAP_SIZE);
+	}
+
+	set_bit(EV_KEY, tpacpi_inputdev->evbit);
+	set_bit(EV_MSC, tpacpi_inputdev->evbit);
+	set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
+	tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
+	tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
+	tpacpi_inputdev->keycode = hotkey_keycode_map;
+	for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
+		if (hotkey_keycode_map[i] != KEY_RESERVED) {
+			set_bit(hotkey_keycode_map[i],
+				tpacpi_inputdev->keybit);
 		} else {
-			dbg_printk(TPACPI_DBG_INIT,
-				   "using IBM default hot key map\n");
-			memcpy(hotkey_keycode_map, &ibm_keycode_map,
-				TPACPI_HOTKEY_MAP_SIZE);
-		}
-
-		set_bit(EV_KEY, tpacpi_inputdev->evbit);
-		set_bit(EV_MSC, tpacpi_inputdev->evbit);
-		set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
-		tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
-		tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
-		tpacpi_inputdev->keycode = hotkey_keycode_map;
-		for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
-			if (hotkey_keycode_map[i] != KEY_RESERVED) {
-				set_bit(hotkey_keycode_map[i],
-					tpacpi_inputdev->keybit);
-			} else {
-				if (i < sizeof(hotkey_reserved_mask)*8)
-					hotkey_reserved_mask |= 1 << i;
-			}
-		}
-
-		if (tp_features.hotkey_wlsw) {
-			set_bit(EV_SW, tpacpi_inputdev->evbit);
-			set_bit(SW_RADIO, tpacpi_inputdev->swbit);
-		}
-		if (tp_features.hotkey_tablet) {
-			set_bit(EV_SW, tpacpi_inputdev->evbit);
-			set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit);
+			if (i < sizeof(hotkey_reserved_mask)*8)
+				hotkey_reserved_mask |= 1 << i;
 		}
+	}
 
-		/* Do not issue duplicate brightness change events to
-		 * userspace */
-		if (!tp_features.bright_acpimode)
-			/* update bright_acpimode... */
-			tpacpi_check_std_acpi_brightness_support();
-
-		if (tp_features.bright_acpimode) {
-			printk(TPACPI_INFO
-			       "This ThinkPad has standard ACPI backlight "
-			       "brightness control, supported by the ACPI "
-			       "video driver\n");
-			printk(TPACPI_NOTICE
-			       "Disabling thinkpad-acpi brightness events "
-			       "by default...\n");
-
-			/* The hotkey_reserved_mask change below is not
-			 * necessary while the keys are at KEY_RESERVED in the
-			 * default map, but better safe than sorry, leave it
-			 * here as a marker of what we have to do, especially
-			 * when we finally become able to set this at runtime
-			 * on response to X.org requests */
-			hotkey_reserved_mask |=
-				(1 << TP_ACPI_HOTKEYSCAN_FNHOME)
-				| (1 << TP_ACPI_HOTKEYSCAN_FNEND);
-		}
+	if (tp_features.hotkey_wlsw) {
+		set_bit(EV_SW, tpacpi_inputdev->evbit);
+		set_bit(SW_RADIO, tpacpi_inputdev->swbit);
+	}
+	if (tp_features.hotkey_tablet) {
+		set_bit(EV_SW, tpacpi_inputdev->evbit);
+		set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit);
+	}
 
-		dbg_printk(TPACPI_DBG_INIT,
-				"enabling hot key handling\n");
-		res = hotkey_status_set(1);
-		if (res)
-			return res;
-		res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask)
-					& ~hotkey_reserved_mask)
-					| hotkey_orig_mask);
-		if (res < 0 && res != -ENXIO)
-			return res;
+	/* Do not issue duplicate brightness change events to
+	 * userspace */
+	if (!tp_features.bright_acpimode)
+		/* update bright_acpimode... */
+		tpacpi_check_std_acpi_brightness_support();
 
-		dbg_printk(TPACPI_DBG_INIT,
-				"legacy hot key reporting over procfs %s\n",
-				(hotkey_report_mode < 2) ?
-					"enabled" : "disabled");
+	if (tp_features.bright_acpimode) {
+		printk(TPACPI_INFO
+		       "This ThinkPad has standard ACPI backlight "
+		       "brightness control, supported by the ACPI "
+		       "video driver\n");
+		printk(TPACPI_NOTICE
+		       "Disabling thinkpad-acpi brightness events "
+		       "by default...\n");
+
+		/* The hotkey_reserved_mask change below is not
+		 * necessary while the keys are at KEY_RESERVED in the
+		 * default map, but better safe than sorry, leave it
+		 * here as a marker of what we have to do, especially
+		 * when we finally become able to set this at runtime
+		 * on response to X.org requests */
+		hotkey_reserved_mask |=
+			(1 << TP_ACPI_HOTKEYSCAN_FNHOME)
+			| (1 << TP_ACPI_HOTKEYSCAN_FNEND);
+	}
+
+	dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n");
+	res = hotkey_status_set(1);
+	if (res) {
+		hotkey_exit();
+		return res;
+	}
+	res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask)
+				& ~hotkey_reserved_mask)
+				| hotkey_orig_mask);
+	if (res < 0 && res != -ENXIO) {
+		hotkey_exit();
+		return res;
+	}
 
-		tpacpi_inputdev->open = &hotkey_inputdev_open;
-		tpacpi_inputdev->close = &hotkey_inputdev_close;
+	dbg_printk(TPACPI_DBG_INIT,
+			"legacy hot key reporting over procfs %s\n",
+			(hotkey_report_mode < 2) ?
+				"enabled" : "disabled");
 
-		hotkey_poll_setup_safe(1);
-		tpacpi_input_send_radiosw();
-		tpacpi_input_send_tabletsw();
-	}
+	tpacpi_inputdev->open = &hotkey_inputdev_open;
+	tpacpi_inputdev->close = &hotkey_inputdev_close;
 
-	return (tp_features.hotkey)? 0 : 1;
-}
+	hotkey_poll_setup_safe(1);
+	tpacpi_input_send_radiosw();
+	tpacpi_input_send_tabletsw();
 
-static void hotkey_exit(void)
-{
-#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
-	hotkey_poll_stop_sync();
-#endif
+	return 0;
 
-	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");
-	}
+err_exit:
+	delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
+	hotkey_dev_attributes = NULL;
 
-	if (hotkey_dev_attributes) {
-		delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
-		hotkey_dev_attributes = NULL;
-	}
+	return (res < 0)? res : 1;
 }
 
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
@@ -3319,7 +3336,7 @@ static struct tpacpi_led_classdev tpacpi_led_thinklight = {
 
 static int __init light_init(struct ibm_init_struct *iibm)
 {
-	int rc = 0;
+	int rc;
 
 	vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
 
@@ -3337,20 +3354,23 @@ static int __init light_init(struct ibm_init_struct *iibm)
 		tp_features.light_status =
 			acpi_evalf(ec_handle, NULL, "KBLT", "qv");
 
-	vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
-		str_supported(tp_features.light));
+	vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n",
+		str_supported(tp_features.light),
+		str_supported(tp_features.light_status));
 
-	if (tp_features.light) {
-		rc = led_classdev_register(&tpacpi_pdev->dev,
-					   &tpacpi_led_thinklight.led_classdev);
-	}
+	if (!tp_features.light)
+		return 1;
+
+	rc = led_classdev_register(&tpacpi_pdev->dev,
+				   &tpacpi_led_thinklight.led_classdev);
 
 	if (rc < 0) {
 		tp_features.light = 0;
 		tp_features.light_status = 0;
-	} else {
-		rc = (tp_features.light)? 0 : 1;
+	} else  {
+		rc = 0;
 	}
+
 	return rc;
 }
 
@@ -3978,7 +3998,6 @@ static void led_exit(void)
 	}
 
 	kfree(tpacpi_leds);
-	tpacpi_leds = NULL;
 }
 
 static int __init led_init(struct ibm_init_struct *iibm)
@@ -4802,7 +4821,6 @@ static void brightness_exit(void)
 		vdbg_printk(TPACPI_DBG_EXIT,
 			    "calling backlight_device_unregister()\n");
 		backlight_device_unregister(ibm_backlight_device);
-		ibm_backlight_device = NULL;
 	}
 }
 
@@ -5764,11 +5782,16 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 	    fan_control_access_mode != TPACPI_FAN_WR_NONE) {
 		rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
 					 &fan_attr_group);
-		if (!(rc < 0))
-			rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
-					&driver_attr_fan_watchdog);
 		if (rc < 0)
 			return rc;
+
+		rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
+					&driver_attr_fan_watchdog);
+		if (rc < 0) {
+			sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
+					&fan_attr_group);
+			return rc;
+		}
 		return 0;
 	} else
 		return 1;
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 02/15] ACPI: thinkpad-acpi: fix LED handling on older ThinkPads
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
  2008-05-18 18:47 ` [PATCH 01/15] ACPI: thinkpad-acpi: fix initialization error paths Henrique de Moraes Holschuh
@ 2008-05-18 18:47 ` Henrique de Moraes Holschuh
  2008-05-18 18:47 ` [PATCH 03/15] Input: rename SW_RADIO to SW_RFKILL_ALL (v2) Henrique de Moraes Holschuh
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh,
	Adrian Bunk

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, 1 };	/* led# * */
-	static const int const led_led_arg1[] = { 0, 0x80, 0xc0 };
+	static const unsigned int const led_sled_arg1[] = { 0, 1, 3 };
+	static const unsigned int const led_led_arg1[] = { 0, 0x80, 0xc0 };
 
 	int rc = 0;
 
 	switch (led_supported) {
 	case TPACPI_LED_570:
-			/* 570 */
-			led = 1 << led;
-			if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
-					led, led_sled_arg1[ledstatus]))
-				rc = -EIO;
-			break;
+		/* 570 */
+		if (led > 7)
+			return -EINVAL;
+		if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
+				(1 << led), led_sled_arg1[ledstatus]))
+			rc = -EIO;
+		break;
 	case TPACPI_LED_OLD:
-			/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
-			led = 1 << led;
-			rc = ec_write(TPACPI_LED_EC_HLMS, led);
-			if (rc >= 0)
-				rc = ec_write(TPACPI_LED_EC_HLBL,
-					      led * led_exp_hlbl[ledstatus]);
-			if (rc >= 0)
-				rc = ec_write(TPACPI_LED_EC_HLCL,
-					      led * led_exp_hlcl[ledstatus]);
-			break;
+		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
+		if (led > 7)
+			return -EINVAL;
+		rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
+		if (rc >= 0)
+			rc = ec_write(TPACPI_LED_EC_HLBL,
+				      (ledstatus == TPACPI_LED_BLINK) << led);
+		if (rc >= 0)
+			rc = ec_write(TPACPI_LED_EC_HLCL,
+				      (ledstatus != TPACPI_LED_OFF) << led);
+		break;
 	case TPACPI_LED_NEW:
-			/* all others */
-			if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
-					led, led_led_arg1[ledstatus]))
-				rc = -EIO;
-			break;
+		/* all others */
+		if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
+				led, led_led_arg1[ledstatus]))
+			rc = -EIO;
+		break;
 	default:
 		rc = -ENXIO;
 	}
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 03/15] Input: rename SW_RADIO to SW_RFKILL_ALL (v2)
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
  2008-05-18 18:47 ` [PATCH 01/15] ACPI: thinkpad-acpi: fix initialization error paths Henrique de Moraes Holschuh
  2008-05-18 18:47 ` [PATCH 02/15] ACPI: thinkpad-acpi: fix LED handling on older ThinkPads Henrique de Moraes Holschuh
@ 2008-05-18 18:47 ` Henrique de Moraes Holschuh
  2008-05-18 18:47 ` [PATCH 04/15] rfkill: clarify meaning of rfkill states Henrique de Moraes Holschuh
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh

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 int __init hotkey_init(struct ibm_init_struct *iibm)
 
 	if (tp_features.hotkey_wlsw) {
 		set_bit(EV_SW, tpacpi_inputdev->evbit);
-		set_bit(SW_RADIO, tpacpi_inputdev->swbit);
+		set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit);
 	}
 	if (tp_features.hotkey_tablet) {
 		set_bit(EV_SW, tpacpi_inputdev->evbit);
diff --git a/include/linux/input.h b/include/linux/input.h
index 28a094f..e075c4b 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -637,7 +637,9 @@ struct input_absinfo {
 #define SW_LID			0x00  /* set = lid shut */
 #define SW_TABLET_MODE		0x01  /* set = tablet mode */
 #define SW_HEADPHONE_INSERT	0x02  /* set = inserted */
-#define SW_RADIO		0x03  /* set = radio enabled */
+#define SW_RFKILL_ALL		0x03  /* rfkill master switch, type "any"
+					 set = radio enabled */
+#define SW_RADIO		SW_RFKILL_ALL	/* deprecated */
 #define SW_MAX			0x0f
 #define SW_CNT			(SW_MAX+1)
 
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 04/15] rfkill: clarify meaning of rfkill states
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (2 preceding siblings ...)
  2008-05-18 18:47 ` [PATCH 03/15] Input: rename SW_RADIO to SW_RFKILL_ALL (v2) Henrique de Moraes Holschuh
@ 2008-05-18 18:47 ` Henrique de Moraes Holschuh
  2008-05-20 10:08   ` Ivo van Doorn
  2008-05-18 18:47 ` [PATCH 05/15] rfkill: fix minor typo in kernel doc Henrique de Moraes Holschuh
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh,
	John W. Linville, Dmitry Torokhov

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 be a value from enum rfkill_type.
- * @state: State of the switch (on/off).
+ * @state: State of the switch, "ON" means radio can operate.
  * @user_claim_unsupported: Whether the hardware supports exclusive
  *	RF-kill control by userspace. Set this before registering.
  * @user_claim: Set when the switch is controlled exlusively by userspace.
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 05/15] rfkill: fix minor typo in kernel doc
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (3 preceding siblings ...)
  2008-05-18 18:47 ` [PATCH 04/15] rfkill: clarify meaning of rfkill states Henrique de Moraes Holschuh
@ 2008-05-18 18:47 ` Henrique de Moraes Holschuh
  2008-05-20 10:08   ` Ivo van Doorn
  2008-05-18 18:47 ` [PATCH 06/15] rfkill: handle SW_RFKILL_ALL events Henrique de Moraes Holschuh
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh,
	John W. Linville, Dmitry Torokhov

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


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 06/15] rfkill: handle SW_RFKILL_ALL events
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (4 preceding siblings ...)
  2008-05-18 18:47 ` [PATCH 05/15] rfkill: fix minor typo in kernel doc Henrique de Moraes Holschuh
@ 2008-05-18 18:47 ` Henrique de Moraes Holschuh
  2008-05-20 10:08   ` Ivo van Doorn
  2008-05-18 18:47 ` [PATCH 07/15] rfkill: add parameter to disable radios by default Henrique de Moraes Holschuh
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh,
	Dmitry Torokhov

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:
+						    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);
+			break;
+		default:
+			break;
+		}
 	}
 }
 
@@ -168,6 +204,11 @@ static const struct input_device_id rfkill_ids[] = {
 		.evbit = { BIT_MASK(EV_KEY) },
 		.keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
 	},
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
+		.evbit = { BIT(EV_SW) },
+		.swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
+	},
 	{ }
 };
 
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 07/15] rfkill: add parameter to disable radios by default
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (5 preceding siblings ...)
  2008-05-18 18:47 ` [PATCH 06/15] rfkill: handle SW_RFKILL_ALL events Henrique de Moraes Holschuh
@ 2008-05-18 18:47 ` Henrique de Moraes Holschuh
  2008-05-18 18:47 ` [PATCH 08/15] rfkill: add read-write rfkill switch support Henrique de Moraes Holschuh
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh

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


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 08/15] rfkill: add read-write rfkill switch support
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (6 preceding siblings ...)
  2008-05-18 18:47 ` [PATCH 07/15] rfkill: add parameter to disable radios by default Henrique de Moraes Holschuh
@ 2008-05-18 18:47 ` Henrique de Moraes Holschuh
  2008-05-20 10:08   ` Ivo van Doorn
  2008-05-18 18:47 ` [PATCH 09/15] rfkill: add the WWAN radio type Henrique de Moraes Holschuh
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh,
	Dmitry Torokhov

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 radio state.
  * @toggle_radio(): Mandatory handler to control state of the radio.
+ * @get_state(): handler to read current radio state from hardware,
+ *      may be called from atomic context, should return 0 on success.
  * @led_trigger: A LED trigger for this button's LED.
  * @dev: Device structure integrating the switch into device tree.
  * @node: Used to place switch into list of all switches known to the
@@ -80,6 +82,7 @@ struct rfkill {
 
 	void *data;
 	int (*toggle_radio)(void *data, enum rfkill_state state);
+	int (*get_state)(void *data, enum rfkill_state *state);
 
 #ifdef CONFIG_RFKILL_LEDS
 	struct led_trigger led_trigger;
@@ -95,6 +98,8 @@ void rfkill_free(struct rfkill *rfkill);
 int rfkill_register(struct rfkill *rfkill);
 void rfkill_unregister(struct rfkill *rfkill);
 
+int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state);
+
 /**
  * rfkill_get_led_name - Get the LED trigger name for the button's LED.
  * This function might return a NULL pointer if registering of the
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 3edc585..2e19b68 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -62,19 +62,39 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
 #endif /* CONFIG_RFKILL_LEDS */
 }
 
+static void update_rfkill_state(struct rfkill *rfkill)
+{
+	enum rfkill_state newstate;
+
+	if (rfkill->get_state) {
+		mutex_lock(&rfkill->mutex);
+		if (!rfkill->get_state(rfkill->data, &newstate))
+			rfkill->state = newstate;
+		mutex_unlock(&rfkill->mutex);
+	}
+}
+
 static int rfkill_toggle_radio(struct rfkill *rfkill,
 				enum rfkill_state state)
 {
 	int retval = 0;
+	enum rfkill_state oldstate, newstate;
+
+	oldstate = rfkill->state;
+
+	if (rfkill->get_state &&
+	    !rfkill->get_state(rfkill->data, &newstate))
+		rfkill->state = newstate;
 
 	if (state != rfkill->state) {
 		retval = rfkill->toggle_radio(rfkill->data, state);
-		if (!retval) {
+		if (!retval)
 			rfkill->state = state;
-			rfkill_led_trigger(rfkill, state);
-		}
 	}
 
+	if (rfkill->state != oldstate)
+		rfkill_led_trigger(rfkill, rfkill->state);
+
 	return retval;
 }
 
@@ -105,6 +125,28 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
 }
 EXPORT_SYMBOL(rfkill_switch_all);
 
+/**
+ * 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)
+{
+	mutex_lock(&rfkill->mutex);
+	rfkill->state = state;
+	mutex_unlock(&rfkill->mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(rfkill_force_state);
+
 static ssize_t rfkill_name_show(struct device *dev,
 				struct device_attribute *attr,
 				char *buf)
@@ -147,6 +189,7 @@ static ssize_t rfkill_state_show(struct device *dev,
 {
 	struct rfkill *rfkill = to_rfkill(dev);
 
+	update_rfkill_state(rfkill);
 	return sprintf(buf, "%d\n", rfkill->state);
 }
 
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 09/15] rfkill: add the WWAN radio type
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (7 preceding siblings ...)
  2008-05-18 18:47 ` [PATCH 08/15] rfkill: add read-write rfkill switch support Henrique de Moraes Holschuh
@ 2008-05-18 18:47 ` Henrique de Moraes Holschuh
  2008-05-20 10:08   ` Ivo van Doorn
  2008-05-18 18:48 ` [PATCH 10/15] rfkill: rework suspend and resume handlers Henrique de Moraes Holschuh
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:47 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh,
	Inaky Perez-Gonzalez, Iñaky Pérez-González,
	John W. Linville, David S. Miller

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 @@ 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);
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 2e19b68..c5a79ab 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -176,6 +176,9 @@ static ssize_t rfkill_type_show(struct device *dev,
 	case RFKILL_TYPE_WIMAX:
 		type = "wimax";
 		break;
+	case RFKILL_TYPE_WWAN:
+		type = "wwan";
+		break;
 	default:
 		BUG();
 	}
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 10/15] rfkill: rework suspend and resume handlers
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (8 preceding siblings ...)
  2008-05-18 18:47 ` [PATCH 09/15] rfkill: add the WWAN radio type Henrique de Moraes Holschuh
@ 2008-05-18 18:48 ` Henrique de Moraes Holschuh
  2008-05-20 10:08   ` Ivo van Doorn
  2008-05-18 18:48 ` [PATCH 11/15] rfkill: add notifier chains support Henrique de Moraes Holschuh
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:48 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh

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 ((!rfkill->user_claim) && (rfkill->type == type))
-			rfkill_toggle_radio(rfkill, state);
+			rfkill_toggle_radio(rfkill, state, 0);
 	}
 
 	mutex_unlock(&rfkill_mutex);
@@ -210,7 +210,8 @@ static ssize_t rfkill_state_store(struct device *dev,
 	if (mutex_lock_interruptible(&rfkill->mutex))
 		return -ERESTARTSYS;
 	error = rfkill_toggle_radio(rfkill,
-			state ? RFKILL_STATE_ON : RFKILL_STATE_OFF);
+			state ? RFKILL_STATE_ON : RFKILL_STATE_OFF,
+			0);
 	mutex_unlock(&rfkill->mutex);
 
 	return error ? error : count;
@@ -251,7 +252,8 @@ static ssize_t rfkill_claim_store(struct device *dev,
 	if (rfkill->user_claim != claim) {
 		if (!claim)
 			rfkill_toggle_radio(rfkill,
-					    rfkill_states[rfkill->type]);
+					    rfkill_states[rfkill->type],
+					    0);
 		rfkill->user_claim = claim;
 	}
 
@@ -284,12 +286,11 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
 
 	if (dev->power.power_state.event != state.event) {
 		if (state.event & PM_EVENT_SLEEP) {
-			mutex_lock(&rfkill->mutex);
-
-			if (rfkill->state == RFKILL_STATE_ON)
-				rfkill->toggle_radio(rfkill->data,
-						     RFKILL_STATE_OFF);
+			/* Stop transmitter, keep state, no notifies */
+			update_rfkill_state(rfkill);
 
+			mutex_lock(&rfkill->mutex);
+			rfkill->toggle_radio(rfkill->data, RFKILL_STATE_OFF);
 			mutex_unlock(&rfkill->mutex);
 		}
 
@@ -306,8 +307,8 @@ static int rfkill_resume(struct device *dev)
 	if (dev->power.power_state.event != PM_EVENT_ON) {
 		mutex_lock(&rfkill->mutex);
 
-		if (rfkill->state == RFKILL_STATE_ON)
-			rfkill->toggle_radio(rfkill->data, RFKILL_STATE_ON);
+		/* restore radio state AND notify everybody */
+		rfkill_toggle_radio(rfkill, rfkill->state, 1);
 
 		mutex_unlock(&rfkill->mutex);
 	}
@@ -334,7 +335,7 @@ static int rfkill_add_switch(struct rfkill *rfkill)
 
 	mutex_lock(&rfkill_mutex);
 
-	error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]);
+	error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0);
 	if (!error)
 		list_add_tail(&rfkill->node, &rfkill_list);
 
@@ -347,7 +348,7 @@ static void rfkill_remove_switch(struct rfkill *rfkill)
 {
 	mutex_lock(&rfkill_mutex);
 	list_del_init(&rfkill->node);
-	rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF);
+	rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF, 1);
 	mutex_unlock(&rfkill_mutex);
 }
 
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 11/15] rfkill: add notifier chains support
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (9 preceding siblings ...)
  2008-05-18 18:48 ` [PATCH 10/15] rfkill: rework suspend and resume handlers Henrique de Moraes Holschuh
@ 2008-05-18 18:48 ` Henrique de Moraes Holschuh
  2008-05-19  8:44   ` Thomas Renninger
  2008-05-20 10:09   ` Ivo van Doorn
  2008-05-18 18:48 ` [PATCH 12/15] rfkill: add type string helper Henrique de Moraes Holschuh
                   ` (3 subsequent siblings)
  14 siblings, 2 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:48 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh

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 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
+ * one must assume unordered assynchronous 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 rfkill_led_trigger(struct rfkill *rfkill,
 			       enum rfkill_state state)
@@ -62,14 +105,25 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
 #endif /* CONFIG_RFKILL_LEDS */
 }
 
+static void notify_rfkill_state_change(struct rfkill *rfkill)
+{
+	blocking_notifier_call_chain(&rfkill_notifier_list,
+			RFKILL_STATE_CHANGED,
+			rfkill);
+}
+
 static void update_rfkill_state(struct rfkill *rfkill)
 {
-	enum rfkill_state newstate;
+	enum rfkill_state newstate, oldstate;
 
 	if (rfkill->get_state) {
 		mutex_lock(&rfkill->mutex);
-		if (!rfkill->get_state(rfkill->data, &newstate))
+		if (!rfkill->get_state(rfkill->data, &newstate)) {
+			oldstate = rfkill->state;
 			rfkill->state = newstate;
+			if (oldstate != newstate)
+				notify_rfkill_state_change(rfkill);
+		}
 		mutex_unlock(&rfkill->mutex);
 	}
 }
@@ -93,8 +147,10 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
 			rfkill->state = state;
 	}
 
-	if (force || rfkill->state != oldstate)
+	if (force || rfkill->state != oldstate) {
 		rfkill_led_trigger(rfkill, rfkill->state);
+		notify_rfkill_state_change(rfkill);
+	}
 
 	return retval;
 }
@@ -139,8 +195,16 @@ EXPORT_SYMBOL(rfkill_switch_all);
  */
 int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
 {
+	enum rfkill_state oldstate;
+
 	mutex_lock(&rfkill->mutex);
+
+	oldstate = rfkill->state;
 	rfkill->state = state;
+
+	if (state != oldstate)
+		notify_rfkill_state_change(rfkill);
+
 	mutex_unlock(&rfkill->mutex);
 
 	return 0;
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 12/15] rfkill: add type string helper
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (10 preceding siblings ...)
  2008-05-18 18:48 ` [PATCH 11/15] rfkill: add notifier chains support Henrique de Moraes Holschuh
@ 2008-05-18 18:48 ` Henrique de Moraes Holschuh
  2008-05-20 10:09   ` Ivo van Doorn
  2008-05-18 18:48 ` [PATCH 13/15] rfkill: add uevent notifications Henrique de Moraes Holschuh
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:48 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh

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


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 13/15] rfkill: add uevent notifications
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (11 preceding siblings ...)
  2008-05-18 18:48 ` [PATCH 12/15] rfkill: add type string helper Henrique de Moraes Holschuh
@ 2008-05-18 18:48 ` Henrique de Moraes Holschuh
  2008-05-20 10:09   ` Ivo van Doorn
  2008-05-18 18:48 ` [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF Henrique de Moraes Holschuh
  2008-05-18 18:48 ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions Henrique de Moraes Holschuh
  14 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh,
	Dmitry Torokhov

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 error;
+}
+
 static struct class rfkill_class = {
 	.name		= "rfkill",
 	.dev_release	= rfkill_release,
 	.dev_attrs	= rfkill_dev_attrs,
 	.suspend	= rfkill_suspend,
 	.resume		= rfkill_resume,
+	.dev_uevent	= rfkill_dev_uevent,
 };
 
 static int rfkill_add_switch(struct rfkill *rfkill)
@@ -562,11 +601,14 @@ static int __init rfkill_init(void)
 		return error;
 	}
 
+	register_rfkill_notifier(&rfkill_blocking_uevent_nb);
+
 	return 0;
 }
 
 static void __exit rfkill_exit(void)
 {
+	unregister_rfkill_notifier(&rfkill_blocking_uevent_nb);
 	class_unregister(&rfkill_class);
 }
 
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (12 preceding siblings ...)
  2008-05-18 18:48 ` [PATCH 13/15] rfkill: add uevent notifications Henrique de Moraes Holschuh
@ 2008-05-18 18:48 ` Henrique de Moraes Holschuh
  2008-05-20 10:09   ` Ivo van Doorn
  2008-05-18 18:48 ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions Henrique de Moraes Holschuh
  14 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh,
	Dmitry Torokhov

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,
+						    RFKILL_STATE_ON);
+				rfkill_schedule_set(&rfkill_bt,
+						    RFKILL_STATE_ON);
+				rfkill_schedule_set(&rfkill_wlan,
+						    RFKILL_STATE_ON);
+			} else
+				rfkill_epo();
 			break;
 		default:
 			break;
diff --git a/net/rfkill/rfkill-input.h b/net/rfkill/rfkill-input.h
index 4dae500..f63d050 100644
--- a/net/rfkill/rfkill-input.h
+++ b/net/rfkill/rfkill-input.h
@@ -12,5 +12,6 @@
 #define __RFKILL_INPUT_H
 
 void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state);
+void rfkill_epo(void);
 
 #endif /* __RFKILL_INPUT_H */
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index ba25bde..fdde692 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -182,6 +182,24 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
 EXPORT_SYMBOL(rfkill_switch_all);
 
 /**
+ * rfkill_epo - emergency power off all transmitters
+ *
+ * This kicks all rfkill devices to RFKILL_STATE_OFF, ignoring
+ * everything in its path but rfkill_mutex.
+ */
+void rfkill_epo(void)
+{
+	struct rfkill *rfkill;
+
+	mutex_lock(&rfkill_mutex);
+	list_for_each_entry(rfkill, &rfkill_list, node) {
+		rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF, 1);
+	}
+	mutex_unlock(&rfkill_mutex);
+}
+EXPORT_SYMBOL_GPL(rfkill_epo);
+
+/**
  * 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.
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions
  2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
                   ` (13 preceding siblings ...)
  2008-05-18 18:48 ` [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF Henrique de Moraes Holschuh
@ 2008-05-18 18:48 ` Henrique de Moraes Holschuh
  2008-05-19 17:51   ` Randy Dunlap
  2008-05-20 10:09   ` Ivo van Doorn
  14 siblings, 2 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-18 18:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ivo van Doorn, Thomas Renninger, Henrique de Moraes Holschuh,
	Dmitry Torokhov

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).
 
-This is done by providing the user 3 possibilities:
- 1 - The rfkill system handles all events; userspace is not aware of events.
- 2 - The rfkill system handles all events; userspace is informed about the events.
- 3 - The rfkill system does not handle events; userspace handles all events.
+Because of this requirement, userspace support for the keys should not be made
+mandatory.  Because userspace might want to perform some additional smarter
+tasks when the key is pressed, rfkill provides userspace the possibility to
+take over the task to handle the key events.
 
-The buttons to enable and disable the wireless radios are important in
-situations where the user is for example using his laptop on a location where
-wireless radios _must_ be disabled (e.g. airplanes).
-Because of this requirement, userspace support for the keys should not be
-made mandatory. Because userspace might want to perform some additional smarter
-tasks when the key is pressed, rfkill still provides userspace the possibility
-to take over the task to handle the key events.
+===============================================================================
+1: Implementation details
+
+The rfkill class provides kernel drivers with an interface that allows them to
+know when they should enable or disable a wireless network device transmitter.
+
+The rfkill-input module provides the kernel with the hability to implement
+a basic response to when the user presses a key or button (or toggles a switch)
+related to rfkill functionality.  This is optional, and can also be done in
+userspace.
+
+All state changes on rfkill devices is propagated by the rfkill class to a
+notification chain and also to userspace through uevents.
 
 The system inside the kernel has been split into 2 separate sections:
 	1 - RFKILL
 	2 - RFKILL_INPUT
 
-The first option enables rfkill support and will make sure userspace will
-be notified of any events through the input device. It also creates several
-sysfs entries which can be used by userspace. See section "Userspace support".
+The first option enables rfkill support and will make sure userspace will be
+notified of any events through uevents.  It provides a notification chain for
+interested parties in the kernel to also get notified of rfkill state changes
+in other drivers.  It creates several sysfs entries which can be used by
+userspace.  See section "Userspace support".
+
+The second option provides an rfkill input handler. This handler will listen to
+all rfkill key events and will toggle the radio accordingly.  With this option
+enabled userspace could either do nothing or simply perform monitoring tasks.
+
+When a rfkill switch is in the RFKILL_STATE_ON, the wireless transmitter (radio
+TX circuit for example) is *enabled*.  When the rfkill switch is in the
+RFKILL_STATE_OFF, the wireless transmitter is to be *blocked* from operating.
+
+Full rfkill functionality requires two different subsystems to cooperate: the
+input layer, and the rfkill class.  The input layer issues *commands* to the
+entire system requesting that devices registered to the rfkill class change
+state.  The way this interation happens is not complex, but it is not obvious
+either:
+
+Kernel Input layer:
+	* Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
+	  other such events when the user presses certain keys, buttons, or
+	  toggles certain physical switches.
+
+	THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE
+	KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT.  It is
+	used to issue *commands* for the system to change behaviour, and these
+	commands may or may not be carried out by some kernel driver or
+	userspace application.  It follows that doing user feedback based only
+	on input events is broken, there is no guarantee that an input event
+	will be acted upon.
+
+	Most wireless communication device drivers implementing rfkill
+	functionality MUST NOT generate these events, and have no reason to
+	register themselves with the input layer.  This is a common
+	misconception.  There is an API to propagate rfkill status change
+	information, and it is NOT the input layer.
+
+rfkill class:
+	* Calls a hook in a driver to effectively change the wireless
+	  transmitter state;
+	* Keeps track of the wireless transmitter state (with help from
+	  the driver);
+	* Generates userspace notifications (uevents) and a call to a
+	  notification chain (kernel) when there is a wireless transmitter
+	  state change;
+	* Connects a wireless communications driver with the common rfkill
+	  control system, which, for example, allows actions such as
+	  "switch all bluetooth devices offline" to be carried out by
+	  userspace or by rfkill-input.
+
+	THE RFKILL CLASS NEVER ISSUES INPUT EVENTS.  THE RFKILL CLASS DOES
+	NOT LISTEN TO INPUT EVENTS.  NO DRIVER USING THE RFKILL CLASS SHALL
+	EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS.
+
+	Most wireless data communication drivers in the kernel have just to
+	implement the rfkill class API to work properly.  Interfacing to the
+	input layer is not often required (and is very often a *bug*).
+
+Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
+	* Implements the policy of what should happen when one of the input
+	  layer events related to rfkill operation is received.
+	* Uses the sysfs interface (userspace) or private rfkill API calls
+	  to tell the devices registered with the rfkill class to change
+	  their state (i.e. translates the input layer event into real
+	  action).
+
+Userspace uevent handler or kernel platform-specific drivers hooked to the
+rfkill notifier chain:
+
+	* Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,
+	  in order to know when a device that is registered with the rfkill
+	  class changes state;
+	* Issues feedback notifications to the user;
+	* In the rare platforms where this is required, synthesizes an input
+	  event to command all *OTHER* rfkill devices to also change their
+	  statues when a specific rfkill device changes state.
+
+
+===============================================================================
+2: Kernel driver guidelines
+
+The first thing one needs to know is whether his driver should be talking to
+the rfkill class, or to the input layer.
+
+Do not mistake input devices for rfkill devices.  The only type of "rfkill
+switch" device that is to be registered with the rfkill class are those
+directly controlling the circuits that cause a wireless transmitter to stop
+working (or the software equivalent of them).  Every other kind of "rfkill
+switch" is just an input device and MUST NOT be registered with the rfkill
+class.
+
+A driver should register a device with the rfkill class when ALL of the
+following conditions are met:
+
+1. The device is/controls a data communications wireless transmitter;
+
+2. The kernel can interact with the hardware/firmware to CHANGE the wireless
+   transmitter state (block/unblock TX operation);
+
+A driver should register a device with the input subsystem to issue
+rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,
+SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:
+
+1. It is directly related to some physical device the user interacts with, to
+   command the O.S./firmware/hardware to enable/disable a data communications
+   wireless transmitter.
+
+   Examples of the physical device are: buttons, keys and switches the user
+   will press/touch/slide/switch to enable or disable the wireless
+   communication device.
+
+2. It is NOT slaved to another device, i.e. there is no other device that
+   issues rfkill-related input events in preference to this one.
+
+   Typically, the ACPI "radio kill" switch of a laptop is the master input
+   device to issue rfkill events, and, e.g., the WLAN card is just a slave
+   device that gets disabled by its hardware radio-kill input pin.
 
-The second option provides an rfkill input handler. This handler will
-listen to all rfkill key events and will toggle the radio accordingly.
-With this option enabled userspace could either do nothing or simply
-perform monitoring tasks.
+When in doubt, do not issue input events.  For drivers that should generate
+input events in some platforms, but not in others (e.g. b43), the best solution
+is to NEVER generate input events in the first place.  That work should be
+deferred to a platform-specific kernel module (which will known when to
+generate events through the rfkill notifier chain), or to userspace.  This
+avoids the usual maintenance problems with DMI whitelisting.
 
+
+Corner cases and examples:
 ====================================
-2: Driver support
 
-To build a driver with rfkill subsystem support, the driver should
-depend on the Kconfig symbol RFKILL; it should _not_ depend on
-RKFILL_INPUT.
+1. If the device is an input device that, because of hardware or firmware,
+causes wireless transmitters to be blocked regardless of the kernel's will, it
+is still just an input device, and NOT to be registered with the rfkill class.
 
-Unless key events trigger an interrupt to which the driver listens, polling
-will be required to determine the key state changes. For this the input
-layer providers the input-polldev handler.
+2. If the wireless transmitter switch control is read-only, it is an input
+device and not to be registered with the rfkill class (and maybe not to be made
+an input layer event source either, see below).
 
-A driver should implement a few steps to correctly make use of the
-rfkill subsystem. First for non-polling drivers:
+3. If there is some other device driver *closer* to the actuall hardware the
+user interacted with (the button/switch/key) to issue an input event, THAT is
+the device driver that should be issuing input events.
 
-	- rfkill_allocate()
-	- input_allocate_device()
-	- rfkill_register()
-	- input_register_device()
+E.g:
+  [RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
+                           (platform driver)    (wireless card driver)
+
+The user is closer to the RFKILL slide switch plaform driver, so the driver
+which must issue input events is the platform driver looking at the GPIO
+hardware, and NEVER the wireless card driver (which is just a slave).  It is
+very likely that there are other leaves than just the WLAN card rf-kill input
+(e.g. a bluetooth card, etc)...
+
+On the other hand, some embedded devices do this:
+
+  [RFKILL slider switch] -- [WLAN card rf-kill input]
+                             (wireless card driver)
+
+In this situation, the wireless card driver *could* register itself as an input
+device and issue rf-kill related input events... but in order to AVOID the need
+for DMI whitelisting, the wireless card driver does NOT do it.  Userspace (HAL)
+or a platform driver (that exists only on these embedded devices) will do the
+dirty job of issuing the input events.
+
+
+COMMON MISTAKES in kernel drivers, related to rfkill:
+====================================
+
+1. NEVER confuse input device keys and buttons with input device switches.
+
+  1a. Switches are always set or reset.  They report the current state
+      (on position or off position).
+
+  1b. Keys and buttons are either in the pressed or not-pressed state, and
+      that's it.  A "button" that latches down when you press it, and
+      unlatches when you press it again is in fact a switch as far as input
+      devices go.
+
+Add the SW_* events you need them for switches, do NOT try to emulate a button
+using KEY_* events just because there is no such SW_* event yet.  Do NOT try to
+use, for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
+
+2. Input device switches (sources of EV_SW events) DO store their current
+state, and that state CAN be queried from userspace through IOCTLs.  There is
+no sysfs interface for this, but that doesn't mean you should break things
+trying to hook it to the rfkill class to get a sysfs interface :-)
+
+
+===============================================================================
+3: Kernel API
+
+To build a driver with rfkill subsystem support, the driver should depend on
+the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
+
+The hardware the driver talks to may be write-only (where the current state
+of the hardware is unknown), or read-write (where the hardware can be queried
+about its current state).
+
+The rfkill class will call the get_state hook of a device every time it needs
+to know the *real* current state of the hardware.  This can happen often.
+
+Some hardware provide events when its status change.  In these cases, it is
+best for the driver to not provide a get_state hook, and instead register the
+rfkill class *already* with the correct status, and keep it updated using
+rfkill_force_state() when it gets an event from the hardware.
 
-For polling drivers:
+There is no provision for a statically-allocated rfkill struct.  You must
+use rfkill_allocate() to allocate one.
 
+You should:
 	- rfkill_allocate()
-	- input_allocate_polled_device()
+	- modify rfkill fields (flags, name)
+	- modify state to the current hardware state (THIS IS THE ONLY TIME
+	  YOU CAN ACCESS state DIRECTLY)
 	- rfkill_register()
-	- input_register_polled_device()
 
-When a key event has been detected, the correct event should be
-sent over the input device which has been registered by the driver.
+Please refer to the source for more documentation.
 
-====================================
-3: Userspace support
+===============================================================================
+4: Userspace support
+
+rfkill devices issue uevents (with an action of "change"), with the following
+environment variables set:
+
+RFKILL_NAME
+RFKILL_STATE
+RFKILL_TYPE
 
-For each key an input device will be created which will send out the correct
-key event when the rfkill key has been pressed.
+The ABI for these variables is defined by the sysfs attributes.  It is best
+to take a quick look at the source to make sure of the possible values.
+
+It is expected that HAL will trap those, and bridge them to DBUS, etc.  These
+events CAN and SHOULD be used to give feedback to the user about the rfkill
+status of the system.
+
+Input devices may issue events that are related to rfkill.  These are the
+various KEY_* events and SW_* events supported by rfkill-input.c.
+
+******IMPORTANT******
+When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF A RFKILL
+SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it
+has set to true the user_claim attribute for that particular switch.  This rule
+is *absolute*, do NOT violate it.
+******IMPORTANT******
+
+When rfkill-input is not active, userspace must initiate an rfkill status
+change by writing to the "state" attribute in order for anything to happen.
+
+Take particular care to implement EV_SW SW_RFKILL_ALL properly.  When that
+switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
+OFF state, no questions asked.
 
 The following sysfs entries will be created:
 
@@ -89,8 +306,16 @@ The following sysfs entries will be created:
 Both the "state" and "claim" entries are also writable. For the "state" entry
 this means that when 1 or 0 is written all radios, not yet in the requested
 state, will be will be toggled accordingly.
+
 For the "claim" entry writing 1 to it means that the kernel no longer handles
 key events even though RFKILL_INPUT input was enabled. When "claim" has been
 set to 0, userspace should make sure that it listens for the input events or
-check the sysfs "state" entry regularly to correctly perform the required
-tasks when the rkfill key is pressed.
+check the sysfs "state" entry regularly to correctly perform the required tasks
+when the rkfill key is pressed.
+
+A note about input devices and EV_SW events:
+
+In order to know the current state of an input device switch (like
+SW_RFKILL_ALL), you will need to use an IOCTL.  That information is not
+available through sysfs in a generic way at this time, and it is not available
+through the rfkill class AT ALL.
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 11/15] rfkill: add notifier chains support
  2008-05-18 18:48 ` [PATCH 11/15] rfkill: add notifier chains support Henrique de Moraes Holschuh
@ 2008-05-19  8:44   ` Thomas Renninger
  2008-05-19 13:10     ` Henrique de Moraes Holschuh
  2008-05-20 10:09   ` Ivo van Doorn
  1 sibling, 1 reply; 58+ messages in thread
From: Thomas Renninger @ 2008-05-19  8:44 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh; +Cc: linux-kernel, Ivo van Doorn

On Sun, 2008-05-18 at 15:48 -0300, Henrique de Moraes Holschuh wrote:
> 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 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
> + * one must assume unordered assynchronous behaviour, there is no way to
One must, one must...,         asynchronous
...

   Thomas




^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 11/15] rfkill: add notifier chains support
  2008-05-19  8:44   ` Thomas Renninger
@ 2008-05-19 13:10     ` Henrique de Moraes Holschuh
  0 siblings, 0 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-19 13:10 UTC (permalink / raw)
  To: Thomas Renninger; +Cc: linux-kernel, Ivo van Doorn

On Mon, 19 May 2008, Thomas Renninger wrote:
> > + * Calls to this chain may have been done through a workqueue.  One must
> > + * one must assume unordered assynchronous behaviour, there is no way to
> One must, one must...,         asynchronous
> ...

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions
  2008-05-18 18:48 ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions Henrique de Moraes Holschuh
@ 2008-05-19 17:51   ` Randy Dunlap
  2008-05-19 22:04     ` Henrique de Moraes Holschuh
  2008-05-19 22:52     ` Elias Oltmanns
  2008-05-20 10:09   ` Ivo van Doorn
  1 sibling, 2 replies; 58+ messages in thread
From: Randy Dunlap @ 2008-05-19 17:51 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Ivo van Doorn, Thomas Renninger, Dmitry Torokhov

On Sun, 18 May 2008 15:48:05 -0300 Henrique de Moraes Holschuh wrote:

> 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
>  ====================================
>  

Add INTRODUCTION item here?

>  1 Implementation details
> -2 Driver support
> -3 Userspace support
> +2 Kernel driver guidelines
> +3 Kernel API
> +4 Userspace support
>  
> -===============================================================================
> -1: Implementation details
> +
> +INTRODUCTION:
>  

[snip]

> +===============================================================================
> +1: Implementation details
> +
> +The rfkill class provides kernel drivers with an interface that allows them to
> +know when they should enable or disable a wireless network device transmitter.
> +
> +The rfkill-input module provides the kernel with the hability to implement

s/hability/ability/

> +a basic response to when the user presses a key or button (or toggles a switch)

s/to when/when/

> +related to rfkill functionality.  This is optional, and can also be done in
> +userspace.
> +
> +All state changes on rfkill devices is propagated by the rfkill class to a

s/is/are/

> +notification chain and also to userspace through uevents.
>  
>  The system inside the kernel has been split into 2 separate sections:
>  	1 - RFKILL
>  	2 - RFKILL_INPUT
>  
> -The first option enables rfkill support and will make sure userspace will
> -be notified of any events through the input device. It also creates several
> -sysfs entries which can be used by userspace. See section "Userspace support".
> +The first option enables rfkill support and will make sure userspace will be
> +notified of any events through uevents.  It provides a notification chain for
> +interested parties in the kernel to also get notified of rfkill state changes
> +in other drivers.  It creates several sysfs entries which can be used by
> +userspace.  See section "Userspace support".
> +
> +The second option provides an rfkill input handler. This handler will listen to
> +all rfkill key events and will toggle the radio accordingly.  With this option
> +enabled userspace could either do nothing or simply perform monitoring tasks.
> +
> +When a rfkill switch is in the RFKILL_STATE_ON, the wireless transmitter (radio
> +TX circuit for example) is *enabled*.  When the rfkill switch is in the
> +RFKILL_STATE_OFF, the wireless transmitter is to be *blocked* from operating.
> +
> +Full rfkill functionality requires two different subsystems to cooperate: the
> +input layer, and the rfkill class.  The input layer issues *commands* to the

no comma.

> +entire system requesting that devices registered to the rfkill class change
> +state.  The way this interation happens is not complex, but it is not

                        interaction

 obvious
> +either:
> +
> +Kernel Input layer:
> +	* Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
> +	  other such events when the user presses certain keys, buttons, or
> +	  toggles certain physical switches.

[snip]

> +===============================================================================
> +2: Kernel driver guidelines
> +
> +The first thing one needs to know is whether his driver should be talking to
> +the rfkill class, or to the input layer.

no comma.

> +
> +Do not mistake input devices for rfkill devices.  The only type of "rfkill
> +switch" device that is to be registered with the rfkill class are those
> +directly controlling the circuits that cause a wireless transmitter to stop
> +working (or the software equivalent of them).  Every other kind of "rfkill
> +switch" is just an input device and MUST NOT be registered with the rfkill
> +class.

[snip]

> +   Typically, the ACPI "radio kill" switch of a laptop is the master input
> +   device to issue rfkill events, and, e.g., the WLAN card is just a slave
> +   device that gets disabled by its hardware radio-kill input pin.
>  
> -The second option provides an rfkill input handler. This handler will
> -listen to all rfkill key events and will toggle the radio accordingly.
> -With this option enabled userspace could either do nothing or simply
> -perform monitoring tasks.
> +When in doubt, do not issue input events.  For drivers that should generate
> +input events in some platforms, but not in others (e.g. b43), the best solution
> +is to NEVER generate input events in the first place.  That work should be
> +deferred to a platform-specific kernel module (which will known when to

s/known/know/

> +generate events through the rfkill notifier chain), or to userspace.  This

no comma.

> +avoids the usual maintenance problems with DMI whitelisting.
>  
> +
> +Corner cases and examples:
>  ====================================
> -2: Driver support
>  
> -To build a driver with rfkill subsystem support, the driver should
> -depend on the Kconfig symbol RFKILL; it should _not_ depend on
> -RKFILL_INPUT.
> +1. If the device is an input device that, because of hardware or firmware,
> +causes wireless transmitters to be blocked regardless of the kernel's will, it
> +is still just an input device, and NOT to be registered with the rfkill class.
>  
> -Unless key events trigger an interrupt to which the driver listens, polling
> -will be required to determine the key state changes. For this the input
> -layer providers the input-polldev handler.
> +2. If the wireless transmitter switch control is read-only, it is an input
> +device and not to be registered with the rfkill class (and maybe not to be made
> +an input layer event source either, see below).
>  
> -A driver should implement a few steps to correctly make use of the
> -rfkill subsystem. First for non-polling drivers:
> +3. If there is some other device driver *closer* to the actuall hardware the

s/actuall/actual/

> +user interacted with (the button/switch/key) to issue an input event, THAT is

[snip]

> +the device driver that should be issuing input events.
> +COMMON MISTAKES in kernel drivers, related to rfkill:
> +====================================
> +
> +1. NEVER confuse input device keys and buttons with input device switches.
> +
> +  1a. Switches are always set or reset.  They report the current state
> +      (on position or off position).
> +
> +  1b. Keys and buttons are either in the pressed or not-pressed state, and
> +      that's it.  A "button" that latches down when you press it, and
> +      unlatches when you press it again is in fact a switch as far as input
> +      devices go.
> +
> +Add the SW_* events you need them for switches, do NOT try to emulate a button

Delete "them"?  A little misworded/confusing.

> +using KEY_* events just because there is no such SW_* event yet.  Do NOT try to
> +use, for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
> +
> +2. Input device switches (sources of EV_SW events) DO store their current
> +state, and that state CAN be queried from userspace through IOCTLs.  There is
> +no sysfs interface for this, but that doesn't mean you should break things
> +trying to hook it to the rfkill class to get a sysfs interface :-)
> +
> +
> +===============================================================================
> +3: Kernel API
> +
> +To build a driver with rfkill subsystem support, the driver should depend on
> +the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
> +
> +The hardware the driver talks to may be write-only (where the current state
> +of the hardware is unknown), or read-write (where the hardware can be queried
> +about its current state).
> +
> +The rfkill class will call the get_state hook of a device every time it needs
> +to know the *real* current state of the hardware.  This can happen often.
> +
> +Some hardware provide events when its status change.  In these cases, it is

                 provides

> +best for the driver to not provide a get_state hook, and instead register the
> +rfkill class *already* with the correct status, and keep it updated using
> +rfkill_force_state() when it gets an event from the hardware.

[snip]

+===============================================================================
> +4: Userspace support
> +
> +rfkill devices issue uevents (with an action of "change"), with the following
> +environment variables set:
> +
> +RFKILL_NAME
> +RFKILL_STATE
> +RFKILL_TYPE
>  
> -For each key an input device will be created which will send out the correct
> -key event when the rfkill key has been pressed.
> +The ABI for these variables is defined by the sysfs attributes.  It is best
> +to take a quick look at the source to make sure of the possible values.
> +
> +It is expected that HAL will trap those, and bridge them to DBUS, etc.  These
> +events CAN and SHOULD be used to give feedback to the user about the rfkill
> +status of the system.
> +
> +Input devices may issue events that are related to rfkill.  These are the
> +various KEY_* events and SW_* events supported by rfkill-input.c.
> +
> +******IMPORTANT******
> +When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF A RFKILL

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

> +SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it
> +has set to true the user_claim attribute for that particular switch.  This rule
> +is *absolute*, do NOT violate it.

s/,/;/

> +******IMPORTANT******
> +
> +When rfkill-input is not active, userspace must initiate an rfkill status
> +change by writing to the "state" attribute in order for anything to happen.
> +
> +Take particular care to implement EV_SW SW_RFKILL_ALL properly.  When that
> +switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
> +OFF state, no questions asked.
>  
>  The following sysfs entries will be created:

[snip]

---
~Randy

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions
  2008-05-19 17:51   ` Randy Dunlap
@ 2008-05-19 22:04     ` Henrique de Moraes Holschuh
  2008-05-19 22:52     ` Elias Oltmanns
  1 sibling, 0 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-19 22:04 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: linux-kernel, Ivo van Doorn, Thomas Renninger, Dmitry Torokhov

On Mon, 19 May 2008, Randy Dunlap wrote:
> Add INTRODUCTION item here?

Will do, for completeness if anything.

[snip]

> > +Add the SW_* events you need them for switches, do NOT try to emulate a button
> 
> Delete "them"?  A little misworded/confusing.

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

> > +******IMPORTANT******
> > +When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF A RFKILL
> 
> OF AN RKFILL ?
> i.e., does one say "R F KILL" or does one say "rifkill" or "rufkill" or
> something else?

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions
  2008-05-19 17:51   ` Randy Dunlap
  2008-05-19 22:04     ` Henrique de Moraes Holschuh
@ 2008-05-19 22:52     ` Elias Oltmanns
  2008-05-19 22:56       ` Randy Dunlap
  1 sibling, 1 reply; 58+ messages in thread
From: Elias Oltmanns @ 2008-05-19 22:52 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Henrique de Moraes Holschuh, linux-kernel, Ivo van Doorn,
	Thomas Renninger, Dmitry Torokhov

Randy Dunlap <randy.dunlap@oracle.com> wrote:
> On Sun, 18 May 2008 15:48:05 -0300 Henrique de Moraes Holschuh wrote:
[...]
>> +===============================================================================
>> +3: Kernel API
>> +
>> +To build a driver with rfkill subsystem support, the driver should depend on
>> +the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
>> +
>> +The hardware the driver talks to may be write-only (where the current state
>> +of the hardware is unknown), or read-write (where the hardware can be queried
>> +about its current state).
>> +
>> +The rfkill class will call the get_state hook of a device every time it needs
>> +to know the *real* current state of the hardware.  This can happen often.
>> +
>> +Some hardware provide events when its status change.  In these cases, it is
>
>                  provides

Wouldn't that be "changes" as welll?

Regards,

Elias

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions
  2008-05-19 22:52     ` Elias Oltmanns
@ 2008-05-19 22:56       ` Randy Dunlap
  0 siblings, 0 replies; 58+ messages in thread
From: Randy Dunlap @ 2008-05-19 22:56 UTC (permalink / raw)
  To: Elias Oltmanns
  Cc: Dmitry Torokhov, Henrique de Moraes Holschuh, linux-kernel,
	Thomas Renninger, Ivo van Doorn

--- Original Message ---
> Randy Dunlap <randy.dunlap@oracle.com> wrote:
> > On Sun, 18 May 2008 15:48:05 -0300 Henrique de Moraes Holschuh wrote:
> [...]
> >> +===============================================================================
> >> +3: Kernel API
> >> +
> >> +To build a driver with rfkill subsystem support, the driver should depend on
> >> +the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
> >> +
> >> +The hardware the driver talks to may be write-only (where the current state
> >> +of the hardware is unknown), or read-write (where the hardware can be queried
> >> +about its current state).
> >> +
> >> +The rfkill class will call the get_state hook of a device every time it needs
> >> +to know the *real* current state of the hardware.  This can happen often.
> >> +
> >> +Some hardware provide events when its status change.  In these cases, it is
> >
> >                  provides
> 
> Wouldn't that be "changes" as welll?

Yes.  Thanks.

~Randy



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/15] rfkill: clarify meaning of rfkill states
  2008-05-18 18:47 ` [PATCH 04/15] rfkill: clarify meaning of rfkill states Henrique de Moraes Holschuh
@ 2008-05-20 10:08   ` Ivo van Doorn
  0 siblings, 0 replies; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:08 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, John W. Linville, Dmitry Torokhov

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> 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>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> 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 be a value from enum rfkill_type.
> - * @state: State of the switch (on/off).
> + * @state: State of the switch, "ON" means radio can operate.
>   * @user_claim_unsupported: Whether the hardware supports exclusive
>   *	RF-kill control by userspace. Set this before registering.
>   * @user_claim: Set when the switch is controlled exlusively by userspace.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 05/15] rfkill: fix minor typo in kernel doc
  2008-05-18 18:47 ` [PATCH 05/15] rfkill: fix minor typo in kernel doc Henrique de Moraes Holschuh
@ 2008-05-20 10:08   ` Ivo van Doorn
  0 siblings, 0 replies; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:08 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, John W. Linville, Dmitry Torokhov

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> Fix a minor typo in an exported function documentation
> 
> Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> 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



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 06/15] rfkill: handle SW_RFKILL_ALL events
  2008-05-18 18:47 ` [PATCH 06/15] rfkill: handle SW_RFKILL_ALL events Henrique de Moraes Holschuh
@ 2008-05-20 10:08   ` Ivo van Doorn
  0 siblings, 0 replies; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:08 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> 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>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> 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:
> +						    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);
> +			break;
> +		default:
> +			break;
> +		}
>  	}
>  }
>  
> @@ -168,6 +204,11 @@ static const struct input_device_id rfkill_ids[] = {
>  		.evbit = { BIT_MASK(EV_KEY) },
>  		.keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
>  	},
> +	{
> +		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
> +		.evbit = { BIT(EV_SW) },
> +		.swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
> +	},
>  	{ }
>  };
>  



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 08/15] rfkill: add read-write rfkill switch support
  2008-05-18 18:47 ` [PATCH 08/15] rfkill: add read-write rfkill switch support Henrique de Moraes Holschuh
@ 2008-05-20 10:08   ` Ivo van Doorn
  0 siblings, 0 replies; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:08 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> 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>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> 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 radio state.
>   * @toggle_radio(): Mandatory handler to control state of the radio.
> + * @get_state(): handler to read current radio state from hardware,
> + *      may be called from atomic context, should return 0 on success.
>   * @led_trigger: A LED trigger for this button's LED.
>   * @dev: Device structure integrating the switch into device tree.
>   * @node: Used to place switch into list of all switches known to the
> @@ -80,6 +82,7 @@ struct rfkill {
>  
>  	void *data;
>  	int (*toggle_radio)(void *data, enum rfkill_state state);
> +	int (*get_state)(void *data, enum rfkill_state *state);
>  
>  #ifdef CONFIG_RFKILL_LEDS
>  	struct led_trigger led_trigger;
> @@ -95,6 +98,8 @@ void rfkill_free(struct rfkill *rfkill);
>  int rfkill_register(struct rfkill *rfkill);
>  void rfkill_unregister(struct rfkill *rfkill);
>  
> +int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state);
> +
>  /**
>   * rfkill_get_led_name - Get the LED trigger name for the button's LED.
>   * This function might return a NULL pointer if registering of the
> diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
> index 3edc585..2e19b68 100644
> --- a/net/rfkill/rfkill.c
> +++ b/net/rfkill/rfkill.c
> @@ -62,19 +62,39 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
>  #endif /* CONFIG_RFKILL_LEDS */
>  }
>  
> +static void update_rfkill_state(struct rfkill *rfkill)
> +{
> +	enum rfkill_state newstate;
> +
> +	if (rfkill->get_state) {
> +		mutex_lock(&rfkill->mutex);
> +		if (!rfkill->get_state(rfkill->data, &newstate))
> +			rfkill->state = newstate;
> +		mutex_unlock(&rfkill->mutex);
> +	}
> +}
> +
>  static int rfkill_toggle_radio(struct rfkill *rfkill,
>  				enum rfkill_state state)
>  {
>  	int retval = 0;
> +	enum rfkill_state oldstate, newstate;
> +
> +	oldstate = rfkill->state;
> +
> +	if (rfkill->get_state &&
> +	    !rfkill->get_state(rfkill->data, &newstate))
> +		rfkill->state = newstate;
>  
>  	if (state != rfkill->state) {
>  		retval = rfkill->toggle_radio(rfkill->data, state);
> -		if (!retval) {
> +		if (!retval)
>  			rfkill->state = state;
> -			rfkill_led_trigger(rfkill, state);
> -		}
>  	}
>  
> +	if (rfkill->state != oldstate)
> +		rfkill_led_trigger(rfkill, rfkill->state);
> +
>  	return retval;
>  }
>  
> @@ -105,6 +125,28 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
>  }
>  EXPORT_SYMBOL(rfkill_switch_all);
>  
> +/**
> + * 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)
> +{
> +	mutex_lock(&rfkill->mutex);
> +	rfkill->state = state;
> +	mutex_unlock(&rfkill->mutex);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(rfkill_force_state);
> +
>  static ssize_t rfkill_name_show(struct device *dev,
>  				struct device_attribute *attr,
>  				char *buf)
> @@ -147,6 +189,7 @@ static ssize_t rfkill_state_show(struct device *dev,
>  {
>  	struct rfkill *rfkill = to_rfkill(dev);
>  
> +	update_rfkill_state(rfkill);
>  	return sprintf(buf, "%d\n", rfkill->state);
>  }
>  



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 09/15] rfkill: add the WWAN radio type
  2008-05-18 18:47 ` [PATCH 09/15] rfkill: add the WWAN radio type Henrique de Moraes Holschuh
@ 2008-05-20 10:08   ` Ivo van Doorn
  2008-05-21  1:12     ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:08 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Inaky Perez-Gonzalez,
	Iñaky Pérez-González, John W. Linville,
	David S. Miller

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> 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>

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. :)

Acked-by: Ivo van Doorn <IvDoorn@gmail.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 @@ 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);
> diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
> index 2e19b68..c5a79ab 100644
> --- a/net/rfkill/rfkill.c
> +++ b/net/rfkill/rfkill.c
> @@ -176,6 +176,9 @@ static ssize_t rfkill_type_show(struct device *dev,
>  	case RFKILL_TYPE_WIMAX:
>  		type = "wimax";
>  		break;
> +	case RFKILL_TYPE_WWAN:
> +		type = "wwan";
> +		break;
>  	default:
>  		BUG();
>  	}



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 10/15] rfkill: rework suspend and resume handlers
  2008-05-18 18:48 ` [PATCH 10/15] rfkill: rework suspend and resume handlers Henrique de Moraes Holschuh
@ 2008-05-20 10:08   ` Ivo van Doorn
  0 siblings, 0 replies; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:08 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh; +Cc: linux-kernel, Thomas Renninger

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> 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>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> 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 ((!rfkill->user_claim) && (rfkill->type == type))
> -			rfkill_toggle_radio(rfkill, state);
> +			rfkill_toggle_radio(rfkill, state, 0);
>  	}
>  
>  	mutex_unlock(&rfkill_mutex);
> @@ -210,7 +210,8 @@ static ssize_t rfkill_state_store(struct device *dev,
>  	if (mutex_lock_interruptible(&rfkill->mutex))
>  		return -ERESTARTSYS;
>  	error = rfkill_toggle_radio(rfkill,
> -			state ? RFKILL_STATE_ON : RFKILL_STATE_OFF);
> +			state ? RFKILL_STATE_ON : RFKILL_STATE_OFF,
> +			0);
>  	mutex_unlock(&rfkill->mutex);
>  
>  	return error ? error : count;
> @@ -251,7 +252,8 @@ static ssize_t rfkill_claim_store(struct device *dev,
>  	if (rfkill->user_claim != claim) {
>  		if (!claim)
>  			rfkill_toggle_radio(rfkill,
> -					    rfkill_states[rfkill->type]);
> +					    rfkill_states[rfkill->type],
> +					    0);
>  		rfkill->user_claim = claim;
>  	}
>  
> @@ -284,12 +286,11 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
>  
>  	if (dev->power.power_state.event != state.event) {
>  		if (state.event & PM_EVENT_SLEEP) {
> -			mutex_lock(&rfkill->mutex);
> -
> -			if (rfkill->state == RFKILL_STATE_ON)
> -				rfkill->toggle_radio(rfkill->data,
> -						     RFKILL_STATE_OFF);
> +			/* Stop transmitter, keep state, no notifies */
> +			update_rfkill_state(rfkill);
>  
> +			mutex_lock(&rfkill->mutex);
> +			rfkill->toggle_radio(rfkill->data, RFKILL_STATE_OFF);
>  			mutex_unlock(&rfkill->mutex);
>  		}
>  
> @@ -306,8 +307,8 @@ static int rfkill_resume(struct device *dev)
>  	if (dev->power.power_state.event != PM_EVENT_ON) {
>  		mutex_lock(&rfkill->mutex);
>  
> -		if (rfkill->state == RFKILL_STATE_ON)
> -			rfkill->toggle_radio(rfkill->data, RFKILL_STATE_ON);
> +		/* restore radio state AND notify everybody */
> +		rfkill_toggle_radio(rfkill, rfkill->state, 1);
>  
>  		mutex_unlock(&rfkill->mutex);
>  	}
> @@ -334,7 +335,7 @@ static int rfkill_add_switch(struct rfkill *rfkill)
>  
>  	mutex_lock(&rfkill_mutex);
>  
> -	error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]);
> +	error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0);
>  	if (!error)
>  		list_add_tail(&rfkill->node, &rfkill_list);
>  
> @@ -347,7 +348,7 @@ static void rfkill_remove_switch(struct rfkill *rfkill)
>  {
>  	mutex_lock(&rfkill_mutex);
>  	list_del_init(&rfkill->node);
> -	rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF);
> +	rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF, 1);
>  	mutex_unlock(&rfkill_mutex);
>  }
>  



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 11/15] rfkill: add notifier chains support
  2008-05-18 18:48 ` [PATCH 11/15] rfkill: add notifier chains support Henrique de Moraes Holschuh
  2008-05-19  8:44   ` Thomas Renninger
@ 2008-05-20 10:09   ` Ivo van Doorn
  1 sibling, 0 replies; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:09 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh; +Cc: linux-kernel, Thomas Renninger

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> 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>

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

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> 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 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
> + * one must assume unordered assynchronous 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 rfkill_led_trigger(struct rfkill *rfkill,
>  			       enum rfkill_state state)
> @@ -62,14 +105,25 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
>  #endif /* CONFIG_RFKILL_LEDS */
>  }
>  
> +static void notify_rfkill_state_change(struct rfkill *rfkill)
> +{
> +	blocking_notifier_call_chain(&rfkill_notifier_list,
> +			RFKILL_STATE_CHANGED,
> +			rfkill);
> +}
> +
>  static void update_rfkill_state(struct rfkill *rfkill)
>  {
> -	enum rfkill_state newstate;
> +	enum rfkill_state newstate, oldstate;
>  
>  	if (rfkill->get_state) {
>  		mutex_lock(&rfkill->mutex);
> -		if (!rfkill->get_state(rfkill->data, &newstate))
> +		if (!rfkill->get_state(rfkill->data, &newstate)) {
> +			oldstate = rfkill->state;
>  			rfkill->state = newstate;
> +			if (oldstate != newstate)
> +				notify_rfkill_state_change(rfkill);
> +		}
>  		mutex_unlock(&rfkill->mutex);
>  	}
>  }
> @@ -93,8 +147,10 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
>  			rfkill->state = state;
>  	}
>  
> -	if (force || rfkill->state != oldstate)
> +	if (force || rfkill->state != oldstate) {
>  		rfkill_led_trigger(rfkill, rfkill->state);
> +		notify_rfkill_state_change(rfkill);
> +	}
>  
>  	return retval;
>  }
> @@ -139,8 +195,16 @@ EXPORT_SYMBOL(rfkill_switch_all);
>   */
>  int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
>  {
> +	enum rfkill_state oldstate;
> +
>  	mutex_lock(&rfkill->mutex);
> +
> +	oldstate = rfkill->state;
>  	rfkill->state = state;
> +
> +	if (state != oldstate)
> +		notify_rfkill_state_change(rfkill);
> +
>  	mutex_unlock(&rfkill->mutex);
>  
>  	return 0;



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 12/15] rfkill: add type string helper
  2008-05-18 18:48 ` [PATCH 12/15] rfkill: add type string helper Henrique de Moraes Holschuh
@ 2008-05-20 10:09   ` Ivo van Doorn
  0 siblings, 0 replies; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:09 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh; +Cc: linux-kernel, Thomas Renninger

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> 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>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> 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,



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 13/15] rfkill: add uevent notifications
  2008-05-18 18:48 ` [PATCH 13/15] rfkill: add uevent notifications Henrique de Moraes Holschuh
@ 2008-05-20 10:09   ` Ivo van Doorn
  0 siblings, 0 replies; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:09 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> 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>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> 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 error;
> +}
> +
>  static struct class rfkill_class = {
>  	.name		= "rfkill",
>  	.dev_release	= rfkill_release,
>  	.dev_attrs	= rfkill_dev_attrs,
>  	.suspend	= rfkill_suspend,
>  	.resume		= rfkill_resume,
> +	.dev_uevent	= rfkill_dev_uevent,
>  };
>  
>  static int rfkill_add_switch(struct rfkill *rfkill)
> @@ -562,11 +601,14 @@ static int __init rfkill_init(void)
>  		return error;
>  	}
>  
> +	register_rfkill_notifier(&rfkill_blocking_uevent_nb);
> +
>  	return 0;
>  }
>  
>  static void __exit rfkill_exit(void)
>  {
> +	unregister_rfkill_notifier(&rfkill_blocking_uevent_nb);
>  	class_unregister(&rfkill_class);
>  }
>  



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF
  2008-05-18 18:48 ` [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF Henrique de Moraes Holschuh
@ 2008-05-20 10:09   ` Ivo van Doorn
  2008-05-22 20:51     ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:09 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> 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.

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
force the change, or none of them should.

> 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,
> +						    RFKILL_STATE_ON);
> +				rfkill_schedule_set(&rfkill_bt,
> +						    RFKILL_STATE_ON);
> +				rfkill_schedule_set(&rfkill_wlan,
> +						    RFKILL_STATE_ON);
> +			} else
> +				rfkill_epo();
>  			break;
>  		default:
>  			break;
> diff --git a/net/rfkill/rfkill-input.h b/net/rfkill/rfkill-input.h
> index 4dae500..f63d050 100644
> --- a/net/rfkill/rfkill-input.h
> +++ b/net/rfkill/rfkill-input.h
> @@ -12,5 +12,6 @@
>  #define __RFKILL_INPUT_H
>  
>  void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state);
> +void rfkill_epo(void);
>  
>  #endif /* __RFKILL_INPUT_H */
> diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
> index ba25bde..fdde692 100644
> --- a/net/rfkill/rfkill.c
> +++ b/net/rfkill/rfkill.c
> @@ -182,6 +182,24 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
>  EXPORT_SYMBOL(rfkill_switch_all);
>  
>  /**
> + * rfkill_epo - emergency power off all transmitters
> + *
> + * This kicks all rfkill devices to RFKILL_STATE_OFF, ignoring
> + * everything in its path but rfkill_mutex.
> + */
> +void rfkill_epo(void)
> +{
> +	struct rfkill *rfkill;
> +
> +	mutex_lock(&rfkill_mutex);
> +	list_for_each_entry(rfkill, &rfkill_list, node) {
> +		rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF, 1);
> +	}
> +	mutex_unlock(&rfkill_mutex);
> +}
> +EXPORT_SYMBOL_GPL(rfkill_epo);
> +
> +/**
>   * 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.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions
  2008-05-18 18:48 ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions Henrique de Moraes Holschuh
  2008-05-19 17:51   ` Randy Dunlap
@ 2008-05-20 10:09   ` Ivo van Doorn
  2008-05-20 15:54     ` Henrique de Moraes Holschuh
  1 sibling, 1 reply; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 10:09 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

> +You should:
>  	- rfkill_allocate()
> -	- input_allocate_polled_device()
> +	- modify rfkill fields (flags, name)
> +	- modify state to the current hardware state (THIS IS THE ONLY TIME
> +	  YOU CAN ACCESS state DIRECTLY)
>  	- rfkill_register()
> -	- input_register_polled_device()

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions
  2008-05-20 10:09   ` Ivo van Doorn
@ 2008-05-20 15:54     ` Henrique de Moraes Holschuh
  2008-05-20 17:18       ` Ivo van Doorn
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-20 15:54 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov


On Tue, 20 May 2008 12:09:08 +0200, "Ivo van Doorn" <ivdoorn@gmail.com> said:
> > +You should:
> >  	- rfkill_allocate()
> > -	- input_allocate_polled_device()
> > +	- modify rfkill fields (flags, name)
> > +	- modify state to the current hardware state (THIS IS THE ONLY TIME
> > +	  YOU CAN ACCESS state DIRECTLY)
> >  	- rfkill_register()
> > -	- input_register_polled_device()
> 
> 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?

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


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions
  2008-05-20 15:54     ` Henrique de Moraes Holschuh
@ 2008-05-20 17:18       ` Ivo van Doorn
  2008-05-21  1:44         ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-20 17:18 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Tuesday 20 May 2008, Henrique de Moraes Holschuh wrote:
> 
> On Tue, 20 May 2008 12:09:08 +0200, "Ivo van Doorn" <ivdoorn@gmail.com> said:
> > > +You should:
> > >  	- rfkill_allocate()
> > > -	- input_allocate_polled_device()
> > > +	- modify rfkill fields (flags, name)
> > > +	- modify state to the current hardware state (THIS IS THE ONLY TIME
> > > +	  YOU CAN ACCESS state DIRECTLY)
> > >  	- rfkill_register()
> > > -	- input_register_polled_device()
> > 
> > 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?
> 
> 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?

Sounds good to me. :)

Ivo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 09/15] rfkill: add the WWAN radio type
  2008-05-20 10:08   ` Ivo van Doorn
@ 2008-05-21  1:12     ` Henrique de Moraes Holschuh
  2008-05-21  3:35       ` Inaky Perez-Gonzalez
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-21  1:12 UTC (permalink / raw)
  To: Ivo van Doorn
  Cc: linux-kernel, Thomas Renninger, Inaky Perez-Gonzalez,
	Iñaky Pérez-González, John W. Linville,
	David S. Miller

On Tue, 20 May 2008, Ivo van Doorn wrote:
> On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> > 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>
> 
> 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. :)

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions
  2008-05-20 17:18       ` Ivo van Doorn
@ 2008-05-21  1:44         ` Henrique de Moraes Holschuh
  2008-05-29  0:45           ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2) Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-21  1:44 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Tue, 20 May 2008, Ivo van Doorn wrote:
> > 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?
> 
> Sounds good to me. :)

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 09/15] rfkill: add the WWAN radio type
  2008-05-21  1:12     ` Henrique de Moraes Holschuh
@ 2008-05-21  3:35       ` Inaky Perez-Gonzalez
  2008-05-21  3:42         ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Inaky Perez-Gonzalez @ 2008-05-21  3:35 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: Ivo van Doorn, linux-kernel, Thomas Renninger, John W. Linville,
	David S. Miller

On Tuesday 20 May 2008, Henrique de Moraes Holschuh wrote:
> On Tue, 20 May 2008, Ivo van Doorn wrote:
> > On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:

> > > 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>

BTW, I just realized this was mistakenly put in your initial patch; 
you signed off for me and also added me to the CC :)
 
> 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.

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 09/15] rfkill: add the WWAN radio type
  2008-05-21  3:35       ` Inaky Perez-Gonzalez
@ 2008-05-21  3:42         ` Henrique de Moraes Holschuh
  2008-05-21  6:48           ` Inaky Perez-Gonzalez
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-21  3:42 UTC (permalink / raw)
  To: Inaky Perez-Gonzalez
  Cc: Ivo van Doorn, linux-kernel, Thomas Renninger, John W. Linville,
	David S. Miller

On Tue, 20 May 2008, Inaky Perez-Gonzalez wrote:
> On Tuesday 20 May 2008, Henrique de Moraes Holschuh wrote:
> > On Tue, 20 May 2008, Ivo van Doorn wrote:
> > > On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> > > > 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>
> 
> BTW, I just realized this was mistakenly put in your initial patch; 
> you signed off for me and also added me to the CC :)

Urk, that's embarassing.  Sorry about it!  Fixed.

> > 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.
> 
> 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.

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 09/15] rfkill: add the WWAN radio type
  2008-05-21  3:42         ` Henrique de Moraes Holschuh
@ 2008-05-21  6:48           ` Inaky Perez-Gonzalez
  2008-05-21 14:07             ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Inaky Perez-Gonzalez @ 2008-05-21  6:48 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: Ivo van Doorn, linux-kernel, Thomas Renninger, John W. Linville,
	David S. Miller

On Tuesday 20 May 2008, Henrique de Moraes Holschuh wrote:
> On Tue, 20 May 2008, Inaky Perez-Gonzalez wrote:
> > > 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.
> > 
> > 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.
> 
> I don't understand.  Switch one off and turn the other one off?  Isn't
> that the same thing?

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

-- 
Inaky

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 09/15] rfkill: add the WWAN radio type
  2008-05-21  6:48           ` Inaky Perez-Gonzalez
@ 2008-05-21 14:07             ` Henrique de Moraes Holschuh
  0 siblings, 0 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-21 14:07 UTC (permalink / raw)
  To: Inaky Perez-Gonzalez
  Cc: Ivo van Doorn, linux-kernel, Thomas Renninger, John W. Linville,
	David S. Miller

On Tue, 20 May 2008, Inaky Perez-Gonzalez wrote:
> On Tuesday 20 May 2008, Henrique de Moraes Holschuh wrote:
> > On Tue, 20 May 2008, Inaky Perez-Gonzalez wrote:
> > > > 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.
> > > 
> > > 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.
> > 
> > I don't understand.  Switch one off and turn the other one off?  Isn't
> > that the same thing?
> 
> -EOPERATORISDUMB, sorry; I meant turn one off and the other on. 

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF
  2008-05-20 10:09   ` Ivo van Doorn
@ 2008-05-22 20:51     ` Henrique de Moraes Holschuh
  2008-05-23 14:15       ` Ivo van Doorn
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-22 20:51 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Tue, 20 May 2008, Ivo van Doorn wrote:
> On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> > 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.
> 
> 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?

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
in my laptop.  But one thing at a time.  Small steps.

> All keys should have the same rules when it is pressed, so either all keys should
> force the change, or none of them should.

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 to.

-- 
  "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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF
  2008-05-22 20:51     ` Henrique de Moraes Holschuh
@ 2008-05-23 14:15       ` Ivo van Doorn
  2008-05-27 14:08         ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-23 14:15 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Thursday 22 May 2008, Henrique de Moraes Holschuh wrote:
> On Tue, 20 May 2008, Ivo van Doorn wrote:
> > On Sunday 18 May 2008, Henrique de Moraes Holschuh wrote:
> > > 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.
> > 
> > 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?
> 
> 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.

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
should be turned on/off.

> 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.

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
rfkill keys.

> 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.

Through the write-only rfkill class right? ;)

> 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
> in my laptop.  But one thing at a time.  Small steps.
> 
> > All keys should have the same rules when it is pressed, so either all keys should
> > force the change, or none of them should.
> 
> 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 to.

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF
  2008-05-23 14:15       ` Ivo van Doorn
@ 2008-05-27 14:08         ` Henrique de Moraes Holschuh
  2008-05-27 14:38           ` Ivo van Doorn
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-27 14:08 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Fri, 23 May 2008 16:15:33 +0200, "Ivo van Doorn" <ivdoorn@gmail.com> said:
> On Thursday 22 May 2008, Henrique de Moraes Holschuh wrote:
> > 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.
> 
> 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
> should be turned on/off.

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
are lucky if you get firmware that can make it work without the O.S.

> > 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.
> 
> 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
> rfkill keys.

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,
but I recommend against giving anything else EPO semanthics in rfkill.

> > 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.
> 
> Through the write-only rfkill class right? ;)

More like through the new read-write/write-only rfkill class, since you have
already ACKed those patches, but yes :-)

> > 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 to.
> 
> 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.

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 each 
wlan device being the room switch... while RFKILL_ALL is certainly The Master
Switch.

You will find this basic UI notion in *everything* dealing with an hierarchy of
switches: you have it on the power-grid and the mains input on your house, you
have it on your hydraulic pipes, and you have it in just about everything that
has not been bitten by the "standby" disease.  When you place a master switch in
"OFF" state, it bloody well *STAYS* *OFF*, and everything else after it is also
FORCED OFF, no matter what.

But of course, you have to make sure the master switch WILL bloody well stay off
when off by design.  You engineer it so that all possible failure modes will
cause it to go to the off state.

I would really appreciate that the rfkill class would abide to this UI notion for
the master rfkill events (*_RFKILL_ALL).

-- 
  "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


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF
  2008-05-27 14:08         ` Henrique de Moraes Holschuh
@ 2008-05-27 14:38           ` Ivo van Doorn
  2008-05-27 17:41             ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-27 14:38 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

> > > 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.
> > 
> > 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
> > rfkill keys.
> 
> 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,
> but I recommend against giving anything else EPO semanthics in rfkill.

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,
since both control specific radio types.

> > > 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 to.
> > 
> > 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.
> 
> 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.

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
switch or not.

> But of course, you have to make sure the master switch WILL bloody well stay off
> when off by design.  You engineer it so that all possible failure modes will
> cause it to go to the off state.
> 
> I would really appreciate that the rfkill class would abide to this UI notion for
> the master rfkill events (*_RFKILL_ALL).

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF
  2008-05-27 14:38           ` Ivo van Doorn
@ 2008-05-27 17:41             ` Henrique de Moraes Holschuh
  2008-05-27 18:13               ` Ivo van Doorn
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-27 17:41 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Tue, 27 May 2008 16:38:04 +0200, "Ivo van Doorn" <ivdoorn@gmail.com> said:
> > 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,
> > but I recommend against giving anything else EPO semanthics in rfkill.
> 
> 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)

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.

So, my ThinkPad T43 would NEVER issue *_RFKILL_ALL events by default.

> And each key really controls the hardware, without any software required.

Works just like a ThinkPad before you set its hotkey mask to request the firmware
to hands-off the hotkeys, then.

> Especially for Laptop one it will not be nice to attack RFKILL_ALL to
> both keys,
> since both control specific radio types.

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

> 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.

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
KEY_RFKILL_ALL (although I didn't propose a KEY_RFKILL_ALL yet).

> 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 switch or not.

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
from ACPI as well, you probably want to let the ACPI driver issue the input events.

> > But of course, you have to make sure the master switch WILL bloody well stay off
> > when off by design.  You engineer it so that all possible failure modes will
> > cause it to go to the off state.
> > 
> > I would really appreciate that the rfkill class would abide to this UI notion for
> > the master rfkill events (*_RFKILL_ALL).
> 
> 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.

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


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF
  2008-05-27 17:41             ` Henrique de Moraes Holschuh
@ 2008-05-27 18:13               ` Ivo van Doorn
  0 siblings, 0 replies; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-27 18:13 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Tuesday 27 May 2008, Henrique de Moraes Holschuh wrote:
> On Tue, 27 May 2008 16:38:04 +0200, "Ivo van Doorn" <ivdoorn@gmail.com> said:
> > > 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,
> > > but I recommend against giving anything else EPO semanthics in rfkill.
> > 
> > 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)
> 
> 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.

Exactly the point I wanted to make. ;)

> > 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 switch or not.
> 
> 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.

And that is exactly how things should work in rfkill. ;)

> > > But of course, you have to make sure the master switch WILL bloody well stay off
> > > when off by design.  You engineer it so that all possible failure modes will
> > > cause it to go to the off state.
> > > 
> > > I would really appreciate that the rfkill class would abide to this UI notion for
> > > the master rfkill events (*_RFKILL_ALL).
> > 
> > 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.
> 
> 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?

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-21  1:44         ` Henrique de Moraes Holschuh
@ 2008-05-29  0:45           ` Henrique de Moraes Holschuh
  2008-05-29 13:02             ` Ivo van Doorn
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-29  0:45 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

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 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).
 
-This is done by providing the user 3 possibilities:
- 1 - The rfkill system handles all events; userspace is not aware of events.
- 2 - The rfkill system handles all events; userspace is informed about the events.
- 3 - The rfkill system does not handle events; userspace handles all events.
+Because of this requirement, userspace support for the keys should not be made
+mandatory.  Because userspace might want to perform some additional smarter
+tasks when the key is pressed, rfkill provides userspace the possibility to
+take over the task to handle the key events.
 
-The buttons to enable and disable the wireless radios are important in
-situations where the user is for example using his laptop on a location where
-wireless radios _must_ be disabled (e.g. airplanes).
-Because of this requirement, userspace support for the keys should not be
-made mandatory. Because userspace might want to perform some additional smarter
-tasks when the key is pressed, rfkill still provides userspace the possibility
-to take over the task to handle the key events.
+===============================================================================
+2: Implementation details
+
+The rfkill class provides kernel drivers with an interface that allows them to
+know when they should enable or disable a wireless network device transmitter.
+
+The rfkill-input module provides the kernel with the ability to implement
+a basic response when the user presses a key or button (or toggles a switch)
+related to rfkill functionality.  This is optional, and can also be done in
+userspace.
+
+The rfkill-input module also provides EPO (emergency power-off) functionality
+for all wireless transmitters.  This function cannot be overriden, and it is
+always active.  rfkill EPO is related to *_RFKILL_ALL input events.
+
+All state changes on rfkill devices are propagated by the rfkill class to a
+notification chain and also to userspace through uevents.
 
 The system inside the kernel has been split into 2 separate sections:
 	1 - RFKILL
 	2 - RFKILL_INPUT
 
-The first option enables rfkill support and will make sure userspace will
-be notified of any events through the input device. It also creates several
-sysfs entries which can be used by userspace. See section "Userspace support".
+The first option enables rfkill support and will make sure userspace will be
+notified of any events through uevents.  It provides a notification chain for
+interested parties in the kernel to also get notified of rfkill state changes
+in other drivers.  It creates several sysfs entries which can be used by
+userspace.  See section "Userspace support".
+
+The second option provides an rfkill input handler. This handler will listen to
+all rfkill key events and will toggle the radio accordingly.  With this option
+enabled userspace could either do nothing or simply perform monitoring tasks.
+
+When a rfkill switch is in the RFKILL_STATE_ON, the wireless transmitter (radio
+TX circuit for example) is *enabled*.  When the rfkill switch is in the
+RFKILL_STATE_OFF, the wireless transmitter is to be *blocked* from operating.
+
+Full rfkill functionality requires two different subsystems to cooperate: the
+input layer and the rfkill class.  The input layer issues *commands* to the
+entire system requesting that devices registered to the rfkill class change
+state.  The way this interaction happens is not complex, but it is not obvious
+either:
+
+Kernel Input layer:
+
+	* Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
+	  other such events when the user presses certain keys, buttons, or
+	  toggles certain physical switches.
+
+	THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE
+	KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT.  It is
+	used to issue *commands* for the system to change behaviour, and these
+	commands may or may not be carried out by some kernel driver or
+	userspace application.  It follows that doing user feedback based only
+	on input events is broken, there is no guarantee that an input event
+	will be acted upon.
+
+	Most wireless communication device drivers implementing rfkill
+	functionality MUST NOT generate these events, and have no reason to
+	register themselves with the input layer.  This is a common
+	misconception.  There is an API to propagate rfkill status change
+	information, and it is NOT the input layer.
+
+rfkill class:
+
+	* Calls a hook in a driver to effectively change the wireless
+	  transmitter state;
+	* Keeps track of the wireless transmitter state (with help from
+	  the driver);
+	* Generates userspace notifications (uevents) and a call to a
+	  notification chain (kernel) when there is a wireless transmitter
+	  state change;
+	* Connects a wireless communications driver with the common rfkill
+	  control system, which, for example, allows actions such as
+	  "switch all bluetooth devices offline" to be carried out by
+	  userspace or by rfkill-input.
+
+	THE RFKILL CLASS NEVER ISSUES INPUT EVENTS.  THE RFKILL CLASS DOES
+	NOT LISTEN TO INPUT EVENTS.  NO DRIVER USING THE RFKILL CLASS SHALL
+	EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS.
+
+	Most wireless data communication drivers in the kernel have just to
+	implement the rfkill class API to work properly.  Interfacing to the
+	input layer is not often required (and is very often a *bug*).
+
+Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
+
+	* Implements the policy of what should happen when one of the input
+	  layer events related to rfkill operation is received.
+	* Uses the sysfs interface (userspace) or private rfkill API calls
+	  to tell the devices registered with the rfkill class to change
+	  their state (i.e. translates the input layer event into real
+	  action).
+	* rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0
+	  (power off all transmitters) in a special way: it ignores any
+	  overrides and local state cache and forces all transmitters to
+	  the OFF state (including those which are already supposed to be
+	  OFF).  Note that the opposite event (power on all transmitters)
+	  is handled normally.
+
+Userspace uevent handler or kernel platform-specific drivers hooked to the
+rfkill notifier chain:
+
+	* Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,
+	  in order to know when a device that is registered with the rfkill
+	  class changes state;
+	* Issues feedback notifications to the user;
+	* In the rare platforms where this is required, synthesizes an input
+	  event to command all *OTHER* rfkill devices to also change their
+	  statues when a specific rfkill device changes state.
+
+
+===============================================================================
+3: Kernel driver guidelines
+
+The first thing one needs to know is whether his driver should be talking to
+the rfkill class or to the input layer.
+
+Do not mistake input devices for rfkill devices.  The only type of "rfkill
+switch" device that is to be registered with the rfkill class are those
+directly controlling the circuits that cause a wireless transmitter to stop
+working (or the software equivalent of them).  Every other kind of "rfkill
+switch" is just an input device and MUST NOT be registered with the rfkill
+class.
+
+A driver should register a device with the rfkill class when ALL of the
+following conditions are met:
+
+1. The device is/controls a data communications wireless transmitter;
+
+2. The kernel can interact with the hardware/firmware to CHANGE the wireless
+   transmitter state (block/unblock TX operation);
+
+A driver should register a device with the input subsystem to issue
+rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,
+SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:
+
+1. It is directly related to some physical device the user interacts with, to
+   command the O.S./firmware/hardware to enable/disable a data communications
+   wireless transmitter.
+
+   Examples of the physical device are: buttons, keys and switches the user
+   will press/touch/slide/switch to enable or disable the wireless
+   communication device.
+
+2. It is NOT slaved to another device, i.e. there is no other device that
+   issues rfkill-related input events in preference to this one.
+
+   Typically, the ACPI "radio kill" switch of a laptop is the master input
+   device to issue rfkill events, and, e.g., the WLAN card is just a slave
+   device that gets disabled by its hardware radio-kill input pin.
 
-The second option provides an rfkill input handler. This handler will
-listen to all rfkill key events and will toggle the radio accordingly.
-With this option enabled userspace could either do nothing or simply
-perform monitoring tasks.
+When in doubt, do not issue input events.  For drivers that should generate
+input events in some platforms, but not in others (e.g. b43), the best solution
+is to NEVER generate input events in the first place.  That work should be
+deferred to a platform-specific kernel module (which will know when to generate
+events through the rfkill notifier chain) or to userspace.  This avoids the
+usual maintenance problems with DMI whitelisting.
 
+
+Corner cases and examples:
 ====================================
-2: Driver support
 
-To build a driver with rfkill subsystem support, the driver should
-depend on the Kconfig symbol RFKILL; it should _not_ depend on
-RKFILL_INPUT.
+1. If the device is an input device that, because of hardware or firmware,
+causes wireless transmitters to be blocked regardless of the kernel's will, it
+is still just an input device, and NOT to be registered with the rfkill class.
 
-Unless key events trigger an interrupt to which the driver listens, polling
-will be required to determine the key state changes. For this the input
-layer providers the input-polldev handler.
+2. If the wireless transmitter switch control is read-only, it is an input
+device and not to be registered with the rfkill class (and maybe not to be made
+an input layer event source either, see below).
 
-A driver should implement a few steps to correctly make use of the
-rfkill subsystem. First for non-polling drivers:
+3. If there is some other device driver *closer* to the actual hardware the
+user interacted with (the button/switch/key) to issue an input event, THAT is
+the device driver that should be issuing input events.
 
-	- rfkill_allocate()
-	- input_allocate_device()
-	- rfkill_register()
-	- input_register_device()
+E.g:
+  [RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
+                           (platform driver)    (wireless card driver)
+
+The user is closer to the RFKILL slide switch plaform driver, so the driver
+which must issue input events is the platform driver looking at the GPIO
+hardware, and NEVER the wireless card driver (which is just a slave).  It is
+very likely that there are other leaves than just the WLAN card rf-kill input
+(e.g. a bluetooth card, etc)...
+
+On the other hand, some embedded devices do this:
+
+  [RFKILL slider switch] -- [WLAN card rf-kill input]
+                             (wireless card driver)
+
+In this situation, the wireless card driver *could* register itself as an input
+device and issue rf-kill related input events... but in order to AVOID the need
+for DMI whitelisting, the wireless card driver does NOT do it.  Userspace (HAL)
+or a platform driver (that exists only on these embedded devices) will do the
+dirty job of issuing the input events.
+
+
+COMMON MISTAKES in kernel drivers, related to rfkill:
+====================================
+
+1. NEVER confuse input device keys and buttons with input device switches.
+
+  1a. Switches are always set or reset.  They report the current state
+      (on position or off position).
+
+  1b. Keys and buttons are either in the pressed or not-pressed state, and
+      that's it.  A "button" that latches down when you press it, and
+      unlatches when you press it again is in fact a switch as far as input
+      devices go.
+
+Add the SW_* events you need for switches, do NOT try to emulate a button using
+KEY_* events just because there is no such SW_* event yet.  Do NOT try to use,
+for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
+
+2. Input device switches (sources of EV_SW events) DO store their current
+state, and that state CAN be queried from userspace through IOCTLs.  There is
+no sysfs interface for this, but that doesn't mean you should break things
+trying to hook it to the rfkill class to get a sysfs interface :-)
+
+3. Do not issue *_RFKILL_ALL events, unless you are sure it is the correct
+event for your switch/button.  These events are emergency power-off events when
+they are trying to turn the transmitters off.  An example of an input device
+which SHOULD generate *_RFKILL_ALL events is the wireless-kill switch in a
+laptop which is NOT a hotkey, but a real switch that kills radios in hardware,
+even if the O.S. has gone to lunch.  An example of an input device which SHOULD
+NOT generate *_RFKILL_ALL events is any sort of hot key that does nothing by
+itself, as well as any hot key that is type-specific (e.g. the one for WLAN).
+
+
+===============================================================================
+4: Kernel API
+
+To build a driver with rfkill subsystem support, the driver should depend on
+the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
+
+The hardware the driver talks to may be write-only (where the current state
+of the hardware is unknown), or read-write (where the hardware can be queried
+about its current state).
+
+The rfkill class will call the get_state hook of a device every time it needs
+to know the *real* current state of the hardware.  This can happen often.
+
+Some hardware provides events when its status changes.  In these cases, it is
+best for the driver to not provide a get_state hook, and instead register the
+rfkill class *already* with the correct status, and keep it updated using
+rfkill_force_state() when it gets an event from the hardware.
 
-For polling drivers:
+There is no provision for a statically-allocated rfkill struct.  You must
+use rfkill_allocate() to allocate one.
 
+You should:
 	- rfkill_allocate()
-	- input_allocate_polled_device()
+	- modify rfkill fields (flags, name)
+	- modify state to the current hardware state (THIS IS THE ONLY TIME
+	  YOU CAN ACCESS state DIRECTLY)
 	- rfkill_register()
-	- input_register_polled_device()
 
-When a key event has been detected, the correct event should be
-sent over the input device which has been registered by the driver.
+Please refer to the source for more documentation.
 
-====================================
-3: Userspace support
+===============================================================================
+5: Userspace support
+
+rfkill devices issue uevents (with an action of "change"), with the following
+environment variables set:
+
+RFKILL_NAME
+RFKILL_STATE
+RFKILL_TYPE
 
-For each key an input device will be created which will send out the correct
-key event when the rfkill key has been pressed.
+The ABI for these variables is defined by the sysfs attributes.  It is best
+to take a quick look at the source to make sure of the possible values.
+
+It is expected that HAL will trap those, and bridge them to DBUS, etc.  These
+events CAN and SHOULD be used to give feedback to the user about the rfkill
+status of the system.
+
+Input devices may issue events that are related to rfkill.  These are the
+various KEY_* events and SW_* events supported by rfkill-input.c.
+
+******IMPORTANT******
+When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF AN RFKILL
+SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it
+has set to true the user_claim attribute for that particular switch.  This rule
+is *absolute*; do NOT violate it.
+******IMPORTANT******
+
+Userspace must not assume it is the only source of control for rfkill switches.
+Their state CAN and WILL change on its own, due to firmware actions, direct
+user actions, and the rfkill-input EPO override for *_RFKILL_ALL.
+
+When rfkill-input is not active, userspace must initiate an rfkill status
+change by writing to the "state" attribute in order for anything to happen.
+
+Take particular care to implement EV_SW SW_RFKILL_ALL properly.  When that
+switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
+OFF state, no questions asked.
 
 The following sysfs entries will be created:
 
@@ -89,8 +333,16 @@ The following sysfs entries will be created:
 Both the "state" and "claim" entries are also writable. For the "state" entry
 this means that when 1 or 0 is written all radios, not yet in the requested
 state, will be will be toggled accordingly.
+
 For the "claim" entry writing 1 to it means that the kernel no longer handles
 key events even though RFKILL_INPUT input was enabled. When "claim" has been
 set to 0, userspace should make sure that it listens for the input events or
-check the sysfs "state" entry regularly to correctly perform the required
-tasks when the rkfill key is pressed.
+check the sysfs "state" entry regularly to correctly perform the required tasks
+when the rkfill key is pressed.
+
+A note about input devices and EV_SW events:
+
+In order to know the current state of an input device switch (like
+SW_RFKILL_ALL), you will need to use an IOCTL.  That information is not
+available through sysfs in a generic way at this time, and it is not available
+through the rfkill class AT ALL.
-- 
1.5.5.2


-- 
  "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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-29  0:45           ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2) Henrique de Moraes Holschuh
@ 2008-05-29 13:02             ` Ivo van Doorn
  2008-05-29 16:26               ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-29 13:02 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> 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?

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

Ivo

> ---
>  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 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).
>  
> -This is done by providing the user 3 possibilities:
> - 1 - The rfkill system handles all events; userspace is not aware of events.
> - 2 - The rfkill system handles all events; userspace is informed about the events.
> - 3 - The rfkill system does not handle events; userspace handles all events.
> +Because of this requirement, userspace support for the keys should not be made
> +mandatory.  Because userspace might want to perform some additional smarter
> +tasks when the key is pressed, rfkill provides userspace the possibility to
> +take over the task to handle the key events.
>  
> -The buttons to enable and disable the wireless radios are important in
> -situations where the user is for example using his laptop on a location where
> -wireless radios _must_ be disabled (e.g. airplanes).
> -Because of this requirement, userspace support for the keys should not be
> -made mandatory. Because userspace might want to perform some additional smarter
> -tasks when the key is pressed, rfkill still provides userspace the possibility
> -to take over the task to handle the key events.
> +===============================================================================
> +2: Implementation details
> +
> +The rfkill class provides kernel drivers with an interface that allows them to
> +know when they should enable or disable a wireless network device transmitter.
> +
> +The rfkill-input module provides the kernel with the ability to implement
> +a basic response when the user presses a key or button (or toggles a switch)
> +related to rfkill functionality.  This is optional, and can also be done in
> +userspace.
> +
> +The rfkill-input module also provides EPO (emergency power-off) functionality
> +for all wireless transmitters.  This function cannot be overriden, and it is
> +always active.  rfkill EPO is related to *_RFKILL_ALL input events.
> +
> +All state changes on rfkill devices are propagated by the rfkill class to a
> +notification chain and also to userspace through uevents.
>  
>  The system inside the kernel has been split into 2 separate sections:
>  	1 - RFKILL
>  	2 - RFKILL_INPUT
>  
> -The first option enables rfkill support and will make sure userspace will
> -be notified of any events through the input device. It also creates several
> -sysfs entries which can be used by userspace. See section "Userspace support".
> +The first option enables rfkill support and will make sure userspace will be
> +notified of any events through uevents.  It provides a notification chain for
> +interested parties in the kernel to also get notified of rfkill state changes
> +in other drivers.  It creates several sysfs entries which can be used by
> +userspace.  See section "Userspace support".
> +
> +The second option provides an rfkill input handler. This handler will listen to
> +all rfkill key events and will toggle the radio accordingly.  With this option
> +enabled userspace could either do nothing or simply perform monitoring tasks.
> +
> +When a rfkill switch is in the RFKILL_STATE_ON, the wireless transmitter (radio
> +TX circuit for example) is *enabled*.  When the rfkill switch is in the
> +RFKILL_STATE_OFF, the wireless transmitter is to be *blocked* from operating.
> +
> +Full rfkill functionality requires two different subsystems to cooperate: the
> +input layer and the rfkill class.  The input layer issues *commands* to the
> +entire system requesting that devices registered to the rfkill class change
> +state.  The way this interaction happens is not complex, but it is not obvious
> +either:
> +
> +Kernel Input layer:
> +
> +	* Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
> +	  other such events when the user presses certain keys, buttons, or
> +	  toggles certain physical switches.
> +
> +	THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE
> +	KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT.  It is
> +	used to issue *commands* for the system to change behaviour, and these
> +	commands may or may not be carried out by some kernel driver or
> +	userspace application.  It follows that doing user feedback based only
> +	on input events is broken, there is no guarantee that an input event
> +	will be acted upon.
> +
> +	Most wireless communication device drivers implementing rfkill
> +	functionality MUST NOT generate these events, and have no reason to
> +	register themselves with the input layer.  This is a common
> +	misconception.  There is an API to propagate rfkill status change
> +	information, and it is NOT the input layer.
> +
> +rfkill class:
> +
> +	* Calls a hook in a driver to effectively change the wireless
> +	  transmitter state;
> +	* Keeps track of the wireless transmitter state (with help from
> +	  the driver);
> +	* Generates userspace notifications (uevents) and a call to a
> +	  notification chain (kernel) when there is a wireless transmitter
> +	  state change;
> +	* Connects a wireless communications driver with the common rfkill
> +	  control system, which, for example, allows actions such as
> +	  "switch all bluetooth devices offline" to be carried out by
> +	  userspace or by rfkill-input.
> +
> +	THE RFKILL CLASS NEVER ISSUES INPUT EVENTS.  THE RFKILL CLASS DOES
> +	NOT LISTEN TO INPUT EVENTS.  NO DRIVER USING THE RFKILL CLASS SHALL
> +	EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS.
> +
> +	Most wireless data communication drivers in the kernel have just to
> +	implement the rfkill class API to work properly.  Interfacing to the
> +	input layer is not often required (and is very often a *bug*).
> +
> +Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
> +
> +	* Implements the policy of what should happen when one of the input
> +	  layer events related to rfkill operation is received.
> +	* Uses the sysfs interface (userspace) or private rfkill API calls
> +	  to tell the devices registered with the rfkill class to change
> +	  their state (i.e. translates the input layer event into real
> +	  action).
> +	* rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0
> +	  (power off all transmitters) in a special way: it ignores any
> +	  overrides and local state cache and forces all transmitters to
> +	  the OFF state (including those which are already supposed to be
> +	  OFF).  Note that the opposite event (power on all transmitters)
> +	  is handled normally.
> +
> +Userspace uevent handler or kernel platform-specific drivers hooked to the
> +rfkill notifier chain:
> +
> +	* Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,
> +	  in order to know when a device that is registered with the rfkill
> +	  class changes state;
> +	* Issues feedback notifications to the user;
> +	* In the rare platforms where this is required, synthesizes an input
> +	  event to command all *OTHER* rfkill devices to also change their
> +	  statues when a specific rfkill device changes state.
> +
> +
> +===============================================================================
> +3: Kernel driver guidelines
> +
> +The first thing one needs to know is whether his driver should be talking to
> +the rfkill class or to the input layer.
> +
> +Do not mistake input devices for rfkill devices.  The only type of "rfkill
> +switch" device that is to be registered with the rfkill class are those
> +directly controlling the circuits that cause a wireless transmitter to stop
> +working (or the software equivalent of them).  Every other kind of "rfkill
> +switch" is just an input device and MUST NOT be registered with the rfkill
> +class.
> +
> +A driver should register a device with the rfkill class when ALL of the
> +following conditions are met:
> +
> +1. The device is/controls a data communications wireless transmitter;
> +
> +2. The kernel can interact with the hardware/firmware to CHANGE the wireless
> +   transmitter state (block/unblock TX operation);
> +
> +A driver should register a device with the input subsystem to issue
> +rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,
> +SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:
> +
> +1. It is directly related to some physical device the user interacts with, to
> +   command the O.S./firmware/hardware to enable/disable a data communications
> +   wireless transmitter.
> +
> +   Examples of the physical device are: buttons, keys and switches the user
> +   will press/touch/slide/switch to enable or disable the wireless
> +   communication device.
> +
> +2. It is NOT slaved to another device, i.e. there is no other device that
> +   issues rfkill-related input events in preference to this one.
> +
> +   Typically, the ACPI "radio kill" switch of a laptop is the master input
> +   device to issue rfkill events, and, e.g., the WLAN card is just a slave
> +   device that gets disabled by its hardware radio-kill input pin.
>  
> -The second option provides an rfkill input handler. This handler will
> -listen to all rfkill key events and will toggle the radio accordingly.
> -With this option enabled userspace could either do nothing or simply
> -perform monitoring tasks.
> +When in doubt, do not issue input events.  For drivers that should generate
> +input events in some platforms, but not in others (e.g. b43), the best solution
> +is to NEVER generate input events in the first place.  That work should be
> +deferred to a platform-specific kernel module (which will know when to generate
> +events through the rfkill notifier chain) or to userspace.  This avoids the
> +usual maintenance problems with DMI whitelisting.
>  
> +
> +Corner cases and examples:
>  ====================================
> -2: Driver support
>  
> -To build a driver with rfkill subsystem support, the driver should
> -depend on the Kconfig symbol RFKILL; it should _not_ depend on
> -RKFILL_INPUT.
> +1. If the device is an input device that, because of hardware or firmware,
> +causes wireless transmitters to be blocked regardless of the kernel's will, it
> +is still just an input device, and NOT to be registered with the rfkill class.
>  
> -Unless key events trigger an interrupt to which the driver listens, polling
> -will be required to determine the key state changes. For this the input
> -layer providers the input-polldev handler.
> +2. If the wireless transmitter switch control is read-only, it is an input
> +device and not to be registered with the rfkill class (and maybe not to be made
> +an input layer event source either, see below).
>  
> -A driver should implement a few steps to correctly make use of the
> -rfkill subsystem. First for non-polling drivers:
> +3. If there is some other device driver *closer* to the actual hardware the
> +user interacted with (the button/switch/key) to issue an input event, THAT is
> +the device driver that should be issuing input events.
>  
> -	- rfkill_allocate()
> -	- input_allocate_device()
> -	- rfkill_register()
> -	- input_register_device()
> +E.g:
> +  [RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
> +                           (platform driver)    (wireless card driver)
> +
> +The user is closer to the RFKILL slide switch plaform driver, so the driver
> +which must issue input events is the platform driver looking at the GPIO
> +hardware, and NEVER the wireless card driver (which is just a slave).  It is
> +very likely that there are other leaves than just the WLAN card rf-kill input
> +(e.g. a bluetooth card, etc)...
> +
> +On the other hand, some embedded devices do this:
> +
> +  [RFKILL slider switch] -- [WLAN card rf-kill input]
> +                             (wireless card driver)
> +
> +In this situation, the wireless card driver *could* register itself as an input
> +device and issue rf-kill related input events... but in order to AVOID the need
> +for DMI whitelisting, the wireless card driver does NOT do it.  Userspace (HAL)
> +or a platform driver (that exists only on these embedded devices) will do the
> +dirty job of issuing the input events.
> +
> +
> +COMMON MISTAKES in kernel drivers, related to rfkill:
> +====================================
> +
> +1. NEVER confuse input device keys and buttons with input device switches.
> +
> +  1a. Switches are always set or reset.  They report the current state
> +      (on position or off position).
> +
> +  1b. Keys and buttons are either in the pressed or not-pressed state, and
> +      that's it.  A "button" that latches down when you press it, and
> +      unlatches when you press it again is in fact a switch as far as input
> +      devices go.
> +
> +Add the SW_* events you need for switches, do NOT try to emulate a button using
> +KEY_* events just because there is no such SW_* event yet.  Do NOT try to use,
> +for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
> +
> +2. Input device switches (sources of EV_SW events) DO store their current
> +state, and that state CAN be queried from userspace through IOCTLs.  There is
> +no sysfs interface for this, but that doesn't mean you should break things
> +trying to hook it to the rfkill class to get a sysfs interface :-)
> +
> +3. Do not issue *_RFKILL_ALL events, unless you are sure it is the correct
> +event for your switch/button.  These events are emergency power-off events when
> +they are trying to turn the transmitters off.  An example of an input device
> +which SHOULD generate *_RFKILL_ALL events is the wireless-kill switch in a
> +laptop which is NOT a hotkey, but a real switch that kills radios in hardware,
> +even if the O.S. has gone to lunch.  An example of an input device which SHOULD
> +NOT generate *_RFKILL_ALL events is any sort of hot key that does nothing by
> +itself, as well as any hot key that is type-specific (e.g. the one for WLAN).
> +
> +
> +===============================================================================
> +4: Kernel API
> +
> +To build a driver with rfkill subsystem support, the driver should depend on
> +the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
> +
> +The hardware the driver talks to may be write-only (where the current state
> +of the hardware is unknown), or read-write (where the hardware can be queried
> +about its current state).
> +
> +The rfkill class will call the get_state hook of a device every time it needs
> +to know the *real* current state of the hardware.  This can happen often.
> +
> +Some hardware provides events when its status changes.  In these cases, it is
> +best for the driver to not provide a get_state hook, and instead register the
> +rfkill class *already* with the correct status, and keep it updated using
> +rfkill_force_state() when it gets an event from the hardware.
>  
> -For polling drivers:
> +There is no provision for a statically-allocated rfkill struct.  You must
> +use rfkill_allocate() to allocate one.
>  
> +You should:
>  	- rfkill_allocate()
> -	- input_allocate_polled_device()
> +	- modify rfkill fields (flags, name)
> +	- modify state to the current hardware state (THIS IS THE ONLY TIME
> +	  YOU CAN ACCESS state DIRECTLY)
>  	- rfkill_register()
> -	- input_register_polled_device()
>  
> -When a key event has been detected, the correct event should be
> -sent over the input device which has been registered by the driver.
> +Please refer to the source for more documentation.
>  
> -====================================
> -3: Userspace support
> +===============================================================================
> +5: Userspace support
> +
> +rfkill devices issue uevents (with an action of "change"), with the following
> +environment variables set:
> +
> +RFKILL_NAME
> +RFKILL_STATE
> +RFKILL_TYPE
>  
> -For each key an input device will be created which will send out the correct
> -key event when the rfkill key has been pressed.
> +The ABI for these variables is defined by the sysfs attributes.  It is best
> +to take a quick look at the source to make sure of the possible values.
> +
> +It is expected that HAL will trap those, and bridge them to DBUS, etc.  These
> +events CAN and SHOULD be used to give feedback to the user about the rfkill
> +status of the system.
> +
> +Input devices may issue events that are related to rfkill.  These are the
> +various KEY_* events and SW_* events supported by rfkill-input.c.
> +
> +******IMPORTANT******
> +When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF AN RFKILL
> +SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it
> +has set to true the user_claim attribute for that particular switch.  This rule
> +is *absolute*; do NOT violate it.
> +******IMPORTANT******
> +
> +Userspace must not assume it is the only source of control for rfkill switches.
> +Their state CAN and WILL change on its own, due to firmware actions, direct
> +user actions, and the rfkill-input EPO override for *_RFKILL_ALL.
> +
> +When rfkill-input is not active, userspace must initiate an rfkill status
> +change by writing to the "state" attribute in order for anything to happen.
> +
> +Take particular care to implement EV_SW SW_RFKILL_ALL properly.  When that
> +switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
> +OFF state, no questions asked.
>  
>  The following sysfs entries will be created:
>  
> @@ -89,8 +333,16 @@ The following sysfs entries will be created:
>  Both the "state" and "claim" entries are also writable. For the "state" entry
>  this means that when 1 or 0 is written all radios, not yet in the requested
>  state, will be will be toggled accordingly.
> +
>  For the "claim" entry writing 1 to it means that the kernel no longer handles
>  key events even though RFKILL_INPUT input was enabled. When "claim" has been
>  set to 0, userspace should make sure that it listens for the input events or
> -check the sysfs "state" entry regularly to correctly perform the required
> -tasks when the rkfill key is pressed.
> +check the sysfs "state" entry regularly to correctly perform the required tasks
> +when the rkfill key is pressed.
> +
> +A note about input devices and EV_SW events:
> +
> +In order to know the current state of an input device switch (like
> +SW_RFKILL_ALL), you will need to use an IOCTL.  That information is not
> +available through sysfs in a generic way at this time, and it is not available
> +through the rfkill class AT ALL.
> -- 
> 1.5.5.2
> 
> 



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-29 13:02             ` Ivo van Doorn
@ 2008-05-29 16:26               ` Henrique de Moraes Holschuh
  2008-05-29 17:19                 ` Ivo van Doorn
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-29 16:26 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Thu, 29 May 2008, Ivo van Doorn wrote:
> > This version better documents *_RFKILL_ALL.  Is it good enough for an
> > ACK for patch 14 of 15?
> 
> Yes, you can put my ack on patch 14.
> Thanks for the documentation update. :)

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-29 16:26               ` Henrique de Moraes Holschuh
@ 2008-05-29 17:19                 ` Ivo van Doorn
  2008-05-29 17:22                   ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-29 17:19 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> On Thu, 29 May 2008, Ivo van Doorn wrote:
> > > This version better documents *_RFKILL_ALL.  Is it good enough for an
> > > ACK for patch 14 of 15?
> > 
> > Yes, you can put my ack on patch 14.
> > Thanks for the documentation update. :)
> 
> 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.

Actually,  I believe the correct merge order would through wireless-dev,
which means the patches should go to John Linville and linux-wireless in the CC.

> 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.

Ivo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-29 17:19                 ` Ivo van Doorn
@ 2008-05-29 17:22                   ` Henrique de Moraes Holschuh
  2008-05-29 17:40                     ` Ivo van Doorn
  2008-06-04  3:11                     ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2) Henrique de Moraes Holschuh
  0 siblings, 2 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-29 17:22 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Thu, 29 May 2008, Ivo van Doorn wrote:
> On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> > On Thu, 29 May 2008, Ivo van Doorn wrote:
> > > > This version better documents *_RFKILL_ALL.  Is it good enough for an
> > > > ACK for patch 14 of 15?
> > > 
> > > Yes, you can put my ack on patch 14.
> > > Thanks for the documentation update. :)
> > 
> > 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.
> 
> Actually,  I believe the correct merge order would through wireless-dev,
> which means the patches should go to John Linville and linux-wireless in the CC.

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-29 17:22                   ` Henrique de Moraes Holschuh
@ 2008-05-29 17:40                     ` Ivo van Doorn
  2008-05-29 17:46                       ` Henrique de Moraes Holschuh
  2008-06-04  3:11                     ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2) Henrique de Moraes Holschuh
  1 sibling, 1 reply; 58+ messages in thread
From: Ivo van Doorn @ 2008-05-29 17:40 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh
  Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> On Thu, 29 May 2008, Ivo van Doorn wrote:
> > On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> > > On Thu, 29 May 2008, Ivo van Doorn wrote:
> > > > > This version better documents *_RFKILL_ALL.  Is it good enough for an
> > > > > ACK for patch 14 of 15?
> > > > 
> > > > Yes, you can put my ack on patch 14.
> > > > Thanks for the documentation update. :)
> > > 
> > > 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.
> > 
> > Actually,  I believe the correct merge order would through wireless-dev,
> > which means the patches should go to John Linville and linux-wireless in the CC.
> 
> 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?

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-29 17:40                     ` Ivo van Doorn
@ 2008-05-29 17:46                       ` Henrique de Moraes Holschuh
  2008-05-29 18:58                         ` Dmitry Torokhov
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-29 17:46 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Thu, 29 May 2008, Ivo van Doorn wrote:
> On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> > On Thu, 29 May 2008, Ivo van Doorn wrote:
> > > On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> > > > On Thu, 29 May 2008, Ivo van Doorn wrote:
> > > > > > This version better documents *_RFKILL_ALL.  Is it good enough for an
> > > > > > ACK for patch 14 of 15?
> > > > > 
> > > > > Yes, you can put my ack on patch 14.
> > > > > Thanks for the documentation update. :)
> > > > 
> > > > 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.
> > > 
> > > Actually,  I believe the correct merge order would through wireless-dev,
> > > which means the patches should go to John Linville and linux-wireless in the CC.
> > 
> > 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?
> 
> 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.

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-29 17:46                       ` Henrique de Moraes Holschuh
@ 2008-05-29 18:58                         ` Dmitry Torokhov
  2008-05-29 21:16                           ` Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Dmitry Torokhov @ 2008-05-29 18:58 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh; +Cc: Ivo van Doorn, linux-kernel, Thomas Renninger

On Thu, May 29, 2008 at 02:46:21PM -0300, Henrique de Moraes Holschuh wrote:
> On Thu, 29 May 2008, Ivo van Doorn wrote:
> > On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> > > On Thu, 29 May 2008, Ivo van Doorn wrote:
> > > > On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> > > > > On Thu, 29 May 2008, Ivo van Doorn wrote:
> > > > > > > This version better documents *_RFKILL_ALL.  Is it good enough for an
> > > > > > > ACK for patch 14 of 15?
> > > > > > 
> > > > > > Yes, you can put my ack on patch 14.
> > > > > > Thanks for the documentation update. :)
> > > > > 
> > > > > 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.
> > > > 
> > > > Actually,  I believe the correct merge order would through wireless-dev,
> > > > which means the patches should go to John Linville and linux-wireless in the CC.
> > > 
> > > 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?
> > 
> > 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.
> 
> 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.
> 

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-29 18:58                         ` Dmitry Torokhov
@ 2008-05-29 21:16                           ` Henrique de Moraes Holschuh
  2008-05-29 21:25                             ` [PATCH] Input: rename SW_RADIO to SW_RFKILL_ALL (v2) Henrique de Moraes Holschuh
  0 siblings, 1 reply; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-29 21:16 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Ivo van Doorn, linux-kernel, Thomas Renninger

On Thu, 29 May 2008, Dmitry Torokhov wrote:
> 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.

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
they never modify anything in ACPI proper.

> 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.

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH] Input: rename SW_RADIO to SW_RFKILL_ALL (v2)
  2008-05-29 21:16                           ` Henrique de Moraes Holschuh
@ 2008-05-29 21:25                             ` Henrique de Moraes Holschuh
  0 siblings, 0 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-05-29 21:25 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-kernel, Henrique de Moraes Holschuh, Ivo van Doorn

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 int __init hotkey_init(struct ibm_init_struct *iibm)
 
 		if (tp_features.hotkey_wlsw) {
 			set_bit(EV_SW, tpacpi_inputdev->evbit);
-			set_bit(SW_RADIO, tpacpi_inputdev->swbit);
+			set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit);
 		}
 		if (tp_features.hotkey_tablet) {
 			set_bit(EV_SW, tpacpi_inputdev->evbit);
diff --git a/include/linux/input.h b/include/linux/input.h
index 28a094f..e075c4b 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -637,7 +637,9 @@ struct input_absinfo {
 #define SW_LID			0x00  /* set = lid shut */
 #define SW_TABLET_MODE		0x01  /* set = tablet mode */
 #define SW_HEADPHONE_INSERT	0x02  /* set = inserted */
-#define SW_RADIO		0x03  /* set = radio enabled */
+#define SW_RFKILL_ALL		0x03  /* rfkill master switch, type "any"
+					 set = radio enabled */
+#define SW_RADIO		SW_RFKILL_ALL	/* deprecated */
 #define SW_MAX			0x0f
 #define SW_CNT			(SW_MAX+1)
 
-- 
1.5.5.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2)
  2008-05-29 17:22                   ` Henrique de Moraes Holschuh
  2008-05-29 17:40                     ` Ivo van Doorn
@ 2008-06-04  3:11                     ` Henrique de Moraes Holschuh
  1 sibling, 0 replies; 58+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-06-04  3:11 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: linux-kernel, Thomas Renninger, Dmitry Torokhov

On Thu, 29 May 2008, Henrique de Moraes Holschuh wrote:
> On Thu, 29 May 2008, Ivo van Doorn wrote:
> > On Thursday 29 May 2008, Henrique de Moraes Holschuh wrote:
> > > On Thu, 29 May 2008, Ivo van Doorn wrote:
> > > > > This version better documents *_RFKILL_ALL.  Is it good enough for an
> > > > > ACK for patch 14 of 15?
> > > > 
> > > > Yes, you can put my ack on patch 14.
> > > > Thanks for the documentation update. :)
> > > 
> > > 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.
> > 
> > Actually,  I believe the correct merge order would through wireless-dev,
> > which means the patches should go to John Linville and linux-wireless in the CC.
> 
> 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.

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2008-06-04  3:12 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-18 18:47 [RFC] rfkill class rework Henrique de Moraes Holschuh
2008-05-18 18:47 ` [PATCH 01/15] ACPI: thinkpad-acpi: fix initialization error paths Henrique de Moraes Holschuh
2008-05-18 18:47 ` [PATCH 02/15] ACPI: thinkpad-acpi: fix LED handling on older ThinkPads Henrique de Moraes Holschuh
2008-05-18 18:47 ` [PATCH 03/15] Input: rename SW_RADIO to SW_RFKILL_ALL (v2) Henrique de Moraes Holschuh
2008-05-18 18:47 ` [PATCH 04/15] rfkill: clarify meaning of rfkill states Henrique de Moraes Holschuh
2008-05-20 10:08   ` Ivo van Doorn
2008-05-18 18:47 ` [PATCH 05/15] rfkill: fix minor typo in kernel doc Henrique de Moraes Holschuh
2008-05-20 10:08   ` Ivo van Doorn
2008-05-18 18:47 ` [PATCH 06/15] rfkill: handle SW_RFKILL_ALL events Henrique de Moraes Holschuh
2008-05-20 10:08   ` Ivo van Doorn
2008-05-18 18:47 ` [PATCH 07/15] rfkill: add parameter to disable radios by default Henrique de Moraes Holschuh
2008-05-18 18:47 ` [PATCH 08/15] rfkill: add read-write rfkill switch support Henrique de Moraes Holschuh
2008-05-20 10:08   ` Ivo van Doorn
2008-05-18 18:47 ` [PATCH 09/15] rfkill: add the WWAN radio type Henrique de Moraes Holschuh
2008-05-20 10:08   ` Ivo van Doorn
2008-05-21  1:12     ` Henrique de Moraes Holschuh
2008-05-21  3:35       ` Inaky Perez-Gonzalez
2008-05-21  3:42         ` Henrique de Moraes Holschuh
2008-05-21  6:48           ` Inaky Perez-Gonzalez
2008-05-21 14:07             ` Henrique de Moraes Holschuh
2008-05-18 18:48 ` [PATCH 10/15] rfkill: rework suspend and resume handlers Henrique de Moraes Holschuh
2008-05-20 10:08   ` Ivo van Doorn
2008-05-18 18:48 ` [PATCH 11/15] rfkill: add notifier chains support Henrique de Moraes Holschuh
2008-05-19  8:44   ` Thomas Renninger
2008-05-19 13:10     ` Henrique de Moraes Holschuh
2008-05-20 10:09   ` Ivo van Doorn
2008-05-18 18:48 ` [PATCH 12/15] rfkill: add type string helper Henrique de Moraes Holschuh
2008-05-20 10:09   ` Ivo van Doorn
2008-05-18 18:48 ` [PATCH 13/15] rfkill: add uevent notifications Henrique de Moraes Holschuh
2008-05-20 10:09   ` Ivo van Doorn
2008-05-18 18:48 ` [PATCH 14/15] rfkill: do not allow userspace to override ALL RADIOS OFF Henrique de Moraes Holschuh
2008-05-20 10:09   ` Ivo van Doorn
2008-05-22 20:51     ` Henrique de Moraes Holschuh
2008-05-23 14:15       ` Ivo van Doorn
2008-05-27 14:08         ` Henrique de Moraes Holschuh
2008-05-27 14:38           ` Ivo van Doorn
2008-05-27 17:41             ` Henrique de Moraes Holschuh
2008-05-27 18:13               ` Ivo van Doorn
2008-05-18 18:48 ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions Henrique de Moraes Holschuh
2008-05-19 17:51   ` Randy Dunlap
2008-05-19 22:04     ` Henrique de Moraes Holschuh
2008-05-19 22:52     ` Elias Oltmanns
2008-05-19 22:56       ` Randy Dunlap
2008-05-20 10:09   ` Ivo van Doorn
2008-05-20 15:54     ` Henrique de Moraes Holschuh
2008-05-20 17:18       ` Ivo van Doorn
2008-05-21  1:44         ` Henrique de Moraes Holschuh
2008-05-29  0:45           ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2) Henrique de Moraes Holschuh
2008-05-29 13:02             ` Ivo van Doorn
2008-05-29 16:26               ` Henrique de Moraes Holschuh
2008-05-29 17:19                 ` Ivo van Doorn
2008-05-29 17:22                   ` Henrique de Moraes Holschuh
2008-05-29 17:40                     ` Ivo van Doorn
2008-05-29 17:46                       ` Henrique de Moraes Holschuh
2008-05-29 18:58                         ` Dmitry Torokhov
2008-05-29 21:16                           ` Henrique de Moraes Holschuh
2008-05-29 21:25                             ` [PATCH] Input: rename SW_RADIO to SW_RFKILL_ALL (v2) Henrique de Moraes Holschuh
2008-06-04  3:11                     ` [PATCH 15/15] rfkill: document rw rfkill switches and clarify input subsystem interactions (v2) Henrique de Moraes Holschuh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).