code:
===================================
Light-weight System Calls for IA-64
===================================

		        Started: 13-Jan-2003

		    Last update: 27-Sep-2003

	              David Mosberger-Tang
		      <davidm@hpl.hp.com>

Using the "epc" instruction effectively introduces a new mode of
execution to the ia64 linux kernel.  We call this mode the
"fsys-mode".  To recap, the normal states of execution are:

  - kernel mode:
	Both the register stack and the memory stack have been
	switched over to kernel memory.  The user-level state is saved
	in a pt-regs structure at the top of the kernel memory stack.

  - user mode:
	Both the register stack and the kernel stack are in
	user memory.  The user-level state is contained in the
	CPU registers.

  - bank 0 interruption-handling mode:
	This is the non-interruptible state which all
	interruption-handlers start execution in.  The user-level
	state remains in the CPU registers and some kernel state may
	be stored in bank 0 of registers r16-r31.

In contrast, fsys-mode has the following special properties:

  - execution is at privilege level 0 (most-privileged)

  - CPU registers may contain a mixture of user-level and kernel-level
    state (it is the responsibility of the kernel to ensure that no
    security-sensitive kernel-level state is leaked back to
    user-level)

  - execution is interruptible and preemptible (an fsys-mode handler
    can disable interrupts and avoid all other interruption-sources
    to avoid preemption)

  - neither the memory-stack nor the register-stack can be trusted while
    in fsys-mode (they point to the user-level stacks, which may
    be invalid, or completely bogus addresses)

In summary, fsys-mode is much more similar to running in user-mode
than it is to running in kernel-mode.  Of course, given that the
privilege level is at level 0, this means that fsys-mode requires some
care (see below).

How to tell fsys-mode
=====================

Linux operates in fsys-mode when (a) the privilege level is 0 (most
privileged) and (b) the stacks have NOT been switched to kernel memory
yet.  For convenience, the header file <asm-ia64/ptrace.h> provides
three macros::

	user_mode(regs)
	user_stack(task,regs)
	fsys_mode(task,regs)

The "regs" argument is a pointer to a pt_regs structure.  The "task"
argument is a pointer to the task structure to which the "regs"
pointer belongs to.  user_mode() returns TRUE if the CPU state pointed
to by "regs" was executing in user mode (privilege level 3).
user_stack() returns TRUE if the state pointed to by "regs" was
executing on the user-level stack(s).  Finally, fsys_mode() returns
TRUE if the CPU state pointed to by "regs" was executing in fsys-mode.
The fsys_mode() macro is equivalent to the expression::

	!user_mode(regs) && user_stack(task,regs)

How to write an fsyscall handler
================================

The file arch/ia64/kernel/fsys.S contains a table of fsyscall-handlers
(fsyscall_table).  This table contains one entry for each system call.
By default, a system call is handled by fsys_fallback_syscall().  This
routine takes care of entering (full) kernel mode and calling the
normal Linux system call handler.  For performance-critical system
calls, it is possible to write a hand-tuned fsyscall_handler.  For
example, fsys.S contains fsys_getpid(), which is a hand-tuned version
of the getpid() system call.

The entry and exit-state of an fsyscall handler is as follows:

Machine state on entry to fsyscall handler
------------------------------------------

  ========= ===============================================================
  r10	    0
  r11	    saved ar.pfs (a user-level value)
  r15	    system call number
  r16	    "current" task pointer (in normal kernel-mode, this is in r13)
  r32-r39   system call arguments
  b6	    return address (a user-level value)
  ar.pfs    previous frame-state (a user-level value)
  PSR.be    cleared to zero (i.e., little-endian byte order is in effect)
  -         all other registers may contain values passed in from user-mode
  ========= ===============================================================

Required machine state on exit to fsyscall handler
--------------------------------------------------

  ========= ===========================================================
  r11	    saved ar.pfs (as passed into the fsyscall handler)
  r15	    system call number (as passed into the fsyscall handler)
  r32-r39   system call arguments (as passed into the fsyscall handler)
  b6	    return address (as passed into the fsyscall handler)
  ar.pfs    previous frame-state (as passed into the fsyscall handler)
  ========= ===========================================================

Fsyscall handlers can execute with very little overhead, but with that
speed comes a set of restrictions:

 * Fsyscall-handlers MUST check for any pending work in the flags
   member of the thread-info structure and if any of the
   TIF_ALLWORK_MASK flags are set, the handler needs to fall back on
   doing a full system call (by calling fsys_fallback_syscall).

 * Fsyscall-handlers MUST preserve incoming arguments (r32-r39, r11,
   r15, b6, and ar.pfs) because they will be needed in case of a
   system call restart.  Of course, all "preserved" registers also
   must be preserved, in accordance to the normal calling conventions.

 * Fsyscall-handlers MUST check argument registers for containing a
   NaT value before using them in any way that could trigger a
   NaT-consumption fault.  If a system call argument is found to
   contain a NaT value, an fsyscall-handler may return immediately
   with r8=EINVAL, r10=-1.

 * Fsyscall-handlers MUST NOT use the "alloc" instruction or perform
   any other operation that would trigger mandatory RSE
   (register-stack engine) traffic.

 * Fsyscall-handlers MUST NOT write to any stacked registers because
   it is not safe to assume that user-level called a handler with the
   proper number of arguments.

 * Fsyscall-handlers need to be careful when accessing per-CPU variables:
   unless proper safe-guards are taken (e.g., interruptions are avoided),
   execution may be pre-empted and resumed on another CPU at any given
   time.

 * Fsyscall-handlers must be careful not to leak sensitive kernel'
   information back to user-level.  In particular, before returning to
   user-level, care needs to be taken to clear any scratch registers
   that could contain sensitive information (note that the current
   task pointer is not considered sensitive: it's already exposed
   through ar.k6).

 * Fsyscall-handlers MUST NOT access user-memory without first
   validating access-permission (this can be done typically via
   probe.r.fault and/or probe.w.fault) and without guarding against
   memory access exceptions (this can be done with the EX() macros
   defined by asmmacro.h).

The above restrictions may seem draconian, but remember that it's
possible to trade off some of the restrictions by paying a slightly
higher overhead.  For example, if an fsyscall-handler could benefit
from the shadow register bank, it could temporarily disable PSR.i and
PSR.ic, switch to bank 0 (bsw.0) and then use the shadow registers as
needed.  In other words, following the above rules yields extremely
fast system call execution (while fully preserving system call
semantics), but there is also a lot of flexibility in handling more
complicated cases.

Signal handling
===============

The delivery of (asynchronous) signals must be delayed until fsys-mode
is exited.  This is accomplished with the help of the lower-privilege
transfer trap: arch/ia64/kernel/process.c:do_notify_resume_user()
checks whether the interrupted task was in fsys-mode and, if so, sets
PSR.lp and returns immediately.  When fsys-mode is exited via the
"br.ret" instruction that lowers the privilege level, a trap will
occur.  The trap handler clears PSR.lp again and returns immediately.
The kernel exit path then checks for and delivers any pending signals.

PSR Handling
============

The "epc" instruction doesn't change the contents of PSR at all.  This
is in contrast to a regular interruption, which clears almost all
bits.  Because of that, some care needs to be taken to ensure things
work as expected.  The following discussion describes how each PSR bit
is handled.

======= =======================================================================
PSR.be	Cleared when entering fsys-mode.  A srlz.d instruction is used
	to ensure the CPU is in little-endian mode before the first
	load/store instruction is executed.  PSR.be is normally NOT
	restored upon return from an fsys-mode handler.  In other
	words, user-level code must not rely on PSR.be being preserved
	across a system call.
PSR.up	Unchanged.
PSR.ac	Unchanged.
PSR.mfl Unchanged.  Note: fsys-mode handlers must not write-registers!
PSR.mfh	Unchanged.  Note: fsys-mode handlers must not write-registers!
PSR.ic	Unchanged.  Note: fsys-mode handlers can clear the bit, if needed.
PSR.i	Unchanged.  Note: fsys-mode handlers can clear the bit, if needed.
PSR.pk	Unchanged.
PSR.dt	Unchanged.
PSR.dfl	Unchanged.  Note: fsys-mode handlers must not write-registers!
PSR.dfh	Unchanged.  Note: fsys-mode handlers must not write-registers!
PSR.sp	Unchanged.
PSR.pp	Unchanged.
PSR.di	Unchanged.
PSR.si	Unchanged.
PSR.db	Unchanged.  The kernel prevents user-level from setting a hardware
	breakpoint that triggers at any privilege level other than
	3 (user-mode).
PSR.lp	Unchanged.
PSR.tb	Lazy redirect.  If a taken-branch trap occurs while in
	fsys-mode, the trap-handler modifies the saved machine state
	such that execution resumes in the gate page at
	syscall_via_break(), with privilege level 3.  Note: the
	taken branch would occur on the branch invoking the
	fsyscall-handler, at which point, by definition, a syscall
	restart is still safe.  If the system call number is invalid,
	the fsys-mode handler will return directly to user-level.  This
	return will trigger a taken-branch trap, but since the trap is
	taken _after_ restoring the privilege level, the CPU has already
	left fsys-mode, so no special treatment is needed.
PSR.rt	Unchanged.
PSR.cpl	Cleared to 0.
PSR.is	Unchanged (guaranteed to be 0 on entry to the gate page).
PSR.mc	Unchanged.
PSR.it	Unchanged (guaranteed to be 1).
PSR.id	Unchanged.  Note: the ia64 linux kernel never sets this bit.
PSR.da	Unchanged.  Note: the ia64 linux kernel never sets this bit.
PSR.dd	Unchanged.  Note: the ia64 linux kernel never sets this bit.
PSR.ss	Lazy redirect.  If set, "epc" will cause a Single Step Trap to
	be taken.  The trap handler then modifies the saved machine
	state such that execution resumes in the gate page at
	syscall_via_break(), with privilege level 3.
PSR.ri	Unchanged.
PSR.ed	Unchanged.  Note: This bit could only have an effect if an fsys-mode
	handler performed a speculative load that gets NaTted.  If so, this
	would be the normal & expected behavior, so no special treatment is
	needed.
PSR.bn	Unchanged.  Note: fsys-mode handlers may clear the bit, if needed.
	Doing so requires clearing PSR.i and PSR.ic as well.
PSR.ia	Unchanged.  Note: the ia64 linux kernel never sets this bit.
======= =======================================================================

Using fast system calls
=======================

To use fast system calls, userspace applications need simply call
__kernel_syscall_via_epc().  For example

-- example fgettimeofday() call --

