Clean up the following igor warnings:

- wrap long line
- add blank line after previous line
- use tabs instead of spaces
- straggling <tag>

Event:	    vBSDcon FreeBSD Hackathon
This commit is contained in:
Benedict Reuschling 2019-09-05 20:22:58 +00:00
parent e6a8ba37d0
commit 6c190c76c3
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=53377

View file

@ -4,7 +4,9 @@
$FreeBSD$ $FreeBSD$
--> -->
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="pci"> <chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="pci">
<title>PCI Devices</title> <title>PCI Devices</title>
<indexterm><primary>PCI bus</primary></indexterm> <indexterm><primary>PCI bus</primary></indexterm>
@ -20,9 +22,10 @@
to any of them.</para> to any of them.</para>
<sect2> <sect2>
<title>Sample Driver Source (<filename>mypci.c</filename>)</title> <title>Sample Driver Source
(<filename>mypci.c</filename>)</title>
<programlisting>/* <programlisting>/*
* Simple KLD to play with the PCI functions. * Simple KLD to play with the PCI functions.
* *
* Murray Stokely * Murray Stokely
@ -232,7 +235,7 @@ DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);</programlisting>
<sect2> <sect2>
<title><filename>Makefile</filename> for Sample Driver</title> <title><filename>Makefile</filename> for Sample Driver</title>
<programlisting># Makefile for mypci driver <programlisting># Makefile for mypci driver
KMOD= mypci KMOD= mypci
SRCS= mypci.c SRCS= mypci.c
@ -251,13 +254,16 @@ SRCS+= device_if.h bus_if.h pci_if.h
<sect2> <sect2>
<title>Additional Resources</title> <title>Additional Resources</title>
<itemizedlist> <itemizedlist>
<listitem><simpara><link xlink:href="http://www.pcisig.org/">PCI <listitem>
Special Interest Group</link></simpara></listitem> <simpara><link xlink:href="http://www.pcisig.org/">PCI
Special Interest Group</link></simpara>
</listitem>
<listitem><simpara>PCI System Architecture, Fourth Edition by <listitem><simpara>PCI System Architecture, Fourth Edition by
Tom Shanley, et al.</simpara></listitem> Tom Shanley, et al.</simpara>
</listitem>
</itemizedlist> </itemizedlist>
</sect2> </sect2>
</sect1> </sect1>
@ -265,7 +271,8 @@ SRCS+= device_if.h bus_if.h pci_if.h
<sect1 xml:id="pci-bus"> <sect1 xml:id="pci-bus">
<title>Bus Resources</title> <title>Bus Resources</title>
<indexterm><primary>PCI bus</primary><secondary>resources</secondary></indexterm> <indexterm><primary>PCI
bus</primary><secondary>resources</secondary></indexterm>
<para>FreeBSD provides an object-oriented mechanism for requesting <para>FreeBSD provides an object-oriented mechanism for requesting
resources from a parent bus. Almost all devices will be a child resources from a parent bus. Almost all devices will be a child
member of some sort of bus (PCI, ISA, USB, SCSI, etc) and these member of some sort of bus (PCI, ISA, USB, SCSI, etc) and these
@ -275,18 +282,20 @@ SRCS+= device_if.h bus_if.h pci_if.h
<sect2> <sect2>
<title>Base Address Registers</title> <title>Base Address Registers</title>
<indexterm><primary>PCI bus</primary><secondary>Base Address Registers</secondary></indexterm> <indexterm><primary>PCI bus</primary><secondary>Base Address
Registers</secondary></indexterm>
<para>To do anything particularly useful with a PCI device you <para>To do anything particularly useful with a PCI device you
will need to obtain the <emphasis>Base Address will need to obtain the <emphasis>Base Address
Registers</emphasis> (BARs) from the PCI Configuration space. Registers</emphasis> (BARs) from the PCI Configuration
The PCI-specific details of obtaining the BAR are abstracted in space. The PCI-specific details of obtaining the BAR are
the <function>bus_alloc_resource()</function> function.</para> abstracted in the <function>bus_alloc_resource()</function>
function.</para>
<para>For example, a typical driver might have something similar <para>For example, a typical driver might have something similar
to this in the <function>attach()</function> function:</para> to this in the <function>attach()</function> function:</para>
<programlisting> sc-&gt;bar0id = PCIR_BAR(0); <programlisting> sc-&gt;bar0id = PCIR_BAR(0);
sc-&gt;bar0res = bus_alloc_resource(dev, SYS_RES_MEMORY, &amp;sc-&gt;bar0id, sc-&gt;bar0res = bus_alloc_resource(dev, SYS_RES_MEMORY, &amp;sc-&gt;bar0id,
0, ~0, 1, RF_ACTIVE); 0, ~0, 1, RF_ACTIVE);
if (sc-&gt;bar0res == NULL) { if (sc-&gt;bar0res == NULL) {
@ -309,34 +318,33 @@ SRCS+= device_if.h bus_if.h pci_if.h
sc-&gt;bar1_bh = rman_get_bushandle(sc-&gt;bar1res);</programlisting> sc-&gt;bar1_bh = rman_get_bushandle(sc-&gt;bar1res);</programlisting>
<para>Handles for each base address register are kept in the <para>Handles for each base address register are kept in the
<varname remap="structname">softc</varname> structure so that they can be <varname remap="structname">softc</varname> structure so that
used to write to the device later.</para> they can be used to write to the device later.</para>
<para>These handles can then be used to read or write from the <para>These handles can then be used to read or write from the
device registers with the <function>bus_space_*</function> device registers with the <function>bus_space_*</function>
functions. For example, a driver might contain a shorthand functions. For example, a driver might contain a shorthand
function to read from a board specific register like this:</para> function to read from a board specific register like
this:</para>
<programlisting>uint16_t <programlisting>uint16_t
board_read(struct ni_softc *sc, uint16_t address) board_read(struct ni_softc *sc, uint16_t address)
{ {
return bus_space_read_2(sc-&gt;bar1_bt, sc-&gt;bar1_bh, address); return bus_space_read_2(sc-&gt;bar1_bt, sc-&gt;bar1_bh, address);
} }</programlisting>
</programlisting>
<para>Similarly, one could write to the registers with:</para> <para>Similarly, one could write to the registers with:</para>
<programlisting>void <programlisting>void
board_write(struct ni_softc *sc, uint16_t address, uint16_t value) board_write(struct ni_softc *sc, uint16_t address, uint16_t value)
{ {
bus_space_write_2(sc-&gt;bar1_bt, sc-&gt;bar1_bh, address, value); bus_space_write_2(sc-&gt;bar1_bt, sc-&gt;bar1_bh, address, value);
} }</programlisting>
</programlisting>
<para>These functions exist in 8bit, 16bit, and 32bit versions <para>These functions exist in 8bit, 16bit, and 32bit versions
and you should use and you should use
<function>bus_space_{read|write}_{1|2|4}</function> <function>bus_space_{read|write}_{1|2|4}</function>
accordingly.</para> accordingly.</para>
<note> <note>
<para>In FreeBSD 7.0 and later, you can use the <para>In FreeBSD 7.0 and later, you can use the
@ -345,31 +353,33 @@ board_write(struct ni_softc *sc, uint16_t address, uint16_t value)
<function>bus_*</function> functions take a <type>struct <function>bus_*</function> functions take a <type>struct
resource *</type> pointer instead of a bus tag and handle. resource *</type> pointer instead of a bus tag and handle.
Thus, you could drop the bus tag and bus handle members from Thus, you could drop the bus tag and bus handle members from
the <varname remap="structname">softc</varname> and rewrite the the <varname remap="structname">softc</varname> and rewrite
<function>board_read()</function> function as:</para> the <function>board_read()</function> function as:</para>
<programlisting>uint16_t <programlisting>uint16_t
board_read(struct ni_softc *sc, uint16_t address) board_read(struct ni_softc *sc, uint16_t address)
{ {
return (bus_read(sc-&gt;bar1res, address)); return (bus_read(sc-&gt;bar1res, address));
} }</programlisting>
</programlisting>
</note> </note>
</sect2> </sect2>
<sect2> <sect2>
<title>Interrupts</title> <title>Interrupts</title>
<indexterm><primary>PCI bus</primary><secondary>interrupts</secondary></indexterm> <indexterm><primary>PCI
bus</primary><secondary>interrupts</secondary></indexterm>
<para>Interrupts are allocated from the object-oriented bus code <para>Interrupts are allocated from the object-oriented bus code
in a way similar to the memory resources. First an IRQ in a way similar to the memory resources. First an IRQ
resource must be allocated from the parent bus, and then the resource must be allocated from the parent bus, and then the
interrupt handler must be set up to deal with this IRQ.</para> interrupt handler must be set up to deal with this IRQ.</para>
<para>Again, a sample from a device <para>Again, a sample from a device
<function>attach()</function> function says more than <function>attach()</function> function says more than
words.</para> words.</para>
<programlisting>/* Get the IRQ resource */ <programlisting>/* Get the IRQ resource */
sc-&gt;irqid = 0x0; sc-&gt;irqid = 0x0;
sc-&gt;irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &amp;(sc-&gt;irqid), sc-&gt;irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &amp;(sc-&gt;irqid),
@ -387,67 +397,62 @@ board_read(struct ni_softc *sc, uint16_t address)
if (error) { if (error) {
printf("Couldn't set up irq\n"); printf("Couldn't set up irq\n");
goto fail4; goto fail4;
} }</programlisting>
</programlisting>
<para>Some care must be taken in the detach routine of the <para>Some care must be taken in the detach routine of the
driver. You must quiesce the device's interrupt stream, and driver. You must quiesce the device's interrupt stream, and
remove the interrupt handler. Once remove the interrupt handler. Once
<function>bus_teardown_intr()</function> has returned, you <function>bus_teardown_intr()</function> has returned, you
know that your interrupt handler will no longer be called and know that your interrupt handler will no longer be called and
that all threads that might have been executing this interrupt handler that all threads that might have been executing this interrupt
have returned. Since this function can sleep, you must not hold handler have returned. Since this function can sleep, you
any mutexes when calling this function.</para> must not hold any mutexes when calling this function.</para>
</sect2> </sect2>
<sect2> <sect2>
<title>DMA</title> <title>DMA</title>
<indexterm><primary>PCI bus</primary><secondary>DMA</secondary></indexterm> <indexterm><primary>PCI
bus</primary><secondary>DMA</secondary></indexterm>
<para>This section is obsolete, and present only for historical <para>This section is obsolete, and present only for historical
reasons. The proper methods for dealing with these issues is to reasons. The proper methods for dealing with these issues is
use the <function>bus_space_dma*()</function> functions instead. to use the <function>bus_space_dma*()</function> functions
This paragraph can be removed when this section is updated to reflect instead. This paragraph can be removed when this section is
that usage. However, at the moment, the API is in a bit of updated to reflect that usage. However, at the moment, the
flux, so once that settles down, it would be good to update this API is in a bit of flux, so once that settles down, it would
section to reflect that.</para> be good to update this section to reflect that.</para>
<para>On the PC, peripherals that want to do bus-mastering DMA <para>On the PC, peripherals that want to do bus-mastering DMA
must deal with physical addresses. This is a problem since must deal with physical addresses. This is a problem since
FreeBSD uses virtual memory and deals almost exclusively with FreeBSD uses virtual memory and deals almost exclusively with
virtual addresses. Fortunately, there is a function, virtual addresses. Fortunately, there is a function,
<function>vtophys()</function> to help.</para> <function>vtophys()</function> to help.</para>
<programlisting>#include &lt;vm/vm.h&gt; <programlisting>#include &lt;vm/vm.h&gt;
#include &lt;vm/pmap.h&gt; #include &lt;vm/pmap.h&gt;
#define vtophys(virtual_address) (...) #define vtophys(virtual_address) (...)</programlisting>
</programlisting>
<para>The solution is a bit different on the alpha however, and <para>The solution is a bit different on the alpha however, and
what we really want is a function called what we really want is a function called
<function>vtobus()</function>.</para> <function>vtobus()</function>.</para>
<programlisting>#if defined(__alpha__) <programlisting>#if defined(__alpha__)
#define vtobus(va) alpha_XXX_dmamap((vm_offset_t)va) #define vtobus(va) alpha_XXX_dmamap((vm_offset_t)va)
#else #else
#define vtobus(va) vtophys(va) #define vtobus(va) vtophys(va)
#endif #endif</programlisting>
</programlisting>
</sect2> </sect2>
<sect2> <sect2>
<title>Deallocating Resources</title> <title>Deallocating Resources</title>
<para>It is very important to deallocate all of the resources <para>It is very important to deallocate all of the resources
that were allocated during <function>attach()</function>. that were allocated during <function>attach()</function>.
Care must be taken to deallocate the correct stuff even on a Care must be taken to deallocate the correct stuff even on a
failure condition so that the system will remain usable while failure condition so that the system will remain usable while
your driver dies.</para> your driver dies.</para>
</sect2> </sect2>
</sect1> </sect1>
</chapter> </chapter>