rfkill: rename the rfkill_state states and add block-locked state
The current naming of rfkill_state causes a lot of confusion: not only the
"kill" in rfkill suggests negative logic, but also the fact that rfkill cannot
turn anything on (it can just force something off or stop forcing something
off) is often forgotten.
Rename RFKILL_STATE_OFF to RFKILL_STATE_SOFT_BLOCKED (transmitter is blocked
and will not operate; state can be changed by a toggle_radio request), and
RFKILL_STATE_ON to RFKILL_STATE_UNBLOCKED (transmitter is not blocked, and may
operate).
Also, add a new third state, RFKILL_STATE_HARD_BLOCKED (transmitter is blocked
and will not operate; state cannot be changed through a toggle_radio request),
which is used by drivers to indicate a wireless transmiter was blocked by a
hardware rfkill line that accepts no overrides.
Keep the old names as #defines, but document them as deprecated. This way,
drivers can be converted to the new names *and* verified to actually use rfkill
correctly one by one.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt
index cf230c1..5316cea 100644
--- a/Documentation/rfkill.txt
+++ b/Documentation/rfkill.txt
@@ -60,9 +60,20 @@
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.
+When a rfkill switch is in the RFKILL_STATE_UNBLOCKED, the wireless transmitter
+(radio TX circuit for example) is *enabled*. When the rfkill switch is in the
+RFKILL_STATE_SOFT_BLOCKED or RFKILL_STATE_HARD_BLOCKED, the wireless
+transmitter is to be *blocked* from operating.
+
+RFKILL_STATE_SOFT_BLOCKED indicates that a call to toggle_radio() can change
+that state. RFKILL_STATE_HARD_BLOCKED indicates that a call to toggle_radio()
+will not be able to change the state and will return with a suitable error if
+attempts are made to set the state to RFKILL_STATE_UNBLOCKED.
+
+RFKILL_STATE_HARD_BLOCKED is used by drivers to signal that the device is
+locked in the BLOCKED state by a hardwire rfkill line (typically an input pin
+that, when active, forces the transmitter to be disabled) which the driver
+CANNOT override.
Full rfkill functionality requires two different subsystems to cooperate: the
input layer and the rfkill class. The input layer issues *commands* to the
@@ -122,10 +133,10 @@
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.
+ overrides and local state cache and forces all transmitters to the
+ RFKILL_STATE_SOFT_BLOCKED state (including those which are already
+ supposed to be BLOCKED). 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:
@@ -284,6 +295,19 @@
YOU CAN ACCESS state DIRECTLY)
- rfkill_register()
+The only way to set a device to the RFKILL_STATE_HARD_BLOCKED state is through
+a suitable return of get_state() or through rfkill_force_state().
+
+When a device is in the RFKILL_STATE_HARD_BLOCKED state, the only way to switch
+it to a different state is through a suitable return of get_state() or through
+rfkill_force_state().
+
+If toggle_radio() is called to set a device to state RFKILL_STATE_SOFT_BLOCKED
+when that device is already at the RFKILL_STATE_HARD_BLOCKED state, it should
+not return an error. Instead, it should try to double-block the transmitter,
+so that its state will change from RFKILL_STATE_HARD_BLOCKED to
+RFKILL_STATE_SOFT_BLOCKED should the hardware blocking cease.
+
Please refer to the source for more documentation.
===============================================================================
@@ -322,13 +346,27 @@
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.
+RFKILL_STATE_SOFT_BLOCKED state, no questions asked.
The following sysfs entries will be created:
name: Name assigned by driver to this key (interface or driver name).
type: Name of the key type ("wlan", "bluetooth", etc).
- state: Current state of the key. 1: On, 0: Off.
+ state: Current state of the transmitter
+ 0: RFKILL_STATE_SOFT_BLOCKED
+ transmitter is forced off, but you can override it
+ by a write to the state attribute, or through input
+ events (if rfkill-input is loaded).
+ 1: RFKILL_STATE_UNBLOCKED
+ transmiter is NOT forced off, and may operate if
+ all other conditions for such operation are met
+ (such as interface is up and configured, etc).
+ 2: RFKILL_STATE_HARD_BLOCKED
+ transmitter is forced off by something outside of
+ the driver's control.
+
+ You cannot set a device to this state through
+ writes to the state attribute.
claim: 1: Userspace handles events, 0: Kernel handles events
Both the "state" and "claim" entries are also writable. For the "state" entry