-- fgettimeofday.S --

::

  #include <asm/asmmacro.h>

  GLOBAL_ENTRY(fgettimeofday)
  .prologue
  .save ar.pfs, r11
  mov r11 = ar.pfs
  .body

  mov r2 = 0xa000000000020660;;  // gate address
			       // found by inspection of System.map for the
			       // __kernel_syscall_via_epc() function.  See
			       // below for how to do this for real.

  mov b7 = r2
  mov r15 = 1087		       // gettimeofday syscall
  ;;
  br.call.sptk.many b6 = b7
  ;;

  .restore sp

  mov ar.pfs = r11
  br.ret.sptk.many rp;;	      // return to caller
  END(fgettimeofday)

-- end fgettimeofday.S --

In reality, getting the gate address is accomplished by two extra
values passed via the ELF auxiliary vector (include/asm-ia64/elf.h)

 * AT_SYSINFO : is the address of __kernel_syscall_via_epc()
 * AT_SYSINFO_EHDR : is the address of the kernel gate ELF DSO

The ELF DSO is a pre-linked library that is mapped in by the kernel at
the gate page.  It is a proper ELF shared object so, with a dynamic
loader that recognises the library, you should be able to make calls to
the exported functions within it as with any other shared library.
AT_SYSINFO points into the kernel DSO at the
__kernel_syscall_via_epc() function for historical reasons (it was
used before the kernel DSO) and as a convenience.


code:
===========================================
Linux kernel release for the IA-64 Platform
===========================================

   These are the release notes for Linux since version 2.4 for IA-64
   platform.  This document provides information specific to IA-64
   ONLY, to get additional information about the Linux kernel also
   read the original Linux README provided with the kernel.

Installing the Kernel
=====================

 - IA-64 kernel installation is the same as the other platforms, see
   original README for details.

Software Requirements
=====================

   Compiling and running this kernel requires an IA-64 compliant GCC
   compiler.  And various software packages also compiled with an
   IA-64 compliant GCC compiler.

Configuring the Kernel
======================

   Configuration is the same, see original README for details.

Compiling the Kernel:

 - Compiling this kernel doesn't differ from other platform so read
   the original README for details BUT make sure you have an IA-64
   compliant GCC compiler.

IA-64 Specifics
===============

 - General issues:

    * Hardly any performance tuning has been done. Obvious targets
      include the library routines (IP checksum, etc.). Less
      obvious targets include making sure we don't flush the TLB
      needlessly, etc.

    * SMP locks cleanup/optimization

    * IA32 support.  Currently experimental.  It mostly works.

repo_name: angery/linux


code:
.. SPDX-License-Identifier: GPL-2.0

==================
IA-64 Architecture
==================

.. toctree::
   :maxdepth: 1

   ia64
   aliasing
   efirtc
   err_inject
   fsys
   irq-redir
   mca
   serial

   features


code:
==============================
IRQ affinity on IA64 platforms
==============================

07.01.2002, Erich Focht <efocht@ess.nec.de>

By writing to /proc/irq/IRQ#/smp_affinity the interrupt routing can be
controlled. The behavior on IA64 platforms is slightly different from
that described in Documentation/core-api/irq/irq-affinity.rst for i386 systems.

Because of the usage of SAPIC mode and physical destination mode the
IRQ target is one particular CPU and cannot be a mask of several
CPUs. Only the first non-zero bit is taken into account.

Usage examples
==============

The target CPU has to be specified as a hexadecimal CPU mask. The
first non-zero bit is the selected CPU. This format has been kept for
compatibility reasons with i386.

Set the delivery mode of interrupt 41 to fixed and route the
interrupts to CPU #3 (logical CPU number) (2^3=0x08)::

     echo "8" >/proc/irq/41/smp_affinity

Set the default route for IRQ number 41 to CPU 6 in lowest priority
delivery mode (redirectable)::

     echo "r 40" >/proc/irq/41/smp_affinity

The output of the command::

     cat /proc/irq/IRQ#/smp_affinity

gives the target CPU mask for the specified interrupt vector. If the CPU
mask is preceded by the character "r", the interrupt is redirectable
(i.e. lowest priority mode routing is used), otherwise its route is
fixed.

Initialization and default behavior
===================================

If the platform features IRQ redirection (info provided by SAL) all
IO-SAPIC interrupts are initialized with CPU#0 as their default target
and the routing is the so called "lowest priority mode" (actually
fixed SAPIC mode with hint). The XTP chipset registers are used as hints
for the IRQ routing. Currently in Linux XTP registers can have three
values:

	- minimal for an idle task,
	- normal if any other task runs,
	- maximal if the CPU is going to be switched off.

The IRQ is routed to the CPU with lowest XTP register value, the
search begins at the default CPU. Therefore most of the interrupts
will be handled by CPU #0.

If the platform doesn't feature interrupt redirection IOSAPIC fixed
routing is used. The target CPUs are distributed in a round robin
manner. IRQs will be routed only to the selected target CPUs. Check
with::

        cat /proc/interrupts

Comments
========

On large (multi-node) systems it is recommended to route the IRQs to
the node to which the corresponding device is connected.
For systems like the NEC AzusA we get IRQ node-affinity for free. This
is because usually the chipsets on each node redirect the interrupts
only to their own CPUs (as they cannot see the XTP registers on the
other nodes).


code:
=============================================================
An ad-hoc collection of notes on IA64 MCA and INIT processing
=============================================================

Feel free to update it with notes about any area that is not clear.

---

MCA/INIT are completely asynchronous.  They can occur at any time, when
the OS is in any state.  Including when one of the cpus is already
holding a spinlock.  Trying to get any lock from MCA/INIT state is
asking for deadlock.  Also the state of structures that are protected
by locks is indeterminate, including linked lists.

---

The complicated ia64 MCA process.  All of this is mandated by Intel's
specification for ia64 SAL, error recovery and unwind, it is not as
if we have a choice here.

* MCA occurs on one cpu, usually due to a double bit memory error.
  This is the monarch cpu.

* SAL sends an MCA rendezvous interrupt (which is a normal interrupt)
  to all the other cpus, the slaves.

* Slave cpus that receive the MCA interrupt call down into SAL, they
  end up spinning disabled while the MCA is being serviced.

* If any slave cpu was already spinning disabled when the MCA occurred
  then it cannot service the MCA interrupt.  SAL waits ~20 seconds then
  sends an unmaskable INIT event to the slave cpus that have not
  already rendezvoused.

* Because MCA/INIT can be delivered at any time, including when the cpu
  is down in PAL in physical mode, the registers at the time of the
  event are _completely_ undefined.  In particular the MCA/INIT
  handlers cannot rely on the thread pointer, PAL physical mode can
  (and does) modify TP.  It is allowed to do that as long as it resets
  TP on return.  However MCA/INIT events expose us to these PAL
  internal TP changes.  Hence curr_task().

* If an MCA/INIT event occurs while the kernel was running (not user
  space) and the kernel has called PAL then the MCA/INIT handler cannot
  assume that the kernel stack is in a fit state to be used.  Mainly
  because PAL may or may not maintain the stack pointer internally.
  Because the MCA/INIT handlers cannot trust the kernel stack, they
  have to use their own, per-cpu stacks.  The MCA/INIT stacks are
  preformatted with just enough task state to let the relevant handlers
  do their job.

* Unlike most other architectures, the ia64 struct task is embedded in
  the kernel stack[1].  So switching to a new kernel stack means that
  we switch to a new task as well.  Because various bits of the kernel
  assume that current points into the struct task, switching to a new
  stack also means a new value for current.

* Once all slaves have rendezvoused and are spinning disabled, the
  monarch is entered.  The monarch now tries to diagnose the problem
  and decide if it can recover or not.

* Part of the monarch's job is to look at the state of all the other
  tasks.  The only way to do that on ia64 is to call the unwinder,
  as mandated by Intel.

* The starting point for the unwind depends on whether a task is
  running or not.  That is, whether it is on a cpu or is blocked.  The
  monarch has to determine whether or not a task is on a cpu before it
  knows how to start unwinding it.  The tasks that received an MCA or
  INIT event are no longer running, they have been converted to blocked
  tasks.  But (and its a big but), the cpus that received the MCA
  rendezvous interrupt are still running on their normal kernel stacks!

* To distinguish between these two cases, the monarch must know which
  tasks are on a cpu and which are not.  Hence each slave cpu that
  switches to an MCA/INIT stack, registers its new stack using
  set_curr_task(), so the monarch can tell that the _original_ task is
  no longer running on that cpu.  That gives us a decent chance of
  getting a valid backtrace of the _original_ task.

* MCA/INIT can be nested, to a depth of 2 on any cpu.  In the case of a
  nested error, we want diagnostics on the MCA/INIT handler that
  failed, not on the task that was originally running.  Again this
  requires set_curr_task() so the MCA/INIT handlers can register their
  own stack as running on that cpu.  Then a recursive error gets a
  trace of the failing handler's "task".

[1]
    My (Keith Owens) original design called for ia64 to separate its
    struct task and the kernel stacks.  Then the MCA/INIT data would be
    chained stacks like i386 interrupt stacks.  But that required
    radical surgery on the rest of ia64, plus extra hard wired TLB
    entries with its associated performance degradation.  David
    Mosberger vetoed that approach.  Which meant that separate kernel
    stacks meant separate "tasks" for the MCA/INIT handlers.

---

INIT is less complicated than MCA.  Pressing the nmi button or using
the equivalent command on the management console sends INIT to all
cpus.  SAL picks one of the cpus as the monarch and the rest are
slaves.  All the OS INIT handlers are entered at approximately the same
time.  The OS monarch prints the state of all tasks and returns, after
which the slaves return and the system resumes.

At least that is what is supposed to happen.  Alas there are broken
versions of SAL out there.  Some drive all the cpus as monarchs.  Some
drive them all as slaves.  Some drive one cpu as monarch, wait for that
cpu to return from the OS then drive the rest as slaves.  Some versions
of SAL cannot even cope with returning from the OS, they spin inside
SAL on resume.  The OS INIT code has workarounds for some of these
broken SAL symptoms, but some simply cannot be fixed from the OS side.

---

The scheduler hooks used by ia64 (curr_task, set_curr_task) are layer
violations.  Unfortunately MCA/INIT start off as massive layer
violations (can occur at _any_ time) and they build from there.

At least ia64 makes an attempt at recovering from hardware errors, but
it is a difficult problem because of the asynchronous nature of these
errors.  When processing an unmaskable interrupt we sometimes need
special code to cope with our inability to take any locks.

