string: factorize skip_spaces and export it to be generally available
[safe/jmp/linux-2.6] / Documentation / rfkill.txt
index cf230c1..b486050 100644 (file)
-rfkill - RF switch subsystem support
-====================================
-
-1 Introduction
-2 Implementation details
-3 Kernel driver guidelines
-4 Kernel API
-5 Userspace support
-
-
-1. Introduction:
-
-The rfkill switch subsystem exists to add a generic interface to circuitry that
-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.
-
-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 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).
-
-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.
-
-===============================================================================
-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.  It is an in-kernel implementation of default
-policy of reacting to rfkill-related input events and neither mandatory nor
-required for wireless drivers to operate.
-
-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 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.
-
-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:
-====================================
+rfkill - RF kill switch support
+===============================
 
-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.
+1. Introduction
+2. Implementation details
+3. Kernel API
+4. Userspace support
 
-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).
 
-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.
+1. Introduction
 
-E.g:
-  [RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
-                           (platform driver)    (wireless card driver)
+The rfkill subsystem provides a generic interface to disabling any radio
+transmitter in the system. When a transmitter is blocked, it shall not
+radiate any power.
 
-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)...
+The subsystem also provides the ability to react on button presses and
+disable all transmitters of a certain type (or all). This is intended for
+situations where transmitters need to be turned off, for example on
+aircraft.
 
-On the other hand, some embedded devices do this:
+The rfkill subsystem has a concept of "hard" and "soft" block, which
+differ little in their meaning (block == transmitters off) but rather in
+whether they can be changed or not:
+ - hard block: read-only radio block that cannot be overriden by software
+ - soft block: writable radio block (need not be readable) that is set by
+               the system software.
 
-  [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.
+2. Implementation details
 
+The rfkill subsystem is composed of three main components:
+ * the rfkill core,
+ * the deprecated rfkill-input module (an input layer handler, being
+   replaced by userspace policy code) and
+ * the rfkill drivers.
 
-COMMON MISTAKES in kernel drivers, related to rfkill:
-====================================
+The rfkill core provides API for kernel drivers to register their radio
+transmitter with the kernel, methods for turning it on and off and, letting
+the system know about hardware-disabled states that may be implemented on
+the device.
 
-1. NEVER confuse input device keys and buttons with input device switches.
+The rfkill core code also notifies userspace of state changes, and provides
+ways for userspace to query the current states. See the "Userspace support"
+section below.
 
-  1a. Switches are always set or reset.  They report the current state
-      (on position or off position).
+When the device is hard-blocked (either by a call to rfkill_set_hw_state()
+or from query_hw_block) set_block() will be invoked for additional software
+block, but drivers can ignore the method call since they can use the return
+value of the function rfkill_set_hw_state() to sync the software state
+instead of keeping track of calls to set_block(). In fact, drivers should
+use the return value of rfkill_set_hw_state() unless the hardware actually
+keeps track of soft and hard block separately.
 
-  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.
+3. Kernel API
 
-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).
+Drivers for radio transmitters normally implement an rfkill driver.
 
+Platform drivers might implement input devices if the rfkill button is just
+that, a button. If that button influences the hardware then you need to
+implement an rfkill driver instead. This also applies if the platform provides
+a way to turn on/off the transmitter(s).
 
-===============================================================================
-4: Kernel API
+For some platforms, it is possible that the hardware state changes during
+suspend/hibernation, in which case it will be necessary to update the rfkill
+core with the current state is at resume time.
 
-To build a driver with rfkill subsystem support, the driver should depend on
-the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
+To create an rfkill driver, driver's Kconfig needs to have
 
-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).
+       depends on RFKILL || !RFKILL
 
-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.
+to ensure the driver cannot be built-in when rfkill is modular. The !RFKILL
+case allows the driver to be built when rfkill is not configured, which which
+case all rfkill API can still be used but will be provided by static inlines
+which compile to almost nothing.
 
-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.
+Calling rfkill_set_hw_state() when a state change happens is required from
+rfkill drivers that control devices that can be hard-blocked unless they also
+assign the poll_hw_block() callback (then the rfkill core will poll the
+device). Don't do this unless you cannot get the event in any other way.
 
-There is no provision for a statically-allocated rfkill struct.  You must
-use rfkill_allocate() to allocate one.
 
-You should:
-       - rfkill_allocate()
-       - modify rfkill fields (flags, name)
-       - modify state to the current hardware state (THIS IS THE ONLY TIME
-         YOU CAN ACCESS state DIRECTLY)
-       - rfkill_register()
 
-Please refer to the source for more documentation.
+5. Userspace support
 
-===============================================================================
-5: Userspace support
+The recommended userspace interface to use is /dev/rfkill, which is a misc
+character device that allows userspace to obtain and set the state of rfkill
+devices and sets of devices. It also notifies userspace about device addition
+and removal. The API is a simple read/write API that is defined in
+linux/rfkill.h, with one ioctl that allows turning off the deprecated input
+handler in the kernel for the transition period.
 
-rfkill devices issue uevents (with an action of "change"), with the following
-environment variables set:
+Except for the one ioctl, communication with the kernel is done via read()
+and write() of instances of 'struct rfkill_event'. In this structure, the
+soft and hard block are properly separated (unlike sysfs, see below) and
+userspace is able to get a consistent snapshot of all rfkill devices in the
+system. Also, it is possible to switch all rfkill drivers (or all drivers of
+a specified type) into a state which also updates the default state for
+hotplugged devices.
 
-RFKILL_NAME
-RFKILL_STATE
-RFKILL_TYPE
-
-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.
+After an application opens /dev/rfkill, it can read the current state of
+all devices, and afterwards can poll the descriptor for hotplug or state
+change events.
 
-******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******
+Applications must ignore operations (the "op" field) they do not handle,
+this allows the API to be extended in the future.
 
-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.
+Additionally, each rfkill device is registered in sysfs and there has the
+following attributes:
 
-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.
+       name: Name assigned by driver to this key (interface or driver name).
+       type: Driver type string ("wlan", "bluetooth", etc).
+       persistent: Whether the soft blocked state is initialised from
+                   non-volatile storage at startup.
+       state: Current state of the transmitter
+               0: RFKILL_STATE_SOFT_BLOCKED
+                       transmitter is turned off by software
+               1: RFKILL_STATE_UNBLOCKED
+                       transmitter is (potentially) active
+               2: RFKILL_STATE_HARD_BLOCKED
+                       transmitter is forced off by something outside of
+                       the driver's control.
+              This file is deprecated because it can only properly show
+              three of the four possible states, soft-and-hard-blocked is
+              missing.
+       claim: 0: Kernel handles events
+              This file is deprecated because there no longer is a way to
+              claim just control over a single rfkill instance.
+
+rfkill devices also issue uevents (with an action of "change"), with the
+following environment variables set:
 
-The following sysfs entries will be created:
+RFKILL_NAME
+RFKILL_STATE
+RFKILL_TYPE
 
-       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.
-       claim: 1: Userspace handles events, 0: Kernel handles events
-
-Both the "state" and "claim" entries are also writable. For the "state" entry
-this means that when 1 or 0 is written, the device rfkill state (if 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.
-
-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.
+The contents of these variables corresponds to the "name", "state" and
+"type" sysfs files explained above.