diff options
Diffstat (limited to 'Documentation/driver-api')
38 files changed, 5670 insertions, 85 deletions
diff --git a/Documentation/driver-api/80211/cfg80211.rst b/Documentation/driver-api/80211/cfg80211.rst new file mode 100644 index 000000000000..eca534ab6172 --- /dev/null +++ b/Documentation/driver-api/80211/cfg80211.rst @@ -0,0 +1,348 @@ +================== +cfg80211 subsystem +================== + +Device registration +=================== + +.. kernel-doc:: include/net/cfg80211.h + :doc: Device registration + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_channel_flags + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_channel + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_rate_flags + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_rate + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_sta_ht_cap + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_supported_band + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_signal_type + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_params_flags + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_flags + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy + +.. kernel-doc:: include/net/cfg80211.h + :functions: wireless_dev + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_new + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_read_of_freq_limits + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_register + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_unregister + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_free + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_name + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_dev + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_priv + +.. kernel-doc:: include/net/cfg80211.h + :functions: priv_to_wiphy + +.. kernel-doc:: include/net/cfg80211.h + :functions: set_wiphy_dev + +.. kernel-doc:: include/net/cfg80211.h + :functions: wdev_priv + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_iface_limit + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_iface_combination + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_check_combinations + +Actions and configuration +========================= + +.. kernel-doc:: include/net/cfg80211.h + :doc: Actions and configuration + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_ops + +.. kernel-doc:: include/net/cfg80211.h + :functions: vif_params + +.. kernel-doc:: include/net/cfg80211.h + :functions: key_params + +.. kernel-doc:: include/net/cfg80211.h + :functions: survey_info_flags + +.. kernel-doc:: include/net/cfg80211.h + :functions: survey_info + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_beacon_data + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_ap_settings + +.. kernel-doc:: include/net/cfg80211.h + :functions: station_parameters + +.. kernel-doc:: include/net/cfg80211.h + :functions: rate_info_flags + +.. kernel-doc:: include/net/cfg80211.h + :functions: rate_info + +.. kernel-doc:: include/net/cfg80211.h + :functions: station_info + +.. kernel-doc:: include/net/cfg80211.h + :functions: monitor_flags + +.. kernel-doc:: include/net/cfg80211.h + :functions: mpath_info_flags + +.. kernel-doc:: include/net/cfg80211.h + :functions: mpath_info + +.. kernel-doc:: include/net/cfg80211.h + :functions: bss_parameters + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_txq_params + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_crypto_settings + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_auth_request + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_assoc_request + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_deauth_request + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_disassoc_request + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_ibss_params + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_connect_params + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_pmksa + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_rx_mlme_mgmt + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_auth_timeout + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_rx_assoc_resp + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_assoc_timeout + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_tx_mlme_mgmt + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_ibss_joined + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_connect_result + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_connect_bss + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_connect_timeout + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_roamed + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_disconnected + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_ready_on_channel + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_remain_on_channel_expired + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_new_sta + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_rx_mgmt + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_mgmt_tx_status + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_cqm_rssi_notify + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_cqm_pktloss_notify + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_michael_mic_failure + +Scanning and BSS list handling +============================== + +.. kernel-doc:: include/net/cfg80211.h + :doc: Scanning and BSS list handling + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_ssid + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_scan_request + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_scan_done + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_bss + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_inform_bss + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_inform_bss_frame_data + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_inform_bss_data + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_unlink_bss + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_find_ie + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_bss_get_ie + +Utility functions +================= + +.. kernel-doc:: include/net/cfg80211.h + :doc: Utility functions + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_channel_to_frequency + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_frequency_to_channel + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_get_channel + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_get_response_rate + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_hdrlen + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_get_hdrlen_from_skb + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_radiotap_iterator + +Data path helpers +================= + +.. kernel-doc:: include/net/cfg80211.h + :doc: Data path helpers + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_data_to_8023 + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_data_from_8023 + +.. kernel-doc:: include/net/cfg80211.h + :functions: ieee80211_amsdu_to_8023s + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_classify8021d + +Regulatory enforcement infrastructure +===================================== + +.. kernel-doc:: include/net/cfg80211.h + :doc: Regulatory enforcement infrastructure + +.. kernel-doc:: include/net/cfg80211.h + :functions: regulatory_hint + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_apply_custom_regulatory + +.. kernel-doc:: include/net/cfg80211.h + :functions: freq_reg_info + +RFkill integration +================== + +.. kernel-doc:: include/net/cfg80211.h + :doc: RFkill integration + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_rfkill_set_hw_state + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_rfkill_start_polling + +.. kernel-doc:: include/net/cfg80211.h + :functions: wiphy_rfkill_stop_polling + +Test mode +========= + +.. kernel-doc:: include/net/cfg80211.h + :doc: Test mode + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_testmode_alloc_reply_skb + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_testmode_reply + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_testmode_alloc_event_skb + +.. kernel-doc:: include/net/cfg80211.h + :functions: cfg80211_testmode_event diff --git a/Documentation/driver-api/80211/conf.py b/Documentation/driver-api/80211/conf.py new file mode 100644 index 000000000000..4424b4b0b9c3 --- /dev/null +++ b/Documentation/driver-api/80211/conf.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8; mode: python -*- + +project = "Linux 802.11 Driver Developer's Guide" + +tags.add("subproject") + +latex_documents = [ + ('index', '80211.tex', project, + 'The kernel development community', 'manual'), +] diff --git a/Documentation/driver-api/80211/index.rst b/Documentation/driver-api/80211/index.rst new file mode 100644 index 000000000000..af210859d3e1 --- /dev/null +++ b/Documentation/driver-api/80211/index.rst @@ -0,0 +1,17 @@ +===================================== +Linux 802.11 Driver Developer's Guide +===================================== + +.. toctree:: + + introduction + cfg80211 + mac80211 + mac80211-advanced + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/driver-api/80211/introduction.rst b/Documentation/driver-api/80211/introduction.rst new file mode 100644 index 000000000000..4938fa87691c --- /dev/null +++ b/Documentation/driver-api/80211/introduction.rst @@ -0,0 +1,17 @@ +============ +Introduction +============ + +Explaining wireless 802.11 networking in the Linux kernel + +Copyright 2007-2009 Johannes Berg + +These books attempt to give a description of the various subsystems +that play a role in 802.11 wireless networking in Linux. Since these +books are for kernel developers they attempts to document the +structures and functions used in the kernel as well as giving a +higher-level overview. + +The reader is expected to be familiar with the 802.11 standard as +published by the IEEE in 802.11-2007 (or possibly later versions). +References to this standard will be given as "802.11-2007 8.1.5". diff --git a/Documentation/driver-api/80211/mac80211-advanced.rst b/Documentation/driver-api/80211/mac80211-advanced.rst new file mode 100644 index 000000000000..70a89b2163c2 --- /dev/null +++ b/Documentation/driver-api/80211/mac80211-advanced.rst @@ -0,0 +1,295 @@ +============================= +mac80211 subsystem (advanced) +============================= + +Information contained within this part of the book is of interest only +for advanced interaction of mac80211 with drivers to exploit more +hardware capabilities and improve performance. + +LED support +=========== + +Mac80211 supports various ways of blinking LEDs. Wherever possible, +device LEDs should be exposed as LED class devices and hooked up to the +appropriate trigger, which will then be triggered appropriately by +mac80211. + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_get_tx_led_name + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_get_rx_led_name + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_get_assoc_led_name + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_get_radio_led_name + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tpt_blink + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tpt_led_trigger_flags + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_create_tpt_led_trigger + +Hardware crypto acceleration +============================ + +.. kernel-doc:: include/net/mac80211.h + :doc: Hardware crypto acceleration + +.. kernel-doc:: include/net/mac80211.h + :functions: set_key_cmd + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_key_conf + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_key_flags + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_get_tkip_p1k + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_get_tkip_p1k_iv + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_get_tkip_p2k + +Powersave support +================= + +.. kernel-doc:: include/net/mac80211.h + :doc: Powersave support + +Beacon filter support +===================== + +.. kernel-doc:: include/net/mac80211.h + :doc: Beacon filter support + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_beacon_loss + +Multiple queues and QoS support +=============================== + +TBD + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tx_queue_params + +Access point mode support +========================= + +TBD + +Some parts of the if_conf should be discussed here instead + +Insert notes about VLAN interfaces with hw crypto here or in the hw +crypto chapter. + +support for powersaving clients +------------------------------- + +.. kernel-doc:: include/net/mac80211.h + :doc: AP support for powersaving clients + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_get_buffered_bc + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_beacon_get + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_sta_eosp + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_frame_release_type + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_sta_ps_transition + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_sta_ps_transition_ni + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_sta_set_buffered + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_sta_block_awake + +Supporting multiple virtual interfaces +====================================== + +TBD + +Note: WDS with identical MAC address should almost always be OK + +Insert notes about having multiple virtual interfaces with different MAC +addresses here, note which configurations are supported by mac80211, add +notes about supporting hw crypto with it. + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_iterate_active_interfaces + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_iterate_active_interfaces_atomic + +Station handling +================ + +TODO + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_sta + +.. kernel-doc:: include/net/mac80211.h + :functions: sta_notify_cmd + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_find_sta + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_find_sta_by_ifaddr + +Hardware scan offload +===================== + +TBD + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_scan_completed + +Aggregation +=========== + +TX A-MPDU aggregation +--------------------- + +.. kernel-doc:: net/mac80211/agg-tx.c + :doc: TX A-MPDU aggregation + +.. WARNING: DOCPROC directive not supported: !Cnet/mac80211/agg-tx.c + +RX A-MPDU aggregation +--------------------- + +.. kernel-doc:: net/mac80211/agg-rx.c + :doc: RX A-MPDU aggregation + +.. WARNING: DOCPROC directive not supported: !Cnet/mac80211/agg-rx.c + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_ampdu_mlme_action + +Spatial Multiplexing Powersave (SMPS) +===================================== + +.. kernel-doc:: include/net/mac80211.h + :doc: Spatial multiplexing power save + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_request_smps + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_smps_mode + +TBD + +This part of the book describes the rate control algorithm interface and +how it relates to mac80211 and drivers. + +Rate Control API +================ + +TBD + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_start_tx_ba_session + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_start_tx_ba_cb_irqsafe + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_stop_tx_ba_session + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_stop_tx_ba_cb_irqsafe + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_rate_control_changed + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tx_rate_control + +.. kernel-doc:: include/net/mac80211.h + :functions: rate_control_send_low + +TBD + +This part of the book describes mac80211 internals. + +Key handling +============ + +Key handling basics +------------------- + +.. kernel-doc:: net/mac80211/key.c + :doc: Key handling basics + +MORE TBD +-------- + +TBD + +Receive processing +================== + +TBD + +Transmit processing +=================== + +TBD + +Station info handling +===================== + +Programming information +----------------------- + +.. kernel-doc:: net/mac80211/sta_info.h + :functions: sta_info + +.. kernel-doc:: net/mac80211/sta_info.h + :functions: ieee80211_sta_info_flags + +STA information lifetime rules +------------------------------ + +.. kernel-doc:: net/mac80211/sta_info.c + :doc: STA information lifetime rules + +Aggregation +=========== + +.. kernel-doc:: net/mac80211/sta_info.h + :functions: sta_ampdu_mlme + +.. kernel-doc:: net/mac80211/sta_info.h + :functions: tid_ampdu_tx + +.. kernel-doc:: net/mac80211/sta_info.h + :functions: tid_ampdu_rx + +Synchronisation +=============== + +TBD + +Locking, lots of RCU diff --git a/Documentation/driver-api/80211/mac80211.rst b/Documentation/driver-api/80211/mac80211.rst new file mode 100644 index 000000000000..85a8335e80b6 --- /dev/null +++ b/Documentation/driver-api/80211/mac80211.rst @@ -0,0 +1,216 @@ +=========================== +mac80211 subsystem (basics) +=========================== + +You should read and understand the information contained within this +part of the book while implementing a mac80211 driver. In some chapters, +advanced usage is noted, those may be skipped if this isn't needed. + +This part of the book only covers station and monitor mode +functionality, additional information required to implement the other +modes is covered in the second part of the book. + +Basic hardware handling +======================= + +TBD + +This chapter shall contain information on getting a hw struct allocated +and registered with mac80211. + +Since it is required to allocate rates/modes before registering a hw +struct, this chapter shall also contain information on setting up the +rate/mode structs. + +Additionally, some discussion about the callbacks and the general +programming model should be in here, including the definition of +ieee80211_ops which will be referred to a lot. + +Finally, a discussion of hardware capabilities should be done with +references to other parts of the book. + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_hw + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_hw_flags + +.. kernel-doc:: include/net/mac80211.h + :functions: SET_IEEE80211_DEV + +.. kernel-doc:: include/net/mac80211.h + :functions: SET_IEEE80211_PERM_ADDR + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_ops + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_alloc_hw + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_register_hw + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_unregister_hw + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_free_hw + +PHY configuration +================= + +TBD + +This chapter should describe PHY handling including start/stop callbacks +and the various structures used. + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_conf + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_conf_flags + +Virtual interfaces +================== + +TBD + +This chapter should describe virtual interface basics that are relevant +to the driver (VLANs, MGMT etc are not.) It should explain the use of +the add_iface/remove_iface callbacks as well as the interface +configuration callbacks. + +Things related to AP mode should be discussed there. + +Things related to supporting multiple interfaces should be in the +appropriate chapter, a BIG FAT note should be here about this though and +the recommendation to allow only a single interface in STA mode at +first! + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_vif + +Receive and transmit processing +=============================== + +what should be here +------------------- + +TBD + +This should describe the receive and transmit paths in mac80211/the +drivers as well as transmit status handling. + +Frame format +------------ + +.. kernel-doc:: include/net/mac80211.h + :doc: Frame format + +Packet alignment +---------------- + +.. kernel-doc:: net/mac80211/rx.c + :doc: Packet alignment + +Calling into mac80211 from interrupts +------------------------------------- + +.. kernel-doc:: include/net/mac80211.h + :doc: Calling mac80211 from interrupts + +functions/definitions +--------------------- + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_rx_status + +.. kernel-doc:: include/net/mac80211.h + :functions: mac80211_rx_flags + +.. kernel-doc:: include/net/mac80211.h + :functions: mac80211_tx_info_flags + +.. kernel-doc:: include/net/mac80211.h + :functions: mac80211_tx_control_flags + +.. kernel-doc:: include/net/mac80211.h + :functions: mac80211_rate_control_flags + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tx_rate + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tx_info + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tx_info_clear_status + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_rx + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_rx_ni + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_rx_irqsafe + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tx_status + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tx_status_ni + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_tx_status_irqsafe + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_rts_get + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_rts_duration + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_ctstoself_get + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_ctstoself_duration + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_generic_frame_duration + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_wake_queue + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_stop_queue + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_wake_queues + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_stop_queues + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_queue_stopped + +Frame filtering +=============== + +.. kernel-doc:: include/net/mac80211.h + :doc: Frame filtering + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_filter_flags + +The mac80211 workqueue +====================== + +.. kernel-doc:: include/net/mac80211.h + :doc: mac80211 workqueue + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_queue_work + +.. kernel-doc:: include/net/mac80211.h + :functions: ieee80211_queue_delayed_work diff --git a/Documentation/driver-api/conf.py b/Documentation/driver-api/conf.py new file mode 100644 index 000000000000..202726d20088 --- /dev/null +++ b/Documentation/driver-api/conf.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8; mode: python -*- + +project = "The Linux driver implementer's API guide" + +tags.add("subproject") + +latex_documents = [ + ('index', 'driver-api.tex', project, + 'The kernel development community', 'manual'), +] diff --git a/Documentation/driver-api/device-io.rst b/Documentation/driver-api/device-io.rst new file mode 100644 index 000000000000..b00b23903078 --- /dev/null +++ b/Documentation/driver-api/device-io.rst @@ -0,0 +1,201 @@ +.. Copyright 2001 Matthew Wilcox +.. +.. This documentation is free software; you can redistribute +.. it and/or modify it under the terms of the GNU General Public +.. License as published by the Free Software Foundation; either +.. version 2 of the License, or (at your option) any later +.. version. + +=============================== +Bus-Independent Device Accesses +=============================== + +:Author: Matthew Wilcox +:Author: Alan Cox + +Introduction +============ + +Linux provides an API which abstracts performing IO across all busses +and devices, allowing device drivers to be written independently of bus +type. + +Memory Mapped IO +================ + +Getting Access to the Device +---------------------------- + +The most widely supported form of IO is memory mapped IO. That is, a +part of the CPU's address space is interpreted not as accesses to +memory, but as accesses to a device. Some architectures define devices +to be at a fixed address, but most have some method of discovering +devices. The PCI bus walk is a good example of such a scheme. This +document does not cover how to receive such an address, but assumes you +are starting with one. Physical addresses are of type unsigned long. + +This address should not be used directly. Instead, to get an address +suitable for passing to the accessor functions described below, you +should call :c:func:`ioremap()`. An address suitable for accessing +the device will be returned to you. + +After you've finished using the device (say, in your module's exit +routine), call :c:func:`iounmap()` in order to return the address +space to the kernel. Most architectures allocate new address space each +time you call :c:func:`ioremap()`, and they can run out unless you +call :c:func:`iounmap()`. + +Accessing the device +-------------------- + +The part of the interface most used by drivers is reading and writing +memory-mapped registers on the device. Linux provides interfaces to read +and write 8-bit, 16-bit, 32-bit and 64-bit quantities. Due to a +historical accident, these are named byte, word, long and quad accesses. +Both read and write accesses are supported; there is no prefetch support +at this time. + +The functions are named readb(), readw(), readl(), readq(), +readb_relaxed(), readw_relaxed(), readl_relaxed(), readq_relaxed(), +writeb(), writew(), writel() and writeq(). + +Some devices (such as framebuffers) would like to use larger transfers than +8 bytes at a time. For these devices, the :c:func:`memcpy_toio()`, +:c:func:`memcpy_fromio()` and :c:func:`memset_io()` functions are +provided. Do not use memset or memcpy on IO addresses; they are not +guaranteed to copy data in order. + +The read and write functions are defined to be ordered. That is the +compiler is not permitted to reorder the I/O sequence. When the ordering +can be compiler optimised, you can use __readb() and friends to +indicate the relaxed ordering. Use this with care. + +While the basic functions are defined to be synchronous with respect to +each other and ordered with respect to each other the busses the devices +sit on may themselves have asynchronicity. In particular many authors +are burned by the fact that PCI bus writes are posted asynchronously. A +driver author must issue a read from the same device to ensure that +writes have occurred in the specific cases the author cares. This kind +of property cannot be hidden from driver writers in the API. In some +cases, the read used to flush the device may be expected to fail (if the +card is resetting, for example). In that case, the read should be done +from config space, which is guaranteed to soft-fail if the card doesn't +respond. + +The following is an example of flushing a write to a device when the +driver would like to ensure the write's effects are visible prior to +continuing execution:: + + static inline void + qla1280_disable_intrs(struct scsi_qla_host *ha) + { + struct device_reg *reg; + + reg = ha->iobase; + /* disable risc and host interrupts */ + WRT_REG_WORD(®->ictrl, 0); + /* + * The following read will ensure that the above write + * has been received by the device before we return from this + * function. + */ + RD_REG_WORD(®->ictrl); + ha->flags.ints_enabled = 0; + } + +In addition to write posting, on some large multiprocessing systems +(e.g. SGI Challenge, Origin and Altix machines) posted writes won't be +strongly ordered coming from different CPUs. Thus it's important to +properly protect parts of your driver that do memory-mapped writes with +locks and use the :c:func:`mmiowb()` to make sure they arrive in the +order intended. Issuing a regular readX() will also ensure write ordering, +but should only be used when the +driver has to be sure that the write has actually arrived at the device +(not that it's simply ordered with respect to other writes), since a +full readX() is a relatively expensive operation. + +Generally, one should use :c:func:`mmiowb()` prior to releasing a spinlock +that protects regions using :c:func:`writeb()` or similar functions that +aren't surrounded by readb() calls, which will ensure ordering +and flushing. The following pseudocode illustrates what might occur if +write ordering isn't guaranteed via :c:func:`mmiowb()` or one of the +readX() functions:: + + CPU A: spin_lock_irqsave(&dev_lock, flags) + CPU A: ... + CPU A: writel(newval, ring_ptr); + CPU A: spin_unlock_irqrestore(&dev_lock, flags) + ... + CPU B: spin_lock_irqsave(&dev_lock, flags) + CPU B: writel(newval2, ring_ptr); + CPU B: ... + CPU B: spin_unlock_irqrestore(&dev_lock, flags) + +In the case above, newval2 could be written to ring_ptr before newval. +Fixing it is easy though:: + + CPU A: spin_lock_irqsave(&dev_lock, flags) + CPU A: ... + CPU A: writel(newval, ring_ptr); + CPU A: mmiowb(); /* ensure no other writes beat us to the device */ + CPU A: spin_unlock_irqrestore(&dev_lock, flags) + ... + CPU B: spin_lock_irqsave(&dev_lock, flags) + CPU B: writel(newval2, ring_ptr); + CPU B: ... + CPU B: mmiowb(); + CPU B: spin_unlock_irqrestore(&dev_lock, flags) + +See tg3.c for a real world example of how to use :c:func:`mmiowb()` + +PCI ordering rules also guarantee that PIO read responses arrive after any +outstanding DMA writes from that bus, since for some devices the result of +a readb() call may signal to the driver that a DMA transaction is +complete. In many cases, however, the driver may want to indicate that the +next readb() call has no relation to any previous DMA writes +performed by the device. The driver can use readb_relaxed() for +these cases, although only some platforms will honor the relaxed +semantics. Using the relaxed read functions will provide significant +performance benefits on platforms that support it. The qla2xxx driver +provides examples of how to use readX_relaxed(). In many cases, a majority +of the driver's readX() calls can safely be converted to readX_relaxed() +calls, since only a few will indicate or depend on DMA completion. + +Port Space Accesses +=================== + +Port Space Explained +-------------------- + +Another form of IO commonly supported is Port Space. This is a range of +addresses separate to the normal memory address space. Access to these +addresses is generally not as fast as accesses to the memory mapped +addresses, and it also has a potentially smaller address space. + +Unlike memory mapped IO, no preparation is required to access port +space. + +Accessing Port Space +-------------------- + +Accesses to this space are provided through a set of functions which +allow 8-bit, 16-bit and 32-bit accesses; also known as byte, word and +long. These functions are :c:func:`inb()`, :c:func:`inw()`, +:c:func:`inl()`, :c:func:`outb()`, :c:func:`outw()` and +:c:func:`outl()`. + +Some variants are provided for these functions. Some devices require +that accesses to their ports are slowed down. This functionality is +provided by appending a ``_p`` to the end of the function. +There are also equivalents to memcpy. The :c:func:`ins()` and +:c:func:`outs()` functions copy bytes, words or longs to the given +port. + +Public Functions Provided +========================= + +.. kernel-doc:: arch/x86/include/asm/io.h + :internal: + +.. kernel-doc:: lib/pci_iomap.c + :export: diff --git a/Documentation/driver-api/device_link.rst b/Documentation/driver-api/device_link.rst new file mode 100644 index 000000000000..70e328e16aad --- /dev/null +++ b/Documentation/driver-api/device_link.rst @@ -0,0 +1,281 @@ +.. |struct dev_pm_domain| replace:: :c:type:`struct dev_pm_domain <dev_pm_domain>` +.. |struct generic_pm_domain| replace:: :c:type:`struct generic_pm_domain <generic_pm_domain>` + +============ +Device links +============ + +By default, the driver core only enforces dependencies between devices +that are borne out of a parent/child relationship within the device +hierarchy: When suspending, resuming or shutting down the system, devices +are ordered based on this relationship, i.e. children are always suspended +before their parent, and the parent is always resumed before its children. + +Sometimes there is a need to represent device dependencies beyond the +mere parent/child relationship, e.g. between siblings, and have the +driver core automatically take care of them. + +Secondly, the driver core by default does not enforce any driver presence +dependencies, i.e. that one device must be bound to a driver before +another one can probe or function correctly. + +Often these two dependency types come together, so a device depends on +another one both with regards to driver presence *and* with regards to +suspend/resume and shutdown ordering. + +Device links allow representation of such dependencies in the driver core. + +In its standard form, a device link combines *both* dependency types: +It guarantees correct suspend/resume and shutdown ordering between a +"supplier" device and its "consumer" devices, and it guarantees driver +presence on the supplier. The consumer devices are not probed before the +supplier is bound to a driver, and they're unbound before the supplier +is unbound. + +When driver presence on the supplier is irrelevant and only correct +suspend/resume and shutdown ordering is needed, the device link may +simply be set up with the ``DL_FLAG_STATELESS`` flag. In other words, +enforcing driver presence on the supplier is optional. + +Another optional feature is runtime PM integration: By setting the +``DL_FLAG_PM_RUNTIME`` flag on addition of the device link, the PM core +is instructed to runtime resume the supplier and keep it active +whenever and for as long as the consumer is runtime resumed. + +Usage +===== + +The earliest point in time when device links can be added is after +:c:func:`device_add()` has been called for the supplier and +:c:func:`device_initialize()` has been called for the consumer. + +It is legal to add them later, but care must be taken that the system +remains in a consistent state: E.g. a device link cannot be added in +the midst of a suspend/resume transition, so either commencement of +such a transition needs to be prevented with :c:func:`lock_system_sleep()`, +or the device link needs to be added from a function which is guaranteed +not to run in parallel to a suspend/resume transition, such as from a +device ``->probe`` callback or a boot-time PCI quirk. + +Another example for an inconsistent state would be a device link that +represents a driver presence dependency, yet is added from the consumer's +``->probe`` callback while the supplier hasn't probed yet: Had the driver +core known about the device link earlier, it wouldn't have probed the +consumer in the first place. The onus is thus on the consumer to check +presence of the supplier after adding the link, and defer probing on +non-presence. + +If a device link is added in the ``->probe`` callback of the supplier or +consumer driver, it is typically deleted in its ``->remove`` callback for +symmetry. That way, if the driver is compiled as a module, the device +link is added on module load and orderly deleted on unload. The same +restrictions that apply to device link addition (e.g. exclusion of a +parallel suspend/resume transition) apply equally to deletion. + +Several flags may be specified on device link addition, two of which +have already been mentioned above: ``DL_FLAG_STATELESS`` to express that no +driver presence dependency is needed (but only correct suspend/resume and +shutdown ordering) and ``DL_FLAG_PM_RUNTIME`` to express that runtime PM +integration is desired. + +Two other flags are specifically targeted at use cases where the device +link is added from the consumer's ``->probe`` callback: ``DL_FLAG_RPM_ACTIVE`` +can be specified to runtime resume the supplier upon addition of the +device link. ``DL_FLAG_AUTOREMOVE`` causes the device link to be automatically +purged when the consumer fails to probe or later unbinds. This obviates +the need to explicitly delete the link in the ``->remove`` callback or in +the error path of the ``->probe`` callback. + +Limitations +=========== + +Driver authors should be aware that a driver presence dependency (i.e. when +``DL_FLAG_STATELESS`` is not specified on link addition) may cause probing of +the consumer to be deferred indefinitely. This can become a problem if the +consumer is required to probe before a certain initcall level is reached. +Worse, if the supplier driver is blacklisted or missing, the consumer will +never be probed. + +Sometimes drivers depend on optional resources. They are able to operate +in a degraded mode (reduced feature set or performance) when those resources +are not present. An example is an SPI controller that can use a DMA engine +or work in PIO mode. The controller can determine presence of the optional +resources at probe time but on non-presence there is no way to know whether +they will become available in the near future (due to a supplier driver +probing) or never. Consequently it cannot be determined whether to defer +probing or not. It would be possible to notify drivers when optional +resources become available after probing, but it would come at a high cost +for drivers as switching between modes of operation at runtime based on the +availability of such resources would be much more complex than a mechanism +based on probe deferral. In any case optional resources are beyond the +scope of device links. + +Examples +======== + +* An MMU device exists alongside a busmaster device, both are in the same + power domain. The MMU implements DMA address translation for the busmaster + device and shall be runtime resumed and kept active whenever and as long + as the busmaster device is active. The busmaster device's driver shall + not bind before the MMU is bound. To achieve this, a device link with + runtime PM integration is added from the busmaster device (consumer) + to the MMU device (supplier). The effect with regards to runtime PM + is the same as if the MMU was the parent of the master device. + + The fact that both devices share the same power domain would normally + suggest usage of a |struct dev_pm_domain| or |struct generic_pm_domain|, + however these are not independent devices that happen to share a power + switch, but rather the MMU device serves the busmaster device and is + useless without it. A device link creates a synthetic hierarchical + relationship between the devices and is thus more apt. + +* A Thunderbolt host controller comprises a number of PCIe hotplug ports + and an NHI device to manage the PCIe switch. On resume from system sleep, + the NHI device needs to re-establish PCI tunnels to attached devices + before the hotplug ports can resume. If the hotplug ports were children + of the NHI, this resume order would automatically be enforced by the + PM core, but unfortunately they're aunts. The solution is to add + device links from the hotplug ports (consumers) to the NHI device + (supplier). A driver presence dependency is not necessary for this + use case. + +* Discrete GPUs in hybrid graphics laptops often feature an HDA controller + for HDMI/DP audio. In the device hierarchy the HDA controller is a sibling + of the VGA device, yet both share the same power domain and the HDA + controller is only ever needed when an HDMI/DP display is attached to the + VGA device. A device link from the HDA controller (consumer) to the + VGA device (supplier) aptly represents this relationship. + +* ACPI allows definition of a device start order by way of _DEP objects. + A classical example is when ACPI power management methods on one device + are implemented in terms of I\ :sup:`2`\ C accesses and require a specific + I\ :sup:`2`\ C controller to be present and functional for the power + management of the device in question to work. + +* In some SoCs a functional dependency exists from display, video codec and + video processing IP cores on transparent memory access IP cores that handle + burst access and compression/decompression. + +Alternatives +============ + +* A |struct dev_pm_domain| can be used to override the bus, + class or device type callbacks. It is intended for devices sharing + a single on/off switch, however it does not guarantee a specific + suspend/resume ordering, this needs to be implemented separately. + It also does not by itself track the runtime PM status of the involved + devices and turn off the power switch only when all of them are runtime + suspended. Furthermore it cannot be used to enforce a specific shutdown + ordering or a driver presence dependency. + +* A |struct generic_pm_domain| is a lot more heavyweight than a + device link and does not allow for shutdown ordering or driver presence + dependencies. It also cannot be used on ACPI systems. + +Implementation +============== + +The device hierarchy, which -- as the name implies -- is a tree, +becomes a directed acyclic graph once device links are added. + +Ordering of these devices during suspend/resume is determined by the +dpm_list. During shutdown it is determined by the devices_kset. With +no device links present, the two lists are a flattened, one-dimensional +representations of the device tree such that a device is placed behind +all its ancestors. That is achieved by traversing the ACPI namespace +or OpenFirmware device tree top-down and appending devices to the lists +as they are discovered. + +Once device links are added, the lists need to satisfy the additional +constraint that a device is placed behind all its suppliers, recursively. +To ensure this, upon addition of the device link the consumer and the +entire sub-graph below it (all children and consumers of the consumer) +are moved to the end of the list. (Call to :c:func:`device_reorder_to_tail()` +from :c:func:`device_link_add()`.) + +To prevent introduction of dependency loops into the graph, it is +verified upon device link addition that the supplier is not dependent +on the consumer or any children or consumers of the consumer. +(Call to :c:func:`device_is_dependent()` from :c:func:`device_link_add()`.) +If that constraint is violated, :c:func:`device_link_add()` will return +``NULL`` and a ``WARNING`` will be logged. + +Notably this also prevents the addition of a device link from a parent +device to a child. However the converse is allowed, i.e. a device link +from a child to a parent. Since the driver core already guarantees +correct suspend/resume and shutdown ordering between parent and child, +such a device link only makes sense if a driver presence dependency is +needed on top of that. In this case driver authors should weigh +carefully if a device link is at all the right tool for the purpose. +A more suitable approach might be to simply use deferred probing or +add a device flag causing the parent driver to be probed before the +child one. + +State machine +============= + +.. kernel-doc:: include/linux/device.h + :functions: device_link_state + +:: + + .=============================. + | | + v | + DORMANT <=> AVAILABLE <=> CONSUMER_PROBE => ACTIVE + ^ | + | | + '============ SUPPLIER_UNBIND <============' + +* The initial state of a device link is automatically determined by + :c:func:`device_link_add()` based on the driver presence on the supplier + and consumer. If the link is created before any devices are probed, it + is set to ``DL_STATE_DORMANT``. + +* When a supplier device is bound to a driver, links to its consumers + progress to ``DL_STATE_AVAILABLE``. + (Call to :c:func:`device_links_driver_bound()` from + :c:func:`driver_bound()`.) + +* Before a consumer device is probed, presence of supplier drivers is + verified by checking that links to suppliers are in ``DL_STATE_AVAILABLE`` + state. The state of the links is updated to ``DL_STATE_CONSUMER_PROBE``. + (Call to :c:func:`device_links_check_suppliers()` from + :c:func:`really_probe()`.) + This prevents the supplier from unbinding. + (Call to :c:func:`wait_for_device_probe()` from + :c:func:`device_links_unbind_consumers()`.) + +* If the probe fails, links to suppliers revert back to ``DL_STATE_AVAILABLE``. + (Call to :c:func:`device_links_no_driver()` from :c:func:`really_probe()`.) + +* If the probe succeeds, links to suppliers progress to ``DL_STATE_ACTIVE``. + (Call to :c:func:`device_links_driver_bound()` from :c:func:`driver_bound()`.) + +* When the consumer's driver is later on removed, links to suppliers revert + back to ``DL_STATE_AVAILABLE``. + (Call to :c:func:`__device_links_no_driver()` from + :c:func:`device_links_driver_cleanup()`, which in turn is called from + :c:func:`__device_release_driver()`.) + +* Before a supplier's driver is removed, links to consumers that are not + bound to a driver are updated to ``DL_STATE_SUPPLIER_UNBIND``. + (Call to :c:func:`device_links_busy()` from + :c:func:`__device_release_driver()`.) + This prevents the consumers from binding. + (Call to :c:func:`device_links_check_suppliers()` from + :c:func:`really_probe()`.) + Consumers that are bound are freed from their driver; consumers that are + probing are waited for until they are done. + (Call to :c:func:`device_links_unbind_consumers()` from + :c:func:`__device_release_driver()`.) + Once all links to consumers are in ``DL_STATE_SUPPLIER_UNBIND`` state, + the supplier driver is released and the links revert to ``DL_STATE_DORMANT``. + (Call to :c:func:`device_links_driver_cleanup()` from + :c:func:`__device_release_driver()`.) + +API +=== + +.. kernel-doc:: drivers/base/core.c + :functions: device_link_add device_link_del diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst new file mode 100644 index 000000000000..31671b469627 --- /dev/null +++ b/Documentation/driver-api/dma-buf.rst @@ -0,0 +1,165 @@ +Buffer Sharing and Synchronization +================================== + +The dma-buf subsystem provides the framework for sharing buffers for +hardware (DMA) access across multiple device drivers and subsystems, and +for synchronizing asynchronous hardware access. + +This is used, for example, by drm "prime" multi-GPU support, but is of +course not limited to GPU use cases. + +The three main components of this are: (1) dma-buf, representing a +sg_table and exposed to userspace as a file descriptor to allow passing +between devices, (2) fence, which provides a mechanism to signal when +one device as finished access, and (3) reservation, which manages the +shared or exclusive fence(s) associated with the buffer. + +Shared DMA Buffers +------------------ + +This document serves as a guide to device-driver writers on what is the dma-buf +buffer sharing API, how to use it for exporting and using shared buffers. + +Any device driver which wishes to be a part of DMA buffer sharing, can do so as +either the 'exporter' of buffers, or the 'user' or 'importer' of buffers. + +Say a driver A wants to use buffers created by driver B, then we call B as the +exporter, and A as buffer-user/importer. + +The exporter + + - implements and manages operations in :c:type:`struct dma_buf_ops + <dma_buf_ops>` for the buffer, + - allows other users to share the buffer by using dma_buf sharing APIs, + - manages the details of buffer allocation, wrapped int a :c:type:`struct + dma_buf <dma_buf>`, + - decides about the actual backing storage where this allocation happens, + - and takes care of any migration of scatterlist - for all (shared) users of + this buffer. + +The buffer-user + + - is one of (many) sharing users of the buffer. + - doesn't need to worry about how the buffer is allocated, or where. + - and needs a mechanism to get access to the scatterlist that makes up this + buffer in memory, mapped into its own address space, so it can access the + same area of memory. This interface is provided by :c:type:`struct + dma_buf_attachment <dma_buf_attachment>`. + +Any exporters or users of the dma-buf buffer sharing framework must have a +'select DMA_SHARED_BUFFER' in their respective Kconfigs. + +Userspace Interface Notes +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Mostly a DMA buffer file descriptor is simply an opaque object for userspace, +and hence the generic interface exposed is very minimal. There's a few things to +consider though: + +- Since kernel 3.12 the dma-buf FD supports the llseek system call, but only + with offset=0 and whence=SEEK_END|SEEK_SET. SEEK_SET is supported to allow + the usual size discover pattern size = SEEK_END(0); SEEK_SET(0). Every other + llseek operation will report -EINVAL. + + If llseek on dma-buf FDs isn't support the kernel will report -ESPIPE for all + cases. Userspace can use this to detect support for discovering the dma-buf + size using llseek. + +- In order to avoid fd leaks on exec, the FD_CLOEXEC flag must be set + on the file descriptor. This is not just a resource leak, but a + potential security hole. It could give the newly exec'd application + access to buffers, via the leaked fd, to which it should otherwise + not be permitted access. + + The problem with doing this via a separate fcntl() call, versus doing it + atomically when the fd is created, is that this is inherently racy in a + multi-threaded app[3]. The issue is made worse when it is library code + opening/creating the file descriptor, as the application may not even be + aware of the fd's. + + To avoid this problem, userspace must have a way to request O_CLOEXEC + flag be set when the dma-buf fd is created. So any API provided by + the exporting driver to create a dmabuf fd must provide a way to let + userspace control setting of O_CLOEXEC flag passed in to dma_buf_fd(). + +- Memory mapping the contents of the DMA buffer is also supported. See the + discussion below on `CPU Access to DMA Buffer Objects`_ for the full details. + +- The DMA buffer FD is also pollable, see `Fence Poll Support`_ below for + details. + +Basic Operation and Device DMA Access +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/dma-buf/dma-buf.c + :doc: dma buf device access + +CPU Access to DMA Buffer Objects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/dma-buf/dma-buf.c + :doc: cpu access + +Fence Poll Support +~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/dma-buf/dma-buf.c + :doc: fence polling + +Kernel Functions and Structures Reference +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/dma-buf/dma-buf.c + :export: + +.. kernel-doc:: include/linux/dma-buf.h + :internal: + +Reservation Objects +------------------- + +.. kernel-doc:: drivers/dma-buf/reservation.c + :doc: Reservation Object Overview + +.. kernel-doc:: drivers/dma-buf/reservation.c + :export: + +.. kernel-doc:: include/linux/reservation.h + :internal: + +DMA Fences +---------- + +.. kernel-doc:: drivers/dma-buf/dma-fence.c + :export: + +.. kernel-doc:: include/linux/dma-fence.h + :internal: + +Seqno Hardware Fences +~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/dma-buf/seqno-fence.c + :export: + +.. kernel-doc:: include/linux/seqno-fence.h + :internal: + +DMA Fence Array +~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/dma-buf/dma-fence-array.c + :export: + +.. kernel-doc:: include/linux/dma-fence-array.h + :internal: + +DMA Fence uABI/Sync File +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/dma-buf/sync_file.c + :export: + +.. kernel-doc:: include/linux/sync_file.h + :internal: + diff --git a/Documentation/driver-api/edac.rst b/Documentation/driver-api/edac.rst new file mode 100644 index 000000000000..b8c742aa0a71 --- /dev/null +++ b/Documentation/driver-api/edac.rst @@ -0,0 +1,178 @@ +Error Detection And Correction (EDAC) Devices +============================================= + +Main Concepts used at the EDAC subsystem +---------------------------------------- + +There are several things to be aware of that aren't at all obvious, like +*sockets, *socket sets*, *banks*, *rows*, *chip-select rows*, *channels*, +etc... + +These are some of the many terms that are thrown about that don't always +mean what people think they mean (Inconceivable!). In the interest of +creating a common ground for discussion, terms and their definitions +will be established. + +* Memory devices + +The individual DRAM chips on a memory stick. These devices commonly +output 4 and 8 bits each (x4, x8). Grouping several of these in parallel +provides the number of bits that the memory controller expects: +typically 72 bits, in order to provide 64 bits + 8 bits of ECC data. + +* Memory Stick + +A printed circuit board that aggregates multiple memory devices in +parallel. In general, this is the Field Replaceable Unit (FRU) which +gets replaced, in the case of excessive errors. Most often it is also +called DIMM (Dual Inline Memory Module). + +* Memory Socket + +A physical connector on the motherboard that accepts a single memory +stick. Also called as "slot" on several datasheets. + +* Channel + +A memory controller channel, responsible to communicate with a group of +DIMMs. Each channel has its own independent control (command) and data +bus, and can be used independently or grouped with other channels. + +* Branch + +It is typically the highest hierarchy on a Fully-Buffered DIMM memory +controller. Typically, it contains two channels. Two channels at the +same branch can be used in single mode or in lockstep mode. When +lockstep is enabled, the cacheline is doubled, but it generally brings +some performance penalty. Also, it is generally not possible to point to +just one memory stick when an error occurs, as the error correction code +is calculated using two DIMMs instead of one. Due to that, it is capable +of correcting more errors than on single mode. + +* Single-channel + +The data accessed by the memory controller is contained into one dimm +only. E. g. if the data is 64 bits-wide, the data flows to the CPU using +one 64 bits parallel access. Typically used with SDR, DDR, DDR2 and DDR3 +memories. FB-DIMM and RAMBUS use a different concept for channel, so +this concept doesn't apply there. + +* Double-channel + +The data size accessed by the memory controller is interlaced into two +dimms, accessed at the same time. E. g. if the DIMM is 64 bits-wide (72 +bits with ECC), the data flows to the CPU using a 128 bits parallel +access. + +* Chip-select row + +This is the name of the DRAM signal used to select the DRAM ranks to be +accessed. Common chip-select rows for single channel are 64 bits, for +dual channel 128 bits. It may not be visible by the memory controller, +as some DIMM types have a memory buffer that can hide direct access to +it from the Memory Controller. + +* Single-Ranked stick + +A Single-ranked stick has 1 chip-select row of memory. Motherboards +commonly drive two chip-select pins to a memory stick. A single-ranked +stick, will occupy only one of those rows. The other will be unused. + +.. _doubleranked: + +* Double-Ranked stick + +A double-ranked stick has two chip-select rows which access different +sets of memory devices. The two rows cannot be accessed concurrently. + +* Double-sided stick + +**DEPRECATED TERM**, see :ref:`Double-Ranked stick <doubleranked>`. + +A double-sided stick has two chip-select rows which access different sets +of memory devices. The two rows cannot be accessed concurrently. +"Double-sided" is irrespective of the memory devices being mounted on +both sides of the memory stick. + +* Socket set + +All of the memory sticks that are required for a single memory access or +all of the memory sticks spanned by a chip-select row. A single socket +set has two chip-select rows and if double-sided sticks are used these +will occupy those chip-select rows. + +* Bank + +This term is avoided because it is unclear when needing to distinguish +between chip-select rows and socket sets. + + +Memory Controllers +------------------ + +Most of the EDAC core is focused on doing Memory Controller error detection. +The :c:func:`edac_mc_alloc`. It uses internally the struct ``mem_ctl_info`` +to describe the memory controllers, with is an opaque struct for the EDAC +drivers. Only the EDAC core is allowed to touch it. + +.. kernel-doc:: include/linux/edac.h + +.. kernel-doc:: drivers/edac/edac_mc.h + +PCI Controllers +--------------- + +The EDAC subsystem provides a mechanism to handle PCI controllers by calling +the :c:func:`edac_pci_alloc_ctl_info`. It will use the struct +:c:type:`edac_pci_ctl_info` to describe the PCI controllers. + +.. kernel-doc:: drivers/edac/edac_pci.h + +EDAC Blocks +----------- + +The EDAC subsystem also provides a generic mechanism to report errors on +other parts of the hardware via :c:func:`edac_device_alloc_ctl_info` function. + +The structures :c:type:`edac_dev_sysfs_block_attribute`, +:c:type:`edac_device_block`, :c:type:`edac_device_instance` and +:c:type:`edac_device_ctl_info` provide a generic or abstract 'edac_device' +representation at sysfs. + +This set of structures and the code that implements the APIs for the same, provide for registering EDAC type devices which are NOT standard memory or +PCI, like: + +- CPU caches (L1 and L2) +- DMA engines +- Core CPU switches +- Fabric switch units +- PCIe interface controllers +- other EDAC/ECC type devices that can be monitored for + errors, etc. + +It allows for a 2 level set of hierarchy. + +For example, a cache could be composed of L1, L2 and L3 levels of cache. +Each CPU core would have its own L1 cache, while sharing L2 and maybe L3 +caches. On such case, those can be represented via the following sysfs +nodes:: + + /sys/devices/system/edac/.. + + pci/ <existing pci directory (if available)> + mc/ <existing memory device directory> + cpu/cpu0/.. <L1 and L2 block directory> + /L1-cache/ce_count + /ue_count + /L2-cache/ce_count + /ue_count + cpu/cpu1/.. <L1 and L2 block directory> + /L1-cache/ce_count + /ue_count + /L2-cache/ce_count + /ue_count + ... + + the L1 and L2 directories would be "edac_device_block's" + +.. kernel-doc:: drivers/edac/edac_device.h diff --git a/Documentation/driver-api/firmware/built-in-fw.rst b/Documentation/driver-api/firmware/built-in-fw.rst new file mode 100644 index 000000000000..7300e66857f8 --- /dev/null +++ b/Documentation/driver-api/firmware/built-in-fw.rst @@ -0,0 +1,38 @@ +================= +Built-in firmware +================= + +Firmware can be built-in to the kernel, this means building the firmware +into vmlinux directly, to enable avoiding having to look for firmware from +the filesystem. Instead, firmware can be looked for inside the kernel +directly. You can enable built-in firmware using the kernel configuration +options: + + * CONFIG_EXTRA_FIRMWARE + * CONFIG_EXTRA_FIRMWARE_DIR + +This should not be confused with CONFIG_FIRMWARE_IN_KERNEL, this is for drivers +which enables firmware to be built as part of the kernel build process. This +option, CONFIG_FIRMWARE_IN_KERNEL, will build all firmware for all drivers +enabled which ship its firmware inside the Linux kernel source tree. + +There are a few reasons why you might want to consider building your firmware +into the kernel with CONFIG_EXTRA_FIRMWARE though: + +* Speed +* Firmware is needed for accessing the boot device, and the user doesn't + want to stuff the firmware into the boot initramfs. + +Even if you have these needs there are a few reasons why you may not be +able to make use of built-in firmware: + +* Legalese - firmware is non-GPL compatible +* Some firmware may be optional +* Firmware upgrades are possible, therefore a new firmware would implicate + a complete kernel rebuild. +* Some firmware files may be really large in size. The remote-proc subsystem + is an example subsystem which deals with these sorts of firmware +* The firmware may need to be scraped out from some device specific location + dynamically, an example is calibration data for for some WiFi chipsets. This + calibration data can be unique per sold device. + diff --git a/Documentation/driver-api/firmware/core.rst b/Documentation/driver-api/firmware/core.rst new file mode 100644 index 000000000000..1d1688cbc078 --- /dev/null +++ b/Documentation/driver-api/firmware/core.rst @@ -0,0 +1,16 @@ +========================== +Firmware API core features +========================== + +The firmware API has a rich set of core features available. This section +documents these features. + +.. toctree:: + + fw_search_path + built-in-fw + firmware_cache + direct-fs-lookup + fallback-mechanisms + lookup-order + diff --git a/Documentation/driver-api/firmware/direct-fs-lookup.rst b/Documentation/driver-api/firmware/direct-fs-lookup.rst new file mode 100644 index 000000000000..82b4d585a213 --- /dev/null +++ b/Documentation/driver-api/firmware/direct-fs-lookup.rst @@ -0,0 +1,30 @@ +======================== +Direct filesystem lookup +======================== + +Direct filesystem lookup is the most common form of firmware lookup performed +by the kernel. The kernel looks for the firmware directly on the root +filesystem in the paths documented in the section 'Firmware search paths'. +The filesystem lookup is implemented in fw_get_filesystem_firmware(), it +uses common core kernel file loader facility kernel_read_file_from_path(). +The max path allowed is PATH_MAX -- currently this is 4096 characters. + +It is recommended you keep /lib/firmware paths on your root filesystem, +avoid having a separate partition for them in order to avoid possible +races with lookups and avoid uses of the custom fallback mechanisms +documented below. + +Firmware and initramfs +---------------------- + +Drivers which are built-in to the kernel should have the firmware integrated +also as part of the initramfs used to boot the kernel given that otherwise +a race is possible with loading the driver and the real rootfs not yet being +available. Stuffing the firmware into initramfs resolves this race issue, +however note that using initrd does not suffice to address the same race. + +There are circumstances that justify not wanting to include firmware into +initramfs, such as dealing with large firmware firmware files for the +remote-proc subsystem. For such cases using a userspace fallback mechanism +is currently the only viable solution as only userspace can know for sure +when the real rootfs is ready and mounted. diff --git a/Documentation/driver-api/firmware/fallback-mechanisms.rst b/Documentation/driver-api/firmware/fallback-mechanisms.rst new file mode 100644 index 000000000000..d19354794e67 --- /dev/null +++ b/Documentation/driver-api/firmware/fallback-mechanisms.rst @@ -0,0 +1,195 @@ +=================== +Fallback mechanisms +=================== + +A fallback mechanism is supported to allow to overcome failures to do a direct +filesystem lookup on the root filesystem or when the firmware simply cannot be +installed for practical reasons on the root filesystem. The kernel +configuration options related to supporting the firmware fallback mechanism are: + + * CONFIG_FW_LOADER_USER_HELPER: enables building the firmware fallback + mechanism. Most distributions enable this option today. If enabled but + CONFIG_FW_LOADER_USER_HELPER_FALLBACK is disabled, only the custom fallback + mechanism is available and for the request_firmware_nowait() call. + * CONFIG_FW_LOADER_USER_HELPER_FALLBACK: force enables each request to + enable the kobject uevent fallback mechanism on all firmware API calls + except request_firmware_direct(). Most distributions disable this option + today. The call request_firmware_nowait() allows for one alternative + fallback mechanism: if this kconfig option is enabled and your second + argument to request_firmware_nowait(), uevent, is set to false you are + informing the kernel that you have a custom fallback mechanism and it will + manually load the firmware. Read below for more details. + +Note that this means when having this configuration: + +CONFIG_FW_LOADER_USER_HELPER=y +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n + +the kobject uevent fallback mechanism will never take effect even +for request_firmware_nowait() when uevent is set to true. + +Justifying the firmware fallback mechanism +========================================== + +Direct filesystem lookups may fail for a variety of reasons. Known reasons for +this are worth itemizing and documenting as it justifies the need for the +fallback mechanism: + +* Race against access with the root filesystem upon bootup. + +* Races upon resume from suspend. This is resolved by the firmware cache, but + the firmware cache is only supported if you use uevents, and its not + supported for request_firmware_into_buf(). + +* Firmware is not accessible through typical means: + * It cannot be installed into the root filesystem + * The firmware provides very unique device specific data tailored for + the unit gathered with local information. An example is calibration + data for WiFi chipsets for mobile devices. This calibration data is + not common to all units, but tailored per unit. Such information may + be installed on a separate flash partition other than where the root + filesystem is provided. + +Types of fallback mechanisms +============================ + +There are really two fallback mechanisms available using one shared sysfs +interface as a loading facility: + +* Kobject uevent fallback mechanism +* Custom fallback mechanism + +First lets document the shared sysfs loading facility. + +Firmware sysfs loading facility +=============================== + +In order to help device drivers upload firmware using a fallback mechanism +the firmware infrastructure creates a sysfs interface to enable userspace +to load and indicate when firmware is ready. The sysfs directory is created +via fw_create_instance(). This call creates a new struct device named after +the firmware requested, and establishes it in the device hierarchy by +associating the device used to make the request as the device's parent. +The sysfs directory's file attributes are defined and controlled through +the new device's class (firmare_class) and group (fw_dev_attr_groups). +This is actually where the original firmware_class.c file name comes from, +as originally the only firmware loading mechanism available was the +mechanism we now use as a fallback mechanism. + +To load firmware using the sysfs interface we expose a loading indicator, +and a file upload firmware into: + + * /sys/$DEVPATH/loading + * /sys/$DEVPATH/data + +To upload firmware you will echo 1 onto the loading file to indicate +you are loading firmware. You then cat the firmware into the data file, +and you notify the kernel the firmware is ready by echo'ing 0 onto +the loading file. + +The firmware device used to help load firmware using sysfs is only created if +direct firmware loading fails and if the fallback mechanism is enabled for your +firmware request, this is set up with fw_load_from_user_helper(). It is +important to re-iterate that no device is created if a direct filesystem lookup +succeeded. + +Using:: + + echo 1 > /sys/$DEVPATH/loading + +Will clean any previous partial load at once and make the firmware API +return an error. When loading firmware the firmware_class grows a buffer +for the firmware in PAGE_SIZE increments to hold the image as it comes in. + +firmware_data_read() and firmware_loading_show() are just provided for the +test_firmware driver for testing, they are not called in normal use or +expected to be used regularly by userspace. + +Firmware kobject uevent fallback mechanism +========================================== + +Since a device is created for the sysfs interface to help load firmware as a +fallback mechanism userspace can be informed of the addition of the device by +relying on kobject uevents. The addition of the device into the device +hierarchy means the fallback mechanism for firmware loading has been initiated. +For details of implementation refer to _request_firmware_load(), in particular +on the use of dev_set_uevent_suppress() and kobject_uevent(). + +The kernel's kobject uevent mechanism is implemented in lib/kobject_uevent.c, +it issues uevents to userspace. As a supplement to kobject uevents Linux +distributions could also enable CONFIG_UEVENT_HELPER_PATH, which makes use of +core kernel's usermode helper (UMH) functionality to call out to a userspace +helper for kobject uevents. In practice though no standard distribution has +ever used the CONFIG_UEVENT_HELPER_PATH. If CONFIG_UEVENT_HELPER_PATH is +enabled this binary would be called each time kobject_uevent_env() gets called +in the kernel for each kobject uevent triggered. + +Different implementations have been supported in userspace to take advantage of +this fallback mechanism. When firmware loading was only possible using the +sysfs mechanism the userspace component "hotplug" provided the functionality of +monitoring for kobject events. Historically this was superseded be systemd's +udev, however firmware loading support was removed from udev as of systemd +commit be2ea723b1d0 ("udev: remove userspace firmware loading support") +as of v217 on August, 2014. This means most Linux distributions today are +not using or taking advantage of the firmware fallback mechanism provided +by kobject uevents. This is specially exacerbated due to the fact that most +distributions today disable CONFIG_FW_LOADER_USER_HELPER_FALLBACK. + +Refer to do_firmware_uevent() for details of the kobject event variables +setup. Variables passwdd with a kobject add event: + +* FIRMWARE=firmware name +* TIMEOUT=timeout value +* ASYNC=whether or not the API request was asynchronous + +By default DEVPATH is set by the internal kernel kobject infrastructure. +Below is an example simple kobject uevent script:: + + # Both $DEVPATH and $FIRMWARE are already provided in the environment. + MY_FW_DIR=/lib/firmware/ + echo 1 > /sys/$DEVPATH/loading + cat $MY_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data + echo 0 > /sys/$DEVPATH/loading + +Firmware custom fallback mechanism +================================== + +Users of the request_firmware_nowait() call have yet another option available +at their disposal: rely on the sysfs fallback mechanism but request that no +kobject uevents be issued to userspace. The original logic behind this +was that utilities other than udev might be required to lookup firmware +in non-traditional paths -- paths outside of the listing documented in the +section 'Direct filesystem lookup'. This option is not available to any of +the other API calls as uevents are always forced for them. + +Since uevents are only meaningful if the fallback mechanism is enabled +in your kernel it would seem odd to enable uevents with kernels that do not +have the fallback mechanism enabled in their kernels. Unfortunately we also +rely on the uevent flag which can be disabled by request_firmware_nowait() to +also setup the firmware cache for firmware requests. As documented above, +the firmware cache is only set up if uevent is enabled for an API call. +Although this can disable the firmware cache for request_firmware_nowait() +calls, users of this API should not use it for the purposes of disabling +the cache as that was not the original purpose of the flag. Not setting +the uevent flag means you want to opt-in for the firmware fallback mechanism +but you want to suppress kobject uevents, as you have a custom solution which +will monitor for your device addition into the device hierarchy somehow and +load firmware for you through a custom path. + +Firmware fallback timeout +========================= + +The firmware fallback mechanism has a timeout. If firmware is not loaded +onto the sysfs interface by the timeout value an error is sent to the +driver. By default the timeout is set to 60 seconds if uevents are +desirable, otherwise MAX_JIFFY_OFFSET is used (max timeout possible). +The logic behind using MAX_JIFFY_OFFSET for non-uevents is that a custom +solution will have as much time as it needs to load firmware. + +You can customize the firmware timeout by echo'ing your desired timeout into +the following file: + +* /sys/class/firmware/timeout + +If you echo 0 into it means MAX_JIFFY_OFFSET will be used. The data type +for the timeout is an int. diff --git a/Documentation/driver-api/firmware/firmware_cache.rst b/Documentation/driver-api/firmware/firmware_cache.rst new file mode 100644 index 000000000000..2210e5bfb332 --- /dev/null +++ b/Documentation/driver-api/firmware/firmware_cache.rst @@ -0,0 +1,51 @@ +============== +Firmware cache +============== + +When Linux resumes from suspend some device drivers require firmware lookups to +re-initialize devices. During resume there may be a period of time during which +firmware lookups are not possible, during this short period of time firmware +requests will fail. Time is of essence though, and delaying drivers to wait for +the root filesystem for firmware delays user experience with device +functionality. In order to support these requirements the firmware +infrastructure implements a firmware cache for device drivers for most API +calls, automatically behind the scenes. + +The firmware cache makes using certain firmware API calls safe during a device +driver's suspend and resume callback. Users of these API calls needn't cache +the firmware by themselves for dealing with firmware loss during system resume. + +The firmware cache works by requesting for firmware prior to suspend and +caching it in memory. Upon resume device drivers using the firmware API will +have access to the firmware immediately, without having to wait for the root +filesystem to mount or dealing with possible race issues with lookups as the +root filesystem mounts. + +Some implementation details about the firmware cache setup: + +* The firmware cache is setup by adding a devres entry for each device that + uses all synchronous call except :c:func:`request_firmware_into_buf`. + +* If an asynchronous call is used the firmware cache is only set up for a + device if if the second argument (uevent) to request_firmware_nowait() is + true. When uevent is true it requests that a kobject uevent be sent to + userspace for the firmware request. For details refer to the Fackback + mechanism documented below. + +* If the firmware cache is determined to be needed as per the above two + criteria the firmware cache is setup by adding a devres entry for the + device making the firmware request. + +* The firmware devres entry is maintained throughout the lifetime of the + device. This means that even if you release_firmware() the firmware cache + will still be used on resume from suspend. + +* The timeout for the fallback mechanism is temporarily reduced to 10 seconds + as the firmware cache is set up during suspend, the timeout is set back to + the old value you had configured after the cache is set up. + +* Upon suspend any pending non-uevent firmware requests are killed to avoid + stalling the kernel, this is done with kill_requests_without_uevent(). Kernel + calls requiring the non-uevent therefore need to implement their own firmware + cache mechanism but must not use the firmware API on suspend. + diff --git a/Documentation/driver-api/firmware/fw_search_path.rst b/Documentation/driver-api/firmware/fw_search_path.rst new file mode 100644 index 000000000000..a360f1009fa3 --- /dev/null +++ b/Documentation/driver-api/firmware/fw_search_path.rst @@ -0,0 +1,26 @@ +===================== +Firmware search paths +===================== + +The following search paths are used to look for firmware on your +root filesystem. + +* fw_path_para - module parameter - default is empty so this is ignored +* /lib/firmware/updates/UTS_RELEASE/ +* /lib/firmware/updates/ +* /lib/firmware/UTS_RELEASE/ +* /lib/firmware/ + +The module parameter ''path'' can be passed to the firmware_class module +to activate the first optional custom fw_path_para. The custom path can +only be up to 256 characters long. The kernel parameter passed would be: + +* 'firmware_class.path=$CUSTOMIZED_PATH' + +There is an alternative to customize the path at run time after bootup, you +can use the file: + +* /sys/module/firmware_class/parameters/path + +You would echo into it your custom path and firmware requested will be +searched for there first. diff --git a/Documentation/driver-api/firmware/index.rst b/Documentation/driver-api/firmware/index.rst new file mode 100644 index 000000000000..1abe01793031 --- /dev/null +++ b/Documentation/driver-api/firmware/index.rst @@ -0,0 +1,16 @@ +================== +Linux Firmware API +================== + +.. toctree:: + + introduction + core + request_firmware + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/driver-api/firmware/introduction.rst b/Documentation/driver-api/firmware/introduction.rst new file mode 100644 index 000000000000..211cb44eb972 --- /dev/null +++ b/Documentation/driver-api/firmware/introduction.rst @@ -0,0 +1,27 @@ +============ +Introduction +============ + +The firmware API enables kernel code to request files required +for functionality from userspace, the uses vary: + +* Microcode for CPU errata +* Device driver firmware, required to be loaded onto device + microcontrollers +* Device driver information data (calibration data, EEPROM overrides), + some of which can be completely optional. + +Types of firmware requests +========================== + +There are two types of calls: + +* Synchronous +* Asynchronous + +Which one you use vary depending on your requirements, the rule of thumb +however is you should strive to use the asynchronous APIs unless you also +are already using asynchronous initialization mechanisms which will not +stall or delay boot. Even if loading firmware does not take a lot of time +processing firmware might, and this can still delay boot or initialization, +as such mechanisms such as asynchronous probe can help supplement drivers. diff --git a/Documentation/driver-api/firmware/lookup-order.rst b/Documentation/driver-api/firmware/lookup-order.rst new file mode 100644 index 000000000000..88c81739683c --- /dev/null +++ b/Documentation/driver-api/firmware/lookup-order.rst @@ -0,0 +1,18 @@ +===================== +Firmware lookup order +===================== + +Different functionality is available to enable firmware to be found. +Below is chronological order of how firmware will be looked for once +a driver issues a firmware API call. + +* The ''Built-in firmware'' is checked first, if the firmware is present we + return it immediately +* The ''Firmware cache'' is looked at next. If the firmware is found we + return it immediately +* The ''Direct filesystem lookup'' is performed next, if found we + return it immediately +* If no firmware has been found and the fallback mechanism was enabled + the sysfs interface is created. After this either a kobject uevent + is issued or the custom firmware loading is relied upon for firmware + loading up to the timeout value. diff --git a/Documentation/driver-api/firmware/request_firmware.rst b/Documentation/driver-api/firmware/request_firmware.rst new file mode 100644 index 000000000000..cc0aea880824 --- /dev/null +++ b/Documentation/driver-api/firmware/request_firmware.rst @@ -0,0 +1,56 @@ +==================== +request_firmware API +==================== + +You would typically load firmware and then load it into your device somehow. +The typical firmware work flow is reflected below:: + + if(request_firmware(&fw_entry, $FIRMWARE, device) == 0) + copy_fw_to_device(fw_entry->data, fw_entry->size); + release_firmware(fw_entry); + +Synchronous firmware requests +============================= + +Synchronous firmware requests will wait until the firmware is found or until +an error is returned. + +request_firmware +---------------- +.. kernel-doc:: drivers/base/firmware_class.c + :functions: request_firmware + +request_firmware_direct +----------------------- +.. kernel-doc:: drivers/base/firmware_class.c + :functions: request_firmware_direct + +request_firmware_into_buf +------------------------- +.. kernel-doc:: drivers/base/firmware_class.c + :functions: request_firmware_into_buf + +Asynchronous firmware requests +============================== + +Asynchronous firmware requests allow driver code to not have to wait +until the firmware or an error is returned. Function callbacks are +provided so that when the firmware or an error is found the driver is +informed through the callback. request_firmware_nowait() cannot be called +in atomic contexts. + +request_firmware_nowait +----------------------- +.. kernel-doc:: drivers/base/firmware_class.c + :functions: request_firmware_nowait + +request firmware API expected driver use +======================================== + +Once an API call returns you process the firmware and then release the +firmware. For example if you used request_firmware() and it returns, +the driver has the firmware image accessible in fw_entry->{data,size}. +If something went wrong request_firmware() returns non-zero and fw_entry +is set to NULL. Once your driver is done with processing the firmware it +can call call release_firmware(fw_entry) to release the firmware image +and any related resource. diff --git a/Documentation/driver-api/iio/buffers.rst b/Documentation/driver-api/iio/buffers.rst new file mode 100644 index 000000000000..02c99a6bee18 --- /dev/null +++ b/Documentation/driver-api/iio/buffers.rst @@ -0,0 +1,125 @@ +======= +Buffers +======= + +* struct :c:type:`iio_buffer` — general buffer structure +* :c:func:`iio_validate_scan_mask_onehot` — Validates that exactly one channel + is selected +* :c:func:`iio_buffer_get` — Grab a reference to the buffer +* :c:func:`iio_buffer_put` — Release the reference to the buffer + +The Industrial I/O core offers a way for continuous data capture based on a +trigger source. Multiple data channels can be read at once from +:file:`/dev/iio:device{X}` character device node, thus reducing the CPU load. + +IIO buffer sysfs interface +========================== +An IIO buffer has an associated attributes directory under +:file:`/sys/bus/iio/iio:device{X}/buffer/*`. Here are some of the existing +attributes: + +* :file:`length`, the total number of data samples (capacity) that can be + stored by the buffer. +* :file:`enable`, activate buffer capture. + +IIO buffer setup +================ + +The meta information associated with a channel reading placed in a buffer is +called a scan element . The important bits configuring scan elements are +exposed to userspace applications via the +:file:`/sys/bus/iio/iio:device{X}/scan_elements/*` directory. This file contains +attributes of the following form: + +* :file:`enable`, used for enabling a channel. If and only if its attribute + is non *zero*, then a triggered capture will contain data samples for this + channel. +* :file:`type`, description of the scan element data storage within the buffer + and hence the form in which it is read from user space. + Format is [be|le]:[s|u]bits/storagebitsXrepeat[>>shift] . + * *be* or *le*, specifies big or little endian. + * *s* or *u*, specifies if signed (2's complement) or unsigned. + * *bits*, is the number of valid data bits. + * *storagebits*, is the number of bits (after padding) that it occupies in the + buffer. + * *shift*, if specified, is the shift that needs to be applied prior to + masking out unused bits. + * *repeat*, specifies the number of bits/storagebits repetitions. When the + repeat element is 0 or 1, then the repeat value is omitted. + +For example, a driver for a 3-axis accelerometer with 12 bit resolution where +data is stored in two 8-bits registers as follows:: + + 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+ + |D3 |D2 |D1 |D0 | X | X | X | X | (LOW byte, address 0x06) + +---+---+---+---+---+---+---+---+ + + 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+ + |D11|D10|D9 |D8 |D7 |D6 |D5 |D4 | (HIGH byte, address 0x07) + +---+---+---+---+---+---+---+---+ + +will have the following scan element type for each axis:: + + $ cat /sys/bus/iio/devices/iio:device0/scan_elements/in_accel_y_type + le:s12/16>>4 + +A user space application will interpret data samples read from the buffer as +two byte little endian signed data, that needs a 4 bits right shift before +masking out the 12 valid bits of data. + +For implementing buffer support a driver should initialize the following +fields in iio_chan_spec definition:: + + struct iio_chan_spec { + /* other members */ + int scan_index + struct { + char sign; + u8 realbits; + u8 storagebits; + u8 shift; + u8 repeat; + enum iio_endian endianness; + } scan_type; + }; + +The driver implementing the accelerometer described above will have the +following channel definition:: + + struct struct iio_chan_spec accel_channels[] = { + { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + /* other stuff here */ + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 12, + .storagebits = 16, + .shift = 4, + .endianness = IIO_LE, + }, + } + /* similar for Y (with channel2 = IIO_MOD_Y, scan_index = 1) + * and Z (with channel2 = IIO_MOD_Z, scan_index = 2) axis + */ + } + +Here **scan_index** defines the order in which the enabled channels are placed +inside the buffer. Channels with a lower **scan_index** will be placed before +channels with a higher index. Each channel needs to have a unique +**scan_index**. + +Setting **scan_index** to -1 can be used to indicate that the specific channel +does not support buffered capture. In this case no entries will be created for +the channel in the scan_elements directory. + +More details +============ +.. kernel-doc:: include/linux/iio/buffer.h +.. kernel-doc:: drivers/iio/industrialio-buffer.c + :export: + diff --git a/Documentation/driver-api/iio/core.rst b/Documentation/driver-api/iio/core.rst new file mode 100644 index 000000000000..9a34ae03b679 --- /dev/null +++ b/Documentation/driver-api/iio/core.rst @@ -0,0 +1,182 @@ +============= +Core elements +============= + +The Industrial I/O core offers a unified framework for writing drivers for +many different types of embedded sensors. a standard interface to user space +applications manipulating sensors. The implementation can be found under +:file:`drivers/iio/industrialio-*` + +Industrial I/O Devices +---------------------- + +* struct :c:type:`iio_dev` - industrial I/O device +* :c:func:`iio_device_alloc()` - alocate an :c:type:`iio_dev` from a driver +* :c:func:`iio_device_free()` - free an :c:type:`iio_dev` from a driver +* :c:func:`iio_device_register()` - register a device with the IIO subsystem +* :c:func:`iio_device_unregister()` - unregister a device from the IIO + subsystem + +An IIO device usually corresponds to a single hardware sensor and it +provides all the information needed by a driver handling a device. +Let's first have a look at the functionality embedded in an IIO device +then we will show how a device driver makes use of an IIO device. + +There are two ways for a user space application to interact with an IIO driver. + +1. :file:`/sys/bus/iio/iio:device{X}/`, this represents a hardware sensor + and groups together the data channels of the same chip. +2. :file:`/dev/iio:device{X}`, character device node interface used for + buffered data transfer and for events information retrieval. + +A typical IIO driver will register itself as an :doc:`I2C <../i2c>` or +:doc:`SPI <../spi>` driver and will create two routines, probe and remove. + +At probe: + +1. Call :c:func:`iio_device_alloc()`, which allocates memory for an IIO device. +2. Initialize IIO device fields with driver specific information (e.g. + device name, device channels). +3. Call :c:func:`iio_device_register()`, this registers the device with the + IIO core. After this call the device is ready to accept requests from user + space applications. + +At remove, we free the resources allocated in probe in reverse order: + +1. :c:func:`iio_device_unregister()`, unregister the device from the IIO core. +2. :c:func:`iio_device_free()`, free the memory allocated for the IIO device. + +IIO device sysfs interface +========================== + +Attributes are sysfs files used to expose chip info and also allowing +applications to set various configuration parameters. For device with +index X, attributes can be found under /sys/bus/iio/iio:deviceX/ directory. +Common attributes are: + +* :file:`name`, description of the physical chip. +* :file:`dev`, shows the major:minor pair associated with + :file:`/dev/iio:deviceX` node. +* :file:`sampling_frequency_available`, available discrete set of sampling + frequency values for device. +* Available standard attributes for IIO devices are described in the + :file:`Documentation/ABI/testing/sysfs-bus-iio` file in the Linux kernel + sources. + +IIO device channels +=================== + +struct :c:type:`iio_chan_spec` - specification of a single channel + +An IIO device channel is a representation of a data channel. An IIO device can +have one or multiple channels. For example: + +* a thermometer sensor has one channel representing the temperature measurement. +* a light sensor with two channels indicating the measurements in the visible + and infrared spectrum. +* an accelerometer can have up to 3 channels representing acceleration on X, Y + and Z axes. + +An IIO channel is described by the struct :c:type:`iio_chan_spec`. +A thermometer driver for the temperature sensor in the example above would +have to describe its channel as follows:: + + static const struct iio_chan_spec temp_channel[] = { + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + }, + }; + +Channel sysfs attributes exposed to userspace are specified in the form of +bitmasks. Depending on their shared info, attributes can be set in one of the +following masks: + +* **info_mask_separate**, attributes will be specific to + this channel +* **info_mask_shared_by_type**, attributes are shared by all channels of the + same type +* **info_mask_shared_by_dir**, attributes are shared by all channels of the same + direction +* **info_mask_shared_by_all**, attributes are shared by all channels + +When there are multiple data channels per channel type we have two ways to +distinguish between them: + +* set **.modified** field of :c:type:`iio_chan_spec` to 1. Modifiers are + specified using **.channel2** field of the same :c:type:`iio_chan_spec` + structure and are used to indicate a physically unique characteristic of the + channel such as its direction or spectral response. For example, a light + sensor can have two channels, one for infrared light and one for both + infrared and visible light. +* set **.indexed** field of :c:type:`iio_chan_spec` to 1. In this case the + channel is simply another instance with an index specified by the **.channel** + field. + +Here is how we can make use of the channel's modifiers:: + + static const struct iio_chan_spec light_channels[] = { + { + .type = IIO_INTENSITY, + .modified = 1, + .channel2 = IIO_MOD_LIGHT_IR, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ), + }, + { + .type = IIO_INTENSITY, + .modified = 1, + .channel2 = IIO_MOD_LIGHT_BOTH, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ), + }, + { + .type = IIO_LIGHT, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ), + }, + } + +This channel's definition will generate two separate sysfs files for raw data +retrieval: + +* :file:`/sys/bus/iio/iio:device{X}/in_intensity_ir_raw` +* :file:`/sys/bus/iio/iio:device{X}/in_intensity_both_raw` + +one file for processed data: + +* :file:`/sys/bus/iio/iio:device{X}/in_illuminance_input` + +and one shared sysfs file for sampling frequency: + +* :file:`/sys/bus/iio/iio:device{X}/sampling_frequency`. + +Here is how we can make use of the channel's indexing:: + + static const struct iio_chan_spec light_channels[] = { + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + }, + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + }, + } + +This will generate two separate attributes files for raw data retrieval: + +* :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage0_raw`, representing + voltage measurement for channel 0. +* :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage1_raw`, representing + voltage measurement for channel 1. + +More details +============ +.. kernel-doc:: include/linux/iio/iio.h +.. kernel-doc:: drivers/iio/industrialio-core.c + :export: diff --git a/Documentation/driver-api/iio/index.rst b/Documentation/driver-api/iio/index.rst new file mode 100644 index 000000000000..e5c3922d1b6f --- /dev/null +++ b/Documentation/driver-api/iio/index.rst @@ -0,0 +1,17 @@ +.. include:: <isonum.txt> + +Industrial I/O +============== + +**Copyright** |copy| 2015 Intel Corporation + +Contents: + +.. toctree:: + :maxdepth: 2 + + intro + core + buffers + triggers + triggered-buffers diff --git a/Documentation/driver-api/iio/intro.rst b/Documentation/driver-api/iio/intro.rst new file mode 100644 index 000000000000..3653fbd57069 --- /dev/null +++ b/Documentation/driver-api/iio/intro.rst @@ -0,0 +1,33 @@ +.. include:: <isonum.txt> + +============ +Introduction +============ + +The main purpose of the Industrial I/O subsystem (IIO) is to provide support +for devices that in some sense perform either +analog-to-digital conversion (ADC) or digital-to-analog conversion (DAC) +or both. The aim is to fill the gap between the somewhat similar hwmon and +:doc:`input <../input>` subsystems. Hwmon is directed at low sample rate +sensors used to monitor and control the system itself, like fan speed control +or temperature measurement. :doc:`Input <../input>` is, as its name suggests, +focused on human interaction input devices (keyboard, mouse, touchscreen). +In some cases there is considerable overlap between these and IIO. + +Devices that fall into this category include: + +* analog to digital converters (ADCs) +* accelerometers +* capacitance to digital converters (CDCs) +* digital to analog converters (DACs) +* gyroscopes +* inertial measurement units (IMUs) +* color and light sensors +* magnetometers +* pressure sensors +* proximity sensors +* temperature sensors + +Usually these sensors are connected via :doc:`SPI <../spi>` or +:doc:`I2C <../i2c>`. A common use case of the sensors devices is to have +combined functionality (e.g. light plus proximity sensor). diff --git a/Documentation/driver-api/iio/triggered-buffers.rst b/Documentation/driver-api/iio/triggered-buffers.rst new file mode 100644 index 000000000000..0db12660cc90 --- /dev/null +++ b/Documentation/driver-api/iio/triggered-buffers.rst @@ -0,0 +1,69 @@ +================= +Triggered Buffers +================= + +Now that we know what buffers and triggers are let's see how they work together. + +IIO triggered buffer setup +========================== + +* :c:func:`iio_triggered_buffer_setup` — Setup triggered buffer and pollfunc +* :c:func:`iio_triggered_buffer_cleanup` — Free resources allocated by + :c:func:`iio_triggered_buffer_setup` +* struct :c:type:`iio_buffer_setup_ops` — buffer setup related callbacks + +A typical triggered buffer setup looks like this:: + + const struct iio_buffer_setup_ops sensor_buffer_setup_ops = { + .preenable = sensor_buffer_preenable, + .postenable = sensor_buffer_postenable, + .postdisable = sensor_buffer_postdisable, + .predisable = sensor_buffer_predisable, + }; + + irqreturn_t sensor_iio_pollfunc(int irq, void *p) + { + pf->timestamp = iio_get_time_ns((struct indio_dev *)p); + return IRQ_WAKE_THREAD; + } + + irqreturn_t sensor_trigger_handler(int irq, void *p) + { + u16 buf[8]; + int i = 0; + + /* read data for each active channel */ + for_each_set_bit(bit, active_scan_mask, masklength) + buf[i++] = sensor_get_data(bit) + + iio_push_to_buffers_with_timestamp(indio_dev, buf, timestamp); + + iio_trigger_notify_done(trigger); + return IRQ_HANDLED; + } + + /* setup triggered buffer, usually in probe function */ + iio_triggered_buffer_setup(indio_dev, sensor_iio_polfunc, + sensor_trigger_handler, + sensor_buffer_setup_ops); + +The important things to notice here are: + +* :c:type:`iio_buffer_setup_ops`, the buffer setup functions to be called at + predefined points in the buffer configuration sequence (e.g. before enable, + after disable). If not specified, the IIO core uses the default + iio_triggered_buffer_setup_ops. +* **sensor_iio_pollfunc**, the function that will be used as top half of poll + function. It should do as little processing as possible, because it runs in + interrupt context. The most common operation is recording of the current + timestamp and for this reason one can use the IIO core defined + :c:func:`iio_pollfunc_store_time` function. +* **sensor_trigger_handler**, the function that will be used as bottom half of + the poll function. This runs in the context of a kernel thread and all the + processing takes place here. It usually reads data from the device and + stores it in the internal buffer together with the timestamp recorded in the + top half. + +More details +============ +.. kernel-doc:: drivers/iio/buffer/industrialio-triggered-buffer.c diff --git a/Documentation/driver-api/iio/triggers.rst b/Documentation/driver-api/iio/triggers.rst new file mode 100644 index 000000000000..f89d37e7dd82 --- /dev/null +++ b/Documentation/driver-api/iio/triggers.rst @@ -0,0 +1,80 @@ +======== +Triggers +======== + +* struct :c:type:`iio_trigger` — industrial I/O trigger device +* :c:func:`devm_iio_trigger_alloc` — Resource-managed iio_trigger_alloc +* :c:func:`devm_iio_trigger_free` — Resource-managed iio_trigger_free +* :c:func:`devm_iio_trigger_register` — Resource-managed iio_trigger_register +* :c:func:`devm_iio_trigger_unregister` — Resource-managed + iio_trigger_unregister +* :c:func:`iio_trigger_validate_own_device` — Check if a trigger and IIO + device belong to the same device + +In many situations it is useful for a driver to be able to capture data based +on some external event (trigger) as opposed to periodically polling for data. +An IIO trigger can be provided by a device driver that also has an IIO device +based on hardware generated events (e.g. data ready or threshold exceeded) or +provided by a separate driver from an independent interrupt source (e.g. GPIO +line connected to some external system, timer interrupt or user space writing +a specific file in sysfs). A trigger may initiate data capture for a number of +sensors and also it may be completely unrelated to the sensor itself. + +IIO trigger sysfs interface +=========================== + +There are two locations in sysfs related to triggers: + +* :file:`/sys/bus/iio/devices/trigger{Y}/*`, this file is created once an + IIO trigger is registered with the IIO core and corresponds to trigger + with index Y. + Because triggers can be very different depending on type there are few + standard attributes that we can describe here: + + * :file:`name`, trigger name that can be later used for association with a + device. + * :file:`sampling_frequency`, some timer based triggers use this attribute to + specify the frequency for trigger calls. + +* :file:`/sys/bus/iio/devices/iio:device{X}/trigger/*`, this directory is + created once the device supports a triggered buffer. We can associate a + trigger with our device by writing the trigger's name in the + :file:`current_trigger` file. + +IIO trigger setup +================= + +Let's see a simple example of how to setup a trigger to be used by a driver:: + + struct iio_trigger_ops trigger_ops = { + .set_trigger_state = sample_trigger_state, + .validate_device = sample_validate_device, + } + + struct iio_trigger *trig; + + /* first, allocate memory for our trigger */ + trig = iio_trigger_alloc(dev, "trig-%s-%d", name, idx); + + /* setup trigger operations field */ + trig->ops = &trigger_ops; + + /* now register the trigger with the IIO core */ + iio_trigger_register(trig); + +IIO trigger ops +=============== + +* struct :c:type:`iio_trigger_ops` — operations structure for an iio_trigger. + +Notice that a trigger has a set of operations attached: + +* :file:`set_trigger_state`, switch the trigger on/off on demand. +* :file:`validate_device`, function to validate the device when the current + trigger gets changed. + +More details +============ +.. kernel-doc:: include/linux/iio/trigger.h +.. kernel-doc:: drivers/iio/industrialio-trigger.c + :export: diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index 8e259c5d0322..60db00d1532b 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -16,11 +16,30 @@ available subsections can be seen below. basics infrastructure + pm/index + device-io + dma-buf + device_link message-based sound frame-buffer + regulator + iio/index input + usb spi i2c hsi + edac miscellaneous + vme + 80211/index + uio-howto + firmware/index + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/driver-api/infrastructure.rst b/Documentation/driver-api/infrastructure.rst index 5d50d6733db3..6d9ff316b608 100644 --- a/Documentation/driver-api/infrastructure.rst +++ b/Documentation/driver-api/infrastructure.rst @@ -46,76 +46,6 @@ Device Drivers Base .. kernel-doc:: drivers/base/bus.c :export: -Buffer Sharing and Synchronization ----------------------------------- - -The dma-buf subsystem provides the framework for sharing buffers for -hardware (DMA) access across multiple device drivers and subsystems, and -for synchronizing asynchronous hardware access. - -This is used, for example, by drm "prime" multi-GPU support, but is of -course not limited to GPU use cases. - -The three main components of this are: (1) dma-buf, representing a -sg_table and exposed to userspace as a file descriptor to allow passing -between devices, (2) fence, which provides a mechanism to signal when -one device as finished access, and (3) reservation, which manages the -shared or exclusive fence(s) associated with the buffer. - -dma-buf -~~~~~~~ - -.. kernel-doc:: drivers/dma-buf/dma-buf.c - :export: - -.. kernel-doc:: include/linux/dma-buf.h - :internal: - -reservation -~~~~~~~~~~~ - -.. kernel-doc:: drivers/dma-buf/reservation.c - :doc: Reservation Object Overview - -.. kernel-doc:: drivers/dma-buf/reservation.c - :export: - -.. kernel-doc:: include/linux/reservation.h - :internal: - -fence -~~~~~ - -.. kernel-doc:: drivers/dma-buf/fence.c - :export: - -.. kernel-doc:: include/linux/fence.h - :internal: - -.. kernel-doc:: drivers/dma-buf/seqno-fence.c - :export: - -.. kernel-doc:: include/linux/seqno-fence.h - :internal: - -.. kernel-doc:: drivers/dma-buf/fence-array.c - :export: - -.. kernel-doc:: include/linux/fence-array.h - :internal: - -.. kernel-doc:: drivers/dma-buf/reservation.c - :export: - -.. kernel-doc:: include/linux/reservation.h - :internal: - -.. kernel-doc:: drivers/dma-buf/sync_file.c - :export: - -.. kernel-doc:: include/linux/sync_file.h - :internal: - Device Drivers DMA Management ----------------------------- @@ -125,21 +55,6 @@ Device Drivers DMA Management .. kernel-doc:: drivers/base/dma-mapping.c :export: -Device Drivers Power Management -------------------------------- - -.. kernel-doc:: drivers/base/power/main.c - :export: - -Device Drivers ACPI Support ---------------------------- - -.. kernel-doc:: drivers/acpi/scan.c - :export: - -.. kernel-doc:: drivers/acpi/scan.c - :internal: - Device drivers PnP support -------------------------- diff --git a/Documentation/driver-api/pm/conf.py b/Documentation/driver-api/pm/conf.py new file mode 100644 index 000000000000..a89fac11272f --- /dev/null +++ b/Documentation/driver-api/pm/conf.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8; mode: python -*- + +project = "Device Power Management" + +tags.add("subproject") + +latex_documents = [ + ('index', 'pm.tex', project, + 'The kernel development community', 'manual'), +] diff --git a/Documentation/driver-api/pm/devices.rst b/Documentation/driver-api/pm/devices.rst new file mode 100644 index 000000000000..bedd32388dac --- /dev/null +++ b/Documentation/driver-api/pm/devices.rst @@ -0,0 +1,736 @@ +.. |struct dev_pm_ops| replace:: :c:type:`struct dev_pm_ops <dev_pm_ops>` +.. |struct dev_pm_domain| replace:: :c:type:`struct dev_pm_domain <dev_pm_domain>` +.. |struct bus_type| replace:: :c:type:`struct bus_type <bus_type>` +.. |struct device_type| replace:: :c:type:`struct device_type <device_type>` +.. |struct class| replace:: :c:type:`struct class <class>` +.. |struct wakeup_source| replace:: :c:type:`struct wakeup_source <wakeup_source>` +.. |struct device| replace:: :c:type:`struct device <device>` + +============================== +Device Power Management Basics +============================== + +:: + + Copyright (c) 2010-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. + Copyright (c) 2010 Alan Stern <stern@rowland.harvard.edu> + Copyright (c) 2016 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +Most of the code in Linux is device drivers, so most of the Linux power +management (PM) code is also driver-specific. Most drivers will do very +little; others, especially for platforms with small batteries (like cell +phones), will do a lot. + +This writeup gives an overview of how drivers interact with system-wide +power management goals, emphasizing the models and interfaces that are +shared by everything that hooks up to the driver model core. Read it as +background for the domain-specific work you'd do with any specific driver. + + +Two Models for Device Power Management +====================================== + +Drivers will use one or both of these models to put devices into low-power +states: + + System Sleep model: + + Drivers can enter low-power states as part of entering system-wide + low-power states like "suspend" (also known as "suspend-to-RAM"), or + (mostly for systems with disks) "hibernation" (also known as + "suspend-to-disk"). + + This is something that device, bus, and class drivers collaborate on + by implementing various role-specific suspend and resume methods to + cleanly power down hardware and software subsystems, then reactivate + them without loss of data. + + Some drivers can manage hardware wakeup events, which make the system + leave the low-power state. This feature may be enabled or disabled + using the relevant :file:`/sys/devices/.../power/wakeup` file (for + Ethernet drivers the ioctl interface used by ethtool may also be used + for this purpose); enabling it may cost some power usage, but let the + whole system enter low-power states more often. + + Runtime Power Management model: + + Devices may also be put into low-power states while the system is + running, independently of other power management activity in principle. + However, devices are not generally independent of each other (for + example, a parent device cannot be suspended unless all of its child + devices have been suspended). Moreover, depending on the bus type the + device is on, it may be necessary to carry out some bus-specific + operations on the device for this purpose. Devices put into low power + states at run time may require special handling during system-wide power + transitions (suspend or hibernation). + + For these reasons not only the device driver itself, but also the + appropriate subsystem (bus type, device type or device class) driver and + the PM core are involved in runtime power management. As in the system + sleep power management case, they need to collaborate by implementing + various role-specific suspend and resume methods, so that the hardware + is cleanly powered down and reactivated without data or service loss. + +There's not a lot to be said about those low-power states except that they are +very system-specific, and often device-specific. Also, that if enough devices +have been put into low-power states (at runtime), the effect may be very similar +to entering some system-wide low-power state (system sleep) ... and that +synergies exist, so that several drivers using runtime PM might put the system +into a state where even deeper power saving options are available. + +Most suspended devices will have quiesced all I/O: no more DMA or IRQs (except +for wakeup events), no more data read or written, and requests from upstream +drivers are no longer accepted. A given bus or platform may have different +requirements though. + +Examples of hardware wakeup events include an alarm from a real time clock, +network wake-on-LAN packets, keyboard or mouse activity, and media insertion +or removal (for PCMCIA, MMC/SD, USB, and so on). + +Interfaces for Entering System Sleep States +=========================================== + +There are programming interfaces provided for subsystems (bus type, device type, +device class) and device drivers to allow them to participate in the power +management of devices they are concerned with. These interfaces cover both +system sleep and runtime power management. + + +Device Power Management Operations +---------------------------------- + +Device power management operations, at the subsystem level as well as at the +device driver level, are implemented by defining and populating objects of type +|struct dev_pm_ops| defined in :file:`include/linux/pm.h`. The roles of the +methods included in it will be explained in what follows. For now, it should be +sufficient to remember that the last three methods are specific to runtime power +management while the remaining ones are used during system-wide power +transitions. + +There also is a deprecated "old" or "legacy" interface for power management +operations available at least for some subsystems. This approach does not use +|struct dev_pm_ops| objects and it is suitable only for implementing system +sleep power management methods in a limited way. Therefore it is not described +in this document, so please refer directly to the source code for more +information about it. + + +Subsystem-Level Methods +----------------------- + +The core methods to suspend and resume devices reside in +|struct dev_pm_ops| pointed to by the :c:member:`ops` member of +|struct dev_pm_domain|, or by the :c:member:`pm` member of |struct bus_type|, +|struct device_type| and |struct class|. They are mostly of interest to the +people writing infrastructure for platforms and buses, like PCI or USB, or +device type and device class drivers. They also are relevant to the writers of +device drivers whose subsystems (PM domains, device types, device classes and +bus types) don't provide all power management methods. + +Bus drivers implement these methods as appropriate for the hardware and the +drivers using it; PCI works differently from USB, and so on. Not many people +write subsystem-level drivers; most driver code is a "device driver" that builds +on top of bus-specific framework code. + +For more information on these driver calls, see the description later; +they are called in phases for every device, respecting the parent-child +sequencing in the driver model tree. + + +:file:`/sys/devices/.../power/wakeup` files +------------------------------------------- + +All device objects in the driver model contain fields that control the handling +of system wakeup events (hardware signals that can force the system out of a +sleep state). These fields are initialized by bus or device driver code using +:c:func:`device_set_wakeup_capable()` and :c:func:`device_set_wakeup_enable()`, +defined in :file:`include/linux/pm_wakeup.h`. + +The :c:member:`power.can_wakeup` flag just records whether the device (and its +driver) can physically support wakeup events. The +:c:func:`device_set_wakeup_capable()` routine affects this flag. The +:c:member:`power.wakeup` field is a pointer to an object of type +|struct wakeup_source| used for controlling whether or not the device should use +its system wakeup mechanism and for notifying the PM core of system wakeup +events signaled by the device. This object is only present for wakeup-capable +devices (i.e. devices whose :c:member:`can_wakeup` flags are set) and is created +(or removed) by :c:func:`device_set_wakeup_capable()`. + +Whether or not a device is capable of issuing wakeup events is a hardware +matter, and the kernel is responsible for keeping track of it. By contrast, +whether or not a wakeup-capable device should issue wakeup events is a policy +decision, and it is managed by user space through a sysfs attribute: the +:file:`power/wakeup` file. User space can write the "enabled" or "disabled" +strings to it to indicate whether or not, respectively, the device is supposed +to signal system wakeup. This file is only present if the +:c:member:`power.wakeup` object exists for the given device and is created (or +removed) along with that object, by :c:func:`device_set_wakeup_capable()`. +Reads from the file will return the corresponding string. + +The initial value in the :file:`power/wakeup` file is "disabled" for the +majority of devices; the major exceptions are power buttons, keyboards, and +Ethernet adapters whose WoL (wake-on-LAN) feature has been set up with ethtool. +It should also default to "enabled" for devices that don't generate wakeup +requests on their own but merely forward wakeup requests from one bus to another +(like PCI Express ports). + +The :c:func:`device_may_wakeup()` routine returns true only if the +:c:member:`power.wakeup` object exists and the corresponding :file:`power/wakeup` +file contains the "enabled" string. This information is used by subsystems, +like the PCI bus type code, to see whether or not to enable the devices' wakeup +mechanisms. If device wakeup mechanisms are enabled or disabled directly by +drivers, they also should use :c:func:`device_may_wakeup()` to decide what to do +during a system sleep transition. Device drivers, however, are not expected to +call :c:func:`device_set_wakeup_enable()` directly in any case. + +It ought to be noted that system wakeup is conceptually different from "remote +wakeup" used by runtime power management, although it may be supported by the +same physical mechanism. Remote wakeup is a feature allowing devices in +low-power states to trigger specific interrupts to signal conditions in which +they should be put into the full-power state. Those interrupts may or may not +be used to signal system wakeup events, depending on the hardware design. On +some systems it is impossible to trigger them from system sleep states. In any +case, remote wakeup should always be enabled for runtime power management for +all devices and drivers that support it. + + +:file:`/sys/devices/.../power/control` files +-------------------------------------------- + +Each device in the driver model has a flag to control whether it is subject to +runtime power management. This flag, :c:member:`runtime_auto`, is initialized +by the bus type (or generally subsystem) code using :c:func:`pm_runtime_allow()` +or :c:func:`pm_runtime_forbid()`; the default is to allow runtime power +management. + +The setting can be adjusted by user space by writing either "on" or "auto" to +the device's :file:`power/control` sysfs file. Writing "auto" calls +:c:func:`pm_runtime_allow()`, setting the flag and allowing the device to be +runtime power-managed by its driver. Writing "on" calls +:c:func:`pm_runtime_forbid()`, clearing the flag, returning the device to full +power if it was in a low-power state, and preventing the +device from being runtime power-managed. User space can check the current value +of the :c:member:`runtime_auto` flag by reading that file. + +The device's :c:member:`runtime_auto` flag has no effect on the handling of +system-wide power transitions. In particular, the device can (and in the +majority of cases should and will) be put into a low-power state during a +system-wide transition to a sleep state even though its :c:member:`runtime_auto` +flag is clear. + +For more information about the runtime power management framework, refer to +:file:`Documentation/power/runtime_pm.txt`. + + +Calling Drivers to Enter and Leave System Sleep States +====================================================== + +When the system goes into a sleep state, each device's driver is asked to +suspend the device by putting it into a state compatible with the target +system state. That's usually some version of "off", but the details are +system-specific. Also, wakeup-enabled devices will usually stay partly +functional in order to wake the system. + +When the system leaves that low-power state, the device's driver is asked to +resume it by returning it to full power. The suspend and resume operations +always go together, and both are multi-phase operations. + +For simple drivers, suspend might quiesce the device using class code +and then turn its hardware as "off" as possible during suspend_noirq. The +matching resume calls would then completely reinitialize the hardware +before reactivating its class I/O queues. + +More power-aware drivers might prepare the devices for triggering system wakeup +events. + + +Call Sequence Guarantees +------------------------ + +To ensure that bridges and similar links needing to talk to a device are +available when the device is suspended or resumed, the device hierarchy is +walked in a bottom-up order to suspend devices. A top-down order is +used to resume those devices. + +The ordering of the device hierarchy is defined by the order in which devices +get registered: a child can never be registered, probed or resumed before +its parent; and can't be removed or suspended after that parent. + +The policy is that the device hierarchy should match hardware bus topology. +[Or at least the control bus, for devices which use multiple busses.] +In particular, this means that a device registration may fail if the parent of +the device is suspending (i.e. has been chosen by the PM core as the next +device to suspend) or has already suspended, as well as after all of the other +devices have been suspended. Device drivers must be prepared to cope with such +situations. + + +System Power Management Phases +------------------------------ + +Suspending or resuming the system is done in several phases. Different phases +are used for suspend-to-idle, shallow (standby), and deep ("suspend-to-RAM") +sleep states and the hibernation state ("suspend-to-disk"). Each phase involves +executing callbacks for every device before the next phase begins. Not all +buses or classes support all these callbacks and not all drivers use all the +callbacks. The various phases always run after tasks have been frozen and +before they are unfrozen. Furthermore, the ``*_noirq phases`` run at a time +when IRQ handlers have been disabled (except for those marked with the +IRQF_NO_SUSPEND flag). + +All phases use PM domain, bus, type, class or driver callbacks (that is, methods +defined in ``dev->pm_domain->ops``, ``dev->bus->pm``, ``dev->type->pm``, +``dev->class->pm`` or ``dev->driver->pm``). These callbacks are regarded by the +PM core as mutually exclusive. Moreover, PM domain callbacks always take +precedence over all of the other callbacks and, for example, type callbacks take +precedence over bus, class and driver callbacks. To be precise, the following +rules are used to determine which callback to execute in the given phase: + + 1. If ``dev->pm_domain`` is present, the PM core will choose the callback + provided by ``dev->pm_domain->ops`` for execution. + + 2. Otherwise, if both ``dev->type`` and ``dev->type->pm`` are present, the + callback provided by ``dev->type->pm`` will be chosen for execution. + + 3. Otherwise, if both ``dev->class`` and ``dev->class->pm`` are present, + the callback provided by ``dev->class->pm`` will be chosen for + execution. + + 4. Otherwise, if both ``dev->bus`` and ``dev->bus->pm`` are present, the + callback provided by ``dev->bus->pm`` will be chosen for execution. + +This allows PM domains and device types to override callbacks provided by bus +types or device classes if necessary. + +The PM domain, type, class and bus callbacks may in turn invoke device- or +driver-specific methods stored in ``dev->driver->pm``, but they don't have to do +that. + +If the subsystem callback chosen for execution is not present, the PM core will +execute the corresponding method from the ``dev->driver->pm`` set instead if +there is one. + + +Entering System Suspend +----------------------- + +When the system goes into the freeze, standby or memory sleep state, +the phases are: ``prepare``, ``suspend``, ``suspend_late``, ``suspend_noirq``. + + 1. The ``prepare`` phase is meant to prevent races by preventing new + devices from being registered; the PM core would never know that all the + children of a device had been suspended if new children could be + registered at will. [By contrast, from the PM core's perspective, + devices may be unregistered at any time.] Unlike the other + suspend-related phases, during the ``prepare`` phase the device + hierarchy is traversed top-down. + + After the ``->prepare`` callback method returns, no new children may be + registered below the device. The method may also prepare the device or + driver in some way for the upcoming system power transition, but it + should not put the device into a low-power state. + + For devices supporting runtime power management, the return value of the + prepare callback can be used to indicate to the PM core that it may + safely leave the device in runtime suspend (if runtime-suspended + already), provided that all of the device's descendants are also left in + runtime suspend. Namely, if the prepare callback returns a positive + number and that happens for all of the descendants of the device too, + and all of them (including the device itself) are runtime-suspended, the + PM core will skip the ``suspend``, ``suspend_late`` and + ``suspend_noirq`` phases as well as all of the corresponding phases of + the subsequent device resume for all of these devices. In that case, + the ``->complete`` callback will be invoked directly after the + ``->prepare`` callback and is entirely responsible for putting the + device into a consistent state as appropriate. + + Note that this direct-complete procedure applies even if the device is + disabled for runtime PM; only the runtime-PM status matters. It follows + that if a device has system-sleep callbacks but does not support runtime + PM, then its prepare callback must never return a positive value. This + is because all such devices are initially set to runtime-suspended with + runtime PM disabled. + + 2. The ``->suspend`` methods should quiesce the device to stop it from + performing I/O. They also may save the device registers and put it into + the appropriate low-power state, depending on the bus type the device is + on, and they may enable wakeup events. + + 3. For a number of devices it is convenient to split suspend into the + "quiesce device" and "save device state" phases, in which cases + ``suspend_late`` is meant to do the latter. It is always executed after + runtime power management has been disabled for the device in question. + + 4. The ``suspend_noirq`` phase occurs after IRQ handlers have been disabled, + which means that the driver's interrupt handler will not be called while + the callback method is running. The ``->suspend_noirq`` methods should + save the values of the device's registers that weren't saved previously + and finally put the device into the appropriate low-power state. + + The majority of subsystems and device drivers need not implement this + callback. However, bus types allowing devices to share interrupt + vectors, like PCI, generally need it; otherwise a driver might encounter + an error during the suspend phase by fielding a shared interrupt + generated by some other device after its own device had been set to low + power. + +At the end of these phases, drivers should have stopped all I/O transactions +(DMA, IRQs), saved enough state that they can re-initialize or restore previous +state (as needed by the hardware), and placed the device into a low-power state. +On many platforms they will gate off one or more clock sources; sometimes they +will also switch off power supplies or reduce voltages. [Drivers supporting +runtime PM may already have performed some or all of these steps.] + +If :c:func:`device_may_wakeup(dev)` returns ``true``, the device should be +prepared for generating hardware wakeup signals to trigger a system wakeup event +when the system is in the sleep state. For example, :c:func:`enable_irq_wake()` +might identify GPIO signals hooked up to a switch or other external hardware, +and :c:func:`pci_enable_wake()` does something similar for the PCI PME signal. + +If any of these callbacks returns an error, the system won't enter the desired +low-power state. Instead, the PM core will unwind its actions by resuming all +the devices that were suspended. + + +Leaving System Suspend +---------------------- + +When resuming from freeze, standby or memory sleep, the phases are: +``resume_noirq``, ``resume_early``, ``resume``, ``complete``. + + 1. The ``->resume_noirq`` callback methods should perform any actions + needed before the driver's interrupt handlers are invoked. This + generally means undoing the actions of the ``suspend_noirq`` phase. If + the bus type permits devices to share interrupt vectors, like PCI, the + method should bring the device and its driver into a state in which the + driver can recognize if the device is the source of incoming interrupts, + if any, and handle them correctly. + + For example, the PCI bus type's ``->pm.resume_noirq()`` puts the device + into the full-power state (D0 in the PCI terminology) and restores the + standard configuration registers of the device. Then it calls the + device driver's ``->pm.resume_noirq()`` method to perform device-specific + actions. + + 2. The ``->resume_early`` methods should prepare devices for the execution + of the resume methods. This generally involves undoing the actions of + the preceding ``suspend_late`` phase. + + 3. The ``->resume`` methods should bring the device back to its operating + state, so that it can perform normal I/O. This generally involves + undoing the actions of the ``suspend`` phase. + + 4. The ``complete`` phase should undo the actions of the ``prepare`` phase. + For this reason, unlike the other resume-related phases, during the + ``complete`` phase the device hierarchy is traversed bottom-up. + + Note, however, that new children may be registered below the device as + soon as the ``->resume`` callbacks occur; it's not necessary to wait + until the ``complete`` phase with that. + + Moreover, if the preceding ``->prepare`` callback returned a positive + number, the device may have been left in runtime suspend throughout the + whole system suspend and resume (the ``suspend``, ``suspend_late``, + ``suspend_noirq`` phases of system suspend and the ``resume_noirq``, + ``resume_early``, ``resume`` phases of system resume may have been + skipped for it). In that case, the ``->complete`` callback is entirely + responsible for putting the device into a consistent state after system + suspend if necessary. [For example, it may need to queue up a runtime + resume request for the device for this purpose.] To check if that is + the case, the ``->complete`` callback can consult the device's + ``power.direct_complete`` flag. Namely, if that flag is set when the + ``->complete`` callback is being run, it has been called directly after + the preceding ``->prepare`` and special actions may be required + to make the device work correctly afterward. + +At the end of these phases, drivers should be as functional as they were before +suspending: I/O can be performed using DMA and IRQs, and the relevant clocks are +gated on. + +However, the details here may again be platform-specific. For example, +some systems support multiple "run" states, and the mode in effect at +the end of resume might not be the one which preceded suspension. +That means availability of certain clocks or power supplies changed, +which could easily affect how a driver works. + +Drivers need to be able to handle hardware which has been reset since all of the +suspend methods were called, for example by complete reinitialization. +This may be the hardest part, and the one most protected by NDA'd documents +and chip errata. It's simplest if the hardware state hasn't changed since +the suspend was carried out, but that can only be guaranteed if the target +system sleep entered was suspend-to-idle. For the other system sleep states +that may not be the case (and usually isn't for ACPI-defined system sleep +states, like S3). + +Drivers must also be prepared to notice that the device has been removed +while the system was powered down, whenever that's physically possible. +PCMCIA, MMC, USB, Firewire, SCSI, and even IDE are common examples of busses +where common Linux platforms will see such removal. Details of how drivers +will notice and handle such removals are currently bus-specific, and often +involve a separate thread. + +These callbacks may return an error value, but the PM core will ignore such +errors since there's nothing it can do about them other than printing them in +the system log. + + +Entering Hibernation +-------------------- + +Hibernating the system is more complicated than putting it into sleep states, +because it involves creating and saving a system image. Therefore there are +more phases for hibernation, with a different set of callbacks. These phases +always run after tasks have been frozen and enough memory has been freed. + +The general procedure for hibernation is to quiesce all devices ("freeze"), +create an image of the system memory while everything is stable, reactivate all +devices ("thaw"), write the image to permanent storage, and finally shut down +the system ("power off"). The phases used to accomplish this are: ``prepare``, +``freeze``, ``freeze_late``, ``freeze_noirq``, ``thaw_noirq``, ``thaw_early``, +``thaw``, ``complete``, ``prepare``, ``poweroff``, ``poweroff_late``, +``poweroff_noirq``. + + 1. The ``prepare`` phase is discussed in the "Entering System Suspend" + section above. + + 2. The ``->freeze`` methods should quiesce the device so that it doesn't + generate IRQs or DMA, and they may need to save the values of device + registers. However the device does not have to be put in a low-power + state, and to save time it's best not to do so. Also, the device should + not be prepared to generate wakeup events. + + 3. The ``freeze_late`` phase is analogous to the ``suspend_late`` phase + described earlier, except that the device should not be put into a + low-power state and should not be allowed to generate wakeup events. + + 4. The ``freeze_noirq`` phase is analogous to the ``suspend_noirq`` phase + discussed earlier, except again that the device should not be put into + a low-power state and should not be allowed to generate wakeup events. + +At this point the system image is created. All devices should be inactive and +the contents of memory should remain undisturbed while this happens, so that the +image forms an atomic snapshot of the system state. + + 5. The ``thaw_noirq`` phase is analogous to the ``resume_noirq`` phase + discussed earlier. The main difference is that its methods can assume + the device is in the same state as at the end of the ``freeze_noirq`` + phase. + + 6. The ``thaw_early`` phase is analogous to the ``resume_early`` phase + described above. Its methods should undo the actions of the preceding + ``freeze_late``, if necessary. + + 7. The ``thaw`` phase is analogous to the ``resume`` phase discussed + earlier. Its methods should bring the device back to an operating + state, so that it can be used for saving the image if necessary. + + 8. The ``complete`` phase is discussed in the "Leaving System Suspend" + section above. + +At this point the system image is saved, and the devices then need to be +prepared for the upcoming system shutdown. This is much like suspending them +before putting the system into the suspend-to-idle, shallow or deep sleep state, +and the phases are similar. + + 9. The ``prepare`` phase is discussed above. + + 10. The ``poweroff`` phase is analogous to the ``suspend`` phase. + + 11. The ``poweroff_late`` phase is analogous to the ``suspend_late`` phase. + + 12. The ``poweroff_noirq`` phase is analogous to the ``suspend_noirq`` phase. + +The ``->poweroff``, ``->poweroff_late`` and ``->poweroff_noirq`` callbacks +should do essentially the same things as the ``->suspend``, ``->suspend_late`` +and ``->suspend_noirq`` callbacks, respectively. The only notable difference is +that they need not store the device register values, because the registers +should already have been stored during the ``freeze``, ``freeze_late`` or +``freeze_noirq`` phases. + + +Leaving Hibernation +------------------- + +Resuming from hibernation is, again, more complicated than resuming from a sleep +state in which the contents of main memory are preserved, because it requires +a system image to be loaded into memory and the pre-hibernation memory contents +to be restored before control can be passed back to the image kernel. + +Although in principle the image might be loaded into memory and the +pre-hibernation memory contents restored by the boot loader, in practice this +can't be done because boot loaders aren't smart enough and there is no +established protocol for passing the necessary information. So instead, the +boot loader loads a fresh instance of the kernel, called "the restore kernel", +into memory and passes control to it in the usual way. Then the restore kernel +reads the system image, restores the pre-hibernation memory contents, and passes +control to the image kernel. Thus two different kernel instances are involved +in resuming from hibernation. In fact, the restore kernel may be completely +different from the image kernel: a different configuration and even a different +version. This has important consequences for device drivers and their +subsystems. + +To be able to load the system image into memory, the restore kernel needs to +include at least a subset of device drivers allowing it to access the storage +medium containing the image, although it doesn't need to include all of the +drivers present in the image kernel. After the image has been loaded, the +devices managed by the boot kernel need to be prepared for passing control back +to the image kernel. This is very similar to the initial steps involved in +creating a system image, and it is accomplished in the same way, using +``prepare``, ``freeze``, and ``freeze_noirq`` phases. However, the devices +affected by these phases are only those having drivers in the restore kernel; +other devices will still be in whatever state the boot loader left them. + +Should the restoration of the pre-hibernation memory contents fail, the restore +kernel would go through the "thawing" procedure described above, using the +``thaw_noirq``, ``thaw_early``, ``thaw``, and ``complete`` phases, and then +continue running normally. This happens only rarely. Most often the +pre-hibernation memory contents are restored successfully and control is passed +to the image kernel, which then becomes responsible for bringing the system back +to the working state. + +To achieve this, the image kernel must restore the devices' pre-hibernation +functionality. The operation is much like waking up from a sleep state (with +the memory contents preserved), although it involves different phases: +``restore_noirq``, ``restore_early``, ``restore``, ``complete``. + + 1. The ``restore_noirq`` phase is analogous to the ``resume_noirq`` phase. + + 2. The ``restore_early`` phase is analogous to the ``resume_early`` phase. + + 3. The ``restore`` phase is analogous to the ``resume`` phase. + + 4. The ``complete`` phase is discussed above. + +The main difference from ``resume[_early|_noirq]`` is that +``restore[_early|_noirq]`` must assume the device has been accessed and +reconfigured by the boot loader or the restore kernel. Consequently, the state +of the device may be different from the state remembered from the ``freeze``, +``freeze_late`` and ``freeze_noirq`` phases. The device may even need to be +reset and completely re-initialized. In many cases this difference doesn't +matter, so the ``->resume[_early|_noirq]`` and ``->restore[_early|_norq]`` +method pointers can be set to the same routines. Nevertheless, different +callback pointers are used in case there is a situation where it actually does +matter. + + +Power Management Notifiers +========================== + +There are some operations that cannot be carried out by the power management +callbacks discussed above, because the callbacks occur too late or too early. +To handle these cases, subsystems and device drivers may register power +management notifiers that are called before tasks are frozen and after they have +been thawed. Generally speaking, the PM notifiers are suitable for performing +actions that either require user space to be available, or at least won't +interfere with user space. + +For details refer to :doc:`notifiers`. + + +Device Low-Power (suspend) States +================================= + +Device low-power states aren't standard. One device might only handle +"on" and "off", while another might support a dozen different versions of +"on" (how many engines are active?), plus a state that gets back to "on" +faster than from a full "off". + +Some buses define rules about what different suspend states mean. PCI +gives one example: after the suspend sequence completes, a non-legacy +PCI device may not perform DMA or issue IRQs, and any wakeup events it +issues would be issued through the PME# bus signal. Plus, there are +several PCI-standard device states, some of which are optional. + +In contrast, integrated system-on-chip processors often use IRQs as the +wakeup event sources (so drivers would call :c:func:`enable_irq_wake`) and +might be able to treat DMA completion as a wakeup event (sometimes DMA can stay +active too, it'd only be the CPU and some peripherals that sleep). + +Some details here may be platform-specific. Systems may have devices that +can be fully active in certain sleep states, such as an LCD display that's +refreshed using DMA while most of the system is sleeping lightly ... and +its frame buffer might even be updated by a DSP or other non-Linux CPU while +the Linux control processor stays idle. + +Moreover, the specific actions taken may depend on the target system state. +One target system state might allow a given device to be very operational; +another might require a hard shut down with re-initialization on resume. +And two different target systems might use the same device in different +ways; the aforementioned LCD might be active in one product's "standby", +but a different product using the same SOC might work differently. + + +Device Power Management Domains +=============================== + +Sometimes devices share reference clocks or other power resources. In those +cases it generally is not possible to put devices into low-power states +individually. Instead, a set of devices sharing a power resource can be put +into a low-power state together at the same time by turning off the shared +power resource. Of course, they also need to be put into the full-power state +together, by turning the shared power resource on. A set of devices with this +property is often referred to as a power domain. A power domain may also be +nested inside another power domain. The nested domain is referred to as the +sub-domain of the parent domain. + +Support for power domains is provided through the :c:member:`pm_domain` field of +|struct device|. This field is a pointer to an object of type +|struct dev_pm_domain|, defined in :file:`include/linux/pm.h``, providing a set +of power management callbacks analogous to the subsystem-level and device driver +callbacks that are executed for the given device during all power transitions, +instead of the respective subsystem-level callbacks. Specifically, if a +device's :c:member:`pm_domain` pointer is not NULL, the ``->suspend()`` callback +from the object pointed to by it will be executed instead of its subsystem's +(e.g. bus type's) ``->suspend()`` callback and analogously for all of the +remaining callbacks. In other words, power management domain callbacks, if +defined for the given device, always take precedence over the callbacks provided +by the device's subsystem (e.g. bus type). + +The support for device power management domains is only relevant to platforms +needing to use the same device driver power management callbacks in many +different power domain configurations and wanting to avoid incorporating the +support for power domains into subsystem-level callbacks, for example by +modifying the platform bus type. Other platforms need not implement it or take +it into account in any way. + +Devices may be defined as IRQ-safe which indicates to the PM core that their +runtime PM callbacks may be invoked with disabled interrupts (see +:file:`Documentation/power/runtime_pm.txt` for more information). If an +IRQ-safe device belongs to a PM domain, the runtime PM of the domain will be +disallowed, unless the domain itself is defined as IRQ-safe. However, it +makes sense to define a PM domain as IRQ-safe only if all the devices in it +are IRQ-safe. Moreover, if an IRQ-safe domain has a parent domain, the runtime +PM of the parent is only allowed if the parent itself is IRQ-safe too with the +additional restriction that all child domains of an IRQ-safe parent must also +be IRQ-safe. + + +Runtime Power Management +======================== + +Many devices are able to dynamically power down while the system is still +running. This feature is useful for devices that are not being used, and +can offer significant power savings on a running system. These devices +often support a range of runtime power states, which might use names such +as "off", "sleep", "idle", "active", and so on. Those states will in some +cases (like PCI) be partially constrained by the bus the device uses, and will +usually include hardware states that are also used in system sleep states. + +A system-wide power transition can be started while some devices are in low +power states due to runtime power management. The system sleep PM callbacks +should recognize such situations and react to them appropriately, but the +necessary actions are subsystem-specific. + +In some cases the decision may be made at the subsystem level while in other +cases the device driver may be left to decide. In some cases it may be +desirable to leave a suspended device in that state during a system-wide power +transition, but in other cases the device must be put back into the full-power +state temporarily, for example so that its system wakeup capability can be +disabled. This all depends on the hardware and the design of the subsystem and +device driver in question. + +During system-wide resume from a sleep state it's easiest to put devices into +the full-power state, as explained in :file:`Documentation/power/runtime_pm.txt`. +Refer to that document for more information regarding this particular issue as +well as for information on the device runtime power management framework in +general. diff --git a/Documentation/driver-api/pm/index.rst b/Documentation/driver-api/pm/index.rst new file mode 100644 index 000000000000..2f6d0e9cf6b7 --- /dev/null +++ b/Documentation/driver-api/pm/index.rst @@ -0,0 +1,16 @@ +======================= +Device Power Management +======================= + +.. toctree:: + + devices + notifiers + types + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/driver-api/pm/notifiers.rst b/Documentation/driver-api/pm/notifiers.rst new file mode 100644 index 000000000000..62f860026992 --- /dev/null +++ b/Documentation/driver-api/pm/notifiers.rst @@ -0,0 +1,70 @@ +============================= +Suspend/Hibernation Notifiers +============================= + +:: + + Copyright (c) 2016 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +There are some operations that subsystems or drivers may want to carry out +before hibernation/suspend or after restore/resume, but they require the system +to be fully functional, so the drivers' and subsystems' ``->suspend()`` and +``->resume()`` or even ``->prepare()`` and ``->complete()`` callbacks are not +suitable for this purpose. + +For example, device drivers may want to upload firmware to their devices after +resume/restore, but they cannot do it by calling :c:func:`request_firmware()` +from their ``->resume()`` or ``->complete()`` callback routines (user land +processes are frozen at these points). The solution may be to load the firmware +into memory before processes are frozen and upload it from there in the +``->resume()`` routine. A suspend/hibernation notifier may be used for that. + +Subsystems or drivers having such needs can register suspend notifiers that +will be called upon the following events by the PM core: + +``PM_HIBERNATION_PREPARE`` + The system is going to hibernate, tasks will be frozen immediately. This + is different from ``PM_SUSPEND_PREPARE`` below, because in this case + additional work is done between the notifiers and the invocation of PM + callbacks for the "freeze" transition. + +``PM_POST_HIBERNATION`` + The system memory state has been restored from a hibernation image or an + error occurred during hibernation. Device restore callbacks have been + executed and tasks have been thawed. + +``PM_RESTORE_PREPARE`` + The system is going to restore a hibernation image. If all goes well, + the restored image kernel will issue a ``PM_POST_HIBERNATION`` + notification. + +``PM_POST_RESTORE`` + An error occurred during restore from hibernation. Device restore + callbacks have been executed and tasks have been thawed. + +``PM_SUSPEND_PREPARE`` + The system is preparing for suspend. + +``PM_POST_SUSPEND`` + The system has just resumed or an error occurred during suspend. Device + resume callbacks have been executed and tasks have been thawed. + +It is generally assumed that whatever the notifiers do for +``PM_HIBERNATION_PREPARE``, should be undone for ``PM_POST_HIBERNATION``. +Analogously, operations carried out for ``PM_SUSPEND_PREPARE`` should be +reversed for ``PM_POST_SUSPEND``. + +Moreover, if one of the notifiers fails for the ``PM_HIBERNATION_PREPARE`` or +``PM_SUSPEND_PREPARE`` event, the notifiers that have already succeeded for that +event will be called for ``PM_POST_HIBERNATION`` or ``PM_POST_SUSPEND``, +respectively. + +The hibernation and suspend notifiers are called with :c:data:`pm_mutex` held. +They are defined in the usual way, but their last argument is meaningless (it is +always NULL). + +To register and/or unregister a suspend notifier use +:c:func:`register_pm_notifier()` and :c:func:`unregister_pm_notifier()`, +respectively (both defined in :file:`include/linux/suspend.h`). If you don't +need to unregister the notifier, you can also use the :c:func:`pm_notifier()` +macro defined in :file:`include/linux/suspend.h`. diff --git a/Documentation/driver-api/pm/types.rst b/Documentation/driver-api/pm/types.rst new file mode 100644 index 000000000000..3ebdecc54104 --- /dev/null +++ b/Documentation/driver-api/pm/types.rst @@ -0,0 +1,5 @@ +================================== +Device Power Management Data Types +================================== + +.. kernel-doc:: include/linux/pm.h diff --git a/Documentation/driver-api/regulator.rst b/Documentation/driver-api/regulator.rst new file mode 100644 index 000000000000..520da0a5251d --- /dev/null +++ b/Documentation/driver-api/regulator.rst @@ -0,0 +1,170 @@ +.. Copyright 2007-2008 Wolfson Microelectronics + +.. This documentation is free software; you can redistribute +.. it and/or modify it under the terms of the GNU General Public +.. License version 2 as published by the Free Software Foundation. + +================================= +Voltage and current regulator API +================================= + +:Author: Liam Girdwood +:Author: Mark Brown + +Introduction +============ + +This framework is designed to provide a standard kernel interface to +control voltage and current regulators. + +The intention is to allow systems to dynamically control regulator power +output in order to save power and prolong battery life. This applies to +both voltage regulators (where voltage output is controllable) and +current sinks (where current limit is controllable). + +Note that additional (and currently more complete) documentation is +available in the Linux kernel source under +``Documentation/power/regulator``. + +Glossary +-------- + +The regulator API uses a number of terms which may not be familiar: + +Regulator + + Electronic device that supplies power to other devices. Most regulators + can enable and disable their output and some can also control their + output voltage or current. + +Consumer + + Electronic device which consumes power provided by a regulator. These + may either be static, requiring only a fixed supply, or dynamic, + requiring active management of the regulator at runtime. + +Power Domain + + The electronic circuit supplied by a given regulator, including the + regulator and all consumer devices. The configuration of the regulator + is shared between all the components in the circuit. + +Power Management Integrated Circuit (PMIC) + + An IC which contains numerous regulators and often also other + subsystems. In an embedded system the primary PMIC is often equivalent + to a combination of the PSU and southbridge in a desktop system. + +Consumer driver interface +========================= + +This offers a similar API to the kernel clock framework. Consumer +drivers use `get <#API-regulator-get>`__ and +`put <#API-regulator-put>`__ operations to acquire and release +regulators. Functions are provided to `enable <#API-regulator-enable>`__ +and `disable <#API-regulator-disable>`__ the regulator and to get and +set the runtime parameters of the regulator. + +When requesting regulators consumers use symbolic names for their +supplies, such as "Vcc", which are mapped into actual regulator devices +by the machine interface. + +A stub version of this API is provided when the regulator framework is +not in use in order to minimise the need to use ifdefs. + +Enabling and disabling +---------------------- + +The regulator API provides reference counted enabling and disabling of +regulators. Consumer devices use the :c:func:`regulator_enable()` and +:c:func:`regulator_disable()` functions to enable and disable +regulators. Calls to the two functions must be balanced. + +Note that since multiple consumers may be using a regulator and machine +constraints may not allow the regulator to be disabled there is no +guarantee that calling :c:func:`regulator_disable()` will actually +cause the supply provided by the regulator to be disabled. Consumer +drivers should assume that the regulator may be enabled at all times. + +Configuration +------------- + +Some consumer devices may need to be able to dynamically configure their +supplies. For example, MMC drivers may need to select the correct +operating voltage for their cards. This may be done while the regulator +is enabled or disabled. + +The :c:func:`regulator_set_voltage()` and +:c:func:`regulator_set_current_limit()` functions provide the primary +interface for this. Both take ranges of voltages and currents, supporting +drivers that do not require a specific value (eg, CPU frequency scaling +normally permits the CPU to use a wider range of supply voltages at lower +frequencies but does not require that the supply voltage be lowered). Where +an exact value is required both minimum and maximum values should be +identical. + +Callbacks +--------- + +Callbacks may also be registered for events such as regulation failures. + +Regulator driver interface +========================== + +Drivers for regulator chips register the regulators with the regulator +core, providing operations structures to the core. A notifier interface +allows error conditions to be reported to the core. + +Registration should be triggered by explicit setup done by the platform, +supplying a struct :c:type:`regulator_init_data` for the regulator +containing constraint and supply information. + +Machine interface +================= + +This interface provides a way to define how regulators are connected to +consumers on a given system and what the valid operating parameters are +for the system. + +Supplies +-------- + +Regulator supplies are specified using struct +:c:type:`regulator_consumer_supply`. This is done at driver registration +time as part of the machine constraints. + +Constraints +----------- + +As well as defining the connections the machine interface also provides +constraints defining the operations that clients are allowed to perform +and the parameters that may be set. This is required since generally +regulator devices will offer more flexibility than it is safe to use on +a given system, for example supporting higher supply voltages than the +consumers are rated for. + +This is done at driver registration time` by providing a +struct :c:type:`regulation_constraints`. + +The constraints may also specify an initial configuration for the +regulator in the constraints, which is particularly useful for use with +static consumers. + +API reference +============= + +Due to limitations of the kernel documentation framework and the +existing layout of the source code the entire regulator API is +documented here. + +.. kernel-doc:: include/linux/regulator/consumer.h + :internal: + +.. kernel-doc:: include/linux/regulator/machine.h + :internal: + +.. kernel-doc:: include/linux/regulator/driver.h + :internal: + +.. kernel-doc:: drivers/regulator/core.c + :export: diff --git a/Documentation/driver-api/uio-howto.rst b/Documentation/driver-api/uio-howto.rst new file mode 100644 index 000000000000..f73d660b2956 --- /dev/null +++ b/Documentation/driver-api/uio-howto.rst @@ -0,0 +1,705 @@ +======================= +The Userspace I/O HOWTO +======================= + +:Author: Hans-Jürgen Koch Linux developer, Linutronix +:Date: 2006-12-11 + +About this document +=================== + +Translations +------------ + +If you know of any translations for this document, or you are interested +in translating it, please email me hjk@hansjkoch.de. + +Preface +------- + +For many types of devices, creating a Linux kernel driver is overkill. +All that is really needed is some way to handle an interrupt and provide +access to the memory space of the device. The logic of controlling the +device does not necessarily have to be within the kernel, as the device +does not need to take advantage of any of other resources that the +kernel provides. One such common class of devices that are like this are +for industrial I/O cards. + +To address this situation, the userspace I/O system (UIO) was designed. +For typical industrial I/O cards, only a very small kernel module is +needed. The main part of the driver will run in user space. This +simplifies development and reduces the risk of serious bugs within a +kernel module. + +Please note that UIO is not an universal driver interface. Devices that +are already handled well by other kernel subsystems (like networking or +serial or USB) are no candidates for an UIO driver. Hardware that is +ideally suited for an UIO driver fulfills all of the following: + +- The device has memory that can be mapped. The device can be + controlled completely by writing to this memory. + +- The device usually generates interrupts. + +- The device does not fit into one of the standard kernel subsystems. + +Acknowledgments +--------------- + +I'd like to thank Thomas Gleixner and Benedikt Spranger of Linutronix, +who have not only written most of the UIO code, but also helped greatly +writing this HOWTO by giving me all kinds of background information. + +Feedback +-------- + +Find something wrong with this document? (Or perhaps something right?) I +would love to hear from you. Please email me at hjk@hansjkoch.de. + +About UIO +========= + +If you use UIO for your card's driver, here's what you get: + +- only one small kernel module to write and maintain. + +- develop the main part of your driver in user space, with all the + tools and libraries you're used to. + +- bugs in your driver won't crash the kernel. + +- updates of your driver can take place without recompiling the kernel. + +How UIO works +------------- + +Each UIO device is accessed through a device file and several sysfs +attribute files. The device file will be called ``/dev/uio0`` for the +first device, and ``/dev/uio1``, ``/dev/uio2`` and so on for subsequent +devices. + +``/dev/uioX`` is used to access the address space of the card. Just use +:c:func:`mmap()` to access registers or RAM locations of your card. + +Interrupts are handled by reading from ``/dev/uioX``. A blocking +:c:func:`read()` from ``/dev/uioX`` will return as soon as an +interrupt occurs. You can also use :c:func:`select()` on +``/dev/uioX`` to wait for an interrupt. The integer value read from +``/dev/uioX`` represents the total interrupt count. You can use this +number to figure out if you missed some interrupts. + +For some hardware that has more than one interrupt source internally, +but not separate IRQ mask and status registers, there might be +situations where userspace cannot determine what the interrupt source +was if the kernel handler disables them by writing to the chip's IRQ +register. In such a case, the kernel has to disable the IRQ completely +to leave the chip's register untouched. Now the userspace part can +determine the cause of the interrupt, but it cannot re-enable +interrupts. Another cornercase is chips where re-enabling interrupts is +a read-modify-write operation to a combined IRQ status/acknowledge +register. This would be racy if a new interrupt occurred simultaneously. + +To address these problems, UIO also implements a write() function. It is +normally not used and can be ignored for hardware that has only a single +interrupt source or has separate IRQ mask and status registers. If you +need it, however, a write to ``/dev/uioX`` will call the +:c:func:`irqcontrol()` function implemented by the driver. You have +to write a 32-bit value that is usually either 0 or 1 to disable or +enable interrupts. If a driver does not implement +:c:func:`irqcontrol()`, :c:func:`write()` will return with +``-ENOSYS``. + +To handle interrupts properly, your custom kernel module can provide its +own interrupt handler. It will automatically be called by the built-in +handler. + +For cards that don't generate interrupts but need to be polled, there is +the possibility to set up a timer that triggers the interrupt handler at +configurable time intervals. This interrupt simulation is done by +calling :c:func:`uio_event_notify()` from the timer's event +handler. + +Each driver provides attributes that are used to read or write +variables. These attributes are accessible through sysfs files. A custom +kernel driver module can add its own attributes to the device owned by +the uio driver, but not added to the UIO device itself at this time. +This might change in the future if it would be found to be useful. + +The following standard attributes are provided by the UIO framework: + +- ``name``: The name of your device. It is recommended to use the name + of your kernel module for this. + +- ``version``: A version string defined by your driver. This allows the + user space part of your driver to deal with different versions of the + kernel module. + +- ``event``: The total number of interrupts handled by the driver since + the last time the device node was read. + +These attributes appear under the ``/sys/class/uio/uioX`` directory. +Please note that this directory might be a symlink, and not a real +directory. Any userspace code that accesses it must be able to handle +this. + +Each UIO device can make one or more memory regions available for memory +mapping. This is necessary because some industrial I/O cards require +access to more than one PCI memory region in a driver. + +Each mapping has its own directory in sysfs, the first mapping appears +as ``/sys/class/uio/uioX/maps/map0/``. Subsequent mappings create +directories ``map1/``, ``map2/``, and so on. These directories will only +appear if the size of the mapping is not 0. + +Each ``mapX/`` directory contains four read-only files that show +attributes of the memory: + +- ``name``: A string identifier for this mapping. This is optional, the + string can be empty. Drivers can set this to make it easier for + userspace to find the correct mapping. + +- ``addr``: The address of memory that can be mapped. + +- ``size``: The size, in bytes, of the memory pointed to by addr. + +- ``offset``: The offset, in bytes, that has to be added to the pointer + returned by :c:func:`mmap()` to get to the actual device memory. + This is important if the device's memory is not page aligned. + Remember that pointers returned by :c:func:`mmap()` are always + page aligned, so it is good style to always add this offset. + +From userspace, the different mappings are distinguished by adjusting +the ``offset`` parameter of the :c:func:`mmap()` call. To map the +memory of mapping N, you have to use N times the page size as your +offset:: + + offset = N * getpagesize(); + +Sometimes there is hardware with memory-like regions that can not be +mapped with the technique described here, but there are still ways to +access them from userspace. The most common example are x86 ioports. On +x86 systems, userspace can access these ioports using +:c:func:`ioperm()`, :c:func:`iopl()`, :c:func:`inb()`, +:c:func:`outb()`, and similar functions. + +Since these ioport regions can not be mapped, they will not appear under +``/sys/class/uio/uioX/maps/`` like the normal memory described above. +Without information about the port regions a hardware has to offer, it +becomes difficult for the userspace part of the driver to find out which +ports belong to which UIO device. + +To address this situation, the new directory +``/sys/class/uio/uioX/portio/`` was added. It only exists if the driver +wants to pass information about one or more port regions to userspace. +If that is the case, subdirectories named ``port0``, ``port1``, and so +on, will appear underneath ``/sys/class/uio/uioX/portio/``. + +Each ``portX/`` directory contains four read-only files that show name, +start, size, and type of the port region: + +- ``name``: A string identifier for this port region. The string is + optional and can be empty. Drivers can set it to make it easier for + userspace to find a certain port region. + +- ``start``: The first port of this region. + +- ``size``: The number of ports in this region. + +- ``porttype``: A string describing the type of port. + +Writing your own kernel module +============================== + +Please have a look at ``uio_cif.c`` as an example. The following +paragraphs explain the different sections of this file. + +struct uio_info +--------------- + +This structure tells the framework the details of your driver, Some of +the members are required, others are optional. + +- ``const char *name``: Required. The name of your driver as it will + appear in sysfs. I recommend using the name of your module for this. + +- ``const char *version``: Required. This string appears in + ``/sys/class/uio/uioX/version``. + +- ``struct uio_mem mem[ MAX_UIO_MAPS ]``: Required if you have memory + that can be mapped with :c:func:`mmap()`. For each mapping you + need to fill one of the ``uio_mem`` structures. See the description + below for details. + +- ``struct uio_port port[ MAX_UIO_PORTS_REGIONS ]``: Required if you + want to pass information about ioports to userspace. For each port + region you need to fill one of the ``uio_port`` structures. See the + description below for details. + +- ``long irq``: Required. If your hardware generates an interrupt, it's + your modules task to determine the irq number during initialization. + If you don't have a hardware generated interrupt but want to trigger + the interrupt handler in some other way, set ``irq`` to + ``UIO_IRQ_CUSTOM``. If you had no interrupt at all, you could set + ``irq`` to ``UIO_IRQ_NONE``, though this rarely makes sense. + +- ``unsigned long irq_flags``: Required if you've set ``irq`` to a + hardware interrupt number. The flags given here will be used in the + call to :c:func:`request_irq()`. + +- ``int (*mmap)(struct uio_info *info, struct vm_area_struct *vma)``: + Optional. If you need a special :c:func:`mmap()` + function, you can set it here. If this pointer is not NULL, your + :c:func:`mmap()` will be called instead of the built-in one. + +- ``int (*open)(struct uio_info *info, struct inode *inode)``: + Optional. You might want to have your own :c:func:`open()`, + e.g. to enable interrupts only when your device is actually used. + +- ``int (*release)(struct uio_info *info, struct inode *inode)``: + Optional. If you define your own :c:func:`open()`, you will + probably also want a custom :c:func:`release()` function. + +- ``int (*irqcontrol)(struct uio_info *info, s32 irq_on)``: + Optional. If you need to be able to enable or disable interrupts + from userspace by writing to ``/dev/uioX``, you can implement this + function. The parameter ``irq_on`` will be 0 to disable interrupts + and 1 to enable them. + +Usually, your device will have one or more memory regions that can be +mapped to user space. For each region, you have to set up a +``struct uio_mem`` in the ``mem[]`` array. Here's a description of the +fields of ``struct uio_mem``: + +- ``const char *name``: Optional. Set this to help identify the memory + region, it will show up in the corresponding sysfs node. + +- ``int memtype``: Required if the mapping is used. Set this to + ``UIO_MEM_PHYS`` if you you have physical memory on your card to be + mapped. Use ``UIO_MEM_LOGICAL`` for logical memory (e.g. allocated + with :c:func:`kmalloc()`). There's also ``UIO_MEM_VIRTUAL`` for + virtual memory. + +- ``phys_addr_t addr``: Required if the mapping is used. Fill in the + address of your memory block. This address is the one that appears in + sysfs. + +- ``resource_size_t size``: Fill in the size of the memory block that + ``addr`` points to. If ``size`` is zero, the mapping is considered + unused. Note that you *must* initialize ``size`` with zero for all + unused mappings. + +- ``void *internal_addr``: If you have to access this memory region + from within your kernel module, you will want to map it internally by + using something like :c:func:`ioremap()`. Addresses returned by + this function cannot be mapped to user space, so you must not store + it in ``addr``. Use ``internal_addr`` instead to remember such an + address. + +Please do not touch the ``map`` element of ``struct uio_mem``! It is +used by the UIO framework to set up sysfs files for this mapping. Simply +leave it alone. + +Sometimes, your device can have one or more port regions which can not +be mapped to userspace. But if there are other possibilities for +userspace to access these ports, it makes sense to make information +about the ports available in sysfs. For each region, you have to set up +a ``struct uio_port`` in the ``port[]`` array. Here's a description of +the fields of ``struct uio_port``: + +- ``char *porttype``: Required. Set this to one of the predefined + constants. Use ``UIO_PORT_X86`` for the ioports found in x86 + architectures. + +- ``unsigned long start``: Required if the port region is used. Fill in + the number of the first port of this region. + +- ``unsigned long size``: Fill in the number of ports in this region. + If ``size`` is zero, the region is considered unused. Note that you + *must* initialize ``size`` with zero for all unused regions. + +Please do not touch the ``portio`` element of ``struct uio_port``! It is +used internally by the UIO framework to set up sysfs files for this +region. Simply leave it alone. + +Adding an interrupt handler +--------------------------- + +What you need to do in your interrupt handler depends on your hardware +and on how you want to handle it. You should try to keep the amount of +code in your kernel interrupt handler low. If your hardware requires no +action that you *have* to perform after each interrupt, then your +handler can be empty. + +If, on the other hand, your hardware *needs* some action to be performed +after each interrupt, then you *must* do it in your kernel module. Note +that you cannot rely on the userspace part of your driver. Your +userspace program can terminate at any time, possibly leaving your +hardware in a state where proper interrupt handling is still required. + +There might also be applications where you want to read data from your +hardware at each interrupt and buffer it in a piece of kernel memory +you've allocated for that purpose. With this technique you could avoid +loss of data if your userspace program misses an interrupt. + +A note on shared interrupts: Your driver should support interrupt +sharing whenever this is possible. It is possible if and only if your +driver can detect whether your hardware has triggered the interrupt or +not. This is usually done by looking at an interrupt status register. If +your driver sees that the IRQ bit is actually set, it will perform its +actions, and the handler returns IRQ_HANDLED. If the driver detects +that it was not your hardware that caused the interrupt, it will do +nothing and return IRQ_NONE, allowing the kernel to call the next +possible interrupt handler. + +If you decide not to support shared interrupts, your card won't work in +computers with no free interrupts. As this frequently happens on the PC +platform, you can save yourself a lot of trouble by supporting interrupt +sharing. + +Using uio_pdrv for platform devices +----------------------------------- + +In many cases, UIO drivers for platform devices can be handled in a +generic way. In the same place where you define your +``struct platform_device``, you simply also implement your interrupt +handler and fill your ``struct uio_info``. A pointer to this +``struct uio_info`` is then used as ``platform_data`` for your platform +device. + +You also need to set up an array of ``struct resource`` containing +addresses and sizes of your memory mappings. This information is passed +to the driver using the ``.resource`` and ``.num_resources`` elements of +``struct platform_device``. + +You now have to set the ``.name`` element of ``struct platform_device`` +to ``"uio_pdrv"`` to use the generic UIO platform device driver. This +driver will fill the ``mem[]`` array according to the resources given, +and register the device. + +The advantage of this approach is that you only have to edit a file you +need to edit anyway. You do not have to create an extra driver. + +Using uio_pdrv_genirq for platform devices +------------------------------------------ + +Especially in embedded devices, you frequently find chips where the irq +pin is tied to its own dedicated interrupt line. In such cases, where +you can be really sure the interrupt is not shared, we can take the +concept of ``uio_pdrv`` one step further and use a generic interrupt +handler. That's what ``uio_pdrv_genirq`` does. + +The setup for this driver is the same as described above for +``uio_pdrv``, except that you do not implement an interrupt handler. The +``.handler`` element of ``struct uio_info`` must remain ``NULL``. The +``.irq_flags`` element must not contain ``IRQF_SHARED``. + +You will set the ``.name`` element of ``struct platform_device`` to +``"uio_pdrv_genirq"`` to use this driver. + +The generic interrupt handler of ``uio_pdrv_genirq`` will simply disable +the interrupt line using :c:func:`disable_irq_nosync()`. After +doing its work, userspace can reenable the interrupt by writing +0x00000001 to the UIO device file. The driver already implements an +:c:func:`irq_control()` to make this possible, you must not +implement your own. + +Using ``uio_pdrv_genirq`` not only saves a few lines of interrupt +handler code. You also do not need to know anything about the chip's +internal registers to create the kernel part of the driver. All you need +to know is the irq number of the pin the chip is connected to. + +Using uio_dmem_genirq for platform devices +------------------------------------------ + +In addition to statically allocated memory ranges, they may also be a +desire to use dynamically allocated regions in a user space driver. In +particular, being able to access memory made available through the +dma-mapping API, may be particularly useful. The ``uio_dmem_genirq`` +driver provides a way to accomplish this. + +This driver is used in a similar manner to the ``"uio_pdrv_genirq"`` +driver with respect to interrupt configuration and handling. + +Set the ``.name`` element of ``struct platform_device`` to +``"uio_dmem_genirq"`` to use this driver. + +When using this driver, fill in the ``.platform_data`` element of +``struct platform_device``, which is of type +``struct uio_dmem_genirq_pdata`` and which contains the following +elements: + +- ``struct uio_info uioinfo``: The same structure used as the + ``uio_pdrv_genirq`` platform data + +- ``unsigned int *dynamic_region_sizes``: Pointer to list of sizes of + dynamic memory regions to be mapped into user space. + +- ``unsigned int num_dynamic_regions``: Number of elements in + ``dynamic_region_sizes`` array. + +The dynamic regions defined in the platform data will be appended to the +`` mem[] `` array after the platform device resources, which implies +that the total number of static and dynamic memory regions cannot exceed +``MAX_UIO_MAPS``. + +The dynamic memory regions will be allocated when the UIO device file, +``/dev/uioX`` is opened. Similar to static memory resources, the memory +region information for dynamic regions is then visible via sysfs at +``/sys/class/uio/uioX/maps/mapY/*``. The dynamic memory regions will be +freed when the UIO device file is closed. When no processes are holding +the device file open, the address returned to userspace is ~0. + +Writing a driver in userspace +============================= + +Once you have a working kernel module for your hardware, you can write +the userspace part of your driver. You don't need any special libraries, +your driver can be written in any reasonable language, you can use +floating point numbers and so on. In short, you can use all the tools +and libraries you'd normally use for writing a userspace application. + +Getting information about your UIO device +----------------------------------------- + +Information about all UIO devices is available in sysfs. The first thing +you should do in your driver is check ``name`` and ``version`` to make +sure your talking to the right device and that its kernel driver has the +version you expect. + +You should also make sure that the memory mapping you need exists and +has the size you expect. + +There is a tool called ``lsuio`` that lists UIO devices and their +attributes. It is available here: + +http://www.osadl.org/projects/downloads/UIO/user/ + +With ``lsuio`` you can quickly check if your kernel module is loaded and +which attributes it exports. Have a look at the manpage for details. + +The source code of ``lsuio`` can serve as an example for getting +information about an UIO device. The file ``uio_helper.c`` contains a +lot of functions you could use in your userspace driver code. + +mmap() device memory +-------------------- + +After you made sure you've got the right device with the memory mappings +you need, all you have to do is to call :c:func:`mmap()` to map the +device's memory to userspace. + +The parameter ``offset`` of the :c:func:`mmap()` call has a special +meaning for UIO devices: It is used to select which mapping of your +device you want to map. To map the memory of mapping N, you have to use +N times the page size as your offset:: + + offset = N * getpagesize(); + +N starts from zero, so if you've got only one memory range to map, set +``offset = 0``. A drawback of this technique is that memory is always +mapped beginning with its start address. + +Waiting for interrupts +---------------------- + +After you successfully mapped your devices memory, you can access it +like an ordinary array. Usually, you will perform some initialization. +After that, your hardware starts working and will generate an interrupt +as soon as it's finished, has some data available, or needs your +attention because an error occurred. + +``/dev/uioX`` is a read-only file. A :c:func:`read()` will always +block until an interrupt occurs. There is only one legal value for the +``count`` parameter of :c:func:`read()`, and that is the size of a +signed 32 bit integer (4). Any other value for ``count`` causes +:c:func:`read()` to fail. The signed 32 bit integer read is the +interrupt count of your device. If the value is one more than the value +you read the last time, everything is OK. If the difference is greater +than one, you missed interrupts. + +You can also use :c:func:`select()` on ``/dev/uioX``. + +Generic PCI UIO driver +====================== + +The generic driver is a kernel module named uio_pci_generic. It can +work with any device compliant to PCI 2.3 (circa 2002) and any compliant +PCI Express device. Using this, you only need to write the userspace +driver, removing the need to write a hardware-specific kernel module. + +Making the driver recognize the device +-------------------------------------- + +Since the driver does not declare any device ids, it will not get loaded +automatically and will not automatically bind to any devices, you must +load it and allocate id to the driver yourself. For example:: + + modprobe uio_pci_generic + echo "8086 10f5" > /sys/bus/pci/drivers/uio_pci_generic/new_id + +If there already is a hardware specific kernel driver for your device, +the generic driver still won't bind to it, in this case if you want to +use the generic driver (why would you?) you'll have to manually unbind +the hardware specific driver and bind the generic driver, like this:: + + echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind + echo -n 0000:00:19.0 > /sys/bus/pci/drivers/uio_pci_generic/bind + +You can verify that the device has been bound to the driver by looking +for it in sysfs, for example like the following:: + + ls -l /sys/bus/pci/devices/0000:00:19.0/driver + +Which if successful should print:: + + .../0000:00:19.0/driver -> ../../../bus/pci/drivers/uio_pci_generic + +Note that the generic driver will not bind to old PCI 2.2 devices. If +binding the device failed, run the following command:: + + dmesg + +and look in the output for failure reasons. + +Things to know about uio_pci_generic +------------------------------------ + +Interrupts are handled using the Interrupt Disable bit in the PCI +command register and Interrupt Status bit in the PCI status register. +All devices compliant to PCI 2.3 (circa 2002) and all compliant PCI +Express devices should support these bits. uio_pci_generic detects +this support, and won't bind to devices which do not support the +Interrupt Disable Bit in the command register. + +On each interrupt, uio_pci_generic sets the Interrupt Disable bit. +This prevents the device from generating further interrupts until the +bit is cleared. The userspace driver should clear this bit before +blocking and waiting for more interrupts. + +Writing userspace driver using uio_pci_generic +------------------------------------------------ + +Userspace driver can use pci sysfs interface, or the libpci library that +wraps it, to talk to the device and to re-enable interrupts by writing +to the command register. + +Example code using uio_pci_generic +---------------------------------- + +Here is some sample userspace driver code using uio_pci_generic:: + + #include <stdlib.h> + #include <stdio.h> + #include <unistd.h> + #include <sys/types.h> + #include <sys/stat.h> + #include <fcntl.h> + #include <errno.h> + + int main() + { + int uiofd; + int configfd; + int err; + int i; + unsigned icount; + unsigned char command_high; + + uiofd = open("/dev/uio0", O_RDONLY); + if (uiofd < 0) { + perror("uio open:"); + return errno; + } + configfd = open("/sys/class/uio/uio0/device/config", O_RDWR); + if (configfd < 0) { + perror("config open:"); + return errno; + } + + /* Read and cache command value */ + err = pread(configfd, &command_high, 1, 5); + if (err != 1) { + perror("command config read:"); + return errno; + } + command_high &= ~0x4; + + for(i = 0;; ++i) { + /* Print out a message, for debugging. */ + if (i == 0) + fprintf(stderr, "Started uio test driver.\n"); + else + fprintf(stderr, "Interrupts: %d\n", icount); + + /****************************************/ + /* Here we got an interrupt from the + device. Do something to it. */ + /****************************************/ + + /* Re-enable interrupts. */ + err = pwrite(configfd, &command_high, 1, 5); + if (err != 1) { + perror("config write:"); + break; + } + + /* Wait for next interrupt. */ + err = read(uiofd, &icount, 4); + if (err != 4) { + perror("uio read:"); + break; + } + + } + return errno; + } + +Generic Hyper-V UIO driver +========================== + +The generic driver is a kernel module named uio_hv_generic. It +supports devices on the Hyper-V VMBus similar to uio_pci_generic on +PCI bus. + +Making the driver recognize the device +-------------------------------------- + +Since the driver does not declare any device GUID's, it will not get +loaded automatically and will not automatically bind to any devices, you +must load it and allocate id to the driver yourself. For example, to use +the network device GUID:: + + modprobe uio_hv_generic + echo "f8615163-df3e-46c5-913f-f2d2f965ed0e" > /sys/bus/vmbus/drivers/uio_hv_generic/new_id + +If there already is a hardware specific kernel driver for the device, +the generic driver still won't bind to it, in this case if you want to +use the generic driver (why would you?) you'll have to manually unbind +the hardware specific driver and bind the generic driver, like this:: + + echo -n vmbus-ed963694-e847-4b2a-85af-bc9cfc11d6f3 > /sys/bus/vmbus/drivers/hv_netvsc/unbind + echo -n vmbus-ed963694-e847-4b2a-85af-bc9cfc11d6f3 > /sys/bus/vmbus/drivers/uio_hv_generic/bind + +You can verify that the device has been bound to the driver by looking +for it in sysfs, for example like the following:: + + ls -l /sys/bus/vmbus/devices/vmbus-ed963694-e847-4b2a-85af-bc9cfc11d6f3/driver + +Which if successful should print:: + + .../vmbus-ed963694-e847-4b2a-85af-bc9cfc11d6f3/driver -> ../../../bus/vmbus/drivers/uio_hv_generic + +Things to know about uio_hv_generic +----------------------------------- + +On each interrupt, uio_hv_generic sets the Interrupt Disable bit. This +prevents the device from generating further interrupts until the bit is +cleared. The userspace driver should clear this bit before blocking and +waiting for more interrupts. + +Further information +=================== + +- `OSADL homepage. <http://www.osadl.org>`_ + +- `Linutronix homepage. <http://www.linutronix.de>`_ diff --git a/Documentation/driver-api/usb.rst b/Documentation/driver-api/usb.rst new file mode 100644 index 000000000000..851cc40b66b5 --- /dev/null +++ b/Documentation/driver-api/usb.rst @@ -0,0 +1,748 @@ +=========================== +The Linux-USB Host Side API +=========================== + +Introduction to USB on Linux +============================ + +A Universal Serial Bus (USB) is used to connect a host, such as a PC or +workstation, to a number of peripheral devices. USB uses a tree +structure, with the host as the root (the system's master), hubs as +interior nodes, and peripherals as leaves (and slaves). Modern PCs +support several such trees of USB devices, usually +a few USB 3.0 (5 GBit/s) or USB 3.1 (10 GBit/s) and some legacy +USB 2.0 (480 MBit/s) busses just in case. + +That master/slave asymmetry was designed-in for a number of reasons, one +being ease of use. It is not physically possible to mistake upstream and +downstream or it does not matter with a type C plug (or they are built into the +peripheral). Also, the host software doesn't need to deal with +distributed auto-configuration since the pre-designated master node +manages all that. + +Kernel developers added USB support to Linux early in the 2.2 kernel +series and have been developing it further since then. Besides support +for each new generation of USB, various host controllers gained support, +new drivers for peripherals have been added and advanced features for latency +measurement and improved power management introduced. + +Linux can run inside USB devices as well as on the hosts that control +the devices. But USB device drivers running inside those peripherals +don't do the same things as the ones running inside hosts, so they've +been given a different name: *gadget drivers*. This document does not +cover gadget drivers. + +USB Host-Side API Model +======================= + +Host-side drivers for USB devices talk to the "usbcore" APIs. There are +two. One is intended for *general-purpose* drivers (exposed through +driver frameworks), and the other is for drivers that are *part of the +core*. Such core drivers include the *hub* driver (which manages trees +of USB devices) and several different kinds of *host controller +drivers*, which control individual busses. + +The device model seen by USB drivers is relatively complex. + +- USB supports four kinds of data transfers (control, bulk, interrupt, + and isochronous). Two of them (control and bulk) use bandwidth as + it's available, while the other two (interrupt and isochronous) are + scheduled to provide guaranteed bandwidth. + +- The device description model includes one or more "configurations" + per device, only one of which is active at a time. Devices are supposed + to be capable of operating at lower than their top + speeds and may provide a BOS descriptor showing the lowest speed they + remain fully operational at. + +- From USB 3.0 on configurations have one or more "functions", which + provide a common functionality and are grouped together for purposes + of power management. + +- Configurations or functions have one or more "interfaces", each of which may have + "alternate settings". Interfaces may be standardized by USB "Class" + specifications, or may be specific to a vendor or device. + + USB device drivers actually bind to interfaces, not devices. Think of + them as "interface drivers", though you may not see many devices + where the distinction is important. *Most USB devices are simple, + with only one function, one configuration, one interface, and one alternate + setting.* + +- Interfaces have one or more "endpoints", each of which supports one + type and direction of data transfer such as "bulk out" or "interrupt + in". The entire configuration may have up to sixteen endpoints in + each direction, allocated as needed among all the interfaces. + +- Data transfer on USB is packetized; each endpoint has a maximum + packet size. Drivers must often be aware of conventions such as + flagging the end of bulk transfers using "short" (including zero + length) packets. + +- The Linux USB API supports synchronous calls for control and bulk + messages. It also supports asynchronous calls for all kinds of data + transfer, using request structures called "URBs" (USB Request + Blocks). + +Accordingly, the USB Core API exposed to device drivers covers quite a +lot of territory. You'll probably need to consult the USB 3.0 +specification, available online from www.usb.org at no cost, as well as +class or device specifications. + +The only host-side drivers that actually touch hardware (reading/writing +registers, handling IRQs, and so on) are the HCDs. In theory, all HCDs +provide the same functionality through the same API. In practice, that's +becoming more true, but there are still differences +that crop up especially with fault handling on the less common controllers. +Different controllers don't +necessarily report the same aspects of failures, and recovery from +faults (including software-induced ones like unlinking an URB) isn't yet +fully consistent. Device driver authors should make a point of doing +disconnect testing (while the device is active) with each different host +controller driver, to make sure drivers don't have bugs of their own as +well as to make sure they aren't relying on some HCD-specific behavior. + +USB-Standard Types +================== + +In ``<linux/usb/ch9.h>`` you will find the USB data types defined in +chapter 9 of the USB specification. These data types are used throughout +USB, and in APIs including this host side API, gadget APIs, and usbfs. + +.. kernel-doc:: include/linux/usb/ch9.h + :internal: + +Host-Side Data Types and Macros +=============================== + +The host side API exposes several layers to drivers, some of which are +more necessary than others. These support lifecycle models for host side +drivers and devices, and support passing buffers through usbcore to some +HCD that performs the I/O for the device driver. + +.. kernel-doc:: include/linux/usb.h + :internal: + +USB Core APIs +============= + +There are two basic I/O models in the USB API. The most elemental one is +asynchronous: drivers submit requests in the form of an URB, and the +URB's completion callback handles the next step. All USB transfer types +support that model, although there are special cases for control URBs +(which always have setup and status stages, but may not have a data +stage) and isochronous URBs (which allow large packets and include +per-packet fault reports). Built on top of that is synchronous API +support, where a driver calls a routine that allocates one or more URBs, +submits them, and waits until they complete. There are synchronous +wrappers for single-buffer control and bulk transfers (which are awkward +to use in some driver disconnect scenarios), and for scatterlist based +streaming i/o (bulk or interrupt). + +USB drivers need to provide buffers that can be used for DMA, although +they don't necessarily need to provide the DMA mapping themselves. There +are APIs to use used when allocating DMA buffers, which can prevent use +of bounce buffers on some systems. In some cases, drivers may be able to +rely on 64bit DMA to eliminate another kind of bounce buffer. + +.. kernel-doc:: drivers/usb/core/urb.c + :export: + +.. kernel-doc:: drivers/usb/core/message.c + :export: + +.. kernel-doc:: drivers/usb/core/file.c + :export: + +.. kernel-doc:: drivers/usb/core/driver.c + :export: + +.. kernel-doc:: drivers/usb/core/usb.c + :export: + +.. kernel-doc:: drivers/usb/core/hub.c + :export: + +Host Controller APIs +==================== + +These APIs are only for use by host controller drivers, most of which +implement standard register interfaces such as XHCI, EHCI, OHCI, or UHCI. UHCI +was one of the first interfaces, designed by Intel and also used by VIA; +it doesn't do much in hardware. OHCI was designed later, to have the +hardware do more work (bigger transfers, tracking protocol state, and so +on). EHCI was designed with USB 2.0; its design has features that +resemble OHCI (hardware does much more work) as well as UHCI (some parts +of ISO support, TD list processing). XHCI was designed with USB 3.0. It +continues to shift support for functionality into hardware. + +There are host controllers other than the "big three", although most PCI +based controllers (and a few non-PCI based ones) use one of those +interfaces. Not all host controllers use DMA; some use PIO, and there is +also a simulator and a virtual host controller to pipe USB over the network. + +The same basic APIs are available to drivers for all those controllers. +For historical reasons they are in two layers: :c:type:`struct +usb_bus <usb_bus>` is a rather thin layer that became available +in the 2.2 kernels, while :c:type:`struct usb_hcd <usb_hcd>` +is a more featureful layer +that lets HCDs share common code, to shrink driver size and +significantly reduce hcd-specific behaviors. + +.. kernel-doc:: drivers/usb/core/hcd.c + :export: + +.. kernel-doc:: drivers/usb/core/hcd-pci.c + :export: + +.. kernel-doc:: drivers/usb/core/buffer.c + :internal: + +The USB Filesystem (usbfs) +========================== + +This chapter presents the Linux *usbfs*. You may prefer to avoid writing +new kernel code for your USB driver; that's the problem that usbfs set +out to solve. User mode device drivers are usually packaged as +applications or libraries, and may use usbfs through some programming +library that wraps it. Such libraries include +`libusb <http://libusb.sourceforge.net>`__ for C/C++, and +`jUSB <http://jUSB.sourceforge.net>`__ for Java. + + **Note** + + This particular documentation is incomplete, especially with respect + to the asynchronous mode. As of kernel 2.5.66 the code and this + (new) documentation need to be cross-reviewed. + +Configure usbfs into Linux kernels by enabling the *USB filesystem* +option (CONFIG_USB_DEVICEFS), and you get basic support for user mode +USB device drivers. Until relatively recently it was often (confusingly) +called *usbdevfs* although it wasn't solving what *devfs* was. Every USB +device will appear in usbfs, regardless of whether or not it has a +kernel driver. + +What files are in "usbfs"? +-------------------------- + +Conventionally mounted at ``/proc/bus/usb``, usbfs features include: + +- ``/proc/bus/usb/devices`` ... a text file showing each of the USB + devices on known to the kernel, and their configuration descriptors. + You can also poll() this to learn about new devices. + +- ``/proc/bus/usb/BBB/DDD`` ... magic files exposing the each device's + configuration descriptors, and supporting a series of ioctls for + making device requests, including I/O to devices. (Purely for access + by programs.) + +Each bus is given a number (BBB) based on when it was enumerated; within +each bus, each device is given a similar number (DDD). Those BBB/DDD +paths are not "stable" identifiers; expect them to change even if you +always leave the devices plugged in to the same hub port. *Don't even +think of saving these in application configuration files.* Stable +identifiers are available, for user mode applications that want to use +them. HID and networking devices expose these stable IDs, so that for +example you can be sure that you told the right UPS to power down its +second server. "usbfs" doesn't (yet) expose those IDs. + +Mounting and Access Control +--------------------------- + +There are a number of mount options for usbfs, which will be of most +interest to you if you need to override the default access control +policy. That policy is that only root may read or write device files +(``/proc/bus/BBB/DDD``) although anyone may read the ``devices`` or +``drivers`` files. I/O requests to the device also need the +CAP_SYS_RAWIO capability, + +The significance of that is that by default, all user mode device +drivers need super-user privileges. You can change modes or ownership in +a driver setup when the device hotplugs, or maye just start the driver +right then, as a privileged server (or some activity within one). That's +the most secure approach for multi-user systems, but for single user +systems ("trusted" by that user) it's more convenient just to grant +everyone all access (using the *devmode=0666* option) so the driver can +start whenever it's needed. + +The mount options for usbfs, usable in /etc/fstab or in command line +invocations of *mount*, are: + +*busgid*\ =NNNNN + Controls the GID used for the /proc/bus/usb/BBB directories. + (Default: 0) + +*busmode*\ =MMM + Controls the file mode used for the /proc/bus/usb/BBB directories. + (Default: 0555) + +*busuid*\ =NNNNN + Controls the UID used for the /proc/bus/usb/BBB directories. + (Default: 0) + +*devgid*\ =NNNNN + Controls the GID used for the /proc/bus/usb/BBB/DDD files. (Default: + 0) + +*devmode*\ =MMM + Controls the file mode used for the /proc/bus/usb/BBB/DDD files. + (Default: 0644) + +*devuid*\ =NNNNN + Controls the UID used for the /proc/bus/usb/BBB/DDD files. (Default: + 0) + +*listgid*\ =NNNNN + Controls the GID used for the /proc/bus/usb/devices and drivers + files. (Default: 0) + +*listmode*\ =MMM + Controls the file mode used for the /proc/bus/usb/devices and + drivers files. (Default: 0444) + +*listuid*\ =NNNNN + Controls the UID used for the /proc/bus/usb/devices and drivers + files. (Default: 0) + +Note that many Linux distributions hard-wire the mount options for usbfs +in their init scripts, such as ``/etc/rc.d/rc.sysinit``, rather than +making it easy to set this per-system policy in ``/etc/fstab``. + +/proc/bus/usb/devices +--------------------- + +This file is handy for status viewing tools in user mode, which can scan +the text format and ignore most of it. More detailed device status +(including class and vendor status) is available from device-specific +files. For information about the current format of this file, see the +``Documentation/usb/proc_usb_info.txt`` file in your Linux kernel +sources. + +This file, in combination with the poll() system call, can also be used +to detect when devices are added or removed: + +:: + + int fd; + struct pollfd pfd; + + fd = open("/proc/bus/usb/devices", O_RDONLY); + pfd = { fd, POLLIN, 0 }; + for (;;) { + /* The first time through, this call will return immediately. */ + poll(&pfd, 1, -1); + + /* To see what's changed, compare the file's previous and current + contents or scan the filesystem. (Scanning is more precise.) */ + } + +Note that this behavior is intended to be used for informational and +debug purposes. It would be more appropriate to use programs such as +udev or HAL to initialize a device or start a user-mode helper program, +for instance. + +/proc/bus/usb/BBB/DDD +--------------------- + +Use these files in one of these basic ways: + +*They can be read,* producing first the device descriptor (18 bytes) and +then the descriptors for the current configuration. See the USB 2.0 spec +for details about those binary data formats. You'll need to convert most +multibyte values from little endian format to your native host byte +order, although a few of the fields in the device descriptor (both of +the BCD-encoded fields, and the vendor and product IDs) will be +byteswapped for you. Note that configuration descriptors include +descriptors for interfaces, altsettings, endpoints, and maybe additional +class descriptors. + +*Perform USB operations* using *ioctl()* requests to make endpoint I/O +requests (synchronously or asynchronously) or manage the device. These +requests need the CAP_SYS_RAWIO capability, as well as filesystem +access permissions. Only one ioctl request can be made on one of these +device files at a time. This means that if you are synchronously reading +an endpoint from one thread, you won't be able to write to a different +endpoint from another thread until the read completes. This works for +*half duplex* protocols, but otherwise you'd use asynchronous i/o +requests. + +Life Cycle of User Mode Drivers +------------------------------- + +Such a driver first needs to find a device file for a device it knows +how to handle. Maybe it was told about it because a ``/sbin/hotplug`` +event handling agent chose that driver to handle the new device. Or +maybe it's an application that scans all the /proc/bus/usb device files, +and ignores most devices. In either case, it should :c:func:`read()` +all the descriptors from the device file, and check them against what it +knows how to handle. It might just reject everything except a particular +vendor and product ID, or need a more complex policy. + +Never assume there will only be one such device on the system at a time! +If your code can't handle more than one device at a time, at least +detect when there's more than one, and have your users choose which +device to use. + +Once your user mode driver knows what device to use, it interacts with +it in either of two styles. The simple style is to make only control +requests; some devices don't need more complex interactions than those. +(An example might be software using vendor-specific control requests for +some initialization or configuration tasks, with a kernel driver for the +rest.) + +More likely, you need a more complex style driver: one using non-control +endpoints, reading or writing data and claiming exclusive use of an +interface. *Bulk* transfers are easiest to use, but only their sibling +*interrupt* transfers work with low speed devices. Both interrupt and +*isochronous* transfers offer service guarantees because their bandwidth +is reserved. Such "periodic" transfers are awkward to use through usbfs, +unless you're using the asynchronous calls. However, interrupt transfers +can also be used in a synchronous "one shot" style. + +Your user-mode driver should never need to worry about cleaning up +request state when the device is disconnected, although it should close +its open file descriptors as soon as it starts seeing the ENODEV errors. + +The ioctl() Requests +-------------------- + +To use these ioctls, you need to include the following headers in your +userspace program: + +:: + + #include <linux/usb.h> + #include <linux/usbdevice_fs.h> + #include <asm/byteorder.h> + +The standard USB device model requests, from "Chapter 9" of the USB 2.0 +specification, are automatically included from the ``<linux/usb/ch9.h>`` +header. + +Unless noted otherwise, the ioctl requests described here will update +the modification time on the usbfs file to which they are applied +(unless they fail). A return of zero indicates success; otherwise, a +standard USB error code is returned. (These are documented in +``Documentation/usb/error-codes.txt`` in your kernel sources.) + +Each of these files multiplexes access to several I/O streams, one per +endpoint. Each device has one control endpoint (endpoint zero) which +supports a limited RPC style RPC access. Devices are configured by +hub_wq (in the kernel) setting a device-wide *configuration* that +affects things like power consumption and basic functionality. The +endpoints are part of USB *interfaces*, which may have *altsettings* +affecting things like which endpoints are available. Many devices only +have a single configuration and interface, so drivers for them will +ignore configurations and altsettings. + +Management/Status Requests +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A number of usbfs requests don't deal very directly with device I/O. +They mostly relate to device management and status. These are all +synchronous requests. + +USBDEVFS_CLAIMINTERFACE + This is used to force usbfs to claim a specific interface, which has + not previously been claimed by usbfs or any other kernel driver. The + ioctl parameter is an integer holding the number of the interface + (bInterfaceNumber from descriptor). + + Note that if your driver doesn't claim an interface before trying to + use one of its endpoints, and no other driver has bound to it, then + the interface is automatically claimed by usbfs. + + This claim will be released by a RELEASEINTERFACE ioctl, or by + closing the file descriptor. File modification time is not updated + by this request. + +USBDEVFS_CONNECTINFO + Says whether the device is lowspeed. The ioctl parameter points to a + structure like this: + + :: + + struct usbdevfs_connectinfo { + unsigned int devnum; + unsigned char slow; + }; + + File modification time is not updated by this request. + + *You can't tell whether a "not slow" device is connected at high + speed (480 MBit/sec) or just full speed (12 MBit/sec).* You should + know the devnum value already, it's the DDD value of the device file + name. + +USBDEVFS_GETDRIVER + Returns the name of the kernel driver bound to a given interface (a + string). Parameter is a pointer to this structure, which is + modified: + + :: + + struct usbdevfs_getdriver { + unsigned int interface; + char driver[USBDEVFS_MAXDRIVERNAME + 1]; + }; + + File modification time is not updated by this request. + +USBDEVFS_IOCTL + Passes a request from userspace through to a kernel driver that has + an ioctl entry in the *struct usb_driver* it registered. + + :: + + struct usbdevfs_ioctl { + int ifno; + int ioctl_code; + void *data; + }; + + /* user mode call looks like this. + * 'request' becomes the driver->ioctl() 'code' parameter. + * the size of 'param' is encoded in 'request', and that data + * is copied to or from the driver->ioctl() 'buf' parameter. + */ + static int + usbdev_ioctl (int fd, int ifno, unsigned request, void *param) + { + struct usbdevfs_ioctl wrapper; + + wrapper.ifno = ifno; + wrapper.ioctl_code = request; + wrapper.data = param; + + return ioctl (fd, USBDEVFS_IOCTL, &wrapper); + } + + File modification time is not updated by this request. + + This request lets kernel drivers talk to user mode code through + filesystem operations even when they don't create a character or + block special device. It's also been used to do things like ask + devices what device special file should be used. Two pre-defined + ioctls are used to disconnect and reconnect kernel drivers, so that + user mode code can completely manage binding and configuration of + devices. + +USBDEVFS_RELEASEINTERFACE + This is used to release the claim usbfs made on interface, either + implicitly or because of a USBDEVFS_CLAIMINTERFACE call, before the + file descriptor is closed. The ioctl parameter is an integer holding + the number of the interface (bInterfaceNumber from descriptor); File + modification time is not updated by this request. + + **Warning** + + *No security check is made to ensure that the task which made + the claim is the one which is releasing it. This means that user + mode driver may interfere other ones.* + +USBDEVFS_RESETEP + Resets the data toggle value for an endpoint (bulk or interrupt) to + DATA0. The ioctl parameter is an integer endpoint number (1 to 15, + as identified in the endpoint descriptor), with USB_DIR_IN added + if the device's endpoint sends data to the host. + + **Warning** + + *Avoid using this request. It should probably be removed.* Using + it typically means the device and driver will lose toggle + synchronization. If you really lost synchronization, you likely + need to completely handshake with the device, using a request + like CLEAR_HALT or SET_INTERFACE. + +USBDEVFS_DROP_PRIVILEGES + This is used to relinquish the ability to do certain operations + which are considered to be privileged on a usbfs file descriptor. + This includes claiming arbitrary interfaces, resetting a device on + which there are currently claimed interfaces from other users, and + issuing USBDEVFS_IOCTL calls. The ioctl parameter is a 32 bit mask + of interfaces the user is allowed to claim on this file descriptor. + You may issue this ioctl more than one time to narrow said mask. + +Synchronous I/O Support +~~~~~~~~~~~~~~~~~~~~~~~ + +Synchronous requests involve the kernel blocking until the user mode +request completes, either by finishing successfully or by reporting an +error. In most cases this is the simplest way to use usbfs, although as +noted above it does prevent performing I/O to more than one endpoint at +a time. + +USBDEVFS_BULK + Issues a bulk read or write request to the device. The ioctl + parameter is a pointer to this structure: + + :: + + struct usbdevfs_bulktransfer { + unsigned int ep; + unsigned int len; + unsigned int timeout; /* in milliseconds */ + void *data; + }; + + The "ep" value identifies a bulk endpoint number (1 to 15, as + identified in an endpoint descriptor), masked with USB_DIR_IN when + referring to an endpoint which sends data to the host from the + device. The length of the data buffer is identified by "len"; Recent + kernels support requests up to about 128KBytes. *FIXME say how read + length is returned, and how short reads are handled.*. + +USBDEVFS_CLEAR_HALT + Clears endpoint halt (stall) and resets the endpoint toggle. This is + only meaningful for bulk or interrupt endpoints. The ioctl parameter + is an integer endpoint number (1 to 15, as identified in an endpoint + descriptor), masked with USB_DIR_IN when referring to an endpoint + which sends data to the host from the device. + + Use this on bulk or interrupt endpoints which have stalled, + returning *-EPIPE* status to a data transfer request. Do not issue + the control request directly, since that could invalidate the host's + record of the data toggle. + +USBDEVFS_CONTROL + Issues a control request to the device. The ioctl parameter points + to a structure like this: + + :: + + struct usbdevfs_ctrltransfer { + __u8 bRequestType; + __u8 bRequest; + __u16 wValue; + __u16 wIndex; + __u16 wLength; + __u32 timeout; /* in milliseconds */ + void *data; + }; + + The first eight bytes of this structure are the contents of the + SETUP packet to be sent to the device; see the USB 2.0 specification + for details. The bRequestType value is composed by combining a + USB_TYPE_\* value, a USB_DIR_\* value, and a USB_RECIP_\* + value (from *<linux/usb.h>*). If wLength is nonzero, it describes + the length of the data buffer, which is either written to the device + (USB_DIR_OUT) or read from the device (USB_DIR_IN). + + At this writing, you can't transfer more than 4 KBytes of data to or + from a device; usbfs has a limit, and some host controller drivers + have a limit. (That's not usually a problem.) *Also* there's no way + to say it's not OK to get a short read back from the device. + +USBDEVFS_RESET + Does a USB level device reset. The ioctl parameter is ignored. After + the reset, this rebinds all device interfaces. File modification + time is not updated by this request. + + **Warning** + + *Avoid using this call* until some usbcore bugs get fixed, since + it does not fully synchronize device, interface, and driver (not + just usbfs) state. + +USBDEVFS_SETINTERFACE + Sets the alternate setting for an interface. The ioctl parameter is + a pointer to a structure like this: + + :: + + struct usbdevfs_setinterface { + unsigned int interface; + unsigned int altsetting; + }; + + File modification time is not updated by this request. + + Those struct members are from some interface descriptor applying to + the current configuration. The interface number is the + bInterfaceNumber value, and the altsetting number is the + bAlternateSetting value. (This resets each endpoint in the + interface.) + +USBDEVFS_SETCONFIGURATION + Issues the :c:func:`usb_set_configuration()` call for the + device. The parameter is an integer holding the number of a + configuration (bConfigurationValue from descriptor). File + modification time is not updated by this request. + + **Warning** + + *Avoid using this call* until some usbcore bugs get fixed, since + it does not fully synchronize device, interface, and driver (not + just usbfs) state. + +Asynchronous I/O Support +~~~~~~~~~~~~~~~~~~~~~~~~ + +As mentioned above, there are situations where it may be important to +initiate concurrent operations from user mode code. This is particularly +important for periodic transfers (interrupt and isochronous), but it can +be used for other kinds of USB requests too. In such cases, the +asynchronous requests described here are essential. Rather than +submitting one request and having the kernel block until it completes, +the blocking is separate. + +These requests are packaged into a structure that resembles the URB used +by kernel device drivers. (No POSIX Async I/O support here, sorry.) It +identifies the endpoint type (USBDEVFS_URB_TYPE_\*), endpoint +(number, masked with USB_DIR_IN as appropriate), buffer and length, +and a user "context" value serving to uniquely identify each request. +(It's usually a pointer to per-request data.) Flags can modify requests +(not as many as supported for kernel drivers). + +Each request can specify a realtime signal number (between SIGRTMIN and +SIGRTMAX, inclusive) to request a signal be sent when the request +completes. + +When usbfs returns these urbs, the status value is updated, and the +buffer may have been modified. Except for isochronous transfers, the +actual_length is updated to say how many bytes were transferred; if the +USBDEVFS_URB_DISABLE_SPD flag is set ("short packets are not OK"), if +fewer bytes were read than were requested then you get an error report. + +:: + + struct usbdevfs_iso_packet_desc { + unsigned int length; + unsigned int actual_length; + unsigned int status; + }; + + struct usbdevfs_urb { + unsigned char type; + unsigned char endpoint; + int status; + unsigned int flags; + void *buffer; + int buffer_length; + int actual_length; + int start_frame; + int number_of_packets; + int error_count; + unsigned int signr; + void *usercontext; + struct usbdevfs_iso_packet_desc iso_frame_desc[]; + }; + +For these asynchronous requests, the file modification time reflects +when the request was initiated. This contrasts with their use with the +synchronous requests, where it reflects when requests complete. + +USBDEVFS_DISCARDURB + *TBS* File modification time is not updated by this request. + +USBDEVFS_DISCSIGNAL + *TBS* File modification time is not updated by this request. + +USBDEVFS_REAPURB + *TBS* File modification time is not updated by this request. + +USBDEVFS_REAPURBNDELAY + *TBS* File modification time is not updated by this request. + +USBDEVFS_SUBMITURB + *TBS* diff --git a/Documentation/driver-api/vme.rst b/Documentation/driver-api/vme.rst new file mode 100644 index 000000000000..89776fb3c8bd --- /dev/null +++ b/Documentation/driver-api/vme.rst @@ -0,0 +1,474 @@ +VME Device Drivers +================== + +Driver registration +------------------- + +As with other subsystems within the Linux kernel, VME device drivers register +with the VME subsystem, typically called from the devices init routine. This is +achieved via a call to the following function: + +.. code-block:: c + + int vme_register_driver (struct vme_driver *driver, unsigned int ndevs); + +If driver registration is successful this function returns zero, if an error +occurred a negative error code will be returned. + +A pointer to a structure of type 'vme_driver' must be provided to the +registration function. Along with ndevs, which is the number of devices your +driver is able to support. The structure is as follows: + +.. code-block:: c + + struct vme_driver { + struct list_head node; + const char *name; + int (*match)(struct vme_dev *); + int (*probe)(struct vme_dev *); + int (*remove)(struct vme_dev *); + void (*shutdown)(void); + struct device_driver driver; + struct list_head devices; + unsigned int ndev; + }; + +At the minimum, the '.name', '.match' and '.probe' elements of this structure +should be correctly set. The '.name' element is a pointer to a string holding +the device driver's name. + +The '.match' function allows control over which VME devices should be registered +with the driver. The match function should return 1 if a device should be +probed and 0 otherwise. This example match function (from vme_user.c) limits +the number of devices probed to one: + +.. code-block:: c + + #define USER_BUS_MAX 1 + ... + static int vme_user_match(struct vme_dev *vdev) + { + if (vdev->id.num >= USER_BUS_MAX) + return 0; + return 1; + } + +The '.probe' element should contain a pointer to the probe routine. The +probe routine is passed a 'struct vme_dev' pointer as an argument. The +'struct vme_dev' structure looks like the following: + +.. code-block:: c + + struct vme_dev { + int num; + struct vme_bridge *bridge; + struct device dev; + struct list_head drv_list; + struct list_head bridge_list; + }; + +Here, the 'num' field refers to the sequential device ID for this specific +driver. The bridge number (or bus number) can be accessed using +dev->bridge->num. + +A function is also provided to unregister the driver from the VME core and is +usually called from the device driver's exit routine: + +.. code-block:: c + + void vme_unregister_driver (struct vme_driver *driver); + + +Resource management +------------------- + +Once a driver has registered with the VME core the provided match routine will +be called the number of times specified during the registration. If a match +succeeds, a non-zero value should be returned. A zero return value indicates +failure. For all successful matches, the probe routine of the corresponding +driver is called. The probe routine is passed a pointer to the devices +device structure. This pointer should be saved, it will be required for +requesting VME resources. + +The driver can request ownership of one or more master windows, slave windows +and/or dma channels. Rather than allowing the device driver to request a +specific window or DMA channel (which may be used by a different driver) this +driver allows a resource to be assigned based on the required attributes of the +driver in question: + +.. code-block:: c + + struct vme_resource * vme_master_request(struct vme_dev *dev, + u32 aspace, u32 cycle, u32 width); + + struct vme_resource * vme_slave_request(struct vme_dev *dev, u32 aspace, + u32 cycle); + + struct vme_resource *vme_dma_request(struct vme_dev *dev, u32 route); + +For slave windows these attributes are split into the VME address spaces that +need to be accessed in 'aspace' and VME bus cycle types required in 'cycle'. +Master windows add a further set of attributes in 'width' specifying the +required data transfer widths. These attributes are defined as bitmasks and as +such any combination of the attributes can be requested for a single window, +the core will assign a window that meets the requirements, returning a pointer +of type vme_resource that should be used to identify the allocated resource +when it is used. For DMA controllers, the request function requires the +potential direction of any transfers to be provided in the route attributes. +This is typically VME-to-MEM and/or MEM-to-VME, though some hardware can +support VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. +If an unallocated window fitting the requirements can not be found a NULL +pointer will be returned. + +Functions are also provided to free window allocations once they are no longer +required. These functions should be passed the pointer to the resource provided +during resource allocation: + +.. code-block:: c + + void vme_master_free(struct vme_resource *res); + + void vme_slave_free(struct vme_resource *res); + + void vme_dma_free(struct vme_resource *res); + + +Master windows +-------------- + +Master windows provide access from the local processor[s] out onto the VME bus. +The number of windows available and the available access modes is dependent on +the underlying chipset. A window must be configured before it can be used. + + +Master window configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once a master window has been assigned the following functions can be used to +configure it and retrieve the current settings: + +.. code-block:: c + + int vme_master_set (struct vme_resource *res, int enabled, + unsigned long long base, unsigned long long size, u32 aspace, + u32 cycle, u32 width); + + int vme_master_get (struct vme_resource *res, int *enabled, + unsigned long long *base, unsigned long long *size, u32 *aspace, + u32 *cycle, u32 *width); + +The address spaces, transfer widths and cycle types are the same as described +under resource management, however some of the options are mutually exclusive. +For example, only one address space may be specified. + +These functions return 0 on success or an error code should the call fail. + + +Master window access +~~~~~~~~~~~~~~~~~~~~ + +The following functions can be used to read from and write to configured master +windows. These functions return the number of bytes copied: + +.. code-block:: c + + ssize_t vme_master_read(struct vme_resource *res, void *buf, + size_t count, loff_t offset); + + ssize_t vme_master_write(struct vme_resource *res, void *buf, + size_t count, loff_t offset); + +In addition to simple reads and writes, a function is provided to do a +read-modify-write transaction. This function returns the original value of the +VME bus location : + +.. code-block:: c + + unsigned int vme_master_rmw (struct vme_resource *res, + unsigned int mask, unsigned int compare, unsigned int swap, + loff_t offset); + +This functions by reading the offset, applying the mask. If the bits selected in +the mask match with the values of the corresponding bits in the compare field, +the value of swap is written the specified offset. + +Parts of a VME window can be mapped into user space memory using the following +function: + +.. code-block:: c + + int vme_master_mmap(struct vme_resource *resource, + struct vm_area_struct *vma) + + +Slave windows +------------- + +Slave windows provide devices on the VME bus access into mapped portions of the +local memory. The number of windows available and the access modes that can be +used is dependent on the underlying chipset. A window must be configured before +it can be used. + + +Slave window configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once a slave window has been assigned the following functions can be used to +configure it and retrieve the current settings: + +.. code-block:: c + + int vme_slave_set (struct vme_resource *res, int enabled, + unsigned long long base, unsigned long long size, + dma_addr_t mem, u32 aspace, u32 cycle); + + int vme_slave_get (struct vme_resource *res, int *enabled, + unsigned long long *base, unsigned long long *size, + dma_addr_t *mem, u32 *aspace, u32 *cycle); + +The address spaces, transfer widths and cycle types are the same as described +under resource management, however some of the options are mutually exclusive. +For example, only one address space may be specified. + +These functions return 0 on success or an error code should the call fail. + + +Slave window buffer allocation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Functions are provided to allow the user to allocate and free a contiguous +buffers which will be accessible by the VME bridge. These functions do not have +to be used, other methods can be used to allocate a buffer, though care must be +taken to ensure that they are contiguous and accessible by the VME bridge: + +.. code-block:: c + + void * vme_alloc_consistent(struct vme_resource *res, size_t size, + dma_addr_t *mem); + + void vme_free_consistent(struct vme_resource *res, size_t size, + void *virt, dma_addr_t mem); + + +Slave window access +~~~~~~~~~~~~~~~~~~~ + +Slave windows map local memory onto the VME bus, the standard methods for +accessing memory should be used. + + +DMA channels +------------ + +The VME DMA transfer provides the ability to run link-list DMA transfers. The +API introduces the concept of DMA lists. Each DMA list is a link-list which can +be passed to a DMA controller. Multiple lists can be created, extended, +executed, reused and destroyed. + + +List Management +~~~~~~~~~~~~~~~ + +The following functions are provided to create and destroy DMA lists. Execution +of a list will not automatically destroy the list, thus enabling a list to be +reused for repetitive tasks: + +.. code-block:: c + + struct vme_dma_list *vme_new_dma_list(struct vme_resource *res); + + int vme_dma_list_free(struct vme_dma_list *list); + + +List Population +~~~~~~~~~~~~~~~ + +An item can be added to a list using the following function ( the source and +destination attributes need to be created before calling this function, this is +covered under "Transfer Attributes"): + +.. code-block:: c + + int vme_dma_list_add(struct vme_dma_list *list, + struct vme_dma_attr *src, struct vme_dma_attr *dest, + size_t count); + +.. note:: + + The detailed attributes of the transfers source and destination + are not checked until an entry is added to a DMA list, the request + for a DMA channel purely checks the directions in which the + controller is expected to transfer data. As a result it is + possible for this call to return an error, for example if the + source or destination is in an unsupported VME address space. + +Transfer Attributes +~~~~~~~~~~~~~~~~~~~ + +The attributes for the source and destination are handled separately from adding +an item to a list. This is due to the diverse attributes required for each type +of source and destination. There are functions to create attributes for PCI, VME +and pattern sources and destinations (where appropriate): + +Pattern source: + +.. code-block:: c + + struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type); + +PCI source or destination: + +.. code-block:: c + + struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem); + +VME source or destination: + +.. code-block:: c + + struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base, + u32 aspace, u32 cycle, u32 width); + +The following function should be used to free an attribute: + +.. code-block:: c + + void vme_dma_free_attribute(struct vme_dma_attr *attr); + + +List Execution +~~~~~~~~~~~~~~ + +The following function queues a list for execution. The function will return +once the list has been executed: + +.. code-block:: c + + int vme_dma_list_exec(struct vme_dma_list *list); + + +Interrupts +---------- + +The VME API provides functions to attach and detach callbacks to specific VME +level and status ID combinations and for the generation of VME interrupts with +specific VME level and status IDs. + + +Attaching Interrupt Handlers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following functions can be used to attach and free a specific VME level and +status ID combination. Any given combination can only be assigned a single +callback function. A void pointer parameter is provided, the value of which is +passed to the callback function, the use of this pointer is user undefined: + +.. code-block:: c + + int vme_irq_request(struct vme_dev *dev, int level, int statid, + void (*callback)(int, int, void *), void *priv); + + void vme_irq_free(struct vme_dev *dev, int level, int statid); + +The callback parameters are as follows. Care must be taken in writing a callback +function, callback functions run in interrupt context: + +.. code-block:: c + + void callback(int level, int statid, void *priv); + + +Interrupt Generation +~~~~~~~~~~~~~~~~~~~~ + +The following function can be used to generate a VME interrupt at a given VME +level and VME status ID: + +.. code-block:: c + + int vme_irq_generate(struct vme_dev *dev, int level, int statid); + + +Location monitors +----------------- + +The VME API provides the following functionality to configure the location +monitor. + + +Location Monitor Management +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following functions are provided to request the use of a block of location +monitors and to free them after they are no longer required: + +.. code-block:: c + + struct vme_resource * vme_lm_request(struct vme_dev *dev); + + void vme_lm_free(struct vme_resource * res); + +Each block may provide a number of location monitors, monitoring adjacent +locations. The following function can be used to determine how many locations +are provided: + +.. code-block:: c + + int vme_lm_count(struct vme_resource * res); + + +Location Monitor Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once a bank of location monitors has been allocated, the following functions +are provided to configure the location and mode of the location monitor: + +.. code-block:: c + + int vme_lm_set(struct vme_resource *res, unsigned long long base, + u32 aspace, u32 cycle); + + int vme_lm_get(struct vme_resource *res, unsigned long long *base, + u32 *aspace, u32 *cycle); + + +Location Monitor Use +~~~~~~~~~~~~~~~~~~~~ + +The following functions allow a callback to be attached and detached from each +location monitor location. Each location monitor can monitor a number of +adjacent locations: + +.. code-block:: c + + int vme_lm_attach(struct vme_resource *res, int num, + void (*callback)(void *)); + + int vme_lm_detach(struct vme_resource *res, int num); + +The callback function is declared as follows. + +.. code-block:: c + + void callback(void *data); + + +Slot Detection +-------------- + +This function returns the slot ID of the provided bridge. + +.. code-block:: c + + int vme_slot_num(struct vme_dev *dev); + + +Bus Detection +------------- + +This function returns the bus ID of the provided bridge. + +.. code-block:: c + + int vme_bus_num(struct vme_dev *dev); + |