---

How is ia64 MCA/INIT different from x86 NMI?

* x86 NMI typically gets delivered to one cpu.  MCA/INIT gets sent to
  all cpus.

* x86 NMI cannot be nested.  MCA/INIT can be nested, to a depth of 2
  per cpu.

* x86 has a separate struct task which points to one of multiple kernel
  stacks.  ia64 has the struct task embedded in the single kernel
  stack, so switching stack means switching task.

* x86 does not call the BIOS so the NMI handler does not have to worry
  about any registers having changed.  MCA/INIT can occur while the cpu
  is in PAL in physical mode, with undefined registers and an undefined
  kernel stack.

* i386 backtrace is not very sensitive to whether a process is running
  or not.  ia64 unwind is very, very sensitive to whether a process is
  running or not.

---

What happens when MCA/INIT is delivered what a cpu is running user
space code?

The user mode registers are stored in the RSE area of the MCA/INIT on
entry to the OS and are restored from there on return to SAL, so user
mode registers are preserved across a recoverable MCA/INIT.  Since the
OS has no idea what unwind data is available for the user space stack,
MCA/INIT never tries to backtrace user space.  Which means that the OS
does not bother making the user space process look like a blocked task,
i.e. the OS does not copy pt_regs and switch_stack to the user space
stack.  Also the OS has no idea how big the user space RSE and memory
stacks are, which makes it too risky to copy the saved state to a user
mode stack.

---

How do we get a backtrace on the tasks that were running when MCA/INIT
was delivered?

mca.c:::ia64_mca_modify_original_stack().  That identifies and
verifies the original kernel stack, copies the dirty registers from
the MCA/INIT stack's RSE to the original stack's RSE, copies the
skeleton struct pt_regs and switch_stack to the original stack, fills
in the skeleton structures from the PAL minstate area and updates the
original stack's thread.ksp.  That makes the original stack look
exactly like any other blocked task, i.e. it now appears to be
sleeping.  To get a backtrace, just start with thread.ksp for the
original task and unwind like any other sleeping task.

---

How do we identify the tasks that were running when MCA/INIT was
delivered?

If the previous task has been verified and converted to a blocked
state, then sos->prev_task on the MCA/INIT stack is updated to point to
the previous task.  You can look at that field in dumps or debuggers.
To help distinguish between the handler and the original tasks,
handlers have _TIF_MCA_INIT set in thread_info.flags.

The sos data is always in the MCA/INIT handler stack, at offset
MCA_SOS_OFFSET.  You can get that value from mca_asm.h or calculate it
as KERNEL_STACK_SIZE - sizeof(struct pt_regs) - sizeof(struct
ia64_sal_os_state), with 16 byte alignment for all structures.

Also the comm field of the MCA/INIT task is modified to include the pid
of the original task, for humans to use.  For example, a comm field of
'MCA 12159' means that pid 12159 was running when the MCA was
delivered.


code:
==============
Serial Devices
==============

Serial Device Naming
====================

    As of 2.6.10, serial devices on ia64 are named based on the
    order of ACPI and PCI enumeration.  The first device in the
    ACPI namespace (if any) becomes /dev/ttyS0, the second becomes
    /dev/ttyS1, etc., and PCI devices are named sequentially
    starting after the ACPI devices.

    Prior to 2.6.10, there were confusing exceptions to this:

	- Firmware on some machines (mostly from HP) provides an HCDP
	  table[1] that tells the kernel about devices that can be used
	  as a serial console.  If the user specified "console=ttyS0"
	  or the EFI ConOut path contained only UART devices, the
	  kernel registered the device described by the HCDP as
	  /dev/ttyS0.

	- If there was no HCDP, we assumed there were UARTs at the
	  legacy COM port addresses (I/O ports 0x3f8 and 0x2f8), so
	  the kernel registered those as /dev/ttyS0 and /dev/ttyS1.

    Any additional ACPI or PCI devices were registered sequentially
    after /dev/ttyS0 as they were discovered.

    With an HCDP, device names changed depending on EFI configuration
    and "console=" arguments.  Without an HCDP, device names didn't
    change, but we registered devices that might not really exist.

    For example, an HP rx1600 with a single built-in serial port
    (described in the ACPI namespace) plus an MP[2] (a PCI device) has
    these ports:

      ==========  ==========     ============    ============   =======
      Type        MMIO           pre-2.6.10      pre-2.6.10     2.6.10+
		  address
				 (EFI console    (EFI console
                                 on builtin)     on MP port)
      ==========  ==========     ============    ============   =======
      builtin     0xff5e0000        ttyS0           ttyS1         ttyS0
      MP UPS      0xf8031000        ttyS1           ttyS2         ttyS1
      MP Console  0xf8030000        ttyS2           ttyS0         ttyS2
      MP 2        0xf8030010        ttyS3           ttyS3         ttyS3
      MP 3        0xf8030038        ttyS4           ttyS4         ttyS4
      ==========  ==========     ============    ============   =======

Console Selection
=================

    EFI knows what your console devices are, but it doesn't tell the
    kernel quite enough to actually locate them.  The DIG64 HCDP
    table[1] does tell the kernel where potential serial console
    devices are, but not all firmware supplies it.  Also, EFI supports
    multiple simultaneous consoles and doesn't tell the kernel which
    should be the "primary" one.

    So how do you tell Linux which console device to use?

	- If your firmware supplies the HCDP, it is simplest to
	  configure EFI with a single device (either a UART or a VGA
	  card) as the console.  Then you don't need to tell Linux
	  anything; the kernel will automatically use the EFI console.

	  (This works only in 2.6.6 or later; prior to that you had
	  to specify "console=ttyS0" to get a serial console.)

	- Without an HCDP, Linux defaults to a VGA console unless you
	  specify a "console=" argument.

    NOTE: Don't assume that a serial console device will be /dev/ttyS0.
    It might be ttyS1, ttyS2, etc.  Make sure you have the appropriate
    entries in /etc/inittab (for getty) and /etc/securetty (to allow
    root login).

Early Serial Console
====================

    The kernel can't start using a serial console until it knows where
    the device lives.  Normally this happens when the driver enumerates
    all the serial devices, which can happen a minute or more after the
    kernel starts booting.

    2.6.10 and later kernels have an "early uart" driver that works
    very early in the boot process.  The kernel will automatically use
    this if the user supplies an argument like "console=uart,io,0x3f8",
    or if the EFI console path contains only a UART device and the
    firmware supplies an HCDP.

Troubleshooting Serial Console Problems
=======================================

    No kernel output after elilo prints "Uncompressing Linux... done":

	- You specified "console=ttyS0" but Linux changed the device
	  to which ttyS0 refers.  Configure exactly one EFI console
	  device[3] and remove the "console=" option.

	- The EFI console path contains both a VGA device and a UART.
	  EFI and elilo use both, but Linux defaults to VGA.  Remove
	  the VGA device from the EFI console path[3].

	- Multiple UARTs selected as EFI console devices.  EFI and
	  elilo use all selected devices, but Linux uses only one.
	  Make sure only one UART is selected in the EFI console
	  path[3].

	- You're connected to an HP MP port[2] but have a non-MP UART
	  selected as EFI console device.  EFI uses the MP as a
	  console device even when it isn't explicitly selected.
	  Either move the console cable to the non-MP UART, or change
	  the EFI console path[3] to the MP UART.

    Long pause (60+ seconds) between "Uncompressing Linux... done" and
    start of kernel output:

	- No early console because you used "console=ttyS<n>".  Remove
	  the "console=" option if your firmware supplies an HCDP.

	- If you don't have an HCDP, the kernel doesn't know where
	  your console lives until the driver discovers serial
	  devices.  Use "console=uart,io,0x3f8" (or appropriate
	  address for your machine).

    Kernel and init script output works fine, but no "login:" prompt:

	- Add getty entry to /etc/inittab for console tty.  Look for
	  the "Adding console on ttyS<n>" message that tells you which
	  device is the console.

    "login:" prompt, but can't login as root:

	- Add entry to /etc/securetty for console tty.

    No ACPI serial devices found in 2.6.17 or later:

	- Turn on CONFIG_PNP and CONFIG_PNPACPI.  Prior to 2.6.17, ACPI
	  serial devices were discovered by 8250_acpi.  In 2.6.17,
	  8250_acpi was replaced by the combination of 8250_pnp and
	  CONFIG_PNPACPI.

[1]
    http://www.dig64.org/specifications/agreement
    The table was originally defined as the "HCDP" for "Headless
    Console/Debug Port."  The current version is the "PCDP" for
    "Primary Console and Debug Port Devices."

[2]
    The HP MP (management processor) is a PCI device that provides
    several UARTs.  One of the UARTs is often used as a console; the
    EFI Boot Manager identifies it as "Acpi(HWP0002,700)/Pci(...)/Uart".
    The external connection is usually a 25-pin connector, and a
    special dongle converts that to three 9-pin connectors, one of
    which is labelled "Console."

[3]
    EFI console devices are configured using the EFI Boot Manager
    "Boot option maintenance" menu.  You may have to interrupt the
    boot sequence to use this menu, and you will have to reset the
    box after changing console configuration.


code:
.. SPDX-License-Identifier: GPL-2.0

==============================
BNO055 driver
==============================

1. Overview
===========

This driver supports Bosch BNO055 IMUs (on both serial and I2C busses).

Accelerometer, magnetometer and gyroscope measures are always provided.
When "fusion_enable" sysfs attribute is set to 1, orientation (both Euler
angles and quaternion), linear velocity and gravity vector are also
provided, but some sensor settings (e.g. low pass filtering and range)
became locked (the IMU firmware controls them).

This driver supports also IIO buffers.

2. Calibration
==============

The IMU continuously performs an autocalibration procedure if (and only if)
operating in fusion mode. The magnetometer autocalibration can however be
disabled writing 0 in the sysfs in_magn_calibration_fast_enable attribute.

The driver provides access to autocalibration flags (i.e. you can known if
the IMU has successfully autocalibrated) and to the calibration data blob.

The user can save this blob in a firmware file (i.e. in /lib/firmware) that
the driver looks for at probe time. If found, then the IMU is initialized
with this calibration data. This saves the user from performing the
calibration procedure every time (which consist of moving the IMU in
various way).

The driver looks for calibration data file using two different names: first
a file whose name is suffixed with the IMU unique ID (exposed in sysfs as
serial_number) is searched for; this is useful when there is more than one
IMU instance. If this file is not found, then a "generic" calibration file
is searched for (which can be used when only one IMU is present, without
struggling with fancy names, that change on each device).

