+++ /dev/null
-<?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(&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(&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(&dev_lock, flags)
-CPU A: ...
-CPU A: writel(newval, ring_ptr);
-CPU A: spin_unlock_irqrestore(&dev_lock, flags)
- ...
-CPU B: spin_lock_irqsave(&dev_lock, flags)
-CPU B: writel(newval2, ring_ptr);
-CPU B: ...
-CPU B: spin_unlock_irqrestore(&dev_lock, flags)
-</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(&dev_lock, flags)
-CPU A: ...
-CPU A: writel(newval, ring_ptr);
-CPU A: mmiowb(); /* ensure no other writes beat us to the device */
-CPU A: spin_unlock_irqrestore(&dev_lock, flags)
- ...
-CPU B: spin_lock_irqsave(&dev_lock, flags)
-CPU B: writel(newval2, ring_ptr);
-CPU B: ...
-CPU B: mmiowb();
-CPU B: spin_unlock_irqrestore(&dev_lock, flags)
-</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>
--- /dev/null
+.. Copyright 2001 Matthew Wilcox
+..
+.. This documentation is free software; you can redistribute
+.. it and/or modify it under the terms of the GNU General Public
+.. License as published by the Free Software Foundation; either
+.. version 2 of the License, or (at your option) any later
+.. version.
+
+===============================
+Bus-Independent Device Accesses
+===============================
+
+:Author: Matthew Wilcox
+:Author: Alan Cox
+
+Introduction
+============
+
+Linux provides an API which abstracts performing IO across all busses
+and devices, allowing device drivers to be written independently of bus
+type.
+
+Memory Mapped IO
+================
+
+Getting Access to the Device
+----------------------------
+
+The most widely supported form of IO is memory mapped IO. That is, a
+part of the CPU's address space is interpreted not as accesses to
+memory, but as accesses to a device. Some architectures define devices
+to be at a fixed address, but most have some method of discovering
+devices. The PCI bus walk is a good example of such a scheme. This
+document does not cover how to receive such an address, but assumes you
+are starting with one. Physical addresses are of type unsigned long.
+
+This address should not be used directly. Instead, to get an address
+suitable for passing to the accessor functions described below, you
+should call :c:func:`ioremap()`. An address suitable for accessing
+the device will be returned to you.
+
+After you've finished using the device (say, in your module's exit
+routine), call :c:func:`iounmap()` in order to return the address
+space to the kernel. Most architectures allocate new address space each
+time you call :c:func:`ioremap()`, and they can run out unless you
+call :c:func:`iounmap()`.
+
+Accessing the device
+--------------------
+
+The part of the interface most used by drivers is reading and writing
+memory-mapped registers on the device. Linux provides interfaces to read
+and write 8-bit, 16-bit, 32-bit and 64-bit quantities. Due to a
+historical accident, these are named byte, word, long and quad accesses.
+Both read and write accesses are supported; there is no prefetch support
+at this time.
+
+The functions are named readb(), readw(), readl(), readq(),
+readb_relaxed(), readw_relaxed(), readl_relaxed(), readq_relaxed(),
+writeb(), writew(), writel() and writeq().
+
+Some devices (such as framebuffers) would like to use larger transfers than
+8 bytes at a time. For these devices, the :c:func:`memcpy_toio()`,
+:c:func:`memcpy_fromio()` and :c:func:`memset_io()` functions are
+provided. Do not use memset or memcpy on IO addresses; they are not
+guaranteed to copy data in order.
+
+The read and write functions are defined to be ordered. That is the
+compiler is not permitted to reorder the I/O sequence. When the ordering
+can be compiler optimised, you can use __readb() and friends to
+indicate the relaxed ordering. Use this with care.
+
+While the basic functions are defined to be synchronous with respect to
+each other and ordered with respect to each other the busses the devices
+sit on may themselves have asynchronicity. In particular many authors
+are burned by the fact that PCI bus writes are posted asynchronously. A
+driver author must issue a read from the same device to ensure that
+writes have occurred in the specific cases the author cares. This kind
+of property cannot be hidden from driver writers in the API. In some
+cases, the read used to flush the device may be expected to fail (if the
+card is resetting, for example). In that case, the read should be done
+from config space, which is guaranteed to soft-fail if the card doesn't
+respond.
+
+The following is an example of flushing a write to a device when the
+driver would like to ensure the write's effects are visible prior to
+continuing execution::
+
+ static inline void
+ qla1280_disable_intrs(struct scsi_qla_host *ha)
+ {
+ struct device_reg *reg;
+
+ reg = ha->iobase;
+ /* disable risc and host interrupts */
+ WRT_REG_WORD(®->ictrl, 0);
+ /*
+ * The following read will ensure that the above write
+ * has been received by the device before we return from this
+ * function.
+ */
+ RD_REG_WORD(®->ictrl);
+ ha->flags.ints_enabled = 0;
+ }
+
+In addition to write posting, on some large multiprocessing systems
+(e.g. SGI Challenge, Origin and Altix machines) posted writes won't be
+strongly ordered coming from different CPUs. Thus it's important to
+properly protect parts of your driver that do memory-mapped writes with
+locks and use the :c:func:`mmiowb()` to make sure they arrive in the
+order intended. Issuing a regular readX() will also ensure write ordering,
+but should only be used when the
+driver has to be sure that the write has actually arrived at the device
+(not that it's simply ordered with respect to other writes), since a
+full readX() is a relatively expensive operation.
+
+Generally, one should use :c:func:`mmiowb()` prior to releasing a spinlock
+that protects regions using :c:func:`writeb()` or similar functions that
+aren't surrounded by readb() calls, which will ensure ordering
+and flushing. The following pseudocode illustrates what might occur if
+write ordering isn't guaranteed via :c:func:`mmiowb()` or one of the
+readX() functions::
+
+ CPU A: spin_lock_irqsave(&dev_lock, flags)
+ CPU A: ...
+ CPU A: writel(newval, ring_ptr);
+ CPU A: spin_unlock_irqrestore(&dev_lock, flags)
+ ...
+ CPU B: spin_lock_irqsave(&dev_lock, flags)
+ CPU B: writel(newval2, ring_ptr);
+ CPU B: ...
+ CPU B: spin_unlock_irqrestore(&dev_lock, flags)
+
+In the case above, newval2 could be written to ring_ptr before newval.
+Fixing it is easy though::
+
+ CPU A: spin_lock_irqsave(&dev_lock, flags)
+ CPU A: ...
+ CPU A: writel(newval, ring_ptr);
+ CPU A: mmiowb(); /* ensure no other writes beat us to the device */
+ CPU A: spin_unlock_irqrestore(&dev_lock, flags)
+ ...
+ CPU B: spin_lock_irqsave(&dev_lock, flags)
+ CPU B: writel(newval2, ring_ptr);
+ CPU B: ...
+ CPU B: mmiowb();
+ CPU B: spin_unlock_irqrestore(&dev_lock, flags)
+
+See tg3.c for a real world example of how to use :c:func:`mmiowb()`
+
+PCI ordering rules also guarantee that PIO read responses arrive after any
+outstanding DMA writes from that bus, since for some devices the result of
+a readb() call may signal to the driver that a DMA transaction is
+complete. In many cases, however, the driver may want to indicate that the
+next readb() call has no relation to any previous DMA writes
+performed by the device. The driver can use readb_relaxed() for
+these cases, although only some platforms will honor the relaxed
+semantics. Using the relaxed read functions will provide significant
+performance benefits on platforms that support it. The qla2xxx driver
+provides examples of how to use readX_relaxed(). In many cases, a majority
+of the driver's readX() calls can safely be converted to readX_relaxed()
+calls, since only a few will indicate or depend on DMA completion.
+
+Port Space Accesses
+===================
+
+Port Space Explained
+--------------------
+
+Another form of IO commonly supported is Port Space. This is a range of
+addresses separate to the normal memory address space. Access to these
+addresses is generally not as fast as accesses to the memory mapped
+addresses, and it also has a potentially smaller address space.
+
+Unlike memory mapped IO, no preparation is required to access port
+space.
+
+Accessing Port Space
+--------------------
+
+Accesses to this space are provided through a set of functions which
+allow 8-bit, 16-bit and 32-bit accesses; also known as byte, word and
+long. These functions are :c:func:`inb()`, :c:func:`inw()`,
+:c:func:`inl()`, :c:func:`outb()`, :c:func:`outw()` and
+:c:func:`outl()`.
+
+Some variants are provided for these functions. Some devices require
+that accesses to their ports are slowed down. This functionality is
+provided by appending a ``_p`` to the end of the function.
+There are also equivalents to memcpy. The :c:func:`ins()` and
+:c:func:`outs()` functions copy bytes, words or longs to the given
+port.
+
+Public Functions Provided
+=========================
+
+.. kernel-doc:: arch/x86/include/asm/io.h
+ :internal:
+
+.. kernel-doc:: lib/pci_iomap.c
+ :export: