aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/DocBook
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/DocBook')
-rw-r--r--Documentation/DocBook/Makefile16
-rw-r--r--Documentation/DocBook/alsa-driver-api.tmpl142
-rw-r--r--Documentation/DocBook/crypto-API.tmpl2092
-rw-r--r--Documentation/DocBook/debugobjects.tmpl443
-rw-r--r--Documentation/DocBook/deviceiobook.tmpl323
-rw-r--r--Documentation/DocBook/iio.tmpl697
-rw-r--r--Documentation/DocBook/kernel-hacking.tmpl4
-rw-r--r--Documentation/DocBook/kgdb.tmpl8
-rw-r--r--Documentation/DocBook/libata.tmpl2
-rw-r--r--Documentation/DocBook/regulator.tmpl304
-rw-r--r--Documentation/DocBook/tracepoint.tmpl112
-rw-r--r--Documentation/DocBook/uio-howto.tmpl1050
-rw-r--r--Documentation/DocBook/usb.tmpl992
-rw-r--r--Documentation/DocBook/writing-an-alsa-driver.tmpl6206
14 files changed, 15 insertions, 12376 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index fdf8232d0eeb..164c1c76971f 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -7,15 +7,13 @@
# list of DOCBOOKS.
DOCBOOKS := z8530book.xml \
- kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
+ kernel-hacking.xml kernel-locking.xml \
writing_usb_driver.xml networking.xml \
- kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
+ kernel-api.xml filesystems.xml lsm.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
- genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
- debugobjects.xml sh.xml regulator.xml \
- alsa-driver-api.xml writing-an-alsa-driver.xml \
- tracepoint.xml w1.xml \
- writing_musb_glue_layer.xml crypto-API.xml iio.xml
+ genericirq.xml s390-drivers.xml scsi.xml \
+ sh.xml w1.xml \
+ writing_musb_glue_layer.xml
ifeq ($(DOCBOOKS),)
@@ -73,6 +71,7 @@ installmandocs: mandocs
# no-op for the DocBook toolchain
epubdocs:
latexdocs:
+linkcheckdocs:
###
#External programs used
@@ -264,6 +263,7 @@ clean-files := $(DOCBOOKS) \
$(patsubst %.xml, %.aux.xml, $(DOCBOOKS)) \
$(patsubst %.xml, %.xml.db, $(DOCBOOKS)) \
$(patsubst %.xml, %.xml, $(DOCBOOKS)) \
+ $(patsubst %.xml, .%.xml.cmd, $(DOCBOOKS)) \
$(index)
clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man
@@ -273,6 +273,6 @@ cleandocs:
$(Q)rm -rf $(call objectify, $(clean-dirs))
# Declare the contents of the .PHONY variable as phony. We keep that
-# information in a variable se we can use it in if_changed and friends.
+# information in a variable so we can use it in if_changed and friends.
.PHONY: $(PHONY)
diff --git a/Documentation/DocBook/alsa-driver-api.tmpl b/Documentation/DocBook/alsa-driver-api.tmpl
deleted file mode 100644
index 53f439dcc94b..000000000000
--- a/Documentation/DocBook/alsa-driver-api.tmpl
+++ /dev/null
@@ -1,142 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<!-- ****************************************************** -->
-<!-- Header -->
-<!-- ****************************************************** -->
-<book id="ALSA-Driver-API">
- <bookinfo>
- <title>The ALSA Driver API</title>
-
- <legalnotice>
- <para>
- This document is free; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- </para>
-
- <para>
- This document is distributed in the hope that it will be useful,
- but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
- implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE</emphasis>. See the GNU General Public License
- for more details.
- </para>
-
- <para>
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- </para>
- </legalnotice>
-
- </bookinfo>
-
-<toc></toc>
-
- <chapter><title>Management of Cards and Devices</title>
- <sect1><title>Card Management</title>
-!Esound/core/init.c
- </sect1>
- <sect1><title>Device Components</title>
-!Esound/core/device.c
- </sect1>
- <sect1><title>Module requests and Device File Entries</title>
-!Esound/core/sound.c
- </sect1>
- <sect1><title>Memory Management Helpers</title>
-!Esound/core/memory.c
-!Esound/core/memalloc.c
- </sect1>
- </chapter>
- <chapter><title>PCM API</title>
- <sect1><title>PCM Core</title>
-!Esound/core/pcm.c
-!Esound/core/pcm_lib.c
-!Esound/core/pcm_native.c
-!Iinclude/sound/pcm.h
- </sect1>
- <sect1><title>PCM Format Helpers</title>
-!Esound/core/pcm_misc.c
- </sect1>
- <sect1><title>PCM Memory Management</title>
-!Esound/core/pcm_memory.c
- </sect1>
- <sect1><title>PCM DMA Engine API</title>
-!Esound/core/pcm_dmaengine.c
-!Iinclude/sound/dmaengine_pcm.h
- </sect1>
- </chapter>
- <chapter><title>Control/Mixer API</title>
- <sect1><title>General Control Interface</title>
-!Esound/core/control.c
- </sect1>
- <sect1><title>AC97 Codec API</title>
-!Esound/pci/ac97/ac97_codec.c
-!Esound/pci/ac97/ac97_pcm.c
- </sect1>
- <sect1><title>Virtual Master Control API</title>
-!Esound/core/vmaster.c
-!Iinclude/sound/control.h
- </sect1>
- </chapter>
- <chapter><title>MIDI API</title>
- <sect1><title>Raw MIDI API</title>
-!Esound/core/rawmidi.c
- </sect1>
- <sect1><title>MPU401-UART API</title>
-!Esound/drivers/mpu401/mpu401_uart.c
- </sect1>
- </chapter>
- <chapter><title>Proc Info API</title>
- <sect1><title>Proc Info Interface</title>
-!Esound/core/info.c
- </sect1>
- </chapter>
- <chapter><title>Compress Offload</title>
- <sect1><title>Compress Offload API</title>
-!Esound/core/compress_offload.c
-!Iinclude/uapi/sound/compress_offload.h
-!Iinclude/uapi/sound/compress_params.h
-!Iinclude/sound/compress_driver.h
- </sect1>
- </chapter>
- <chapter><title>ASoC</title>
- <sect1><title>ASoC Core API</title>
-!Iinclude/sound/soc.h
-!Esound/soc/soc-core.c
-<!-- !Esound/soc/soc-cache.c no docbook comments here -->
-!Esound/soc/soc-devres.c
-!Esound/soc/soc-io.c
-!Esound/soc/soc-pcm.c
-!Esound/soc/soc-ops.c
-!Esound/soc/soc-compress.c
- </sect1>
- <sect1><title>ASoC DAPM API</title>
-!Esound/soc/soc-dapm.c
- </sect1>
- <sect1><title>ASoC DMA Engine API</title>
-!Esound/soc/soc-generic-dmaengine-pcm.c
- </sect1>
- </chapter>
- <chapter><title>Miscellaneous Functions</title>
- <sect1><title>Hardware-Dependent Devices API</title>
-!Esound/core/hwdep.c
- </sect1>
- <sect1><title>Jack Abstraction Layer API</title>
-!Iinclude/sound/jack.h
-!Esound/core/jack.c
-!Esound/soc/soc-jack.c
- </sect1>
- <sect1><title>ISA DMA Helpers</title>
-!Esound/core/isadma.c
- </sect1>
- <sect1><title>Other Helper Macros</title>
-!Iinclude/sound/core.h
- </sect1>
- </chapter>
-
-</book>
diff --git a/Documentation/DocBook/crypto-API.tmpl b/Documentation/DocBook/crypto-API.tmpl
deleted file mode 100644
index 088b79c341ff..000000000000
--- a/Documentation/DocBook/crypto-API.tmpl
+++ /dev/null
@@ -1,2092 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="KernelCryptoAPI">
- <bookinfo>
- <title>Linux Kernel Crypto API</title>
-
- <authorgroup>
- <author>
- <firstname>Stephan</firstname>
- <surname>Mueller</surname>
- <affiliation>
- <address>
- <email>smueller@chronox.de</email>
- </address>
- </affiliation>
- </author>
- <author>
- <firstname>Marek</firstname>
- <surname>Vasut</surname>
- <affiliation>
- <address>
- <email>marek@denx.de</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2014</year>
- <holder>Stephan Mueller</holder>
- </copyright>
-
-
- <legalnotice>
- <para>
- This documentation is free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later
- version.
- </para>
-
- <para>
- 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.
- </para>
-
- <para>
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
- </bookinfo>
-
- <toc></toc>
-
- <chapter id="Intro">
- <title>Kernel Crypto API Interface Specification</title>
-
- <sect1><title>Introduction</title>
-
- <para>
- The kernel crypto API offers a rich set of cryptographic ciphers as
- well as other data transformation mechanisms and methods to invoke
- these. This document contains a description of the API and provides
- example code.
- </para>
-
- <para>
- To understand and properly use the kernel crypto API a brief
- explanation of its structure is given. Based on the architecture,
- the API can be separated into different components. Following the
- architecture specification, hints to developers of ciphers are
- provided. Pointers to the API function call documentation are
- given at the end.
- </para>
-
- <para>
- The kernel crypto API refers to all algorithms as "transformations".
- Therefore, a cipher handle variable usually has the name "tfm".
- Besides cryptographic operations, the kernel crypto API also knows
- compression transformations and handles them the same way as ciphers.
- </para>
-
- <para>
- The kernel crypto API serves the following entity types:
-
- <itemizedlist>
- <listitem>
- <para>consumers requesting cryptographic services</para>
- </listitem>
- <listitem>
- <para>data transformation implementations (typically ciphers)
- that can be called by consumers using the kernel crypto
- API</para>
- </listitem>
- </itemizedlist>
- </para>
-
- <para>
- This specification is intended for consumers of the kernel crypto
- API as well as for developers implementing ciphers. This API
- specification, however, does not discuss all API calls available
- to data transformation implementations (i.e. implementations of
- ciphers and other transformations (such as CRC or even compression
- algorithms) that can register with the kernel crypto API).
- </para>
-
- <para>
- Note: The terms "transformation" and cipher algorithm are used
- interchangeably.
- </para>
- </sect1>
-
- <sect1><title>Terminology</title>
- <para>
- The transformation implementation is an actual code or interface
- to hardware which implements a certain transformation with precisely
- defined behavior.
- </para>
-
- <para>
- The transformation object (TFM) is an instance of a transformation
- implementation. There can be multiple transformation objects
- associated with a single transformation implementation. Each of
- those transformation objects is held by a crypto API consumer or
- another transformation. Transformation object is allocated when a
- crypto API consumer requests a transformation implementation.
- The consumer is then provided with a structure, which contains
- a transformation object (TFM).
- </para>
-
- <para>
- The structure that contains transformation objects may also be
- referred to as a "cipher handle". Such a cipher handle is always
- subject to the following phases that are reflected in the API calls
- applicable to such a cipher handle:
- </para>
-
- <orderedlist>
- <listitem>
- <para>Initialization of a cipher handle.</para>
- </listitem>
- <listitem>
- <para>Execution of all intended cipher operations applicable
- for the handle where the cipher handle must be furnished to
- every API call.</para>
- </listitem>
- <listitem>
- <para>Destruction of a cipher handle.</para>
- </listitem>
- </orderedlist>
-
- <para>
- When using the initialization API calls, a cipher handle is
- created and returned to the consumer. Therefore, please refer
- to all initialization API calls that refer to the data
- structure type a consumer is expected to receive and subsequently
- to use. The initialization API calls have all the same naming
- conventions of crypto_alloc_*.
- </para>
-
- <para>
- The transformation context is private data associated with
- the transformation object.
- </para>
- </sect1>
- </chapter>
-
- <chapter id="Architecture"><title>Kernel Crypto API Architecture</title>
- <sect1><title>Cipher algorithm types</title>
- <para>
- The kernel crypto API provides different API calls for the
- following cipher types:
-
- <itemizedlist>
- <listitem><para>Symmetric ciphers</para></listitem>
- <listitem><para>AEAD ciphers</para></listitem>
- <listitem><para>Message digest, including keyed message digest</para></listitem>
- <listitem><para>Random number generation</para></listitem>
- <listitem><para>User space interface</para></listitem>
- </itemizedlist>
- </para>
- </sect1>
-
- <sect1><title>Ciphers And Templates</title>
- <para>
- The kernel crypto API provides implementations of single block
- ciphers and message digests. In addition, the kernel crypto API
- provides numerous "templates" that can be used in conjunction
- with the single block ciphers and message digests. Templates
- include all types of block chaining mode, the HMAC mechanism, etc.
- </para>
-
- <para>
- Single block ciphers and message digests can either be directly
- used by a caller or invoked together with a template to form
- multi-block ciphers or keyed message digests.
- </para>
-
- <para>
- A single block cipher may even be called with multiple templates.
- However, templates cannot be used without a single cipher.
- </para>
-
- <para>
- See /proc/crypto and search for "name". For example:
-
- <itemizedlist>
- <listitem><para>aes</para></listitem>
- <listitem><para>ecb(aes)</para></listitem>
- <listitem><para>cmac(aes)</para></listitem>
- <listitem><para>ccm(aes)</para></listitem>
- <listitem><para>rfc4106(gcm(aes))</para></listitem>
- <listitem><para>sha1</para></listitem>
- <listitem><para>hmac(sha1)</para></listitem>
- <listitem><para>authenc(hmac(sha1),cbc(aes))</para></listitem>
- </itemizedlist>
- </para>
-
- <para>
- In these examples, "aes" and "sha1" are the ciphers and all
- others are the templates.
- </para>
- </sect1>
-
- <sect1><title>Synchronous And Asynchronous Operation</title>
- <para>
- The kernel crypto API provides synchronous and asynchronous
- API operations.
- </para>
-
- <para>
- When using the synchronous API operation, the caller invokes
- a cipher operation which is performed synchronously by the
- kernel crypto API. That means, the caller waits until the
- cipher operation completes. Therefore, the kernel crypto API
- calls work like regular function calls. For synchronous
- operation, the set of API calls is small and conceptually
- similar to any other crypto library.
- </para>
-
- <para>
- Asynchronous operation is provided by the kernel crypto API
- which implies that the invocation of a cipher operation will
- complete almost instantly. That invocation triggers the
- cipher operation but it does not signal its completion. Before
- invoking a cipher operation, the caller must provide a callback
- function the kernel crypto API can invoke to signal the
- completion of the cipher operation. Furthermore, the caller
- must ensure it can handle such asynchronous events by applying
- appropriate locking around its data. The kernel crypto API
- does not perform any special serialization operation to protect
- the caller's data integrity.
- </para>
- </sect1>
-
- <sect1><title>Crypto API Cipher References And Priority</title>
- <para>
- A cipher is referenced by the caller with a string. That string
- has the following semantics:
-
- <programlisting>
- template(single block cipher)
- </programlisting>
-
- where "template" and "single block cipher" is the aforementioned
- template and single block cipher, respectively. If applicable,
- additional templates may enclose other templates, such as
-
- <programlisting>
- template1(template2(single block cipher)))
- </programlisting>
- </para>
-
- <para>
- The kernel crypto API may provide multiple implementations of a
- template or a single block cipher. For example, AES on newer
- Intel hardware has the following implementations: AES-NI,
- assembler implementation, or straight C. Now, when using the
- string "aes" with the kernel crypto API, which cipher
- implementation is used? The answer to that question is the
- priority number assigned to each cipher implementation by the
- kernel crypto API. When a caller uses the string to refer to a
- cipher during initialization of a cipher handle, the kernel
- crypto API looks up all implementations providing an
- implementation with that name and selects the implementation
- with the highest priority.
- </para>
-
- <para>
- Now, a caller may have the need to refer to a specific cipher
- implementation and thus does not want to rely on the
- priority-based selection. To accommodate this scenario, the
- kernel crypto API allows the cipher implementation to register
- a unique name in addition to common names. When using that
- unique name, a caller is therefore always sure to refer to
- the intended cipher implementation.
- </para>
-
- <para>
- The list of available ciphers is given in /proc/crypto. However,
- that list does not specify all possible permutations of
- templates and ciphers. Each block listed in /proc/crypto may
- contain the following information -- if one of the components
- listed as follows are not applicable to a cipher, it is not
- displayed:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>name: the generic name of the cipher that is subject
- to the priority-based selection -- this name can be used by
- the cipher allocation API calls (all names listed above are
- examples for such generic names)</para>
- </listitem>
- <listitem>
- <para>driver: the unique name of the cipher -- this name can
- be used by the cipher allocation API calls</para>
- </listitem>
- <listitem>
- <para>module: the kernel module providing the cipher
- implementation (or "kernel" for statically linked ciphers)</para>
- </listitem>
- <listitem>
- <para>priority: the priority value of the cipher implementation</para>
- </listitem>
- <listitem>
- <para>refcnt: the reference count of the respective cipher
- (i.e. the number of current consumers of this cipher)</para>
- </listitem>
- <listitem>
- <para>selftest: specification whether the self test for the
- cipher passed</para>
- </listitem>
- <listitem>
- <para>type:
- <itemizedlist>
- <listitem>
- <para>skcipher for symmetric key ciphers</para>
- </listitem>
- <listitem>
- <para>cipher for single block ciphers that may be used with
- an additional template</para>
- </listitem>
- <listitem>
- <para>shash for synchronous message digest</para>
- </listitem>
- <listitem>
- <para>ahash for asynchronous message digest</para>
- </listitem>
- <listitem>
- <para>aead for AEAD cipher type</para>
- </listitem>
- <listitem>
- <para>compression for compression type transformations</para>
- </listitem>
- <listitem>
- <para>rng for random number generator</para>
- </listitem>
- <listitem>
- <para>givcipher for cipher with associated IV generator
- (see the geniv entry below for the specification of the
- IV generator type used by the cipher implementation)</para>
- </listitem>
- </itemizedlist>
- </para>
- </listitem>
- <listitem>
- <para>blocksize: blocksize of cipher in bytes</para>
- </listitem>
- <listitem>
- <para>keysize: key size in bytes</para>
- </listitem>
- <listitem>
- <para>ivsize: IV size in bytes</para>
- </listitem>
- <listitem>
- <para>seedsize: required size of seed data for random number
- generator</para>
- </listitem>
- <listitem>
- <para>digestsize: output size of the message digest</para>
- </listitem>
- <listitem>
- <para>geniv: IV generation type:
- <itemizedlist>
- <listitem>
- <para>eseqiv for encrypted sequence number based IV
- generation</para>
- </listitem>
- <listitem>
- <para>seqiv for sequence number based IV generation</para>
- </listitem>
- <listitem>
- <para>chainiv for chain iv generation</para>
- </listitem>
- <listitem>
- <para>&lt;builtin&gt; is a marker that the cipher implements
- IV generation and handling as it is specific to the given
- cipher</para>
- </listitem>
- </itemizedlist>
- </para>
- </listitem>
- </itemizedlist>
- </sect1>
-
- <sect1><title>Key Sizes</title>
- <para>
- When allocating a cipher handle, the caller only specifies the
- cipher type. Symmetric ciphers, however, typically support
- multiple key sizes (e.g. AES-128 vs. AES-192 vs. AES-256).
- These key sizes are determined with the length of the provided
- key. Thus, the kernel crypto API does not provide a separate
- way to select the particular symmetric cipher key size.
- </para>
- </sect1>
-
- <sect1><title>Cipher Allocation Type And Masks</title>
- <para>
- The different cipher handle allocation functions allow the
- specification of a type and mask flag. Both parameters have
- the following meaning (and are therefore not covered in the
- subsequent sections).
- </para>
-
- <para>
- The type flag specifies the type of the cipher algorithm.
- The caller usually provides a 0 when the caller wants the
- default handling. Otherwise, the caller may provide the
- following selections which match the aforementioned cipher
- types:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>CRYPTO_ALG_TYPE_CIPHER Single block cipher</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_COMPRESS Compression</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_AEAD Authenticated Encryption with
- Associated Data (MAC)</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_BLKCIPHER Synchronous multi-block cipher</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_ABLKCIPHER Asynchronous multi-block cipher</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_GIVCIPHER Asynchronous multi-block
- cipher packed together with an IV generator (see geniv field
- in the /proc/crypto listing for the known IV generators)</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_DIGEST Raw message digest</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_HASH Alias for CRYPTO_ALG_TYPE_DIGEST</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_SHASH Synchronous multi-block hash</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_AHASH Asynchronous multi-block hash</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_RNG Random Number Generation</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_AKCIPHER Asymmetric cipher</para>
- </listitem>
- <listitem>
- <para>CRYPTO_ALG_TYPE_PCOMPRESS Enhanced version of
- CRYPTO_ALG_TYPE_COMPRESS allowing for segmented compression /
- decompression instead of performing the operation on one
- segment only. CRYPTO_ALG_TYPE_PCOMPRESS is intended to replace
- CRYPTO_ALG_TYPE_COMPRESS once existing consumers are converted.</para>
- </listitem>
- </itemizedlist>
-
- <para>
- The mask flag restricts the type of cipher. The only allowed
- flag is CRYPTO_ALG_ASYNC to restrict the cipher lookup function
- to asynchronous ciphers. Usually, a caller provides a 0 for the
- mask flag.
- </para>
-
- <para>
- When the caller provides a mask and type specification, the
- caller limits the search the kernel crypto API can perform for
- a suitable cipher implementation for the given cipher name.
- That means, even when a caller uses a cipher name that exists
- during its initialization call, the kernel crypto API may not
- select it due to the used type and mask field.
- </para>
- </sect1>
-
- <sect1><title>Internal Structure of Kernel Crypto API</title>
-
- <para>
- The kernel crypto API has an internal structure where a cipher
- implementation may use many layers and indirections. This section
- shall help to clarify how the kernel crypto API uses
- various components to implement the complete cipher.
- </para>
-
- <para>
- The following subsections explain the internal structure based
- on existing cipher implementations. The first section addresses
- the most complex scenario where all other scenarios form a logical
- subset.
- </para>
-
- <sect2><title>Generic AEAD Cipher Structure</title>
-
- <para>
- The following ASCII art decomposes the kernel crypto API layers
- when using the AEAD cipher with the automated IV generation. The
- shown example is used by the IPSEC layer.
- </para>
-
- <para>
- For other use cases of AEAD ciphers, the ASCII art applies as
- well, but the caller may not use the AEAD cipher with a separate
- IV generator. In this case, the caller must generate the IV.
- </para>
-
- <para>
- The depicted example decomposes the AEAD cipher of GCM(AES) based
- on the generic C implementations (gcm.c, aes-generic.c, ctr.c,
- ghash-generic.c, seqiv.c). The generic implementation serves as an
- example showing the complete logic of the kernel crypto API.
- </para>
-
- <para>
- It is possible that some streamlined cipher implementations (like
- AES-NI) provide implementations merging aspects which in the view
- of the kernel crypto API cannot be decomposed into layers any more.
- In case of the AES-NI implementation, the CTR mode, the GHASH
- implementation and the AES cipher are all merged into one cipher
- implementation registered with the kernel crypto API. In this case,
- the concept described by the following ASCII art applies too. However,
- the decomposition of GCM into the individual sub-components
- by the kernel crypto API is not done any more.
- </para>
-
- <para>
- Each block in the following ASCII art is an independent cipher
- instance obtained from the kernel crypto API. Each block
- is accessed by the caller or by other blocks using the API functions
- defined by the kernel crypto API for the cipher implementation type.
- </para>
-
- <para>
- The blocks below indicate the cipher type as well as the specific
- logic implemented in the cipher.
- </para>
-
- <para>
- The ASCII art picture also indicates the call structure, i.e. who
- calls which component. The arrows point to the invoked block
- where the caller uses the API applicable to the cipher type
- specified for the block.
- </para>
-
- <programlisting>
-<![CDATA[
-kernel crypto API | IPSEC Layer
- |
-+-----------+ |
-| | (1)
-| aead | <----------------------------------- esp_output
-| (seqiv) | ---+
-+-----------+ |
- | (2)
-+-----------+ |
-| | <--+ (2)
-| aead | <----------------------------------- esp_input
-| (gcm) | ------------+
-+-----------+ |
- | (3) | (5)
- v v
-+-----------+ +-----------+
-| | | |
-| skcipher | | ahash |
-| (ctr) | ---+ | (ghash) |
-+-----------+ | +-----------+
- |
-+-----------+ | (4)
-| | <--+
-| cipher |
-| (aes) |
-+-----------+
-]]>
- </programlisting>
-
- <para>
- The following call sequence is applicable when the IPSEC layer
- triggers an encryption operation with the esp_output function. During
- configuration, the administrator set up the use of rfc4106(gcm(aes)) as
- the cipher for ESP. The following call sequence is now depicted in the
- ASCII art above:
- </para>
-
- <orderedlist>
- <listitem>
- <para>
- esp_output() invokes crypto_aead_encrypt() to trigger an encryption
- operation of the AEAD cipher with IV generator.
- </para>
-
- <para>
- In case of GCM, the SEQIV implementation is registered as GIVCIPHER
- in crypto_rfc4106_alloc().
- </para>
-
- <para>
- The SEQIV performs its operation to generate an IV where the core
- function is seqiv_geniv().
- </para>
- </listitem>
-
- <listitem>
- <para>
- Now, SEQIV uses the AEAD API function calls to invoke the associated
- AEAD cipher. In our case, during the instantiation of SEQIV, the
- cipher handle for GCM is provided to SEQIV. This means that SEQIV
- invokes AEAD cipher operations with the GCM cipher handle.
- </para>
-
- <para>
- During instantiation of the GCM handle, the CTR(AES) and GHASH
- ciphers are instantiated. The cipher handles for CTR(AES) and GHASH
- are retained for later use.
- </para>
-
- <para>
- The GCM implementation is responsible to invoke the CTR mode AES and
- the GHASH cipher in the right manner to implement the GCM
- specification.
- </para>
- </listitem>
-
- <listitem>
- <para>
- The GCM AEAD cipher type implementation now invokes the SKCIPHER API
- with the instantiated CTR(AES) cipher handle.
- </para>
-
- <para>
- During instantiation of the CTR(AES) cipher, the CIPHER type
- implementation of AES is instantiated. The cipher handle for AES is
- retained.
- </para>
-
- <para>
- That means that the SKCIPHER implementation of CTR(AES) only
- implements the CTR block chaining mode. After performing the block
- chaining operation, the CIPHER implementation of AES is invoked.
- </para>
- </listitem>
-
- <listitem>
- <para>
- The SKCIPHER of CTR(AES) now invokes the CIPHER API with the AES
- cipher handle to encrypt one block.
- </para>
- </listitem>
-
- <listitem>
- <para>
- The GCM AEAD implementation also invokes the GHASH cipher
- implementation via the AHASH API.
- </para>
- </listitem>
- </orderedlist>
-
- <para>
- When the IPSEC layer triggers the esp_input() function, the same call
- sequence is followed with the only difference that the operation starts
- with step (2).
- </para>
- </sect2>
-
- <sect2><title>Generic Block Cipher Structure</title>
- <para>
- Generic block ciphers follow the same concept as depicted with the ASCII
- art picture above.
- </para>
-
- <para>
- For example, CBC(AES) is implemented with cbc.c, and aes-generic.c. The
- ASCII art picture above applies as well with the difference that only
- step (4) is used and the SKCIPHER block chaining mode is CBC.
- </para>
- </sect2>
-
- <sect2><title>Generic Keyed Message Digest Structure</title>
- <para>
- Keyed message digest implementations again follow the same concept as
- depicted in the ASCII art picture above.
- </para>
-
- <para>
- For example, HMAC(SHA256) is implemented with hmac.c and
- sha256_generic.c. The following ASCII art illustrates the
- implementation:
- </para>
-
- <programlisting>
-<![CDATA[
-kernel crypto API | Caller
- |
-+-----------+ (1) |
-| | <------------------ some_function
-| ahash |
-| (hmac) | ---+
-+-----------+ |
- | (2)
-+-----------+ |
-| | <--+
-| shash |
-| (sha256) |
-+-----------+
-]]>
- </programlisting>
-
- <para>
- The following call sequence is applicable when a caller triggers
- an HMAC operation:
- </para>
-
- <orderedlist>
- <listitem>
- <para>
- The AHASH API functions are invoked by the caller. The HMAC
- implementation performs its operation as needed.
- </para>
-
- <para>
- During initialization of the HMAC cipher, the SHASH cipher type of
- SHA256 is instantiated. The cipher handle for the SHA256 instance is
- retained.
- </para>
-
- <para>
- At one time, the HMAC implementation requires a SHA256 operation
- where the SHA256 cipher handle is used.
- </para>
- </listitem>
-
- <listitem>
- <para>
- The HMAC instance now invokes the SHASH API with the SHA256
- cipher handle to calculate the message digest.
- </para>
- </listitem>
- </orderedlist>
- </sect2>
- </sect1>
- </chapter>
-
- <chapter id="Development"><title>Developing Cipher Algorithms</title>
- <sect1><title>Registering And Unregistering Transformation</title>
- <para>
- There are three distinct types of registration functions in
- the Crypto API. One is used to register a generic cryptographic
- transformation, while the other two are specific to HASH
- transformations and COMPRESSion. We will discuss the latter
- two in a separate chapter, here we will only look at the
- generic ones.
- </para>
-
- <para>
- Before discussing the register functions, the data structure
- to be filled with each, struct crypto_alg, must be considered
- -- see below for a description of this data structure.
- </para>
-
- <para>
- The generic registration functions can be found in
- include/linux/crypto.h and their definition can be seen below.
- The former function registers a single transformation, while
- the latter works on an array of transformation descriptions.
- The latter is useful when registering transformations in bulk,
- for example when a driver implements multiple transformations.
- </para>
-
- <programlisting>
- int crypto_register_alg(struct crypto_alg *alg);
- int crypto_register_algs(struct crypto_alg *algs, int count);
- </programlisting>
-
- <para>
- The counterparts to those functions are listed below.
- </para>
-
- <programlisting>
- int crypto_unregister_alg(struct crypto_alg *alg);
- int crypto_unregister_algs(struct crypto_alg *algs, int count);
- </programlisting>
-
- <para>
- Notice that both registration and unregistration functions
- do return a value, so make sure to handle errors. A return
- code of zero implies success. Any return code &lt; 0 implies
- an error.
- </para>
-
- <para>
- The bulk registration/unregistration functions
- register/unregister each transformation in the given array of
- length count. They handle errors as follows:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- crypto_register_algs() succeeds if and only if it
- successfully registers all the given transformations. If an
- error occurs partway through, then it rolls back successful
- registrations before returning the error code. Note that if
- a driver needs to handle registration errors for individual
- transformations, then it will need to use the non-bulk
- function crypto_register_alg() instead.
- </para>
- </listitem>
- <listitem>
- <para>
- crypto_unregister_algs() tries to unregister all the given
- transformations, continuing on error. It logs errors and
- always returns zero.
- </para>
- </listitem>
- </itemizedlist>
-
- </sect1>
-
- <sect1><title>Single-Block Symmetric Ciphers [CIPHER]</title>
- <para>
- Example of transformations: aes, arc4, ...
- </para>
-
- <para>
- This section describes the simplest of all transformation
- implementations, that being the CIPHER type used for symmetric
- ciphers. The CIPHER type is used for transformations which
- operate on exactly one block at a time and there are no
- dependencies between blocks at all.
- </para>
-
- <sect2><title>Registration specifics</title>
- <para>
- The registration of [CIPHER] algorithm is specific in that
- struct crypto_alg field .cra_type is empty. The .cra_u.cipher
- has to be filled in with proper callbacks to implement this
- transformation.
- </para>
-
- <para>
- See struct cipher_alg below.
- </para>
- </sect2>
-
- <sect2><title>Cipher Definition With struct cipher_alg</title>
- <para>
- Struct cipher_alg defines a single block cipher.
- </para>
-
- <para>
- Here are schematics of how these functions are called when
- operated from other part of the kernel. Note that the
- .cia_setkey() call might happen before or after any of these
- schematics happen, but must not happen during any of these
- are in-flight.
- </para>
-
- <para>
- <programlisting>
- KEY ---. PLAINTEXT ---.
- v v
- .cia_setkey() -&gt; .cia_encrypt()
- |
- '-----&gt; CIPHERTEXT
- </programlisting>
- </para>
-
- <para>
- Please note that a pattern where .cia_setkey() is called
- multiple times is also valid:
- </para>
-
- <para>
- <programlisting>
-
- KEY1 --. PLAINTEXT1 --. KEY2 --. PLAINTEXT2 --.
- v v v v
- .cia_setkey() -&gt; .cia_encrypt() -&gt; .cia_setkey() -&gt; .cia_encrypt()
- | |
- '---&gt; CIPHERTEXT1 '---&gt; CIPHERTEXT2
- </programlisting>
- </para>
-
- </sect2>
- </sect1>
-
- <sect1><title>Multi-Block Ciphers</title>
- <para>
- Example of transformations: cbc(aes), ecb(arc4), ...
- </para>
-
- <para>
- This section describes the multi-block cipher transformation
- implementations. The multi-block ciphers are
- used for transformations which operate on scatterlists of
- data supplied to the transformation functions. They output
- the result into a scatterlist of data as well.
- </para>
-
- <sect2><title>Registration Specifics</title>
-
- <para>
- The registration of multi-block cipher algorithms
- is one of the most standard procedures throughout the crypto API.
- </para>
-
- <para>
- Note, if a cipher implementation requires a proper alignment
- of data, the caller should use the functions of
- crypto_skcipher_alignmask() to identify a memory alignment mask.
- The kernel crypto API is able to process requests that are unaligned.
- This implies, however, additional overhead as the kernel
- crypto API needs to perform the realignment of the data which
- may imply moving of data.
- </para>
- </sect2>
-
- <sect2><title>Cipher Definition With struct blkcipher_alg and ablkcipher_alg</title>
- <para>
- Struct blkcipher_alg defines a synchronous block cipher whereas
- struct ablkcipher_alg defines an asynchronous block cipher.
- </para>
-
- <para>
- Please refer to the single block cipher description for schematics
- of the block cipher usage.
- </para>
- </sect2>
-
- <sect2><title>Specifics Of Asynchronous Multi-Block Cipher</title>
- <para>
- There are a couple of specifics to the asynchronous interface.
- </para>
-
- <para>
- First of all, some of the drivers will want to use the
- Generic ScatterWalk in case the hardware needs to be fed
- separate chunks of the scatterlist which contains the
- plaintext and will contain the ciphertext. Please refer
- to the ScatterWalk interface offered by the Linux kernel
- scatter / gather list implementation.
- </para>
- </sect2>
- </sect1>
-
- <sect1><title>Hashing [HASH]</title>
-
- <para>
- Example of transformations: crc32, md5, sha1, sha256,...
- </para>
-
- <sect2><title>Registering And Unregistering The Transformation</title>
-
- <para>
- There are multiple ways to register a HASH transformation,
- depending on whether the transformation is synchronous [SHASH]
- or asynchronous [AHASH] and the amount of HASH transformations
- we are registering. You can find the prototypes defined in
- include/crypto/internal/hash.h:
- </para>
-
- <programlisting>
- int crypto_register_ahash(struct ahash_alg *alg);
-
- int crypto_register_shash(struct shash_alg *alg);
- int crypto_register_shashes(struct shash_alg *algs, int count);
- </programlisting>
-
- <para>
- The respective counterparts for unregistering the HASH
- transformation are as follows:
- </para>
-
- <programlisting>
- int crypto_unregister_ahash(struct ahash_alg *alg);
-
- int crypto_unregister_shash(struct shash_alg *alg);
- int crypto_unregister_shashes(struct shash_alg *algs, int count);
- </programlisting>
- </sect2>
-
- <sect2><title>Cipher Definition With struct shash_alg and ahash_alg</title>
- <para>
- Here are schematics of how these functions are called when
- operated from other part of the kernel. Note that the .setkey()
- call might happen before or after any of these schematics happen,
- but must not happen during any of these are in-flight. Please note
- that calling .init() followed immediately by .finish() is also a
- perfectly valid transformation.
- </para>
-
- <programlisting>
- I) DATA -----------.
- v
- .init() -&gt; .update() -&gt; .final() ! .update() might not be called
- ^ | | at all in this scenario.
- '----' '---&gt; HASH
-
- II) DATA -----------.-----------.
- v v
- .init() -&gt; .update() -&gt; .finup() ! .update() may not be called
- ^ | | at all in this scenario.
- '----' '---&gt; HASH
-
- III) DATA -----------.
- v
- .digest() ! The entire process is handled
- | by the .digest() call.
- '---------------&gt; HASH
- </programlisting>
-
- <para>
- Here is a schematic of how the .export()/.import() functions are
- called when used from another part of the kernel.
- </para>
-
- <programlisting>
- KEY--. DATA--.
- v v ! .update() may not be called
- .setkey() -&gt; .init() -&gt; .update() -&gt; .export() at all in this scenario.
- ^ | |
- '-----' '--&gt; PARTIAL_HASH
-
- ----------- other transformations happen here -----------
-
- PARTIAL_HASH--. DATA1--.
- v v
- .import -&gt; .update() -&gt; .final() ! .update() may not be called
- ^ | | at all in this scenario.
- '----' '--&gt; HASH1
-
- PARTIAL_HASH--. DATA2-.
- v v
- .import -&gt; .finup()
- |
- '---------------&gt; HASH2
- </programlisting>
- </sect2>
-
- <sect2><title>Specifics Of Asynchronous HASH Transformation</title>
- <para>
- Some of the drivers will want to use the Generic ScatterWalk
- in case the implementation needs to be fed separate chunks of the
- scatterlist which contains the input data. The buffer containing
- the resulting hash will always be properly aligned to
- .cra_alignmask so there is no need to worry about this.
- </para>
- </sect2>
- </sect1>
- </chapter>
-
- <chapter id="User"><title>User Space Interface</title>
- <sect1><title>Introduction</title>
- <para>
- The concepts of the kernel crypto API visible to kernel space is fully
- applicable to the user space interface as well. Therefore, the kernel
- crypto API high level discussion for the in-kernel use cases applies
- here as well.
- </para>
-
- <para>
- The major difference, however, is that user space can only act as a
- consumer and never as a provider of a transformation or cipher algorithm.
- </para>
-
- <para>
- The following covers the user space interface exported by the kernel
- crypto API. A working example of this description is libkcapi that
- can be obtained from [1]. That library can be used by user space
- applications that require cryptographic services from the kernel.
- </para>
-
- <para>
- Some details of the in-kernel kernel crypto API aspects do not
- apply to user space, however. This includes the difference between
- synchronous and asynchronous invocations. The user space API call
- is fully synchronous.
- </para>
-
- <para>
- [1] <ulink url="http://www.chronox.de/libkcapi.html">http://www.chronox.de/libkcapi.html</ulink>
- </para>
-
- </sect1>
-
- <sect1><title>User Space API General Remarks</title>
- <para>
- The kernel crypto API is accessible from user space. Currently,
- the following ciphers are accessible:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>Message digest including keyed message digest (HMAC, CMAC)</para>
- </listitem>
-
- <listitem>
- <para>Symmetric ciphers</para>
- </listitem>
-
- <listitem>
- <para>AEAD ciphers</para>
- </listitem>
-
- <listitem>
- <para>Random Number Generators</para>
- </listitem>
- </itemizedlist>
-
- <para>
- The interface is provided via socket type using the type AF_ALG.
- In addition, the setsockopt option type is SOL_ALG. In case the
- user space header files do not export these flags yet, use the
- following macros:
- </para>
-
- <programlisting>
-#ifndef AF_ALG
-#define AF_ALG 38
-#endif
-#ifndef SOL_ALG
-#define SOL_ALG 279
-#endif
- </programlisting>
-
- <para>
- A cipher is accessed with the same name as done for the in-kernel
- API calls. This includes the generic vs. unique naming schema for
- ciphers as well as the enforcement of priorities for generic names.
- </para>
-
- <para>
- To interact with the kernel crypto API, a socket must be
- created by the user space application. User space invokes the cipher
- operation with the send()/write() system call family. The result of the
- cipher operation is obtained with the read()/recv() system call family.
- </para>
-
- <para>
- The following API calls assume that the socket descriptor
- is already opened by the user space application and discusses only
- the kernel crypto API specific invocations.
- </para>
-
- <para>
- To initialize the socket interface, the following sequence has to
- be performed by the consumer:
- </para>
-
- <orderedlist>
- <listitem>
- <para>
- Create a socket of type AF_ALG with the struct sockaddr_alg
- parameter specified below for the different cipher types.
- </para>
- </listitem>
-
- <listitem>
- <para>
- Invoke bind with the socket descriptor
- </para>
- </listitem>
-
- <listitem>
- <para>
- Invoke accept with the socket descriptor. The accept system call
- returns a new file descriptor that is to be used to interact with
- the particular cipher instance. When invoking send/write or recv/read
- system calls to send data to the kernel or obtain data from the
- kernel, the file descriptor returned by accept must be used.
- </para>
- </listitem>
- </orderedlist>
- </sect1>
-
- <sect1><title>In-place Cipher operation</title>
- <para>
- Just like the in-kernel operation of the kernel crypto API, the user
- space interface allows the cipher operation in-place. That means that
- the input buffer used for the send/write system call and the output
- buffer used by the read/recv system call may be one and the same.
- This is of particular interest for symmetric cipher operations where a
- copying of the output data to its final destination can be avoided.
- </para>
-
- <para>
- If a consumer on the other hand wants to maintain the plaintext and
- the ciphertext in different memory locations, all a consumer needs
- to do is to provide different memory pointers for the encryption and
- decryption operation.
- </para>
- </sect1>
-
- <sect1><title>Message Digest API</title>
- <para>
- The message digest type to be used for the cipher operation is
- selected when invoking the bind syscall. bind requires the caller
- to provide a filled struct sockaddr data structure. This data
- structure must be filled as follows:
- </para>
-
- <programlisting>
-struct sockaddr_alg sa = {
- .salg_family = AF_ALG,
- .salg_type = "hash", /* this selects the hash logic in the kernel */
- .salg_name = "sha1" /* this is the cipher name */
-};
- </programlisting>
-
- <para>
- The salg_type value "hash" applies to message digests and keyed
- message digests. Though, a keyed message digest is referenced by
- the appropriate salg_name. Please see below for the setsockopt
- interface that explains how the key can be set for a keyed message
- digest.
- </para>
-
- <para>
- Using the send() system call, the application provides the data that
- should be processed with the message digest. The send system call
- allows the following flags to be specified:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- MSG_MORE: If this flag is set, the send system call acts like a
- message digest update function where the final hash is not
- yet calculated. If the flag is not set, the send system call
- calculates the final message digest immediately.
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- With the recv() system call, the application can read the message
- digest from the kernel crypto API. If the buffer is too small for the
- message digest, the flag MSG_TRUNC is set by the kernel.
- </para>
-
- <para>
- In order to set a message digest key, the calling application must use
- the setsockopt() option of ALG_SET_KEY. If the key is not set the HMAC
- operation is performed without the initial HMAC state change caused by
- the key.
- </para>
- </sect1>
-
- <sect1><title>Symmetric Cipher API</title>
- <para>
- The operation is very similar to the message digest discussion.
- During initialization, the struct sockaddr data structure must be
- filled as follows:
- </para>
-
- <programlisting>
-struct sockaddr_alg sa = {
- .salg_family = AF_ALG,
- .salg_type = "skcipher", /* this selects the symmetric cipher */
- .salg_name = "cbc(aes)" /* this is the cipher name */
-};
- </programlisting>
-
- <para>
- Before data can be sent to the kernel using the write/send system
- call family, the consumer must set the key. The key setting is
- described with the setsockopt invocation below.
- </para>
-
- <para>
- Using the sendmsg() system call, the application provides the data that should be processed for encryption or decryption. In addition, the IV is
- specified with the data structure provided by the sendmsg() system call.
- </para>
-
- <para>
- The sendmsg system call parameter of struct msghdr is embedded into the
- struct cmsghdr data structure. See recv(2) and cmsg(3) for more
- information on how the cmsghdr data structure is used together with the
- send/recv system call family. That cmsghdr data structure holds the
- following information specified with a separate header instances:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- specification of the cipher operation type with one of these flags:
- </para>
- <itemizedlist>
- <listitem>
- <para>ALG_OP_ENCRYPT - encryption of data</para>
- </listitem>
- <listitem>
- <para>ALG_OP_DECRYPT - decryption of data</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>
- specification of the IV information marked with the flag ALG_SET_IV
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- The send system call family allows the following flag to be specified:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- MSG_MORE: If this flag is set, the send system call acts like a
- cipher update function where more input data is expected
- with a subsequent invocation of the send system call.
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- Note: The kernel reports -EINVAL for any unexpected data. The caller
- must make sure that all data matches the constraints given in
- /proc/crypto for the selected cipher.
- </para>
-
- <para>
- With the recv() system call, the application can read the result of
- the cipher operation from the kernel crypto API. The output buffer
- must be at least as large as to hold all blocks of the encrypted or
- decrypted data. If the output data size is smaller, only as many
- blocks are returned that fit into that output buffer size.
- </para>
- </sect1>
-
- <sect1><title>AEAD Cipher API</title>
- <para>
- The operation is very similar to the symmetric cipher discussion.
- During initialization, the struct sockaddr data structure must be
- filled as follows:
- </para>
-
- <programlisting>
-struct sockaddr_alg sa = {
- .salg_family = AF_ALG,
- .salg_type = "aead", /* this selects the symmetric cipher */
- .salg_name = "gcm(aes)" /* this is the cipher name */
-};
- </programlisting>
-
- <para>
- Before data can be sent to the kernel using the write/send system
- call family, the consumer must set the key. The key setting is
- described with the setsockopt invocation below.
- </para>
-
- <para>
- In addition, before data can be sent to the kernel using the
- write/send system call family, the consumer must set the authentication
- tag size. To set the authentication tag size, the caller must use the
- setsockopt invocation described below.
- </para>
-
- <para>
- Using the sendmsg() system call, the application provides the data that should be processed for encryption or decryption. In addition, the IV is
- specified with the data structure provided by the sendmsg() system call.
- </para>
-
- <para>
- The sendmsg system call parameter of struct msghdr is embedded into the
- struct cmsghdr data structure. See recv(2) and cmsg(3) for more
- information on how the cmsghdr data structure is used together with the
- send/recv system call family. That cmsghdr data structure holds the
- following information specified with a separate header instances:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- specification of the cipher operation type with one of these flags:
- </para>
- <itemizedlist>
- <listitem>
- <para>ALG_OP_ENCRYPT - encryption of data</para>
- </listitem>
- <listitem>
- <para>ALG_OP_DECRYPT - decryption of data</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>
- specification of the IV information marked with the flag ALG_SET_IV
- </para>
- </listitem>
-
- <listitem>
- <para>
- specification of the associated authentication data (AAD) with the
- flag ALG_SET_AEAD_ASSOCLEN. The AAD is sent to the kernel together
- with the plaintext / ciphertext. See below for the memory structure.
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- The send system call family allows the following flag to be specified:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- MSG_MORE: If this flag is set, the send system call acts like a
- cipher update function where more input data is expected
- with a subsequent invocation of the send system call.
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- Note: The kernel reports -EINVAL for any unexpected data. The caller
- must make sure that all data matches the constraints given in
- /proc/crypto for the selected cipher.
- </para>
-
- <para>
- With the recv() system call, the application can read the result of
- the cipher operation from the kernel crypto API. The output buffer
- must be at least as large as defined with the memory structure below.
- If the output data size is smaller, the cipher operation is not performed.
- </para>
-
- <para>
- The authenticated decryption operation may indicate an integrity error.
- Such breach in integrity is marked with the -EBADMSG error code.
- </para>
-
- <sect2><title>AEAD Memory Structure</title>
- <para>
- The AEAD cipher operates with the following information that
- is communicated between user and kernel space as one data stream:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>plaintext or ciphertext</para>
- </listitem>
-
- <listitem>
- <para>associated authentication data (AAD)</para>
- </listitem>
-
- <listitem>
- <para>authentication tag</para>
- </listitem>
- </itemizedlist>
-
- <para>
- The sizes of the AAD and the authentication tag are provided with
- the sendmsg and setsockopt calls (see there). As the kernel knows
- the size of the entire data stream, the kernel is now able to
- calculate the right offsets of the data components in the data
- stream.
- </para>
-
- <para>
- The user space caller must arrange the aforementioned information
- in the following order:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- AEAD encryption input: AAD || plaintext
- </para>
- </listitem>
-
- <listitem>
- <para>
- AEAD decryption input: AAD || ciphertext || authentication tag
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- The output buffer the user space caller provides must be at least as
- large to hold the following data:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- AEAD encryption output: ciphertext || authentication tag
- </para>
- </listitem>
-
- <listitem>
- <para>
- AEAD decryption output: plaintext
- </para>
- </listitem>
- </itemizedlist>
- </sect2>
- </sect1>
-
- <sect1><title>Random Number Generator API</title>
- <para>
- Again, the operation is very similar to the other APIs.
- During initialization, the struct sockaddr data structure must be
- filled as follows:
- </para>
-
- <programlisting>
-struct sockaddr_alg sa = {
- .salg_family = AF_ALG,
- .salg_type = "rng", /* this selects the symmetric cipher */
- .salg_name = "drbg_nopr_sha256" /* this is the cipher name */
-};
- </programlisting>
-
- <para>
- Depending on the RNG type, the RNG must be seeded. The seed is provided
- using the setsockopt interface to set the key. For example, the
- ansi_cprng requires a seed. The DRBGs do not require a seed, but
- may be seeded.
- </para>
-
- <para>
- Using the read()/recvmsg() system calls, random numbers can be obtained.
- The kernel generates at most 128 bytes in one call. If user space
- requires more data, multiple calls to read()/recvmsg() must be made.
- </para>
-
- <para>
- WARNING: The user space caller may invoke the initially mentioned
- accept system call multiple times. In this case, the returned file
- descriptors have the same state.
- </para>
-
- </sect1>
-
- <sect1><title>Zero-Copy Interface</title>
- <para>
- In addition to the send/write/read/recv system call family, the AF_ALG
- interface can be accessed with the zero-copy interface of splice/vmsplice.
- As the name indicates, the kernel tries to avoid a copy operation into
- kernel space.
- </para>
-
- <para>
- The zero-copy operation requires data to be aligned at the page boundary.
- Non-aligned data can be used as well, but may require more operations of
- the kernel which would defeat the speed gains obtained from the zero-copy
- interface.
- </para>
-
- <para>
- The system-interent limit for the size of one zero-copy operation is
- 16 pages. If more data is to be sent to AF_ALG, user space must slice
- the input into segments with a maximum size of 16 pages.
- </para>
-
- <para>
- Zero-copy can be used with the following code example (a complete working
- example is provided with libkcapi):
- </para>
-
- <programlisting>
-int pipes[2];
-
-pipe(pipes);
-/* input data in iov */
-vmsplice(pipes[1], iov, iovlen, SPLICE_F_GIFT);
-/* opfd is the file descriptor returned from accept() system call */
-splice(pipes[0], NULL, opfd, NULL, ret, 0);
-read(opfd, out, outlen);
- </programlisting>
-
- </sect1>
-
- <sect1><title>Setsockopt Interface</title>
- <para>
- In addition to the read/recv and send/write system call handling
- to send and retrieve data subject to the cipher operation, a consumer
- also needs to set the additional information for the cipher operation.
- This additional information is set using the setsockopt system call
- that must be invoked with the file descriptor of the open cipher
- (i.e. the file descriptor returned by the accept system call).
- </para>
-
- <para>
- Each setsockopt invocation must use the level SOL_ALG.
- </para>
-
- <para>
- The setsockopt interface allows setting the following data using
- the mentioned optname:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- ALG_SET_KEY -- Setting the key. Key setting is applicable to:
- </para>
- <itemizedlist>
- <listitem>
- <para>the skcipher cipher type (symmetric ciphers)</para>
- </listitem>
- <listitem>
- <para>the hash cipher type (keyed message digests)</para>
- </listitem>
- <listitem>
- <para>the AEAD cipher type</para>
- </listitem>
- <listitem>
- <para>the RNG cipher type to provide the seed</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>
- ALG_SET_AEAD_AUTHSIZE -- Setting the authentication tag size
- for AEAD ciphers. For a encryption operation, the authentication
- tag of the given size will be generated. For a decryption operation,
- the provided ciphertext is assumed to contain an authentication tag
- of the given size (see section about AEAD memory layout below).
- </para>
- </listitem>
- </itemizedlist>
-
- </sect1>
-
- <sect1><title>User space API example</title>
- <para>
- Please see [1] for libkcapi which provides an easy-to-use wrapper
- around the aforementioned Netlink kernel interface. [1] also contains
- a test application that invokes all libkcapi API calls.
- </para>
-
- <para>
- [1] <ulink url="http://www.chronox.de/libkcapi.html">http://www.chronox.de/libkcapi.html</ulink>
- </para>
-
- </sect1>
-
- </chapter>
-
- <chapter id="API"><title>Programming Interface</title>
- <para>
- Please note that the kernel crypto API contains the AEAD givcrypt
- API (crypto_aead_giv* and aead_givcrypt_* function calls in
- include/crypto/aead.h). This API is obsolete and will be removed
- in the future. To obtain the functionality of an AEAD cipher with
- internal IV generation, use the IV generator as a regular cipher.
- For example, rfc4106(gcm(aes)) is the AEAD cipher with external
- IV generation and seqniv(rfc4106(gcm(aes))) implies that the kernel
- crypto API generates the IV. Different IV generators are available.
- </para>
- <sect1><title>Block Cipher Context Data Structures</title>
-!Pinclude/linux/crypto.h Block Cipher Context Data Structures
-!Finclude/crypto/aead.h aead_request
- </sect1>
- <sect1><title>Block Cipher Algorithm Definitions</title>
-!Pinclude/linux/crypto.h Block Cipher Algorithm Definitions
-!Finclude/linux/crypto.h crypto_alg
-!Finclude/linux/crypto.h ablkcipher_alg
-!Finclude/crypto/aead.h aead_alg
-!Finclude/linux/crypto.h blkcipher_alg
-!Finclude/linux/crypto.h cipher_alg
-!Finclude/crypto/rng.h rng_alg
- </sect1>
- <sect1><title>Symmetric Key Cipher API</title>
-!Pinclude/crypto/skcipher.h Symmetric Key Cipher API
-!Finclude/crypto/skcipher.h crypto_alloc_skcipher
-!Finclude/crypto/skcipher.h crypto_free_skcipher
-!Finclude/crypto/skcipher.h crypto_has_skcipher
-!Finclude/crypto/skcipher.h crypto_skcipher_ivsize
-!Finclude/crypto/skcipher.h crypto_skcipher_blocksize
-!Finclude/crypto/skcipher.h crypto_skcipher_setkey
-!Finclude/crypto/skcipher.h crypto_skcipher_reqtfm
-!Finclude/crypto/skcipher.h crypto_skcipher_encrypt
-!Finclude/crypto/skcipher.h crypto_skcipher_decrypt
- </sect1>
- <sect1><title>Symmetric Key Cipher Request Handle</title>
-!Pinclude/crypto/skcipher.h Symmetric Key Cipher Request Handle
-!Finclude/crypto/skcipher.h crypto_skcipher_reqsize
-!Finclude/crypto/skcipher.h skcipher_request_set_tfm
-!Finclude/crypto/skcipher.h skcipher_request_alloc
-!Finclude/crypto/skcipher.h skcipher_request_free
-!Finclude/crypto/skcipher.h skcipher_request_set_callback
-!Finclude/crypto/skcipher.h skcipher_request_set_crypt
- </sect1>
- <sect1><title>Asynchronous Block Cipher API - Deprecated</title>
-!Pinclude/linux/crypto.h Asynchronous Block Cipher API
-!Finclude/linux/crypto.h crypto_alloc_ablkcipher
-!Finclude/linux/crypto.h crypto_free_ablkcipher
-!Finclude/linux/crypto.h crypto_has_ablkcipher
-!Finclude/linux/crypto.h crypto_ablkcipher_ivsize
-!Finclude/linux/crypto.h crypto_ablkcipher_blocksize
-!Finclude/linux/crypto.h crypto_ablkcipher_setkey
-!Finclude/linux/crypto.h crypto_ablkcipher_reqtfm
-!Finclude/linux/crypto.h crypto_ablkcipher_encrypt
-!Finclude/linux/crypto.h crypto_ablkcipher_decrypt
- </sect1>
- <sect1><title>Asynchronous Cipher Request Handle - Deprecated</title>
-!Pinclude/linux/crypto.h Asynchronous Cipher Request Handle
-!Finclude/linux/crypto.h crypto_ablkcipher_reqsize
-!Finclude/linux/crypto.h ablkcipher_request_set_tfm
-!Finclude/linux/crypto.h ablkcipher_request_alloc
-!Finclude/linux/crypto.h ablkcipher_request_free
-!Finclude/linux/crypto.h ablkcipher_request_set_callback
-!Finclude/linux/crypto.h ablkcipher_request_set_crypt
- </sect1>
- <sect1><title>Authenticated Encryption With Associated Data (AEAD) Cipher API</title>
-!Pinclude/crypto/aead.h Authenticated Encryption With Associated Data (AEAD) Cipher API
-!Finclude/crypto/aead.h crypto_alloc_aead
-!Finclude/crypto/aead.h crypto_free_aead
-!Finclude/crypto/aead.h crypto_aead_ivsize
-!Finclude/crypto/aead.h crypto_aead_authsize
-!Finclude/crypto/aead.h crypto_aead_blocksize
-!Finclude/crypto/aead.h crypto_aead_setkey
-!Finclude/crypto/aead.h crypto_aead_setauthsize
-!Finclude/crypto/aead.h crypto_aead_encrypt
-!Finclude/crypto/aead.h crypto_aead_decrypt
- </sect1>
- <sect1><title>Asynchronous AEAD Request Handle</title>
-!Pinclude/crypto/aead.h Asynchronous AEAD Request Handle
-!Finclude/crypto/aead.h crypto_aead_reqsize
-!Finclude/crypto/aead.h aead_request_set_tfm
-!Finclude/crypto/aead.h aead_request_alloc
-!Finclude/crypto/aead.h aead_request_free
-!Finclude/crypto/aead.h aead_request_set_callback
-!Finclude/crypto/aead.h aead_request_set_crypt
-!Finclude/crypto/aead.h aead_request_set_ad
- </sect1>
- <sect1><title>Synchronous Block Cipher API - Deprecated</title>
-!Pinclude/linux/crypto.h Synchronous Block Cipher API
-!Finclude/linux/crypto.h crypto_alloc_blkcipher
-!Finclude/linux/crypto.h crypto_free_blkcipher
-!Finclude/linux/crypto.h crypto_has_blkcipher
-!Finclude/linux/crypto.h crypto_blkcipher_name
-!Finclude/linux/crypto.h crypto_blkcipher_ivsize
-!Finclude/linux/crypto.h crypto_blkcipher_blocksize
-!Finclude/linux/crypto.h crypto_blkcipher_setkey
-!Finclude/linux/crypto.h crypto_blkcipher_encrypt
-!Finclude/linux/crypto.h crypto_blkcipher_encrypt_iv
-!Finclude/linux/crypto.h crypto_blkcipher_decrypt
-!Finclude/linux/crypto.h crypto_blkcipher_decrypt_iv
-!Finclude/linux/crypto.h crypto_blkcipher_set_iv
-!Finclude/linux/crypto.h crypto_blkcipher_get_iv
- </sect1>
- <sect1><title>Single Block Cipher API</title>
-!Pinclude/linux/crypto.h Single Block Cipher API
-!Finclude/linux/crypto.h crypto_alloc_cipher
-!Finclude/linux/crypto.h crypto_free_cipher
-!Finclude/linux/crypto.h crypto_has_cipher
-!Finclude/linux/crypto.h crypto_cipher_blocksize
-!Finclude/linux/crypto.h crypto_cipher_setkey
-!Finclude/linux/crypto.h crypto_cipher_encrypt_one
-!Finclude/linux/crypto.h crypto_cipher_decrypt_one
- </sect1>
- <sect1><title>Message Digest Algorithm Definitions</title>
-!Pinclude/crypto/hash.h Message Digest Algorithm Definitions
-!Finclude/crypto/hash.h hash_alg_common
-!Finclude/crypto/hash.h ahash_alg
-!Finclude/crypto/hash.h shash_alg
- </sect1>
- <sect1><title>Asynchronous Message Digest API</title>
-!Pinclude/crypto/hash.h Asynchronous Message Digest API
-!Finclude/crypto/hash.h crypto_alloc_ahash
-!Finclude/crypto/hash.h crypto_free_ahash
-!Finclude/crypto/hash.h crypto_ahash_init
-!Finclude/crypto/hash.h crypto_ahash_digestsize
-!Finclude/crypto/hash.h crypto_ahash_reqtfm
-!Finclude/crypto/hash.h crypto_ahash_reqsize
-!Finclude/crypto/hash.h crypto_ahash_setkey
-!Finclude/crypto/hash.h crypto_ahash_finup
-!Finclude/crypto/hash.h crypto_ahash_final
-!Finclude/crypto/hash.h crypto_ahash_digest
-!Finclude/crypto/hash.h crypto_ahash_export
-!Finclude/crypto/hash.h crypto_ahash_import
- </sect1>
- <sect1><title>Asynchronous Hash Request Handle</title>
-!Pinclude/crypto/hash.h Asynchronous Hash Request Handle
-!Finclude/crypto/hash.h ahash_request_set_tfm
-!Finclude/crypto/hash.h ahash_request_alloc
-!Finclude/crypto/hash.h ahash_request_free
-!Finclude/crypto/hash.h ahash_request_set_callback
-!Finclude/crypto/hash.h ahash_request_set_crypt
- </sect1>
- <sect1><title>Synchronous Message Digest API</title>
-!Pinclude/crypto/hash.h Synchronous Message Digest API
-!Finclude/crypto/hash.h crypto_alloc_shash
-!Finclude/crypto/hash.h crypto_free_shash
-!Finclude/crypto/hash.h crypto_shash_blocksize
-!Finclude/crypto/hash.h crypto_shash_digestsize
-!Finclude/crypto/hash.h crypto_shash_descsize
-!Finclude/crypto/hash.h crypto_shash_setkey
-!Finclude/crypto/hash.h crypto_shash_digest
-!Finclude/crypto/hash.h crypto_shash_export
-!Finclude/crypto/hash.h crypto_shash_import
-!Finclude/crypto/hash.h crypto_shash_init
-!Finclude/crypto/hash.h crypto_shash_update
-!Finclude/crypto/hash.h crypto_shash_final
-!Finclude/crypto/hash.h crypto_shash_finup
- </sect1>
- <sect1><title>Crypto API Random Number API</title>
-!Pinclude/crypto/rng.h Random number generator API
-!Finclude/crypto/rng.h crypto_alloc_rng
-!Finclude/crypto/rng.h crypto_rng_alg
-!Finclude/crypto/rng.h crypto_free_rng
-!Finclude/crypto/rng.h crypto_rng_generate
-!Finclude/crypto/rng.h crypto_rng_get_bytes
-!Finclude/crypto/rng.h crypto_rng_reset
-!Finclude/crypto/rng.h crypto_rng_seedsize
-!Cinclude/crypto/rng.h
- </sect1>
- <sect1><title>Asymmetric Cipher API</title>
-!Pinclude/crypto/akcipher.h Generic Public Key API
-!Finclude/crypto/akcipher.h akcipher_alg
-!Finclude/crypto/akcipher.h akcipher_request
-!Finclude/crypto/akcipher.h crypto_alloc_akcipher
-!Finclude/crypto/akcipher.h crypto_free_akcipher
-!Finclude/crypto/akcipher.h crypto_akcipher_set_pub_key
-!Finclude/crypto/akcipher.h crypto_akcipher_set_priv_key
- </sect1>
- <sect1><title>Asymmetric Cipher Request Handle</title>
-!Finclude/crypto/akcipher.h akcipher_request_alloc
-!Finclude/crypto/akcipher.h akcipher_request_free
-!Finclude/crypto/akcipher.h akcipher_request_set_callback
-!Finclude/crypto/akcipher.h akcipher_request_set_crypt
-!Finclude/crypto/akcipher.h crypto_akcipher_maxsize
-!Finclude/crypto/akcipher.h crypto_akcipher_encrypt
-!Finclude/crypto/akcipher.h crypto_akcipher_decrypt
-!Finclude/crypto/akcipher.h crypto_akcipher_sign
-!Finclude/crypto/akcipher.h crypto_akcipher_verify
- </sect1>
- </chapter>
-
- <chapter id="Code"><title>Code Examples</title>
- <sect1><title>Code Example For Symmetric Key Cipher Operation</title>
- <programlisting>
-
-struct tcrypt_result {
- struct completion completion;
- int err;
-};
-
-/* tie all data structures together */
-struct skcipher_def {
- struct scatterlist sg;
- struct crypto_skcipher *tfm;
- struct skcipher_request *req;
- struct tcrypt_result result;
-};
-
-/* Callback function */
-static void test_skcipher_cb(struct crypto_async_request *req, int error)
-{
- struct tcrypt_result *result = req-&gt;data;
-
- if (error == -EINPROGRESS)
- return;
- result-&gt;err = error;
- complete(&amp;result-&gt;completion);
- pr_info("Encryption finished successfully\n");
-}
-
-/* Perform cipher operation */
-static unsigned int test_skcipher_encdec(struct skcipher_def *sk,
- int enc)
-{
- int rc = 0;
-
- if (enc)
- rc = crypto_skcipher_encrypt(sk-&gt;req);
- else
- rc = crypto_skcipher_decrypt(sk-&gt;req);
-
- switch (rc) {
- case 0:
- break;
- case -EINPROGRESS:
- case -EBUSY:
- rc = wait_for_completion_interruptible(
- &amp;sk-&gt;result.completion);
- if (!rc &amp;&amp; !sk-&gt;result.err) {
- reinit_completion(&amp;sk-&gt;result.completion);
- break;
- }
- default:
- pr_info("skcipher encrypt returned with %d result %d\n",
- rc, sk-&gt;result.err);
- break;
- }
- init_completion(&amp;sk-&gt;result.completion);
-
- return rc;
-}
-
-/* Initialize and trigger cipher operation */
-static int test_skcipher(void)
-{
- struct skcipher_def sk;
- struct crypto_skcipher *skcipher = NULL;
- struct skcipher_request *req = NULL;
- char *scratchpad = NULL;
- char *ivdata = NULL;
- unsigned char key[32];
- int ret = -EFAULT;
-
- skcipher = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0);
- if (IS_ERR(skcipher)) {
- pr_info("could not allocate skcipher handle\n");
- return PTR_ERR(skcipher);
- }
-
- req = skcipher_request_alloc(skcipher, GFP_KERNEL);
- if (!req) {
- pr_info("could not allocate skcipher request\n");
- ret = -ENOMEM;
- goto out;
- }
-
- skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
- test_skcipher_cb,
- &amp;sk.result);
-
- /* AES 256 with random key */
- get_random_bytes(&amp;key, 32);
- if (crypto_skcipher_setkey(skcipher, key, 32)) {
- pr_info("key could not be set\n");
- ret = -EAGAIN;
- goto out;
- }
-
- /* IV will be random */
- ivdata = kmalloc(16, GFP_KERNEL);
- if (!ivdata) {
- pr_info("could not allocate ivdata\n");
- goto out;
- }
- get_random_bytes(ivdata, 16);
-
- /* Input data will be random */
- scratchpad = kmalloc(16, GFP_KERNEL);
- if (!scratchpad) {
- pr_info("could not allocate scratchpad\n");
- goto out;
- }
- get_random_bytes(scratchpad, 16);
-
- sk.tfm = skcipher;
- sk.req = req;
-
- /* We encrypt one block */
- sg_init_one(&amp;sk.sg, scratchpad, 16);
- skcipher_request_set_crypt(req, &amp;sk.sg, &amp;sk.sg, 16, ivdata);
- init_completion(&amp;sk.result.completion);
-
- /* encrypt data */
- ret = test_skcipher_encdec(&amp;sk, 1);
- if (ret)
- goto out;
-
- pr_info("Encryption triggered successfully\n");
-
-out:
- if (skcipher)
- crypto_free_skcipher(skcipher);
- if (req)
- skcipher_request_free(req);
- if (ivdata)
- kfree(ivdata);
- if (scratchpad)
- kfree(scratchpad);
- return ret;
-}
- </programlisting>
- </sect1>
-
- <sect1><title>Code Example For Use of Operational State Memory With SHASH</title>
- <programlisting>
-
-struct sdesc {
- struct shash_desc shash;
- char ctx[];
-};
-
-static struct sdescinit_sdesc(struct crypto_shash *alg)
-{
- struct sdescsdesc;
- int size;
-
- size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
- sdesc = kmalloc(size, GFP_KERNEL);
- if (!sdesc)
- return ERR_PTR(-ENOMEM);
- sdesc-&gt;shash.tfm = alg;
- sdesc-&gt;shash.flags = 0x0;
- return sdesc;
-}
-
-static int calc_hash(struct crypto_shashalg,
- const unsigned chardata, unsigned int datalen,
- unsigned chardigest) {
- struct sdescsdesc;
- int ret;
-
- sdesc = init_sdesc(alg);
- if (IS_ERR(sdesc)) {
- pr_info("trusted_key: can't alloc %s\n", hash_alg);
- return PTR_ERR(sdesc);
- }
-
- ret = crypto_shash_digest(&amp;sdesc-&gt;shash, data, datalen, digest);
- kfree(sdesc);
- return ret;
-}
- </programlisting>
- </sect1>
-
- <sect1><title>Code Example For Random Number Generator Usage</title>
- <programlisting>
-
-static int get_random_numbers(u8 *buf, unsigned int len)
-{
- struct crypto_rngrng = NULL;
- chardrbg = "drbg_nopr_sha256"; /* Hash DRBG with SHA-256, no PR */
- int ret;
-
- if (!buf || !len) {
- pr_debug("No output buffer provided\n");
- return -EINVAL;
- }
-
- rng = crypto_alloc_rng(drbg, 0, 0);
- if (IS_ERR(rng)) {
- pr_debug("could not allocate RNG handle for %s\n", drbg);
- return -PTR_ERR(rng);
- }
-
- ret = crypto_rng_get_bytes(rng, buf, len);
- if (ret &lt; 0)
- pr_debug("generation of random numbers failed\n");
- else if (ret == 0)
- pr_debug("RNG returned no data");
- else
- pr_debug("RNG returned %d bytes of data\n", ret);
-
-out:
- crypto_free_rng(rng);
- return ret;
-}
- </programlisting>
- </sect1>
- </chapter>
- </book>
diff --git a/Documentation/DocBook/debugobjects.tmpl b/Documentation/DocBook/debugobjects.tmpl
deleted file mode 100644
index 7e4f34fde697..000000000000
--- a/Documentation/DocBook/debugobjects.tmpl
+++ /dev/null
@@ -1,443 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="debug-objects-guide">
- <bookinfo>
- <title>Debug objects life time</title>
-
- <authorgroup>
- <author>
- <firstname>Thomas</firstname>
- <surname>Gleixner</surname>
- <affiliation>
- <address>
- <email>tglx@linutronix.de</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2008</year>
- <holder>Thomas Gleixner</holder>
- </copyright>
-
- <legalnotice>
- <para>
- This documentation is free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public
- License version 2 as published by the Free Software Foundation.
- </para>
-
- <para>
- 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.
- </para>
-
- <para>
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
- </bookinfo>
-
-<toc></toc>
-
- <chapter id="intro">
- <title>Introduction</title>
- <para>
- debugobjects is a generic infrastructure to track the life time
- of kernel objects and validate the operations on those.
- </para>
- <para>
- debugobjects is useful to check for the following error patterns:
- <itemizedlist>
- <listitem><para>Activation of uninitialized objects</para></listitem>
- <listitem><para>Initialization of active objects</para></listitem>
- <listitem><para>Usage of freed/destroyed objects</para></listitem>
- </itemizedlist>
- </para>
- <para>
- debugobjects is not changing the data structure of the real
- object so it can be compiled in with a minimal runtime impact
- and enabled on demand with a kernel command line option.
- </para>
- </chapter>
-
- <chapter id="howto">
- <title>Howto use debugobjects</title>
- <para>
- A kernel subsystem needs to provide a data structure which
- describes the object type and add calls into the debug code at
- appropriate places. The data structure to describe the object
- type needs at minimum the name of the object type. Optional
- functions can and should be provided to fixup detected problems
- so the kernel can continue to work and the debug information can
- be retrieved from a live system instead of hard core debugging
- with serial consoles and stack trace transcripts from the
- monitor.
- </para>
- <para>
- The debug calls provided by debugobjects are:
- <itemizedlist>
- <listitem><para>debug_object_init</para></listitem>
- <listitem><para>debug_object_init_on_stack</para></listitem>
- <listitem><para>debug_object_activate</para></listitem>
- <listitem><para>debug_object_deactivate</para></listitem>
- <listitem><para>debug_object_destroy</para></listitem>
- <listitem><para>debug_object_free</para></listitem>
- <listitem><para>debug_object_assert_init</para></listitem>
- </itemizedlist>
- Each of these functions takes the address of the real object and
- a pointer to the object type specific debug description
- structure.
- </para>
- <para>
- Each detected error is reported in the statistics and a limited
- number of errors are printk'ed including a full stack trace.
- </para>
- <para>
- The statistics are available via /sys/kernel/debug/debug_objects/stats.
- They provide information about the number of warnings and the
- number of successful fixups along with information about the
- usage of the internal tracking objects and the state of the
- internal tracking objects pool.
- </para>
- </chapter>
- <chapter id="debugfunctions">
- <title>Debug functions</title>
- <sect1 id="prototypes">
- <title>Debug object function reference</title>
-!Elib/debugobjects.c
- </sect1>
- <sect1 id="debug_object_init">
- <title>debug_object_init</title>
- <para>
- This function is called whenever the initialization function
- of a real object is called.
- </para>
- <para>
- When the real object is already tracked by debugobjects it is
- checked, whether the object can be initialized. Initializing
- is not allowed for active and destroyed objects. When
- debugobjects detects an error, then it calls the fixup_init
- function of the object type description structure if provided
- by the caller. The fixup function can correct the problem
- before the real initialization of the object happens. E.g. it
- can deactivate an active object in order to prevent damage to
- the subsystem.
- </para>
- <para>
- When the real object is not yet tracked by debugobjects,
- debugobjects allocates a tracker object for the real object
- and sets the tracker object state to ODEBUG_STATE_INIT. It
- verifies that the object is not on the callers stack. If it is
- on the callers stack then a limited number of warnings
- including a full stack trace is printk'ed. The calling code
- must use debug_object_init_on_stack() and remove the object
- before leaving the function which allocated it. See next
- section.
- </para>
- </sect1>
-
- <sect1 id="debug_object_init_on_stack">
- <title>debug_object_init_on_stack</title>
- <para>
- This function is called whenever the initialization function
- of a real object which resides on the stack is called.
- </para>
- <para>
- When the real object is already tracked by debugobjects it is
- checked, whether the object can be initialized. Initializing
- is not allowed for active and destroyed objects. When
- debugobjects detects an error, then it calls the fixup_init
- function of the object type description structure if provided
- by the caller. The fixup function can correct the problem
- before the real initialization of the object happens. E.g. it
- can deactivate an active object in order to prevent damage to
- the subsystem.
- </para>
- <para>
- When the real object is not yet tracked by debugobjects
- debugobjects allocates a tracker object for the real object
- and sets the tracker object state to ODEBUG_STATE_INIT. It
- verifies that the object is on the callers stack.
- </para>
- <para>
- An object which is on the stack must be removed from the
- tracker by calling debug_object_free() before the function
- which allocates the object returns. Otherwise we keep track of
- stale objects.
- </para>
- </sect1>
-
- <sect1 id="debug_object_activate">
- <title>debug_object_activate</title>
- <para>
- This function is called whenever the activation function of a
- real object is called.
- </para>
- <para>
- When the real object is already tracked by debugobjects it is
- checked, whether the object can be activated. Activating is
- not allowed for active and destroyed objects. When
- debugobjects detects an error, then it calls the
- fixup_activate function of the object type description
- structure if provided by the caller. The fixup function can
- correct the problem before the real activation of the object
- happens. E.g. it can deactivate an active object in order to
- prevent damage to the subsystem.
- </para>
- <para>
- When the real object is not yet tracked by debugobjects then
- the fixup_activate function is called if available. This is
- necessary to allow the legitimate activation of statically
- allocated and initialized objects. The fixup function checks
- whether the object is valid and calls the debug_objects_init()
- function to initialize the tracking of this object.
- </para>
- <para>
- When the activation is legitimate, then the state of the
- associated tracker object is set to ODEBUG_STATE_ACTIVE.
- </para>
- </sect1>
-
- <sect1 id="debug_object_deactivate">
- <title>debug_object_deactivate</title>
- <para>
- This function is called whenever the deactivation function of
- a real object is called.
- </para>
- <para>
- When the real object is tracked by debugobjects it is checked,
- whether the object can be deactivated. Deactivating is not
- allowed for untracked or destroyed objects.
- </para>
- <para>
- When the deactivation is legitimate, then the state of the
- associated tracker object is set to ODEBUG_STATE_INACTIVE.
- </para>
- </sect1>
-
- <sect1 id="debug_object_destroy">
- <title>debug_object_destroy</title>
- <para>
- This function is called to mark an object destroyed. This is
- useful to prevent the usage of invalid objects, which are
- still available in memory: either statically allocated objects
- or objects which are freed later.
- </para>
- <para>
- When the real object is tracked by debugobjects it is checked,
- whether the object can be destroyed. Destruction is not
- allowed for active and destroyed objects. When debugobjects
- detects an error, then it calls the fixup_destroy function of
- the object type description structure if provided by the
- caller. The fixup function can correct the problem before the
- real destruction of the object happens. E.g. it can deactivate
- an active object in order to prevent damage to the subsystem.
- </para>
- <para>
- When the destruction is legitimate, then the state of the
- associated tracker object is set to ODEBUG_STATE_DESTROYED.
- </para>
- </sect1>
-
- <sect1 id="debug_object_free">
- <title>debug_object_free</title>
- <para>
- This function is called before an object is freed.
- </para>
- <para>
- When the real object is tracked by debugobjects it is checked,
- whether the object can be freed. Free is not allowed for
- active objects. When debugobjects detects an error, then it
- calls the fixup_free function of the object type description
- structure if provided by the caller. The fixup function can
- correct the problem before the real free of the object
- happens. E.g. it can deactivate an active object in order to
- prevent damage to the subsystem.
- </para>
- <para>
- Note that debug_object_free removes the object from the
- tracker. Later usage of the object is detected by the other
- debug checks.
- </para>
- </sect1>
-
- <sect1 id="debug_object_assert_init">
- <title>debug_object_assert_init</title>
- <para>
- This function is called to assert that an object has been
- initialized.
- </para>
- <para>
- When the real object is not tracked by debugobjects, it calls
- fixup_assert_init of the object type description structure
- provided by the caller, with the hardcoded object state
- ODEBUG_NOT_AVAILABLE. The fixup function can correct the problem
- by calling debug_object_init and other specific initializing
- functions.
- </para>
- <para>
- When the real object is already tracked by debugobjects it is
- ignored.
- </para>
- </sect1>
- </chapter>
- <chapter id="fixupfunctions">
- <title>Fixup functions</title>
- <sect1 id="debug_obj_descr">
- <title>Debug object type description structure</title>
-!Iinclude/linux/debugobjects.h
- </sect1>
- <sect1 id="fixup_init">
- <title>fixup_init</title>
- <para>
- This function is called from the debug code whenever a problem
- in debug_object_init is detected. The function takes the
- address of the object and the state which is currently
- recorded in the tracker.
- </para>
- <para>
- Called from debug_object_init when the object state is:
- <itemizedlist>
- <listitem><para>ODEBUG_STATE_ACTIVE</para></listitem>
- </itemizedlist>
- </para>
- <para>
- The function returns true when the fixup was successful,
- otherwise false. The return value is used to update the
- statistics.
- </para>
- <para>
- Note, that the function needs to call the debug_object_init()
- function again, after the damage has been repaired in order to
- keep the state consistent.
- </para>
- </sect1>
-
- <sect1 id="fixup_activate">
- <title>fixup_activate</title>
- <para>
- This function is called from the debug code whenever a problem
- in debug_object_activate is detected.
- </para>
- <para>
- Called from debug_object_activate when the object state is:
- <itemizedlist>
- <listitem><para>ODEBUG_STATE_NOTAVAILABLE</para></listitem>
- <listitem><para>ODEBUG_STATE_ACTIVE</para></listitem>
- </itemizedlist>
- </para>
- <para>
- The function returns true when the fixup was successful,
- otherwise false. The return value is used to update the
- statistics.
- </para>
- <para>
- Note that the function needs to call the debug_object_activate()
- function again after the damage has been repaired in order to
- keep the state consistent.
- </para>
- <para>
- The activation of statically initialized objects is a special
- case. When debug_object_activate() has no tracked object for
- this object address then fixup_activate() is called with
- object state ODEBUG_STATE_NOTAVAILABLE. The fixup function
- needs to check whether this is a legitimate case of a
- statically initialized object or not. In case it is it calls
- debug_object_init() and debug_object_activate() to make the
- object known to the tracker and marked active. In this case
- the function should return false because this is not a real
- fixup.
- </para>
- </sect1>
-
- <sect1 id="fixup_destroy">
- <title>fixup_destroy</title>
- <para>
- This function is called from the debug code whenever a problem
- in debug_object_destroy is detected.
- </para>
- <para>
- Called from debug_object_destroy when the object state is:
- <itemizedlist>
- <listitem><para>ODEBUG_STATE_ACTIVE</para></listitem>
- </itemizedlist>
- </para>
- <para>
- The function returns true when the fixup was successful,
- otherwise false. The return value is used to update the
- statistics.
- </para>
- </sect1>
- <sect1 id="fixup_free">
- <title>fixup_free</title>
- <para>
- This function is called from the debug code whenever a problem
- in debug_object_free is detected. Further it can be called
- from the debug checks in kfree/vfree, when an active object is
- detected from the debug_check_no_obj_freed() sanity checks.
- </para>
- <para>
- Called from debug_object_free() or debug_check_no_obj_freed()
- when the object state is:
- <itemizedlist>
- <listitem><para>ODEBUG_STATE_ACTIVE</para></listitem>
- </itemizedlist>
- </para>
- <para>
- The function returns true when the fixup was successful,
- otherwise false. The return value is used to update the
- statistics.
- </para>
- </sect1>
- <sect1 id="fixup_assert_init">
- <title>fixup_assert_init</title>
- <para>
- This function is called from the debug code whenever a problem
- in debug_object_assert_init is detected.
- </para>
- <para>
- Called from debug_object_assert_init() with a hardcoded state
- ODEBUG_STATE_NOTAVAILABLE when the object is not found in the
- debug bucket.
- </para>
- <para>
- The function returns true when the fixup was successful,
- otherwise false. The return value is used to update the
- statistics.
- </para>
- <para>
- Note, this function should make sure debug_object_init() is
- called before returning.
- </para>
- <para>
- The handling of statically initialized objects is a special
- case. The fixup function should check if this is a legitimate
- case of a statically initialized object or not. In this case only
- debug_object_init() should be called to make the object known to
- the tracker. Then the function should return false because this
- is not
- a real fixup.
- </para>
- </sect1>
- </chapter>
- <chapter id="bugs">
- <title>Known Bugs And Assumptions</title>
- <para>
- None (knock on wood).
- </para>
- </chapter>
-</book>
diff --git a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl
deleted file mode 100644
index 54199a0dcf9a..000000000000
--- a/Documentation/DocBook/deviceiobook.tmpl
+++ /dev/null
@@ -1,323 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="DoingIO">
- <bookinfo>
- <title>Bus-Independent Device Accesses</title>
-
- <authorgroup>
- <author>
- <firstname>Matthew</firstname>
- <surname>Wilcox</surname>
- <affiliation>
- <address>
- <email>matthew@wil.cx</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <authorgroup>
- <author>
- <firstname>Alan</firstname>
- <surname>Cox</surname>
- <affiliation>
- <address>
- <email>alan@lxorguk.ukuu.org.uk</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2001</year>
- <holder>Matthew Wilcox</holder>
- </copyright>
-
- <legalnotice>
- <para>
- This documentation is free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later
- version.
- </para>
-
- <para>
- 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.
- </para>
-
- <para>
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
- </bookinfo>
-
-<toc></toc>
-
- <chapter id="intro">
- <title>Introduction</title>
- <para>
- Linux provides an API which abstracts performing IO across all busses
- and devices, allowing device drivers to be written independently of
- bus type.
- </para>
- </chapter>
-
- <chapter id="bugs">
- <title>Known Bugs And Assumptions</title>
- <para>
- None.
- </para>
- </chapter>
-
- <chapter id="mmio">
- <title>Memory Mapped IO</title>
- <sect1 id="getting_access_to_the_device">
- <title>Getting Access to the Device</title>
- <para>
- The most widely supported form of IO is memory mapped IO.
- That is, a part of the CPU's address space is interpreted
- not as accesses to memory, but as accesses to a device. Some
- architectures define devices to be at a fixed address, but most
- have some method of discovering devices. The PCI bus walk is a
- good example of such a scheme. This document does not cover how
- to receive such an address, but assumes you are starting with one.
- Physical addresses are of type unsigned long.
- </para>
-
- <para>
- This address should not be used directly. Instead, to get an
- address suitable for passing to the accessor functions described
- below, you should call <function>ioremap</function>.
- An address suitable for accessing the device will be returned to you.
- </para>
-
- <para>
- After you've finished using the device (say, in your module's
- exit routine), call <function>iounmap</function> in order to return
- the address space to the kernel. Most architectures allocate new
- address space each time you call <function>ioremap</function>, and
- they can run out unless you call <function>iounmap</function>.
- </para>
- </sect1>
-
- <sect1 id="accessing_the_device">
- <title>Accessing the device</title>
- <para>
- The part of the interface most used by drivers is reading and
- writing memory-mapped registers on the device. Linux provides
- interfaces to read and write 8-bit, 16-bit, 32-bit and 64-bit
- quantities. Due to a historical accident, these are named byte,
- word, long and quad accesses. Both read and write accesses are
- supported; there is no prefetch support at this time.
- </para>
-
- <para>
- The functions are named <function>readb</function>,
- <function>readw</function>, <function>readl</function>,
- <function>readq</function>, <function>readb_relaxed</function>,
- <function>readw_relaxed</function>, <function>readl_relaxed</function>,
- <function>readq_relaxed</function>, <function>writeb</function>,
- <function>writew</function>, <function>writel</function> and
- <function>writeq</function>.
- </para>
-
- <para>
- Some devices (such as framebuffers) would like to use larger
- transfers than 8 bytes at a time. For these devices, the
- <function>memcpy_toio</function>, <function>memcpy_fromio</function>
- and <function>memset_io</function> functions are provided.
- Do not use memset or memcpy on IO addresses; they
- are not guaranteed to copy data in order.
- </para>
-
- <para>
- The read and write functions are defined to be ordered. That is the
- compiler is not permitted to reorder the I/O sequence. When the
- ordering can be compiler optimised, you can use <function>
- __readb</function> and friends to indicate the relaxed ordering. Use
- this with care.
- </para>
-
- <para>
- While the basic functions are defined to be synchronous with respect
- to each other and ordered with respect to each other the busses the
- devices sit on may themselves have asynchronicity. In particular many
- authors are burned by the fact that PCI bus writes are posted
- asynchronously. A driver author must issue a read from the same
- device to ensure that writes have occurred in the specific cases the
- author cares. This kind of property cannot be hidden from driver
- writers in the API. In some cases, the read used to flush the device
- may be expected to fail (if the card is resetting, for example). In
- that case, the read should be done from config space, which is
- guaranteed to soft-fail if the card doesn't respond.
- </para>
-
- <para>
- The following is an example of flushing a write to a device when
- the driver would like to ensure the write's effects are visible prior
- to continuing execution.
- </para>
-
-<programlisting>
-static inline void
-qla1280_disable_intrs(struct scsi_qla_host *ha)
-{
- struct device_reg *reg;
-
- reg = ha->iobase;
- /* disable risc and host interrupts */
- WRT_REG_WORD(&amp;reg->ictrl, 0);
- /*
- * The following read will ensure that the above write
- * has been received by the device before we return from this
- * function.
- */
- RD_REG_WORD(&amp;reg->ictrl);
- ha->flags.ints_enabled = 0;
-}
-</programlisting>
-
- <para>
- In addition to write posting, on some large multiprocessing systems
- (e.g. SGI Challenge, Origin and Altix machines) posted writes won't
- be strongly ordered coming from different CPUs. Thus it's important
- to properly protect parts of your driver that do memory-mapped writes
- with locks and use the <function>mmiowb</function> to make sure they
- arrive in the order intended. Issuing a regular <function>readX
- </function> will also ensure write ordering, but should only be used
- when the driver has to be sure that the write has actually arrived
- at the device (not that it's simply ordered with respect to other
- writes), since a full <function>readX</function> is a relatively
- expensive operation.
- </para>
-
- <para>
- Generally, one should use <function>mmiowb</function> prior to
- releasing a spinlock that protects regions using <function>writeb
- </function> or similar functions that aren't surrounded by <function>
- readb</function> calls, which will ensure ordering and flushing. The
- following pseudocode illustrates what might occur if write ordering
- isn't guaranteed via <function>mmiowb</function> or one of the
- <function>readX</function> functions.
- </para>
-
-<programlisting>
-CPU A: spin_lock_irqsave(&amp;dev_lock, flags)
-CPU A: ...
-CPU A: writel(newval, ring_ptr);
-CPU A: spin_unlock_irqrestore(&amp;dev_lock, flags)
- ...
-CPU B: spin_lock_irqsave(&amp;dev_lock, flags)
-CPU B: writel(newval2, ring_ptr);
-CPU B: ...
-CPU B: spin_unlock_irqrestore(&amp;dev_lock, flags)
-</programlisting>
-
- <para>
- In the case above, newval2 could be written to ring_ptr before
- newval. Fixing it is easy though:
- </para>
-
-<programlisting>
-CPU A: spin_lock_irqsave(&amp;dev_lock, flags)
-CPU A: ...
-CPU A: writel(newval, ring_ptr);
-CPU A: mmiowb(); /* ensure no other writes beat us to the device */
-CPU A: spin_unlock_irqrestore(&amp;dev_lock, flags)
- ...
-CPU B: spin_lock_irqsave(&amp;dev_lock, flags)
-CPU B: writel(newval2, ring_ptr);
-CPU B: ...
-CPU B: mmiowb();
-CPU B: spin_unlock_irqrestore(&amp;dev_lock, flags)
-</programlisting>
-
- <para>
- See tg3.c for a real world example of how to use <function>mmiowb
- </function>
- </para>
-
- <para>
- PCI ordering rules also guarantee that PIO read responses arrive
- after any outstanding DMA writes from that bus, since for some devices
- the result of a <function>readb</function> call may signal to the
- driver that a DMA transaction is complete. In many cases, however,
- the driver may want to indicate that the next
- <function>readb</function> call has no relation to any previous DMA
- writes performed by the device. The driver can use
- <function>readb_relaxed</function> for these cases, although only
- some platforms will honor the relaxed semantics. Using the relaxed
- read functions will provide significant performance benefits on
- platforms that support it. The qla2xxx driver provides examples
- of how to use <function>readX_relaxed</function>. In many cases,
- a majority of the driver's <function>readX</function> calls can
- safely be converted to <function>readX_relaxed</function> calls, since
- only a few will indicate or depend on DMA completion.
- </para>
- </sect1>
-
- </chapter>
-
- <chapter id="port_space_accesses">
- <title>Port Space Accesses</title>
- <sect1 id="port_space_explained">
- <title>Port Space Explained</title>
-
- <para>
- Another form of IO commonly supported is Port Space. This is a
- range of addresses separate to the normal memory address space.
- Access to these addresses is generally not as fast as accesses
- to the memory mapped addresses, and it also has a potentially
- smaller address space.
- </para>
-
- <para>
- Unlike memory mapped IO, no preparation is required
- to access port space.
- </para>
-
- </sect1>
- <sect1 id="accessing_port_space">
- <title>Accessing Port Space</title>
- <para>
- Accesses to this space are provided through a set of functions
- which allow 8-bit, 16-bit and 32-bit accesses; also
- known as byte, word and long. These functions are
- <function>inb</function>, <function>inw</function>,
- <function>inl</function>, <function>outb</function>,
- <function>outw</function> and <function>outl</function>.
- </para>
-
- <para>
- Some variants are provided for these functions. Some devices
- require that accesses to their ports are slowed down. This
- functionality is provided by appending a <function>_p</function>
- to the end of the function. There are also equivalents to memcpy.
- The <function>ins</function> and <function>outs</function>
- functions copy bytes, words or longs to the given port.
- </para>
- </sect1>
-
- </chapter>
-
- <chapter id="pubfunctions">
- <title>Public Functions Provided</title>
-!Iarch/x86/include/asm/io.h
-!Elib/pci_iomap.c
- </chapter>
-
-</book>
diff --git a/Documentation/DocBook/iio.tmpl b/Documentation/DocBook/iio.tmpl
deleted file mode 100644
index e2ab6a1f223e..000000000000
--- a/Documentation/DocBook/iio.tmpl
+++ /dev/null
@@ -1,697 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="iioid">
- <bookinfo>
- <title>Industrial I/O driver developer's guide </title>
-
- <authorgroup>
- <author>
- <firstname>Daniel</firstname>
- <surname>Baluta</surname>
- <affiliation>
- <address>
- <email>daniel.baluta@intel.com</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2015</year>
- <holder>Intel Corporation</holder>
- </copyright>
-
- <legalnotice>
- <para>
- This documentation is free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public
- License version 2.
- </para>
- </legalnotice>
- </bookinfo>
-
- <toc></toc>
-
- <chapter id="intro">
- <title>Introduction</title>
- <para>
- The main purpose of the Industrial I/O subsystem (IIO) is to provide
- support for devices that in some sense perform either analog-to-digital
- conversion (ADC) or digital-to-analog conversion (DAC) or both. The aim
- is to fill the gap between the somewhat similar hwmon and input
- subsystems.
- Hwmon is directed at low sample rate sensors used to monitor and
- control the system itself, like fan speed control or temperature
- measurement. Input is, as its name suggests, focused on human interaction
- input devices (keyboard, mouse, touchscreen). In some cases there is
- considerable overlap between these and IIO.
- </para>
- <para>
- Devices that fall into this category include:
- <itemizedlist>
- <listitem>
- analog to digital converters (ADCs)
- </listitem>
- <listitem>
- accelerometers
- </listitem>
- <listitem>
- capacitance to digital converters (CDCs)
- </listitem>
- <listitem>
- digital to analog converters (DACs)
- </listitem>
- <listitem>
- gyroscopes
- </listitem>
- <listitem>
- inertial measurement units (IMUs)
- </listitem>
- <listitem>
- color and light sensors
- </listitem>
- <listitem>
- magnetometers
- </listitem>
- <listitem>
- pressure sensors
- </listitem>
- <listitem>
- proximity sensors
- </listitem>
- <listitem>
- temperature sensors
- </listitem>
- </itemizedlist>
- Usually these sensors are connected via SPI or I2C. A common use case of the
- sensors devices is to have combined functionality (e.g. light plus proximity
- sensor).
- </para>
- </chapter>
- <chapter id='iiosubsys'>
- <title>Industrial I/O core</title>
- <para>
- The Industrial I/O core offers:
- <itemizedlist>
- <listitem>
- a unified framework for writing drivers for many different types of
- embedded sensors.
- </listitem>
- <listitem>
- a standard interface to user space applications manipulating sensors.
- </listitem>
- </itemizedlist>
- The implementation can be found under <filename>
- drivers/iio/industrialio-*</filename>
- </para>
- <sect1 id="iiodevice">
- <title> Industrial I/O devices </title>
-
-!Finclude/linux/iio/iio.h iio_dev
-!Fdrivers/iio/industrialio-core.c iio_device_alloc
-!Fdrivers/iio/industrialio-core.c iio_device_free
-!Fdrivers/iio/industrialio-core.c iio_device_register
-!Fdrivers/iio/industrialio-core.c iio_device_unregister
-
- <para>
- An IIO device usually corresponds to a single hardware sensor and it
- provides all the information needed by a driver handling a device.
- Let's first have a look at the functionality embedded in an IIO
- device then we will show how a device driver makes use of an IIO
- device.
- </para>
- <para>
- There are two ways for a user space application to interact
- with an IIO driver.
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/</filename>, this
- represents a hardware sensor and groups together the data
- channels of the same chip.
- </listitem>
- <listitem>
- <filename>/dev/iio:deviceX</filename>, character device node
- interface used for buffered data transfer and for events information
- retrieval.
- </listitem>
- </itemizedlist>
- </para>
- A typical IIO driver will register itself as an I2C or SPI driver and will
- create two routines, <function> probe </function> and <function> remove
- </function>. At <function>probe</function>:
- <itemizedlist>
- <listitem>call <function>iio_device_alloc</function>, which allocates memory
- for an IIO device.
- </listitem>
- <listitem> initialize IIO device fields with driver specific information
- (e.g. device name, device channels).
- </listitem>
- <listitem>call <function> iio_device_register</function>, this registers the
- device with the IIO core. After this call the device is ready to accept
- requests from user space applications.
- </listitem>
- </itemizedlist>
- At <function>remove</function>, we free the resources allocated in
- <function>probe</function> in reverse order:
- <itemizedlist>
- <listitem><function>iio_device_unregister</function>, unregister the device
- from the IIO core.
- </listitem>
- <listitem><function>iio_device_free</function>, free the memory allocated
- for the IIO device.
- </listitem>
- </itemizedlist>
-
- <sect2 id="iioattr"> <title> IIO device sysfs interface </title>
- <para>
- Attributes are sysfs files used to expose chip info and also allowing
- applications to set various configuration parameters. For device
- with index X, attributes can be found under
- <filename>/sys/bus/iio/iio:deviceX/ </filename> directory.
- Common attributes are:
- <itemizedlist>
- <listitem><filename>name</filename>, description of the physical
- chip.
- </listitem>
- <listitem><filename>dev</filename>, shows the major:minor pair
- associated with <filename>/dev/iio:deviceX</filename> node.
- </listitem>
- <listitem><filename>sampling_frequency_available</filename>,
- available discrete set of sampling frequency values for
- device.
- </listitem>
- </itemizedlist>
- Available standard attributes for IIO devices are described in the
- <filename>Documentation/ABI/testing/sysfs-bus-iio </filename> file
- in the Linux kernel sources.
- </para>
- </sect2>
- <sect2 id="iiochannel"> <title> IIO device channels </title>
-!Finclude/linux/iio/iio.h iio_chan_spec structure.
- <para>
- An IIO device channel is a representation of a data channel. An
- IIO device can have one or multiple channels. For example:
- <itemizedlist>
- <listitem>
- a thermometer sensor has one channel representing the
- temperature measurement.
- </listitem>
- <listitem>
- a light sensor with two channels indicating the measurements in
- the visible and infrared spectrum.
- </listitem>
- <listitem>
- an accelerometer can have up to 3 channels representing
- acceleration on X, Y and Z axes.
- </listitem>
- </itemizedlist>
- An IIO channel is described by the <type> struct iio_chan_spec
- </type>. A thermometer driver for the temperature sensor in the
- example above would have to describe its channel as follows:
- <programlisting>
- static const struct iio_chan_spec temp_channel[] = {
- {
- .type = IIO_TEMP,
- .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
- },
- };
-
- </programlisting>
- Channel sysfs attributes exposed to userspace are specified in
- the form of <emphasis>bitmasks</emphasis>. Depending on their
- shared info, attributes can be set in one of the following masks:
- <itemizedlist>
- <listitem><emphasis>info_mask_separate</emphasis>, attributes will
- be specific to this channel</listitem>
- <listitem><emphasis>info_mask_shared_by_type</emphasis>,
- attributes are shared by all channels of the same type</listitem>
- <listitem><emphasis>info_mask_shared_by_dir</emphasis>, attributes
- are shared by all channels of the same direction </listitem>
- <listitem><emphasis>info_mask_shared_by_all</emphasis>,
- attributes are shared by all channels</listitem>
- </itemizedlist>
- When there are multiple data channels per channel type we have two
- ways to distinguish between them:
- <itemizedlist>
- <listitem> set <emphasis> .modified</emphasis> field of <type>
- iio_chan_spec</type> to 1. Modifiers are specified using
- <emphasis>.channel2</emphasis> field of the same
- <type>iio_chan_spec</type> structure and are used to indicate a
- physically unique characteristic of the channel such as its direction
- or spectral response. For example, a light sensor can have two channels,
- one for infrared light and one for both infrared and visible light.
- </listitem>
- <listitem> set <emphasis>.indexed </emphasis> field of
- <type>iio_chan_spec</type> to 1. In this case the channel is
- simply another instance with an index specified by the
- <emphasis>.channel</emphasis> field.
- </listitem>
- </itemizedlist>
- Here is how we can make use of the channel's modifiers:
- <programlisting>
- static const struct iio_chan_spec light_channels[] = {
- {
- .type = IIO_INTENSITY,
- .modified = 1,
- .channel2 = IIO_MOD_LIGHT_IR,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
- },
- {
- .type = IIO_INTENSITY,
- .modified = 1,
- .channel2 = IIO_MOD_LIGHT_BOTH,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
- },
- {
- .type = IIO_LIGHT,
- .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
- .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
- },
-
- }
- </programlisting>
- This channel's definition will generate two separate sysfs files
- for raw data retrieval:
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/in_intensity_ir_raw</filename>
- </listitem>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/in_intensity_both_raw</filename>
- </listitem>
- </itemizedlist>
- one file for processed data:
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/in_illuminance_input
- </filename>
- </listitem>
- </itemizedlist>
- and one shared sysfs file for sampling frequency:
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/sampling_frequency.
- </filename>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- Here is how we can make use of the channel's indexing:
- <programlisting>
- static const struct iio_chan_spec light_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- },
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- },
- }
- </programlisting>
- This will generate two separate attributes files for raw data
- retrieval:
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/devices/iio:deviceX/in_voltage0_raw</filename>,
- representing voltage measurement for channel 0.
- </listitem>
- <listitem>
- <filename>/sys/bus/iio/devices/iio:deviceX/in_voltage1_raw</filename>,
- representing voltage measurement for channel 1.
- </listitem>
- </itemizedlist>
- </para>
- </sect2>
- </sect1>
-
- <sect1 id="iiobuffer"> <title> Industrial I/O buffers </title>
-!Finclude/linux/iio/buffer.h iio_buffer
-!Edrivers/iio/industrialio-buffer.c
-
- <para>
- The Industrial I/O core offers a way for continuous data capture
- based on a trigger source. Multiple data channels can be read at once
- from <filename>/dev/iio:deviceX</filename> character device node,
- thus reducing the CPU load.
- </para>
-
- <sect2 id="iiobuffersysfs">
- <title>IIO buffer sysfs interface </title>
- <para>
- An IIO buffer has an associated attributes directory under <filename>
- /sys/bus/iio/iio:deviceX/buffer/</filename>. Here are the existing
- attributes:
- <itemizedlist>
- <listitem>
- <emphasis>length</emphasis>, the total number of data samples
- (capacity) that can be stored by the buffer.
- </listitem>
- <listitem>
- <emphasis>enable</emphasis>, activate buffer capture.
- </listitem>
- </itemizedlist>
-
- </para>
- </sect2>
- <sect2 id="iiobuffersetup"> <title> IIO buffer setup </title>
- <para>The meta information associated with a channel reading
- placed in a buffer is called a <emphasis> scan element </emphasis>.
- The important bits configuring scan elements are exposed to
- userspace applications via the <filename>
- /sys/bus/iio/iio:deviceX/scan_elements/</filename> directory. This
- file contains attributes of the following form:
- <itemizedlist>
- <listitem><emphasis>enable</emphasis>, used for enabling a channel.
- If and only if its attribute is non zero, then a triggered capture
- will contain data samples for this channel.
- </listitem>
- <listitem><emphasis>type</emphasis>, description of the scan element
- data storage within the buffer and hence the form in which it is
- read from user space. Format is <emphasis>
- [be|le]:[s|u]bits/storagebitsXrepeat[>>shift] </emphasis>.
- <itemizedlist>
- <listitem> <emphasis>be</emphasis> or <emphasis>le</emphasis>, specifies
- big or little endian.
- </listitem>
- <listitem>
- <emphasis>s </emphasis>or <emphasis>u</emphasis>, specifies if
- signed (2's complement) or unsigned.
- </listitem>
- <listitem><emphasis>bits</emphasis>, is the number of valid data
- bits.
- </listitem>
- <listitem><emphasis>storagebits</emphasis>, is the number of bits
- (after padding) that it occupies in the buffer.
- </listitem>
- <listitem>
- <emphasis>shift</emphasis>, if specified, is the shift that needs
- to be applied prior to masking out unused bits.
- </listitem>
- <listitem>
- <emphasis>repeat</emphasis>, specifies the number of bits/storagebits
- repetitions. When the repeat element is 0 or 1, then the repeat
- value is omitted.
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- For example, a driver for a 3-axis accelerometer with 12 bit
- resolution where data is stored in two 8-bits registers as
- follows:
- <programlisting>
- 7 6 5 4 3 2 1 0
- +---+---+---+---+---+---+---+---+
- |D3 |D2 |D1 |D0 | X | X | X | X | (LOW byte, address 0x06)
- +---+---+---+---+---+---+---+---+
-
- 7 6 5 4 3 2 1 0
- +---+---+---+---+---+---+---+---+
- |D11|D10|D9 |D8 |D7 |D6 |D5 |D4 | (HIGH byte, address 0x07)
- +---+---+---+---+---+---+---+---+
- </programlisting>
-
- will have the following scan element type for each axis:
- <programlisting>
- $ cat /sys/bus/iio/devices/iio:device0/scan_elements/in_accel_y_type
- le:s12/16>>4
- </programlisting>
- A user space application will interpret data samples read from the
- buffer as two byte little endian signed data, that needs a 4 bits
- right shift before masking out the 12 valid bits of data.
- </para>
- <para>
- For implementing buffer support a driver should initialize the following
- fields in <type>iio_chan_spec</type> definition:
- <programlisting>
- struct iio_chan_spec {
- /* other members */
- int scan_index
- struct {
- char sign;
- u8 realbits;
- u8 storagebits;
- u8 shift;
- u8 repeat;
- enum iio_endian endianness;
- } scan_type;
- };
- </programlisting>
- The driver implementing the accelerometer described above will
- have the following channel definition:
- <programlisting>
- struct struct iio_chan_spec accel_channels[] = {
- {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- /* other stuff here */
- .scan_index = 0,
- .scan_type = {
- .sign = 's',
- .realbits = 12,
- .storagebits = 16,
- .shift = 4,
- .endianness = IIO_LE,
- },
- }
- /* similar for Y (with channel2 = IIO_MOD_Y, scan_index = 1)
- * and Z (with channel2 = IIO_MOD_Z, scan_index = 2) axis
- */
- }
- </programlisting>
- </para>
- <para>
- Here <emphasis> scan_index </emphasis> defines the order in which
- the enabled channels are placed inside the buffer. Channels with a lower
- scan_index will be placed before channels with a higher index. Each
- channel needs to have a unique scan_index.
- </para>
- <para>
- Setting scan_index to -1 can be used to indicate that the specific
- channel does not support buffered capture. In this case no entries will
- be created for the channel in the scan_elements directory.
- </para>
- </sect2>
- </sect1>
-
- <sect1 id="iiotrigger"> <title> Industrial I/O triggers </title>
-!Finclude/linux/iio/trigger.h iio_trigger
-!Edrivers/iio/industrialio-trigger.c
- <para>
- In many situations it is useful for a driver to be able to
- capture data based on some external event (trigger) as opposed
- to periodically polling for data. An IIO trigger can be provided
- by a device driver that also has an IIO device based on hardware
- generated events (e.g. data ready or threshold exceeded) or
- provided by a separate driver from an independent interrupt
- source (e.g. GPIO line connected to some external system, timer
- interrupt or user space writing a specific file in sysfs). A
- trigger may initiate data capture for a number of sensors and
- also it may be completely unrelated to the sensor itself.
- </para>
-
- <sect2 id="iiotrigsysfs"> <title> IIO trigger sysfs interface </title>
- There are two locations in sysfs related to triggers:
- <itemizedlist>
- <listitem><filename>/sys/bus/iio/devices/triggerY</filename>,
- this file is created once an IIO trigger is registered with
- the IIO core and corresponds to trigger with index Y. Because
- triggers can be very different depending on type there are few
- standard attributes that we can describe here:
- <itemizedlist>
- <listitem>
- <emphasis>name</emphasis>, trigger name that can be later
- used for association with a device.
- </listitem>
- <listitem>
- <emphasis>sampling_frequency</emphasis>, some timer based
- triggers use this attribute to specify the frequency for
- trigger calls.
- </listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <filename>/sys/bus/iio/devices/iio:deviceX/trigger/</filename>, this
- directory is created once the device supports a triggered
- buffer. We can associate a trigger with our device by writing
- the trigger's name in the <filename>current_trigger</filename> file.
- </listitem>
- </itemizedlist>
- </sect2>
-
- <sect2 id="iiotrigattr"> <title> IIO trigger setup</title>
-
- <para>
- Let's see a simple example of how to setup a trigger to be used
- by a driver.
-
- <programlisting>
- struct iio_trigger_ops trigger_ops = {
- .set_trigger_state = sample_trigger_state,
- .validate_device = sample_validate_device,
- }
-
- struct iio_trigger *trig;
-
- /* first, allocate memory for our trigger */
- trig = iio_trigger_alloc(dev, "trig-%s-%d", name, idx);
-
- /* setup trigger operations field */
- trig->ops = &amp;trigger_ops;
-
- /* now register the trigger with the IIO core */
- iio_trigger_register(trig);
- </programlisting>
- </para>
- </sect2>
-
- <sect2 id="iiotrigsetup"> <title> IIO trigger ops</title>
-!Finclude/linux/iio/trigger.h iio_trigger_ops
- <para>
- Notice that a trigger has a set of operations attached:
- <itemizedlist>
- <listitem>
- <function>set_trigger_state</function>, switch the trigger on/off
- on demand.
- </listitem>
- <listitem>
- <function>validate_device</function>, function to validate the
- device when the current trigger gets changed.
- </listitem>
- </itemizedlist>
- </para>
- </sect2>
- </sect1>
- <sect1 id="iiotriggered_buffer">
- <title> Industrial I/O triggered buffers </title>
- <para>
- Now that we know what buffers and triggers are let's see how they
- work together.
- </para>
- <sect2 id="iiotrigbufsetup"> <title> IIO triggered buffer setup</title>
-!Edrivers/iio/buffer/industrialio-triggered-buffer.c
-!Finclude/linux/iio/iio.h iio_buffer_setup_ops
-
-
- <para>
- A typical triggered buffer setup looks like this:
- <programlisting>
- const struct iio_buffer_setup_ops sensor_buffer_setup_ops = {
- .preenable = sensor_buffer_preenable,
- .postenable = sensor_buffer_postenable,
- .postdisable = sensor_buffer_postdisable,
- .predisable = sensor_buffer_predisable,
- };
-
- irqreturn_t sensor_iio_pollfunc(int irq, void *p)
- {
- pf->timestamp = iio_get_time_ns((struct indio_dev *)p);
- return IRQ_WAKE_THREAD;
- }
-
- irqreturn_t sensor_trigger_handler(int irq, void *p)
- {
- u16 buf[8];
- int i = 0;
-
- /* read data for each active channel */
- for_each_set_bit(bit, active_scan_mask, masklength)
- buf[i++] = sensor_get_data(bit)
-
- iio_push_to_buffers_with_timestamp(indio_dev, buf, timestamp);
-
- iio_trigger_notify_done(trigger);
- return IRQ_HANDLED;
- }
-
- /* setup triggered buffer, usually in probe function */
- iio_triggered_buffer_setup(indio_dev, sensor_iio_polfunc,
- sensor_trigger_handler,
- sensor_buffer_setup_ops);
- </programlisting>
- </para>
- The important things to notice here are:
- <itemizedlist>
- <listitem><function> iio_buffer_setup_ops</function>, the buffer setup
- functions to be called at predefined points in the buffer configuration
- sequence (e.g. before enable, after disable). If not specified, the
- IIO core uses the default <type>iio_triggered_buffer_setup_ops</type>.
- </listitem>
- <listitem><function>sensor_iio_pollfunc</function>, the function that
- will be used as top half of poll function. It should do as little
- processing as possible, because it runs in interrupt context. The most
- common operation is recording of the current timestamp and for this reason
- one can use the IIO core defined <function>iio_pollfunc_store_time
- </function> function.
- </listitem>
- <listitem><function>sensor_trigger_handler</function>, the function that
- will be used as bottom half of the poll function. This runs in the
- context of a kernel thread and all the processing takes place here.
- It usually reads data from the device and stores it in the internal
- buffer together with the timestamp recorded in the top half.
- </listitem>
- </itemizedlist>
- </sect2>
- </sect1>
- </chapter>
- <chapter id='iioresources'>
- <title> Resources </title>
- IIO core may change during time so the best documentation to read is the
- source code. There are several locations where you should look:
- <itemizedlist>
- <listitem>
- <filename>drivers/iio/</filename>, contains the IIO core plus
- and directories for each sensor type (e.g. accel, magnetometer,
- etc.)
- </listitem>
- <listitem>
- <filename>include/linux/iio/</filename>, contains the header
- files, nice to read for the internal kernel interfaces.
- </listitem>
- <listitem>
- <filename>include/uapi/linux/iio/</filename>, contains files to be
- used by user space applications.
- </listitem>
- <listitem>
- <filename>tools/iio/</filename>, contains tools for rapidly
- testing buffers, events and device creation.
- </listitem>
- <listitem>
- <filename>drivers/staging/iio/</filename>, contains code for some
- drivers or experimental features that are not yet mature enough
- to be moved out.
- </listitem>
- </itemizedlist>
- <para>
- Besides the code, there are some good online documentation sources:
- <itemizedlist>
- <listitem>
- <ulink url="http://marc.info/?l=linux-iio"> Industrial I/O mailing
- list </ulink>
- </listitem>
- <listitem>
- <ulink url="http://wiki.analog.com/software/linux/docs/iio/iio">
- Analog Device IIO wiki page </ulink>
- </listitem>
- <listitem>
- <ulink url="https://fosdem.org/2015/schedule/event/iiosdr/">
- Using the Linux IIO framework for SDR, Lars-Peter Clausen's
- presentation at FOSDEM </ulink>
- </listitem>
- </itemizedlist>
- </para>
- </chapter>
-</book>
-
-<!--
-vim: softtabstop=2:shiftwidth=2:expandtab:textwidth=72
--->
diff --git a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
index 2a272275c81b..da5c087462b1 100644
--- a/Documentation/DocBook/kernel-hacking.tmpl
+++ b/Documentation/DocBook/kernel-hacking.tmpl
@@ -1208,8 +1208,8 @@ static struct block_device_operations opt_fops = {
<listitem>
<para>
- Finally, don't forget to read <filename>Documentation/SubmittingPatches</filename>
- and possibly <filename>Documentation/SubmittingDrivers</filename>.
+ Finally, don't forget to read <filename>Documentation/process/submitting-patches.rst</filename>
+ and possibly <filename>Documentation/process/submitting-drivers.rst</filename>.
</para>
</listitem>
</itemizedlist>
diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl
index f3abca7ec53d..856ac20bf367 100644
--- a/Documentation/DocBook/kgdb.tmpl
+++ b/Documentation/DocBook/kgdb.tmpl
@@ -115,12 +115,12 @@
</para>
<para>
If the architecture that you are using supports the kernel option
- CONFIG_DEBUG_RODATA, you should consider turning it off. This
+ CONFIG_STRICT_KERNEL_RWX, you should consider turning it off. This
option will prevent the use of software breakpoints because it
marks certain regions of the kernel's memory space as read-only.
If kgdb supports it for the architecture you are using, you can
use hardware breakpoints if you desire to run with the
- CONFIG_DEBUG_RODATA option turned on, else you need to turn off
+ CONFIG_STRICT_KERNEL_RWX option turned on, else you need to turn off
this option.
</para>
<para>
@@ -135,7 +135,7 @@
<para>Here is an example set of .config symbols to enable or
disable for kgdb:
<itemizedlist>
- <listitem><para># CONFIG_DEBUG_RODATA is not set</para></listitem>
+ <listitem><para># CONFIG_STRICT_KERNEL_RWX is not set</para></listitem>
<listitem><para>CONFIG_FRAME_POINTER=y</para></listitem>
<listitem><para>CONFIG_KGDB=y</para></listitem>
<listitem><para>CONFIG_KGDB_SERIAL_CONSOLE=y</para></listitem>
@@ -166,7 +166,7 @@
</para>
<para>Here is an example set of .config symbols to enable/disable kdb:
<itemizedlist>
- <listitem><para># CONFIG_DEBUG_RODATA is not set</para></listitem>
+ <listitem><para># CONFIG_STRICT_KERNEL_RWX is not set</para></listitem>
<listitem><para>CONFIG_FRAME_POINTER=y</para></listitem>
<listitem><para>CONFIG_KGDB=y</para></listitem>
<listitem><para>CONFIG_KGDB_SERIAL_CONSOLE=y</para></listitem>
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index d7fcdc5a4379..0320910b866d 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -1020,7 +1020,7 @@ and other resources, etc.
</itemizedlist>
<para>
- Of errors detected as above, the followings are not ATA/ATAPI
+ Of errors detected as above, the following are not ATA/ATAPI
device errors but ATA bus errors and should be handled
according to <xref linkend="excatATAbusErr"/>.
</para>
diff --git a/Documentation/DocBook/regulator.tmpl b/Documentation/DocBook/regulator.tmpl
deleted file mode 100644
index 3b08a085d2c7..000000000000
--- a/Documentation/DocBook/regulator.tmpl
+++ /dev/null
@@ -1,304 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="regulator-api">
- <bookinfo>
- <title>Voltage and current regulator API</title>
-
- <authorgroup>
- <author>
- <firstname>Liam</firstname>
- <surname>Girdwood</surname>
- <affiliation>
- <address>
- <email>lrg@slimlogic.co.uk</email>
- </address>
- </affiliation>
- </author>
- <author>
- <firstname>Mark</firstname>
- <surname>Brown</surname>
- <affiliation>
- <orgname>Wolfson Microelectronics</orgname>
- <address>
- <email>broonie@opensource.wolfsonmicro.com</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2007-2008</year>
- <holder>Wolfson Microelectronics</holder>
- </copyright>
- <copyright>
- <year>2008</year>
- <holder>Liam Girdwood</holder>
- </copyright>
-
- <legalnotice>
- <para>
- This documentation is free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public
- License version 2 as published by the Free Software Foundation.
- </para>
-
- <para>
- 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.
- </para>
-
- <para>
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
- </bookinfo>
-
-<toc></toc>
-
- <chapter id="intro">
- <title>Introduction</title>
- <para>
- This framework is designed to provide a standard kernel
- interface to control voltage and current regulators.
- </para>
- <para>
- The intention is to allow systems to dynamically control
- regulator power output in order to save power and prolong
- battery life. This applies to both voltage regulators (where
- voltage output is controllable) and current sinks (where current
- limit is controllable).
- </para>
- <para>
- Note that additional (and currently more complete) documentation
- is available in the Linux kernel source under
- <filename>Documentation/power/regulator</filename>.
- </para>
-
- <sect1 id="glossary">
- <title>Glossary</title>
- <para>
- The regulator API uses a number of terms which may not be
- familiar:
- </para>
- <glossary>
-
- <glossentry>
- <glossterm>Regulator</glossterm>
- <glossdef>
- <para>
- Electronic device that supplies power to other devices. Most
- regulators can enable and disable their output and some can also
- control their output voltage or current.
- </para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>Consumer</glossterm>
- <glossdef>
- <para>
- Electronic device which consumes power provided by a regulator.
- These may either be static, requiring only a fixed supply, or
- dynamic, requiring active management of the regulator at
- runtime.
- </para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>Power Domain</glossterm>
- <glossdef>
- <para>
- The electronic circuit supplied by a given regulator, including
- the regulator and all consumer devices. The configuration of
- the regulator is shared between all the components in the
- circuit.
- </para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>Power Management Integrated Circuit</glossterm>
- <acronym>PMIC</acronym>
- <glossdef>
- <para>
- An IC which contains numerous regulators and often also other
- subsystems. In an embedded system the primary PMIC is often
- equivalent to a combination of the PSU and southbridge in a
- desktop system.
- </para>
- </glossdef>
- </glossentry>
- </glossary>
- </sect1>
- </chapter>
-
- <chapter id="consumer">
- <title>Consumer driver interface</title>
- <para>
- This offers a similar API to the kernel clock framework.
- Consumer drivers use <link
- linkend='API-regulator-get'>get</link> and <link
- linkend='API-regulator-put'>put</link> operations to acquire and
- release regulators. Functions are
- provided to <link linkend='API-regulator-enable'>enable</link>
- and <link linkend='API-regulator-disable'>disable</link> the
- regulator and to get and set the runtime parameters of the
- regulator.
- </para>
- <para>
- When requesting regulators consumers use symbolic names for their
- supplies, such as "Vcc", which are mapped into actual regulator
- devices by the machine interface.
- </para>
- <para>
- A stub version of this API is provided when the regulator
- framework is not in use in order to minimise the need to use
- ifdefs.
- </para>
-
- <sect1 id="consumer-enable">
- <title>Enabling and disabling</title>
- <para>
- The regulator API provides reference counted enabling and
- disabling of regulators. Consumer devices use the <function><link
- linkend='API-regulator-enable'>regulator_enable</link></function>
- and <function><link
- linkend='API-regulator-disable'>regulator_disable</link>
- </function> functions to enable and disable regulators. Calls
- to the two functions must be balanced.
- </para>
- <para>
- Note that since multiple consumers may be using a regulator and
- machine constraints may not allow the regulator to be disabled
- there is no guarantee that calling
- <function>regulator_disable</function> will actually cause the
- supply provided by the regulator to be disabled. Consumer
- drivers should assume that the regulator may be enabled at all
- times.
- </para>
- </sect1>
-
- <sect1 id="consumer-config">
- <title>Configuration</title>
- <para>
- Some consumer devices may need to be able to dynamically
- configure their supplies. For example, MMC drivers may need to
- select the correct operating voltage for their cards. This may
- be done while the regulator is enabled or disabled.
- </para>
- <para>
- The <function><link
- linkend='API-regulator-set-voltage'>regulator_set_voltage</link>
- </function> and <function><link
- linkend='API-regulator-set-current-limit'
- >regulator_set_current_limit</link>
- </function> functions provide the primary interface for this.
- Both take ranges of voltages and currents, supporting drivers
- that do not require a specific value (eg, CPU frequency scaling
- normally permits the CPU to use a wider range of supply
- voltages at lower frequencies but does not require that the
- supply voltage be lowered). Where an exact value is required
- both minimum and maximum values should be identical.
- </para>
- </sect1>
-
- <sect1 id="consumer-callback">
- <title>Callbacks</title>
- <para>
- Callbacks may also be <link
- linkend='API-regulator-register-notifier'>registered</link>
- for events such as regulation failures.
- </para>
- </sect1>
- </chapter>
-
- <chapter id="driver">
- <title>Regulator driver interface</title>
- <para>
- Drivers for regulator chips <link
- linkend='API-regulator-register'>register</link> the regulators
- with the regulator core, providing operations structures to the
- core. A <link
- linkend='API-regulator-notifier-call-chain'>notifier</link> interface
- allows error conditions to be reported to the core.
- </para>
- <para>
- Registration should be triggered by explicit setup done by the
- platform, supplying a <link
- linkend='API-struct-regulator-init-data'>struct
- regulator_init_data</link> for the regulator containing
- <link linkend='machine-constraint'>constraint</link> and
- <link linkend='machine-supply'>supply</link> information.
- </para>
- </chapter>
-
- <chapter id="machine">
- <title>Machine interface</title>
- <para>
- This interface provides a way to define how regulators are
- connected to consumers on a given system and what the valid
- operating parameters are for the system.
- </para>
-
- <sect1 id="machine-supply">
- <title>Supplies</title>
- <para>
- Regulator supplies are specified using <link
- linkend='API-struct-regulator-consumer-supply'>struct
- regulator_consumer_supply</link>. This is done at
- <link linkend='driver'>driver registration
- time</link> as part of the machine constraints.
- </para>
- </sect1>
-
- <sect1 id="machine-constraint">
- <title>Constraints</title>
- <para>
- As well as defining the connections the machine interface
- also provides constraints defining the operations that
- clients are allowed to perform and the parameters that may be
- set. This is required since generally regulator devices will
- offer more flexibility than it is safe to use on a given
- system, for example supporting higher supply voltages than the
- consumers are rated for.
- </para>
- <para>
- This is done at <link linkend='driver'>driver
- registration time</link> by providing a <link
- linkend='API-struct-regulation-constraints'>struct
- regulation_constraints</link>.
- </para>
- <para>
- The constraints may also specify an initial configuration for the
- regulator in the constraints, which is particularly useful for
- use with static consumers.
- </para>
- </sect1>
- </chapter>
-
- <chapter id="api">
- <title>API reference</title>
- <para>
- Due to limitations of the kernel documentation framework and the
- existing layout of the source code the entire regulator API is
- documented here.
- </para>
-!Iinclude/linux/regulator/consumer.h
-!Iinclude/linux/regulator/machine.h
-!Iinclude/linux/regulator/driver.h
-!Edrivers/regulator/core.c
- </chapter>
-</book>
diff --git a/Documentation/DocBook/tracepoint.tmpl b/Documentation/DocBook/tracepoint.tmpl
deleted file mode 100644
index b57a9ede3224..000000000000
--- a/Documentation/DocBook/tracepoint.tmpl
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="Tracepoints">
- <bookinfo>
- <title>The Linux Kernel Tracepoint API</title>
-
- <authorgroup>
- <author>
- <firstname>Jason</firstname>
- <surname>Baron</surname>
- <affiliation>
- <address>
- <email>jbaron@redhat.com</email>
- </address>
- </affiliation>
- </author>
- <author>
- <firstname>William</firstname>
- <surname>Cohen</surname>
- <affiliation>
- <address>
- <email>wcohen@redhat.com</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <legalnotice>
- <para>
- This documentation is free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later
- version.
- </para>
-
- <para>
- 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.
- </para>
-
- <para>
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
- </bookinfo>
-
- <toc></toc>
- <chapter id="intro">
- <title>Introduction</title>
- <para>
- Tracepoints are static probe points that are located in strategic points
- throughout the kernel. 'Probes' register/unregister with tracepoints
- via a callback mechanism. The 'probes' are strictly typed functions that
- are passed a unique set of parameters defined by each tracepoint.
- </para>
-
- <para>
- From this simple callback mechanism, 'probes' can be used to profile, debug,
- and understand kernel behavior. There are a number of tools that provide a
- framework for using 'probes'. These tools include Systemtap, ftrace, and
- LTTng.
- </para>
-
- <para>
- Tracepoints are defined in a number of header files via various macros. Thus,
- the purpose of this document is to provide a clear accounting of the available
- tracepoints. The intention is to understand not only what tracepoints are
- available but also to understand where future tracepoints might be added.
- </para>
-
- <para>
- The API presented has functions of the form:
- <function>trace_tracepointname(function parameters)</function>. These are the
- tracepoints callbacks that are found throughout the code. Registering and
- unregistering probes with these callback sites is covered in the
- <filename>Documentation/trace/*</filename> directory.
- </para>
- </chapter>
-
- <chapter id="irq">
- <title>IRQ</title>
-!Iinclude/trace/events/irq.h
- </chapter>
-
- <chapter id="signal">
- <title>SIGNAL</title>
-!Iinclude/trace/events/signal.h
- </chapter>
-
- <chapter id="block">
- <title>Block IO</title>
-!Iinclude/trace/events/block.h
- </chapter>
-
- <chapter id="workqueue">
- <title>Workqueue</title>
-!Iinclude/trace/events/workqueue.h
- </chapter>
-</book>
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
deleted file mode 100644
index cd0e452dfed5..000000000000
--- a/Documentation/DocBook/uio-howto.tmpl
+++ /dev/null
@@ -1,1050 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
-
-<book id="index">
-<bookinfo>
-<title>The Userspace I/O HOWTO</title>
-
-<author>
- <firstname>Hans-Jürgen</firstname>
- <surname>Koch</surname>
- <authorblurb><para>Linux developer, Linutronix</para></authorblurb>
- <affiliation>
- <orgname>
- <ulink url="http://www.linutronix.de">Linutronix</ulink>
- </orgname>
-
- <address>
- <email>hjk@hansjkoch.de</email>
- </address>
- </affiliation>
-</author>
-
-<copyright>
- <year>2006-2008</year>
- <holder>Hans-Jürgen Koch.</holder>
-</copyright>
-<copyright>
- <year>2009</year>
- <holder>Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)</holder>
-</copyright>
-
-<legalnotice>
-<para>
-This documentation is Free Software licensed under the terms of the
-GPL version 2.
-</para>
-</legalnotice>
-
-<pubdate>2006-12-11</pubdate>
-
-<abstract>
- <para>This HOWTO describes concept and usage of Linux kernel's
- Userspace I/O system.</para>
-</abstract>
-
-<revhistory>
- <revision>
- <revnumber>0.9</revnumber>
- <date>2009-07-16</date>
- <authorinitials>mst</authorinitials>
- <revremark>Added generic pci driver
- </revremark>
- </revision>
- <revision>
- <revnumber>0.8</revnumber>
- <date>2008-12-24</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Added name attributes in mem and portio sysfs directories.
- </revremark>
- </revision>
- <revision>
- <revnumber>0.7</revnumber>
- <date>2008-12-23</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Added generic platform drivers and offset attribute.</revremark>
- </revision>
- <revision>
- <revnumber>0.6</revnumber>
- <date>2008-12-05</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Added description of portio sysfs attributes.</revremark>
- </revision>
- <revision>
- <revnumber>0.5</revnumber>
- <date>2008-05-22</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Added description of write() function.</revremark>
- </revision>
- <revision>
- <revnumber>0.4</revnumber>
- <date>2007-11-26</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Removed section about uio_dummy.</revremark>
- </revision>
- <revision>
- <revnumber>0.3</revnumber>
- <date>2007-04-29</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Added section about userspace drivers.</revremark>
- </revision>
- <revision>
- <revnumber>0.2</revnumber>
- <date>2007-02-13</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Update after multiple mappings were added.</revremark>
- </revision>
- <revision>
- <revnumber>0.1</revnumber>
- <date>2006-12-11</date>
- <authorinitials>hjk</authorinitials>
- <revremark>First draft.</revremark>
- </revision>
-</revhistory>
-</bookinfo>
-
-<chapter id="aboutthisdoc">
-<?dbhtml filename="aboutthis.html"?>
-<title>About this document</title>
-
-<sect1 id="translations">
-<?dbhtml filename="translations.html"?>
-<title>Translations</title>
-
-<para>If you know of any translations for this document, or you are
-interested in translating it, please email me
-<email>hjk@hansjkoch.de</email>.
-</para>
-</sect1>
-
-<sect1 id="preface">
-<title>Preface</title>
- <para>
- For many types of devices, creating a Linux kernel driver is
- overkill. All that is really needed is some way to handle an
- interrupt and provide access to the memory space of the
- device. The logic of controlling the device does not
- necessarily have to be within the kernel, as the device does
- not need to take advantage of any of other resources that the
- kernel provides. One such common class of devices that are
- like this are for industrial I/O cards.
- </para>
- <para>
- To address this situation, the userspace I/O system (UIO) was
- designed. For typical industrial I/O cards, only a very small
- kernel module is needed. The main part of the driver will run in
- user space. This simplifies development and reduces the risk of
- serious bugs within a kernel module.
- </para>
- <para>
- Please note that UIO is not an universal driver interface. Devices
- that are already handled well by other kernel subsystems (like
- networking or serial or USB) are no candidates for an UIO driver.
- Hardware that is ideally suited for an UIO driver fulfills all of
- the following:
- </para>
-<itemizedlist>
-<listitem>
- <para>The device has memory that can be mapped. The device can be
- controlled completely by writing to this memory.</para>
-</listitem>
-<listitem>
- <para>The device usually generates interrupts.</para>
-</listitem>
-<listitem>
- <para>The device does not fit into one of the standard kernel
- subsystems.</para>
-</listitem>
-</itemizedlist>
-</sect1>
-
-<sect1 id="thanks">
-<title>Acknowledgments</title>
- <para>I'd like to thank Thomas Gleixner and Benedikt Spranger of
- Linutronix, who have not only written most of the UIO code, but also
- helped greatly writing this HOWTO by giving me all kinds of background
- information.</para>
-</sect1>
-
-<sect1 id="feedback">
-<title>Feedback</title>
- <para>Find something wrong with this document? (Or perhaps something
- right?) I would love to hear from you. Please email me at
- <email>hjk@hansjkoch.de</email>.</para>
-</sect1>
-</chapter>
-
-<chapter id="about">
-<?dbhtml filename="about.html"?>
-<title>About UIO</title>
-
-<para>If you use UIO for your card's driver, here's what you get:</para>
-
-<itemizedlist>
-<listitem>
- <para>only one small kernel module to write and maintain.</para>
-</listitem>
-<listitem>
- <para>develop the main part of your driver in user space,
- with all the tools and libraries you're used to.</para>
-</listitem>
-<listitem>
- <para>bugs in your driver won't crash the kernel.</para>
-</listitem>
-<listitem>
- <para>updates of your driver can take place without recompiling
- the kernel.</para>
-</listitem>
-</itemizedlist>
-
-<sect1 id="how_uio_works">
-<title>How UIO works</title>
- <para>
- Each UIO device is accessed through a device file and several
- sysfs attribute files. The device file will be called
- <filename>/dev/uio0</filename> for the first device, and
- <filename>/dev/uio1</filename>, <filename>/dev/uio2</filename>
- and so on for subsequent devices.
- </para>
-
- <para><filename>/dev/uioX</filename> is used to access the
- address space of the card. Just use
- <function>mmap()</function> to access registers or RAM
- locations of your card.
- </para>
-
- <para>
- Interrupts are handled by reading from
- <filename>/dev/uioX</filename>. A blocking
- <function>read()</function> from
- <filename>/dev/uioX</filename> will return as soon as an
- interrupt occurs. You can also use
- <function>select()</function> on
- <filename>/dev/uioX</filename> to wait for an interrupt. The
- integer value read from <filename>/dev/uioX</filename>
- represents the total interrupt count. You can use this number
- to figure out if you missed some interrupts.
- </para>
- <para>
- For some hardware that has more than one interrupt source internally,
- but not separate IRQ mask and status registers, there might be
- situations where userspace cannot determine what the interrupt source
- was if the kernel handler disables them by writing to the chip's IRQ
- register. In such a case, the kernel has to disable the IRQ completely
- to leave the chip's register untouched. Now the userspace part can
- determine the cause of the interrupt, but it cannot re-enable
- interrupts. Another cornercase is chips where re-enabling interrupts
- is a read-modify-write operation to a combined IRQ status/acknowledge
- register. This would be racy if a new interrupt occurred
- simultaneously.
- </para>
- <para>
- To address these problems, UIO also implements a write() function. It
- is normally not used and can be ignored for hardware that has only a
- single interrupt source or has separate IRQ mask and status registers.
- If you need it, however, a write to <filename>/dev/uioX</filename>
- will call the <function>irqcontrol()</function> function implemented
- by the driver. You have to write a 32-bit value that is usually either
- 0 or 1 to disable or enable interrupts. If a driver does not implement
- <function>irqcontrol()</function>, <function>write()</function> will
- return with <varname>-ENOSYS</varname>.
- </para>
-
- <para>
- To handle interrupts properly, your custom kernel module can
- provide its own interrupt handler. It will automatically be
- called by the built-in handler.
- </para>
-
- <para>
- For cards that don't generate interrupts but need to be
- polled, there is the possibility to set up a timer that
- triggers the interrupt handler at configurable time intervals.
- This interrupt simulation is done by calling
- <function>uio_event_notify()</function>
- from the timer's event handler.
- </para>
-
- <para>
- Each driver provides attributes that are used to read or write
- variables. These attributes are accessible through sysfs
- files. A custom kernel driver module can add its own
- attributes to the device owned by the uio driver, but not added
- to the UIO device itself at this time. This might change in the
- future if it would be found to be useful.
- </para>
-
- <para>
- The following standard attributes are provided by the UIO
- framework:
- </para>
-<itemizedlist>
-<listitem>
- <para>
- <filename>name</filename>: The name of your device. It is
- recommended to use the name of your kernel module for this.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>version</filename>: A version string defined by your
- driver. This allows the user space part of your driver to deal
- with different versions of the kernel module.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>event</filename>: The total number of interrupts
- handled by the driver since the last time the device node was
- read.
- </para>
-</listitem>
-</itemizedlist>
-<para>
- These attributes appear under the
- <filename>/sys/class/uio/uioX</filename> directory. Please
- note that this directory might be a symlink, and not a real
- directory. Any userspace code that accesses it must be able
- to handle this.
-</para>
-<para>
- Each UIO device can make one or more memory regions available for
- memory mapping. This is necessary because some industrial I/O cards
- require access to more than one PCI memory region in a driver.
-</para>
-<para>
- Each mapping has its own directory in sysfs, the first mapping
- appears as <filename>/sys/class/uio/uioX/maps/map0/</filename>.
- Subsequent mappings create directories <filename>map1/</filename>,
- <filename>map2/</filename>, and so on. These directories will only
- appear if the size of the mapping is not 0.
-</para>
-<para>
- Each <filename>mapX/</filename> directory contains four read-only files
- that show attributes of the memory:
-</para>
-<itemizedlist>
-<listitem>
- <para>
- <filename>name</filename>: A string identifier for this mapping. This
- is optional, the string can be empty. Drivers can set this to make it
- easier for userspace to find the correct mapping.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>addr</filename>: The address of memory that can be mapped.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>size</filename>: The size, in bytes, of the memory
- pointed to by addr.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>offset</filename>: The offset, in bytes, that has to be
- added to the pointer returned by <function>mmap()</function> to get
- to the actual device memory. This is important if the device's memory
- is not page aligned. Remember that pointers returned by
- <function>mmap()</function> are always page aligned, so it is good
- style to always add this offset.
- </para>
-</listitem>
-</itemizedlist>
-
-<para>
- From userspace, the different mappings are distinguished by adjusting
- the <varname>offset</varname> parameter of the
- <function>mmap()</function> call. To map the memory of mapping N, you
- have to use N times the page size as your offset:
-</para>
-<programlisting format="linespecific">
-offset = N * getpagesize();
-</programlisting>
-
-<para>
- Sometimes there is hardware with memory-like regions that can not be
- mapped with the technique described here, but there are still ways to
- access them from userspace. The most common example are x86 ioports.
- On x86 systems, userspace can access these ioports using
- <function>ioperm()</function>, <function>iopl()</function>,
- <function>inb()</function>, <function>outb()</function>, and similar
- functions.
-</para>
-<para>
- Since these ioport regions can not be mapped, they will not appear under
- <filename>/sys/class/uio/uioX/maps/</filename> like the normal memory
- described above. Without information about the port regions a hardware
- has to offer, it becomes difficult for the userspace part of the
- driver to find out which ports belong to which UIO device.
-</para>
-<para>
- To address this situation, the new directory
- <filename>/sys/class/uio/uioX/portio/</filename> was added. It only
- exists if the driver wants to pass information about one or more port
- regions to userspace. If that is the case, subdirectories named
- <filename>port0</filename>, <filename>port1</filename>, and so on,
- will appear underneath
- <filename>/sys/class/uio/uioX/portio/</filename>.
-</para>
-<para>
- Each <filename>portX/</filename> directory contains four read-only
- files that show name, start, size, and type of the port region:
-</para>
-<itemizedlist>
-<listitem>
- <para>
- <filename>name</filename>: A string identifier for this port region.
- The string is optional and can be empty. Drivers can set it to make it
- easier for userspace to find a certain port region.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>start</filename>: The first port of this region.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>size</filename>: The number of ports in this region.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>porttype</filename>: A string describing the type of port.
- </para>
-</listitem>
-</itemizedlist>
-
-
-</sect1>
-</chapter>
-
-<chapter id="custom_kernel_module" xreflabel="Writing your own kernel module">
-<?dbhtml filename="custom_kernel_module.html"?>
-<title>Writing your own kernel module</title>
- <para>
- Please have a look at <filename>uio_cif.c</filename> as an
- example. The following paragraphs explain the different
- sections of this file.
- </para>
-
-<sect1 id="uio_info">
-<title>struct uio_info</title>
- <para>
- This structure tells the framework the details of your driver,
- Some of the members are required, others are optional.
- </para>
-
-<itemizedlist>
-<listitem><para>
-<varname>const char *name</varname>: Required. The name of your driver as
-it will appear in sysfs. I recommend using the name of your module for this.
-</para></listitem>
-
-<listitem><para>
-<varname>const char *version</varname>: Required. This string appears in
-<filename>/sys/class/uio/uioX/version</filename>.
-</para></listitem>
-
-<listitem><para>
-<varname>struct uio_mem mem[ MAX_UIO_MAPS ]</varname>: Required if you
-have memory that can be mapped with <function>mmap()</function>. For each
-mapping you need to fill one of the <varname>uio_mem</varname> structures.
-See the description below for details.
-</para></listitem>
-
-<listitem><para>
-<varname>struct uio_port port[ MAX_UIO_PORTS_REGIONS ]</varname>: Required
-if you want to pass information about ioports to userspace. For each port
-region you need to fill one of the <varname>uio_port</varname> structures.
-See the description below for details.
-</para></listitem>
-
-<listitem><para>
-<varname>long irq</varname>: Required. If your hardware generates an
-interrupt, it's your modules task to determine the irq number during
-initialization. If you don't have a hardware generated interrupt but
-want to trigger the interrupt handler in some other way, set
-<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>.
-If you had no interrupt at all, you could set
-<varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
-rarely makes sense.
-</para></listitem>
-
-<listitem><para>
-<varname>unsigned long irq_flags</varname>: Required if you've set
-<varname>irq</varname> to a hardware interrupt number. The flags given
-here will be used in the call to <function>request_irq()</function>.
-</para></listitem>
-
-<listitem><para>
-<varname>int (*mmap)(struct uio_info *info, struct vm_area_struct
-*vma)</varname>: Optional. If you need a special
-<function>mmap()</function> function, you can set it here. If this
-pointer is not NULL, your <function>mmap()</function> will be called
-instead of the built-in one.
-</para></listitem>
-
-<listitem><para>
-<varname>int (*open)(struct uio_info *info, struct inode *inode)
-</varname>: Optional. You might want to have your own
-<function>open()</function>, e.g. to enable interrupts only when your
-device is actually used.
-</para></listitem>
-
-<listitem><para>
-<varname>int (*release)(struct uio_info *info, struct inode *inode)
-</varname>: Optional. If you define your own
-<function>open()</function>, you will probably also want a custom
-<function>release()</function> function.
-</para></listitem>
-
-<listitem><para>
-<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on)
-</varname>: Optional. If you need to be able to enable or disable
-interrupts from userspace by writing to <filename>/dev/uioX</filename>,
-you can implement this function. The parameter <varname>irq_on</varname>
-will be 0 to disable interrupts and 1 to enable them.
-</para></listitem>
-</itemizedlist>
-
-<para>
-Usually, your device will have one or more memory regions that can be mapped
-to user space. For each region, you have to set up a
-<varname>struct uio_mem</varname> in the <varname>mem[]</varname> array.
-Here's a description of the fields of <varname>struct uio_mem</varname>:
-</para>
-
-<itemizedlist>
-<listitem><para>
-<varname>const char *name</varname>: Optional. Set this to help identify
-the memory region, it will show up in the corresponding sysfs node.
-</para></listitem>
-
-<listitem><para>
-<varname>int memtype</varname>: Required if the mapping is used. Set this to
-<varname>UIO_MEM_PHYS</varname> if you you have physical memory on your
-card to be mapped. Use <varname>UIO_MEM_LOGICAL</varname> for logical
-memory (e.g. allocated with <function>kmalloc()</function>). There's also
-<varname>UIO_MEM_VIRTUAL</varname> for virtual memory.
-</para></listitem>
-
-<listitem><para>
-<varname>phys_addr_t addr</varname>: Required if the mapping is used.
-Fill in the address of your memory block. This address is the one that
-appears in sysfs.
-</para></listitem>
-
-<listitem><para>
-<varname>resource_size_t size</varname>: Fill in the size of the
-memory block that <varname>addr</varname> points to. If <varname>size</varname>
-is zero, the mapping is considered unused. Note that you
-<emphasis>must</emphasis> initialize <varname>size</varname> with zero for
-all unused mappings.
-</para></listitem>
-
-<listitem><para>
-<varname>void *internal_addr</varname>: If you have to access this memory
-region from within your kernel module, you will want to map it internally by
-using something like <function>ioremap()</function>. Addresses
-returned by this function cannot be mapped to user space, so you must not
-store it in <varname>addr</varname>. Use <varname>internal_addr</varname>
-instead to remember such an address.
-</para></listitem>
-</itemizedlist>
-
-<para>
-Please do not touch the <varname>map</varname> element of
-<varname>struct uio_mem</varname>! It is used by the UIO framework
-to set up sysfs files for this mapping. Simply leave it alone.
-</para>
-
-<para>
-Sometimes, your device can have one or more port regions which can not be
-mapped to userspace. But if there are other possibilities for userspace to
-access these ports, it makes sense to make information about the ports
-available in sysfs. For each region, you have to set up a
-<varname>struct uio_port</varname> in the <varname>port[]</varname> array.
-Here's a description of the fields of <varname>struct uio_port</varname>:
-</para>
-
-<itemizedlist>
-<listitem><para>
-<varname>char *porttype</varname>: Required. Set this to one of the predefined
-constants. Use <varname>UIO_PORT_X86</varname> for the ioports found in x86
-architectures.
-</para></listitem>
-
-<listitem><para>
-<varname>unsigned long start</varname>: Required if the port region is used.
-Fill in the number of the first port of this region.
-</para></listitem>
-
-<listitem><para>
-<varname>unsigned long size</varname>: Fill in the number of ports in this
-region. If <varname>size</varname> is zero, the region is considered unused.
-Note that you <emphasis>must</emphasis> initialize <varname>size</varname>
-with zero for all unused regions.
-</para></listitem>
-</itemizedlist>
-
-<para>
-Please do not touch the <varname>portio</varname> element of
-<varname>struct uio_port</varname>! It is used internally by the UIO
-framework to set up sysfs files for this region. Simply leave it alone.
-</para>
-
-</sect1>
-
-<sect1 id="adding_irq_handler">
-<title>Adding an interrupt handler</title>
- <para>
- What you need to do in your interrupt handler depends on your
- hardware and on how you want to handle it. You should try to
- keep the amount of code in your kernel interrupt handler low.
- If your hardware requires no action that you
- <emphasis>have</emphasis> to perform after each interrupt,
- then your handler can be empty.</para> <para>If, on the other
- hand, your hardware <emphasis>needs</emphasis> some action to
- be performed after each interrupt, then you
- <emphasis>must</emphasis> do it in your kernel module. Note
- that you cannot rely on the userspace part of your driver. Your
- userspace program can terminate at any time, possibly leaving
- your hardware in a state where proper interrupt handling is
- still required.
- </para>
-
- <para>
- There might also be applications where you want to read data
- from your hardware at each interrupt and buffer it in a piece
- of kernel memory you've allocated for that purpose. With this
- technique you could avoid loss of data if your userspace
- program misses an interrupt.
- </para>
-
- <para>
- A note on shared interrupts: Your driver should support
- interrupt sharing whenever this is possible. It is possible if
- and only if your driver can detect whether your hardware has
- triggered the interrupt or not. This is usually done by looking
- at an interrupt status register. If your driver sees that the
- IRQ bit is actually set, it will perform its actions, and the
- handler returns IRQ_HANDLED. If the driver detects that it was
- not your hardware that caused the interrupt, it will do nothing
- and return IRQ_NONE, allowing the kernel to call the next
- possible interrupt handler.
- </para>
-
- <para>
- If you decide not to support shared interrupts, your card
- won't work in computers with no free interrupts. As this
- frequently happens on the PC platform, you can save yourself a
- lot of trouble by supporting interrupt sharing.
- </para>
-</sect1>
-
-<sect1 id="using_uio_pdrv">
-<title>Using uio_pdrv for platform devices</title>
- <para>
- In many cases, UIO drivers for platform devices can be handled in a
- generic way. In the same place where you define your
- <varname>struct platform_device</varname>, you simply also implement
- your interrupt handler and fill your
- <varname>struct uio_info</varname>. A pointer to this
- <varname>struct uio_info</varname> is then used as
- <varname>platform_data</varname> for your platform device.
- </para>
- <para>
- You also need to set up an array of <varname>struct resource</varname>
- containing addresses and sizes of your memory mappings. This
- information is passed to the driver using the
- <varname>.resource</varname> and <varname>.num_resources</varname>
- elements of <varname>struct platform_device</varname>.
- </para>
- <para>
- You now have to set the <varname>.name</varname> element of
- <varname>struct platform_device</varname> to
- <varname>"uio_pdrv"</varname> to use the generic UIO platform device
- driver. This driver will fill the <varname>mem[]</varname> array
- according to the resources given, and register the device.
- </para>
- <para>
- The advantage of this approach is that you only have to edit a file
- you need to edit anyway. You do not have to create an extra driver.
- </para>
-</sect1>
-
-<sect1 id="using_uio_pdrv_genirq">
-<title>Using uio_pdrv_genirq for platform devices</title>
- <para>
- Especially in embedded devices, you frequently find chips where the
- irq pin is tied to its own dedicated interrupt line. In such cases,
- where you can be really sure the interrupt is not shared, we can take
- the concept of <varname>uio_pdrv</varname> one step further and use a
- generic interrupt handler. That's what
- <varname>uio_pdrv_genirq</varname> does.
- </para>
- <para>
- The setup for this driver is the same as described above for
- <varname>uio_pdrv</varname>, except that you do not implement an
- interrupt handler. The <varname>.handler</varname> element of
- <varname>struct uio_info</varname> must remain
- <varname>NULL</varname>. The <varname>.irq_flags</varname> element
- must not contain <varname>IRQF_SHARED</varname>.
- </para>
- <para>
- You will set the <varname>.name</varname> element of
- <varname>struct platform_device</varname> to
- <varname>"uio_pdrv_genirq"</varname> to use this driver.
- </para>
- <para>
- The generic interrupt handler of <varname>uio_pdrv_genirq</varname>
- will simply disable the interrupt line using
- <function>disable_irq_nosync()</function>. After doing its work,
- userspace can reenable the interrupt by writing 0x00000001 to the UIO
- device file. The driver already implements an
- <function>irq_control()</function> to make this possible, you must not
- implement your own.
- </para>
- <para>
- Using <varname>uio_pdrv_genirq</varname> not only saves a few lines of
- interrupt handler code. You also do not need to know anything about
- the chip's internal registers to create the kernel part of the driver.
- All you need to know is the irq number of the pin the chip is
- connected to.
- </para>
-</sect1>
-
-<sect1 id="using-uio_dmem_genirq">
-<title>Using uio_dmem_genirq for platform devices</title>
- <para>
- In addition to statically allocated memory ranges, they may also be
- a desire to use dynamically allocated regions in a user space driver.
- In particular, being able to access memory made available through the
- dma-mapping API, may be particularly useful. The
- <varname>uio_dmem_genirq</varname> driver provides a way to accomplish
- this.
- </para>
- <para>
- This driver is used in a similar manner to the
- <varname>"uio_pdrv_genirq"</varname> driver with respect to interrupt
- configuration and handling.
- </para>
- <para>
- Set the <varname>.name</varname> element of
- <varname>struct platform_device</varname> to
- <varname>"uio_dmem_genirq"</varname> to use this driver.
- </para>
- <para>
- When using this driver, fill in the <varname>.platform_data</varname>
- element of <varname>struct platform_device</varname>, which is of type
- <varname>struct uio_dmem_genirq_pdata</varname> and which contains the
- following elements:
- </para>
- <itemizedlist>
- <listitem><para><varname>struct uio_info uioinfo</varname>: The same
- structure used as the <varname>uio_pdrv_genirq</varname> platform
- data</para></listitem>
- <listitem><para><varname>unsigned int *dynamic_region_sizes</varname>:
- Pointer to list of sizes of dynamic memory regions to be mapped into
- user space.
- </para></listitem>
- <listitem><para><varname>unsigned int num_dynamic_regions</varname>:
- Number of elements in <varname>dynamic_region_sizes</varname> array.
- </para></listitem>
- </itemizedlist>
- <para>
- The dynamic regions defined in the platform data will be appended to
- the <varname> mem[] </varname> array after the platform device
- resources, which implies that the total number of static and dynamic
- memory regions cannot exceed <varname>MAX_UIO_MAPS</varname>.
- </para>
- <para>
- The dynamic memory regions will be allocated when the UIO device file,
- <varname>/dev/uioX</varname> is opened.
- Similar to static memory resources, the memory region information for
- dynamic regions is then visible via sysfs at
- <varname>/sys/class/uio/uioX/maps/mapY/*</varname>.
- The dynamic memory regions will be freed when the UIO device file is
- closed. When no processes are holding the device file open, the address
- returned to userspace is ~0.
- </para>
-</sect1>
-
-</chapter>
-
-<chapter id="userspace_driver" xreflabel="Writing a driver in user space">
-<?dbhtml filename="userspace_driver.html"?>
-<title>Writing a driver in userspace</title>
- <para>
- Once you have a working kernel module for your hardware, you can
- write the userspace part of your driver. You don't need any special
- libraries, your driver can be written in any reasonable language,
- you can use floating point numbers and so on. In short, you can
- use all the tools and libraries you'd normally use for writing a
- userspace application.
- </para>
-
-<sect1 id="getting_uio_information">
-<title>Getting information about your UIO device</title>
- <para>
- Information about all UIO devices is available in sysfs. The
- first thing you should do in your driver is check
- <varname>name</varname> and <varname>version</varname> to
- make sure your talking to the right device and that its kernel
- driver has the version you expect.
- </para>
- <para>
- You should also make sure that the memory mapping you need
- exists and has the size you expect.
- </para>
- <para>
- There is a tool called <varname>lsuio</varname> that lists
- UIO devices and their attributes. It is available here:
- </para>
- <para>
- <ulink url="http://www.osadl.org/projects/downloads/UIO/user/">
- http://www.osadl.org/projects/downloads/UIO/user/</ulink>
- </para>
- <para>
- With <varname>lsuio</varname> you can quickly check if your
- kernel module is loaded and which attributes it exports.
- Have a look at the manpage for details.
- </para>
- <para>
- The source code of <varname>lsuio</varname> can serve as an
- example for getting information about an UIO device.
- The file <filename>uio_helper.c</filename> contains a lot of
- functions you could use in your userspace driver code.
- </para>
-</sect1>
-
-<sect1 id="mmap_device_memory">
-<title>mmap() device memory</title>
- <para>
- After you made sure you've got the right device with the
- memory mappings you need, all you have to do is to call
- <function>mmap()</function> to map the device's memory
- to userspace.
- </para>
- <para>
- The parameter <varname>offset</varname> of the
- <function>mmap()</function> call has a special meaning
- for UIO devices: It is used to select which mapping of
- your device you want to map. To map the memory of
- mapping N, you have to use N times the page size as
- your offset:
- </para>
-<programlisting format="linespecific">
- offset = N * getpagesize();
-</programlisting>
- <para>
- N starts from zero, so if you've got only one memory
- range to map, set <varname>offset = 0</varname>.
- A drawback of this technique is that memory is always
- mapped beginning with its start address.
- </para>
-</sect1>
-
-<sect1 id="wait_for_interrupts">
-<title>Waiting for interrupts</title>
- <para>
- After you successfully mapped your devices memory, you
- can access it like an ordinary array. Usually, you will
- perform some initialization. After that, your hardware
- starts working and will generate an interrupt as soon
- as it's finished, has some data available, or needs your
- attention because an error occurred.
- </para>
- <para>
- <filename>/dev/uioX</filename> is a read-only file. A
- <function>read()</function> will always block until an
- interrupt occurs. There is only one legal value for the
- <varname>count</varname> parameter of
- <function>read()</function>, and that is the size of a
- signed 32 bit integer (4). Any other value for
- <varname>count</varname> causes <function>read()</function>
- to fail. The signed 32 bit integer read is the interrupt
- count of your device. If the value is one more than the value
- you read the last time, everything is OK. If the difference
- is greater than one, you missed interrupts.
- </para>
- <para>
- You can also use <function>select()</function> on
- <filename>/dev/uioX</filename>.
- </para>
-</sect1>
-
-</chapter>
-
-<chapter id="uio_pci_generic" xreflabel="Using Generic driver for PCI cards">
-<?dbhtml filename="uio_pci_generic.html"?>
-<title>Generic PCI UIO driver</title>
- <para>
- The generic driver is a kernel module named uio_pci_generic.
- It can work with any device compliant to PCI 2.3 (circa 2002) and
- any compliant PCI Express device. Using this, you only need to
- write the userspace driver, removing the need to write
- a hardware-specific kernel module.
- </para>
-
-<sect1 id="uio_pci_generic_binding">
-<title>Making the driver recognize the device</title>
- <para>
-Since the driver does not declare any device ids, it will not get loaded
-automatically and will not automatically bind to any devices, you must load it
-and allocate id to the driver yourself. For example:
- <programlisting>
- modprobe uio_pci_generic
- echo &quot;8086 10f5&quot; &gt; /sys/bus/pci/drivers/uio_pci_generic/new_id
- </programlisting>
- </para>
- <para>
-If there already is a hardware specific kernel driver for your device, the
-generic driver still won't bind to it, in this case if you want to use the
-generic driver (why would you?) you'll have to manually unbind the hardware
-specific driver and bind the generic driver, like this:
- <programlisting>
- echo -n 0000:00:19.0 &gt; /sys/bus/pci/drivers/e1000e/unbind
- echo -n 0000:00:19.0 &gt; /sys/bus/pci/drivers/uio_pci_generic/bind
- </programlisting>
- </para>
- <para>
-You can verify that the device has been bound to the driver
-by looking for it in sysfs, for example like the following:
- <programlisting>
- ls -l /sys/bus/pci/devices/0000:00:19.0/driver
- </programlisting>
-Which if successful should print
- <programlisting>
- .../0000:00:19.0/driver -&gt; ../../../bus/pci/drivers/uio_pci_generic
- </programlisting>
-Note that the generic driver will not bind to old PCI 2.2 devices.
-If binding the device failed, run the following command:
- <programlisting>
- dmesg
- </programlisting>
-and look in the output for failure reasons
- </para>
-</sect1>
-
-<sect1 id="uio_pci_generic_internals">
-<title>Things to know about uio_pci_generic</title>
- <para>
-Interrupts are handled using the Interrupt Disable bit in the PCI command
-register and Interrupt Status bit in the PCI status register. All devices
-compliant to PCI 2.3 (circa 2002) and all compliant PCI Express devices should
-support these bits. uio_pci_generic detects this support, and won't bind to
-devices which do not support the Interrupt Disable Bit in the command register.
- </para>
- <para>
-On each interrupt, uio_pci_generic sets the Interrupt Disable bit.
-This prevents the device from generating further interrupts
-until the bit is cleared. The userspace driver should clear this
-bit before blocking and waiting for more interrupts.
- </para>
-</sect1>
-<sect1 id="uio_pci_generic_userspace">
-<title>Writing userspace driver using uio_pci_generic</title>
- <para>
-Userspace driver can use pci sysfs interface, or the
-libpci libray that wraps it, to talk to the device and to
-re-enable interrupts by writing to the command register.
- </para>
-</sect1>
-<sect1 id="uio_pci_generic_example">
-<title>Example code using uio_pci_generic</title>
- <para>
-Here is some sample userspace driver code using uio_pci_generic:
-<programlisting>
-#include &lt;stdlib.h&gt;
-#include &lt;stdio.h&gt;
-#include &lt;unistd.h&gt;
-#include &lt;sys/types.h&gt;
-#include &lt;sys/stat.h&gt;
-#include &lt;fcntl.h&gt;
-#include &lt;errno.h&gt;
-
-int main()
-{
- int uiofd;
- int configfd;
- int err;
- int i;
- unsigned icount;
- unsigned char command_high;
-
- uiofd = open(&quot;/dev/uio0&quot;, O_RDONLY);
- if (uiofd &lt; 0) {
- perror(&quot;uio open:&quot;);
- return errno;
- }
- configfd = open(&quot;/sys/class/uio/uio0/device/config&quot;, O_RDWR);
- if (configfd &lt; 0) {
- perror(&quot;config open:&quot;);
- return errno;
- }
-
- /* Read and cache command value */
- err = pread(configfd, &amp;command_high, 1, 5);
- if (err != 1) {
- perror(&quot;command config read:&quot;);
- return errno;
- }
- command_high &amp;= ~0x4;
-
- for(i = 0;; ++i) {
- /* Print out a message, for debugging. */
- if (i == 0)
- fprintf(stderr, &quot;Started uio test driver.\n&quot;);
- else
- fprintf(stderr, &quot;Interrupts: %d\n&quot;, icount);
-
- /****************************************/
- /* Here we got an interrupt from the
- device. Do something to it. */
- /****************************************/
-
- /* Re-enable interrupts. */
- err = pwrite(configfd, &amp;command_high, 1, 5);
- if (err != 1) {
- perror(&quot;config write:&quot;);
- break;
- }
-
- /* Wait for next interrupt. */
- err = read(uiofd, &amp;icount, 4);
- if (err != 4) {
- perror(&quot;uio read:&quot;);
- break;
- }
-
- }
- return errno;
-}
-
-</programlisting>
- </para>
-</sect1>
-
-</chapter>
-
-<appendix id="app1">
-<title>Further information</title>
-<itemizedlist>
- <listitem><para>
- <ulink url="http://www.osadl.org">
- OSADL homepage.</ulink>
- </para></listitem>
- <listitem><para>
- <ulink url="http://www.linutronix.de">
- Linutronix homepage.</ulink>
- </para></listitem>
-</itemizedlist>
-</appendix>
-
-</book>
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl
deleted file mode 100644
index bc776be0f19c..000000000000
--- a/Documentation/DocBook/usb.tmpl
+++ /dev/null
@@ -1,992 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="Linux-USB-API">
- <bookinfo>
- <title>The Linux-USB Host Side API</title>
-
- <legalnotice>
- <para>
- This documentation is free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later
- version.
- </para>
-
- <para>
- 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.
- </para>
-
- <para>
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
- </bookinfo>
-
-<toc></toc>
-
-<chapter id="intro">
- <title>Introduction to USB on Linux</title>
-
- <para>A Universal Serial Bus (USB) is used to connect a host,
- such as a PC or workstation, to a number of peripheral
- devices. USB uses a tree structure, with the host as the
- root (the system's master), hubs as interior nodes, and
- peripherals as leaves (and slaves).
- Modern PCs support several such trees of USB devices, usually
- one USB 2.0 tree (480 Mbit/sec each) with
- a few USB 1.1 trees (12 Mbit/sec each) that are used when you
- connect a USB 1.1 device directly to the machine's "root hub".
- </para>
-
- <para>That master/slave asymmetry was designed-in for a number of
- reasons, one being ease of use. It is not physically possible to
- assemble (legal) USB cables incorrectly: all upstream "to the host"
- connectors are the rectangular type (matching the sockets on
- root hubs), and all downstream connectors are the squarish type
- (or they are built into the peripheral).
- Also, the host software doesn't need to deal with distributed
- auto-configuration since the pre-designated master node manages all that.
- And finally, at the electrical level, bus protocol overhead is reduced by
- eliminating arbitration and moving scheduling into the host software.
- </para>
-
- <para>USB 1.0 was announced in January 1996 and was revised
- as USB 1.1 (with improvements in hub specification and
- support for interrupt-out transfers) in September 1998.
- USB 2.0 was released in April 2000, adding high-speed
- transfers and transaction-translating hubs (used for USB 1.1
- and 1.0 backward compatibility).
- </para>
-
- <para>Kernel developers added USB support to Linux early in the 2.2 kernel
- series, shortly before 2.3 development forked. Updates from 2.3 were
- regularly folded back into 2.2 releases, which improved reliability and
- brought <filename>/sbin/hotplug</filename> support as well more drivers.
- Such improvements were continued in the 2.5 kernel series, where they added
- USB 2.0 support, improved performance, and made the host controller drivers
- (HCDs) more consistent. They also simplified the API (to make bugs less
- likely) and added internal "kerneldoc" documentation.
- </para>
-
- <para>Linux can run inside USB devices as well as on
- the hosts that control the devices.
- But USB device drivers running inside those peripherals
- don't do the same things as the ones running inside hosts,
- so they've been given a different name:
- <emphasis>gadget drivers</emphasis>.
- This document does not cover gadget drivers.
- </para>
-
- </chapter>
-
-<chapter id="host">
- <title>USB Host-Side API Model</title>
-
- <para>Host-side drivers for USB devices talk to the "usbcore" APIs.
- There are two. One is intended for
- <emphasis>general-purpose</emphasis> drivers (exposed through
- driver frameworks), and the other is for drivers that are
- <emphasis>part of the core</emphasis>.
- Such core drivers include the <emphasis>hub</emphasis> driver
- (which manages trees of USB devices) and several different kinds
- of <emphasis>host controller drivers</emphasis>,
- which control individual busses.
- </para>
-
- <para>The device model seen by USB drivers is relatively complex.
- </para>
-
- <itemizedlist>
-
- <listitem><para>USB supports four kinds of data transfers
- (control, bulk, interrupt, and isochronous). Two of them (control
- and bulk) use bandwidth as it's available,
- while the other two (interrupt and isochronous)
- are scheduled to provide guaranteed bandwidth.
- </para></listitem>
-
- <listitem><para>The device description model includes one or more
- "configurations" per device, only one of which is active at a time.
- Devices that are capable of high-speed operation must also support
- full-speed configurations, along with a way to ask about the
- "other speed" configurations which might be used.
- </para></listitem>
-
- <listitem><para>Configurations have one or more "interfaces", each
- of which may have "alternate settings". Interfaces may be
- standardized by USB "Class" specifications, or may be specific to
- a vendor or device.</para>
-
- <para>USB device drivers actually bind to interfaces, not devices.
- Think of them as "interface drivers", though you
- may not see many devices where the distinction is important.
- <emphasis>Most USB devices are simple, with only one configuration,
- one interface, and one alternate setting.</emphasis>
- </para></listitem>
-
- <listitem><para>Interfaces have one or more "endpoints", each of
- which supports one type and direction of data transfer such as
- "bulk out" or "interrupt in". The entire configuration may have
- up to sixteen endpoints in each direction, allocated as needed
- among all the interfaces.
- </para></listitem>
-
- <listitem><para>Data transfer on USB is packetized; each endpoint
- has a maximum packet size.
- Drivers must often be aware of conventions such as flagging the end
- of bulk transfers using "short" (including zero length) packets.
- </para></listitem>
-
- <listitem><para>The Linux USB API supports synchronous calls for
- control and bulk messages.
- It also supports asynchronous calls for all kinds of data transfer,
- using request structures called "URBs" (USB Request Blocks).
- </para></listitem>
-
- </itemizedlist>
-
- <para>Accordingly, the USB Core API exposed to device drivers
- covers quite a lot of territory. You'll probably need to consult
- the USB 2.0 specification, available online from www.usb.org at
- no cost, as well as class or device specifications.
- </para>
-
- <para>The only host-side drivers that actually touch hardware
- (reading/writing registers, handling IRQs, and so on) are the HCDs.
- In theory, all HCDs provide the same functionality through the same
- API. In practice, that's becoming more true on the 2.5 kernels,
- but there are still differences that crop up especially with
- fault handling. Different controllers don't necessarily report
- the same aspects of failures, and recovery from faults (including
- software-induced ones like unlinking an URB) isn't yet fully
- consistent.
- Device driver authors should make a point of doing disconnect
- testing (while the device is active) with each different host
- controller driver, to make sure drivers don't have bugs of
- their own as well as to make sure they aren't relying on some
- HCD-specific behavior.
- (You will need external USB 1.1 and/or
- USB 2.0 hubs to perform all those tests.)
- </para>
-
- </chapter>
-
-<chapter id="types"><title>USB-Standard Types</title>
-
- <para>In <filename>&lt;linux/usb/ch9.h&gt;</filename> you will find
- the USB data types defined in chapter 9 of the USB specification.
- These data types are used throughout USB, and in APIs including
- this host side API, gadget APIs, and usbfs.
- </para>
-
-!Iinclude/linux/usb/ch9.h
-
- </chapter>
-
-<chapter id="hostside"><title>Host-Side Data Types and Macros</title>
-
- <para>The host side API exposes several layers to drivers, some of
- which are more necessary than others.
- These support lifecycle models for host side drivers
- and devices, and support passing buffers through usbcore to
- some HCD that performs the I/O for the device driver.
- </para>
-
-
-!Iinclude/linux/usb.h
-
- </chapter>
-
- <chapter id="usbcore"><title>USB Core APIs</title>
-
- <para>There are two basic I/O models in the USB API.
- The most elemental one is asynchronous: drivers submit requests
- in the form of an URB, and the URB's completion callback
- handle the next step.
- All USB transfer types support that model, although there
- are special cases for control URBs (which always have setup
- and status stages, but may not have a data stage) and
- isochronous URBs (which allow large packets and include
- per-packet fault reports).
- Built on top of that is synchronous API support, where a
- driver calls a routine that allocates one or more URBs,
- submits them, and waits until they complete.
- There are synchronous wrappers for single-buffer control
- and bulk transfers (which are awkward to use in some
- driver disconnect scenarios), and for scatterlist based
- streaming i/o (bulk or interrupt).
- </para>
-
- <para>USB drivers need to provide buffers that can be
- used for DMA, although they don't necessarily need to
- provide the DMA mapping themselves.
- There are APIs to use used when allocating DMA buffers,
- which can prevent use of bounce buffers on some systems.
- In some cases, drivers may be able to rely on 64bit DMA
- to eliminate another kind of bounce buffer.
- </para>
-
-!Edrivers/usb/core/urb.c
-!Edrivers/usb/core/message.c
-!Edrivers/usb/core/file.c
-!Edrivers/usb/core/driver.c
-!Edrivers/usb/core/usb.c
-!Edrivers/usb/core/hub.c
- </chapter>
-
- <chapter id="hcd"><title>Host Controller APIs</title>
-
- <para>These APIs are only for use by host controller drivers,
- most of which implement standard register interfaces such as
- EHCI, OHCI, or UHCI.
- UHCI was one of the first interfaces, designed by Intel and
- also used by VIA; it doesn't do much in hardware.
- OHCI was designed later, to have the hardware do more work
- (bigger transfers, tracking protocol state, and so on).
- EHCI was designed with USB 2.0; its design has features that
- resemble OHCI (hardware does much more work) as well as
- UHCI (some parts of ISO support, TD list processing).
- </para>
-
- <para>There are host controllers other than the "big three",
- although most PCI based controllers (and a few non-PCI based
- ones) use one of those interfaces.
- Not all host controllers use DMA; some use PIO, and there
- is also a simulator.
- </para>
-
- <para>The same basic APIs are available to drivers for all
- those controllers.
- For historical reasons they are in two layers:
- <structname>struct usb_bus</structname> is a rather thin
- layer that became available in the 2.2 kernels, while
- <structname>struct usb_hcd</structname> is a more featureful
- layer (available in later 2.4 kernels and in 2.5) that
- lets HCDs share common code, to shrink driver size
- and significantly reduce hcd-specific behaviors.
- </para>
-
-!Edrivers/usb/core/hcd.c
-!Edrivers/usb/core/hcd-pci.c
-!Idrivers/usb/core/buffer.c
- </chapter>
-
- <chapter id="usbfs">
- <title>The USB Filesystem (usbfs)</title>
-
- <para>This chapter presents the Linux <emphasis>usbfs</emphasis>.
- You may prefer to avoid writing new kernel code for your
- USB driver; that's the problem that usbfs set out to solve.
- User mode device drivers are usually packaged as applications
- or libraries, and may use usbfs through some programming library
- that wraps it. Such libraries include
- <ulink url="http://libusb.sourceforge.net">libusb</ulink>
- for C/C++, and
- <ulink url="http://jUSB.sourceforge.net">jUSB</ulink> for Java.
- </para>
-
- <note><title>Unfinished</title>
- <para>This particular documentation is incomplete,
- especially with respect to the asynchronous mode.
- As of kernel 2.5.66 the code and this (new) documentation
- need to be cross-reviewed.
- </para>
- </note>
-
- <para>Configure usbfs into Linux kernels by enabling the
- <emphasis>USB filesystem</emphasis> option (CONFIG_USB_DEVICEFS),
- and you get basic support for user mode USB device drivers.
- Until relatively recently it was often (confusingly) called
- <emphasis>usbdevfs</emphasis> although it wasn't solving what
- <emphasis>devfs</emphasis> was.
- Every USB device will appear in usbfs, regardless of whether or
- not it has a kernel driver.
- </para>
-
- <sect1 id="usbfs-files">
- <title>What files are in "usbfs"?</title>
-
- <para>Conventionally mounted at
- <filename>/proc/bus/usb</filename>, usbfs
- features include:
- <itemizedlist>
- <listitem><para><filename>/proc/bus/usb/devices</filename>
- ... a text file
- showing each of the USB devices on known to the kernel,
- and their configuration descriptors.
- You can also poll() this to learn about new devices.
- </para></listitem>
- <listitem><para><filename>/proc/bus/usb/BBB/DDD</filename>
- ... magic files
- exposing the each device's configuration descriptors, and
- supporting a series of ioctls for making device requests,
- including I/O to devices. (Purely for access by programs.)
- </para></listitem>
- </itemizedlist>
- </para>
-
- <para> Each bus is given a number (BBB) based on when it was
- enumerated; within each bus, each device is given a similar
- number (DDD).
- Those BBB/DDD paths are not "stable" identifiers;
- expect them to change even if you always leave the devices
- plugged in to the same hub port.
- <emphasis>Don't even think of saving these in application
- configuration files.</emphasis>
- Stable identifiers are available, for user mode applications
- that want to use them. HID and networking devices expose
- these stable IDs, so that for example you can be sure that
- you told the right UPS to power down its second server.
- "usbfs" doesn't (yet) expose those IDs.
- </para>
-
- </sect1>
-
- <sect1 id="usbfs-fstab">
- <title>Mounting and Access Control</title>
-
- <para>There are a number of mount options for usbfs, which will
- be of most interest to you if you need to override the default
- access control policy.
- That policy is that only root may read or write device files
- (<filename>/proc/bus/BBB/DDD</filename>) although anyone may read
- the <filename>devices</filename>
- or <filename>drivers</filename> files.
- I/O requests to the device also need the CAP_SYS_RAWIO capability,
- </para>
-
- <para>The significance of that is that by default, all user mode
- device drivers need super-user privileges.
- You can change modes or ownership in a driver setup
- when the device hotplugs, or maye just start the
- driver right then, as a privileged server (or some activity
- within one).
- That's the most secure approach for multi-user systems,
- but for single user systems ("trusted" by that user)
- it's more convenient just to grant everyone all access
- (using the <emphasis>devmode=0666</emphasis> option)
- so the driver can start whenever it's needed.
- </para>
-
- <para>The mount options for usbfs, usable in /etc/fstab or
- in command line invocations of <emphasis>mount</emphasis>, are:
-
- <variablelist>
- <varlistentry>
- <term><emphasis>busgid</emphasis>=NNNNN</term>
- <listitem><para>Controls the GID used for the
- /proc/bus/usb/BBB
- directories. (Default: 0)</para></listitem></varlistentry>
- <varlistentry><term><emphasis>busmode</emphasis>=MMM</term>
- <listitem><para>Controls the file mode used for the
- /proc/bus/usb/BBB
- directories. (Default: 0555)
- </para></listitem></varlistentry>
- <varlistentry><term><emphasis>busuid</emphasis>=NNNNN</term>
- <listitem><para>Controls the UID used for the
- /proc/bus/usb/BBB
- directories. (Default: 0)</para></listitem></varlistentry>
-
- <varlistentry><term><emphasis>devgid</emphasis>=NNNNN</term>
- <listitem><para>Controls the GID used for the
- /proc/bus/usb/BBB/DDD
- files. (Default: 0)</para></listitem></varlistentry>
- <varlistentry><term><emphasis>devmode</emphasis>=MMM</term>
- <listitem><para>Controls the file mode used for the
- /proc/bus/usb/BBB/DDD
- files. (Default: 0644)</para></listitem></varlistentry>
- <varlistentry><term><emphasis>devuid</emphasis>=NNNNN</term>
- <listitem><para>Controls the UID used for the
- /proc/bus/usb/BBB/DDD
- files. (Default: 0)</para></listitem></varlistentry>
-
- <varlistentry><term><emphasis>listgid</emphasis>=NNNNN</term>
- <listitem><para>Controls the GID used for the
- /proc/bus/usb/devices and drivers files.
- (Default: 0)</para></listitem></varlistentry>
- <varlistentry><term><emphasis>listmode</emphasis>=MMM</term>
- <listitem><para>Controls the file mode used for the
- /proc/bus/usb/devices and drivers files.
- (Default: 0444)</para></listitem></varlistentry>
- <varlistentry><term><emphasis>listuid</emphasis>=NNNNN</term>
- <listitem><para>Controls the UID used for the
- /proc/bus/usb/devices and drivers files.
- (Default: 0)</para></listitem></varlistentry>
- </variablelist>
-
- </para>
-
- <para>Note that many Linux distributions hard-wire the mount options
- for usbfs in their init scripts, such as
- <filename>/etc/rc.d/rc.sysinit</filename>,
- rather than making it easy to set this per-system
- policy in <filename>/etc/fstab</filename>.
- </para>
-
- </sect1>
-
- <sect1 id="usbfs-devices">
- <title>/proc/bus/usb/devices</title>
-
- <para>This file is handy for status viewing tools in user
- mode, which can scan the text format and ignore most of it.
- More detailed device status (including class and vendor
- status) is available from device-specific files.
- For information about the current format of this file,
- see the
- <filename>Documentation/usb/proc_usb_info.txt</filename>
- file in your Linux kernel sources.
- </para>
-
- <para>This file, in combination with the poll() system call, can
- also be used to detect when devices are added or removed:
-<programlisting>int fd;
-struct pollfd pfd;
-
-fd = open("/proc/bus/usb/devices", O_RDONLY);
-pfd = { fd, POLLIN, 0 };
-for (;;) {
- /* The first time through, this call will return immediately. */
- poll(&amp;pfd, 1, -1);
-
- /* To see what's changed, compare the file's previous and current
- contents or scan the filesystem. (Scanning is more precise.) */
-}</programlisting>
- Note that this behavior is intended to be used for informational
- and debug purposes. It would be more appropriate to use programs
- such as udev or HAL to initialize a device or start a user-mode
- helper program, for instance.
- </para>
- </sect1>
-
- <sect1 id="usbfs-bbbddd">
- <title>/proc/bus/usb/BBB/DDD</title>
-
- <para>Use these files in one of these basic ways:
- </para>
-
- <para><emphasis>They can be read,</emphasis>
- producing first the device descriptor
- (18 bytes) and then the descriptors for the current configuration.
- See the USB 2.0 spec for details about those binary data formats.
- You'll need to convert most multibyte values from little endian
- format to your native host byte order, although a few of the
- fields in the device descriptor (both of the BCD-encoded fields,
- and the vendor and product IDs) will be byteswapped for you.
- Note that configuration descriptors include descriptors for
- interfaces, altsettings, endpoints, and maybe additional
- class descriptors.
- </para>
-
- <para><emphasis>Perform USB operations</emphasis> using
- <emphasis>ioctl()</emphasis> requests to make endpoint I/O
- requests (synchronously or asynchronously) or manage
- the device.
- These requests need the CAP_SYS_RAWIO capability,
- as well as filesystem access permissions.
- Only one ioctl request can be made on one of these
- device files at a time.
- This means that if you are synchronously reading an endpoint
- from one thread, you won't be able to write to a different
- endpoint from another thread until the read completes.
- This works for <emphasis>half duplex</emphasis> protocols,
- but otherwise you'd use asynchronous i/o requests.
- </para>
-
- </sect1>
-
-
- <sect1 id="usbfs-lifecycle">
- <title>Life Cycle of User Mode Drivers</title>
-
- <para>Such a driver first needs to find a device file
- for a device it knows how to handle.
- Maybe it was told about it because a
- <filename>/sbin/hotplug</filename> event handling agent
- chose that driver to handle the new device.
- Or maybe it's an application that scans all the
- /proc/bus/usb device files, and ignores most devices.
- In either case, it should <function>read()</function> all
- the descriptors from the device file,
- and check them against what it knows how to handle.
- It might just reject everything except a particular
- vendor and product ID, or need a more complex policy.
- </para>
-
- <para>Never assume there will only be one such device
- on the system at a time!
- If your code can't handle more than one device at
- a time, at least detect when there's more than one, and
- have your users choose which device to use.
- </para>
-
- <para>Once your user mode driver knows what device to use,
- it interacts with it in either of two styles.
- The simple style is to make only control requests; some
- devices don't need more complex interactions than those.
- (An example might be software using vendor-specific control
- requests for some initialization or configuration tasks,
- with a kernel driver for the rest.)
- </para>
-
- <para>More likely, you need a more complex style driver:
- one using non-control endpoints, reading or writing data
- and claiming exclusive use of an interface.
- <emphasis>Bulk</emphasis> transfers are easiest to use,
- but only their sibling <emphasis>interrupt</emphasis> transfers
- work with low speed devices.
- Both interrupt and <emphasis>isochronous</emphasis> transfers
- offer service guarantees because their bandwidth is reserved.
- Such "periodic" transfers are awkward to use through usbfs,
- unless you're using the asynchronous calls. However, interrupt
- transfers can also be used in a synchronous "one shot" style.
- </para>
-
- <para>Your user-mode driver should never need to worry
- about cleaning up request state when the device is
- disconnected, although it should close its open file
- descriptors as soon as it starts seeing the ENODEV
- errors.
- </para>
-
- </sect1>
-
- <sect1 id="usbfs-ioctl"><title>The ioctl() Requests</title>
-
- <para>To use these ioctls, you need to include the following
- headers in your userspace program:
-<programlisting>#include &lt;linux/usb.h&gt;
-#include &lt;linux/usbdevice_fs.h&gt;
-#include &lt;asm/byteorder.h&gt;</programlisting>
- The standard USB device model requests, from "Chapter 9" of
- the USB 2.0 specification, are automatically included from
- the <filename>&lt;linux/usb/ch9.h&gt;</filename> header.
- </para>
-
- <para>Unless noted otherwise, the ioctl requests
- described here will
- update the modification time on the usbfs file to which
- they are applied (unless they fail).
- A return of zero indicates success; otherwise, a
- standard USB error code is returned. (These are
- documented in
- <filename>Documentation/usb/error-codes.txt</filename>
- in your kernel sources.)
- </para>
-
- <para>Each of these files multiplexes access to several
- I/O streams, one per endpoint.
- Each device has one control endpoint (endpoint zero)
- which supports a limited RPC style RPC access.
- Devices are configured
- by hub_wq (in the kernel) setting a device-wide
- <emphasis>configuration</emphasis> that affects things
- like power consumption and basic functionality.
- The endpoints are part of USB <emphasis>interfaces</emphasis>,
- which may have <emphasis>altsettings</emphasis>
- affecting things like which endpoints are available.
- Many devices only have a single configuration and interface,
- so drivers for them will ignore configurations and altsettings.
- </para>
-
-
- <sect2 id="usbfs-mgmt">
- <title>Management/Status Requests</title>
-
- <para>A number of usbfs requests don't deal very directly
- with device I/O.
- They mostly relate to device management and status.
- These are all synchronous requests.
- </para>
-
- <variablelist>
-
- <varlistentry><term>USBDEVFS_CLAIMINTERFACE</term>
- <listitem><para>This is used to force usbfs to
- claim a specific interface,
- which has not previously been claimed by usbfs or any other
- kernel driver.
- The ioctl parameter is an integer holding the number of
- the interface (bInterfaceNumber from descriptor).
- </para><para>
- Note that if your driver doesn't claim an interface
- before trying to use one of its endpoints, and no
- other driver has bound to it, then the interface is
- automatically claimed by usbfs.
- </para><para>
- This claim will be released by a RELEASEINTERFACE ioctl,
- or by closing the file descriptor.
- File modification time is not updated by this request.
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_CONNECTINFO</term>
- <listitem><para>Says whether the device is lowspeed.
- The ioctl parameter points to a structure like this:
-<programlisting>struct usbdevfs_connectinfo {
- unsigned int devnum;
- unsigned char slow;
-}; </programlisting>
- File modification time is not updated by this request.
- </para><para>
- <emphasis>You can't tell whether a "not slow"
- device is connected at high speed (480 MBit/sec)
- or just full speed (12 MBit/sec).</emphasis>
- You should know the devnum value already,
- it's the DDD value of the device file name.
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_GETDRIVER</term>
- <listitem><para>Returns the name of the kernel driver
- bound to a given interface (a string). Parameter
- is a pointer to this structure, which is modified:
-<programlisting>struct usbdevfs_getdriver {
- unsigned int interface;
- char driver[USBDEVFS_MAXDRIVERNAME + 1];
-};</programlisting>
- File modification time is not updated by this request.
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_IOCTL</term>
- <listitem><para>Passes a request from userspace through
- to a kernel driver that has an ioctl entry in the
- <emphasis>struct usb_driver</emphasis> it registered.
-<programlisting>struct usbdevfs_ioctl {
- int ifno;
- int ioctl_code;
- void *data;
-};
-
-/* user mode call looks like this.
- * 'request' becomes the driver->ioctl() 'code' parameter.
- * the size of 'param' is encoded in 'request', and that data
- * is copied to or from the driver->ioctl() 'buf' parameter.
- */
-static int
-usbdev_ioctl (int fd, int ifno, unsigned request, void *param)
-{
- struct usbdevfs_ioctl wrapper;
-
- wrapper.ifno = ifno;
- wrapper.ioctl_code = request;
- wrapper.data = param;
-
- return ioctl (fd, USBDEVFS_IOCTL, &amp;wrapper);
-} </programlisting>
- File modification time is not updated by this request.
- </para><para>
- This request lets kernel drivers talk to user mode code
- through filesystem operations even when they don't create
- a character or block special device.
- It's also been used to do things like ask devices what
- device special file should be used.
- Two pre-defined ioctls are used
- to disconnect and reconnect kernel drivers, so
- that user mode code can completely manage binding
- and configuration of devices.
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_RELEASEINTERFACE</term>
- <listitem><para>This is used to release the claim usbfs
- made on interface, either implicitly or because of a
- USBDEVFS_CLAIMINTERFACE call, before the file
- descriptor is closed.
- The ioctl parameter is an integer holding the number of
- the interface (bInterfaceNumber from descriptor);
- File modification time is not updated by this request.
- </para><warning><para>
- <emphasis>No security check is made to ensure
- that the task which made the claim is the one
- which is releasing it.
- This means that user mode driver may interfere
- other ones. </emphasis>
- </para></warning></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_RESETEP</term>
- <listitem><para>Resets the data toggle value for an endpoint
- (bulk or interrupt) to DATA0.
- The ioctl parameter is an integer endpoint number
- (1 to 15, as identified in the endpoint descriptor),
- with USB_DIR_IN added if the device's endpoint sends
- data to the host.
- </para><warning><para>
- <emphasis>Avoid using this request.
- It should probably be removed.</emphasis>
- Using it typically means the device and driver will lose
- toggle synchronization. If you really lost synchronization,
- you likely need to completely handshake with the device,
- using a request like CLEAR_HALT
- or SET_INTERFACE.
- </para></warning></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_DROP_PRIVILEGES</term>
- <listitem><para>This is used to relinquish the ability
- to do certain operations which are considered to be
- privileged on a usbfs file descriptor.
- This includes claiming arbitrary interfaces, resetting
- a device on which there are currently claimed interfaces
- from other users, and issuing USBDEVFS_IOCTL calls.
- The ioctl parameter is a 32 bit mask of interfaces
- the user is allowed to claim on this file descriptor.
- You may issue this ioctl more than one time to narrow
- said mask.
- </para></listitem></varlistentry>
- </variablelist>
-
- </sect2>
-
- <sect2 id="usbfs-sync">
- <title>Synchronous I/O Support</title>
-
- <para>Synchronous requests involve the kernel blocking
- until the user mode request completes, either by
- finishing successfully or by reporting an error.
- In most cases this is the simplest way to use usbfs,
- although as noted above it does prevent performing I/O
- to more than one endpoint at a time.
- </para>
-
- <variablelist>
-
- <varlistentry><term>USBDEVFS_BULK</term>
- <listitem><para>Issues a bulk read or write request to the
- device.
- The ioctl parameter is a pointer to this structure:
-<programlisting>struct usbdevfs_bulktransfer {
- unsigned int ep;
- unsigned int len;
- unsigned int timeout; /* in milliseconds */
- void *data;
-};</programlisting>
- </para><para>The "ep" value identifies a
- bulk endpoint number (1 to 15, as identified in an endpoint
- descriptor),
- masked with USB_DIR_IN when referring to an endpoint which
- sends data to the host from the device.
- The length of the data buffer is identified by "len";
- Recent kernels support requests up to about 128KBytes.
- <emphasis>FIXME say how read length is returned,
- and how short reads are handled.</emphasis>.
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_CLEAR_HALT</term>
- <listitem><para>Clears endpoint halt (stall) and
- resets the endpoint toggle. This is only
- meaningful for bulk or interrupt endpoints.
- The ioctl parameter is an integer endpoint number
- (1 to 15, as identified in an endpoint descriptor),
- masked with USB_DIR_IN when referring to an endpoint which
- sends data to the host from the device.
- </para><para>
- Use this on bulk or interrupt endpoints which have
- stalled, returning <emphasis>-EPIPE</emphasis> status
- to a data transfer request.
- Do not issue the control request directly, since
- that could invalidate the host's record of the
- data toggle.
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_CONTROL</term>
- <listitem><para>Issues a control request to the device.
- The ioctl parameter points to a structure like this:
-<programlisting>struct usbdevfs_ctrltransfer {
- __u8 bRequestType;
- __u8 bRequest;
- __u16 wValue;
- __u16 wIndex;
- __u16 wLength;
- __u32 timeout; /* in milliseconds */
- void *data;
-};</programlisting>
- </para><para>
- The first eight bytes of this structure are the contents
- of the SETUP packet to be sent to the device; see the
- USB 2.0 specification for details.
- The bRequestType value is composed by combining a
- USB_TYPE_* value, a USB_DIR_* value, and a
- USB_RECIP_* value (from
- <emphasis>&lt;linux/usb.h&gt;</emphasis>).
- If wLength is nonzero, it describes the length of the data
- buffer, which is either written to the device
- (USB_DIR_OUT) or read from the device (USB_DIR_IN).
- </para><para>
- At this writing, you can't transfer more than 4 KBytes
- of data to or from a device; usbfs has a limit, and
- some host controller drivers have a limit.
- (That's not usually a problem.)
- <emphasis>Also</emphasis> there's no way to say it's
- not OK to get a short read back from the device.
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_RESET</term>
- <listitem><para>Does a USB level device reset.
- The ioctl parameter is ignored.
- After the reset, this rebinds all device interfaces.
- File modification time is not updated by this request.
- </para><warning><para>
- <emphasis>Avoid using this call</emphasis>
- until some usbcore bugs get fixed,
- since it does not fully synchronize device, interface,
- and driver (not just usbfs) state.
- </para></warning></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_SETINTERFACE</term>
- <listitem><para>Sets the alternate setting for an
- interface. The ioctl parameter is a pointer to a
- structure like this:
-<programlisting>struct usbdevfs_setinterface {
- unsigned int interface;
- unsigned int altsetting;
-}; </programlisting>
- File modification time is not updated by this request.
- </para><para>
- Those struct members are from some interface descriptor
- applying to the current configuration.
- The interface number is the bInterfaceNumber value, and
- the altsetting number is the bAlternateSetting value.
- (This resets each endpoint in the interface.)
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_SETCONFIGURATION</term>
- <listitem><para>Issues the
- <function>usb_set_configuration</function> call
- for the device.
- The parameter is an integer holding the number of
- a configuration (bConfigurationValue from descriptor).
- File modification time is not updated by this request.
- </para><warning><para>
- <emphasis>Avoid using this call</emphasis>
- until some usbcore bugs get fixed,
- since it does not fully synchronize device, interface,
- and driver (not just usbfs) state.
- </para></warning></listitem></varlistentry>
-
- </variablelist>
- </sect2>
-
- <sect2 id="usbfs-async">
- <title>Asynchronous I/O Support</title>
-
- <para>As mentioned above, there are situations where it may be
- important to initiate concurrent operations from user mode code.
- This is particularly important for periodic transfers
- (interrupt and isochronous), but it can be used for other
- kinds of USB requests too.
- In such cases, the asynchronous requests described here
- are essential. Rather than submitting one request and having
- the kernel block until it completes, the blocking is separate.
- </para>
-
- <para>These requests are packaged into a structure that
- resembles the URB used by kernel device drivers.
- (No POSIX Async I/O support here, sorry.)
- It identifies the endpoint type (USBDEVFS_URB_TYPE_*),
- endpoint (number, masked with USB_DIR_IN as appropriate),
- buffer and length, and a user "context" value serving to
- uniquely identify each request.
- (It's usually a pointer to per-request data.)
- Flags can modify requests (not as many as supported for
- kernel drivers).
- </para>
-
- <para>Each request can specify a realtime signal number
- (between SIGRTMIN and SIGRTMAX, inclusive) to request a
- signal be sent when the request completes.
- </para>
-
- <para>When usbfs returns these urbs, the status value
- is updated, and the buffer may have been modified.
- Except for isochronous transfers, the actual_length is
- updated to say how many bytes were transferred; if the
- USBDEVFS_URB_DISABLE_SPD flag is set
- ("short packets are not OK"), if fewer bytes were read
- than were requested then you get an error report.
- </para>
-
-<programlisting>struct usbdevfs_iso_packet_desc {
- unsigned int length;
- unsigned int actual_length;
- unsigned int status;
-};
-
-struct usbdevfs_urb {
- unsigned char type;
- unsigned char endpoint;
- int status;
- unsigned int flags;
- void *buffer;
- int buffer_length;
- int actual_length;
- int start_frame;
- int number_of_packets;
- int error_count;
- unsigned int signr;
- void *usercontext;
- struct usbdevfs_iso_packet_desc iso_frame_desc[];
-};</programlisting>
-
- <para> For these asynchronous requests, the file modification
- time reflects when the request was initiated.
- This contrasts with their use with the synchronous requests,
- where it reflects when requests complete.
- </para>
-
- <variablelist>
-
- <varlistentry><term>USBDEVFS_DISCARDURB</term>
- <listitem><para>
- <emphasis>TBS</emphasis>
- File modification time is not updated by this request.
- </para><para>
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_DISCSIGNAL</term>
- <listitem><para>
- <emphasis>TBS</emphasis>
- File modification time is not updated by this request.
- </para><para>
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_REAPURB</term>
- <listitem><para>
- <emphasis>TBS</emphasis>
- File modification time is not updated by this request.
- </para><para>
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_REAPURBNDELAY</term>
- <listitem><para>
- <emphasis>TBS</emphasis>
- File modification time is not updated by this request.
- </para><para>
- </para></listitem></varlistentry>
-
- <varlistentry><term>USBDEVFS_SUBMITURB</term>
- <listitem><para>
- <emphasis>TBS</emphasis>
- </para><para>
- </para></listitem></varlistentry>
-
- </variablelist>
- </sect2>
-
- </sect1>
-
- </chapter>
-
-</book>
-<!-- vim:syntax=sgml:sw=4
--->
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
deleted file mode 100644
index a27ab9f53fb6..000000000000
--- a/Documentation/DocBook/writing-an-alsa-driver.tmpl
+++ /dev/null
@@ -1,6206 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<!-- ****************************************************** -->
-<!-- Header -->
-<!-- ****************************************************** -->
-<book id="Writing-an-ALSA-Driver">
- <bookinfo>
- <title>Writing an ALSA Driver</title>
- <author>
- <firstname>Takashi</firstname>
- <surname>Iwai</surname>
- <affiliation>
- <address>
- <email>tiwai@suse.de</email>
- </address>
- </affiliation>
- </author>
-
- <date>Oct 15, 2007</date>
- <edition>0.3.7</edition>
-
- <abstract>
- <para>
- This document describes how to write an ALSA (Advanced Linux
- Sound Architecture) driver.
- </para>
- </abstract>
-
- <legalnotice>
- <para>
- Copyright (c) 2002-2005 Takashi Iwai <email>tiwai@suse.de</email>
- </para>
-
- <para>
- This document is free; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- </para>
-
- <para>
- This document is distributed in the hope that it will be useful,
- but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
- implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
- PARTICULAR PURPOSE</emphasis>. See the GNU General Public License
- for more details.
- </para>
-
- <para>
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- </para>
- </legalnotice>
-
- </bookinfo>
-
-<!-- ****************************************************** -->
-<!-- Preface -->
-<!-- ****************************************************** -->
- <preface id="preface">
- <title>Preface</title>
- <para>
- This document describes how to write an
- <ulink url="http://www.alsa-project.org/"><citetitle>
- ALSA (Advanced Linux Sound Architecture)</citetitle></ulink>
- driver. The document focuses mainly on PCI soundcards.
- In the case of other device types, the API might
- be different, too. However, at least the ALSA kernel API is
- consistent, and therefore it would be still a bit help for
- writing them.
- </para>
-
- <para>
- This document targets people who already have enough
- C language skills and have basic linux kernel programming
- knowledge. This document doesn't explain the general
- topic of linux kernel coding and doesn't cover low-level
- driver implementation details. It only describes
- the standard way to write a PCI sound driver on ALSA.
- </para>
-
- <para>
- If you are already familiar with the older ALSA ver.0.5.x API, you
- can check the drivers such as <filename>sound/pci/es1938.c</filename> or
- <filename>sound/pci/maestro3.c</filename> which have also almost the same
- code-base in the ALSA 0.5.x tree, so you can compare the differences.
- </para>
-
- <para>
- This document is still a draft version. Any feedback and
- corrections, please!!
- </para>
- </preface>
-
-
-<!-- ****************************************************** -->
-<!-- File Tree Structure -->
-<!-- ****************************************************** -->
- <chapter id="file-tree">
- <title>File Tree Structure</title>
-
- <section id="file-tree-general">
- <title>General</title>
- <para>
- The ALSA drivers are provided in two ways.
- </para>
-
- <para>
- One is the trees provided as a tarball or via cvs from the
- ALSA's ftp site, and another is the 2.6 (or later) Linux kernel
- tree. To synchronize both, the ALSA driver tree is split into
- two different trees: alsa-kernel and alsa-driver. The former
- contains purely the source code for the Linux 2.6 (or later)
- tree. This tree is designed only for compilation on 2.6 or
- later environment. The latter, alsa-driver, contains many subtle
- files for compiling ALSA drivers outside of the Linux kernel tree,
- wrapper functions for older 2.2 and 2.4 kernels, to adapt the latest kernel API,
- and additional drivers which are still in development or in
- tests. The drivers in alsa-driver tree will be moved to
- alsa-kernel (and eventually to the 2.6 kernel tree) when they are
- finished and confirmed to work fine.
- </para>
-
- <para>
- The file tree structure of ALSA driver is depicted below. Both
- alsa-kernel and alsa-driver have almost the same file
- structure, except for <quote>core</quote> directory. It's
- named as <quote>acore</quote> in alsa-driver tree.
-
- <example>
- <title>ALSA File Tree Structure</title>
- <literallayout>
- sound
- /core
- /oss
- /seq
- /oss
- /instr
- /ioctl32
- /include
- /drivers
- /mpu401
- /opl3
- /i2c
- /l3
- /synth
- /emux
- /pci
- /(cards)
- /isa
- /(cards)
- /arm
- /ppc
- /sparc
- /usb
- /pcmcia /(cards)
- /oss
- </literallayout>
- </example>
- </para>
- </section>
-
- <section id="file-tree-core-directory">
- <title>core directory</title>
- <para>
- This directory contains the middle layer which is the heart
- of ALSA drivers. In this directory, the native ALSA modules are
- stored. The sub-directories contain different modules and are
- dependent upon the kernel config.
- </para>
-
- <section id="file-tree-core-directory-oss">
- <title>core/oss</title>
-
- <para>
- The codes for PCM and mixer OSS emulation modules are stored
- in this directory. The rawmidi OSS emulation is included in
- the ALSA rawmidi code since it's quite small. The sequencer
- code is stored in <filename>core/seq/oss</filename> directory (see
- <link linkend="file-tree-core-directory-seq-oss"><citetitle>
- below</citetitle></link>).
- </para>
- </section>
-
- <section id="file-tree-core-directory-ioctl32">
- <title>core/ioctl32</title>
-
- <para>
- This directory contains the 32bit-ioctl wrappers for 64bit
- architectures such like x86-64, ppc64 and sparc64. For 32bit
- and alpha architectures, these are not compiled.
- </para>
- </section>
-
- <section id="file-tree-core-directory-seq">
- <title>core/seq</title>
- <para>
- This directory and its sub-directories are for the ALSA
- sequencer. This directory contains the sequencer core and
- primary sequencer modules such like snd-seq-midi,
- snd-seq-virmidi, etc. They are compiled only when
- <constant>CONFIG_SND_SEQUENCER</constant> is set in the kernel
- config.
- </para>
- </section>
-
- <section id="file-tree-core-directory-seq-oss">
- <title>core/seq/oss</title>
- <para>
- This contains the OSS sequencer emulation codes.
- </para>
- </section>
-
- <section id="file-tree-core-directory-deq-instr">
- <title>core/seq/instr</title>
- <para>
- This directory contains the modules for the sequencer
- instrument layer.
- </para>
- </section>
- </section>
-
- <section id="file-tree-include-directory">
- <title>include directory</title>
- <para>
- This is the place for the public header files of ALSA drivers,
- which are to be exported to user-space, or included by
- several files at different directories. Basically, the private
- header files should not be placed in this directory, but you may
- still find files there, due to historical reasons :)
- </para>
- </section>
-
- <section id="file-tree-drivers-directory">
- <title>drivers directory</title>
- <para>
- This directory contains code shared among different drivers
- on different architectures. They are hence supposed not to be
- architecture-specific.
- For example, the dummy pcm driver and the serial MIDI
- driver are found in this directory. In the sub-directories,
- there is code for components which are independent from
- bus and cpu architectures.
- </para>
-
- <section id="file-tree-drivers-directory-mpu401">
- <title>drivers/mpu401</title>
- <para>
- The MPU401 and MPU401-UART modules are stored here.
- </para>
- </section>
-
- <section id="file-tree-drivers-directory-opl3">
- <title>drivers/opl3 and opl4</title>
- <para>
- The OPL3 and OPL4 FM-synth stuff is found here.
- </para>
- </section>
- </section>
-
- <section id="file-tree-i2c-directory">
- <title>i2c directory</title>
- <para>
- This contains the ALSA i2c components.
- </para>
-
- <para>
- Although there is a standard i2c layer on Linux, ALSA has its
- own i2c code for some cards, because the soundcard needs only a
- simple operation and the standard i2c API is too complicated for
- such a purpose.
- </para>
-
- <section id="file-tree-i2c-directory-l3">
- <title>i2c/l3</title>
- <para>
- This is a sub-directory for ARM L3 i2c.
- </para>
- </section>
- </section>
-
- <section id="file-tree-synth-directory">
- <title>synth directory</title>
- <para>
- This contains the synth middle-level modules.
- </para>
-
- <para>
- So far, there is only Emu8000/Emu10k1 synth driver under
- the <filename>synth/emux</filename> sub-directory.
- </para>
- </section>
-
- <section id="file-tree-pci-directory">
- <title>pci directory</title>
- <para>
- This directory and its sub-directories hold the top-level card modules
- for PCI soundcards and the code specific to the PCI BUS.
- </para>
-
- <para>
- The drivers compiled from a single file are stored directly
- in the pci directory, while the drivers with several source files are
- stored on their own sub-directory (e.g. emu10k1, ice1712).
- </para>
- </section>
-
- <section id="file-tree-isa-directory">
- <title>isa directory</title>
- <para>
- This directory and its sub-directories hold the top-level card modules
- for ISA soundcards.
- </para>
- </section>
-
- <section id="file-tree-arm-ppc-sparc-directories">
- <title>arm, ppc, and sparc directories</title>
- <para>
- They are used for top-level card modules which are
- specific to one of these architectures.
- </para>
- </section>
-
- <section id="file-tree-usb-directory">
- <title>usb directory</title>
- <para>
- This directory contains the USB-audio driver. In the latest version, the
- USB MIDI driver is integrated in the usb-audio driver.
- </para>
- </section>
-
- <section id="file-tree-pcmcia-directory">
- <title>pcmcia directory</title>
- <para>
- The PCMCIA, especially PCCard drivers will go here. CardBus
- drivers will be in the pci directory, because their API is identical
- to that of standard PCI cards.
- </para>
- </section>
-
- <section id="file-tree-oss-directory">
- <title>oss directory</title>
- <para>
- The OSS/Lite source files are stored here in Linux 2.6 (or
- later) tree. In the ALSA driver tarball, this directory is empty,
- of course :)
- </para>
- </section>
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Basic Flow for PCI Drivers -->
-<!-- ****************************************************** -->
- <chapter id="basic-flow">
- <title>Basic Flow for PCI Drivers</title>
-
- <section id="basic-flow-outline">
- <title>Outline</title>
- <para>
- The minimum flow for PCI soundcards is as follows:
-
- <itemizedlist>
- <listitem><para>define the PCI ID table (see the section
- <link linkend="pci-resource-entries"><citetitle>PCI Entries
- </citetitle></link>).</para></listitem>
- <listitem><para>create <function>probe()</function> callback.</para></listitem>
- <listitem><para>create <function>remove()</function> callback.</para></listitem>
- <listitem><para>create a <structname>pci_driver</structname> structure
- containing the three pointers above.</para></listitem>
- <listitem><para>create an <function>init()</function> function just calling
- the <function>pci_register_driver()</function> to register the pci_driver table
- defined above.</para></listitem>
- <listitem><para>create an <function>exit()</function> function to call
- the <function>pci_unregister_driver()</function> function.</para></listitem>
- </itemizedlist>
- </para>
- </section>
-
- <section id="basic-flow-example">
- <title>Full Code Example</title>
- <para>
- The code example is shown below. Some parts are kept
- unimplemented at this moment but will be filled in the
- next sections. The numbers in the comment lines of the
- <function>snd_mychip_probe()</function> function
- refer to details explained in the following section.
-
- <example>
- <title>Basic Flow for PCI Drivers - Example</title>
- <programlisting>
-<![CDATA[
- #include <linux/init.h>
- #include <linux/pci.h>
- #include <linux/slab.h>
- #include <sound/core.h>
- #include <sound/initval.h>
-
- /* module parameters (see "Module Parameters") */
- /* SNDRV_CARDS: maximum number of cards supported by this module */
- static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
- static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
- static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
- /* definition of the chip-specific record */
- struct mychip {
- struct snd_card *card;
- /* the rest of the implementation will be in section
- * "PCI Resource Management"
- */
- };
-
- /* chip-specific destructor
- * (see "PCI Resource Management")
- */
- static int snd_mychip_free(struct mychip *chip)
- {
- .... /* will be implemented later... */
- }
-
- /* component-destructor
- * (see "Management of Cards and Components")
- */
- static int snd_mychip_dev_free(struct snd_device *device)
- {
- return snd_mychip_free(device->device_data);
- }
-
- /* chip-specific constructor
- * (see "Management of Cards and Components")
- */
- static int snd_mychip_create(struct snd_card *card,
- struct pci_dev *pci,
- struct mychip **rchip)
- {
- struct mychip *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_mychip_dev_free,
- };
-
- *rchip = NULL;
-
- /* check PCI availability here
- * (see "PCI Resource Management")
- */
- ....
-
- /* allocate a chip-specific data with zero filled */
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
- chip->card = card;
-
- /* rest of initialization here; will be implemented
- * later, see "PCI Resource Management"
- */
- ....
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_mychip_free(chip);
- return err;
- }
-
- *rchip = chip;
- return 0;
- }
-
- /* constructor -- see "Constructor" sub-section */
- static int snd_mychip_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
- {
- static int dev;
- struct snd_card *card;
- struct mychip *chip;
- int err;
-
- /* (1) */
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- /* (2) */
- err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
- 0, &card);
- if (err < 0)
- return err;
-
- /* (3) */
- err = snd_mychip_create(card, pci, &chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- /* (4) */
- strcpy(card->driver, "My Chip");
- strcpy(card->shortname, "My Own Chip 123");
- sprintf(card->longname, "%s at 0x%lx irq %i",
- card->shortname, chip->ioport, chip->irq);
-
- /* (5) */
- .... /* implemented later */
-
- /* (6) */
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- /* (7) */
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
- }
-
- /* destructor -- see the "Destructor" sub-section */
- static void snd_mychip_remove(struct pci_dev *pci)
- {
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
- }
-]]>
- </programlisting>
- </example>
- </para>
- </section>
-
- <section id="basic-flow-constructor">
- <title>Constructor</title>
- <para>
- The real constructor of PCI drivers is the <function>probe</function> callback.
- The <function>probe</function> callback and other component-constructors which are called
- from the <function>probe</function> callback cannot be used with
- the <parameter>__init</parameter> prefix
- because any PCI device could be a hotplug device.
- </para>
-
- <para>
- In the <function>probe</function> callback, the following scheme is often used.
- </para>
-
- <section id="basic-flow-constructor-device-index">
- <title>1) Check and increment the device index.</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- static int dev;
- ....
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-]]>
- </programlisting>
- </informalexample>
-
- where enable[dev] is the module option.
- </para>
-
- <para>
- Each time the <function>probe</function> callback is called, check the
- availability of the device. If not available, simply increment
- the device index and returns. dev will be incremented also
- later (<link
- linkend="basic-flow-constructor-set-pci"><citetitle>step
- 7</citetitle></link>).
- </para>
- </section>
-
- <section id="basic-flow-constructor-create-card">
- <title>2) Create a card instance</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_card *card;
- int err;
- ....
- err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
- 0, &card);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The details will be explained in the section
- <link linkend="card-management-card-instance"><citetitle>
- Management of Cards and Components</citetitle></link>.
- </para>
- </section>
-
- <section id="basic-flow-constructor-create-main">
- <title>3) Create a main component</title>
- <para>
- In this part, the PCI resources are allocated.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct mychip *chip;
- ....
- err = snd_mychip_create(card, pci, &chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-]]>
- </programlisting>
- </informalexample>
-
- The details will be explained in the section <link
- linkend="pci-resource"><citetitle>PCI Resource
- Management</citetitle></link>.
- </para>
- </section>
-
- <section id="basic-flow-constructor-main-component">
- <title>4) Set the driver ID and name strings.</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- strcpy(card->driver, "My Chip");
- strcpy(card->shortname, "My Own Chip 123");
- sprintf(card->longname, "%s at 0x%lx irq %i",
- card->shortname, chip->ioport, chip->irq);
-]]>
- </programlisting>
- </informalexample>
-
- The driver field holds the minimal ID string of the
- chip. This is used by alsa-lib's configurator, so keep it
- simple but unique.
- Even the same driver can have different driver IDs to
- distinguish the functionality of each chip type.
- </para>
-
- <para>
- The shortname field is a string shown as more verbose
- name. The longname field contains the information
- shown in <filename>/proc/asound/cards</filename>.
- </para>
- </section>
-
- <section id="basic-flow-constructor-create-other">
- <title>5) Create other components, such as mixer, MIDI, etc.</title>
- <para>
- Here you define the basic components such as
- <link linkend="pcm-interface"><citetitle>PCM</citetitle></link>,
- mixer (e.g. <link linkend="api-ac97"><citetitle>AC97</citetitle></link>),
- MIDI (e.g. <link linkend="midi-interface"><citetitle>MPU-401</citetitle></link>),
- and other interfaces.
- Also, if you want a <link linkend="proc-interface"><citetitle>proc
- file</citetitle></link>, define it here, too.
- </para>
- </section>
-
- <section id="basic-flow-constructor-register-card">
- <title>6) Register the card instance.</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Will be explained in the section <link
- linkend="card-management-registration"><citetitle>Management
- of Cards and Components</citetitle></link>, too.
- </para>
- </section>
-
- <section id="basic-flow-constructor-set-pci">
- <title>7) Set the PCI driver data and return zero.</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-]]>
- </programlisting>
- </informalexample>
-
- In the above, the card record is stored. This pointer is
- used in the remove callback and power-management
- callbacks, too.
- </para>
- </section>
- </section>
-
- <section id="basic-flow-destructor">
- <title>Destructor</title>
- <para>
- The destructor, remove callback, simply releases the card
- instance. Then the ALSA middle layer will release all the
- attached components automatically.
- </para>
-
- <para>
- It would be typically like the following:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static void snd_mychip_remove(struct pci_dev *pci)
- {
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
- }
-]]>
- </programlisting>
- </informalexample>
-
- The above code assumes that the card pointer is set to the PCI
- driver data.
- </para>
- </section>
-
- <section id="basic-flow-header-files">
- <title>Header Files</title>
- <para>
- For the above example, at least the following include files
- are necessary.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- #include <linux/init.h>
- #include <linux/pci.h>
- #include <linux/slab.h>
- #include <sound/core.h>
- #include <sound/initval.h>
-]]>
- </programlisting>
- </informalexample>
-
- where the last one is necessary only when module options are
- defined in the source file. If the code is split into several
- files, the files without module options don't need them.
- </para>
-
- <para>
- In addition to these headers, you'll need
- <filename>&lt;linux/interrupt.h&gt;</filename> for interrupt
- handling, and <filename>&lt;asm/io.h&gt;</filename> for I/O
- access. If you use the <function>mdelay()</function> or
- <function>udelay()</function> functions, you'll need to include
- <filename>&lt;linux/delay.h&gt;</filename> too.
- </para>
-
- <para>
- The ALSA interfaces like the PCM and control APIs are defined in other
- <filename>&lt;sound/xxx.h&gt;</filename> header files.
- They have to be included after
- <filename>&lt;sound/core.h&gt;</filename>.
- </para>
-
- </section>
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Management of Cards and Components -->
-<!-- ****************************************************** -->
- <chapter id="card-management">
- <title>Management of Cards and Components</title>
-
- <section id="card-management-card-instance">
- <title>Card Instance</title>
- <para>
- For each soundcard, a <quote>card</quote> record must be allocated.
- </para>
-
- <para>
- A card record is the headquarters of the soundcard. It manages
- the whole list of devices (components) on the soundcard, such as
- PCM, mixers, MIDI, synthesizer, and so on. Also, the card
- record holds the ID and the name strings of the card, manages
- the root of proc files, and controls the power-management states
- and hotplug disconnections. The component list on the card
- record is used to manage the correct release of resources at
- destruction.
- </para>
-
- <para>
- As mentioned above, to create a card instance, call
- <function>snd_card_new()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_card *card;
- int err;
- err = snd_card_new(&pci->dev, index, id, module, extra_size, &card);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The function takes six arguments: the parent device pointer,
- the card-index number, the id string, the module pointer (usually
- <constant>THIS_MODULE</constant>),
- the size of extra-data space, and the pointer to return the
- card instance. The extra_size argument is used to
- allocate card-&gt;private_data for the
- chip-specific data. Note that these data
- are allocated by <function>snd_card_new()</function>.
- </para>
-
- <para>
- The first argument, the pointer of struct
- <structname>device</structname>, specifies the parent device.
- For PCI devices, typically &amp;pci-&gt; is passed there.
- </para>
- </section>
-
- <section id="card-management-component">
- <title>Components</title>
- <para>
- After the card is created, you can attach the components
- (devices) to the card instance. In an ALSA driver, a component is
- represented as a struct <structname>snd_device</structname> object.
- A component can be a PCM instance, a control interface, a raw
- MIDI interface, etc. Each such instance has one component
- entry.
- </para>
-
- <para>
- A component can be created via
- <function>snd_device_new()</function> function.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_device_new(card, SNDRV_DEV_XXX, chip, &ops);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- This takes the card pointer, the device-level
- (<constant>SNDRV_DEV_XXX</constant>), the data pointer, and the
- callback pointers (<parameter>&amp;ops</parameter>). The
- device-level defines the type of components and the order of
- registration and de-registration. For most components, the
- device-level is already defined. For a user-defined component,
- you can use <constant>SNDRV_DEV_LOWLEVEL</constant>.
- </para>
-
- <para>
- This function itself doesn't allocate the data space. The data
- must be allocated manually beforehand, and its pointer is passed
- as the argument. This pointer (<parameter>chip</parameter> in the
- above example) is used as the identifier for the instance.
- </para>
-
- <para>
- Each pre-defined ALSA component such as ac97 and pcm calls
- <function>snd_device_new()</function> inside its
- constructor. The destructor for each component is defined in the
- callback pointers. Hence, you don't need to take care of
- calling a destructor for such a component.
- </para>
-
- <para>
- If you wish to create your own component, you need to
- set the destructor function to the dev_free callback in
- the <parameter>ops</parameter>, so that it can be released
- automatically via <function>snd_card_free()</function>.
- The next example will show an implementation of chip-specific
- data.
- </para>
- </section>
-
- <section id="card-management-chip-specific">
- <title>Chip-Specific Data</title>
- <para>
- Chip-specific information, e.g. the I/O port address, its
- resource pointer, or the irq number, is stored in the
- chip-specific record.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct mychip {
- ....
- };
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- In general, there are two ways of allocating the chip record.
- </para>
-
- <section id="card-management-chip-specific-snd-card-new">
- <title>1. Allocating via <function>snd_card_new()</function>.</title>
- <para>
- As mentioned above, you can pass the extra-data-length
- to the 5th argument of <function>snd_card_new()</function>, i.e.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
- sizeof(struct mychip), &card);
-]]>
- </programlisting>
- </informalexample>
-
- struct <structname>mychip</structname> is the type of the chip record.
- </para>
-
- <para>
- In return, the allocated record can be accessed as
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct mychip *chip = card->private_data;
-]]>
- </programlisting>
- </informalexample>
-
- With this method, you don't have to allocate twice.
- The record is released together with the card instance.
- </para>
- </section>
-
- <section id="card-management-chip-specific-allocate-extra">
- <title>2. Allocating an extra device.</title>
-
- <para>
- After allocating a card instance via
- <function>snd_card_new()</function> (with
- <constant>0</constant> on the 4th arg), call
- <function>kzalloc()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_card *card;
- struct mychip *chip;
- err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
- 0, &card);
- .....
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The chip record should have the field to hold the card
- pointer at least,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct mychip {
- struct snd_card *card;
- ....
- };
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Then, set the card pointer in the returned chip instance.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- chip->card = card;
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Next, initialize the fields, and register this chip
- record as a low-level device with a specified
- <parameter>ops</parameter>,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static struct snd_device_ops ops = {
- .dev_free = snd_mychip_dev_free,
- };
- ....
- snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
-]]>
- </programlisting>
- </informalexample>
-
- <function>snd_mychip_dev_free()</function> is the
- device-destructor function, which will call the real
- destructor.
- </para>
-
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_mychip_dev_free(struct snd_device *device)
- {
- return snd_mychip_free(device->device_data);
- }
-]]>
- </programlisting>
- </informalexample>
-
- where <function>snd_mychip_free()</function> is the real destructor.
- </para>
- </section>
- </section>
-
- <section id="card-management-registration">
- <title>Registration and Release</title>
- <para>
- After all components are assigned, register the card instance
- by calling <function>snd_card_register()</function>. Access
- to the device files is enabled at this point. That is, before
- <function>snd_card_register()</function> is called, the
- components are safely inaccessible from external side. If this
- call fails, exit the probe function after releasing the card via
- <function>snd_card_free()</function>.
- </para>
-
- <para>
- For releasing the card instance, you can call simply
- <function>snd_card_free()</function>. As mentioned earlier, all
- components are released automatically by this call.
- </para>
-
- <para>
- For a device which allows hotplugging, you can use
- <function>snd_card_free_when_closed</function>. This one will
- postpone the destruction until all devices are closed.
- </para>
-
- </section>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- PCI Resource Management -->
-<!-- ****************************************************** -->
- <chapter id="pci-resource">
- <title>PCI Resource Management</title>
-
- <section id="pci-resource-example">
- <title>Full Code Example</title>
- <para>
- In this section, we'll complete the chip-specific constructor,
- destructor and PCI entries. Example code is shown first,
- below.
-
- <example>
- <title>PCI Resource Management Example</title>
- <programlisting>
-<![CDATA[
- struct mychip {
- struct snd_card *card;
- struct pci_dev *pci;
-
- unsigned long port;
- int irq;
- };
-
- static int snd_mychip_free(struct mychip *chip)
- {
- /* disable hardware here if any */
- .... /* (not implemented in this document) */
-
- /* release the irq */
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- /* release the I/O ports & memory */
- pci_release_regions(chip->pci);
- /* disable the PCI entry */
- pci_disable_device(chip->pci);
- /* release the data */
- kfree(chip);
- return 0;
- }
-
- /* chip-specific constructor */
- static int snd_mychip_create(struct snd_card *card,
- struct pci_dev *pci,
- struct mychip **rchip)
- {
- struct mychip *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_mychip_dev_free,
- };
-
- *rchip = NULL;
-
- /* initialize the PCI entry */
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
- /* check PCI availability (28bit DMA) */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
- printk(KERN_ERR "error to set 28bit mask DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- /* initialize the stuff */
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- /* (1) PCI resource allocation */
- err = pci_request_regions(pci, "My Chip");
- if (err < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_mychip_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
- snd_mychip_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
- /* (2) initialization of the chip hardware */
- .... /* (not implemented in this document) */
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_mychip_free(chip);
- return err;
- }
-
- *rchip = chip;
- return 0;
- }
-
- /* PCI IDs */
- static struct pci_device_id snd_mychip_ids[] = {
- { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- ....
- { 0, }
- };
- MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
-
- /* pci_driver definition */
- static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_mychip_ids,
- .probe = snd_mychip_probe,
- .remove = snd_mychip_remove,
- };
-
- /* module initialization */
- static int __init alsa_card_mychip_init(void)
- {
- return pci_register_driver(&driver);
- }
-
- /* module clean up */
- static void __exit alsa_card_mychip_exit(void)
- {
- pci_unregister_driver(&driver);
- }
-
- module_init(alsa_card_mychip_init)
- module_exit(alsa_card_mychip_exit)
-
- EXPORT_NO_SYMBOLS; /* for old kernels only */
-]]>
- </programlisting>
- </example>
- </para>
- </section>
-
- <section id="pci-resource-some-haftas">
- <title>Some Hafta's</title>
- <para>
- The allocation of PCI resources is done in the
- <function>probe()</function> function, and usually an extra
- <function>xxx_create()</function> function is written for this
- purpose.
- </para>
-
- <para>
- In the case of PCI devices, you first have to call
- the <function>pci_enable_device()</function> function before
- allocating resources. Also, you need to set the proper PCI DMA
- mask to limit the accessed I/O range. In some cases, you might
- need to call <function>pci_set_master()</function> function,
- too.
- </para>
-
- <para>
- Suppose the 28bit mask, and the code to be added would be like:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
- printk(KERN_ERR "error to set 28bit mask DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
-]]>
- </programlisting>
- </informalexample>
- </para>
- </section>
-
- <section id="pci-resource-resource-allocation">
- <title>Resource Allocation</title>
- <para>
- The allocation of I/O ports and irqs is done via standard kernel
- functions. Unlike ALSA ver.0.5.x., there are no helpers for
- that. And these resources must be released in the destructor
- function (see below). Also, on ALSA 0.9.x, you don't need to
- allocate (pseudo-)DMA for PCI like in ALSA 0.5.x.
- </para>
-
- <para>
- Now assume that the PCI device has an I/O port with 8 bytes
- and an interrupt. Then struct <structname>mychip</structname> will have the
- following fields:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct mychip {
- struct snd_card *card;
-
- unsigned long port;
- int irq;
- };
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- For an I/O port (and also a memory region), you need to have
- the resource pointer for the standard resource management. For
- an irq, you have to keep only the irq number (integer). But you
- need to initialize this number as -1 before actual allocation,
- since irq 0 is valid. The port address and its resource pointer
- can be initialized as null by
- <function>kzalloc()</function> automatically, so you
- don't have to take care of resetting them.
- </para>
-
- <para>
- The allocation of an I/O port is done like this:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- err = pci_request_regions(pci, "My Chip");
- if (err < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->port = pci_resource_start(pci, 0);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- <!-- obsolete -->
- It will reserve the I/O port region of 8 bytes of the given
- PCI device. The returned value, chip-&gt;res_port, is allocated
- via <function>kmalloc()</function> by
- <function>request_region()</function>. The pointer must be
- released via <function>kfree()</function>, but there is a
- problem with this. This issue will be explained later.
- </para>
-
- <para>
- The allocation of an interrupt source is done like this:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- if (request_irq(pci->irq, snd_mychip_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
- snd_mychip_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-]]>
- </programlisting>
- </informalexample>
-
- where <function>snd_mychip_interrupt()</function> is the
- interrupt handler defined <link
- linkend="pcm-interface-interrupt-handler"><citetitle>later</citetitle></link>.
- Note that chip-&gt;irq should be defined
- only when <function>request_irq()</function> succeeded.
- </para>
-
- <para>
- On the PCI bus, interrupts can be shared. Thus,
- <constant>IRQF_SHARED</constant> is used as the interrupt flag of
- <function>request_irq()</function>.
- </para>
-
- <para>
- The last argument of <function>request_irq()</function> is the
- data pointer passed to the interrupt handler. Usually, the
- chip-specific record is used for that, but you can use what you
- like, too.
- </para>
-
- <para>
- I won't give details about the interrupt handler at this
- point, but at least its appearance can be explained now. The
- interrupt handler looks usually like the following:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
- {
- struct mychip *chip = dev_id;
- ....
- return IRQ_HANDLED;
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Now let's write the corresponding destructor for the resources
- above. The role of destructor is simple: disable the hardware
- (if already activated) and release the resources. So far, we
- have no hardware part, so the disabling code is not written here.
- </para>
-
- <para>
- To release the resources, the <quote>check-and-release</quote>
- method is a safer way. For the interrupt, do like this:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-]]>
- </programlisting>
- </informalexample>
-
- Since the irq number can start from 0, you should initialize
- chip-&gt;irq with a negative value (e.g. -1), so that you can
- check the validity of the irq number as above.
- </para>
-
- <para>
- When you requested I/O ports or memory regions via
- <function>pci_request_region()</function> or
- <function>pci_request_regions()</function> like in this example,
- release the resource(s) using the corresponding function,
- <function>pci_release_region()</function> or
- <function>pci_release_regions()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- pci_release_regions(chip->pci);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- When you requested manually via <function>request_region()</function>
- or <function>request_mem_region</function>, you can release it via
- <function>release_resource()</function>. Suppose that you keep
- the resource pointer returned from <function>request_region()</function>
- in chip-&gt;res_port, the release procedure looks like:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- release_and_free_resource(chip->res_port);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Don't forget to call <function>pci_disable_device()</function>
- before the end.
- </para>
-
- <para>
- And finally, release the chip-specific record.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- kfree(chip);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- We didn't implement the hardware disabling part in the above.
- If you need to do this, please note that the destructor may be
- called even before the initialization of the chip is completed.
- It would be better to have a flag to skip hardware disabling
- if the hardware was not initialized yet.
- </para>
-
- <para>
- When the chip-data is assigned to the card using
- <function>snd_device_new()</function> with
- <constant>SNDRV_DEV_LOWLELVEL</constant> , its destructor is
- called at the last. That is, it is assured that all other
- components like PCMs and controls have already been released.
- You don't have to stop PCMs, etc. explicitly, but just
- call low-level hardware stopping.
- </para>
-
- <para>
- The management of a memory-mapped region is almost as same as
- the management of an I/O port. You'll need three fields like
- the following:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct mychip {
- ....
- unsigned long iobase_phys;
- void __iomem *iobase_virt;
- };
-]]>
- </programlisting>
- </informalexample>
-
- and the allocation would be like below:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- if ((err = pci_request_regions(pci, "My Chip")) < 0) {
- kfree(chip);
- return err;
- }
- chip->iobase_phys = pci_resource_start(pci, 0);
- chip->iobase_virt = ioremap_nocache(chip->iobase_phys,
- pci_resource_len(pci, 0));
-]]>
- </programlisting>
- </informalexample>
-
- and the corresponding destructor would be:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_mychip_free(struct mychip *chip)
- {
- ....
- if (chip->iobase_virt)
- iounmap(chip->iobase_virt);
- ....
- pci_release_regions(chip->pci);
- ....
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- </section>
-
- <section id="pci-resource-entries">
- <title>PCI Entries</title>
- <para>
- So far, so good. Let's finish the missing PCI
- stuff. At first, we need a
- <structname>pci_device_id</structname> table for this
- chipset. It's a table of PCI vendor/device ID number, and some
- masks.
- </para>
-
- <para>
- For example,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static struct pci_device_id snd_mychip_ids[] = {
- { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- ....
- { 0, }
- };
- MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The first and second fields of
- the <structname>pci_device_id</structname> structure are the vendor and
- device IDs. If you have no reason to filter the matching
- devices, you can leave the remaining fields as above. The last
- field of the <structname>pci_device_id</structname> struct contains
- private data for this entry. You can specify any value here, for
- example, to define specific operations for supported device IDs.
- Such an example is found in the intel8x0 driver.
- </para>
-
- <para>
- The last entry of this list is the terminator. You must
- specify this all-zero entry.
- </para>
-
- <para>
- Then, prepare the <structname>pci_driver</structname> record:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_mychip_ids,
- .probe = snd_mychip_probe,
- .remove = snd_mychip_remove,
- };
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The <structfield>probe</structfield> and
- <structfield>remove</structfield> functions have already
- been defined in the previous sections.
- The <structfield>name</structfield>
- field is the name string of this device. Note that you must not
- use a slash <quote>/</quote> in this string.
- </para>
-
- <para>
- And at last, the module entries:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int __init alsa_card_mychip_init(void)
- {
- return pci_register_driver(&driver);
- }
-
- static void __exit alsa_card_mychip_exit(void)
- {
- pci_unregister_driver(&driver);
- }
-
- module_init(alsa_card_mychip_init)
- module_exit(alsa_card_mychip_exit)
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Note that these module entries are tagged with
- <parameter>__init</parameter> and
- <parameter>__exit</parameter> prefixes.
- </para>
-
- <para>
- Oh, one thing was forgotten. If you have no exported symbols,
- you need to declare it in 2.2 or 2.4 kernels (it's not necessary in 2.6 kernels).
-
- <informalexample>
- <programlisting>
-<![CDATA[
- EXPORT_NO_SYMBOLS;
-]]>
- </programlisting>
- </informalexample>
-
- That's all!
- </para>
- </section>
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- PCM Interface -->
-<!-- ****************************************************** -->
- <chapter id="pcm-interface">
- <title>PCM Interface</title>
-
- <section id="pcm-interface-general">
- <title>General</title>
- <para>
- The PCM middle layer of ALSA is quite powerful and it is only
- necessary for each driver to implement the low-level functions
- to access its hardware.
- </para>
-
- <para>
- For accessing to the PCM layer, you need to include
- <filename>&lt;sound/pcm.h&gt;</filename> first. In addition,
- <filename>&lt;sound/pcm_params.h&gt;</filename> might be needed
- if you access to some functions related with hw_param.
- </para>
-
- <para>
- Each card device can have up to four pcm instances. A pcm
- instance corresponds to a pcm device file. The limitation of
- number of instances comes only from the available bit size of
- the Linux's device numbers. Once when 64bit device number is
- used, we'll have more pcm instances available.
- </para>
-
- <para>
- A pcm instance consists of pcm playback and capture streams,
- and each pcm stream consists of one or more pcm substreams. Some
- soundcards support multiple playback functions. For example,
- emu10k1 has a PCM playback of 32 stereo substreams. In this case, at
- each open, a free substream is (usually) automatically chosen
- and opened. Meanwhile, when only one substream exists and it was
- already opened, the successful open will either block
- or error with <constant>EAGAIN</constant> according to the
- file open mode. But you don't have to care about such details in your
- driver. The PCM middle layer will take care of such work.
- </para>
- </section>
-
- <section id="pcm-interface-example">
- <title>Full Code Example</title>
- <para>
- The example code below does not include any hardware access
- routines but shows only the skeleton, how to build up the PCM
- interfaces.
-
- <example>
- <title>PCM Example Code</title>
- <programlisting>
-<![CDATA[
- #include <sound/pcm.h>
- ....
-
- /* hardware definition */
- static struct snd_pcm_hardware snd_mychip_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 32768,
- .period_bytes_min = 4096,
- .period_bytes_max = 32768,
- .periods_min = 1,
- .periods_max = 1024,
- };
-
- /* hardware definition */
- static struct snd_pcm_hardware snd_mychip_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 32768,
- .period_bytes_min = 4096,
- .period_bytes_max = 32768,
- .periods_min = 1,
- .periods_max = 1024,
- };
-
- /* open callback */
- static int snd_mychip_playback_open(struct snd_pcm_substream *substream)
- {
- struct mychip *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_mychip_playback_hw;
- /* more hardware-initialization will be done here */
- ....
- return 0;
- }
-
- /* close callback */
- static int snd_mychip_playback_close(struct snd_pcm_substream *substream)
- {
- struct mychip *chip = snd_pcm_substream_chip(substream);
- /* the hardware-specific codes will be here */
- ....
- return 0;
-
- }
-
- /* open callback */
- static int snd_mychip_capture_open(struct snd_pcm_substream *substream)
- {
- struct mychip *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_mychip_capture_hw;
- /* more hardware-initialization will be done here */
- ....
- return 0;
- }
-
- /* close callback */
- static int snd_mychip_capture_close(struct snd_pcm_substream *substream)
- {
- struct mychip *chip = snd_pcm_substream_chip(substream);
- /* the hardware-specific codes will be here */
- ....
- return 0;
-
- }
-
- /* hw_params callback */
- static int snd_mychip_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
- {
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- }
-
- /* hw_free callback */
- static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream)
- {
- return snd_pcm_lib_free_pages(substream);
- }
-
- /* prepare callback */
- static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream)
- {
- struct mychip *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- /* set up the hardware with the current configuration
- * for example...
- */
- mychip_set_sample_format(chip, runtime->format);
- mychip_set_sample_rate(chip, runtime->rate);
- mychip_set_channels(chip, runtime->channels);
- mychip_set_dma_setup(chip, runtime->dma_addr,
- chip->buffer_size,
- chip->period_size);
- return 0;
- }
-
- /* trigger callback */
- static int snd_mychip_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
- {
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* do something to start the PCM engine */
- ....
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- /* do something to stop the PCM engine */
- ....
- break;
- default:
- return -EINVAL;
- }
- }
-
- /* pointer callback */
- static snd_pcm_uframes_t
- snd_mychip_pcm_pointer(struct snd_pcm_substream *substream)
- {
- struct mychip *chip = snd_pcm_substream_chip(substream);
- unsigned int current_ptr;
-
- /* get the current hardware pointer */
- current_ptr = mychip_get_hw_pointer(chip);
- return current_ptr;
- }
-
- /* operators */
- static struct snd_pcm_ops snd_mychip_playback_ops = {
- .open = snd_mychip_playback_open,
- .close = snd_mychip_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_mychip_pcm_hw_params,
- .hw_free = snd_mychip_pcm_hw_free,
- .prepare = snd_mychip_pcm_prepare,
- .trigger = snd_mychip_pcm_trigger,
- .pointer = snd_mychip_pcm_pointer,
- };
-
- /* operators */
- static struct snd_pcm_ops snd_mychip_capture_ops = {
- .open = snd_mychip_capture_open,
- .close = snd_mychip_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_mychip_pcm_hw_params,
- .hw_free = snd_mychip_pcm_hw_free,
- .prepare = snd_mychip_pcm_prepare,
- .trigger = snd_mychip_pcm_trigger,
- .pointer = snd_mychip_pcm_pointer,
- };
-
- /*
- * definitions of capture are omitted here...
- */
-
- /* create a pcm device */
- static int snd_mychip_new_pcm(struct mychip *chip)
- {
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = chip;
- strcpy(pcm->name, "My Chip");
- chip->pcm = pcm;
- /* set operators */
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_mychip_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_mychip_capture_ops);
- /* pre-allocation of buffers */
- /* NOTE: this may fail */
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- 64*1024, 64*1024);
- return 0;
- }
-]]>
- </programlisting>
- </example>
- </para>
- </section>
-
- <section id="pcm-interface-constructor">
- <title>Constructor</title>
- <para>
- A pcm instance is allocated by the <function>snd_pcm_new()</function>
- function. It would be better to create a constructor for pcm,
- namely,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_mychip_new_pcm(struct mychip *chip)
- {
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = chip;
- strcpy(pcm->name, "My Chip");
- chip->pcm = pcm;
- ....
- return 0;
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The <function>snd_pcm_new()</function> function takes four
- arguments. The first argument is the card pointer to which this
- pcm is assigned, and the second is the ID string.
- </para>
-
- <para>
- The third argument (<parameter>index</parameter>, 0 in the
- above) is the index of this new pcm. It begins from zero. If
- you create more than one pcm instances, specify the
- different numbers in this argument. For example,
- <parameter>index</parameter> = 1 for the second PCM device.
- </para>
-
- <para>
- The fourth and fifth arguments are the number of substreams
- for playback and capture, respectively. Here 1 is used for
- both arguments. When no playback or capture substreams are available,
- pass 0 to the corresponding argument.
- </para>
-
- <para>
- If a chip supports multiple playbacks or captures, you can
- specify more numbers, but they must be handled properly in
- open/close, etc. callbacks. When you need to know which
- substream you are referring to, then it can be obtained from
- struct <structname>snd_pcm_substream</structname> data passed to each callback
- as follows:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_pcm_substream *substream;
- int index = substream->number;
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- After the pcm is created, you need to set operators for each
- pcm stream.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_mychip_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_mychip_capture_ops);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The operators are defined typically like this:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static struct snd_pcm_ops snd_mychip_playback_ops = {
- .open = snd_mychip_pcm_open,
- .close = snd_mychip_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_mychip_pcm_hw_params,
- .hw_free = snd_mychip_pcm_hw_free,
- .prepare = snd_mychip_pcm_prepare,
- .trigger = snd_mychip_pcm_trigger,
- .pointer = snd_mychip_pcm_pointer,
- };
-]]>
- </programlisting>
- </informalexample>
-
- All the callbacks are described in the
- <link linkend="pcm-interface-operators"><citetitle>
- Operators</citetitle></link> subsection.
- </para>
-
- <para>
- After setting the operators, you probably will want to
- pre-allocate the buffer. For the pre-allocation, simply call
- the following:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- 64*1024, 64*1024);
-]]>
- </programlisting>
- </informalexample>
-
- It will allocate a buffer up to 64kB as default.
- Buffer management details will be described in the later section <link
- linkend="buffer-and-memory"><citetitle>Buffer and Memory
- Management</citetitle></link>.
- </para>
-
- <para>
- Additionally, you can set some extra information for this pcm
- in pcm-&gt;info_flags.
- The available values are defined as
- <constant>SNDRV_PCM_INFO_XXX</constant> in
- <filename>&lt;sound/asound.h&gt;</filename>, which is used for
- the hardware definition (described later). When your soundchip
- supports only half-duplex, specify like this:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
-]]>
- </programlisting>
- </informalexample>
- </para>
- </section>
-
- <section id="pcm-interface-destructor">
- <title>... And the Destructor?</title>
- <para>
- The destructor for a pcm instance is not always
- necessary. Since the pcm device will be released by the middle
- layer code automatically, you don't have to call the destructor
- explicitly.
- </para>
-
- <para>
- The destructor would be necessary if you created
- special records internally and needed to release them. In such a
- case, set the destructor function to
- pcm-&gt;private_free:
-
- <example>
- <title>PCM Instance with a Destructor</title>
- <programlisting>
-<![CDATA[
- static void mychip_pcm_free(struct snd_pcm *pcm)
- {
- struct mychip *chip = snd_pcm_chip(pcm);
- /* free your own data */
- kfree(chip->my_private_pcm_data);
- /* do what you like else */
- ....
- }
-
- static int snd_mychip_new_pcm(struct mychip *chip)
- {
- struct snd_pcm *pcm;
- ....
- /* allocate your own data */
- chip->my_private_pcm_data = kmalloc(...);
- /* set the destructor */
- pcm->private_data = chip;
- pcm->private_free = mychip_pcm_free;
- ....
- }
-]]>
- </programlisting>
- </example>
- </para>
- </section>
-
- <section id="pcm-interface-runtime">
- <title>Runtime Pointer - The Chest of PCM Information</title>
- <para>
- When the PCM substream is opened, a PCM runtime instance is
- allocated and assigned to the substream. This pointer is
- accessible via <constant>substream-&gt;runtime</constant>.
- This runtime pointer holds most information you need
- to control the PCM: the copy of hw_params and sw_params configurations, the buffer
- pointers, mmap records, spinlocks, etc.
- </para>
-
- <para>
- The definition of runtime instance is found in
- <filename>&lt;sound/pcm.h&gt;</filename>. Here are
- the contents of this file:
- <informalexample>
- <programlisting>
-<![CDATA[
-struct _snd_pcm_runtime {
- /* -- Status -- */
- struct snd_pcm_substream *trigger_master;
- snd_timestamp_t trigger_tstamp; /* trigger timestamp */
- int overrange;
- snd_pcm_uframes_t avail_max;
- snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
- snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time*/
-
- /* -- HW params -- */
- snd_pcm_access_t access; /* access mode */
- snd_pcm_format_t format; /* SNDRV_PCM_FORMAT_* */
- snd_pcm_subformat_t subformat; /* subformat */
- unsigned int rate; /* rate in Hz */
- unsigned int channels; /* channels */
- snd_pcm_uframes_t period_size; /* period size */
- unsigned int periods; /* periods */
- snd_pcm_uframes_t buffer_size; /* buffer size */
- unsigned int tick_time; /* tick time */
- snd_pcm_uframes_t min_align; /* Min alignment for the format */
- size_t byte_align;
- unsigned int frame_bits;
- unsigned int sample_bits;
- unsigned int info;
- unsigned int rate_num;
- unsigned int rate_den;
-
- /* -- SW params -- */
- struct timespec tstamp_mode; /* mmap timestamp is updated */
- unsigned int period_step;
- unsigned int sleep_min; /* min ticks to sleep */
- snd_pcm_uframes_t start_threshold;
- snd_pcm_uframes_t stop_threshold;
- snd_pcm_uframes_t silence_threshold; /* Silence filling happens when
- noise is nearest than this */
- snd_pcm_uframes_t silence_size; /* Silence filling size */
- snd_pcm_uframes_t boundary; /* pointers wrap point */
-
- snd_pcm_uframes_t silenced_start;
- snd_pcm_uframes_t silenced_size;
-
- snd_pcm_sync_id_t sync; /* hardware synchronization ID */
-
- /* -- mmap -- */
- volatile struct snd_pcm_mmap_status *status;
- volatile struct snd_pcm_mmap_control *control;
- atomic_t mmap_count;
-
- /* -- locking / scheduling -- */
- spinlock_t lock;
- wait_queue_head_t sleep;
- struct timer_list tick_timer;
- struct fasync_struct *fasync;
-
- /* -- private section -- */
- void *private_data;
- void (*private_free)(struct snd_pcm_runtime *runtime);
-
- /* -- hardware description -- */
- struct snd_pcm_hardware hw;
- struct snd_pcm_hw_constraints hw_constraints;
-
- /* -- timer -- */
- unsigned int timer_resolution; /* timer resolution */
-
- /* -- DMA -- */
- unsigned char *dma_area; /* DMA area */
- dma_addr_t dma_addr; /* physical bus address (not accessible from main CPU) */
- size_t dma_bytes; /* size of DMA area */
-
- struct snd_dma_buffer *dma_buffer_p; /* allocated buffer */
-
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
- /* -- OSS things -- */
- struct snd_pcm_oss_runtime oss;
-#endif
-};
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- For the operators (callbacks) of each sound driver, most of
- these records are supposed to be read-only. Only the PCM
- middle-layer changes / updates them. The exceptions are
- the hardware description (hw) DMA buffer information and the
- private data. Besides, if you use the standard buffer allocation
- method via <function>snd_pcm_lib_malloc_pages()</function>,
- you don't need to set the DMA buffer information by yourself.
- </para>
-
- <para>
- In the sections below, important records are explained.
- </para>
-
- <section id="pcm-interface-runtime-hw">
- <title>Hardware Description</title>
- <para>
- The hardware descriptor (struct <structname>snd_pcm_hardware</structname>)
- contains the definitions of the fundamental hardware
- configuration. Above all, you'll need to define this in
- <link linkend="pcm-interface-operators-open-callback"><citetitle>
- the open callback</citetitle></link>.
- Note that the runtime instance holds the copy of the
- descriptor, not the pointer to the existing descriptor. That
- is, in the open callback, you can modify the copied descriptor
- (<constant>runtime-&gt;hw</constant>) as you need. For example, if the maximum
- number of channels is 1 only on some chip models, you can
- still use the same hardware descriptor and change the
- channels_max later:
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_pcm_runtime *runtime = substream->runtime;
- ...
- runtime->hw = snd_mychip_playback_hw; /* common definition */
- if (chip->model == VERY_OLD_ONE)
- runtime->hw.channels_max = 1;
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Typically, you'll have a hardware descriptor as below:
- <informalexample>
- <programlisting>
-<![CDATA[
- static struct snd_pcm_hardware snd_mychip_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 32768,
- .period_bytes_min = 4096,
- .period_bytes_max = 32768,
- .periods_min = 1,
- .periods_max = 1024,
- };
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- <itemizedlist>
- <listitem><para>
- The <structfield>info</structfield> field contains the type and
- capabilities of this pcm. The bit flags are defined in
- <filename>&lt;sound/asound.h&gt;</filename> as
- <constant>SNDRV_PCM_INFO_XXX</constant>. Here, at least, you
- have to specify whether the mmap is supported and which
- interleaved format is supported.
- When the hardware supports mmap, add the
- <constant>SNDRV_PCM_INFO_MMAP</constant> flag here. When the
- hardware supports the interleaved or the non-interleaved
- formats, <constant>SNDRV_PCM_INFO_INTERLEAVED</constant> or
- <constant>SNDRV_PCM_INFO_NONINTERLEAVED</constant> flag must
- be set, respectively. If both are supported, you can set both,
- too.
- </para>
-
- <para>
- In the above example, <constant>MMAP_VALID</constant> and
- <constant>BLOCK_TRANSFER</constant> are specified for the OSS mmap
- mode. Usually both are set. Of course,
- <constant>MMAP_VALID</constant> is set only if the mmap is
- really supported.
- </para>
-
- <para>
- The other possible flags are
- <constant>SNDRV_PCM_INFO_PAUSE</constant> and
- <constant>SNDRV_PCM_INFO_RESUME</constant>. The
- <constant>PAUSE</constant> bit means that the pcm supports the
- <quote>pause</quote> operation, while the
- <constant>RESUME</constant> bit means that the pcm supports
- the full <quote>suspend/resume</quote> operation.
- If the <constant>PAUSE</constant> flag is set,
- the <structfield>trigger</structfield> callback below
- must handle the corresponding (pause push/release) commands.
- The suspend/resume trigger commands can be defined even without
- the <constant>RESUME</constant> flag. See <link
- linkend="power-management"><citetitle>
- Power Management</citetitle></link> section for details.
- </para>
-
- <para>
- When the PCM substreams can be synchronized (typically,
- synchronized start/stop of a playback and a capture streams),
- you can give <constant>SNDRV_PCM_INFO_SYNC_START</constant>,
- too. In this case, you'll need to check the linked-list of
- PCM substreams in the trigger callback. This will be
- described in the later section.
- </para>
- </listitem>
-
- <listitem>
- <para>
- <structfield>formats</structfield> field contains the bit-flags
- of supported formats (<constant>SNDRV_PCM_FMTBIT_XXX</constant>).
- If the hardware supports more than one format, give all or'ed
- bits. In the example above, the signed 16bit little-endian
- format is specified.
- </para>
- </listitem>
-
- <listitem>
- <para>
- <structfield>rates</structfield> field contains the bit-flags of
- supported rates (<constant>SNDRV_PCM_RATE_XXX</constant>).
- When the chip supports continuous rates, pass
- <constant>CONTINUOUS</constant> bit additionally.
- The pre-defined rate bits are provided only for typical
- rates. If your chip supports unconventional rates, you need to add
- the <constant>KNOT</constant> bit and set up the hardware
- constraint manually (explained later).
- </para>
- </listitem>
-
- <listitem>
- <para>
- <structfield>rate_min</structfield> and
- <structfield>rate_max</structfield> define the minimum and
- maximum sample rate. This should correspond somehow to
- <structfield>rates</structfield> bits.
- </para>
- </listitem>
-
- <listitem>
- <para>
- <structfield>channel_min</structfield> and
- <structfield>channel_max</structfield>
- define, as you might already expected, the minimum and maximum
- number of channels.
- </para>
- </listitem>
-
- <listitem>
- <para>
- <structfield>buffer_bytes_max</structfield> defines the
- maximum buffer size in bytes. There is no
- <structfield>buffer_bytes_min</structfield> field, since
- it can be calculated from the minimum period size and the
- minimum number of periods.
- Meanwhile, <structfield>period_bytes_min</structfield> and
- define the minimum and maximum size of the period in bytes.
- <structfield>periods_max</structfield> and
- <structfield>periods_min</structfield> define the maximum and
- minimum number of periods in the buffer.
- </para>
-
- <para>
- The <quote>period</quote> is a term that corresponds to
- a fragment in the OSS world. The period defines the size at
- which a PCM interrupt is generated. This size strongly
- depends on the hardware.
- Generally, the smaller period size will give you more
- interrupts, that is, more controls.
- In the case of capture, this size defines the input latency.
- On the other hand, the whole buffer size defines the
- output latency for the playback direction.
- </para>
- </listitem>
-
- <listitem>
- <para>
- There is also a field <structfield>fifo_size</structfield>.
- This specifies the size of the hardware FIFO, but currently it
- is neither used in the driver nor in the alsa-lib. So, you
- can ignore this field.
- </para>
- </listitem>
- </itemizedlist>
- </para>
- </section>
-
- <section id="pcm-interface-runtime-config">
- <title>PCM Configurations</title>
- <para>
- Ok, let's go back again to the PCM runtime records.
- The most frequently referred records in the runtime instance are
- the PCM configurations.
- The PCM configurations are stored in the runtime instance
- after the application sends <type>hw_params</type> data via
- alsa-lib. There are many fields copied from hw_params and
- sw_params structs. For example,
- <structfield>format</structfield> holds the format type
- chosen by the application. This field contains the enum value
- <constant>SNDRV_PCM_FORMAT_XXX</constant>.
- </para>
-
- <para>
- One thing to be noted is that the configured buffer and period
- sizes are stored in <quote>frames</quote> in the runtime.
- In the ALSA world, 1 frame = channels * samples-size.
- For conversion between frames and bytes, you can use the
- <function>frames_to_bytes()</function> and
- <function>bytes_to_frames()</function> helper functions.
- <informalexample>
- <programlisting>
-<![CDATA[
- period_bytes = frames_to_bytes(runtime, runtime->period_size);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Also, many software parameters (sw_params) are
- stored in frames, too. Please check the type of the field.
- <type>snd_pcm_uframes_t</type> is for the frames as unsigned
- integer while <type>snd_pcm_sframes_t</type> is for the frames
- as signed integer.
- </para>
- </section>
-
- <section id="pcm-interface-runtime-dma">
- <title>DMA Buffer Information</title>
- <para>
- The DMA buffer is defined by the following four fields,
- <structfield>dma_area</structfield>,
- <structfield>dma_addr</structfield>,
- <structfield>dma_bytes</structfield> and
- <structfield>dma_private</structfield>.
- The <structfield>dma_area</structfield> holds the buffer
- pointer (the logical address). You can call
- <function>memcpy</function> from/to
- this pointer. Meanwhile, <structfield>dma_addr</structfield>
- holds the physical address of the buffer. This field is
- specified only when the buffer is a linear buffer.
- <structfield>dma_bytes</structfield> holds the size of buffer
- in bytes. <structfield>dma_private</structfield> is used for
- the ALSA DMA allocator.
- </para>
-
- <para>
- If you use a standard ALSA function,
- <function>snd_pcm_lib_malloc_pages()</function>, for
- allocating the buffer, these fields are set by the ALSA middle
- layer, and you should <emphasis>not</emphasis> change them by
- yourself. You can read them but not write them.
- On the other hand, if you want to allocate the buffer by
- yourself, you'll need to manage it in hw_params callback.
- At least, <structfield>dma_bytes</structfield> is mandatory.
- <structfield>dma_area</structfield> is necessary when the
- buffer is mmapped. If your driver doesn't support mmap, this
- field is not necessary. <structfield>dma_addr</structfield>
- is also optional. You can use
- <structfield>dma_private</structfield> as you like, too.
- </para>
- </section>
-
- <section id="pcm-interface-runtime-status">
- <title>Running Status</title>
- <para>
- The running status can be referred via <constant>runtime-&gt;status</constant>.
- This is the pointer to the struct <structname>snd_pcm_mmap_status</structname>
- record. For example, you can get the current DMA hardware
- pointer via <constant>runtime-&gt;status-&gt;hw_ptr</constant>.
- </para>
-
- <para>
- The DMA application pointer can be referred via
- <constant>runtime-&gt;control</constant>, which points to the
- struct <structname>snd_pcm_mmap_control</structname> record.
- However, accessing directly to this value is not recommended.
- </para>
- </section>
-
- <section id="pcm-interface-runtime-private">
- <title>Private Data</title>
- <para>
- You can allocate a record for the substream and store it in
- <constant>runtime-&gt;private_data</constant>. Usually, this
- is done in
- <link linkend="pcm-interface-operators-open-callback"><citetitle>
- the open callback</citetitle></link>.
- Don't mix this with <constant>pcm-&gt;private_data</constant>.
- The <constant>pcm-&gt;private_data</constant> usually points to the
- chip instance assigned statically at the creation of PCM, while the
- <constant>runtime-&gt;private_data</constant> points to a dynamic
- data structure created at the PCM open callback.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_open(struct snd_pcm_substream *substream)
- {
- struct my_pcm_data *data;
- ....
- data = kmalloc(sizeof(*data), GFP_KERNEL);
- substream->runtime->private_data = data;
- ....
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The allocated object must be released in
- <link linkend="pcm-interface-operators-open-callback"><citetitle>
- the close callback</citetitle></link>.
- </para>
- </section>
-
- </section>
-
- <section id="pcm-interface-operators">
- <title>Operators</title>
- <para>
- OK, now let me give details about each pcm callback
- (<parameter>ops</parameter>). In general, every callback must
- return 0 if successful, or a negative error number
- such as <constant>-EINVAL</constant>. To choose an appropriate
- error number, it is advised to check what value other parts of
- the kernel return when the same kind of request fails.
- </para>
-
- <para>
- The callback function takes at least the argument with
- <structname>snd_pcm_substream</structname> pointer. To retrieve
- the chip record from the given substream instance, you can use the
- following macro.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- int xxx() {
- struct mychip *chip = snd_pcm_substream_chip(substream);
- ....
- }
-]]>
- </programlisting>
- </informalexample>
-
- The macro reads <constant>substream-&gt;private_data</constant>,
- which is a copy of <constant>pcm-&gt;private_data</constant>.
- You can override the former if you need to assign different data
- records per PCM substream. For example, the cmi8330 driver assigns
- different private_data for playback and capture directions,
- because it uses two different codecs (SB- and AD-compatible) for
- different directions.
- </para>
-
- <section id="pcm-interface-operators-open-callback">
- <title>open callback</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_open(struct snd_pcm_substream *substream);
-]]>
- </programlisting>
- </informalexample>
-
- This is called when a pcm substream is opened.
- </para>
-
- <para>
- At least, here you have to initialize the runtime-&gt;hw
- record. Typically, this is done by like this:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_open(struct snd_pcm_substream *substream)
- {
- struct mychip *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_mychip_playback_hw;
- return 0;
- }
-]]>
- </programlisting>
- </informalexample>
-
- where <parameter>snd_mychip_playback_hw</parameter> is the
- pre-defined hardware description.
- </para>
-
- <para>
- You can allocate a private data in this callback, as described
- in <link linkend="pcm-interface-runtime-private"><citetitle>
- Private Data</citetitle></link> section.
- </para>
-
- <para>
- If the hardware configuration needs more constraints, set the
- hardware constraints here, too.
- See <link linkend="pcm-interface-constraints"><citetitle>
- Constraints</citetitle></link> for more details.
- </para>
- </section>
-
- <section id="pcm-interface-operators-close-callback">
- <title>close callback</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_close(struct snd_pcm_substream *substream);
-]]>
- </programlisting>
- </informalexample>
-
- Obviously, this is called when a pcm substream is closed.
- </para>
-
- <para>
- Any private instance for a pcm substream allocated in the
- open callback will be released here.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_close(struct snd_pcm_substream *substream)
- {
- ....
- kfree(substream->runtime->private_data);
- ....
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
- </section>
-
- <section id="pcm-interface-operators-ioctl-callback">
- <title>ioctl callback</title>
- <para>
- This is used for any special call to pcm ioctls. But
- usually you can pass a generic ioctl callback,
- <function>snd_pcm_lib_ioctl</function>.
- </para>
- </section>
-
- <section id="pcm-interface-operators-hw-params-callback">
- <title>hw_params callback</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- This is called when the hardware parameter
- (<structfield>hw_params</structfield>) is set
- up by the application,
- that is, once when the buffer size, the period size, the
- format, etc. are defined for the pcm substream.
- </para>
-
- <para>
- Many hardware setups should be done in this callback,
- including the allocation of buffers.
- </para>
-
- <para>
- Parameters to be initialized are retrieved by
- <function>params_xxx()</function> macros. To allocate
- buffer, you can call a helper function,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-]]>
- </programlisting>
- </informalexample>
-
- <function>snd_pcm_lib_malloc_pages()</function> is available
- only when the DMA buffers have been pre-allocated.
- See the section <link
- linkend="buffer-and-memory-buffer-types"><citetitle>
- Buffer Types</citetitle></link> for more details.
- </para>
-
- <para>
- Note that this and <structfield>prepare</structfield> callbacks
- may be called multiple times per initialization.
- For example, the OSS emulation may
- call these callbacks at each change via its ioctl.
- </para>
-
- <para>
- Thus, you need to be careful not to allocate the same buffers
- many times, which will lead to memory leaks! Calling the
- helper function above many times is OK. It will release the
- previous buffer automatically when it was already allocated.
- </para>
-
- <para>
- Another note is that this callback is non-atomic
- (schedulable) as default, i.e. when no
- <structfield>nonatomic</structfield> flag set.
- This is important, because the
- <structfield>trigger</structfield> callback
- is atomic (non-schedulable). That is, mutexes or any
- schedule-related functions are not available in
- <structfield>trigger</structfield> callback.
- Please see the subsection
- <link linkend="pcm-interface-atomicity"><citetitle>
- Atomicity</citetitle></link> for details.
- </para>
- </section>
-
- <section id="pcm-interface-operators-hw-free-callback">
- <title>hw_free callback</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_hw_free(struct snd_pcm_substream *substream);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- This is called to release the resources allocated via
- <structfield>hw_params</structfield>. For example, releasing the
- buffer via
- <function>snd_pcm_lib_malloc_pages()</function> is done by
- calling the following:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_pcm_lib_free_pages(substream);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- This function is always called before the close callback is called.
- Also, the callback may be called multiple times, too.
- Keep track whether the resource was already released.
- </para>
- </section>
-
- <section id="pcm-interface-operators-prepare-callback">
- <title>prepare callback</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_prepare(struct snd_pcm_substream *substream);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- This callback is called when the pcm is
- <quote>prepared</quote>. You can set the format type, sample
- rate, etc. here. The difference from
- <structfield>hw_params</structfield> is that the
- <structfield>prepare</structfield> callback will be called each
- time
- <function>snd_pcm_prepare()</function> is called, i.e. when
- recovering after underruns, etc.
- </para>
-
- <para>
- Note that this callback is now non-atomic.
- You can use schedule-related functions safely in this callback.
- </para>
-
- <para>
- In this and the following callbacks, you can refer to the
- values via the runtime record,
- substream-&gt;runtime.
- For example, to get the current
- rate, format or channels, access to
- runtime-&gt;rate,
- runtime-&gt;format or
- runtime-&gt;channels, respectively.
- The physical address of the allocated buffer is set to
- runtime-&gt;dma_area. The buffer and period sizes are
- in runtime-&gt;buffer_size and runtime-&gt;period_size,
- respectively.
- </para>
-
- <para>
- Be careful that this callback will be called many times at
- each setup, too.
- </para>
- </section>
-
- <section id="pcm-interface-operators-trigger-callback">
- <title>trigger callback</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_trigger(struct snd_pcm_substream *substream, int cmd);
-]]>
- </programlisting>
- </informalexample>
-
- This is called when the pcm is started, stopped or paused.
- </para>
-
- <para>
- Which action is specified in the second argument,
- <constant>SNDRV_PCM_TRIGGER_XXX</constant> in
- <filename>&lt;sound/pcm.h&gt;</filename>. At least,
- the <constant>START</constant> and <constant>STOP</constant>
- commands must be defined in this callback.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* do something to start the PCM engine */
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- /* do something to stop the PCM engine */
- break;
- default:
- return -EINVAL;
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- When the pcm supports the pause operation (given in the info
- field of the hardware table), the <constant>PAUSE_PUSH</constant>
- and <constant>PAUSE_RELEASE</constant> commands must be
- handled here, too. The former is the command to pause the pcm,
- and the latter to restart the pcm again.
- </para>
-
- <para>
- When the pcm supports the suspend/resume operation,
- regardless of full or partial suspend/resume support,
- the <constant>SUSPEND</constant> and <constant>RESUME</constant>
- commands must be handled, too.
- These commands are issued when the power-management status is
- changed. Obviously, the <constant>SUSPEND</constant> and
- <constant>RESUME</constant> commands
- suspend and resume the pcm substream, and usually, they
- are identical to the <constant>STOP</constant> and
- <constant>START</constant> commands, respectively.
- See the <link linkend="power-management"><citetitle>
- Power Management</citetitle></link> section for details.
- </para>
-
- <para>
- As mentioned, this callback is atomic as default unless
- <structfield>nonatomic</structfield> flag set, and
- you cannot call functions which may sleep.
- The trigger callback should be as minimal as possible,
- just really triggering the DMA. The other stuff should be
- initialized hw_params and prepare callbacks properly
- beforehand.
- </para>
- </section>
-
- <section id="pcm-interface-operators-pointer-callback">
- <title>pointer callback</title>
- <para>
- <informalexample>
- <programlisting>
-<![CDATA[
- static snd_pcm_uframes_t snd_xxx_pointer(struct snd_pcm_substream *substream)
-]]>
- </programlisting>
- </informalexample>
-
- This callback is called when the PCM middle layer inquires
- the current hardware position on the buffer. The position must
- be returned in frames,
- ranging from 0 to buffer_size - 1.
- </para>
-
- <para>
- This is called usually from the buffer-update routine in the
- pcm middle layer, which is invoked when
- <function>snd_pcm_period_elapsed()</function> is called in the
- interrupt routine. Then the pcm middle layer updates the
- position and calculates the available space, and wakes up the
- sleeping poll threads, etc.
- </para>
-
- <para>
- This callback is also atomic as default.
- </para>
- </section>
-
- <section id="pcm-interface-operators-copy-silence">
- <title>copy and silence callbacks</title>
- <para>
- These callbacks are not mandatory, and can be omitted in
- most cases. These callbacks are used when the hardware buffer
- cannot be in the normal memory space. Some chips have their
- own buffer on the hardware which is not mappable. In such a
- case, you have to transfer the data manually from the memory
- buffer to the hardware buffer. Or, if the buffer is
- non-contiguous on both physical and virtual memory spaces,
- these callbacks must be defined, too.
- </para>
-
- <para>
- If these two callbacks are defined, copy and set-silence
- operations are done by them. The detailed will be described in
- the later section <link
- linkend="buffer-and-memory"><citetitle>Buffer and Memory
- Management</citetitle></link>.
- </para>
- </section>
-
- <section id="pcm-interface-operators-ack">
- <title>ack callback</title>
- <para>
- This callback is also not mandatory. This callback is called
- when the appl_ptr is updated in read or write operations.
- Some drivers like emu10k1-fx and cs46xx need to track the
- current appl_ptr for the internal buffer, and this callback
- is useful only for such a purpose.
- </para>
- <para>
- This callback is atomic as default.
- </para>
- </section>
-
- <section id="pcm-interface-operators-page-callback">
- <title>page callback</title>
-
- <para>
- This callback is optional too. This callback is used
- mainly for non-contiguous buffers. The mmap calls this
- callback to get the page address. Some examples will be
- explained in the later section <link
- linkend="buffer-and-memory"><citetitle>Buffer and Memory
- Management</citetitle></link>, too.
- </para>
- </section>
- </section>
-
- <section id="pcm-interface-interrupt-handler">
- <title>Interrupt Handler</title>
- <para>
- The rest of pcm stuff is the PCM interrupt handler. The
- role of PCM interrupt handler in the sound driver is to update
- the buffer position and to tell the PCM middle layer when the
- buffer position goes across the prescribed period size. To
- inform this, call the <function>snd_pcm_period_elapsed()</function>
- function.
- </para>
-
- <para>
- There are several types of sound chips to generate the interrupts.
- </para>
-
- <section id="pcm-interface-interrupt-handler-boundary">
- <title>Interrupts at the period (fragment) boundary</title>
- <para>
- This is the most frequently found type: the hardware
- generates an interrupt at each period boundary.
- In this case, you can call
- <function>snd_pcm_period_elapsed()</function> at each
- interrupt.
- </para>
-
- <para>
- <function>snd_pcm_period_elapsed()</function> takes the
- substream pointer as its argument. Thus, you need to keep the
- substream pointer accessible from the chip instance. For
- example, define substream field in the chip record to hold the
- current running substream pointer, and set the pointer value
- at open callback (and reset at close callback).
- </para>
-
- <para>
- If you acquire a spinlock in the interrupt handler, and the
- lock is used in other pcm callbacks, too, then you have to
- release the lock before calling
- <function>snd_pcm_period_elapsed()</function>, because
- <function>snd_pcm_period_elapsed()</function> calls other pcm
- callbacks inside.
- </para>
-
- <para>
- Typical code would be like:
-
- <example>
- <title>Interrupt Handler Case #1</title>
- <programlisting>
-<![CDATA[
- static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
- {
- struct mychip *chip = dev_id;
- spin_lock(&chip->lock);
- ....
- if (pcm_irq_invoked(chip)) {
- /* call updater, unlock before it */
- spin_unlock(&chip->lock);
- snd_pcm_period_elapsed(chip->substream);
- spin_lock(&chip->lock);
- /* acknowledge the interrupt if necessary */
- }
- ....
- spin_unlock(&chip->lock);
- return IRQ_HANDLED;
- }
-]]>
- </programlisting>
- </example>
- </para>
- </section>
-
- <section id="pcm-interface-interrupt-handler-timer">
- <title>High frequency timer interrupts</title>
- <para>
- This happens when the hardware doesn't generate interrupts
- at the period boundary but issues timer interrupts at a fixed
- timer rate (e.g. es1968 or ymfpci drivers).
- In this case, you need to check the current hardware
- position and accumulate the processed sample length at each
- interrupt. When the accumulated size exceeds the period
- size, call
- <function>snd_pcm_period_elapsed()</function> and reset the
- accumulator.
- </para>
-
- <para>
- Typical code would be like the following.
-
- <example>
- <title>Interrupt Handler Case #2</title>
- <programlisting>
-<![CDATA[
- static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
- {
- struct mychip *chip = dev_id;
- spin_lock(&chip->lock);
- ....
- if (pcm_irq_invoked(chip)) {
- unsigned int last_ptr, size;
- /* get the current hardware pointer (in frames) */
- last_ptr = get_hw_ptr(chip);
- /* calculate the processed frames since the
- * last update
- */
- if (last_ptr < chip->last_ptr)
- size = runtime->buffer_size + last_ptr
- - chip->last_ptr;
- else
- size = last_ptr - chip->last_ptr;
- /* remember the last updated point */
- chip->last_ptr = last_ptr;
- /* accumulate the size */
- chip->size += size;
- /* over the period boundary? */
- if (chip->size >= runtime->period_size) {
- /* reset the accumulator */
- chip->size %= runtime->period_size;
- /* call updater */
- spin_unlock(&chip->lock);
- snd_pcm_period_elapsed(substream);
- spin_lock(&chip->lock);
- }
- /* acknowledge the interrupt if necessary */
- }
- ....
- spin_unlock(&chip->lock);
- return IRQ_HANDLED;
- }
-]]>
- </programlisting>
- </example>
- </para>
- </section>
-
- <section id="pcm-interface-interrupt-handler-both">
- <title>On calling <function>snd_pcm_period_elapsed()</function></title>
- <para>
- In both cases, even if more than one period are elapsed, you
- don't have to call
- <function>snd_pcm_period_elapsed()</function> many times. Call
- only once. And the pcm layer will check the current hardware
- pointer and update to the latest status.
- </para>
- </section>
- </section>
-
- <section id="pcm-interface-atomicity">
- <title>Atomicity</title>
- <para>
- One of the most important (and thus difficult to debug) problems
- in kernel programming are race conditions.
- In the Linux kernel, they are usually avoided via spin-locks, mutexes
- or semaphores. In general, if a race condition can happen
- in an interrupt handler, it has to be managed atomically, and you
- have to use a spinlock to protect the critical session. If the
- critical section is not in interrupt handler code and
- if taking a relatively long time to execute is acceptable, you
- should use mutexes or semaphores instead.
- </para>
-
- <para>
- As already seen, some pcm callbacks are atomic and some are
- not. For example, the <parameter>hw_params</parameter> callback is
- non-atomic, while <parameter>trigger</parameter> callback is
- atomic. This means, the latter is called already in a spinlock
- held by the PCM middle layer. Please take this atomicity into
- account when you choose a locking scheme in the callbacks.
- </para>
-
- <para>
- In the atomic callbacks, you cannot use functions which may call
- <function>schedule</function> or go to
- <function>sleep</function>. Semaphores and mutexes can sleep,
- and hence they cannot be used inside the atomic callbacks
- (e.g. <parameter>trigger</parameter> callback).
- To implement some delay in such a callback, please use
- <function>udelay()</function> or <function>mdelay()</function>.
- </para>
-
- <para>
- All three atomic callbacks (trigger, pointer, and ack) are
- called with local interrupts disabled.
- </para>
-
- <para>
- The recent changes in PCM core code, however, allow all PCM
- operations to be non-atomic. This assumes that the all caller
- sides are in non-atomic contexts. For example, the function
- <function>snd_pcm_period_elapsed()</function> is called
- typically from the interrupt handler. But, if you set up the
- driver to use a threaded interrupt handler, this call can be in
- non-atomic context, too. In such a case, you can set
- <structfield>nonatomic</structfield> filed of
- <structname>snd_pcm</structname> object after creating it.
- When this flag is set, mutex and rwsem are used internally in
- the PCM core instead of spin and rwlocks, so that you can call
- all PCM functions safely in a non-atomic context.
- </para>
-
- </section>
- <section id="pcm-interface-constraints">
- <title>Constraints</title>
- <para>
- If your chip supports unconventional sample rates, or only the
- limited samples, you need to set a constraint for the
- condition.
- </para>
-
- <para>
- For example, in order to restrict the sample rates in the some
- supported values, use
- <function>snd_pcm_hw_constraint_list()</function>.
- You need to call this function in the open callback.
-
- <example>
- <title>Example of Hardware Constraints</title>
- <programlisting>
-<![CDATA[
- static unsigned int rates[] =
- {4000, 10000, 22050, 44100};
- static struct snd_pcm_hw_constraint_list constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
- };
-
- static int snd_mychip_pcm_open(struct snd_pcm_substream *substream)
- {
- int err;
- ....
- err = snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &constraints_rates);
- if (err < 0)
- return err;
- ....
- }
-]]>
- </programlisting>
- </example>
- </para>
-
- <para>
- There are many different constraints.
- Look at <filename>sound/pcm.h</filename> for a complete list.
- You can even define your own constraint rules.
- For example, let's suppose my_chip can manage a substream of 1 channel
- if and only if the format is S16_LE, otherwise it supports any format
- specified in the <structname>snd_pcm_hardware</structname> structure (or in any
- other constraint_list). You can build a rule like this:
-
- <example>
- <title>Example of Hardware Constraints for Channels</title>
- <programlisting>
-<![CDATA[
- static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
- {
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_interval ch;
-
- snd_interval_any(&ch);
- if (f->bits[0] == SNDRV_PCM_FMTBIT_S16_LE) {
- ch.min = ch.max = 1;
- ch.integer = 1;
- return snd_interval_refine(c, &ch);
- }
- return 0;
- }
-]]>
- </programlisting>
- </example>
- </para>
-
- <para>
- Then you need to call this function to add your rule:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_channels_by_format, NULL,
- SNDRV_PCM_HW_PARAM_FORMAT, -1);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The rule function is called when an application sets the PCM
- format, and it refines the number of channels accordingly.
- But an application may set the number of channels before
- setting the format. Thus you also need to define the inverse rule:
-
- <example>
- <title>Example of Hardware Constraints for Formats</title>
- <programlisting>
-<![CDATA[
- static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
- {
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_mask fmt;
-
- snd_mask_any(&fmt); /* Init the struct */
- if (c->min < 2) {
- fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_LE;
- return snd_mask_refine(f, &fmt);
- }
- return 0;
- }
-]]>
- </programlisting>
- </example>
- </para>
-
- <para>
- ...and in the open callback:
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
- hw_rule_format_by_channels, NULL,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- I won't give more details here, rather I
- would like to say, <quote>Luke, use the source.</quote>
- </para>
- </section>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Control Interface -->
-<!-- ****************************************************** -->
- <chapter id="control-interface">
- <title>Control Interface</title>
-
- <section id="control-interface-general">
- <title>General</title>
- <para>
- The control interface is used widely for many switches,
- sliders, etc. which are accessed from user-space. Its most
- important use is the mixer interface. In other words, since ALSA
- 0.9.x, all the mixer stuff is implemented on the control kernel API.
- </para>
-
- <para>
- ALSA has a well-defined AC97 control module. If your chip
- supports only the AC97 and nothing else, you can skip this
- section.
- </para>
-
- <para>
- The control API is defined in
- <filename>&lt;sound/control.h&gt;</filename>.
- Include this file if you want to add your own controls.
- </para>
- </section>
-
- <section id="control-interface-definition">
- <title>Definition of Controls</title>
- <para>
- To create a new control, you need to define the
- following three
- callbacks: <structfield>info</structfield>,
- <structfield>get</structfield> and
- <structfield>put</structfield>. Then, define a
- struct <structname>snd_kcontrol_new</structname> record, such as:
-
- <example>
- <title>Definition of a Control</title>
- <programlisting>
-<![CDATA[
- static struct snd_kcontrol_new my_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0xffff,
- .info = my_control_info,
- .get = my_control_get,
- .put = my_control_put
- };
-]]>
- </programlisting>
- </example>
- </para>
-
- <para>
- The <structfield>iface</structfield> field specifies the control
- type, <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>, which
- is usually <constant>MIXER</constant>.
- Use <constant>CARD</constant> for global controls that are not
- logically part of the mixer.
- If the control is closely associated with some specific device on
- the sound card, use <constant>HWDEP</constant>,
- <constant>PCM</constant>, <constant>RAWMIDI</constant>,
- <constant>TIMER</constant>, or <constant>SEQUENCER</constant>, and
- specify the device number with the
- <structfield>device</structfield> and
- <structfield>subdevice</structfield> fields.
- </para>
-
- <para>
- The <structfield>name</structfield> is the name identifier
- string. Since ALSA 0.9.x, the control name is very important,
- because its role is classified from its name. There are
- pre-defined standard control names. The details are described in
- the <link linkend="control-interface-control-names"><citetitle>
- Control Names</citetitle></link> subsection.
- </para>
-
- <para>
- The <structfield>index</structfield> field holds the index number
- of this control. If there are several different controls with
- the same name, they can be distinguished by the index
- number. This is the case when
- several codecs exist on the card. If the index is zero, you can
- omit the definition above.
- </para>
-
- <para>
- The <structfield>access</structfield> field contains the access
- type of this control. Give the combination of bit masks,
- <constant>SNDRV_CTL_ELEM_ACCESS_XXX</constant>, there.
- The details will be explained in
- the <link linkend="control-interface-access-flags"><citetitle>
- Access Flags</citetitle></link> subsection.
- </para>
-
- <para>
- The <structfield>private_value</structfield> field contains
- an arbitrary long integer value for this record. When using
- the generic <structfield>info</structfield>,
- <structfield>get</structfield> and
- <structfield>put</structfield> callbacks, you can pass a value
- through this field. If several small numbers are necessary, you can
- combine them in bitwise. Or, it's possible to give a pointer
- (casted to unsigned long) of some record to this field, too.
- </para>
-
- <para>
- The <structfield>tlv</structfield> field can be used to provide
- metadata about the control; see the
- <link linkend="control-interface-tlv">
- <citetitle>Metadata</citetitle></link> subsection.
- </para>
-
- <para>
- The other three are
- <link linkend="control-interface-callbacks"><citetitle>
- callback functions</citetitle></link>.
- </para>
- </section>
-
- <section id="control-interface-control-names">
- <title>Control Names</title>
- <para>
- There are some standards to define the control names. A
- control is usually defined from the three parts as
- <quote>SOURCE DIRECTION FUNCTION</quote>.
- </para>
-
- <para>
- The first, <constant>SOURCE</constant>, specifies the source
- of the control, and is a string such as <quote>Master</quote>,
- <quote>PCM</quote>, <quote>CD</quote> and
- <quote>Line</quote>. There are many pre-defined sources.
- </para>
-
- <para>
- The second, <constant>DIRECTION</constant>, is one of the
- following strings according to the direction of the control:
- <quote>Playback</quote>, <quote>Capture</quote>, <quote>Bypass
- Playback</quote> and <quote>Bypass Capture</quote>. Or, it can
- be omitted, meaning both playback and capture directions.
- </para>
-
- <para>
- The third, <constant>FUNCTION</constant>, is one of the
- following strings according to the function of the control:
- <quote>Switch</quote>, <quote>Volume</quote> and
- <quote>Route</quote>.
- </para>
-
- <para>
- The example of control names are, thus, <quote>Master Capture
- Switch</quote> or <quote>PCM Playback Volume</quote>.
- </para>
-
- <para>
- There are some exceptions:
- </para>
-
- <section id="control-interface-control-names-global">
- <title>Global capture and playback</title>
- <para>
- <quote>Capture Source</quote>, <quote>Capture Switch</quote>
- and <quote>Capture Volume</quote> are used for the global
- capture (input) source, switch and volume. Similarly,
- <quote>Playback Switch</quote> and <quote>Playback
- Volume</quote> are used for the global output gain switch and
- volume.
- </para>
- </section>
-
- <section id="control-interface-control-names-tone">
- <title>Tone-controls</title>
- <para>
- tone-control switch and volumes are specified like
- <quote>Tone Control - XXX</quote>, e.g. <quote>Tone Control -
- Switch</quote>, <quote>Tone Control - Bass</quote>,
- <quote>Tone Control - Center</quote>.
- </para>
- </section>
-
- <section id="control-interface-control-names-3d">
- <title>3D controls</title>
- <para>
- 3D-control switches and volumes are specified like <quote>3D
- Control - XXX</quote>, e.g. <quote>3D Control -
- Switch</quote>, <quote>3D Control - Center</quote>, <quote>3D
- Control - Space</quote>.
- </para>
- </section>
-
- <section id="control-interface-control-names-mic">
- <title>Mic boost</title>
- <para>
- Mic-boost switch is set as <quote>Mic Boost</quote> or
- <quote>Mic Boost (6dB)</quote>.
- </para>
-
- <para>
- More precise information can be found in
- <filename>Documentation/sound/alsa/ControlNames.txt</filename>.
- </para>
- </section>
- </section>
-
- <section id="control-interface-access-flags">
- <title>Access Flags</title>
-
- <para>
- The access flag is the bitmask which specifies the access type
- of the given control. The default access type is
- <constant>SNDRV_CTL_ELEM_ACCESS_READWRITE</constant>,
- which means both read and write are allowed to this control.
- When the access flag is omitted (i.e. = 0), it is
- considered as <constant>READWRITE</constant> access as default.
- </para>
-
- <para>
- When the control is read-only, pass
- <constant>SNDRV_CTL_ELEM_ACCESS_READ</constant> instead.
- In this case, you don't have to define
- the <structfield>put</structfield> callback.
- Similarly, when the control is write-only (although it's a rare
- case), you can use the <constant>WRITE</constant> flag instead, and
- you don't need the <structfield>get</structfield> callback.
- </para>
-
- <para>
- If the control value changes frequently (e.g. the VU meter),
- <constant>VOLATILE</constant> flag should be given. This means
- that the control may be changed without
- <link linkend="control-interface-change-notification"><citetitle>
- notification</citetitle></link>. Applications should poll such
- a control constantly.
- </para>
-
- <para>
- When the control is inactive, set
- the <constant>INACTIVE</constant> flag, too.
- There are <constant>LOCK</constant> and
- <constant>OWNER</constant> flags to change the write
- permissions.
- </para>
-
- </section>
-
- <section id="control-interface-callbacks">
- <title>Callbacks</title>
-
- <section id="control-interface-callbacks-info">
- <title>info callback</title>
- <para>
- The <structfield>info</structfield> callback is used to get
- detailed information on this control. This must store the
- values of the given struct <structname>snd_ctl_elem_info</structname>
- object. For example, for a boolean control with a single
- element:
-
- <example>
- <title>Example of info callback</title>
- <programlisting>
-<![CDATA[
- static int snd_myctl_mono_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
- {
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
- }
-]]>
- </programlisting>
- </example>
- </para>
-
- <para>
- The <structfield>type</structfield> field specifies the type
- of the control. There are <constant>BOOLEAN</constant>,
- <constant>INTEGER</constant>, <constant>ENUMERATED</constant>,
- <constant>BYTES</constant>, <constant>IEC958</constant> and
- <constant>INTEGER64</constant>. The
- <structfield>count</structfield> field specifies the
- number of elements in this control. For example, a stereo
- volume would have count = 2. The
- <structfield>value</structfield> field is a union, and
- the values stored are depending on the type. The boolean and
- integer types are identical.
- </para>
-
- <para>
- The enumerated type is a bit different from others. You'll
- need to set the string for the currently given item index.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_myctl_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
- {
- static char *texts[4] = {
- "First", "Second", "Third", "Fourth"
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3)
- uinfo->value.enumerated.item = 3;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The above callback can be simplified with a helper function,
- <function>snd_ctl_enum_info</function>. The final code
- looks like below.
- (You can pass ARRAY_SIZE(texts) instead of 4 in the third
- argument; it's a matter of taste.)
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_myctl_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
- {
- static char *texts[4] = {
- "First", "Second", "Third", "Fourth"
- };
- return snd_ctl_enum_info(uinfo, 1, 4, texts);
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Some common info callbacks are available for your convenience:
- <function>snd_ctl_boolean_mono_info()</function> and
- <function>snd_ctl_boolean_stereo_info()</function>.
- Obviously, the former is an info callback for a mono channel
- boolean item, just like <function>snd_myctl_mono_info</function>
- above, and the latter is for a stereo channel boolean item.
- </para>
-
- </section>
-
- <section id="control-interface-callbacks-get">
- <title>get callback</title>
-
- <para>
- This callback is used to read the current value of the
- control and to return to user-space.
- </para>
-
- <para>
- For example,
-
- <example>
- <title>Example of get callback</title>
- <programlisting>
-<![CDATA[
- static int snd_myctl_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct mychip *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = get_some_value(chip);
- return 0;
- }
-]]>
- </programlisting>
- </example>
- </para>
-
- <para>
- The <structfield>value</structfield> field depends on
- the type of control as well as on the info callback. For example,
- the sb driver uses this field to store the register offset,
- the bit-shift and the bit-mask. The
- <structfield>private_value</structfield> field is set as follows:
- <informalexample>
- <programlisting>
-<![CDATA[
- .private_value = reg | (shift << 16) | (mask << 24)
-]]>
- </programlisting>
- </informalexample>
- and is retrieved in callbacks like
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 16) & 0xff;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- ....
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- In the <structfield>get</structfield> callback,
- you have to fill all the elements if the
- control has more than one elements,
- i.e. <structfield>count</structfield> &gt; 1.
- In the example above, we filled only one element
- (<structfield>value.integer.value[0]</structfield>) since it's
- assumed as <structfield>count</structfield> = 1.
- </para>
- </section>
-
- <section id="control-interface-callbacks-put">
- <title>put callback</title>
-
- <para>
- This callback is used to write a value from user-space.
- </para>
-
- <para>
- For example,
-
- <example>
- <title>Example of put callback</title>
- <programlisting>
-<![CDATA[
- static int snd_myctl_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct mychip *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- if (chip->current_value !=
- ucontrol->value.integer.value[0]) {
- change_current_value(chip,
- ucontrol->value.integer.value[0]);
- changed = 1;
- }
- return changed;
- }
-]]>
- </programlisting>
- </example>
-
- As seen above, you have to return 1 if the value is
- changed. If the value is not changed, return 0 instead.
- If any fatal error happens, return a negative error code as
- usual.
- </para>
-
- <para>
- As in the <structfield>get</structfield> callback,
- when the control has more than one elements,
- all elements must be evaluated in this callback, too.
- </para>
- </section>
-
- <section id="control-interface-callbacks-all">
- <title>Callbacks are not atomic</title>
- <para>
- All these three callbacks are basically not atomic.
- </para>
- </section>
- </section>
-
- <section id="control-interface-constructor">
- <title>Constructor</title>
- <para>
- When everything is ready, finally we can create a new
- control. To create a control, there are two functions to be
- called, <function>snd_ctl_new1()</function> and
- <function>snd_ctl_add()</function>.
- </para>
-
- <para>
- In the simplest way, you can do like this:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip));
- if (err < 0)
- return err;
-]]>
- </programlisting>
- </informalexample>
-
- where <parameter>my_control</parameter> is the
- struct <structname>snd_kcontrol_new</structname> object defined above, and chip
- is the object pointer to be passed to
- kcontrol-&gt;private_data
- which can be referred to in callbacks.
- </para>
-
- <para>
- <function>snd_ctl_new1()</function> allocates a new
- <structname>snd_kcontrol</structname> instance,
- and <function>snd_ctl_add</function> assigns the given
- control component to the card.
- </para>
- </section>
-
- <section id="control-interface-change-notification">
- <title>Change Notification</title>
- <para>
- If you need to change and update a control in the interrupt
- routine, you can call <function>snd_ctl_notify()</function>. For
- example,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, id_pointer);
-]]>
- </programlisting>
- </informalexample>
-
- This function takes the card pointer, the event-mask, and the
- control id pointer for the notification. The event-mask
- specifies the types of notification, for example, in the above
- example, the change of control values is notified.
- The id pointer is the pointer of struct <structname>snd_ctl_elem_id</structname>
- to be notified.
- You can find some examples in <filename>es1938.c</filename> or
- <filename>es1968.c</filename> for hardware volume interrupts.
- </para>
- </section>
-
- <section id="control-interface-tlv">
- <title>Metadata</title>
- <para>
- To provide information about the dB values of a mixer control, use
- on of the <constant>DECLARE_TLV_xxx</constant> macros from
- <filename>&lt;sound/tlv.h&gt;</filename> to define a variable
- containing this information, set the<structfield>tlv.p
- </structfield> field to point to this variable, and include the
- <constant>SNDRV_CTL_ELEM_ACCESS_TLV_READ</constant> flag in the
- <structfield>access</structfield> field; like this:
- <informalexample>
- <programlisting>
-<![CDATA[
- static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);
-
- static struct snd_kcontrol_new my_control = {
- ...
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- ...
- .tlv.p = db_scale_my_control,
- };
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The <function>DECLARE_TLV_DB_SCALE</function> macro defines
- information about a mixer control where each step in the control's
- value changes the dB value by a constant dB amount.
- The first parameter is the name of the variable to be defined.
- The second parameter is the minimum value, in units of 0.01 dB.
- The third parameter is the step size, in units of 0.01 dB.
- Set the fourth parameter to 1 if the minimum value actually mutes
- the control.
- </para>
-
- <para>
- The <function>DECLARE_TLV_DB_LINEAR</function> macro defines
- information about a mixer control where the control's value affects
- the output linearly.
- The first parameter is the name of the variable to be defined.
- The second parameter is the minimum value, in units of 0.01 dB.
- The third parameter is the maximum value, in units of 0.01 dB.
- If the minimum value mutes the control, set the second parameter to
- <constant>TLV_DB_GAIN_MUTE</constant>.
- </para>
- </section>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- API for AC97 Codec -->
-<!-- ****************************************************** -->
- <chapter id="api-ac97">
- <title>API for AC97 Codec</title>
-
- <section>
- <title>General</title>
- <para>
- The ALSA AC97 codec layer is a well-defined one, and you don't
- have to write much code to control it. Only low-level control
- routines are necessary. The AC97 codec API is defined in
- <filename>&lt;sound/ac97_codec.h&gt;</filename>.
- </para>
- </section>
-
- <section id="api-ac97-example">
- <title>Full Code Example</title>
- <para>
- <example>
- <title>Example of AC97 Interface</title>
- <programlisting>
-<![CDATA[
- struct mychip {
- ....
- struct snd_ac97 *ac97;
- ....
- };
-
- static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
- {
- struct mychip *chip = ac97->private_data;
- ....
- /* read a register value here from the codec */
- return the_register_value;
- }
-
- static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
- {
- struct mychip *chip = ac97->private_data;
- ....
- /* write the given register value to the codec */
- }
-
- static int snd_mychip_ac97(struct mychip *chip)
- {
- struct snd_ac97_bus *bus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_mychip_ac97_write,
- .read = snd_mychip_ac97_read,
- };
-
- err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
- if (err < 0)
- return err;
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- return snd_ac97_mixer(bus, &ac97, &chip->ac97);
- }
-
-]]>
- </programlisting>
- </example>
- </para>
- </section>
-
- <section id="api-ac97-constructor">
- <title>Constructor</title>
- <para>
- To create an ac97 instance, first call <function>snd_ac97_bus</function>
- with an <type>ac97_bus_ops_t</type> record with callback functions.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_ac97_bus *bus;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_mychip_ac97_write,
- .read = snd_mychip_ac97_read,
- };
-
- snd_ac97_bus(card, 0, &ops, NULL, &pbus);
-]]>
- </programlisting>
- </informalexample>
-
- The bus record is shared among all belonging ac97 instances.
- </para>
-
- <para>
- And then call <function>snd_ac97_mixer()</function> with an
- struct <structname>snd_ac97_template</structname>
- record together with the bus pointer created above.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_ac97_template ac97;
- int err;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- snd_ac97_mixer(bus, &ac97, &chip->ac97);
-]]>
- </programlisting>
- </informalexample>
-
- where chip-&gt;ac97 is a pointer to a newly created
- <type>ac97_t</type> instance.
- In this case, the chip pointer is set as the private data, so that
- the read/write callback functions can refer to this chip instance.
- This instance is not necessarily stored in the chip
- record. If you need to change the register values from the
- driver, or need the suspend/resume of ac97 codecs, keep this
- pointer to pass to the corresponding functions.
- </para>
- </section>
-
- <section id="api-ac97-callbacks">
- <title>Callbacks</title>
- <para>
- The standard callbacks are <structfield>read</structfield> and
- <structfield>write</structfield>. Obviously they
- correspond to the functions for read and write accesses to the
- hardware low-level codes.
- </para>
-
- <para>
- The <structfield>read</structfield> callback returns the
- register value specified in the argument.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
- {
- struct mychip *chip = ac97->private_data;
- ....
- return the_register_value;
- }
-]]>
- </programlisting>
- </informalexample>
-
- Here, the chip can be cast from ac97-&gt;private_data.
- </para>
-
- <para>
- Meanwhile, the <structfield>write</structfield> callback is
- used to set the register value.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- These callbacks are non-atomic like the control API callbacks.
- </para>
-
- <para>
- There are also other callbacks:
- <structfield>reset</structfield>,
- <structfield>wait</structfield> and
- <structfield>init</structfield>.
- </para>
-
- <para>
- The <structfield>reset</structfield> callback is used to reset
- the codec. If the chip requires a special kind of reset, you can
- define this callback.
- </para>
-
- <para>
- The <structfield>wait</structfield> callback is used to
- add some waiting time in the standard initialization of the codec. If the
- chip requires the extra waiting time, define this callback.
- </para>
-
- <para>
- The <structfield>init</structfield> callback is used for
- additional initialization of the codec.
- </para>
- </section>
-
- <section id="api-ac97-updating-registers">
- <title>Updating Registers in The Driver</title>
- <para>
- If you need to access to the codec from the driver, you can
- call the following functions:
- <function>snd_ac97_write()</function>,
- <function>snd_ac97_read()</function>,
- <function>snd_ac97_update()</function> and
- <function>snd_ac97_update_bits()</function>.
- </para>
-
- <para>
- Both <function>snd_ac97_write()</function> and
- <function>snd_ac97_update()</function> functions are used to
- set a value to the given register
- (<constant>AC97_XXX</constant>). The difference between them is
- that <function>snd_ac97_update()</function> doesn't write a
- value if the given value has been already set, while
- <function>snd_ac97_write()</function> always rewrites the
- value.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_ac97_write(ac97, AC97_MASTER, 0x8080);
- snd_ac97_update(ac97, AC97_MASTER, 0x8080);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- <function>snd_ac97_read()</function> is used to read the value
- of the given register. For example,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- value = snd_ac97_read(ac97, AC97_MASTER);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- <function>snd_ac97_update_bits()</function> is used to update
- some bits in the given register.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_ac97_update_bits(ac97, reg, mask, value);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Also, there is a function to change the sample rate (of a
- given register such as
- <constant>AC97_PCM_FRONT_DAC_RATE</constant>) when VRA or
- DRA is supported by the codec:
- <function>snd_ac97_set_rate()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_ac97_set_rate(ac97, AC97_PCM_FRONT_DAC_RATE, 44100);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The following registers are available to set the rate:
- <constant>AC97_PCM_MIC_ADC_RATE</constant>,
- <constant>AC97_PCM_FRONT_DAC_RATE</constant>,
- <constant>AC97_PCM_LR_ADC_RATE</constant>,
- <constant>AC97_SPDIF</constant>. When
- <constant>AC97_SPDIF</constant> is specified, the register is
- not really changed but the corresponding IEC958 status bits will
- be updated.
- </para>
- </section>
-
- <section id="api-ac97-clock-adjustment">
- <title>Clock Adjustment</title>
- <para>
- In some chips, the clock of the codec isn't 48000 but using a
- PCI clock (to save a quartz!). In this case, change the field
- bus-&gt;clock to the corresponding
- value. For example, intel8x0
- and es1968 drivers have their own function to read from the clock.
- </para>
- </section>
-
- <section id="api-ac97-proc-files">
- <title>Proc Files</title>
- <para>
- The ALSA AC97 interface will create a proc file such as
- <filename>/proc/asound/card0/codec97#0/ac97#0-0</filename> and
- <filename>ac97#0-0+regs</filename>. You can refer to these files to
- see the current status and registers of the codec.
- </para>
- </section>
-
- <section id="api-ac97-multiple-codecs">
- <title>Multiple Codecs</title>
- <para>
- When there are several codecs on the same card, you need to
- call <function>snd_ac97_mixer()</function> multiple times with
- ac97.num=1 or greater. The <structfield>num</structfield> field
- specifies the codec number.
- </para>
-
- <para>
- If you set up multiple codecs, you either need to write
- different callbacks for each codec or check
- ac97-&gt;num in the callback routines.
- </para>
- </section>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- MIDI (MPU401-UART) Interface -->
-<!-- ****************************************************** -->
- <chapter id="midi-interface">
- <title>MIDI (MPU401-UART) Interface</title>
-
- <section id="midi-interface-general">
- <title>General</title>
- <para>
- Many soundcards have built-in MIDI (MPU401-UART)
- interfaces. When the soundcard supports the standard MPU401-UART
- interface, most likely you can use the ALSA MPU401-UART API. The
- MPU401-UART API is defined in
- <filename>&lt;sound/mpu401.h&gt;</filename>.
- </para>
-
- <para>
- Some soundchips have a similar but slightly different
- implementation of mpu401 stuff. For example, emu10k1 has its own
- mpu401 routines.
- </para>
- </section>
-
- <section id="midi-interface-constructor">
- <title>Constructor</title>
- <para>
- To create a rawmidi object, call
- <function>snd_mpu401_uart_new()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_rawmidi *rmidi;
- snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
- irq, &rmidi);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The first argument is the card pointer, and the second is the
- index of this component. You can create up to 8 rawmidi
- devices.
- </para>
-
- <para>
- The third argument is the type of the hardware,
- <constant>MPU401_HW_XXX</constant>. If it's not a special one,
- you can use <constant>MPU401_HW_MPU401</constant>.
- </para>
-
- <para>
- The 4th argument is the I/O port address. Many
- backward-compatible MPU401 have an I/O port such as 0x330. Or, it
- might be a part of its own PCI I/O region. It depends on the
- chip design.
- </para>
-
- <para>
- The 5th argument is a bitflag for additional information.
- When the I/O port address above is part of the PCI I/O
- region, the MPU401 I/O port might have been already allocated
- (reserved) by the driver itself. In such a case, pass a bit flag
- <constant>MPU401_INFO_INTEGRATED</constant>,
- and the mpu401-uart layer will allocate the I/O ports by itself.
- </para>
-
- <para>
- When the controller supports only the input or output MIDI stream,
- pass the <constant>MPU401_INFO_INPUT</constant> or
- <constant>MPU401_INFO_OUTPUT</constant> bitflag, respectively.
- Then the rawmidi instance is created as a single stream.
- </para>
-
- <para>
- <constant>MPU401_INFO_MMIO</constant> bitflag is used to change
- the access method to MMIO (via readb and writeb) instead of
- iob and outb. In this case, you have to pass the iomapped address
- to <function>snd_mpu401_uart_new()</function>.
- </para>
-
- <para>
- When <constant>MPU401_INFO_TX_IRQ</constant> is set, the output
- stream isn't checked in the default interrupt handler. The driver
- needs to call <function>snd_mpu401_uart_interrupt_tx()</function>
- by itself to start processing the output stream in the irq handler.
- </para>
-
- <para>
- If the MPU-401 interface shares its interrupt with the other logical
- devices on the card, set <constant>MPU401_INFO_IRQ_HOOK</constant>
- (see <link linkend="midi-interface-interrupt-handler"><citetitle>
- below</citetitle></link>).
- </para>
-
- <para>
- Usually, the port address corresponds to the command port and
- port + 1 corresponds to the data port. If not, you may change
- the <structfield>cport</structfield> field of
- struct <structname>snd_mpu401</structname> manually
- afterward. However, <structname>snd_mpu401</structname> pointer is not
- returned explicitly by
- <function>snd_mpu401_uart_new()</function>. You need to cast
- rmidi-&gt;private_data to
- <structname>snd_mpu401</structname> explicitly,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_mpu401 *mpu;
- mpu = rmidi->private_data;
-]]>
- </programlisting>
- </informalexample>
-
- and reset the cport as you like:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- mpu->cport = my_own_control_port;
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The 6th argument specifies the ISA irq number that will be
- allocated. If no interrupt is to be allocated (because your
- code is already allocating a shared interrupt, or because the
- device does not use interrupts), pass -1 instead.
- For a MPU-401 device without an interrupt, a polling timer
- will be used instead.
- </para>
- </section>
-
- <section id="midi-interface-interrupt-handler">
- <title>Interrupt Handler</title>
- <para>
- When the interrupt is allocated in
- <function>snd_mpu401_uart_new()</function>, an exclusive ISA
- interrupt handler is automatically used, hence you don't have
- anything else to do than creating the mpu401 stuff. Otherwise, you
- have to set <constant>MPU401_INFO_IRQ_HOOK</constant>, and call
- <function>snd_mpu401_uart_interrupt()</function> explicitly from your
- own interrupt handler when it has determined that a UART interrupt
- has occurred.
- </para>
-
- <para>
- In this case, you need to pass the private_data of the
- returned rawmidi object from
- <function>snd_mpu401_uart_new()</function> as the second
- argument of <function>snd_mpu401_uart_interrupt()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_mpu401_uart_interrupt(irq, rmidi->private_data, regs);
-]]>
- </programlisting>
- </informalexample>
- </para>
- </section>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- RawMIDI Interface -->
-<!-- ****************************************************** -->
- <chapter id="rawmidi-interface">
- <title>RawMIDI Interface</title>
-
- <section id="rawmidi-interface-overview">
- <title>Overview</title>
-
- <para>
- The raw MIDI interface is used for hardware MIDI ports that can
- be accessed as a byte stream. It is not used for synthesizer
- chips that do not directly understand MIDI.
- </para>
-
- <para>
- ALSA handles file and buffer management. All you have to do is
- to write some code to move data between the buffer and the
- hardware.
- </para>
-
- <para>
- The rawmidi API is defined in
- <filename>&lt;sound/rawmidi.h&gt;</filename>.
- </para>
- </section>
-
- <section id="rawmidi-interface-constructor">
- <title>Constructor</title>
-
- <para>
- To create a rawmidi device, call the
- <function>snd_rawmidi_new</function> function:
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_rawmidi *rmidi;
- err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi);
- if (err < 0)
- return err;
- rmidi->private_data = chip;
- strcpy(rmidi->name, "My MIDI");
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The first argument is the card pointer, the second argument is
- the ID string.
- </para>
-
- <para>
- The third argument is the index of this component. You can
- create up to 8 rawmidi devices.
- </para>
-
- <para>
- The fourth and fifth arguments are the number of output and
- input substreams, respectively, of this device (a substream is
- the equivalent of a MIDI port).
- </para>
-
- <para>
- Set the <structfield>info_flags</structfield> field to specify
- the capabilities of the device.
- Set <constant>SNDRV_RAWMIDI_INFO_OUTPUT</constant> if there is
- at least one output port,
- <constant>SNDRV_RAWMIDI_INFO_INPUT</constant> if there is at
- least one input port,
- and <constant>SNDRV_RAWMIDI_INFO_DUPLEX</constant> if the device
- can handle output and input at the same time.
- </para>
-
- <para>
- After the rawmidi device is created, you need to set the
- operators (callbacks) for each substream. There are helper
- functions to set the operators for all the substreams of a device:
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The operators are usually defined like this:
- <informalexample>
- <programlisting>
-<![CDATA[
- static struct snd_rawmidi_ops snd_mymidi_output_ops = {
- .open = snd_mymidi_output_open,
- .close = snd_mymidi_output_close,
- .trigger = snd_mymidi_output_trigger,
- };
-]]>
- </programlisting>
- </informalexample>
- These callbacks are explained in the <link
- linkend="rawmidi-interface-callbacks"><citetitle>Callbacks</citetitle></link>
- section.
- </para>
-
- <para>
- If there are more than one substream, you should give a
- unique name to each of them:
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_rawmidi_substream *substream;
- list_for_each_entry(substream,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
- list {
- sprintf(substream->name, "My MIDI Port %d", substream->number + 1);
- }
- /* same for SNDRV_RAWMIDI_STREAM_INPUT */
-]]>
- </programlisting>
- </informalexample>
- </para>
- </section>
-
- <section id="rawmidi-interface-callbacks">
- <title>Callbacks</title>
-
- <para>
- In all the callbacks, the private data that you've set for the
- rawmidi device can be accessed as
- substream-&gt;rmidi-&gt;private_data.
- <!-- <code> isn't available before DocBook 4.3 -->
- </para>
-
- <para>
- If there is more than one port, your callbacks can determine the
- port index from the struct snd_rawmidi_substream data passed to each
- callback:
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_rawmidi_substream *substream;
- int index = substream->number;
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <section id="rawmidi-interface-op-open">
- <title><function>open</function> callback</title>
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_open(struct snd_rawmidi_substream *substream);
-]]>
- </programlisting>
- </informalexample>
-
- <para>
- This is called when a substream is opened.
- You can initialize the hardware here, but you shouldn't
- start transmitting/receiving data yet.
- </para>
- </section>
-
- <section id="rawmidi-interface-op-close">
- <title><function>close</function> callback</title>
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_xxx_close(struct snd_rawmidi_substream *substream);
-]]>
- </programlisting>
- </informalexample>
-
- <para>
- Guess what.
- </para>
-
- <para>
- The <function>open</function> and <function>close</function>
- callbacks of a rawmidi device are serialized with a mutex,
- and can sleep.
- </para>
- </section>
-
- <section id="rawmidi-interface-op-trigger-out">
- <title><function>trigger</function> callback for output
- substreams</title>
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static void snd_xxx_output_trigger(struct snd_rawmidi_substream *substream, int up);
-]]>
- </programlisting>
- </informalexample>
-
- <para>
- This is called with a nonzero <parameter>up</parameter>
- parameter when there is some data in the substream buffer that
- must be transmitted.
- </para>
-
- <para>
- To read data from the buffer, call
- <function>snd_rawmidi_transmit_peek</function>. It will
- return the number of bytes that have been read; this will be
- less than the number of bytes requested when there are no more
- data in the buffer.
- After the data have been transmitted successfully, call
- <function>snd_rawmidi_transmit_ack</function> to remove the
- data from the substream buffer:
- <informalexample>
- <programlisting>
-<![CDATA[
- unsigned char data;
- while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
- if (snd_mychip_try_to_transmit(data))
- snd_rawmidi_transmit_ack(substream, 1);
- else
- break; /* hardware FIFO full */
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- If you know beforehand that the hardware will accept data, you
- can use the <function>snd_rawmidi_transmit</function> function
- which reads some data and removes them from the buffer at once:
- <informalexample>
- <programlisting>
-<![CDATA[
- while (snd_mychip_transmit_possible()) {
- unsigned char data;
- if (snd_rawmidi_transmit(substream, &data, 1) != 1)
- break; /* no more data */
- snd_mychip_transmit(data);
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- If you know beforehand how many bytes you can accept, you can
- use a buffer size greater than one with the
- <function>snd_rawmidi_transmit*</function> functions.
- </para>
-
- <para>
- The <function>trigger</function> callback must not sleep. If
- the hardware FIFO is full before the substream buffer has been
- emptied, you have to continue transmitting data later, either
- in an interrupt handler, or with a timer if the hardware
- doesn't have a MIDI transmit interrupt.
- </para>
-
- <para>
- The <function>trigger</function> callback is called with a
- zero <parameter>up</parameter> parameter when the transmission
- of data should be aborted.
- </para>
- </section>
-
- <section id="rawmidi-interface-op-trigger-in">
- <title><function>trigger</function> callback for input
- substreams</title>
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static void snd_xxx_input_trigger(struct snd_rawmidi_substream *substream, int up);
-]]>
- </programlisting>
- </informalexample>
-
- <para>
- This is called with a nonzero <parameter>up</parameter>
- parameter to enable receiving data, or with a zero
- <parameter>up</parameter> parameter do disable receiving data.
- </para>
-
- <para>
- The <function>trigger</function> callback must not sleep; the
- actual reading of data from the device is usually done in an
- interrupt handler.
- </para>
-
- <para>
- When data reception is enabled, your interrupt handler should
- call <function>snd_rawmidi_receive</function> for all received
- data:
- <informalexample>
- <programlisting>
-<![CDATA[
- void snd_mychip_midi_interrupt(...)
- {
- while (mychip_midi_available()) {
- unsigned char data;
- data = mychip_midi_read();
- snd_rawmidi_receive(substream, &data, 1);
- }
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
- </section>
-
- <section id="rawmidi-interface-op-drain">
- <title><function>drain</function> callback</title>
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static void snd_xxx_drain(struct snd_rawmidi_substream *substream);
-]]>
- </programlisting>
- </informalexample>
-
- <para>
- This is only used with output substreams. This function should wait
- until all data read from the substream buffer have been transmitted.
- This ensures that the device can be closed and the driver unloaded
- without losing data.
- </para>
-
- <para>
- This callback is optional. If you do not set
- <structfield>drain</structfield> in the struct snd_rawmidi_ops
- structure, ALSA will simply wait for 50&nbsp;milliseconds
- instead.
- </para>
- </section>
- </section>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Miscellaneous Devices -->
-<!-- ****************************************************** -->
- <chapter id="misc-devices">
- <title>Miscellaneous Devices</title>
-
- <section id="misc-devices-opl3">
- <title>FM OPL3</title>
- <para>
- The FM OPL3 is still used in many chips (mainly for backward
- compatibility). ALSA has a nice OPL3 FM control layer, too. The
- OPL3 API is defined in
- <filename>&lt;sound/opl3.h&gt;</filename>.
- </para>
-
- <para>
- FM registers can be directly accessed through the direct-FM API,
- defined in <filename>&lt;sound/asound_fm.h&gt;</filename>. In
- ALSA native mode, FM registers are accessed through
- the Hardware-Dependent Device direct-FM extension API, whereas in
- OSS compatible mode, FM registers can be accessed with the OSS
- direct-FM compatible API in <filename>/dev/dmfmX</filename> device.
- </para>
-
- <para>
- To create the OPL3 component, you have two functions to
- call. The first one is a constructor for the <type>opl3_t</type>
- instance.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_opl3 *opl3;
- snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX,
- integrated, &opl3);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The first argument is the card pointer, the second one is the
- left port address, and the third is the right port address. In
- most cases, the right port is placed at the left port + 2.
- </para>
-
- <para>
- The fourth argument is the hardware type.
- </para>
-
- <para>
- When the left and right ports have been already allocated by
- the card driver, pass non-zero to the fifth argument
- (<parameter>integrated</parameter>). Otherwise, the opl3 module will
- allocate the specified ports by itself.
- </para>
-
- <para>
- When the accessing the hardware requires special method
- instead of the standard I/O access, you can create opl3 instance
- separately with <function>snd_opl3_new()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_opl3 *opl3;
- snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Then set <structfield>command</structfield>,
- <structfield>private_data</structfield> and
- <structfield>private_free</structfield> for the private
- access function, the private data and the destructor.
- The l_port and r_port are not necessarily set. Only the
- command must be set properly. You can retrieve the data
- from the opl3-&gt;private_data field.
- </para>
-
- <para>
- After creating the opl3 instance via <function>snd_opl3_new()</function>,
- call <function>snd_opl3_init()</function> to initialize the chip to the
- proper state. Note that <function>snd_opl3_create()</function> always
- calls it internally.
- </para>
-
- <para>
- If the opl3 instance is created successfully, then create a
- hwdep device for this opl3.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_hwdep *opl3hwdep;
- snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The first argument is the <type>opl3_t</type> instance you
- created, and the second is the index number, usually 0.
- </para>
-
- <para>
- The third argument is the index-offset for the sequencer
- client assigned to the OPL3 port. When there is an MPU401-UART,
- give 1 for here (UART always takes 0).
- </para>
- </section>
-
- <section id="misc-devices-hardware-dependent">
- <title>Hardware-Dependent Devices</title>
- <para>
- Some chips need user-space access for special
- controls or for loading the micro code. In such a case, you can
- create a hwdep (hardware-dependent) device. The hwdep API is
- defined in <filename>&lt;sound/hwdep.h&gt;</filename>. You can
- find examples in opl3 driver or
- <filename>isa/sb/sb16_csp.c</filename>.
- </para>
-
- <para>
- The creation of the <type>hwdep</type> instance is done via
- <function>snd_hwdep_new()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_hwdep *hw;
- snd_hwdep_new(card, "My HWDEP", 0, &hw);
-]]>
- </programlisting>
- </informalexample>
-
- where the third argument is the index number.
- </para>
-
- <para>
- You can then pass any pointer value to the
- <parameter>private_data</parameter>.
- If you assign a private data, you should define the
- destructor, too. The destructor function is set in
- the <structfield>private_free</structfield> field.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
- hw->private_data = p;
- hw->private_free = mydata_free;
-]]>
- </programlisting>
- </informalexample>
-
- and the implementation of the destructor would be:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static void mydata_free(struct snd_hwdep *hw)
- {
- struct mydata *p = hw->private_data;
- kfree(p);
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The arbitrary file operations can be defined for this
- instance. The file operators are defined in
- the <parameter>ops</parameter> table. For example, assume that
- this chip needs an ioctl.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- hw->ops.open = mydata_open;
- hw->ops.ioctl = mydata_ioctl;
- hw->ops.release = mydata_release;
-]]>
- </programlisting>
- </informalexample>
-
- And implement the callback functions as you like.
- </para>
- </section>
-
- <section id="misc-devices-IEC958">
- <title>IEC958 (S/PDIF)</title>
- <para>
- Usually the controls for IEC958 devices are implemented via
- the control interface. There is a macro to compose a name string for
- IEC958 controls, <function>SNDRV_CTL_NAME_IEC958()</function>
- defined in <filename>&lt;include/asound.h&gt;</filename>.
- </para>
-
- <para>
- There are some standard controls for IEC958 status bits. These
- controls use the type <type>SNDRV_CTL_ELEM_TYPE_IEC958</type>,
- and the size of element is fixed as 4 bytes array
- (value.iec958.status[x]). For the <structfield>info</structfield>
- callback, you don't specify
- the value field for this type (the count field must be set,
- though).
- </para>
-
- <para>
- <quote>IEC958 Playback Con Mask</quote> is used to return the
- bit-mask for the IEC958 status bits of consumer mode. Similarly,
- <quote>IEC958 Playback Pro Mask</quote> returns the bitmask for
- professional mode. They are read-only controls, and are defined
- as MIXER controls (iface =
- <constant>SNDRV_CTL_ELEM_IFACE_MIXER</constant>).
- </para>
-
- <para>
- Meanwhile, <quote>IEC958 Playback Default</quote> control is
- defined for getting and setting the current default IEC958
- bits. Note that this one is usually defined as a PCM control
- (iface = <constant>SNDRV_CTL_ELEM_IFACE_PCM</constant>),
- although in some places it's defined as a MIXER control.
- </para>
-
- <para>
- In addition, you can define the control switches to
- enable/disable or to set the raw bit mode. The implementation
- will depend on the chip, but the control should be named as
- <quote>IEC958 xxx</quote>, preferably using
- the <function>SNDRV_CTL_NAME_IEC958()</function> macro.
- </para>
-
- <para>
- You can find several cases, for example,
- <filename>pci/emu10k1</filename>,
- <filename>pci/ice1712</filename>, or
- <filename>pci/cmipci.c</filename>.
- </para>
- </section>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Buffer and Memory Management -->
-<!-- ****************************************************** -->
- <chapter id="buffer-and-memory">
- <title>Buffer and Memory Management</title>
-
- <section id="buffer-and-memory-buffer-types">
- <title>Buffer Types</title>
- <para>
- ALSA provides several different buffer allocation functions
- depending on the bus and the architecture. All these have a
- consistent API. The allocation of physically-contiguous pages is
- done via
- <function>snd_malloc_xxx_pages()</function> function, where xxx
- is the bus type.
- </para>
-
- <para>
- The allocation of pages with fallback is
- <function>snd_malloc_xxx_pages_fallback()</function>. This
- function tries to allocate the specified pages but if the pages
- are not available, it tries to reduce the page sizes until
- enough space is found.
- </para>
-
- <para>
- The release the pages, call
- <function>snd_free_xxx_pages()</function> function.
- </para>
-
- <para>
- Usually, ALSA drivers try to allocate and reserve
- a large contiguous physical space
- at the time the module is loaded for the later use.
- This is called <quote>pre-allocation</quote>.
- As already written, you can call the following function at
- pcm instance construction time (in the case of PCI bus).
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(pci), size, max);
-]]>
- </programlisting>
- </informalexample>
-
- where <parameter>size</parameter> is the byte size to be
- pre-allocated and the <parameter>max</parameter> is the maximum
- size to be changed via the <filename>prealloc</filename> proc file.
- The allocator will try to get an area as large as possible
- within the given size.
- </para>
-
- <para>
- The second argument (type) and the third argument (device pointer)
- are dependent on the bus.
- In the case of the ISA bus, pass <function>snd_dma_isa_data()</function>
- as the third argument with <constant>SNDRV_DMA_TYPE_DEV</constant> type.
- For the continuous buffer unrelated to the bus can be pre-allocated
- with <constant>SNDRV_DMA_TYPE_CONTINUOUS</constant> type and the
- <function>snd_dma_continuous_data(GFP_KERNEL)</function> device pointer,
- where <constant>GFP_KERNEL</constant> is the kernel allocation flag to
- use.
- For the PCI scatter-gather buffers, use
- <constant>SNDRV_DMA_TYPE_DEV_SG</constant> with
- <function>snd_dma_pci_data(pci)</function>
- (see the
- <link linkend="buffer-and-memory-non-contiguous"><citetitle>Non-Contiguous Buffers
- </citetitle></link> section).
- </para>
-
- <para>
- Once the buffer is pre-allocated, you can use the
- allocator in the <structfield>hw_params</structfield> callback:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_pcm_lib_malloc_pages(substream, size);
-]]>
- </programlisting>
- </informalexample>
-
- Note that you have to pre-allocate to use this function.
- </para>
- </section>
-
- <section id="buffer-and-memory-external-hardware">
- <title>External Hardware Buffers</title>
- <para>
- Some chips have their own hardware buffers and the DMA
- transfer from the host memory is not available. In such a case,
- you need to either 1) copy/set the audio data directly to the
- external hardware buffer, or 2) make an intermediate buffer and
- copy/set the data from it to the external hardware buffer in
- interrupts (or in tasklets, preferably).
- </para>
-
- <para>
- The first case works fine if the external hardware buffer is large
- enough. This method doesn't need any extra buffers and thus is
- more effective. You need to define the
- <structfield>copy</structfield> and
- <structfield>silence</structfield> callbacks for
- the data transfer. However, there is a drawback: it cannot
- be mmapped. The examples are GUS's GF1 PCM or emu8000's
- wavetable PCM.
- </para>
-
- <para>
- The second case allows for mmap on the buffer, although you have
- to handle an interrupt or a tasklet to transfer the data
- from the intermediate buffer to the hardware buffer. You can find an
- example in the vxpocket driver.
- </para>
-
- <para>
- Another case is when the chip uses a PCI memory-map
- region for the buffer instead of the host memory. In this case,
- mmap is available only on certain architectures like the Intel one.
- In non-mmap mode, the data cannot be transferred as in the normal
- way. Thus you need to define the <structfield>copy</structfield> and
- <structfield>silence</structfield> callbacks as well,
- as in the cases above. The examples are found in
- <filename>rme32.c</filename> and <filename>rme96.c</filename>.
- </para>
-
- <para>
- The implementation of the <structfield>copy</structfield> and
- <structfield>silence</structfield> callbacks depends upon
- whether the hardware supports interleaved or non-interleaved
- samples. The <structfield>copy</structfield> callback is
- defined like below, a bit
- differently depending whether the direction is playback or
- capture:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int playback_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count);
- static int capture_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- In the case of interleaved samples, the second argument
- (<parameter>channel</parameter>) is not used. The third argument
- (<parameter>pos</parameter>) points the
- current position offset in frames.
- </para>
-
- <para>
- The meaning of the fourth argument is different between
- playback and capture. For playback, it holds the source data
- pointer, and for capture, it's the destination data pointer.
- </para>
-
- <para>
- The last argument is the number of frames to be copied.
- </para>
-
- <para>
- What you have to do in this callback is again different
- between playback and capture directions. In the
- playback case, you copy the given amount of data
- (<parameter>count</parameter>) at the specified pointer
- (<parameter>src</parameter>) to the specified offset
- (<parameter>pos</parameter>) on the hardware buffer. When
- coded like memcpy-like way, the copy would be like:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- my_memcpy(my_buffer + frames_to_bytes(runtime, pos), src,
- frames_to_bytes(runtime, count));
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- For the capture direction, you copy the given amount of
- data (<parameter>count</parameter>) at the specified offset
- (<parameter>pos</parameter>) on the hardware buffer to the
- specified pointer (<parameter>dst</parameter>).
-
- <informalexample>
- <programlisting>
-<![CDATA[
- my_memcpy(dst, my_buffer + frames_to_bytes(runtime, pos),
- frames_to_bytes(runtime, count));
-]]>
- </programlisting>
- </informalexample>
-
- Note that both the position and the amount of data are given
- in frames.
- </para>
-
- <para>
- In the case of non-interleaved samples, the implementation
- will be a bit more complicated.
- </para>
-
- <para>
- You need to check the channel argument, and if it's -1, copy
- the whole channels. Otherwise, you have to copy only the
- specified channel. Please check
- <filename>isa/gus/gus_pcm.c</filename> as an example.
- </para>
-
- <para>
- The <structfield>silence</structfield> callback is also
- implemented in a similar way.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int silence(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The meanings of arguments are the same as in the
- <structfield>copy</structfield>
- callback, although there is no <parameter>src/dst</parameter>
- argument. In the case of interleaved samples, the channel
- argument has no meaning, as well as on
- <structfield>copy</structfield> callback.
- </para>
-
- <para>
- The role of <structfield>silence</structfield> callback is to
- set the given amount
- (<parameter>count</parameter>) of silence data at the
- specified offset (<parameter>pos</parameter>) on the hardware
- buffer. Suppose that the data format is signed (that is, the
- silent-data is 0), and the implementation using a memset-like
- function would be like:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- my_memcpy(my_buffer + frames_to_bytes(runtime, pos), 0,
- frames_to_bytes(runtime, count));
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- In the case of non-interleaved samples, again, the
- implementation becomes a bit more complicated. See, for example,
- <filename>isa/gus/gus_pcm.c</filename>.
- </para>
- </section>
-
- <section id="buffer-and-memory-non-contiguous">
- <title>Non-Contiguous Buffers</title>
- <para>
- If your hardware supports the page table as in emu10k1 or the
- buffer descriptors as in via82xx, you can use the scatter-gather
- (SG) DMA. ALSA provides an interface for handling SG-buffers.
- The API is provided in <filename>&lt;sound/pcm.h&gt;</filename>.
- </para>
-
- <para>
- For creating the SG-buffer handler, call
- <function>snd_pcm_lib_preallocate_pages()</function> or
- <function>snd_pcm_lib_preallocate_pages_for_all()</function>
- with <constant>SNDRV_DMA_TYPE_DEV_SG</constant>
- in the PCM constructor like other PCI pre-allocator.
- You need to pass <function>snd_dma_pci_data(pci)</function>,
- where pci is the struct <structname>pci_dev</structname> pointer
- of the chip as well.
- The <type>struct snd_sg_buf</type> instance is created as
- substream-&gt;dma_private. You can cast
- the pointer like:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Then call <function>snd_pcm_lib_malloc_pages()</function>
- in the <structfield>hw_params</structfield> callback
- as well as in the case of normal PCI buffer.
- The SG-buffer handler will allocate the non-contiguous kernel
- pages of the given size and map them onto the virtually contiguous
- memory. The virtual pointer is addressed in runtime-&gt;dma_area.
- The physical address (runtime-&gt;dma_addr) is set to zero,
- because the buffer is physically non-contiguous.
- The physical address table is set up in sgbuf-&gt;table.
- You can get the physical address at a certain offset via
- <function>snd_pcm_sgbuf_get_addr()</function>.
- </para>
-
- <para>
- When a SG-handler is used, you need to set
- <function>snd_pcm_sgbuf_ops_page</function> as
- the <structfield>page</structfield> callback.
- (See <link linkend="pcm-interface-operators-page-callback">
- <citetitle>page callback section</citetitle></link>.)
- </para>
-
- <para>
- To release the data, call
- <function>snd_pcm_lib_free_pages()</function> in the
- <structfield>hw_free</structfield> callback as usual.
- </para>
- </section>
-
- <section id="buffer-and-memory-vmalloced">
- <title>Vmalloc'ed Buffers</title>
- <para>
- It's possible to use a buffer allocated via
- <function>vmalloc</function>, for example, for an intermediate
- buffer. Since the allocated pages are not contiguous, you need
- to set the <structfield>page</structfield> callback to obtain
- the physical address at every offset.
- </para>
-
- <para>
- The implementation of <structfield>page</structfield> callback
- would be like this:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- #include <linux/vmalloc.h>
-
- /* get the physical page pointer on the given offset */
- static struct page *mychip_page(struct snd_pcm_substream *substream,
- unsigned long offset)
- {
- void *pageptr = substream->runtime->dma_area + offset;
- return vmalloc_to_page(pageptr);
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
- </section>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Proc Interface -->
-<!-- ****************************************************** -->
- <chapter id="proc-interface">
- <title>Proc Interface</title>
- <para>
- ALSA provides an easy interface for procfs. The proc files are
- very useful for debugging. I recommend you set up proc files if
- you write a driver and want to get a running status or register
- dumps. The API is found in
- <filename>&lt;sound/info.h&gt;</filename>.
- </para>
-
- <para>
- To create a proc file, call
- <function>snd_card_proc_new()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- struct snd_info_entry *entry;
- int err = snd_card_proc_new(card, "my-file", &entry);
-]]>
- </programlisting>
- </informalexample>
-
- where the second argument specifies the name of the proc file to be
- created. The above example will create a file
- <filename>my-file</filename> under the card directory,
- e.g. <filename>/proc/asound/card0/my-file</filename>.
- </para>
-
- <para>
- Like other components, the proc entry created via
- <function>snd_card_proc_new()</function> will be registered and
- released automatically in the card registration and release
- functions.
- </para>
-
- <para>
- When the creation is successful, the function stores a new
- instance in the pointer given in the third argument.
- It is initialized as a text proc file for read only. To use
- this proc file as a read-only text file as it is, set the read
- callback with a private data via
- <function>snd_info_set_text_ops()</function>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_info_set_text_ops(entry, chip, my_proc_read);
-]]>
- </programlisting>
- </informalexample>
-
- where the second argument (<parameter>chip</parameter>) is the
- private data to be used in the callbacks. The third parameter
- specifies the read buffer size and the fourth
- (<parameter>my_proc_read</parameter>) is the callback function, which
- is defined like
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static void my_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer);
-]]>
- </programlisting>
- </informalexample>
-
- </para>
-
- <para>
- In the read callback, use <function>snd_iprintf()</function> for
- output strings, which works just like normal
- <function>printf()</function>. For example,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static void my_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
- {
- struct my_chip *chip = entry->private_data;
-
- snd_iprintf(buffer, "This is my chip!\n");
- snd_iprintf(buffer, "Port = %ld\n", chip->port);
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The file permissions can be changed afterwards. As default, it's
- set as read only for all users. If you want to add write
- permission for the user (root as default), do as follows:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-]]>
- </programlisting>
- </informalexample>
-
- and set the write buffer size and the callback
-
- <informalexample>
- <programlisting>
-<![CDATA[
- entry->c.text.write = my_proc_write;
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- For the write callback, you can use
- <function>snd_info_get_line()</function> to get a text line, and
- <function>snd_info_get_str()</function> to retrieve a string from
- the line. Some examples are found in
- <filename>core/oss/mixer_oss.c</filename>, core/oss/and
- <filename>pcm_oss.c</filename>.
- </para>
-
- <para>
- For a raw-data proc-file, set the attributes as follows:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static struct snd_info_entry_ops my_file_io_ops = {
- .read = my_file_io_read,
- };
-
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = chip;
- entry->c.ops = &my_file_io_ops;
- entry->size = 4096;
- entry->mode = S_IFREG | S_IRUGO;
-]]>
- </programlisting>
- </informalexample>
-
- For the raw data, <structfield>size</structfield> field must be
- set properly. This specifies the maximum size of the proc file access.
- </para>
-
- <para>
- The read/write callbacks of raw mode are more direct than the text mode.
- You need to use a low-level I/O functions such as
- <function>copy_from/to_user()</function> to transfer the
- data.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static ssize_t my_file_io_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file,
- char *buf,
- size_t count,
- loff_t pos)
- {
- if (copy_to_user(buf, local_data + pos, count))
- return -EFAULT;
- return count;
- }
-]]>
- </programlisting>
- </informalexample>
-
- If the size of the info entry has been set up properly,
- <structfield>count</structfield> and <structfield>pos</structfield> are
- guaranteed to fit within 0 and the given size.
- You don't have to check the range in the callbacks unless any
- other condition is required.
-
- </para>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Power Management -->
-<!-- ****************************************************** -->
- <chapter id="power-management">
- <title>Power Management</title>
- <para>
- If the chip is supposed to work with suspend/resume
- functions, you need to add power-management code to the
- driver. The additional code for power-management should be
- <function>ifdef</function>'ed with
- <constant>CONFIG_PM</constant>.
- </para>
-
- <para>
- If the driver <emphasis>fully</emphasis> supports suspend/resume
- that is, the device can be
- properly resumed to its state when suspend was called,
- you can set the <constant>SNDRV_PCM_INFO_RESUME</constant> flag
- in the pcm info field. Usually, this is possible when the
- registers of the chip can be safely saved and restored to
- RAM. If this is set, the trigger callback is called with
- <constant>SNDRV_PCM_TRIGGER_RESUME</constant> after the resume
- callback completes.
- </para>
-
- <para>
- Even if the driver doesn't support PM fully but
- partial suspend/resume is still possible, it's still worthy to
- implement suspend/resume callbacks. In such a case, applications
- would reset the status by calling
- <function>snd_pcm_prepare()</function> and restart the stream
- appropriately. Hence, you can define suspend/resume callbacks
- below but don't set <constant>SNDRV_PCM_INFO_RESUME</constant>
- info flag to the PCM.
- </para>
-
- <para>
- Note that the trigger with SUSPEND can always be called when
- <function>snd_pcm_suspend_all</function> is called,
- regardless of the <constant>SNDRV_PCM_INFO_RESUME</constant> flag.
- The <constant>RESUME</constant> flag affects only the behavior
- of <function>snd_pcm_resume()</function>.
- (Thus, in theory,
- <constant>SNDRV_PCM_TRIGGER_RESUME</constant> isn't needed
- to be handled in the trigger callback when no
- <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set. But,
- it's better to keep it for compatibility reasons.)
- </para>
- <para>
- In the earlier version of ALSA drivers, a common
- power-management layer was provided, but it has been removed.
- The driver needs to define the suspend/resume hooks according to
- the bus the device is connected to. In the case of PCI drivers, the
- callbacks look like below:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- #ifdef CONFIG_PM
- static int snd_my_suspend(struct pci_dev *pci, pm_message_t state)
- {
- .... /* do things for suspend */
- return 0;
- }
- static int snd_my_resume(struct pci_dev *pci)
- {
- .... /* do things for suspend */
- return 0;
- }
- #endif
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The scheme of the real suspend job is as follows.
-
- <orderedlist>
- <listitem><para>Retrieve the card and the chip data.</para></listitem>
- <listitem><para>Call <function>snd_power_change_state()</function> with
- <constant>SNDRV_CTL_POWER_D3hot</constant> to change the
- power status.</para></listitem>
- <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
- <listitem><para>If AC97 codecs are used, call
- <function>snd_ac97_suspend()</function> for each codec.</para></listitem>
- <listitem><para>Save the register values if necessary.</para></listitem>
- <listitem><para>Stop the hardware if necessary.</para></listitem>
- <listitem><para>Disable the PCI device by calling
- <function>pci_disable_device()</function>. Then, call
- <function>pci_save_state()</function> at last.</para></listitem>
- </orderedlist>
- </para>
-
- <para>
- A typical code would be like:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int mychip_suspend(struct pci_dev *pci, pm_message_t state)
- {
- /* (1) */
- struct snd_card *card = pci_get_drvdata(pci);
- struct mychip *chip = card->private_data;
- /* (2) */
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- /* (3) */
- snd_pcm_suspend_all(chip->pcm);
- /* (4) */
- snd_ac97_suspend(chip->ac97);
- /* (5) */
- snd_mychip_save_registers(chip);
- /* (6) */
- snd_mychip_stop_hardware(chip);
- /* (7) */
- pci_disable_device(pci);
- pci_save_state(pci);
- return 0;
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- The scheme of the real resume job is as follows.
-
- <orderedlist>
- <listitem><para>Retrieve the card and the chip data.</para></listitem>
- <listitem><para>Set up PCI. First, call <function>pci_restore_state()</function>.
- Then enable the pci device again by calling <function>pci_enable_device()</function>.
- Call <function>pci_set_master()</function> if necessary, too.</para></listitem>
- <listitem><para>Re-initialize the chip.</para></listitem>
- <listitem><para>Restore the saved registers if necessary.</para></listitem>
- <listitem><para>Resume the mixer, e.g. calling
- <function>snd_ac97_resume()</function>.</para></listitem>
- <listitem><para>Restart the hardware (if any).</para></listitem>
- <listitem><para>Call <function>snd_power_change_state()</function> with
- <constant>SNDRV_CTL_POWER_D0</constant> to notify the processes.</para></listitem>
- </orderedlist>
- </para>
-
- <para>
- A typical code would be like:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int mychip_resume(struct pci_dev *pci)
- {
- /* (1) */
- struct snd_card *card = pci_get_drvdata(pci);
- struct mychip *chip = card->private_data;
- /* (2) */
- pci_restore_state(pci);
- pci_enable_device(pci);
- pci_set_master(pci);
- /* (3) */
- snd_mychip_reinit_chip(chip);
- /* (4) */
- snd_mychip_restore_registers(chip);
- /* (5) */
- snd_ac97_resume(chip->ac97);
- /* (6) */
- snd_mychip_restart_chip(chip);
- /* (7) */
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
- }
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- As shown in the above, it's better to save registers after
- suspending the PCM operations via
- <function>snd_pcm_suspend_all()</function> or
- <function>snd_pcm_suspend()</function>. It means that the PCM
- streams are already stopped when the register snapshot is
- taken. But, remember that you don't have to restart the PCM
- stream in the resume callback. It'll be restarted via
- trigger call with <constant>SNDRV_PCM_TRIGGER_RESUME</constant>
- when necessary.
- </para>
-
- <para>
- OK, we have all callbacks now. Let's set them up. In the
- initialization of the card, make sure that you can get the chip
- data from the card instance, typically via
- <structfield>private_data</structfield> field, in case you
- created the chip data individually.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_mychip_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
- {
- ....
- struct snd_card *card;
- struct mychip *chip;
- int err;
- ....
- err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
- 0, &card);
- ....
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- ....
- card->private_data = chip;
- ....
- }
-]]>
- </programlisting>
- </informalexample>
-
- When you created the chip data with
- <function>snd_card_new()</function>, it's anyway accessible
- via <structfield>private_data</structfield> field.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int snd_mychip_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
- {
- ....
- struct snd_card *card;
- struct mychip *chip;
- int err;
- ....
- err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
- sizeof(struct mychip), &card);
- ....
- chip = card->private_data;
- ....
- }
-]]>
- </programlisting>
- </informalexample>
-
- </para>
-
- <para>
- If you need a space to save the registers, allocate the
- buffer for it here, too, since it would be fatal
- if you cannot allocate a memory in the suspend phase.
- The allocated buffer should be released in the corresponding
- destructor.
- </para>
-
- <para>
- And next, set suspend/resume callbacks to the pci_driver.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_my_ids,
- .probe = snd_my_probe,
- .remove = snd_my_remove,
- #ifdef CONFIG_PM
- .suspend = snd_my_suspend,
- .resume = snd_my_resume,
- #endif
- };
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Module Parameters -->
-<!-- ****************************************************** -->
- <chapter id="module-parameters">
- <title>Module Parameters</title>
- <para>
- There are standard module options for ALSA. At least, each
- module should have the <parameter>index</parameter>,
- <parameter>id</parameter> and <parameter>enable</parameter>
- options.
- </para>
-
- <para>
- If the module supports multiple cards (usually up to
- 8 = <constant>SNDRV_CARDS</constant> cards), they should be
- arrays. The default initial values are defined already as
- constants for easier programming:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
- static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
- static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- If the module supports only a single card, they could be single
- variables, instead. <parameter>enable</parameter> option is not
- always necessary in this case, but it would be better to have a
- dummy option for compatibility.
- </para>
-
- <para>
- The module parameters must be declared with the standard
- <function>module_param()()</function>,
- <function>module_param_array()()</function> and
- <function>MODULE_PARM_DESC()</function> macros.
- </para>
-
- <para>
- The typical coding would be like below:
-
- <informalexample>
- <programlisting>
-<![CDATA[
- #define CARD_NAME "My Chip"
-
- module_param_array(index, int, NULL, 0444);
- MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
- module_param_array(id, charp, NULL, 0444);
- MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
- module_param_array(enable, bool, NULL, 0444);
- MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- Also, don't forget to define the module description, classes,
- license and devices. Especially, the recent modprobe requires to
- define the module license as GPL, etc., otherwise the system is
- shown as <quote>tainted</quote>.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- MODULE_DESCRIPTION("My Chip");
- MODULE_LICENSE("GPL");
- MODULE_SUPPORTED_DEVICE("{{Vendor,My Chip Name}}");
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- How To Put Your Driver -->
-<!-- ****************************************************** -->
- <chapter id="how-to-put-your-driver">
- <title>How To Put Your Driver Into ALSA Tree</title>
- <section>
- <title>General</title>
- <para>
- So far, you've learned how to write the driver codes.
- And you might have a question now: how to put my own
- driver into the ALSA driver tree?
- Here (finally :) the standard procedure is described briefly.
- </para>
-
- <para>
- Suppose that you create a new PCI driver for the card
- <quote>xyz</quote>. The card module name would be
- snd-xyz. The new driver is usually put into the alsa-driver
- tree, <filename>alsa-driver/pci</filename> directory in
- the case of PCI cards.
- Then the driver is evaluated, audited and tested
- by developers and users. After a certain time, the driver
- will go to the alsa-kernel tree (to the corresponding directory,
- such as <filename>alsa-kernel/pci</filename>) and eventually
- will be integrated into the Linux 2.6 tree (the directory would be
- <filename>linux/sound/pci</filename>).
- </para>
-
- <para>
- In the following sections, the driver code is supposed
- to be put into alsa-driver tree. The two cases are covered:
- a driver consisting of a single source file and one consisting
- of several source files.
- </para>
- </section>
-
- <section>
- <title>Driver with A Single Source File</title>
- <para>
- <orderedlist>
- <listitem>
- <para>
- Modify alsa-driver/pci/Makefile
- </para>
-
- <para>
- Suppose you have a file xyz.c. Add the following
- two lines
- <informalexample>
- <programlisting>
-<![CDATA[
- snd-xyz-objs := xyz.o
- obj-$(CONFIG_SND_XYZ) += snd-xyz.o
-]]>
- </programlisting>
- </informalexample>
- </para>
- </listitem>
-
- <listitem>
- <para>
- Create the Kconfig entry
- </para>
-
- <para>
- Add the new entry of Kconfig for your xyz driver.
- <informalexample>
- <programlisting>
-<![CDATA[
- config SND_XYZ
- tristate "Foobar XYZ"
- depends on SND
- select SND_PCM
- help
- Say Y here to include support for Foobar XYZ soundcard.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-xyz.
-]]>
- </programlisting>
- </informalexample>
-
- the line, select SND_PCM, specifies that the driver xyz supports
- PCM. In addition to SND_PCM, the following components are
- supported for select command:
- SND_RAWMIDI, SND_TIMER, SND_HWDEP, SND_MPU401_UART,
- SND_OPL3_LIB, SND_OPL4_LIB, SND_VX_LIB, SND_AC97_CODEC.
- Add the select command for each supported component.
- </para>
-
- <para>
- Note that some selections imply the lowlevel selections.
- For example, PCM includes TIMER, MPU401_UART includes RAWMIDI,
- AC97_CODEC includes PCM, and OPL3_LIB includes HWDEP.
- You don't need to give the lowlevel selections again.
- </para>
-
- <para>
- For the details of Kconfig script, refer to the kbuild
- documentation.
- </para>
-
- </listitem>
-
- <listitem>
- <para>
- Run cvscompile script to re-generate the configure script and
- build the whole stuff again.
- </para>
- </listitem>
- </orderedlist>
- </para>
- </section>
-
- <section>
- <title>Drivers with Several Source Files</title>
- <para>
- Suppose that the driver snd-xyz have several source files.
- They are located in the new subdirectory,
- pci/xyz.
-
- <orderedlist>
- <listitem>
- <para>
- Add a new directory (<filename>xyz</filename>) in
- <filename>alsa-driver/pci/Makefile</filename> as below
-
- <informalexample>
- <programlisting>
-<![CDATA[
- obj-$(CONFIG_SND) += xyz/
-]]>
- </programlisting>
- </informalexample>
- </para>
- </listitem>
-
- <listitem>
- <para>
- Under the directory <filename>xyz</filename>, create a Makefile
-
- <example>
- <title>Sample Makefile for a driver xyz</title>
- <programlisting>
-<![CDATA[
- ifndef SND_TOPDIR
- SND_TOPDIR=../..
- endif
-
- include $(SND_TOPDIR)/toplevel.config
- include $(SND_TOPDIR)/Makefile.conf
-
- snd-xyz-objs := xyz.o abc.o def.o
-
- obj-$(CONFIG_SND_XYZ) += snd-xyz.o
-
- include $(SND_TOPDIR)/Rules.make
-]]>
- </programlisting>
- </example>
- </para>
- </listitem>
-
- <listitem>
- <para>
- Create the Kconfig entry
- </para>
-
- <para>
- This procedure is as same as in the last section.
- </para>
- </listitem>
-
- <listitem>
- <para>
- Run cvscompile script to re-generate the configure script and
- build the whole stuff again.
- </para>
- </listitem>
- </orderedlist>
- </para>
- </section>
-
- </chapter>
-
-<!-- ****************************************************** -->
-<!-- Useful Functions -->
-<!-- ****************************************************** -->
- <chapter id="useful-functions">
- <title>Useful Functions</title>
-
- <section id="useful-functions-snd-printk">
- <title><function>snd_printk()</function> and friends</title>
- <para>
- ALSA provides a verbose version of the
- <function>printk()</function> function. If a kernel config
- <constant>CONFIG_SND_VERBOSE_PRINTK</constant> is set, this
- function prints the given message together with the file name
- and the line of the caller. The <constant>KERN_XXX</constant>
- prefix is processed as
- well as the original <function>printk()</function> does, so it's
- recommended to add this prefix, e.g.
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_printk(KERN_ERR "Oh my, sorry, it's extremely bad!\n");
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- There are also <function>printk()</function>'s for
- debugging. <function>snd_printd()</function> can be used for
- general debugging purposes. If
- <constant>CONFIG_SND_DEBUG</constant> is set, this function is
- compiled, and works just like
- <function>snd_printk()</function>. If the ALSA is compiled
- without the debugging flag, it's ignored.
- </para>
-
- <para>
- <function>snd_printdd()</function> is compiled in only when
- <constant>CONFIG_SND_DEBUG_VERBOSE</constant> is set. Please note
- that <constant>CONFIG_SND_DEBUG_VERBOSE</constant> is not set as default
- even if you configure the alsa-driver with
- <option>--with-debug=full</option> option. You need to give
- explicitly <option>--with-debug=detect</option> option instead.
- </para>
- </section>
-
- <section id="useful-functions-snd-bug">
- <title><function>snd_BUG()</function></title>
- <para>
- It shows the <computeroutput>BUG?</computeroutput> message and
- stack trace as well as <function>snd_BUG_ON</function> at the point.
- It's useful to show that a fatal error happens there.
- </para>
- <para>
- When no debug flag is set, this macro is ignored.
- </para>
- </section>
-
- <section id="useful-functions-snd-bug-on">
- <title><function>snd_BUG_ON()</function></title>
- <para>
- <function>snd_BUG_ON()</function> macro is similar with
- <function>WARN_ON()</function> macro. For example,
-
- <informalexample>
- <programlisting>
-<![CDATA[
- snd_BUG_ON(!pointer);
-]]>
- </programlisting>
- </informalexample>
-
- or it can be used as the condition,
- <informalexample>
- <programlisting>
-<![CDATA[
- if (snd_BUG_ON(non_zero_is_bug))
- return -EINVAL;
-]]>
- </programlisting>
- </informalexample>
-
- </para>
-
- <para>
- The macro takes an conditional expression to evaluate.
- When <constant>CONFIG_SND_DEBUG</constant>, is set, if the
- expression is non-zero, it shows the warning message such as
- <computeroutput>BUG? (xxx)</computeroutput>
- normally followed by stack trace.
-
- In both cases it returns the evaluated value.
- </para>
-
- </section>
-
- </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Acknowledgments -->
-<!-- ****************************************************** -->
- <chapter id="acknowledgments">
- <title>Acknowledgments</title>
- <para>
- I would like to thank Phil Kerr for his help for improvement and
- corrections of this document.
- </para>
- <para>
- Kevin Conder reformatted the original plain-text to the
- DocBook format.
- </para>
- <para>
- Giuliano Pochini corrected typos and contributed the example codes
- in the hardware constraints section.
- </para>
- </chapter>
-</book>