Valid calibration file names would be e.g.
 bno055-caldata-0e7c26a33541515120204a35342b04ff.dat
 bno055-caldata.dat

In non-fusion mode the IIO 'offset' attributes provide access to the
offsets from calibration data (if any), so that the user can apply them to
the accel, angvel and magn IIO attributes. In fusion mode they are not
needed (the IMU firmware internally applies those corrections) and they
read as zero.


code:
===============================
Industrial IIO configfs support
===============================

1. Overview
===========

Configfs is a filesystem-based manager of kernel objects. IIO uses some
objects that could be easily configured using configfs (e.g.: devices,
triggers).

See Documentation/filesystems/configfs.rst for more information
about how configfs works.

2. Usage
========

In order to use configfs support in IIO we need to select it at compile
time via CONFIG_IIO_CONFIGFS config option.

Then, mount the configfs filesystem (usually under /config directory)::

  $ mkdir /config
  $ mount -t configfs none /config

At this point, all default IIO groups will be created and can be accessed
under /config/iio. Next chapters will describe available IIO configuration
objects.

3. Software triggers
====================

One of the IIO default configfs groups is the "triggers" group. It is
automagically accessible when the configfs is mounted and can be found
under /config/iio/triggers.

IIO software triggers implementation offers support for creating multiple
trigger types. A new trigger type is usually implemented as a separate
kernel module following the interface in include/linux/iio/sw_trigger.h::

  /*
   * drivers/iio/trigger/iio-trig-sample.c
   * sample kernel module implementing a new trigger type
   */
  #include <linux/iio/sw_trigger.h>

  static struct iio_sw_trigger *iio_trig_sample_probe(const char *name)
  {
	/*
	 * This allocates and registers an IIO trigger plus other
	 * trigger type specific initialization.
	 */
  }

  static int iio_trig_sample_remove(struct iio_sw_trigger *swt)
  {
	/*
	 * This undoes the actions in iio_trig_sample_probe
	 */
  }

  static const struct iio_sw_trigger_ops iio_trig_sample_ops = {
	.probe		= iio_trig_sample_probe,
	.remove		= iio_trig_sample_remove,
  };

  static struct iio_sw_trigger_type iio_trig_sample = {
	.name = "trig-sample",
	.owner = THIS_MODULE,
	.ops = &iio_trig_sample_ops,
  };

  module_iio_sw_trigger_driver(iio_trig_sample);

Each trigger type has its own directory under /config/iio/triggers. Loading
iio-trig-sample module will create 'trig-sample' trigger type directory
/config/iio/triggers/trig-sample.

We support the following interrupt sources (trigger types):

	* hrtimer, uses high resolution timers as interrupt source

3.1 Hrtimer triggers creation and destruction
---------------------------------------------

Loading iio-trig-hrtimer module will register hrtimer trigger types allowing
users to create hrtimer triggers under /config/iio/triggers/hrtimer.

e.g::

  $ mkdir /config/iio/triggers/hrtimer/instance1
  $ rmdir /config/iio/triggers/hrtimer/instance1

Each trigger can have one or more attributes specific to the trigger type.

3.2 "hrtimer" trigger types attributes
--------------------------------------

"hrtimer" trigger type doesn't have any configurable attribute from /config dir.
It does introduce the sampling_frequency attribute to trigger directory.
That attribute sets the polling frequency in Hz, with mHz precision.


code:
.. SPDX-License-Identifier: GPL-2.0

==============
Industrial I/O
==============

.. toctree::
   :maxdepth: 1

   iio_configfs

   ep93xx_adc

   bno055


code:
This is the full-colour version of the currently unofficial Linux logo
("currently unofficial" just means that there has been no paperwork and
that I have not really announced it yet).  It was created by Larry Ewing,
and is freely usable as long as you acknowledge Larry as the original
artist.

Note that there are black-and-white versions of this available that
scale down to smaller sizes and are better for letterheads or whatever
you want to use it for: for the full range of logos take a look at
Larry's web-page:

	https://www.isc.tamu.edu/~lewing/linux/

The SVG version was re-illustrated in vector by Garrett LeSage and
refined and cleaned up by IFo Hancroft. It is also freely usable
as long as you acknowledge Larry, Garrett and IFo as above.

There are also black-and-white and inverted vector versions at
Garrett's repository:

	https://github.com/garrett/Tux

path: Documentation/images/COPYING-logo


code:
.. SPDX-License-Identifier: GPL-2.0

.. _linux_doc:

The Linux Kernel documentation
==============================

This is the top level of the kernel's documentation tree.  Kernel
documentation, like the kernel itself, is very much a work in progress;
that is especially true as we work to integrate our many scattered
documents into a coherent whole.  Please note that improvements to the
documentation are welcome; join the linux-doc list at vger.kernel.org if
you want to help out.

Working with the development community
--------------------------------------

The essential guides for interacting with the kernel's development
community and getting your work upstream.

.. toctree::
   :maxdepth: 1

   process/development-process
   process/submitting-patches
   Code of conduct <process/code-of-conduct>
   maintainer/index
   All development-process docs <process/index>

Internal API manuals
--------------------

Manuals for use by developers working to interface with the rest of the
kernel.

.. toctree::
   :maxdepth: 1

   core-api/index
   driver-api/index
   subsystem-apis
   Locking in the kernel <locking/index>

Development tools and processes
-------------------------------

Various other manuals with useful information for all kernel developers.

.. toctree::
   :maxdepth: 1

   process/license-rules
   doc-guide/index
   dev-tools/index
   dev-tools/testing-overview
   kernel-hacking/index
   trace/index
   fault-injection/index
   livepatch/index
   rust/index

User-oriented documentation
---------------------------

The following manuals are written for *users* of the kernel — those who are
trying to get it to work optimally on a given system and application
developers seeking information on the kernel's user-space APIs.

.. toctree::
   :maxdepth: 1

   admin-guide/index
   The kernel build system <kbuild/index>
   admin-guide/reporting-issues.rst
   User-space tools <tools/index>
   userspace-api/index

See also: the `Linux man pages <https://www.kernel.org/doc/man-pages/>`_,
which are kept separately from the kernel's own documentation.

Firmware-related documentation
------------------------------
The following holds information on the kernel's expectations regarding the
platform firmwares.

.. toctree::
   :maxdepth: 1

   firmware-guide/index
   devicetree/index

Architecture-specific documentation
-----------------------------------

.. toctree::
   :maxdepth: 2

   arch

Other documentation
-------------------

There are several unsorted documents that don't seem to fit on other parts
of the documentation body, or may require some adjustments and/or conversion
to ReStructured Text format, or are simply too old.

.. toctree::
   :maxdepth: 1

   staging/index

Translations
------------

.. toctree::
   :maxdepth: 2

   translations/index

Indices and tables
==================

* :ref:`genindex`


code:
===========================
InfiniBand Midlayer Locking
===========================

  This guide is an attempt to make explicit the locking assumptions
  made by the InfiniBand midlayer.  It describes the requirements on
  both low-level drivers that sit below the midlayer and upper level
  protocols that use the midlayer.

Sleeping and interrupt context
==============================

  With the following exceptions, a low-level driver implementation of
  all of the methods in struct ib_device may sleep.  The exceptions
  are any methods from the list:

    - create_ah
    - modify_ah
    - query_ah
    - destroy_ah
    - post_send
    - post_recv
    - poll_cq
    - req_notify_cq

  which may not sleep and must be callable from any context.

  The corresponding functions exported to upper level protocol
  consumers:

    - rdma_create_ah
    - rdma_modify_ah
    - rdma_query_ah
    - rdma_destroy_ah
    - ib_post_send
    - ib_post_recv
    - ib_req_notify_cq

  are therefore safe to call from any context.

  In addition, the function

    - ib_dispatch_event

  used by low-level drivers to dispatch asynchronous events through
  the midlayer is also safe to call from any context.

Reentrancy
----------

  All of the methods in struct ib_device exported by a low-level
  driver must be fully reentrant.  The low-level driver is required to
  perform all synchronization necessary to maintain consistency, even
  if multiple function calls using the same object are run
  simultaneously.

  The IB midlayer does not perform any serialization of function calls.

  Because low-level drivers are reentrant, upper level protocol
  consumers are not required to perform any serialization.  However,
  some serialization may be required to get sensible results.  For
  example, a consumer may safely call ib_poll_cq() on multiple CPUs
  simultaneously.  However, the ordering of the work completion
  information between different calls of ib_poll_cq() is not defined.

Callbacks
---------

  A low-level driver must not perform a callback directly from the
  same callchain as an ib_device method call.  For example, it is not
  allowed for a low-level driver to call a consumer's completion event
  handler directly from its post_send method.  Instead, the low-level
  driver should defer this callback by, for example, scheduling a
  tasklet to perform the callback.

  The low-level driver is responsible for ensuring that multiple
  completion event handlers for the same CQ are not called
  simultaneously.  The driver must guarantee that only one CQ event
  handler for a given CQ is running at a time.  In other words, the
  following situation is not allowed::

          CPU1                                    CPU2

    low-level driver ->
      consumer CQ event callback:
        /* ... */
        ib_req_notify_cq(cq, ...);
                                          low-level driver ->
        /* ... */                           consumer CQ event callback:
                                              /* ... */
        return from CQ event handler

  The context in which completion event and asynchronous event
  callbacks run is not defined.  Depending on the low-level driver, it
  may be process context, softirq context, or interrupt context.
  Upper level protocol consumers may not sleep in a callback.

Hot-plug
--------

  A low-level driver announces that a device is ready for use by
  consumers when it calls ib_register_device(), all initialization
  must be complete before this call.  The device must remain usable
  until the driver's call to ib_unregister_device() has returned.

  A low-level driver must call ib_register_device() and
  ib_unregister_device() from process context.  It must not hold any
  semaphores that could cause deadlock if a consumer calls back into
  the driver across these calls.

  An upper level protocol consumer may begin using an IB device as
  soon as the add method of its struct ib_client is called for that
  device.  A consumer must finish all cleanup and free all resources
  relating to a device before returning from the remove method.

  A consumer is permitted to sleep in its add and remove methods.


code:
.. SPDX-License-Identifier: GPL-2.0

==========
InfiniBand
==========

