rfkill - radio frequency (RF) connector kill switch support
-For details to this subsystem look at Documentation/rfkill.txt.
+For details to this subsystem look at Documentation/driver-api/rfkill.rst.
What: /sys/class/rfkill/rfkill[0-9]+/claim
Date: 09-Jul-2007
rfkill - radio frequency (RF) connector kill switch support
-For details to this subsystem look at Documentation/rfkill.txt.
+For details to this subsystem look at Documentation/driver-api/rfkill.rst.
For the deprecated /sys/class/rfkill/*/claim knobs of this interface look in
Documentation/ABI/removed/sysfs-class-rfkill.
switchtec - Microsemi Switchtec PCI Switch Management Endpoint
-For details on this subsystem look at Documentation/switchtec.txt.
+For details on this subsystem look at Documentation/driver-api/switchtec.rst.
What: /sys/class/switchtec
Date: 05-Jan-2017
+++ /dev/null
-:orphan:
-
-====
-EDID
-====
-
-In the good old days when graphics parameters were configured explicitly
-in a file called xorg.conf, even broken hardware could be managed.
-
-Today, with the advent of Kernel Mode Setting, a graphics board is
-either correctly working because all components follow the standards -
-or the computer is unusable, because the screen remains dark after
-booting or it displays the wrong area. Cases when this happens are:
-- The graphics board does not recognize the monitor.
-- The graphics board is unable to detect any EDID data.
-- The graphics board incorrectly forwards EDID data to the driver.
-- The monitor sends no or bogus EDID data.
-- A KVM sends its own EDID data instead of querying the connected monitor.
-Adding the kernel parameter "nomodeset" helps in most cases, but causes
-restrictions later on.
-
-As a remedy for such situations, the kernel configuration item
-CONFIG_DRM_LOAD_EDID_FIRMWARE was introduced. It allows to provide an
-individually prepared or corrected EDID data set in the /lib/firmware
-directory from where it is loaded via the firmware interface. The code
-(see drivers/gpu/drm/drm_edid_load.c) contains built-in data sets for
-commonly used screen resolutions (800x600, 1024x768, 1280x1024, 1600x1200,
-1680x1050, 1920x1080) as binary blobs, but the kernel source tree does
-not contain code to create these data. In order to elucidate the origin
-of the built-in binary EDID blobs and to facilitate the creation of
-individual data for a specific misbehaving monitor, commented sources
-and a Makefile environment are given here.
-
-To create binary EDID and C source code files from the existing data
-material, simply type "make".
-
-If you want to create your own EDID file, copy the file 1024x768.S,
-replace the settings with your own data and add a new target to the
-Makefile. Please note that the EDID data structure expects the timing
-values in a different way as compared to the standard X11 format.
-
-X11:
- HTimings:
- hdisp hsyncstart hsyncend htotal
- VTimings:
- vdisp vsyncstart vsyncend vtotal
-
-EDID::
-
- #define XPIX hdisp
- #define XBLANK htotal-hdisp
- #define XOFFSET hsyncstart-hdisp
- #define XPULSE hsyncend-hsyncstart
-
- #define YPIX vdisp
- #define YBLANK vtotal-vdisp
- #define YOFFSET vsyncstart-vdisp
- #define YPULSE vsyncend-vsyncstart
+++ /dev/null
-.. include:: <isonum.txt>
-
-============
-SM501 Driver
-============
-
-:Copyright: |copy| 2006, 2007 Simtec Electronics
-
-The Silicon Motion SM501 multimedia companion chip is a multifunction device
-which may provide numerous interfaces including USB host controller USB gadget,
-asynchronous serial ports, audio functions, and a dual display video interface.
-The device may be connected by PCI or local bus with varying functions enabled.
-
-Core
-----
-
-The core driver in drivers/mfd provides common services for the
-drivers which manage the specific hardware blocks. These services
-include locking for common registers, clock control and resource
-management.
-
-The core registers drivers for both PCI and generic bus based
-chips via the platform device and driver system.
-
-On detection of a device, the core initialises the chip (which may
-be specified by the platform data) and then exports the selected
-peripheral set as platform devices for the specific drivers.
-
-The core re-uses the platform device system as the platform device
-system provides enough features to support the drivers without the
-need to create a new bus-type and the associated code to go with it.
-
-
-Resources
----------
-
-Each peripheral has a view of the device which is implicitly narrowed to
-the specific set of resources that peripheral requires in order to
-function correctly.
-
-The centralised memory allocation allows the driver to ensure that the
-maximum possible resource allocation can be made to the video subsystem
-as this is by-far the most resource-sensitive of the on-chip functions.
-
-The primary issue with memory allocation is that of moving the video
-buffers once a display mode is chosen. Indeed when a video mode change
-occurs the memory footprint of the video subsystem changes.
-
-Since video memory is difficult to move without changing the display
-(unless sufficient contiguous memory can be provided for the old and new
-modes simultaneously) the video driver fully utilises the memory area
-given to it by aligning fb0 to the start of the area and fb1 to the end
-of it. Any memory left over in the middle is used for the acceleration
-functions, which are transient and thus their location is less critical
-as it can be moved.
-
-
-Configuration
--------------
-
-The platform device driver uses a set of platform data to pass
-configurations through to the core and the subsidiary drivers
-so that there can be support for more than one system carrying
-an SM501 built into a single kernel image.
-
-The PCI driver assumes that the PCI card behaves as per the Silicon
-Motion reference design.
-
-There is an errata (AB-5) affecting the selection of the
-of the M1XCLK and M1CLK frequencies. These two clocks
-must be sourced from the same PLL, although they can then
-be divided down individually. If this is not set, then SM501 may
-lock and hang the whole system. The driver will refuse to
-attach if the PLL selection is different.
edid/1680x1050.bin, or edid/1920x1080.bin is given
and no file with the same name exists. Details and
instructions how to build your own EDID data are
- available in Documentation/EDID/howto.rst. An EDID
+ available in Documentation/driver-api/edid.rst. An EDID
data set will only be used for a particular connector,
if its name and a colon are prepended to the EDID
name. Each connector may use a unique EDID data
2010.
rfkill controller switch "tpacpi_bluetooth_sw": refer to
- Documentation/rfkill.txt for details.
+ Documentation/driver-api/rfkill.rst for details.
Video output control -- /proc/acpi/ibm/video
2010.
rfkill controller switch "tpacpi_wwan_sw": refer to
- Documentation/rfkill.txt for details.
+ Documentation/driver-api/rfkill.rst for details.
EXPERIMENTAL: UWB
^^^^^^^^^^^
rfkill controller switch "tpacpi_uwb_sw": refer to
- Documentation/rfkill.txt for details.
+ Documentation/driver-api/rfkill.rst for details.
Adaptive keyboard
-----------------
+++ /dev/null
-===================================================================
-A driver for a selfmade cheap BT8xx based PCI GPIO-card (bt8xxgpio)
-===================================================================
-
-For advanced documentation, see http://www.bu3sch.de/btgpio.php
-
-A generic digital 24-port PCI GPIO card can be built out of an ordinary
-Brooktree bt848, bt849, bt878 or bt879 based analog TV tuner card. The
-Brooktree chip is used in old analog Hauppauge WinTV PCI cards. You can easily
-find them used for low prices on the net.
-
-The bt8xx chip does have 24 digital GPIO ports.
-These ports are accessible via 24 pins on the SMD chip package.
-
-
-How to physically access the GPIO pins
-======================================
-
-The are several ways to access these pins. One might unsolder the whole chip
-and put it on a custom PCI board, or one might only unsolder each individual
-GPIO pin and solder that to some tiny wire. As the chip package really is tiny
-there are some advanced soldering skills needed in any case.
-
-The physical pinouts are drawn in the following ASCII art.
-The GPIO pins are marked with G00-G23::
-
- G G G G G G G G G G G G G G G G G G
- 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
- ---------------------------------------------------------------------------
- --| ^ ^ |--
- --| pin 86 pin 67 |--
- --| |--
- --| pin 61 > |-- G18
- --| |-- G19
- --| |-- G20
- --| |-- G21
- --| |-- G22
- --| pin 56 > |-- G23
- --| |--
- --| Brooktree 878/879 |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| |--
- --| O |--
- --| |--
- ---------------------------------------------------------------------------
- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
- ^
- This is pin 1
-
+++ /dev/null
-:orphan:
-
-================
-Kernel Connector
-================
-
-Kernel connector - new netlink based userspace <-> kernel space easy
-to use communication module.
-
-The Connector driver makes it easy to connect various agents using a
-netlink based network. One must register a callback and an identifier.
-When the driver receives a special netlink message with the appropriate
-identifier, the appropriate callback will be called.
-
-From the userspace point of view it's quite straightforward:
-
- - socket();
- - bind();
- - send();
- - recv();
-
-But if kernelspace wants to use the full power of such connections, the
-driver writer must create special sockets, must know about struct sk_buff
-handling, etc... The Connector driver allows any kernelspace agents to use
-netlink based networking for inter-process communication in a significantly
-easier way::
-
- int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
- void cn_netlink_send_multi(struct cn_msg *msg, u16 len, u32 portid, u32 __group, int gfp_mask);
- void cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group, int gfp_mask);
-
- struct cb_id
- {
- __u32 idx;
- __u32 val;
- };
-
-idx and val are unique identifiers which must be registered in the
-connector.h header for in-kernel usage. `void (*callback) (void *)` is a
-callback function which will be called when a message with above idx.val
-is received by the connector core. The argument for that function must
-be dereferenced to `struct cn_msg *`::
-
- struct cn_msg
- {
- struct cb_id id;
-
- __u32 seq;
- __u32 ack;
-
- __u32 len; /* Length of the following data */
- __u8 data[0];
- };
-
-Connector interfaces
-====================
-
- .. kernel-doc:: include/linux/connector.h
-
- Note:
- When registering new callback user, connector core assigns
- netlink group to the user which is equal to its id.idx.
-
-Protocol description
-====================
-
-The current framework offers a transport layer with fixed headers. The
-recommended protocol which uses such a header is as following:
-
-msg->seq and msg->ack are used to determine message genealogy. When
-someone sends a message, they use a locally unique sequence and random
-acknowledge number. The sequence number may be copied into
-nlmsghdr->nlmsg_seq too.
-
-The sequence number is incremented with each message sent.
-
-If you expect a reply to the message, then the sequence number in the
-received message MUST be the same as in the original message, and the
-acknowledge number MUST be the same + 1.
-
-If we receive a message and its sequence number is not equal to one we
-are expecting, then it is a new message. If we receive a message and
-its sequence number is the same as one we are expecting, but its
-acknowledge is not equal to the sequence number in the original
-message + 1, then it is a new message.
-
-Obviously, the protocol header contains the above id.
-
-The connector allows event notification in the following form: kernel
-driver or userspace process can ask connector to notify it when
-selected ids will be turned on or off (registered or unregistered its
-callback). It is done by sending a special command to the connector
-driver (it also registers itself with id={-1, -1}).
-
-As example of this usage can be found in the cn_test.c module which
-uses the connector to request notification and to send messages.
-
-Reliability
-===========
-
-Netlink itself is not a reliable protocol. That means that messages can
-be lost due to memory pressure or process' receiving queue overflowed,
-so caller is warned that it must be prepared. That is why the struct
-cn_msg [main connector's message header] contains u32 seq and u32 ack
-fields.
-
-Userspace usage
-===============
-
-2.6.14 has a new netlink socket implementation, which by default does not
-allow people to send data to netlink groups other than 1.
-So, if you wish to use a netlink socket (for example using connector)
-with a different group number, the userspace application must subscribe to
-that group first. It can be achieved by the following pseudocode::
-
- s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
-
- l_local.nl_family = AF_NETLINK;
- l_local.nl_groups = 12345;
- l_local.nl_pid = 0;
-
- if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
- perror("bind");
- close(s);
- return -1;
- }
-
- {
- int on = l_local.nl_groups;
- setsockopt(s, 270, 1, &on, sizeof(on));
- }
-
-Where 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket
-option. To drop a multicast subscription, one should call the above socket
-option with the NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.
-
-2.6.14 netlink code only allows to select a group which is less or equal to
-the maximum group number, which is used at netlink_kernel_create() time.
-In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use
-group number 12345, you must increment CN_NETLINK_USERS to that number.
-Additional 0xf numbers are allocated to be used by non-in-kernel users.
-
-Due to this limitation, group 0xffffffff does not work now, so one can
-not use add/remove connector's group notifications, but as far as I know,
-only cn_test.c test module used it.
-
-Some work in netlink area is still being done, so things can be changed in
-2.6.15 timeframe, if it will happen, documentation will be updated for that
-kernel.
-
-Code samples
-============
-
-Sample code for a connector test module and user space can be found
-in samples/connector/. To build this code, enable CONFIG_CONNECTOR
-and CONFIG_SAMPLES.
+++ /dev/null
-:orphan:
-
-===============
-Console Drivers
-===============
-
-The Linux kernel has 2 general types of console drivers. The first type is
-assigned by the kernel to all the virtual consoles during the boot process.
-This type will be called 'system driver', and only one system driver is allowed
-to exist. The system driver is persistent and it can never be unloaded, though
-it may become inactive.
-
-The second type has to be explicitly loaded and unloaded. This will be called
-'modular driver' by this document. Multiple modular drivers can coexist at
-any time with each driver sharing the console with other drivers including
-the system driver. However, modular drivers cannot take over the console
-that is currently occupied by another modular driver. (Exception: Drivers that
-call do_take_over_console() will succeed in the takeover regardless of the type
-of driver occupying the consoles.) They can only take over the console that is
-occupied by the system driver. In the same token, if the modular driver is
-released by the console, the system driver will take over.
-
-Modular drivers, from the programmer's point of view, have to call::
-
- do_take_over_console() - load and bind driver to console layer
- give_up_console() - unload driver; it will only work if driver
- is fully unbound
-
-In newer kernels, the following are also available::
-
- do_register_con_driver()
- do_unregister_con_driver()
-
-If sysfs is enabled, the contents of /sys/class/vtconsole can be
-examined. This shows the console backends currently registered by the
-system which are named vtcon<n> where <n> is an integer from 0 to 15.
-Thus::
-
- ls /sys/class/vtconsole
- . .. vtcon0 vtcon1
-
-Each directory in /sys/class/vtconsole has 3 files::
-
- ls /sys/class/vtconsole/vtcon0
- . .. bind name uevent
-
-What do these files signify?
-
- 1. bind - this is a read/write file. It shows the status of the driver if
- read, or acts to bind or unbind the driver to the virtual consoles
- when written to. The possible values are:
-
- 0
- - means the driver is not bound and if echo'ed, commands the driver
- to unbind
-
- 1
- - means the driver is bound and if echo'ed, commands the driver to
- bind
-
- 2. name - read-only file. Shows the name of the driver in this format::
-
- cat /sys/class/vtconsole/vtcon0/name
- (S) VGA+
-
- '(S)' stands for a (S)ystem driver, i.e., it cannot be directly
- commanded to bind or unbind
-
- 'VGA+' is the name of the driver
-
- cat /sys/class/vtconsole/vtcon1/name
- (M) frame buffer device
-
- In this case, '(M)' stands for a (M)odular driver, one that can be
- directly commanded to bind or unbind.
-
- 3. uevent - ignore this file
-
-When unbinding, the modular driver is detached first, and then the system
-driver takes over the consoles vacated by the driver. Binding, on the other
-hand, will bind the driver to the consoles that are currently occupied by a
-system driver.
-
-NOTE1:
- Binding and unbinding must be selected in Kconfig. It's under::
-
- Device Drivers ->
- Character devices ->
- Support for binding and unbinding console drivers
-
-NOTE2:
- If any of the virtual consoles are in KD_GRAPHICS mode, then binding or
- unbinding will not succeed. An example of an application that sets the
- console to KD_GRAPHICS is X.
-
-How useful is this feature? This is very useful for console driver
-developers. By unbinding the driver from the console layer, one can unload the
-driver, make changes, recompile, reload and rebind the driver without any need
-for rebooting the kernel. For regular users who may want to switch from
-framebuffer console to VGA console and vice versa, this feature also makes
-this possible. (NOTE NOTE NOTE: Please read fbcon.txt under Documentation/fb
-for more details.)
-
-Notes for developers
-====================
-
-do_take_over_console() is now broken up into::
-
- do_register_con_driver()
- do_bind_con_driver() - private function
-
-give_up_console() is a wrapper to do_unregister_con_driver(), and a driver must
-be fully unbound for this call to succeed. con_is_bound() will check if the
-driver is bound or not.
-
-Guidelines for console driver writers
-=====================================
-
-In order for binding to and unbinding from the console to properly work,
-console drivers must follow these guidelines:
-
-1. All drivers, except system drivers, must call either do_register_con_driver()
- or do_take_over_console(). do_register_con_driver() will just add the driver
- to the console's internal list. It won't take over the
- console. do_take_over_console(), as it name implies, will also take over (or
- bind to) the console.
-
-2. All resources allocated during con->con_init() must be released in
- con->con_deinit().
-
-3. All resources allocated in con->con_startup() must be released when the
- driver, which was previously bound, becomes unbound. The console layer
- does not have a complementary call to con->con_startup() so it's up to the
- driver to check when it's legal to release these resources. Calling
- con_is_bound() in con->con_deinit() will help. If the call returned
- false(), then it's safe to release the resources. This balance has to be
- ensured because con->con_startup() can be called again when a request to
- rebind the driver to the console arrives.
-
-4. Upon exit of the driver, ensure that the driver is totally unbound. If the
- condition is satisfied, then the driver must call do_unregister_con_driver()
- or give_up_console().
-
-5. do_unregister_con_driver() can also be called on conditions which make it
- impossible for the driver to service console requests. This can happen
- with the framebuffer console that suddenly lost all of its drivers.
-
-The current crop of console drivers should still work correctly, but binding
-and unbinding them may cause problems. With minimal fixes, these drivers can
-be made to work correctly.
-
-Antonino Daplas <adaplas@pol.net>
+++ /dev/null
-===================================
-Dell Systems Management Base Driver
-===================================
-
-Overview
-========
-
-The Dell Systems Management Base Driver provides a sysfs interface for
-systems management software such as Dell OpenManage to perform system
-management interrupts and host control actions (system power cycle or
-power off after OS shutdown) on certain Dell systems.
-
-Dell OpenManage requires this driver on the following Dell PowerEdge systems:
-300, 1300, 1400, 400SC, 500SC, 1500SC, 1550, 600SC, 1600SC, 650, 1655MC,
-700, and 750. Other Dell software such as the open source libsmbios project
-is expected to make use of this driver, and it may include the use of this
-driver on other Dell systems.
-
-The Dell libsmbios project aims towards providing access to as much BIOS
-information as possible. See http://linux.dell.com/libsmbios/main/ for
-more information about the libsmbios project.
-
-
-System Management Interrupt
-===========================
-
-On some Dell systems, systems management software must access certain
-management information via a system management interrupt (SMI). The SMI data
-buffer must reside in 32-bit address space, and the physical address of the
-buffer is required for the SMI. The driver maintains the memory required for
-the SMI and provides a way for the application to generate the SMI.
-The driver creates the following sysfs entries for systems management
-software to perform these system management interrupts::
-
- /sys/devices/platform/dcdbas/smi_data
- /sys/devices/platform/dcdbas/smi_data_buf_phys_addr
- /sys/devices/platform/dcdbas/smi_data_buf_size
- /sys/devices/platform/dcdbas/smi_request
-
-Systems management software must perform the following steps to execute
-a SMI using this driver:
-
-1) Lock smi_data.
-2) Write system management command to smi_data.
-3) Write "1" to smi_request to generate a calling interface SMI or
- "2" to generate a raw SMI.
-4) Read system management command response from smi_data.
-5) Unlock smi_data.
-
-
-Host Control Action
-===================
-
-Dell OpenManage supports a host control feature that allows the administrator
-to perform a power cycle or power off of the system after the OS has finished
-shutting down. On some Dell systems, this host control feature requires that
-a driver perform a SMI after the OS has finished shutting down.
-
-The driver creates the following sysfs entries for systems management software
-to schedule the driver to perform a power cycle or power off host control
-action after the system has finished shutting down:
-
-/sys/devices/platform/dcdbas/host_control_action
-/sys/devices/platform/dcdbas/host_control_smi_type
-/sys/devices/platform/dcdbas/host_control_on_shutdown
-
-Dell OpenManage performs the following steps to execute a power cycle or
-power off host control action using this driver:
-
-1) Write host control action to be performed to host_control_action.
-2) Write type of SMI that driver needs to perform to host_control_smi_type.
-3) Write "1" to host_control_on_shutdown to enable host control action.
-4) Initiate OS shutdown.
- (Driver will perform host control SMI when it is notified that the OS
- has finished shutting down.)
-
-
-Host Control SMI Type
-=====================
-
-The following table shows the value to write to host_control_smi_type to
-perform a power cycle or power off host control action:
-
-=================== =====================
-PowerEdge System Host Control SMI Type
-=================== =====================
- 300 HC_SMITYPE_TYPE1
- 1300 HC_SMITYPE_TYPE1
- 1400 HC_SMITYPE_TYPE2
- 500SC HC_SMITYPE_TYPE2
- 1500SC HC_SMITYPE_TYPE2
- 1550 HC_SMITYPE_TYPE2
- 600SC HC_SMITYPE_TYPE2
- 1600SC HC_SMITYPE_TYPE2
- 650 HC_SMITYPE_TYPE2
- 1655MC HC_SMITYPE_TYPE2
- 700 HC_SMITYPE_TYPE3
- 750 HC_SMITYPE_TYPE3
-=================== =====================
+++ /dev/null
-=============================================================
-Usage of the new open sourced rbu (Remote BIOS Update) driver
-=============================================================
-
-Purpose
-=======
-
-Document demonstrating the use of the Dell Remote BIOS Update driver.
-for updating BIOS images on Dell servers and desktops.
-
-Scope
-=====
-
-This document discusses the functionality of the rbu driver only.
-It does not cover the support needed from applications to enable the BIOS to
-update itself with the image downloaded in to the memory.
-
-Overview
-========
-
-This driver works with Dell OpenManage or Dell Update Packages for updating
-the BIOS on Dell servers (starting from servers sold since 1999), desktops
-and notebooks (starting from those sold in 2005).
-
-Please go to http://support.dell.com register and you can find info on
-OpenManage and Dell Update packages (DUP).
-
-Libsmbios can also be used to update BIOS on Dell systems go to
-http://linux.dell.com/libsmbios/ for details.
-
-Dell_RBU driver supports BIOS update using the monolithic image and packetized
-image methods. In case of monolithic the driver allocates a contiguous chunk
-of physical pages having the BIOS image. In case of packetized the app
-using the driver breaks the image in to packets of fixed sizes and the driver
-would place each packet in contiguous physical memory. The driver also
-maintains a link list of packets for reading them back.
-
-If the dell_rbu driver is unloaded all the allocated memory is freed.
-
-The rbu driver needs to have an application (as mentioned above)which will
-inform the BIOS to enable the update in the next system reboot.
-
-The user should not unload the rbu driver after downloading the BIOS image
-or updating.
-
-The driver load creates the following directories under the /sys file system::
-
- /sys/class/firmware/dell_rbu/loading
- /sys/class/firmware/dell_rbu/data
- /sys/devices/platform/dell_rbu/image_type
- /sys/devices/platform/dell_rbu/data
- /sys/devices/platform/dell_rbu/packet_size
-
-The driver supports two types of update mechanism; monolithic and packetized.
-These update mechanism depends upon the BIOS currently running on the system.
-Most of the Dell systems support a monolithic update where the BIOS image is
-copied to a single contiguous block of physical memory.
-
-In case of packet mechanism the single memory can be broken in smaller chunks
-of contiguous memory and the BIOS image is scattered in these packets.
-
-By default the driver uses monolithic memory for the update type. This can be
-changed to packets during the driver load time by specifying the load
-parameter image_type=packet. This can also be changed later as below::
-
- echo packet > /sys/devices/platform/dell_rbu/image_type
-
-In packet update mode the packet size has to be given before any packets can
-be downloaded. It is done as below::
-
- echo XXXX > /sys/devices/platform/dell_rbu/packet_size
-
-In the packet update mechanism, the user needs to create a new file having
-packets of data arranged back to back. It can be done as follows
-The user creates packets header, gets the chunk of the BIOS image and
-places it next to the packetheader; now, the packetheader + BIOS image chunk
-added together should match the specified packet_size. This makes one
-packet, the user needs to create more such packets out of the entire BIOS
-image file and then arrange all these packets back to back in to one single
-file.
-
-This file is then copied to /sys/class/firmware/dell_rbu/data.
-Once this file gets to the driver, the driver extracts packet_size data from
-the file and spreads it across the physical memory in contiguous packet_sized
-space.
-
-This method makes sure that all the packets get to the driver in a single operation.
-
-In monolithic update the user simply get the BIOS image (.hdr file) and copies
-to the data file as is without any change to the BIOS image itself.
-
-Do the steps below to download the BIOS image.
-
-1) echo 1 > /sys/class/firmware/dell_rbu/loading
-2) cp bios_image.hdr /sys/class/firmware/dell_rbu/data
-3) echo 0 > /sys/class/firmware/dell_rbu/loading
-
-The /sys/class/firmware/dell_rbu/ entries will remain till the following is
-done.
-
-::
-
- echo -1 > /sys/class/firmware/dell_rbu/loading
-
-Until this step is completed the driver cannot be unloaded.
-
-Also echoing either mono, packet or init in to image_type will free up the
-memory allocated by the driver.
-
-If a user by accident executes steps 1 and 3 above without executing step 2;
-it will make the /sys/class/firmware/dell_rbu/ entries disappear.
-
-The entries can be recreated by doing the following::
-
- echo init > /sys/devices/platform/dell_rbu/image_type
-
-.. note:: echoing init in image_type does not change it original value.
-
-Also the driver provides /sys/devices/platform/dell_rbu/data readonly file to
-read back the image downloaded.
-
-.. note::
-
- After updating the BIOS image a user mode application needs to execute
- code which sends the BIOS update request to the BIOS. So on the next reboot
- the BIOS knows about the new image downloaded and it updates itself.
- Also don't unload the rbu driver if the image has to be updated.
-
--- /dev/null
+===================================================================
+A driver for a selfmade cheap BT8xx based PCI GPIO-card (bt8xxgpio)
+===================================================================
+
+For advanced documentation, see http://www.bu3sch.de/btgpio.php
+
+A generic digital 24-port PCI GPIO card can be built out of an ordinary
+Brooktree bt848, bt849, bt878 or bt879 based analog TV tuner card. The
+Brooktree chip is used in old analog Hauppauge WinTV PCI cards. You can easily
+find them used for low prices on the net.
+
+The bt8xx chip does have 24 digital GPIO ports.
+These ports are accessible via 24 pins on the SMD chip package.
+
+
+How to physically access the GPIO pins
+======================================
+
+The are several ways to access these pins. One might unsolder the whole chip
+and put it on a custom PCI board, or one might only unsolder each individual
+GPIO pin and solder that to some tiny wire. As the chip package really is tiny
+there are some advanced soldering skills needed in any case.
+
+The physical pinouts are drawn in the following ASCII art.
+The GPIO pins are marked with G00-G23::
+
+ G G G G G G G G G G G G G G G G G G
+ 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+ ---------------------------------------------------------------------------
+ --| ^ ^ |--
+ --| pin 86 pin 67 |--
+ --| |--
+ --| pin 61 > |-- G18
+ --| |-- G19
+ --| |-- G20
+ --| |-- G21
+ --| |-- G22
+ --| pin 56 > |-- G23
+ --| |--
+ --| Brooktree 878/879 |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| |--
+ --| O |--
+ --| |--
+ ---------------------------------------------------------------------------
+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+ ^
+ This is pin 1
+
--- /dev/null
+.. SPDX-License-Identifier: GPL-2.0
+
+================
+Kernel Connector
+================
+
+Kernel connector - new netlink based userspace <-> kernel space easy
+to use communication module.
+
+The Connector driver makes it easy to connect various agents using a
+netlink based network. One must register a callback and an identifier.
+When the driver receives a special netlink message with the appropriate
+identifier, the appropriate callback will be called.
+
+From the userspace point of view it's quite straightforward:
+
+ - socket();
+ - bind();
+ - send();
+ - recv();
+
+But if kernelspace wants to use the full power of such connections, the
+driver writer must create special sockets, must know about struct sk_buff
+handling, etc... The Connector driver allows any kernelspace agents to use
+netlink based networking for inter-process communication in a significantly
+easier way::
+
+ int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
+ void cn_netlink_send_multi(struct cn_msg *msg, u16 len, u32 portid, u32 __group, int gfp_mask);
+ void cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group, int gfp_mask);
+
+ struct cb_id
+ {
+ __u32 idx;
+ __u32 val;
+ };
+
+idx and val are unique identifiers which must be registered in the
+connector.h header for in-kernel usage. `void (*callback) (void *)` is a
+callback function which will be called when a message with above idx.val
+is received by the connector core. The argument for that function must
+be dereferenced to `struct cn_msg *`::
+
+ struct cn_msg
+ {
+ struct cb_id id;
+
+ __u32 seq;
+ __u32 ack;
+
+ __u32 len; /* Length of the following data */
+ __u8 data[0];
+ };
+
+Connector interfaces
+====================
+
+ .. kernel-doc:: include/linux/connector.h
+
+ Note:
+ When registering new callback user, connector core assigns
+ netlink group to the user which is equal to its id.idx.
+
+Protocol description
+====================
+
+The current framework offers a transport layer with fixed headers. The
+recommended protocol which uses such a header is as following:
+
+msg->seq and msg->ack are used to determine message genealogy. When
+someone sends a message, they use a locally unique sequence and random
+acknowledge number. The sequence number may be copied into
+nlmsghdr->nlmsg_seq too.
+
+The sequence number is incremented with each message sent.
+
+If you expect a reply to the message, then the sequence number in the
+received message MUST be the same as in the original message, and the
+acknowledge number MUST be the same + 1.
+
+If we receive a message and its sequence number is not equal to one we
+are expecting, then it is a new message. If we receive a message and
+its sequence number is the same as one we are expecting, but its
+acknowledge is not equal to the sequence number in the original
+message + 1, then it is a new message.
+
+Obviously, the protocol header contains the above id.
+
+The connector allows event notification in the following form: kernel
+driver or userspace process can ask connector to notify it when
+selected ids will be turned on or off (registered or unregistered its
+callback). It is done by sending a special command to the connector
+driver (it also registers itself with id={-1, -1}).
+
+As example of this usage can be found in the cn_test.c module which
+uses the connector to request notification and to send messages.
+
+Reliability
+===========
+
+Netlink itself is not a reliable protocol. That means that messages can
+be lost due to memory pressure or process' receiving queue overflowed,
+so caller is warned that it must be prepared. That is why the struct
+cn_msg [main connector's message header] contains u32 seq and u32 ack
+fields.
+
+Userspace usage
+===============
+
+2.6.14 has a new netlink socket implementation, which by default does not
+allow people to send data to netlink groups other than 1.
+So, if you wish to use a netlink socket (for example using connector)
+with a different group number, the userspace application must subscribe to
+that group first. It can be achieved by the following pseudocode::
+
+ s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+
+ l_local.nl_family = AF_NETLINK;
+ l_local.nl_groups = 12345;
+ l_local.nl_pid = 0;
+
+ if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
+ perror("bind");
+ close(s);
+ return -1;
+ }
+
+ {
+ int on = l_local.nl_groups;
+ setsockopt(s, 270, 1, &on, sizeof(on));
+ }
+
+Where 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket
+option. To drop a multicast subscription, one should call the above socket
+option with the NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.
+
+2.6.14 netlink code only allows to select a group which is less or equal to
+the maximum group number, which is used at netlink_kernel_create() time.
+In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use
+group number 12345, you must increment CN_NETLINK_USERS to that number.
+Additional 0xf numbers are allocated to be used by non-in-kernel users.
+
+Due to this limitation, group 0xffffffff does not work now, so one can
+not use add/remove connector's group notifications, but as far as I know,
+only cn_test.c test module used it.
+
+Some work in netlink area is still being done, so things can be changed in
+2.6.15 timeframe, if it will happen, documentation will be updated for that
+kernel.
+
+Code samples
+============
+
+Sample code for a connector test module and user space can be found
+in samples/connector/. To build this code, enable CONFIG_CONNECTOR
+and CONFIG_SAMPLES.
--- /dev/null
+.. SPDX-License-Identifier: GPL-2.0
+
+===============
+Console Drivers
+===============
+
+The Linux kernel has 2 general types of console drivers. The first type is
+assigned by the kernel to all the virtual consoles during the boot process.
+This type will be called 'system driver', and only one system driver is allowed
+to exist. The system driver is persistent and it can never be unloaded, though
+it may become inactive.
+
+The second type has to be explicitly loaded and unloaded. This will be called
+'modular driver' by this document. Multiple modular drivers can coexist at
+any time with each driver sharing the console with other drivers including
+the system driver. However, modular drivers cannot take over the console
+that is currently occupied by another modular driver. (Exception: Drivers that
+call do_take_over_console() will succeed in the takeover regardless of the type
+of driver occupying the consoles.) They can only take over the console that is
+occupied by the system driver. In the same token, if the modular driver is
+released by the console, the system driver will take over.
+
+Modular drivers, from the programmer's point of view, have to call::
+
+ do_take_over_console() - load and bind driver to console layer
+ give_up_console() - unload driver; it will only work if driver
+ is fully unbound
+
+In newer kernels, the following are also available::
+
+ do_register_con_driver()
+ do_unregister_con_driver()
+
+If sysfs is enabled, the contents of /sys/class/vtconsole can be
+examined. This shows the console backends currently registered by the
+system which are named vtcon<n> where <n> is an integer from 0 to 15.
+Thus::
+
+ ls /sys/class/vtconsole
+ . .. vtcon0 vtcon1
+
+Each directory in /sys/class/vtconsole has 3 files::
+
+ ls /sys/class/vtconsole/vtcon0
+ . .. bind name uevent
+
+What do these files signify?
+
+ 1. bind - this is a read/write file. It shows the status of the driver if
+ read, or acts to bind or unbind the driver to the virtual consoles
+ when written to. The possible values are:
+
+ 0
+ - means the driver is not bound and if echo'ed, commands the driver
+ to unbind
+
+ 1
+ - means the driver is bound and if echo'ed, commands the driver to
+ bind
+
+ 2. name - read-only file. Shows the name of the driver in this format::
+
+ cat /sys/class/vtconsole/vtcon0/name
+ (S) VGA+
+
+ '(S)' stands for a (S)ystem driver, i.e., it cannot be directly
+ commanded to bind or unbind
+
+ 'VGA+' is the name of the driver
+
+ cat /sys/class/vtconsole/vtcon1/name
+ (M) frame buffer device
+
+ In this case, '(M)' stands for a (M)odular driver, one that can be
+ directly commanded to bind or unbind.
+
+ 3. uevent - ignore this file
+
+When unbinding, the modular driver is detached first, and then the system
+driver takes over the consoles vacated by the driver. Binding, on the other
+hand, will bind the driver to the consoles that are currently occupied by a
+system driver.
+
+NOTE1:
+ Binding and unbinding must be selected in Kconfig. It's under::
+
+ Device Drivers ->
+ Character devices ->
+ Support for binding and unbinding console drivers
+
+NOTE2:
+ If any of the virtual consoles are in KD_GRAPHICS mode, then binding or
+ unbinding will not succeed. An example of an application that sets the
+ console to KD_GRAPHICS is X.
+
+How useful is this feature? This is very useful for console driver
+developers. By unbinding the driver from the console layer, one can unload the
+driver, make changes, recompile, reload and rebind the driver without any need
+for rebooting the kernel. For regular users who may want to switch from
+framebuffer console to VGA console and vice versa, this feature also makes
+this possible. (NOTE NOTE NOTE: Please read fbcon.txt under Documentation/fb
+for more details.)
+
+Notes for developers
+====================
+
+do_take_over_console() is now broken up into::
+
+ do_register_con_driver()
+ do_bind_con_driver() - private function
+
+give_up_console() is a wrapper to do_unregister_con_driver(), and a driver must
+be fully unbound for this call to succeed. con_is_bound() will check if the
+driver is bound or not.
+
+Guidelines for console driver writers
+=====================================
+
+In order for binding to and unbinding from the console to properly work,
+console drivers must follow these guidelines:
+
+1. All drivers, except system drivers, must call either do_register_con_driver()
+ or do_take_over_console(). do_register_con_driver() will just add the driver
+ to the console's internal list. It won't take over the
+ console. do_take_over_console(), as it name implies, will also take over (or
+ bind to) the console.
+
+2. All resources allocated during con->con_init() must be released in
+ con->con_deinit().
+
+3. All resources allocated in con->con_startup() must be released when the
+ driver, which was previously bound, becomes unbound. The console layer
+ does not have a complementary call to con->con_startup() so it's up to the
+ driver to check when it's legal to release these resources. Calling
+ con_is_bound() in con->con_deinit() will help. If the call returned
+ false(), then it's safe to release the resources. This balance has to be
+ ensured because con->con_startup() can be called again when a request to
+ rebind the driver to the console arrives.
+
+4. Upon exit of the driver, ensure that the driver is totally unbound. If the
+ condition is satisfied, then the driver must call do_unregister_con_driver()
+ or give_up_console().
+
+5. do_unregister_con_driver() can also be called on conditions which make it
+ impossible for the driver to service console requests. This can happen
+ with the framebuffer console that suddenly lost all of its drivers.
+
+The current crop of console drivers should still work correctly, but binding
+and unbinding them may cause problems. With minimal fixes, these drivers can
+be made to work correctly.
+
+Antonino Daplas <adaplas@pol.net>
--- /dev/null
+===================================
+Dell Systems Management Base Driver
+===================================
+
+Overview
+========
+
+The Dell Systems Management Base Driver provides a sysfs interface for
+systems management software such as Dell OpenManage to perform system
+management interrupts and host control actions (system power cycle or
+power off after OS shutdown) on certain Dell systems.
+
+Dell OpenManage requires this driver on the following Dell PowerEdge systems:
+300, 1300, 1400, 400SC, 500SC, 1500SC, 1550, 600SC, 1600SC, 650, 1655MC,
+700, and 750. Other Dell software such as the open source libsmbios project
+is expected to make use of this driver, and it may include the use of this
+driver on other Dell systems.
+
+The Dell libsmbios project aims towards providing access to as much BIOS
+information as possible. See http://linux.dell.com/libsmbios/main/ for
+more information about the libsmbios project.
+
+
+System Management Interrupt
+===========================
+
+On some Dell systems, systems management software must access certain
+management information via a system management interrupt (SMI). The SMI data
+buffer must reside in 32-bit address space, and the physical address of the
+buffer is required for the SMI. The driver maintains the memory required for
+the SMI and provides a way for the application to generate the SMI.
+The driver creates the following sysfs entries for systems management
+software to perform these system management interrupts::
+
+ /sys/devices/platform/dcdbas/smi_data
+ /sys/devices/platform/dcdbas/smi_data_buf_phys_addr
+ /sys/devices/platform/dcdbas/smi_data_buf_size
+ /sys/devices/platform/dcdbas/smi_request
+
+Systems management software must perform the following steps to execute
+a SMI using this driver:
+
+1) Lock smi_data.
+2) Write system management command to smi_data.
+3) Write "1" to smi_request to generate a calling interface SMI or
+ "2" to generate a raw SMI.
+4) Read system management command response from smi_data.
+5) Unlock smi_data.
+
+
+Host Control Action
+===================
+
+Dell OpenManage supports a host control feature that allows the administrator
+to perform a power cycle or power off of the system after the OS has finished
+shutting down. On some Dell systems, this host control feature requires that
+a driver perform a SMI after the OS has finished shutting down.
+
+The driver creates the following sysfs entries for systems management software
+to schedule the driver to perform a power cycle or power off host control
+action after the system has finished shutting down:
+
+/sys/devices/platform/dcdbas/host_control_action
+/sys/devices/platform/dcdbas/host_control_smi_type
+/sys/devices/platform/dcdbas/host_control_on_shutdown
+
+Dell OpenManage performs the following steps to execute a power cycle or
+power off host control action using this driver:
+
+1) Write host control action to be performed to host_control_action.
+2) Write type of SMI that driver needs to perform to host_control_smi_type.
+3) Write "1" to host_control_on_shutdown to enable host control action.
+4) Initiate OS shutdown.
+ (Driver will perform host control SMI when it is notified that the OS
+ has finished shutting down.)
+
+
+Host Control SMI Type
+=====================
+
+The following table shows the value to write to host_control_smi_type to
+perform a power cycle or power off host control action:
+
+=================== =====================
+PowerEdge System Host Control SMI Type
+=================== =====================
+ 300 HC_SMITYPE_TYPE1
+ 1300 HC_SMITYPE_TYPE1
+ 1400 HC_SMITYPE_TYPE2
+ 500SC HC_SMITYPE_TYPE2
+ 1500SC HC_SMITYPE_TYPE2
+ 1550 HC_SMITYPE_TYPE2
+ 600SC HC_SMITYPE_TYPE2
+ 1600SC HC_SMITYPE_TYPE2
+ 650 HC_SMITYPE_TYPE2
+ 1655MC HC_SMITYPE_TYPE2
+ 700 HC_SMITYPE_TYPE3
+ 750 HC_SMITYPE_TYPE3
+=================== =====================
--- /dev/null
+=============================================================
+Usage of the new open sourced rbu (Remote BIOS Update) driver
+=============================================================
+
+Purpose
+=======
+
+Document demonstrating the use of the Dell Remote BIOS Update driver.
+for updating BIOS images on Dell servers and desktops.
+
+Scope
+=====
+
+This document discusses the functionality of the rbu driver only.
+It does not cover the support needed from applications to enable the BIOS to
+update itself with the image downloaded in to the memory.
+
+Overview
+========
+
+This driver works with Dell OpenManage or Dell Update Packages for updating
+the BIOS on Dell servers (starting from servers sold since 1999), desktops
+and notebooks (starting from those sold in 2005).
+
+Please go to http://support.dell.com register and you can find info on
+OpenManage and Dell Update packages (DUP).
+
+Libsmbios can also be used to update BIOS on Dell systems go to
+http://linux.dell.com/libsmbios/ for details.
+
+Dell_RBU driver supports BIOS update using the monolithic image and packetized
+image methods. In case of monolithic the driver allocates a contiguous chunk
+of physical pages having the BIOS image. In case of packetized the app
+using the driver breaks the image in to packets of fixed sizes and the driver
+would place each packet in contiguous physical memory. The driver also
+maintains a link list of packets for reading them back.
+
+If the dell_rbu driver is unloaded all the allocated memory is freed.
+
+The rbu driver needs to have an application (as mentioned above)which will
+inform the BIOS to enable the update in the next system reboot.
+
+The user should not unload the rbu driver after downloading the BIOS image
+or updating.
+
+The driver load creates the following directories under the /sys file system::
+
+ /sys/class/firmware/dell_rbu/loading
+ /sys/class/firmware/dell_rbu/data
+ /sys/devices/platform/dell_rbu/image_type
+ /sys/devices/platform/dell_rbu/data
+ /sys/devices/platform/dell_rbu/packet_size
+
+The driver supports two types of update mechanism; monolithic and packetized.
+These update mechanism depends upon the BIOS currently running on the system.
+Most of the Dell systems support a monolithic update where the BIOS image is
+copied to a single contiguous block of physical memory.
+
+In case of packet mechanism the single memory can be broken in smaller chunks
+of contiguous memory and the BIOS image is scattered in these packets.
+
+By default the driver uses monolithic memory for the update type. This can be
+changed to packets during the driver load time by specifying the load
+parameter image_type=packet. This can also be changed later as below::
+
+ echo packet > /sys/devices/platform/dell_rbu/image_type
+
+In packet update mode the packet size has to be given before any packets can
+be downloaded. It is done as below::
+
+ echo XXXX > /sys/devices/platform/dell_rbu/packet_size
+
+In the packet update mechanism, the user needs to create a new file having
+packets of data arranged back to back. It can be done as follows
+The user creates packets header, gets the chunk of the BIOS image and
+places it next to the packetheader; now, the packetheader + BIOS image chunk
+added together should match the specified packet_size. This makes one
+packet, the user needs to create more such packets out of the entire BIOS
+image file and then arrange all these packets back to back in to one single
+file.
+
+This file is then copied to /sys/class/firmware/dell_rbu/data.
+Once this file gets to the driver, the driver extracts packet_size data from
+the file and spreads it across the physical memory in contiguous packet_sized
+space.
+
+This method makes sure that all the packets get to the driver in a single operation.
+
+In monolithic update the user simply get the BIOS image (.hdr file) and copies
+to the data file as is without any change to the BIOS image itself.
+
+Do the steps below to download the BIOS image.
+
+1) echo 1 > /sys/class/firmware/dell_rbu/loading
+2) cp bios_image.hdr /sys/class/firmware/dell_rbu/data
+3) echo 0 > /sys/class/firmware/dell_rbu/loading
+
+The /sys/class/firmware/dell_rbu/ entries will remain till the following is
+done.
+
+::
+
+ echo -1 > /sys/class/firmware/dell_rbu/loading
+
+Until this step is completed the driver cannot be unloaded.
+
+Also echoing either mono, packet or init in to image_type will free up the
+memory allocated by the driver.
+
+If a user by accident executes steps 1 and 3 above without executing step 2;
+it will make the /sys/class/firmware/dell_rbu/ entries disappear.
+
+The entries can be recreated by doing the following::
+
+ echo init > /sys/devices/platform/dell_rbu/image_type
+
+.. note:: echoing init in image_type does not change it original value.
+
+Also the driver provides /sys/devices/platform/dell_rbu/data readonly file to
+read back the image downloaded.
+
+.. note::
+
+ After updating the BIOS image a user mode application needs to execute
+ code which sends the BIOS update request to the BIOS. So on the next reboot
+ the BIOS knows about the new image downloaded and it updates itself.
+ Also don't unload the rbu driver if the image has to be updated.
+
--- /dev/null
+.. SPDX-License-Identifier: GPL-2.0
+
+====
+EDID
+====
+
+In the good old days when graphics parameters were configured explicitly
+in a file called xorg.conf, even broken hardware could be managed.
+
+Today, with the advent of Kernel Mode Setting, a graphics board is
+either correctly working because all components follow the standards -
+or the computer is unusable, because the screen remains dark after
+booting or it displays the wrong area. Cases when this happens are:
+- The graphics board does not recognize the monitor.
+- The graphics board is unable to detect any EDID data.
+- The graphics board incorrectly forwards EDID data to the driver.
+- The monitor sends no or bogus EDID data.
+- A KVM sends its own EDID data instead of querying the connected monitor.
+Adding the kernel parameter "nomodeset" helps in most cases, but causes
+restrictions later on.
+
+As a remedy for such situations, the kernel configuration item
+CONFIG_DRM_LOAD_EDID_FIRMWARE was introduced. It allows to provide an
+individually prepared or corrected EDID data set in the /lib/firmware
+directory from where it is loaded via the firmware interface. The code
+(see drivers/gpu/drm/drm_edid_load.c) contains built-in data sets for
+commonly used screen resolutions (800x600, 1024x768, 1280x1024, 1600x1200,
+1680x1050, 1920x1080) as binary blobs, but the kernel source tree does
+not contain code to create these data. In order to elucidate the origin
+of the built-in binary EDID blobs and to facilitate the creation of
+individual data for a specific misbehaving monitor, commented sources
+and a Makefile environment are given here.
+
+To create binary EDID and C source code files from the existing data
+material, simply type "make".
+
+If you want to create your own EDID file, copy the file 1024x768.S,
+replace the settings with your own data and add a new target to the
+Makefile. Please note that the EDID data structure expects the timing
+values in a different way as compared to the standard X11 format.
+
+X11:
+ HTimings:
+ hdisp hsyncstart hsyncend htotal
+ VTimings:
+ vdisp vsyncstart vsyncend vtotal
+
+EDID::
+
+ #define XPIX hdisp
+ #define XBLANK htotal-hdisp
+ #define XOFFSET hsyncstart-hdisp
+ #define XPULSE hsyncend-hsyncstart
+
+ #define YPIX vdisp
+ #define YBLANK vtotal-vdisp
+ #define YOFFSET vsyncstart-vdisp
+ #define YPULSE vsyncend-vsyncstart
--- /dev/null
+================
+EISA bus support
+================
+
+:Author: Marc Zyngier <maz@wild-wind.fr.eu.org>
+
+This document groups random notes about porting EISA drivers to the
+new EISA/sysfs API.
+
+Starting from version 2.5.59, the EISA bus is almost given the same
+status as other much more mainstream busses such as PCI or USB. This
+has been possible through sysfs, which defines a nice enough set of
+abstractions to manage busses, devices and drivers.
+
+Although the new API is quite simple to use, converting existing
+drivers to the new infrastructure is not an easy task (mostly because
+detection code is generally also used to probe ISA cards). Moreover,
+most EISA drivers are among the oldest Linux drivers so, as you can
+imagine, some dust has settled here over the years.
+
+The EISA infrastructure is made up of three parts:
+
+ - The bus code implements most of the generic code. It is shared
+ among all the architectures that the EISA code runs on. It
+ implements bus probing (detecting EISA cards available on the bus),
+ allocates I/O resources, allows fancy naming through sysfs, and
+ offers interfaces for driver to register.
+
+ - The bus root driver implements the glue between the bus hardware
+ and the generic bus code. It is responsible for discovering the
+ device implementing the bus, and setting it up to be latter probed
+ by the bus code. This can go from something as simple as reserving
+ an I/O region on x86, to the rather more complex, like the hppa
+ EISA code. This is the part to implement in order to have EISA
+ running on an "new" platform.
+
+ - The driver offers the bus a list of devices that it manages, and
+ implements the necessary callbacks to probe and release devices
+ whenever told to.
+
+Every function/structure below lives in <linux/eisa.h>, which depends
+heavily on <linux/device.h>.
+
+Bus root driver
+===============
+
+::
+
+ int eisa_root_register (struct eisa_root_device *root);
+
+The eisa_root_register function is used to declare a device as the
+root of an EISA bus. The eisa_root_device structure holds a reference
+to this device, as well as some parameters for probing purposes::
+
+ struct eisa_root_device {
+ struct device *dev; /* Pointer to bridge device */
+ struct resource *res;
+ unsigned long bus_base_addr;
+ int slots; /* Max slot number */
+ int force_probe; /* Probe even when no slot 0 */
+ u64 dma_mask; /* from bridge device */
+ int bus_nr; /* Set by eisa_root_register */
+ struct resource eisa_root_res; /* ditto */
+ };
+
+============= ======================================================
+node used for eisa_root_register internal purpose
+dev pointer to the root device
+res root device I/O resource
+bus_base_addr slot 0 address on this bus
+slots max slot number to probe
+force_probe Probe even when slot 0 is empty (no EISA mainboard)
+dma_mask Default DMA mask. Usually the bridge device dma_mask.
+bus_nr unique bus id, set by eisa_root_register
+============= ======================================================
+
+Driver
+======
+
+::
+
+ int eisa_driver_register (struct eisa_driver *edrv);
+ void eisa_driver_unregister (struct eisa_driver *edrv);
+
+Clear enough ?
+
+::
+
+ struct eisa_device_id {
+ char sig[EISA_SIG_LEN];
+ unsigned long driver_data;
+ };
+
+ struct eisa_driver {
+ const struct eisa_device_id *id_table;
+ struct device_driver driver;
+ };
+
+=============== ====================================================
+id_table an array of NULL terminated EISA id strings,
+ followed by an empty string. Each string can
+ optionally be paired with a driver-dependent value
+ (driver_data).
+
+driver a generic driver, such as described in
+ Documentation/driver-api/driver-model/driver.rst. Only .name,
+ .probe and .remove members are mandatory.
+=============== ====================================================
+
+An example is the 3c59x driver::
+
+ static struct eisa_device_id vortex_eisa_ids[] = {
+ { "TCM5920", EISA_3C592_OFFSET },
+ { "TCM5970", EISA_3C597_OFFSET },
+ { "" }
+ };
+
+ static struct eisa_driver vortex_eisa_driver = {
+ .id_table = vortex_eisa_ids,
+ .driver = {
+ .name = "3c59x",
+ .probe = vortex_eisa_probe,
+ .remove = vortex_eisa_remove
+ }
+ };
+
+Device
+======
+
+The sysfs framework calls .probe and .remove functions upon device
+discovery and removal (note that the .remove function is only called
+when driver is built as a module).
+
+Both functions are passed a pointer to a 'struct device', which is
+encapsulated in a 'struct eisa_device' described as follows::
+
+ struct eisa_device {
+ struct eisa_device_id id;
+ int slot;
+ int state;
+ unsigned long base_addr;
+ struct resource res[EISA_MAX_RESOURCES];
+ u64 dma_mask;
+ struct device dev; /* generic device */
+ };
+
+======== ============================================================
+id EISA id, as read from device. id.driver_data is set from the
+ matching driver EISA id.
+slot slot number which the device was detected on
+state set of flags indicating the state of the device. Current
+ flags are EISA_CONFIG_ENABLED and EISA_CONFIG_FORCED.
+res set of four 256 bytes I/O regions allocated to this device
+dma_mask DMA mask set from the parent device.
+dev generic device (see Documentation/driver-api/driver-model/device.rst)
+======== ============================================================
+
+You can get the 'struct eisa_device' from 'struct device' using the
+'to_eisa_device' macro.
+
+Misc stuff
+==========
+
+::
+
+ void eisa_set_drvdata (struct eisa_device *edev, void *data);
+
+Stores data into the device's driver_data area.
+
+::
+
+ void *eisa_get_drvdata (struct eisa_device *edev):
+
+Gets the pointer previously stored into the device's driver_data area.
+
+::
+
+ int eisa_get_region_index (void *addr);
+
+Returns the region number (0 <= x < EISA_MAX_RESOURCES) of a given
+address.
+
+Kernel parameters
+=================
+
+eisa_bus.enable_dev
+ A comma-separated list of slots to be enabled, even if the firmware
+ set the card as disabled. The driver must be able to properly
+ initialize the device in such conditions.
+
+eisa_bus.disable_dev
+ A comma-separated list of slots to be enabled, even if the firmware
+ set the card as enabled. The driver won't be called to handle this
+ device.
+
+virtual_root.force_probe
+ Force the probing code to probe EISA slots even when it cannot find an
+ EISA compliant mainboard (nothing appears on slot 0). Defaults to 0
+ (don't force), and set to 1 (force probing) when either
+ CONFIG_ALPHA_JENSEN or CONFIG_EISA_VLB_PRIMING are set.
+
+Random notes
+============
+
+Converting an EISA driver to the new API mostly involves *deleting*
+code (since probing is now in the core EISA code). Unfortunately, most
+drivers share their probing routine between ISA, and EISA. Special
+care must be taken when ripping out the EISA code, so other busses
+won't suffer from these surgical strikes...
+
+You *must not* expect any EISA device to be detected when returning
+from eisa_driver_register, since the chances are that the bus has not
+yet been probed. In fact, that's what happens most of the time (the
+bus root driver usually kicks in rather late in the boot process).
+Unfortunately, most drivers are doing the probing by themselves, and
+expect to have explored the whole machine when they exit their probe
+routine.
+
+For example, switching your favorite EISA SCSI card to the "hotplug"
+model is "the right thing"(tm).
+
+Thanks
+======
+
+I'd like to thank the following people for their help:
+
+- Xavier Benigni for lending me a wonderful Alpha Jensen,
+- James Bottomley, Jeff Garzik for getting this stuff into the kernel,
+- Andries Brouwer for contributing numerous EISA ids,
+- Catrin Jones for coping with far too many machines at home.
fpga/index
acpi/index
backlight/lp855x-driver.rst
+ bt8xxgpio
+ connector
+ console
+ dcdbas
+ dell_rbu
+ edid
+ eisa
+ isa
+ isapnp
generic-counter
+ lightnvm-pblk
+ men-chameleon-bus
+ ntb
+ nvmem
+ parport-lowlevel
+ pti_intel_mid
+ pwm
+ rfkill
+ sgi-ioc4
+ sm501
+ smsc_ece1099
+ switchtec
+ sync_file
+ vfio-mediated-device
+ vfio
+ xillybus
+ zorro
.. only:: subproject and html
--- /dev/null
+===========
+ISA Drivers
+===========
+
+The following text is adapted from the commit message of the initial
+commit of the ISA bus driver authored by Rene Herman.
+
+During the recent "isa drivers using platform devices" discussion it was
+pointed out that (ALSA) ISA drivers ran into the problem of not having
+the option to fail driver load (device registration rather) upon not
+finding their hardware due to a probe() error not being passed up
+through the driver model. In the course of that, I suggested a separate
+ISA bus might be best; Russell King agreed and suggested this bus could
+use the .match() method for the actual device discovery.
+
+The attached does this. For this old non (generically) discoverable ISA
+hardware only the driver itself can do discovery so as a difference with
+the platform_bus, this isa_bus also distributes match() up to the
+driver.
+
+As another difference: these devices only exist in the driver model due
+to the driver creating them because it might want to drive them, meaning
+that all device creation has been made internal as well.
+
+The usage model this provides is nice, and has been acked from the ALSA
+side by Takashi Iwai and Jaroslav Kysela. The ALSA driver module_init's
+now (for oldisa-only drivers) become::
+
+ static int __init alsa_card_foo_init(void)
+ {
+ return isa_register_driver(&snd_foo_isa_driver, SNDRV_CARDS);
+ }
+
+ static void __exit alsa_card_foo_exit(void)
+ {
+ isa_unregister_driver(&snd_foo_isa_driver);
+ }
+
+Quite like the other bus models therefore. This removes a lot of
+duplicated init code from the ALSA ISA drivers.
+
+The passed in isa_driver struct is the regular driver struct embedding a
+struct device_driver, the normal probe/remove/shutdown/suspend/resume
+callbacks, and as indicated that .match callback.
+
+The "SNDRV_CARDS" you see being passed in is a "unsigned int ndev"
+parameter, indicating how many devices to create and call our methods
+with.
+
+The platform_driver callbacks are called with a platform_device param;
+the isa_driver callbacks are being called with a ``struct device *dev,
+unsigned int id`` pair directly -- with the device creation completely
+internal to the bus it's much cleaner to not leak isa_dev's by passing
+them in at all. The id is the only thing we ever want other then the
+struct device anyways, and it makes for nicer code in the callbacks as
+well.
+
+With this additional .match() callback ISA drivers have all options. If
+ALSA would want to keep the old non-load behaviour, it could stick all
+of the old .probe in .match, which would only keep them registered after
+everything was found to be present and accounted for. If it wanted the
+behaviour of always loading as it inadvertently did for a bit after the
+changeover to platform devices, it could just not provide a .match() and
+do everything in .probe() as before.
+
+If it, as Takashi Iwai already suggested earlier as a way of following
+the model from saner buses more closely, wants to load when a later bind
+could conceivably succeed, it could use .match() for the prerequisites
+(such as checking the user wants the card enabled and that port/irq/dma
+values have been passed in) and .probe() for everything else. This is
+the nicest model.
+
+To the code...
+
+This exports only two functions; isa_{,un}register_driver().
+
+isa_register_driver() register's the struct device_driver, and then
+loops over the passed in ndev creating devices and registering them.
+This causes the bus match method to be called for them, which is::
+
+ int isa_bus_match(struct device *dev, struct device_driver *driver)
+ {
+ struct isa_driver *isa_driver = to_isa_driver(driver);
+
+ if (dev->platform_data == isa_driver) {
+ if (!isa_driver->match ||
+ isa_driver->match(dev, to_isa_dev(dev)->id))
+ return 1;
+ dev->platform_data = NULL;
+ }
+ return 0;
+ }
+
+The first thing this does is check if this device is in fact one of this
+driver's devices by seeing if the device's platform_data pointer is set
+to this driver. Platform devices compare strings, but we don't need to
+do that with everything being internal, so isa_register_driver() abuses
+dev->platform_data as a isa_driver pointer which we can then check here.
+I believe platform_data is available for this, but if rather not, moving
+the isa_driver pointer to the private struct isa_dev is ofcourse fine as
+well.
+
+Then, if the the driver did not provide a .match, it matches. If it did,
+the driver match() method is called to determine a match.
+
+If it did **not** match, dev->platform_data is reset to indicate this to
+isa_register_driver which can then unregister the device again.
+
+If during all this, there's any error, or no devices matched at all
+everything is backed out again and the error, or -ENODEV, is returned.
+
+isa_unregister_driver() just unregisters the matched devices and the
+driver itself.
+
+module_isa_driver is a helper macro for ISA drivers which do not do
+anything special in module init/exit. This eliminates a lot of
+boilerplate code. Each module may only use this macro once, and calling
+it replaces module_init and module_exit.
+
+max_num_isa_dev is a macro to determine the maximum possible number of
+ISA devices which may be registered in the I/O port address space given
+the address extent of the ISA devices.
--- /dev/null
+==========================================================
+ISA Plug & Play support by Jaroslav Kysela <perex@suse.cz>
+==========================================================
+
+Interface /proc/isapnp
+======================
+
+The interface has been removed. See pnp.txt for more details.
+
+Interface /proc/bus/isapnp
+==========================
+
+This directory allows access to ISA PnP cards and logical devices.
+The regular files contain the contents of ISA PnP registers for
+a logical device.
--- /dev/null
+pblk: Physical Block Device Target
+==================================
+
+pblk implements a fully associative, host-based FTL that exposes a traditional
+block I/O interface. Its primary responsibilities are:
+
+ - Map logical addresses onto physical addresses (4KB granularity) in a
+ logical-to-physical (L2P) table.
+ - Maintain the integrity and consistency of the L2P table as well as its
+ recovery from normal tear down and power outage.
+ - Deal with controller- and media-specific constrains.
+ - Handle I/O errors.
+ - Implement garbage collection.
+ - Maintain consistency across the I/O stack during synchronization points.
+
+For more information please refer to:
+
+ http://lightnvm.io
+
+which maintains updated FAQs, manual pages, technical documentation, tools,
+contacts, etc.
--- /dev/null
+=================
+MEN Chameleon Bus
+=================
+
+.. Table of Contents
+ =================
+ 1 Introduction
+ 1.1 Scope of this Document
+ 1.2 Limitations of the current implementation
+ 2 Architecture
+ 2.1 MEN Chameleon Bus
+ 2.2 Carrier Devices
+ 2.3 Parser
+ 3 Resource handling
+ 3.1 Memory Resources
+ 3.2 IRQs
+ 4 Writing an MCB driver
+ 4.1 The driver structure
+ 4.2 Probing and attaching
+ 4.3 Initializing the driver
+
+
+Introduction
+============
+
+This document describes the architecture and implementation of the MEN
+Chameleon Bus (called MCB throughout this document).
+
+Scope of this Document
+----------------------
+
+This document is intended to be a short overview of the current
+implementation and does by no means describe the complete possibilities of MCB
+based devices.
+
+Limitations of the current implementation
+-----------------------------------------
+
+The current implementation is limited to PCI and PCIe based carrier devices
+that only use a single memory resource and share the PCI legacy IRQ. Not
+implemented are:
+
+- Multi-resource MCB devices like the VME Controller or M-Module carrier.
+- MCB devices that need another MCB device, like SRAM for a DMA Controller's
+ buffer descriptors or a video controller's video memory.
+- A per-carrier IRQ domain for carrier devices that have one (or more) IRQs
+ per MCB device like PCIe based carriers with MSI or MSI-X support.
+
+Architecture
+============
+
+MCB is divided into 3 functional blocks:
+
+- The MEN Chameleon Bus itself,
+- drivers for MCB Carrier Devices and
+- the parser for the Chameleon table.
+
+MEN Chameleon Bus
+-----------------
+
+The MEN Chameleon Bus is an artificial bus system that attaches to a so
+called Chameleon FPGA device found on some hardware produced my MEN Mikro
+Elektronik GmbH. These devices are multi-function devices implemented in a
+single FPGA and usually attached via some sort of PCI or PCIe link. Each
+FPGA contains a header section describing the content of the FPGA. The
+header lists the device id, PCI BAR, offset from the beginning of the PCI
+BAR, size in the FPGA, interrupt number and some other properties currently
+not handled by the MCB implementation.
+
+Carrier Devices
+---------------
+
+A carrier device is just an abstraction for the real world physical bus the
+Chameleon FPGA is attached to. Some IP Core drivers may need to interact with
+properties of the carrier device (like querying the IRQ number of a PCI
+device). To provide abstraction from the real hardware bus, an MCB carrier
+device provides callback methods to translate the driver's MCB function calls
+to hardware related function calls. For example a carrier device may
+implement the get_irq() method which can be translated into a hardware bus
+query for the IRQ number the device should use.
+
+Parser
+------
+
+The parser reads the first 512 bytes of a Chameleon device and parses the
+Chameleon table. Currently the parser only supports the Chameleon v2 variant
+of the Chameleon table but can easily be adopted to support an older or
+possible future variant. While parsing the table's entries new MCB devices
+are allocated and their resources are assigned according to the resource
+assignment in the Chameleon table. After resource assignment is finished, the
+MCB devices are registered at the MCB and thus at the driver core of the
+Linux kernel.
+
+Resource handling
+=================
+
+The current implementation assigns exactly one memory and one IRQ resource
+per MCB device. But this is likely going to change in the future.
+
+Memory Resources
+----------------
+
+Each MCB device has exactly one memory resource, which can be requested from
+the MCB bus. This memory resource is the physical address of the MCB device
+inside the carrier and is intended to be passed to ioremap() and friends. It
+is already requested from the kernel by calling request_mem_region().
+
+IRQs
+----
+
+Each MCB device has exactly one IRQ resource, which can be requested from the
+MCB bus. If a carrier device driver implements the ->get_irq() callback
+method, the IRQ number assigned by the carrier device will be returned,
+otherwise the IRQ number inside the Chameleon table will be returned. This
+number is suitable to be passed to request_irq().
+
+Writing an MCB driver
+=====================
+
+The driver structure
+--------------------
+
+Each MCB driver has a structure to identify the device driver as well as
+device ids which identify the IP Core inside the FPGA. The driver structure
+also contains callback methods which get executed on driver probe and
+removal from the system::
+
+ static const struct mcb_device_id foo_ids[] = {
+ { .device = 0x123 },
+ { }
+ };
+ MODULE_DEVICE_TABLE(mcb, foo_ids);
+
+ static struct mcb_driver foo_driver = {
+ driver = {
+ .name = "foo-bar",
+ .owner = THIS_MODULE,
+ },
+ .probe = foo_probe,
+ .remove = foo_remove,
+ .id_table = foo_ids,
+ };
+
+Probing and attaching
+---------------------
+
+When a driver is loaded and the MCB devices it services are found, the MCB
+core will call the driver's probe callback method. When the driver is removed
+from the system, the MCB core will call the driver's remove callback method::
+
+ static init foo_probe(struct mcb_device *mdev, const struct mcb_device_id *id);
+ static void foo_remove(struct mcb_device *mdev);
+
+Initializing the driver
+-----------------------
+
+When the kernel is booted or your foo driver module is inserted, you have to
+perform driver initialization. Usually it is enough to register your driver
+module at the MCB core::
+
+ static int __init foo_init(void)
+ {
+ return mcb_register_driver(&foo_driver);
+ }
+ module_init(foo_init);
+
+ static void __exit foo_exit(void)
+ {
+ mcb_unregister_driver(&foo_driver);
+ }
+ module_exit(foo_exit);
+
+The module_mcb_driver() macro can be used to reduce the above code::
+
+ module_mcb_driver(foo_driver);
--- /dev/null
+===========
+NTB Drivers
+===========
+
+NTB (Non-Transparent Bridge) is a type of PCI-Express bridge chip that connects
+the separate memory systems of two or more computers to the same PCI-Express
+fabric. Existing NTB hardware supports a common feature set: doorbell
+registers and memory translation windows, as well as non common features like
+scratchpad and message registers. Scratchpad registers are read-and-writable
+registers that are accessible from either side of the device, so that peers can
+exchange a small amount of information at a fixed address. Message registers can
+be utilized for the same purpose. Additionally they are provided with with
+special status bits to make sure the information isn't rewritten by another
+peer. Doorbell registers provide a way for peers to send interrupt events.
+Memory windows allow translated read and write access to the peer memory.
+
+NTB Core Driver (ntb)
+=====================
+
+The NTB core driver defines an api wrapping the common feature set, and allows
+clients interested in NTB features to discover NTB the devices supported by
+hardware drivers. The term "client" is used here to mean an upper layer
+component making use of the NTB api. The term "driver," or "hardware driver,"
+is used here to mean a driver for a specific vendor and model of NTB hardware.
+
+NTB Client Drivers
+==================
+
+NTB client drivers should register with the NTB core driver. After
+registering, the client probe and remove functions will be called appropriately
+as ntb hardware, or hardware drivers, are inserted and removed. The
+registration uses the Linux Device framework, so it should feel familiar to
+anyone who has written a pci driver.
+
+NTB Typical client driver implementation
+----------------------------------------
+
+Primary purpose of NTB is to share some peace of memory between at least two
+systems. So the NTB device features like Scratchpad/Message registers are
+mainly used to perform the proper memory window initialization. Typically
+there are two types of memory window interfaces supported by the NTB API:
+inbound translation configured on the local ntb port and outbound translation
+configured by the peer, on the peer ntb port. The first type is
+depicted on the next figure::
+
+ Inbound translation:
+
+ Memory: Local NTB Port: Peer NTB Port: Peer MMIO:
+ ____________
+ | dma-mapped |-ntb_mw_set_trans(addr) |
+ | memory | _v____________ | ______________
+ | (addr) |<======| MW xlat addr |<====| MW base addr |<== memory-mapped IO
+ |------------| |--------------| | |--------------|
+
+So typical scenario of the first type memory window initialization looks:
+1) allocate a memory region, 2) put translated address to NTB config,
+3) somehow notify a peer device of performed initialization, 4) peer device
+maps corresponding outbound memory window so to have access to the shared
+memory region.
+
+The second type of interface, that implies the shared windows being
+initialized by a peer device, is depicted on the figure::
+
+ Outbound translation:
+
+ Memory: Local NTB Port: Peer NTB Port: Peer MMIO:
+ ____________ ______________
+ | dma-mapped | | | MW base addr |<== memory-mapped IO
+ | memory | | |--------------|
+ | (addr) |<===================| MW xlat addr |<-ntb_peer_mw_set_trans(addr)
+ |------------| | |--------------|
+
+Typical scenario of the second type interface initialization would be:
+1) allocate a memory region, 2) somehow deliver a translated address to a peer
+device, 3) peer puts the translated address to NTB config, 4) peer device maps
+outbound memory window so to have access to the shared memory region.
+
+As one can see the described scenarios can be combined in one portable
+algorithm.
+
+ Local device:
+ 1) Allocate memory for a shared window
+ 2) Initialize memory window by translated address of the allocated region
+ (it may fail if local memory window initialization is unsupported)
+ 3) Send the translated address and memory window index to a peer device
+
+ Peer device:
+ 1) Initialize memory window with retrieved address of the allocated
+ by another device memory region (it may fail if peer memory window
+ initialization is unsupported)
+ 2) Map outbound memory window
+
+In accordance with this scenario, the NTB Memory Window API can be used as
+follows:
+
+ Local device:
+ 1) ntb_mw_count(pidx) - retrieve number of memory ranges, which can
+ be allocated for memory windows between local device and peer device
+ of port with specified index.
+ 2) ntb_get_align(pidx, midx) - retrieve parameters restricting the
+ shared memory region alignment and size. Then memory can be properly
+ allocated.
+ 3) Allocate physically contiguous memory region in compliance with
+ restrictions retrieved in 2).
+ 4) ntb_mw_set_trans(pidx, midx) - try to set translation address of
+ the memory window with specified index for the defined peer device
+ (it may fail if local translated address setting is not supported)
+ 5) Send translated base address (usually together with memory window
+ number) to the peer device using, for instance, scratchpad or message
+ registers.
+
+ Peer device:
+ 1) ntb_peer_mw_set_trans(pidx, midx) - try to set received from other
+ device (related to pidx) translated address for specified memory
+ window. It may fail if retrieved address, for instance, exceeds
+ maximum possible address or isn't properly aligned.
+ 2) ntb_peer_mw_get_addr(widx) - retrieve MMIO address to map the memory
+ window so to have an access to the shared memory.
+
+Also it is worth to note, that method ntb_mw_count(pidx) should return the
+same value as ntb_peer_mw_count() on the peer with port index - pidx.
+
+NTB Transport Client (ntb\_transport) and NTB Netdev (ntb\_netdev)
+------------------------------------------------------------------
+
+The primary client for NTB is the Transport client, used in tandem with NTB
+Netdev. These drivers function together to create a logical link to the peer,
+across the ntb, to exchange packets of network data. The Transport client
+establishes a logical link to the peer, and creates queue pairs to exchange
+messages and data. The NTB Netdev then creates an ethernet device using a
+Transport queue pair. Network data is copied between socket buffers and the
+Transport queue pair buffer. The Transport client may be used for other things
+besides Netdev, however no other applications have yet been written.
+
+NTB Ping Pong Test Client (ntb\_pingpong)
+-----------------------------------------
+
+The Ping Pong test client serves as a demonstration to exercise the doorbell
+and scratchpad registers of NTB hardware, and as an example simple NTB client.
+Ping Pong enables the link when started, waits for the NTB link to come up, and
+then proceeds to read and write the doorbell scratchpad registers of the NTB.
+The peers interrupt each other using a bit mask of doorbell bits, which is
+shifted by one in each round, to test the behavior of multiple doorbell bits
+and interrupt vectors. The Ping Pong driver also reads the first local
+scratchpad, and writes the value plus one to the first peer scratchpad, each
+round before writing the peer doorbell register.
+
+Module Parameters:
+
+* unsafe - Some hardware has known issues with scratchpad and doorbell
+ registers. By default, Ping Pong will not attempt to exercise such
+ hardware. You may override this behavior at your own risk by setting
+ unsafe=1.
+* delay\_ms - Specify the delay between receiving a doorbell
+ interrupt event and setting the peer doorbell register for the next
+ round.
+* init\_db - Specify the doorbell bits to start new series of rounds. A new
+ series begins once all the doorbell bits have been shifted out of
+ range.
+* dyndbg - It is suggested to specify dyndbg=+p when loading this module, and
+ then to observe debugging output on the console.
+
+NTB Tool Test Client (ntb\_tool)
+--------------------------------
+
+The Tool test client serves for debugging, primarily, ntb hardware and drivers.
+The Tool provides access through debugfs for reading, setting, and clearing the
+NTB doorbell, and reading and writing scratchpads.
+
+The Tool does not currently have any module parameters.
+
+Debugfs Files:
+
+* *debugfs*/ntb\_tool/*hw*/
+ A directory in debugfs will be created for each
+ NTB device probed by the tool. This directory is shortened to *hw*
+ below.
+* *hw*/db
+ This file is used to read, set, and clear the local doorbell. Not
+ all operations may be supported by all hardware. To read the doorbell,
+ read the file. To set the doorbell, write `s` followed by the bits to
+ set (eg: `echo 's 0x0101' > db`). To clear the doorbell, write `c`
+ followed by the bits to clear.
+* *hw*/mask
+ This file is used to read, set, and clear the local doorbell mask.
+ See *db* for details.
+* *hw*/peer\_db
+ This file is used to read, set, and clear the peer doorbell.
+ See *db* for details.
+* *hw*/peer\_mask
+ This file is used to read, set, and clear the peer doorbell
+ mask. See *db* for details.
+* *hw*/spad
+ This file is used to read and write local scratchpads. To read
+ the values of all scratchpads, read the file. To write values, write a
+ series of pairs of scratchpad number and value
+ (eg: `echo '4 0x123 7 0xabc' > spad`
+ # to set scratchpads `4` and `7` to `0x123` and `0xabc`, respectively).
+* *hw*/peer\_spad
+ This file is used to read and write peer scratchpads. See
+ *spad* for details.
+
+NTB Hardware Drivers
+====================
+
+NTB hardware drivers should register devices with the NTB core driver. After
+registering, clients probe and remove functions will be called.
+
+NTB Intel Hardware Driver (ntb\_hw\_intel)
+------------------------------------------
+
+The Intel hardware driver supports NTB on Xeon and Atom CPUs.
+
+Module Parameters:
+
+* b2b\_mw\_idx
+ If the peer ntb is to be accessed via a memory window, then use
+ this memory window to access the peer ntb. A value of zero or positive
+ starts from the first mw idx, and a negative value starts from the last
+ mw idx. Both sides MUST set the same value here! The default value is
+ `-1`.
+* b2b\_mw\_share
+ If the peer ntb is to be accessed via a memory window, and if
+ the memory window is large enough, still allow the client to use the
+ second half of the memory window for address translation to the peer.
+* xeon\_b2b\_usd\_bar2\_addr64
+ If using B2B topology on Xeon hardware, use
+ this 64 bit address on the bus between the NTB devices for the window
+ at BAR2, on the upstream side of the link.
+* xeon\_b2b\_usd\_bar4\_addr64 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_usd\_bar4\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_usd\_bar5\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_dsd\_bar2\_addr64 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_dsd\_bar4\_addr64 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_dsd\_bar4\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_dsd\_bar5\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
--- /dev/null
+.. SPDX-License-Identifier: GPL-2.0
+
+===============
+NVMEM Subsystem
+===============
+
+ Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+
+This document explains the NVMEM Framework along with the APIs provided,
+and how to use it.
+
+1. Introduction
+===============
+*NVMEM* is the abbreviation for Non Volatile Memory layer. It is used to
+retrieve configuration of SOC or Device specific data from non volatile
+memories like eeprom, efuses and so on.
+
+Before this framework existed, NVMEM drivers like eeprom were stored in
+drivers/misc, where they all had to duplicate pretty much the same code to
+register a sysfs file, allow in-kernel users to access the content of the
+devices they were driving, etc.
+
+This was also a problem as far as other in-kernel users were involved, since
+the solutions used were pretty much different from one driver to another, there
+was a rather big abstraction leak.
+
+This framework aims at solve these problems. It also introduces DT
+representation for consumer devices to go get the data they require (MAC
+Addresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs. This
+framework is based on regmap, so that most of the abstraction available in
+regmap can be reused, across multiple types of buses.
+
+NVMEM Providers
++++++++++++++++
+
+NVMEM provider refers to an entity that implements methods to initialize, read
+and write the non-volatile memory.
+
+2. Registering/Unregistering the NVMEM provider
+===============================================
+
+A NVMEM provider can register with NVMEM core by supplying relevant
+nvmem configuration to nvmem_register(), on success core would return a valid
+nvmem_device pointer.
+
+nvmem_unregister(nvmem) is used to unregister a previously registered provider.
+
+For example, a simple qfprom case::
+
+ static struct nvmem_config econfig = {
+ .name = "qfprom",
+ .owner = THIS_MODULE,
+ };
+
+ static int qfprom_probe(struct platform_device *pdev)
+ {
+ ...
+ econfig.dev = &pdev->dev;
+ nvmem = nvmem_register(&econfig);
+ ...
+ }
+
+It is mandatory that the NVMEM provider has a regmap associated with its
+struct device. Failure to do would return error code from nvmem_register().
+
+Users of board files can define and register nvmem cells using the
+nvmem_cell_table struct::
+
+ static struct nvmem_cell_info foo_nvmem_cells[] = {
+ {
+ .name = "macaddr",
+ .offset = 0x7f00,
+ .bytes = ETH_ALEN,
+ }
+ };
+
+ static struct nvmem_cell_table foo_nvmem_cell_table = {
+ .nvmem_name = "i2c-eeprom",
+ .cells = foo_nvmem_cells,
+ .ncells = ARRAY_SIZE(foo_nvmem_cells),
+ };
+
+ nvmem_add_cell_table(&foo_nvmem_cell_table);
+
+Additionally it is possible to create nvmem cell lookup entries and register
+them with the nvmem framework from machine code as shown in the example below::
+
+ static struct nvmem_cell_lookup foo_nvmem_lookup = {
+ .nvmem_name = "i2c-eeprom",
+ .cell_name = "macaddr",
+ .dev_id = "foo_mac.0",
+ .con_id = "mac-address",
+ };
+
+ nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
+
+NVMEM Consumers
++++++++++++++++
+
+NVMEM consumers are the entities which make use of the NVMEM provider to
+read from and to NVMEM.
+
+3. NVMEM cell based consumer APIs
+=================================
+
+NVMEM cells are the data entries/fields in the NVMEM.
+The NVMEM framework provides 3 APIs to read/write NVMEM cells::
+
+ struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);
+ struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);
+
+ void nvmem_cell_put(struct nvmem_cell *cell);
+ void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
+
+ void *nvmem_cell_read(struct nvmem_cell *cell, ssize_t *len);
+ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, ssize_t len);
+
+`*nvmem_cell_get()` apis will get a reference to nvmem cell for a given id,
+and nvmem_cell_read/write() can then read or write to the cell.
+Once the usage of the cell is finished the consumer should call
+`*nvmem_cell_put()` to free all the allocation memory for the cell.
+
+4. Direct NVMEM device based consumer APIs
+==========================================
+
+In some instances it is necessary to directly read/write the NVMEM.
+To facilitate such consumers NVMEM framework provides below apis::
+
+ struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
+ struct nvmem_device *devm_nvmem_device_get(struct device *dev,
+ const char *name);
+ void nvmem_device_put(struct nvmem_device *nvmem);
+ int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
+ size_t bytes, void *buf);
+ int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
+ size_t bytes, void *buf);
+ int nvmem_device_cell_read(struct nvmem_device *nvmem,
+ struct nvmem_cell_info *info, void *buf);
+ int nvmem_device_cell_write(struct nvmem_device *nvmem,
+ struct nvmem_cell_info *info, void *buf);
+
+Before the consumers can read/write NVMEM directly, it should get hold
+of nvmem_controller from one of the `*nvmem_device_get()` api.
+
+The difference between these apis and cell based apis is that these apis always
+take nvmem_device as parameter.
+
+5. Releasing a reference to the NVMEM
+=====================================
+
+When a consumer no longer needs the NVMEM, it has to release the reference
+to the NVMEM it has obtained using the APIs mentioned in the above section.
+The NVMEM framework provides 2 APIs to release a reference to the NVMEM::
+
+ void nvmem_cell_put(struct nvmem_cell *cell);
+ void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
+ void nvmem_device_put(struct nvmem_device *nvmem);
+ void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem);
+
+Both these APIs are used to release a reference to the NVMEM and
+devm_nvmem_cell_put and devm_nvmem_device_put destroys the devres associated
+with this NVMEM.
+
+Userspace
++++++++++
+
+6. Userspace binary interface
+==============================
+
+Userspace can read/write the raw NVMEM file located at::
+
+ /sys/bus/nvmem/devices/*/nvmem
+
+ex::
+
+ hexdump /sys/bus/nvmem/devices/qfprom0/nvmem
+
+ 0000000 0000 0000 0000 0000 0000 0000 0000 0000
+ *
+ 00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00
+ 0000000 0000 0000 0000 0000 0000 0000 0000 0000
+ ...
+ *
+ 0001000
+
+7. DeviceTree Binding
+=====================
+
+See Documentation/devicetree/bindings/nvmem/nvmem.txt
--- /dev/null
+===============================
+PARPORT interface documentation
+===============================
+
+:Time-stamp: <2000-02-24 13:30:20 twaugh>
+
+Described here are the following functions:
+
+Global functions::
+ parport_register_driver
+ parport_unregister_driver
+ parport_enumerate
+ parport_register_device
+ parport_unregister_device
+ parport_claim
+ parport_claim_or_block
+ parport_release
+ parport_yield
+ parport_yield_blocking
+ parport_wait_peripheral
+ parport_poll_peripheral
+ parport_wait_event
+ parport_negotiate
+ parport_read
+ parport_write
+ parport_open
+ parport_close
+ parport_device_id
+ parport_device_coords
+ parport_find_class
+ parport_find_device
+ parport_set_timeout
+
+Port functions (can be overridden by low-level drivers):
+
+ SPP::
+ port->ops->read_data
+ port->ops->write_data
+ port->ops->read_status
+ port->ops->read_control
+ port->ops->write_control
+ port->ops->frob_control
+ port->ops->enable_irq
+ port->ops->disable_irq
+ port->ops->data_forward
+ port->ops->data_reverse
+
+ EPP::
+ port->ops->epp_write_data
+ port->ops->epp_read_data
+ port->ops->epp_write_addr
+ port->ops->epp_read_addr
+
+ ECP::
+ port->ops->ecp_write_data
+ port->ops->ecp_read_data
+ port->ops->ecp_write_addr
+
+ Other::
+ port->ops->nibble_read_data
+ port->ops->byte_read_data
+ port->ops->compat_write_data
+
+The parport subsystem comprises ``parport`` (the core port-sharing
+code), and a variety of low-level drivers that actually do the port
+accesses. Each low-level driver handles a particular style of port
+(PC, Amiga, and so on).
+
+The parport interface to the device driver author can be broken down
+into global functions and port functions.
+
+The global functions are mostly for communicating between the device
+driver and the parport subsystem: acquiring a list of available ports,
+claiming a port for exclusive use, and so on. They also include
+``generic`` functions for doing standard things that will work on any
+IEEE 1284-capable architecture.
+
+The port functions are provided by the low-level drivers, although the
+core parport module provides generic ``defaults`` for some routines.
+The port functions can be split into three groups: SPP, EPP, and ECP.
+
+SPP (Standard Parallel Port) functions modify so-called ``SPP``
+registers: data, status, and control. The hardware may not actually
+have registers exactly like that, but the PC does and this interface is
+modelled after common PC implementations. Other low-level drivers may
+be able to emulate most of the functionality.
+
+EPP (Enhanced Parallel Port) functions are provided for reading and
+writing in IEEE 1284 EPP mode, and ECP (Extended Capabilities Port)
+functions are used for IEEE 1284 ECP mode. (What about BECP? Does
+anyone care?)
+
+Hardware assistance for EPP and/or ECP transfers may or may not be
+available, and if it is available it may or may not be used. If
+hardware is not used, the transfer will be software-driven. In order
+to cope with peripherals that only tenuously support IEEE 1284, a
+low-level driver specific function is provided, for altering 'fudge
+factors'.
+\f
+Global functions
+================
+
+parport_register_driver - register a device driver with parport
+---------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_driver {
+ const char *name;
+ void (*attach) (struct parport *);
+ void (*detach) (struct parport *);
+ struct parport_driver *next;
+ };
+ int parport_register_driver (struct parport_driver *driver);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+In order to be notified about parallel ports when they are detected,
+parport_register_driver should be called. Your driver will
+immediately be notified of all ports that have already been detected,
+and of each new port as low-level drivers are loaded.
+
+A ``struct parport_driver`` contains the textual name of your driver,
+a pointer to a function to handle new ports, and a pointer to a
+function to handle ports going away due to a low-level driver
+unloading. Ports will only be detached if they are not being used
+(i.e. there are no devices registered on them).
+
+The visible parts of the ``struct parport *`` argument given to
+attach/detach are::
+
+ struct parport
+ {
+ struct parport *next; /* next parport in list */
+ const char *name; /* port's name */
+ unsigned int modes; /* bitfield of hardware modes */
+ struct parport_device_info probe_info;
+ /* IEEE1284 info */
+ int number; /* parport index */
+ struct parport_operations *ops;
+ ...
+ };
+
+There are other members of the structure, but they should not be
+touched.
+
+The ``modes`` member summarises the capabilities of the underlying
+hardware. It consists of flags which may be bitwise-ored together:
+
+ ============================= ===============================================
+ PARPORT_MODE_PCSPP IBM PC registers are available,
+ i.e. functions that act on data,
+ control and status registers are
+ probably writing directly to the
+ hardware.
+ PARPORT_MODE_TRISTATE The data drivers may be turned off.
+ This allows the data lines to be used
+ for reverse (peripheral to host)
+ transfers.
+ PARPORT_MODE_COMPAT The hardware can assist with
+ compatibility-mode (printer)
+ transfers, i.e. compat_write_block.
+ PARPORT_MODE_EPP The hardware can assist with EPP
+ transfers.
+ PARPORT_MODE_ECP The hardware can assist with ECP
+ transfers.
+ PARPORT_MODE_DMA The hardware can use DMA, so you might
+ want to pass ISA DMA-able memory
+ (i.e. memory allocated using the
+ GFP_DMA flag with kmalloc) to the
+ low-level driver in order to take
+ advantage of it.
+ ============================= ===============================================
+
+There may be other flags in ``modes`` as well.
+
+The contents of ``modes`` is advisory only. For example, if the
+hardware is capable of DMA, and PARPORT_MODE_DMA is in ``modes``, it
+doesn't necessarily mean that DMA will always be used when possible.
+Similarly, hardware that is capable of assisting ECP transfers won't
+necessarily be used.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+Zero on success, otherwise an error code.
+
+ERRORS
+^^^^^^
+
+None. (Can it fail? Why return int?)
+
+EXAMPLE
+^^^^^^^
+
+::
+
+ static void lp_attach (struct parport *port)
+ {
+ ...
+ private = kmalloc (...);
+ dev[count++] = parport_register_device (...);
+ ...
+ }
+
+ static void lp_detach (struct parport *port)
+ {
+ ...
+ }
+
+ static struct parport_driver lp_driver = {
+ "lp",
+ lp_attach,
+ lp_detach,
+ NULL /* always put NULL here */
+ };
+
+ int lp_init (void)
+ {
+ ...
+ if (parport_register_driver (&lp_driver)) {
+ /* Failed; nothing we can do. */
+ return -EIO;
+ }
+ ...
+ }
+
+
+SEE ALSO
+^^^^^^^^
+
+parport_unregister_driver, parport_register_device, parport_enumerate
+
+
+
+parport_unregister_driver - tell parport to forget about this driver
+--------------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_driver {
+ const char *name;
+ void (*attach) (struct parport *);
+ void (*detach) (struct parport *);
+ struct parport_driver *next;
+ };
+ void parport_unregister_driver (struct parport_driver *driver);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+This tells parport not to notify the device driver of new ports or of
+ports going away. Registered devices belonging to that driver are NOT
+unregistered: parport_unregister_device must be used for each one.
+
+EXAMPLE
+^^^^^^^
+
+::
+
+ void cleanup_module (void)
+ {
+ ...
+ /* Stop notifications. */
+ parport_unregister_driver (&lp_driver);
+
+ /* Unregister devices. */
+ for (i = 0; i < NUM_DEVS; i++)
+ parport_unregister_device (dev[i]);
+ ...
+ }
+
+SEE ALSO
+^^^^^^^^
+
+parport_register_driver, parport_enumerate
+
+
+
+parport_enumerate - retrieve a list of parallel ports (DEPRECATED)
+------------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport *parport_enumerate (void);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Retrieve the first of a list of valid parallel ports for this machine.
+Successive parallel ports can be found using the ``struct parport
+*next`` element of the ``struct parport *`` that is returned. If ``next``
+is NULL, there are no more parallel ports in the list. The number of
+ports in the list will not exceed PARPORT_MAX.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+A ``struct parport *`` describing a valid parallel port for the machine,
+or NULL if there are none.
+
+ERRORS
+^^^^^^
+
+This function can return NULL to indicate that there are no parallel
+ports to use.
+
+EXAMPLE
+^^^^^^^
+
+::
+
+ int detect_device (void)
+ {
+ struct parport *port;
+
+ for (port = parport_enumerate ();
+ port != NULL;
+ port = port->next) {
+ /* Try to detect a device on the port... */
+ ...
+ }
+ }
+
+ ...
+ }
+
+NOTES
+^^^^^
+
+parport_enumerate is deprecated; parport_register_driver should be
+used instead.
+
+SEE ALSO
+^^^^^^^^
+
+parport_register_driver, parport_unregister_driver
+
+
+
+parport_register_device - register to use a port
+------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ typedef int (*preempt_func) (void *handle);
+ typedef void (*wakeup_func) (void *handle);
+ typedef int (*irq_func) (int irq, void *handle, struct pt_regs *);
+
+ struct pardevice *parport_register_device(struct parport *port,
+ const char *name,
+ preempt_func preempt,
+ wakeup_func wakeup,
+ irq_func irq,
+ int flags,
+ void *handle);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Use this function to register your device driver on a parallel port
+(``port``). Once you have done that, you will be able to use
+parport_claim and parport_release in order to use the port.
+
+The (``name``) argument is the name of the device that appears in /proc
+filesystem. The string must be valid for the whole lifetime of the
+device (until parport_unregister_device is called).
+
+This function will register three callbacks into your driver:
+``preempt``, ``wakeup`` and ``irq``. Each of these may be NULL in order to
+indicate that you do not want a callback.
+
+When the ``preempt`` function is called, it is because another driver
+wishes to use the parallel port. The ``preempt`` function should return
+non-zero if the parallel port cannot be released yet -- if zero is
+returned, the port is lost to another driver and the port must be
+re-claimed before use.
+
+The ``wakeup`` function is called once another driver has released the
+port and no other driver has yet claimed it. You can claim the
+parallel port from within the ``wakeup`` function (in which case the
+claim is guaranteed to succeed), or choose not to if you don't need it
+now.
+
+If an interrupt occurs on the parallel port your driver has claimed,
+the ``irq`` function will be called. (Write something about shared
+interrupts here.)
+
+The ``handle`` is a pointer to driver-specific data, and is passed to
+the callback functions.
+
+``flags`` may be a bitwise combination of the following flags:
+
+ ===================== =================================================
+ Flag Meaning
+ ===================== =================================================
+ PARPORT_DEV_EXCL The device cannot share the parallel port at all.
+ Use this only when absolutely necessary.
+ ===================== =================================================
+
+The typedefs are not actually defined -- they are only shown in order
+to make the function prototype more readable.
+
+The visible parts of the returned ``struct pardevice`` are::
+
+ struct pardevice {
+ struct parport *port; /* Associated port */
+ void *private; /* Device driver's 'handle' */
+ ...
+ };
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+A ``struct pardevice *``: a handle to the registered parallel port
+device that can be used for parport_claim, parport_release, etc.
+
+ERRORS
+^^^^^^
+
+A return value of NULL indicates that there was a problem registering
+a device on that port.
+
+EXAMPLE
+^^^^^^^
+
+::
+
+ static int preempt (void *handle)
+ {
+ if (busy_right_now)
+ return 1;
+
+ must_reclaim_port = 1;
+ return 0;
+ }
+
+ static void wakeup (void *handle)
+ {
+ struct toaster *private = handle;
+ struct pardevice *dev = private->dev;
+ if (!dev) return; /* avoid races */
+
+ if (want_port)
+ parport_claim (dev);
+ }
+
+ static int toaster_detect (struct toaster *private, struct parport *port)
+ {
+ private->dev = parport_register_device (port, "toaster", preempt,
+ wakeup, NULL, 0,
+ private);
+ if (!private->dev)
+ /* Couldn't register with parport. */
+ return -EIO;
+
+ must_reclaim_port = 0;
+ busy_right_now = 1;
+ parport_claim_or_block (private->dev);
+ ...
+ /* Don't need the port while the toaster warms up. */
+ busy_right_now = 0;
+ ...
+ busy_right_now = 1;
+ if (must_reclaim_port) {
+ parport_claim_or_block (private->dev);
+ must_reclaim_port = 0;
+ }
+ ...
+ }
+
+SEE ALSO
+^^^^^^^^
+
+parport_unregister_device, parport_claim
+
+
+\f
+parport_unregister_device - finish using a port
+-----------------------------------------------
+
+SYNPOPSIS
+
+::
+
+ #include <linux/parport.h>
+
+ void parport_unregister_device (struct pardevice *dev);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+This function is the opposite of parport_register_device. After using
+parport_unregister_device, ``dev`` is no longer a valid device handle.
+
+You should not unregister a device that is currently claimed, although
+if you do it will be released automatically.
+
+EXAMPLE
+^^^^^^^
+
+::
+
+ ...
+ kfree (dev->private); /* before we lose the pointer */
+ parport_unregister_device (dev);
+ ...
+
+SEE ALSO
+^^^^^^^^
+
+
+parport_unregister_driver
+\f
+parport_claim, parport_claim_or_block - claim the parallel port for a device
+----------------------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ int parport_claim (struct pardevice *dev);
+ int parport_claim_or_block (struct pardevice *dev);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+These functions attempt to gain control of the parallel port on which
+``dev`` is registered. ``parport_claim`` does not block, but
+``parport_claim_or_block`` may do. (Put something here about blocking
+interruptibly or non-interruptibly.)
+
+You should not try to claim a port that you have already claimed.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+A return value of zero indicates that the port was successfully
+claimed, and the caller now has possession of the parallel port.
+
+If ``parport_claim_or_block`` blocks before returning successfully, the
+return value is positive.
+
+ERRORS
+^^^^^^
+
+========== ==========================================================
+ -EAGAIN The port is unavailable at the moment, but another attempt
+ to claim it may succeed.
+========== ==========================================================
+
+SEE ALSO
+^^^^^^^^
+
+
+parport_release
+\f
+parport_release - release the parallel port
+-------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ void parport_release (struct pardevice *dev);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Once a parallel port device has been claimed, it can be released using
+``parport_release``. It cannot fail, but you should not release a
+device that you do not have possession of.
+
+EXAMPLE
+^^^^^^^
+
+::
+
+ static size_t write (struct pardevice *dev, const void *buf,
+ size_t len)
+ {
+ ...
+ written = dev->port->ops->write_ecp_data (dev->port, buf,
+ len);
+ parport_release (dev);
+ ...
+ }
+
+
+SEE ALSO
+^^^^^^^^
+
+change_mode, parport_claim, parport_claim_or_block, parport_yield
+
+
+
+parport_yield, parport_yield_blocking - temporarily release a parallel port
+---------------------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ int parport_yield (struct pardevice *dev)
+ int parport_yield_blocking (struct pardevice *dev);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+When a driver has control of a parallel port, it may allow another
+driver to temporarily ``borrow`` it. ``parport_yield`` does not block;
+``parport_yield_blocking`` may do.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+A return value of zero indicates that the caller still owns the port
+and the call did not block.
+
+A positive return value from ``parport_yield_blocking`` indicates that
+the caller still owns the port and the call blocked.
+
+A return value of -EAGAIN indicates that the caller no longer owns the
+port, and it must be re-claimed before use.
+
+ERRORS
+^^^^^^
+
+========= ==========================================================
+ -EAGAIN Ownership of the parallel port was given away.
+========= ==========================================================
+
+SEE ALSO
+^^^^^^^^
+
+parport_release
+
+
+\f
+parport_wait_peripheral - wait for status lines, up to 35ms
+-----------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ int parport_wait_peripheral (struct parport *port,
+ unsigned char mask,
+ unsigned char val);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Wait for the status lines in mask to match the values in val.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+======== ==========================================================
+ -EINTR a signal is pending
+ 0 the status lines in mask have values in val
+ 1 timed out while waiting (35ms elapsed)
+======== ==========================================================
+
+SEE ALSO
+^^^^^^^^
+
+parport_poll_peripheral
+
+
+\f
+parport_poll_peripheral - wait for status lines, in usec
+--------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ int parport_poll_peripheral (struct parport *port,
+ unsigned char mask,
+ unsigned char val,
+ int usec);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Wait for the status lines in mask to match the values in val.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+======== ==========================================================
+ -EINTR a signal is pending
+ 0 the status lines in mask have values in val
+ 1 timed out while waiting (usec microseconds have elapsed)
+======== ==========================================================
+
+SEE ALSO
+^^^^^^^^
+
+parport_wait_peripheral
+
+
+
+parport_wait_event - wait for an event on a port
+------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ int parport_wait_event (struct parport *port, signed long timeout)
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Wait for an event (e.g. interrupt) on a port. The timeout is in
+jiffies.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+======= ==========================================================
+ 0 success
+ <0 error (exit as soon as possible)
+ >0 timed out
+======= ==========================================================
+
+parport_negotiate - perform IEEE 1284 negotiation
+-------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ int parport_negotiate (struct parport *, int mode);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Perform IEEE 1284 negotiation.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+======= ==========================================================
+ 0 handshake OK; IEEE 1284 peripheral and mode available
+ -1 handshake failed; peripheral not compliant (or none present)
+ 1 handshake OK; IEEE 1284 peripheral present but mode not
+ available
+======= ==========================================================
+
+SEE ALSO
+^^^^^^^^
+
+parport_read, parport_write
+
+
+
+parport_read - read data from device
+------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ ssize_t parport_read (struct parport *, void *buf, size_t len);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Read data from device in current IEEE 1284 transfer mode. This only
+works for modes that support reverse data transfer.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+If negative, an error code; otherwise the number of bytes transferred.
+
+SEE ALSO
+^^^^^^^^
+
+parport_write, parport_negotiate
+
+
+
+parport_write - write data to device
+------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ ssize_t parport_write (struct parport *, const void *buf, size_t len);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Write data to device in current IEEE 1284 transfer mode. This only
+works for modes that support forward data transfer.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+If negative, an error code; otherwise the number of bytes transferred.
+
+SEE ALSO
+^^^^^^^^
+
+parport_read, parport_negotiate
+
+
+\f
+parport_open - register device for particular device number
+-----------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct pardevice *parport_open (int devnum, const char *name,
+ int (*pf) (void *),
+ void (*kf) (void *),
+ void (*irqf) (int, void *,
+ struct pt_regs *),
+ int flags, void *handle);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+This is like parport_register_device but takes a device number instead
+of a pointer to a struct parport.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+See parport_register_device. If no device is associated with devnum,
+NULL is returned.
+
+SEE ALSO
+^^^^^^^^
+
+parport_register_device
+
+
+
+parport_close - unregister device for particular device number
+--------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ void parport_close (struct pardevice *dev);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+This is the equivalent of parport_unregister_device for parport_open.
+
+SEE ALSO
+^^^^^^^^
+
+parport_unregister_device, parport_open
+
+
+
+parport_device_id - obtain IEEE 1284 Device ID
+----------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ ssize_t parport_device_id (int devnum, char *buffer, size_t len);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Obtains the IEEE 1284 Device ID associated with a given device.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+If negative, an error code; otherwise, the number of bytes of buffer
+that contain the device ID. The format of the device ID is as
+follows::
+
+ [length][ID]
+
+The first two bytes indicate the inclusive length of the entire Device
+ID, and are in big-endian order. The ID is a sequence of pairs of the
+form::
+
+ key:value;
+
+NOTES
+^^^^^
+
+Many devices have ill-formed IEEE 1284 Device IDs.
+
+SEE ALSO
+^^^^^^^^
+
+parport_find_class, parport_find_device
+
+
+
+parport_device_coords - convert device number to device coordinates
+-------------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ int parport_device_coords (int devnum, int *parport, int *mux,
+ int *daisy);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Convert between device number (zero-based) and device coordinates
+(port, multiplexor, daisy chain address).
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+Zero on success, in which case the coordinates are (``*parport``, ``*mux``,
+``*daisy``).
+
+SEE ALSO
+^^^^^^^^
+
+parport_open, parport_device_id
+
+
+
+parport_find_class - find a device by its class
+-----------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ typedef enum {
+ PARPORT_CLASS_LEGACY = 0, /* Non-IEEE1284 device */
+ PARPORT_CLASS_PRINTER,
+ PARPORT_CLASS_MODEM,
+ PARPORT_CLASS_NET,
+ PARPORT_CLASS_HDC, /* Hard disk controller */
+ PARPORT_CLASS_PCMCIA,
+ PARPORT_CLASS_MEDIA, /* Multimedia device */
+ PARPORT_CLASS_FDC, /* Floppy disk controller */
+ PARPORT_CLASS_PORTS,
+ PARPORT_CLASS_SCANNER,
+ PARPORT_CLASS_DIGCAM,
+ PARPORT_CLASS_OTHER, /* Anything else */
+ PARPORT_CLASS_UNSPEC, /* No CLS field in ID */
+ PARPORT_CLASS_SCSIADAPTER
+ } parport_device_class;
+
+ int parport_find_class (parport_device_class cls, int from);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Find a device by class. The search starts from device number from+1.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+The device number of the next device in that class, or -1 if no such
+device exists.
+
+NOTES
+^^^^^
+
+Example usage::
+
+ int devnum = -1;
+ while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM, devnum)) != -1) {
+ struct pardevice *dev = parport_open (devnum, ...);
+ ...
+ }
+
+SEE ALSO
+^^^^^^^^
+
+parport_find_device, parport_open, parport_device_id
+
+
+
+parport_find_device - find a device by its class
+------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ int parport_find_device (const char *mfg, const char *mdl, int from);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Find a device by vendor and model. The search starts from device
+number from+1.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+The device number of the next device matching the specifications, or
+-1 if no such device exists.
+
+NOTES
+^^^^^
+
+Example usage::
+
+ int devnum = -1;
+ while ((devnum = parport_find_device ("IOMEGA", "ZIP+", devnum)) != -1) {
+ struct pardevice *dev = parport_open (devnum, ...);
+ ...
+ }
+
+SEE ALSO
+^^^^^^^^
+
+parport_find_class, parport_open, parport_device_id
+
+
+\f
+parport_set_timeout - set the inactivity timeout
+------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ long parport_set_timeout (struct pardevice *dev, long inactivity);
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Set the inactivity timeout, in jiffies, for a registered device. The
+previous timeout is returned.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+The previous timeout, in jiffies.
+
+NOTES
+^^^^^
+
+Some of the port->ops functions for a parport may take time, owing to
+delays at the peripheral. After the peripheral has not responded for
+``inactivity`` jiffies, a timeout will occur and the blocking function
+will return.
+
+A timeout of 0 jiffies is a special case: the function must do as much
+as it can without blocking or leaving the hardware in an unknown
+state. If port operations are performed from within an interrupt
+handler, for instance, a timeout of 0 jiffies should be used.
+
+Once set for a registered device, the timeout will remain at the set
+value until set again.
+
+SEE ALSO
+^^^^^^^^
+
+port->ops->xxx_read/write_yyy
+
+
+
+
+PORT FUNCTIONS
+==============
+
+The functions in the port->ops structure (struct parport_operations)
+are provided by the low-level driver responsible for that port.
+
+port->ops->read_data - read the data register
+---------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ unsigned char (*read_data) (struct parport *port);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+If port->modes contains the PARPORT_MODE_TRISTATE flag and the
+PARPORT_CONTROL_DIRECTION bit in the control register is set, this
+returns the value on the data pins. If port->modes contains the
+PARPORT_MODE_TRISTATE flag and the PARPORT_CONTROL_DIRECTION bit is
+not set, the return value _may_ be the last value written to the data
+register. Otherwise the return value is undefined.
+
+SEE ALSO
+^^^^^^^^
+
+write_data, read_status, write_control
+
+
+\f
+port->ops->write_data - write the data register
+-----------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ void (*write_data) (struct parport *port, unsigned char d);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Writes to the data register. May have side-effects (a STROBE pulse,
+for instance).
+
+SEE ALSO
+^^^^^^^^
+
+read_data, read_status, write_control
+
+
+\f
+port->ops->read_status - read the status register
+-------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ unsigned char (*read_status) (struct parport *port);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Reads from the status register. This is a bitmask:
+
+- PARPORT_STATUS_ERROR (printer fault, "nFault")
+- PARPORT_STATUS_SELECT (on-line, "Select")
+- PARPORT_STATUS_PAPEROUT (no paper, "PError")
+- PARPORT_STATUS_ACK (handshake, "nAck")
+- PARPORT_STATUS_BUSY (busy, "Busy")
+
+There may be other bits set.
+
+SEE ALSO
+^^^^^^^^
+
+read_data, write_data, write_control
+
+
+\f
+port->ops->read_control - read the control register
+---------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ unsigned char (*read_control) (struct parport *port);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Returns the last value written to the control register (either from
+write_control or frob_control). No port access is performed.
+
+SEE ALSO
+^^^^^^^^
+
+read_data, write_data, read_status, write_control
+
+
+\f
+port->ops->write_control - write the control register
+-----------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ void (*write_control) (struct parport *port, unsigned char s);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Writes to the control register. This is a bitmask::
+
+ _______
+ - PARPORT_CONTROL_STROBE (nStrobe)
+ _______
+ - PARPORT_CONTROL_AUTOFD (nAutoFd)
+ _____
+ - PARPORT_CONTROL_INIT (nInit)
+ _________
+ - PARPORT_CONTROL_SELECT (nSelectIn)
+
+SEE ALSO
+^^^^^^^^
+
+read_data, write_data, read_status, frob_control
+
+
+\f
+port->ops->frob_control - write control register bits
+-----------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ unsigned char (*frob_control) (struct parport *port,
+ unsigned char mask,
+ unsigned char val);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+This is equivalent to reading from the control register, masking out
+the bits in mask, exclusive-or'ing with the bits in val, and writing
+the result to the control register.
+
+As some ports don't allow reads from the control port, a software copy
+of its contents is maintained, so frob_control is in fact only one
+port access.
+
+SEE ALSO
+^^^^^^^^
+
+read_data, write_data, read_status, write_control
+
+
+\f
+port->ops->enable_irq - enable interrupt generation
+---------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ void (*enable_irq) (struct parport *port);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+The parallel port hardware is instructed to generate interrupts at
+appropriate moments, although those moments are
+architecture-specific. For the PC architecture, interrupts are
+commonly generated on the rising edge of nAck.
+
+SEE ALSO
+^^^^^^^^
+
+disable_irq
+
+
+\f
+port->ops->disable_irq - disable interrupt generation
+-----------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ void (*disable_irq) (struct parport *port);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+The parallel port hardware is instructed not to generate interrupts.
+The interrupt itself is not masked.
+
+SEE ALSO
+^^^^^^^^
+
+enable_irq
+\f
+
+
+port->ops->data_forward - enable data drivers
+---------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ void (*data_forward) (struct parport *port);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Enables the data line drivers, for 8-bit host-to-peripheral
+communications.
+
+SEE ALSO
+^^^^^^^^
+
+data_reverse
+
+
+\f
+port->ops->data_reverse - tristate the buffer
+---------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ void (*data_reverse) (struct parport *port);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Places the data bus in a high impedance state, if port->modes has the
+PARPORT_MODE_TRISTATE bit set.
+
+SEE ALSO
+^^^^^^^^
+
+data_forward
+
+
+
+port->ops->epp_write_data - write EPP data
+------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*epp_write_data) (struct parport *port, const void *buf,
+ size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Writes data in EPP mode, and returns the number of bytes written.
+
+The ``flags`` parameter may be one or more of the following,
+bitwise-or'ed together:
+
+======================= =================================================
+PARPORT_EPP_FAST Use fast transfers. Some chips provide 16-bit and
+ 32-bit registers. However, if a transfer
+ times out, the return value may be unreliable.
+======================= =================================================
+
+SEE ALSO
+^^^^^^^^
+
+epp_read_data, epp_write_addr, epp_read_addr
+
+
+\f
+port->ops->epp_read_data - read EPP data
+----------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*epp_read_data) (struct parport *port, void *buf,
+ size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Reads data in EPP mode, and returns the number of bytes read.
+
+The ``flags`` parameter may be one or more of the following,
+bitwise-or'ed together:
+
+======================= =================================================
+PARPORT_EPP_FAST Use fast transfers. Some chips provide 16-bit and
+ 32-bit registers. However, if a transfer
+ times out, the return value may be unreliable.
+======================= =================================================
+
+SEE ALSO
+^^^^^^^^
+
+epp_write_data, epp_write_addr, epp_read_addr
+
+
+
+port->ops->epp_write_addr - write EPP address
+---------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*epp_write_addr) (struct parport *port,
+ const void *buf, size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Writes EPP addresses (8 bits each), and returns the number written.
+
+The ``flags`` parameter may be one or more of the following,
+bitwise-or'ed together:
+
+======================= =================================================
+PARPORT_EPP_FAST Use fast transfers. Some chips provide 16-bit and
+ 32-bit registers. However, if a transfer
+ times out, the return value may be unreliable.
+======================= =================================================
+
+(Does PARPORT_EPP_FAST make sense for this function?)
+
+SEE ALSO
+^^^^^^^^
+
+epp_write_data, epp_read_data, epp_read_addr
+
+
+\f
+port->ops->epp_read_addr - read EPP address
+-------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*epp_read_addr) (struct parport *port, void *buf,
+ size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Reads EPP addresses (8 bits each), and returns the number read.
+
+The ``flags`` parameter may be one or more of the following,
+bitwise-or'ed together:
+
+======================= =================================================
+PARPORT_EPP_FAST Use fast transfers. Some chips provide 16-bit and
+ 32-bit registers. However, if a transfer
+ times out, the return value may be unreliable.
+======================= =================================================
+
+(Does PARPORT_EPP_FAST make sense for this function?)
+
+SEE ALSO
+^^^^^^^^
+
+epp_write_data, epp_read_data, epp_write_addr
+
+
+\f
+port->ops->ecp_write_data - write a block of ECP data
+-----------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*ecp_write_data) (struct parport *port,
+ const void *buf, size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Writes a block of ECP data. The ``flags`` parameter is ignored.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+The number of bytes written.
+
+SEE ALSO
+^^^^^^^^
+
+ecp_read_data, ecp_write_addr
+\f
+
+
+port->ops->ecp_read_data - read a block of ECP data
+---------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*ecp_read_data) (struct parport *port,
+ void *buf, size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Reads a block of ECP data. The ``flags`` parameter is ignored.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+The number of bytes read. NB. There may be more unread data in a
+FIFO. Is there a way of stunning the FIFO to prevent this?
+
+SEE ALSO
+^^^^^^^^
+
+ecp_write_block, ecp_write_addr
+
+
+
+port->ops->ecp_write_addr - write a block of ECP addresses
+----------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*ecp_write_addr) (struct parport *port,
+ const void *buf, size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Writes a block of ECP addresses. The ``flags`` parameter is ignored.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+The number of bytes written.
+
+NOTES
+^^^^^
+
+This may use a FIFO, and if so shall not return until the FIFO is empty.
+
+SEE ALSO
+^^^^^^^^
+
+ecp_read_data, ecp_write_data
+
+
+
+port->ops->nibble_read_data - read a block of data in nibble mode
+-----------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*nibble_read_data) (struct parport *port,
+ void *buf, size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Reads a block of data in nibble mode. The ``flags`` parameter is ignored.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+The number of whole bytes read.
+
+SEE ALSO
+^^^^^^^^
+
+byte_read_data, compat_write_data
+
+
+\f
+port->ops->byte_read_data - read a block of data in byte mode
+-------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*byte_read_data) (struct parport *port,
+ void *buf, size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Reads a block of data in byte mode. The ``flags`` parameter is ignored.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+The number of bytes read.
+
+SEE ALSO
+^^^^^^^^
+
+nibble_read_data, compat_write_data
+
+
+\f
+port->ops->compat_write_data - write a block of data in compatibility mode
+--------------------------------------------------------------------------
+
+SYNOPSIS
+^^^^^^^^
+
+::
+
+ #include <linux/parport.h>
+
+ struct parport_operations {
+ ...
+ size_t (*compat_write_data) (struct parport *port,
+ const void *buf, size_t len, int flags);
+ ...
+ };
+
+DESCRIPTION
+^^^^^^^^^^^
+
+Writes a block of data in compatibility mode. The ``flags`` parameter
+is ignored.
+
+RETURN VALUE
+^^^^^^^^^^^^
+
+The number of bytes written.
+
+SEE ALSO
+^^^^^^^^
+
+nibble_read_data, byte_read_data
--- /dev/null
+.. SPDX-License-Identifier: GPL-2.0
+
+=============
+Intel MID PTI
+=============
+
+The Intel MID PTI project is HW implemented in Intel Atom
+system-on-a-chip designs based on the Parallel Trace
+Interface for MIPI P1149.7 cJTAG standard. The kernel solution
+for this platform involves the following files::
+
+ ./include/linux/pti.h
+ ./drivers/.../n_tracesink.h
+ ./drivers/.../n_tracerouter.c
+ ./drivers/.../n_tracesink.c
+ ./drivers/.../pti.c
+
+pti.c is the driver that enables various debugging features
+popular on platforms from certain mobile manufacturers.
+n_tracerouter.c and n_tracesink.c allow extra system information to
+be collected and routed to the pti driver, such as trace
+debugging data from a modem. Although n_tracerouter
+and n_tracesink are a part of the complete PTI solution,
+these two line disciplines can work separately from
+pti.c and route any data stream from one /dev/tty node
+to another /dev/tty node via kernel-space. This provides
+a stable, reliable connection that will not break unless
+the user-space application shuts down (plus avoids
+kernel->user->kernel context switch overheads of routing
+data).
+
+An example debugging usage for this driver system:
+
+ * Hook /dev/ttyPTI0 to syslogd. Opening this port will also start
+ a console device to further capture debugging messages to PTI.
+ * Hook /dev/ttyPTI1 to modem debugging data to write to PTI HW.
+ This is where n_tracerouter and n_tracesink are used.
+ * Hook /dev/pti to a user-level debugging application for writing
+ to PTI HW.
+ * `Use mipi_` Kernel Driver API in other device drivers for
+ debugging to PTI by first requesting a PTI write address via
+ mipi_request_masterchannel(1).
+
+Below is example pseudo-code on how a 'privileged' application
+can hook up n_tracerouter and n_tracesink to any tty on
+a system. 'Privileged' means the application has enough
+privileges to successfully manipulate the ldisc drivers
+but is not just blindly executing as 'root'. Keep in mind
+the use of ioctl(,TIOCSETD,) is not specific to the n_tracerouter
+and n_tracesink line discpline drivers but is a generic
+operation for a program to use a line discpline driver
+on a tty port other than the default n_tty::
+
+ /////////// To hook up n_tracerouter and n_tracesink /////////
+
+ // Note that n_tracerouter depends on n_tracesink.
+ #include <errno.h>
+ #define ONE_TTY "/dev/ttyOne"
+ #define TWO_TTY "/dev/ttyTwo"
+
+ // needed global to hand onto ldisc connection
+ static int g_fd_source = -1;
+ static int g_fd_sink = -1;
+
+ // these two vars used to grab LDISC values from loaded ldisc drivers
+ // in OS. Look at /proc/tty/ldiscs to get the right numbers from
+ // the ldiscs loaded in the system.
+ int source_ldisc_num, sink_ldisc_num = -1;
+ int retval;
+
+ g_fd_source = open(ONE_TTY, O_RDWR); // must be R/W
+ g_fd_sink = open(TWO_TTY, O_RDWR); // must be R/W
+
+ if (g_fd_source <= 0) || (g_fd_sink <= 0) {
+ // doubt you'll want to use these exact error lines of code
+ printf("Error on open(). errno: %d\n",errno);
+ return errno;
+ }
+
+ retval = ioctl(g_fd_sink, TIOCSETD, &sink_ldisc_num);
+ if (retval < 0) {
+ printf("Error on ioctl(). errno: %d\n", errno);
+ return errno;
+ }
+
+ retval = ioctl(g_fd_source, TIOCSETD, &source_ldisc_num);
+ if (retval < 0) {
+ printf("Error on ioctl(). errno: %d\n", errno);
+ return errno;
+ }
+
+ /////////// To disconnect n_tracerouter and n_tracesink ////////
+
+ // First make sure data through the ldiscs has stopped.
+
+ // Second, disconnect ldiscs. This provides a
+ // little cleaner shutdown on tty stack.
+ sink_ldisc_num = 0;
+ source_ldisc_num = 0;
+ ioctl(g_fd_uart, TIOCSETD, &sink_ldisc_num);
+ ioctl(g_fd_gadget, TIOCSETD, &source_ldisc_num);
+
+ // Three, program closes connection, and cleanup:
+ close(g_fd_uart);
+ close(g_fd_gadget);
+ g_fd_uart = g_fd_gadget = NULL;
--- /dev/null
+======================================
+Pulse Width Modulation (PWM) interface
+======================================
+
+This provides an overview about the Linux PWM interface
+
+PWMs are commonly used for controlling LEDs, fans or vibrators in
+cell phones. PWMs with a fixed purpose have no need implementing
+the Linux PWM API (although they could). However, PWMs are often
+found as discrete devices on SoCs which have no fixed purpose. It's
+up to the board designer to connect them to LEDs or fans. To provide
+this kind of flexibility the generic PWM API exists.
+
+Identifying PWMs
+----------------
+
+Users of the legacy PWM API use unique IDs to refer to PWM devices.
+
+Instead of referring to a PWM device via its unique ID, board setup code
+should instead register a static mapping that can be used to match PWM
+consumers to providers, as given in the following example::
+
+ static struct pwm_lookup board_pwm_lookup[] = {
+ PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight", NULL,
+ 50000, PWM_POLARITY_NORMAL),
+ };
+
+ static void __init board_init(void)
+ {
+ ...
+ pwm_add_table(board_pwm_lookup, ARRAY_SIZE(board_pwm_lookup));
+ ...
+ }
+
+Using PWMs
+----------
+
+Legacy users can request a PWM device using pwm_request() and free it
+after usage with pwm_free().
+
+New users should use the pwm_get() function and pass to it the consumer
+device or a consumer name. pwm_put() is used to free the PWM device. Managed
+variants of these functions, devm_pwm_get() and devm_pwm_put(), also exist.
+
+After being requested, a PWM has to be configured using::
+
+ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state);
+
+This API controls both the PWM period/duty_cycle config and the
+enable/disable state.
+
+The pwm_config(), pwm_enable() and pwm_disable() functions are just wrappers
+around pwm_apply_state() and should not be used if the user wants to change
+several parameter at once. For example, if you see pwm_config() and
+pwm_{enable,disable}() calls in the same function, this probably means you
+should switch to pwm_apply_state().
+
+The PWM user API also allows one to query the PWM state with pwm_get_state().
+
+In addition to the PWM state, the PWM API also exposes PWM arguments, which
+are the reference PWM config one should use on this PWM.
+PWM arguments are usually platform-specific and allows the PWM user to only
+care about dutycycle relatively to the full period (like, duty = 50% of the
+period). struct pwm_args contains 2 fields (period and polarity) and should
+be used to set the initial PWM config (usually done in the probe function
+of the PWM user). PWM arguments are retrieved with pwm_get_args().
+
+All consumers should really be reconfiguring the PWM upon resume as
+appropriate. This is the only way to ensure that everything is resumed in
+the proper order.
+
+Using PWMs with the sysfs interface
+-----------------------------------
+
+If CONFIG_SYSFS is enabled in your kernel configuration a simple sysfs
+interface is provided to use the PWMs from userspace. It is exposed at
+/sys/class/pwm/. Each probed PWM controller/chip will be exported as
+pwmchipN, where N is the base of the PWM chip. Inside the directory you
+will find:
+
+ npwm
+ The number of PWM channels this chip supports (read-only).
+
+ export
+ Exports a PWM channel for use with sysfs (write-only).
+
+ unexport
+ Unexports a PWM channel from sysfs (write-only).
+
+The PWM channels are numbered using a per-chip index from 0 to npwm-1.
+
+When a PWM channel is exported a pwmX directory will be created in the
+pwmchipN directory it is associated with, where X is the number of the
+channel that was exported. The following properties will then be available:
+
+ period
+ The total period of the PWM signal (read/write).
+ Value is in nanoseconds and is the sum of the active and inactive
+ time of the PWM.
+
+ duty_cycle
+ The active time of the PWM signal (read/write).
+ Value is in nanoseconds and must be less than the period.
+
+ polarity
+ Changes the polarity of the PWM signal (read/write).
+ Writes to this property only work if the PWM chip supports changing
+ the polarity. The polarity can only be changed if the PWM is not
+ enabled. Value is the string "normal" or "inversed".
+
+ enable
+ Enable/disable the PWM signal (read/write).
+
+ - 0 - disabled
+ - 1 - enabled
+
+Implementing a PWM driver
+-------------------------
+
+Currently there are two ways to implement pwm drivers. Traditionally
+there only has been the barebone API meaning that each driver has
+to implement the pwm_*() functions itself. This means that it's impossible
+to have multiple PWM drivers in the system. For this reason it's mandatory
+for new drivers to use the generic PWM framework.
+
+A new PWM controller/chip can be added using pwmchip_add() and removed
+again with pwmchip_remove(). pwmchip_add() takes a filled in struct
+pwm_chip as argument which provides a description of the PWM chip, the
+number of PWM devices provided by the chip and the chip-specific
+implementation of the supported PWM operations to the framework.
+
+When implementing polarity support in a PWM driver, make sure to respect the
+signal conventions in the PWM framework. By definition, normal polarity
+characterizes a signal starts high for the duration of the duty cycle and
+goes low for the remainder of the period. Conversely, a signal with inversed
+polarity starts low for the duration of the duty cycle and goes high for the
+remainder of the period.
+
+Drivers are encouraged to implement ->apply() instead of the legacy
+->enable(), ->disable() and ->config() methods. Doing that should provide
+atomicity in the PWM config workflow, which is required when the PWM controls
+a critical device (like a regulator).
+
+The implementation of ->get_state() (a method used to retrieve initial PWM
+state) is also encouraged for the same reason: letting the PWM user know
+about the current PWM state would allow him to avoid glitches.
+
+Drivers should not implement any power management. In other words,
+consumers should implement it as described in the "Using PWMs" section.
+
+Locking
+-------
+
+The PWM core list manipulations are protected by a mutex, so pwm_request()
+and pwm_free() may not be called from an atomic context. Currently the
+PWM core does not enforce any locking to pwm_enable(), pwm_disable() and
+pwm_config(), so the calling context is currently driver specific. This
+is an issue derived from the former barebone API and should be fixed soon.
+
+Helpers
+-------
+
+Currently a PWM can only be configured with period_ns and duty_ns. For several
+use cases freq_hz and duty_percent might be better. Instead of calculating
+this in your driver please consider adding appropriate helpers to the framework.
--- /dev/null
+===============================
+rfkill - RF kill switch support
+===============================
+
+
+.. contents::
+ :depth: 2
+
+Introduction
+============
+
+The rfkill subsystem provides a generic interface for disabling any radio
+transmitter in the system. When a transmitter is blocked, it shall not
+radiate any power.
+
+The subsystem also provides the ability to react on button presses and
+disable all transmitters of a certain type (or all). This is intended for
+situations where transmitters need to be turned off, for example on
+aircraft.
+
+The rfkill subsystem has a concept of "hard" and "soft" block, which
+differ little in their meaning (block == transmitters off) but rather in
+whether they can be changed or not:
+
+ - hard block
+ read-only radio block that cannot be overridden by software
+
+ - soft block
+ writable radio block (need not be readable) that is set by
+ the system software.
+
+The rfkill subsystem has two parameters, rfkill.default_state and
+rfkill.master_switch_mode, which are documented in
+admin-guide/kernel-parameters.rst.
+
+
+Implementation details
+======================
+
+The rfkill subsystem is composed of three main components:
+
+ * the rfkill core,
+ * the deprecated rfkill-input module (an input layer handler, being
+ replaced by userspace policy code) and
+ * the rfkill drivers.
+
+The rfkill core provides API for kernel drivers to register their radio
+transmitter with the kernel, methods for turning it on and off, and letting
+the system know about hardware-disabled states that may be implemented on
+the device.
+
+The rfkill core code also notifies userspace of state changes, and provides
+ways for userspace to query the current states. See the "Userspace support"
+section below.
+
+When the device is hard-blocked (either by a call to rfkill_set_hw_state()
+or from query_hw_block), set_block() will be invoked for additional software
+block, but drivers can ignore the method call since they can use the return
+value of the function rfkill_set_hw_state() to sync the software state
+instead of keeping track of calls to set_block(). In fact, drivers should
+use the return value of rfkill_set_hw_state() unless the hardware actually
+keeps track of soft and hard block separately.
+
+
+Kernel API
+==========
+
+Drivers for radio transmitters normally implement an rfkill driver.
+
+Platform drivers might implement input devices if the rfkill button is just
+that, a button. If that button influences the hardware then you need to
+implement an rfkill driver instead. This also applies if the platform provides
+a way to turn on/off the transmitter(s).
+
+For some platforms, it is possible that the hardware state changes during
+suspend/hibernation, in which case it will be necessary to update the rfkill
+core with the current state at resume time.
+
+To create an rfkill driver, driver's Kconfig needs to have::
+
+ depends on RFKILL || !RFKILL
+
+to ensure the driver cannot be built-in when rfkill is modular. The !RFKILL
+case allows the driver to be built when rfkill is not configured, in which
+case all rfkill API can still be used but will be provided by static inlines
+which compile to almost nothing.
+
+Calling rfkill_set_hw_state() when a state change happens is required from
+rfkill drivers that control devices that can be hard-blocked unless they also
+assign the poll_hw_block() callback (then the rfkill core will poll the
+device). Don't do this unless you cannot get the event in any other way.
+
+rfkill provides per-switch LED triggers, which can be used to drive LEDs
+according to the switch state (LED_FULL when blocked, LED_OFF otherwise).
+
+
+Userspace support
+=================
+
+The recommended userspace interface to use is /dev/rfkill, which is a misc
+character device that allows userspace to obtain and set the state of rfkill
+devices and sets of devices. It also notifies userspace about device addition
+and removal. The API is a simple read/write API that is defined in
+linux/rfkill.h, with one ioctl that allows turning off the deprecated input
+handler in the kernel for the transition period.
+
+Except for the one ioctl, communication with the kernel is done via read()
+and write() of instances of 'struct rfkill_event'. In this structure, the
+soft and hard block are properly separated (unlike sysfs, see below) and
+userspace is able to get a consistent snapshot of all rfkill devices in the
+system. Also, it is possible to switch all rfkill drivers (or all drivers of
+a specified type) into a state which also updates the default state for
+hotplugged devices.
+
+After an application opens /dev/rfkill, it can read the current state of all
+devices. Changes can be obtained by either polling the descriptor for
+hotplug or state change events or by listening for uevents emitted by the
+rfkill core framework.
+
+Additionally, each rfkill device is registered in sysfs and emits uevents.
+
+rfkill devices issue uevents (with an action of "change"), with the following
+environment variables set::
+
+ RFKILL_NAME
+ RFKILL_STATE
+ RFKILL_TYPE
+
+The content of these variables corresponds to the "name", "state" and
+"type" sysfs files explained above.
+
+For further details consult Documentation/ABI/stable/sysfs-class-rfkill.
--- /dev/null
+====================================
+SGI IOC4 PCI (multi function) device
+====================================
+
+The SGI IOC4 PCI device is a bit of a strange beast, so some notes on
+it are in order.
+
+First, even though the IOC4 performs multiple functions, such as an
+IDE controller, a serial controller, a PS/2 keyboard/mouse controller,
+and an external interrupt mechanism, it's not implemented as a
+multifunction device. The consequence of this from a software
+standpoint is that all these functions share a single IRQ, and
+they can't all register to own the same PCI device ID. To make
+matters a bit worse, some of the register blocks (and even registers
+themselves) present in IOC4 are mixed-purpose between these several
+functions, meaning that there's no clear "owning" device driver.
+
+The solution is to organize the IOC4 driver into several independent
+drivers, "ioc4", "sgiioc4", and "ioc4_serial". Note that there is no
+PS/2 controller driver as this functionality has never been wired up
+on a shipping IO card.
+
+ioc4
+====
+This is the core (or shim) driver for IOC4. It is responsible for
+initializing the basic functionality of the chip, and allocating
+the PCI resources that are shared between the IOC4 functions.
+
+This driver also provides registration functions that the other
+IOC4 drivers can call to make their presence known. Each driver
+needs to provide a probe and remove function, which are invoked
+by the core driver at appropriate times. The interface of these
+IOC4 function probe and remove operations isn't precisely the same
+as PCI device probe and remove operations, but is logically the
+same operation.
+
+sgiioc4
+=======
+This is the IDE driver for IOC4. Its name isn't very descriptive
+simply for historical reasons (it used to be the only IOC4 driver
+component). There's not much to say about it other than it hooks
+up to the ioc4 driver via the appropriate registration, probe, and
+remove functions.
+
+ioc4_serial
+===========
+This is the serial driver for IOC4. There's not much to say about it
+other than it hooks up to the ioc4 driver via the appropriate registration,
+probe, and remove functions.
--- /dev/null
+.. include:: <isonum.txt>
+
+============
+SM501 Driver
+============
+
+:Copyright: |copy| 2006, 2007 Simtec Electronics
+
+The Silicon Motion SM501 multimedia companion chip is a multifunction device
+which may provide numerous interfaces including USB host controller USB gadget,
+asynchronous serial ports, audio functions, and a dual display video interface.
+The device may be connected by PCI or local bus with varying functions enabled.
+
+Core
+----
+
+The core driver in drivers/mfd provides common services for the
+drivers which manage the specific hardware blocks. These services
+include locking for common registers, clock control and resource
+management.
+
+The core registers drivers for both PCI and generic bus based
+chips via the platform device and driver system.
+
+On detection of a device, the core initialises the chip (which may
+be specified by the platform data) and then exports the selected
+peripheral set as platform devices for the specific drivers.
+
+The core re-uses the platform device system as the platform device
+system provides enough features to support the drivers without the
+need to create a new bus-type and the associated code to go with it.
+
+
+Resources
+---------
+
+Each peripheral has a view of the device which is implicitly narrowed to
+the specific set of resources that peripheral requires in order to
+function correctly.
+
+The centralised memory allocation allows the driver to ensure that the
+maximum possible resource allocation can be made to the video subsystem
+as this is by-far the most resource-sensitive of the on-chip functions.
+
+The primary issue with memory allocation is that of moving the video
+buffers once a display mode is chosen. Indeed when a video mode change
+occurs the memory footprint of the video subsystem changes.
+
+Since video memory is difficult to move without changing the display
+(unless sufficient contiguous memory can be provided for the old and new
+modes simultaneously) the video driver fully utilises the memory area
+given to it by aligning fb0 to the start of the area and fb1 to the end
+of it. Any memory left over in the middle is used for the acceleration
+functions, which are transient and thus their location is less critical
+as it can be moved.
+
+
+Configuration
+-------------
+
+The platform device driver uses a set of platform data to pass
+configurations through to the core and the subsidiary drivers
+so that there can be support for more than one system carrying
+an SM501 built into a single kernel image.
+
+The PCI driver assumes that the PCI card behaves as per the Silicon
+Motion reference design.
+
+There is an errata (AB-5) affecting the selection of the
+of the M1XCLK and M1CLK frequencies. These two clocks
+must be sourced from the same PLL, although they can then
+be divided down individually. If this is not set, then SM501 may
+lock and hang the whole system. The driver will refuse to
+attach if the PLL selection is different.
--- /dev/null
+=================================================
+Msc Keyboard Scan Expansion/GPIO Expansion device
+=================================================
+
+What is smsc-ece1099?
+----------------------
+
+The ECE1099 is a 40-Pin 3.3V Keyboard Scan Expansion
+or GPIO Expansion device. The device supports a keyboard
+scan matrix of 23x8. The device is connected to a Master
+via the SMSC BC-Link interface or via the SMBus.
+Keypad scan Input(KSI) and Keypad Scan Output(KSO) signals
+are multiplexed with GPIOs.
+
+Interrupt generation
+--------------------
+
+Interrupts can be generated by an edge detection on a GPIO
+pin or an edge detection on one of the bus interface pins.
+Interrupts can also be detected on the keyboard scan interface.
+The bus interrupt pin (BC_INT# or SMBUS_INT#) is asserted if
+any bit in one of the Interrupt Status registers is 1 and
+the corresponding Interrupt Mask bit is also 1.
+
+In order for software to determine which device is the source
+of an interrupt, it should first read the Group Interrupt Status Register
+to determine which Status register group is a source for the interrupt.
+Software should read both the Status register and the associated Mask register,
+then AND the two values together. Bits that are 1 in the result of the AND
+are active interrupts. Software clears an interrupt by writing a 1 to the
+corresponding bit in the Status register.
+
+Communication Protocol
+----------------------
+
+- SMbus slave Interface
+ The host processor communicates with the ECE1099 device
+ through a series of read/write registers via the SMBus
+ interface. SMBus is a serial communication protocol between
+ a computer host and its peripheral devices. The SMBus data
+ rate is 10KHz minimum to 400 KHz maximum
+
+- Slave Bus Interface
+ The ECE1099 device SMBus implementation is a subset of the
+ SMBus interface to the host. The device is a slave-only SMBus device.
+ The implementation in the device is a subset of SMBus since it
+ only supports four protocols.
+
+ The Write Byte, Read Byte, Send Byte, and Receive Byte protocols are the
+ only valid SMBus protocols for the device.
+
+- BC-LinkTM Interface
+ The BC-Link is a proprietary bus that allows communication
+ between a Master device and a Companion device. The Master
+ device uses this serial bus to read and write registers
+ located on the Companion device. The bus comprises three signals,
+ BC_CLK, BC_DAT and BC_INT#. The Master device always provides the
+ clock, BC_CLK, and the Companion device is the source for an
+ independent asynchronous interrupt signal, BC_INT#. The ECE1099
+ supports BC-Link speeds up to 24MHz.
--- /dev/null
+========================
+Linux Switchtec Support
+========================
+
+Microsemi's "Switchtec" line of PCI switch devices is already
+supported by the kernel with standard PCI switch drivers. However, the
+Switchtec device advertises a special management endpoint which
+enables some additional functionality. This includes:
+
+* Packet and Byte Counters
+* Firmware Upgrades
+* Event and Error logs
+* Querying port link status
+* Custom user firmware commands
+
+The switchtec kernel module implements this functionality.
+
+
+Interface
+=========
+
+The primary means of communicating with the Switchtec management firmware is
+through the Memory-mapped Remote Procedure Call (MRPC) interface.
+Commands are submitted to the interface with a 4-byte command
+identifier and up to 1KB of command specific data. The firmware will
+respond with a 4-byte return code and up to 1KB of command-specific
+data. The interface only processes a single command at a time.
+
+
+Userspace Interface
+===================
+
+The MRPC interface will be exposed to userspace through a simple char
+device: /dev/switchtec#, one for each management endpoint in the system.
+
+The char device has the following semantics:
+
+* A write must consist of at least 4 bytes and no more than 1028 bytes.
+ The first 4 bytes will be interpreted as the Command ID and the
+ remainder will be used as the input data. A write will send the
+ command to the firmware to begin processing.
+
+* Each write must be followed by exactly one read. Any double write will
+ produce an error and any read that doesn't follow a write will
+ produce an error.
+
+* A read will block until the firmware completes the command and return
+ the 4-byte Command Return Value plus up to 1024 bytes of output
+ data. (The length will be specified by the size parameter of the read
+ call -- reading less than 4 bytes will produce an error.)
+
+* The poll call will also be supported for userspace applications that
+ need to do other things while waiting for the command to complete.
+
+The following IOCTLs are also supported by the device:
+
+* SWITCHTEC_IOCTL_FLASH_INFO - Retrieve firmware length and number
+ of partitions in the device.
+
+* SWITCHTEC_IOCTL_FLASH_PART_INFO - Retrieve address and lengeth for
+ any specified partition in flash.
+
+* SWITCHTEC_IOCTL_EVENT_SUMMARY - Read a structure of bitmaps
+ indicating all uncleared events.
+
+* SWITCHTEC_IOCTL_EVENT_CTL - Get the current count, clear and set flags
+ for any event. This ioctl takes in a switchtec_ioctl_event_ctl struct
+ with the event_id, index and flags set (index being the partition or PFF
+ number for non-global events). It returns whether the event has
+ occurred, the number of times and any event specific data. The flags
+ can be used to clear the count or enable and disable actions to
+ happen when the event occurs.
+ By using the SWITCHTEC_IOCTL_EVENT_FLAG_EN_POLL flag,
+ you can set an event to trigger a poll command to return with
+ POLLPRI. In this way, userspace can wait for events to occur.
+
+* SWITCHTEC_IOCTL_PFF_TO_PORT and SWITCHTEC_IOCTL_PORT_TO_PFF convert
+ between PCI Function Framework number (used by the event system)
+ and Switchtec Logic Port ID and Partition number (which is more
+ user friendly).
+
+
+Non-Transparent Bridge (NTB) Driver
+===================================
+
+An NTB hardware driver is provided for the Switchtec hardware in
+ntb_hw_switchtec. Currently, it only supports switches configured with
+exactly 2 NT partitions and zero or more non-NT partitions. It also requires
+the following configuration settings:
+
+* Both NT partitions must be able to access each other's GAS spaces.
+ Thus, the bits in the GAS Access Vector under Management Settings
+ must be set to support this.
+* Kernel configuration MUST include support for NTB (CONFIG_NTB needs
+ to be set)
+
+NT EP BAR 2 will be dynamically configured as a Direct Window, and
+the configuration file does not need to configure it explicitly.
+
+Please refer to Documentation/driver-api/ntb.rst in Linux source tree for an overall
+understanding of the Linux NTB stack. ntb_hw_switchtec works as an NTB
+Hardware Driver in this stack.
--- /dev/null
+===================
+Sync File API Guide
+===================
+
+:Author: Gustavo Padovan <gustavo at padovan dot org>
+
+This document serves as a guide for device drivers writers on what the
+sync_file API is, and how drivers can support it. Sync file is the carrier of
+the fences(struct dma_fence) that are needed to synchronize between drivers or
+across process boundaries.
+
+The sync_file API is meant to be used to send and receive fence information
+to/from userspace. It enables userspace to do explicit fencing, where instead
+of attaching a fence to the buffer a producer driver (such as a GPU or V4L
+driver) sends the fence related to the buffer to userspace via a sync_file.
+
+The sync_file then can be sent to the consumer (DRM driver for example), that
+will not use the buffer for anything before the fence(s) signals, i.e., the
+driver that issued the fence is not using/processing the buffer anymore, so it
+signals that the buffer is ready to use. And vice-versa for the consumer ->
+producer part of the cycle.
+
+Sync files allows userspace awareness on buffer sharing synchronization between
+drivers.
+
+Sync file was originally added in the Android kernel but current Linux Desktop
+can benefit a lot from it.
+
+in-fences and out-fences
+------------------------
+
+Sync files can go either to or from userspace. When a sync_file is sent from
+the driver to userspace we call the fences it contains 'out-fences'. They are
+related to a buffer that the driver is processing or is going to process, so
+the driver creates an out-fence to be able to notify, through
+dma_fence_signal(), when it has finished using (or processing) that buffer.
+Out-fences are fences that the driver creates.
+
+On the other hand if the driver receives fence(s) through a sync_file from
+userspace we call these fence(s) 'in-fences'. Receiving in-fences means that
+we need to wait for the fence(s) to signal before using any buffer related to
+the in-fences.
+
+Creating Sync Files
+-------------------
+
+When a driver needs to send an out-fence userspace it creates a sync_file.
+
+Interface::
+
+ struct sync_file *sync_file_create(struct dma_fence *fence);
+
+The caller pass the out-fence and gets back the sync_file. That is just the
+first step, next it needs to install an fd on sync_file->file. So it gets an
+fd::
+
+ fd = get_unused_fd_flags(O_CLOEXEC);
+
+and installs it on sync_file->file::
+
+ fd_install(fd, sync_file->file);
+
+The sync_file fd now can be sent to userspace.
+
+If the creation process fail, or the sync_file needs to be released by any
+other reason fput(sync_file->file) should be used.
+
+Receiving Sync Files from Userspace
+-----------------------------------
+
+When userspace needs to send an in-fence to the driver it passes file descriptor
+of the Sync File to the kernel. The kernel can then retrieve the fences
+from it.
+
+Interface::
+
+ struct dma_fence *sync_file_get_fence(int fd);
+
+
+The returned reference is owned by the caller and must be disposed of
+afterwards using dma_fence_put(). In case of error, a NULL is returned instead.
+
+References:
+
+1. struct sync_file in include/linux/sync_file.h
+2. All interfaces mentioned above defined in include/linux/sync_file.h
--- /dev/null
+.. include:: <isonum.txt>
+
+=====================
+VFIO Mediated devices
+=====================
+
+:Copyright: |copy| 2016, NVIDIA CORPORATION. All rights reserved.
+:Author: Neo Jia <cjia@nvidia.com>
+:Author: Kirti Wankhede <kwankhede@nvidia.com>
+
+This program 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.
+
+
+Virtual Function I/O (VFIO) Mediated devices[1]
+===============================================
+
+The number of use cases for virtualizing DMA devices that do not have built-in
+SR_IOV capability is increasing. Previously, to virtualize such devices,
+developers had to create their own management interfaces and APIs, and then
+integrate them with user space software. To simplify integration with user space
+software, we have identified common requirements and a unified management
+interface for such devices.
+
+The VFIO driver framework provides unified APIs for direct device access. It is
+an IOMMU/device-agnostic framework for exposing direct device access to user
+space in a secure, IOMMU-protected environment. This framework is used for
+multiple devices, such as GPUs, network adapters, and compute accelerators. With
+direct device access, virtual machines or user space applications have direct
+access to the physical device. This framework is reused for mediated devices.
+
+The mediated core driver provides a common interface for mediated device
+management that can be used by drivers of different devices. This module
+provides a generic interface to perform these operations:
+
+* Create and destroy a mediated device
+* Add a mediated device to and remove it from a mediated bus driver
+* Add a mediated device to and remove it from an IOMMU group
+
+The mediated core driver also provides an interface to register a bus driver.
+For example, the mediated VFIO mdev driver is designed for mediated devices and
+supports VFIO APIs. The mediated bus driver adds a mediated device to and
+removes it from a VFIO group.
+
+The following high-level block diagram shows the main components and interfaces
+in the VFIO mediated driver framework. The diagram shows NVIDIA, Intel, and IBM
+devices as examples, as these devices are the first devices to use this module::
+
+ +---------------+
+ | |
+ | +-----------+ | mdev_register_driver() +--------------+
+ | | | +<------------------------+ |
+ | | mdev | | | |
+ | | bus | +------------------------>+ vfio_mdev.ko |<-> VFIO user
+ | | driver | | probe()/remove() | | APIs
+ | | | | +--------------+
+ | +-----------+ |
+ | |
+ | MDEV CORE |
+ | MODULE |
+ | mdev.ko |
+ | +-----------+ | mdev_register_device() +--------------+
+ | | | +<------------------------+ |
+ | | | | | nvidia.ko |<-> physical
+ | | | +------------------------>+ | device
+ | | | | callbacks +--------------+
+ | | Physical | |
+ | | device | | mdev_register_device() +--------------+
+ | | interface | |<------------------------+ |
+ | | | | | i915.ko |<-> physical
+ | | | +------------------------>+ | device
+ | | | | callbacks +--------------+
+ | | | |
+ | | | | mdev_register_device() +--------------+
+ | | | +<------------------------+ |
+ | | | | | ccw_device.ko|<-> physical
+ | | | +------------------------>+ | device
+ | | | | callbacks +--------------+
+ | +-----------+ |
+ +---------------+
+
+
+Registration Interfaces
+=======================
+
+The mediated core driver provides the following types of registration
+interfaces:
+
+* Registration interface for a mediated bus driver
+* Physical device driver interface
+
+Registration Interface for a Mediated Bus Driver
+------------------------------------------------
+
+The registration interface for a mediated bus driver provides the following
+structure to represent a mediated device's driver::
+
+ /*
+ * struct mdev_driver [2] - Mediated device's driver
+ * @name: driver name
+ * @probe: called when new device created
+ * @remove: called when device removed
+ * @driver: device driver structure
+ */
+ struct mdev_driver {
+ const char *name;
+ int (*probe) (struct device *dev);
+ void (*remove) (struct device *dev);
+ struct device_driver driver;
+ };
+
+A mediated bus driver for mdev should use this structure in the function calls
+to register and unregister itself with the core driver:
+
+* Register::
+
+ extern int mdev_register_driver(struct mdev_driver *drv,
+ struct module *owner);
+
+* Unregister::
+
+ extern void mdev_unregister_driver(struct mdev_driver *drv);
+
+The mediated bus driver is responsible for adding mediated devices to the VFIO
+group when devices are bound to the driver and removing mediated devices from
+the VFIO when devices are unbound from the driver.
+
+
+Physical Device Driver Interface
+--------------------------------
+
+The physical device driver interface provides the mdev_parent_ops[3] structure
+to define the APIs to manage work in the mediated core driver that is related
+to the physical device.
+
+The structures in the mdev_parent_ops structure are as follows:
+
+* dev_attr_groups: attributes of the parent device
+* mdev_attr_groups: attributes of the mediated device
+* supported_config: attributes to define supported configurations
+
+The functions in the mdev_parent_ops structure are as follows:
+
+* create: allocate basic resources in a driver for a mediated device
+* remove: free resources in a driver when a mediated device is destroyed
+
+(Note that mdev-core provides no implicit serialization of create/remove
+callbacks per mdev parent device, per mdev type, or any other categorization.
+Vendor drivers are expected to be fully asynchronous in this respect or
+provide their own internal resource protection.)
+
+The callbacks in the mdev_parent_ops structure are as follows:
+
+* open: open callback of mediated device
+* close: close callback of mediated device
+* ioctl: ioctl callback of mediated device
+* read : read emulation callback
+* write: write emulation callback
+* mmap: mmap emulation callback
+
+A driver should use the mdev_parent_ops structure in the function call to
+register itself with the mdev core driver::
+
+ extern int mdev_register_device(struct device *dev,
+ const struct mdev_parent_ops *ops);
+
+However, the mdev_parent_ops structure is not required in the function call
+that a driver should use to unregister itself with the mdev core driver::
+
+ extern void mdev_unregister_device(struct device *dev);
+
+
+Mediated Device Management Interface Through sysfs
+==================================================
+
+The management interface through sysfs enables user space software, such as
+libvirt, to query and configure mediated devices in a hardware-agnostic fashion.
+This management interface provides flexibility to the underlying physical
+device's driver to support features such as:
+
+* Mediated device hot plug
+* Multiple mediated devices in a single virtual machine
+* Multiple mediated devices from different physical devices
+
+Links in the mdev_bus Class Directory
+-------------------------------------
+The /sys/class/mdev_bus/ directory contains links to devices that are registered
+with the mdev core driver.
+
+Directories and files under the sysfs for Each Physical Device
+--------------------------------------------------------------
+
+::
+
+ |- [parent physical device]
+ |--- Vendor-specific-attributes [optional]
+ |--- [mdev_supported_types]
+ | |--- [<type-id>]
+ | | |--- create
+ | | |--- name
+ | | |--- available_instances
+ | | |--- device_api
+ | | |--- description
+ | | |--- [devices]
+ | |--- [<type-id>]
+ | | |--- create
+ | | |--- name
+ | | |--- available_instances
+ | | |--- device_api
+ | | |--- description
+ | | |--- [devices]
+ | |--- [<type-id>]
+ | |--- create
+ | |--- name
+ | |--- available_instances
+ | |--- device_api
+ | |--- description
+ | |--- [devices]
+
+* [mdev_supported_types]
+
+ The list of currently supported mediated device types and their details.
+
+ [<type-id>], device_api, and available_instances are mandatory attributes
+ that should be provided by vendor driver.
+
+* [<type-id>]
+
+ The [<type-id>] name is created by adding the device driver string as a prefix
+ to the string provided by the vendor driver. This format of this name is as
+ follows::
+
+ sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name);
+
+ (or using mdev_parent_dev(mdev) to arrive at the parent device outside
+ of the core mdev code)
+
+* device_api
+
+ This attribute should show which device API is being created, for example,
+ "vfio-pci" for a PCI device.
+
+* available_instances
+
+ This attribute should show the number of devices of type <type-id> that can be
+ created.
+
+* [device]
+
+ This directory contains links to the devices of type <type-id> that have been
+ created.
+
+* name
+
+ This attribute should show human readable name. This is optional attribute.
+
+* description
+
+ This attribute should show brief features/description of the type. This is
+ optional attribute.
+
+Directories and Files Under the sysfs for Each mdev Device
+----------------------------------------------------------
+
+::
+
+ |- [parent phy device]
+ |--- [$MDEV_UUID]
+ |--- remove
+ |--- mdev_type {link to its type}
+ |--- vendor-specific-attributes [optional]
+
+* remove (write only)
+
+Writing '1' to the 'remove' file destroys the mdev device. The vendor driver can
+fail the remove() callback if that device is active and the vendor driver
+doesn't support hot unplug.
+
+Example::
+
+ # echo 1 > /sys/bus/mdev/devices/$mdev_UUID/remove
+
+Mediated device Hot plug
+------------------------
+
+Mediated devices can be created and assigned at runtime. The procedure to hot
+plug a mediated device is the same as the procedure to hot plug a PCI device.
+
+Translation APIs for Mediated Devices
+=====================================
+
+The following APIs are provided for translating user pfn to host pfn in a VFIO
+driver::
+
+ extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn,
+ int npage, int prot, unsigned long *phys_pfn);
+
+ extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn,
+ int npage);
+
+These functions call back into the back-end IOMMU module by using the pin_pages
+and unpin_pages callbacks of the struct vfio_iommu_driver_ops[4]. Currently
+these callbacks are supported in the TYPE1 IOMMU module. To enable them for
+other IOMMU backend modules, such as PPC64 sPAPR module, they need to provide
+these two callback functions.
+
+Using the Sample Code
+=====================
+
+mtty.c in samples/vfio-mdev/ directory is a sample driver program to
+demonstrate how to use the mediated device framework.
+
+The sample driver creates an mdev device that simulates a serial port over a PCI
+card.
+
+1. Build and load the mtty.ko module.
+
+ This step creates a dummy device, /sys/devices/virtual/mtty/mtty/
+
+ Files in this device directory in sysfs are similar to the following::
+
+ # tree /sys/devices/virtual/mtty/mtty/
+ /sys/devices/virtual/mtty/mtty/
+ |-- mdev_supported_types
+ | |-- mtty-1
+ | | |-- available_instances
+ | | |-- create
+ | | |-- device_api
+ | | |-- devices
+ | | `-- name
+ | `-- mtty-2
+ | |-- available_instances
+ | |-- create
+ | |-- device_api
+ | |-- devices
+ | `-- name
+ |-- mtty_dev
+ | `-- sample_mtty_dev
+ |-- power
+ | |-- autosuspend_delay_ms
+ | |-- control
+ | |-- runtime_active_time
+ | |-- runtime_status
+ | `-- runtime_suspended_time
+ |-- subsystem -> ../../../../class/mtty
+ `-- uevent
+
+2. Create a mediated device by using the dummy device that you created in the
+ previous step::
+
+ # echo "83b8f4f2-509f-382f-3c1e-e6bfe0fa1001" > \
+ /sys/devices/virtual/mtty/mtty/mdev_supported_types/mtty-2/create
+
+3. Add parameters to qemu-kvm::
+
+ -device vfio-pci,\
+ sysfsdev=/sys/bus/mdev/devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001
+
+4. Boot the VM.
+
+ In the Linux guest VM, with no hardware on the host, the device appears
+ as follows::
+
+ # lspci -s 00:05.0 -xxvv
+ 00:05.0 Serial controller: Device 4348:3253 (rev 10) (prog-if 02 [16550])
+ Subsystem: Device 4348:3253
+ Physical Slot: 5
+ Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr-
+ Stepping- SERR- FastB2B- DisINTx-
+ Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort-
+ <TAbort- <MAbort- >SERR- <PERR- INTx-
+ Interrupt: pin A routed to IRQ 10
+ Region 0: I/O ports at c150 [size=8]
+ Region 1: I/O ports at c158 [size=8]
+ Kernel driver in use: serial
+ 00: 48 43 53 32 01 00 00 02 10 02 00 07 00 00 00 00
+ 10: 51 c1 00 00 59 c1 00 00 00 00 00 00 00 00 00 00
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 48 43 53 32
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 0a 01 00 00
+
+ In the Linux guest VM, dmesg output for the device is as follows:
+
+ serial 0000:00:05.0: PCI INT A -> Link[LNKA] -> GSI 10 (level, high) -> IRQ 10
+ 0000:00:05.0: ttyS1 at I/O 0xc150 (irq = 10) is a 16550A
+ 0000:00:05.0: ttyS2 at I/O 0xc158 (irq = 10) is a 16550A
+
+
+5. In the Linux guest VM, check the serial ports::
+
+ # setserial -g /dev/ttyS*
+ /dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
+ /dev/ttyS1, UART: 16550A, Port: 0xc150, IRQ: 10
+ /dev/ttyS2, UART: 16550A, Port: 0xc158, IRQ: 10
+
+6. Using minicom or any terminal emulation program, open port /dev/ttyS1 or
+ /dev/ttyS2 with hardware flow control disabled.
+
+7. Type data on the minicom terminal or send data to the terminal emulation
+ program and read the data.
+
+ Data is loop backed from hosts mtty driver.
+
+8. Destroy the mediated device that you created::
+
+ # echo 1 > /sys/bus/mdev/devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001/remove
+
+References
+==========
+
+1. See Documentation/driver-api/vfio.rst for more information on VFIO.
+2. struct mdev_driver in include/linux/mdev.h
+3. struct mdev_parent_ops in include/linux/mdev.h
+4. struct vfio_iommu_driver_ops in include/linux/vfio.h
--- /dev/null
+==================================
+VFIO - "Virtual Function I/O" [1]_
+==================================
+
+Many modern system now provide DMA and interrupt remapping facilities
+to help ensure I/O devices behave within the boundaries they've been
+allotted. This includes x86 hardware with AMD-Vi and Intel VT-d,
+POWER systems with Partitionable Endpoints (PEs) and embedded PowerPC
+systems such as Freescale PAMU. The VFIO driver is an IOMMU/device
+agnostic framework for exposing direct device access to userspace, in
+a secure, IOMMU protected environment. In other words, this allows
+safe [2]_, non-privileged, userspace drivers.
+
+Why do we want that? Virtual machines often make use of direct device
+access ("device assignment") when configured for the highest possible
+I/O performance. From a device and host perspective, this simply
+turns the VM into a userspace driver, with the benefits of
+significantly reduced latency, higher bandwidth, and direct use of
+bare-metal device drivers [3]_.
+
+Some applications, particularly in the high performance computing
+field, also benefit from low-overhead, direct device access from
+userspace. Examples include network adapters (often non-TCP/IP based)
+and compute accelerators. Prior to VFIO, these drivers had to either
+go through the full development cycle to become proper upstream
+driver, be maintained out of tree, or make use of the UIO framework,
+which has no notion of IOMMU protection, limited interrupt support,
+and requires root privileges to access things like PCI configuration
+space.
+
+The VFIO driver framework intends to unify these, replacing both the
+KVM PCI specific device assignment code as well as provide a more
+secure, more featureful userspace driver environment than UIO.
+
+Groups, Devices, and IOMMUs
+---------------------------
+
+Devices are the main target of any I/O driver. Devices typically
+create a programming interface made up of I/O access, interrupts,
+and DMA. Without going into the details of each of these, DMA is
+by far the most critical aspect for maintaining a secure environment
+as allowing a device read-write access to system memory imposes the
+greatest risk to the overall system integrity.
+
+To help mitigate this risk, many modern IOMMUs now incorporate
+isolation properties into what was, in many cases, an interface only
+meant for translation (ie. solving the addressing problems of devices
+with limited address spaces). With this, devices can now be isolated
+from each other and from arbitrary memory access, thus allowing
+things like secure direct assignment of devices into virtual machines.
+
+This isolation is not always at the granularity of a single device
+though. Even when an IOMMU is capable of this, properties of devices,
+interconnects, and IOMMU topologies can each reduce this isolation.
+For instance, an individual device may be part of a larger multi-
+function enclosure. While the IOMMU may be able to distinguish
+between devices within the enclosure, the enclosure may not require
+transactions between devices to reach the IOMMU. Examples of this
+could be anything from a multi-function PCI device with backdoors
+between functions to a non-PCI-ACS (Access Control Services) capable
+bridge allowing redirection without reaching the IOMMU. Topology
+can also play a factor in terms of hiding devices. A PCIe-to-PCI
+bridge masks the devices behind it, making transaction appear as if
+from the bridge itself. Obviously IOMMU design plays a major factor
+as well.
+
+Therefore, while for the most part an IOMMU may have device level
+granularity, any system is susceptible to reduced granularity. The
+IOMMU API therefore supports a notion of IOMMU groups. A group is
+a set of devices which is isolatable from all other devices in the
+system. Groups are therefore the unit of ownership used by VFIO.
+
+While the group is the minimum granularity that must be used to
+ensure secure user access, it's not necessarily the preferred
+granularity. In IOMMUs which make use of page tables, it may be
+possible to share a set of page tables between different groups,
+reducing the overhead both to the platform (reduced TLB thrashing,
+reduced duplicate page tables), and to the user (programming only
+a single set of translations). For this reason, VFIO makes use of
+a container class, which may hold one or more groups. A container
+is created by simply opening the /dev/vfio/vfio character device.
+
+On its own, the container provides little functionality, with all
+but a couple version and extension query interfaces locked away.
+The user needs to add a group into the container for the next level
+of functionality. To do this, the user first needs to identify the
+group associated with the desired device. This can be done using
+the sysfs links described in the example below. By unbinding the
+device from the host driver and binding it to a VFIO driver, a new
+VFIO group will appear for the group as /dev/vfio/$GROUP, where
+$GROUP is the IOMMU group number of which the device is a member.
+If the IOMMU group contains multiple devices, each will need to
+be bound to a VFIO driver before operations on the VFIO group
+are allowed (it's also sufficient to only unbind the device from
+host drivers if a VFIO driver is unavailable; this will make the
+group available, but not that particular device). TBD - interface
+for disabling driver probing/locking a device.
+
+Once the group is ready, it may be added to the container by opening
+the VFIO group character device (/dev/vfio/$GROUP) and using the
+VFIO_GROUP_SET_CONTAINER ioctl, passing the file descriptor of the
+previously opened container file. If desired and if the IOMMU driver
+supports sharing the IOMMU context between groups, multiple groups may
+be set to the same container. If a group fails to set to a container
+with existing groups, a new empty container will need to be used
+instead.
+
+With a group (or groups) attached to a container, the remaining
+ioctls become available, enabling access to the VFIO IOMMU interfaces.
+Additionally, it now becomes possible to get file descriptors for each
+device within a group using an ioctl on the VFIO group file descriptor.
+
+The VFIO device API includes ioctls for describing the device, the I/O
+regions and their read/write/mmap offsets on the device descriptor, as
+well as mechanisms for describing and registering interrupt
+notifications.
+
+VFIO Usage Example
+------------------
+
+Assume user wants to access PCI device 0000:06:0d.0::
+
+ $ readlink /sys/bus/pci/devices/0000:06:0d.0/iommu_group
+ ../../../../kernel/iommu_groups/26
+
+This device is therefore in IOMMU group 26. This device is on the
+pci bus, therefore the user will make use of vfio-pci to manage the
+group::
+
+ # modprobe vfio-pci
+
+Binding this device to the vfio-pci driver creates the VFIO group
+character devices for this group::
+
+ $ lspci -n -s 0000:06:0d.0
+ 06:0d.0 0401: 1102:0002 (rev 08)
+ # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
+ # echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
+
+Now we need to look at what other devices are in the group to free
+it for use by VFIO::
+
+ $ ls -l /sys/bus/pci/devices/0000:06:0d.0/iommu_group/devices
+ total 0
+ lrwxrwxrwx. 1 root root 0 Apr 23 16:13 0000:00:1e.0 ->
+ ../../../../devices/pci0000:00/0000:00:1e.0
+ lrwxrwxrwx. 1 root root 0 Apr 23 16:13 0000:06:0d.0 ->
+ ../../../../devices/pci0000:00/0000:00:1e.0/0000:06:0d.0
+ lrwxrwxrwx. 1 root root 0 Apr 23 16:13 0000:06:0d.1 ->
+ ../../../../devices/pci0000:00/0000:00:1e.0/0000:06:0d.1
+
+This device is behind a PCIe-to-PCI bridge [4]_, therefore we also
+need to add device 0000:06:0d.1 to the group following the same
+procedure as above. Device 0000:00:1e.0 is a bridge that does
+not currently have a host driver, therefore it's not required to
+bind this device to the vfio-pci driver (vfio-pci does not currently
+support PCI bridges).
+
+The final step is to provide the user with access to the group if
+unprivileged operation is desired (note that /dev/vfio/vfio provides
+no capabilities on its own and is therefore expected to be set to
+mode 0666 by the system)::
+
+ # chown user:user /dev/vfio/26
+
+The user now has full access to all the devices and the iommu for this
+group and can access them as follows::
+
+ int container, group, device, i;
+ struct vfio_group_status group_status =
+ { .argsz = sizeof(group_status) };
+ struct vfio_iommu_type1_info iommu_info = { .argsz = sizeof(iommu_info) };
+ struct vfio_iommu_type1_dma_map dma_map = { .argsz = sizeof(dma_map) };
+ struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+
+ /* Create a new container */
+ container = open("/dev/vfio/vfio", O_RDWR);
+
+ if (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION)
+ /* Unknown API version */
+
+ if (!ioctl(container, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU))
+ /* Doesn't support the IOMMU driver we want. */
+
+ /* Open the group */
+ group = open("/dev/vfio/26", O_RDWR);
+
+ /* Test the group is viable and available */
+ ioctl(group, VFIO_GROUP_GET_STATUS, &group_status);
+
+ if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE))
+ /* Group is not viable (ie, not all devices bound for vfio) */
+
+ /* Add the group to the container */
+ ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
+
+ /* Enable the IOMMU model we want */
+ ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
+
+ /* Get addition IOMMU info */
+ ioctl(container, VFIO_IOMMU_GET_INFO, &iommu_info);
+
+ /* Allocate some space and setup a DMA mapping */
+ dma_map.vaddr = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ dma_map.size = 1024 * 1024;
+ dma_map.iova = 0; /* 1MB starting at 0x0 from device view */
+ dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
+
+ ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
+
+ /* Get a file descriptor for the device */
+ device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "0000:06:0d.0");
+
+ /* Test and setup the device */
+ ioctl(device, VFIO_DEVICE_GET_INFO, &device_info);
+
+ for (i = 0; i < device_info.num_regions; i++) {
+ struct vfio_region_info reg = { .argsz = sizeof(reg) };
+
+ reg.index = i;
+
+ ioctl(device, VFIO_DEVICE_GET_REGION_INFO, ®);
+
+ /* Setup mappings... read/write offsets, mmaps
+ * For PCI devices, config space is a region */
+ }
+
+ for (i = 0; i < device_info.num_irqs; i++) {
+ struct vfio_irq_info irq = { .argsz = sizeof(irq) };
+
+ irq.index = i;
+
+ ioctl(device, VFIO_DEVICE_GET_IRQ_INFO, &irq);
+
+ /* Setup IRQs... eventfds, VFIO_DEVICE_SET_IRQS */
+ }
+
+ /* Gratuitous device reset and go... */
+ ioctl(device, VFIO_DEVICE_RESET);
+
+VFIO User API
+-------------------------------------------------------------------------------
+
+Please see include/linux/vfio.h for complete API documentation.
+
+VFIO bus driver API
+-------------------------------------------------------------------------------
+
+VFIO bus drivers, such as vfio-pci make use of only a few interfaces
+into VFIO core. When devices are bound and unbound to the driver,
+the driver should call vfio_add_group_dev() and vfio_del_group_dev()
+respectively::
+
+ extern int vfio_add_group_dev(struct device *dev,
+ const struct vfio_device_ops *ops,
+ void *device_data);
+
+ extern void *vfio_del_group_dev(struct device *dev);
+
+vfio_add_group_dev() indicates to the core to begin tracking the
+iommu_group of the specified dev and register the dev as owned by
+a VFIO bus driver. The driver provides an ops structure for callbacks
+similar to a file operations structure::
+
+ struct vfio_device_ops {
+ int (*open)(void *device_data);
+ void (*release)(void *device_data);
+ ssize_t (*read)(void *device_data, char __user *buf,
+ size_t count, loff_t *ppos);
+ ssize_t (*write)(void *device_data, const char __user *buf,
+ size_t size, loff_t *ppos);
+ long (*ioctl)(void *device_data, unsigned int cmd,
+ unsigned long arg);
+ int (*mmap)(void *device_data, struct vm_area_struct *vma);
+ };
+
+Each function is passed the device_data that was originally registered
+in the vfio_add_group_dev() call above. This allows the bus driver
+an easy place to store its opaque, private data. The open/release
+callbacks are issued when a new file descriptor is created for a
+device (via VFIO_GROUP_GET_DEVICE_FD). The ioctl interface provides
+a direct pass through for VFIO_DEVICE_* ioctls. The read/write/mmap
+interfaces implement the device region access defined by the device's
+own VFIO_DEVICE_GET_REGION_INFO ioctl.
+
+
+PPC64 sPAPR implementation note
+-------------------------------
+
+This implementation has some specifics:
+
+1) On older systems (POWER7 with P5IOC2/IODA1) only one IOMMU group per
+ container is supported as an IOMMU table is allocated at the boot time,
+ one table per a IOMMU group which is a Partitionable Endpoint (PE)
+ (PE is often a PCI domain but not always).
+
+ Newer systems (POWER8 with IODA2) have improved hardware design which allows
+ to remove this limitation and have multiple IOMMU groups per a VFIO
+ container.
+
+2) The hardware supports so called DMA windows - the PCI address range
+ within which DMA transfer is allowed, any attempt to access address space
+ out of the window leads to the whole PE isolation.
+
+3) PPC64 guests are paravirtualized but not fully emulated. There is an API
+ to map/unmap pages for DMA, and it normally maps 1..32 pages per call and
+ currently there is no way to reduce the number of calls. In order to make
+ things faster, the map/unmap handling has been implemented in real mode
+ which provides an excellent performance which has limitations such as
+ inability to do locked pages accounting in real time.
+
+4) According to sPAPR specification, A Partitionable Endpoint (PE) is an I/O
+ subtree that can be treated as a unit for the purposes of partitioning and
+ error recovery. A PE may be a single or multi-function IOA (IO Adapter), a
+ function of a multi-function IOA, or multiple IOAs (possibly including
+ switch and bridge structures above the multiple IOAs). PPC64 guests detect
+ PCI errors and recover from them via EEH RTAS services, which works on the
+ basis of additional ioctl commands.
+
+ So 4 additional ioctls have been added:
+
+ VFIO_IOMMU_SPAPR_TCE_GET_INFO
+ returns the size and the start of the DMA window on the PCI bus.
+
+ VFIO_IOMMU_ENABLE
+ enables the container. The locked pages accounting
+ is done at this point. This lets user first to know what
+ the DMA window is and adjust rlimit before doing any real job.
+
+ VFIO_IOMMU_DISABLE
+ disables the container.
+
+ VFIO_EEH_PE_OP
+ provides an API for EEH setup, error detection and recovery.
+
+ The code flow from the example above should be slightly changed::
+
+ struct vfio_eeh_pe_op pe_op = { .argsz = sizeof(pe_op), .flags = 0 };
+
+ .....
+ /* Add the group to the container */
+ ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
+
+ /* Enable the IOMMU model we want */
+ ioctl(container, VFIO_SET_IOMMU, VFIO_SPAPR_TCE_IOMMU)
+
+ /* Get addition sPAPR IOMMU info */
+ vfio_iommu_spapr_tce_info spapr_iommu_info;
+ ioctl(container, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &spapr_iommu_info);
+
+ if (ioctl(container, VFIO_IOMMU_ENABLE))
+ /* Cannot enable container, may be low rlimit */
+
+ /* Allocate some space and setup a DMA mapping */
+ dma_map.vaddr = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+
+ dma_map.size = 1024 * 1024;
+ dma_map.iova = 0; /* 1MB starting at 0x0 from device view */
+ dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
+
+ /* Check here is .iova/.size are within DMA window from spapr_iommu_info */
+ ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
+
+ /* Get a file descriptor for the device */
+ device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "0000:06:0d.0");
+
+ ....
+
+ /* Gratuitous device reset and go... */
+ ioctl(device, VFIO_DEVICE_RESET);
+
+ /* Make sure EEH is supported */
+ ioctl(container, VFIO_CHECK_EXTENSION, VFIO_EEH);
+
+ /* Enable the EEH functionality on the device */
+ pe_op.op = VFIO_EEH_PE_ENABLE;
+ ioctl(container, VFIO_EEH_PE_OP, &pe_op);
+
+ /* You're suggested to create additional data struct to represent
+ * PE, and put child devices belonging to same IOMMU group to the
+ * PE instance for later reference.
+ */
+
+ /* Check the PE's state and make sure it's in functional state */
+ pe_op.op = VFIO_EEH_PE_GET_STATE;
+ ioctl(container, VFIO_EEH_PE_OP, &pe_op);
+
+ /* Save device state using pci_save_state().
+ * EEH should be enabled on the specified device.
+ */
+
+ ....
+
+ /* Inject EEH error, which is expected to be caused by 32-bits
+ * config load.
+ */
+ pe_op.op = VFIO_EEH_PE_INJECT_ERR;
+ pe_op.err.type = EEH_ERR_TYPE_32;
+ pe_op.err.func = EEH_ERR_FUNC_LD_CFG_ADDR;
+ pe_op.err.addr = 0ul;
+ pe_op.err.mask = 0ul;
+ ioctl(container, VFIO_EEH_PE_OP, &pe_op);
+
+ ....
+
+ /* When 0xFF's returned from reading PCI config space or IO BARs
+ * of the PCI device. Check the PE's state to see if that has been
+ * frozen.
+ */
+ ioctl(container, VFIO_EEH_PE_OP, &pe_op);
+
+ /* Waiting for pending PCI transactions to be completed and don't
+ * produce any more PCI traffic from/to the affected PE until
+ * recovery is finished.
+ */
+
+ /* Enable IO for the affected PE and collect logs. Usually, the
+ * standard part of PCI config space, AER registers are dumped
+ * as logs for further analysis.
+ */
+ pe_op.op = VFIO_EEH_PE_UNFREEZE_IO;
+ ioctl(container, VFIO_EEH_PE_OP, &pe_op);
+
+ /*
+ * Issue PE reset: hot or fundamental reset. Usually, hot reset
+ * is enough. However, the firmware of some PCI adapters would
+ * require fundamental reset.
+ */
+ pe_op.op = VFIO_EEH_PE_RESET_HOT;
+ ioctl(container, VFIO_EEH_PE_OP, &pe_op);
+ pe_op.op = VFIO_EEH_PE_RESET_DEACTIVATE;
+ ioctl(container, VFIO_EEH_PE_OP, &pe_op);
+
+ /* Configure the PCI bridges for the affected PE */
+ pe_op.op = VFIO_EEH_PE_CONFIGURE;
+ ioctl(container, VFIO_EEH_PE_OP, &pe_op);
+
+ /* Restored state we saved at initialization time. pci_restore_state()
+ * is good enough as an example.
+ */
+
+ /* Hopefully, error is recovered successfully. Now, you can resume to
+ * start PCI traffic to/from the affected PE.
+ */
+
+ ....
+
+5) There is v2 of SPAPR TCE IOMMU. It deprecates VFIO_IOMMU_ENABLE/
+ VFIO_IOMMU_DISABLE and implements 2 new ioctls:
+ VFIO_IOMMU_SPAPR_REGISTER_MEMORY and VFIO_IOMMU_SPAPR_UNREGISTER_MEMORY
+ (which are unsupported in v1 IOMMU).
+
+ PPC64 paravirtualized guests generate a lot of map/unmap requests,
+ and the handling of those includes pinning/unpinning pages and updating
+ mm::locked_vm counter to make sure we do not exceed the rlimit.
+ The v2 IOMMU splits accounting and pinning into separate operations:
+
+ - VFIO_IOMMU_SPAPR_REGISTER_MEMORY/VFIO_IOMMU_SPAPR_UNREGISTER_MEMORY ioctls
+ receive a user space address and size of the block to be pinned.
+ Bisecting is not supported and VFIO_IOMMU_UNREGISTER_MEMORY is expected to
+ be called with the exact address and size used for registering
+ the memory block. The userspace is not expected to call these often.
+ The ranges are stored in a linked list in a VFIO container.
+
+ - VFIO_IOMMU_MAP_DMA/VFIO_IOMMU_UNMAP_DMA ioctls only update the actual
+ IOMMU table and do not do pinning; instead these check that the userspace
+ address is from pre-registered range.
+
+ This separation helps in optimizing DMA for guests.
+
+6) sPAPR specification allows guests to have an additional DMA window(s) on
+ a PCI bus with a variable page size. Two ioctls have been added to support
+ this: VFIO_IOMMU_SPAPR_TCE_CREATE and VFIO_IOMMU_SPAPR_TCE_REMOVE.
+ The platform has to support the functionality or error will be returned to
+ the userspace. The existing hardware supports up to 2 DMA windows, one is
+ 2GB long, uses 4K pages and called "default 32bit window"; the other can
+ be as big as entire RAM, use different page size, it is optional - guests
+ create those in run-time if the guest driver supports 64bit DMA.
+
+ VFIO_IOMMU_SPAPR_TCE_CREATE receives a page shift, a DMA window size and
+ a number of TCE table levels (if a TCE table is going to be big enough and
+ the kernel may not be able to allocate enough of physically contiguous
+ memory). It creates a new window in the available slot and returns the bus
+ address where the new window starts. Due to hardware limitation, the user
+ space cannot choose the location of DMA windows.
+
+ VFIO_IOMMU_SPAPR_TCE_REMOVE receives the bus start address of the window
+ and removes it.
+
+-------------------------------------------------------------------------------
+
+.. [1] VFIO was originally an acronym for "Virtual Function I/O" in its
+ initial implementation by Tom Lyon while as Cisco. We've since
+ outgrown the acronym, but it's catchy.
+
+.. [2] "safe" also depends upon a device being "well behaved". It's
+ possible for multi-function devices to have backdoors between
+ functions and even for single function devices to have alternative
+ access to things like PCI config space through MMIO registers. To
+ guard against the former we can include additional precautions in the
+ IOMMU driver to group multi-function PCI devices together
+ (iommu=group_mf). The latter we can't prevent, but the IOMMU should
+ still provide isolation. For PCI, SR-IOV Virtual Functions are the
+ best indicator of "well behaved", as these are designed for
+ virtualization usage models.
+
+.. [3] As always there are trade-offs to virtual machine device
+ assignment that are beyond the scope of VFIO. It's expected that
+ future IOMMU technologies will reduce some, but maybe not all, of
+ these trade-offs.
+
+.. [4] In this case the device is below a PCI bridge, so transactions
+ from either function of the device are indistinguishable to the iommu::
+
+ -[0000:00]-+-1e.0-[06]--+-0d.0
+ \-0d.1
+
+ 00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev 90)
--- /dev/null
+==========================================
+Xillybus driver for generic FPGA interface
+==========================================
+
+:Author: Eli Billauer, Xillybus Ltd. (http://xillybus.com)
+:Email: eli.billauer@gmail.com or as advertised on Xillybus' site.
+
+.. Contents:
+
+ - Introduction
+ -- Background
+ -- Xillybus Overview
+
+ - Usage
+ -- User interface
+ -- Synchronization
+ -- Seekable pipes
+
+ - Internals
+ -- Source code organization
+ -- Pipe attributes
+ -- Host never reads from the FPGA
+ -- Channels, pipes, and the message channel
+ -- Data streaming
+ -- Data granularity
+ -- Probing
+ -- Buffer allocation
+ -- The "nonempty" message (supporting poll)
+
+
+Introduction
+============
+
+Background
+----------
+
+An FPGA (Field Programmable Gate Array) is a piece of logic hardware, which
+can be programmed to become virtually anything that is usually found as a
+dedicated chipset: For instance, a display adapter, network interface card,
+or even a processor with its peripherals. FPGAs are the LEGO of hardware:
+Based upon certain building blocks, you make your own toys the way you like
+them. It's usually pointless to reimplement something that is already
+available on the market as a chipset, so FPGAs are mostly used when some
+special functionality is needed, and the production volume is relatively low
+(hence not justifying the development of an ASIC).
+
+The challenge with FPGAs is that everything is implemented at a very low
+level, even lower than assembly language. In order to allow FPGA designers to
+focus on their specific project, and not reinvent the wheel over and over
+again, pre-designed building blocks, IP cores, are often used. These are the
+FPGA parallels of library functions. IP cores may implement certain
+mathematical functions, a functional unit (e.g. a USB interface), an entire
+processor (e.g. ARM) or anything that might come handy. Think of them as a
+building block, with electrical wires dangling on the sides for connection to
+other blocks.
+
+One of the daunting tasks in FPGA design is communicating with a fullblown
+operating system (actually, with the processor running it): Implementing the
+low-level bus protocol and the somewhat higher-level interface with the host
+(registers, interrupts, DMA etc.) is a project in itself. When the FPGA's
+function is a well-known one (e.g. a video adapter card, or a NIC), it can
+make sense to design the FPGA's interface logic specifically for the project.
+A special driver is then written to present the FPGA as a well-known interface
+to the kernel and/or user space. In that case, there is no reason to treat the
+FPGA differently than any device on the bus.
+
+It's however common that the desired data communication doesn't fit any well-
+known peripheral function. Also, the effort of designing an elegant
+abstraction for the data exchange is often considered too big. In those cases,
+a quicker and possibly less elegant solution is sought: The driver is
+effectively written as a user space program, leaving the kernel space part
+with just elementary data transport. This still requires designing some
+interface logic for the FPGA, and write a simple ad-hoc driver for the kernel.
+
+Xillybus Overview
+-----------------
+
+Xillybus is an IP core and a Linux driver. Together, they form a kit for
+elementary data transport between an FPGA and the host, providing pipe-like
+data streams with a straightforward user interface. It's intended as a low-
+effort solution for mixed FPGA-host projects, for which it makes sense to
+have the project-specific part of the driver running in a user-space program.
+
+Since the communication requirements may vary significantly from one FPGA
+project to another (the number of data pipes needed in each direction and
+their attributes), there isn't one specific chunk of logic being the Xillybus
+IP core. Rather, the IP core is configured and built based upon a
+specification given by its end user.
+
+Xillybus presents independent data streams, which resemble pipes or TCP/IP
+communication to the user. At the host side, a character device file is used
+just like any pipe file. On the FPGA side, hardware FIFOs are used to stream
+the data. This is contrary to a common method of communicating through fixed-
+sized buffers (even though such buffers are used by Xillybus under the hood).
+There may be more than a hundred of these streams on a single IP core, but
+also no more than one, depending on the configuration.
+
+In order to ease the deployment of the Xillybus IP core, it contains a simple
+data structure which completely defines the core's configuration. The Linux
+driver fetches this data structure during its initialization process, and sets
+up the DMA buffers and character devices accordingly. As a result, a single
+driver is used to work out of the box with any Xillybus IP core.
+
+The data structure just mentioned should not be confused with PCI's
+configuration space or the Flattened Device Tree.
+
+Usage
+=====
+
+User interface
+--------------
+
+On the host, all interface with Xillybus is done through /dev/xillybus_*
+device files, which are generated automatically as the drivers loads. The
+names of these files depend on the IP core that is loaded in the FPGA (see
+Probing below). To communicate with the FPGA, open the device file that
+corresponds to the hardware FIFO you want to send data or receive data from,
+and use plain write() or read() calls, just like with a regular pipe. In
+particular, it makes perfect sense to go::
+
+ $ cat mydata > /dev/xillybus_thisfifo
+
+ $ cat /dev/xillybus_thatfifo > hisdata
+
+possibly pressing CTRL-C as some stage, even though the xillybus_* pipes have
+the capability to send an EOF (but may not use it).
+
+The driver and hardware are designed to behave sensibly as pipes, including:
+
+* Supporting non-blocking I/O (by setting O_NONBLOCK on open() ).
+
+* Supporting poll() and select().
+
+* Being bandwidth efficient under load (using DMA) but also handle small
+ pieces of data sent across (like TCP/IP) by autoflushing.
+
+A device file can be read only, write only or bidirectional. Bidirectional
+device files are treated like two independent pipes (except for sharing a
+"channel" structure in the implementation code).
+
+Synchronization
+---------------
+
+Xillybus pipes are configured (on the IP core) to be either synchronous or
+asynchronous. For a synchronous pipe, write() returns successfully only after
+some data has been submitted and acknowledged by the FPGA. This slows down
+bulk data transfers, and is nearly impossible for use with streams that
+require data at a constant rate: There is no data transmitted to the FPGA
+between write() calls, in particular when the process loses the CPU.
+
+When a pipe is configured asynchronous, write() returns if there was enough
+room in the buffers to store any of the data in the buffers.
+
+For FPGA to host pipes, asynchronous pipes allow data transfer from the FPGA
+as soon as the respective device file is opened, regardless of if the data
+has been requested by a read() call. On synchronous pipes, only the amount
+of data requested by a read() call is transmitted.
+
+In summary, for synchronous pipes, data between the host and FPGA is
+transmitted only to satisfy the read() or write() call currently handled
+by the driver, and those calls wait for the transmission to complete before
+returning.
+
+Note that the synchronization attribute has nothing to do with the possibility
+that read() or write() completes less bytes than requested. There is a
+separate configuration flag ("allowpartial") that determines whether such a
+partial completion is allowed.
+
+Seekable pipes
+--------------
+
+A synchronous pipe can be configured to have the stream's position exposed
+to the user logic at the FPGA. Such a pipe is also seekable on the host API.
+With this feature, a memory or register interface can be attached on the
+FPGA side to the seekable stream. Reading or writing to a certain address in
+the attached memory is done by seeking to the desired address, and calling
+read() or write() as required.
+
+
+Internals
+=========
+
+Source code organization
+------------------------
+
+The Xillybus driver consists of a core module, xillybus_core.c, and modules
+that depend on the specific bus interface (xillybus_of.c and xillybus_pcie.c).
+
+The bus specific modules are those probed when a suitable device is found by
+the kernel. Since the DMA mapping and synchronization functions, which are bus
+dependent by their nature, are used by the core module, a
+xilly_endpoint_hardware structure is passed to the core module on
+initialization. This structure is populated with pointers to wrapper functions
+which execute the DMA-related operations on the bus.
+
+Pipe attributes
+---------------
+
+Each pipe has a number of attributes which are set when the FPGA component
+(IP core) is built. They are fetched from the IDT (the data structure which
+defines the core's configuration, see Probing below) by xilly_setupchannels()
+in xillybus_core.c as follows:
+
+* is_writebuf: The pipe's direction. A non-zero value means it's an FPGA to
+ host pipe (the FPGA "writes").
+
+* channelnum: The pipe's identification number in communication between the
+ host and FPGA.
+
+* format: The underlying data width. See Data Granularity below.
+
+* allowpartial: A non-zero value means that a read() or write() (whichever
+ applies) may return with less than the requested number of bytes. The common
+ choice is a non-zero value, to match standard UNIX behavior.
+
+* synchronous: A non-zero value means that the pipe is synchronous. See
+ Synchronization above.
+
+* bufsize: Each DMA buffer's size. Always a power of two.
+
+* bufnum: The number of buffers allocated for this pipe. Always a power of two.
+
+* exclusive_open: A non-zero value forces exclusive opening of the associated
+ device file. If the device file is bidirectional, and already opened only in
+ one direction, the opposite direction may be opened once.
+
+* seekable: A non-zero value indicates that the pipe is seekable. See
+ Seekable pipes above.
+
+* supports_nonempty: A non-zero value (which is typical) indicates that the
+ hardware will send the messages that are necessary to support select() and
+ poll() for this pipe.
+
+Host never reads from the FPGA
+------------------------------
+
+Even though PCI Express is hotpluggable in general, a typical motherboard
+doesn't expect a card to go away all of the sudden. But since the PCIe card
+is based upon reprogrammable logic, a sudden disappearance from the bus is
+quite likely as a result of an accidental reprogramming of the FPGA while the
+host is up. In practice, nothing happens immediately in such a situation. But
+if the host attempts to read from an address that is mapped to the PCI Express
+device, that leads to an immediate freeze of the system on some motherboards,
+even though the PCIe standard requires a graceful recovery.
+
+In order to avoid these freezes, the Xillybus driver refrains completely from
+reading from the device's register space. All communication from the FPGA to
+the host is done through DMA. In particular, the Interrupt Service Routine
+doesn't follow the common practice of checking a status register when it's
+invoked. Rather, the FPGA prepares a small buffer which contains short
+messages, which inform the host what the interrupt was about.
+
+This mechanism is used on non-PCIe buses as well for the sake of uniformity.
+
+
+Channels, pipes, and the message channel
+----------------------------------------
+
+Each of the (possibly bidirectional) pipes presented to the user is allocated
+a data channel between the FPGA and the host. The distinction between channels
+and pipes is necessary only because of channel 0, which is used for interrupt-
+related messages from the FPGA, and has no pipe attached to it.
+
+Data streaming
+--------------
+
+Even though a non-segmented data stream is presented to the user at both
+sides, the implementation relies on a set of DMA buffers which is allocated
+for each channel. For the sake of illustration, let's take the FPGA to host
+direction: As data streams into the respective channel's interface in the
+FPGA, the Xillybus IP core writes it to one of the DMA buffers. When the
+buffer is full, the FPGA informs the host about that (appending a
+XILLYMSG_OPCODE_RELEASEBUF message channel 0 and sending an interrupt if
+necessary). The host responds by making the data available for reading through
+the character device. When all data has been read, the host writes on the
+the FPGA's buffer control register, allowing the buffer's overwriting. Flow
+control mechanisms exist on both sides to prevent underflows and overflows.
+
+This is not good enough for creating a TCP/IP-like stream: If the data flow
+stops momentarily before a DMA buffer is filled, the intuitive expectation is
+that the partial data in buffer will arrive anyhow, despite the buffer not
+being completed. This is implemented by adding a field in the
+XILLYMSG_OPCODE_RELEASEBUF message, through which the FPGA informs not just
+which buffer is submitted, but how much data it contains.
+
+But the FPGA will submit a partially filled buffer only if directed to do so
+by the host. This situation occurs when the read() method has been blocking
+for XILLY_RX_TIMEOUT jiffies (currently 10 ms), after which the host commands
+the FPGA to submit a DMA buffer as soon as it can. This timeout mechanism
+balances between bus bandwidth efficiency (preventing a lot of partially
+filled buffers being sent) and a latency held fairly low for tails of data.
+
+A similar setting is used in the host to FPGA direction. The handling of
+partial DMA buffers is somewhat different, though. The user can tell the
+driver to submit all data it has in the buffers to the FPGA, by issuing a
+write() with the byte count set to zero. This is similar to a flush request,
+but it doesn't block. There is also an autoflushing mechanism, which triggers
+an equivalent flush roughly XILLY_RX_TIMEOUT jiffies after the last write().
+This allows the user to be oblivious about the underlying buffering mechanism
+and yet enjoy a stream-like interface.
+
+Note that the issue of partial buffer flushing is irrelevant for pipes having
+the "synchronous" attribute nonzero, since synchronous pipes don't allow data
+to lay around in the DMA buffers between read() and write() anyhow.
+
+Data granularity
+----------------
+
+The data arrives or is sent at the FPGA as 8, 16 or 32 bit wide words, as
+configured by the "format" attribute. Whenever possible, the driver attempts
+to hide this when the pipe is accessed differently from its natural alignment.
+For example, reading single bytes from a pipe with 32 bit granularity works
+with no issues. Writing single bytes to pipes with 16 or 32 bit granularity
+will also work, but the driver can't send partially completed words to the
+FPGA, so the transmission of up to one word may be held until it's fully
+occupied with user data.
+
+This somewhat complicates the handling of host to FPGA streams, because
+when a buffer is flushed, it may contain up to 3 bytes don't form a word in
+the FPGA, and hence can't be sent. To prevent loss of data, these leftover
+bytes need to be moved to the next buffer. The parts in xillybus_core.c
+that mention "leftovers" in some way are related to this complication.
+
+Probing
+-------
+
+As mentioned earlier, the number of pipes that are created when the driver
+loads and their attributes depend on the Xillybus IP core in the FPGA. During
+the driver's initialization, a blob containing configuration info, the
+Interface Description Table (IDT), is sent from the FPGA to the host. The
+bootstrap process is done in three phases:
+
+1. Acquire the length of the IDT, so a buffer can be allocated for it. This
+ is done by sending a quiesce command to the device, since the acknowledge
+ for this command contains the IDT's buffer length.
+
+2. Acquire the IDT itself.
+
+3. Create the interfaces according to the IDT.
+
+Buffer allocation
+-----------------
+
+In order to simplify the logic that prevents illegal boundary crossings of
+PCIe packets, the following rule applies: If a buffer is smaller than 4kB,
+it must not cross a 4kB boundary. Otherwise, it must be 4kB aligned. The
+xilly_setupchannels() functions allocates these buffers by requesting whole
+pages from the kernel, and diving them into DMA buffers as necessary. Since
+all buffers' sizes are powers of two, it's possible to pack any set of such
+buffers, with a maximal waste of one page of memory.
+
+All buffers are allocated when the driver is loaded. This is necessary,
+since large continuous physical memory segments are sometimes requested,
+which are more likely to be available when the system is freshly booted.
+
+The allocation of buffer memory takes place in the same order they appear in
+the IDT. The driver relies on a rule that the pipes are sorted with decreasing
+buffer size in the IDT. If a requested buffer is larger or equal to a page,
+the necessary number of pages is requested from the kernel, and these are
+used for this buffer. If the requested buffer is smaller than a page, one
+single page is requested from the kernel, and that page is partially used.
+Or, if there already is a partially used page at hand, the buffer is packed
+into that page. It can be shown that all pages requested from the kernel
+(except possibly for the last) are 100% utilized this way.
+
+The "nonempty" message (supporting poll)
+----------------------------------------
+
+In order to support the "poll" method (and hence select() ), there is a small
+catch regarding the FPGA to host direction: The FPGA may have filled a DMA
+buffer with some data, but not submitted that buffer. If the host waited for
+the buffer's submission by the FPGA, there would be a possibility that the
+FPGA side has sent data, but a select() call would still block, because the
+host has not received any notification about this. This is solved with
+XILLYMSG_OPCODE_NONEMPTY messages sent by the FPGA when a channel goes from
+completely empty to containing some data.
+
+These messages are used only to support poll() and select(). The IP core can
+be configured not to send them for a slight reduction of bandwidth.
--- /dev/null
+========================================
+Writing Device Drivers for Zorro Devices
+========================================
+
+:Author: Written by Geert Uytterhoeven <geert@linux-m68k.org>
+:Last revised: September 5, 2003
+
+
+Introduction
+------------
+
+The Zorro bus is the bus used in the Amiga family of computers. Thanks to
+AutoConfig(tm), it's 100% Plug-and-Play.
+
+There are two types of Zorro buses, Zorro II and Zorro III:
+
+ - The Zorro II address space is 24-bit and lies within the first 16 MB of the
+ Amiga's address map.
+
+ - Zorro III is a 32-bit extension of Zorro II, which is backwards compatible
+ with Zorro II. The Zorro III address space lies outside the first 16 MB.
+
+
+Probing for Zorro Devices
+-------------------------
+
+Zorro devices are found by calling ``zorro_find_device()``, which returns a
+pointer to the ``next`` Zorro device with the specified Zorro ID. A probe loop
+for the board with Zorro ID ``ZORRO_PROD_xxx`` looks like::
+
+ struct zorro_dev *z = NULL;
+
+ while ((z = zorro_find_device(ZORRO_PROD_xxx, z))) {
+ if (!zorro_request_region(z->resource.start+MY_START, MY_SIZE,
+ "My explanation"))
+ ...
+ }
+
+``ZORRO_WILDCARD`` acts as a wildcard and finds any Zorro device. If your driver
+supports different types of boards, you can use a construct like::
+
+ struct zorro_dev *z = NULL;
+
+ while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
+ if (z->id != ZORRO_PROD_xxx1 && z->id != ZORRO_PROD_xxx2 && ...)
+ continue;
+ if (!zorro_request_region(z->resource.start+MY_START, MY_SIZE,
+ "My explanation"))
+ ...
+ }
+
+
+Zorro Resources
+---------------
+
+Before you can access a Zorro device's registers, you have to make sure it's
+not yet in use. This is done using the I/O memory space resource management
+functions::
+
+ request_mem_region()
+ release_mem_region()
+
+Shortcuts to claim the whole device's address space are provided as well::
+
+ zorro_request_device
+ zorro_release_device
+
+
+Accessing the Zorro Address Space
+---------------------------------
+
+The address regions in the Zorro device resources are Zorro bus address
+regions. Due to the identity bus-physical address mapping on the Zorro bus,
+they are CPU physical addresses as well.
+
+The treatment of these regions depends on the type of Zorro space:
+
+ - Zorro II address space is always mapped and does not have to be mapped
+ explicitly using z_ioremap().
+
+ Conversion from bus/physical Zorro II addresses to kernel virtual addresses
+ and vice versa is done using::
+
+ virt_addr = ZTWO_VADDR(bus_addr);
+ bus_addr = ZTWO_PADDR(virt_addr);
+
+ - Zorro III address space must be mapped explicitly using z_ioremap() first
+ before it can be accessed::
+
+ virt_addr = z_ioremap(bus_addr, size);
+ ...
+ z_iounmap(virt_addr);
+
+
+References
+----------
+
+#. linux/include/linux/zorro.h
+#. linux/include/uapi/linux/zorro.h
+#. linux/include/uapi/linux/zorro_ids.h
+#. linux/arch/m68k/include/asm/zorro.h
+#. linux/drivers/zorro
+#. /proc/bus/zorro
+
+++ /dev/null
-================
-EISA bus support
-================
-
-:Author: Marc Zyngier <maz@wild-wind.fr.eu.org>
-
-This document groups random notes about porting EISA drivers to the
-new EISA/sysfs API.
-
-Starting from version 2.5.59, the EISA bus is almost given the same
-status as other much more mainstream busses such as PCI or USB. This
-has been possible through sysfs, which defines a nice enough set of
-abstractions to manage busses, devices and drivers.
-
-Although the new API is quite simple to use, converting existing
-drivers to the new infrastructure is not an easy task (mostly because
-detection code is generally also used to probe ISA cards). Moreover,
-most EISA drivers are among the oldest Linux drivers so, as you can
-imagine, some dust has settled here over the years.
-
-The EISA infrastructure is made up of three parts:
-
- - The bus code implements most of the generic code. It is shared
- among all the architectures that the EISA code runs on. It
- implements bus probing (detecting EISA cards available on the bus),
- allocates I/O resources, allows fancy naming through sysfs, and
- offers interfaces for driver to register.
-
- - The bus root driver implements the glue between the bus hardware
- and the generic bus code. It is responsible for discovering the
- device implementing the bus, and setting it up to be latter probed
- by the bus code. This can go from something as simple as reserving
- an I/O region on x86, to the rather more complex, like the hppa
- EISA code. This is the part to implement in order to have EISA
- running on an "new" platform.
-
- - The driver offers the bus a list of devices that it manages, and
- implements the necessary callbacks to probe and release devices
- whenever told to.
-
-Every function/structure below lives in <linux/eisa.h>, which depends
-heavily on <linux/device.h>.
-
-Bus root driver
-===============
-
-::
-
- int eisa_root_register (struct eisa_root_device *root);
-
-The eisa_root_register function is used to declare a device as the
-root of an EISA bus. The eisa_root_device structure holds a reference
-to this device, as well as some parameters for probing purposes::
-
- struct eisa_root_device {
- struct device *dev; /* Pointer to bridge device */
- struct resource *res;
- unsigned long bus_base_addr;
- int slots; /* Max slot number */
- int force_probe; /* Probe even when no slot 0 */
- u64 dma_mask; /* from bridge device */
- int bus_nr; /* Set by eisa_root_register */
- struct resource eisa_root_res; /* ditto */
- };
-
-============= ======================================================
-node used for eisa_root_register internal purpose
-dev pointer to the root device
-res root device I/O resource
-bus_base_addr slot 0 address on this bus
-slots max slot number to probe
-force_probe Probe even when slot 0 is empty (no EISA mainboard)
-dma_mask Default DMA mask. Usually the bridge device dma_mask.
-bus_nr unique bus id, set by eisa_root_register
-============= ======================================================
-
-Driver
-======
-
-::
-
- int eisa_driver_register (struct eisa_driver *edrv);
- void eisa_driver_unregister (struct eisa_driver *edrv);
-
-Clear enough ?
-
-::
-
- struct eisa_device_id {
- char sig[EISA_SIG_LEN];
- unsigned long driver_data;
- };
-
- struct eisa_driver {
- const struct eisa_device_id *id_table;
- struct device_driver driver;
- };
-
-=============== ====================================================
-id_table an array of NULL terminated EISA id strings,
- followed by an empty string. Each string can
- optionally be paired with a driver-dependent value
- (driver_data).
-
-driver a generic driver, such as described in
- Documentation/driver-api/driver-model/driver.rst. Only .name,
- .probe and .remove members are mandatory.
-=============== ====================================================
-
-An example is the 3c59x driver::
-
- static struct eisa_device_id vortex_eisa_ids[] = {
- { "TCM5920", EISA_3C592_OFFSET },
- { "TCM5970", EISA_3C597_OFFSET },
- { "" }
- };
-
- static struct eisa_driver vortex_eisa_driver = {
- .id_table = vortex_eisa_ids,
- .driver = {
- .name = "3c59x",
- .probe = vortex_eisa_probe,
- .remove = vortex_eisa_remove
- }
- };
-
-Device
-======
-
-The sysfs framework calls .probe and .remove functions upon device
-discovery and removal (note that the .remove function is only called
-when driver is built as a module).
-
-Both functions are passed a pointer to a 'struct device', which is
-encapsulated in a 'struct eisa_device' described as follows::
-
- struct eisa_device {
- struct eisa_device_id id;
- int slot;
- int state;
- unsigned long base_addr;
- struct resource res[EISA_MAX_RESOURCES];
- u64 dma_mask;
- struct device dev; /* generic device */
- };
-
-======== ============================================================
-id EISA id, as read from device. id.driver_data is set from the
- matching driver EISA id.
-slot slot number which the device was detected on
-state set of flags indicating the state of the device. Current
- flags are EISA_CONFIG_ENABLED and EISA_CONFIG_FORCED.
-res set of four 256 bytes I/O regions allocated to this device
-dma_mask DMA mask set from the parent device.
-dev generic device (see Documentation/driver-api/driver-model/device.rst)
-======== ============================================================
-
-You can get the 'struct eisa_device' from 'struct device' using the
-'to_eisa_device' macro.
-
-Misc stuff
-==========
-
-::
-
- void eisa_set_drvdata (struct eisa_device *edev, void *data);
-
-Stores data into the device's driver_data area.
-
-::
-
- void *eisa_get_drvdata (struct eisa_device *edev):
-
-Gets the pointer previously stored into the device's driver_data area.
-
-::
-
- int eisa_get_region_index (void *addr);
-
-Returns the region number (0 <= x < EISA_MAX_RESOURCES) of a given
-address.
-
-Kernel parameters
-=================
-
-eisa_bus.enable_dev
- A comma-separated list of slots to be enabled, even if the firmware
- set the card as disabled. The driver must be able to properly
- initialize the device in such conditions.
-
-eisa_bus.disable_dev
- A comma-separated list of slots to be enabled, even if the firmware
- set the card as enabled. The driver won't be called to handle this
- device.
-
-virtual_root.force_probe
- Force the probing code to probe EISA slots even when it cannot find an
- EISA compliant mainboard (nothing appears on slot 0). Defaults to 0
- (don't force), and set to 1 (force probing) when either
- CONFIG_ALPHA_JENSEN or CONFIG_EISA_VLB_PRIMING are set.
-
-Random notes
-============
-
-Converting an EISA driver to the new API mostly involves *deleting*
-code (since probing is now in the core EISA code). Unfortunately, most
-drivers share their probing routine between ISA, and EISA. Special
-care must be taken when ripping out the EISA code, so other busses
-won't suffer from these surgical strikes...
-
-You *must not* expect any EISA device to be detected when returning
-from eisa_driver_register, since the chances are that the bus has not
-yet been probed. In fact, that's what happens most of the time (the
-bus root driver usually kicks in rather late in the boot process).
-Unfortunately, most drivers are doing the probing by themselves, and
-expect to have explored the whole machine when they exit their probe
-routine.
-
-For example, switching your favorite EISA SCSI card to the "hotplug"
-model is "the right thing"(tm).
-
-Thanks
-======
-
-I'd like to thank the following people for their help:
-
-- Xavier Benigni for lending me a wonderful Alpha Jensen,
-- James Bottomley, Jeff Garzik for getting this stuff into the kernel,
-- Andries Brouwer for contributing numerous EISA ids,
-- Catrin Jones for coping with far too many machines at home.
Assuming the VGA driver can be unloaded, one must first unbind the VGA driver
from the console layer before unloading the driver. The VGA driver cannot be
unloaded if it is still bound to the console layer. (See
-Documentation/console/console.rst for more information).
+Documentation/driver-api/console.rst for more information).
This is more complicated in the case of the framebuffer console (fbcon),
because fbcon is an intermediate layer between the console and the drivers::
fbcon.
So, how do we unbind fbcon from the console? Part of the answer is in
-Documentation/console/console.rst. To summarize:
+Documentation/driver-api/console.rst. To summarize:
Echo a value to the bind file that represents the framebuffer console
driver. So assuming vtcon1 represents fbcon, then::
+++ /dev/null
-===========
-ISA Drivers
-===========
-
-The following text is adapted from the commit message of the initial
-commit of the ISA bus driver authored by Rene Herman.
-
-During the recent "isa drivers using platform devices" discussion it was
-pointed out that (ALSA) ISA drivers ran into the problem of not having
-the option to fail driver load (device registration rather) upon not
-finding their hardware due to a probe() error not being passed up
-through the driver model. In the course of that, I suggested a separate
-ISA bus might be best; Russell King agreed and suggested this bus could
-use the .match() method for the actual device discovery.
-
-The attached does this. For this old non (generically) discoverable ISA
-hardware only the driver itself can do discovery so as a difference with
-the platform_bus, this isa_bus also distributes match() up to the
-driver.
-
-As another difference: these devices only exist in the driver model due
-to the driver creating them because it might want to drive them, meaning
-that all device creation has been made internal as well.
-
-The usage model this provides is nice, and has been acked from the ALSA
-side by Takashi Iwai and Jaroslav Kysela. The ALSA driver module_init's
-now (for oldisa-only drivers) become::
-
- static int __init alsa_card_foo_init(void)
- {
- return isa_register_driver(&snd_foo_isa_driver, SNDRV_CARDS);
- }
-
- static void __exit alsa_card_foo_exit(void)
- {
- isa_unregister_driver(&snd_foo_isa_driver);
- }
-
-Quite like the other bus models therefore. This removes a lot of
-duplicated init code from the ALSA ISA drivers.
-
-The passed in isa_driver struct is the regular driver struct embedding a
-struct device_driver, the normal probe/remove/shutdown/suspend/resume
-callbacks, and as indicated that .match callback.
-
-The "SNDRV_CARDS" you see being passed in is a "unsigned int ndev"
-parameter, indicating how many devices to create and call our methods
-with.
-
-The platform_driver callbacks are called with a platform_device param;
-the isa_driver callbacks are being called with a ``struct device *dev,
-unsigned int id`` pair directly -- with the device creation completely
-internal to the bus it's much cleaner to not leak isa_dev's by passing
-them in at all. The id is the only thing we ever want other then the
-struct device anyways, and it makes for nicer code in the callbacks as
-well.
-
-With this additional .match() callback ISA drivers have all options. If
-ALSA would want to keep the old non-load behaviour, it could stick all
-of the old .probe in .match, which would only keep them registered after
-everything was found to be present and accounted for. If it wanted the
-behaviour of always loading as it inadvertently did for a bit after the
-changeover to platform devices, it could just not provide a .match() and
-do everything in .probe() as before.
-
-If it, as Takashi Iwai already suggested earlier as a way of following
-the model from saner buses more closely, wants to load when a later bind
-could conceivably succeed, it could use .match() for the prerequisites
-(such as checking the user wants the card enabled and that port/irq/dma
-values have been passed in) and .probe() for everything else. This is
-the nicest model.
-
-To the code...
-
-This exports only two functions; isa_{,un}register_driver().
-
-isa_register_driver() register's the struct device_driver, and then
-loops over the passed in ndev creating devices and registering them.
-This causes the bus match method to be called for them, which is::
-
- int isa_bus_match(struct device *dev, struct device_driver *driver)
- {
- struct isa_driver *isa_driver = to_isa_driver(driver);
-
- if (dev->platform_data == isa_driver) {
- if (!isa_driver->match ||
- isa_driver->match(dev, to_isa_dev(dev)->id))
- return 1;
- dev->platform_data = NULL;
- }
- return 0;
- }
-
-The first thing this does is check if this device is in fact one of this
-driver's devices by seeing if the device's platform_data pointer is set
-to this driver. Platform devices compare strings, but we don't need to
-do that with everything being internal, so isa_register_driver() abuses
-dev->platform_data as a isa_driver pointer which we can then check here.
-I believe platform_data is available for this, but if rather not, moving
-the isa_driver pointer to the private struct isa_dev is ofcourse fine as
-well.
-
-Then, if the the driver did not provide a .match, it matches. If it did,
-the driver match() method is called to determine a match.
-
-If it did **not** match, dev->platform_data is reset to indicate this to
-isa_register_driver which can then unregister the device again.
-
-If during all this, there's any error, or no devices matched at all
-everything is backed out again and the error, or -ENODEV, is returned.
-
-isa_unregister_driver() just unregisters the matched devices and the
-driver itself.
-
-module_isa_driver is a helper macro for ISA drivers which do not do
-anything special in module init/exit. This eliminates a lot of
-boilerplate code. Each module may only use this macro once, and calling
-it replaces module_init and module_exit.
-
-max_num_isa_dev is a macro to determine the maximum possible number of
-ISA devices which may be registered in the I/O port address space given
-the address extent of the ISA devices.
+++ /dev/null
-==========================================================
-ISA Plug & Play support by Jaroslav Kysela <perex@suse.cz>
-==========================================================
-
-Interface /proc/isapnp
-======================
-
-The interface has been removed. See pnp.txt for more details.
-
-Interface /proc/bus/isapnp
-==========================
-
-This directory allows access to ISA PnP cards and logical devices.
-The regular files contain the contents of ISA PnP registers for
-a logical device.
+++ /dev/null
-pblk: Physical Block Device Target
-==================================
-
-pblk implements a fully associative, host-based FTL that exposes a traditional
-block I/O interface. Its primary responsibilities are:
-
- - Map logical addresses onto physical addresses (4KB granularity) in a
- logical-to-physical (L2P) table.
- - Maintain the integrity and consistency of the L2P table as well as its
- recovery from normal tear down and power outage.
- - Deal with controller- and media-specific constrains.
- - Handle I/O errors.
- - Implement garbage collection.
- - Maintain consistency across the I/O stack during synchronization points.
-
-For more information please refer to:
-
- http://lightnvm.io
-
-which maintains updated FAQs, manual pages, technical documentation, tools,
-contacts, etc.
+++ /dev/null
-=================
-MEN Chameleon Bus
-=================
-
-.. Table of Contents
- =================
- 1 Introduction
- 1.1 Scope of this Document
- 1.2 Limitations of the current implementation
- 2 Architecture
- 2.1 MEN Chameleon Bus
- 2.2 Carrier Devices
- 2.3 Parser
- 3 Resource handling
- 3.1 Memory Resources
- 3.2 IRQs
- 4 Writing an MCB driver
- 4.1 The driver structure
- 4.2 Probing and attaching
- 4.3 Initializing the driver
-
-
-Introduction
-============
-
-This document describes the architecture and implementation of the MEN
-Chameleon Bus (called MCB throughout this document).
-
-Scope of this Document
-----------------------
-
-This document is intended to be a short overview of the current
-implementation and does by no means describe the complete possibilities of MCB
-based devices.
-
-Limitations of the current implementation
------------------------------------------
-
-The current implementation is limited to PCI and PCIe based carrier devices
-that only use a single memory resource and share the PCI legacy IRQ. Not
-implemented are:
-
-- Multi-resource MCB devices like the VME Controller or M-Module carrier.
-- MCB devices that need another MCB device, like SRAM for a DMA Controller's
- buffer descriptors or a video controller's video memory.
-- A per-carrier IRQ domain for carrier devices that have one (or more) IRQs
- per MCB device like PCIe based carriers with MSI or MSI-X support.
-
-Architecture
-============
-
-MCB is divided into 3 functional blocks:
-
-- The MEN Chameleon Bus itself,
-- drivers for MCB Carrier Devices and
-- the parser for the Chameleon table.
-
-MEN Chameleon Bus
------------------
-
-The MEN Chameleon Bus is an artificial bus system that attaches to a so
-called Chameleon FPGA device found on some hardware produced my MEN Mikro
-Elektronik GmbH. These devices are multi-function devices implemented in a
-single FPGA and usually attached via some sort of PCI or PCIe link. Each
-FPGA contains a header section describing the content of the FPGA. The
-header lists the device id, PCI BAR, offset from the beginning of the PCI
-BAR, size in the FPGA, interrupt number and some other properties currently
-not handled by the MCB implementation.
-
-Carrier Devices
----------------
-
-A carrier device is just an abstraction for the real world physical bus the
-Chameleon FPGA is attached to. Some IP Core drivers may need to interact with
-properties of the carrier device (like querying the IRQ number of a PCI
-device). To provide abstraction from the real hardware bus, an MCB carrier
-device provides callback methods to translate the driver's MCB function calls
-to hardware related function calls. For example a carrier device may
-implement the get_irq() method which can be translated into a hardware bus
-query for the IRQ number the device should use.
-
-Parser
-------
-
-The parser reads the first 512 bytes of a Chameleon device and parses the
-Chameleon table. Currently the parser only supports the Chameleon v2 variant
-of the Chameleon table but can easily be adopted to support an older or
-possible future variant. While parsing the table's entries new MCB devices
-are allocated and their resources are assigned according to the resource
-assignment in the Chameleon table. After resource assignment is finished, the
-MCB devices are registered at the MCB and thus at the driver core of the
-Linux kernel.
-
-Resource handling
-=================
-
-The current implementation assigns exactly one memory and one IRQ resource
-per MCB device. But this is likely going to change in the future.
-
-Memory Resources
-----------------
-
-Each MCB device has exactly one memory resource, which can be requested from
-the MCB bus. This memory resource is the physical address of the MCB device
-inside the carrier and is intended to be passed to ioremap() and friends. It
-is already requested from the kernel by calling request_mem_region().
-
-IRQs
-----
-
-Each MCB device has exactly one IRQ resource, which can be requested from the
-MCB bus. If a carrier device driver implements the ->get_irq() callback
-method, the IRQ number assigned by the carrier device will be returned,
-otherwise the IRQ number inside the Chameleon table will be returned. This
-number is suitable to be passed to request_irq().
-
-Writing an MCB driver
-=====================
-
-The driver structure
---------------------
-
-Each MCB driver has a structure to identify the device driver as well as
-device ids which identify the IP Core inside the FPGA. The driver structure
-also contains callback methods which get executed on driver probe and
-removal from the system::
-
- static const struct mcb_device_id foo_ids[] = {
- { .device = 0x123 },
- { }
- };
- MODULE_DEVICE_TABLE(mcb, foo_ids);
-
- static struct mcb_driver foo_driver = {
- driver = {
- .name = "foo-bar",
- .owner = THIS_MODULE,
- },
- .probe = foo_probe,
- .remove = foo_remove,
- .id_table = foo_ids,
- };
-
-Probing and attaching
----------------------
-
-When a driver is loaded and the MCB devices it services are found, the MCB
-core will call the driver's probe callback method. When the driver is removed
-from the system, the MCB core will call the driver's remove callback method::
-
- static init foo_probe(struct mcb_device *mdev, const struct mcb_device_id *id);
- static void foo_remove(struct mcb_device *mdev);
-
-Initializing the driver
------------------------
-
-When the kernel is booted or your foo driver module is inserted, you have to
-perform driver initialization. Usually it is enough to register your driver
-module at the MCB core::
-
- static int __init foo_init(void)
- {
- return mcb_register_driver(&foo_driver);
- }
- module_init(foo_init);
-
- static void __exit foo_exit(void)
- {
- mcb_unregister_driver(&foo_driver);
- }
- module_exit(foo_exit);
-
-The module_mcb_driver() macro can be used to reduce the above code::
-
- module_mcb_driver(foo_driver);
+++ /dev/null
-===========
-NTB Drivers
-===========
-
-NTB (Non-Transparent Bridge) is a type of PCI-Express bridge chip that connects
-the separate memory systems of two or more computers to the same PCI-Express
-fabric. Existing NTB hardware supports a common feature set: doorbell
-registers and memory translation windows, as well as non common features like
-scratchpad and message registers. Scratchpad registers are read-and-writable
-registers that are accessible from either side of the device, so that peers can
-exchange a small amount of information at a fixed address. Message registers can
-be utilized for the same purpose. Additionally they are provided with with
-special status bits to make sure the information isn't rewritten by another
-peer. Doorbell registers provide a way for peers to send interrupt events.
-Memory windows allow translated read and write access to the peer memory.
-
-NTB Core Driver (ntb)
-=====================
-
-The NTB core driver defines an api wrapping the common feature set, and allows
-clients interested in NTB features to discover NTB the devices supported by
-hardware drivers. The term "client" is used here to mean an upper layer
-component making use of the NTB api. The term "driver," or "hardware driver,"
-is used here to mean a driver for a specific vendor and model of NTB hardware.
-
-NTB Client Drivers
-==================
-
-NTB client drivers should register with the NTB core driver. After
-registering, the client probe and remove functions will be called appropriately
-as ntb hardware, or hardware drivers, are inserted and removed. The
-registration uses the Linux Device framework, so it should feel familiar to
-anyone who has written a pci driver.
-
-NTB Typical client driver implementation
-----------------------------------------
-
-Primary purpose of NTB is to share some peace of memory between at least two
-systems. So the NTB device features like Scratchpad/Message registers are
-mainly used to perform the proper memory window initialization. Typically
-there are two types of memory window interfaces supported by the NTB API:
-inbound translation configured on the local ntb port and outbound translation
-configured by the peer, on the peer ntb port. The first type is
-depicted on the next figure::
-
- Inbound translation:
-
- Memory: Local NTB Port: Peer NTB Port: Peer MMIO:
- ____________
- | dma-mapped |-ntb_mw_set_trans(addr) |
- | memory | _v____________ | ______________
- | (addr) |<======| MW xlat addr |<====| MW base addr |<== memory-mapped IO
- |------------| |--------------| | |--------------|
-
-So typical scenario of the first type memory window initialization looks:
-1) allocate a memory region, 2) put translated address to NTB config,
-3) somehow notify a peer device of performed initialization, 4) peer device
-maps corresponding outbound memory window so to have access to the shared
-memory region.
-
-The second type of interface, that implies the shared windows being
-initialized by a peer device, is depicted on the figure::
-
- Outbound translation:
-
- Memory: Local NTB Port: Peer NTB Port: Peer MMIO:
- ____________ ______________
- | dma-mapped | | | MW base addr |<== memory-mapped IO
- | memory | | |--------------|
- | (addr) |<===================| MW xlat addr |<-ntb_peer_mw_set_trans(addr)
- |------------| | |--------------|
-
-Typical scenario of the second type interface initialization would be:
-1) allocate a memory region, 2) somehow deliver a translated address to a peer
-device, 3) peer puts the translated address to NTB config, 4) peer device maps
-outbound memory window so to have access to the shared memory region.
-
-As one can see the described scenarios can be combined in one portable
-algorithm.
-
- Local device:
- 1) Allocate memory for a shared window
- 2) Initialize memory window by translated address of the allocated region
- (it may fail if local memory window initialization is unsupported)
- 3) Send the translated address and memory window index to a peer device
-
- Peer device:
- 1) Initialize memory window with retrieved address of the allocated
- by another device memory region (it may fail if peer memory window
- initialization is unsupported)
- 2) Map outbound memory window
-
-In accordance with this scenario, the NTB Memory Window API can be used as
-follows:
-
- Local device:
- 1) ntb_mw_count(pidx) - retrieve number of memory ranges, which can
- be allocated for memory windows between local device and peer device
- of port with specified index.
- 2) ntb_get_align(pidx, midx) - retrieve parameters restricting the
- shared memory region alignment and size. Then memory can be properly
- allocated.
- 3) Allocate physically contiguous memory region in compliance with
- restrictions retrieved in 2).
- 4) ntb_mw_set_trans(pidx, midx) - try to set translation address of
- the memory window with specified index for the defined peer device
- (it may fail if local translated address setting is not supported)
- 5) Send translated base address (usually together with memory window
- number) to the peer device using, for instance, scratchpad or message
- registers.
-
- Peer device:
- 1) ntb_peer_mw_set_trans(pidx, midx) - try to set received from other
- device (related to pidx) translated address for specified memory
- window. It may fail if retrieved address, for instance, exceeds
- maximum possible address or isn't properly aligned.
- 2) ntb_peer_mw_get_addr(widx) - retrieve MMIO address to map the memory
- window so to have an access to the shared memory.
-
-Also it is worth to note, that method ntb_mw_count(pidx) should return the
-same value as ntb_peer_mw_count() on the peer with port index - pidx.
-
-NTB Transport Client (ntb\_transport) and NTB Netdev (ntb\_netdev)
-------------------------------------------------------------------
-
-The primary client for NTB is the Transport client, used in tandem with NTB
-Netdev. These drivers function together to create a logical link to the peer,
-across the ntb, to exchange packets of network data. The Transport client
-establishes a logical link to the peer, and creates queue pairs to exchange
-messages and data. The NTB Netdev then creates an ethernet device using a
-Transport queue pair. Network data is copied between socket buffers and the
-Transport queue pair buffer. The Transport client may be used for other things
-besides Netdev, however no other applications have yet been written.
-
-NTB Ping Pong Test Client (ntb\_pingpong)
------------------------------------------
-
-The Ping Pong test client serves as a demonstration to exercise the doorbell
-and scratchpad registers of NTB hardware, and as an example simple NTB client.
-Ping Pong enables the link when started, waits for the NTB link to come up, and
-then proceeds to read and write the doorbell scratchpad registers of the NTB.
-The peers interrupt each other using a bit mask of doorbell bits, which is
-shifted by one in each round, to test the behavior of multiple doorbell bits
-and interrupt vectors. The Ping Pong driver also reads the first local
-scratchpad, and writes the value plus one to the first peer scratchpad, each
-round before writing the peer doorbell register.
-
-Module Parameters:
-
-* unsafe - Some hardware has known issues with scratchpad and doorbell
- registers. By default, Ping Pong will not attempt to exercise such
- hardware. You may override this behavior at your own risk by setting
- unsafe=1.
-* delay\_ms - Specify the delay between receiving a doorbell
- interrupt event and setting the peer doorbell register for the next
- round.
-* init\_db - Specify the doorbell bits to start new series of rounds. A new
- series begins once all the doorbell bits have been shifted out of
- range.
-* dyndbg - It is suggested to specify dyndbg=+p when loading this module, and
- then to observe debugging output on the console.
-
-NTB Tool Test Client (ntb\_tool)
---------------------------------
-
-The Tool test client serves for debugging, primarily, ntb hardware and drivers.
-The Tool provides access through debugfs for reading, setting, and clearing the
-NTB doorbell, and reading and writing scratchpads.
-
-The Tool does not currently have any module parameters.
-
-Debugfs Files:
-
-* *debugfs*/ntb\_tool/*hw*/
- A directory in debugfs will be created for each
- NTB device probed by the tool. This directory is shortened to *hw*
- below.
-* *hw*/db
- This file is used to read, set, and clear the local doorbell. Not
- all operations may be supported by all hardware. To read the doorbell,
- read the file. To set the doorbell, write `s` followed by the bits to
- set (eg: `echo 's 0x0101' > db`). To clear the doorbell, write `c`
- followed by the bits to clear.
-* *hw*/mask
- This file is used to read, set, and clear the local doorbell mask.
- See *db* for details.
-* *hw*/peer\_db
- This file is used to read, set, and clear the peer doorbell.
- See *db* for details.
-* *hw*/peer\_mask
- This file is used to read, set, and clear the peer doorbell
- mask. See *db* for details.
-* *hw*/spad
- This file is used to read and write local scratchpads. To read
- the values of all scratchpads, read the file. To write values, write a
- series of pairs of scratchpad number and value
- (eg: `echo '4 0x123 7 0xabc' > spad`
- # to set scratchpads `4` and `7` to `0x123` and `0xabc`, respectively).
-* *hw*/peer\_spad
- This file is used to read and write peer scratchpads. See
- *spad* for details.
-
-NTB Hardware Drivers
-====================
-
-NTB hardware drivers should register devices with the NTB core driver. After
-registering, clients probe and remove functions will be called.
-
-NTB Intel Hardware Driver (ntb\_hw\_intel)
-------------------------------------------
-
-The Intel hardware driver supports NTB on Xeon and Atom CPUs.
-
-Module Parameters:
-
-* b2b\_mw\_idx
- If the peer ntb is to be accessed via a memory window, then use
- this memory window to access the peer ntb. A value of zero or positive
- starts from the first mw idx, and a negative value starts from the last
- mw idx. Both sides MUST set the same value here! The default value is
- `-1`.
-* b2b\_mw\_share
- If the peer ntb is to be accessed via a memory window, and if
- the memory window is large enough, still allow the client to use the
- second half of the memory window for address translation to the peer.
-* xeon\_b2b\_usd\_bar2\_addr64
- If using B2B topology on Xeon hardware, use
- this 64 bit address on the bus between the NTB devices for the window
- at BAR2, on the upstream side of the link.
-* xeon\_b2b\_usd\_bar4\_addr64 - See *xeon\_b2b\_bar2\_addr64*.
-* xeon\_b2b\_usd\_bar4\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
-* xeon\_b2b\_usd\_bar5\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
-* xeon\_b2b\_dsd\_bar2\_addr64 - See *xeon\_b2b\_bar2\_addr64*.
-* xeon\_b2b\_dsd\_bar4\_addr64 - See *xeon\_b2b\_bar2\_addr64*.
-* xeon\_b2b\_dsd\_bar4\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
-* xeon\_b2b\_dsd\_bar5\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
+++ /dev/null
-:orphan:
-
-===============
-NVMEM Subsystem
-===============
-
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-
-This document explains the NVMEM Framework along with the APIs provided,
-and how to use it.
-
-1. Introduction
-===============
-*NVMEM* is the abbreviation for Non Volatile Memory layer. It is used to
-retrieve configuration of SOC or Device specific data from non volatile
-memories like eeprom, efuses and so on.
-
-Before this framework existed, NVMEM drivers like eeprom were stored in
-drivers/misc, where they all had to duplicate pretty much the same code to
-register a sysfs file, allow in-kernel users to access the content of the
-devices they were driving, etc.
-
-This was also a problem as far as other in-kernel users were involved, since
-the solutions used were pretty much different from one driver to another, there
-was a rather big abstraction leak.
-
-This framework aims at solve these problems. It also introduces DT
-representation for consumer devices to go get the data they require (MAC
-Addresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs. This
-framework is based on regmap, so that most of the abstraction available in
-regmap can be reused, across multiple types of buses.
-
-NVMEM Providers
-+++++++++++++++
-
-NVMEM provider refers to an entity that implements methods to initialize, read
-and write the non-volatile memory.
-
-2. Registering/Unregistering the NVMEM provider
-===============================================
-
-A NVMEM provider can register with NVMEM core by supplying relevant
-nvmem configuration to nvmem_register(), on success core would return a valid
-nvmem_device pointer.
-
-nvmem_unregister(nvmem) is used to unregister a previously registered provider.
-
-For example, a simple qfprom case::
-
- static struct nvmem_config econfig = {
- .name = "qfprom",
- .owner = THIS_MODULE,
- };
-
- static int qfprom_probe(struct platform_device *pdev)
- {
- ...
- econfig.dev = &pdev->dev;
- nvmem = nvmem_register(&econfig);
- ...
- }
-
-It is mandatory that the NVMEM provider has a regmap associated with its
-struct device. Failure to do would return error code from nvmem_register().
-
-Users of board files can define and register nvmem cells using the
-nvmem_cell_table struct::
-
- static struct nvmem_cell_info foo_nvmem_cells[] = {
- {
- .name = "macaddr",
- .offset = 0x7f00,
- .bytes = ETH_ALEN,
- }
- };
-
- static struct nvmem_cell_table foo_nvmem_cell_table = {
- .nvmem_name = "i2c-eeprom",
- .cells = foo_nvmem_cells,
- .ncells = ARRAY_SIZE(foo_nvmem_cells),
- };
-
- nvmem_add_cell_table(&foo_nvmem_cell_table);
-
-Additionally it is possible to create nvmem cell lookup entries and register
-them with the nvmem framework from machine code as shown in the example below::
-
- static struct nvmem_cell_lookup foo_nvmem_lookup = {
- .nvmem_name = "i2c-eeprom",
- .cell_name = "macaddr",
- .dev_id = "foo_mac.0",
- .con_id = "mac-address",
- };
-
- nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
-
-NVMEM Consumers
-+++++++++++++++
-
-NVMEM consumers are the entities which make use of the NVMEM provider to
-read from and to NVMEM.
-
-3. NVMEM cell based consumer APIs
-=================================
-
-NVMEM cells are the data entries/fields in the NVMEM.
-The NVMEM framework provides 3 APIs to read/write NVMEM cells::
-
- struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);
- struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);
-
- void nvmem_cell_put(struct nvmem_cell *cell);
- void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
-
- void *nvmem_cell_read(struct nvmem_cell *cell, ssize_t *len);
- int nvmem_cell_write(struct nvmem_cell *cell, void *buf, ssize_t len);
-
-`*nvmem_cell_get()` apis will get a reference to nvmem cell for a given id,
-and nvmem_cell_read/write() can then read or write to the cell.
-Once the usage of the cell is finished the consumer should call
-`*nvmem_cell_put()` to free all the allocation memory for the cell.
-
-4. Direct NVMEM device based consumer APIs
-==========================================
-
-In some instances it is necessary to directly read/write the NVMEM.
-To facilitate such consumers NVMEM framework provides below apis::
-
- struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
- struct nvmem_device *devm_nvmem_device_get(struct device *dev,
- const char *name);
- void nvmem_device_put(struct nvmem_device *nvmem);
- int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
- size_t bytes, void *buf);
- int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
- size_t bytes, void *buf);
- int nvmem_device_cell_read(struct nvmem_device *nvmem,
- struct nvmem_cell_info *info, void *buf);
- int nvmem_device_cell_write(struct nvmem_device *nvmem,
- struct nvmem_cell_info *info, void *buf);
-
-Before the consumers can read/write NVMEM directly, it should get hold
-of nvmem_controller from one of the `*nvmem_device_get()` api.
-
-The difference between these apis and cell based apis is that these apis always
-take nvmem_device as parameter.
-
-5. Releasing a reference to the NVMEM
-=====================================
-
-When a consumer no longer needs the NVMEM, it has to release the reference
-to the NVMEM it has obtained using the APIs mentioned in the above section.
-The NVMEM framework provides 2 APIs to release a reference to the NVMEM::
-
- void nvmem_cell_put(struct nvmem_cell *cell);
- void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
- void nvmem_device_put(struct nvmem_device *nvmem);
- void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem);
-
-Both these APIs are used to release a reference to the NVMEM and
-devm_nvmem_cell_put and devm_nvmem_device_put destroys the devres associated
-with this NVMEM.
-
-Userspace
-+++++++++
-
-6. Userspace binary interface
-==============================
-
-Userspace can read/write the raw NVMEM file located at::
-
- /sys/bus/nvmem/devices/*/nvmem
-
-ex::
-
- hexdump /sys/bus/nvmem/devices/qfprom0/nvmem
-
- 0000000 0000 0000 0000 0000 0000 0000 0000 0000
- *
- 00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00
- 0000000 0000 0000 0000 0000 0000 0000 0000 0000
- ...
- *
- 0001000
-
-7. DeviceTree Binding
-=====================
-
-See Documentation/devicetree/bindings/nvmem/nvmem.txt
+++ /dev/null
-===============================
-PARPORT interface documentation
-===============================
-
-:Time-stamp: <2000-02-24 13:30:20 twaugh>
-
-Described here are the following functions:
-
-Global functions::
- parport_register_driver
- parport_unregister_driver
- parport_enumerate
- parport_register_device
- parport_unregister_device
- parport_claim
- parport_claim_or_block
- parport_release
- parport_yield
- parport_yield_blocking
- parport_wait_peripheral
- parport_poll_peripheral
- parport_wait_event
- parport_negotiate
- parport_read
- parport_write
- parport_open
- parport_close
- parport_device_id
- parport_device_coords
- parport_find_class
- parport_find_device
- parport_set_timeout
-
-Port functions (can be overridden by low-level drivers):
-
- SPP::
- port->ops->read_data
- port->ops->write_data
- port->ops->read_status
- port->ops->read_control
- port->ops->write_control
- port->ops->frob_control
- port->ops->enable_irq
- port->ops->disable_irq
- port->ops->data_forward
- port->ops->data_reverse
-
- EPP::
- port->ops->epp_write_data
- port->ops->epp_read_data
- port->ops->epp_write_addr
- port->ops->epp_read_addr
-
- ECP::
- port->ops->ecp_write_data
- port->ops->ecp_read_data
- port->ops->ecp_write_addr
-
- Other::
- port->ops->nibble_read_data
- port->ops->byte_read_data
- port->ops->compat_write_data
-
-The parport subsystem comprises ``parport`` (the core port-sharing
-code), and a variety of low-level drivers that actually do the port
-accesses. Each low-level driver handles a particular style of port
-(PC, Amiga, and so on).
-
-The parport interface to the device driver author can be broken down
-into global functions and port functions.
-
-The global functions are mostly for communicating between the device
-driver and the parport subsystem: acquiring a list of available ports,
-claiming a port for exclusive use, and so on. They also include
-``generic`` functions for doing standard things that will work on any
-IEEE 1284-capable architecture.
-
-The port functions are provided by the low-level drivers, although the
-core parport module provides generic ``defaults`` for some routines.
-The port functions can be split into three groups: SPP, EPP, and ECP.
-
-SPP (Standard Parallel Port) functions modify so-called ``SPP``
-registers: data, status, and control. The hardware may not actually
-have registers exactly like that, but the PC does and this interface is
-modelled after common PC implementations. Other low-level drivers may
-be able to emulate most of the functionality.
-
-EPP (Enhanced Parallel Port) functions are provided for reading and
-writing in IEEE 1284 EPP mode, and ECP (Extended Capabilities Port)
-functions are used for IEEE 1284 ECP mode. (What about BECP? Does
-anyone care?)
-
-Hardware assistance for EPP and/or ECP transfers may or may not be
-available, and if it is available it may or may not be used. If
-hardware is not used, the transfer will be software-driven. In order
-to cope with peripherals that only tenuously support IEEE 1284, a
-low-level driver specific function is provided, for altering 'fudge
-factors'.
-\f
-Global functions
-================
-
-parport_register_driver - register a device driver with parport
----------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_driver {
- const char *name;
- void (*attach) (struct parport *);
- void (*detach) (struct parport *);
- struct parport_driver *next;
- };
- int parport_register_driver (struct parport_driver *driver);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-In order to be notified about parallel ports when they are detected,
-parport_register_driver should be called. Your driver will
-immediately be notified of all ports that have already been detected,
-and of each new port as low-level drivers are loaded.
-
-A ``struct parport_driver`` contains the textual name of your driver,
-a pointer to a function to handle new ports, and a pointer to a
-function to handle ports going away due to a low-level driver
-unloading. Ports will only be detached if they are not being used
-(i.e. there are no devices registered on them).
-
-The visible parts of the ``struct parport *`` argument given to
-attach/detach are::
-
- struct parport
- {
- struct parport *next; /* next parport in list */
- const char *name; /* port's name */
- unsigned int modes; /* bitfield of hardware modes */
- struct parport_device_info probe_info;
- /* IEEE1284 info */
- int number; /* parport index */
- struct parport_operations *ops;
- ...
- };
-
-There are other members of the structure, but they should not be
-touched.
-
-The ``modes`` member summarises the capabilities of the underlying
-hardware. It consists of flags which may be bitwise-ored together:
-
- ============================= ===============================================
- PARPORT_MODE_PCSPP IBM PC registers are available,
- i.e. functions that act on data,
- control and status registers are
- probably writing directly to the
- hardware.
- PARPORT_MODE_TRISTATE The data drivers may be turned off.
- This allows the data lines to be used
- for reverse (peripheral to host)
- transfers.
- PARPORT_MODE_COMPAT The hardware can assist with
- compatibility-mode (printer)
- transfers, i.e. compat_write_block.
- PARPORT_MODE_EPP The hardware can assist with EPP
- transfers.
- PARPORT_MODE_ECP The hardware can assist with ECP
- transfers.
- PARPORT_MODE_DMA The hardware can use DMA, so you might
- want to pass ISA DMA-able memory
- (i.e. memory allocated using the
- GFP_DMA flag with kmalloc) to the
- low-level driver in order to take
- advantage of it.
- ============================= ===============================================
-
-There may be other flags in ``modes`` as well.
-
-The contents of ``modes`` is advisory only. For example, if the
-hardware is capable of DMA, and PARPORT_MODE_DMA is in ``modes``, it
-doesn't necessarily mean that DMA will always be used when possible.
-Similarly, hardware that is capable of assisting ECP transfers won't
-necessarily be used.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-Zero on success, otherwise an error code.
-
-ERRORS
-^^^^^^
-
-None. (Can it fail? Why return int?)
-
-EXAMPLE
-^^^^^^^
-
-::
-
- static void lp_attach (struct parport *port)
- {
- ...
- private = kmalloc (...);
- dev[count++] = parport_register_device (...);
- ...
- }
-
- static void lp_detach (struct parport *port)
- {
- ...
- }
-
- static struct parport_driver lp_driver = {
- "lp",
- lp_attach,
- lp_detach,
- NULL /* always put NULL here */
- };
-
- int lp_init (void)
- {
- ...
- if (parport_register_driver (&lp_driver)) {
- /* Failed; nothing we can do. */
- return -EIO;
- }
- ...
- }
-
-
-SEE ALSO
-^^^^^^^^
-
-parport_unregister_driver, parport_register_device, parport_enumerate
-
-
-
-parport_unregister_driver - tell parport to forget about this driver
---------------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_driver {
- const char *name;
- void (*attach) (struct parport *);
- void (*detach) (struct parport *);
- struct parport_driver *next;
- };
- void parport_unregister_driver (struct parport_driver *driver);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-This tells parport not to notify the device driver of new ports or of
-ports going away. Registered devices belonging to that driver are NOT
-unregistered: parport_unregister_device must be used for each one.
-
-EXAMPLE
-^^^^^^^
-
-::
-
- void cleanup_module (void)
- {
- ...
- /* Stop notifications. */
- parport_unregister_driver (&lp_driver);
-
- /* Unregister devices. */
- for (i = 0; i < NUM_DEVS; i++)
- parport_unregister_device (dev[i]);
- ...
- }
-
-SEE ALSO
-^^^^^^^^
-
-parport_register_driver, parport_enumerate
-
-
-
-parport_enumerate - retrieve a list of parallel ports (DEPRECATED)
-------------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport *parport_enumerate (void);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Retrieve the first of a list of valid parallel ports for this machine.
-Successive parallel ports can be found using the ``struct parport
-*next`` element of the ``struct parport *`` that is returned. If ``next``
-is NULL, there are no more parallel ports in the list. The number of
-ports in the list will not exceed PARPORT_MAX.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-A ``struct parport *`` describing a valid parallel port for the machine,
-or NULL if there are none.
-
-ERRORS
-^^^^^^
-
-This function can return NULL to indicate that there are no parallel
-ports to use.
-
-EXAMPLE
-^^^^^^^
-
-::
-
- int detect_device (void)
- {
- struct parport *port;
-
- for (port = parport_enumerate ();
- port != NULL;
- port = port->next) {
- /* Try to detect a device on the port... */
- ...
- }
- }
-
- ...
- }
-
-NOTES
-^^^^^
-
-parport_enumerate is deprecated; parport_register_driver should be
-used instead.
-
-SEE ALSO
-^^^^^^^^
-
-parport_register_driver, parport_unregister_driver
-
-
-
-parport_register_device - register to use a port
-------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- typedef int (*preempt_func) (void *handle);
- typedef void (*wakeup_func) (void *handle);
- typedef int (*irq_func) (int irq, void *handle, struct pt_regs *);
-
- struct pardevice *parport_register_device(struct parport *port,
- const char *name,
- preempt_func preempt,
- wakeup_func wakeup,
- irq_func irq,
- int flags,
- void *handle);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Use this function to register your device driver on a parallel port
-(``port``). Once you have done that, you will be able to use
-parport_claim and parport_release in order to use the port.
-
-The (``name``) argument is the name of the device that appears in /proc
-filesystem. The string must be valid for the whole lifetime of the
-device (until parport_unregister_device is called).
-
-This function will register three callbacks into your driver:
-``preempt``, ``wakeup`` and ``irq``. Each of these may be NULL in order to
-indicate that you do not want a callback.
-
-When the ``preempt`` function is called, it is because another driver
-wishes to use the parallel port. The ``preempt`` function should return
-non-zero if the parallel port cannot be released yet -- if zero is
-returned, the port is lost to another driver and the port must be
-re-claimed before use.
-
-The ``wakeup`` function is called once another driver has released the
-port and no other driver has yet claimed it. You can claim the
-parallel port from within the ``wakeup`` function (in which case the
-claim is guaranteed to succeed), or choose not to if you don't need it
-now.
-
-If an interrupt occurs on the parallel port your driver has claimed,
-the ``irq`` function will be called. (Write something about shared
-interrupts here.)
-
-The ``handle`` is a pointer to driver-specific data, and is passed to
-the callback functions.
-
-``flags`` may be a bitwise combination of the following flags:
-
- ===================== =================================================
- Flag Meaning
- ===================== =================================================
- PARPORT_DEV_EXCL The device cannot share the parallel port at all.
- Use this only when absolutely necessary.
- ===================== =================================================
-
-The typedefs are not actually defined -- they are only shown in order
-to make the function prototype more readable.
-
-The visible parts of the returned ``struct pardevice`` are::
-
- struct pardevice {
- struct parport *port; /* Associated port */
- void *private; /* Device driver's 'handle' */
- ...
- };
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-A ``struct pardevice *``: a handle to the registered parallel port
-device that can be used for parport_claim, parport_release, etc.
-
-ERRORS
-^^^^^^
-
-A return value of NULL indicates that there was a problem registering
-a device on that port.
-
-EXAMPLE
-^^^^^^^
-
-::
-
- static int preempt (void *handle)
- {
- if (busy_right_now)
- return 1;
-
- must_reclaim_port = 1;
- return 0;
- }
-
- static void wakeup (void *handle)
- {
- struct toaster *private = handle;
- struct pardevice *dev = private->dev;
- if (!dev) return; /* avoid races */
-
- if (want_port)
- parport_claim (dev);
- }
-
- static int toaster_detect (struct toaster *private, struct parport *port)
- {
- private->dev = parport_register_device (port, "toaster", preempt,
- wakeup, NULL, 0,
- private);
- if (!private->dev)
- /* Couldn't register with parport. */
- return -EIO;
-
- must_reclaim_port = 0;
- busy_right_now = 1;
- parport_claim_or_block (private->dev);
- ...
- /* Don't need the port while the toaster warms up. */
- busy_right_now = 0;
- ...
- busy_right_now = 1;
- if (must_reclaim_port) {
- parport_claim_or_block (private->dev);
- must_reclaim_port = 0;
- }
- ...
- }
-
-SEE ALSO
-^^^^^^^^
-
-parport_unregister_device, parport_claim
-
-
-\f
-parport_unregister_device - finish using a port
------------------------------------------------
-
-SYNPOPSIS
-
-::
-
- #include <linux/parport.h>
-
- void parport_unregister_device (struct pardevice *dev);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-This function is the opposite of parport_register_device. After using
-parport_unregister_device, ``dev`` is no longer a valid device handle.
-
-You should not unregister a device that is currently claimed, although
-if you do it will be released automatically.
-
-EXAMPLE
-^^^^^^^
-
-::
-
- ...
- kfree (dev->private); /* before we lose the pointer */
- parport_unregister_device (dev);
- ...
-
-SEE ALSO
-^^^^^^^^
-
-
-parport_unregister_driver
-\f
-parport_claim, parport_claim_or_block - claim the parallel port for a device
-----------------------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- int parport_claim (struct pardevice *dev);
- int parport_claim_or_block (struct pardevice *dev);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-These functions attempt to gain control of the parallel port on which
-``dev`` is registered. ``parport_claim`` does not block, but
-``parport_claim_or_block`` may do. (Put something here about blocking
-interruptibly or non-interruptibly.)
-
-You should not try to claim a port that you have already claimed.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-A return value of zero indicates that the port was successfully
-claimed, and the caller now has possession of the parallel port.
-
-If ``parport_claim_or_block`` blocks before returning successfully, the
-return value is positive.
-
-ERRORS
-^^^^^^
-
-========== ==========================================================
- -EAGAIN The port is unavailable at the moment, but another attempt
- to claim it may succeed.
-========== ==========================================================
-
-SEE ALSO
-^^^^^^^^
-
-
-parport_release
-\f
-parport_release - release the parallel port
--------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- void parport_release (struct pardevice *dev);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Once a parallel port device has been claimed, it can be released using
-``parport_release``. It cannot fail, but you should not release a
-device that you do not have possession of.
-
-EXAMPLE
-^^^^^^^
-
-::
-
- static size_t write (struct pardevice *dev, const void *buf,
- size_t len)
- {
- ...
- written = dev->port->ops->write_ecp_data (dev->port, buf,
- len);
- parport_release (dev);
- ...
- }
-
-
-SEE ALSO
-^^^^^^^^
-
-change_mode, parport_claim, parport_claim_or_block, parport_yield
-
-
-
-parport_yield, parport_yield_blocking - temporarily release a parallel port
----------------------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- int parport_yield (struct pardevice *dev)
- int parport_yield_blocking (struct pardevice *dev);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-When a driver has control of a parallel port, it may allow another
-driver to temporarily ``borrow`` it. ``parport_yield`` does not block;
-``parport_yield_blocking`` may do.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-A return value of zero indicates that the caller still owns the port
-and the call did not block.
-
-A positive return value from ``parport_yield_blocking`` indicates that
-the caller still owns the port and the call blocked.
-
-A return value of -EAGAIN indicates that the caller no longer owns the
-port, and it must be re-claimed before use.
-
-ERRORS
-^^^^^^
-
-========= ==========================================================
- -EAGAIN Ownership of the parallel port was given away.
-========= ==========================================================
-
-SEE ALSO
-^^^^^^^^
-
-parport_release
-
-
-\f
-parport_wait_peripheral - wait for status lines, up to 35ms
------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- int parport_wait_peripheral (struct parport *port,
- unsigned char mask,
- unsigned char val);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Wait for the status lines in mask to match the values in val.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-======== ==========================================================
- -EINTR a signal is pending
- 0 the status lines in mask have values in val
- 1 timed out while waiting (35ms elapsed)
-======== ==========================================================
-
-SEE ALSO
-^^^^^^^^
-
-parport_poll_peripheral
-
-
-\f
-parport_poll_peripheral - wait for status lines, in usec
---------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- int parport_poll_peripheral (struct parport *port,
- unsigned char mask,
- unsigned char val,
- int usec);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Wait for the status lines in mask to match the values in val.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-======== ==========================================================
- -EINTR a signal is pending
- 0 the status lines in mask have values in val
- 1 timed out while waiting (usec microseconds have elapsed)
-======== ==========================================================
-
-SEE ALSO
-^^^^^^^^
-
-parport_wait_peripheral
-
-
-
-parport_wait_event - wait for an event on a port
-------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- int parport_wait_event (struct parport *port, signed long timeout)
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Wait for an event (e.g. interrupt) on a port. The timeout is in
-jiffies.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-======= ==========================================================
- 0 success
- <0 error (exit as soon as possible)
- >0 timed out
-======= ==========================================================
-
-parport_negotiate - perform IEEE 1284 negotiation
--------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- int parport_negotiate (struct parport *, int mode);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Perform IEEE 1284 negotiation.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-======= ==========================================================
- 0 handshake OK; IEEE 1284 peripheral and mode available
- -1 handshake failed; peripheral not compliant (or none present)
- 1 handshake OK; IEEE 1284 peripheral present but mode not
- available
-======= ==========================================================
-
-SEE ALSO
-^^^^^^^^
-
-parport_read, parport_write
-
-
-
-parport_read - read data from device
-------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- ssize_t parport_read (struct parport *, void *buf, size_t len);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Read data from device in current IEEE 1284 transfer mode. This only
-works for modes that support reverse data transfer.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-If negative, an error code; otherwise the number of bytes transferred.
-
-SEE ALSO
-^^^^^^^^
-
-parport_write, parport_negotiate
-
-
-
-parport_write - write data to device
-------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- ssize_t parport_write (struct parport *, const void *buf, size_t len);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Write data to device in current IEEE 1284 transfer mode. This only
-works for modes that support forward data transfer.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-If negative, an error code; otherwise the number of bytes transferred.
-
-SEE ALSO
-^^^^^^^^
-
-parport_read, parport_negotiate
-
-
-\f
-parport_open - register device for particular device number
------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct pardevice *parport_open (int devnum, const char *name,
- int (*pf) (void *),
- void (*kf) (void *),
- void (*irqf) (int, void *,
- struct pt_regs *),
- int flags, void *handle);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-This is like parport_register_device but takes a device number instead
-of a pointer to a struct parport.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-See parport_register_device. If no device is associated with devnum,
-NULL is returned.
-
-SEE ALSO
-^^^^^^^^
-
-parport_register_device
-
-
-
-parport_close - unregister device for particular device number
---------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- void parport_close (struct pardevice *dev);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-This is the equivalent of parport_unregister_device for parport_open.
-
-SEE ALSO
-^^^^^^^^
-
-parport_unregister_device, parport_open
-
-
-
-parport_device_id - obtain IEEE 1284 Device ID
-----------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- ssize_t parport_device_id (int devnum, char *buffer, size_t len);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Obtains the IEEE 1284 Device ID associated with a given device.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-If negative, an error code; otherwise, the number of bytes of buffer
-that contain the device ID. The format of the device ID is as
-follows::
-
- [length][ID]
-
-The first two bytes indicate the inclusive length of the entire Device
-ID, and are in big-endian order. The ID is a sequence of pairs of the
-form::
-
- key:value;
-
-NOTES
-^^^^^
-
-Many devices have ill-formed IEEE 1284 Device IDs.
-
-SEE ALSO
-^^^^^^^^
-
-parport_find_class, parport_find_device
-
-
-
-parport_device_coords - convert device number to device coordinates
--------------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- int parport_device_coords (int devnum, int *parport, int *mux,
- int *daisy);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Convert between device number (zero-based) and device coordinates
-(port, multiplexor, daisy chain address).
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-Zero on success, in which case the coordinates are (``*parport``, ``*mux``,
-``*daisy``).
-
-SEE ALSO
-^^^^^^^^
-
-parport_open, parport_device_id
-
-
-
-parport_find_class - find a device by its class
------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- typedef enum {
- PARPORT_CLASS_LEGACY = 0, /* Non-IEEE1284 device */
- PARPORT_CLASS_PRINTER,
- PARPORT_CLASS_MODEM,
- PARPORT_CLASS_NET,
- PARPORT_CLASS_HDC, /* Hard disk controller */
- PARPORT_CLASS_PCMCIA,
- PARPORT_CLASS_MEDIA, /* Multimedia device */
- PARPORT_CLASS_FDC, /* Floppy disk controller */
- PARPORT_CLASS_PORTS,
- PARPORT_CLASS_SCANNER,
- PARPORT_CLASS_DIGCAM,
- PARPORT_CLASS_OTHER, /* Anything else */
- PARPORT_CLASS_UNSPEC, /* No CLS field in ID */
- PARPORT_CLASS_SCSIADAPTER
- } parport_device_class;
-
- int parport_find_class (parport_device_class cls, int from);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Find a device by class. The search starts from device number from+1.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-The device number of the next device in that class, or -1 if no such
-device exists.
-
-NOTES
-^^^^^
-
-Example usage::
-
- int devnum = -1;
- while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM, devnum)) != -1) {
- struct pardevice *dev = parport_open (devnum, ...);
- ...
- }
-
-SEE ALSO
-^^^^^^^^
-
-parport_find_device, parport_open, parport_device_id
-
-
-
-parport_find_device - find a device by its class
-------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- int parport_find_device (const char *mfg, const char *mdl, int from);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Find a device by vendor and model. The search starts from device
-number from+1.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-The device number of the next device matching the specifications, or
--1 if no such device exists.
-
-NOTES
-^^^^^
-
-Example usage::
-
- int devnum = -1;
- while ((devnum = parport_find_device ("IOMEGA", "ZIP+", devnum)) != -1) {
- struct pardevice *dev = parport_open (devnum, ...);
- ...
- }
-
-SEE ALSO
-^^^^^^^^
-
-parport_find_class, parport_open, parport_device_id
-
-
-\f
-parport_set_timeout - set the inactivity timeout
-------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- long parport_set_timeout (struct pardevice *dev, long inactivity);
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Set the inactivity timeout, in jiffies, for a registered device. The
-previous timeout is returned.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-The previous timeout, in jiffies.
-
-NOTES
-^^^^^
-
-Some of the port->ops functions for a parport may take time, owing to
-delays at the peripheral. After the peripheral has not responded for
-``inactivity`` jiffies, a timeout will occur and the blocking function
-will return.
-
-A timeout of 0 jiffies is a special case: the function must do as much
-as it can without blocking or leaving the hardware in an unknown
-state. If port operations are performed from within an interrupt
-handler, for instance, a timeout of 0 jiffies should be used.
-
-Once set for a registered device, the timeout will remain at the set
-value until set again.
-
-SEE ALSO
-^^^^^^^^
-
-port->ops->xxx_read/write_yyy
-
-
-
-
-PORT FUNCTIONS
-==============
-
-The functions in the port->ops structure (struct parport_operations)
-are provided by the low-level driver responsible for that port.
-
-port->ops->read_data - read the data register
----------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- unsigned char (*read_data) (struct parport *port);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-If port->modes contains the PARPORT_MODE_TRISTATE flag and the
-PARPORT_CONTROL_DIRECTION bit in the control register is set, this
-returns the value on the data pins. If port->modes contains the
-PARPORT_MODE_TRISTATE flag and the PARPORT_CONTROL_DIRECTION bit is
-not set, the return value _may_ be the last value written to the data
-register. Otherwise the return value is undefined.
-
-SEE ALSO
-^^^^^^^^
-
-write_data, read_status, write_control
-
-
-\f
-port->ops->write_data - write the data register
------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- void (*write_data) (struct parport *port, unsigned char d);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Writes to the data register. May have side-effects (a STROBE pulse,
-for instance).
-
-SEE ALSO
-^^^^^^^^
-
-read_data, read_status, write_control
-
-
-\f
-port->ops->read_status - read the status register
--------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- unsigned char (*read_status) (struct parport *port);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Reads from the status register. This is a bitmask:
-
-- PARPORT_STATUS_ERROR (printer fault, "nFault")
-- PARPORT_STATUS_SELECT (on-line, "Select")
-- PARPORT_STATUS_PAPEROUT (no paper, "PError")
-- PARPORT_STATUS_ACK (handshake, "nAck")
-- PARPORT_STATUS_BUSY (busy, "Busy")
-
-There may be other bits set.
-
-SEE ALSO
-^^^^^^^^
-
-read_data, write_data, write_control
-
-
-\f
-port->ops->read_control - read the control register
----------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- unsigned char (*read_control) (struct parport *port);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Returns the last value written to the control register (either from
-write_control or frob_control). No port access is performed.
-
-SEE ALSO
-^^^^^^^^
-
-read_data, write_data, read_status, write_control
-
-
-\f
-port->ops->write_control - write the control register
------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- void (*write_control) (struct parport *port, unsigned char s);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Writes to the control register. This is a bitmask::
-
- _______
- - PARPORT_CONTROL_STROBE (nStrobe)
- _______
- - PARPORT_CONTROL_AUTOFD (nAutoFd)
- _____
- - PARPORT_CONTROL_INIT (nInit)
- _________
- - PARPORT_CONTROL_SELECT (nSelectIn)
-
-SEE ALSO
-^^^^^^^^
-
-read_data, write_data, read_status, frob_control
-
-
-\f
-port->ops->frob_control - write control register bits
------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- unsigned char (*frob_control) (struct parport *port,
- unsigned char mask,
- unsigned char val);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-This is equivalent to reading from the control register, masking out
-the bits in mask, exclusive-or'ing with the bits in val, and writing
-the result to the control register.
-
-As some ports don't allow reads from the control port, a software copy
-of its contents is maintained, so frob_control is in fact only one
-port access.
-
-SEE ALSO
-^^^^^^^^
-
-read_data, write_data, read_status, write_control
-
-
-\f
-port->ops->enable_irq - enable interrupt generation
----------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- void (*enable_irq) (struct parport *port);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-The parallel port hardware is instructed to generate interrupts at
-appropriate moments, although those moments are
-architecture-specific. For the PC architecture, interrupts are
-commonly generated on the rising edge of nAck.
-
-SEE ALSO
-^^^^^^^^
-
-disable_irq
-
-
-\f
-port->ops->disable_irq - disable interrupt generation
------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- void (*disable_irq) (struct parport *port);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-The parallel port hardware is instructed not to generate interrupts.
-The interrupt itself is not masked.
-
-SEE ALSO
-^^^^^^^^
-
-enable_irq
-\f
-
-
-port->ops->data_forward - enable data drivers
----------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- void (*data_forward) (struct parport *port);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Enables the data line drivers, for 8-bit host-to-peripheral
-communications.
-
-SEE ALSO
-^^^^^^^^
-
-data_reverse
-
-
-\f
-port->ops->data_reverse - tristate the buffer
----------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- void (*data_reverse) (struct parport *port);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Places the data bus in a high impedance state, if port->modes has the
-PARPORT_MODE_TRISTATE bit set.
-
-SEE ALSO
-^^^^^^^^
-
-data_forward
-
-
-
-port->ops->epp_write_data - write EPP data
-------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*epp_write_data) (struct parport *port, const void *buf,
- size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Writes data in EPP mode, and returns the number of bytes written.
-
-The ``flags`` parameter may be one or more of the following,
-bitwise-or'ed together:
-
-======================= =================================================
-PARPORT_EPP_FAST Use fast transfers. Some chips provide 16-bit and
- 32-bit registers. However, if a transfer
- times out, the return value may be unreliable.
-======================= =================================================
-
-SEE ALSO
-^^^^^^^^
-
-epp_read_data, epp_write_addr, epp_read_addr
-
-
-\f
-port->ops->epp_read_data - read EPP data
-----------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*epp_read_data) (struct parport *port, void *buf,
- size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Reads data in EPP mode, and returns the number of bytes read.
-
-The ``flags`` parameter may be one or more of the following,
-bitwise-or'ed together:
-
-======================= =================================================
-PARPORT_EPP_FAST Use fast transfers. Some chips provide 16-bit and
- 32-bit registers. However, if a transfer
- times out, the return value may be unreliable.
-======================= =================================================
-
-SEE ALSO
-^^^^^^^^
-
-epp_write_data, epp_write_addr, epp_read_addr
-
-
-
-port->ops->epp_write_addr - write EPP address
----------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*epp_write_addr) (struct parport *port,
- const void *buf, size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Writes EPP addresses (8 bits each), and returns the number written.
-
-The ``flags`` parameter may be one or more of the following,
-bitwise-or'ed together:
-
-======================= =================================================
-PARPORT_EPP_FAST Use fast transfers. Some chips provide 16-bit and
- 32-bit registers. However, if a transfer
- times out, the return value may be unreliable.
-======================= =================================================
-
-(Does PARPORT_EPP_FAST make sense for this function?)
-
-SEE ALSO
-^^^^^^^^
-
-epp_write_data, epp_read_data, epp_read_addr
-
-
-\f
-port->ops->epp_read_addr - read EPP address
--------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*epp_read_addr) (struct parport *port, void *buf,
- size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Reads EPP addresses (8 bits each), and returns the number read.
-
-The ``flags`` parameter may be one or more of the following,
-bitwise-or'ed together:
-
-======================= =================================================
-PARPORT_EPP_FAST Use fast transfers. Some chips provide 16-bit and
- 32-bit registers. However, if a transfer
- times out, the return value may be unreliable.
-======================= =================================================
-
-(Does PARPORT_EPP_FAST make sense for this function?)
-
-SEE ALSO
-^^^^^^^^
-
-epp_write_data, epp_read_data, epp_write_addr
-
-
-\f
-port->ops->ecp_write_data - write a block of ECP data
------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*ecp_write_data) (struct parport *port,
- const void *buf, size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Writes a block of ECP data. The ``flags`` parameter is ignored.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-The number of bytes written.
-
-SEE ALSO
-^^^^^^^^
-
-ecp_read_data, ecp_write_addr
-\f
-
-
-port->ops->ecp_read_data - read a block of ECP data
----------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*ecp_read_data) (struct parport *port,
- void *buf, size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Reads a block of ECP data. The ``flags`` parameter is ignored.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-The number of bytes read. NB. There may be more unread data in a
-FIFO. Is there a way of stunning the FIFO to prevent this?
-
-SEE ALSO
-^^^^^^^^
-
-ecp_write_block, ecp_write_addr
-
-
-
-port->ops->ecp_write_addr - write a block of ECP addresses
-----------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*ecp_write_addr) (struct parport *port,
- const void *buf, size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Writes a block of ECP addresses. The ``flags`` parameter is ignored.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-The number of bytes written.
-
-NOTES
-^^^^^
-
-This may use a FIFO, and if so shall not return until the FIFO is empty.
-
-SEE ALSO
-^^^^^^^^
-
-ecp_read_data, ecp_write_data
-
-
-
-port->ops->nibble_read_data - read a block of data in nibble mode
------------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*nibble_read_data) (struct parport *port,
- void *buf, size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Reads a block of data in nibble mode. The ``flags`` parameter is ignored.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-The number of whole bytes read.
-
-SEE ALSO
-^^^^^^^^
-
-byte_read_data, compat_write_data
-
-
-\f
-port->ops->byte_read_data - read a block of data in byte mode
--------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*byte_read_data) (struct parport *port,
- void *buf, size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Reads a block of data in byte mode. The ``flags`` parameter is ignored.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-The number of bytes read.
-
-SEE ALSO
-^^^^^^^^
-
-nibble_read_data, compat_write_data
-
-
-\f
-port->ops->compat_write_data - write a block of data in compatibility mode
---------------------------------------------------------------------------
-
-SYNOPSIS
-^^^^^^^^
-
-::
-
- #include <linux/parport.h>
-
- struct parport_operations {
- ...
- size_t (*compat_write_data) (struct parport *port,
- const void *buf, size_t len, int flags);
- ...
- };
-
-DESCRIPTION
-^^^^^^^^^^^
-
-Writes a block of data in compatibility mode. The ``flags`` parameter
-is ignored.
-
-RETURN VALUE
-^^^^^^^^^^^^
-
-The number of bytes written.
-
-SEE ALSO
-^^^^^^^^
-
-nibble_read_data, byte_read_data
+++ /dev/null
-:orphan:
-
-=============
-Intel MID PTI
-=============
-
-The Intel MID PTI project is HW implemented in Intel Atom
-system-on-a-chip designs based on the Parallel Trace
-Interface for MIPI P1149.7 cJTAG standard. The kernel solution
-for this platform involves the following files::
-
- ./include/linux/pti.h
- ./drivers/.../n_tracesink.h
- ./drivers/.../n_tracerouter.c
- ./drivers/.../n_tracesink.c
- ./drivers/.../pti.c
-
-pti.c is the driver that enables various debugging features
-popular on platforms from certain mobile manufacturers.
-n_tracerouter.c and n_tracesink.c allow extra system information to
-be collected and routed to the pti driver, such as trace
-debugging data from a modem. Although n_tracerouter
-and n_tracesink are a part of the complete PTI solution,
-these two line disciplines can work separately from
-pti.c and route any data stream from one /dev/tty node
-to another /dev/tty node via kernel-space. This provides
-a stable, reliable connection that will not break unless
-the user-space application shuts down (plus avoids
-kernel->user->kernel context switch overheads of routing
-data).
-
-An example debugging usage for this driver system:
-
- * Hook /dev/ttyPTI0 to syslogd. Opening this port will also start
- a console device to further capture debugging messages to PTI.
- * Hook /dev/ttyPTI1 to modem debugging data to write to PTI HW.
- This is where n_tracerouter and n_tracesink are used.
- * Hook /dev/pti to a user-level debugging application for writing
- to PTI HW.
- * `Use mipi_` Kernel Driver API in other device drivers for
- debugging to PTI by first requesting a PTI write address via
- mipi_request_masterchannel(1).
-
-Below is example pseudo-code on how a 'privileged' application
-can hook up n_tracerouter and n_tracesink to any tty on
-a system. 'Privileged' means the application has enough
-privileges to successfully manipulate the ldisc drivers
-but is not just blindly executing as 'root'. Keep in mind
-the use of ioctl(,TIOCSETD,) is not specific to the n_tracerouter
-and n_tracesink line discpline drivers but is a generic
-operation for a program to use a line discpline driver
-on a tty port other than the default n_tty::
-
- /////////// To hook up n_tracerouter and n_tracesink /////////
-
- // Note that n_tracerouter depends on n_tracesink.
- #include <errno.h>
- #define ONE_TTY "/dev/ttyOne"
- #define TWO_TTY "/dev/ttyTwo"
-
- // needed global to hand onto ldisc connection
- static int g_fd_source = -1;
- static int g_fd_sink = -1;
-
- // these two vars used to grab LDISC values from loaded ldisc drivers
- // in OS. Look at /proc/tty/ldiscs to get the right numbers from
- // the ldiscs loaded in the system.
- int source_ldisc_num, sink_ldisc_num = -1;
- int retval;
-
- g_fd_source = open(ONE_TTY, O_RDWR); // must be R/W
- g_fd_sink = open(TWO_TTY, O_RDWR); // must be R/W
-
- if (g_fd_source <= 0) || (g_fd_sink <= 0) {
- // doubt you'll want to use these exact error lines of code
- printf("Error on open(). errno: %d\n",errno);
- return errno;
- }
-
- retval = ioctl(g_fd_sink, TIOCSETD, &sink_ldisc_num);
- if (retval < 0) {
- printf("Error on ioctl(). errno: %d\n", errno);
- return errno;
- }
-
- retval = ioctl(g_fd_source, TIOCSETD, &source_ldisc_num);
- if (retval < 0) {
- printf("Error on ioctl(). errno: %d\n", errno);
- return errno;
- }
-
- /////////// To disconnect n_tracerouter and n_tracesink ////////
-
- // First make sure data through the ldiscs has stopped.
-
- // Second, disconnect ldiscs. This provides a
- // little cleaner shutdown on tty stack.
- sink_ldisc_num = 0;
- source_ldisc_num = 0;
- ioctl(g_fd_uart, TIOCSETD, &sink_ldisc_num);
- ioctl(g_fd_gadget, TIOCSETD, &source_ldisc_num);
-
- // Three, program closes connection, and cleanup:
- close(g_fd_uart);
- close(g_fd_gadget);
- g_fd_uart = g_fd_gadget = NULL;
+++ /dev/null
-======================================
-Pulse Width Modulation (PWM) interface
-======================================
-
-This provides an overview about the Linux PWM interface
-
-PWMs are commonly used for controlling LEDs, fans or vibrators in
-cell phones. PWMs with a fixed purpose have no need implementing
-the Linux PWM API (although they could). However, PWMs are often
-found as discrete devices on SoCs which have no fixed purpose. It's
-up to the board designer to connect them to LEDs or fans. To provide
-this kind of flexibility the generic PWM API exists.
-
-Identifying PWMs
-----------------
-
-Users of the legacy PWM API use unique IDs to refer to PWM devices.
-
-Instead of referring to a PWM device via its unique ID, board setup code
-should instead register a static mapping that can be used to match PWM
-consumers to providers, as given in the following example::
-
- static struct pwm_lookup board_pwm_lookup[] = {
- PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight", NULL,
- 50000, PWM_POLARITY_NORMAL),
- };
-
- static void __init board_init(void)
- {
- ...
- pwm_add_table(board_pwm_lookup, ARRAY_SIZE(board_pwm_lookup));
- ...
- }
-
-Using PWMs
-----------
-
-Legacy users can request a PWM device using pwm_request() and free it
-after usage with pwm_free().
-
-New users should use the pwm_get() function and pass to it the consumer
-device or a consumer name. pwm_put() is used to free the PWM device. Managed
-variants of these functions, devm_pwm_get() and devm_pwm_put(), also exist.
-
-After being requested, a PWM has to be configured using::
-
- int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state);
-
-This API controls both the PWM period/duty_cycle config and the
-enable/disable state.
-
-The pwm_config(), pwm_enable() and pwm_disable() functions are just wrappers
-around pwm_apply_state() and should not be used if the user wants to change
-several parameter at once. For example, if you see pwm_config() and
-pwm_{enable,disable}() calls in the same function, this probably means you
-should switch to pwm_apply_state().
-
-The PWM user API also allows one to query the PWM state with pwm_get_state().
-
-In addition to the PWM state, the PWM API also exposes PWM arguments, which
-are the reference PWM config one should use on this PWM.
-PWM arguments are usually platform-specific and allows the PWM user to only
-care about dutycycle relatively to the full period (like, duty = 50% of the
-period). struct pwm_args contains 2 fields (period and polarity) and should
-be used to set the initial PWM config (usually done in the probe function
-of the PWM user). PWM arguments are retrieved with pwm_get_args().
-
-All consumers should really be reconfiguring the PWM upon resume as
-appropriate. This is the only way to ensure that everything is resumed in
-the proper order.
-
-Using PWMs with the sysfs interface
------------------------------------
-
-If CONFIG_SYSFS is enabled in your kernel configuration a simple sysfs
-interface is provided to use the PWMs from userspace. It is exposed at
-/sys/class/pwm/. Each probed PWM controller/chip will be exported as
-pwmchipN, where N is the base of the PWM chip. Inside the directory you
-will find:
-
- npwm
- The number of PWM channels this chip supports (read-only).
-
- export
- Exports a PWM channel for use with sysfs (write-only).
-
- unexport
- Unexports a PWM channel from sysfs (write-only).
-
-The PWM channels are numbered using a per-chip index from 0 to npwm-1.
-
-When a PWM channel is exported a pwmX directory will be created in the
-pwmchipN directory it is associated with, where X is the number of the
-channel that was exported. The following properties will then be available:
-
- period
- The total period of the PWM signal (read/write).
- Value is in nanoseconds and is the sum of the active and inactive
- time of the PWM.
-
- duty_cycle
- The active time of the PWM signal (read/write).
- Value is in nanoseconds and must be less than the period.
-
- polarity
- Changes the polarity of the PWM signal (read/write).
- Writes to this property only work if the PWM chip supports changing
- the polarity. The polarity can only be changed if the PWM is not
- enabled. Value is the string "normal" or "inversed".
-
- enable
- Enable/disable the PWM signal (read/write).
-
- - 0 - disabled
- - 1 - enabled
-
-Implementing a PWM driver
--------------------------
-
-Currently there are two ways to implement pwm drivers. Traditionally
-there only has been the barebone API meaning that each driver has
-to implement the pwm_*() functions itself. This means that it's impossible
-to have multiple PWM drivers in the system. For this reason it's mandatory
-for new drivers to use the generic PWM framework.
-
-A new PWM controller/chip can be added using pwmchip_add() and removed
-again with pwmchip_remove(). pwmchip_add() takes a filled in struct
-pwm_chip as argument which provides a description of the PWM chip, the
-number of PWM devices provided by the chip and the chip-specific
-implementation of the supported PWM operations to the framework.
-
-When implementing polarity support in a PWM driver, make sure to respect the
-signal conventions in the PWM framework. By definition, normal polarity
-characterizes a signal starts high for the duration of the duty cycle and
-goes low for the remainder of the period. Conversely, a signal with inversed
-polarity starts low for the duration of the duty cycle and goes high for the
-remainder of the period.
-
-Drivers are encouraged to implement ->apply() instead of the legacy
-->enable(), ->disable() and ->config() methods. Doing that should provide
-atomicity in the PWM config workflow, which is required when the PWM controls
-a critical device (like a regulator).
-
-The implementation of ->get_state() (a method used to retrieve initial PWM
-state) is also encouraged for the same reason: letting the PWM user know
-about the current PWM state would allow him to avoid glitches.
-
-Drivers should not implement any power management. In other words,
-consumers should implement it as described in the "Using PWMs" section.
-
-Locking
--------
-
-The PWM core list manipulations are protected by a mutex, so pwm_request()
-and pwm_free() may not be called from an atomic context. Currently the
-PWM core does not enforce any locking to pwm_enable(), pwm_disable() and
-pwm_config(), so the calling context is currently driver specific. This
-is an issue derived from the former barebone API and should be fixed soon.
-
-Helpers
--------
-
-Currently a PWM can only be configured with period_ns and duty_ns. For several
-use cases freq_hz and duty_percent might be better. Instead of calculating
-this in your driver please consider adding appropriate helpers to the framework.
+++ /dev/null
-===============================
-rfkill - RF kill switch support
-===============================
-
-
-.. contents::
- :depth: 2
-
-Introduction
-============
-
-The rfkill subsystem provides a generic interface for disabling any radio
-transmitter in the system. When a transmitter is blocked, it shall not
-radiate any power.
-
-The subsystem also provides the ability to react on button presses and
-disable all transmitters of a certain type (or all). This is intended for
-situations where transmitters need to be turned off, for example on
-aircraft.
-
-The rfkill subsystem has a concept of "hard" and "soft" block, which
-differ little in their meaning (block == transmitters off) but rather in
-whether they can be changed or not:
-
- - hard block
- read-only radio block that cannot be overridden by software
-
- - soft block
- writable radio block (need not be readable) that is set by
- the system software.
-
-The rfkill subsystem has two parameters, rfkill.default_state and
-rfkill.master_switch_mode, which are documented in
-admin-guide/kernel-parameters.rst.
-
-
-Implementation details
-======================
-
-The rfkill subsystem is composed of three main components:
-
- * the rfkill core,
- * the deprecated rfkill-input module (an input layer handler, being
- replaced by userspace policy code) and
- * the rfkill drivers.
-
-The rfkill core provides API for kernel drivers to register their radio
-transmitter with the kernel, methods for turning it on and off, and letting
-the system know about hardware-disabled states that may be implemented on
-the device.
-
-The rfkill core code also notifies userspace of state changes, and provides
-ways for userspace to query the current states. See the "Userspace support"
-section below.
-
-When the device is hard-blocked (either by a call to rfkill_set_hw_state()
-or from query_hw_block), set_block() will be invoked for additional software
-block, but drivers can ignore the method call since they can use the return
-value of the function rfkill_set_hw_state() to sync the software state
-instead of keeping track of calls to set_block(). In fact, drivers should
-use the return value of rfkill_set_hw_state() unless the hardware actually
-keeps track of soft and hard block separately.
-
-
-Kernel API
-==========
-
-Drivers for radio transmitters normally implement an rfkill driver.
-
-Platform drivers might implement input devices if the rfkill button is just
-that, a button. If that button influences the hardware then you need to
-implement an rfkill driver instead. This also applies if the platform provides
-a way to turn on/off the transmitter(s).
-
-For some platforms, it is possible that the hardware state changes during
-suspend/hibernation, in which case it will be necessary to update the rfkill
-core with the current state at resume time.
-
-To create an rfkill driver, driver's Kconfig needs to have::
-
- depends on RFKILL || !RFKILL
-
-to ensure the driver cannot be built-in when rfkill is modular. The !RFKILL
-case allows the driver to be built when rfkill is not configured, in which
-case all rfkill API can still be used but will be provided by static inlines
-which compile to almost nothing.
-
-Calling rfkill_set_hw_state() when a state change happens is required from
-rfkill drivers that control devices that can be hard-blocked unless they also
-assign the poll_hw_block() callback (then the rfkill core will poll the
-device). Don't do this unless you cannot get the event in any other way.
-
-rfkill provides per-switch LED triggers, which can be used to drive LEDs
-according to the switch state (LED_FULL when blocked, LED_OFF otherwise).
-
-
-Userspace support
-=================
-
-The recommended userspace interface to use is /dev/rfkill, which is a misc
-character device that allows userspace to obtain and set the state of rfkill
-devices and sets of devices. It also notifies userspace about device addition
-and removal. The API is a simple read/write API that is defined in
-linux/rfkill.h, with one ioctl that allows turning off the deprecated input
-handler in the kernel for the transition period.
-
-Except for the one ioctl, communication with the kernel is done via read()
-and write() of instances of 'struct rfkill_event'. In this structure, the
-soft and hard block are properly separated (unlike sysfs, see below) and
-userspace is able to get a consistent snapshot of all rfkill devices in the
-system. Also, it is possible to switch all rfkill drivers (or all drivers of
-a specified type) into a state which also updates the default state for
-hotplugged devices.
-
-After an application opens /dev/rfkill, it can read the current state of all
-devices. Changes can be obtained by either polling the descriptor for
-hotplug or state change events or by listening for uevents emitted by the
-rfkill core framework.
-
-Additionally, each rfkill device is registered in sysfs and emits uevents.
-
-rfkill devices issue uevents (with an action of "change"), with the following
-environment variables set::
-
- RFKILL_NAME
- RFKILL_STATE
- RFKILL_TYPE
-
-The content of these variables corresponds to the "name", "state" and
-"type" sysfs files explained above.
-
-For further details consult Documentation/ABI/stable/sysfs-class-rfkill.
qemu/hw/s390x/css.c
For vfio mediated device framework:
-- Documentation/vfio-mediated-device.txt
+- Documentation/driver-api/vfio-mediated-device.rst
Motivation of vfio-ccw
----------------------
2. ESA/390 Common I/O Device Commands manual (IBM Form. No. SA22-7204)
3. https://en.wikipedia.org/wiki/Channel_I/O
4. Documentation/s390/cds.rst
-5. Documentation/vfio.txt
-6. Documentation/vfio-mediated-device.txt
+5. Documentation/driver-api/vfio.rst
+6. Documentation/driver-api/vfio-mediated-device.rst
+++ /dev/null
-====================================
-SGI IOC4 PCI (multi function) device
-====================================
-
-The SGI IOC4 PCI device is a bit of a strange beast, so some notes on
-it are in order.
-
-First, even though the IOC4 performs multiple functions, such as an
-IDE controller, a serial controller, a PS/2 keyboard/mouse controller,
-and an external interrupt mechanism, it's not implemented as a
-multifunction device. The consequence of this from a software
-standpoint is that all these functions share a single IRQ, and
-they can't all register to own the same PCI device ID. To make
-matters a bit worse, some of the register blocks (and even registers
-themselves) present in IOC4 are mixed-purpose between these several
-functions, meaning that there's no clear "owning" device driver.
-
-The solution is to organize the IOC4 driver into several independent
-drivers, "ioc4", "sgiioc4", and "ioc4_serial". Note that there is no
-PS/2 controller driver as this functionality has never been wired up
-on a shipping IO card.
-
-ioc4
-====
-This is the core (or shim) driver for IOC4. It is responsible for
-initializing the basic functionality of the chip, and allocating
-the PCI resources that are shared between the IOC4 functions.
-
-This driver also provides registration functions that the other
-IOC4 drivers can call to make their presence known. Each driver
-needs to provide a probe and remove function, which are invoked
-by the core driver at appropriate times. The interface of these
-IOC4 function probe and remove operations isn't precisely the same
-as PCI device probe and remove operations, but is logically the
-same operation.
-
-sgiioc4
-=======
-This is the IDE driver for IOC4. Its name isn't very descriptive
-simply for historical reasons (it used to be the only IOC4 driver
-component). There's not much to say about it other than it hooks
-up to the ioc4 driver via the appropriate registration, probe, and
-remove functions.
-
-ioc4_serial
-===========
-This is the serial driver for IOC4. There's not much to say about it
-other than it hooks up to the ioc4 driver via the appropriate registration,
-probe, and remove functions.
+++ /dev/null
-=================================================
-Msc Keyboard Scan Expansion/GPIO Expansion device
-=================================================
-
-What is smsc-ece1099?
-----------------------
-
-The ECE1099 is a 40-Pin 3.3V Keyboard Scan Expansion
-or GPIO Expansion device. The device supports a keyboard
-scan matrix of 23x8. The device is connected to a Master
-via the SMSC BC-Link interface or via the SMBus.
-Keypad scan Input(KSI) and Keypad Scan Output(KSO) signals
-are multiplexed with GPIOs.
-
-Interrupt generation
---------------------
-
-Interrupts can be generated by an edge detection on a GPIO
-pin or an edge detection on one of the bus interface pins.
-Interrupts can also be detected on the keyboard scan interface.
-The bus interrupt pin (BC_INT# or SMBUS_INT#) is asserted if
-any bit in one of the Interrupt Status registers is 1 and
-the corresponding Interrupt Mask bit is also 1.
-
-In order for software to determine which device is the source
-of an interrupt, it should first read the Group Interrupt Status Register
-to determine which Status register group is a source for the interrupt.
-Software should read both the Status register and the associated Mask register,
-then AND the two values together. Bits that are 1 in the result of the AND
-are active interrupts. Software clears an interrupt by writing a 1 to the
-corresponding bit in the Status register.
-
-Communication Protocol
-----------------------
-
-- SMbus slave Interface
- The host processor communicates with the ECE1099 device
- through a series of read/write registers via the SMBus
- interface. SMBus is a serial communication protocol between
- a computer host and its peripheral devices. The SMBus data
- rate is 10KHz minimum to 400 KHz maximum
-
-- Slave Bus Interface
- The ECE1099 device SMBus implementation is a subset of the
- SMBus interface to the host. The device is a slave-only SMBus device.
- The implementation in the device is a subset of SMBus since it
- only supports four protocols.
-
- The Write Byte, Read Byte, Send Byte, and Receive Byte protocols are the
- only valid SMBus protocols for the device.
-
-- BC-LinkTM Interface
- The BC-Link is a proprietary bus that allows communication
- between a Master device and a Companion device. The Master
- device uses this serial bus to read and write registers
- located on the Companion device. The bus comprises three signals,
- BC_CLK, BC_DAT and BC_INT#. The Master device always provides the
- clock, BC_CLK, and the Companion device is the source for an
- independent asynchronous interrupt signal, BC_INT#. The ECE1099
- supports BC-Link speeds up to 24MHz.
+++ /dev/null
-========================
-Linux Switchtec Support
-========================
-
-Microsemi's "Switchtec" line of PCI switch devices is already
-supported by the kernel with standard PCI switch drivers. However, the
-Switchtec device advertises a special management endpoint which
-enables some additional functionality. This includes:
-
-* Packet and Byte Counters
-* Firmware Upgrades
-* Event and Error logs
-* Querying port link status
-* Custom user firmware commands
-
-The switchtec kernel module implements this functionality.
-
-
-Interface
-=========
-
-The primary means of communicating with the Switchtec management firmware is
-through the Memory-mapped Remote Procedure Call (MRPC) interface.
-Commands are submitted to the interface with a 4-byte command
-identifier and up to 1KB of command specific data. The firmware will
-respond with a 4-byte return code and up to 1KB of command-specific
-data. The interface only processes a single command at a time.
-
-
-Userspace Interface
-===================
-
-The MRPC interface will be exposed to userspace through a simple char
-device: /dev/switchtec#, one for each management endpoint in the system.
-
-The char device has the following semantics:
-
-* A write must consist of at least 4 bytes and no more than 1028 bytes.
- The first 4 bytes will be interpreted as the Command ID and the
- remainder will be used as the input data. A write will send the
- command to the firmware to begin processing.
-
-* Each write must be followed by exactly one read. Any double write will
- produce an error and any read that doesn't follow a write will
- produce an error.
-
-* A read will block until the firmware completes the command and return
- the 4-byte Command Return Value plus up to 1024 bytes of output
- data. (The length will be specified by the size parameter of the read
- call -- reading less than 4 bytes will produce an error.)
-
-* The poll call will also be supported for userspace applications that
- need to do other things while waiting for the command to complete.
-
-The following IOCTLs are also supported by the device:
-
-* SWITCHTEC_IOCTL_FLASH_INFO - Retrieve firmware length and number
- of partitions in the device.
-
-* SWITCHTEC_IOCTL_FLASH_PART_INFO - Retrieve address and lengeth for
- any specified partition in flash.
-
-* SWITCHTEC_IOCTL_EVENT_SUMMARY - Read a structure of bitmaps
- indicating all uncleared events.
-
-* SWITCHTEC_IOCTL_EVENT_CTL - Get the current count, clear and set flags
- for any event. This ioctl takes in a switchtec_ioctl_event_ctl struct
- with the event_id, index and flags set (index being the partition or PFF
- number for non-global events). It returns whether the event has
- occurred, the number of times and any event specific data. The flags
- can be used to clear the count or enable and disable actions to
- happen when the event occurs.
- By using the SWITCHTEC_IOCTL_EVENT_FLAG_EN_POLL flag,
- you can set an event to trigger a poll command to return with
- POLLPRI. In this way, userspace can wait for events to occur.
-
-* SWITCHTEC_IOCTL_PFF_TO_PORT and SWITCHTEC_IOCTL_PORT_TO_PFF convert
- between PCI Function Framework number (used by the event system)
- and Switchtec Logic Port ID and Partition number (which is more
- user friendly).
-
-
-Non-Transparent Bridge (NTB) Driver
-===================================
-
-An NTB hardware driver is provided for the Switchtec hardware in
-ntb_hw_switchtec. Currently, it only supports switches configured with
-exactly 2 NT partitions and zero or more non-NT partitions. It also requires
-the following configuration settings:
-
-* Both NT partitions must be able to access each other's GAS spaces.
- Thus, the bits in the GAS Access Vector under Management Settings
- must be set to support this.
-* Kernel configuration MUST include support for NTB (CONFIG_NTB needs
- to be set)
-
-NT EP BAR 2 will be dynamically configured as a Direct Window, and
-the configuration file does not need to configure it explicitly.
-
-Please refer to Documentation/ntb.txt in Linux source tree for an overall
-understanding of the Linux NTB stack. ntb_hw_switchtec works as an NTB
-Hardware Driver in this stack.
+++ /dev/null
-===================
-Sync File API Guide
-===================
-
-:Author: Gustavo Padovan <gustavo at padovan dot org>
-
-This document serves as a guide for device drivers writers on what the
-sync_file API is, and how drivers can support it. Sync file is the carrier of
-the fences(struct dma_fence) that are needed to synchronize between drivers or
-across process boundaries.
-
-The sync_file API is meant to be used to send and receive fence information
-to/from userspace. It enables userspace to do explicit fencing, where instead
-of attaching a fence to the buffer a producer driver (such as a GPU or V4L
-driver) sends the fence related to the buffer to userspace via a sync_file.
-
-The sync_file then can be sent to the consumer (DRM driver for example), that
-will not use the buffer for anything before the fence(s) signals, i.e., the
-driver that issued the fence is not using/processing the buffer anymore, so it
-signals that the buffer is ready to use. And vice-versa for the consumer ->
-producer part of the cycle.
-
-Sync files allows userspace awareness on buffer sharing synchronization between
-drivers.
-
-Sync file was originally added in the Android kernel but current Linux Desktop
-can benefit a lot from it.
-
-in-fences and out-fences
-------------------------
-
-Sync files can go either to or from userspace. When a sync_file is sent from
-the driver to userspace we call the fences it contains 'out-fences'. They are
-related to a buffer that the driver is processing or is going to process, so
-the driver creates an out-fence to be able to notify, through
-dma_fence_signal(), when it has finished using (or processing) that buffer.
-Out-fences are fences that the driver creates.
-
-On the other hand if the driver receives fence(s) through a sync_file from
-userspace we call these fence(s) 'in-fences'. Receiving in-fences means that
-we need to wait for the fence(s) to signal before using any buffer related to
-the in-fences.
-
-Creating Sync Files
--------------------
-
-When a driver needs to send an out-fence userspace it creates a sync_file.
-
-Interface::
-
- struct sync_file *sync_file_create(struct dma_fence *fence);
-
-The caller pass the out-fence and gets back the sync_file. That is just the
-first step, next it needs to install an fd on sync_file->file. So it gets an
-fd::
-
- fd = get_unused_fd_flags(O_CLOEXEC);
-
-and installs it on sync_file->file::
-
- fd_install(fd, sync_file->file);
-
-The sync_file fd now can be sent to userspace.
-
-If the creation process fail, or the sync_file needs to be released by any
-other reason fput(sync_file->file) should be used.
-
-Receiving Sync Files from Userspace
------------------------------------
-
-When userspace needs to send an in-fence to the driver it passes file descriptor
-of the Sync File to the kernel. The kernel can then retrieve the fences
-from it.
-
-Interface::
-
- struct dma_fence *sync_file_get_fence(int fd);
-
-
-The returned reference is owned by the caller and must be disposed of
-afterwards using dma_fence_put(). In case of error, a NULL is returned instead.
-
-References:
-
-1. struct sync_file in include/linux/sync_file.h
-2. All interfaces mentioned above defined in include/linux/sync_file.h
+++ /dev/null
-.. include:: <isonum.txt>
-
-=====================
-VFIO Mediated devices
-=====================
-
-:Copyright: |copy| 2016, NVIDIA CORPORATION. All rights reserved.
-:Author: Neo Jia <cjia@nvidia.com>
-:Author: Kirti Wankhede <kwankhede@nvidia.com>
-
-This program 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.
-
-
-Virtual Function I/O (VFIO) Mediated devices[1]
-===============================================
-
-The number of use cases for virtualizing DMA devices that do not have built-in
-SR_IOV capability is increasing. Previously, to virtualize such devices,
-developers had to create their own management interfaces and APIs, and then
-integrate them with user space software. To simplify integration with user space
-software, we have identified common requirements and a unified management
-interface for such devices.
-
-The VFIO driver framework provides unified APIs for direct device access. It is
-an IOMMU/device-agnostic framework for exposing direct device access to user
-space in a secure, IOMMU-protected environment. This framework is used for
-multiple devices, such as GPUs, network adapters, and compute accelerators. With
-direct device access, virtual machines or user space applications have direct
-access to the physical device. This framework is reused for mediated devices.
-
-The mediated core driver provides a common interface for mediated device
-management that can be used by drivers of different devices. This module
-provides a generic interface to perform these operations:
-
-* Create and destroy a mediated device
-* Add a mediated device to and remove it from a mediated bus driver
-* Add a mediated device to and remove it from an IOMMU group
-
-The mediated core driver also provides an interface to register a bus driver.
-For example, the mediated VFIO mdev driver is designed for mediated devices and
-supports VFIO APIs. The mediated bus driver adds a mediated device to and
-removes it from a VFIO group.
-
-The following high-level block diagram shows the main components and interfaces
-in the VFIO mediated driver framework. The diagram shows NVIDIA, Intel, and IBM
-devices as examples, as these devices are the first devices to use this module::
-
- +---------------+
- | |
- | +-----------+ | mdev_register_driver() +--------------+
- | | | +<------------------------+ |
- | | mdev | | | |
- | | bus | +------------------------>+ vfio_mdev.ko |<-> VFIO user
- | | driver | | probe()/remove() | | APIs
- | | | | +--------------+
- | +-----------+ |
- | |
- | MDEV CORE |
- | MODULE |
- | mdev.ko |
- | +-----------+ | mdev_register_device() +--------------+
- | | | +<------------------------+ |
- | | | | | nvidia.ko |<-> physical
- | | | +------------------------>+ | device
- | | | | callbacks +--------------+
- | | Physical | |
- | | device | | mdev_register_device() +--------------+
- | | interface | |<------------------------+ |
- | | | | | i915.ko |<-> physical
- | | | +------------------------>+ | device
- | | | | callbacks +--------------+
- | | | |
- | | | | mdev_register_device() +--------------+
- | | | +<------------------------+ |
- | | | | | ccw_device.ko|<-> physical
- | | | +------------------------>+ | device
- | | | | callbacks +--------------+
- | +-----------+ |
- +---------------+
-
-
-Registration Interfaces
-=======================
-
-The mediated core driver provides the following types of registration
-interfaces:
-
-* Registration interface for a mediated bus driver
-* Physical device driver interface
-
-Registration Interface for a Mediated Bus Driver
-------------------------------------------------
-
-The registration interface for a mediated bus driver provides the following
-structure to represent a mediated device's driver::
-
- /*
- * struct mdev_driver [2] - Mediated device's driver
- * @name: driver name
- * @probe: called when new device created
- * @remove: called when device removed
- * @driver: device driver structure
- */
- struct mdev_driver {
- const char *name;
- int (*probe) (struct device *dev);
- void (*remove) (struct device *dev);
- struct device_driver driver;
- };
-
-A mediated bus driver for mdev should use this structure in the function calls
-to register and unregister itself with the core driver:
-
-* Register::
-
- extern int mdev_register_driver(struct mdev_driver *drv,
- struct module *owner);
-
-* Unregister::
-
- extern void mdev_unregister_driver(struct mdev_driver *drv);
-
-The mediated bus driver is responsible for adding mediated devices to the VFIO
-group when devices are bound to the driver and removing mediated devices from
-the VFIO when devices are unbound from the driver.
-
-
-Physical Device Driver Interface
---------------------------------
-
-The physical device driver interface provides the mdev_parent_ops[3] structure
-to define the APIs to manage work in the mediated core driver that is related
-to the physical device.
-
-The structures in the mdev_parent_ops structure are as follows:
-
-* dev_attr_groups: attributes of the parent device
-* mdev_attr_groups: attributes of the mediated device
-* supported_config: attributes to define supported configurations
-
-The functions in the mdev_parent_ops structure are as follows:
-
-* create: allocate basic resources in a driver for a mediated device
-* remove: free resources in a driver when a mediated device is destroyed
-
-(Note that mdev-core provides no implicit serialization of create/remove
-callbacks per mdev parent device, per mdev type, or any other categorization.
-Vendor drivers are expected to be fully asynchronous in this respect or
-provide their own internal resource protection.)
-
-The callbacks in the mdev_parent_ops structure are as follows:
-
-* open: open callback of mediated device
-* close: close callback of mediated device
-* ioctl: ioctl callback of mediated device
-* read : read emulation callback
-* write: write emulation callback
-* mmap: mmap emulation callback
-
-A driver should use the mdev_parent_ops structure in the function call to
-register itself with the mdev core driver::
-
- extern int mdev_register_device(struct device *dev,
- const struct mdev_parent_ops *ops);
-
-However, the mdev_parent_ops structure is not required in the function call
-that a driver should use to unregister itself with the mdev core driver::
-
- extern void mdev_unregister_device(struct device *dev);
-
-
-Mediated Device Management Interface Through sysfs
-==================================================
-
-The management interface through sysfs enables user space software, such as
-libvirt, to query and configure mediated devices in a hardware-agnostic fashion.
-This management interface provides flexibility to the underlying physical
-device's driver to support features such as:
-
-* Mediated device hot plug
-* Multiple mediated devices in a single virtual machine
-* Multiple mediated devices from different physical devices
-
-Links in the mdev_bus Class Directory
--------------------------------------
-The /sys/class/mdev_bus/ directory contains links to devices that are registered
-with the mdev core driver.
-
-Directories and files under the sysfs for Each Physical Device
---------------------------------------------------------------
-
-::
-
- |- [parent physical device]
- |--- Vendor-specific-attributes [optional]
- |--- [mdev_supported_types]
- | |--- [<type-id>]
- | | |--- create
- | | |--- name
- | | |--- available_instances
- | | |--- device_api
- | | |--- description
- | | |--- [devices]
- | |--- [<type-id>]
- | | |--- create
- | | |--- name
- | | |--- available_instances
- | | |--- device_api
- | | |--- description
- | | |--- [devices]
- | |--- [<type-id>]
- | |--- create
- | |--- name
- | |--- available_instances
- | |--- device_api
- | |--- description
- | |--- [devices]
-
-* [mdev_supported_types]
-
- The list of currently supported mediated device types and their details.
-
- [<type-id>], device_api, and available_instances are mandatory attributes
- that should be provided by vendor driver.
-
-* [<type-id>]
-
- The [<type-id>] name is created by adding the device driver string as a prefix
- to the string provided by the vendor driver. This format of this name is as
- follows::
-
- sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name);
-
- (or using mdev_parent_dev(mdev) to arrive at the parent device outside
- of the core mdev code)
-
-* device_api
-
- This attribute should show which device API is being created, for example,
- "vfio-pci" for a PCI device.
-
-* available_instances
-
- This attribute should show the number of devices of type <type-id> that can be
- created.
-
-* [device]
-
- This directory contains links to the devices of type <type-id> that have been
- created.
-
-* name
-
- This attribute should show human readable name. This is optional attribute.
-
-* description
-
- This attribute should show brief features/description of the type. This is
- optional attribute.
-
-Directories and Files Under the sysfs for Each mdev Device
-----------------------------------------------------------
-
-::
-
- |- [parent phy device]
- |--- [$MDEV_UUID]
- |--- remove
- |--- mdev_type {link to its type}
- |--- vendor-specific-attributes [optional]
-
-* remove (write only)
-
-Writing '1' to the 'remove' file destroys the mdev device. The vendor driver can
-fail the remove() callback if that device is active and the vendor driver
-doesn't support hot unplug.
-
-Example::
-
- # echo 1 > /sys/bus/mdev/devices/$mdev_UUID/remove
-
-Mediated device Hot plug
-------------------------
-
-Mediated devices can be created and assigned at runtime. The procedure to hot
-plug a mediated device is the same as the procedure to hot plug a PCI device.
-
-Translation APIs for Mediated Devices
-=====================================
-
-The following APIs are provided for translating user pfn to host pfn in a VFIO
-driver::
-
- extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn,
- int npage, int prot, unsigned long *phys_pfn);
-
- extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn,
- int npage);
-
-These functions call back into the back-end IOMMU module by using the pin_pages
-and unpin_pages callbacks of the struct vfio_iommu_driver_ops[4]. Currently
-these callbacks are supported in the TYPE1 IOMMU module. To enable them for
-other IOMMU backend modules, such as PPC64 sPAPR module, they need to provide
-these two callback functions.
-
-Using the Sample Code
-=====================
-
-mtty.c in samples/vfio-mdev/ directory is a sample driver program to
-demonstrate how to use the mediated device framework.
-
-The sample driver creates an mdev device that simulates a serial port over a PCI
-card.
-
-1. Build and load the mtty.ko module.
-
- This step creates a dummy device, /sys/devices/virtual/mtty/mtty/
-
- Files in this device directory in sysfs are similar to the following::
-
- # tree /sys/devices/virtual/mtty/mtty/
- /sys/devices/virtual/mtty/mtty/
- |-- mdev_supported_types
- | |-- mtty-1
- | | |-- available_instances
- | | |-- create
- | | |-- device_api
- | | |-- devices
- | | `-- name
- | `-- mtty-2
- | |-- available_instances
- | |-- create
- | |-- device_api
- | |-- devices
- | `-- name
- |-- mtty_dev
- | `-- sample_mtty_dev
- |-- power
- | |-- autosuspend_delay_ms
- | |-- control
- | |-- runtime_active_time
- | |-- runtime_status
- | `-- runtime_suspended_time
- |-- subsystem -> ../../../../class/mtty
- `-- uevent
-
-2. Create a mediated device by using the dummy device that you created in the
- previous step::
-
- # echo "83b8f4f2-509f-382f-3c1e-e6bfe0fa1001" > \
- /sys/devices/virtual/mtty/mtty/mdev_supported_types/mtty-2/create
-
-3. Add parameters to qemu-kvm::
-
- -device vfio-pci,\
- sysfsdev=/sys/bus/mdev/devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001
-
-4. Boot the VM.
-
- In the Linux guest VM, with no hardware on the host, the device appears
- as follows::
-
- # lspci -s 00:05.0 -xxvv
- 00:05.0 Serial controller: Device 4348:3253 (rev 10) (prog-if 02 [16550])
- Subsystem: Device 4348:3253
- Physical Slot: 5
- Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr-
- Stepping- SERR- FastB2B- DisINTx-
- Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort-
- <TAbort- <MAbort- >SERR- <PERR- INTx-
- Interrupt: pin A routed to IRQ 10
- Region 0: I/O ports at c150 [size=8]
- Region 1: I/O ports at c158 [size=8]
- Kernel driver in use: serial
- 00: 48 43 53 32 01 00 00 02 10 02 00 07 00 00 00 00
- 10: 51 c1 00 00 59 c1 00 00 00 00 00 00 00 00 00 00
- 20: 00 00 00 00 00 00 00 00 00 00 00 00 48 43 53 32
- 30: 00 00 00 00 00 00 00 00 00 00 00 00 0a 01 00 00
-
- In the Linux guest VM, dmesg output for the device is as follows:
-
- serial 0000:00:05.0: PCI INT A -> Link[LNKA] -> GSI 10 (level, high) -> IRQ 10
- 0000:00:05.0: ttyS1 at I/O 0xc150 (irq = 10) is a 16550A
- 0000:00:05.0: ttyS2 at I/O 0xc158 (irq = 10) is a 16550A
-
-
-5. In the Linux guest VM, check the serial ports::
-
- # setserial -g /dev/ttyS*
- /dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
- /dev/ttyS1, UART: 16550A, Port: 0xc150, IRQ: 10
- /dev/ttyS2, UART: 16550A, Port: 0xc158, IRQ: 10
-
-6. Using minicom or any terminal emulation program, open port /dev/ttyS1 or
- /dev/ttyS2 with hardware flow control disabled.
-
-7. Type data on the minicom terminal or send data to the terminal emulation
- program and read the data.
-
- Data is loop backed from hosts mtty driver.
-
-8. Destroy the mediated device that you created::
-
- # echo 1 > /sys/bus/mdev/devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001/remove
-
-References
-==========
-
-1. See Documentation/vfio.txt for more information on VFIO.
-2. struct mdev_driver in include/linux/mdev.h
-3. struct mdev_parent_ops in include/linux/mdev.h
-4. struct vfio_iommu_driver_ops in include/linux/vfio.h
+++ /dev/null
-==================================
-VFIO - "Virtual Function I/O" [1]_
-==================================
-
-Many modern system now provide DMA and interrupt remapping facilities
-to help ensure I/O devices behave within the boundaries they've been
-allotted. This includes x86 hardware with AMD-Vi and Intel VT-d,
-POWER systems with Partitionable Endpoints (PEs) and embedded PowerPC
-systems such as Freescale PAMU. The VFIO driver is an IOMMU/device
-agnostic framework for exposing direct device access to userspace, in
-a secure, IOMMU protected environment. In other words, this allows
-safe [2]_, non-privileged, userspace drivers.
-
-Why do we want that? Virtual machines often make use of direct device
-access ("device assignment") when configured for the highest possible
-I/O performance. From a device and host perspective, this simply
-turns the VM into a userspace driver, with the benefits of
-significantly reduced latency, higher bandwidth, and direct use of
-bare-metal device drivers [3]_.
-
-Some applications, particularly in the high performance computing
-field, also benefit from low-overhead, direct device access from
-userspace. Examples include network adapters (often non-TCP/IP based)
-and compute accelerators. Prior to VFIO, these drivers had to either
-go through the full development cycle to become proper upstream
-driver, be maintained out of tree, or make use of the UIO framework,
-which has no notion of IOMMU protection, limited interrupt support,
-and requires root privileges to access things like PCI configuration
-space.
-
-The VFIO driver framework intends to unify these, replacing both the
-KVM PCI specific device assignment code as well as provide a more
-secure, more featureful userspace driver environment than UIO.
-
-Groups, Devices, and IOMMUs
----------------------------
-
-Devices are the main target of any I/O driver. Devices typically
-create a programming interface made up of I/O access, interrupts,
-and DMA. Without going into the details of each of these, DMA is
-by far the most critical aspect for maintaining a secure environment
-as allowing a device read-write access to system memory imposes the
-greatest risk to the overall system integrity.
-
-To help mitigate this risk, many modern IOMMUs now incorporate
-isolation properties into what was, in many cases, an interface only
-meant for translation (ie. solving the addressing problems of devices
-with limited address spaces). With this, devices can now be isolated
-from each other and from arbitrary memory access, thus allowing
-things like secure direct assignment of devices into virtual machines.
-
-This isolation is not always at the granularity of a single device
-though. Even when an IOMMU is capable of this, properties of devices,
-interconnects, and IOMMU topologies can each reduce this isolation.
-For instance, an individual device may be part of a larger multi-
-function enclosure. While the IOMMU may be able to distinguish
-between devices within the enclosure, the enclosure may not require
-transactions between devices to reach the IOMMU. Examples of this
-could be anything from a multi-function PCI device with backdoors
-between functions to a non-PCI-ACS (Access Control Services) capable
-bridge allowing redirection without reaching the IOMMU. Topology
-can also play a factor in terms of hiding devices. A PCIe-to-PCI
-bridge masks the devices behind it, making transaction appear as if
-from the bridge itself. Obviously IOMMU design plays a major factor
-as well.
-
-Therefore, while for the most part an IOMMU may have device level
-granularity, any system is susceptible to reduced granularity. The
-IOMMU API therefore supports a notion of IOMMU groups. A group is
-a set of devices which is isolatable from all other devices in the
-system. Groups are therefore the unit of ownership used by VFIO.
-
-While the group is the minimum granularity that must be used to
-ensure secure user access, it's not necessarily the preferred
-granularity. In IOMMUs which make use of page tables, it may be
-possible to share a set of page tables between different groups,
-reducing the overhead both to the platform (reduced TLB thrashing,
-reduced duplicate page tables), and to the user (programming only
-a single set of translations). For this reason, VFIO makes use of
-a container class, which may hold one or more groups. A container
-is created by simply opening the /dev/vfio/vfio character device.
-
-On its own, the container provides little functionality, with all
-but a couple version and extension query interfaces locked away.
-The user needs to add a group into the container for the next level
-of functionality. To do this, the user first needs to identify the
-group associated with the desired device. This can be done using
-the sysfs links described in the example below. By unbinding the
-device from the host driver and binding it to a VFIO driver, a new
-VFIO group will appear for the group as /dev/vfio/$GROUP, where
-$GROUP is the IOMMU group number of which the device is a member.
-If the IOMMU group contains multiple devices, each will need to
-be bound to a VFIO driver before operations on the VFIO group
-are allowed (it's also sufficient to only unbind the device from
-host drivers if a VFIO driver is unavailable; this will make the
-group available, but not that particular device). TBD - interface
-for disabling driver probing/locking a device.
-
-Once the group is ready, it may be added to the container by opening
-the VFIO group character device (/dev/vfio/$GROUP) and using the
-VFIO_GROUP_SET_CONTAINER ioctl, passing the file descriptor of the
-previously opened container file. If desired and if the IOMMU driver
-supports sharing the IOMMU context between groups, multiple groups may
-be set to the same container. If a group fails to set to a container
-with existing groups, a new empty container will need to be used
-instead.
-
-With a group (or groups) attached to a container, the remaining
-ioctls become available, enabling access to the VFIO IOMMU interfaces.
-Additionally, it now becomes possible to get file descriptors for each
-device within a group using an ioctl on the VFIO group file descriptor.
-
-The VFIO device API includes ioctls for describing the device, the I/O
-regions and their read/write/mmap offsets on the device descriptor, as
-well as mechanisms for describing and registering interrupt
-notifications.
-
-VFIO Usage Example
-------------------
-
-Assume user wants to access PCI device 0000:06:0d.0::
-
- $ readlink /sys/bus/pci/devices/0000:06:0d.0/iommu_group
- ../../../../kernel/iommu_groups/26
-
-This device is therefore in IOMMU group 26. This device is on the
-pci bus, therefore the user will make use of vfio-pci to manage the
-group::
-
- # modprobe vfio-pci
-
-Binding this device to the vfio-pci driver creates the VFIO group
-character devices for this group::
-
- $ lspci -n -s 0000:06:0d.0
- 06:0d.0 0401: 1102:0002 (rev 08)
- # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
- # echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
-
-Now we need to look at what other devices are in the group to free
-it for use by VFIO::
-
- $ ls -l /sys/bus/pci/devices/0000:06:0d.0/iommu_group/devices
- total 0
- lrwxrwxrwx. 1 root root 0 Apr 23 16:13 0000:00:1e.0 ->
- ../../../../devices/pci0000:00/0000:00:1e.0
- lrwxrwxrwx. 1 root root 0 Apr 23 16:13 0000:06:0d.0 ->
- ../../../../devices/pci0000:00/0000:00:1e.0/0000:06:0d.0
- lrwxrwxrwx. 1 root root 0 Apr 23 16:13 0000:06:0d.1 ->
- ../../../../devices/pci0000:00/0000:00:1e.0/0000:06:0d.1
-
-This device is behind a PCIe-to-PCI bridge [4]_, therefore we also
-need to add device 0000:06:0d.1 to the group following the same
-procedure as above. Device 0000:00:1e.0 is a bridge that does
-not currently have a host driver, therefore it's not required to
-bind this device to the vfio-pci driver (vfio-pci does not currently
-support PCI bridges).
-
-The final step is to provide the user with access to the group if
-unprivileged operation is desired (note that /dev/vfio/vfio provides
-no capabilities on its own and is therefore expected to be set to
-mode 0666 by the system)::
-
- # chown user:user /dev/vfio/26
-
-The user now has full access to all the devices and the iommu for this
-group and can access them as follows::
-
- int container, group, device, i;
- struct vfio_group_status group_status =
- { .argsz = sizeof(group_status) };
- struct vfio_iommu_type1_info iommu_info = { .argsz = sizeof(iommu_info) };
- struct vfio_iommu_type1_dma_map dma_map = { .argsz = sizeof(dma_map) };
- struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-
- /* Create a new container */
- container = open("/dev/vfio/vfio", O_RDWR);
-
- if (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION)
- /* Unknown API version */
-
- if (!ioctl(container, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU))
- /* Doesn't support the IOMMU driver we want. */
-
- /* Open the group */
- group = open("/dev/vfio/26", O_RDWR);
-
- /* Test the group is viable and available */
- ioctl(group, VFIO_GROUP_GET_STATUS, &group_status);
-
- if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE))
- /* Group is not viable (ie, not all devices bound for vfio) */
-
- /* Add the group to the container */
- ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
-
- /* Enable the IOMMU model we want */
- ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
-
- /* Get addition IOMMU info */
- ioctl(container, VFIO_IOMMU_GET_INFO, &iommu_info);
-
- /* Allocate some space and setup a DMA mapping */
- dma_map.vaddr = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
- dma_map.size = 1024 * 1024;
- dma_map.iova = 0; /* 1MB starting at 0x0 from device view */
- dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
-
- ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
-
- /* Get a file descriptor for the device */
- device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "0000:06:0d.0");
-
- /* Test and setup the device */
- ioctl(device, VFIO_DEVICE_GET_INFO, &device_info);
-
- for (i = 0; i < device_info.num_regions; i++) {
- struct vfio_region_info reg = { .argsz = sizeof(reg) };
-
- reg.index = i;
-
- ioctl(device, VFIO_DEVICE_GET_REGION_INFO, ®);
-
- /* Setup mappings... read/write offsets, mmaps
- * For PCI devices, config space is a region */
- }
-
- for (i = 0; i < device_info.num_irqs; i++) {
- struct vfio_irq_info irq = { .argsz = sizeof(irq) };
-
- irq.index = i;
-
- ioctl(device, VFIO_DEVICE_GET_IRQ_INFO, &irq);
-
- /* Setup IRQs... eventfds, VFIO_DEVICE_SET_IRQS */
- }
-
- /* Gratuitous device reset and go... */
- ioctl(device, VFIO_DEVICE_RESET);
-
-VFIO User API
--------------------------------------------------------------------------------
-
-Please see include/linux/vfio.h for complete API documentation.
-
-VFIO bus driver API
--------------------------------------------------------------------------------
-
-VFIO bus drivers, such as vfio-pci make use of only a few interfaces
-into VFIO core. When devices are bound and unbound to the driver,
-the driver should call vfio_add_group_dev() and vfio_del_group_dev()
-respectively::
-
- extern int vfio_add_group_dev(struct device *dev,
- const struct vfio_device_ops *ops,
- void *device_data);
-
- extern void *vfio_del_group_dev(struct device *dev);
-
-vfio_add_group_dev() indicates to the core to begin tracking the
-iommu_group of the specified dev and register the dev as owned by
-a VFIO bus driver. The driver provides an ops structure for callbacks
-similar to a file operations structure::
-
- struct vfio_device_ops {
- int (*open)(void *device_data);
- void (*release)(void *device_data);
- ssize_t (*read)(void *device_data, char __user *buf,
- size_t count, loff_t *ppos);
- ssize_t (*write)(void *device_data, const char __user *buf,
- size_t size, loff_t *ppos);
- long (*ioctl)(void *device_data, unsigned int cmd,
- unsigned long arg);
- int (*mmap)(void *device_data, struct vm_area_struct *vma);
- };
-
-Each function is passed the device_data that was originally registered
-in the vfio_add_group_dev() call above. This allows the bus driver
-an easy place to store its opaque, private data. The open/release
-callbacks are issued when a new file descriptor is created for a
-device (via VFIO_GROUP_GET_DEVICE_FD). The ioctl interface provides
-a direct pass through for VFIO_DEVICE_* ioctls. The read/write/mmap
-interfaces implement the device region access defined by the device's
-own VFIO_DEVICE_GET_REGION_INFO ioctl.
-
-
-PPC64 sPAPR implementation note
--------------------------------
-
-This implementation has some specifics:
-
-1) On older systems (POWER7 with P5IOC2/IODA1) only one IOMMU group per
- container is supported as an IOMMU table is allocated at the boot time,
- one table per a IOMMU group which is a Partitionable Endpoint (PE)
- (PE is often a PCI domain but not always).
-
- Newer systems (POWER8 with IODA2) have improved hardware design which allows
- to remove this limitation and have multiple IOMMU groups per a VFIO
- container.
-
-2) The hardware supports so called DMA windows - the PCI address range
- within which DMA transfer is allowed, any attempt to access address space
- out of the window leads to the whole PE isolation.
-
-3) PPC64 guests are paravirtualized but not fully emulated. There is an API
- to map/unmap pages for DMA, and it normally maps 1..32 pages per call and
- currently there is no way to reduce the number of calls. In order to make
- things faster, the map/unmap handling has been implemented in real mode
- which provides an excellent performance which has limitations such as
- inability to do locked pages accounting in real time.
-
-4) According to sPAPR specification, A Partitionable Endpoint (PE) is an I/O
- subtree that can be treated as a unit for the purposes of partitioning and
- error recovery. A PE may be a single or multi-function IOA (IO Adapter), a
- function of a multi-function IOA, or multiple IOAs (possibly including
- switch and bridge structures above the multiple IOAs). PPC64 guests detect
- PCI errors and recover from them via EEH RTAS services, which works on the
- basis of additional ioctl commands.
-
- So 4 additional ioctls have been added:
-
- VFIO_IOMMU_SPAPR_TCE_GET_INFO
- returns the size and the start of the DMA window on the PCI bus.
-
- VFIO_IOMMU_ENABLE
- enables the container. The locked pages accounting
- is done at this point. This lets user first to know what
- the DMA window is and adjust rlimit before doing any real job.
-
- VFIO_IOMMU_DISABLE
- disables the container.
-
- VFIO_EEH_PE_OP
- provides an API for EEH setup, error detection and recovery.
-
- The code flow from the example above should be slightly changed::
-
- struct vfio_eeh_pe_op pe_op = { .argsz = sizeof(pe_op), .flags = 0 };
-
- .....
- /* Add the group to the container */
- ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
-
- /* Enable the IOMMU model we want */
- ioctl(container, VFIO_SET_IOMMU, VFIO_SPAPR_TCE_IOMMU)
-
- /* Get addition sPAPR IOMMU info */
- vfio_iommu_spapr_tce_info spapr_iommu_info;
- ioctl(container, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &spapr_iommu_info);
-
- if (ioctl(container, VFIO_IOMMU_ENABLE))
- /* Cannot enable container, may be low rlimit */
-
- /* Allocate some space and setup a DMA mapping */
- dma_map.vaddr = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
-
- dma_map.size = 1024 * 1024;
- dma_map.iova = 0; /* 1MB starting at 0x0 from device view */
- dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
-
- /* Check here is .iova/.size are within DMA window from spapr_iommu_info */
- ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
-
- /* Get a file descriptor for the device */
- device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "0000:06:0d.0");
-
- ....
-
- /* Gratuitous device reset and go... */
- ioctl(device, VFIO_DEVICE_RESET);
-
- /* Make sure EEH is supported */
- ioctl(container, VFIO_CHECK_EXTENSION, VFIO_EEH);
-
- /* Enable the EEH functionality on the device */
- pe_op.op = VFIO_EEH_PE_ENABLE;
- ioctl(container, VFIO_EEH_PE_OP, &pe_op);
-
- /* You're suggested to create additional data struct to represent
- * PE, and put child devices belonging to same IOMMU group to the
- * PE instance for later reference.
- */
-
- /* Check the PE's state and make sure it's in functional state */
- pe_op.op = VFIO_EEH_PE_GET_STATE;
- ioctl(container, VFIO_EEH_PE_OP, &pe_op);
-
- /* Save device state using pci_save_state().
- * EEH should be enabled on the specified device.
- */
-
- ....
-
- /* Inject EEH error, which is expected to be caused by 32-bits
- * config load.
- */
- pe_op.op = VFIO_EEH_PE_INJECT_ERR;
- pe_op.err.type = EEH_ERR_TYPE_32;
- pe_op.err.func = EEH_ERR_FUNC_LD_CFG_ADDR;
- pe_op.err.addr = 0ul;
- pe_op.err.mask = 0ul;
- ioctl(container, VFIO_EEH_PE_OP, &pe_op);
-
- ....
-
- /* When 0xFF's returned from reading PCI config space or IO BARs
- * of the PCI device. Check the PE's state to see if that has been
- * frozen.
- */
- ioctl(container, VFIO_EEH_PE_OP, &pe_op);
-
- /* Waiting for pending PCI transactions to be completed and don't
- * produce any more PCI traffic from/to the affected PE until
- * recovery is finished.
- */
-
- /* Enable IO for the affected PE and collect logs. Usually, the
- * standard part of PCI config space, AER registers are dumped
- * as logs for further analysis.
- */
- pe_op.op = VFIO_EEH_PE_UNFREEZE_IO;
- ioctl(container, VFIO_EEH_PE_OP, &pe_op);
-
- /*
- * Issue PE reset: hot or fundamental reset. Usually, hot reset
- * is enough. However, the firmware of some PCI adapters would
- * require fundamental reset.
- */
- pe_op.op = VFIO_EEH_PE_RESET_HOT;
- ioctl(container, VFIO_EEH_PE_OP, &pe_op);
- pe_op.op = VFIO_EEH_PE_RESET_DEACTIVATE;
- ioctl(container, VFIO_EEH_PE_OP, &pe_op);
-
- /* Configure the PCI bridges for the affected PE */
- pe_op.op = VFIO_EEH_PE_CONFIGURE;
- ioctl(container, VFIO_EEH_PE_OP, &pe_op);
-
- /* Restored state we saved at initialization time. pci_restore_state()
- * is good enough as an example.
- */
-
- /* Hopefully, error is recovered successfully. Now, you can resume to
- * start PCI traffic to/from the affected PE.
- */
-
- ....
-
-5) There is v2 of SPAPR TCE IOMMU. It deprecates VFIO_IOMMU_ENABLE/
- VFIO_IOMMU_DISABLE and implements 2 new ioctls:
- VFIO_IOMMU_SPAPR_REGISTER_MEMORY and VFIO_IOMMU_SPAPR_UNREGISTER_MEMORY
- (which are unsupported in v1 IOMMU).
-
- PPC64 paravirtualized guests generate a lot of map/unmap requests,
- and the handling of those includes pinning/unpinning pages and updating
- mm::locked_vm counter to make sure we do not exceed the rlimit.
- The v2 IOMMU splits accounting and pinning into separate operations:
-
- - VFIO_IOMMU_SPAPR_REGISTER_MEMORY/VFIO_IOMMU_SPAPR_UNREGISTER_MEMORY ioctls
- receive a user space address and size of the block to be pinned.
- Bisecting is not supported and VFIO_IOMMU_UNREGISTER_MEMORY is expected to
- be called with the exact address and size used for registering
- the memory block. The userspace is not expected to call these often.
- The ranges are stored in a linked list in a VFIO container.
-
- - VFIO_IOMMU_MAP_DMA/VFIO_IOMMU_UNMAP_DMA ioctls only update the actual
- IOMMU table and do not do pinning; instead these check that the userspace
- address is from pre-registered range.
-
- This separation helps in optimizing DMA for guests.
-
-6) sPAPR specification allows guests to have an additional DMA window(s) on
- a PCI bus with a variable page size. Two ioctls have been added to support
- this: VFIO_IOMMU_SPAPR_TCE_CREATE and VFIO_IOMMU_SPAPR_TCE_REMOVE.
- The platform has to support the functionality or error will be returned to
- the userspace. The existing hardware supports up to 2 DMA windows, one is
- 2GB long, uses 4K pages and called "default 32bit window"; the other can
- be as big as entire RAM, use different page size, it is optional - guests
- create those in run-time if the guest driver supports 64bit DMA.
-
- VFIO_IOMMU_SPAPR_TCE_CREATE receives a page shift, a DMA window size and
- a number of TCE table levels (if a TCE table is going to be big enough and
- the kernel may not be able to allocate enough of physically contiguous
- memory). It creates a new window in the available slot and returns the bus
- address where the new window starts. Due to hardware limitation, the user
- space cannot choose the location of DMA windows.
-
- VFIO_IOMMU_SPAPR_TCE_REMOVE receives the bus start address of the window
- and removes it.
-
--------------------------------------------------------------------------------
-
-.. [1] VFIO was originally an acronym for "Virtual Function I/O" in its
- initial implementation by Tom Lyon while as Cisco. We've since
- outgrown the acronym, but it's catchy.
-
-.. [2] "safe" also depends upon a device being "well behaved". It's
- possible for multi-function devices to have backdoors between
- functions and even for single function devices to have alternative
- access to things like PCI config space through MMIO registers. To
- guard against the former we can include additional precautions in the
- IOMMU driver to group multi-function PCI devices together
- (iommu=group_mf). The latter we can't prevent, but the IOMMU should
- still provide isolation. For PCI, SR-IOV Virtual Functions are the
- best indicator of "well behaved", as these are designed for
- virtualization usage models.
-
-.. [3] As always there are trade-offs to virtual machine device
- assignment that are beyond the scope of VFIO. It's expected that
- future IOMMU technologies will reduce some, but maybe not all, of
- these trade-offs.
-
-.. [4] In this case the device is below a PCI bridge, so transactions
- from either function of the device are indistinguishable to the iommu::
-
- -[0000:00]-+-1e.0-[06]--+-0d.0
- \-0d.1
-
- 00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev 90)
Additional documantion, source code examples.
============================================
-1. Documentation/connector
+1. Documentation/driver-api/connector.rst
2. http://www.ioremap.net/archive/w1
This archive includes userspace application w1d.c which uses
read/write/search commands for all master/slave devices found on the bus.
+++ /dev/null
-==========================================
-Xillybus driver for generic FPGA interface
-==========================================
-
-:Author: Eli Billauer, Xillybus Ltd. (http://xillybus.com)
-:Email: eli.billauer@gmail.com or as advertised on Xillybus' site.
-
-.. Contents:
-
- - Introduction
- -- Background
- -- Xillybus Overview
-
- - Usage
- -- User interface
- -- Synchronization
- -- Seekable pipes
-
- - Internals
- -- Source code organization
- -- Pipe attributes
- -- Host never reads from the FPGA
- -- Channels, pipes, and the message channel
- -- Data streaming
- -- Data granularity
- -- Probing
- -- Buffer allocation
- -- The "nonempty" message (supporting poll)
-
-
-Introduction
-============
-
-Background
-----------
-
-An FPGA (Field Programmable Gate Array) is a piece of logic hardware, which
-can be programmed to become virtually anything that is usually found as a
-dedicated chipset: For instance, a display adapter, network interface card,
-or even a processor with its peripherals. FPGAs are the LEGO of hardware:
-Based upon certain building blocks, you make your own toys the way you like
-them. It's usually pointless to reimplement something that is already
-available on the market as a chipset, so FPGAs are mostly used when some
-special functionality is needed, and the production volume is relatively low
-(hence not justifying the development of an ASIC).
-
-The challenge with FPGAs is that everything is implemented at a very low
-level, even lower than assembly language. In order to allow FPGA designers to
-focus on their specific project, and not reinvent the wheel over and over
-again, pre-designed building blocks, IP cores, are often used. These are the
-FPGA parallels of library functions. IP cores may implement certain
-mathematical functions, a functional unit (e.g. a USB interface), an entire
-processor (e.g. ARM) or anything that might come handy. Think of them as a
-building block, with electrical wires dangling on the sides for connection to
-other blocks.
-
-One of the daunting tasks in FPGA design is communicating with a fullblown
-operating system (actually, with the processor running it): Implementing the
-low-level bus protocol and the somewhat higher-level interface with the host
-(registers, interrupts, DMA etc.) is a project in itself. When the FPGA's
-function is a well-known one (e.g. a video adapter card, or a NIC), it can
-make sense to design the FPGA's interface logic specifically for the project.
-A special driver is then written to present the FPGA as a well-known interface
-to the kernel and/or user space. In that case, there is no reason to treat the
-FPGA differently than any device on the bus.
-
-It's however common that the desired data communication doesn't fit any well-
-known peripheral function. Also, the effort of designing an elegant
-abstraction for the data exchange is often considered too big. In those cases,
-a quicker and possibly less elegant solution is sought: The driver is
-effectively written as a user space program, leaving the kernel space part
-with just elementary data transport. This still requires designing some
-interface logic for the FPGA, and write a simple ad-hoc driver for the kernel.
-
-Xillybus Overview
------------------
-
-Xillybus is an IP core and a Linux driver. Together, they form a kit for
-elementary data transport between an FPGA and the host, providing pipe-like
-data streams with a straightforward user interface. It's intended as a low-
-effort solution for mixed FPGA-host projects, for which it makes sense to
-have the project-specific part of the driver running in a user-space program.
-
-Since the communication requirements may vary significantly from one FPGA
-project to another (the number of data pipes needed in each direction and
-their attributes), there isn't one specific chunk of logic being the Xillybus
-IP core. Rather, the IP core is configured and built based upon a
-specification given by its end user.
-
-Xillybus presents independent data streams, which resemble pipes or TCP/IP
-communication to the user. At the host side, a character device file is used
-just like any pipe file. On the FPGA side, hardware FIFOs are used to stream
-the data. This is contrary to a common method of communicating through fixed-
-sized buffers (even though such buffers are used by Xillybus under the hood).
-There may be more than a hundred of these streams on a single IP core, but
-also no more than one, depending on the configuration.
-
-In order to ease the deployment of the Xillybus IP core, it contains a simple
-data structure which completely defines the core's configuration. The Linux
-driver fetches this data structure during its initialization process, and sets
-up the DMA buffers and character devices accordingly. As a result, a single
-driver is used to work out of the box with any Xillybus IP core.
-
-The data structure just mentioned should not be confused with PCI's
-configuration space or the Flattened Device Tree.
-
-Usage
-=====
-
-User interface
---------------
-
-On the host, all interface with Xillybus is done through /dev/xillybus_*
-device files, which are generated automatically as the drivers loads. The
-names of these files depend on the IP core that is loaded in the FPGA (see
-Probing below). To communicate with the FPGA, open the device file that
-corresponds to the hardware FIFO you want to send data or receive data from,
-and use plain write() or read() calls, just like with a regular pipe. In
-particular, it makes perfect sense to go::
-
- $ cat mydata > /dev/xillybus_thisfifo
-
- $ cat /dev/xillybus_thatfifo > hisdata
-
-possibly pressing CTRL-C as some stage, even though the xillybus_* pipes have
-the capability to send an EOF (but may not use it).
-
-The driver and hardware are designed to behave sensibly as pipes, including:
-
-* Supporting non-blocking I/O (by setting O_NONBLOCK on open() ).
-
-* Supporting poll() and select().
-
-* Being bandwidth efficient under load (using DMA) but also handle small
- pieces of data sent across (like TCP/IP) by autoflushing.
-
-A device file can be read only, write only or bidirectional. Bidirectional
-device files are treated like two independent pipes (except for sharing a
-"channel" structure in the implementation code).
-
-Synchronization
----------------
-
-Xillybus pipes are configured (on the IP core) to be either synchronous or
-asynchronous. For a synchronous pipe, write() returns successfully only after
-some data has been submitted and acknowledged by the FPGA. This slows down
-bulk data transfers, and is nearly impossible for use with streams that
-require data at a constant rate: There is no data transmitted to the FPGA
-between write() calls, in particular when the process loses the CPU.
-
-When a pipe is configured asynchronous, write() returns if there was enough
-room in the buffers to store any of the data in the buffers.
-
-For FPGA to host pipes, asynchronous pipes allow data transfer from the FPGA
-as soon as the respective device file is opened, regardless of if the data
-has been requested by a read() call. On synchronous pipes, only the amount
-of data requested by a read() call is transmitted.
-
-In summary, for synchronous pipes, data between the host and FPGA is
-transmitted only to satisfy the read() or write() call currently handled
-by the driver, and those calls wait for the transmission to complete before
-returning.
-
-Note that the synchronization attribute has nothing to do with the possibility
-that read() or write() completes less bytes than requested. There is a
-separate configuration flag ("allowpartial") that determines whether such a
-partial completion is allowed.
-
-Seekable pipes
---------------
-
-A synchronous pipe can be configured to have the stream's position exposed
-to the user logic at the FPGA. Such a pipe is also seekable on the host API.
-With this feature, a memory or register interface can be attached on the
-FPGA side to the seekable stream. Reading or writing to a certain address in
-the attached memory is done by seeking to the desired address, and calling
-read() or write() as required.
-
-
-Internals
-=========
-
-Source code organization
-------------------------
-
-The Xillybus driver consists of a core module, xillybus_core.c, and modules
-that depend on the specific bus interface (xillybus_of.c and xillybus_pcie.c).
-
-The bus specific modules are those probed when a suitable device is found by
-the kernel. Since the DMA mapping and synchronization functions, which are bus
-dependent by their nature, are used by the core module, a
-xilly_endpoint_hardware structure is passed to the core module on
-initialization. This structure is populated with pointers to wrapper functions
-which execute the DMA-related operations on the bus.
-
-Pipe attributes
----------------
-
-Each pipe has a number of attributes which are set when the FPGA component
-(IP core) is built. They are fetched from the IDT (the data structure which
-defines the core's configuration, see Probing below) by xilly_setupchannels()
-in xillybus_core.c as follows:
-
-* is_writebuf: The pipe's direction. A non-zero value means it's an FPGA to
- host pipe (the FPGA "writes").
-
-* channelnum: The pipe's identification number in communication between the
- host and FPGA.
-
-* format: The underlying data width. See Data Granularity below.
-
-* allowpartial: A non-zero value means that a read() or write() (whichever
- applies) may return with less than the requested number of bytes. The common
- choice is a non-zero value, to match standard UNIX behavior.
-
-* synchronous: A non-zero value means that the pipe is synchronous. See
- Synchronization above.
-
-* bufsize: Each DMA buffer's size. Always a power of two.
-
-* bufnum: The number of buffers allocated for this pipe. Always a power of two.
-
-* exclusive_open: A non-zero value forces exclusive opening of the associated
- device file. If the device file is bidirectional, and already opened only in
- one direction, the opposite direction may be opened once.
-
-* seekable: A non-zero value indicates that the pipe is seekable. See
- Seekable pipes above.
-
-* supports_nonempty: A non-zero value (which is typical) indicates that the
- hardware will send the messages that are necessary to support select() and
- poll() for this pipe.
-
-Host never reads from the FPGA
-------------------------------
-
-Even though PCI Express is hotpluggable in general, a typical motherboard
-doesn't expect a card to go away all of the sudden. But since the PCIe card
-is based upon reprogrammable logic, a sudden disappearance from the bus is
-quite likely as a result of an accidental reprogramming of the FPGA while the
-host is up. In practice, nothing happens immediately in such a situation. But
-if the host attempts to read from an address that is mapped to the PCI Express
-device, that leads to an immediate freeze of the system on some motherboards,
-even though the PCIe standard requires a graceful recovery.
-
-In order to avoid these freezes, the Xillybus driver refrains completely from
-reading from the device's register space. All communication from the FPGA to
-the host is done through DMA. In particular, the Interrupt Service Routine
-doesn't follow the common practice of checking a status register when it's
-invoked. Rather, the FPGA prepares a small buffer which contains short
-messages, which inform the host what the interrupt was about.
-
-This mechanism is used on non-PCIe buses as well for the sake of uniformity.
-
-
-Channels, pipes, and the message channel
-----------------------------------------
-
-Each of the (possibly bidirectional) pipes presented to the user is allocated
-a data channel between the FPGA and the host. The distinction between channels
-and pipes is necessary only because of channel 0, which is used for interrupt-
-related messages from the FPGA, and has no pipe attached to it.
-
-Data streaming
---------------
-
-Even though a non-segmented data stream is presented to the user at both
-sides, the implementation relies on a set of DMA buffers which is allocated
-for each channel. For the sake of illustration, let's take the FPGA to host
-direction: As data streams into the respective channel's interface in the
-FPGA, the Xillybus IP core writes it to one of the DMA buffers. When the
-buffer is full, the FPGA informs the host about that (appending a
-XILLYMSG_OPCODE_RELEASEBUF message channel 0 and sending an interrupt if
-necessary). The host responds by making the data available for reading through
-the character device. When all data has been read, the host writes on the
-the FPGA's buffer control register, allowing the buffer's overwriting. Flow
-control mechanisms exist on both sides to prevent underflows and overflows.
-
-This is not good enough for creating a TCP/IP-like stream: If the data flow
-stops momentarily before a DMA buffer is filled, the intuitive expectation is
-that the partial data in buffer will arrive anyhow, despite the buffer not
-being completed. This is implemented by adding a field in the
-XILLYMSG_OPCODE_RELEASEBUF message, through which the FPGA informs not just
-which buffer is submitted, but how much data it contains.
-
-But the FPGA will submit a partially filled buffer only if directed to do so
-by the host. This situation occurs when the read() method has been blocking
-for XILLY_RX_TIMEOUT jiffies (currently 10 ms), after which the host commands
-the FPGA to submit a DMA buffer as soon as it can. This timeout mechanism
-balances between bus bandwidth efficiency (preventing a lot of partially
-filled buffers being sent) and a latency held fairly low for tails of data.
-
-A similar setting is used in the host to FPGA direction. The handling of
-partial DMA buffers is somewhat different, though. The user can tell the
-driver to submit all data it has in the buffers to the FPGA, by issuing a
-write() with the byte count set to zero. This is similar to a flush request,
-but it doesn't block. There is also an autoflushing mechanism, which triggers
-an equivalent flush roughly XILLY_RX_TIMEOUT jiffies after the last write().
-This allows the user to be oblivious about the underlying buffering mechanism
-and yet enjoy a stream-like interface.
-
-Note that the issue of partial buffer flushing is irrelevant for pipes having
-the "synchronous" attribute nonzero, since synchronous pipes don't allow data
-to lay around in the DMA buffers between read() and write() anyhow.
-
-Data granularity
-----------------
-
-The data arrives or is sent at the FPGA as 8, 16 or 32 bit wide words, as
-configured by the "format" attribute. Whenever possible, the driver attempts
-to hide this when the pipe is accessed differently from its natural alignment.
-For example, reading single bytes from a pipe with 32 bit granularity works
-with no issues. Writing single bytes to pipes with 16 or 32 bit granularity
-will also work, but the driver can't send partially completed words to the
-FPGA, so the transmission of up to one word may be held until it's fully
-occupied with user data.
-
-This somewhat complicates the handling of host to FPGA streams, because
-when a buffer is flushed, it may contain up to 3 bytes don't form a word in
-the FPGA, and hence can't be sent. To prevent loss of data, these leftover
-bytes need to be moved to the next buffer. The parts in xillybus_core.c
-that mention "leftovers" in some way are related to this complication.
-
-Probing
--------
-
-As mentioned earlier, the number of pipes that are created when the driver
-loads and their attributes depend on the Xillybus IP core in the FPGA. During
-the driver's initialization, a blob containing configuration info, the
-Interface Description Table (IDT), is sent from the FPGA to the host. The
-bootstrap process is done in three phases:
-
-1. Acquire the length of the IDT, so a buffer can be allocated for it. This
- is done by sending a quiesce command to the device, since the acknowledge
- for this command contains the IDT's buffer length.
-
-2. Acquire the IDT itself.
-
-3. Create the interfaces according to the IDT.
-
-Buffer allocation
------------------
-
-In order to simplify the logic that prevents illegal boundary crossings of
-PCIe packets, the following rule applies: If a buffer is smaller than 4kB,
-it must not cross a 4kB boundary. Otherwise, it must be 4kB aligned. The
-xilly_setupchannels() functions allocates these buffers by requesting whole
-pages from the kernel, and diving them into DMA buffers as necessary. Since
-all buffers' sizes are powers of two, it's possible to pack any set of such
-buffers, with a maximal waste of one page of memory.
-
-All buffers are allocated when the driver is loaded. This is necessary,
-since large continuous physical memory segments are sometimes requested,
-which are more likely to be available when the system is freshly booted.
-
-The allocation of buffer memory takes place in the same order they appear in
-the IDT. The driver relies on a rule that the pipes are sorted with decreasing
-buffer size in the IDT. If a requested buffer is larger or equal to a page,
-the necessary number of pages is requested from the kernel, and these are
-used for this buffer. If the requested buffer is smaller than a page, one
-single page is requested from the kernel, and that page is partially used.
-Or, if there already is a partially used page at hand, the buffer is packed
-into that page. It can be shown that all pages requested from the kernel
-(except possibly for the last) are 100% utilized this way.
-
-The "nonempty" message (supporting poll)
-----------------------------------------
-
-In order to support the "poll" method (and hence select() ), there is a small
-catch regarding the FPGA to host direction: The FPGA may have filled a DMA
-buffer with some data, but not submitted that buffer. If the host waited for
-the buffer's submission by the FPGA, there would be a possibility that the
-FPGA side has sent data, but a select() call would still block, because the
-host has not received any notification about this. This is solved with
-XILLYMSG_OPCODE_NONEMPTY messages sent by the FPGA when a channel goes from
-completely empty to containing some data.
-
-These messages are used only to support poll() and select(). The IP core can
-be configured not to send them for a slight reduction of bandwidth.
+++ /dev/null
-========================================
-Writing Device Drivers for Zorro Devices
-========================================
-
-:Author: Written by Geert Uytterhoeven <geert@linux-m68k.org>
-:Last revised: September 5, 2003
-
-
-Introduction
-------------
-
-The Zorro bus is the bus used in the Amiga family of computers. Thanks to
-AutoConfig(tm), it's 100% Plug-and-Play.
-
-There are two types of Zorro buses, Zorro II and Zorro III:
-
- - The Zorro II address space is 24-bit and lies within the first 16 MB of the
- Amiga's address map.
-
- - Zorro III is a 32-bit extension of Zorro II, which is backwards compatible
- with Zorro II. The Zorro III address space lies outside the first 16 MB.
-
-
-Probing for Zorro Devices
--------------------------
-
-Zorro devices are found by calling ``zorro_find_device()``, which returns a
-pointer to the ``next`` Zorro device with the specified Zorro ID. A probe loop
-for the board with Zorro ID ``ZORRO_PROD_xxx`` looks like::
-
- struct zorro_dev *z = NULL;
-
- while ((z = zorro_find_device(ZORRO_PROD_xxx, z))) {
- if (!zorro_request_region(z->resource.start+MY_START, MY_SIZE,
- "My explanation"))
- ...
- }
-
-``ZORRO_WILDCARD`` acts as a wildcard and finds any Zorro device. If your driver
-supports different types of boards, you can use a construct like::
-
- struct zorro_dev *z = NULL;
-
- while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
- if (z->id != ZORRO_PROD_xxx1 && z->id != ZORRO_PROD_xxx2 && ...)
- continue;
- if (!zorro_request_region(z->resource.start+MY_START, MY_SIZE,
- "My explanation"))
- ...
- }
-
-
-Zorro Resources
----------------
-
-Before you can access a Zorro device's registers, you have to make sure it's
-not yet in use. This is done using the I/O memory space resource management
-functions::
-
- request_mem_region()
- release_mem_region()
-
-Shortcuts to claim the whole device's address space are provided as well::
-
- zorro_request_device
- zorro_release_device
-
-
-Accessing the Zorro Address Space
----------------------------------
-
-The address regions in the Zorro device resources are Zorro bus address
-regions. Due to the identity bus-physical address mapping on the Zorro bus,
-they are CPU physical addresses as well.
-
-The treatment of these regions depends on the type of Zorro space:
-
- - Zorro II address space is always mapped and does not have to be mapped
- explicitly using z_ioremap().
-
- Conversion from bus/physical Zorro II addresses to kernel virtual addresses
- and vice versa is done using::
-
- virt_addr = ZTWO_VADDR(bus_addr);
- bus_addr = ZTWO_PADDR(virt_addr);
-
- - Zorro III address space must be mapped explicitly using z_ioremap() first
- before it can be accessed::
-
- virt_addr = z_ioremap(bus_addr, size);
- ...
- z_iounmap(virt_addr);
-
-
-References
-----------
-
-#. linux/include/linux/zorro.h
-#. linux/include/uapi/linux/zorro.h
-#. linux/include/uapi/linux/zorro_ids.h
-#. linux/arch/m68k/include/asm/zorro.h
-#. linux/drivers/zorro
-#. /proc/bus/zorro
-
M: Stuart Hayes <stuart.w.hayes@gmail.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
-F: Documentation/dcdbas.txt
+F: Documentation/driver-api/dcdbas.rst
F: drivers/platform/x86/dcdbas.*
DELL WMI NOTIFICATIONS DRIVER
ISA
M: William Breathitt Gray <vilhelm.gray@gmail.com>
S: Maintained
-F: Documentation/isa.txt
+F: Documentation/driver-api/isa.rst
F: drivers/base/isa.c
F: include/linux/isa.h
ISAPNP
M: Jaroslav Kysela <perex@perex.cz>
S: Maintained
-F: Documentation/isapnp.txt
+F: Documentation/driver-api/isapnp.rst
F: drivers/pnp/isapnp/
F: include/linux/isapnp.h
S: Maintained
F: drivers/mcb/
F: include/linux/mcb.h
-F: Documentation/men-chameleon-bus.txt
+F: Documentation/driver-api/men-chameleon-bus.rst
MEN F21BMC (Board Management Controller)
M: Andreas Werner <andreas.werner@men.de>
F: include/linux/parport*.h
F: drivers/char/ppdev.c
F: include/uapi/linux/ppdev.h
-F: Documentation/parport*.txt
+F: Documentation/driver-api/parport*.rst
PARAVIRT_OPS INTERFACE
M: Juergen Gross <jgross@suse.com>
M: Logan Gunthorpe <logang@deltatee.com>
L: linux-pci@vger.kernel.org
S: Maintained
-F: Documentation/switchtec.txt
+F: Documentation/driver-api/switchtec.rst
F: Documentation/ABI/testing/sysfs-class-switchtec
F: drivers/pci/switch/switchtec*
F: include/uapi/linux/switchtec_ioctl.h
L: linux-pwm@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git
-F: Documentation/pwm.txt
+F: Documentation/driver-api/pwm.rst
F: Documentation/devicetree/bindings/pwm/
F: include/linux/pwm.h
F: drivers/pwm/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
S: Maintained
-F: Documentation/rfkill.txt
+F: Documentation/driver-api/rfkill.rst
F: Documentation/ABI/stable/sysfs-class-rfkill
F: net/rfkill/
F: include/linux/rfkill.h
F: drivers/dma-buf/sw_sync.c
F: include/linux/sync_file.h
F: include/uapi/linux/sync_file.h
-F: Documentation/sync_file.txt
+F: Documentation/driver-api/sync_file.rst
T: git git://anongit.freedesktop.org/drm/drm-misc
SYNOPSYS ARC ARCHITECTURE
L: kvm@vger.kernel.org
T: git git://github.com/awilliam/linux-vfio.git
S: Maintained
-F: Documentation/vfio.txt
+F: Documentation/driver-api/vfio.rst
F: drivers/vfio/
F: include/linux/vfio.h
F: include/uapi/linux/vfio.h
M: Kirti Wankhede <kwankhede@nvidia.com>
L: kvm@vger.kernel.org
S: Maintained
-F: Documentation/vfio-mediated-device.txt
+F: Documentation/driver-api/vfio-mediated-device.rst
F: drivers/vfio/mdev/
F: include/linux/mdev.h
F: samples/vfio-mdev/
associated with a buffer. When a job is submitted to the GPU a fence
is attached to the buffer and is transferred via userspace, using Sync
Files fds, to the DRM driver for example. More details at
- Documentation/sync_file.txt.
+ Documentation/driver-api/sync_file.rst.
config SW_SYNC
bool "Sync File Validation Framework"
The card needs to be physically altered for using it as a
GPIO card. For more information on how to build a GPIO card
from a BT8xx TV card, see the documentation file at
- Documentation/bt8xxgpio.txt
+ Documentation/driver-api/bt8xxgpio.rst
If unsure, say N.
monitor are unable to provide appropriate EDID data. Since this
feature is provided as a workaround for broken hardware, the
default case is N. Details and instructions how to build your own
- EDID data are given in Documentation/EDID/howto.rst.
+ EDID data are given in Documentation/driver-api/edid.rst.
config DRM_DP_CEC
bool "Enable DisplayPort CEC-Tunneling-over-AUX HDMI support"
Enables support for the management interface for the MicroSemi
Switchtec series of PCIe switches. Supports userspace access
to submit MRPC commands to the switch via /dev/switchtecX
- devices. See <file:Documentation/switchtec.txt> for more
+ devices. See <file:Documentation/driver-api/switchtec.rst> for more
information.
endmenu
Interrupts (SMIs) and Host Control Actions (system power cycle or
power off after OS shutdown) on certain Dell systems.
- See <file:Documentation/dcdbas.txt> for more details on the driver
+ See <file:Documentation/driver-api/dcdbas.rst> for more details on the driver
and the Dell systems on which Dell systems management software makes
use of this driver.
DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
supporting application to communicate with the BIOS regarding the new
image for the image update to take effect.
- See <file:Documentation/dell_rbu.txt> for more details on the driver.
+ See <file:Documentation/driver-api/dell_rbu.rst> for more details on the driver.
config FUJITSU_LAPTOP
* and Host Control Actions (power cycle or power off after OS shutdown) on
* Dell systems.
*
- * See Documentation/dcdbas.txt for more information.
+ * See Documentation/driver-api/dcdbas.rst for more information.
*
* Copyright (C) 1995-2006 Dell Inc.
*/
* on every time the packet data is written. This driver requires an
* application to break the BIOS image in to fixed sized packet chunks.
*
- * See Documentation/dell_rbu.txt for more info.
+ * See Documentation/driver-api/dell_rbu.rst for more info.
*/
#include <linux/init.h>
#include <linux/module.h>
depends on ISA || COMPILE_TEST
help
Say Y here if you would like support for ISA Plug and Play devices.
- Some information is in <file:Documentation/isapnp.txt>.
+ Some information is in <file:Documentation/driver-api/isapnp.rst>.
If unsure, say Y.
select the console driver that will serve as the backend for the
virtual terminals.
- See <file:Documentation/console/console.rst> for more
+ See <file:Documentation/driver-api/console.rst> for more
information. For framebuffer console users, please refer to
<file:Documentation/fb/fbcon.rst>.
select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM || ARM64)
help
VFIO provides a framework for secure userspace device drivers.
- See Documentation/vfio.txt for more details.
+ See Documentation/driver-api/vfio.rst for more details.
If you don't know what to do here, say N.
default n
help
Provides a framework to virtualize devices.
- See Documentation/vfio-mediated-device.txt for more details.
+ See Documentation/driver-api/vfio-mediated-device.rst for more details.
If you don't know what do here, say N.
default y
---help---
This allows to communicate with userspace using connector. For more
- information see <file:Documentation/connector/connector.rst>.
+ information see <file:Documentation/driver-api/connector.rst>.
There are three types of messages between w1 core and userspace:
1. Events. They are generated each time new master or slave device found
either due to automatic or requested search.
When enabled, this builds both a sample kernel module for
the connector interface and a user space tool to communicate
with it.
- See also Documentation/connector/connector.rst
+ See also Documentation/driver-api/connector.rst
config SAMPLE_HIDRAW
bool "hidraw sample"