Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,34 @@
.. SPDX-License-Identifier: GPL-2.0
=================================
Linux-specific ELF idiosyncrasies
=================================
Definitions
===========
"First" program header is the one with the smallest offset in the file:
e_phoff.
"Last" program header is the one with the biggest offset in the file:
e_phoff + (e_phnum - 1) * sizeof(Elf_Phdr).
PT_INTERP
=========
First PT_INTERP program header is used to locate the filename of ELF
interpreter. Other PT_INTERP headers are ignored (since Linux 2.4.11).
PT_GNU_STACK
============
Last PT_GNU_STACK program header defines userspace stack executability
(since Linux 2.6.6). Other PT_GNU_STACK headers are ignored.
PT_GNU_PROPERTY
===============
ELF interpreter's last PT_GNU_PROPERTY program header is used (since
Linux 5.8). If interpreter doesn't have one, then the last PT_GNU_PROPERTY
program header of an executable is used. Other PT_GNU_PROPERTY headers
are ignored.
@@ -0,0 +1,179 @@
========================================================
OpenCAPI (Open Coherent Accelerator Processor Interface)
========================================================
OpenCAPI is an interface between processors and accelerators. It aims
at being low-latency and high-bandwidth.
The specification was developed by the OpenCAPI Consortium, and is now
available from the `Compute Express Link Consortium
<https://computeexpresslink.org/resource/opencapi-specification-archive/>`_.
It allows an accelerator (which could be an FPGA, ASICs, ...) to access
the host memory coherently, using virtual addresses. An OpenCAPI
device can also host its own memory, that can be accessed from the
host.
OpenCAPI is known in linux as 'ocxl', as the open, processor-agnostic
evolution of 'cxl' (the driver for the IBM CAPI interface for
powerpc), which was named that way to avoid confusion with the ISDN
CAPI subsystem.
High-level view
===============
OpenCAPI defines a Data Link Layer (DL) and Transaction Layer (TL), to
be implemented on top of a physical link. Any processor or device
implementing the DL and TL can start sharing memory.
::
+-----------+ +-------------+
| | | |
| | | Accelerated |
| Processor | | Function |
| | +--------+ | Unit | +--------+
| |--| Memory | | (AFU) |--| Memory |
| | +--------+ | | +--------+
+-----------+ +-------------+
| |
+-----------+ +-------------+
| TL | | TLX |
+-----------+ +-------------+
| |
+-----------+ +-------------+
| DL | | DLX |
+-----------+ +-------------+
| |
| PHY |
+---------------------------------------+
Device discovery
================
OpenCAPI relies on a PCI-like configuration space, implemented on the
device. So the host can discover AFUs by querying the config space.
OpenCAPI devices in Linux are treated like PCI devices (with a few
caveats). The firmware is expected to abstract the hardware as if it
was a PCI link. A lot of the existing PCI infrastructure is reused:
devices are scanned and BARs are assigned during the standard PCI
enumeration. Commands like 'lspci' can therefore be used to see what
devices are available.
The configuration space defines the AFU(s) that can be found on the
physical adapter, such as its name, how many memory contexts it can
work with, the size of its MMIO areas, ...
MMIO
====
OpenCAPI defines two MMIO areas for each AFU:
* the global MMIO area, with registers pertinent to the whole AFU.
* a per-process MMIO area, which has a fixed size for each context.
AFU interrupts
==============
OpenCAPI includes the possibility for an AFU to send an interrupt to a
host process. It is done through a 'intrp_req' defined in the
Transaction Layer, specifying a 64-bit object handle which defines the
interrupt.
The driver allows a process to allocate an interrupt and obtain its
64-bit object handle, that can be passed to the AFU.
char devices
============
The driver creates one char device per AFU found on the physical
device. A physical device may have multiple functions and each
function can have multiple AFUs. At the time of this writing though,
it has only been tested with devices exporting only one AFU.
Char devices can be found in /dev/ocxl/ and are named as:
/dev/ocxl/<AFU name>.<location>.<index>
where <AFU name> is a max 20-character long name, as found in the
config space of the AFU.
<location> is added by the driver and can help distinguish devices
when a system has more than one instance of the same OpenCAPI device.
<index> is also to help distinguish AFUs in the unlikely case where a
device carries multiple copies of the same AFU.
Sysfs class
===========
An ocxl class is added for the devices representing the AFUs. See
/sys/class/ocxl. The layout is described in
Documentation/ABI/testing/sysfs-class-ocxl
User API
========
open
----
Based on the AFU definition found in the config space, an AFU may
support working with more than one memory context, in which case the
associated char device may be opened multiple times by different
processes.
ioctl
-----
OCXL_IOCTL_ATTACH:
Attach the memory context of the calling process to the AFU so that
the AFU can access its memory.
OCXL_IOCTL_IRQ_ALLOC:
Allocate an AFU interrupt and return an identifier.
OCXL_IOCTL_IRQ_FREE:
Free a previously allocated AFU interrupt.
OCXL_IOCTL_IRQ_SET_FD:
Associate an event fd to an AFU interrupt so that the user process
can be notified when the AFU sends an interrupt.
OCXL_IOCTL_GET_METADATA:
Obtains configuration information from the card, such at the size of
MMIO areas, the AFU version, and the PASID for the current context.
OCXL_IOCTL_ENABLE_P9_WAIT:
Allows the AFU to wake a userspace thread executing 'wait'. Returns
information to userspace to allow it to configure the AFU. Note that
this is only available on POWER9.
OCXL_IOCTL_GET_FEATURES:
Reports on which CPU features that affect OpenCAPI are usable from
userspace.
mmap
----
A process can mmap the per-process MMIO area for interactions with the
AFU.
@@ -0,0 +1,144 @@
.. SPDX-License-Identifier: GPL-2.0
.. Copyright © 2024 Microsoft Corporation
===================
Executability check
===================
The ``AT_EXECVE_CHECK`` :manpage:`execveat(2)` flag, and the
``SECBIT_EXEC_RESTRICT_FILE`` and ``SECBIT_EXEC_DENY_INTERACTIVE`` securebits
are intended for script interpreters and dynamic linkers to enforce a
consistent execution security policy handled by the kernel. See the
`samples/check-exec/inc.c`_ example.
Whether an interpreter should check these securebits or not depends on the
security risk of running malicious scripts with respect to the execution
environment, and whether the kernel can check if a script is trustworthy or
not. For instance, Python scripts running on a server can use arbitrary
syscalls and access arbitrary files. Such interpreters should then be
enlighten to use these securebits and let users define their security policy.
However, a JavaScript engine running in a web browser should already be
sandboxed and then should not be able to harm the user's environment.
Script interpreters or dynamic linkers built for tailored execution environments
(e.g. hardened Linux distributions or hermetic container images) could use
``AT_EXECVE_CHECK`` without checking the related securebits if backward
compatibility is handled by something else (e.g. atomic update ensuring that
all legitimate libraries are allowed to be executed). It is then recommended
for script interpreters and dynamic linkers to check the securebits at run time
by default, but also to provide the ability for custom builds to behave like if
``SECBIT_EXEC_RESTRICT_FILE`` or ``SECBIT_EXEC_DENY_INTERACTIVE`` were always
set to 1 (i.e. always enforce restrictions).
AT_EXECVE_CHECK
===============
Passing the ``AT_EXECVE_CHECK`` flag to :manpage:`execveat(2)` only performs a
check on a regular file and returns 0 if execution of this file would be
allowed, ignoring the file format and then the related interpreter dependencies
(e.g. ELF libraries, script's shebang).
Programs should always perform this check to apply kernel-level checks against
files that are not directly executed by the kernel but passed to a user space
interpreter instead. All files that contain executable code, from the point of
view of the interpreter, should be checked. However the result of this check
should only be enforced according to ``SECBIT_EXEC_RESTRICT_FILE`` or
``SECBIT_EXEC_DENY_INTERACTIVE.``.
The main purpose of this flag is to improve the security and consistency of an
execution environment to ensure that direct file execution (e.g.
``./script.sh``) and indirect file execution (e.g. ``sh script.sh``) lead to
the same result. For instance, this can be used to check if a file is
trustworthy according to the caller's environment.
In a secure environment, libraries and any executable dependencies should also
be checked. For instance, dynamic linking should make sure that all libraries
are allowed for execution to avoid trivial bypass (e.g. using ``LD_PRELOAD``).
For such secure execution environment to make sense, only trusted code should
be executable, which also requires integrity guarantees.
To avoid race conditions leading to time-of-check to time-of-use issues,
``AT_EXECVE_CHECK`` should be used with ``AT_EMPTY_PATH`` to check against a
file descriptor instead of a path.
SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE
==========================================================
When ``SECBIT_EXEC_RESTRICT_FILE`` is set, a process should only interpret or
execute a file if a call to :manpage:`execveat(2)` with the related file
descriptor and the ``AT_EXECVE_CHECK`` flag succeed.
This secure bit may be set by user session managers, service managers,
container runtimes, sandboxer tools... Except for test environments, the
related ``SECBIT_EXEC_RESTRICT_FILE_LOCKED`` bit should also be set.
Programs should only enforce consistent restrictions according to the
securebits but without relying on any other user-controlled configuration.
Indeed, the use case for these securebits is to only trust executable code
vetted by the system configuration (through the kernel), so we should be
careful to not let untrusted users control this configuration.
However, script interpreters may still use user configuration such as
environment variables as long as it is not a way to disable the securebits
checks. For instance, the ``PATH`` and ``LD_PRELOAD`` variables can be set by
a script's caller. Changing these variables may lead to unintended code
executions, but only from vetted executable programs, which is OK. For this to
make sense, the system should provide a consistent security policy to avoid
arbitrary code execution e.g., by enforcing a write xor execute policy.
When ``SECBIT_EXEC_DENY_INTERACTIVE`` is set, a process should never interpret
interactive user commands (e.g. scripts). However, if such commands are passed
through a file descriptor (e.g. stdin), its content should be interpreted if a
call to :manpage:`execveat(2)` with the related file descriptor and the
``AT_EXECVE_CHECK`` flag succeed.
For instance, script interpreters called with a script snippet as argument
should always deny such execution if ``SECBIT_EXEC_DENY_INTERACTIVE`` is set.
This secure bit may be set by user session managers, service managers,
container runtimes, sandboxer tools... Except for test environments, the
related ``SECBIT_EXEC_DENY_INTERACTIVE_LOCKED`` bit should also be set.
Here is the expected behavior for a script interpreter according to combination
of any exec securebits:
1. ``SECBIT_EXEC_RESTRICT_FILE=0`` and ``SECBIT_EXEC_DENY_INTERACTIVE=0``
Always interpret scripts, and allow arbitrary user commands (default).
No threat, everyone and everything is trusted, but we can get ahead of
potential issues thanks to the call to :manpage:`execveat(2)` with
``AT_EXECVE_CHECK`` which should always be performed but ignored by the
script interpreter. Indeed, this check is still important to enable systems
administrators to verify requests (e.g. with audit) and prepare for
migration to a secure mode.
2. ``SECBIT_EXEC_RESTRICT_FILE=1`` and ``SECBIT_EXEC_DENY_INTERACTIVE=0``
Deny script interpretation if they are not executable, but allow
arbitrary user commands.
The threat is (potential) malicious scripts run by trusted (and not fooled)
users. That can protect against unintended script executions (e.g. ``sh
/tmp/*.sh``). This makes sense for (semi-restricted) user sessions.
3. ``SECBIT_EXEC_RESTRICT_FILE=0`` and ``SECBIT_EXEC_DENY_INTERACTIVE=1``
Always interpret scripts, but deny arbitrary user commands.
This use case may be useful for secure services (i.e. without interactive
user session) where scripts' integrity is verified (e.g. with IMA/EVM or
dm-verity/IPE) but where access rights might not be ready yet. Indeed,
arbitrary interactive commands would be much more difficult to check.
4. ``SECBIT_EXEC_RESTRICT_FILE=1`` and ``SECBIT_EXEC_DENY_INTERACTIVE=1``
Deny script interpretation if they are not executable, and also deny
any arbitrary user commands.
The threat is malicious scripts run by untrusted users (but trusted code).
This makes sense for system services that may only execute trusted scripts.
.. Links
.. _samples/check-exec/inc.c:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/check-exec/inc.c
@@ -0,0 +1,99 @@
===================================
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
=================== =====================
@@ -0,0 +1,389 @@
.. SPDX-License-Identifier: GPL-2.0
.. Copyright 2021-2023 Collabora Ltd.
========================
Exchanging pixel buffers
========================
As originally designed, the Linux graphics subsystem had extremely limited
support for sharing pixel-buffer allocations between processes, devices, and
subsystems. Modern systems require extensive integration between all three
classes; this document details how applications and kernel subsystems should
approach this sharing for two-dimensional image data.
It is written with reference to the DRM subsystem for GPU and display devices,
V4L2 for media devices, and also to Vulkan, EGL and Wayland, for userspace
support, however any other subsystems should also follow this design and advice.
Glossary of terms
=================
.. glossary::
image:
Conceptually a two-dimensional array of pixels. The pixels may be stored
in one or more memory buffers. Has width and height in pixels, pixel
format and modifier (implicit or explicit).
row:
A span along a single y-axis value, e.g. from co-ordinates (0,100) to
(200,100).
scanline:
Synonym for row.
column:
A span along a single x-axis value, e.g. from co-ordinates (100,0) to
(100,100).
memory buffer:
A piece of memory for storing (parts of) pixel data. Has stride and size
in bytes and at least one handle in some API. May contain one or more
planes.
plane:
A two-dimensional array of some or all of an image's color and alpha
channel values.
pixel:
A picture element. Has a single color value which is defined by one or
more color channels values, e.g. R, G and B, or Y, Cb and Cr. May also
have an alpha value as an additional channel.
pixel data:
Bytes or bits that represent some or all of the color/alpha channel values
of a pixel or an image. The data for one pixel may be spread over several
planes or memory buffers depending on format and modifier.
color value:
A tuple of numbers, representing a color. Each element in the tuple is a
color channel value.
color channel:
One of the dimensions in a color model. For example, RGB model has
channels R, G, and B. Alpha channel is sometimes counted as a color
channel as well.
pixel format:
A description of how pixel data represents the pixel's color and alpha
values.
modifier:
A description of how pixel data is laid out in memory buffers.
alpha:
A value that denotes the color coverage in a pixel. Sometimes used for
translucency instead.
stride:
A value that denotes the relationship between pixel-location co-ordinates
and byte-offset values. Typically used as the byte offset between two
pixels at the start of vertically-consecutive tiling blocks. For linear
layouts, the byte offset between two vertically-adjacent pixels. For
non-linear formats the stride must be computed in a consistent way, which
usually is done as-if the layout was linear.
pitch:
Synonym for stride.
Formats and modifiers
=====================
Each buffer must have an underlying format. This format describes the color
values provided for each pixel. Although each subsystem has its own format
descriptions (e.g. V4L2 and fbdev), the ``DRM_FORMAT_*`` tokens should be reused
wherever possible, as they are the standard descriptions used for interchange.
These tokens are described in the ``drm_fourcc.h`` file, which is a part of
DRM's uAPI.
Each ``DRM_FORMAT_*`` token describes the translation between a pixel
co-ordinate in an image, and the color values for that pixel contained within
its memory buffers. The number and type of color channels are described:
whether they are RGB or YUV, integer or floating-point, the size of each channel
and their locations within the pixel memory, and the relationship between color
planes.
For example, ``DRM_FORMAT_ARGB8888`` describes a format in which each pixel has
a single 32-bit value in memory. Alpha, red, green, and blue, color channels are
available at 8-bit precision per channel, ordered respectively from most to
least significant bits in little-endian storage. ``DRM_FORMAT_*`` is not
affected by either CPU or device endianness; the byte pattern in memory is
always as described in the format definition, which is usually little-endian.
As a more complex example, ``DRM_FORMAT_NV12`` describes a format in which luma
and chroma YUV samples are stored in separate planes, where the chroma plane is
stored at half the resolution in both dimensions (i.e. one U/V chroma
sample is stored for each 2x2 pixel grouping).
Format modifiers describe a translation mechanism between these per-pixel memory
samples, and the actual memory storage for the buffer. The most straightforward
modifier is ``DRM_FORMAT_MOD_LINEAR``, describing a scheme in which each plane
is laid out row-sequentially, from the top-left to the bottom-right corner.
This is considered the baseline interchange format, and most convenient for CPU
access.
Modern hardware employs much more sophisticated access mechanisms, typically
making use of tiled access and possibly also compression. For example, the
``DRM_FORMAT_MOD_VIVANTE_TILED`` modifier describes memory storage where pixels
are stored in 4x4 blocks arranged in row-major ordering, i.e. the first tile in
a plane stores pixels (0,0) to (3,3) inclusive, and the second tile in a plane
stores pixels (4,0) to (7,3) inclusive.
Some modifiers may modify the number of planes required for an image; for
example, the ``I915_FORMAT_MOD_Y_TILED_CCS`` modifier adds a second plane to RGB
formats in which it stores data about the status of every tile, notably
including whether the tile is fully populated with pixel data, or can be
expanded from a single solid color.
These extended layouts are highly vendor-specific, and even specific to
particular generations or configurations of devices per-vendor. For this reason,
support of modifiers must be explicitly enumerated and negotiated by all users
in order to ensure a compatible and optimal pipeline, as discussed below.
Dimensions and size
===================
Each pixel buffer must be accompanied by logical pixel dimensions. This refers
to the number of unique samples which can be extracted from, or stored to, the
underlying memory storage. For example, even though a 1920x1080
``DRM_FORMAT_NV12`` buffer has a luma plane containing 1920x1080 samples for the Y
component, and 960x540 samples for the U and V components, the overall buffer is
still described as having dimensions of 1920x1080.
The in-memory storage of a buffer is not guaranteed to begin immediately at the
base address of the underlying memory, nor is it guaranteed that the memory
storage is tightly clipped to either dimension.
Each plane must therefore be described with an ``offset`` in bytes, which will be
added to the base address of the memory storage before performing any per-pixel
calculations. This may be used to combine multiple planes into a single memory
buffer; for example, ``DRM_FORMAT_NV12`` may be stored in a single memory buffer
where the luma plane's storage begins immediately at the start of the buffer
with an offset of 0, and the chroma plane's storage follows within the same buffer
beginning from the byte offset for that plane.
Each plane must also have a ``stride`` in bytes, expressing the offset in memory
between two contiguous row. For example, a ``DRM_FORMAT_MOD_LINEAR`` buffer
with dimensions of 1000x1000 may have been allocated as if it were 1024x1000, in
order to allow for aligned access patterns. In this case, the buffer will still
be described with a width of 1000, however the stride will be ``1024 * bpp``,
indicating that there are 24 pixels at the positive extreme of the x axis whose
values are not significant.
Buffers may also be padded further in the y dimension, simply by allocating a
larger area than would ordinarily be required. For example, many media decoders
are not able to natively output buffers of height 1080, but instead require an
effective height of 1088 pixels. In this case, the buffer continues to be
described as having a height of 1080, with the memory allocation for each buffer
being increased to account for the extra padding.
Enumeration
===========
Every user of pixel buffers must be able to enumerate a set of supported formats
and modifiers, described together. Within KMS, this is achieved with the
``IN_FORMATS`` property on each DRM plane, listing the supported DRM formats, and
the modifiers supported for each format. In userspace, this is supported through
the `EGL_EXT_image_dma_buf_import_modifiers`_ extension entrypoints for EGL, the
`VK_EXT_image_drm_format_modifier`_ extension for Vulkan, and the
`zwp_linux_dmabuf_v1`_ extension for Wayland.
Each of these interfaces allows users to query a set of supported
format+modifier combinations.
Negotiation
===========
It is the responsibility of userspace to negotiate an acceptable format+modifier
combination for its usage. This is performed through a simple intersection of
lists. For example, if a user wants to use Vulkan to render an image to be
displayed on a KMS plane, it must:
- query KMS for the ``IN_FORMATS`` property for the given plane
- query Vulkan for the supported formats for its physical device, making sure
to pass the ``VkImageUsageFlagBits`` and ``VkImageCreateFlagBits``
corresponding to the intended rendering use
- intersect these formats to determine the most appropriate one
- for this format, intersect the lists of supported modifiers for both KMS and
Vulkan, to obtain a final list of acceptable modifiers for that format
This intersection must be performed for all usages. For example, if the user
also wishes to encode the image to a video stream, it must query the media API
it intends to use for encoding for the set of modifiers it supports, and
additionally intersect against this list.
If the intersection of all lists is an empty list, it is not possible to share
buffers in this way, and an alternate strategy must be considered (e.g. using
CPU access routines to copy data between the different uses, with the
corresponding performance cost).
The resulting modifier list is unsorted; the order is not significant.
Allocation
==========
Once userspace has determined an appropriate format, and corresponding list of
acceptable modifiers, it must allocate the buffer. As there is no universal
buffer-allocation interface available at either kernel or userspace level, the
client makes an arbitrary choice of allocation interface such as Vulkan, GBM, or
a media API.
Each allocation request must take, at a minimum: the pixel format, a list of
acceptable modifiers, and the buffer's width and height. Each API may extend
this set of properties in different ways, such as allowing allocation in more
than two dimensions, intended usage patterns, etc.
The component which allocates the buffer will make an arbitrary choice of what
it considers the 'best' modifier within the acceptable list for the requested
allocation, any padding required, and further properties of the underlying
memory buffers such as whether they are stored in system or device-specific
memory, whether or not they are physically contiguous, and their cache mode.
These properties of the memory buffer are not visible to userspace, however the
``dma-heaps`` API is an effort to address this.
After allocation, the client must query the allocator to determine the actual
modifier selected for the buffer, as well as the per-plane offset and stride.
Allocators are not permitted to vary the format in use, to select a modifier not
provided within the acceptable list, nor to vary the pixel dimensions other than
the padding expressed through offset, stride, and size.
Communicating additional constraints, such as alignment of stride or offset,
placement within a particular memory area, etc, is out of scope of dma-buf,
and is not solved by format and modifier tokens.
Import
======
To use a buffer within a different context, device, or subsystem, the user
passes these parameters (format, modifier, width, height, and per-plane offset
and stride) to an importing API.
Each memory buffer is referred to by a buffer handle, which may be unique or
duplicated within an image. For example, a ``DRM_FORMAT_NV12`` buffer may have
the luma and chroma buffers combined into a single memory buffer by use of the
per-plane offset parameters, or they may be completely separate allocations in
memory. For this reason, each import and allocation API must provide a separate
handle for each plane.
Each kernel subsystem has its own types and interfaces for buffer management.
DRM uses GEM buffer objects (BOs), V4L2 has its own references, etc. These types
are not portable between contexts, processes, devices, or subsystems.
To address this, ``dma-buf`` handles are used as the universal interchange for
buffers. Subsystem-specific operations are used to export native buffer handles
to a ``dma-buf`` file descriptor, and to import those file descriptors into a
native buffer handle. dma-buf file descriptors can be transferred between
contexts, processes, devices, and subsystems.
For example, a Wayland media player may use V4L2 to decode a video frame into a
``DRM_FORMAT_NV12`` buffer. This will result in two memory planes (luma and
chroma) being dequeued by the user from V4L2. These planes are then exported to
one dma-buf file descriptor per plane, these descriptors are then sent along
with the metadata (format, modifier, width, height, per-plane offset and stride)
to the Wayland server. The Wayland server will then import these file
descriptors as an EGLImage for use through EGL/OpenGL (ES), a VkImage for use
through Vulkan, or a KMS framebuffer object; each of these import operations
will take the same metadata and convert the dma-buf file descriptors into their
native buffer handles.
Having a non-empty intersection of supported modifiers does not guarantee that
import will succeed into all consumers; they may have constraints beyond those
implied by modifiers which must be satisfied.
Implicit modifiers
==================
The concept of modifiers post-dates all of the subsystems mentioned above. As
such, it has been retrofitted into all of these APIs, and in order to ensure
backwards compatibility, support is needed for drivers and userspace which do
not (yet) support modifiers.
As an example, GBM is used to allocate buffers to be shared between EGL for
rendering and KMS for display. It has two entrypoints for allocating buffers:
``gbm_bo_create`` which only takes the format, width, height, and a usage token,
and ``gbm_bo_create_with_modifiers`` which extends this with a list of modifiers.
In the latter case, the allocation is as discussed above, being provided with a
list of acceptable modifiers that the implementation can choose from (or fail if
it is not possible to allocate within those constraints). In the former case
where modifiers are not provided, the GBM implementation must make its own
choice as to what is likely to be the 'best' layout. Such a choice is entirely
implementation-specific: some will internally use tiled layouts which are not
CPU-accessible if the implementation decides that is a good idea through
whatever heuristic. It is the implementation's responsibility to ensure that
this choice is appropriate.
To support this case where the layout is not known because there is no awareness
of modifiers, a special ``DRM_FORMAT_MOD_INVALID`` token has been defined. This
pseudo-modifier declares that the layout is not known, and that the driver
should use its own logic to determine what the underlying layout may be.
.. note::
``DRM_FORMAT_MOD_INVALID`` is a non-zero value. The modifier value zero is
``DRM_FORMAT_MOD_LINEAR``, which is an explicit guarantee that the image
has the linear layout. Care and attention should be taken to ensure that
zero as a default value is not mixed up with either no modifier or the linear
modifier. Also note that in some APIs the invalid modifier value is specified
with an out-of-band flag, like in ``DRM_IOCTL_MODE_ADDFB2``.
There are four cases where this token may be used:
- during enumeration, an interface may return ``DRM_FORMAT_MOD_INVALID``, either
as the sole member of a modifier list to declare that explicit modifiers are
not supported, or as part of a larger list to declare that implicit modifiers
may be used
- during allocation, a user may supply ``DRM_FORMAT_MOD_INVALID``, either as the
sole member of a modifier list (equivalent to not supplying a modifier list
at all) to declare that explicit modifiers are not supported and must not be
used, or as part of a larger list to declare that an allocation using implicit
modifiers is acceptable
- in a post-allocation query, an implementation may return
``DRM_FORMAT_MOD_INVALID`` as the modifier of the allocated buffer to declare
that the underlying layout is implementation-defined and that an explicit
modifier description is not available; per the above rules, this may only be
returned when the user has included ``DRM_FORMAT_MOD_INVALID`` as part of the
list of acceptable modifiers, or not provided a list
- when importing a buffer, the user may supply ``DRM_FORMAT_MOD_INVALID`` as the
buffer modifier (or not supply a modifier) to indicate that the modifier is
unknown for whatever reason; this is only acceptable when the buffer has
not been allocated with an explicit modifier
It follows from this that for any single buffer, the complete chain of operations
formed by the producer and all the consumers must be either fully implicit or fully
explicit. For example, if a user wishes to allocate a buffer for use between
GPU, display, and media, but the media API does not support modifiers, then the
user **must not** allocate the buffer with explicit modifiers and attempt to
import the buffer into the media API with no modifier, but either perform the
allocation using implicit modifiers, or allocate the buffer for media use
separately and copy between the two buffers.
As one exception to the above, allocations may be 'upgraded' from implicit
to explicit modifiers. For example, if the buffer is allocated with
``gbm_bo_create`` (taking no modifiers), the user may then query the modifier with
``gbm_bo_get_modifier`` and then use this modifier as an explicit modifier token
if a valid modifier is returned.
When allocating buffers for exchange between different users and modifiers are
not available, implementations are strongly encouraged to use
``DRM_FORMAT_MOD_LINEAR`` for their allocation, as this is the universal baseline
for exchange. However, it is not guaranteed that this will result in the correct
interpretation of buffer content, as implicit modifier operation may still be
subject to driver-specific heuristics.
Any new users - userspace programs and protocols, kernel subsystems, etc -
wishing to exchange buffers must offer interoperability through dma-buf file
descriptors for memory planes, DRM format tokens to describe the format, DRM
format modifiers to describe the layout in memory, at least width and height for
dimensions, and at least offset and stride for each memory plane.
.. _zwp_linux_dmabuf_v1: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml
.. _VK_EXT_image_drm_format_modifier: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_image_drm_format_modifier.html
.. _EGL_EXT_image_dma_buf_import_modifiers: https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt
@@ -0,0 +1,74 @@
.. SPDX-License-Identifier: GPL-2.0
==============================
Allocating dma-buf using heaps
==============================
Dma-buf Heaps are a way for userspace to allocate dma-buf objects. They are
typically used to allocate buffers from a specific allocation pool, or to share
buffers across frameworks.
Heaps
=====
A heap represents a specific allocator. The Linux kernel currently supports the
following heaps:
- The ``system`` heap allocates virtually contiguous, cacheable, buffers.
- The ``system_cc_shared`` heap allocates virtually contiguous, cacheable,
buffers using shared (decrypted) memory. It is only present on
confidential computing (CoCo) VMs where memory encryption is active
(e.g., AMD SEV, Intel TDX). The allocated pages have the encryption
bit cleared, making them accessible for device DMA without TDISP
support. On non-CoCo VM configurations, this heap is not registered.
- The ``default_cma_region`` heap allocates physically contiguous,
cacheable, buffers. Only present if a CMA region is present. Such a
region is usually created either through the kernel commandline
through the ``cma`` parameter, a memory region Device-Tree node with
the ``linux,cma-default`` property set, or through the
``CMA_SIZE_MBYTES`` or ``CMA_SIZE_PERCENTAGE`` Kconfig options. Prior
to Linux 6.17, its name wasn't stable and could be called
``reserved``, ``linux,cma``, or ``default-pool``, depending on the
platform.
- A heap will be created for each reusable region in the device tree
with the ``shared-dma-pool`` compatible, using the full device tree
node name as its name. The buffer semantics are identical to
``default-cma-region``.
Naming Convention
=================
``dma-buf`` heaps name should meet a number of constraints:
- The name must be stable, and must not change from one version to the other.
Userspace identifies heaps by their name, so if the names ever change, we
would be likely to introduce regressions.
- The name must describe the memory region the heap will allocate from, and
must uniquely identify it in a given platform. Since userspace applications
use the heap name as the discriminant, it must be able to tell which heap it
wants to use reliably if there's multiple heaps.
- The name must not mention implementation details, such as the allocator. The
heap driver will change over time, and implementation details when it was
introduced might not be relevant in the future.
- The name should describe properties of the buffers that would be allocated.
Doing so will make heap identification easier for userspace. Such properties
are:
- ``contiguous`` for physically contiguous buffers;
- ``protected`` for encrypted buffers not accessible the OS;
- The name may describe intended usage. Doing so will make heap identification
easier for userspace applications and users.
For example, assuming a platform with a reserved memory region located
at the RAM address 0x42000000, intended to allocate video framebuffers,
physically contiguous, and backed by the CMA kernel allocator, good
names would be ``memory@42000000-contiguous`` or ``video@42000000``, but
``cma-video`` wouldn't.
@@ -0,0 +1,17 @@
.. SPDX-License-Identifier: GPL-2.0
eBPF Userspace API
==================
eBPF is a kernel mechanism to provide a sandboxed runtime environment in the
Linux kernel for runtime extension and instrumentation without changing kernel
source code or loading kernel modules. eBPF programs can be attached to various
kernel subsystems, including networking, tracing and Linux security modules
(LSM).
For internal kernel documentation on eBPF, see Documentation/bpf/index.rst.
.. toctree::
:maxdepth: 1
syscall
@@ -0,0 +1,24 @@
.. SPDX-License-Identifier: GPL-2.0
eBPF Syscall
------------
:Authors: - Alexei Starovoitov <ast@kernel.org>
- Joe Stringer <joe@wand.net.nz>
- Michael Kerrisk <mtk.manpages@gmail.com>
The primary info for the bpf syscall is available in the `man-pages`_
for `bpf(2)`_.
bpf() subcommand reference
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. kernel-doc:: include/uapi/linux/bpf.h
:doc: eBPF Syscall Preamble
.. kernel-doc:: include/uapi/linux/bpf.h
:doc: eBPF Syscall Commands
.. Links:
.. _man-pages: https://www.kernel.org/doc/man-pages/
.. _bpf(2): https://man7.org/linux/man-pages/man2/bpf.2.html
@@ -0,0 +1,86 @@
.. SPDX-License-Identifier: GPL-2.0
======
futex2
======
:Author: André Almeida <andrealmeid@collabora.com>
futex, or fast user mutex, is a set of syscalls to allow userspace to create
performant synchronization mechanisms, such as mutexes, semaphores and
conditional variables in userspace. C standard libraries, like glibc, uses it
as a means to implement more high level interfaces like pthreads.
futex2 is a followup version of the initial futex syscall, designed to overcome
limitations of the original interface.
User API
========
``futex_waitv()``
-----------------
Wait on an array of futexes, wake on any::
futex_waitv(struct futex_waitv *waiters, unsigned int nr_futexes,
unsigned int flags, struct timespec *timeout, clockid_t clockid)
struct futex_waitv {
__u64 val;
__u64 uaddr;
__u32 flags;
__u32 __reserved;
};
Userspace sets an array of struct futex_waitv (up to a max of 128 entries),
using ``uaddr`` for the address to wait for, ``val`` for the expected value
and ``flags`` to specify the type (e.g. private) and size of futex.
``__reserved`` needs to be 0, but it can be used for future extension. The
pointer for the first item of the array is passed as ``waiters``. An invalid
address for ``waiters`` or for any ``uaddr`` returns ``-EFAULT``.
If userspace has 32-bit pointers, it should do a explicit cast to make sure
the upper bits are zeroed. ``uintptr_t`` does the tricky and it works for
both 32/64-bit pointers.
``nr_futexes`` specifies the size of the array. Numbers out of [1, 128]
interval will make the syscall return ``-EINVAL``.
The ``flags`` argument of the syscall needs to be 0, but it can be used for
future extension.
For each entry in ``waiters`` array, the current value at ``uaddr`` is compared
to ``val``. If it's different, the syscall undo all the work done so far and
return ``-EAGAIN``. If all tests and verifications succeeds, syscall waits until
one of the following happens:
- The timeout expires, returning ``-ETIMEOUT``.
- A signal was sent to the sleeping task, returning ``-ERESTARTSYS``.
- Some futex at the list was woken, returning the index of some waked futex.
An example of how to use the interface can be found at ``tools/testing/selftests/futex/functional/futex_waitv.c``.
Timeout
-------
``struct timespec *timeout`` argument is an optional argument that points to an
absolute timeout. You need to specify the type of clock being used at
``clockid`` argument. ``CLOCK_MONOTONIC`` and ``CLOCK_REALTIME`` are supported.
This syscall accepts only 64bit timespec structs.
Types of futex
--------------
A futex can be either private or shared. Private is used for processes that
shares the same memory space and the virtual address of the futex will be the
same for all processes. This allows for optimizations in the kernel. To use
private futexes, it's necessary to specify ``FUTEX_PRIVATE_FLAG`` in the futex
flag. For processes that doesn't share the same memory space and therefore can
have different virtual addresses for the same futex (using, for instance, a
file-backed shared memory) requires different internal mechanisms to be get
properly enqueued. This is the default behavior, and it works with both private
and shared futexes.
Futexes can be of different sizes: 8, 16, 32 or 64 bits. Currently, the only
supported one is 32 bit sized futex, and it need to be specified using
``FUTEX_32`` flag.
@@ -0,0 +1,74 @@
.. SPDX-License-Identifier: GPL-2.0
=================
fwctl bnxt driver
=================
:Author: Pavan Chebbi
Overview
========
BNXT driver makes a fwctl service available through an auxiliary_device.
The bnxt_fwctl driver binds to this device and registers itself with the
fwctl subsystem.
The bnxt_fwctl driver is agnostic to the device firmware internals. It
uses the Upper Layer Protocol (ULP) conduit provided by bnxt to send
HardWare Resource Manager (HWRM) commands to firmware.
These commands can query or change firmware driven device configurations
and read/write registers that are useful for debugging.
bnxt_fwctl User API
===================
Each RPC request contains the HWRM input structure in the fwctl_rpc
'in' buffer while 'out' will contain the response.
A typical user application can send a FWCTL_INFO command using ioctl()
to discover bnxt_fwctl's RPC capabilities as shown below:
ioctl(fd, FWCTL_INFO, &fwctl_info_msg);
where fwctl_info_msg (of type struct fwctl_info) describes bnxt_info_msg
(of type struct fwctl_info_bnxt). fwctl_info_msg is set up as follows:
size = sizeof(struct fwctl_info);
flags = 0;
device_data_len = sizeof(bnxt_info_msg);
out_device_data = (__aligned_u64)&bnxt_info_msg;
The uctx_caps of bnxt_info_msg represents the capabilities as described
in fwctl_bnxt_commands of include/uapi/fwctl/bnxt.h
The FW RPC itself, FWCTL_RPC can be sent using ioctl() as:
ioctl(fd, FWCTL_RPC, &fwctl_rpc_msg);
where fwctl_rpc_msg (of type struct fwctl_rpc) carries the HWRM command
in its 'in' buffer. The HWRM input structures are described in
include/linux/bnxt/hsi.h. An example for HWRM_VER_GET is shown below:
struct hwrm_ver_get_output resp;
struct fwctl_rpc fwctl_rpc_msg;
struct hwrm_ver_get_input req;
req.req_type = HWRM_VER_GET;
req.hwrm_intf_maj = HWRM_VERSION_MAJOR;
req.hwrm_intf_min = HWRM_VERSION_MINOR;
req.hwrm_intf_upd = HWRM_VERSION_UPDATE;
req.cmpl_ring = -1;
req.target_id = -1;
fwctl_rpc_msg.size = sizeof(struct fwctl_rpc);
fwctl_rpc_msg.scope = FWCTL_RPC_DEBUG_READ_ONLY;
fwctl_rpc_msg.in_len = sizeof(req);
fwctl_rpc_msg.out_len = sizeof(resp);
fwctl_rpc_msg.in = (__aligned_u64)&req;
fwctl_rpc_msg.out = (__aligned_u64)&resp;
An example python3 program that can exercise this interface can be found in
the following git repository:
https://github.com/Broadcom/fwctl-tools
@@ -0,0 +1,142 @@
.. SPDX-License-Identifier: GPL-2.0
================
fwctl cxl driver
================
:Author: Dave Jiang
Overview
========
The CXL spec defines a set of commands that can be issued to the mailbox of a
CXL device or switch. It also left room for vendor specific commands to be
issued to the mailbox as well. fwctl provides a path to issue a set of allowed
mailbox commands from user space to the device moderated by the kernel driver.
The following 3 commands will be used to support CXL Features:
CXL spec r3.1 8.2.9.6.1 Get Supported Features (Opcode 0500h)
CXL spec r3.1 8.2.9.6.2 Get Feature (Opcode 0501h)
CXL spec r3.1 8.2.9.6.3 Set Feature (Opcode 0502h)
The "Get Supported Features" return data may be filtered by the kernel driver to
drop any features that are forbidden by the kernel or being exclusively used by
the kernel. The driver will set the "Set Feature Size" of the "Get Supported
Features Supported Feature Entry" to 0 to indicate that the Feature cannot be
modified. The "Get Supported Features" command and the "Get Features" falls
under the fwctl policy of FWCTL_RPC_CONFIGURATION.
For "Set Feature" command, the access policy currently is broken down into two
categories depending on the Set Feature effects reported by the device. If the
Set Feature will cause immediate change to the device, the fwctl access policy
must be FWCTL_RPC_DEBUG_WRITE_FULL. The effects for this level are
"immediate config change", "immediate data change", "immediate policy change",
or "immediate log change" for the set effects mask. If the effects are "config
change with cold reset" or "config change with conventional reset", then the
fwctl access policy must be FWCTL_RPC_DEBUG_WRITE or higher.
fwctl cxl User API
==================
.. kernel-doc:: include/uapi/fwctl/cxl.h
1. Driver info query
--------------------
First step for the app is to issue the ioctl(FWCTL_CMD_INFO). Successful
invocation of the ioctl implies the Features capability is operational and
returns an all zeros 32bit payload. A ``struct fwctl_info`` needs to be filled
out with the ``fwctl_info.out_device_type`` set to ``FWCTL_DEVICE_TYPE_CXL``.
The return data should be ``struct fwctl_info_cxl`` that contains a reserved
32bit field that should be all zeros.
2. Send hardware commands
-------------------------
Next step is to send the 'Get Supported Features' command to the driver from
user space via ioctl(FWCTL_RPC). A ``struct fwctl_rpc_cxl`` is pointed to
by ``fwctl_rpc.in``. ``struct fwctl_rpc_cxl.in_payload`` points to
the hardware input structure that is defined by the CXL spec. ``fwctl_rpc.out``
points to the buffer that contains a ``struct fwctl_rpc_cxl_out`` that includes
the hardware output data inlined as ``fwctl_rpc_cxl_out.payload``. This command
is called twice. First time to retrieve the number of features supported.
A second time to retrieve the specific feature details as the output data.
After getting the specific feature details, a Get/Set Feature command can be
appropriately programmed and sent. For a "Set Feature" command, the retrieved
feature info contains an effects field that details the resulting
"Set Feature" command will trigger. That will inform the user whether
the system is configured to allowed the "Set Feature" command or not.
Code example of a Get Feature
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: c
static int cxl_fwctl_rpc_get_test_feature(int fd, struct test_feature *feat_ctx,
const uint32_t expected_data)
{
struct cxl_mbox_get_feat_in *feat_in;
struct fwctl_rpc_cxl_out *out;
struct fwctl_rpc rpc = {0};
struct fwctl_rpc_cxl *in;
size_t out_size, in_size;
uint32_t val;
void *data;
int rc;
in_size = sizeof(*in) + sizeof(*feat_in);
rc = posix_memalign((void **)&in, 16, in_size);
if (rc)
return -ENOMEM;
memset(in, 0, in_size);
feat_in = &in->get_feat_in;
uuid_copy(feat_in->uuid, feat_ctx->uuid);
feat_in->count = feat_ctx->get_size;
out_size = sizeof(*out) + feat_ctx->get_size;
rc = posix_memalign((void **)&out, 16, out_size);
if (rc)
goto free_in;
memset(out, 0, out_size);
in->opcode = CXL_MBOX_OPCODE_GET_FEATURE;
in->op_size = sizeof(*feat_in);
rpc.size = sizeof(rpc);
rpc.scope = FWCTL_RPC_CONFIGURATION;
rpc.in_len = in_size;
rpc.out_len = out_size;
rpc.in = (uint64_t)(uint64_t *)in;
rpc.out = (uint64_t)(uint64_t *)out;
rc = send_command(fd, &rpc, out);
if (rc)
goto free_all;
data = out->payload;
val = le32toh(*(__le32 *)data);
if (memcmp(&val, &expected_data, sizeof(val)) != 0) {
rc = -ENXIO;
goto free_all;
}
free_all:
free(out);
free_in:
free(in);
return rc;
}
Take a look at CXL CLI test directory
<https://github.com/pmem/ndctl/tree/main/test/fwctl.c> for a detailed user code
for examples on how to exercise this path.
fwctl cxl Kernel API
====================
.. kernel-doc:: drivers/cxl/core/features.c
:export:
.. kernel-doc:: include/cxl/features.h
@@ -0,0 +1,287 @@
.. SPDX-License-Identifier: GPL-2.0
===============
fwctl subsystem
===============
:Author: Jason Gunthorpe
Overview
========
Modern devices contain extensive amounts of FW, and in many cases, are largely
software-defined pieces of hardware. The evolution of this approach is largely a
reaction to Moore's Law where a chip tape out is now highly expensive, and the
chip design is extremely large. Replacing fixed HW logic with a flexible and
tightly coupled FW/HW combination is an effective risk mitigation against chip
respin. Problems in the HW design can be counteracted in device FW. This is
especially true for devices which present a stable and backwards compatible
interface to the operating system driver (such as NVMe).
The FW layer in devices has grown to incredible size and devices frequently
integrate clusters of fast processors to run it. For example, mlx5 devices have
over 30MB of FW code, and big configurations operate with over 1GB of FW managed
runtime state.
The availability of such a flexible layer has created quite a variety in the
industry where single pieces of silicon are now configurable software-defined
devices and can operate in substantially different ways depending on the need.
Further, we often see cases where specific sites wish to operate devices in ways
that are highly specialized and require applications that have been tailored to
their unique configuration.
Further, devices have become multi-functional and integrated to the point they
no longer fit neatly into the kernel's division of subsystems. Modern
multi-functional devices have drivers, such as bnxt/ice/mlx5/pds, that span many
subsystems while sharing the underlying hardware using the auxiliary device
system.
All together this creates a challenge for the operating system, where devices
have an expansive FW environment that needs robust device-specific debugging
support, and FW-driven functionality that is not well suited to “generic”
interfaces. fwctl seeks to allow access to the full device functionality from
user space in the areas of debuggability, management, and first-boot/nth-boot
provisioning.
fwctl is aimed at the common device design pattern where the OS and FW
communicate via an RPC message layer constructed with a queue or mailbox scheme.
In this case the driver will typically have some layer to deliver RPC messages
and collect RPC responses from device FW. The in-kernel subsystem drivers that
operate the device for its primary purposes will use these RPCs to build their
drivers, but devices also usually have a set of ancillary RPCs that don't really
fit into any specific subsystem. For example, a HW RAID controller is primarily
operated by the block layer but also comes with a set of RPCs to administer the
construction of drives within the HW RAID.
In the past when devices were more single function, individual subsystems would
grow different approaches to solving some of these common problems. For instance,
monitoring device health, manipulating its FLASH, debugging the FW,
provisioning, all have various unique interfaces across the kernel.
fwctl's purpose is to define a common set of limited rules, described below,
that allow user space to securely construct and execute RPCs inside device FW.
The rules serve as an agreement between the operating system and FW on how to
correctly design the RPC interface. As a uAPI the subsystem provides a thin
layer of discovery and a generic uAPI to deliver the RPCs and collect the
response. It supports a system of user space libraries and tools which will
use this interface to control the device using the device native protocols.
Scope of Action
---------------
fwctl drivers are strictly restricted to being a way to operate the device FW.
It is not an avenue to access random kernel internals, or other operating system
SW states.
fwctl instances must operate on a well-defined device function, and the device
should have a well-defined security model for what scope within the physical
device the function is permitted to access. For instance, the most complex PCIe
device today may broadly have several function-level scopes:
1. A privileged function with full access to the on-device global state and
configuration
2. Multiple hypervisor functions with control over itself and child functions
used with VMs
3. Multiple VM functions tightly scoped within the VM
The device may create a logical parent/child relationship between these scopes.
For instance, a child VM's FW may be within the scope of the hypervisor FW. It is
quite common in the VFIO world that the hypervisor environment has a complex
provisioning/profiling/configuration responsibility for the function VFIO
assigns to the VM.
Further, within the function, devices often have RPC commands that fall within
some general scopes of action (see enum fwctl_rpc_scope):
1. Access to function & child configuration, FLASH, etc. that becomes live at a
function reset. Access to function & child runtime configuration that is
transparent or non-disruptive to any driver or VM.
2. Read-only access to function debug information that may report on FW objects
in the function & child, including FW objects owned by other kernel
subsystems.
3. Write access to function & child debug information strictly compatible with
the principles of kernel lockdown and kernel integrity protection. Triggers
a kernel taint.
4. Full debug device access. Triggers a kernel taint, requires CAP_SYS_RAWIO.
User space will provide a scope label on each RPC and the kernel must enforce the
above CAPs and taints based on that scope. A combination of kernel and FW can
enforce that RPCs are placed in the correct scope by user space.
Disallowed behavior
-------------------
There are many things this interface must not allow user space to do (without a
taint or CAP), broadly derived from the principles of kernel lockdown. Some
examples:
1. DMA to/from arbitrary memory, hang the system, compromise FW integrity with
untrusted code, or otherwise compromise device or system security and
integrity.
2. Provide an abnormal “back door” to kernel drivers. No manipulation of kernel
objects owned by kernel drivers.
3. Directly configure or otherwise control kernel drivers. A subsystem kernel
driver can react to the device configuration at function reset/driver load
time, but otherwise must not be coupled to fwctl.
4. Operate the HW in a way that overlaps with the core purpose of another
primary kernel subsystem, such as read/write to LBAs, send/receive of
network packets, or operate an accelerator's data plane.
fwctl is not a replacement for device direct access subsystems like uacce or
VFIO.
Operations exposed through fwctl's non-tainting interfaces should be fully
sharable with other users of the device. For instance, exposing a RPC through
fwctl should never prevent a kernel subsystem from also concurrently using that
same RPC or hardware unit down the road. In such cases fwctl will be less
important than proper kernel subsystems that eventually emerge. Mistakes in this
area resulting in clashes will be resolved in favour of a kernel implementation.
fwctl User API
==============
.. kernel-doc:: include/uapi/fwctl/bnxt.h
.. kernel-doc:: include/uapi/fwctl/fwctl.h
.. kernel-doc:: include/uapi/fwctl/mlx5.h
.. kernel-doc:: include/uapi/fwctl/pds.h
sysfs Class
-----------
fwctl has a sysfs class (/sys/class/fwctl/fwctlNN/) and character devices
(/dev/fwctl/fwctlNN) with a simple numbered scheme. The character device
operates the iotcl uAPI described above.
fwctl devices can be related to driver components in other subsystems through
sysfs::
$ ls /sys/class/fwctl/fwctl0/device/infiniband/
ibp0s10f0
$ ls /sys/class/infiniband/ibp0s10f0/device/fwctl/
fwctl0/
$ ls /sys/devices/pci0000:00/0000:00:0a.0/fwctl/fwctl0
dev device power subsystem uevent
User space Community
--------------------
Drawing inspiration from nvme-cli, participating in the kernel side must come
with a user space in a common TBD git tree, at a minimum to usefully operate the
kernel driver. Providing such an implementation is a pre-condition to merging a
kernel driver.
The goal is to build user space community around some of the shared problems
we all have, and ideally develop some common user space programs with some
starting themes of:
- Device in-field debugging
- HW provisioning
- VFIO child device profiling before VM boot
- Confidential Compute topics (attestation, secure provisioning)
that stretch across all subsystems in the kernel. fwupd is a great example of
how an excellent user space experience can emerge out of kernel-side diversity.
fwctl Kernel API
================
.. kernel-doc:: drivers/fwctl/main.c
:export:
.. kernel-doc:: include/linux/fwctl.h
fwctl Driver design
-------------------
In many cases a fwctl driver is going to be part of a larger cross-subsystem
device possibly using the auxiliary_device mechanism. In that case several
subsystems are going to be sharing the same device and FW interface layer so the
device design must already provide for isolation and cooperation between kernel
subsystems. fwctl should fit into that same model.
Part of the driver should include a description of how its scope restrictions
and security model work. The driver and FW together must ensure that RPCs
provided by user space are mapped to the appropriate scope. If the validation is
done in the driver then the validation can read a 'command effects' report from
the device, or hardwire the enforcement. If the validation is done in the FW,
then the driver should pass the fwctl_rpc_scope to the FW along with the command.
The driver and FW must cooperate to ensure that either fwctl cannot allocate
any FW resources, or any resources it does allocate are freed on FD closure. A
driver primarily constructed around FW RPCs may find that its core PCI function
and RPC layer belongs under fwctl with auxiliary devices connecting to other
subsystems.
Each device type must be mindful of Linux's philosophy for stable ABI. The FW
RPC interface does not have to meet a strictly stable ABI, but it does need to
meet an expectation that user space tools that are deployed and in significant
use don't needlessly break. FW upgrade and kernel upgrade should keep widely
deployed tooling working.
Development and debugging focused RPCs under more permissive scopes can have
less stability if the tools using them are only run under exceptional
circumstances and not for every day use of the device. Debugging tools may even
require exact version matching as they may require something similar to DWARF
debug information from the FW binary.
Security Response
=================
The kernel remains the gatekeeper for this interface. If violations of the
scopes, security or isolation principles are found, we have options to let
devices fix them with a FW update, push a kernel patch to parse and block RPC
commands or push a kernel patch to block entire firmware versions/devices.
While the kernel can always directly parse and restrict RPCs, it is expected
that the existing kernel pattern of allowing drivers to delegate validation to
FW to be a useful design.
Existing Similar Examples
=========================
The approach described in this document is not a new idea. Direct, or near
direct device access has been offered by the kernel in different areas for
decades. With more devices wanting to follow this design pattern it is becoming
clear that it is not entirely well understood and, more importantly, the
security considerations are not well defined or agreed upon.
Some examples:
- HW RAID controllers. This includes RPCs to do things like compose drives into
a RAID volume, configure RAID parameters, monitor the HW and more.
- Baseboard managers. RPCs for configuring settings in the device and more.
- NVMe vendor command capsules. nvme-cli provides access to some monitoring
functions that different products have defined, but more exist.
- CXL also has a NVMe-like vendor command system.
- DRM allows user space drivers to send commands to the device via kernel
mediation.
- RDMA allows user space drivers to directly push commands to the device
without kernel involvement.
- Various “raw” APIs, raw HID (SDL2), raw USB, NVMe Generic Interface, etc.
The first 4 are examples of areas that fwctl intends to cover. The latter three
are examples of disallowed behavior as they fully overlap with the primary purpose
of a kernel subsystem.
Some key lessons learned from these past efforts are the importance of having a
common user space project to use as a pre-condition for obtaining a kernel
driver. Developing good community around useful software in user space is key to
getting companies to fund participation to enable their products.
@@ -0,0 +1,15 @@
.. SPDX-License-Identifier: GPL-2.0
Firmware Control (FWCTL) Userspace API
======================================
A framework that define a common set of limited rules that allows user space
to securely construct and execute RPCs inside device firmware.
.. toctree::
:maxdepth: 1
fwctl
bnxt_fwctl
fwctl-cxl
pds_fwctl
@@ -0,0 +1,46 @@
.. SPDX-License-Identifier: GPL-2.0
================
fwctl pds driver
================
:Author: Shannon Nelson
Overview
========
The PDS Core device makes a fwctl service available through an
auxiliary_device named pds_core.fwctl.N. The pds_fwctl driver binds to
this device and registers itself with the fwctl subsystem. The resulting
userspace interface is used by an application that is a part of the
AMD Pensando software package for the Distributed Service Card (DSC).
The pds_fwctl driver has little knowledge of the firmware's internals.
It only knows how to send commands through pds_core's message queue to the
firmware for fwctl requests. The set of fwctl operations available
depends on the firmware in the DSC, and the userspace application
version must match the firmware so that they can talk to each other.
When a connection is created the pds_fwctl driver requests from the
firmware a list of firmware object endpoints, and for each endpoint the
driver requests a list of operations for that endpoint.
Each operation description includes a firmware defined command attribute
that maps to the FWCTL scope levels. The driver translates those firmware
values into the FWCTL scope values which can then be used for filtering the
scoped user requests.
pds_fwctl User API
==================
Each RPC request includes the target endpoint and the operation id, and in
and out buffer lengths and pointers. The driver verifies the existence
of the requested endpoint and operations, then checks the request scope
against the required scope of the operation. The request is then put
together with the request data and sent through pds_core's message queue
to the firmware, and the results are returned to the caller.
The RPC endpoints, operations, and buffer contents are defined by the
particular firmware package in the device, which varies across the
available product configurations. The details are available in the
specific product SDK documentation.
@@ -0,0 +1,116 @@
.. SPDX-License-Identifier: GPL-2.0
===================================
GPIO Character Device Userspace API
===================================
This is latest version (v2) of the character device API, as defined in
``include/uapi/linux/gpio.h.``
First added in 5.10.
.. note::
Do NOT abuse userspace APIs to control hardware that has proper kernel
drivers. There may already be a driver for your use case, and an existing
kernel driver is sure to provide a superior solution to bitbashing
from userspace.
Read Documentation/driver-api/gpio/drivers-on-gpio.rst to avoid reinventing
kernel wheels in userspace.
Similarly, for multi-function lines there may be other subsystems, such as
Documentation/spi/index.rst, Documentation/i2c/index.rst,
Documentation/driver-api/pwm.rst, Documentation/w1/index.rst etc, that
provide suitable drivers and APIs for your hardware.
Basic examples using the character device API can be found in ``tools/gpio/*``.
The API is based around two major objects, the :ref:`gpio-v2-chip` and the
:ref:`gpio-v2-line-request`.
.. _gpio-v2-chip:
Chip
====
The Chip represents a single GPIO chip and is exposed to userspace using device
files of the form ``/dev/gpiochipX``.
Each chip supports a number of GPIO lines,
:c:type:`chip.lines<gpiochip_info>`. Lines on the chip are identified by an
``offset`` in the range from 0 to ``chip.lines - 1``, i.e. `[0,chip.lines)`.
Lines are requested from the chip using gpio-v2-get-line-ioctl.rst
and the resulting line request is used to access the GPIO chip's lines or
monitor the lines for edge events.
Within this documentation, the file descriptor returned by calling `open()`
on the GPIO device file is referred to as ``chip_fd``.
Operations
----------
The following operations may be performed on the chip:
.. toctree::
:titlesonly:
Get Line <gpio-v2-get-line-ioctl>
Get Chip Info <gpio-get-chipinfo-ioctl>
Get Line Info <gpio-v2-get-lineinfo-ioctl>
Watch Line Info <gpio-v2-get-lineinfo-watch-ioctl>
Unwatch Line Info <gpio-get-lineinfo-unwatch-ioctl>
Read Line Info Changed Events <gpio-v2-lineinfo-changed-read>
.. _gpio-v2-line-request:
Line Request
============
Line requests are created by gpio-v2-get-line-ioctl.rst and provide
access to a set of requested lines. The line request is exposed to userspace
via the anonymous file descriptor returned in
:c:type:`request.fd<gpio_v2_line_request>` by gpio-v2-get-line-ioctl.rst.
Within this documentation, the line request file descriptor is referred to
as ``req_fd``.
Operations
----------
The following operations may be performed on the line request:
.. toctree::
:titlesonly:
Get Line Values <gpio-v2-line-get-values-ioctl>
Set Line Values <gpio-v2-line-set-values-ioctl>
Read Line Edge Events <gpio-v2-line-event-read>
Reconfigure Lines <gpio-v2-line-set-config-ioctl>
Types
=====
This section contains the structs and enums that are referenced by the API v2,
as defined in ``include/uapi/linux/gpio.h``.
.. kernel-doc:: include/uapi/linux/gpio.h
:identifiers:
gpio_v2_line_attr_id
gpio_v2_line_attribute
gpio_v2_line_changed_type
gpio_v2_line_config
gpio_v2_line_config_attribute
gpio_v2_line_event
gpio_v2_line_event_id
gpio_v2_line_flag
gpio_v2_line_info
gpio_v2_line_info_changed
gpio_v2_line_request
gpio_v2_line_values
gpiochip_info
.. toctree::
:hidden:
error-codes
@@ -0,0 +1,131 @@
.. SPDX-License-Identifier: GPL-2.0
========================================
GPIO Character Device Userspace API (v1)
========================================
.. warning::
This API is obsoleted by chardev.rst (v2).
New developments should use the v2 API, and existing developments are
encouraged to migrate as soon as possible, as this API will be removed
in the future. The v2 API is a functional superset of the v1 API so any
v1 call can be directly translated to a v2 equivalent.
This interface will continue to be maintained for the migration period,
but new features will only be added to the new API.
First added in 4.8.
The API is based around three major objects, the :ref:`gpio-v1-chip`, the
:ref:`gpio-v1-line-handle`, and the :ref:`gpio-v1-line-event`.
Where "line event" is used in this document it refers to the request that can
monitor a line for edge events, not the edge events themselves.
.. _gpio-v1-chip:
Chip
====
The Chip represents a single GPIO chip and is exposed to userspace using device
files of the form ``/dev/gpiochipX``.
Each chip supports a number of GPIO lines,
:c:type:`chip.lines<gpiochip_info>`. Lines on the chip are identified by an
``offset`` in the range from 0 to ``chip.lines - 1``, i.e. `[0,chip.lines)`.
Lines are requested from the chip using either gpio-get-linehandle-ioctl.rst
and the resulting line handle is used to access the GPIO chip's lines, or
gpio-get-lineevent-ioctl.rst and the resulting line event is used to monitor
a GPIO line for edge events.
Within this documentation, the file descriptor returned by calling `open()`
on the GPIO device file is referred to as ``chip_fd``.
Operations
----------
The following operations may be performed on the chip:
.. toctree::
:titlesonly:
Get Line Handle <gpio-get-linehandle-ioctl>
Get Line Event <gpio-get-lineevent-ioctl>
Get Chip Info <gpio-get-chipinfo-ioctl>
Get Line Info <gpio-get-lineinfo-ioctl>
Watch Line Info <gpio-get-lineinfo-watch-ioctl>
Unwatch Line Info <gpio-get-lineinfo-unwatch-ioctl>
Read Line Info Changed Events <gpio-lineinfo-changed-read>
.. _gpio-v1-line-handle:
Line Handle
===========
Line handles are created by gpio-get-linehandle-ioctl.rst and provide
access to a set of requested lines. The line handle is exposed to userspace
via the anonymous file descriptor returned in
:c:type:`request.fd<gpiohandle_request>` by gpio-get-linehandle-ioctl.rst.
Within this documentation, the line handle file descriptor is referred to
as ``handle_fd``.
Operations
----------
The following operations may be performed on the line handle:
.. toctree::
:titlesonly:
Get Line Values <gpio-handle-get-line-values-ioctl>
Set Line Values <gpio-handle-set-line-values-ioctl>
Reconfigure Lines <gpio-handle-set-config-ioctl>
.. _gpio-v1-line-event:
Line Event
==========
Line events are created by gpio-get-lineevent-ioctl.rst and provide
access to a requested line. The line event is exposed to userspace
via the anonymous file descriptor returned in
:c:type:`request.fd<gpioevent_request>` by gpio-get-lineevent-ioctl.rst.
Within this documentation, the line event file descriptor is referred to
as ``event_fd``.
Operations
----------
The following operations may be performed on the line event:
.. toctree::
:titlesonly:
Get Line Value <gpio-handle-get-line-values-ioctl>
Read Line Edge Events <gpio-lineevent-data-read>
Types
=====
This section contains the structs that are referenced by the ABI v1.
The :c:type:`struct gpiochip_info<gpiochip_info>` is common to ABI v1 and v2.
.. kernel-doc:: include/uapi/linux/gpio.h
:identifiers:
gpioevent_data
gpioevent_request
gpiohandle_config
gpiohandle_data
gpiohandle_request
gpioline_info
gpioline_info_changed
.. toctree::
:hidden:
error-codes
@@ -0,0 +1,79 @@
.. SPDX-License-Identifier: GPL-2.0
.. _gpio_errors:
*******************
GPIO Error Codes
*******************
.. _gpio-errors:
.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
.. flat-table:: Common GPIO error codes
:header-rows: 0
:stub-columns: 0
:widths: 1 16
- - ``EAGAIN`` (aka ``EWOULDBLOCK``)
- The device was opened in non-blocking mode and a read can't
be performed as there is no data available.
- - ``EBADF``
- The file descriptor is not valid.
- - ``EBUSY``
- The ioctl can't be handled because the device is busy. Typically
returned when an ioctl attempts something that would require the
usage of a resource that was already allocated. The ioctl must not
be retried without performing another action to fix the problem
first.
- - ``EFAULT``
- There was a failure while copying data from/to userspace, probably
caused by an invalid pointer reference.
- - ``EINVAL``
- One or more of the ioctl parameters are invalid or out of the
allowed range. This is a widely used error code.
- - ``ENODEV``
- Device not found or was removed.
- - ``ENOMEM``
- There's not enough memory to handle the desired operation.
- - ``EPERM``
- Permission denied. Typically returned in response to an attempt
to perform an action incompatible with the current line
configuration.
- - ``EIO``
- I/O error. Typically returned when there are problems communicating
with a hardware device or requesting features that hardware does not
support. This could indicate broken or flaky hardware.
It's a 'Something is wrong, I give up!' type of error.
- - ``ENXIO``
- Typically returned when a feature requiring interrupt support was
requested, but the line does not support interrupts.
.. note::
#. This list is not exhaustive; ioctls may return other error codes.
Since errors may have side effects such as a driver reset,
applications should abort on unexpected errors, or otherwise
assume that the device is in a bad state.
#. Request-specific error codes are listed in the individual
requests descriptions.
@@ -0,0 +1,41 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_GET_CHIPINFO_IOCTL:
***********************
GPIO_GET_CHIPINFO_IOCTL
***********************
Name
====
GPIO_GET_CHIPINFO_IOCTL - Get the publicly available information for a chip.
Synopsis
========
.. c:macro:: GPIO_GET_CHIPINFO_IOCTL
``int ioctl(int chip_fd, GPIO_GET_CHIPINFO_IOCTL, struct gpiochip_info *info)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``info``
The :c:type:`chip_info<gpiochip_info>` to be populated.
Description
===========
Gets the publicly available information for a particular GPIO chip.
Return Value
============
On success 0 and ``info`` is populated with the chip info.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,84 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_GET_LINEEVENT_IOCTL:
************************
GPIO_GET_LINEEVENT_IOCTL
************************
.. warning::
This ioctl is part of chardev_v1.rst and is obsoleted by
gpio-v2-get-line-ioctl.rst.
Name
====
GPIO_GET_LINEEVENT_IOCTL - Request a line with edge detection from the kernel.
Synopsis
========
.. c:macro:: GPIO_GET_LINEEVENT_IOCTL
``int ioctl(int chip_fd, GPIO_GET_LINEEVENT_IOCTL, struct gpioevent_request *request)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``request``
The :c:type:`event_request<gpioevent_request>` specifying the line
to request and its configuration.
Description
===========
Request a line with edge detection from the kernel.
On success, the requesting process is granted exclusive access to the line
value and may receive events when edges are detected on the line, as
described in gpio-lineevent-data-read.rst.
The state of a line is guaranteed to remain as requested until the returned
file descriptor is closed. Once the file descriptor is closed, the state of
the line becomes uncontrolled from the userspace perspective, and may revert
to its default state.
Requesting a line already in use is an error (**EBUSY**).
Requesting edge detection on a line that does not support interrupts is an
error (**ENXIO**).
As with the :ref:`line handle<gpio-get-linehandle-config-support>`, the
bias configuration is best effort.
Closing the ``chip_fd`` has no effect on existing line events.
Configuration Rules
-------------------
The following configuration rules apply:
The line event is requested as an input, so no flags specific to output lines,
``GPIOHANDLE_REQUEST_OUTPUT``, ``GPIOHANDLE_REQUEST_OPEN_DRAIN``, or
``GPIOHANDLE_REQUEST_OPEN_SOURCE``, may be set.
Only one bias flag, ``GPIOHANDLE_REQUEST_BIAS_xxx``, may be set.
If no bias flags are set then the bias configuration is not changed.
The edge flags, ``GPIOEVENT_REQUEST_RISING_EDGE`` and
``GPIOEVENT_REQUEST_FALLING_EDGE``, may be combined to detect both rising
and falling edges.
Requesting an invalid configuration is an error (**EINVAL**).
Return Value
============
On success 0 and the :c:type:`request.fd<gpioevent_request>` contains the file
descriptor for the request.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,125 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_GET_LINEHANDLE_IOCTL:
*************************
GPIO_GET_LINEHANDLE_IOCTL
*************************
.. warning::
This ioctl is part of chardev_v1.rst and is obsoleted by
gpio-v2-get-line-ioctl.rst.
Name
====
GPIO_GET_LINEHANDLE_IOCTL - Request a line or lines from the kernel.
Synopsis
========
.. c:macro:: GPIO_GET_LINEHANDLE_IOCTL
``int ioctl(int chip_fd, GPIO_GET_LINEHANDLE_IOCTL, struct gpiohandle_request *request)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``request``
The :c:type:`handle_request<gpiohandle_request>` specifying the lines to
request and their configuration.
Description
===========
Request a line or lines from the kernel.
While multiple lines may be requested, the same configuration applies to all
lines in the request.
On success, the requesting process is granted exclusive access to the line
value and write access to the line configuration.
The state of a line, including the value of output lines, is guaranteed to
remain as requested until the returned file descriptor is closed. Once the
file descriptor is closed, the state of the line becomes uncontrolled from
the userspace perspective, and may revert to its default state.
Requesting a line already in use is an error (**EBUSY**).
Closing the ``chip_fd`` has no effect on existing line handles.
.. _gpio-get-linehandle-config-rules:
Configuration Rules
-------------------
The following configuration rules apply:
The direction flags, ``GPIOHANDLE_REQUEST_INPUT`` and
``GPIOHANDLE_REQUEST_OUTPUT``, cannot be combined. If neither are set then the
only other flag that may be set is ``GPIOHANDLE_REQUEST_ACTIVE_LOW`` and the
line is requested "as-is" to allow reading of the line value without altering
the electrical configuration.
The drive flags, ``GPIOHANDLE_REQUEST_OPEN_xxx``, require the
``GPIOHANDLE_REQUEST_OUTPUT`` to be set.
Only one drive flag may be set.
If none are set then the line is assumed push-pull.
Only one bias flag, ``GPIOHANDLE_REQUEST_BIAS_xxx``, may be set, and
it requires a direction flag to also be set.
If no bias flags are set then the bias configuration is not changed.
Requesting an invalid configuration is an error (**EINVAL**).
.. _gpio-get-linehandle-config-support:
Configuration Support
---------------------
Where the requested configuration is not directly supported by the underlying
hardware and driver, the kernel applies one of these approaches:
- reject the request
- emulate the feature in software
- treat the feature as best effort
The approach applied depends on whether the feature can reasonably be emulated
in software, and the impact on the hardware and userspace if the feature is not
supported.
The approach applied for each feature is as follows:
============== ===========
Feature Approach
============== ===========
Bias best effort
Direction reject
Drive emulate
============== ===========
Bias is treated as best effort to allow userspace to apply the same
configuration for platforms that support internal bias as those that require
external bias.
Worst case the line floats rather than being biased as expected.
Drive is emulated by switching the line to an input when the line should not
be driven.
In all cases, the configuration reported by gpio-get-lineinfo-ioctl.rst
is the requested configuration, not the resulting hardware configuration.
Userspace cannot determine if a feature is supported in hardware, is
emulated, or is best effort.
Return Value
============
On success 0 and the :c:type:`request.fd<gpiohandle_request>` contains the
file descriptor for the request.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,54 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_GET_LINEINFO_IOCTL:
***********************
GPIO_GET_LINEINFO_IOCTL
***********************
.. warning::
This ioctl is part of chardev_v1.rst and is obsoleted by
gpio-v2-get-lineinfo-ioctl.rst.
Name
====
GPIO_GET_LINEINFO_IOCTL - Get the publicly available information for a line.
Synopsis
========
.. c:macro:: GPIO_GET_LINEINFO_IOCTL
``int ioctl(int chip_fd, GPIO_GET_LINEINFO_IOCTL, struct gpioline_info *info)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``info``
The :c:type:`line_info<gpioline_info>` to be populated, with the
``offset`` field set to indicate the line to be collected.
Description
===========
Get the publicly available information for a line.
This information is available independent of whether the line is in use.
.. note::
The line info does not include the line value.
The line must be requested using gpio-get-linehandle-ioctl.rst or
gpio-get-lineevent-ioctl.rst to access its value.
Return Value
============
On success 0 and ``info`` is populated with the chip info.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,49 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_GET_LINEINFO_UNWATCH_IOCTL:
*******************************
GPIO_GET_LINEINFO_UNWATCH_IOCTL
*******************************
Name
====
GPIO_GET_LINEINFO_UNWATCH_IOCTL - Disable watching a line for changes to its
requested state and configuration information.
Synopsis
========
.. c:macro:: GPIO_GET_LINEINFO_UNWATCH_IOCTL
``int ioctl(int chip_fd, GPIO_GET_LINEINFO_UNWATCH_IOCTL, u32 *offset)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``offset``
The offset of the line to no longer watch.
Description
===========
Remove the line from the list of lines being watched on this ``chip_fd``.
This is the reverse of gpio-v2-get-lineinfo-watch-ioctl.rst (v2) and
gpio-get-lineinfo-watch-ioctl.rst (v1).
Unwatching a line that is not watched is an error (**EBUSY**).
First added in 5.7.
Return Value
============
On success 0.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,74 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_GET_LINEINFO_WATCH_IOCTL:
*****************************
GPIO_GET_LINEINFO_WATCH_IOCTL
*****************************
.. warning::
This ioctl is part of chardev_v1.rst and is obsoleted by
gpio-v2-get-lineinfo-watch-ioctl.rst.
Name
====
GPIO_GET_LINEINFO_WATCH_IOCTL - Enable watching a line for changes to its
request state and configuration information.
Synopsis
========
.. c:macro:: GPIO_GET_LINEINFO_WATCH_IOCTL
``int ioctl(int chip_fd, GPIO_GET_LINEINFO_WATCH_IOCTL, struct gpioline_info *info)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``info``
The :c:type:`line_info<gpioline_info>` struct to be populated, with
the ``offset`` set to indicate the line to watch
Description
===========
Enable watching a line for changes to its request state and configuration
information. Changes to line info include a line being requested, released
or reconfigured.
.. note::
Watching line info is not generally required, and would typically only be
used by a system monitoring component.
The line info does NOT include the line value.
The line must be requested using gpio-get-linehandle-ioctl.rst or
gpio-get-lineevent-ioctl.rst to access its value, and the line event can
monitor a line for events using gpio-lineevent-data-read.rst.
By default all lines are unwatched when the GPIO chip is opened.
Multiple lines may be watched simultaneously by adding a watch for each.
Once a watch is set, any changes to line info will generate events which can be
read from the ``chip_fd`` as described in
gpio-lineinfo-changed-read.rst.
Adding a watch to a line that is already watched is an error (**EBUSY**).
Watches are specific to the ``chip_fd`` and are independent of watches
on the same GPIO chip opened with a separate call to `open()`.
First added in 5.7.
Return Value
============
On success 0 and ``info`` is populated with the current line info.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,63 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIOHANDLE_GET_LINE_VALUES_IOCTL:
********************************
GPIOHANDLE_GET_LINE_VALUES_IOCTL
********************************
.. warning::
This ioctl is part of chardev_v1.rst and is obsoleted by
gpio-v2-line-get-values-ioctl.rst.
Name
====
GPIOHANDLE_GET_LINE_VALUES_IOCTL - Get the values of all requested lines.
Synopsis
========
.. c:macro:: GPIOHANDLE_GET_LINE_VALUES_IOCTL
``int ioctl(int handle_fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, struct gpiohandle_data *values)``
Arguments
=========
``handle_fd``
The file descriptor of the GPIO character device, as returned in the
:c:type:`request.fd<gpiohandle_request>` by gpio-get-linehandle-ioctl.rst.
``values``
The :c:type:`line_values<gpiohandle_data>` to be populated.
Description
===========
Get the values of all requested lines.
The values returned are logical, indicating if the line is active or inactive.
The ``GPIOHANDLE_REQUEST_ACTIVE_LOW`` flag controls the mapping between physical
values (high/low) and logical values (active/inactive).
If ``GPIOHANDLE_REQUEST_ACTIVE_LOW`` is not set then high is active and
low is inactive. If ``GPIOHANDLE_REQUEST_ACTIVE_LOW`` is set then low is active
and high is inactive.
The values of both input and output lines may be read.
For output lines, the value returned is driver and configuration dependent and
may be either the output buffer (the last requested value set) or the input
buffer (the actual level of the line), and depending on the hardware and
configuration these may differ.
This ioctl can also be used to read the line value for line events,
substituting the ``event_fd`` for the ``handle_fd``. As there is only
one line requested in that case, only the one value is returned in ``values``.
Return Value
============
On success 0 and ``values`` populated with the values read.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,66 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIOHANDLE_SET_CONFIG_IOCTL:
***************************
GPIOHANDLE_SET_CONFIG_IOCTL
***************************
.. warning::
This ioctl is part of chardev_v1.rst and is obsoleted by
gpio-v2-line-set-config-ioctl.rst.
Name
====
GPIOHANDLE_SET_CONFIG_IOCTL - Update the configuration of previously requested lines.
Synopsis
========
.. c:macro:: GPIOHANDLE_SET_CONFIG_IOCTL
``int ioctl(int handle_fd, GPIOHANDLE_SET_CONFIG_IOCTL, struct gpiohandle_config *config)``
Arguments
=========
``handle_fd``
The file descriptor of the GPIO character device, as returned in the
:c:type:`request.fd<gpiohandle_request>` by gpio-get-linehandle-ioctl.rst.
``config``
The new :c:type:`configuration<gpiohandle_config>` to apply to the
requested lines.
Description
===========
Update the configuration of previously requested lines, without releasing the
line or introducing potential glitches.
The configuration applies to all requested lines.
The same :ref:`gpio-get-linehandle-config-rules` and
:ref:`gpio-get-linehandle-config-support` that apply when requesting the
lines also apply when updating the line configuration, with the additional
restriction that a direction flag must be set. Requesting an invalid
configuration, including without a direction flag set, is an error
(**EINVAL**).
The motivating use case for this command is changing direction of
bi-directional lines between input and output, but it may be used more
generally to move lines seamlessly from one configuration state to another.
To only change the value of output lines, use
gpio-handle-set-line-values-ioctl.rst.
First added in 5.5.
Return Value
============
On success 0.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,55 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_HANDLE_SET_LINE_VALUES_IOCTL:
*********************************
GPIO_HANDLE_SET_LINE_VALUES_IOCTL
*********************************
.. warning::
This ioctl is part of chardev_v1.rst and is obsoleted by
gpio-v2-line-set-values-ioctl.rst.
Name
====
GPIO_HANDLE_SET_LINE_VALUES_IOCTL - Set the values of all requested output lines.
Synopsis
========
.. c:macro:: GPIO_HANDLE_SET_LINE_VALUES_IOCTL
``int ioctl(int handle_fd, GPIO_HANDLE_SET_LINE_VALUES_IOCTL, struct gpiohandle_data *values)``
Arguments
=========
``handle_fd``
The file descriptor of the GPIO character device, as returned in the
:c:type:`request.fd<gpiohandle_request>` by gpio-get-linehandle-ioctl.rst.
``values``
The :c:type:`line_values<gpiohandle_data>` to set.
Description
===========
Set the values of all requested output lines.
The values set are logical, indicating if the line is to be active or inactive.
The ``GPIOHANDLE_REQUEST_ACTIVE_LOW`` flag controls the mapping between logical
values (active/inactive) and physical values (high/low).
If ``GPIOHANDLE_REQUEST_ACTIVE_LOW`` is not set then active is high and
inactive is low. If ``GPIOHANDLE_REQUEST_ACTIVE_LOW`` is set then active is low
and inactive is high.
Only the values of output lines may be set.
Attempting to set the value of input lines is an error (**EPERM**).
Return Value
============
On success 0.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,89 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_LINEEVENT_DATA_READ:
************************
GPIO_LINEEVENT_DATA_READ
************************
.. warning::
This ioctl is part of chardev_v1.rst and is obsoleted by
gpio-v2-line-event-read.rst.
Name
====
GPIO_LINEEVENT_DATA_READ - Read edge detection events from a line event.
Synopsis
========
``int read(int event_fd, void *buf, size_t count)``
Arguments
=========
``event_fd``
The file descriptor of the GPIO character device, as returned in the
:c:type:`request.fd<gpioevent_request>` by gpio-get-lineevent-ioctl.rst.
``buf``
The buffer to contain the :c:type:`events<gpioevent_data>`.
``count``
The number of bytes available in ``buf``, which must be at
least the size of a :c:type:`gpioevent_data`.
Description
===========
Read edge detection events for a line from a line event.
Edge detection must be enabled for the input line using either
``GPIOEVENT_REQUEST_RISING_EDGE`` or ``GPIOEVENT_REQUEST_FALLING_EDGE``, or
both. Edge events are then generated whenever edge interrupts are detected on
the input line.
Edges are defined in terms of changes to the logical line value, so an inactive
to active transition is a rising edge. If ``GPIOHANDLE_REQUEST_ACTIVE_LOW`` is
set then logical polarity is the opposite of physical polarity, and
``GPIOEVENT_REQUEST_RISING_EDGE`` then corresponds to a falling physical edge.
The kernel captures and timestamps edge events as close as possible to their
occurrence and stores them in a buffer from where they can be read by
userspace at its convenience using `read()`.
The source of the clock for :c:type:`event.timestamp<gpioevent_data>` is
``CLOCK_MONOTONIC``, except for kernels earlier than Linux 5.7 when it was
``CLOCK_REALTIME``. There is no indication in the :c:type:`gpioevent_data`
as to which clock source is used, it must be determined from either the kernel
version or sanity checks on the timestamp itself.
Events read from the buffer are always in the same order that they were
detected by the kernel.
The size of the kernel event buffer is fixed at 16 events.
The buffer may overflow if bursts of events occur quicker than they are read
by userspace. If an overflow occurs then the most recent event is discarded.
Overflow cannot be detected from userspace.
To minimize the number of calls required to copy events from the kernel to
userspace, `read()` supports copying multiple events. The number of events
copied is the lower of the number available in the kernel buffer and the
number that will fit in the userspace buffer (``buf``).
The `read()` will block if no event is available and the ``event_fd`` has not
been set **O_NONBLOCK**.
The presence of an event can be tested for by checking that the ``event_fd`` is
readable using `poll()` or an equivalent.
Return Value
============
On success the number of bytes read, which will be a multiple of the size of
a :c:type:`gpio_lineevent_data` event.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,87 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_LINEINFO_CHANGED_READ:
**************************
GPIO_LINEINFO_CHANGED_READ
**************************
.. warning::
This ioctl is part of chardev_v1.rst and is obsoleted by
gpio-v2-lineinfo-changed-read.rst.
Name
====
GPIO_LINEINFO_CHANGED_READ - Read line info change events for watched lines
from the chip.
Synopsis
========
``int read(int chip_fd, void *buf, size_t count)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``buf``
The buffer to contain the :c:type:`events<gpioline_info_changed>`.
``count``
The number of bytes available in ``buf``, which must be at least the size
of a :c:type:`gpioline_info_changed` event.
Description
===========
Read line info change events for watched lines from the chip.
.. note::
Monitoring line info changes is not generally required, and would typically
only be performed by a system monitoring component.
These events relate to changes in a line's request state or configuration,
not its value. Use gpio-lineevent-data-read.rst to receive events when a
line changes value.
A line must be watched using gpio-get-lineinfo-watch-ioctl.rst to generate
info changed events. Subsequently, a request, release, or reconfiguration
of the line will generate an info changed event.
The kernel timestamps events when they occur and stores them in a buffer
from where they can be read by userspace at its convenience using `read()`.
The size of the kernel event buffer is fixed at 32 events per ``chip_fd``.
The buffer may overflow if bursts of events occur quicker than they are read
by userspace. If an overflow occurs then the most recent event is discarded.
Overflow cannot be detected from userspace.
Events read from the buffer are always in the same order that they were
detected by the kernel, including when multiple lines are being monitored by
the one ``chip_fd``.
To minimize the number of calls required to copy events from the kernel to
userspace, `read()` supports copying multiple events. The number of events
copied is the lower of the number available in the kernel buffer and the
number that will fit in the userspace buffer (``buf``).
A `read()` will block if no event is available and the ``chip_fd`` has not
been set **O_NONBLOCK**.
The presence of an event can be tested for by checking that the ``chip_fd`` is
readable using `poll()` or an equivalent.
First added in 5.7.
Return Value
============
On success the number of bytes read, which will be a multiple of the size of
a :c:type:`gpioline_info_changed` event.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,152 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_V2_GET_LINE_IOCTL:
**********************
GPIO_V2_GET_LINE_IOCTL
**********************
Name
====
GPIO_V2_GET_LINE_IOCTL - Request a line or lines from the kernel.
Synopsis
========
.. c:macro:: GPIO_V2_GET_LINE_IOCTL
``int ioctl(int chip_fd, GPIO_V2_GET_LINE_IOCTL, struct gpio_v2_line_request *request)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``request``
The :c:type:`line_request<gpio_v2_line_request>` specifying the lines
to request and their configuration.
Description
===========
On success, the requesting process is granted exclusive access to the line
value, write access to the line configuration, and may receive events when
edges are detected on the line, all of which are described in more detail in
:ref:`gpio-v2-line-request`.
A number of lines may be requested in the one line request, and request
operations are performed on the requested lines by the kernel as atomically
as possible. e.g. gpio-v2-line-get-values-ioctl.rst will read all the
requested lines at once.
The state of a line, including the value of output lines, is guaranteed to
remain as requested until the returned file descriptor is closed. Once the
file descriptor is closed, the state of the line becomes uncontrolled from
the userspace perspective, and may revert to its default state.
Requesting a line already in use is an error (**EBUSY**).
Closing the ``chip_fd`` has no effect on existing line requests.
.. _gpio-v2-get-line-config-rules:
Configuration Rules
-------------------
For any given requested line, the following configuration rules apply:
The direction flags, ``GPIO_V2_LINE_FLAG_INPUT`` and
``GPIO_V2_LINE_FLAG_OUTPUT``, cannot be combined. If neither are set then
the only other flag that may be set is ``GPIO_V2_LINE_FLAG_ACTIVE_LOW``
and the line is requested "as-is" to allow reading of the line value
without altering the electrical configuration.
The drive flags, ``GPIO_V2_LINE_FLAG_OPEN_xxx``, require the
``GPIO_V2_LINE_FLAG_OUTPUT`` to be set.
Only one drive flag may be set.
If none are set then the line is assumed push-pull.
Only one bias flag, ``GPIO_V2_LINE_FLAG_BIAS_xxx``, may be set, and it
requires a direction flag to also be set.
If no bias flags are set then the bias configuration is not changed.
The edge flags, ``GPIO_V2_LINE_FLAG_EDGE_xxx``, require
``GPIO_V2_LINE_FLAG_INPUT`` to be set and may be combined to detect both rising
and falling edges. Requesting edge detection from a line that does not support
it is an error (**ENXIO**).
Only one event clock flag, ``GPIO_V2_LINE_FLAG_EVENT_CLOCK_xxx``, may be set.
If none are set then the event clock defaults to ``CLOCK_MONOTONIC``.
The ``GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE`` flag requires supporting hardware
and a kernel with ``CONFIG_HTE`` set. Requesting HTE from a device that
doesn't support it is an error (**EOPNOTSUPP**).
The :c:type:`debounce_period_us<gpio_v2_line_attribute>` attribute may only
be applied to lines with ``GPIO_V2_LINE_FLAG_INPUT`` set. When set, debounce
applies to both the values returned by gpio-v2-line-get-values-ioctl.rst and
the edges returned by gpio-v2-line-event-read.rst. If not
supported directly by hardware, debouncing is emulated in software by the
kernel. Requesting debounce on a line that supports neither debounce in
hardware nor interrupts, as required for software emulation, is an error
(**ENXIO**).
Requesting an invalid configuration is an error (**EINVAL**).
.. _gpio-v2-get-line-config-support:
Configuration Support
---------------------
Where the requested configuration is not directly supported by the underlying
hardware and driver, the kernel applies one of these approaches:
- reject the request
- emulate the feature in software
- treat the feature as best effort
The approach applied depends on whether the feature can reasonably be emulated
in software, and the impact on the hardware and userspace if the feature is not
supported.
The approach applied for each feature is as follows:
============== ===========
Feature Approach
============== ===========
Bias best effort
Debounce emulate
Direction reject
Drive emulate
Edge Detection reject
============== ===========
Bias is treated as best effort to allow userspace to apply the same
configuration for platforms that support internal bias as those that require
external bias.
Worst case the line floats rather than being biased as expected.
Debounce is emulated by applying a filter to hardware interrupts on the line.
An edge event is generated after an edge is detected and the line remains
stable for the debounce period.
The event timestamp corresponds to the end of the debounce period.
Drive is emulated by switching the line to an input when the line should not
be actively driven.
Edge detection requires interrupt support, and is rejected if that is not
supported. Emulation by polling can still be performed from userspace.
In all cases, the configuration reported by gpio-v2-get-lineinfo-ioctl.rst
is the requested configuration, not the resulting hardware configuration.
Userspace cannot determine if a feature is supported in hardware, is
emulated, or is best effort.
Return Value
============
On success 0 and the :c:type:`request.fd<gpio_v2_line_request>` contains the
file descriptor for the request.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,50 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_V2_GET_LINEINFO_IOCTL:
**************************
GPIO_V2_GET_LINEINFO_IOCTL
**************************
Name
====
GPIO_V2_GET_LINEINFO_IOCTL - Get the publicly available information for a line.
Synopsis
========
.. c:macro:: GPIO_V2_GET_LINEINFO_IOCTL
``int ioctl(int chip_fd, GPIO_V2_GET_LINEINFO_IOCTL, struct gpio_v2_line_info *info)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``info``
The :c:type:`line_info<gpio_v2_line_info>` to be populated, with the
``offset`` field set to indicate the line to be collected.
Description
===========
Get the publicly available information for a line.
This information is available independent of whether the line is in use.
.. note::
The line info does not include the line value.
The line must be requested using gpio-v2-get-line-ioctl.rst to access its
value.
Return Value
============
On success 0 and ``info`` is populated with the chip info.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,67 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_V2_GET_LINEINFO_WATCH_IOCTL:
********************************
GPIO_V2_GET_LINEINFO_WATCH_IOCTL
********************************
Name
====
GPIO_V2_GET_LINEINFO_WATCH_IOCTL - Enable watching a line for changes to its
request state and configuration information.
Synopsis
========
.. c:macro:: GPIO_V2_GET_LINEINFO_WATCH_IOCTL
``int ioctl(int chip_fd, GPIO_V2_GET_LINEINFO_WATCH_IOCTL, struct gpio_v2_line_info *info)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``info``
The :c:type:`line_info<gpio_v2_line_info>` struct to be populated, with
the ``offset`` set to indicate the line to watch
Description
===========
Enable watching a line for changes to its request state and configuration
information. Changes to line info include a line being requested, released
or reconfigured.
.. note::
Watching line info is not generally required, and would typically only be
used by a system monitoring component.
The line info does NOT include the line value.
The line must be requested using gpio-v2-get-line-ioctl.rst to access
its value, and the line request can monitor a line for events using
gpio-v2-line-event-read.rst.
By default all lines are unwatched when the GPIO chip is opened.
Multiple lines may be watched simultaneously by adding a watch for each.
Once a watch is set, any changes to line info will generate events which can be
read from the ``chip_fd`` as described in
gpio-v2-lineinfo-changed-read.rst.
Adding a watch to a line that is already watched is an error (**EBUSY**).
Watches are specific to the ``chip_fd`` and are independent of watches
on the same GPIO chip opened with a separate call to `open()`.
Return Value
============
On success 0 and ``info`` is populated with the current line info.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,88 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_V2_LINE_EVENT_READ:
***********************
GPIO_V2_LINE_EVENT_READ
***********************
Name
====
GPIO_V2_LINE_EVENT_READ - Read edge detection events for lines from a request.
Synopsis
========
``int read(int req_fd, void *buf, size_t count)``
Arguments
=========
``req_fd``
The file descriptor of the GPIO character device, as returned in the
:c:type:`request.fd<gpio_v2_line_request>` by gpio-v2-get-line-ioctl.rst.
``buf``
The buffer to contain the :c:type:`events<gpio_v2_line_event>`.
``count``
The number of bytes available in ``buf``, which must be at
least the size of a :c:type:`gpio_v2_line_event`.
Description
===========
Read edge detection events for lines from a request.
Edge detection must be enabled for the input line using either
``GPIO_V2_LINE_FLAG_EDGE_RISING`` or ``GPIO_V2_LINE_FLAG_EDGE_FALLING``, or
both. Edge events are then generated whenever edge interrupts are detected on
the input line.
Edges are defined in terms of changes to the logical line value, so an inactive
to active transition is a rising edge. If ``GPIO_V2_LINE_FLAG_ACTIVE_LOW`` is
set then logical polarity is the opposite of physical polarity, and
``GPIO_V2_LINE_FLAG_EDGE_RISING`` then corresponds to a falling physical edge.
The kernel captures and timestamps edge events as close as possible to their
occurrence and stores them in a buffer from where they can be read by
userspace at its convenience using `read()`.
Events read from the buffer are always in the same order that they were
detected by the kernel, including when multiple lines are being monitored by
the one request.
The size of the kernel event buffer is fixed at the time of line request
creation, and can be influenced by the
:c:type:`request.event_buffer_size<gpio_v2_line_request>`.
The default size is 16 times the number of lines requested.
The buffer may overflow if bursts of events occur quicker than they are read
by userspace. If an overflow occurs then the oldest buffered event is
discarded. Overflow can be detected from userspace by monitoring the event
sequence numbers.
To minimize the number of calls required to copy events from the kernel to
userspace, `read()` supports copying multiple events. The number of events
copied is the lower of the number available in the kernel buffer and the
number that will fit in the userspace buffer (``buf``).
Changing the edge detection flags using gpio-v2-line-set-config-ioctl.rst
does not remove or modify the events already contained in the kernel event
buffer.
The `read()` will block if no event is available and the ``req_fd`` has not
been set **O_NONBLOCK**.
The presence of an event can be tested for by checking that the ``req_fd`` is
readable using `poll()` or an equivalent.
Return Value
============
On success the number of bytes read, which will be a multiple of the size of a
:c:type:`gpio_v2_line_event` event.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,58 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_V2_LINE_GET_VALUES_IOCTL:
*****************************
GPIO_V2_LINE_GET_VALUES_IOCTL
*****************************
Name
====
GPIO_V2_LINE_GET_VALUES_IOCTL - Get the values of requested lines.
Synopsis
========
.. c:macro:: GPIO_V2_LINE_GET_VALUES_IOCTL
``int ioctl(int req_fd, GPIO_V2_LINE_GET_VALUES_IOCTL, struct gpio_v2_line_values *values)``
Arguments
=========
``req_fd``
The file descriptor of the GPIO character device, as returned in the
:c:type:`request.fd<gpio_v2_line_request>` by gpio-v2-get-line-ioctl.rst.
``values``
The :c:type:`line_values<gpio_v2_line_values>` to get with the ``mask`` set
to indicate the subset of requested lines to get.
Description
===========
Get the values of requested lines.
The values returned are logical, indicating if the line is active or inactive.
The ``GPIO_V2_LINE_FLAG_ACTIVE_LOW`` flag controls the mapping between physical
values (high/low) and logical values (active/inactive).
If ``GPIO_V2_LINE_FLAG_ACTIVE_LOW`` is not set then high is active and low is
inactive. If ``GPIO_V2_LINE_FLAG_ACTIVE_LOW`` is set then low is active and
high is inactive.
The values of both input and output lines may be read.
For output lines, the value returned is driver and configuration dependent and
may be either the output buffer (the last requested value set) or the input
buffer (the actual level of the line), and depending on the hardware and
configuration these may differ.
Return Value
============
On success 0 and the corresponding :c:type:`values.bits<gpio_v2_line_values>`
contain the value read.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,61 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_V2_LINE_SET_CONFIG_IOCTL:
*****************************
GPIO_V2_LINE_SET_CONFIG_IOCTL
*****************************
Name
====
GPIO_V2_LINE_SET_CONFIG_IOCTL - Update the configuration of previously requested lines.
Synopsis
========
.. c:macro:: GPIO_V2_LINE_SET_CONFIG_IOCTL
``int ioctl(int req_fd, GPIO_V2_LINE_SET_CONFIG_IOCTL, struct gpio_v2_line_config *config)``
Arguments
=========
``req_fd``
The file descriptor of the GPIO character device, as returned in the
:c:type:`request.fd<gpio_v2_line_request>` by gpio-v2-get-line-ioctl.rst.
``config``
The new :c:type:`configuration<gpio_v2_line_config>` to apply to the
requested lines.
Description
===========
Update the configuration of previously requested lines, without releasing the
line or introducing potential glitches.
The new configuration must specify a configuration for all requested lines.
The same :ref:`gpio-v2-get-line-config-rules` and
:ref:`gpio-v2-get-line-config-support` that apply when requesting the lines
also apply when updating the line configuration, with the additional
restriction that a direction flag must be set to enable reconfiguration.
If no direction flag is set in the configuration for a given line then the
configuration for that line is left unchanged.
The motivating use case for this command is changing direction of
bi-directional lines between input and output, but it may also be used to
dynamically control edge detection, or more generally move lines seamlessly
from one configuration state to another.
To only change the value of output lines, use
gpio-v2-line-set-values-ioctl.rst.
Return Value
============
On success 0.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,54 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_V2_LINE_SET_VALUES_IOCTL:
*****************************
GPIO_V2_LINE_SET_VALUES_IOCTL
*****************************
Name
====
GPIO_V2_LINE_SET_VALUES_IOCTL - Set the values of requested output lines.
Synopsis
========
.. c:macro:: GPIO_V2_LINE_SET_VALUES_IOCTL
``int ioctl(int req_fd, GPIO_V2_LINE_SET_VALUES_IOCTL, struct gpio_v2_line_values *values)``
Arguments
=========
``req_fd``
The file descriptor of the GPIO character device, as returned in the
:c:type:`request.fd<gpio_v2_line_request>` by gpio-v2-get-line-ioctl.rst.
``values``
The :c:type:`line_values<gpio_v2_line_values>` to set with the ``mask`` set
to indicate the subset of requested lines to set and ``bits`` set to
indicate the new value.
Description
===========
Set the values of requested output lines.
The values set are logical, indicating if the line is to be active or inactive.
The ``GPIO_V2_LINE_FLAG_ACTIVE_LOW`` flag controls the mapping between logical
values (active/inactive) and physical values (high/low).
If ``GPIO_V2_LINE_FLAG_ACTIVE_LOW`` is not set then active is high and inactive
is low. If ``GPIO_V2_LINE_FLAG_ACTIVE_LOW`` is set then active is low and
inactive is high.
Only the values of output lines may be set.
Attempting to set the value of an input line is an error (**EPERM**).
Return Value
============
On success 0.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,81 @@
.. SPDX-License-Identifier: GPL-2.0
.. _GPIO_V2_LINEINFO_CHANGED_READ:
*****************************
GPIO_V2_LINEINFO_CHANGED_READ
*****************************
Name
====
GPIO_V2_LINEINFO_CHANGED_READ - Read line info changed events for watched
lines from the chip.
Synopsis
========
``int read(int chip_fd, void *buf, size_t count)``
Arguments
=========
``chip_fd``
The file descriptor of the GPIO character device returned by `open()`.
``buf``
The buffer to contain the :c:type:`events<gpio_v2_line_info_changed>`.
``count``
The number of bytes available in ``buf``, which must be at least the size
of a :c:type:`gpio_v2_line_info_changed` event.
Description
===========
Read line info changed events for watched lines from the chip.
.. note::
Monitoring line info changes is not generally required, and would typically
only be performed by a system monitoring component.
These events relate to changes in a line's request state or configuration,
not its value. Use gpio-v2-line-event-read.rst to receive events when a
line changes value.
A line must be watched using gpio-v2-get-lineinfo-watch-ioctl.rst to generate
info changed events. Subsequently, a request, release, or reconfiguration
of the line will generate an info changed event.
The kernel timestamps events when they occur and stores them in a buffer
from where they can be read by userspace at its convenience using `read()`.
The size of the kernel event buffer is fixed at 32 events per ``chip_fd``.
The buffer may overflow if bursts of events occur quicker than they are read
by userspace. If an overflow occurs then the most recent event is discarded.
Overflow cannot be detected from userspace.
Events read from the buffer are always in the same order that they were
detected by the kernel, including when multiple lines are being monitored by
the one ``chip_fd``.
To minimize the number of calls required to copy events from the kernel to
userspace, `read()` supports copying multiple events. The number of events
copied is the lower of the number available in the kernel buffer and the
number that will fit in the userspace buffer (``buf``).
A `read()` will block if no event is available and the ``chip_fd`` has not
been set **O_NONBLOCK**.
The presence of an event can be tested for by checking that the ``chip_fd`` is
readable using `poll()` or an equivalent.
Return Value
============
On success the number of bytes read, which will be a multiple of the size
of a :c:type:`gpio_v2_line_info_changed` event.
On error -1 and the ``errno`` variable is set appropriately.
Common error codes are described in error-codes.rst.
@@ -0,0 +1,11 @@
.. SPDX-License-Identifier: GPL-2.0
====
GPIO
====
.. toctree::
:maxdepth: 1
Character Device Userspace API <chardev>
Obsolete Userspace APIs <obsolete>
@@ -0,0 +1,11 @@
.. SPDX-License-Identifier: GPL-2.0
============================
Obsolete GPIO Userspace APIs
============================
.. toctree::
:maxdepth: 1
Character Device Userspace API (v1) <chardev_v1>
Sysfs Interface <sysfs>
@@ -0,0 +1,171 @@
GPIO Sysfs Interface for Userspace
==================================
.. warning::
This API is obsoleted by the chardev.rst and the ABI documentation has
been moved to Documentation/ABI/obsolete/sysfs-gpio.
New developments should use the chardev.rst, and existing developments are
encouraged to migrate as soon as possible, as this API will be removed
in the future.
This interface will continue to be maintained for the migration period,
but new features will only be added to the new API.
The obsolete sysfs ABI
----------------------
Platforms which use the "gpiolib" implementors framework may choose to
configure a sysfs user interface to GPIOs. This is different from the
debugfs interface, since it provides control over GPIO direction and
value instead of just showing a gpio state summary. Plus, it could be
present on production systems without debugging support.
Given appropriate hardware documentation for the system, userspace could
know for example that GPIO #23 controls the write protect line used to
protect boot loader segments in flash memory. System upgrade procedures
may need to temporarily remove that protection, first importing a GPIO,
then changing its output state, then updating the code before re-enabling
the write protection. In normal use, GPIO #23 would never be touched,
and the kernel would have no need to know about it.
Again depending on appropriate hardware documentation, on some systems
userspace GPIO can be used to determine system configuration data that
standard kernels won't know about. And for some tasks, simple userspace
GPIO drivers could be all that the system really needs.
.. note::
Do NOT abuse sysfs to control hardware that has proper kernel drivers.
Please read Documentation/driver-api/gpio/drivers-on-gpio.rst
to avoid reinventing kernel wheels in userspace.
I MEAN IT. REALLY.
Paths in Sysfs
--------------
There are three kinds of entries in /sys/class/gpio:
- Control interfaces used to get userspace control over GPIOs;
- GPIOs themselves; and
- GPIO controllers ("gpio_chip" instances).
That's in addition to standard files including the "device" symlink.
The control interfaces are write-only:
/sys/class/gpio/
"export" ...
Userspace may ask the kernel to export control of
a GPIO to userspace by writing its number to this file.
Example: "echo 19 > export" will create a "gpio19" node
for GPIO #19, if that's not requested by kernel code.
"unexport" ...
Reverses the effect of exporting to userspace.
Example: "echo 19 > unexport" will remove a "gpio19"
node exported using the "export" file.
GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
and have the following read/write attributes:
/sys/class/gpio/gpioN/
"direction" ...
reads as either "in" or "out". This value may
normally be written. Writing as "out" defaults to
initializing the value as low. To ensure glitch free
operation, values "low" and "high" may be written to
configure the GPIO as an output with that initial value.
Note that this attribute *will not exist* if the kernel
doesn't support changing the direction of a GPIO, or
it was exported by kernel code that didn't explicitly
allow userspace to reconfigure this GPIO's direction.
"value" ...
reads as either 0 (inactive) or 1 (active). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as active.
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, use pread(2) to read the value at offset
zero. Alternatively, either lseek(2) to the beginning of the
sysfs file and read the new value or close the file and
re-open it to read the value.
"edge" ...
reads as either "none", "rising", "falling", or
"both". Write these strings to select the signal edge(s)
that will make poll(2) on the "value" file return.
This file exists only if the pin can be configured as an
interrupt generating input pin.
"active_low" ...
reads as either 0 (false) or 1 (true). Write
any nonzero value to invert the value attribute both
for reading and writing. Existing and subsequent
poll(2) support configuration via the edge attribute
for "rising" and "falling" edges will follow this
setting.
GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
controller implementing GPIOs starting at #42) and have the following
read-only attributes:
/sys/class/gpio/gpiochipN/
"base" ...
same as N, the first GPIO managed by this chip
"label" ...
provided for diagnostics (not always unique)
"ngpio" ...
how many GPIOs this manages (N to N + ngpio - 1)
Board documentation should in most cases cover what GPIOs are used for
what purposes. However, those numbers are not always stable; GPIOs on
a daughtercard might be different depending on the base board being used,
or other cards in the stack. In such cases, you may need to use the
gpiochip nodes (possibly in conjunction with schematics) to determine
the correct GPIO number to use for a given signal.
Exporting from Kernel code
--------------------------
Kernel code can explicitly manage exports of GPIOs which have already been
requested using gpio_request()::
/* export the GPIO to userspace */
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
/* reverse gpiod_export() */
void gpiod_unexport(struct gpio_desc *desc);
/* create a sysfs link to an exported GPIO node */
int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc);
After a kernel driver requests a GPIO, it may only be made available in
the sysfs interface by gpiod_export(). The driver can control whether the
signal direction may change. This helps drivers prevent userspace code
from accidentally clobbering important system state.
This explicit exporting can help with debugging (by making some kinds
of experiments easier), or can provide an always-there interface that's
suitable for documenting as part of a board support package.
After the GPIO has been exported, gpiod_export_link() allows creating
symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
use this to provide the interface under their own device in sysfs with
a descriptive name.
@@ -0,0 +1,71 @@
=====================================
The Linux kernel user-space API guide
=====================================
.. _man-pages: https://www.kernel.org/doc/man-pages/
While much of the kernel's user-space API is documented elsewhere
(particularly in the man-pages_ project), some user-space information can
also be found in the kernel tree itself. This manual is intended to be the
place where this information is gathered.
System calls
============
.. toctree::
:maxdepth: 1
unshare
futex2
ebpf/index
ioctl/index
mseal
rseq
Security-related interfaces
===========================
.. toctree::
:maxdepth: 1
no_new_privs
seccomp_filter
landlock
lsm
mfd_noexec
spec_ctrl
tee
check_exec
Devices and I/O
===============
.. toctree::
:maxdepth: 1
accelerators/ocxl
dma-buf-heaps
dma-buf-alloc-exchange
fwctl/index
gpio/index
iommufd
media/index
dcdbas
vduse
isapnp
Everything else
===============
.. toctree::
:maxdepth: 1
ELF
liveupdate
netlink/index
sysfs-platform_profile
vduse
futex2
perf_ring_buffer
ntsync
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,547 @@
==============================
Summary of `HDIO_` ioctl calls
==============================
- Edward A. Falk <efalk@google.com>
November, 2004
This document attempts to describe the ioctl(2) calls supported by
the HD/IDE layer. These are by-and-large implemented (as of Linux 5.11)
drivers/ata/libata-scsi.c.
ioctl values are listed in <linux/hdreg.h>. As of this writing, they
are as follows:
ioctls that pass argument pointers to user space:
======================= =======================================
HDIO_GETGEO get device geometry
HDIO_GET_32BIT get current io_32bit setting
HDIO_GET_IDENTITY get IDE identification info
HDIO_DRIVE_TASKFILE execute raw taskfile
HDIO_DRIVE_TASK execute task and special drive command
HDIO_DRIVE_CMD execute a special drive command
======================= =======================================
ioctls that pass non-pointer values:
======================= =======================================
HDIO_SET_32BIT change io_32bit flags
======================= =======================================
The information that follows was determined from reading kernel source
code. It is likely that some corrections will be made over time.
------------------------------------------------------------------------------
General:
Unless otherwise specified, all ioctl calls return 0 on success
and -1 with errno set to an appropriate value on error.
Unless otherwise specified, all ioctl calls return -1 and set
errno to EFAULT on a failed attempt to copy data to or from user
address space.
Unless otherwise specified, all data structures and constants
are defined in <linux/hdreg.h>
------------------------------------------------------------------------------
HDIO_GETGEO
get device geometry
usage::
struct hd_geometry geom;
ioctl(fd, HDIO_GETGEO, &geom);
inputs:
none
outputs:
hd_geometry structure containing:
========= ==================================
heads number of heads
sectors number of sectors/track
cylinders number of cylinders, mod 65536
start starting sector of this partition.
========= ==================================
error returns:
- EINVAL
if the device is not a disk drive or floppy drive,
or if the user passes a null pointer
notes:
Not particularly useful with modern disk drives, whose geometry
is a polite fiction anyway. Modern drives are addressed
purely by sector number nowadays (lba addressing), and the
drive geometry is an abstraction which is actually subject
to change. Currently (as of Nov 2004), the geometry values
are the "bios" values -- presumably the values the drive had
when Linux first booted.
In addition, the cylinders field of the hd_geometry is an
unsigned short, meaning that on most architectures, this
ioctl will not return a meaningful value on drives with more
than 65535 tracks.
The start field is unsigned long, meaning that it will not
contain a meaningful value for disks over 219 Gb in size.
HDIO_GET_IDENTITY
get IDE identification info
usage::
unsigned char identity[512];
ioctl(fd, HDIO_GET_IDENTITY, identity);
inputs:
none
outputs:
ATA drive identity information. For full description, see
the IDENTIFY DEVICE and IDENTIFY PACKET DEVICE commands in
the ATA specification.
error returns:
- EINVAL Called on a partition instead of the whole disk device
- ENOMSG IDENTIFY DEVICE information not available
notes:
Returns information that was obtained when the drive was
probed. Some of this information is subject to change, and
this ioctl does not re-probe the drive to update the
information.
This information is also available from /proc/ide/hdX/identify
HDIO_GET_32BIT
get current io_32bit setting
usage::
long val;
ioctl(fd, HDIO_GET_32BIT, &val);
inputs:
none
outputs:
The value of the current io_32bit setting
notes:
0=16-bit, 1=32-bit, 2,3 = 32bit+sync
HDIO_DRIVE_TASKFILE
execute raw taskfile
Note:
If you don't have a copy of the ANSI ATA specification
handy, you should probably ignore this ioctl.
- Execute an ATA disk command directly by writing the "taskfile"
registers of the drive. Requires ADMIN and RAWIO access
privileges.
usage::
struct {
ide_task_request_t req_task;
u8 outbuf[OUTPUT_SIZE];
u8 inbuf[INPUT_SIZE];
} task;
memset(&task.req_task, 0, sizeof(task.req_task));
task.req_task.out_size = sizeof(task.outbuf);
task.req_task.in_size = sizeof(task.inbuf);
...
ioctl(fd, HDIO_DRIVE_TASKFILE, &task);
...
inputs:
(See below for details on memory area passed to ioctl.)
============ ===================================================
io_ports[8] values to be written to taskfile registers
hob_ports[8] high-order bytes, for extended commands.
out_flags flags indicating which registers are valid
in_flags flags indicating which registers should be returned
data_phase see below
req_cmd command type to be executed
out_size size of output buffer
outbuf buffer of data to be transmitted to disk
inbuf buffer of data to be received from disk (see [1])
============ ===================================================
outputs:
=========== ====================================================
io_ports[] values returned in the taskfile registers
hob_ports[] high-order bytes, for extended commands.
out_flags flags indicating which registers are valid (see [2])
in_flags flags indicating which registers should be returned
outbuf buffer of data to be transmitted to disk (see [1])
inbuf buffer of data to be received from disk
=========== ====================================================
error returns:
- EACCES CAP_SYS_ADMIN or CAP_SYS_RAWIO privilege not set.
- ENOMSG Device is not a disk drive.
- ENOMEM Unable to allocate memory for task
- EFAULT req_cmd == TASKFILE_IN_OUT (not implemented as of 2.6.8)
- EPERM
req_cmd == TASKFILE_MULTI_OUT and drive
multi-count not yet set.
- EIO Drive failed the command.
notes:
[1] READ THE FOLLOWING NOTES *CAREFULLY*. THIS IOCTL IS
FULL OF GOTCHAS. Extreme caution should be used with using
this ioctl. A mistake can easily corrupt data or hang the
system.
[2] Both the input and output buffers are copied from the
user and written back to the user, even when not used.
[3] If one or more bits are set in out_flags and in_flags is
zero, the following values are used for in_flags.all and
written back into in_flags on completion.
* IDE_TASKFILE_STD_IN_FLAGS | (IDE_HOB_STD_IN_FLAGS << 8)
if LBA48 addressing is enabled for the drive
* IDE_TASKFILE_STD_IN_FLAGS
if CHS/LBA28
The association between in_flags.all and each enable
bitfield flips depending on endianness; fortunately, TASKFILE
only uses inflags.b.data bit and ignores all other bits.
The end result is that, on any endian machines, it has no
effect other than modifying in_flags on completion.
[4] The default value of SELECT is (0xa0|DEV_bit|LBA_bit)
except for four drives per port chipsets. For four drives
per port chipsets, it's (0xa0|DEV_bit|LBA_bit) for the first
pair and (0x80|DEV_bit|LBA_bit) for the second pair.
[5] The argument to the ioctl is a pointer to a region of
memory containing a ide_task_request_t structure, followed
by an optional buffer of data to be transmitted to the
drive, followed by an optional buffer to receive data from
the drive.
Command is passed to the disk drive via the ide_task_request_t
structure, which contains these fields:
============ ===============================================
io_ports[8] values for the taskfile registers
hob_ports[8] high-order bytes, for extended commands
out_flags flags indicating which entries in the
io_ports[] and hob_ports[] arrays
contain valid values. Type ide_reg_valid_t.
in_flags flags indicating which entries in the
io_ports[] and hob_ports[] arrays
are expected to contain valid values
on return.
data_phase See below
req_cmd Command type, see below
out_size output (user->drive) buffer size, bytes
in_size input (drive->user) buffer size, bytes
============ ===============================================
When out_flags is zero, the following registers are loaded.
============ ===============================================
HOB_FEATURE If the drive supports LBA48
HOB_NSECTOR If the drive supports LBA48
HOB_SECTOR If the drive supports LBA48
HOB_LCYL If the drive supports LBA48
HOB_HCYL If the drive supports LBA48
FEATURE
NSECTOR
SECTOR
LCYL
HCYL
SELECT First, masked with 0xE0 if LBA48, 0xEF
otherwise; then, or'ed with the default
value of SELECT.
============ ===============================================
If any bit in out_flags is set, the following registers are loaded.
============ ===============================================
HOB_DATA If out_flags.b.data is set. HOB_DATA will
travel on DD8-DD15 on little endian machines
and on DD0-DD7 on big endian machines.
DATA If out_flags.b.data is set. DATA will
travel on DD0-DD7 on little endian machines
and on DD8-DD15 on big endian machines.
HOB_NSECTOR If out_flags.b.nsector_hob is set
HOB_SECTOR If out_flags.b.sector_hob is set
HOB_LCYL If out_flags.b.lcyl_hob is set
HOB_HCYL If out_flags.b.hcyl_hob is set
FEATURE If out_flags.b.feature is set
NSECTOR If out_flags.b.nsector is set
SECTOR If out_flags.b.sector is set
LCYL If out_flags.b.lcyl is set
HCYL If out_flags.b.hcyl is set
SELECT Or'ed with the default value of SELECT and
loaded regardless of out_flags.b.select.
============ ===============================================
Taskfile registers are read back from the drive into
{io|hob}_ports[] after the command completes iff one of the
following conditions is met; otherwise, the original values
will be written back, unchanged.
1. The drive fails the command (EIO).
2. One or more than one bits are set in out_flags.
3. The requested data_phase is TASKFILE_NO_DATA.
============ ===============================================
HOB_DATA If in_flags.b.data is set. It will contain
DD8-DD15 on little endian machines and
DD0-DD7 on big endian machines.
DATA If in_flags.b.data is set. It will contain
DD0-DD7 on little endian machines and
DD8-DD15 on big endian machines.
HOB_FEATURE If the drive supports LBA48
HOB_NSECTOR If the drive supports LBA48
HOB_SECTOR If the drive supports LBA48
HOB_LCYL If the drive supports LBA48
HOB_HCYL If the drive supports LBA48
NSECTOR
SECTOR
LCYL
HCYL
============ ===============================================
The data_phase field describes the data transfer to be
performed. Value is one of:
=================== ========================================
TASKFILE_IN
TASKFILE_MULTI_IN
TASKFILE_OUT
TASKFILE_MULTI_OUT
TASKFILE_IN_OUT
TASKFILE_IN_DMA
TASKFILE_IN_DMAQ == IN_DMA (queueing not supported)
TASKFILE_OUT_DMA
TASKFILE_OUT_DMAQ == OUT_DMA (queueing not supported)
TASKFILE_P_IN unimplemented
TASKFILE_P_IN_DMA unimplemented
TASKFILE_P_IN_DMAQ unimplemented
TASKFILE_P_OUT unimplemented
TASKFILE_P_OUT_DMA unimplemented
TASKFILE_P_OUT_DMAQ unimplemented
=================== ========================================
The req_cmd field classifies the command type. It may be
one of:
======================== =======================================
IDE_DRIVE_TASK_NO_DATA
IDE_DRIVE_TASK_SET_XFER unimplemented
IDE_DRIVE_TASK_IN
IDE_DRIVE_TASK_OUT unimplemented
IDE_DRIVE_TASK_RAW_WRITE
======================== =======================================
[6] Do not access {in|out}_flags->all except for resetting
all the bits. Always access individual bit fields. ->all
value will flip depending on endianness. For the same
reason, do not use IDE_{TASKFILE|HOB}_STD_{OUT|IN}_FLAGS
constants defined in hdreg.h.
HDIO_DRIVE_CMD
execute a special drive command
Note: If you don't have a copy of the ANSI ATA specification
handy, you should probably ignore this ioctl.
usage::
u8 args[4+XFER_SIZE];
...
ioctl(fd, HDIO_DRIVE_CMD, args);
inputs:
Commands other than WIN_SMART:
======= =======
args[0] COMMAND
args[1] NSECTOR
args[2] FEATURE
args[3] NSECTOR
======= =======
WIN_SMART:
======= =======
args[0] COMMAND
args[1] SECTOR
args[2] FEATURE
args[3] NSECTOR
======= =======
outputs:
args[] buffer is filled with register values followed by any
data returned by the disk.
======== ====================================================
args[0] status
args[1] error
args[2] NSECTOR
args[3] undefined
args[4+] NSECTOR * 512 bytes of data returned by the command.
======== ====================================================
error returns:
- EACCES Access denied: requires CAP_SYS_RAWIO
- ENOMEM Unable to allocate memory for task
- EIO Drive reports error
notes:
[1] For commands other than WIN_SMART, args[1] should equal
args[3]. SECTOR, LCYL and HCYL are undefined. For
WIN_SMART, 0x4f and 0xc2 are loaded into LCYL and HCYL
respectively. In both cases SELECT will contain the default
value for the drive. Please refer to HDIO_DRIVE_TASKFILE
notes for the default value of SELECT.
[2] If NSECTOR value is greater than zero and the drive sets
DRQ when interrupting for the command, NSECTOR * 512 bytes
are read from the device into the area following NSECTOR.
In the above example, the area would be
args[4..4+XFER_SIZE]. 16bit PIO is used regardless of
HDIO_SET_32BIT setting.
[3] If COMMAND == WIN_SETFEATURES && FEATURE == SETFEATURES_XFER
&& NSECTOR >= XFER_SW_DMA_0 && the drive supports any DMA
mode, IDE driver will try to tune the transfer mode of the
drive accordingly.
HDIO_DRIVE_TASK
execute task and special drive command
Note: If you don't have a copy of the ANSI ATA specification
handy, you should probably ignore this ioctl.
usage::
u8 args[7];
...
ioctl(fd, HDIO_DRIVE_TASK, args);
inputs:
Taskfile register values:
======= =======
args[0] COMMAND
args[1] FEATURE
args[2] NSECTOR
args[3] SECTOR
args[4] LCYL
args[5] HCYL
args[6] SELECT
======= =======
outputs:
Taskfile register values:
======= =======
args[0] status
args[1] error
args[2] NSECTOR
args[3] SECTOR
args[4] LCYL
args[5] HCYL
args[6] SELECT
======= =======
error returns:
- EACCES Access denied: requires CAP_SYS_RAWIO
- ENOMEM Unable to allocate memory for task
- ENOMSG Device is not a disk drive.
- EIO Drive failed the command.
notes:
[1] DEV bit (0x10) of SELECT register is ignored and the
appropriate value for the drive is used. All other bits
are used unaltered.
HDIO_SET_32BIT
change io_32bit flags
usage::
int val;
ioctl(fd, HDIO_SET_32BIT, val);
inputs:
New value for io_32bit flag
outputs:
none
error return:
- EINVAL Called on a partition instead of the whole disk device
- EACCES Access denied: requires CAP_SYS_ADMIN
- EINVAL value out of range [0 3]
- EBUSY Controller busy
@@ -0,0 +1,15 @@
.. SPDX-License-Identifier: GPL-2.0
======
IOCTLs
======
.. toctree::
:maxdepth: 1
ioctl-number
ioctl-decoding
cdrom
hdio
@@ -0,0 +1,31 @@
==============================
Decoding an IOCTL Magic Number
==============================
To decode a hex IOCTL code:
Most architectures use this generic format, but check
include/ARCH/ioctl.h for specifics, e.g. powerpc
uses 3 bits to encode read/write and 13 bits for size.
====== ==================================
bits meaning
====== ==================================
31-30 00 - no parameters: uses _IO macro
10 - read: _IOR
01 - write: _IOW
11 - read/write: _IOWR
29-16 size of arguments
15-8 ascii character supposedly
unique to each driver
7-0 function #
====== ==================================
So for example 0x82187201 is a read with arg length of 0x218,
character 'r' function 1. Grepping the source reveals this is::
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
@@ -0,0 +1,412 @@
=============
Ioctl Numbers
=============
19 October 1999
Michael Elizabeth Chastain
<mec@shout.net>
If you are adding new ioctl's to the kernel, you should use the _IO
macros defined in <linux/ioctl.h>:
====== ===========================
macro parameters
====== ===========================
_IO none
_IOW write (read from userspace)
_IOR read (write to userspace)
_IOWR write and read
====== ===========================
'Write' and 'read' are from the user's point of view, just like the
system calls 'write' and 'read'. For example, a SET_FOO ioctl would
be _IOW, although the kernel would actually read data from user space;
a GET_FOO ioctl would be _IOR, although the kernel would actually write
data to user space.
The first argument to the macros is an identifying letter or number from
the table below. Because of the large number of drivers, many drivers
share a partial letter with other drivers.
If you are writing a driver for a new device and need a letter, pick an
unused block with enough room for expansion: 32 to 256 ioctl commands
should suffice. You can register the block by patching this file and
submitting the patch through :doc:`usual patch submission process
</process/submitting-patches>`.
The second argument is a sequence number to distinguish ioctls from each
other. The third argument (not applicable to _IO) is the type of the data
going into the kernel or coming out of the kernel (e.g. 'int' or
'struct foo').
.. note::
Do NOT use sizeof(arg) as the third argument as this results in your
ioctl thinking it passes an argument of type size_t.
Some devices use their major number as the identifier; this is OK, as
long as it is unique. Some devices are irregular and don't follow any
convention at all.
Following this convention is good because:
(1) Keeping the ioctl's globally unique helps error checking:
if a program calls an ioctl on the wrong device, it will get an
error rather than some unexpected behaviour.
(2) The 'strace' build procedure automatically finds ioctl numbers
defined with the macros.
(3) 'strace' can decode numbers back into useful names when the
numbers are unique.
(4) People looking for ioctls can grep for them more easily when
this convention is used to define the ioctl numbers.
(5) When following the convention, the driver code can use generic
code to copy the parameters between user and kernel space.
This table lists ioctls visible from userland, excluding ones from
drivers/staging/.
==== ===== ========================================================= ================================================================
Code Seq# Include File Comments
(hex)
==== ===== ========================================================= ================================================================
0x00 00-1F linux/fs.h conflict!
0x00 00-1F scsi/scsi_ioctl.h conflict!
0x00 00-1F linux/fb.h conflict!
0x00 00-1F linux/wavefront.h conflict!
0x02 all linux/fd.h
0x03 all linux/hdreg.h
0x04 D2-DC linux/umsdos_fs.h Dead since 2.6.11, but don't reuse these.
0x06 all linux/lp.h
0x07 9F-D0 linux/vmw_vmci_defs.h, uapi/linux/vm_sockets.h
0x09 all linux/raid/md_u.h
0x10 00-0F drivers/char/s390/vmcp.h
0x10 10-1F arch/s390/include/uapi/sclp_ctl.h
0x10 20-2F arch/s390/include/uapi/asm/hypfs.h
0x12 all linux/fs.h BLK* ioctls
linux/blkpg.h
linux/blkzoned.h
linux/blk-crypto.h
0x15 all linux/fs.h FS_IOC_* ioctls
0x1b all InfiniBand Subsystem
<http://infiniband.sourceforge.net/>
0x20 all drivers/cdrom/cm206.h
0x22 all scsi/sg.h
0x3E 00-0F linux/counter.h <mailto:linux-iio@vger.kernel.org>
'!' 00-1F uapi/linux/seccomp.h
'#' 00-3F IEEE 1394 Subsystem
Block for the entire subsystem
'$' 00-0F linux/perf_counter.h, linux/perf_event.h
'%' 00-0F include/uapi/linux/stm.h System Trace Module subsystem
<mailto:alexander.shishkin@linux.intel.com>
'&' 00-07 drivers/firewire/nosy-user.h
'*' 00-1F uapi/linux/user_events.h User Events Subsystem
<mailto:linux-trace-kernel@vger.kernel.org>
'1' 00-1F linux/timepps.h PPS kit from Ulrich Windl
<ftp://ftp.de.kernel.org/pub/linux/daemons/ntp/PPS/>
'2' 01-04 linux/i2o.h
'3' 00-0F drivers/s390/char/raw3270.h conflict!
'3' 00-1F linux/suspend_ioctls.h, conflict!
kernel/power/user.c
'8' all SNP8023 advanced NIC card
<mailto:mcr@solidum.com>
';' 64-7F linux/vfio.h
';' 80-FF linux/iommufd.h
'=' 00-3f uapi/linux/ptp_clock.h <mailto:richardcochran@gmail.com>
'@' 00-0F linux/radeonfb.h conflict!
'@' 00-0F drivers/video/aty/aty128fb.c conflict!
'A' 00-1F linux/apm_bios.h conflict!
'A' 00-0F linux/agpgart.h, conflict!
drivers/char/agp/compat_ioctl.h
'A' 00-7F sound/asound.h conflict!
'B' 00-1F linux/cciss_ioctl.h conflict!
'B' 00-0F include/linux/pmu.h conflict!
'B' C0-FF advanced bbus <mailto:maassen@uni-freiburg.de>
'B' 00-0F xen/xenbus_dev.h conflict!
'C' all linux/soundcard.h conflict!
'C' 01-2F linux/capi.h conflict!
'C' F0-FF drivers/net/wan/cosa.h conflict!
'D' all arch/s390/include/asm/dasd.h
'D' 40-5F drivers/scsi/dpt/dtpi_ioctl.h Dead since 2022
'D' 05 drivers/scsi/pmcraid.h
'E' all linux/input.h conflict!
'E' 00-0F xen/evtchn.h conflict!
'F' all linux/fb.h conflict!
'F' 01-02 drivers/scsi/pmcraid.h conflict!
'F' 20 drivers/video/fsl-diu-fb.h conflict!
'F' 20 linux/ivtvfb.h conflict!
'F' 20 linux/matroxfb.h conflict!
'F' 20 drivers/video/aty/atyfb_base.c conflict!
'F' 00-0F video/da8xx-fb.h conflict!
'F' 80-8F linux/arcfb.h conflict!
'F' DD video/sstfb.h conflict!
'G' 00-3F drivers/misc/sgi-gru/grulib.h conflict!
'G' 00-0F xen/gntalloc.h, xen/gntdev.h conflict!
'H' 00-7F linux/hiddev.h conflict!
'H' 00-0F linux/hidraw.h conflict!
'H' 01 linux/mei.h conflict!
'H' 02 linux/mei.h conflict!
'H' 03 linux/mei.h conflict!
'H' 00-0F sound/asound.h conflict!
'H' 20-40 sound/asound_fm.h conflict!
'H' 80-8F sound/sfnt_info.h conflict!
'H' 10-8F sound/emu10k1.h conflict!
'H' 10-1F sound/sb16_csp.h conflict!
'H' 10-1F sound/hda_hwdep.h conflict!
'H' 40-4F sound/hdspm.h conflict!
'H' 40-4F sound/hdsp.h conflict!
'H' 90 sound/usb/usx2y/usb_stream.h
'H' 00-0F uapi/misc/habanalabs.h conflict!
'H' A0 uapi/linux/usb/cdc-wdm.h
'H' C0-F0 net/bluetooth/hci.h conflict!
'H' C0-DF net/bluetooth/hidp/hidp.h conflict!
'H' C0-DF net/bluetooth/cmtp/cmtp.h conflict!
'H' C0-DF net/bluetooth/bnep/bnep.h conflict!
'H' F1 linux/hid-roccat.h <mailto:erazor_de@users.sourceforge.net>
'H' F8-FA sound/firewire.h
'I' all linux/isdn.h conflict!
'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict!
'I' 40-4F linux/mISDNif.h conflict!
'K' all linux/kd.h
'L' 00-1F linux/loop.h conflict!
'L' 10-1F drivers/scsi/mpt3sas/mpt3sas_ctl.h conflict!
'L' E0-FF linux/ppdd.h encrypted disk device driver
<http://linux01.gwdg.de/~alatham/ppdd.html>
'M' all linux/soundcard.h conflict!
'M' 01-16 mtd/mtd-abi.h conflict!
and drivers/mtd/mtdchar.c
'M' 01-03 drivers/scsi/megaraid/megaraid_sas.h
'M' 00-0F drivers/video/fsl-diu-fb.h conflict!
'N' 00-1F drivers/usb/scanner.h
'N' 40-7F drivers/block/nvme.c
'N' 80-8F uapi/linux/ntsync.h NT synchronization primitives
<mailto:wine-devel@winehq.org>
'O' 00-06 mtd/ubi-user.h UBI
'P' all linux/soundcard.h conflict!
'P' 60-6F sound/sscape_ioctl.h conflict!
'P' 00-0F drivers/usb/class/usblp.c conflict!
'P' 01-09 drivers/misc/pci_endpoint_test.c conflict!
'P' 00-0F xen/privcmd.h conflict!
'P' 00-05 linux/tps6594_pfsm.h conflict!
'Q' all linux/soundcard.h
'R' 00-1F linux/random.h conflict!
'R' 01 linux/rfkill.h conflict!
'R' 20-2F linux/trace_mmap.h
'R' C0-DF net/bluetooth/rfcomm.h
'R' E0 uapi/linux/fsl_mc.h
'S' all linux/cdrom.h conflict!
'S' 80-81 scsi/scsi_ioctl.h conflict!
'S' 82-FF scsi/scsi.h conflict!
'S' 00-7F sound/asequencer.h conflict!
'T' all linux/soundcard.h conflict!
'T' 00-AF sound/asound.h conflict!
'T' all arch/x86/include/asm/ioctls.h conflict!
'T' C0-DF linux/if_tun.h conflict!
'U' all sound/asound.h conflict!
'U' 00-CF linux/uinput.h conflict!
'U' 00-EF linux/usbdevice_fs.h
'U' C0-CF drivers/bluetooth/hci_uart.h
'V' all linux/vt.h conflict!
'V' all linux/videodev2.h conflict!
'V' C0 linux/ivtvfb.h conflict!
'V' C0 linux/ivtv.h conflict!
'V' C0 media/si4713.h conflict!
'W' 00-1F linux/watchdog.h conflict!
'W' 00-1F linux/wanrouter.h conflict! (pre 3.9)
'W' 00-3F sound/asound.h conflict!
'W' 40-5F drivers/pci/switch/switchtec.c
'W' 60-61 linux/watch_queue.h
'X' all fs/xfs/xfs_fs.h, conflict!
fs/xfs/linux-2.6/xfs_ioctl32.h,
include/linux/falloc.h,
linux/fs.h,
'X' all fs/ocfs2/ocfs_fs.h conflict!
'Z' 14-15 drivers/message/fusion/mptctl.h
'[' 00-3F linux/usb/tmc.h USB Test and Measurement Devices
<mailto:gregkh@linuxfoundation.org>
'a' all linux/atm*.h, linux/sonet.h ATM on linux
<http://lrcwww.epfl.ch/>
'b' 00-FF conflict! bit3 vme host bridge
<mailto:natalia@nikhefk.nikhef.nl>
'b' 00-0F linux/dma-buf.h conflict!
'c' 00-7F linux/comstats.h conflict!
'c' 00-7F linux/coda.h conflict!
'c' 00-1F linux/chio.h conflict!
'c' 80-9F arch/s390/include/asm/chsc.h conflict!
'c' A0-AF arch/x86/include/asm/msr.h conflict!
'd' 00-FF linux/char/drm/drm.h conflict!
'd' 02-40 pcmcia/ds.h conflict!
'd' F0-FF linux/digi1.h
'e' all linux/digi1.h conflict!
'f' 00-1F linux/ext2_fs.h conflict!
'f' 00-1F linux/ext3_fs.h conflict!
'f' 00-0F fs/jfs/jfs_dinode.h conflict!
'f' 00-0F fs/ext4/ext4.h conflict!
'f' 00-0F linux/fs.h conflict!
'f' 00-0F fs/ocfs2/ocfs2_fs.h conflict!
'f' 13-27 linux/fscrypt.h
'f' 81-8F linux/fsverity.h
'g' 00-0F linux/usb/gadgetfs.h
'g' 20-2F linux/usb/g_printer.h
'h' 00-7F conflict! Charon filesystem
<mailto:zapman@interlan.net>
'h' 00-1F linux/hpet.h conflict!
'h' 80-8F fs/hfsplus/ioctl.c
'i' 00-3F linux/i2o-dev.h conflict!
'i' 0B-1F linux/ipmi.h conflict!
'i' 80-8F linux/i8k.h
'i' 90-9F `linux/iio/*.h` IIO
'j' 00-3F linux/joystick.h
'k' 00-0F linux/spi/spidev.h conflict!
'k' 00-05 video/kyro.h conflict!
'k' 10-17 linux/hsi/hsi_char.h HSI character device
'l' 00-3F linux/tcfs_fs.h transparent cryptographic file system
<http://web.archive.org/web/%2A/http://mikonos.dia.unisa.it/tcfs>
'l' 40-7F linux/udf_fs_i.h in development:
<https://github.com/pali/udftools>
'm' 00-09 linux/mmtimer.h conflict!
'm' all linux/mtio.h conflict!
'm' all linux/soundcard.h conflict!
'm' 00-19 drivers/message/fusion/mptctl.h conflict!
'm' 00 drivers/scsi/megaraid/megaraid_ioctl.h conflict!
'n' 00-7F linux/ncp_fs.h and fs/ncpfs/ioctl.c
'n' 80-8F uapi/linux/nilfs2_api.h NILFS2
'n' E0-FF linux/matroxfb.h matroxfb
'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2
'o' 00-03 mtd/ubi-user.h conflict! (OCFS2 and UBI overlaps)
'o' 40-41 mtd/ubi-user.h UBI
'o' 01-A1 `linux/dvb/*.h` DVB
'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this)
'p' 00-1F linux/rtc.h conflict!
'p' 40-7F linux/nvram.h
'p' 80-9F linux/ppdev.h user-space parport
<mailto:tim@cyberelk.net>
'p' A1-A5 linux/pps.h LinuxPPS
'p' B1-B3 linux/pps_gen.h LinuxPPS
<mailto:giometti@linux.it>
'q' 00-1F linux/serio.h
'q' 80-FF linux/telephony.h Internet PhoneJACK, Internet LineJACK
linux/ixjuser.h <http://web.archive.org/web/%2A/http://www.quicknet.net>
'r' 00-1F linux/msdos_fs.h and fs/fat/dir.c
's' all linux/cdk.h
't' 00-7F linux/ppp-ioctl.h
't' 80-8F linux/isdn_ppp.h
't' 90-91 linux/toshiba.h toshiba and toshiba_acpi SMM
'u' 00-1F linux/smb_fs.h gone
'u' 00-2F linux/ublk_cmd.h conflict!
'u' 20-3F linux/uvcvideo.h USB video class host driver
'u' 40-4f linux/udmabuf.h userspace dma-buf misc device
'v' 00-1F linux/ext2_fs.h conflict!
'v' 00-1F linux/fs.h conflict!
'v' 00-0F linux/sonypi.h conflict!
'v' 00-0F media/v4l2-subdev.h conflict!
'v' 20-27 arch/powerpc/include/uapi/asm/vas-api.h VAS API
'v' C0-FF linux/meye.h conflict!
'w' all CERN SCI driver
'y' 00-1F packet based user level communications
<mailto:zapman@interlan.net>
'z' 00-3F CAN bus card conflict!
<mailto:hdstich@connectu.ulm.circular.de>
'z' 40-7F CAN bus card conflict!
<mailto:oe@port.de>
'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict!
'|' 00-7F linux/media.h
'|' 80-9F samples/ Any sample and example drivers
0x80 00-1F linux/fb.h
0x81 00-1F linux/vduse.h
0x89 00-06 arch/x86/include/asm/sockios.h
0x89 0B-DF linux/sockios.h
0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range
0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range
0x8A 00-1F linux/eventpoll.h
0x8B all linux/wireless.h
0x8C 00-3F WiNRADiO driver
<http://www.winradio.com.au/>
0x90 00 drivers/cdrom/sbpcd.h
0x92 00-0F drivers/usb/mon/mon_bin.c
0x93 60-7F linux/auto_fs.h
0x94 all fs/btrfs/ioctl.h Btrfs filesystem
and linux/fs.h some lifted to vfs/generic
0x97 00-7F fs/ceph/ioctl.h Ceph file system
0x99 00-0F 537-Addinboard driver
<mailto:buk@buks.ipn.de>
0x9A 00-0F include/uapi/fwctl/fwctl.h
0xA0 all linux/sdp/sdp.h Industrial Device Project
<mailto:kenji@bitgate.com>
0xA1 0 linux/vtpm_proxy.h TPM Emulator Proxy Driver
0xA2 all uapi/linux/acrn.h ACRN hypervisor
0xA3 80-8F Port ACL in development:
<mailto:tlewis@mindspring.com>
0xA4 00-1F uapi/linux/tee.h Generic TEE subsystem
0xA4 00-1F uapi/asm/sgx.h <mailto:linux-sgx@vger.kernel.org>
0xA5 01-05 linux/surface_aggregator/cdev.h Microsoft Surface Platform System Aggregator
<mailto:luzmaximilian@gmail.com>
0xA5 20-2F linux/surface_aggregator/dtx.h Microsoft Surface DTX driver
<mailto:luzmaximilian@gmail.com>
0xAA 00-3F linux/uapi/linux/userfaultfd.h
0xAB 00-1F linux/nbd.h
0xAC 00-1F linux/raw.h
0xAD 00 Netfilter device in development:
<mailto:rusty@rustcorp.com.au>
0xAE 00-1F linux/kvm.h Kernel-based Virtual Machine
<mailto:kvm@vger.kernel.org>
0xAE 40-FF linux/kvm.h Kernel-based Virtual Machine
<mailto:kvm@vger.kernel.org>
0xAE 20-3F linux/nitro_enclaves.h Nitro Enclaves
0xAF 00-1F linux/fsl_hypervisor.h Freescale hypervisor
0xB0 all RATIO devices in development:
<mailto:vgo@ratio.de>
0xB1 00-1F PPPoX
<mailto:mostrows@styx.uwaterloo.ca>
0xB2 00 arch/powerpc/include/uapi/asm/papr-vpd.h powerpc/pseries VPD API
<mailto:linuxppc-dev@lists.ozlabs.org>
0xB2 01-02 arch/powerpc/include/uapi/asm/papr-sysparm.h powerpc/pseries system parameter API
<mailto:linuxppc-dev@lists.ozlabs.org>
0xB2 03-05 arch/powerpc/include/uapi/asm/papr-indices.h powerpc/pseries indices API
<mailto:linuxppc-dev@lists.ozlabs.org>
0xB2 06-07 arch/powerpc/include/uapi/asm/papr-platform-dump.h powerpc/pseries Platform Dump API
<mailto:linuxppc-dev@lists.ozlabs.org>
0xB2 08 arch/powerpc/include/uapi/asm/papr-physical-attestation.h powerpc/pseries Physical Attestation API
<mailto:linuxppc-dev@lists.ozlabs.org>
0xB2 09 arch/powerpc/include/uapi/asm/papr-hvpipe.h powerpc/pseries HVPIPE API
<mailto:linuxppc-dev@lists.ozlabs.org>
0xB3 00 linux/mmc/ioctl.h
0xB4 00-0F linux/gpio.h <mailto:linux-gpio@vger.kernel.org>
0xB5 00-0F uapi/linux/rpmsg.h <mailto:linux-remoteproc@vger.kernel.org>
0xB6 all linux/fpga-dfl.h
0xB7 all uapi/linux/remoteproc_cdev.h <mailto:linux-remoteproc@vger.kernel.org>
0xB7 all uapi/linux/nsfs.h <mailto:Andrei Vagin <avagin@openvz.org>>
0xB8 01-02 uapi/misc/mrvl_cn10k_dpi.h Marvell CN10K DPI driver
0xB8 all uapi/linux/mshv.h Microsoft Hyper-V /dev/mshv driver
<mailto:linux-hyperv@vger.kernel.org>
0xBA 00-0F uapi/linux/liveupdate.h Pasha Tatashin
<mailto:pasha.tatashin@soleen.com>
0xC0 00-0F linux/usb/iowarrior.h
0xCA 00-0F uapi/misc/cxl.h Dead since 6.15
0xCA 10-2F uapi/misc/ocxl.h
0xCA 80-BF uapi/scsi/cxlflash_ioctl.h Dead since 6.15
0xCB 00-1F CBM serial IEC bus in development:
<mailto:michael.klein@puffin.lb.shuttle.de>
0xCC 00-0F drivers/misc/ibmvmc.h pseries VMC driver
0xCD 01 linux/reiserfs_fs.h Dead since 6.13
0xCE 01-02 uapi/linux/cxl_mem.h Compute Express Link Memory Devices
0xCF 02 fs/smb/client/cifs_ioctl.h
0xDD 00-3F ZFCP device driver see drivers/s390/scsi/
<mailto:aherrman@de.ibm.com>
0xE5 00-3F linux/fuse.h
0xEC 00-01 drivers/platform/chrome/cros_ec_dev.h ChromeOS EC driver
0xEE 00-09 uapi/linux/pfrut.h Platform Firmware Runtime Update and Telemetry
0xF3 00-3F drivers/usb/misc/sisusbvga/sisusb.h sisfb (in development)
<mailto:thomas@winischhofer.net>
0xF6 all LTTng Linux Trace Toolkit Next Generation
<mailto:mathieu.desnoyers@efficios.com>
0xF8 all arch/x86/include/uapi/asm/amd_hsmp.h AMD HSMP EPYC system management interface driver
<mailto:nchatrad@amd.com>
0xF9 00-0F uapi/misc/amd-apml.h AMD side band system management interface driver
<mailto:naveenkrishna.chatradhi@amd.com>
0xFD all linux/dm-ioctl.h
0xFE all linux/isst_if.h
==== ===== ========================================================= ================================================================
@@ -0,0 +1,384 @@
.. SPDX-License-Identifier: GPL-2.0+
=======
IOMMUFD
=======
:Author: Jason Gunthorpe
:Author: Kevin Tian
Overview
========
IOMMUFD is the user API to control the IOMMU subsystem as it relates to managing
IO page tables from userspace using file descriptors. It intends to be general
and consumable by any driver that wants to expose DMA to userspace. These
drivers are eventually expected to deprecate any internal IOMMU logic
they may already/historically implement (e.g. vfio_iommu_type1.c).
At minimum iommufd provides universal support of managing I/O address spaces and
I/O page tables for all IOMMUs, with room in the design to add non-generic
features to cater to specific hardware functionality.
In this context the capital letter (IOMMUFD) refers to the subsystem while the
small letter (iommufd) refers to the file descriptors created via /dev/iommu for
use by userspace.
Key Concepts
============
User Visible Objects
--------------------
Following IOMMUFD objects are exposed to userspace:
- IOMMUFD_OBJ_IOAS, representing an I/O address space (IOAS), allowing map/unmap
of user space memory into ranges of I/O Virtual Address (IOVA).
The IOAS is a functional replacement for the VFIO container, and like the VFIO
container it copies an IOVA map to a list of iommu_domains held within it.
- IOMMUFD_OBJ_DEVICE, representing a device that is bound to iommufd by an
external driver.
- IOMMUFD_OBJ_HWPT_PAGING, representing an actual hardware I/O page table
(i.e. a single struct iommu_domain) managed by the iommu driver. "PAGING"
primarily indicates this type of HWPT should be linked to an IOAS. It also
indicates that it is backed by an iommu_domain with __IOMMU_DOMAIN_PAGING
feature flag. This can be either an UNMANAGED stage-1 domain for a device
running in the user space, or a nesting parent stage-2 domain for mappings
from guest-level physical addresses to host-level physical addresses.
The IOAS has a list of HWPT_PAGINGs that share the same IOVA mapping and
it will synchronize its mapping with each member HWPT_PAGING.
- IOMMUFD_OBJ_HWPT_NESTED, representing an actual hardware I/O page table
(i.e. a single struct iommu_domain) managed by user space (e.g. guest OS).
"NESTED" indicates that this type of HWPT should be linked to an HWPT_PAGING.
It also indicates that it is backed by an iommu_domain that has a type of
IOMMU_DOMAIN_NESTED. This must be a stage-1 domain for a device running in
the user space (e.g. in a guest VM enabling the IOMMU nested translation
feature.) As such, it must be created with a given nesting parent stage-2
domain to associate to. This nested stage-1 page table managed by the user
space usually has mappings from guest-level I/O virtual addresses to guest-
level physical addresses.
- IOMMUFD_FAULT, representing a software queue for an HWPT reporting IO page
faults using the IOMMU HW's PRI (Page Request Interface). This queue object
provides user space an FD to poll the page fault events and also to respond
to those events. A FAULT object must be created first to get a fault_id that
could be then used to allocate a fault-enabled HWPT via the IOMMU_HWPT_ALLOC
command by setting the IOMMU_HWPT_FAULT_ID_VALID bit in its flags field.
- IOMMUFD_OBJ_VIOMMU, representing a slice of the physical IOMMU instance,
passed to or shared with a VM. It may be some HW-accelerated virtualization
features and some SW resources used by the VM. For examples:
* Security namespace for guest owned ID, e.g. guest-controlled cache tags
* Non-device-affiliated event reporting, e.g. invalidation queue errors
* Access to a shareable nesting parent pagetable across physical IOMMUs
* Virtualization of various platforms IDs, e.g. RIDs and others
* Delivery of paravirtualized invalidation
* Direct assigned invalidation queues
* Direct assigned interrupts
Such a vIOMMU object generally has the access to a nesting parent pagetable
to support some HW-accelerated virtualization features. So, a vIOMMU object
must be created given a nesting parent HWPT_PAGING object, and then it would
encapsulate that HWPT_PAGING object. Therefore, a vIOMMU object can be used
to allocate an HWPT_NESTED object in place of the encapsulated HWPT_PAGING.
.. note::
The name "vIOMMU" isn't necessarily identical to a virtualized IOMMU in a
VM. A VM can have one giant virtualized IOMMU running on a machine having
multiple physical IOMMUs, in which case the VMM will dispatch the requests
or configurations from this single virtualized IOMMU instance to multiple
vIOMMU objects created for individual slices of different physical IOMMUs.
In other words, a vIOMMU object is always a representation of one physical
IOMMU, not necessarily of a virtualized IOMMU. For VMMs that want the full
virtualization features from physical IOMMUs, it is suggested to build the
same number of virtualized IOMMUs as the number of physical IOMMUs, so the
passed-through devices would be connected to their own virtualized IOMMUs
backed by corresponding vIOMMU objects, in which case a guest OS would do
the "dispatch" naturally instead of VMM trappings.
- IOMMUFD_OBJ_VDEVICE, representing a virtual device for an IOMMUFD_OBJ_DEVICE
against an IOMMUFD_OBJ_VIOMMU. This virtual device holds the device's virtual
information or attributes (related to the vIOMMU) in a VM. An immediate vDATA
example can be the virtual ID of the device on a vIOMMU, which is a unique ID
that VMM assigns to the device for a translation channel/port of the vIOMMU,
e.g. vSID of ARM SMMUv3, vDeviceID of AMD IOMMU, and vRID of Intel VT-d to a
Context Table. Potential use cases of some advanced security information can
be forwarded via this object too, such as security level or realm information
in a Confidential Compute Architecture. A VMM should create a vDEVICE object
to forward all the device information in a VM, when it connects a device to a
vIOMMU, which is a separate ioctl call from attaching the same device to an
HWPT_PAGING that the vIOMMU holds.
- IOMMUFD_OBJ_VEVENTQ, representing a software queue for a vIOMMU to report its
events such as translation faults occurred to a nested stage-1 (excluding I/O
page faults that should go through IOMMUFD_OBJ_FAULT) and HW-specific events.
This queue object provides user space an FD to poll/read the vIOMMU events. A
vIOMMU object must be created first to get its viommu_id, which could be then
used to allocate a vEVENTQ. Each vIOMMU can support multiple types of vEVENTS,
but is confined to one vEVENTQ per vEVENTQ type.
- IOMMUFD_OBJ_HW_QUEUE, representing a hardware accelerated queue, as a subset
of IOMMU's virtualization features, for the IOMMU HW to directly read or write
the virtual queue memory owned by a guest OS. This HW-acceleration feature can
allow VM to work with the IOMMU HW directly without a VM Exit, so as to reduce
overhead from the hypercalls. Along with the HW QUEUE object, iommufd provides
user space an mmap interface for VMM to mmap a physical MMIO region from the
host physical address space to the guest physical address space, allowing the
guest OS to directly control the allocated HW QUEUE. Thus, when allocating a
HW QUEUE, the VMM must request a pair of mmap info (offset/length) and pass in
exactly to an mmap syscall via its offset and length arguments.
All user-visible objects are destroyed via the IOMMU_DESTROY uAPI.
The diagrams below show relationships between user-visible objects and kernel
datastructures (external to iommufd), with numbers referred to operations
creating the objects and links::
_______________________________________________________________________
| iommufd (HWPT_PAGING only) |
| |
| [1] [3] [2] |
| ________________ _____________ ________ |
| | | | | | | |
| | IOAS |<---| HWPT_PAGING |<---------------------| DEVICE | |
| |________________| |_____________| |________| |
| | | | |
|_________|____________________|__________________________________|_____|
| | |
| ______v_____ ___v__
| PFN storage | (paging) | |struct|
|------------>|iommu_domain|<-----------------------|device|
|____________| |______|
_______________________________________________________________________
| iommufd (with HWPT_NESTED) |
| |
| [1] [3] [4] [2] |
| ________________ _____________ _____________ ________ |
| | | | | | | | | |
| | IOAS |<---| HWPT_PAGING |<---| HWPT_NESTED |<--| DEVICE | |
| |________________| |_____________| |_____________| |________| |
| | | | | |
|_________|____________________|__________________|_______________|_____|
| | | |
| ______v_____ ______v_____ ___v__
| PFN storage | (paging) | | (nested) | |struct|
|------------>|iommu_domain|<----|iommu_domain|<----|device|
|____________| |____________| |______|
_______________________________________________________________________
| iommufd (with vIOMMU/vDEVICE) |
| |
| [5] [6] |
| _____________ _____________ |
| | | | | |
| |----------------| vIOMMU |<---| vDEVICE |<----| |
| | | | |_____________| | |
| | | | | |
| | [1] | | [4] | [2] |
| | ______ | | _____________ _|______ |
| | | | | [3] | | | | | |
| | | IOAS |<---|(HWPT_PAGING)|<---| HWPT_NESTED |<--| DEVICE | |
| | |______| |_____________| |_____________| |________| |
| | | | | | |
|______|________|______________|__________________|_______________|_____|
| | | | |
______v_____ | ______v_____ ______v_____ ___v__
| struct | | PFN | (paging) | | (nested) | |struct|
|iommu_device| |------>|iommu_domain|<----|iommu_domain|<----|device|
|____________| storage|____________| |____________| |______|
1. IOMMUFD_OBJ_IOAS is created via the IOMMU_IOAS_ALLOC uAPI. An iommufd can
hold multiple IOAS objects. IOAS is the most generic object and does not
expose interfaces that are specific to single IOMMU drivers. All operations
on the IOAS must operate equally on each of the iommu_domains inside of it.
2. IOMMUFD_OBJ_DEVICE is created when an external driver calls the IOMMUFD kAPI
to bind a device to an iommufd. The driver is expected to implement a set of
ioctls to allow userspace to initiate the binding operation. Successful
completion of this operation establishes the desired DMA ownership over the
device. The driver must also set the driver_managed_dma flag and must not
touch the device until this operation succeeds.
3. IOMMUFD_OBJ_HWPT_PAGING can be created in two ways:
* IOMMUFD_OBJ_HWPT_PAGING is automatically created when an external driver
calls the IOMMUFD kAPI to attach a bound device to an IOAS. Similarly the
external driver uAPI allows userspace to initiate the attaching operation.
If a compatible member HWPT_PAGING object exists in the IOAS's HWPT_PAGING
list, then it will be reused. Otherwise a new HWPT_PAGING that represents
an iommu_domain to userspace will be created, and then added to the list.
Successful completion of this operation sets up the linkages among IOAS,
device and iommu_domain. Once this completes the device could do DMA.
* IOMMUFD_OBJ_HWPT_PAGING can be manually created via the IOMMU_HWPT_ALLOC
uAPI, provided an ioas_id via @pt_id to associate the new HWPT_PAGING to
the corresponding IOAS object. The benefit of this manual allocation is to
allow allocation flags (defined in enum iommufd_hwpt_alloc_flags), e.g. it
allocates a nesting parent HWPT_PAGING if the IOMMU_HWPT_ALLOC_NEST_PARENT
flag is set.
4. IOMMUFD_OBJ_HWPT_NESTED can be only manually created via the IOMMU_HWPT_ALLOC
uAPI, provided an hwpt_id or a viommu_id of a vIOMMU object encapsulating a
nesting parent HWPT_PAGING via @pt_id to associate the new HWPT_NESTED object
to the corresponding HWPT_PAGING object. The associating HWPT_PAGING object
must be a nesting parent manually allocated via the same uAPI previously with
an IOMMU_HWPT_ALLOC_NEST_PARENT flag, otherwise the allocation will fail. The
allocation will be further validated by the IOMMU driver to ensure that the
nesting parent domain and the nested domain being allocated are compatible.
Successful completion of this operation sets up linkages among IOAS, device,
and iommu_domains. Once this completes the device could do DMA via a 2-stage
translation, a.k.a nested translation. Note that multiple HWPT_NESTED objects
can be allocated by (and then associated to) the same nesting parent.
.. note::
Either a manual IOMMUFD_OBJ_HWPT_PAGING or an IOMMUFD_OBJ_HWPT_NESTED is
created via the same IOMMU_HWPT_ALLOC uAPI. The difference is at the type
of the object passed in via the @pt_id field of struct iommufd_hwpt_alloc.
5. IOMMUFD_OBJ_VIOMMU can be only manually created via the IOMMU_VIOMMU_ALLOC
uAPI, provided a dev_id (for the device's physical IOMMU to back the vIOMMU)
and an hwpt_id (to associate the vIOMMU to a nesting parent HWPT_PAGING). The
iommufd core will link the vIOMMU object to the struct iommu_device that the
struct device is behind. And an IOMMU driver can implement a viommu_alloc op
to allocate its own vIOMMU data structure embedding the core-level structure
iommufd_viommu and some driver-specific data. If necessary, the driver can
also configure its HW virtualization feature for that vIOMMU (and thus for
the VM). Successful completion of this operation sets up the linkages between
the vIOMMU object and the HWPT_PAGING, then this vIOMMU object can be used
as a nesting parent object to allocate an HWPT_NESTED object described above.
6. IOMMUFD_OBJ_VDEVICE can be only manually created via the IOMMU_VDEVICE_ALLOC
uAPI, provided a viommu_id for an iommufd_viommu object and a dev_id for an
iommufd_device object. The vDEVICE object will be the binding between these
two parent objects. Another @virt_id will be also set via the uAPI providing
the iommufd core an index to store the vDEVICE object to a vDEVICE array per
vIOMMU. If necessary, the IOMMU driver may choose to implement a vdevce_alloc
op to init its HW for virtualization feature related to a vDEVICE. Successful
completion of this operation sets up the linkages between vIOMMU and device.
A device can only bind to an iommufd due to DMA ownership claim and attach to at
most one IOAS object (no support of PASID yet).
Kernel Datastructure
--------------------
User visible objects are backed by following datastructures:
- iommufd_ioas for IOMMUFD_OBJ_IOAS.
- iommufd_device for IOMMUFD_OBJ_DEVICE.
- iommufd_hwpt_paging for IOMMUFD_OBJ_HWPT_PAGING.
- iommufd_hwpt_nested for IOMMUFD_OBJ_HWPT_NESTED.
- iommufd_fault for IOMMUFD_OBJ_FAULT.
- iommufd_viommu for IOMMUFD_OBJ_VIOMMU.
- iommufd_vdevice for IOMMUFD_OBJ_VDEVICE.
- iommufd_veventq for IOMMUFD_OBJ_VEVENTQ.
- iommufd_hw_queue for IOMMUFD_OBJ_HW_QUEUE.
Several terminologies when looking at these datastructures:
- Automatic domain - refers to an iommu domain created automatically when
attaching a device to an IOAS object. This is compatible to the semantics of
VFIO type1.
- Manual domain - refers to an iommu domain designated by the user as the
target pagetable to be attached to by a device. Though currently there are
no uAPIs to directly create such domain, the datastructure and algorithms
are ready for handling that use case.
- In-kernel user - refers to something like a VFIO mdev that is using the
IOMMUFD access interface to access the IOAS. This starts by creating an
iommufd_access object that is similar to the domain binding a physical device
would do. The access object will then allow converting IOVA ranges into struct
page * lists, or doing direct read/write to an IOVA.
iommufd_ioas serves as the metadata datastructure to manage how IOVA ranges are
mapped to memory pages, composed of:
- struct io_pagetable holding the IOVA map
- struct iopt_area's representing populated portions of IOVA
- struct iopt_pages representing the storage of PFNs
- struct iommu_domain representing the IO page table in the IOMMU
- struct iopt_pages_access representing in-kernel users of PFNs
- struct xarray pinned_pfns holding a list of pages pinned by in-kernel users
Each iopt_pages represents a logical linear array of full PFNs. The PFNs are
ultimately derived from userspace VAs via an mm_struct. Once they have been
pinned the PFNs are stored in IOPTEs of an iommu_domain or inside the pinned_pfns
xarray if they have been pinned through an iommufd_access.
PFN have to be copied between all combinations of storage locations, depending
on what domains are present and what kinds of in-kernel "software access" users
exist. The mechanism ensures that a page is pinned only once.
An io_pagetable is composed of iopt_areas pointing at iopt_pages, along with a
list of iommu_domains that mirror the IOVA to PFN map.
Multiple io_pagetable-s, through their iopt_area-s, can share a single
iopt_pages which avoids multi-pinning and double accounting of page
consumption.
iommufd_ioas is shareable between subsystems, e.g. VFIO and VDPA, as long as
devices managed by different subsystems are bound to a same iommufd.
IOMMUFD User API
================
.. kernel-doc:: include/uapi/linux/iommufd.h
IOMMUFD Kernel API
==================
The IOMMUFD kAPI is device-centric with group-related tricks managed behind the
scene. This allows the external drivers calling such kAPI to implement a simple
device-centric uAPI for connecting its device to an iommufd, instead of
explicitly imposing the group semantics in its uAPI as VFIO does.
.. kernel-doc:: drivers/iommu/iommufd/device.c
:export:
.. kernel-doc:: drivers/iommu/iommufd/main.c
:export:
VFIO and IOMMUFD
----------------
Connecting a VFIO device to iommufd can be done in two ways.
First is a VFIO compatible way by directly implementing the /dev/vfio/vfio
container IOCTLs by mapping them into io_pagetable operations. Doing so allows
the use of iommufd in legacy VFIO applications by symlinking /dev/vfio/vfio to
/dev/iommufd or extending VFIO to SET_CONTAINER using an iommufd instead of a
container fd.
The second approach directly extends VFIO to support a new set of device-centric
user API based on aforementioned IOMMUFD kernel API. It requires userspace
change but better matches the IOMMUFD API semantics and easier to support new
iommufd features when comparing it to the first approach.
Currently both approaches are still work-in-progress.
There are still a few gaps to be resolved to catch up with VFIO type1, as
documented in iommufd_vfio_check_extension().
Future TODOs
============
Currently IOMMUFD supports only kernel-managed I/O page table, similar to VFIO
type1. New features on the radar include:
- Binding iommu_domain's to PASID/SSID
- Userspace page tables, for ARM, x86 and S390
- Kernel bypass'd invalidation of user page tables
- Re-use of the KVM page table in the IOMMU
- Dirty page tracking in the IOMMU
- Runtime Increase/Decrease of IOPTE size
- PRI support with faults resolved in userspace
@@ -0,0 +1,15 @@
=======================
ISA Plug & Play support
=======================
Interface /proc/isapnp
======================
The interface was removed in kernel 2.5.53. See pnp.rst 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.
@@ -0,0 +1,895 @@
.. SPDX-License-Identifier: GPL-2.0
.. Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
.. Copyright © 2019-2020 ANSSI
.. Copyright © 2021-2022 Microsoft Corporation
=====================================
Landlock: unprivileged access control
=====================================
:Author: Mickaël Salaün
:Date: June 2026
The goal of Landlock is to enable restriction of ambient rights (e.g. global
filesystem or network access) for a set of processes. Because Landlock
is a stackable LSM, it makes it possible to create safe security sandboxes as
new security layers in addition to the existing system-wide access-controls.
This kind of sandbox is expected to help mitigate the security impact of bugs or
unexpected/malicious behaviors in user space applications. Landlock empowers
any process, including unprivileged ones, to securely restrict themselves.
We can quickly make sure that Landlock is enabled in the running system by
looking for "landlock: Up and running" in kernel logs (as root):
``dmesg | grep landlock || journalctl -kb -g landlock`` .
Developers can also easily check for Landlock support with a
:ref:`related system call <landlock_abi_versions>`.
If Landlock is not currently supported, we need to
:ref:`configure the kernel appropriately <kernel_support>`.
Landlock rules
==============
A Landlock rule describes an action on an object which the process intends to
perform. A set of rules is aggregated in a ruleset, which can then restrict
the thread enforcing it, and its future children.
The two existing types of rules are:
Filesystem rules
For these rules, the object is a file hierarchy,
and the related filesystem actions are defined with
`filesystem access rights`.
Network rules (since ABI v4 for TCP and v10 for UDP)
For these rules, the object is a TCP or UDP port,
and the related actions are defined with `network access rights`.
Defining and enforcing a security policy
----------------------------------------
We first need to define the ruleset that will contain our rules.
For this example, the ruleset will contain rules that only allow some
filesystem read actions and some specific UDP and TCP actions. Filesystem
write actions and other TCP/UDP actions will be denied.
The ruleset then needs to handle all these kinds of actions. This is
required for backward and forward compatibility (i.e. the kernel and user
space may not know each other's supported restrictions), hence the need
to be explicit about the denied-by-default access rights.
.. code-block:: c
struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs =
LANDLOCK_ACCESS_FS_EXECUTE |
LANDLOCK_ACCESS_FS_WRITE_FILE |
LANDLOCK_ACCESS_FS_READ_FILE |
LANDLOCK_ACCESS_FS_READ_DIR |
LANDLOCK_ACCESS_FS_REMOVE_DIR |
LANDLOCK_ACCESS_FS_REMOVE_FILE |
LANDLOCK_ACCESS_FS_MAKE_CHAR |
LANDLOCK_ACCESS_FS_MAKE_DIR |
LANDLOCK_ACCESS_FS_MAKE_REG |
LANDLOCK_ACCESS_FS_MAKE_SOCK |
LANDLOCK_ACCESS_FS_MAKE_FIFO |
LANDLOCK_ACCESS_FS_MAKE_BLOCK |
LANDLOCK_ACCESS_FS_MAKE_SYM |
LANDLOCK_ACCESS_FS_REFER |
LANDLOCK_ACCESS_FS_TRUNCATE |
LANDLOCK_ACCESS_FS_IOCTL_DEV |
LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
.handled_access_net =
LANDLOCK_ACCESS_NET_BIND_TCP |
LANDLOCK_ACCESS_NET_CONNECT_TCP |
LANDLOCK_ACCESS_NET_BIND_UDP |
LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP,
.scoped =
LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
LANDLOCK_SCOPE_SIGNAL,
};
Because we may not know which kernel version an application will be executed
on, it is safer to follow a best-effort security approach. Indeed, we
should try to protect users as much as possible whatever the kernel they are
using.
To be compatible with older Linux versions, we detect the available Landlock ABI
version, and only use the available subset of access rights:
.. code-block:: c
int abi;
abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
if (abi < 0) {
/* Degrades gracefully if Landlock is not handled. */
perror("The running kernel does not enable to use Landlock");
return 0;
}
switch (abi) {
case 1:
/* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
__attribute__((fallthrough));
case 2:
/* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
__attribute__((fallthrough));
case 3:
/* Removes network support for ABI < 4 */
ruleset_attr.handled_access_net &=
~(LANDLOCK_ACCESS_NET_BIND_TCP |
LANDLOCK_ACCESS_NET_CONNECT_TCP);
__attribute__((fallthrough));
case 4:
/* Removes LANDLOCK_ACCESS_FS_IOCTL_DEV for ABI < 5 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV;
__attribute__((fallthrough));
case 5:
/* Removes LANDLOCK_SCOPE_* for ABI < 6 */
ruleset_attr.scoped &= ~(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
LANDLOCK_SCOPE_SIGNAL);
__attribute__((fallthrough));
case 6 ... 8:
/* Removes LANDLOCK_ACCESS_FS_RESOLVE_UNIX for ABI < 9 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_RESOLVE_UNIX;
__attribute__((fallthrough));
case 9:
/* Removes LANDLOCK_ACCESS_NET_*_UDP for ABI < 10 */
ruleset_attr.handled_access_net &=
~(LANDLOCK_ACCESS_NET_BIND_UDP |
LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP);
}
This enables the creation of an inclusive ruleset that will contain our rules.
.. code-block:: c
int ruleset_fd;
ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
if (ruleset_fd < 0) {
perror("Failed to create a ruleset");
return 1;
}
We can now add a new rule to this ruleset thanks to the returned file
descriptor referring to this ruleset. The rule will allow reading and
executing the file hierarchy ``/usr``. Without another rule, write actions
would then be denied by the ruleset. To add ``/usr`` to the ruleset, we open
it with the ``O_PATH`` flag and fill the &struct landlock_path_beneath_attr with
this file descriptor.
.. code-block:: c
int err = 0;
struct landlock_path_beneath_attr path_beneath = {
.allowed_access =
LANDLOCK_ACCESS_FS_EXECUTE |
LANDLOCK_ACCESS_FS_READ_FILE |
LANDLOCK_ACCESS_FS_READ_DIR,
};
path_beneath.allowed_access &= ruleset_attr.handled_access_fs;
if (path_beneath.allowed_access) {
path_beneath.parent_fd = open("/usr", O_PATH | O_CLOEXEC);
if (path_beneath.parent_fd < 0) {
perror("Failed to open file");
close(ruleset_fd);
return 1;
}
err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
&path_beneath, 0);
close(path_beneath.parent_fd);
if (err) {
perror("Failed to update ruleset");
close(ruleset_fd);
return 1;
}
}
As shown above, masking the rule's ``allowed_access`` against the ruleset's
``handled_access_*`` is the recommended best-effort pattern: rights the running
kernel does not support are dropped (the compatibility switch above already
cleared them in ``handled_access_*``), and the rule is skipped if no supported
right remains.
For network access-control, we will add a set of rules to allow DNS
queries, which requires both UDP and TCP. For TCP, we need to allow
outbound connections to port 53, which can be handled and granted starting
with ABI 4:
.. code-block:: c
struct landlock_net_port_attr tcp_conn = {
.allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP,
.port = 53,
};
tcp_conn.allowed_access &= ruleset_attr.handled_access_net;
if (tcp_conn.allowed_access)
err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
&tcp_conn, 0);
We also need to be able to send UDP datagrams to port 53, which requires
granting ``LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP``. Since our DNS client will
emit datagrams without explicitly binding to a specific source port, its UDP
socket will automatically bind an ephemeral port. To allow this behaviour,
we also need to grant ``LANDLOCK_ACCESS_NET_BIND_UDP`` on port 0, as if
the program explicitly called :manpage:`bind(2)` on port 0.
.. code-block:: c
struct landlock_net_port_attr udp_send = {
.allowed_access = LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP,
.port = 53,
};
udp_send.allowed_access &= ruleset_attr.handled_access_net;
if (udp_send.allowed_access)
err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
&udp_send, 0);
[...]
struct landlock_net_port_attr udp_bind = {
.allowed_access = LANDLOCK_ACCESS_NET_BIND_UDP,
.port = 0,
};
udp_bind.allowed_access &= ruleset_attr.handled_access_net;
if (udp_bind.allowed_access)
err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
&udp_bind, 0);
When passing a non-zero ``flags`` argument to ``landlock_restrict_self()``, a
similar backwards compatibility check is needed for the restrict flags
(see sys_landlock_restrict_self() documentation for available flags):
.. code-block:: c
__u32 restrict_flags =
LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON |
LANDLOCK_RESTRICT_SELF_TSYNC;
switch (abi) {
case 1 ... 6:
/* Removes logging flags for ABI < 7 */
restrict_flags &= ~(LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF |
LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON |
LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF);
__attribute__((fallthrough));
case 7:
/*
* Removes multithreaded enforcement flag for ABI < 8
*
* WARNING: Without this flag, calling landlock_restrict_self(2) is
* only equivalent if the calling process is single-threaded. Below
* ABI v8 (and as of ABI v8, when not using this flag), a Landlock
* policy would only be enforced for the calling thread and its
* children (and not for all threads, including parents and siblings).
*/
restrict_flags &= ~LANDLOCK_RESTRICT_SELF_TSYNC;
}
The next step is to restrict the current thread from gaining more privileges
(e.g. through a SUID binary). We now have a ruleset with the first rule
allowing read and execute access to ``/usr`` while denying all other handled
accesses for the filesystem, and two more rules allowing DNS queries.
.. code-block:: c
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
perror("Failed to restrict privileges");
close(ruleset_fd);
return 1;
}
The current thread is now ready to sandbox itself with the ruleset.
.. code-block:: c
if (landlock_restrict_self(ruleset_fd, restrict_flags)) {
perror("Failed to enforce ruleset");
close(ruleset_fd);
return 1;
}
close(ruleset_fd);
If the ``landlock_restrict_self`` system call succeeds, the current thread is
now restricted and this policy will be enforced on all its subsequently created
children as well. Once a thread is landlocked, there is no way to remove its
security policy; only adding more restrictions is allowed. These threads are
now in a new Landlock domain, which is a merger of their parent one (if any)
with the new ruleset.
Full working code can be found in `samples/landlock/sandboxer.c`_.
Good practices
--------------
It is recommended to set access rights to file hierarchy leaves as much as
possible. For instance, it is better to be able to have ``~/doc/`` as a
read-only hierarchy and ``~/tmp/`` as a read-write hierarchy, compared to
``~/`` as a read-only hierarchy and ``~/tmp/`` as a read-write hierarchy.
Following this good practice leads to self-sufficient hierarchies that do not
depend on their location (i.e. parent directories). This is particularly
relevant when we want to allow linking or renaming. Indeed, having consistent
access rights per directory enables changing the location of such directories
without relying on the destination directory access rights (except those that
are required for this operation, see ``LANDLOCK_ACCESS_FS_REFER``
documentation).
Having self-sufficient hierarchies also helps to tighten the required access
rights to the minimal set of data. This also helps avoid sinkhole directories,
i.e. directories where data can be linked to but not linked from. However,
this depends on data organization, which might not be controlled by developers.
In this case, granting read-write access to ``~/tmp/``, instead of write-only
access, would potentially allow moving ``~/tmp/`` to a non-readable directory
and still keep the ability to list the content of ``~/tmp/``.
Layers of file path access rights
---------------------------------
Each time a thread enforces a ruleset on itself, it updates its Landlock domain
with a new layer of policy. This complementary policy is stacked with any
other rulesets potentially already restricting this thread. A sandboxed thread
can then safely add more constraints to itself with a new enforced ruleset.
One policy layer grants access to a file path if at least one of its rules
encountered on the path grants the access. A sandboxed thread can only access
a file path if all its enforced policy layers grant the access as well as all
the other system access controls (e.g. filesystem DAC, other LSM policies,
etc.).
Bind mounts and OverlayFS
-------------------------
Landlock enables restricting access to file hierarchies, which means that these
access rights can be propagated with bind mounts (cf.
Documentation/filesystems/sharedsubtree.rst) but not with
Documentation/filesystems/overlayfs.rst.
A bind mount mirrors a source file hierarchy to a destination. The destination
hierarchy is then composed of the exact same files, on which Landlock rules can
be tied, either via the source or the destination path. These rules restrict
access when they are encountered on a path, which means that they can restrict
access to multiple file hierarchies at the same time, whether these hierarchies
are the result of bind mounts or not.
An OverlayFS mount point consists of upper and lower layers. These layers are
combined in a merge directory, and that merged directory becomes available at
the mount point. This merge hierarchy may include files from the upper and
lower layers, but modifications performed on the merge hierarchy only reflect
on the upper layer. From a Landlock policy point of view, all OverlayFS layers
and merge hierarchies are standalone and each contains their own set of files
and directories, which is different from bind mounts. A policy restricting an
OverlayFS layer will not restrict the resulted merged hierarchy, and vice versa.
Landlock users should then only think about file hierarchies they want to allow
access to, regardless of the underlying filesystem.
Inheritance
-----------
Every new thread resulting from a :manpage:`clone(2)` inherits Landlock domain
restrictions from its parent. This is similar to seccomp inheritance (cf.
Documentation/userspace-api/seccomp_filter.rst) or any other LSM dealing with
task's :manpage:`credentials(7)`. For instance, one process's thread may apply
Landlock rules to itself, but they will not be automatically applied to other
sibling threads (unlike POSIX thread credential changes, cf.
:manpage:`nptl(7)`).
When a thread sandboxes itself, we have the guarantee that the related security
policy will stay enforced on all this thread's descendants. This allows
creating standalone and modular security policies per application, which will
automatically be composed between themselves according to their runtime parent
policies.
Ptrace restrictions
-------------------
A sandboxed process has less privileges than a non-sandboxed process and must
then be subject to additional restrictions when manipulating another process.
To be allowed to use :manpage:`ptrace(2)` and related syscalls on a target
process, a sandboxed process should have a superset of the target process's
access rights, which means the tracee must be in a sub-domain of the tracer.
IPC scoping
-----------
Similar to the implicit `Ptrace restrictions`_, we may want to further restrict
interactions between sandboxes. Therefore, at ruleset creation time, each
Landlock domain can restrict the scope for certain operations, so that these
operations can only reach out to processes within the same Landlock domain or in
a nested Landlock domain (the "scope").
The operations which can be scoped are:
``LANDLOCK_SCOPE_SIGNAL``
This limits the sending of signals to target processes which run within the
same or a nested Landlock domain.
``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET``
This limits the set of abstract :manpage:`unix(7)` sockets to which we can
:manpage:`connect(2)` to socket addresses which were created by a process in
the same or a nested Landlock domain.
A :manpage:`sendto(2)` on a non-connected datagram socket is treated as if
it were doing an implicit :manpage:`connect(2)` and will be blocked if the
remote end does not stem from the same or a nested Landlock domain.
A :manpage:`sendto(2)` on a socket which was previously connected will not
be restricted. This works for both datagram and stream sockets.
IPC scoping does not support exceptions via :manpage:`landlock_add_rule(2)`.
If an operation is scoped within a domain, no rules can be added to allow access
to resources or processes outside of the scope.
Truncating files
----------------
The operations covered by ``LANDLOCK_ACCESS_FS_WRITE_FILE`` and
``LANDLOCK_ACCESS_FS_TRUNCATE`` both change the contents of a file and sometimes
overlap in non-intuitive ways. It is strongly recommended to always specify
both of these together (either granting both, or granting none).
A particularly surprising example is :manpage:`creat(2)`. The name suggests
that this system call requires the rights to create and write files. However,
it also requires the truncate right if an existing file under the same name is
already present.
It should also be noted that truncating files does not require the
``LANDLOCK_ACCESS_FS_WRITE_FILE`` right. Apart from the :manpage:`truncate(2)`
system call, this can also be done through :manpage:`open(2)` with the flags
``O_RDONLY | O_TRUNC``.
At the same time, on some filesystems, :manpage:`fallocate(2)` offers a way to
shorten file contents with ``FALLOC_FL_COLLAPSE_RANGE`` when the file is opened
for writing, sidestepping the ``LANDLOCK_ACCESS_FS_TRUNCATE`` right.
The truncate right is associated with the opened file (see below).
Rights associated with file descriptors
---------------------------------------
When opening a file, the availability of the ``LANDLOCK_ACCESS_FS_TRUNCATE`` and
``LANDLOCK_ACCESS_FS_IOCTL_DEV`` rights is associated with the newly created
file descriptor and will be used for subsequent truncation and ioctl attempts
using :manpage:`ftruncate(2)` and :manpage:`ioctl(2)`. The behavior is similar
to opening a file for reading or writing, where permissions are checked during
:manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and
:manpage:`write(2)` calls.
As a consequence, it is possible that a process has multiple open file
descriptors referring to the same file, but Landlock enforces different things
when operating with these file descriptors. This can happen when a Landlock
ruleset gets enforced and the process keeps file descriptors which were opened
both before and after the enforcement. It is also possible to pass such file
descriptors between processes, keeping their Landlock properties, even when some
of the involved processes do not have an enforced Landlock ruleset.
Compatibility
=============
Backward and forward compatibility
----------------------------------
Landlock is designed to be compatible with past and future versions of the
kernel. This is achieved thanks to the system call attributes and the
associated bitflags, particularly the ruleset's ``handled_access_fs``. Making
handled access rights explicit enables the kernel and user space to have a clear
contract with each other. This is required to make sure sandboxing will not
get stricter with a system update, which could break applications.
Developers can subscribe to the `Landlock mailing list
<https://subspace.kernel.org/lists.linux.dev.html>`_ to knowingly update and
test their applications with the latest available features. In the interest of
users, and because they may use different kernel versions, it is strongly
encouraged to follow a best-effort security approach by checking the Landlock
ABI version at runtime and only enforcing the supported features.
.. _landlock_abi_versions:
Landlock ABI versions
---------------------
The Landlock ABI version can be read with the sys_landlock_create_ruleset()
system call:
.. code-block:: c
int abi;
abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
if (abi < 0) {
switch (errno) {
case ENOSYS:
printf("Landlock is not supported by the current kernel.\n");
break;
case EOPNOTSUPP:
printf("Landlock is currently disabled.\n");
break;
}
return 0;
}
if (abi >= 2) {
printf("Landlock supports LANDLOCK_ACCESS_FS_REFER.\n");
}
All Landlock kernel interfaces are supported by the first ABI version unless
explicitly noted in their documentation.
Landlock errata
---------------
In addition to ABI versions, Landlock provides an errata mechanism to track
fixes for issues that may affect backwards compatibility or require userspace
awareness. The errata bitmask can be queried using:
.. code-block:: c
int errata;
errata = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_ERRATA);
if (errata < 0) {
/* Landlock not available or disabled */
return 0;
}
The returned value is a bitmask where each bit represents a specific erratum.
If bit N is set (``errata & (1 << (N - 1))``), then erratum N has been fixed
in the running kernel.
.. warning::
**Most applications should NOT check errata.** In 99.9% of cases, checking
errata is unnecessary, increases code complexity, and can potentially
decrease protection if misused. For example, disabling the sandbox when an
erratum is not fixed could leave the system less secure than using
Landlock's best-effort protection. When in doubt, ignore errata.
.. kernel-doc:: security/landlock/errata/abi-4.h
:doc: erratum_1
.. kernel-doc:: security/landlock/errata/abi-6.h
:doc: erratum_2
.. kernel-doc:: security/landlock/errata/abi-1.h
:doc: erratum_3
How to check for errata
~~~~~~~~~~~~~~~~~~~~~~~
If you determine that your application needs to check for specific errata,
use this pattern:
.. code-block:: c
int errata = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_ERRATA);
if (errata >= 0) {
/* Check for specific erratum (1-indexed) */
if (errata & (1 << (erratum_number - 1))) {
/* Erratum N is fixed in this kernel */
} else {
/* Erratum N is NOT fixed - consider implications for your use case */
}
}
**Important:** Only check errata if your application specifically relies on
behavior that changed due to the fix. The fixes generally make Landlock less
restrictive or more correct, not more restrictive.
Kernel interface
================
Access rights
-------------
.. kernel-doc:: include/uapi/linux/landlock.h
:identifiers: fs_access net_access scope
Creating a new ruleset
----------------------
.. kernel-doc:: security/landlock/syscalls.c
:identifiers: sys_landlock_create_ruleset
.. kernel-doc:: include/uapi/linux/landlock.h
:identifiers: landlock_ruleset_attr
Extending a ruleset
-------------------
.. kernel-doc:: security/landlock/syscalls.c
:identifiers: sys_landlock_add_rule
.. kernel-doc:: include/uapi/linux/landlock.h
:identifiers: landlock_rule_type landlock_path_beneath_attr
landlock_net_port_attr
Enforcing a ruleset
-------------------
.. kernel-doc:: security/landlock/syscalls.c
:identifiers: sys_landlock_restrict_self
Current limitations
===================
Filesystem topology modification
--------------------------------
Threads sandboxed with filesystem restrictions cannot modify filesystem
topology, whether via :manpage:`mount(2)` or :manpage:`pivot_root(2)`.
However, :manpage:`chroot(2)` calls are not denied.
Special filesystems
-------------------
Access to regular files and directories can be restricted by Landlock,
according to the handled accesses of a ruleset. However, files that do not
come from a user-visible filesystem (e.g. pipe, socket), but can still be
accessed through ``/proc/<pid>/fd/*``, cannot currently be explicitly
restricted. Likewise, some special kernel filesystems such as nsfs, which can
be accessed through ``/proc/<pid>/ns/*``, cannot currently be explicitly
restricted. However, thanks to the `ptrace restrictions`_, access to such
sensitive ``/proc`` files are automatically restricted according to domain
hierarchies. Future Landlock evolutions could still enable to explicitly
restrict such paths with dedicated ruleset flags.
Ruleset layers
--------------
There is a limit of 16 layers of stacked rulesets. This can be an issue for a
task willing to enforce a new ruleset in complement to its 16 inherited
rulesets. Once this limit is reached, sys_landlock_restrict_self() returns
E2BIG. It is then strongly suggested to carefully build rulesets once in the
life of a thread, especially for applications able to launch other applications
that may also want to sandbox themselves (e.g. shells, container managers,
etc.).
Memory usage
------------
Kernel memory allocated to create rulesets is accounted and can be restricted
by the Documentation/admin-guide/cgroup-v1/memory.rst.
IOCTL support
-------------
The ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right restricts the use of
:manpage:`ioctl(2)`, but it only applies to *newly opened* device files. This
means specifically that pre-existing file descriptors like stdin, stdout and
stderr are unaffected.
Users should be aware that TTY devices have traditionally permitted to control
other processes on the same TTY through the ``TIOCSTI`` and ``TIOCLINUX`` IOCTL
commands. Both of these require ``CAP_SYS_ADMIN`` on modern Linux systems, but
the behavior is configurable for ``TIOCSTI``.
On older systems, it is therefore recommended to close inherited TTY file
descriptors, or to reopen them from ``/proc/self/fd/*`` without the
``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right, if possible.
Landlock's IOCTL support is coarse-grained at the moment, but may become more
fine-grained in the future. Until then, users are advised to establish the
guarantees that they need through the file hierarchy, by only allowing the
``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right on files where it is really required.
Previous limitations
====================
File renaming and linking (ABI < 2)
-----------------------------------
Because Landlock targets unprivileged access controls, it needs to properly
handle composition of rules. Such property also implies rules nesting.
Properly handling multiple layers of rulesets, each one of them able to
restrict access to files, also implies inheritance of the ruleset restrictions
from a parent to its hierarchy. Because files are identified and restricted by
their hierarchy, moving or linking a file from one directory to another implies
propagation of the hierarchy constraints, or restriction of these actions
according to the potentially lost constraints. To protect against privilege
escalations through renaming or linking, and for the sake of simplicity,
Landlock previously limited linking and renaming to the same directory.
Starting with the Landlock ABI version 2, it is now possible to securely
control renaming and linking thanks to the new ``LANDLOCK_ACCESS_FS_REFER``
access right.
File truncation (ABI < 3)
-------------------------
File truncation could not be denied before the third Landlock ABI, so it is
always allowed when using a kernel that only supports the first or second ABI.
Starting with the Landlock ABI version 3, it is now possible to securely control
truncation thanks to the new ``LANDLOCK_ACCESS_FS_TRUNCATE`` access right.
TCP bind and connect (ABI < 4)
------------------------------
Starting with the Landlock ABI version 4, it is now possible to restrict TCP
bind and connect actions to only a set of allowed ports thanks to the new
``LANDLOCK_ACCESS_NET_BIND_TCP`` and ``LANDLOCK_ACCESS_NET_CONNECT_TCP``
access rights.
Device IOCTL (ABI < 5)
----------------------
IOCTL operations could not be denied before the fifth Landlock ABI, so
:manpage:`ioctl(2)` is always allowed when using a kernel that only supports an
earlier ABI.
Starting with the Landlock ABI version 5, it is possible to restrict the use of
:manpage:`ioctl(2)` on character and block devices using the new
``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right.
Abstract UNIX socket (ABI < 6)
------------------------------
Starting with the Landlock ABI version 6, it is possible to restrict
connections to an abstract :manpage:`unix(7)` socket by setting
``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET`` to the ``scoped`` ruleset attribute.
Signal (ABI < 6)
----------------
Starting with the Landlock ABI version 6, it is possible to restrict
:manpage:`signal(7)` sending by setting ``LANDLOCK_SCOPE_SIGNAL`` to the
``scoped`` ruleset attribute.
Logging (ABI < 7)
-----------------
Starting with the Landlock ABI version 7, it is possible to control logging of
Landlock audit events with the ``LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF``,
``LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON``, and
``LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF`` flags passed to
sys_landlock_restrict_self(). See Documentation/admin-guide/LSM/landlock.rst
for more details on audit.
Thread synchronization (ABI < 8)
--------------------------------
Starting with the Landlock ABI version 8, it is now possible to
enforce Landlock rulesets across all threads of the calling process
using the ``LANDLOCK_RESTRICT_SELF_TSYNC`` flag passed to
sys_landlock_restrict_self().
Pathname UNIX sockets (ABI < 9)
-------------------------------
Starting with the Landlock ABI version 9, it is possible to restrict
connections to pathname UNIX domain sockets (:manpage:`unix(7)`) using
the new ``LANDLOCK_ACCESS_FS_RESOLVE_UNIX`` right.
UDP bind, connect and send* (ABI < 10)
--------------------------------------
Starting with the Landlock ABI version 10, it is possible to restrict
setting the local port of UDP sockets with the
``LANDLOCK_ACCESS_NET_BIND_UDP`` right. This includes restricting the
ability to trigger autobind of an ephemeral port by the kernel by e.g.
sending a first datagram or setting the remote peer of a socket.
The ``LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP`` right controls setting the
remote port of UDP sockets (via :manpage:`connect(2)`), and sending
datagrams to an explicit remote port (ignoring any destination set on
UDP sockets, via e.g. :manpage:`sendto(2)`).
Quiet rule flag (ABI < 10)
--------------------------
Starting with the Landlock ABI version 10, it is possible to selectively
suppress logs for specific denied accesses on a per-object basis with
the ``LANDLOCK_ADD_RULE_QUIET`` flag of sys_landlock_add_rule(), in
combination with the ``quiet_access_fs`` and ``quiet_access_net`` fields
of struct landlock_ruleset_attr. It is also now possible to suppress
logs for scope accesses via the ``quiet_scoped`` field of struct
landlock_ruleset_attr. The object is marked as quiet within a ruleset
when at least one sys_landlock_add_rule() call is made for it with the
``LANDLOCK_ADD_RULE_QUIET`` flag, additional add-rule calls for the same
object without this flag do not clear it.
.. _kernel_support:
Kernel support
==============
Build time configuration
------------------------
Landlock was first introduced in Linux 5.13 but it must be configured at build
time with ``CONFIG_SECURITY_LANDLOCK=y``. Landlock must also be enabled at boot
time like other security modules. The list of security modules enabled by
default is set with ``CONFIG_LSM``. The kernel configuration should then
contain ``CONFIG_LSM=landlock,[...]`` with ``[...]`` as the list of other
potentially useful security modules for the running system (see the
``CONFIG_LSM`` help).
Boot time configuration
-----------------------
If the running kernel does not have ``landlock`` in ``CONFIG_LSM``, then we can
enable Landlock by adding ``lsm=landlock,[...]`` to
Documentation/admin-guide/kernel-parameters.rst in the boot loader
configuration.
For example, if the current built-in configuration is:
.. code-block:: console
$ zgrep -h "^CONFIG_LSM=" "/boot/config-$(uname -r)" /proc/config.gz 2>/dev/null
CONFIG_LSM="lockdown,yama,integrity,apparmor"
...and if the cmdline doesn't contain ``landlock`` either:
.. code-block:: console
$ sed -n 's/.*\(\<lsm=\S\+\).*/\1/p' /proc/cmdline
lsm=lockdown,yama,integrity,apparmor
...we should configure the boot loader to set a cmdline extending the ``lsm``
list with the ``landlock,`` prefix::
lsm=landlock,lockdown,yama,integrity,apparmor
After a reboot, we can check that Landlock is up and running by looking at
kernel logs:
.. code-block:: console
# dmesg | grep landlock || journalctl -kb -g landlock
[ 0.000000] Command line: [...] lsm=landlock,lockdown,yama,integrity,apparmor
[ 0.000000] Kernel command line: [...] lsm=landlock,lockdown,yama,integrity,apparmor
[ 0.000000] LSM: initializing lsm=lockdown,capability,landlock,yama,integrity,apparmor
[ 0.000000] landlock: Up and running.
The kernel may be configured at build time to always load the ``lockdown`` and
``capability`` LSMs. In that case, these LSMs will appear at the beginning of
the ``LSM: initializing`` log line as well, even if they are not configured in
the boot loader.
Network support
---------------
To be able to explicitly allow TCP or UDP operations (e.g., adding a network rule with
``LANDLOCK_ACCESS_NET_BIND_TCP``), the kernel must support the TCP/IP protocol suite
(``CONFIG_INET=y``). Otherwise, sys_landlock_add_rule() returns an
``EAFNOSUPPORT`` error, which can safely be ignored because this kind of TCP or UDP
operation is already not possible.
Questions and answers
=====================
What about user space sandbox managers?
---------------------------------------
Using user space processes to enforce restrictions on kernel resources can lead
to race conditions or inconsistent evaluations (i.e. `Incorrect mirroring of
the OS code and state
<https://www.ndss-symposium.org/ndss2003/traps-and-pitfalls-practical-problems-system-call-interposition-based-security-tools/>`_).
What about namespaces and containers?
-------------------------------------
Namespaces can help create sandboxes but they are not designed for
access-control and then miss useful features for such use case (e.g. no
fine-grained restrictions). Moreover, their complexity can lead to security
issues, especially when untrusted processes can manipulate them (cf.
`Controlling access to user namespaces <https://lwn.net/Articles/673597/>`_).
How to disable Landlock audit records?
--------------------------------------
You might want to put in place filters as explained here:
Documentation/admin-guide/LSM/landlock.rst
Additional documentation
========================
* Documentation/admin-guide/LSM/landlock.rst
* Documentation/security/landlock.rst
* https://landlock.io
.. Links
.. _samples/landlock/sandboxer.c:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/samples/landlock/sandboxer.c
@@ -0,0 +1,51 @@
.. SPDX-License-Identifier: GPL-2.0
================
Live Update uAPI
================
:Author: Pasha Tatashin <pasha.tatashin@soleen.com>
ioctl interface
===============
.. kernel-doc:: kernel/liveupdate/luo_core.c
:doc: LUO ioctl Interface
ioctl uAPI
===========
.. kernel-doc:: include/uapi/linux/liveupdate.h
Note on Compatibility
=====================
Note that the Live Update feature is still under development and subject to
change, so compatibility is not guaranteed when kexec rebooting between
different kernel versions. This is expected to change and stabilize in a future
version.
Userspace Integration
=====================
systemd (since version v261) uses LUO to preserve its per-service file
descriptor store across a kexec-based live update. Services opt in by setting
``FileDescriptorStoreMax=`` and ``FileDescriptorStorePreserve=`` in their unit,
and push file descriptors with a name into the store via
``sd_pid_notify_with_fds(... "FDSTORE=1\nFDNAME=foo")``.
Services may also create their own LUO sessions (via ``/dev/liveupdate``) and
push the resulting session fds into their file descriptor store like any other
fd. systemd detects such session fds and handles them accordingly, and
hands the re-retrieved session fd back to the service after kexec, using the
existing file descriptor store service interface.
For details, see:
- `File Descriptor Store <https://systemd.io/FILE_DESCRIPTOR_STORE/>`_
- `systemd.service(5) FileDescriptorStorePreserve=
<https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html#FileDescriptorStorePreserve=>`_
- `sd_pid_notify_with_fds(3)
<https://www.freedesktop.org/software/systemd/man/latest/sd_pid_notify_with_fds.html>`_
See Also
========
- :doc:`Live Update Orchestrator </core-api/liveupdate>`
@@ -0,0 +1,73 @@
.. SPDX-License-Identifier: GPL-2.0
.. Copyright (C) 2022 Casey Schaufler <casey@schaufler-ca.com>
.. Copyright (C) 2022 Intel Corporation
=====================================
Linux Security Modules
=====================================
:Author: Casey Schaufler
:Date: July 2023
Linux security modules (LSM) provide a mechanism to implement
additional access controls to the Linux security policies.
The various security modules may support any of these attributes:
``LSM_ATTR_CURRENT`` is the current, active security context of the
process.
The proc filesystem provides this value in ``/proc/self/attr/current``.
This is supported by the SELinux, Smack and AppArmor security modules.
Smack also provides this value in ``/proc/self/attr/smack/current``.
AppArmor also provides this value in ``/proc/self/attr/apparmor/current``.
``LSM_ATTR_EXEC`` is the security context of the process at the time the
current image was executed.
The proc filesystem provides this value in ``/proc/self/attr/exec``.
This is supported by the SELinux and AppArmor security modules.
AppArmor also provides this value in ``/proc/self/attr/apparmor/exec``.
``LSM_ATTR_FSCREATE`` is the security context of the process used when
creating file system objects.
The proc filesystem provides this value in ``/proc/self/attr/fscreate``.
This is supported by the SELinux security module.
``LSM_ATTR_KEYCREATE`` is the security context of the process used when
creating key objects.
The proc filesystem provides this value in ``/proc/self/attr/keycreate``.
This is supported by the SELinux security module.
``LSM_ATTR_PREV`` is the security context of the process at the time the
current security context was set.
The proc filesystem provides this value in ``/proc/self/attr/prev``.
This is supported by the SELinux and AppArmor security modules.
AppArmor also provides this value in ``/proc/self/attr/apparmor/prev``.
``LSM_ATTR_SOCKCREATE`` is the security context of the process used when
creating socket objects.
The proc filesystem provides this value in ``/proc/self/attr/sockcreate``.
This is supported by the SELinux security module.
Kernel interface
================
Set a security attribute of the current process
-----------------------------------------------
.. kernel-doc:: security/lsm_syscalls.c
:identifiers: sys_lsm_set_self_attr
Get the specified security attributes of the current process
------------------------------------------------------------
.. kernel-doc:: security/lsm_syscalls.c
:identifiers: sys_lsm_get_self_attr
.. kernel-doc:: security/lsm_syscalls.c
:identifiers: sys_lsm_list_modules
Additional documentation
========================
* Documentation/security/lsm.rst
* Documentation/security/lsm-development.rst
@@ -0,0 +1,41 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. include:: <isonum.txt>
.. _cec:
#########################################
Part V - Consumer Electronics Control API
#########################################
This part describes the CEC: Consumer Electronics Control
.. toctree::
:caption: Table of Contents
:maxdepth: 5
:numbered:
cec-intro
cec-funcs
cec-pin-error-inj
cec-header
**********************
Revision and Copyright
**********************
Authors:
- Verkuil, Hans <hverkuil@kernel.org>
- Initial version.
**Copyright** |copy| 2016 : Hans Verkuil
****************
Revision History
****************
:revision: 1.0.0 / 2016-03-17 (*hv*)
Initial revision
@@ -0,0 +1,43 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _cec-func-close:
***********
cec close()
***********
Name
====
cec-close - Close a cec device
Synopsis
========
.. code-block:: c
#include <unistd.h>
.. c:function:: int close( int fd )
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
Description
===========
Closes the cec device. Resources associated with the file descriptor are
freed. The device configuration remain unchanged.
Return Value
============
:c:func:`close()` returns 0 on success. On error, -1 is returned, and
``errno`` is set appropriately. Possible error codes are:
``EBADF``
``fd`` is not a valid open file descriptor.
@@ -0,0 +1,63 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _cec-func-ioctl:
***********
cec ioctl()
***********
Name
====
cec-ioctl - Control a cec device
Synopsis
========
.. code-block:: c
#include <sys/ioctl.h>
``int ioctl(int fd, int request, void *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``request``
CEC ioctl request code as defined in the cec.h header file, for
example :ref:`CEC_ADAP_G_CAPS <CEC_ADAP_G_CAPS>`.
``argp``
Pointer to a request-specific structure.
Description
===========
The :c:func:`ioctl()` function manipulates cec device parameters. The
argument ``fd`` must be an open file descriptor.
The ioctl ``request`` code specifies the cec function to be called. It
has encoded in it whether the argument is an input, output or read/write
parameter, and the size of the argument ``argp`` in bytes.
Macros and structures definitions specifying cec ioctl requests and
their parameters are located in the cec.h header file. All cec ioctl
requests, their respective function and parameters are specified in
:ref:`cec-user-func`.
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
Request-specific error codes are listed in the individual requests
descriptions.
When an ioctl that takes an output or read/write parameter fails, the
parameter remains unmodified.
@@ -0,0 +1,74 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _cec-func-open:
**********
cec open()
**********
Name
====
cec-open - Open a cec device
Synopsis
========
.. code-block:: c
#include <fcntl.h>
.. c:function:: int open( const char *device_name, int flags )
Arguments
=========
``device_name``
Device to be opened.
``flags``
Open flags. Access mode must be ``O_RDWR``.
When the ``O_NONBLOCK`` flag is given, the
:ref:`CEC_RECEIVE <CEC_RECEIVE>` and :ref:`CEC_DQEVENT <CEC_DQEVENT>` ioctls
will return the ``EAGAIN`` error code when no message or event is available, and
ioctls :ref:`CEC_TRANSMIT <CEC_TRANSMIT>`,
:ref:`CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` and
:ref:`CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
all return 0.
Other flags have no effect.
Description
===========
To open a cec device applications call :c:func:`open()` with the
desired device name. The function has no side effects; the device
configuration remain unchanged.
When the device is opened in read-only mode, attempts to modify its
configuration will result in an error, and ``errno`` will be set to
EBADF.
Return Value
============
:c:func:`open()` returns the new file descriptor on success. On error,
-1 is returned, and ``errno`` is set appropriately. Possible error codes
include:
``EACCES``
The requested access to the file is not allowed.
``EMFILE``
The process already has the maximum number of files open.
``ENFILE``
The system limit on the total number of open files has been reached.
``ENOMEM``
Insufficient kernel memory was available.
``ENODEV``
Device not found or was removed.
@@ -0,0 +1,74 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _cec-func-poll:
**********
cec poll()
**********
Name
====
cec-poll - Wait for some event on a file descriptor
Synopsis
========
.. code-block:: c
#include <sys/poll.h>
.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout )
Arguments
=========
``ufds``
List of FD events to be watched
``nfds``
Number of FD events at the \*ufds array
``timeout``
Timeout to wait for events
Description
===========
With the :c:func:`poll()` function applications can wait for CEC
events.
On success :c:func:`poll()` returns the number of file descriptors
that have been selected (that is, file descriptors for which the
``revents`` field of the respective struct :c:type:`pollfd`
is non-zero). CEC devices set the ``POLLIN`` and ``POLLRDNORM`` flags in
the ``revents`` field if there are messages in the receive queue. If the
transmit queue has room for new messages, the ``POLLOUT`` and
``POLLWRNORM`` flags are set. If there are events in the event queue,
then the ``POLLPRI`` flag is set. When the function times out it returns
a value of zero, on failure it returns -1 and the ``errno`` variable is
set appropriately.
For more details see the :c:func:`poll()` manual page.
Return Value
============
On success, :c:func:`poll()` returns the number structures which have
non-zero ``revents`` fields, or zero if the call timed out. On error -1
is returned, and the ``errno`` variable is set appropriately:
``EBADF``
One or more of the ``ufds`` members specify an invalid file
descriptor.
``EFAULT``
``ufds`` references an inaccessible memory area.
``EINTR``
The call was interrupted by a signal.
``EINVAL``
The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
``getrlimit()`` to obtain this value.
@@ -0,0 +1,23 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _cec-user-func:
******************
Function Reference
******************
.. toctree::
:maxdepth: 1
cec-func-open
cec-func-close
cec-func-ioctl
cec-func-poll
cec-ioc-adap-g-caps
cec-ioc-adap-g-log-addrs
cec-ioc-adap-g-phys-addr
cec-ioc-adap-g-conn-info
cec-ioc-dqevent
cec-ioc-g-mode
cec-ioc-receive
@@ -0,0 +1,13 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _cec_header:
****************
CEC uAPI Symbols
****************
.. kernel-include:: include/uapi/linux/cec.h
:generate-cross-refs:
:exception-file: cec.h.rst.exceptions
:toc:
:warn-broken:
@@ -0,0 +1,42 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _cec-intro:
Introduction
============
HDMI connectors provide a single pin for use by the Consumer Electronics
Control protocol. This protocol allows different devices connected by an
HDMI cable to communicate. The protocol for CEC version 1.4 is defined
in supplements 1 (CEC) and 2 (HEAC or HDMI Ethernet and Audio Return
Channel) of the HDMI 1.4a (:ref:`hdmi`) specification and the
extensions added to CEC version 2.0 are defined in chapter 11 of the
HDMI 2.0 (:ref:`hdmi2`) specification.
The bitrate is very slow (effectively no more than 36 bytes per second)
and is based on the ancient AV.link protocol used in old SCART
connectors. The protocol closely resembles a crazy Rube Goldberg
contraption and is an unholy mix of low and high level messages. Some
messages, especially those part of the HEAC protocol layered on top of
CEC, need to be handled by the kernel, others can be handled either by
the kernel or by userspace.
In addition, CEC can be implemented in HDMI receivers, transmitters and
in USB devices that have an HDMI input and an HDMI output and that
control just the CEC pin.
Drivers that support CEC will create a CEC device node (/dev/cecX) to
give userspace access to the CEC adapter. The
:ref:`CEC_ADAP_G_CAPS` ioctl will tell userspace what it is allowed to do.
In order to check the support and test it, it is suggested to download
the `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_ package. It
provides three tools to handle CEC:
- cec-ctl: the Swiss army knife of CEC. Allows you to configure, transmit
and monitor CEC messages.
- cec-compliance: does a CEC compliance test of a remote CEC device to
determine how compliant the CEC implementation is.
- cec-follower: emulates a CEC follower.
@@ -0,0 +1,152 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _CEC_ADAP_G_CAPS:
*********************
ioctl CEC_ADAP_G_CAPS
*********************
Name
====
CEC_ADAP_G_CAPS - Query device capabilities
Synopsis
========
.. c:macro:: CEC_ADAP_G_CAPS
``int ioctl(int fd, CEC_ADAP_G_CAPS, struct cec_caps *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Description
===========
All cec devices must support :ref:`ioctl CEC_ADAP_G_CAPS <CEC_ADAP_G_CAPS>`. To query
device information, applications call the ioctl with a pointer to a
struct :c:type:`cec_caps`. The driver fills the structure and
returns the information to the application. The ioctl never fails.
.. tabularcolumns:: |p{1.2cm}|p{2.5cm}|p{13.6cm}|
.. c:type:: cec_caps
.. flat-table:: struct cec_caps
:header-rows: 0
:stub-columns: 0
:widths: 1 1 16
* - char
- ``driver[32]``
- The name of the cec adapter driver.
* - char
- ``name[32]``
- The name of this CEC adapter. The combination ``driver`` and
``name`` must be unique.
* - __u32
- ``available_log_addrs``
- The maximum number of logical addresses that can be configured.
* - __u32
- ``capabilities``
- The capabilities of the CEC adapter, see
:ref:`cec-capabilities`.
* - __u32
- ``version``
- CEC Framework API version, formatted with the ``KERNEL_VERSION()``
macro.
.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.4cm}|
.. _cec-capabilities:
.. flat-table:: CEC Capabilities Flags
:header-rows: 0
:stub-columns: 0
:widths: 3 1 8
* .. _`CEC-CAP-PHYS-ADDR`:
- ``CEC_CAP_PHYS_ADDR``
- 0x00000001
- Userspace has to configure the physical address by calling
:ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>`. If
this capability isn't set, then setting the physical address is
handled by the kernel whenever the EDID is set (for an HDMI
receiver) or read (for an HDMI transmitter).
* .. _`CEC-CAP-LOG-ADDRS`:
- ``CEC_CAP_LOG_ADDRS``
- 0x00000002
- Userspace has to configure the logical addresses by calling
:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`. If
this capability isn't set, then the kernel will have configured
this.
* .. _`CEC-CAP-TRANSMIT`:
- ``CEC_CAP_TRANSMIT``
- 0x00000004
- Userspace can transmit CEC messages by calling
:ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. This implies that
userspace can be a follower as well, since being able to transmit
messages is a prerequisite of becoming a follower. If this
capability isn't set, then the kernel will handle all CEC
transmits and process all CEC messages it receives.
* .. _`CEC-CAP-PASSTHROUGH`:
- ``CEC_CAP_PASSTHROUGH``
- 0x00000008
- Userspace can use the passthrough mode by calling
:ref:`ioctl CEC_S_MODE <CEC_S_MODE>`.
* .. _`CEC-CAP-RC`:
- ``CEC_CAP_RC``
- 0x00000010
- This adapter supports the remote control protocol.
* .. _`CEC-CAP-MONITOR-ALL`:
- ``CEC_CAP_MONITOR_ALL``
- 0x00000020
- The CEC hardware can monitor all messages, not just directed and
broadcast messages.
* .. _`CEC-CAP-NEEDS-HPD`:
- ``CEC_CAP_NEEDS_HPD``
- 0x00000040
- The CEC hardware is only active if the HDMI Hotplug Detect pin is
high. This makes it impossible to use CEC to wake up displays that
set the HPD pin low when in standby mode, but keep the CEC bus
alive.
* .. _`CEC-CAP-MONITOR-PIN`:
- ``CEC_CAP_MONITOR_PIN``
- 0x00000080
- The CEC hardware can monitor CEC pin changes from low to high voltage
and vice versa. When in pin monitoring mode the application will
receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events.
* .. _`CEC-CAP-CONNECTOR-INFO`:
- ``CEC_CAP_CONNECTOR_INFO``
- 0x00000100
- If this capability is set, then :ref:`CEC_ADAP_G_CONNECTOR_INFO` can
be used.
* .. _`CEC-CAP-REPLY-VENDOR-ID`:
- ``CEC_CAP_REPLY_VENDOR_ID``
- 0x00000200
- If this capability is set, then
:ref:`CEC_MSG_FL_REPLY_VENDOR_ID <cec-msg-flags>` can be used.
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,106 @@
.. SPDX-License-Identifier: GPL-2.0
..
.. Copyright 2019 Google LLC
..
.. c:namespace:: CEC
.. _CEC_ADAP_G_CONNECTOR_INFO:
*******************************
ioctl CEC_ADAP_G_CONNECTOR_INFO
*******************************
Name
====
CEC_ADAP_G_CONNECTOR_INFO - Query HDMI connector information
Synopsis
========
.. c:macro:: CEC_ADAP_G_CONNECTOR_INFO
``int ioctl(int fd, CEC_ADAP_G_CONNECTOR_INFO, struct cec_connector_info *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Description
===========
Using this ioctl an application can learn which HDMI connector this CEC
device corresponds to. While calling this ioctl the application should
provide a pointer to a cec_connector_info struct which will be populated
by the kernel with the info provided by the adapter's driver. This ioctl
is only available if the ``CEC_CAP_CONNECTOR_INFO`` capability is set.
.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.2cm}|
.. c:type:: cec_connector_info
.. flat-table:: struct cec_connector_info
:header-rows: 0
:stub-columns: 0
:widths: 1 1 8
* - __u32
- ``type``
- The type of connector this adapter is associated with.
* - union {
- ``(anonymous)``
* - ``struct cec_drm_connector_info``
- drm
- :ref:`cec-drm-connector-info`
* - }
-
.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.4cm}|
.. _connector-type:
.. flat-table:: Connector types
:header-rows: 0
:stub-columns: 0
:widths: 3 1 8
* .. _`CEC-CONNECTOR-TYPE-NO-CONNECTOR`:
- ``CEC_CONNECTOR_TYPE_NO_CONNECTOR``
- 0
- No connector is associated with the adapter/the information is not
provided by the driver.
* .. _`CEC-CONNECTOR-TYPE-DRM`:
- ``CEC_CONNECTOR_TYPE_DRM``
- 1
- Indicates that a DRM connector is associated with this adapter.
Information about the connector can be found in
:ref:`cec-drm-connector-info`.
.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.4cm}|
.. c:type:: cec_drm_connector_info
.. _cec-drm-connector-info:
.. flat-table:: struct cec_drm_connector_info
:header-rows: 0
:stub-columns: 0
:widths: 3 1 8
* .. _`CEC-DRM-CONNECTOR-TYPE-CARD-NO`:
- __u32
- ``card_no``
- DRM card number: the number from a card's path, e.g. 0 in case of
/dev/card0.
* .. _`CEC-DRM-CONNECTOR-TYPE-CONNECTOR_ID`:
- __u32
- ``connector_id``
- DRM connector ID.
@@ -0,0 +1,367 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _CEC_ADAP_LOG_ADDRS:
.. _CEC_ADAP_G_LOG_ADDRS:
.. _CEC_ADAP_S_LOG_ADDRS:
****************************************************
ioctls CEC_ADAP_G_LOG_ADDRS and CEC_ADAP_S_LOG_ADDRS
****************************************************
Name
====
CEC_ADAP_G_LOG_ADDRS, CEC_ADAP_S_LOG_ADDRS - Get or set the logical addresses
Synopsis
========
.. c:macro:: CEC_ADAP_G_LOG_ADDRS
``int ioctl(int fd, CEC_ADAP_G_LOG_ADDRS, struct cec_log_addrs *argp)``
.. c:macro:: CEC_ADAP_S_LOG_ADDRS
``int ioctl(int fd, CEC_ADAP_S_LOG_ADDRS, struct cec_log_addrs *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Pointer to struct :c:type:`cec_log_addrs`.
Description
===========
To query the current CEC logical addresses, applications call
:ref:`ioctl CEC_ADAP_G_LOG_ADDRS <CEC_ADAP_G_LOG_ADDRS>` with a pointer to a
struct :c:type:`cec_log_addrs` where the driver stores the logical addresses.
To set new logical addresses, applications fill in
struct :c:type:`cec_log_addrs` and call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
with a pointer to this struct. The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
is only available if ``CEC_CAP_LOG_ADDRS`` is set (the ``ENOTTY`` error code is
returned otherwise). The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
can only be called by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not
the ``EBUSY`` error code will be returned.
To clear existing logical addresses set ``num_log_addrs`` to 0. All other fields
will be ignored in that case. The adapter will go to the unconfigured state and the
``cec_version``, ``vendor_id`` and ``osd_name`` fields are all reset to their default
values (CEC version 2.0, no vendor ID and an empty OSD name).
If the physical address is valid (see :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>`),
then this ioctl will block until all requested logical
addresses have been claimed. If the file descriptor is in non-blocking mode then it will
not wait for the logical addresses to be claimed, instead it just returns 0.
A :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` event is sent when the
logical addresses are claimed or cleared.
Attempting to call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` when
logical address types are already defined will return with error ``EBUSY``.
.. c:type:: cec_log_addrs
.. tabularcolumns:: |p{1.0cm}|p{8.0cm}|p{8.0cm}|
.. cssclass:: longtable
.. flat-table:: struct cec_log_addrs
:header-rows: 0
:stub-columns: 0
:widths: 1 1 16
* - __u8
- ``log_addr[CEC_MAX_LOG_ADDRS]``
- The actual logical addresses that were claimed. This is set by the
driver. If no logical address could be claimed, then it is set to
``CEC_LOG_ADDR_INVALID``. If this adapter is Unregistered, then
``log_addr[0]`` is set to 0xf and all others to
``CEC_LOG_ADDR_INVALID``.
* - __u16
- ``log_addr_mask``
- The bitmask of all logical addresses this adapter has claimed. If
this adapter is Unregistered then ``log_addr_mask`` sets bit 15
and clears all other bits. If this adapter is not configured at
all, then ``log_addr_mask`` is set to 0. Set by the driver.
* - __u8
- ``cec_version``
- The CEC version that this adapter shall use. See
:ref:`cec-versions`. Used to implement the
``CEC_MSG_CEC_VERSION`` and ``CEC_MSG_REPORT_FEATURES`` messages.
Note that :ref:`CEC_OP_CEC_VERSION_1_3A <CEC-OP-CEC-VERSION-1-3A>` is not allowed by the CEC
framework.
* - __u8
- ``num_log_addrs``
- Number of logical addresses to set up. Must be ≤
``available_log_addrs`` as returned by
:ref:`CEC_ADAP_G_CAPS`. All arrays in
this structure are only filled up to index
``available_log_addrs``-1. The remaining array elements will be
ignored. Note that the CEC 2.0 standard allows for a maximum of 2
logical addresses, although some hardware has support for more.
``CEC_MAX_LOG_ADDRS`` is 4. The driver will return the actual
number of logical addresses it could claim, which may be less than
what was requested. If this field is set to 0, then the CEC
adapter shall clear all claimed logical addresses and all other
fields will be ignored.
* - __u32
- ``vendor_id``
- The vendor ID is a 24-bit number that identifies the specific
vendor or entity. Based on this ID vendor specific commands may be
defined. If you do not want a vendor ID then set it to
``CEC_VENDOR_ID_NONE``.
* - __u32
- ``flags``
- Flags. See :ref:`cec-log-addrs-flags` for a list of available flags.
* - char
- ``osd_name[15]``
- The On-Screen Display name as is returned by the
``CEC_MSG_SET_OSD_NAME`` message.
* - __u8
- ``primary_device_type[CEC_MAX_LOG_ADDRS]``
- Primary device type for each logical address. See
:ref:`cec-prim-dev-types` for possible types.
* - __u8
- ``log_addr_type[CEC_MAX_LOG_ADDRS]``
- Logical address types. See :ref:`cec-log-addr-types` for
possible types. The driver will update this with the actual
logical address type that it claimed (e.g. it may have to fallback
to :ref:`CEC_LOG_ADDR_TYPE_UNREGISTERED <CEC-LOG-ADDR-TYPE-UNREGISTERED>`).
* - __u8
- ``all_device_types[CEC_MAX_LOG_ADDRS]``
- CEC 2.0 specific: the bit mask of all device types. See
:ref:`cec-all-dev-types-flags`. It is used in the CEC 2.0
``CEC_MSG_REPORT_FEATURES`` message. For CEC 1.4 you can either leave
this field to 0, or fill it in according to the CEC 2.0 guidelines to
give the CEC framework more information about the device type, even
though the framework won't use it directly in the CEC message.
* - __u8
- ``features[CEC_MAX_LOG_ADDRS][12]``
- Features for each logical address. It is used in the CEC 2.0
``CEC_MSG_REPORT_FEATURES`` message. The 12 bytes include both the
RC Profile and the Device Features. For CEC 1.4 you can either leave
this field to all 0, or fill it in according to the CEC 2.0 guidelines to
give the CEC framework more information about the device type, even
though the framework won't use it directly in the CEC message.
.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.5cm}|
.. _cec-log-addrs-flags:
.. flat-table:: Flags for struct cec_log_addrs
:header-rows: 0
:stub-columns: 0
:widths: 3 1 4
* .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`:
- ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK``
- 1
- By default if no logical address of the requested type can be claimed, then
it will go back to the unconfigured state. If this flag is set, then it will
fallback to the Unregistered logical address. Note that if the Unregistered
logical address was explicitly requested, then this flag has no effect.
* .. _`CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU`:
- ``CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU``
- 2
- By default the ``CEC_MSG_USER_CONTROL_PRESSED`` and ``CEC_MSG_USER_CONTROL_RELEASED``
messages are only passed on to the follower(s), if any. If this flag is set,
then these messages are also passed on to the remote control input subsystem
and will appear as keystrokes. This features needs to be enabled explicitly.
If CEC is used to enter e.g. passwords, then you may not want to enable this
to avoid trivial snooping of the keystrokes.
* .. _`CEC-LOG-ADDRS-FL-CDC-ONLY`:
- ``CEC_LOG_ADDRS_FL_CDC_ONLY``
- 4
- If this flag is set, then the device is CDC-Only. CDC-Only CEC devices
are CEC devices that can only handle CDC messages.
All other messages are ignored.
.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.5cm}|
.. _cec-versions:
.. flat-table:: CEC Versions
:header-rows: 0
:stub-columns: 0
:widths: 3 1 4
* .. _`CEC-OP-CEC-VERSION-1-3A`:
- ``CEC_OP_CEC_VERSION_1_3A``
- 4
- CEC version according to the HDMI 1.3a standard.
* .. _`CEC-OP-CEC-VERSION-1-4B`:
- ``CEC_OP_CEC_VERSION_1_4B``
- 5
- CEC version according to the HDMI 1.4b standard.
* .. _`CEC-OP-CEC-VERSION-2-0`:
- ``CEC_OP_CEC_VERSION_2_0``
- 6
- CEC version according to the HDMI 2.0 standard.
.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.5cm}|
.. _cec-prim-dev-types:
.. flat-table:: CEC Primary Device Types
:header-rows: 0
:stub-columns: 0
:widths: 3 1 4
* .. _`CEC-OP-PRIM-DEVTYPE-TV`:
- ``CEC_OP_PRIM_DEVTYPE_TV``
- 0
- Use for a TV.
* .. _`CEC-OP-PRIM-DEVTYPE-RECORD`:
- ``CEC_OP_PRIM_DEVTYPE_RECORD``
- 1
- Use for a recording device.
* .. _`CEC-OP-PRIM-DEVTYPE-TUNER`:
- ``CEC_OP_PRIM_DEVTYPE_TUNER``
- 3
- Use for a device with a tuner.
* .. _`CEC-OP-PRIM-DEVTYPE-PLAYBACK`:
- ``CEC_OP_PRIM_DEVTYPE_PLAYBACK``
- 4
- Use for a playback device.
* .. _`CEC-OP-PRIM-DEVTYPE-AUDIOSYSTEM`:
- ``CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM``
- 5
- Use for an audio system (e.g. an audio/video receiver).
* .. _`CEC-OP-PRIM-DEVTYPE-SWITCH`:
- ``CEC_OP_PRIM_DEVTYPE_SWITCH``
- 6
- Use for a CEC switch.
* .. _`CEC-OP-PRIM-DEVTYPE-VIDEOPROC`:
- ``CEC_OP_PRIM_DEVTYPE_VIDEOPROC``
- 7
- Use for a video processor device.
.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.5cm}|
.. _cec-log-addr-types:
.. flat-table:: CEC Logical Address Types
:header-rows: 0
:stub-columns: 0
:widths: 3 1 16
* .. _`CEC-LOG-ADDR-TYPE-TV`:
- ``CEC_LOG_ADDR_TYPE_TV``
- 0
- Use for a TV.
* .. _`CEC-LOG-ADDR-TYPE-RECORD`:
- ``CEC_LOG_ADDR_TYPE_RECORD``
- 1
- Use for a recording device.
* .. _`CEC-LOG-ADDR-TYPE-TUNER`:
- ``CEC_LOG_ADDR_TYPE_TUNER``
- 2
- Use for a tuner device.
* .. _`CEC-LOG-ADDR-TYPE-PLAYBACK`:
- ``CEC_LOG_ADDR_TYPE_PLAYBACK``
- 3
- Use for a playback device.
* .. _`CEC-LOG-ADDR-TYPE-AUDIOSYSTEM`:
- ``CEC_LOG_ADDR_TYPE_AUDIOSYSTEM``
- 4
- Use for an audio system device.
* .. _`CEC-LOG-ADDR-TYPE-SPECIFIC`:
- ``CEC_LOG_ADDR_TYPE_SPECIFIC``
- 5
- Use for a second TV or for a video processor device.
* .. _`CEC-LOG-ADDR-TYPE-UNREGISTERED`:
- ``CEC_LOG_ADDR_TYPE_UNREGISTERED``
- 6
- Use this if you just want to remain unregistered. Used for pure
CEC switches or CDC-only devices (CDC: Capability Discovery and
Control).
.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.5cm}|
.. _cec-all-dev-types-flags:
.. flat-table:: CEC All Device Types Flags
:header-rows: 0
:stub-columns: 0
:widths: 3 1 4
* .. _`CEC-OP-ALL-DEVTYPE-TV`:
- ``CEC_OP_ALL_DEVTYPE_TV``
- 0x80
- This supports the TV type.
* .. _`CEC-OP-ALL-DEVTYPE-RECORD`:
- ``CEC_OP_ALL_DEVTYPE_RECORD``
- 0x40
- This supports the Recording type.
* .. _`CEC-OP-ALL-DEVTYPE-TUNER`:
- ``CEC_OP_ALL_DEVTYPE_TUNER``
- 0x20
- This supports the Tuner type.
* .. _`CEC-OP-ALL-DEVTYPE-PLAYBACK`:
- ``CEC_OP_ALL_DEVTYPE_PLAYBACK``
- 0x10
- This supports the Playback type.
* .. _`CEC-OP-ALL-DEVTYPE-AUDIOSYSTEM`:
- ``CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM``
- 0x08
- This supports the Audio System type.
* .. _`CEC-OP-ALL-DEVTYPE-SWITCH`:
- ``CEC_OP_ALL_DEVTYPE_SWITCH``
- 0x04
- This supports the CEC Switch or Video Processing type.
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` can return the following
error codes:
ENOTTY
The ``CEC_CAP_LOG_ADDRS`` capability wasn't set, so this ioctl is not supported.
EBUSY
The CEC adapter is currently configuring itself, or it is already configured and
``num_log_addrs`` is non-zero, or another filehandle is in exclusive follower or
initiator mode, or the filehandle is in mode ``CEC_MODE_NO_INITIATOR``.
EINVAL
The contents of struct :c:type:`cec_log_addrs` is invalid.
@@ -0,0 +1,94 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _CEC_ADAP_PHYS_ADDR:
.. _CEC_ADAP_G_PHYS_ADDR:
.. _CEC_ADAP_S_PHYS_ADDR:
****************************************************
ioctls CEC_ADAP_G_PHYS_ADDR and CEC_ADAP_S_PHYS_ADDR
****************************************************
Name
====
CEC_ADAP_G_PHYS_ADDR, CEC_ADAP_S_PHYS_ADDR - Get or set the physical address
Synopsis
========
.. c:macro:: CEC_ADAP_G_PHYS_ADDR
``int ioctl(int fd, CEC_ADAP_G_PHYS_ADDR, __u16 *argp)``
.. c:macro:: CEC_ADAP_S_PHYS_ADDR
``int ioctl(int fd, CEC_ADAP_S_PHYS_ADDR, __u16 *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Pointer to the CEC address.
Description
===========
To query the current physical address applications call
:ref:`ioctl CEC_ADAP_G_PHYS_ADDR <CEC_ADAP_G_PHYS_ADDR>` with a pointer to a __u16 where the
driver stores the physical address.
To set a new physical address applications store the physical address in
a __u16 and call :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` with a pointer to
this integer. The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` is only available if
``CEC_CAP_PHYS_ADDR`` is set (the ``ENOTTY`` error code will be returned
otherwise). The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` can only be called
by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not
the ``EBUSY`` error code will be returned.
To clear an existing physical address use ``CEC_PHYS_ADDR_INVALID``.
The adapter will go to the unconfigured state.
If logical address types have been defined (see :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`),
then this ioctl will block until all
requested logical addresses have been claimed. If the file descriptor is in non-blocking mode
then it will not wait for the logical addresses to be claimed, instead it just returns 0.
A :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` event is sent when the physical address
changes.
The physical address is a 16-bit number where each group of 4 bits
represent a digit of the physical address a.b.c.d where the most
significant 4 bits represent 'a'. The CEC root device (usually the TV)
has address 0.0.0.0. Every device that is hooked up to an input of the
TV has address a.0.0.0 (where 'a' is ≥ 1), devices hooked up to those in
turn have addresses a.b.0.0, etc. So a topology of up to 5 devices deep
is supported. The physical address a device shall use is stored in the
EDID of the sink.
For example, the EDID for each HDMI input of the TV will have a
different physical address of the form a.0.0.0 that the sources will
read out and use as their physical address.
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` can return the following
error codes:
ENOTTY
The ``CEC_CAP_PHYS_ADDR`` capability wasn't set, so this ioctl is not supported.
EBUSY
Another filehandle is in exclusive follower or initiator mode, or the filehandle
is in mode ``CEC_MODE_NO_INITIATOR``.
EINVAL
The physical address is malformed.
@@ -0,0 +1,245 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _CEC_DQEVENT:
*****************
ioctl CEC_DQEVENT
*****************
Name
====
CEC_DQEVENT - Dequeue a CEC event
Synopsis
========
.. c:macro:: CEC_DQEVENT
``int ioctl(int fd, CEC_DQEVENT, struct cec_event *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Description
===========
CEC devices can send asynchronous events. These can be retrieved by
calling :c:func:`CEC_DQEVENT`. If the file descriptor is in
non-blocking mode and no event is pending, then it will return -1 and
set errno to the ``EAGAIN`` error code.
The internal event queues are per-filehandle and per-event type. If
there is no more room in a queue then the last event is overwritten with
the new one. This means that intermediate results can be thrown away but
that the latest event is always available. This also means that is it
possible to read two successive events that have the same value (e.g.
two :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` events with
the same state). In that case the intermediate state changes were lost but
it is guaranteed that the state did change in between the two events.
.. tabularcolumns:: |p{1.2cm}|p{2.9cm}|p{13.2cm}|
.. c:type:: cec_event_state_change
.. flat-table:: struct cec_event_state_change
:header-rows: 0
:stub-columns: 0
:widths: 1 1 8
* - __u16
- ``phys_addr``
- The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no
valid physical address is set.
* - __u16
- ``log_addr_mask``
- The current set of claimed logical addresses. This is 0 if no logical
addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``.
If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device
has the unregistered logical address. In that case all other bits are 0.
* - __u16
- ``have_conn_info``
- If non-zero, then HDMI connector information is available.
This field is only valid if ``CEC_CAP_CONNECTOR_INFO`` is set. If that
capability is set and ``have_conn_info`` is zero, then that indicates
that the HDMI connector device is not instantiated, either because
the HDMI driver is still configuring the device or because the HDMI
device was unbound.
.. c:type:: cec_event_lost_msgs
.. tabularcolumns:: |p{1.0cm}|p{2.0cm}|p{14.3cm}|
.. flat-table:: struct cec_event_lost_msgs
:header-rows: 0
:stub-columns: 0
:widths: 1 1 16
* - __u32
- ``lost_msgs``
- Set to the number of lost messages since the filehandle was opened
or since the last time this event was dequeued for this
filehandle. The messages lost are the oldest messages. So when a
new message arrives and there is no more room, then the oldest
message is discarded to make room for the new one. The internal
size of the message queue guarantees that all messages received in
the last two seconds will be stored. Since messages should be
replied to within a second according to the CEC specification,
this is more than enough.
.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.2cm}|
.. c:type:: cec_event
.. flat-table:: struct cec_event
:header-rows: 0
:stub-columns: 0
:widths: 1 1 8
* - __u64
- ``ts``
- Timestamp of the event in ns.
The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock.
To access the same clock from userspace use :c:func:`clock_gettime`.
* - __u32
- ``event``
- The CEC event type, see :ref:`cec-events`.
* - __u32
- ``flags``
- Event flags, see :ref:`cec-event-flags`.
* - union {
- (anonymous)
* - struct cec_event_state_change
- ``state_change``
- The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>`
event.
* - struct cec_event_lost_msgs
- ``lost_msgs``
- The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS <CEC-EVENT-LOST-MSGS>`
event.
* - }
-
.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{10.8cm}|
.. _cec-events:
.. flat-table:: CEC Events Types
:header-rows: 0
:stub-columns: 0
:widths: 3 1 16
* .. _`CEC-EVENT-STATE-CHANGE`:
- ``CEC_EVENT_STATE_CHANGE``
- 1
- Generated when the CEC Adapter's state changes. When open() is
called an initial event will be generated for that filehandle with
the CEC Adapter's state at that time.
* .. _`CEC-EVENT-LOST-MSGS`:
- ``CEC_EVENT_LOST_MSGS``
- 2
- Generated if one or more CEC messages were lost because the
application didn't dequeue CEC messages fast enough.
* .. _`CEC-EVENT-PIN-CEC-LOW`:
- ``CEC_EVENT_PIN_CEC_LOW``
- 3
- Generated if the CEC pin goes from a high voltage to a low voltage.
Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
capability set.
* .. _`CEC-EVENT-PIN-CEC-HIGH`:
- ``CEC_EVENT_PIN_CEC_HIGH``
- 4
- Generated if the CEC pin goes from a low voltage to a high voltage.
Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
capability set.
* .. _`CEC-EVENT-PIN-HPD-LOW`:
- ``CEC_EVENT_PIN_HPD_LOW``
- 5
- Generated if the HPD pin goes from a high voltage to a low voltage.
Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
capability set. When open() is called, the HPD pin can be read and
if the HPD is low, then an initial event will be generated for that
filehandle.
* .. _`CEC-EVENT-PIN-HPD-HIGH`:
- ``CEC_EVENT_PIN_HPD_HIGH``
- 6
- Generated if the HPD pin goes from a low voltage to a high voltage.
Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
capability set. When open() is called, the HPD pin can be read and
if the HPD is high, then an initial event will be generated for that
filehandle.
* .. _`CEC-EVENT-PIN-5V-LOW`:
- ``CEC_EVENT_PIN_5V_LOW``
- 6
- Generated if the 5V pin goes from a high voltage to a low voltage.
Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
capability set. When open() is called, the 5V pin can be read and
if the 5V is low, then an initial event will be generated for that
filehandle.
* .. _`CEC-EVENT-PIN-5V-HIGH`:
- ``CEC_EVENT_PIN_5V_HIGH``
- 7
- Generated if the 5V pin goes from a low voltage to a high voltage.
Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
capability set. When open() is called, the 5V pin can be read and
if the 5V is high, then an initial event will be generated for that
filehandle.
.. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.7cm}|
.. _cec-event-flags:
.. flat-table:: CEC Event Flags
:header-rows: 0
:stub-columns: 0
:widths: 3 1 8
* .. _`CEC-EVENT-FL-INITIAL-STATE`:
- ``CEC_EVENT_FL_INITIAL_STATE``
- 1
- Set for the initial events that are generated when the device is
opened. See the table above for which events do this. This allows
applications to learn the initial state of the CEC adapter at
open() time.
* .. _`CEC-EVENT-FL-DROPPED-EVENTS`:
- ``CEC_EVENT_FL_DROPPED_EVENTS``
- 2
- Set if one or more events of the given event type have been dropped.
This is an indication that the application cannot keep up.
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
The :ref:`ioctl CEC_DQEVENT <CEC_DQEVENT>` can return the following
error codes:
EAGAIN
This is returned when the filehandle is in non-blocking mode and there
are no pending events.
ERESTARTSYS
An interrupt (e.g. Ctrl-C) arrived while in blocking mode waiting for
events to arrive.
@@ -0,0 +1,294 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _CEC_MODE:
.. _CEC_G_MODE:
.. _CEC_S_MODE:
********************************
ioctls CEC_G_MODE and CEC_S_MODE
********************************
CEC_G_MODE, CEC_S_MODE - Get or set exclusive use of the CEC adapter
Synopsis
========
.. c:macro:: CEC_G_MODE
``int ioctl(int fd, CEC_G_MODE, __u32 *argp)``
.. c:macro:: CEC_S_MODE
``int ioctl(int fd, CEC_S_MODE, __u32 *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Pointer to CEC mode.
Description
===========
By default any filehandle can use :ref:`CEC_TRANSMIT`, but in order to prevent
applications from stepping on each others toes it must be possible to
obtain exclusive access to the CEC adapter. This ioctl sets the
filehandle to initiator and/or follower mode which can be exclusive
depending on the chosen mode. The initiator is the filehandle that is
used to initiate messages, i.e. it commands other CEC devices. The
follower is the filehandle that receives messages sent to the CEC
adapter and processes them. The same filehandle can be both initiator
and follower, or this role can be taken by two different filehandles.
When a CEC message is received, then the CEC framework will decide how
it will be processed. If the message is a reply to an earlier
transmitted message, then the reply is sent back to the filehandle that
is waiting for it. In addition the CEC framework will process it.
If the message is not a reply, then the CEC framework will process it
first. If there is no follower, then the message is just discarded and a
feature abort is sent back to the initiator if the framework couldn't
process it. If there is a follower, then the message is passed on to the
follower who will use :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` to dequeue
the new message. The framework expects the follower to make the right
decisions.
The CEC framework will process core messages unless requested otherwise
by the follower. The follower can enable the passthrough mode. In that
case, the CEC framework will pass on most core messages without
processing them and the follower will have to implement those messages.
There are some messages that the core will always process, regardless of
the passthrough mode. See :ref:`cec-core-processing` for details.
If there is no initiator, then any CEC filehandle can use
:ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. If there is an exclusive
initiator then only that initiator can call
:ref:`CEC_TRANSMIT`. The follower can of course
always call :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`.
Available initiator modes are:
.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{10.8cm}|
.. _cec-mode-initiator_e:
.. flat-table:: Initiator Modes
:header-rows: 0
:stub-columns: 0
:widths: 3 1 16
* .. _`CEC-MODE-NO-INITIATOR`:
- ``CEC_MODE_NO_INITIATOR``
- 0x0
- This is not an initiator, i.e. it cannot transmit CEC messages or
make any other changes to the CEC adapter.
* .. _`CEC-MODE-INITIATOR`:
- ``CEC_MODE_INITIATOR``
- 0x1
- This is an initiator (the default when the device is opened) and
it can transmit CEC messages and make changes to the CEC adapter,
unless there is an exclusive initiator.
* .. _`CEC-MODE-EXCL-INITIATOR`:
- ``CEC_MODE_EXCL_INITIATOR``
- 0x2
- This is an exclusive initiator and this file descriptor is the
only one that can transmit CEC messages and make changes to the
CEC adapter. If someone else is already the exclusive initiator
then an attempt to become one will return the ``EBUSY`` error code
error.
Available follower modes are:
.. tabularcolumns:: |p{6.6cm}|p{0.9cm}|p{9.8cm}|
.. _cec-mode-follower_e:
.. cssclass:: longtable
.. flat-table:: Follower Modes
:header-rows: 0
:stub-columns: 0
:widths: 3 1 16
* .. _`CEC-MODE-NO-FOLLOWER`:
- ``CEC_MODE_NO_FOLLOWER``
- 0x00
- This is not a follower (the default when the device is opened).
* .. _`CEC-MODE-FOLLOWER`:
- ``CEC_MODE_FOLLOWER``
- 0x10
- This is a follower and it will receive CEC messages unless there
is an exclusive follower. You cannot become a follower if
:ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>` is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`
was specified, the ``EINVAL`` error code is returned in that case.
* .. _`CEC-MODE-EXCL-FOLLOWER`:
- ``CEC_MODE_EXCL_FOLLOWER``
- 0x20
- This is an exclusive follower and only this file descriptor will
receive CEC messages for processing. If someone else is already
the exclusive follower then an attempt to become one will return
the ``EBUSY`` error code. You cannot become a follower if
:ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>` is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`
was specified, the ``EINVAL`` error code is returned in that case.
* .. _`CEC-MODE-EXCL-FOLLOWER-PASSTHRU`:
- ``CEC_MODE_EXCL_FOLLOWER_PASSTHRU``
- 0x30
- This is an exclusive follower and only this file descriptor will
receive CEC messages for processing. In addition it will put the
CEC device into passthrough mode, allowing the exclusive follower
to handle most core messages instead of relying on the CEC
framework for that. If someone else is already the exclusive
follower then an attempt to become one will return the ``EBUSY`` error
code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>`
is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>` was specified,
the ``EINVAL`` error code is returned in that case.
* .. _`CEC-MODE-MONITOR-PIN`:
- ``CEC_MODE_MONITOR_PIN``
- 0xd0
- Put the file descriptor into pin monitoring mode. Can only be used in
combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,
otherwise the ``EINVAL`` error code will be returned.
This mode requires that the :ref:`CEC_CAP_MONITOR_PIN <CEC-CAP-MONITOR-PIN>`
capability is set, otherwise the ``EINVAL`` error code is returned.
While in pin monitoring mode this file descriptor can receive the
``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events to see the
low-level CEC pin transitions. This is very useful for debugging.
This mode is only allowed if the process has the ``CAP_NET_ADMIN``
capability. If that is not set, then the ``EPERM`` error code is returned.
* .. _`CEC-MODE-MONITOR`:
- ``CEC_MODE_MONITOR``
- 0xe0
- Put the file descriptor into monitor mode. Can only be used in
combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,
otherwise the ``EINVAL`` error code will be returned.
In monitor mode all messages this CEC
device transmits and all messages it receives (both broadcast
messages and directed messages for one its logical addresses) will
be reported. This is very useful for debugging. This is only
allowed if the process has the ``CAP_NET_ADMIN`` capability. If
that is not set, then the ``EPERM`` error code is returned.
* .. _`CEC-MODE-MONITOR-ALL`:
- ``CEC_MODE_MONITOR_ALL``
- 0xf0
- Put the file descriptor into 'monitor all' mode. Can only be used
in combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`, otherwise
the ``EINVAL`` error code will be returned. In 'monitor all' mode all messages
this CEC device transmits and all messages it receives, including
directed messages for other CEC devices, will be reported. This is
very useful for debugging, but not all devices support this. This
mode requires that the :ref:`CEC_CAP_MONITOR_ALL <CEC-CAP-MONITOR-ALL>` capability is set,
otherwise the ``EINVAL`` error code is returned. This is only allowed if
the process has the ``CAP_NET_ADMIN`` capability. If that is not
set, then the ``EPERM`` error code is returned.
Core message processing details:
.. tabularcolumns:: |p{6.6cm}|p{10.9cm}|
.. _cec-core-processing:
.. flat-table:: Core Message Processing
:header-rows: 0
:stub-columns: 0
:widths: 1 8
* .. _`CEC-MSG-GET-CEC-VERSION`:
- ``CEC_MSG_GET_CEC_VERSION``
- The core will return the CEC version that was set with
:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
except when in passthrough mode. In passthrough mode the core
does nothing and this message has to be handled by a follower
instead.
* .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`:
- ``CEC_MSG_GIVE_DEVICE_VENDOR_ID``
- The core will return the vendor ID that was set with
:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
except when in passthrough mode. In passthrough mode the core
does nothing and this message has to be handled by a follower
instead.
* .. _`CEC-MSG-ABORT`:
- ``CEC_MSG_ABORT``
- The core will return a Feature Abort message with reason
'Feature Refused' as per the specification, except when in
passthrough mode. In passthrough mode the core does nothing
and this message has to be handled by a follower instead.
* .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`:
- ``CEC_MSG_GIVE_PHYSICAL_ADDR``
- The core will report the current physical address, except when
in passthrough mode. In passthrough mode the core does nothing
and this message has to be handled by a follower instead.
* .. _`CEC-MSG-GIVE-OSD-NAME`:
- ``CEC_MSG_GIVE_OSD_NAME``
- The core will report the current OSD name that was set with
:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
except when in passthrough mode. In passthrough mode the core
does nothing and this message has to be handled by a follower
instead.
* .. _`CEC-MSG-GIVE-FEATURES`:
- ``CEC_MSG_GIVE_FEATURES``
- The core will do nothing if the CEC version is older than 2.0,
otherwise it will report the current features that were set with
:ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`,
except when in passthrough mode. In passthrough mode the core
does nothing (for any CEC version) and this message has to be handled
by a follower instead.
* .. _`CEC-MSG-USER-CONTROL-PRESSED`:
- ``CEC_MSG_USER_CONTROL_PRESSED``
- If :ref:`CEC_CAP_RC <CEC-CAP-RC>` is set and if
:ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU <CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU>`
is set, then generate a remote control key
press. This message is always passed on to the follower(s).
* .. _`CEC-MSG-USER-CONTROL-RELEASED`:
- ``CEC_MSG_USER_CONTROL_RELEASED``
- If :ref:`CEC_CAP_RC <CEC-CAP-RC>` is set and if
:ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU <CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU>`
is set, then generate a remote control key
release. This message is always passed on to the follower(s).
* .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`:
- ``CEC_MSG_REPORT_PHYSICAL_ADDR``
- The CEC framework will make note of the reported physical address
and then just pass the message on to the follower(s).
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
The :ref:`ioctl CEC_S_MODE <CEC_S_MODE>` can return the following
error codes:
EINVAL
The requested mode is invalid.
EPERM
Monitor mode is requested, but the process does have the ``CAP_NET_ADMIN``
capability.
EBUSY
Someone else is already an exclusive follower or initiator.
@@ -0,0 +1,400 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: CEC
.. _CEC_TRANSMIT:
.. _CEC_RECEIVE:
***********************************
ioctls CEC_RECEIVE and CEC_TRANSMIT
***********************************
Name
====
CEC_RECEIVE, CEC_TRANSMIT - Receive or transmit a CEC message
Synopsis
========
.. c:macro:: CEC_RECEIVE
``int ioctl(int fd, CEC_RECEIVE, struct cec_msg *argp)``
.. c:macro:: CEC_TRANSMIT
``int ioctl(int fd, CEC_TRANSMIT, struct cec_msg *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Pointer to struct cec_msg.
Description
===========
To receive a CEC message the application has to fill in the
``timeout`` field of struct :c:type:`cec_msg` and pass it to
:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
If the file descriptor is in non-blocking mode and there are no received
messages pending, then it will return -1 and set errno to the ``EAGAIN``
error code. If the file descriptor is in blocking mode and ``timeout``
is non-zero and no message arrived within ``timeout`` milliseconds, then
it will return -1 and set errno to the ``ETIMEDOUT`` error code.
A received message can be:
1. a message received from another CEC device (the ``sequence`` field will
be 0, ``tx_status`` will be 0 and ``rx_status`` will be non-zero).
2. the transmit result of an earlier non-blocking transmit (the ``sequence``
field will be non-zero, ``tx_status`` will be non-zero and ``rx_status``
will be 0).
3. the reply to an earlier non-blocking transmit (the ``sequence`` field will
be non-zero, ``tx_status`` will be 0 and ``rx_status`` will be non-zero).
To send a CEC message the application has to fill in the struct
:c:type:`cec_msg` and pass it to :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`.
The :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is only available if
``CEC_CAP_TRANSMIT`` is set. If there is no more room in the transmit
queue, then it will return -1 and set errno to the ``EBUSY`` error code.
The transmit queue has enough room for 18 messages (about 1 second worth
of 2-byte messages). Note that the CEC kernel framework will also reply
to core messages (see :ref:`cec-core-processing`), so it is not a good
idea to fully fill up the transmit queue.
If the file descriptor is in non-blocking mode then the transmit will
return 0 and the result of the transmit will be available via
:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` once the transmit has finished.
If a non-blocking transmit also specified waiting for a reply, then
the reply will arrive in a later message. The ``sequence`` field can
be used to associate both transmit results and replies with the original
transmit.
Normally calling :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` when the physical
address is invalid (due to e.g. a disconnect) will return ``ENONET``.
However, the CEC specification allows sending messages from 'Unregistered' to
'TV' when the physical address is invalid since some TVs pull the hotplug detect
pin of the HDMI connector low when they go into standby, or when switching to
another input.
When the hotplug detect pin goes low the EDID disappears, and thus the
physical address, but the cable is still connected and CEC still works.
In order to detect/wake up the device it is allowed to send poll and 'Image/Text
View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{12.8cm}|
.. c:type:: cec_msg
.. cssclass:: longtable
.. flat-table:: struct cec_msg
:header-rows: 0
:stub-columns: 0
:widths: 1 1 16
* - __u64
- ``tx_ts``
- Timestamp in ns of when the last byte of the message was transmitted.
The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access
the same clock from userspace use :c:func:`clock_gettime`.
* - __u64
- ``rx_ts``
- Timestamp in ns of when the last byte of the message was received.
The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access
the same clock from userspace use :c:func:`clock_gettime`.
* - __u32
- ``len``
- The length of the message. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in
by the application. The driver will fill this in for
:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` it will be
filled in by the driver with the length of the reply message if ``reply`` was set.
* - __u32
- ``timeout``
- The timeout in milliseconds. This is the time the device will wait
for a message to be received before timing out. If it is set to 0,
then it will wait indefinitely when it is called by :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
If it is 0 and it is called by :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`,
then it will be replaced by 1000 if the ``reply`` is non-zero or
ignored if ``reply`` is 0.
* - __u32
- ``sequence``
- A non-zero sequence number is automatically assigned by the CEC framework
for all transmitted messages. It is used by the CEC framework when it queues
the transmit result for a non-blocking transmit. This allows the application
to associate the received message with the original transmit.
In addition, if a non-blocking transmit will wait for a reply (ii.e. ``timeout``
was not 0), then the ``sequence`` field of the reply will be set to the sequence
value of the original transmit. This allows the application to associate the
received message with the original transmit.
* - __u32
- ``flags``
- Flags. See :ref:`cec-msg-flags` for a list of available flags.
* - __u8
- ``msg[16]``
- The message payload. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in by the
application. The driver will fill this in for :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` it will be filled in by the driver with
the payload of the reply message if ``timeout`` was set.
* - __u8
- ``reply``
- Wait until this message is replied. If ``reply`` is 0 and the
``timeout`` is 0, then don't wait for a reply but return after
transmitting the message. Ignored by :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
The case where ``reply`` is 0 (this is the opcode for the Feature Abort
message) and ``timeout`` is non-zero is specifically allowed to make it
possible to send a message and wait up to ``timeout`` milliseconds for a
Feature Abort reply. In this case ``rx_status`` will either be set
to :ref:`CEC_RX_STATUS_TIMEOUT <CEC-RX-STATUS-TIMEOUT>` or
:ref:`CEC_RX_STATUS_FEATURE_ABORT <CEC-RX-STATUS-FEATURE-ABORT>`.
If the transmitter message is ``CEC_MSG_INITIATE_ARC`` then the ``reply``
values ``CEC_MSG_REPORT_ARC_INITIATED`` and ``CEC_MSG_REPORT_ARC_TERMINATED``
are processed differently: either value will match both possible replies.
The reason is that the ``CEC_MSG_INITIATE_ARC`` message is the only CEC
message that has two possible replies other than Feature Abort. The
``reply`` field will be updated with the actual reply so that it is
synchronized with the contents of the received message.
* - __u8
- ``rx_status``
- The status bits of the received message. See
:ref:`cec-rx-status` for the possible status values.
* - __u8
- ``tx_status``
- The status bits of the transmitted message. See
:ref:`cec-tx-status` for the possible status values.
When calling :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` in non-blocking mode,
this field will be 0 if the transmit started, or non-0 if the transmit
result is known immediately. The latter would be the case when attempting
to transmit a Poll message to yourself. That results in a
:ref:`CEC_TX_STATUS_NACK <CEC-TX-STATUS-NACK>` without ever actually
transmitting the Poll message.
* - __u8
- ``tx_arb_lost_cnt``
- A counter of the number of transmit attempts that resulted in the
Arbitration Lost error. This is only set if the hardware supports
this, otherwise it is always 0. This counter is only valid if the
:ref:`CEC_TX_STATUS_ARB_LOST <CEC-TX-STATUS-ARB-LOST>` status bit is set.
* - __u8
- ``tx_nack_cnt``
- A counter of the number of transmit attempts that resulted in the
Not Acknowledged error. This is only set if the hardware supports
this, otherwise it is always 0. This counter is only valid if the
:ref:`CEC_TX_STATUS_NACK <CEC-TX-STATUS-NACK>` status bit is set.
* - __u8
- ``tx_low_drive_cnt``
- A counter of the number of transmit attempts that resulted in the
Arbitration Lost error. This is only set if the hardware supports
this, otherwise it is always 0. This counter is only valid if the
:ref:`CEC_TX_STATUS_LOW_DRIVE <CEC-TX-STATUS-LOW-DRIVE>` status bit is set.
* - __u8
- ``tx_error_cnt``
- A counter of the number of transmit errors other than Arbitration
Lost or Not Acknowledged. This is only set if the hardware
supports this, otherwise it is always 0. This counter is only
valid if the :ref:`CEC_TX_STATUS_ERROR <CEC-TX-STATUS-ERROR>` status bit is set.
.. tabularcolumns:: |p{6.2cm}|p{1.0cm}|p{10.1cm}|
.. _cec-msg-flags:
.. flat-table:: Flags for struct cec_msg
:header-rows: 0
:stub-columns: 0
:widths: 3 1 4
* .. _`CEC-MSG-FL-REPLY-TO-FOLLOWERS`:
- ``CEC_MSG_FL_REPLY_TO_FOLLOWERS``
- 1
- If a CEC transmit expects a reply, then by default that reply is only sent to
the filehandle that called :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. If this
flag is set, then the reply is also sent to all followers, if any. If the
filehandle that called :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is also a
follower, then that filehandle will receive the reply twice: once as the
result of the :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`, and once via
:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
* .. _`CEC-MSG-FL-RAW`:
- ``CEC_MSG_FL_RAW``
- 2
- Normally CEC messages are validated before transmitting them. If this
flag is set when :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is called,
then no validation takes place and the message is transmitted as-is.
This is useful when debugging CEC issues.
This flag is only allowed if the process has the ``CAP_SYS_RAWIO``
capability. If that is not set, then the ``EPERM`` error code is
returned.
* .. _`CEC-MSG-FL-REPLY-VENDOR-ID`:
- ``CEC_MSG_FL_REPLY_VENDOR_ID``
- 4
- This flag is only available if the ``CEC_CAP_REPLY_VENDOR_ID`` capability
is set. If this flag is set, then the reply is expected to consist of
the ``CEC_MSG_VENDOR_COMMAND_WITH_ID`` opcode followed by the Vendor ID
(in bytes 1-4 of the message), followed by the ``struct cec_msg``
``reply`` field.
Note that this assumes that the byte after the Vendor ID is a
vendor-specific opcode.
This flag makes it easier to wait for replies to vendor commands.
.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{10.8cm}|
.. _cec-tx-status:
.. flat-table:: CEC Transmit Status
:header-rows: 0
:stub-columns: 0
:widths: 3 1 16
* .. _`CEC-TX-STATUS-OK`:
- ``CEC_TX_STATUS_OK``
- 0x01
- The message was transmitted successfully. This is mutually
exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES <CEC-TX-STATUS-MAX-RETRIES>`.
Other bits can still be set if earlier attempts met with failure before
the transmit was eventually successful.
* .. _`CEC-TX-STATUS-ARB-LOST`:
- ``CEC_TX_STATUS_ARB_LOST``
- 0x02
- CEC line arbitration was lost, i.e. another transmit started at the
same time with a higher priority. Optional status, not all hardware
can detect this error condition.
* .. _`CEC-TX-STATUS-NACK`:
- ``CEC_TX_STATUS_NACK``
- 0x04
- Message was not acknowledged. Note that some hardware cannot tell apart
a 'Not Acknowledged' status from other error conditions, i.e. the result
of a transmit is just OK or FAIL. In that case this status will be
returned when the transmit failed.
* .. _`CEC-TX-STATUS-LOW-DRIVE`:
- ``CEC_TX_STATUS_LOW_DRIVE``
- 0x08
- Low drive was detected on the CEC bus. This indicates that a
follower detected an error on the bus and requests a
retransmission. Optional status, not all hardware can detect this
error condition.
* .. _`CEC-TX-STATUS-ERROR`:
- ``CEC_TX_STATUS_ERROR``
- 0x10
- Some error occurred. This is used for any errors that do not fit
``CEC_TX_STATUS_ARB_LOST`` or ``CEC_TX_STATUS_LOW_DRIVE``, either because
the hardware could not tell which error occurred, or because the hardware
tested for other conditions besides those two. Optional status.
* .. _`CEC-TX-STATUS-MAX-RETRIES`:
- ``CEC_TX_STATUS_MAX_RETRIES``
- 0x20
- The transmit failed after one or more retries. This status bit is
mutually exclusive with :ref:`CEC_TX_STATUS_OK <CEC-TX-STATUS-OK>`.
Other bits can still be set to explain which failures were seen.
* .. _`CEC-TX-STATUS-ABORTED`:
- ``CEC_TX_STATUS_ABORTED``
- 0x40
- The transmit was aborted due to an HDMI disconnect, or the adapter
was unconfigured, or a transmit was interrupted, or the driver
returned an error when attempting to start a transmit.
* .. _`CEC-TX-STATUS-TIMEOUT`:
- ``CEC_TX_STATUS_TIMEOUT``
- 0x80
- The transmit timed out. This should not normally happen and this
indicates a driver problem.
.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{10.8cm}|
.. _cec-rx-status:
.. flat-table:: CEC Receive Status
:header-rows: 0
:stub-columns: 0
:widths: 3 1 16
* .. _`CEC-RX-STATUS-OK`:
- ``CEC_RX_STATUS_OK``
- 0x01
- The message was received successfully.
* .. _`CEC-RX-STATUS-TIMEOUT`:
- ``CEC_RX_STATUS_TIMEOUT``
- 0x02
- The reply to an earlier transmitted message timed out.
* .. _`CEC-RX-STATUS-FEATURE-ABORT`:
- ``CEC_RX_STATUS_FEATURE_ABORT``
- 0x04
- The message was received successfully but the reply was
``CEC_MSG_FEATURE_ABORT``. This status is only set if this message
was the reply to an earlier transmitted message.
* .. _`CEC-RX-STATUS-ABORTED`:
- ``CEC_RX_STATUS_ABORTED``
- 0x08
- The wait for a reply to an earlier transmitted message was aborted
because the HDMI cable was disconnected, the adapter was unconfigured
or the :ref:`CEC_TRANSMIT <CEC_RECEIVE>` that waited for a
reply was interrupted.
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
The :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` can return the following
error codes:
EAGAIN
No messages are in the receive queue, and the filehandle is in non-blocking mode.
ETIMEDOUT
The ``timeout`` was reached while waiting for a message.
ERESTARTSYS
The wait for a message was interrupted (e.g. by Ctrl-C).
The :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` can return the following
error codes:
ENOTTY
The ``CEC_CAP_TRANSMIT`` capability wasn't set, so this ioctl is not supported.
EPERM
The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
has never been called, or ``CEC_MSG_FL_RAW`` was used from a process that
did not have the ``CAP_SYS_RAWIO`` capability.
ENONET
The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
was called, but the physical address is invalid so no logical address was claimed.
An exception is made in this case for transmits from initiator 0xf ('Unregistered')
to destination 0 ('TV'). In that case the transmit will proceed as usual.
EBUSY
Another filehandle is in exclusive follower or initiator mode, or the filehandle
is in mode ``CEC_MODE_NO_INITIATOR``. This is also returned if the transmit
queue is full.
EINVAL
The contents of struct :c:type:`cec_msg` is invalid.
ERESTARTSYS
The wait for a successful transmit was interrupted (e.g. by Ctrl-C).
@@ -0,0 +1,371 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _cec_pin_error_inj:
CEC Pin Framework Error Injection
=================================
The CEC Pin Framework is a core CEC framework for CEC hardware that only
has low-level support for the CEC bus. Most hardware today will have
high-level CEC support where the hardware deals with driving the CEC bus,
but some older devices aren't that fancy. However, this framework also
allows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and
you have now made a CEC adapter.
What makes doing this so interesting is that since we have full control
over the bus it is easy to support error injection. This is ideal to
test how well CEC adapters can handle error conditions.
Currently only the cec-gpio driver (when the CEC line is directly
connected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver
support this framework.
If ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available
through debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is
now an ``error-inj`` file.
.. note::
The error injection commands are not a stable ABI and may change in the
future.
With ``cat error-inj`` you can see both the possible commands and the current
error injection status::
$ cat /sys/kernel/debug/cec/cec0/error-inj
# Clear error injections:
# clear clear all rx and tx error injections
# rx-clear clear all rx error injections
# tx-clear clear all tx error injections
# <op> clear clear all rx and tx error injections for <op>
# <op> rx-clear clear all rx error injections for <op>
# <op> tx-clear clear all tx error injections for <op>
#
# RX error injection settings:
# rx-no-low-drive do not generate low-drive pulses
#
# RX error injection:
# <op>[,<mode>] rx-nack NACK the message instead of sending an ACK
# <op>[,<mode>] rx-low-drive <bit> force a low-drive condition at this bit position
# <op>[,<mode>] rx-add-byte add a spurious byte to the received CEC message
# <op>[,<mode>] rx-remove-byte remove the last byte from the received CEC message
# any[,<mode>] rx-arb-lost [<poll>] generate a POLL message to trigger an arbitration lost
#
# TX error injection settings:
# tx-ignore-nack-until-eom ignore early NACKs until EOM
# tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse
# tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse
# tx-custom-pulse transmit the custom pulse once the bus is idle
# tx-glitch-low-usecs <usecs> define the 'low' time for the glitch pulse
# tx-glitch-high-usecs <usecs> define the 'high' time for the glitch pulse
# tx-glitch-falling-edge send the glitch pulse after every falling edge
# tx-glitch-rising-edge send the glitch pulse after every rising edge
#
# TX error injection:
# <op>[,<mode>] tx-no-eom don't set the EOM bit
# <op>[,<mode>] tx-early-eom set the EOM bit one byte too soon
# <op>[,<mode>] tx-add-bytes <num> append <num> (1-255) spurious bytes to the message
# <op>[,<mode>] tx-remove-byte drop the last byte from the message
# <op>[,<mode>] tx-short-bit <bit> make this bit shorter than allowed
# <op>[,<mode>] tx-long-bit <bit> make this bit longer than allowed
# <op>[,<mode>] tx-custom-bit <bit> send the custom pulse instead of this bit
# <op>[,<mode>] tx-short-start send a start pulse that's too short
# <op>[,<mode>] tx-long-start send a start pulse that's too long
# <op>[,<mode>] tx-custom-start send the custom pulse instead of the start pulse
# <op>[,<mode>] tx-last-bit <bit> stop sending after this bit
# <op>[,<mode>] tx-low-drive <bit> force a low-drive condition at this bit position
#
# <op> CEC message opcode (0-255) or 'any'
# <mode> 'once' (default), 'always', 'toggle' or 'off'
# <bit> CEC message bit (0-159)
# 10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK
# <poll> CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f)
# <usecs> microseconds (0-10000000, default 1000)
clear
You can write error injection commands to ``error-inj`` using
``echo 'cmd' >error-inj`` or ``cat cmd.txt >error-inj``. The ``cat error-inj``
output contains the current error commands. You can save the output to a file
and use it as an input to ``error-inj`` later.
Basic Syntax
------------
Leading spaces/tabs are ignored. If the next character is a ``#`` or the end
of the line was reached, then the whole line is ignored. Otherwise a command
is expected.
The error injection commands fall in two main groups: those relating to
receiving CEC messages and those relating to transmitting CEC messages. In
addition, there are commands to clear existing error injection commands and
to create custom pulses on the CEC bus.
Most error injection commands can be executed for specific CEC opcodes or for
all opcodes (``any``). Each command also has a 'mode' which can be ``off``
(can be used to turn off an existing error injection command), ``once``
(the default) which will trigger the error injection only once for the next
received or transmitted message, ``always`` to always trigger the error
injection and ``toggle`` to toggle the error injection on or off for every
transmit or receive.
So '``any rx-nack``' will NACK the next received CEC message,
'``any,always rx-nack``' will NACK all received CEC messages and
'``0x82,toggle rx-nack``' will only NACK if an Active Source message was
received and do that only for every other received message.
After an error was injected with mode ``once`` the error injection command
is cleared automatically, so ``once`` is a one-time deal.
All combinations of ``<op>`` and error injection commands can co-exist. So
this is fine::
0x9e tx-add-bytes 1
0x9e tx-early-eom
0x9f tx-add-bytes 2
any rx-nack
All four error injection commands will be active simultaneously.
However, if the same ``<op>`` and command combination is specified,
but with different arguments::
0x9e tx-add-bytes 1
0x9e tx-add-bytes 2
Then the second will overwrite the first.
Clear Error Injections
----------------------
``clear``
Clear all error injections.
``rx-clear``
Clear all receive error injections
``tx-clear``
Clear all transmit error injections
``<op> clear``
Clear all error injections for the given opcode.
``<op> rx-clear``
Clear all receive error injections for the given opcode.
``<op> tx-clear``
Clear all transmit error injections for the given opcode.
Receive Messages
----------------
``<op>[,<mode>] rx-nack``
NACK broadcast messages and messages directed to this CEC adapter.
Every byte of the message will be NACKed in case the transmitter
keeps transmitting after the first byte was NACKed.
``<op>[,<mode>] rx-low-drive <bit>``
Force a Low Drive condition at this bit position. If <op> specifies
a specific CEC opcode then the bit position must be at least 18,
otherwise the opcode hasn't been received yet. This tests if the
transmitter can handle the Low Drive condition correctly and reports
the error correctly. Note that a Low Drive in the first 4 bits can also
be interpreted as an Arbitration Lost condition by the transmitter.
This is implementation dependent.
``<op>[,<mode>] rx-add-byte``
Add a spurious 0x55 byte to the received CEC message, provided
the message was 15 bytes long or less. This is useful to test
the high-level protocol since spurious bytes should be ignored.
``<op>[,<mode>] rx-remove-byte``
Remove the last byte from the received CEC message, provided it
was at least 2 bytes long. This is useful to test the high-level
protocol since messages that are too short should be ignored.
``<op>[,<mode>] rx-arb-lost <poll>``
Generate a POLL message to trigger an Arbitration Lost condition.
This command is only allowed for ``<op>`` values of ``next`` or ``all``.
As soon as a start bit has been received the CEC adapter will switch
to transmit mode and it will transmit a POLL message. By default this is
0x0f, but it can also be specified explicitly via the ``<poll>`` argument.
This command can be used to test the Arbitration Lost condition in
the remote CEC transmitter. Arbitration happens when two CEC adapters
start sending a message at the same time. In that case the initiator
with the most leading zeroes wins and the other transmitter has to
stop transmitting ('Arbitration Lost'). This is very hard to test,
except by using this error injection command.
This does not work if the remote CEC transmitter has logical address
0 ('TV') since that will always win.
``rx-no-low-drive``
The receiver will ignore situations that would normally generate a
Low Drive pulse (3.6 ms). This is typically done if a spurious pulse is
detected when receiving a message, and it indicates to the transmitter that
the message has to be retransmitted since the receiver got confused.
Disabling this is useful to test how other CEC devices handle glitches
by ensuring we will not be the one that generates a Low Drive.
Transmit Messages
-----------------
``tx-ignore-nack-until-eom``
This setting changes the behavior of transmitting CEC messages. Normally
as soon as the receiver NACKs a byte the transmit will stop, but the
specification also allows that the full message is transmitted and only
at the end will the transmitter look at the ACK bit. This is not
recommended behavior since there is no point in keeping the CEC bus busy
for longer than is strictly needed. Especially given how slow the bus is.
This setting can be used to test how well a receiver deals with
transmitters that ignore NACKs until the very end of the message.
``<op>[,<mode>] tx-no-eom``
Don't set the EOM bit. Normally the last byte of the message has the EOM
(End-Of-Message) bit set. With this command the transmit will just stop
without ever sending an EOM. This can be used to test how a receiver
handles this case. Normally receivers have a time-out after which
they will go back to the Idle state.
``<op>[,<mode>] tx-early-eom``
Set the EOM bit one byte too soon. This obviously only works for messages
of two bytes or more. The EOM bit will be set for the second-to-last byte
and not for the final byte. The receiver should ignore the last byte in
this case. Since the resulting message is likely to be too short for this
same reason the whole message is typically ignored. The receiver should be
in Idle state after the last byte was transmitted.
``<op>[,<mode>] tx-add-bytes <num>``
Append ``<num>`` (1-255) spurious bytes to the message. The extra bytes
have the value of the byte position in the message. So if you transmit a
two byte message (e.g. a Get CEC Version message) and add 2 bytes, then
the full message received by the remote CEC adapter is
``0x40 0x9f 0x02 0x03``.
This command can be used to test buffer overflows in the receiver. E.g.
what does it do when it receives more than the maximum message size of 16
bytes.
``<op>[,<mode>] tx-remove-byte``
Drop the last byte from the message, provided the message is at least
two bytes long. The receiver should ignore messages that are too short.
``<op>[,<mode>] tx-short-bit <bit>``
Make this bit period shorter than allowed. The bit position cannot be
an Ack bit. If <op> specifies a specific CEC opcode then the bit position
must be at least 18, otherwise the opcode hasn't been received yet.
Normally the period of a data bit is between 2.05 and 2.75 milliseconds.
With this command the period of this bit is 1.8 milliseconds, this is
done by reducing the time the CEC bus is high. This bit period is less
than is allowed and the receiver should respond with a Low Drive
condition.
This command is ignored for 0 bits in bit positions 0 to 3. This is
because the receiver also looks for an Arbitration Lost condition in
those first four bits and it is undefined what will happen if it
sees a too-short 0 bit.
``<op>[,<mode>] tx-long-bit <bit>``
Make this bit period longer than is valid. The bit position cannot be
an Ack bit. If <op> specifies a specific CEC opcode then the bit position
must be at least 18, otherwise the opcode hasn't been received yet.
Normally the period of a data bit is between 2.05 and 2.75 milliseconds.
With this command the period of this bit is 2.9 milliseconds, this is
done by increasing the time the CEC bus is high.
Even though this bit period is longer than is valid it is undefined what
a receiver will do. It might just accept it, or it might time out and
return to Idle state. Unfortunately the CEC specification is silent about
this.
This command is ignored for 0 bits in bit positions 0 to 3. This is
because the receiver also looks for an Arbitration Lost condition in
those first four bits and it is undefined what will happen if it
sees a too-long 0 bit.
``<op>[,<mode>] tx-short-start``
Make this start bit period shorter than allowed. Normally the period of
a start bit is between 4.3 and 4.7 milliseconds. With this command the
period of the start bit is 4.1 milliseconds, this is done by reducing
the time the CEC bus is high. This start bit period is less than is
allowed and the receiver should return to Idle state when this is detected.
``<op>[,<mode>] tx-long-start``
Make this start bit period longer than is valid. Normally the period of
a start bit is between 4.3 and 4.7 milliseconds. With this command the
period of the start bit is 5 milliseconds, this is done by increasing
the time the CEC bus is high. This start bit period is more than is
valid and the receiver should return to Idle state when this is detected.
Even though this start bit period is longer than is valid it is undefined
what a receiver will do. It might just accept it, or it might time out and
return to Idle state. Unfortunately the CEC specification is silent about
this.
``<op>[,<mode>] tx-last-bit <bit>``
Just stop transmitting after this bit. If <op> specifies a specific CEC
opcode then the bit position must be at least 18, otherwise the opcode
hasn't been received yet. This command can be used to test how the receiver
reacts when a message just suddenly stops. It should time out and go back
to Idle state.
``<op>[,<mode>] tx-low-drive <bit>``
Force a Low Drive condition at this bit position. If <op> specifies a
specific CEC opcode then the bit position must be at least 18, otherwise
the opcode hasn't been received yet. This can be used to test how the
receiver handles Low Drive conditions. Note that if this happens at bit
positions 0-3 the receiver can interpret this as an Arbitration Lost
condition. This is implementation dependent.
Custom Pulses
-------------
``tx-custom-low-usecs <usecs>``
This defines the duration in microseconds that the custom pulse pulls
the CEC line low. The default is 1000 microseconds.
``tx-custom-high-usecs <usecs>``
This defines the duration in microseconds that the custom pulse keeps the
CEC line high (unless another CEC adapter pulls it low in that time).
The default is 1000 microseconds. The total period of the custom pulse is
``tx-custom-low-usecs + tx-custom-high-usecs``.
``<op>[,<mode>] tx-custom-bit <bit>``
Send the custom bit instead of a regular data bit. The bit position cannot
be an Ack bit. If <op> specifies a specific CEC opcode then the bit
position must be at least 18, otherwise the opcode hasn't been received yet.
``<op>[,<mode>] tx-custom-start``
Send the custom bit instead of a regular start bit.
``tx-custom-pulse``
Transmit a single custom pulse as soon as the CEC bus is idle.
Glitch Pulses
-------------
This emulates what happens if the signal on the CEC line is seeing spurious
pulses. Typically this happens after the falling or rising edge where there
is a short voltage fluctuation that, if the CEC hardware doesn't do
deglitching, can be seen as a spurious pulse and can cause a Low Drive
condition or corrupt data.
``tx-glitch-low-usecs <usecs>``
This defines the duration in microseconds that the glitch pulse pulls
the CEC line low. The default is 1 microsecond. The range is 0-100
microseconds. If 0, then no glitch pulse will be generated.
``tx-glitch-high-usecs <usecs>``
This defines the duration in microseconds that the glitch pulse keeps the
CEC line high (unless another CEC adapter pulls it low in that time).
The default is 1 microseconds. The range is 0-100 microseconds. If 0, then
no glitch pulse will be generated.The total period of the glitch pulse is
``tx-custom-low-usecs + tx-custom-high-usecs``.
``tx-glitch-falling-edge``
Send the glitch pulse right after the falling edge.
``tx-glitch-rising-edge``
Send the glitch pulse right after the rising edge.
@@ -0,0 +1,603 @@
# SPDX-License-Identifier: GPL-2.0
# All symbols belong to CEC namespace
namespace CEC
# Ignore header name
ignore define _CEC_UAPI_H
# define macros to ignore
ignore define CEC_MAX_MSG_SIZE
ignore define CEC_MAX_LOG_ADDRS
ignore define CEC_LOG_ADDR_MASK_TV
ignore define CEC_LOG_ADDR_MASK_RECORD
ignore define CEC_LOG_ADDR_MASK_TUNER
ignore define CEC_LOG_ADDR_MASK_PLAYBACK
ignore define CEC_LOG_ADDR_MASK_AUDIOSYSTEM
ignore define CEC_LOG_ADDR_MASK_BACKUP
ignore define CEC_LOG_ADDR_MASK_SPECIFIC
ignore define CEC_LOG_ADDR_MASK_UNREGISTERED
# Shouldn't them be documented?
ignore define CEC_LOG_ADDR_INVALID
ignore define CEC_PHYS_ADDR_INVALID
ignore define CEC_VENDOR_ID_NONE
ignore define CEC_MODE_INITIATOR_MSK
ignore define CEC_MODE_FOLLOWER_MSK
# Part of CEC 2.0 spec - shouldn't be documented too?
ignore define CEC_LOG_ADDR_TV
ignore define CEC_LOG_ADDR_RECORD_1
ignore define CEC_LOG_ADDR_RECORD_2
ignore define CEC_LOG_ADDR_TUNER_1
ignore define CEC_LOG_ADDR_PLAYBACK_1
ignore define CEC_LOG_ADDR_AUDIOSYSTEM
ignore define CEC_LOG_ADDR_TUNER_2
ignore define CEC_LOG_ADDR_TUNER_3
ignore define CEC_LOG_ADDR_PLAYBACK_2
ignore define CEC_LOG_ADDR_RECORD_3
ignore define CEC_LOG_ADDR_TUNER_4
ignore define CEC_LOG_ADDR_PLAYBACK_3
ignore define CEC_LOG_ADDR_BACKUP_1
ignore define CEC_LOG_ADDR_BACKUP_2
ignore define CEC_LOG_ADDR_SPECIFIC
ignore define CEC_LOG_ADDR_UNREGISTERED
ignore define CEC_LOG_ADDR_BROADCAST
# IMHO, those should also be documented
ignore define CEC_MSG_ACTIVE_SOURCE
ignore define CEC_MSG_IMAGE_VIEW_ON
ignore define CEC_MSG_TEXT_VIEW_ON
ignore define CEC_MSG_INACTIVE_SOURCE
ignore define CEC_MSG_REQUEST_ACTIVE_SOURCE
ignore define CEC_MSG_ROUTING_CHANGE
ignore define CEC_MSG_ROUTING_INFORMATION
ignore define CEC_MSG_SET_STREAM_PATH
ignore define CEC_MSG_STANDBY
ignore define CEC_MSG_RECORD_OFF
ignore define CEC_MSG_RECORD_ON
ignore define CEC_OP_RECORD_SRC_OWN
ignore define CEC_OP_RECORD_SRC_DIGITAL
ignore define CEC_OP_RECORD_SRC_ANALOG
ignore define CEC_OP_RECORD_SRC_EXT_PLUG
ignore define CEC_OP_RECORD_SRC_EXT_PHYS_ADDR
ignore define CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID
ignore define CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T
ignore define CEC_OP_ANA_BCAST_TYPE_CABLE
ignore define CEC_OP_ANA_BCAST_TYPE_SATELLITE
ignore define CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL
ignore define CEC_OP_BCAST_SYSTEM_PAL_BG
ignore define CEC_OP_BCAST_SYSTEM_SECAM_LQ
ignore define CEC_OP_BCAST_SYSTEM_PAL_M
ignore define CEC_OP_BCAST_SYSTEM_NTSC_M
ignore define CEC_OP_BCAST_SYSTEM_PAL_I
ignore define CEC_OP_BCAST_SYSTEM_SECAM_DK
ignore define CEC_OP_BCAST_SYSTEM_SECAM_BG
ignore define CEC_OP_BCAST_SYSTEM_SECAM_L
ignore define CEC_OP_BCAST_SYSTEM_PAL_DK
ignore define CEC_OP_BCAST_SYSTEM_OTHER
ignore define CEC_OP_CHANNEL_NUMBER_FMT_1_PART
ignore define CEC_OP_CHANNEL_NUMBER_FMT_2_PART
ignore define CEC_MSG_RECORD_STATUS
ignore define CEC_OP_RECORD_STATUS_CUR_SRC
ignore define CEC_OP_RECORD_STATUS_DIG_SERVICE
ignore define CEC_OP_RECORD_STATUS_ANA_SERVICE
ignore define CEC_OP_RECORD_STATUS_EXT_INPUT
ignore define CEC_OP_RECORD_STATUS_NO_DIG_SERVICE
ignore define CEC_OP_RECORD_STATUS_NO_ANA_SERVICE
ignore define CEC_OP_RECORD_STATUS_NO_SERVICE
ignore define CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG
ignore define CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR
ignore define CEC_OP_RECORD_STATUS_UNSUP_CA
ignore define CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS
ignore define CEC_OP_RECORD_STATUS_CANT_COPY_SRC
ignore define CEC_OP_RECORD_STATUS_NO_MORE_COPIES
ignore define CEC_OP_RECORD_STATUS_NO_MEDIA
ignore define CEC_OP_RECORD_STATUS_PLAYING
ignore define CEC_OP_RECORD_STATUS_ALREADY_RECORDING
ignore define CEC_OP_RECORD_STATUS_MEDIA_PROT
ignore define CEC_OP_RECORD_STATUS_NO_SIGNAL
ignore define CEC_OP_RECORD_STATUS_MEDIA_PROBLEM
ignore define CEC_OP_RECORD_STATUS_NO_SPACE
ignore define CEC_OP_RECORD_STATUS_PARENTAL_LOCK
ignore define CEC_OP_RECORD_STATUS_TERMINATED_OK
ignore define CEC_OP_RECORD_STATUS_ALREADY_TERM
ignore define CEC_OP_RECORD_STATUS_OTHER
ignore define CEC_MSG_RECORD_TV_SCREEN
ignore define CEC_MSG_CLEAR_ANALOGUE_TIMER
ignore define CEC_OP_REC_SEQ_SUNDAY
ignore define CEC_OP_REC_SEQ_MONDAY
ignore define CEC_OP_REC_SEQ_TUESDAY
ignore define CEC_OP_REC_SEQ_WEDNESDAY
ignore define CEC_OP_REC_SEQ_THURSDAY
ignore define CEC_OP_REC_SEQ_FRIDAY
ignore define CEC_OP_REC_SEQ_SATURDAY
ignore define CEC_OP_REC_SEQ_ONCE_ONLY
ignore define CEC_MSG_CLEAR_DIGITAL_TIMER
ignore define CEC_MSG_CLEAR_EXT_TIMER
ignore define CEC_OP_EXT_SRC_PLUG
ignore define CEC_OP_EXT_SRC_PHYS_ADDR
ignore define CEC_MSG_SET_ANALOGUE_TIMER
ignore define CEC_MSG_SET_DIGITAL_TIMER
ignore define CEC_MSG_SET_EXT_TIMER
ignore define CEC_MSG_SET_TIMER_PROGRAM_TITLE
ignore define CEC_MSG_TIMER_CLEARED_STATUS
ignore define CEC_OP_TIMER_CLR_STAT_RECORDING
ignore define CEC_OP_TIMER_CLR_STAT_NO_MATCHING
ignore define CEC_OP_TIMER_CLR_STAT_NO_INFO
ignore define CEC_OP_TIMER_CLR_STAT_CLEARED
ignore define CEC_MSG_TIMER_STATUS
ignore define CEC_OP_TIMER_OVERLAP_WARNING_NO_OVERLAP
ignore define CEC_OP_TIMER_OVERLAP_WARNING_OVERLAP
ignore define CEC_OP_MEDIA_INFO_UNPROT_MEDIA
ignore define CEC_OP_MEDIA_INFO_PROT_MEDIA
ignore define CEC_OP_MEDIA_INFO_NO_MEDIA
ignore define CEC_OP_PROG_IND_NOT_PROGRAMMED
ignore define CEC_OP_PROG_IND_PROGRAMMED
ignore define CEC_OP_PROG_INFO_ENOUGH_SPACE
ignore define CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE
ignore define CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE
ignore define CEC_OP_PROG_INFO_NONE_AVAILABLE
ignore define CEC_OP_PROG_ERROR_NO_FREE_TIMER
ignore define CEC_OP_PROG_ERROR_DATE_OUT_OF_RANGE
ignore define CEC_OP_PROG_ERROR_REC_SEQ_ERROR
ignore define CEC_OP_PROG_ERROR_INV_EXT_PLUG
ignore define CEC_OP_PROG_ERROR_INV_EXT_PHYS_ADDR
ignore define CEC_OP_PROG_ERROR_CA_UNSUPP
ignore define CEC_OP_PROG_ERROR_INSUF_CA_ENTITLEMENTS
ignore define CEC_OP_PROG_ERROR_RESOLUTION_UNSUPP
ignore define CEC_OP_PROG_ERROR_PARENTAL_LOCK
ignore define CEC_OP_PROG_ERROR_CLOCK_FAILURE
ignore define CEC_OP_PROG_ERROR_DUPLICATE
ignore define CEC_MSG_CEC_VERSION
ignore define CEC_OP_CEC_VERSION_1_3A
ignore define CEC_OP_CEC_VERSION_1_4
ignore define CEC_OP_CEC_VERSION_2_0
ignore define CEC_MSG_GET_CEC_VERSION
ignore define CEC_MSG_GIVE_PHYSICAL_ADDR
ignore define CEC_MSG_GET_MENU_LANGUAGE
ignore define CEC_MSG_REPORT_PHYSICAL_ADDR
ignore define CEC_OP_PRIM_DEVTYPE_TV
ignore define CEC_OP_PRIM_DEVTYPE_RECORD
ignore define CEC_OP_PRIM_DEVTYPE_TUNER
ignore define CEC_OP_PRIM_DEVTYPE_PLAYBACK
ignore define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM
ignore define CEC_OP_PRIM_DEVTYPE_SWITCH
ignore define CEC_OP_PRIM_DEVTYPE_PROCESSOR
ignore define CEC_MSG_SET_MENU_LANGUAGE
ignore define CEC_MSG_REPORT_FEATURES
ignore define CEC_OP_ALL_DEVTYPE_TV
ignore define CEC_OP_ALL_DEVTYPE_RECORD
ignore define CEC_OP_ALL_DEVTYPE_TUNER
ignore define CEC_OP_ALL_DEVTYPE_PLAYBACK
ignore define CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM
ignore define CEC_OP_ALL_DEVTYPE_SWITCH
ignore define CEC_OP_FEAT_EXT
ignore define CEC_OP_FEAT_RC_TV_PROFILE_NONE
ignore define CEC_OP_FEAT_RC_TV_PROFILE_1
ignore define CEC_OP_FEAT_RC_TV_PROFILE_2
ignore define CEC_OP_FEAT_RC_TV_PROFILE_3
ignore define CEC_OP_FEAT_RC_TV_PROFILE_4
ignore define CEC_OP_FEAT_RC_SRC_HAS_DEV_ROOT_MENU
ignore define CEC_OP_FEAT_RC_SRC_HAS_DEV_SETUP_MENU
ignore define CEC_OP_FEAT_RC_SRC_HAS_CONTENTS_MENU
ignore define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_TOP_MENU
ignore define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_CONTEXT_MENU
ignore define CEC_OP_FEAT_DEV_HAS_RECORD_TV_SCREEN
ignore define CEC_OP_FEAT_DEV_HAS_SET_OSD_STRING
ignore define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL
ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE
ignore define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX
ignore define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX
ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_VOLUME_LEVEL
ignore define CEC_MSG_GIVE_FEATURES
ignore define CEC_MSG_DECK_CONTROL
ignore define CEC_OP_DECK_CTL_MODE_SKIP_FWD
ignore define CEC_OP_DECK_CTL_MODE_SKIP_REV
ignore define CEC_OP_DECK_CTL_MODE_STOP
ignore define CEC_OP_DECK_CTL_MODE_EJECT
ignore define CEC_MSG_DECK_STATUS
ignore define CEC_OP_DECK_INFO_PLAY
ignore define CEC_OP_DECK_INFO_RECORD
ignore define CEC_OP_DECK_INFO_PLAY_REV
ignore define CEC_OP_DECK_INFO_STILL
ignore define CEC_OP_DECK_INFO_SLOW
ignore define CEC_OP_DECK_INFO_SLOW_REV
ignore define CEC_OP_DECK_INFO_FAST_FWD
ignore define CEC_OP_DECK_INFO_FAST_REV
ignore define CEC_OP_DECK_INFO_NO_MEDIA
ignore define CEC_OP_DECK_INFO_STOP
ignore define CEC_OP_DECK_INFO_SKIP_FWD
ignore define CEC_OP_DECK_INFO_SKIP_REV
ignore define CEC_OP_DECK_INFO_INDEX_SEARCH_FWD
ignore define CEC_OP_DECK_INFO_INDEX_SEARCH_REV
ignore define CEC_OP_DECK_INFO_OTHER
ignore define CEC_MSG_GIVE_DECK_STATUS
ignore define CEC_OP_STATUS_REQ_ON
ignore define CEC_OP_STATUS_REQ_OFF
ignore define CEC_OP_STATUS_REQ_ONCE
ignore define CEC_MSG_PLAY
ignore define CEC_OP_PLAY_MODE_PLAY_FWD
ignore define CEC_OP_PLAY_MODE_PLAY_REV
ignore define CEC_OP_PLAY_MODE_PLAY_STILL
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX
ignore define CEC_MSG_GIVE_TUNER_DEVICE_STATUS
ignore define CEC_MSG_SELECT_ANALOGUE_SERVICE
ignore define CEC_MSG_SELECT_DIGITAL_SERVICE
ignore define CEC_MSG_TUNER_DEVICE_STATUS
ignore define CEC_OP_REC_FLAG_USED
ignore define CEC_OP_REC_FLAG_NOT_USED
ignore define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL
ignore define CEC_OP_TUNER_DISPLAY_INFO_NONE
ignore define CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE
ignore define CEC_MSG_TUNER_STEP_DECREMENT
ignore define CEC_MSG_TUNER_STEP_INCREMENT
ignore define CEC_MSG_DEVICE_VENDOR_ID
ignore define CEC_MSG_GIVE_DEVICE_VENDOR_ID
ignore define CEC_MSG_VENDOR_COMMAND
ignore define CEC_MSG_VENDOR_COMMAND_WITH_ID
ignore define CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN
ignore define CEC_MSG_VENDOR_REMOTE_BUTTON_UP
ignore define CEC_MSG_SET_OSD_STRING
ignore define CEC_OP_DISP_CTL_DEFAULT
ignore define CEC_OP_DISP_CTL_UNTIL_CLEARED
ignore define CEC_OP_DISP_CTL_CLEAR
ignore define CEC_MSG_GIVE_OSD_NAME
ignore define CEC_MSG_SET_OSD_NAME
ignore define CEC_MSG_MENU_REQUEST
ignore define CEC_OP_MENU_REQUEST_ACTIVATE
ignore define CEC_OP_MENU_REQUEST_DEACTIVATE
ignore define CEC_OP_MENU_REQUEST_QUERY
ignore define CEC_MSG_MENU_STATUS
ignore define CEC_OP_MENU_STATE_ACTIVATED
ignore define CEC_OP_MENU_STATE_DEACTIVATED
ignore define CEC_MSG_USER_CONTROL_PRESSED
ignore define CEC_OP_UI_CMD_SELECT
ignore define CEC_OP_UI_CMD_UP
ignore define CEC_OP_UI_CMD_DOWN
ignore define CEC_OP_UI_CMD_LEFT
ignore define CEC_OP_UI_CMD_RIGHT
ignore define CEC_OP_UI_CMD_RIGHT_UP
ignore define CEC_OP_UI_CMD_RIGHT_DOWN
ignore define CEC_OP_UI_CMD_LEFT_UP
ignore define CEC_OP_UI_CMD_LEFT_DOWN
ignore define CEC_OP_UI_CMD_DEVICE_ROOT_MENU
ignore define CEC_OP_UI_CMD_DEVICE_SETUP_MENU
ignore define CEC_OP_UI_CMD_CONTENTS_MENU
ignore define CEC_OP_UI_CMD_FAVORITE_MENU
ignore define CEC_OP_UI_CMD_BACK
ignore define CEC_OP_UI_CMD_MEDIA_TOP_MENU
ignore define CEC_OP_UI_CMD_MEDIA_CONTEXT_SENSITIVE_MENU
ignore define CEC_OP_UI_CMD_NUMBER_ENTRY_MODE
ignore define CEC_OP_UI_CMD_NUMBER_11
ignore define CEC_OP_UI_CMD_NUMBER_12
ignore define CEC_OP_UI_CMD_NUMBER_0_OR_NUMBER_10
ignore define CEC_OP_UI_CMD_NUMBER_1
ignore define CEC_OP_UI_CMD_NUMBER_2
ignore define CEC_OP_UI_CMD_NUMBER_3
ignore define CEC_OP_UI_CMD_NUMBER_4
ignore define CEC_OP_UI_CMD_NUMBER_5
ignore define CEC_OP_UI_CMD_NUMBER_6
ignore define CEC_OP_UI_CMD_NUMBER_7
ignore define CEC_OP_UI_CMD_NUMBER_8
ignore define CEC_OP_UI_CMD_NUMBER_9
ignore define CEC_OP_UI_CMD_DOT
ignore define CEC_OP_UI_CMD_ENTER
ignore define CEC_OP_UI_CMD_CLEAR
ignore define CEC_OP_UI_CMD_NEXT_FAVORITE
ignore define CEC_OP_UI_CMD_CHANNEL_UP
ignore define CEC_OP_UI_CMD_CHANNEL_DOWN
ignore define CEC_OP_UI_CMD_PREVIOUS_CHANNEL
ignore define CEC_OP_UI_CMD_SOUND_SELECT
ignore define CEC_OP_UI_CMD_INPUT_SELECT
ignore define CEC_OP_UI_CMD_DISPLAY_INFORMATION
ignore define CEC_OP_UI_CMD_HELP
ignore define CEC_OP_UI_CMD_PAGE_UP
ignore define CEC_OP_UI_CMD_PAGE_DOWN
ignore define CEC_OP_UI_CMD_POWER
ignore define CEC_OP_UI_CMD_VOLUME_UP
ignore define CEC_OP_UI_CMD_VOLUME_DOWN
ignore define CEC_OP_UI_CMD_MUTE
ignore define CEC_OP_UI_CMD_PLAY
ignore define CEC_OP_UI_CMD_STOP
ignore define CEC_OP_UI_CMD_PAUSE
ignore define CEC_OP_UI_CMD_RECORD
ignore define CEC_OP_UI_CMD_REWIND
ignore define CEC_OP_UI_CMD_FAST_FORWARD
ignore define CEC_OP_UI_CMD_EJECT
ignore define CEC_OP_UI_CMD_SKIP_FORWARD
ignore define CEC_OP_UI_CMD_SKIP_BACKWARD
ignore define CEC_OP_UI_CMD_STOP_RECORD
ignore define CEC_OP_UI_CMD_PAUSE_RECORD
ignore define CEC_OP_UI_CMD_ANGLE
ignore define CEC_OP_UI_CMD_SUB_PICTURE
ignore define CEC_OP_UI_CMD_VIDEO_ON_DEMAND
ignore define CEC_OP_UI_CMD_ELECTRONIC_PROGRAM_GUIDE
ignore define CEC_OP_UI_CMD_TIMER_PROGRAMMING
ignore define CEC_OP_UI_CMD_INITIAL_CONFIGURATION
ignore define CEC_OP_UI_CMD_SELECT_BROADCAST_TYPE
ignore define CEC_OP_UI_CMD_SELECT_SOUND_PRESENTATION
ignore define CEC_OP_UI_CMD_AUDIO_DESCRIPTION
ignore define CEC_OP_UI_CMD_INTERNET
ignore define CEC_OP_UI_CMD_3D_MODE
ignore define CEC_OP_UI_CMD_PLAY_FUNCTION
ignore define CEC_OP_UI_CMD_PAUSE_PLAY_FUNCTION
ignore define CEC_OP_UI_CMD_RECORD_FUNCTION
ignore define CEC_OP_UI_CMD_PAUSE_RECORD_FUNCTION
ignore define CEC_OP_UI_CMD_STOP_FUNCTION
ignore define CEC_OP_UI_CMD_MUTE_FUNCTION
ignore define CEC_OP_UI_CMD_RESTORE_VOLUME_FUNCTION
ignore define CEC_OP_UI_CMD_TUNE_FUNCTION
ignore define CEC_OP_UI_CMD_SELECT_MEDIA_FUNCTION
ignore define CEC_OP_UI_CMD_SELECT_AV_INPUT_FUNCTION
ignore define CEC_OP_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION
ignore define CEC_OP_UI_CMD_POWER_TOGGLE_FUNCTION
ignore define CEC_OP_UI_CMD_POWER_OFF_FUNCTION
ignore define CEC_OP_UI_CMD_POWER_ON_FUNCTION
ignore define CEC_OP_UI_CMD_F1_BLUE
ignore define CEC_OP_UI_CMD_F2_RED
ignore define CEC_OP_UI_CMD_F3_GREEN
ignore define CEC_OP_UI_CMD_F4_YELLOW
ignore define CEC_OP_UI_CMD_F5
ignore define CEC_OP_UI_CMD_DATA
ignore define CEC_OP_UI_BCAST_TYPE_TOGGLE_ALL
ignore define CEC_OP_UI_BCAST_TYPE_TOGGLE_DIG_ANA
ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE
ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_T
ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_CABLE
ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_SAT
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_T
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_CABLE
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_SAT
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT2
ignore define CEC_OP_UI_BCAST_TYPE_IP
ignore define CEC_OP_UI_SND_PRES_CTL_DUAL_MONO
ignore define CEC_OP_UI_SND_PRES_CTL_KARAOKE
ignore define CEC_OP_UI_SND_PRES_CTL_DOWNMIX
ignore define CEC_OP_UI_SND_PRES_CTL_REVERB
ignore define CEC_OP_UI_SND_PRES_CTL_EQUALIZER
ignore define CEC_OP_UI_SND_PRES_CTL_BASS_UP
ignore define CEC_OP_UI_SND_PRES_CTL_BASS_NEUTRAL
ignore define CEC_OP_UI_SND_PRES_CTL_BASS_DOWN
ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_UP
ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_NEUTRAL
ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_DOWN
ignore define CEC_MSG_USER_CONTROL_RELEASED
ignore define CEC_MSG_GIVE_DEVICE_POWER_STATUS
ignore define CEC_MSG_REPORT_POWER_STATUS
ignore define CEC_OP_POWER_STATUS_ON
ignore define CEC_OP_POWER_STATUS_STANDBY
ignore define CEC_OP_POWER_STATUS_TO_ON
ignore define CEC_OP_POWER_STATUS_TO_STANDBY
ignore define CEC_MSG_FEATURE_ABORT
ignore define CEC_OP_ABORT_UNRECOGNIZED_OP
ignore define CEC_OP_ABORT_INCORRECT_MODE
ignore define CEC_OP_ABORT_NO_SOURCE
ignore define CEC_OP_ABORT_INVALID_OP
ignore define CEC_OP_ABORT_REFUSED
ignore define CEC_OP_ABORT_UNDETERMINED
ignore define CEC_MSG_ABORT
ignore define CEC_MSG_GIVE_AUDIO_STATUS
ignore define CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS
ignore define CEC_MSG_REPORT_AUDIO_STATUS
ignore define CEC_OP_AUD_MUTE_STATUS_OFF
ignore define CEC_OP_AUD_MUTE_STATUS_ON
ignore define CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR
ignore define CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR
ignore define CEC_MSG_SET_SYSTEM_AUDIO_MODE
ignore define CEC_OP_SYS_AUD_STATUS_OFF
ignore define CEC_OP_SYS_AUD_STATUS_ON
ignore define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST
ignore define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS
ignore define CEC_MSG_SET_AUDIO_VOLUME_LEVEL
ignore define CEC_OP_AUD_FMT_ID_CEA861
ignore define CEC_OP_AUD_FMT_ID_CEA861_CXT
ignore define CEC_MSG_SET_AUDIO_RATE
ignore define CEC_OP_AUD_RATE_OFF
ignore define CEC_OP_AUD_RATE_WIDE_STD
ignore define CEC_OP_AUD_RATE_WIDE_FAST
ignore define CEC_OP_AUD_RATE_WIDE_SLOW
ignore define CEC_OP_AUD_RATE_NARROW_STD
ignore define CEC_OP_AUD_RATE_NARROW_FAST
ignore define CEC_OP_AUD_RATE_NARROW_SLOW
ignore define CEC_MSG_INITIATE_ARC
ignore define CEC_MSG_REPORT_ARC_INITIATED
ignore define CEC_MSG_REPORT_ARC_TERMINATED
ignore define CEC_MSG_REQUEST_ARC_INITIATION
ignore define CEC_MSG_REQUEST_ARC_TERMINATION
ignore define CEC_MSG_TERMINATE_ARC
ignore define CEC_MSG_REQUEST_CURRENT_LATENCY
ignore define CEC_MSG_REPORT_CURRENT_LATENCY
ignore define CEC_OP_LOW_LATENCY_MODE_OFF
ignore define CEC_OP_LOW_LATENCY_MODE_ON
ignore define CEC_OP_AUD_OUT_COMPENSATED_NA
ignore define CEC_OP_AUD_OUT_COMPENSATED_DELAY
ignore define CEC_OP_AUD_OUT_COMPENSATED_NO_DELAY
ignore define CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY
ignore define CEC_MSG_REQUEST_LIP_SUPPORT
ignore define CEC_MSG_REPORT_LIP_SUPPORT
ignore define CEC_MSG_REQUEST_AUDIO_AND_VIDEO_LATENCY
ignore define CEC_OP_HDR_FORMAT_GAMMA_SDR
ignore define CEC_OP_HDR_FORMAT_GAMMA_HDR
ignore define CEC_OP_HDR_FORMAT_PQ
ignore define CEC_OP_HDR_FORMAT_HLG
ignore define CEC_OP_HDR_FORMAT_DYNAMIC_HDR_TYPE_1
ignore define CEC_OP_HDR_FORMAT_DYNAMIC_HDR_TYPE_2
ignore define CEC_OP_HDR_FORMAT_DYNAMIC_HDR_TYPE_4
ignore define CEC_OP_HDR_FORMAT_DV_SINK_LED
ignore define CEC_OP_HDR_FORMAT_DV_SOURCE_LED
ignore define CEC_OP_HDR_FORMAT_HDR10PLUS
ignore define CEC_OP_HDR_FORMAT_ETSI_TS_103_433
ignore define CEC_MSG_REPORT_AUDIO_AND_VIDEO_LATENCY
ignore define CEC_MSG_REQUEST_AUDIO_LATENCY
ignore define CEC_MSG_REPORT_AUDIO_LATENCY
ignore define CEC_MSG_REQUEST_VIDEO_LATENCY
ignore define CEC_MSG_REPORT_VIDEO_LATENCY
ignore define CEC_MSG_UPDATE_SQID
ignore define CEC_MSG_CDC_MESSAGE
ignore define CEC_MSG_CDC_HEC_INQUIRE_STATE
ignore define CEC_MSG_CDC_HEC_REPORT_STATE
ignore define CEC_OP_HEC_FUNC_STATE_NOT_SUPPORTED
ignore define CEC_OP_HEC_FUNC_STATE_INACTIVE
ignore define CEC_OP_HEC_FUNC_STATE_ACTIVE
ignore define CEC_OP_HEC_FUNC_STATE_ACTIVATION_FIELD
ignore define CEC_OP_HOST_FUNC_STATE_NOT_SUPPORTED
ignore define CEC_OP_HOST_FUNC_STATE_INACTIVE
ignore define CEC_OP_HOST_FUNC_STATE_ACTIVE
ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_NOT_SUPPORTED
ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_INACTIVE
ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_ACTIVE
ignore define CEC_OP_CDC_ERROR_CODE_NONE
ignore define CEC_OP_CDC_ERROR_CODE_CAP_UNSUPPORTED
ignore define CEC_OP_CDC_ERROR_CODE_WRONG_STATE
ignore define CEC_OP_CDC_ERROR_CODE_OTHER
ignore define CEC_OP_HEC_SUPPORT_NO
ignore define CEC_OP_HEC_SUPPORT_YES
ignore define CEC_OP_HEC_ACTIVATION_ON
ignore define CEC_OP_HEC_ACTIVATION_OFF
ignore define CEC_MSG_CDC_HEC_SET_STATE_ADJACENT
ignore define CEC_MSG_CDC_HEC_SET_STATE
ignore define CEC_OP_HEC_SET_STATE_DEACTIVATE
ignore define CEC_OP_HEC_SET_STATE_ACTIVATE
ignore define CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION
ignore define CEC_MSG_CDC_HEC_NOTIFY_ALIVE
ignore define CEC_MSG_CDC_HEC_DISCOVER
ignore define CEC_MSG_CDC_HPD_SET_STATE
ignore define CEC_OP_HPD_STATE_CP_EDID_DISABLE
ignore define CEC_OP_HPD_STATE_CP_EDID_ENABLE
ignore define CEC_OP_HPD_STATE_CP_EDID_DISABLE_ENABLE
ignore define CEC_OP_HPD_STATE_EDID_DISABLE
ignore define CEC_OP_HPD_STATE_EDID_ENABLE
ignore define CEC_OP_HPD_STATE_EDID_DISABLE_ENABLE
ignore define CEC_MSG_CDC_HPD_REPORT_STATE
ignore define CEC_OP_HPD_ERROR_NONE
ignore define CEC_OP_HPD_ERROR_INITIATOR_NOT_CAPABLE
ignore define CEC_OP_HPD_ERROR_INITIATOR_WRONG_STATE
ignore define CEC_OP_HPD_ERROR_OTHER
ignore define CEC_OP_HPD_ERROR_NONE_NO_VIDEO
@@ -0,0 +1,109 @@
# -*- coding: utf-8; mode: python -*-
# SPDX-License-Identifier: GPL-2.0
project = 'Linux Media Subsystem Documentation'
# It is possible to run Sphinx in nickpick mode with:
nitpicky = True
# within nit-picking build, do not refer to any intersphinx object
intersphinx_mapping = {}
# In nickpick mode, it will complain about lots of missing references that
#
# 1) are just typedefs like: bool, __u32, etc;
# 2) It will complain for things like: enum, NULL;
# 3) It will complain for symbols that should be on different
# books (but currently aren't ported to ReST)
#
# The list below has a list of such symbols to be ignored in nitpick mode
#
nitpick_ignore = [
("c:func", "clock_gettime"),
("c:func", "close"),
("c:func", "container_of"),
("c:func", "copy_from_user"),
("c:func", "copy_to_user"),
("c:func", "determine_valid_ioctls"),
("c:func", "ERR_PTR"),
("c:func", "i2c_new_client_device"),
("c:func", "ioctl"),
("c:func", "IS_ERR"),
("c:func", "KERNEL_VERSION"),
("c:func", "mmap"),
("c:func", "open"),
("c:func", "pci_name"),
("c:func", "poll"),
("c:func", "PTR_ERR"),
("c:func", "read"),
("c:func", "release"),
("c:func", "set"),
("c:func", "struct fd_set"),
("c:func", "struct pollfd"),
("c:func", "usb_make_path"),
("c:func", "write"),
("c:type", "atomic_t"),
("c:type", "bool"),
("c:type", "boolean"),
("c:type", "buf_queue"),
("c:type", "device"),
("c:type", "device_driver"),
("c:type", "device_node"),
("c:type", "enum"),
("c:type", "fd"),
("c:type", "fd_set"),
("c:type", "file"),
("c:type", "i2c_adapter"),
("c:type", "i2c_board_info"),
("c:type", "i2c_client"),
("c:type", "int16_t"),
("c:type", "ktime_t"),
("c:type", "led_classdev_flash"),
("c:type", "list_head"),
("c:type", "lock_class_key"),
("c:type", "module"),
("c:type", "mutex"),
("c:type", "NULL"),
("c:type", "off_t"),
("c:type", "pci_dev"),
("c:type", "pdvbdev"),
("c:type", "poll_table"),
("c:type", "platform_device"),
("c:type", "pollfd"),
("c:type", "poll_table_struct"),
("c:type", "s32"),
("c:type", "s64"),
("c:type", "sd"),
("c:type", "size_t"),
("c:type", "spi_board_info"),
("c:type", "spi_device"),
("c:type", "spi_master"),
("c:type", "ssize_t"),
("c:type", "fb_fix_screeninfo"),
("c:type", "pollfd"),
("c:type", "timeval"),
("c:type", "video_capability"),
("c:type", "timeval"),
("c:type", "__u16"),
("c:type", "u16"),
("c:type", "__u32"),
("c:type", "u32"),
("c:type", "__u64"),
("c:type", "u64"),
("c:type", "u8"),
("c:type", "uint16_t"),
("c:type", "uint32_t"),
("c:type", "union"),
("c:type", "__user"),
("c:type", "usb_device"),
("c:type", "usb_interface"),
("c:type", "v4l2_std_id"),
("c:type", "video_system_t"),
("c:type", "vm_area_struct"),
# Opaque structures
("c:type", "v4l2_m2m_dev"),
]
@@ -0,0 +1,65 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
ASPEED video driver
===================
ASPEED Video Engine found on AST2400/2500/2600 SoC supports high performance
video compressions with a wide range of video quality and compression ratio
options. The adopted compressing algorithm is a modified JPEG algorithm.
There are 2 types of compressions in this IP.
* JPEG JFIF standard mode: for single frame and management compression
* ASPEED proprietary mode: for multi-frame and differential compression.
Support 2-pass (high quality) video compression scheme (Patent pending by
ASPEED). Provide visually lossless video compression quality or to reduce
the network average loading under intranet KVM applications.
VIDIOC_S_FMT can be used to choose which format you want. V4L2_PIX_FMT_JPEG
stands for JPEG JFIF standard mode; V4L2_PIX_FMT_AJPG stands for ASPEED
proprietary mode.
More details on the ASPEED video hardware operations can be found in
*chapter 6.2.16 KVM Video Driver* of SDK_User_Guide which available on
`github <https://github.com/AspeedTech-BMC/openbmc/releases/>`__.
The ASPEED video driver implements the following driver-specific control:
``V4L2_CID_ASPEED_HQ_MODE``
---------------------------
Enable/Disable ASPEED's High quality mode. This is a private control
that can be used to enable high quality for aspeed proprietary mode.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - ``(0)``
- ASPEED HQ mode is disabled.
* - ``(1)``
- ASPEED HQ mode is enabled.
``V4L2_CID_ASPEED_HQ_JPEG_QUALITY``
-----------------------------------
Define the quality of ASPEED's High quality mode. This is a private control
that can be used to decide compression quality if High quality mode enabled
. Higher the value, better the quality and bigger the size.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - ``(1)``
- minimum
* - ``(12)``
- maximum
* - ``(1)``
- step
* - ``(1)``
- default
**Copyright** |copy| 2022 ASPEED Technology Inc.
@@ -0,0 +1,106 @@
.. SPDX-License-Identifier: GPL-2.0
.. _media_using_camera_sensor_drivers:
Using camera sensor drivers
===========================
This section describes common practices for how the V4L2 sub-device interface is
used to control the camera sensor drivers.
You may also find :ref:`media_writing_camera_sensor_drivers` useful.
Sensor internal pipeline configuration
--------------------------------------
Camera sensors have an internal processing pipeline including cropping and
binning functionality. The sensor drivers belong to two distinct classes, freely
configurable and register list-based drivers, depending on how the driver
configures this functionality.
Freely configurable camera sensor drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Freely configurable camera sensor drivers expose the device's internal
processing pipeline as one or more sub-devices with different cropping and
scaling configurations. The output size of the device is the result of a series
of cropping and scaling operations from the device's pixel array's size.
An example of such a driver is the CCS driver.
Register list-based drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Register list-based drivers generally, instead of able to configure the device
they control based on user requests, are limited to a number of preset
configurations that combine a number of different parameters that on hardware
level are independent. How a driver picks such configuration is based on the
format set on a source pad at the end of the device's internal pipeline.
Most sensor drivers are implemented this way.
Frame interval configuration
----------------------------
There are two different methods for obtaining possibilities for different frame
intervals as well as configuring the frame interval. Which one to implement
depends on the type of the device.
Raw camera sensors
~~~~~~~~~~~~~~~~~~
Instead of a high level parameter such as frame interval, the frame interval is
a result of the configuration of a number of camera sensor implementation
specific parameters. Luckily, these parameters tend to be the same for more or
less all modern raw camera sensors.
The frame interval is calculated using the following equation::
frame interval = (analogue crop width + horizontal blanking) *
(analogue crop height + vertical blanking) / pixel rate
The formula is bus independent and is applicable for raw timing parameters on
large variety of devices beyond camera sensors. Devices that have no analogue
crop, use the full source image size, i.e. pixel array size.
Horizontal and vertical blanking are specified by ``V4L2_CID_HBLANK`` and
``V4L2_CID_VBLANK``, respectively. The unit of the ``V4L2_CID_HBLANK`` control
is pixels and the unit of the ``V4L2_CID_VBLANK`` is lines. The pixel rate in
the sensor's **pixel array** is specified by ``V4L2_CID_PIXEL_RATE`` in the same
sub-device. The unit of that control is pixels per second.
Register list-based drivers need to implement read-only sub-device nodes for the
purpose. Devices that are not register list based need these to configure the
device's internal processing pipeline.
The first entity in the linear pipeline is the pixel array. The pixel array may
be followed by other entities that are there to allow configuring binning,
skipping, scaling or digital crop, see :ref:`VIDIOC_SUBDEV_G_SELECTION
<VIDIOC_SUBDEV_G_SELECTION>`.
USB cameras etc. devices
~~~~~~~~~~~~~~~~~~~~~~~~
USB video class hardware, as well as many cameras offering a similar higher
level interface natively, generally use the concept of frame interval (or frame
rate) on device level in firmware or hardware. This means lower level controls
implemented by raw cameras may not be used on uAPI (or even kAPI) to control the
frame interval on these devices.
Rotation, orientation and flipping
----------------------------------
Some systems have the camera sensor mounted upside down compared to its natural
mounting rotation. In such cases, drivers shall expose the information to
userspace with the :ref:`V4L2_CID_CAMERA_SENSOR_ROTATION
<v4l2-camera-sensor-rotation>` control.
Sensor drivers shall also report the sensor's mounting orientation with the
:ref:`V4L2_CID_CAMERA_SENSOR_ORIENTATION <v4l2-camera-sensor-orientation>`.
Sensor drivers that have any vertical or horizontal flips embedded in the
register programming sequences shall initialize the :ref:`V4L2_CID_HFLIP
<v4l2-cid-hflip>` and :ref:`V4L2_CID_VFLIP <v4l2-cid-vflip>` controls with the
values programmed by the register sequences. The default values of these
controls shall be 0 (disabled). Especially these controls shall not be inverted,
independently of the sensor's mounting rotation.
@@ -0,0 +1,114 @@
.. SPDX-License-Identifier: GPL-2.0-only
.. include:: <isonum.txt>
.. _media-ccs-uapi:
MIPI CCS camera sensor driver
=============================
The MIPI CCS camera sensor driver is a generic driver for `MIPI CCS
<https://www.mipi.org/specifications/camera-command-set>`_ compliant
camera sensors. It exposes three sub-devices representing the pixel array,
the binner and the scaler.
As the capabilities of individual devices vary, the driver exposes
interfaces based on the capabilities that exist in hardware.
Also see :ref:`the CCS driver kernel documentation <media-ccs-driver>`.
Pixel Array sub-device
----------------------
The pixel array sub-device represents the camera sensor's pixel matrix, as well
as analogue crop functionality present in many compliant devices. The analogue
crop is configured using the ``V4L2_SEL_TGT_CROP`` on the source pad (0) of the
entity. The size of the pixel matrix can be obtained by getting the
``V4L2_SEL_TGT_NATIVE_SIZE`` target.
Binner
------
The binner sub-device represents the binning functionality on the sensor. For
that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the
sink pad (0).
Additionally, if a device has no scaler or digital crop functionality, the
source pad (1) exposes another digital crop selection rectangle that can only
crop at the end of the lines and frames.
Scaler
------
The scaler sub-device represents the digital crop and scaling functionality of
the sensor. The V4L2 selection target ``V4L2_SEL_TGT_CROP`` is used to
configure the digital crop on the sink pad (0) when digital crop is supported.
Scaling is configured using selection target ``V4L2_SEL_TGT_COMPOSE`` on the
sink pad (0) as well.
Additionally, if the scaler sub-device exists, its source pad (1) exposes
another digital crop selection rectangle that can only crop at the end of the
lines and frames.
Digital and analogue crop
-------------------------
Digital crop functionality is referred to as cropping that effectively works by
dropping some data on the floor. Analogue crop, on the other hand, means that
the cropped information is never retrieved. In case of camera sensors, the
analogue data is never read from the pixel matrix that are outside the
configured selection rectangle that designates crop. The difference has an
effect in device timing and likely also in power consumption.
Private controls
----------------
The MIPI CCS driver implements a number of private controls under
``V4L2_CID_USER_BASE_CCS`` to control the MIPI CCS compliant camera sensors.
Analogue gain model
~~~~~~~~~~~~~~~~~~~
The CCS defines an analogue gain model where the gain can be calculated using
the following formula:
gain = m0 * x + c0 / (m1 * x + c1)
Either m0 or c0 will be zero. The constants that are device specific, can be
obtained from the following controls:
V4L2_CID_CCS_ANALOGUE_GAIN_M0
V4L2_CID_CCS_ANALOGUE_GAIN_M1
V4L2_CID_CCS_ANALOGUE_GAIN_C0
V4L2_CID_CCS_ANALOGUE_GAIN_C1
The analogue gain (``x`` in the formula) is controlled through
``V4L2_CID_ANALOGUE_GAIN`` in this case.
Alternate analogue gain model
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The CCS defines another analogue gain model called alternate analogue gain. In
this case, the formula to calculate actual gain consists of linear and
exponential parts:
gain = linear * 2 ^ exponent
The ``linear`` and ``exponent`` factors can be set using the
``V4L2_CID_CCS_ANALOGUE_LINEAR_GAIN`` and
``V4L2_CID_CCS_ANALOGUE_EXPONENTIAL_GAIN`` controls, respectively
Shading correction
~~~~~~~~~~~~~~~~~~
The CCS standard supports lens shading correction. The feature can be controlled
using ``V4L2_CID_CCS_SHADING_CORRECTION``. Additionally, the luminance
correction level may be changed using
``V4L2_CID_CCS_LUMINANCE_CORRECTION_LEVEL``, where value 0 indicates no
correction and 128 indicates correcting the luminance in corners to 10 % less
than in the centre.
Shading correction needs to be enabled for luminance correction level to have an
effect.
**Copyright** |copy| 2020 Intel Corporation
@@ -0,0 +1,177 @@
.. SPDX-License-Identifier: GPL-2.0
The cx2341x driver
==================
Non-compressed file format
--------------------------
The cx23416 can produce (and the cx23415 can also read) raw YUV output. The
format of a YUV frame is 16x16 linear tiled NV12 (V4L2_PIX_FMT_NV12_16L16).
The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per
four pixels.
The data is encoded as two macroblock planes, the first containing the Y
values, the second containing UV macroblocks.
The Y plane is divided into blocks of 16x16 pixels from left to right
and from top to bottom. Each block is transmitted in turn, line-by-line.
So the first 16 bytes are the first line of the top-left block, the
second 16 bytes are the second line of the top-left block, etc. After
transmitting this block the first line of the block on the right to the
first block is transmitted, etc.
The UV plane is divided into blocks of 16x8 UV values going from left
to right, top to bottom. Each block is transmitted in turn, line-by-line.
So the first 16 bytes are the first line of the top-left block and
contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the
second line of 8 UV pairs of the top-left block, etc. After transmitting
this block the first line of the block on the right to the first block is
transmitted, etc.
The code below is given as an example on how to convert V4L2_PIX_FMT_NV12_16L16
to separate Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
The width of a frame is always 720 pixels, regardless of the actual specified
width.
If the height is not a multiple of 32 lines, then the captured video is
missing macroblocks at the end and is unusable. So the height must be a
multiple of 32.
Raw format c example
~~~~~~~~~~~~~~~~~~~~
.. code-block:: c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static unsigned char frame[576*720*3/2];
static unsigned char framey[576*720];
static unsigned char frameu[576*720 / 4];
static unsigned char framev[576*720 / 4];
static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h)
{
unsigned int y, x, i;
// descramble Y plane
// dstride = 720 = w
// The Y plane is divided into blocks of 16x16 pixels
// Each block in transmitted in turn, line-by-line.
for (y = 0; y < h; y += 16) {
for (x = 0; x < w; x += 16) {
for (i = 0; i < 16; i++) {
memcpy(dst + x + (y + i) * dstride, src, 16);
src += 16;
}
}
}
}
static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h)
{
unsigned int y, x, i;
// descramble U/V plane
// dstride = 720 / 2 = w
// The U/V values are interlaced (UVUV...).
// Again, the UV plane is divided into blocks of 16x16 UV values.
// Each block in transmitted in turn, line-by-line.
for (y = 0; y < h; y += 16) {
for (x = 0; x < w; x += 8) {
for (i = 0; i < 16; i++) {
int idx = x + (y + i) * dstride;
dstu[idx+0] = src[0]; dstv[idx+0] = src[1];
dstu[idx+1] = src[2]; dstv[idx+1] = src[3];
dstu[idx+2] = src[4]; dstv[idx+2] = src[5];
dstu[idx+3] = src[6]; dstv[idx+3] = src[7];
dstu[idx+4] = src[8]; dstv[idx+4] = src[9];
dstu[idx+5] = src[10]; dstv[idx+5] = src[11];
dstu[idx+6] = src[12]; dstv[idx+6] = src[13];
dstu[idx+7] = src[14]; dstv[idx+7] = src[15];
src += 16;
}
}
}
}
/*************************************************************************/
int main(int argc, char **argv)
{
FILE *fin;
int i;
if (argc == 1) fin = stdin;
else fin = fopen(argv[1], "r");
if (fin == NULL) {
fprintf(stderr, "cannot open input\n");
exit(-1);
}
while (fread(frame, sizeof(frame), 1, fin) == 1) {
de_macro_y(framey, frame, 720, 720, 576);
de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2);
fwrite(framey, sizeof(framey), 1, stdout);
fwrite(framev, sizeof(framev), 1, stdout);
fwrite(frameu, sizeof(frameu), 1, stdout);
}
fclose(fin);
return 0;
}
Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data
---------------------------------------------------------
Author: Hans Verkuil <hverkuil@kernel.org>
This section describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data
embedded in an MPEG-2 program stream. This format is in part dictated by some
hardware limitations of the ivtv driver (the driver for the Conexant cx23415/6
chips), in particular a maximum size for the VBI data. Anything longer is cut
off when the MPEG stream is played back through the cx23415.
The advantage of this format is it is very compact and that all VBI data for
all lines can be stored while still fitting within the maximum allowed size.
The stream ID of the VBI data is 0xBD. The maximum size of the embedded data is
4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte
header and a 42 bytes payload each. Anything beyond this limit is cut off by
the cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits
for a bitmask determining which lines are captured and 4 bytes for a magic cookie,
signifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data.
If all lines are used, then there is no longer room for the bitmask. To solve this
two different magic numbers were introduced:
'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first
unsigned long denote which lines of the first field are captured. Bits 18-31 of
the first unsigned long and bits 0-3 of the second unsigned long are used for the
second field.
'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly
implies that the bitmasks are 0xffffffff and 0xf.
After these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the
captured VBI lines start:
For each line the least significant 4 bits of the first byte contain the data type.
Possible values are shown in the table below. The payload is in the following 42
bytes.
Here is the list of possible data types:
.. code-block:: c
#define IVTV_SLICED_TYPE_TELETEXT 0x1 // Teletext (uses lines 6-22 for PAL)
#define IVTV_SLICED_TYPE_CC 0x4 // Closed Captions (line 21 NTSC)
#define IVTV_SLICED_TYPE_WSS 0x5 // Wide Screen Signal (line 23 PAL)
#define IVTV_SLICED_TYPE_VPS 0x7 // Video Programming System (PAL) (line 16)
@@ -0,0 +1,84 @@
.. SPDX-License-Identifier: GPL-2.0
DW100 dewarp driver
===================
The Vivante DW100 Dewarp Processor IP core found on i.MX8MP SoC applies a
programmable geometrical transformation on the input image to correct distortion
introduced by lenses.
The transformation function is exposed by the hardware as a grid map with 16x16
pixel macroblocks indexed using X, Y vertex coordinates.
::
Image width
<--------------------------------------->
^ .-------.-------.-------.-------.-------.
| | 16x16 | | | | |
I | | pixel | | | | |
m | | block | | | | |
a | .-------.-------.-------.-------.-------.
g | | | | | | |
e | | | | | | |
| | | | | | |
h | .-------.-------.-------.-------.-------.
e | | | | | | |
i | | | | | | |
g | | | | | | |
h | .-------.-------.-------.-------.-------.
t | | | | | | |
| | | | | | |
| | | | | | |
v '-------'-------'-------'-------'-------'
Grid of Image Blocks for Dewarping Map
Each x, y coordinate register uses 16 bits to record the coordinate address in
an unsigned 12.4 fixed point format (UQ12.4).
::
.----------------------.--------..----------------------.--------.
| 31~20 | 19~16 || 15~4 | 3~0 |
| (integer) | (frac) || (integer) | (frac) |
'----------------------'--------''----------------------'--------'
<-------------------------------><------------------------------->
Y coordinate X coordinate
Remap Register Layout
The dewarping map is set from applications using the
V4L2_CID_DW100_DEWARPING_16x16_VERTEX_MAP control. The control contains
an array of u32 values storing (x, y) destination coordinates for each
vertex of the grid. The x coordinate is stored in the 16 LSBs and the y
coordinate in the 16 MSBs.
The number of elements in the array must match the image size:
.. code-block:: C
elems = (DIV_ROUND_UP(width, 16) + 1) * (DIV_ROUND_UP(height, 16) + 1);
If the control has not been set by the application, the driver uses an identity
map.
More details on the DW100 hardware operations can be found in
*chapter 13.15 DeWarp* of IMX8MP_ reference manual.
The Vivante DW100 m2m driver implements the following driver-specific control:
``V4L2_CID_DW100_DEWARPING_16x16_VERTEX_MAP (__u32 array)``
Specifies to DW100 driver its dewarping map (aka LUT) blob as described in
*chapter 13.15.2.3 Dewarping Remap* of IMX8MP_ reference manual as an U32
dynamic array. The image is divided into many small 16x16 blocks. If the
width/height of the image is not divisible by 16, the size of the
rightmost/bottommost block is the remainder. The dewarping map only saves
the vertex coordinates of the block. The dewarping grid map is comprised of
vertex coordinates for x and y. Each x, y coordinate register uses 16 bits
(UQ12.4) to record the coordinate address, with the Y coordinate in the
upper bits and X in the lower bits. The driver modifies the dimensions of
this control when the sink format is changed, to reflect the new input
resolution.
.. _IMX8MP: https://www.nxp.com/webapp/Download?colCode=IMX8MPRM
@@ -0,0 +1,125 @@
.. SPDX-License-Identifier: GPL-2.0
=========================
i.MX Video Capture Driver
=========================
Events
======
.. _imx_api_ipuX_csiY:
ipuX_csiY
---------
This subdev can generate the following event when enabling the second
IDMAC source pad:
- V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR
The user application can subscribe to this event from the ipuX_csiY
subdev node. This event is generated by the Frame Interval Monitor
(see below for more on the FIM).
Controls
========
.. _imx_api_FIM:
Frame Interval Monitor in ipuX_csiY
-----------------------------------
The adv718x decoders can occasionally send corrupt fields during
NTSC/PAL signal re-sync (too little or too many video lines). When
this happens, the IPU triggers a mechanism to re-establish vertical
sync by adding 1 dummy line every frame, which causes a rolling effect
from image to image, and can last a long time before a stable image is
recovered. Or sometimes the mechanism doesn't work at all, causing a
permanent split image (one frame contains lines from two consecutive
captured images).
From experiment it was found that during image rolling, the frame
intervals (elapsed time between two EOF's) drop below the nominal
value for the current standard, by about one frame time (60 usec),
and remain at that value until rolling stops.
While the reason for this observation isn't known (the IPU dummy
line mechanism should show an increase in the intervals by 1 line
time every frame, not a fixed value), we can use it to detect the
corrupt fields using a frame interval monitor. If the FIM detects a
bad frame interval, the ipuX_csiY subdev will send the event
V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR. Userland can register with
the FIM event notification on the ipuX_csiY subdev device node.
Userland can issue a streaming restart when this event is received
to correct the rolling/split image.
The ipuX_csiY subdev includes custom controls to tweak some dials for
FIM. If one of these controls is changed during streaming, the FIM will
be reset and will continue at the new settings.
- V4L2_CID_IMX_FIM_ENABLE
Enable/disable the FIM.
- V4L2_CID_IMX_FIM_NUM
How many frame interval measurements to average before comparing against
the nominal frame interval reported by the sensor. This can reduce noise
caused by interrupt latency.
- V4L2_CID_IMX_FIM_TOLERANCE_MIN
If the averaged intervals fall outside nominal by this amount, in
microseconds, the V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR event is sent.
- V4L2_CID_IMX_FIM_TOLERANCE_MAX
If any intervals are higher than this value, those samples are
discarded and do not enter into the average. This can be used to
discard really high interval errors that might be due to interrupt
latency from high system load.
- V4L2_CID_IMX_FIM_NUM_SKIP
How many frames to skip after a FIM reset or stream restart before
FIM begins to average intervals.
- V4L2_CID_IMX_FIM_ICAP_CHANNEL / V4L2_CID_IMX_FIM_ICAP_EDGE
These controls will configure an input capture channel as the method
for measuring frame intervals. This is superior to the default method
of measuring frame intervals via EOF interrupt, since it is not subject
to uncertainty errors introduced by interrupt latency.
Input capture requires hardware support. A VSYNC signal must be routed
to one of the i.MX6 input capture channel pads.
V4L2_CID_IMX_FIM_ICAP_CHANNEL configures which i.MX6 input capture
channel to use. This must be 0 or 1.
V4L2_CID_IMX_FIM_ICAP_EDGE configures which signal edge will trigger
input capture events. By default the input capture method is disabled
with a value of IRQ_TYPE_NONE. Set this control to IRQ_TYPE_EDGE_RISING,
IRQ_TYPE_EDGE_FALLING, or IRQ_TYPE_EDGE_BOTH to enable input capture,
triggered on the given signal edge(s).
When input capture is disabled, frame intervals will be measured via
EOF interrupt.
File list
---------
drivers/staging/media/imx/
include/media/imx.h
include/linux/imx-media.h
Authors
-------
- Steve Longerbeam <steve_longerbeam@mentor.com>
- Philipp Zabel <kernel@pengutronix.de>
- Russell King <linux@armlinux.org.uk>
Copyright (C) 2012-2017 Mentor Graphics Inc.
@@ -0,0 +1,41 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
.. _v4l-drivers_uapi:
################################################
Video4Linux (V4L) driver-specific documentation
################################################
**Copyright** |copy| 1999-2016 : LinuxTV Developers
This documentation is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
For more details see the file COPYING in the source distribution of Linux.
.. toctree::
:caption: Table of Contents
:maxdepth: 5
:numbered:
aspeed-video
camera-sensor
ccs
cx2341x-uapi
dw100
imx-uapi
mali-c55
max2175
npcm-video
omap3isp-uapi
thp7312
uvcvideo
vgxy61
@@ -0,0 +1,55 @@
.. SPDX-License-Identifier: GPL-2.0-only
Arm Mali-C55 ISP driver
=======================
The Arm Mali-C55 ISP driver implements a single driver-specific control:
``V4L2_CID_MALI_C55_CAPABILITIES (bitmask)``
Detail the capabilities of the ISP by giving detail about the fitted blocks.
.. flat-table:: Bitmask meaning definitions
:header-rows: 1
:widths: 2 4 8
* - Bit
- Macro
- Meaning
* - 0
- MALI_C55_PONG
- Pong configuration space is fitted in the ISP
* - 1
- MALI_C55_WDR
- WDR Framestitch, offset and gain is fitted in the ISP
* - 2
- MALI_C55_COMPRESSION
- Temper compression is fitted in the ISP
* - 3
- MALI_C55_TEMPER
- Temper is fitted in the ISP
* - 4
- MALI_C55_SINTER_LITE
- Sinter Lite is fitted in the ISP instead of the full Sinter version
* - 5
- MALI_C55_SINTER
- Sinter is fitted in the ISP
* - 6
- MALI_C55_IRIDIX_LTM
- Iridix local tone mappine is fitted in the ISP
* - 7
- MALI_C55_IRIDIX_GTM
- Iridix global tone mapping is fitted in the ISP
* - 8
- MALI_C55_CNR
- Colour noise reduction is fitted in the ISP
* - 9
- MALI_C55_FRSCALER
- The full resolution pipe scaler is fitted in the ISP
* - 10
- MALI_C55_DS_PIPE
- The downscale pipe is fitted in the ISP
The Mali-C55 ISP can be configured in a number of ways to include or exclude
blocks which may not be necessary. This control provides a way for the
driver to communicate to userspace which of the blocks are fitted in the
design.
@@ -0,0 +1,64 @@
.. SPDX-License-Identifier: GPL-2.0
Maxim Integrated MAX2175 RF to bits tuner driver
================================================
The MAX2175 driver implements the following driver-specific controls:
``V4L2_CID_MAX2175_I2S_ENABLE``
-------------------------------
Enable/Disable I2S output of the tuner. This is a private control
that can be accessed only using the subdev interface.
Refer to Documentation/driver-api/media/v4l2-controls.rst for more details.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - ``(0)``
- I2S output is disabled.
* - ``(1)``
- I2S output is enabled.
``V4L2_CID_MAX2175_HSLS``
-------------------------
The high-side/low-side (HSLS) control of the tuner for a given band.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - ``(0)``
- The LO frequency position is below the desired frequency.
* - ``(1)``
- The LO frequency position is above the desired frequency.
``V4L2_CID_MAX2175_RX_MODE (menu)``
-----------------------------------
The Rx mode controls a number of preset parameters of the tuner like
sample clock (sck), sampling rate etc. These multiple settings are
provided under one single label called Rx mode in the datasheet. The
list below shows the supported modes with a brief description.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - ``"Europe modes"``
* - ``"FM 1.2" (0)``
- This configures FM band with a sample rate of 0.512 million
samples/sec with a 10.24 MHz sck.
* - ``"DAB 1.2" (1)``
- This configures VHF band with a sample rate of 2.048 million
samples/sec with a 32.768 MHz sck.
* - ``"North America modes"``
* - ``"FM 1.0" (0)``
- This configures FM band with a sample rate of 0.7441875 million
samples/sec with a 14.88375 MHz sck.
* - ``"DAB 1.2" (1)``
- This configures FM band with a sample rate of 0.372 million
samples/sec with a 7.441875 MHz sck.
@@ -0,0 +1,66 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
NPCM video driver
=================
This driver is used to control the Video Capture/Differentiation (VCD) engine
and Encoding Compression Engine (ECE) present on Nuvoton NPCM SoCs. The VCD can
capture a frame from digital video input and compare two frames in memory, and
the ECE can compress the frame data into HEXTILE format.
Driver-specific Controls
------------------------
V4L2_CID_NPCM_CAPTURE_MODE
~~~~~~~~~~~~~~~~~~~~~~~~~~
The VCD engine supports two modes:
- COMPLETE mode:
Capture the next complete frame into memory.
- DIFF mode:
Compare the incoming frame with the frame stored in memory, and updates the
differentiated frame in memory.
Application can use ``V4L2_CID_NPCM_CAPTURE_MODE`` control to set the VCD mode
with different control values (enum v4l2_npcm_capture_mode):
- ``V4L2_NPCM_CAPTURE_MODE_COMPLETE``: will set VCD to COMPLETE mode.
- ``V4L2_NPCM_CAPTURE_MODE_DIFF``: will set VCD to DIFF mode.
V4L2_CID_NPCM_RECT_COUNT
~~~~~~~~~~~~~~~~~~~~~~~~
If using V4L2_PIX_FMT_HEXTILE format, VCD will capture frame data and then ECE
will compress the data into HEXTILE rectangles and store them in V4L2 video
buffer with the layout defined in Remote Framebuffer Protocol:
::
(RFC 6143, https://www.rfc-editor.org/rfc/rfc6143.html#section-7.6.1)
+--------------+--------------+-------------------+
| No. of bytes | Type [Value] | Description |
+--------------+--------------+-------------------+
| 2 | U16 | x-position |
| 2 | U16 | y-position |
| 2 | U16 | width |
| 2 | U16 | height |
| 4 | S32 | encoding-type (5) |
+--------------+--------------+-------------------+
| HEXTILE rectangle data |
+-------------------------------------------------+
Application can get the video buffer through VIDIOC_DQBUF, and followed by
calling ``V4L2_CID_NPCM_RECT_COUNT`` control to get the number of HEXTILE
rectangles in this buffer.
References
----------
include/uapi/linux/npcm-video.h
**Copyright** |copy| 2022 Nuvoton Technologies
@@ -0,0 +1,208 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
OMAP 3 Image Signal Processor (ISP) driver
==========================================
Copyright |copy| 2010 Nokia Corporation
Copyright |copy| 2009 Texas Instruments, Inc.
Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
Sakari Ailus <sakari.ailus@iki.fi>, David Cohen <dacohen@gmail.com>
Events
------
The OMAP 3 ISP driver does support the V4L2 event interface on CCDC and
statistics (AEWB, AF and histogram) subdevs.
The CCDC subdev produces V4L2_EVENT_FRAME_SYNC type event on HS_VS
interrupt which is used to signal frame start. Earlier version of this
driver used V4L2_EVENT_OMAP3ISP_HS_VS for this purpose. The event is
triggered exactly when the reception of the first line of the frame starts
in the CCDC module. The event can be subscribed on the CCDC subdev.
(When using parallel interface one must pay account to correct configuration
of the VS signal polarity. This is automatically correct when using the serial
receivers.)
Each of the statistics subdevs is able to produce events. An event is
generated whenever a statistics buffer can be dequeued by a user space
application using the VIDIOC_OMAP3ISP_STAT_REQ IOCTL. The events available
are:
- V4L2_EVENT_OMAP3ISP_AEWB
- V4L2_EVENT_OMAP3ISP_AF
- V4L2_EVENT_OMAP3ISP_HIST
The type of the event data is struct omap3isp_stat_event_status for these
ioctls. If there is an error calculating the statistics, there will be an
event as usual, but no related statistics buffer. In this case
omap3isp_stat_event_status.buf_err is set to non-zero.
Private IOCTLs
--------------
The OMAP 3 ISP driver supports standard V4L2 IOCTLs and controls where
possible and practical. Much of the functions provided by the ISP, however,
does not fall under the standard IOCTLs --- gamma tables and configuration of
statistics collection are examples of such.
In general, there is a private ioctl for configuring each of the blocks
containing hardware-dependent functions.
The following private IOCTLs are supported:
- VIDIOC_OMAP3ISP_CCDC_CFG
- VIDIOC_OMAP3ISP_PRV_CFG
- VIDIOC_OMAP3ISP_AEWB_CFG
- VIDIOC_OMAP3ISP_HIST_CFG
- VIDIOC_OMAP3ISP_AF_CFG
- VIDIOC_OMAP3ISP_STAT_REQ
- VIDIOC_OMAP3ISP_STAT_EN
The parameter structures used by these ioctls are described in
include/linux/omap3isp.h. The detailed functions of the ISP itself related to
a given ISP block is described in the Technical Reference Manuals (TRMs) ---
see the end of the document for those.
While it is possible to use the ISP driver without any use of these private
IOCTLs it is not possible to obtain optimal image quality this way. The AEWB,
AF and histogram modules cannot be used without configuring them using the
appropriate private IOCTLs.
CCDC and preview block IOCTLs
-----------------------------
The VIDIOC_OMAP3ISP_CCDC_CFG and VIDIOC_OMAP3ISP_PRV_CFG IOCTLs are used to
configure, enable and disable functions in the CCDC and preview blocks,
respectively. Both IOCTLs control several functions in the blocks they
control. VIDIOC_OMAP3ISP_CCDC_CFG IOCTL accepts a pointer to struct
omap3isp_ccdc_update_config as its argument. Similarly VIDIOC_OMAP3ISP_PRV_CFG
accepts a pointer to struct omap3isp_prev_update_config. The definition of
both structures is available in [#]_.
The update field in the structures tells whether to update the configuration
for the specific function and the flag tells whether to enable or disable the
function.
The update and flag bit masks accept the following values. Each separate
functions in the CCDC and preview blocks is associated with a flag (either
disable or enable; part of the flag field in the structure) and a pointer to
configuration data for the function.
Valid values for the update and flag fields are listed here for
VIDIOC_OMAP3ISP_CCDC_CFG. Values may be or'ed to configure more than one
function in the same IOCTL call.
- OMAP3ISP_CCDC_ALAW
- OMAP3ISP_CCDC_LPF
- OMAP3ISP_CCDC_BLCLAMP
- OMAP3ISP_CCDC_BCOMP
- OMAP3ISP_CCDC_FPC
- OMAP3ISP_CCDC_CULL
- OMAP3ISP_CCDC_CONFIG_LSC
- OMAP3ISP_CCDC_TBL_LSC
The corresponding values for the VIDIOC_OMAP3ISP_PRV_CFG are here:
- OMAP3ISP_PREV_LUMAENH
- OMAP3ISP_PREV_INVALAW
- OMAP3ISP_PREV_HRZ_MED
- OMAP3ISP_PREV_CFA
- OMAP3ISP_PREV_CHROMA_SUPP
- OMAP3ISP_PREV_WB
- OMAP3ISP_PREV_BLKADJ
- OMAP3ISP_PREV_RGB2RGB
- OMAP3ISP_PREV_COLOR_CONV
- OMAP3ISP_PREV_YC_LIMIT
- OMAP3ISP_PREV_DEFECT_COR
- OMAP3ISP_PREV_GAMMABYPASS
- OMAP3ISP_PREV_DRK_FRM_CAPTURE
- OMAP3ISP_PREV_DRK_FRM_SUBTRACT
- OMAP3ISP_PREV_LENS_SHADING
- OMAP3ISP_PREV_NF
- OMAP3ISP_PREV_GAMMA
The associated configuration pointer for the function may not be NULL when
enabling the function. When disabling a function the configuration pointer is
ignored.
Statistic blocks IOCTLs
-----------------------
The statistics subdevs do offer more dynamic configuration options than the
other subdevs. They can be enabled, disable and reconfigured when the pipeline
is in streaming state.
The statistics blocks always get the input image data from the CCDC (as the
histogram memory read isn't implemented). The statistics are dequeueable by
the user from the statistics subdev nodes using private IOCTLs.
The private IOCTLs offered by the AEWB, AF and histogram subdevs are heavily
reflected by the register level interface offered by the ISP hardware. There
are aspects that are purely related to the driver implementation and these are
discussed next.
VIDIOC_OMAP3ISP_STAT_EN
-----------------------
This private IOCTL enables/disables a statistic module. If this request is
done before streaming, it will take effect as soon as the pipeline starts to
stream. If the pipeline is already streaming, it will take effect as soon as
the CCDC becomes idle.
VIDIOC_OMAP3ISP_AEWB_CFG, VIDIOC_OMAP3ISP_HIST_CFG and VIDIOC_OMAP3ISP_AF_CFG
-----------------------------------------------------------------------------
Those IOCTLs are used to configure the modules. They require user applications
to have an in-depth knowledge of the hardware. Most of the fields explanation
can be found on OMAP's TRMs. The two following fields common to all the above
configure private IOCTLs require explanation for better understanding as they
are not part of the TRM.
omap3isp_[h3a_af/h3a_aewb/hist]\_config.buf_size:
The modules handle their buffers internally. The necessary buffer size for the
module's data output depends on the requested configuration. Although the
driver supports reconfiguration while streaming, it does not support a
reconfiguration which requires bigger buffer size than what is already
internally allocated if the module is enabled. It will return -EBUSY on this
case. In order to avoid such condition, either disable/reconfigure/enable the
module or request the necessary buffer size during the first configuration
while the module is disabled.
The internal buffer size allocation considers the requested configuration's
minimum buffer size and the value set on buf_size field. If buf_size field is
out of [minimum, maximum] buffer size range, it's clamped to fit in there.
The driver then selects the biggest value. The corrected buf_size value is
written back to user application.
omap3isp_[h3a_af/h3a_aewb/hist]\_config.config_counter:
As the configuration doesn't take effect synchronously to the request, the
driver must provide a way to track this information to provide more accurate
data. After a configuration is requested, the config_counter returned to user
space application will be an unique value associated to that request. When
user application receives an event for buffer availability or when a new
buffer is requested, this config_counter is used to match a buffer data and a
configuration.
VIDIOC_OMAP3ISP_STAT_REQ
------------------------
Send to user space the oldest data available in the internal buffer queue and
discards such buffer afterwards. The field omap3isp_stat_data.frame_number
matches with the video buffer's field_count.
References
----------
.. [#] include/linux/omap3isp.h
@@ -0,0 +1,39 @@
.. SPDX-License-Identifier: GPL-2.0-only
THine THP7312 ISP driver
========================
The THP7312 driver implements the following driver-specific controls:
``V4L2_CID_THP7312_LOW_LIGHT_COMPENSATION``
Enable/Disable auto-adjustment, based on lighting conditions, of the frame
rate when auto-exposure is enabled.
``V4L2_CID_THP7312_AUTO_FOCUS_METHOD``
Set method of auto-focus. Only takes effect when auto-focus is enabled.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - ``0``
- Contrast-based auto-focus
* - ``1``
- PDAF
* - ``2``
- Hybrid of contrast-based and PDAF
Supported values for the control depend on the camera sensor module
connected to the THP7312. If the module doesn't have a focus lens actuator,
this control will not be exposed by the THP7312 driver. If the module has a
controllable focus lens but the sensor doesn't support PDAF, only the
contrast-based auto-focus value will be valid. Otherwise all values for the
controls will be supported.
``V4L2_CID_THP7312_NOISE_REDUCTION_AUTO``
Enable/Disable auto noise reduction.
``V4L2_CID_THP7312_NOISE_REDUCTION_ABSOLUTE``
Set the noise reduction strength, where 0 is the weakest and 10 is the
strongest.
@@ -0,0 +1,323 @@
.. SPDX-License-Identifier: GPL-2.0
The Linux USB Video Class (UVC) driver
======================================
This file documents some driver-specific aspects of the UVC driver, such as
driver-specific ioctls and implementation notes.
Questions and remarks can be sent to the Linux UVC development mailing list at
linux-media@vger.kernel.org.
Extension Unit (XU) support
---------------------------
Introduction
~~~~~~~~~~~~
The UVC specification allows for vendor-specific extensions through extension
units (XUs). The Linux UVC driver supports extension unit controls (XU controls)
through two separate mechanisms:
- through mappings of XU controls to V4L2 controls
- through a driver-specific ioctl interface
The first one allows generic V4L2 applications to use XU controls by mapping
certain XU controls onto V4L2 controls, which then show up during ordinary
control enumeration.
The second mechanism requires uvcvideo-specific knowledge for the application to
access XU controls but exposes the entire UVC XU concept to user space for
maximum flexibility.
Both mechanisms complement each other and are described in more detail below.
Control mappings
~~~~~~~~~~~~~~~~
The UVC driver provides an API for user space applications to define so-called
control mappings at runtime. These allow for individual XU controls or byte
ranges thereof to be mapped to new V4L2 controls. Such controls appear and
function exactly like normal V4L2 controls (i.e. the stock controls, such as
brightness, contrast, etc.). However, reading or writing of such a V4L2 controls
triggers a read or write of the associated XU control.
The ioctl used to create these control mappings is called UVCIOC_CTRL_MAP.
Previous driver versions (before 0.2.0) required another ioctl to be used
beforehand (UVCIOC_CTRL_ADD) to pass XU control information to the UVC driver.
This is no longer necessary as newer uvcvideo versions query the information
directly from the device.
For details on the UVCIOC_CTRL_MAP ioctl please refer to the section titled
"IOCTL reference" below.
3. Driver specific XU control interface
For applications that need to access XU controls directly, e.g. for testing
purposes, firmware upload, or accessing binary controls, a second mechanism to
access XU controls is provided in the form of a driver-specific ioctl, namely
UVCIOC_CTRL_QUERY.
A call to this ioctl allows applications to send queries to the UVC driver that
directly map to the low-level UVC control requests.
In order to make such a request the UVC unit ID of the control's extension unit
and the control selector need to be known. This information either needs to be
hardcoded in the application or queried using other ways such as by parsing the
UVC descriptor or, if available, using the media controller API to enumerate a
device's entities.
Unless the control size is already known it is necessary to first make a
UVC_GET_LEN requests in order to be able to allocate a sufficiently large buffer
and set the buffer size to the correct value. Similarly, to find out whether
UVC_GET_CUR or UVC_SET_CUR are valid requests for a given control, a
UVC_GET_INFO request should be made. The bits 0 (GET supported) and 1 (SET
supported) of the resulting byte indicate which requests are valid.
With the addition of the UVCIOC_CTRL_QUERY ioctl the UVCIOC_CTRL_GET and
UVCIOC_CTRL_SET ioctls have become obsolete since their functionality is a
subset of the former ioctl. For the time being they are still supported but
application developers are encouraged to use UVCIOC_CTRL_QUERY instead.
For details on the UVCIOC_CTRL_QUERY ioctl please refer to the section titled
"IOCTL reference" below.
Security
~~~~~~~~
The API doesn't currently provide a fine-grained access control facility. The
UVCIOC_CTRL_ADD and UVCIOC_CTRL_MAP ioctls require super user permissions.
Suggestions on how to improve this are welcome.
Debugging
~~~~~~~~~
In order to debug problems related to XU controls or controls in general it is
recommended to enable the UVC_TRACE_CONTROL bit in the module parameter 'trace'.
This causes extra output to be written into the system log.
IOCTL reference
~~~~~~~~~~~~~~~
UVCIOC_CTRL_MAP - Map a UVC control to a V4L2 control
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**This IOCTL is deprecated and will be eventually removed**
Argument: struct uvc_xu_control_mapping
**Description**:
This ioctl creates a mapping between a UVC control or part of a UVC
control and a V4L2 control. Once mappings are defined, userspace
applications can access vendor-defined UVC control through the V4L2
control API.
To create a mapping, applications fill the uvc_xu_control_mapping
structure with information about an existing UVC control defined with
UVCIOC_CTRL_ADD and a new V4L2 control.
A UVC control can be mapped to several V4L2 controls. For instance,
a UVC pan/tilt control could be mapped to separate pan and tilt V4L2
controls. The UVC control is divided into non overlapping fields using
the 'size' and 'offset' fields and are then independently mapped to
V4L2 control.
For signed integer V4L2 controls the data_type field should be set to
UVC_CTRL_DATA_TYPE_SIGNED. Other values are currently ignored.
**Return value**:
On success 0 is returned. On error -1 is returned and errno is set
appropriately.
ENOMEM
Not enough memory to perform the operation.
EPERM
Insufficient privileges (super user privileges are required).
EINVAL
No such UVC control.
EOVERFLOW
The requested offset and size would overflow the UVC control.
EEXIST
Mapping already exists.
**Data types**:
.. code-block:: none
* struct uvc_xu_control_mapping
__u32 id V4L2 control identifier
__u8 name[32] V4L2 control name
__u8 entity[16] UVC extension unit GUID
__u8 selector UVC control selector
__u8 size V4L2 control size (in bits)
__u8 offset V4L2 control offset (in bits)
enum v4l2_ctrl_type
v4l2_type V4L2 control type
enum uvc_control_data_type
data_type UVC control data type
struct uvc_menu_info
*menu_info Array of menu entries (for menu controls only)
__u32 menu_count Number of menu entries (for menu controls only)
* struct uvc_menu_info
__u32 value Menu entry value used by the device
__u8 name[32] Menu entry name
* enum uvc_control_data_type
UVC_CTRL_DATA_TYPE_RAW Raw control (byte array)
UVC_CTRL_DATA_TYPE_SIGNED Signed integer
UVC_CTRL_DATA_TYPE_UNSIGNED Unsigned integer
UVC_CTRL_DATA_TYPE_BOOLEAN Boolean
UVC_CTRL_DATA_TYPE_ENUM Enumeration
UVC_CTRL_DATA_TYPE_BITMASK Bitmask
UVC_CTRL_DATA_TYPE_RECT Rectangular area
UVCIOC_CTRL_QUERY - Query a UVC XU control
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Argument: struct uvc_xu_control_query
**Description**:
This ioctl queries a UVC XU control identified by its extension unit ID
and control selector.
There are a number of different queries available that closely
correspond to the low-level control requests described in the UVC
specification. These requests are:
UVC_GET_CUR
Obtain the current value of the control.
UVC_GET_MIN
Obtain the minimum value of the control.
UVC_GET_MAX
Obtain the maximum value of the control.
UVC_GET_DEF
Obtain the default value of the control.
UVC_GET_RES
Query the resolution of the control, i.e. the step size of the
allowed control values.
UVC_GET_LEN
Query the size of the control in bytes.
UVC_GET_INFO
Query the control information bitmap, which indicates whether
get/set requests are supported.
UVC_SET_CUR
Update the value of the control.
Applications must set the 'size' field to the correct length for the
control. Exceptions are the UVC_GET_LEN and UVC_GET_INFO queries, for
which the size must be set to 2 and 1, respectively. The 'data' field
must point to a valid writable buffer big enough to hold the indicated
number of data bytes.
Data is copied directly from the device without any driver-side
processing. Applications are responsible for data buffer formatting,
including little-endian/big-endian conversion. This is particularly
important for the result of the UVC_GET_LEN requests, which is always
returned as a little-endian 16-bit integer by the device.
**Return value**:
On success 0 is returned. On error -1 is returned and errno is set
appropriately.
ENOENT
The device does not support the given control or the specified
extension unit could not be found.
ENOBUFS
The specified buffer size is incorrect (too big or too small).
EINVAL
An invalid request code was passed.
EBADRQC
The given request is not supported by the given control.
EFAULT
The data pointer references an inaccessible memory area.
**Data types**:
.. code-block:: none
* struct uvc_xu_control_query
__u8 unit Extension unit ID
__u8 selector Control selector
__u8 query Request code to send to the device
__u16 size Control data size (in bytes)
__u8 *data Control value
Driver-specific V4L2 controls
-----------------------------
The uvcvideo driver implements the following UVC-specific controls:
``V4L2_CID_UVC_REGION_OF_INTEREST_RECT (struct)``
This control determines the region of interest (ROI). ROI is a
rectangular area represented by a struct :c:type:`v4l2_rect`. The
rectangle is in global sensor coordinates using pixel units. It is
independent of the field of view, not impacted by any cropping or
scaling.
Use ``V4L2_CTRL_WHICH_MIN_VAL`` and ``V4L2_CTRL_WHICH_MAX_VAL`` to query
the range of rectangle sizes.
Setting a ROI allows the camera to optimize the capture for the region.
The value of ``V4L2_CID_REGION_OF_INTEREST_AUTO`` control determines
the detailed behavior.
An example of use of this control, can be found in the:
`Chrome OS USB camera HAL.
<https://chromium.googlesource.com/chromiumos/platform2/+/refs/heads/release-R121-15699.B/camera/hal/usb/>`
``V4L2_CID_UVC_REGION_OF_INTEREST_AUTO (bitmask)``
This determines which, if any, on-board features should track to the
Region of Interest specified by the current value of
``V4L2_CID_UVD__REGION_OF_INTEREST_RECT``.
Max value is a mask indicating all supported Auto Controls.
.. flat-table::
:header-rows: 0
:stub-columns: 0
* - ``V4L2_UVC_REGION_OF_INTEREST_AUTO_EXPOSURE``
- Setting this bit causes automatic exposure to track the region of
interest instead of the whole image.
* - ``V4L2_UVC_REGION_OF_INTEREST_AUTO_IRIS``
- Setting this bit causes automatic iris to track the region of interest
instead of the whole image.
* - ``V4L2_UVC_REGION_OF_INTEREST_AUTO_WHITE_BALANCE``
- Setting this bit causes automatic white balance to track the region
of interest instead of the whole image.
* - ``V4L2_UVC_REGION_OF_INTEREST_AUTO_FOCUS``
- Setting this bit causes automatic focus adjustment to track the region
of interest instead of the whole image.
* - ``V4L2_UVC_REGION_OF_INTEREST_AUTO_FACE_DETECT``
- Setting this bit causes automatic face detection to track the region of
interest instead of the whole image.
* - ``V4L2_UVC_REGION_OF_INTEREST_AUTO_DETECT_AND_TRACK``
- Setting this bit enables automatic face detection and tracking. The
current value of ``V4L2_CID_REGION_OF_INTEREST_RECT`` may be updated by
the driver.
* - ``V4L2_UVC_REGION_OF_INTEREST_AUTO_IMAGE_STABILIZATION``
- Setting this bit enables automatic image stabilization. The
current value of ``V4L2_CID_REGION_OF_INTEREST_RECT`` may be updated by
the driver.
* - ``V4L2_UVC_REGION_OF_INTEREST_AUTO_HIGHER_QUALITY``
- Setting this bit enables automatically capture the specified region
with higher quality if possible.
@@ -0,0 +1,25 @@
.. SPDX-License-Identifier: GPL-2.0
ST VGXY61 camera sensor driver
==============================
The ST VGXY61 driver implements the following controls:
``V4L2_CID_HDR_SENSOR_MODE``
-------------------------------
Change the sensor HDR mode. A HDR picture is obtained by merging two
captures of the same scene using two different exposure periods.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - HDR linearize
- The merger outputs a long exposure capture as long as it is not
saturated.
* - HDR subtraction
- This involves subtracting the short exposure frame from the long
exposure frame.
* - No HDR
- This mode is used for standard dynamic range (SDR) exposures.
@@ -0,0 +1,40 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.ca
.. _ca_fclose:
=====================
Digital TV CA close()
=====================
Name
----
Digital TV CA close()
Synopsis
--------
.. c:function:: int close(int fd)
Arguments
---------
``fd``
File descriptor returned by a previous call to :c:func:`open()`.
Description
-----------
This system call closes a previously opened CA device.
Return Value
------------
On success 0 is returned.
On error -1 is returned, and the ``errno`` variable is set
appropriately.
Generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,72 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.ca
.. _ca_fopen:
====================
Digital TV CA open()
====================
Name
----
Digital TV CA open()
Synopsis
--------
.. c:function:: int open(const char *name, int flags)
Arguments
---------
``name``
Name of specific Digital TV CA device.
``flags``
A bit-wise OR of the following flags:
.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 16
- - ``O_RDONLY``
- read-only access
- - ``O_RDWR``
- read/write access
- - ``O_NONBLOCK``
- open in non-blocking mode
(blocking mode is the default)
Description
-----------
This system call opens a named ca device (e.g. ``/dev/dvb/adapter?/ca?``)
for subsequent use.
When an ``open()`` call has succeeded, the device will be ready for use. The
significance of blocking or non-blocking mode is described in the
documentation for functions where there is a difference. It does not
affect the semantics of the ``open()`` call itself. A device opened in
blocking mode can later be put into non-blocking mode (and vice versa)
using the ``F_SETFL`` command of the ``fcntl`` system call. This is a
standard system call, documented in the Linux manual page for fcntl.
Only one user can open the CA Device in ``O_RDWR`` mode. All other
attempts to open the device in this mode will fail, and an error code
will be returned.
Return Value
------------
On success 0 is returned.
On error -1 is returned, and the ``errno`` variable is set
appropriately.
Generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,46 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.ca
.. _CA_GET_CAP:
==========
CA_GET_CAP
==========
Name
----
CA_GET_CAP
Synopsis
--------
.. c:macro:: CA_GET_CAP
``int ioctl(fd, CA_GET_CAP, struct ca_caps *caps)``
Arguments
---------
``fd``
File descriptor returned by a previous call to :c:func:`open()`.
``caps``
Pointer to struct :c:type:`ca_caps`.
Description
-----------
Queries the Kernel for information about the available CA and descrambler
slots, and their types.
Return Value
------------
On success 0 is returned and :c:type:`ca_caps` is filled.
On error, -1 is returned and the ``errno`` variable is set
appropriately.
The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,43 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.ca
.. _CA_GET_DESCR_INFO:
=================
CA_GET_DESCR_INFO
=================
Name
----
CA_GET_DESCR_INFO
Synopsis
--------
.. c:macro:: CA_GET_DESCR_INFO
``int ioctl(fd, CA_GET_DESCR_INFO, struct ca_descr_info *desc)``
Arguments
---------
``fd``
File descriptor returned by a previous call to :c:func:`open()`.
``desc``
Pointer to struct :c:type:`ca_descr_info`.
Description
-----------
Returns information about all descrambler slots.
Return Value
------------
On success 0 is returned, and :c:type:`ca_descr_info` is filled.
On error -1 is returned, and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,50 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.ca
.. _CA_GET_MSG:
==========
CA_GET_MSG
==========
Name
----
CA_GET_MSG
Synopsis
--------
.. c:macro:: CA_GET_MSG
``int ioctl(fd, CA_GET_MSG, struct ca_msg *msg)``
Arguments
---------
``fd``
File descriptor returned by a previous call to :c:func:`open()`.
``msg``
Pointer to struct :c:type:`ca_msg`.
Description
-----------
Receives a message via a CI CA module.
.. note::
Please notice that, on most drivers, this is done by reading from
the /dev/adapter?/ca? device node.
Return Value
------------
On success 0 is returned.
On error -1 is returned, and the ``errno`` variable is set
appropriately.
Generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,56 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.ca
.. _CA_GET_SLOT_INFO:
================
CA_GET_SLOT_INFO
================
Name
----
CA_GET_SLOT_INFO
Synopsis
--------
.. c:macro:: CA_GET_SLOT_INFO
``int ioctl(fd, CA_GET_SLOT_INFO, struct ca_slot_info *info)``
Arguments
---------
``fd``
File descriptor returned by a previous call to :c:func:`open()`.
``info``
Pointer to struct :c:type:`ca_slot_info`.
Description
-----------
Returns information about a CA slot identified by
:c:type:`ca_slot_info`.slot_num.
Return Value
------------
On success 0 is returned, and :c:type:`ca_slot_info` is filled.
On error -1 is returned, and the ``errno`` variable is set
appropriately.
.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 16
- - ``ENODEV``
- the slot is not available.
The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,43 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.ca
.. _CA_RESET:
========
CA_RESET
========
Name
----
CA_RESET
Synopsis
--------
.. c:macro:: CA_RESET
``int ioctl(fd, CA_RESET)``
Arguments
---------
``fd``
File descriptor returned by a previous call to :c:func:`open()`.
Description
-----------
Puts the Conditional Access hardware on its initial state. It should
be called before start using the CA hardware.
Return Value
------------
On success 0 is returned.
On error -1 is returned, and the ``errno`` variable is set
appropriately.
Generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,50 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.ca
.. _CA_SEND_MSG:
===========
CA_SEND_MSG
===========
Name
----
CA_SEND_MSG
Synopsis
--------
.. c:macro:: CA_SEND_MSG
``int ioctl(fd, CA_SEND_MSG, struct ca_msg *msg)``
Arguments
---------
``fd``
File descriptor returned by a previous call to :c:func:`open()`.
``msg``
Pointer to struct :c:type:`ca_msg`.
Description
-----------
Sends a message via a CI CA module.
.. note::
Please notice that, on most drivers, this is done by writing
to the /dev/adapter?/ca? device node.
Return Value
------------
On success 0 is returned.
On error -1 is returned, and the ``errno`` variable is set
appropriately.
Generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,46 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.ca
.. _CA_SET_DESCR:
============
CA_SET_DESCR
============
Name
----
CA_SET_DESCR
Synopsis
--------
.. c:macro:: CA_SET_DESCR
``int ioctl(fd, CA_SET_DESCR, struct ca_descr *desc)``
Arguments
---------
``fd``
File descriptor returned by a previous call to :c:func:`open()`.
``msg``
Pointer to struct :c:type:`ca_descr`.
Description
-----------
CA_SET_DESCR is used for feeding descrambler CA slots with descrambling
keys (referred as control words).
Return Value
------------
On success 0 is returned.
On error -1 is returned, and the ``errno`` variable is set
appropriately.
Generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,25 @@
# SPDX-License-Identifier: GPL-2.0
# Ignore header name
ignore define _DVBCA_H_
# struct ca_slot_info defines
replace define CA_CI :c:type:`ca_slot_info`
replace define CA_CI_LINK :c:type:`ca_slot_info`
replace define CA_CI_PHYS :c:type:`ca_slot_info`
replace define CA_DESCR :c:type:`ca_slot_info`
replace define CA_SC :c:type:`ca_slot_info`
replace define CA_CI_MODULE_PRESENT :c:type:`ca_slot_info`
replace define CA_CI_MODULE_READY :c:type:`ca_slot_info`
# struct ca_descr_info defines
replace define CA_ECD :c:type:`ca_descr_info`
replace define CA_NDS :c:type:`ca_descr_info`
replace define CA_DSS :c:type:`ca_descr_info`
# some typedefs should point to struct/enums
replace typedef ca_slot_info_t :c:type:`ca_slot_info`
replace typedef ca_descr_info_t :c:type:`ca_descr_info`
replace typedef ca_caps_t :c:type:`ca_caps`
replace typedef ca_msg_t :c:type:`ca_msg`
replace typedef ca_descr_t :c:type:`ca_descr`
@@ -0,0 +1,25 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _dvb_ca:
####################
Digital TV CA Device
####################
The Digital TV CA device controls the conditional access hardware. It
can be accessed through ``/dev/dvb/adapter?/ca?``. Data types and ioctl
definitions can be accessed by including ``linux/dvb/ca.h`` in your
application.
.. note::
There are three ioctls at this API that aren't documented:
:ref:`CA_GET_MSG`, :ref:`CA_SEND_MSG` and :ref:`CA_SET_DESCR`.
Documentation for them are welcome.
.. toctree::
:maxdepth: 1
ca_data_types
ca_function_calls
ca_high_level
@@ -0,0 +1,9 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _ca_data_types:
*************
CA Data Types
*************
.. kernel-doc:: include/uapi/linux/dvb/ca.h
@@ -0,0 +1,20 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _ca_function_calls:
*****************
CA Function Calls
*****************
.. toctree::
:maxdepth: 1
ca-fopen
ca-fclose
ca-reset
ca-get-cap
ca-get-slot-info
ca-get-descr-info
ca-get-msg
ca-send-msg
ca-set-descr
@@ -0,0 +1,157 @@
.. SPDX-License-Identifier: GPL-2.0
The High level CI API
=====================
.. note::
This documentation is outdated.
This document describes the high level CI API as in accordance to the
Linux DVB API.
With the High Level CI approach any new card with almost any random
architecture can be implemented with this style, the definitions
inside the switch statement can be easily adapted for any card, thereby
eliminating the need for any additional ioctls.
The disadvantage is that the driver/hardware has to manage the rest. For
the application programmer it would be as simple as sending/receiving an
array to/from the CI ioctls as defined in the Linux DVB API. No changes
have been made in the API to accommodate this feature.
Why the need for another CI interface?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is one of the most commonly asked question. Well a nice question.
Strictly speaking this is not a new interface.
The CI interface is defined in the DVB API in ca.h as:
.. code-block:: c
typedef struct ca_slot_info {
int num; /* slot number */
int type; /* CA interface this slot supports */
#define CA_CI 1 /* CI high level interface */
#define CA_CI_LINK 2 /* CI link layer level interface */
#define CA_CI_PHYS 4 /* CI physical layer level interface */
#define CA_DESCR 8 /* built-in descrambler */
#define CA_SC 128 /* simple smart card interface */
unsigned int flags;
#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
#define CA_CI_MODULE_READY 2
} ca_slot_info_t;
This CI interface follows the CI high level interface, which is not
implemented by most applications. Hence this area is revisited.
This CI interface is quite different in the case that it tries to
accommodate all other CI based devices, that fall into the other categories.
This means that this CI interface handles the EN50221 style tags in the
Application layer only and no session management is taken care of by the
application. The driver/hardware will take care of all that.
This interface is purely an EN50221 interface exchanging APDU's. This
means that no session management, link layer or a transport layer do
exist in this case in the application to driver communication. It is
as simple as that. The driver/hardware has to take care of that.
With this High Level CI interface, the interface can be defined with the
regular ioctls.
All these ioctls are also valid for the High level CI interface
#define CA_RESET _IO('o', 128)
#define CA_GET_CAP _IOR('o', 129, ca_caps_t)
#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t)
#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
#define CA_GET_MSG _IOR('o', 132, ca_msg_t)
#define CA_SEND_MSG _IOW('o', 133, ca_msg_t)
#define CA_SET_DESCR _IOW('o', 134, ca_descr_t)
On querying the device, the device yields information thus:
.. code-block:: none
CA_GET_SLOT_INFO
----------------------------
Command = [info]
APP: Number=[1]
APP: Type=[1]
APP: flags=[1]
APP: CI High level interface
APP: CA/CI Module Present
CA_GET_CAP
----------------------------
Command = [caps]
APP: Slots=[1]
APP: Type=[1]
APP: Descrambler keys=[16]
APP: Type=[1]
CA_SEND_MSG
----------------------------
Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1]
Found CA descriptor @ program level
(20) ES type=[2] ES pid=[201] ES length =[0 (0x0)]
(25) ES type=[4] ES pid=[301] ES length =[0 (0x0)]
ca_message length is 25 (0x19) bytes
EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00]
Not all ioctl's are implemented in the driver from the API, the other
features of the hardware that cannot be implemented by the API are achieved
using the CA_GET_MSG and CA_SEND_MSG ioctls. An EN50221 style wrapper is
used to exchange the data to maintain compatibility with other hardware.
.. code-block:: c
/* a message to/from a CI-CAM */
typedef struct ca_msg {
unsigned int index;
unsigned int type;
unsigned int length;
unsigned char msg[256];
} ca_msg_t;
The flow of data can be described thus,
.. code-block:: none
App (User)
-----
parse
|
|
v
en50221 APDU (package)
--------------------------------------
| | | High Level CI driver
| | |
| v |
| en50221 APDU (unpackage) |
| | |
| | |
| v |
| sanity checks |
| | |
| | |
| v |
| do (H/W dep) |
--------------------------------------
| Hardware
|
v
The High Level CI interface uses the EN50221 DVB standard, following a
standard ensures futureproofness.
@@ -0,0 +1,23 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _dvb_demux:
#######################
Digital TV Demux Device
#######################
The Digital TV demux device controls the MPEG-TS filters for the
digital TV. If the driver and hardware supports, those filters are
implemented at the hardware. Otherwise, the Kernel provides a software
emulation.
It can be accessed through ``/dev/adapter?/demux?``. Data types and
ioctl definitions can be accessed by including ``linux/dvb/dmx.h`` in
your application.
.. toctree::
:maxdepth: 1
dmx_types
dmx_fcalls
@@ -0,0 +1,47 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.dmx
.. _DMX_ADD_PID:
===========
DMX_ADD_PID
===========
Name
----
DMX_ADD_PID
Synopsis
--------
.. c:macro:: DMX_ADD_PID
``int ioctl(fd, DMX_ADD_PID, __u16 *pid)``
Arguments
---------
``fd``
File descriptor returned by :c:func:`open()`.
``pid``
PID number to be filtered.
Description
-----------
This ioctl call allows to add multiple PIDs to a transport stream filter
previously set up with :ref:`DMX_SET_PES_FILTER` and output equal to
:c:type:`DMX_OUT_TSDEMUX_TAP <dmx_output>`.
Return Value
------------
On success 0 is returned.
On error -1 is returned, and the ``errno`` variable is set
appropriately.
Generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
@@ -0,0 +1,87 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.dmx
.. _DMX_EXPBUF:
****************
ioctl DMX_EXPBUF
****************
Name
====
DMX_EXPBUF - Export a buffer as a DMABUF file descriptor.
.. warning:: this API is still experimental
Synopsis
========
.. c:macro:: DMX_EXPBUF
``int ioctl(int fd, DMX_EXPBUF, struct dmx_exportbuffer *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Pointer to struct :c:type:`dmx_exportbuffer`.
Description
===========
This ioctl is an extension to the memory mapping I/O method.
It can be used to export a buffer as a DMABUF file at any time after
buffers have been allocated with the :ref:`DMX_REQBUFS` ioctl.
To export a buffer, applications fill struct :c:type:`dmx_exportbuffer`.
Applications must set the ``index`` field. Valid index numbers
range from zero to the number of buffers allocated with :ref:`DMX_REQBUFS`
(struct :c:type:`dmx_requestbuffers` ``count``) minus one.
Additional flags may be posted in the ``flags`` field. Refer to a manual
for open() for details. Currently only O_CLOEXEC, O_RDONLY, O_WRONLY,
and O_RDWR are supported.
All other fields must be set to zero. In the
case of multi-planar API, every plane is exported separately using
multiple :ref:`DMX_EXPBUF` calls.
After calling :ref:`DMX_EXPBUF` the ``fd`` field will be set by a
driver, on success. This is a DMABUF file descriptor. The application may
pass it to other DMABUF-aware devices. It is recommended to close a DMABUF
file when it is no longer used to allow the associated memory to be reclaimed.
Examples
========
.. code-block:: c
int buffer_export(int v4lfd, enum dmx_buf_type bt, int index, int *dmafd)
{
struct dmx_exportbuffer expbuf;
memset(&expbuf, 0, sizeof(expbuf));
expbuf.type = bt;
expbuf.index = index;
if (ioctl(v4lfd, DMX_EXPBUF, &expbuf) == -1) {
perror("DMX_EXPBUF");
return -1;
}
*dmafd = expbuf.fd;
return 0;
}
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
EINVAL
A queue is not in MMAP mode or DMABUF exporting is not supported or
``flags`` or ``index`` fields are invalid.
@@ -0,0 +1,42 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: DTV.dmx
.. _dmx_fclose:
========================
Digital TV demux close()
========================
Name
----
Digital TV demux close()
Synopsis
--------
.. c:function:: int close(int fd)
Arguments
---------
``fd``
File descriptor returned by a previous call to
:c:func:`open()`.
Description
-----------
This system call deactivates and deallocates a filter that was
previously allocated via the :c:func:`open()` call.
Return Value
------------
On success 0 is returned.
On error, -1 is returned and the ``errno`` variable is set
appropriately.
The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.

Some files were not shown because too many files have changed in this diff Show More