.. toctree::
   :maxdepth: 1

   core_locking
   ipoib
   opa_vnic
   sysfs
   tag_matching
   user_mad
   user_verbs

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
==================
IP over InfiniBand
==================

  The ib_ipoib driver is an implementation of the IP over InfiniBand
  protocol as specified by RFC 4391 and 4392, issued by the IETF ipoib
  working group.  It is a "native" implementation in the sense of
  setting the interface type to ARPHRD_INFINIBAND and the hardware
  address length to 20 (earlier proprietary implementations
  masqueraded to the kernel as ethernet interfaces).

Partitions and P_Keys
=====================

  When the IPoIB driver is loaded, it creates one interface for each
  port using the P_Key at index 0.  To create an interface with a
  different P_Key, write the desired P_Key into the main interface's
  /sys/class/net/<intf name>/create_child file.  For example::

    echo 0x8001 > /sys/class/net/ib0/create_child

  This will create an interface named ib0.8001 with P_Key 0x8001.  To
  remove a subinterface, use the "delete_child" file::

    echo 0x8001 > /sys/class/net/ib0/delete_child

  The P_Key for any interface is given by the "pkey" file, and the
  main interface for a subinterface is in "parent."

  Child interface create/delete can also be done using IPoIB's
  rtnl_link_ops, where children created using either way behave the same.

Datagram vs Connected modes
===========================

  The IPoIB driver supports two modes of operation: datagram and
  connected.  The mode is set and read through an interface's
  /sys/class/net/<intf name>/mode file.

  In datagram mode, the IB UD (Unreliable Datagram) transport is used
  and so the interface MTU has is equal to the IB L2 MTU minus the
  IPoIB encapsulation header (4 bytes).  For example, in a typical IB
  fabric with a 2K MTU, the IPoIB MTU will be 2048 - 4 = 2044 bytes.

  In connected mode, the IB RC (Reliable Connected) transport is used.
  Connected mode takes advantage of the connected nature of the IB
  transport and allows an MTU up to the maximal IP packet size of 64K,
  which reduces the number of IP packets needed for handling large UDP
  datagrams, TCP segments, etc and increases the performance for large
  messages.

  In connected mode, the interface's UD QP is still used for multicast
  and communication with peers that don't support connected mode. In
  this case, RX emulation of ICMP PMTU packets is used to cause the
  networking stack to use the smaller UD MTU for these neighbours.

Stateless offloads
==================

  If the IB HW supports IPoIB stateless offloads, IPoIB advertises
  TCP/IP checksum and/or Large Send (LSO) offloading capability to the
  network stack.

  Large Receive (LRO) offloading is also implemented and may be turned
  on/off using ethtool calls.  Currently LRO is supported only for
  checksum offload capable devices.

  Stateless offloads are supported only in datagram mode.

Interrupt moderation
====================

  If the underlying IB device supports CQ event moderation, one can
  use ethtool to set interrupt mitigation parameters and thus reduce
  the overhead incurred by handling interrupts.  The main code path of
  IPoIB doesn't use events for TX completion signaling so only RX
  moderation is supported.

Debugging Information
=====================

  By compiling the IPoIB driver with CONFIG_INFINIBAND_IPOIB_DEBUG set
  to 'y', tracing messages are compiled into the driver.  They are
  turned on by setting the module parameters debug_level and
  mcast_debug_level to 1.  These parameters can be controlled at
  runtime through files in /sys/module/ib_ipoib/.

  CONFIG_INFINIBAND_IPOIB_DEBUG also enables files in the debugfs
  virtual filesystem.  By mounting this filesystem, for example with::

    mount -t debugfs none /sys/kernel/debug

  it is possible to get statistics about multicast groups from the
  files /sys/kernel/debug/ipoib/ib0_mcg and so on.

  The performance impact of this option is negligible, so it
  is safe to enable this option with debug_level set to 0 for normal
  operation.

  CONFIG_INFINIBAND_IPOIB_DEBUG_DATA enables even more debug output in
  the data path when data_debug_level is set to 1.  However, even with
  the output disabled, enabling this configuration option will affect
  performance, because it adds tests to the fast path.

References
==========

  Transmission of IP over InfiniBand (IPoIB) (RFC 4391)
    http://ietf.org/rfc/rfc4391.txt

  IP over InfiniBand (IPoIB) Architecture (RFC 4392)
    http://ietf.org/rfc/rfc4392.txt

  IP over InfiniBand: Connected Mode (RFC 4755)
    http://ietf.org/rfc/rfc4755.txt


code:
=================================================================
Intel Omni-Path (OPA) Virtual Network Interface Controller (VNIC)
=================================================================

Intel Omni-Path (OPA) Virtual Network Interface Controller (VNIC) feature
supports Ethernet functionality over Omni-Path fabric by encapsulating
the Ethernet packets between HFI nodes.

Architecture
=============
The patterns of exchanges of Omni-Path encapsulated Ethernet packets
involves one or more virtual Ethernet switches overlaid on the Omni-Path
fabric topology. A subset of HFI nodes on the Omni-Path fabric are
permitted to exchange encapsulated Ethernet packets across a particular
virtual Ethernet switch. The virtual Ethernet switches are logical
abstractions achieved by configuring the HFI nodes on the fabric for
header generation and processing. In the simplest configuration all HFI
nodes across the fabric exchange encapsulated Ethernet packets over a
single virtual Ethernet switch. A virtual Ethernet switch, is effectively
an independent Ethernet network. The configuration is performed by an
Ethernet Manager (EM) which is part of the trusted Fabric Manager (FM)
application. HFI nodes can have multiple VNICs each connected to a
different virtual Ethernet switch. The below diagram presents a case
of two virtual Ethernet switches with two HFI nodes::

                               +-------------------+
                               |      Subnet/      |
                               |     Ethernet      |
                               |      Manager      |
                               +-------------------+
                                  /          /
                                /           /
                              /            /
                            /             /
  +-----------------------------+  +------------------------------+
  |  Virtual Ethernet Switch    |  |  Virtual Ethernet Switch     |
  |  +---------+    +---------+ |  | +---------+    +---------+   |
  |  | VPORT   |    |  VPORT  | |  | |  VPORT  |    |  VPORT  |   |
  +--+---------+----+---------+-+  +-+---------+----+---------+---+
           |                 \        /                 |
           |                   \    /                   |
           |                     \/                     |
           |                    /  \                    |
           |                  /      \                  |
       +-----------+------------+  +-----------+------------+
       |   VNIC    |    VNIC    |  |    VNIC   |    VNIC    |
       +-----------+------------+  +-----------+------------+
       |          HFI           |  |          HFI           |
       +------------------------+  +------------------------+

The Omni-Path encapsulated Ethernet packet format is as described below.

==================== ================================
Bits                 Field
==================== ================================
Quad Word 0:
0-19                 SLID (lower 20 bits)
20-30                Length (in Quad Words)
31                   BECN bit
32-51                DLID (lower 20 bits)
52-56                SC (Service Class)
57-59                RC (Routing Control)
60                   FECN bit
61-62                L2 (=10, 16B format)
63                   LT (=1, Link Transfer Head Flit)

Quad Word 1:
0-7                  L4 type (=0x78 ETHERNET)
8-11                 SLID[23:20]
12-15                DLID[23:20]
16-31                PKEY
32-47                Entropy
48-63                Reserved

Quad Word 2:
0-15                 Reserved
16-31                L4 header
32-63                Ethernet Packet

Quad Words 3 to N-1:
0-63                 Ethernet packet (pad extended)

Quad Word N (last):
0-23                 Ethernet packet (pad extended)
24-55                ICRC
56-61                Tail
62-63                LT (=01, Link Transfer Tail Flit)
==================== ================================

Ethernet packet is padded on the transmit side to ensure that the VNIC OPA
packet is quad word aligned. The 'Tail' field contains the number of bytes
padded. On the receive side the 'Tail' field is read and the padding is
removed (along with ICRC, Tail and OPA header) before passing packet up
the network stack.

The L4 header field contains the virtual Ethernet switch id the VNIC port
belongs to. On the receive side, this field is used to de-multiplex the
received VNIC packets to different VNIC ports.

Driver Design
==============
Intel OPA VNIC software design is presented in the below diagram.
OPA VNIC functionality has a HW dependent component and a HW
independent component.

The support has been added for IB device to allocate and free the RDMA
netdev devices. The RDMA netdev supports interfacing with the network
stack thus creating standard network interfaces. OPA_VNIC is an RDMA
netdev device type.

The HW dependent VNIC functionality is part of the HFI1 driver. It
implements the verbs to allocate and free the OPA_VNIC RDMA netdev.
It involves HW resource allocation/management for VNIC functionality.
It interfaces with the network stack and implements the required
net_device_ops functions. It expects Omni-Path encapsulated Ethernet
packets in the transmit path and provides HW access to them. It strips
the Omni-Path header from the received packets before passing them up
the network stack. It also implements the RDMA netdev control operations.

The OPA VNIC module implements the HW independent VNIC functionality.
It consists of two parts. The VNIC Ethernet Management Agent (VEMA)
registers itself with IB core as an IB client and interfaces with the
IB MAD stack. It exchanges the management information with the Ethernet
Manager (EM) and the VNIC netdev. The VNIC netdev part allocates and frees
the OPA_VNIC RDMA netdev devices. It overrides the net_device_ops functions
set by HW dependent VNIC driver where required to accommodate any control
operation. It also handles the encapsulation of Ethernet packets with an
Omni-Path header in the transmit path. For each VNIC interface, the
information required for encapsulation is configured by the EM via VEMA MAD
interface. It also passes any control information to the HW dependent driver
by invoking the RDMA netdev control operations::

        +-------------------+ +----------------------+
        |                   | |       Linux          |
        |     IB MAD        | |      Network         |
        |                   | |       Stack          |
        +-------------------+ +----------------------+
                 |               |          |
                 |               |          |
        +----------------------------+      |
        |                            |      |
        |      OPA VNIC Module       |      |
        |  (OPA VNIC RDMA Netdev     |      |
        |     & EMA functions)       |      |
        |                            |      |
        +----------------------------+      |
                    |                       |
                    |                       |
           +------------------+             |
           |     IB core      |             |
           +------------------+             |
                    |                       |
                    |                       |
        +--------------------------------------------+
        |                                            |
        |      HFI1 Driver with VNIC support         |
        |                                            |
        +--------------------------------------------+


code:
===========
Sysfs files
===========

The sysfs interface has moved to
Documentation/ABI/stable/sysfs-class-infiniband.


code:
==================
Tag matching logic
==================

The MPI standard defines a set of rules, known as tag-matching, for matching
source send operations to destination receives.  The following parameters must
match the following source and destination parameters:

*	Communicator
*	User tag - wild card may be specified by the receiver
*	Source rank – wild car may be specified by the receiver
*	Destination rank – wild

The ordering rules require that when more than one pair of send and receive
message envelopes may match, the pair that includes the earliest posted-send
and the earliest posted-receive is the pair that must be used to satisfy the
matching operation. However, this doesn’t imply that tags are consumed in
the order they are created, e.g., a later generated tag may be consumed, if
earlier tags can’t be used to satisfy the matching rules.

When a message is sent from the sender to the receiver, the communication
library may attempt to process the operation either after or before the
corresponding matching receive is posted.  If a matching receive is posted,
this is an expected message, otherwise it is called an unexpected message.
Implementations frequently use different matching schemes for these two
different matching instances.

To keep MPI library memory footprint down, MPI implementations typically use
two different protocols for this purpose:

1.	The Eager protocol- the complete message is sent when the send is
processed by the sender. A completion send is received in the send_cq
notifying that the buffer can be reused.

2.	The Rendezvous Protocol - the sender sends the tag-matching header,
and perhaps a portion of data when first notifying the receiver. When the
corresponding buffer is posted, the responder will use the information from
the header to initiate an RDMA READ operation directly to the matching buffer.
A fin message needs to be received in order for the buffer to be reused.

Tag matching implementation
===========================

There are two types of matching objects used, the posted receive list and the
unexpected message list. The application posts receive buffers through calls
to the MPI receive routines in the posted receive list and posts send messages
using the MPI send routines. The head of the posted receive list may be
maintained by the hardware, with the software expected to shadow this list.

When send is initiated and arrives at the receive side, if there is no
pre-posted receive for this arriving message, it is passed to the software and
placed in the unexpected message list. Otherwise the match is processed,
including rendezvous processing, if appropriate, delivering the data to the
specified receive buffer. This allows overlapping receive-side MPI tag
matching with computation.

When a receive-message is posted, the communication library will first check
the software unexpected message list for a matching receive. If a match is
found, data is delivered to the user buffer, using a software controlled
protocol. The UCX implementation uses either an eager or rendezvous protocol,
depending on data size. If no match is found, the entire pre-posted receive
list is maintained by the hardware, and there is space to add one more
pre-posted receive to this list, this receive is passed to the hardware.
Software is expected to shadow this list, to help with processing MPI cancel
operations. In addition, because hardware and software are not expected to be
tightly synchronized with respect to the tag-matching operation, this shadow
list is used to detect the case that a pre-posted receive is passed to the
hardware, as the matching unexpected message is being passed from the hardware
to the software.


code:
====================
Userspace MAD access
====================

Device files
============

  Each port of each InfiniBand device has a "umad" device and an
  "issm" device attached.  For example, a two-port HCA will have two
  umad devices and two issm devices, while a switch will have one
  device of each type (for switch port 0).

Creating MAD agents
===================

  A MAD agent can be created by filling in a struct ib_user_mad_reg_req
  and then calling the IB_USER_MAD_REGISTER_AGENT ioctl on a file
  descriptor for the appropriate device file.  If the registration
  request succeeds, a 32-bit id will be returned in the structure.
  For example::

	struct ib_user_mad_reg_req req = { /* ... */ };
	ret = ioctl(fd, IB_USER_MAD_REGISTER_AGENT, (char *) &req);
        if (!ret)
		my_agent = req.id;
	else
		perror("agent register");

  Agents can be unregistered with the IB_USER_MAD_UNREGISTER_AGENT
  ioctl.  Also, all agents registered through a file descriptor will
  be unregistered when the descriptor is closed.

  2014
       a new registration ioctl is now provided which allows additional
       fields to be provided during registration.
       Users of this registration call are implicitly setting the use of
       pkey_index (see below).

Receiving MADs
==============

  MADs are received using read().  The receive side now supports
  RMPP. The buffer passed to read() must be at least one
  struct ib_user_mad + 256 bytes. For example:

  If the buffer passed is not large enough to hold the received
  MAD (RMPP), the errno is set to ENOSPC and the length of the
  buffer needed is set in mad.length.

  Example for normal MAD (non RMPP) reads::

	struct ib_user_mad *mad;
	mad = malloc(sizeof *mad + 256);
	ret = read(fd, mad, sizeof *mad + 256);
	if (ret != sizeof mad + 256) {
		perror("read");
		free(mad);
	}

  Example for RMPP reads::

	struct ib_user_mad *mad;
	mad = malloc(sizeof *mad + 256);
	ret = read(fd, mad, sizeof *mad + 256);
	if (ret == -ENOSPC)) {
		length = mad.length;
		free(mad);
		mad = malloc(sizeof *mad + length);
		ret = read(fd, mad, sizeof *mad + length);
	}
	if (ret < 0) {
		perror("read");
		free(mad);
	}

  In addition to the actual MAD contents, the other struct ib_user_mad
  fields will be filled in with information on the received MAD.  For
  example, the remote LID will be in mad.lid.

  If a send times out, a receive will be generated with mad.status set
  to ETIMEDOUT.  Otherwise when a MAD has been successfully received,
  mad.status will be 0.

  poll()/select() may be used to wait until a MAD can be read.

Sending MADs
============

  MADs are sent using write().  The agent ID for sending should be
  filled into the id field of the MAD, the destination LID should be
  filled into the lid field, and so on.  The send side does support
  RMPP so arbitrary length MAD can be sent. For example::

	struct ib_user_mad *mad;

	mad = malloc(sizeof *mad + mad_length);

	/* fill in mad->data */

	mad->hdr.id  = my_agent;	/* req.id from agent registration */
	mad->hdr.lid = my_dest;		/* in network byte order... */
	/* etc. */

	ret = write(fd, &mad, sizeof *mad + mad_length);
	if (ret != sizeof *mad + mad_length)
		perror("write");

Transaction IDs
===============

  Users of the umad devices can use the lower 32 bits of the
  transaction ID field (that is, the least significant half of the
  field in network byte order) in MADs being sent to match
  request/response pairs.  The upper 32 bits are reserved for use by
  the kernel and will be overwritten before a MAD is sent.

P_Key Index Handling
====================

  The old ib_umad interface did not allow setting the P_Key index for
  MADs that are sent and did not provide a way for obtaining the P_Key
  index of received MADs.  A new layout for struct ib_user_mad_hdr
  with a pkey_index member has been defined; however, to preserve binary
  compatibility with older applications, this new layout will not be used
  unless one of IB_USER_MAD_ENABLE_PKEY or IB_USER_MAD_REGISTER_AGENT2 ioctl's
  are called before a file descriptor is used for anything else.

  In September 2008, the IB_USER_MAD_ABI_VERSION will be incremented
  to 6, the new layout of struct ib_user_mad_hdr will be used by
  default, and the IB_USER_MAD_ENABLE_PKEY ioctl will be removed.

Setting IsSM Capability Bit
===========================

  To set the IsSM capability bit for a port, simply open the
  corresponding issm device file.  If the IsSM bit is already set,
  then the open call will block until the bit is cleared (or return
  immediately with errno set to EAGAIN if the O_NONBLOCK flag is
  passed to open()).  The IsSM bit will be cleared when the issm file
  is closed.  No read, write or other operations can be performed on
  the issm file.

/dev files
==========

  To create the appropriate character device files automatically with
  udev, a rule like::

    KERNEL=="umad*", NAME="infiniband/%k"
    KERNEL=="issm*", NAME="infiniband/%k"

  can be used.  This will create device nodes named::

    /dev/infiniband/umad0
    /dev/infiniband/issm0

  for the first port, and so on.  The InfiniBand device and port
  associated with these devices can be determined from the files::

    /sys/class/infiniband_mad/umad0/ibdev
    /sys/class/infiniband_mad/umad0/port

  and::

    /sys/class/infiniband_mad/issm0/ibdev
    /sys/class/infiniband_mad/issm0/port


code:
======================
Userspace verbs access
======================

  The ib_uverbs module, built by enabling CONFIG_INFINIBAND_USER_VERBS,
  enables direct userspace access to IB hardware via "verbs," as
  described in chapter 11 of the InfiniBand Architecture Specification.

  To use the verbs, the libibverbs library, available from
  https://github.com/linux-rdma/rdma-core, is required. libibverbs contains a
  device-independent API for using the ib_uverbs interface.
  libibverbs also requires appropriate device-dependent kernel and
  userspace driver for your InfiniBand hardware.  For example, to use
  a Mellanox HCA, you will need the ib_mthca kernel module and the
  libmthca userspace driver be installed.

User-kernel communication
=========================

  Userspace communicates with the kernel for slow path, resource
  management operations via the /dev/infiniband/uverbsN character
  devices.  Fast path operations are typically performed by writing
  directly to hardware registers mmap()ed into userspace, with no
  system call or context switch into the kernel.

  Commands are sent to the kernel via write()s on these device files.
  The ABI is defined in drivers/infiniband/include/ib_user_verbs.h.
  The structs for commands that require a response from the kernel
  contain a 64-bit field used to pass a pointer to an output buffer.
  Status is returned to userspace as the return value of the write()
  system call.

Resource management
===================

  Since creation and destruction of all IB resources is done by
  commands passed through a file descriptor, the kernel can keep track
  of which resources are attached to a given userspace context.  The
  ib_uverbs module maintains idr tables that are used to translate
  between kernel pointers and opaque userspace handles, so that kernel
  pointers are never exposed to userspace and userspace cannot trick
  the kernel into following a bogus pointer.

  This also allows the kernel to clean up when a process exits and
  prevent one process from touching another process's resources.

Memory pinning
==============

  Direct userspace I/O requires that memory regions that are potential
  I/O targets be kept resident at the same physical address.  The
  ib_uverbs module manages pinning and unpinning memory regions via
  get_user_pages() and put_page() calls.  It also accounts for the
  amount of memory pinned in the process's pinned_vm, and checks that
  unprivileged processes do not exceed their RLIMIT_MEMLOCK limit.

  Pages that are pinned multiple times are counted each time they are
  pinned, so the value of pinned_vm may be an overestimate of the
  number of pages pinned by a process.

/dev files
==========

  To create the appropriate character device files automatically with
  udev, a rule like::

    KERNEL=="uverbs*", NAME="infiniband/%k"

  can be used.  This will create device nodes named::

    /dev/infiniband/uverbs0

  and so on.  Since the InfiniBand userspace verbs should be safe for
  use by non-privileged processes, it may be useful to add an
  appropriate MODE or GROUP to the udev rule.


code:
----------------------
ALPS Touchpad Protocol
----------------------

Introduction
------------
Currently the ALPS touchpad driver supports seven protocol versions in use by
ALPS touchpads, called versions 1, 2, 3, 4, 5, 6, 7 and 8.

Since roughly mid-2010 several new ALPS touchpads have been released and
integrated into a variety of laptops and netbooks.  These new touchpads
have enough behavior differences that the alps_model_data definition
table, describing the properties of the different versions, is no longer
adequate.  The design choices were to re-define the alps_model_data
table, with the risk of regression testing existing devices, or isolate
the new devices outside of the alps_model_data table.  The latter design
choice was made.  The new touchpad signatures are named: "Rushmore",
"Pinnacle", and "Dolphin", which you will see in the alps.c code.
For the purposes of this document, this group of ALPS touchpads will
generically be called "new ALPS touchpads".

We experimented with probing the ACPI interface _HID (Hardware ID)/_CID
(Compatibility ID) definition as a way to uniquely identify the
different ALPS variants but there did not appear to be a 1:1 mapping.
In fact, it appeared to be an m:n mapping between the _HID and actual
hardware type.

Detection
---------

All ALPS touchpads should respond to the "E6 report" command sequence:
E8-E6-E6-E6-E9. An ALPS touchpad should respond with either 00-00-0A or
00-00-64 if no buttons are pressed. The bits 0-2 of the first byte will be 1s
if some buttons are pressed.

If the E6 report is successful, the touchpad model is identified using the "E7
report" sequence: E8-E7-E7-E7-E9. The response is the model signature and is
matched against known models in the alps_model_data_array.

For older touchpads supporting protocol versions 3 and 4, the E7 report
model signature is always 73-02-64. To differentiate between these
versions, the response from the "Enter Command Mode" sequence must be
inspected as described below.

The new ALPS touchpads have an E7 signature of 73-03-50 or 73-03-0A but
seem to be better differentiated by the EC Command Mode response.

Command Mode
------------

Protocol versions 3 and 4 have a command mode that is used to read and write
one-byte device registers in a 16-bit address space. The command sequence
EC-EC-EC-E9 places the device in command mode, and the device will respond
with 88-07 followed by a third byte. This third byte can be used to determine
whether the devices uses the version 3 or 4 protocol.

To exit command mode, PSMOUSE_CMD_SETSTREAM (EA) is sent to the touchpad.

While in command mode, register addresses can be set by first sending a
specific command, either EC for v3 devices or F5 for v4 devices. Then the
address is sent one nibble at a time, where each nibble is encoded as a
command with optional data. This encoding differs slightly between the v3 and
v4 protocols.

Once an address has been set, the addressed register can be read by sending
PSMOUSE_CMD_GETINFO (E9). The first two bytes of the response contains the
address of the register being read, and the third contains the value of the
register. Registers are written by writing the value one nibble at a time
using the same encoding used for addresses.

For the new ALPS touchpads, the EC command is used to enter command
mode. The response in the new ALPS touchpads is significantly different,
and more important in determining the behavior.  This code has been
separated from the original alps_model_data table and put in the
alps_identify function.  For example, there seem to be two hardware init
sequences for the "Dolphin" touchpads as determined by the second byte
of the EC response.

Packet Format
-------------

In the following tables, the following notation is used::

 CAPITALS = stick, miniscules = touchpad

?'s can have different meanings on different models, such as wheel rotation,
extra buttons, stick buttons on a dualpoint, etc.

PS/2 packet format
------------------

::

 byte 0:  0    0 YSGN XSGN    1    M    R    L
 byte 1: X7   X6   X5   X4   X3   X2   X1   X0
 byte 2: Y7   Y6   Y5   Y4   Y3   Y2   Y1   Y0

Note that the device never signals overflow condition.

For protocol version 2 devices when the trackpoint is used, and no fingers
are on the touchpad, the M R L bits signal the combined status of both the
pointingstick and touchpad buttons.

ALPS Absolute Mode - Protocol Version 1
---------------------------------------

::

 byte 0:  1    0    0    0    1   x9   x8   x7
 byte 1:  0   x6   x5   x4   x3   x2   x1   x0
 byte 2:  0    ?    ?    l    r    ?  fin  ges
 byte 3:  0    ?    ?    ?    ?   y9   y8   y7
 byte 4:  0   y6   y5   y4   y3   y2   y1   y0
 byte 5:  0   z6   z5   z4   z3   z2   z1   z0

ALPS Absolute Mode - Protocol Version 2
---------------------------------------

::

 byte 0:  1    ?    ?    ?    1  PSM  PSR  PSL
 byte 1:  0   x6   x5   x4   x3   x2   x1   x0
 byte 2:  0  x10   x9   x8   x7    ?  fin  ges
 byte 3:  0   y9   y8   y7    1    M    R    L
 byte 4:  0   y6   y5   y4   y3   y2   y1   y0
 byte 5:  0   z6   z5   z4   z3   z2   z1   z0

Protocol Version 2 DualPoint devices send standard PS/2 mouse packets for
the DualPoint Stick. The M, R and L bits signal the combined status of both
the pointingstick and touchpad buttons, except for Dell dualpoint devices
where the pointingstick buttons get reported separately in the PSM, PSR
and PSL bits.

Dualpoint device -- interleaved packet format
---------------------------------------------

::

 byte 0:    1    1    0    0    1    1    1    1
 byte 1:    0   x6   x5   x4   x3   x2   x1   x0
 byte 2:    0  x10   x9   x8   x7    0  fin  ges
 byte 3:    0    0 YSGN XSGN    1    1    1    1
 byte 4:   X7   X6   X5   X4   X3   X2   X1   X0
 byte 5:   Y7   Y6   Y5   Y4   Y3   Y2   Y1   Y0
 byte 6:    0   y9   y8   y7    1    m    r    l
 byte 7:    0   y6   y5   y4   y3   y2   y1   y0
 byte 8:    0   z6   z5   z4   z3   z2   z1   z0

Devices which use the interleaving format normally send standard PS/2 mouse
packets for the DualPoint Stick + ALPS Absolute Mode packets for the
touchpad, switching to the interleaved packet format when both the stick and
the touchpad are used at the same time.

ALPS Absolute Mode - Protocol Version 3
---------------------------------------

ALPS protocol version 3 has three different packet formats. The first two are
associated with touchpad events, and the third is associated with trackstick
events.

The first type is the touchpad position packet::

 byte 0:    1    ?   x1   x0    1    1    1    1
 byte 1:    0  x10   x9   x8   x7   x6   x5   x4
 byte 2:    0  y10   y9   y8   y7   y6   y5   y4
 byte 3:    0    M    R    L    1    m    r    l
 byte 4:    0   mt   x3   x2   y3   y2   y1   y0
 byte 5:    0   z6   z5   z4   z3   z2   z1   z0

Note that for some devices the trackstick buttons are reported in this packet,
and on others it is reported in the trackstick packets.

The second packet type contains bitmaps representing the x and y axes. In the
bitmaps a given bit is set if there is a finger covering that position on the
given axis. Thus the bitmap packet can be used for low-resolution multi-touch
data, although finger tracking is not possible.  This packet also encodes the
number of contacts (f1 and f0 in the table below)::

 byte 0:    1    1   x1   x0    1    1    1    1
 byte 1:    0   x8   x7   x6   x5   x4   x3   x2
 byte 2:    0   y7   y6   y5   y4   y3   y2   y1
 byte 3:    0  y10   y9   y8    1    1    1    1
 byte 4:    0  x14  x13  x12  x11  x10   x9   y0
 byte 5:    0    1    ?    ?    ?    ?   f1   f0

This packet only appears after a position packet with the mt bit set, and
usually only appears when there are two or more contacts (although
occasionally it's seen with only a single contact).

The final v3 packet type is the trackstick packet::

 byte 0:    1    1   x7   y7    1    1    1    1
 byte 1:    0   x6   x5   x4   x3   x2   x1   x0
 byte 2:    0   y6   y5   y4   y3   y2   y1   y0
 byte 3:    0    1   TP   SW    1    M    R    L
 byte 4:    0   z6   z5   z4   z3   z2   z1   z0
 byte 5:    0    0    1    1    1    1    1    1

TP means Tap SW status when tap processing is enabled or Press status when press
processing is enabled. SW means scroll up when 4 buttons are available.

ALPS Absolute Mode - Protocol Version 4
---------------------------------------

Protocol version 4 has an 8-byte packet format::

 byte 0:    1    ?   x1   x0    1    1    1    1
 byte 1:    0  x10   x9   x8   x7   x6   x5   x4
 byte 2:    0  y10   y9   y8   y7   y6   y5   y4
 byte 3:    0    1   x3   x2   y3   y2   y1   y0
 byte 4:    0    ?    ?    ?    1    ?    r    l
 byte 5:    0   z6   z5   z4   z3   z2   z1   z0
 byte 6:    bitmap data (described below)
 byte 7:    bitmap data (described below)

The last two bytes represent a partial bitmap packet, with 3 full packets
required to construct a complete bitmap packet.  Once assembled, the 6-byte
bitmap packet has the following format::

 byte 0:    0    1   x7   x6   x5   x4   x3   x2
 byte 1:    0   x1   x0   y4   y3   y2   y1   y0
 byte 2:    0    0    ?  x14  x13  x12  x11  x10
 byte 3:    0   x9   x8   y9   y8   y7   y6   y5
 byte 4:    0    0    0    0    0    0    0    0
 byte 5:    0    0    0    0    0    0    0  y10

There are several things worth noting here.

 1) In the bitmap data, bit 6 of byte 0 serves as a sync byte to
    identify the first fragment of a bitmap packet.

 2) The bitmaps represent the same data as in the v3 bitmap packets, although
    the packet layout is different.

 3) There doesn't seem to be a count of the contact points anywhere in the v4
    protocol packets. Deriving a count of contact points must be done by
    analyzing the bitmaps.

 4) There is a 3 to 1 ratio of position packets to bitmap packets. Therefore
    MT position can only be updated for every third ST position update, and
    the count of contact points can only be updated every third packet as
    well.

So far no v4 devices with tracksticks have been encountered.

ALPS Absolute Mode - Protocol Version 5
---------------------------------------
This is basically Protocol Version 3 but with different logic for packet
decode.  It uses the same alps_process_touchpad_packet_v3 call with a
specialized decode_fields function pointer to correctly interpret the
packets.  This appears to only be used by the Dolphin devices.

For single-touch, the 6-byte packet format is::

 byte 0:    1    1    0    0    1    0    0    0
 byte 1:    0   x6   x5   x4   x3   x2   x1   x0
 byte 2:    0   y6   y5   y4   y3   y2   y1   y0
 byte 3:    0    M    R    L    1    m    r    l
 byte 4:   y10  y9   y8   y7  x10   x9   x8   x7
 byte 5:    0   z6   z5   z4   z3   z2   z1   z0

For mt, the format is::

 byte 0:    1    1    1    n3   1   n2   n1   x24
 byte 1:    1   y7   y6    y5  y4   y3   y2    y1
 byte 2:    ?   x2   x1   y12 y11  y10   y9    y8
 byte 3:    0  x23  x22   x21 x20  x19  x18   x17
 byte 4:    0   x9   x8    x7  x6   x5   x4    x3
 byte 5:    0  x16  x15   x14 x13  x12  x11   x10

ALPS Absolute Mode - Protocol Version 6
---------------------------------------

For trackstick packet, the format is::

 byte 0:    1    1    1    1    1    1    1    1
 byte 1:    0   X6   X5   X4   X3   X2   X1   X0
 byte 2:    0   Y6   Y5   Y4   Y3   Y2   Y1   Y0
 byte 3:    ?   Y7   X7    ?    ?    M    R    L
 byte 4:   Z7   Z6   Z5   Z4   Z3   Z2   Z1   Z0
 byte 5:    0    1    1    1    1    1    1    1

For touchpad packet, the format is::

 byte 0:    1    1    1    1    1    1    1    1
 byte 1:    0    0    0    0   x3   x2   x1   x0
 byte 2:    0    0    0    0   y3   y2   y1   y0
 byte 3:    ?   x7   x6   x5   x4    ?    r    l
 byte 4:    ?   y7   y6   y5   y4    ?    ?    ?
 byte 5:   z7   z6   z5   z4   z3   z2   z1   z0

(v6 touchpad does not have middle button)

ALPS Absolute Mode - Protocol Version 7
---------------------------------------

For trackstick packet, the format is::

 byte 0:    0    1    0    0    1    0    0    0
 byte 1:    1    1    *    *    1    M    R    L
 byte 2:   X7    1   X5   X4   X3   X2   X1   X0
 byte 3:   Z6    1   Y6   X6    1   Y2   Y1   Y0
 byte 4:   Y7    0   Y5   Y4   Y3    1    1    0
 byte 5:  T&P    0   Z5   Z4   Z3   Z2   Z1   Z0

For touchpad packet, the format is::

         packet-fmt     b7     b6     b5     b4     b3     b2     b1     b0
 byte 0: TWO & MULTI     L      1      R      M      1   Y0-2   Y0-1   Y0-0
 byte 0: NEW             L      1   X1-5      1      1   Y0-2   Y0-1   Y0-0
 byte 1:             Y0-10   Y0-9   Y0-8   Y0-7   Y0-6   Y0-5   Y0-4   Y0-3
 byte 2:             X0-11      1  X0-10   X0-9   X0-8   X0-7   X0-6   X0-5
 byte 3:             X1-11      1   X0-4   X0-3      1   X0-2   X0-1   X0-0
 byte 4: TWO         X1-10    TWO   X1-9   X1-8   X1-7   X1-6   X1-5   X1-4
 byte 4: MULTI       X1-10    TWO   X1-9   X1-8   X1-7   X1-6   Y1-5      1
 byte 4: NEW         X1-10    TWO   X1-9   X1-8   X1-7   X1-6      0      0
 byte 5: TWO & NEW   Y1-10      0   Y1-9   Y1-8   Y1-7   Y1-6   Y1-5   Y1-4
 byte 5: MULTI       Y1-10      0   Y1-9   Y1-8   Y1-7   Y1-6    F-1    F-0

 L:         Left button
 R / M:     Non-clickpads: Right / Middle button
            Clickpads: When > 2 fingers are down, and some fingers
            are in the button area, then the 2 coordinates reported
            are for fingers outside the button area and these report
            extra fingers being present in the right / left button
            area. Note these fingers are not added to the F field!
            so if a TWO packet is received and R = 1 then there are
            3 fingers down, etc.
 TWO:       1: Two touches present, byte 0/4/5 are in TWO fmt
            0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt
               otherwise byte 0 bit 4 must be set and byte 0/4/5 are
               in NEW fmt
 F:         Number of fingers - 3, 0 means 3 fingers, 1 means 4 ...

ALPS Absolute Mode - Protocol Version 8
---------------------------------------

Spoken by SS4 (73 03 14) and SS5 (73 03 28) hardware.

The packet type is given by the APD field, bits 4-5 of byte 3.

Touchpad packet (APD = 0x2)::

           b7   b6   b5   b4   b3   b2   b1   b0
 byte 0:  SWM  SWR  SWL    1    1    0    0   X7
 byte 1:    0   X6   X5   X4   X3   X2   X1   X0
 byte 2:    0   Y6   Y5   Y4   Y3   Y2   Y1   Y0
 byte 3:    0  T&P    1    0    1    0    0   Y7
 byte 4:    0   Z6   Z5   Z4   Z3   Z2   Z1   Z0
 byte 5:    0    0    0    0    0    0    0    0

SWM, SWR, SWL: Middle, Right, and Left button states

Touchpad 1 Finger packet (APD = 0x0)::

           b7   b6   b5   b4   b3   b2   b1   b0
 byte 0:  SWM  SWR  SWL    1    1   X2   X1   X0
 byte 1:   X9   X8   X7    1   X6   X5   X4   X3
 byte 2:    0  X11  X10  LFB   Y3   Y2   Y1   Y0
 byte 3:   Y5   Y4    0    0    1 TAPF2 TAPF1 TAPF0
 byte 4:  Zv7  Y11  Y10    1   Y9   Y8   Y7   Y6
 byte 5:  Zv6  Zv5  Zv4    0  Zv3  Zv2  Zv1  Zv0

TAPF: ???
LFB:  ???

Touchpad 2 Finger packet (APD = 0x1)::

           b7   b6   b5   b4   b3   b2   b1   b0
 byte 0:  SWM  SWR  SWL    1    1  AX6  AX5  AX4
 byte 1: AX11 AX10  AX9  AX8  AX7  AZ1  AY4  AZ0
 byte 2: AY11 AY10  AY9  CONT AY8  AY7  AY6  AY5
 byte 3:    0    0    0    1    1  BX6  BX5  BX4
 byte 4: BX11 BX10  BX9  BX8  BX7  BZ1  BY4  BZ0
 byte 5: BY11 BY10  BY9    0  BY8  BY7  BY5  BY5

CONT: A 3-or-4 Finger packet is to follow

Touchpad 3-or-4 Finger packet (APD = 0x3)::

           b7   b6   b5   b4   b3   b2   b1   b0
 byte 0:  SWM  SWR  SWL    1    1  AX6  AX5  AX4
 byte 1: AX11 AX10  AX9  AX8  AX7  AZ1  AY4  AZ0
 byte 2: AY11 AY10  AY9  OVF  AY8  AY7  AY6  AY5
 byte 3:    0    0    1    1    1  BX6  BX5  BX4
 byte 4: BX11 BX10  BX9  BX8  BX7  BZ1  BY4  BZ0
 byte 5: BY11 BY10  BY9    0  BY8  BY7  BY5  BY5

OVF: 5th finger detected


code:
.. include:: <isonum.txt>

----------------------------------
Apple Touchpad Driver (appletouch)
----------------------------------

:Copyright: |copy| 2005 Stelian Pop <stelian@popies.net>

appletouch is a Linux kernel driver for the USB touchpad found on post
February 2005 and October 2005 Apple Aluminium Powerbooks.

This driver is derived from Johannes Berg's appletrackpad driver [#f1]_,
but it has been improved in some areas:

	* appletouch is a full kernel driver, no userspace program is necessary
	* appletouch can be interfaced with the synaptics X11 driver, in order
	  to have touchpad acceleration, scrolling, etc.

Credits go to Johannes Berg for reverse-engineering the touchpad protocol,
Frank Arnold for further improvements, and Alex Harper for some additional
information about the inner workings of the touchpad sensors. Michael
Hanselmann added support for the October 2005 models.

Usage
-----

In order to use the touchpad in the basic mode, compile the driver and load
the module. A new input device will be detected and you will be able to read
the mouse data from /dev/input/mice (using gpm, or X11).

In X11, you can configure the touchpad to use the synaptics X11 driver, which
will give additional functionalities, like acceleration, scrolling, 2 finger
tap for middle button mouse emulation, 3 finger tap for right button mouse
emulation, etc. In order to do this, make sure you're using a recent version of
the synaptics driver (tested with 0.14.2, available from [#f2]_), and configure
a new input device in your X11 configuration file (take a look below for an
example). For additional configuration, see the synaptics driver documentation::

	Section "InputDevice"
		Identifier      "Synaptics Touchpad"
		Driver          "synaptics"
		Option          "SendCoreEvents"        "true"
		Option          "Device"                "/dev/input/mice"
		Option          "Protocol"              "auto-dev"
		Option		"LeftEdge"		"0"
		Option		"RightEdge"		"850"
		Option		"TopEdge"		"0"
		Option		"BottomEdge"		"645"
		Option		"MinSpeed"		"0.4"
		Option		"MaxSpeed"		"1"
		Option		"AccelFactor"		"0.02"
		Option		"FingerLow"		"0"
		Option		"FingerHigh"		"30"
		Option		"MaxTapMove"		"20"
		Option		"MaxTapTime"		"100"
		Option		"HorizScrollDelta"	"0"
		Option		"VertScrollDelta"	"30"
		Option		"SHMConfig"		"on"
	EndSection

	Section "ServerLayout"
		...
		InputDevice	"Mouse"
		InputDevice	"Synaptics Touchpad"
	...
	EndSection

Fuzz problems
-------------

The touchpad sensors are very sensitive to heat, and will generate a lot of
noise when the temperature changes. This is especially true when you power-on
the laptop for the first time.

The appletouch driver tries to handle this noise and auto adapt itself, but it
is not perfect. If finger movements are not recognized anymore, try reloading
the driver.

You can activate debugging using the 'debug' module parameter. A value of 0
deactivates any debugging, 1 activates tracing of invalid samples, 2 activates
full tracing (each sample is being traced)::

	modprobe appletouch debug=1

or::

	echo "1" > /sys/module/appletouch/parameters/debug

.. Links:

.. [#f1] http://johannes.sipsolutions.net/PowerBook/touchpad/

.. [#f2] `<http://web.archive.org/web/*/http://web.telia.com/~u89404340/touchpad/index.html>`_