aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoc Manager <doceng@FreeBSD.org>2002-08-14 06:50:52 +0000
committerDoc Manager <doceng@FreeBSD.org>2002-08-14 06:50:52 +0000
commitebc3be57a9e4b869b36b3574a131dd0b0709b402 (patch)
tree9349eed2c36aa387059db9308f356ee9112a87fe
parentafc8d2d77427da5c039ea5b8e91cb189a878c43c (diff)
downloaddoc-ebc3be57a9e4b869b36b3574a131dd0b0709b402.tar.gz
doc-ebc3be57a9e4b869b36b3574a131dd0b0709b402.zip
Create tag '4.6.2'.release/4.6.2
Notes
Notes: svn path=/head/; revision=13858 svn path=/release/4.6.2/; revision=13859; tag=release/4.6.2
-rw-r--r--de_DE.ISO8859-1/books/handbook/multimedia/chapter.sgml659
-rw-r--r--en/handbook/contrib/chapter.sgml5796
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/Makefile53
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/book.sgml311
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/chapters.ent45
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/driverbasics/chapter.sgml390
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/isa/chapter.sgml2483
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/jail/chapter.sgml611
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/kobj/chapter.sgml298
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/locking/chapter.sgml333
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml369
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/scsi/chapter.sgml1983
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/sound/chapter.sgml687
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/sysinit/chapter.sgml161
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/usb/chapter.sgml623
-rw-r--r--en_US.ISO8859-1/books/arch-handbook/vm/chapter.sgml255
-rw-r--r--en_US.ISO8859-1/books/handbook/basics/disk-layout.kilbin1450 -> 0 bytes
-rw-r--r--en_US.ISO8859-1/books/handbook/basics/example-dir1.dot7
-rw-r--r--en_US.ISO8859-1/books/handbook/basics/example-dir2.dot8
-rw-r--r--en_US.ISO8859-1/books/handbook/basics/example-dir3.dot8
-rw-r--r--en_US.ISO8859-1/books/handbook/basics/example-dir4.dot9
-rw-r--r--en_US.ISO8859-1/books/handbook/basics/example-dir5.dot9
-rw-r--r--en_US.ISO8859-1/books/handbook/mirrors/chapter.sgml71
-rw-r--r--en_US.ISO8859-1/books/handbook/multimedia/Makefile15
-rw-r--r--en_US.ISO8859-1/books/handbook/multimedia/chapter.sgml589
-rw-r--r--ja_JP.eucJP/books/handbook/multimedia/Makefile16
-rw-r--r--ja_JP.eucJP/books/handbook/multimedia/chapter.sgml397
-rw-r--r--ja_JP.eucJP/man/man1/gtar.1597
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/aic.451
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/apm.4160
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/ar.4108
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/cs.4105
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/cx.4289
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/el.458
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/ep.4121
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/ex.484
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/fe.4284
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/ie.496
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/io.472
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/lnc.4124
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/mcd.4151
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/npx.479
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/pcf.465
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/perfmon.4225
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/pnp.4221
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/scd.465
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/spkr.4234
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/sr.4119
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/vx.4102
-rw-r--r--ja_JP.eucJP/man/man4/man4.i386/wd.4106
-rw-r--r--ja_JP.eucJP/man/man8/man8.i386/apm.8157
-rw-r--r--ja_JP.eucJP/man/man8/man8.i386/apmd.8293
-rw-r--r--share/sgml/freebsd.ent4
-rw-r--r--zh/FAQ/FAQ.sgml70
54 files changed, 54 insertions, 20172 deletions
diff --git a/de_DE.ISO8859-1/books/handbook/multimedia/chapter.sgml b/de_DE.ISO8859-1/books/handbook/multimedia/chapter.sgml
deleted file mode 100644
index 961e8cd9fe..0000000000
--- a/de_DE.ISO8859-1/books/handbook/multimedia/chapter.sgml
+++ /dev/null
@@ -1,659 +0,0 @@
-<!--
- The FreeBSD Documentation Project
- The FreeBSD German Documentation Project
-
- Original version 1.31
- $FreeBSD$
- $FreeBSDde: de-docproj/books/handbook/sound/chapter.sgml,v 1.23 2002/05/24 22:23:22 mheinen Exp $
--->
-
-<chapter id="sound">
- <chapterinfo>
- <authorgroup>
- <author>
- <firstname>Moses</firstname>
- <surname>Moore</surname>
- <contrib>Von </contrib>
- </author>
- </authorgroup>
- <!-- 20 November 2000 -->
- <authorgroup>
- <author>
- <firstname>Benedikt</firstname>
- <surname>K&ouml;hler</surname>
- <contrib>&Uuml;bersetzt von </contrib>
- </author>
- <author>
- <firstname>Uwe</firstname>
- <surname>Pierau</surname>
- </author>
- </authorgroup>
- </chapterinfo>
-
- <title>Sound</title>
-
- <sect1 id="sound-synopsis">
- <title>Zusammenfassung</title>
-
- <para>FreeBSD unterst&uuml;tzt viele unterschiedliche Soundkarten,
- die Ihnen den Genuss von Highfidelity-Kl&auml;ngen auf Ihrem
- Computer erm&ouml;glichen. Dazu geh&ouml;rt unter anderem die
- M&ouml;glichkeit, Tonquellen in den Formaten MPEG Audio Layer 3
- (MP3), WAV, Ogg Vorbis und vielen weiteren Formaten aufzunehmen
- und wiederzugeben. Dar&uuml;ber hinaus enth&auml;lt die FreeBSD
- Ports-Sammlung Anwendungen, die Ihnen das Bearbeiten Ihrer
- aufgenommenen Tonspuren, das Hinzuf&uuml;gen von Klangeffekten
- und die Kontrolle der angeschlossenen MIDI-Ger&auml;te
- erlauben.</para>
-
- <para>Nach dem Lesen dieses Kapitels werden Sie wissen:</para>
- <itemizedlist>
- <listitem><para>Wie Sie Ihre Soundkarte
- bestimmen.</para></listitem>
- <listitem><para>Wie Sie Ihr System so einstellen, dass die
- Soundkarte richtig erkannt wird.</para></listitem>
- <listitem><para>Einige Methoden und Beispielanwendungen, mit
- denen Sie das korrekte Funktionieren Ihrer Soundkarte
- &uuml;berpr&uuml;fen k&ouml;nnen.</para></listitem>
- <listitem><para>Wie Sie Fehler in Ihren
- Soundkarten-Einstellungen finden.</para></listitem>
- <listitem><para>Wie Sie MP3s wiedergeben und
- erzeugen.</para></listitem>
- <listitem><para>Wie Sie CD-Tonspuren in Dateien
- rippen.</para></listitem>
- </itemizedlist>
-
- <para>Bevor Sie dieses Kapitel leben, sollten Sie:</para>
-
- <itemizedlist>
- <listitem><para>Wissen, wie Sie einen neuen Kernel
- konfigurieren und installieren (<xref
- linkend="kernelconfig">).</para></listitem>
- </itemizedlist>
- </sect1>
-
- <sect1 id="sound-devices">
- <title>Bestimmen des korrekten Ger&auml;ts</title>
-
- <indexterm><primary>PCI</primary></indexterm>
- <indexterm><primary>ISA</primary></indexterm>
- <indexterm><primary>Soundkarten</primary></indexterm>
- <para>Zun&auml;chst sollten Sie in Erfahrung bringen, welches
- Modell Ihrer Soundkarte Sie haben, welchen Chip sie benutzt und
- ob es sich um eine PCI- oder ISA-Karte handelt. FreeBSD
- unterst&uuml;tzt eine ganze Reihe sowohl von PCI- als auch von
- ISA-Karten. Wenn Ihre Soundkarte in der folgenden Liste nicht
- auftaucht, konsultieren Sie die &man.pcm.4; Manualpage. Diese
- Liste ist zwar nicht vollst&auml;ndig, deckt jedoch einige der
- verbreitetsten Karten ab.</para>
-
- <itemizedlist>
- <listitem>
- <para>Crystal 4237, 4236, 4232, 4231</para>
- </listitem>
-
- <listitem>
- <para>Yamaha OPL-SAx</para>
- </listitem>
-
- <listitem>
- <para>OPTi931</para>
- </listitem>
-
- <listitem>
- <para>Ensoniq AudioPCI 1370/1371</para>
- </listitem>
-
- <listitem>
- <para>ESS Solo-1/1E</para>
- </listitem>
-
- <listitem>
- <para>NeoMagic 256AV/ZX</para>
- </listitem>
-
- <listitem>
- <para>Sound Blaster Pro, 16, 32, AWE64, AWE128, Live</para>
- </listitem>
-
- <listitem>
- <para>Creative ViBRA16</para>
- </listitem>
-
- <listitem>
- <para>Advanced Asound 100, 110, and Logic ALS120</para>
- </listitem>
-
- <listitem>
- <para>ES 1868, 1869, 1879, 1888</para>
- </listitem>
-
- <listitem>
- <para>Gravis UltraSound</para>
- </listitem>
-
- <listitem>
- <para>Aureal Vortex 1 or 2</para>
- </listitem>
- </itemizedlist>
-
- <indexterm>
- <primary>Kernel</primary>
- <secondary>Konfiguration</secondary>
- </indexterm>
-
- <para>Um Ihre Soundkarte benutzen zu k&ouml;nnen, m&uuml;ssen Sie
- den richtigen Ger&auml;tetreiber laden. Daf&uuml;r gibt es mehrere
- M&ouml;glichkeiten: Am einfachsten ist es, mit &man.kldload.8; das
- entsprechende Kernel-Modul f&uuml;r Ihre Soundkarte zu laden. Sie
- k&ouml;nnen aber auch die Unterst&uuml;tzung Ihrer Soundkarte
- statisch in den Kernel hineinkompilieren. Der folgende Abschnitt
- erkl&auml;rt diese Methode. Weitere Informationen &uuml;ber das
- Kompilieren eines Kernels erhalten sie in dem Kapitel <link
- linkend="kernelconfig">Kernelkonfiguration</link>.</para>
-
- <sect2>
- <title>Creative, Advance und ESS Soundkarten</title>
-
- <para>F&uuml;r jede dieser Karten f&uuml;gen Sie die folgende Zeile
- zu Ihrer Kernelkonfiguration hinzu:</para>
-
- <programlisting>device pcm</programlisting>
-
- <para>ISA-Karten ben&ouml;tigen zus&auml;tzlich noch die
- Zeile:</para>
-
- <programlisting>device sbc</programlisting>
-
- <para>Nicht-PnP f&auml;hige ISA-Karten ben&ouml;tigen die Zeilen:</para>
-
- <programlisting>device pcm
-device sbc0 at isa? port 0x220 irq 5 drq 1 flags 0x15</programlisting>
-
- <para>Dies sind die
- Voreinstellungen. Sie werden unter Umst&auml;nden den IRQ oder
- andere Einstellungen anpassen m&uuml;ssen. In der &man.sbc.4;
- Manualpage finden Sie weitere Informationen dazu.</para>
-
- <note>
- <para>Die Karte Sound Blaster Live wird unter FreeBSD 4.0
- nicht unterst&uuml;tzt. Dazu ben&ouml;tigen Sie einen Patch,
- der in diesem Dokument nicht behandelt wird. Es ist deshalb
- empfehlenswert, dass Sie in diesem Fall Ihr System auf den
- neuesten -STABLE Stand aktualisieren, bevor Sie diese Karte
- benutzen k&ouml;nnen.</para>
- </note>
- </sect2>
-
- <sect2>
- <title>Gravis UltraSound Karten</title>
-
- <para>Eine PnP ISA-Karte ben&ouml;tigt die folgenden Zeilen in der
- Kernelkonfiguration:</para>
-
- <programlisting>device pcm
-device gusc</programlisting>
-
- <para>Wenn Sie eine nicht-PnP f&auml;hige ISA-Karte besitzen,
- f&uuml;gen Sie die folgenden Zeilen ein:</para>
-
- <programlisting>device pcm
-device gus0 at isa? port 0x220 irq 5 drq 1 flags 0x13</programlisting>
-
- <para>Es kann sein, dass Sie den
- IRQ oder andere Einstellungen Ihrer Karte anpassen
- m&uuml;ssen. Lesen Sie dazu die &man.gusc.4; Manualpage
- f&uuml;r weitere Informationen.</para>
- </sect2>
-
- <sect2>
- <title>Crystal Soundkarten</title>
-
- <para>In der Kernelkonfiguration geben Sie f&uuml;r Crystal Karten
- die beiden folgenden Zeilen an:</para>
-
- <programlisting>device pcm
-device csa</programlisting>
- </sect2>
-
- <sect2>
- <title>Allgemeine Unterst&uuml;tzung</title>
-
- <para>F&uuml;r PnP ISA- oder PCI-Karten f&uuml;gen Sie die folgende
- Zeile zu Ihrer Kernelkonfiguration hinzu:</para>
-
- <programlisting>device pcm</programlisting>
-
- <para>Wenn Sie eine nicht-PnP ISA-Karte besitzen, die keinen
- Bridge-Treiber hat, geben Sie zus&auml;tzlich die folgende Zeile
- an:</para>
-
- <programlisting>device pcm0 at isa? irq 10 drq 1 flags 0x0</programlisting>
-
- <para>&Auml;ndern Sie den IRQ oder
- andere Einstellungen so, dass sie Ihrer Soundkarte
- entsprechen.</para>
- </sect2>
-
- <sect2>
- <title>Onboard Sound</title>
-
- <para>Einige Systeme besitzen direkt auf dem Motherboard
- eingebaute Soundger&auml;te. Diese ben&ouml;tigen die folgende
- Angabe in Ihrer Kernelkonfiguration:</para>
-
- <programlisting>options PNPBIOS</programlisting>
- </sect2>
- </sect1>
-
- <sect1 id="sound-devicenodes">
- <title>Erstellen und Testen der Device Nodes</title>
-
- <indexterm><primary>Device Node</primary></indexterm>
- <indexterm><primary>Ger&auml;tedatei</primary></indexterm>
- <para>Nach einem Neustart loggen Sie sich ein und geben
- <command>dmesg | grep pcm</command> ein. Sie sollten etwas wie das
- folgende sehen:</para>
-
- <screen>&prompt.root; dmesg | grep pcm
-pcm0: &lt;SB16 DSP 4.11&gt; on sbc0</screen>
-
- <para>Die Ausgabe Ihres Systems kann anders aussehen. Erscheinen
- keine <devicename>pcm</devicename> Ger&auml;te, dann ist zuvor
- ein Fehler aufgetreten. Wenn das passiert, schauen Sie sich Ihre
- Kernelkonfiguration noch einmal an und vergewissern Sie sich,
- dass Sie den richtigen Treiber gew&auml;hlt haben. Lesen Sie den
- Abschnitt Fehlersuche f&uuml;r weitere Hinweise.</para>
-
- <para>Ergab der vorige Befehl <devicename>pcm0</devicename> als
- Ausgabe, dann m&uuml;ssen Sie folgendes als <username>root</username>
- ausf&uuml;hren:</para>
-
- <screen>&prompt.root; cd /dev
-&prompt.root; sh MAKEDEV snd0</screen>
-
- <para>Wenn auf den vorigen Befehl <devicename>pcm1</devicename>
- als Ausgabe erschienen ist, dann m&uuml;ssen Sie dieselben
- Befehle ausf&uuml;hren, nur dass Sie
- <devicename>snd0</devicename> durch
- <devicename>snd1</devicename> ersetzen.</para>
-
- <note>
- <para>Die obigen Kommandos legen <emphasis>kein</emphasis>
- <devicename>/dev/snd</devicename> Device an.</para>
- </note>
-
- <para>Der Befehl <command>MAKEDEV</command> erzeugt eine Gruppe
- von Device Nodes, darunter:</para>
-
- <informaltable frame="none">
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Device</entry>
- <entry>Beschreibung</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry><devicename>/dev/audio</devicename></entry>
- <entry>SPARC-compatible audio device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/dsp</devicename></entry>
- <entry>Digitized voice device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/dspW</devicename></entry>
- <entry><devicename>/dev/dsp</devicename>-&auml;hnliches
- Device mit 16 bits pro Sample</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/midi</devicename></entry>
- <entry>Raw midi access device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/mixer</devicename></entry>
- <entry>Control port mixer device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/music</devicename></entry>
- <entry>Level 2 sequencer interface</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/sequencer</devicename></entry>
- <entry>Sequencer device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/pss</devicename></entry>
- <entry>Programmable device interface</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
-
- <para>Wenn alles geklappt hat, haben Sie jetzt eine
- funktionierende Soundkarte. Nun k&ouml;nnen Sie eine Anwendung
- wie <filename role="package">audio/mpg123</filename> installieren,
- um Audiodateien anh&ouml;ren zu k&ouml;nnen.</para>
-
- <sect2>
- <title>H&auml;ufige Probleme</title>
-
- <informaltable>
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Fehler</entry>
- <entry>L&ouml;sung</entry>
- </row>
- </thead>
- <indexterm><primary>Device Node</primary></indexterm>
- <indexterm><primary>Ger&auml;tedatei</primary></indexterm>
-
- <tbody>
- <row>
- <entry><errorname>unsupported subdevice XX</errorname></entry>
- <entry><para>Ein oder mehrere Device Nodes wurden nicht
- korrekt angelegt. Wiederholen Sie die oben angegebenen
- Schritte.</para></entry>
- </row>
-
- <indexterm><primary>I/O port</primary></indexterm>
- <row>
- <entry><errorname>sb_dspwr(XX) timed out</errorname></entry>
- <entry><para>Der I/O Port ist nicht korrekt angegeben.</para></entry>
- </row>
-
- <indexterm><primary>IRQ</primary></indexterm>
- <row>
- <entry><errorname>bad irq XX</errorname></entry>
- <entry><para>Der IRQ ist falsch angegeben. Stellen Sie
- sicher, dass der angegebene IRQ mit dem Sound IRQ
- &uuml;bereinstimmt.</para></entry>
- </row>
-
- <row>
- <entry><errorname>xxx: gus pcm not attached, out of
- memory</errorname></entry>
- <entry><para>Es ist nicht genug Speicher verf&uuml;gbar,
- um das Ger&auml;t betreiben zu k&ouml;nnen.</para></entry>
- </row>
-
- <indexterm><primary>DSP</primary></indexterm>
- <row>
- <entry><errorname>xxx: can't open /dev/dsp!</errorname></entry>
- <entry><para>&Uuml;berpr&uuml;fen Sie mit <command>fstat |
- grep dsp</command> ob eine andere Anwendung das
- Ger&auml;t ge&ouml;ffnet hat. H&auml;ufige
- St&ouml;renfriede sind <application>esound</application>
- oder die Sound-Unterst&uuml;tzung von KDE.</para></entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- </sect2>
- </sect1>
-
- <sect1 id="sound-mp3">
- <sect1info>
- <authorgroup>
- <author>
- <firstname>Chern</firstname>
- <surname>Lee</surname>
- <contrib>Ein Beitrag von </contrib>
- </author>
- </authorgroup>
- <!-- 11 Sept 2001 -->
- <authorgroup>
- <author>
- <firstname>Benedikt</firstname>
- <surname>K&ouml;hler</surname>
- <contrib>&Uuml;bersetzt von </contrib>
- </author>
- </authorgroup>
- </sect1info>
-
- <title>MP3 Audio</title>
-
- <para>MP3 (MPEG Layer 3 Audio) erm&ouml;glicht eine
- Klangwiedergabe in CD-&auml;hnlicher Qualit&auml;t, was Sie sich
- auf Ihrem FreeBSD Rechner nicht entgehen lassen sollten.</para>
-
- <sect2 id="mp3-players">
- <title>MP3-Player</title>
-
- <para><application>XMMS</application> (X Multimedia System) ist
- bei weitem der beliebteste XFree86 MP3-Player.
- <application>WinAmp</application>-Skins k&ouml;nnen auch mit
- <application>XMMS</application> genutzt werden, da die
- Benutzerschnittstelle fast identisch mit der von Nullsofts
- <application>WinAmp</application> ist. Daneben
- unterst&uuml;tzt <application>XMMS</application> auch eigene
- Plugins.</para>
-
- <para><application>XMMS</application> kann als
- <filename role="package">audio/xmms</filename> Port oder Package installiert
- werden.</para>
-
- <para>Die Benutzerschnittstelle von
- <application>XMMS</application> ist leicht zu erlernen und
- beinhaltet eine Playlist, einen graphischen Equalizer und
- vieles mehr. Diejenigen, die mit WinAmp vertraut sind, werden
- <application>XMMS</application> sehr leicht zu benutzen
- finden.</para>
-
- <para>Der Port <filename role="package">audio/mpg123</filename> ist
- ein alternativer, kommandozeilenorientierter MP3-Player.</para>
-
- <para><application>mpg123</application> kann ausgef&uuml;hrt
- werden, in dem man das zu benutzende Sound Device und die
- abzuspielende MP3-Datei in der Kommandozeile wie unten
- angibt:</para>
-
- <screen>&prompt.root; mpg123 -a <replaceable>/dev/dsp1.0</replaceable> Foobar-GreatestHits.mp3
-High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2 and 3.
-Version 0.59r (1999/Jun/15). Written and copyrights by Michael Hipp.
-Uses code from various people. See 'README' for more!
-THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!
-
-
-
-
-
-Playing MPEG stream from BT - Foobar-GreastHits.mp3 ...
-MPEG 1.0 layer III, 128 kbit/s, 44100 Hz joint-stereo
-</screen>
-
- <para><literal>/dev/dsp1.0</literal> sollten Sie dabei mit dem
- <devicename>dsp</devicename>-Device Ihres Systems ersetzen.</para>
- </sect2>
-
- <sect2 id="rip-cd">
- <title>CD-Audio Tracks rippen</title>
-
- <para>Bevor man eine ganze CD oder einen CD-Track in das
- MP3-Format umwandeln kann, m&uuml;ssen die Audiodaten von der
- CD auf die Festplatte gerippt werden. Dabei werden die CDDA
- (CD Digital Audio) Rohdaten in WAV-Dateien kopiert.</para>
-
- <para>Die Anwendung <command>cdda2wav</command> die in dem
- <filename role="package">sysutils/cdrtools</filename> Paket enthalten
- ist, kann zum Rippen der Audiodaten und anderen Informationen von CDs
- genutzt werden.</para>
-
- <para>Wenn die Audio CD in dem Laufwerk liegt, k&ouml;nnen Sie
- mit folgenden Befehl (als <username>root</username>) eine
- ganze CD in einzelne WAV-Dateien (eine Datei f&uuml;r jeden
- Track) rippen:</para>
-
- <screen>&prompt.root; cdda2wav -D <replaceable>0,1,0</replaceable> -B</screen>
-
- <para>Der Schalter <option>-D
- <replaceable>0,1,0</replaceable></option> bezieht sich auf
- das SCSI Device <devicename>0,1,0</devicename>, dass sich aus
- dem Ergebnis des Befehls <command>cdrecord -scanbus</command>
- ergibt.</para>
-
- <para>Um einzelne Tracks zu rippen, benutzen Sie den
- <option>-t</option> Schalter wie folgt:</para>
-
- <screen>&prompt.root; cdda2wav -D <replaceable>0,1,0</replaceable> -t 7</screen>
-
- <para>Dieses Beispiel rippt den siebten Track der Audio
- CDROM. Um mehrere Tracks zu rippen, zum Beispiel die Tracks
- eins bis sieben, k&ouml;nnen Sie wie folgt einen Bereich
- angeben:</para>
-
- <screen>&prompt.root; cdda2wav -D <replaceable>0,1,0</replaceable> -t 1+7</screen>
-
- <para><application>cdda2wav</application> unterst&uuml;tzt auch ATAPI
- (IDE) CDROM Laufwerke. Wenn Sie ein IDE Laufwerk benutzen, geben
- Sie beim Aufruf von <command>cdda2wav</command> den
- Ger&auml;tenamen anstelle der SCSI Ger&auml;tenummern an. Um den
- siebten Track eines IDE Laufwerkes zu rippen, benutzen Sie das
- folgende Kommando:</para>
-
- <screen>&prompt.root; cdda2wav -D <replaceable>/dev/acd0a</replaceable> -t 7</screen>
- </sect2>
-
- <sect2 id="mp3-encoding">
- <title>MP3-Dateien kodieren</title>
-
- <para>Gegenw&auml;rtig ist <application>lame</application> der
- meistbenutzte mp3-Encoder. <application>Lame</application>
- finden Sie unter <filename role="package">audio/lame</filename> im
- Ports-Verzeichnis.</para>
-
- <para>Benutzen Sie die WAV-Dateien, die sie von CD gerippt
- haben, und wandeln sie mit dem folgenden Befehl die Datei
- <filename>audio01.wav</filename> in
- <filename>audio01.mp3</filename> um:</para>
-
- <screen>&prompt.root; lame -h -b <replaceable>128</replaceable> \
---tt "<replaceable>Foo Liedtitel</replaceable>" \
---ta "<replaceable>FooBar K&uuml;nstler</replaceable>" \
---tl "<replaceable>FooBar Album</replaceable>" \
---ty "<replaceable>2001</replaceable>" \
---tc "<replaceable>Geripped und kodiert von Foo</replaceable>" \
---tg "<replaceable>Musikrichtung</replaceable>" \
-<replaceable>audio01.wav audio01.mp3</replaceable></screen>
-
- <para>128 kbits ist die gew&ouml;hnliche MP3 Bitrate. Viele
- bevorzugen mit 160 oder 192 eine h&ouml;here Qualit&auml;t. Je
- h&ouml;her die Bitrate ist, desto mehr Speicherplatz
- ben&ouml;tigt die resultierende MP3-Datei, allerdings wird die
- Qualit&auml;t dadurch auch besser. Der Schalter
- <option>-h</option> verwendet den <quote>higher quality but a
- little slower</quote> (h&ouml;here Qualit&auml;t, aber etwas
- langsamer) Modus. Die Schalter, die mit
- <option>--t</option> beginnen, sind ID3-Tags, die in der Regel
- Informationen &uuml;ber das Lied enthalten und in die
- MP3-Datei eingebettet sind. Weitere Optionen k&ouml;nnen in
- der lame-Manualpage nachgelesen werden.</para>
- </sect2>
-
- <sect2 id="mp3-decoding">
- <title>MP3-Dateien dekodieren</title>
-
- <para>Um aus MP3-Dateien eine Audio CD zu erstellen, m&uuml;ssen
- diese in ein nicht komprimiertes WAV-Format umgewandelt
- werden. Sowohl <application>XMMS</application> als auch
- <application>mpg123</application> unterst&uuml;tzen die Ausgabe
- der MP3-Dateien in unkomprimierte Dateiformate.</para>
-
- <para>Dekodieren mit <application>XMMS</application>:</para>
-
- <procedure>
- <step>
- <para>Starten Sie <application>XMMS</application>.</para>
- </step>
-
- <step>
- <para>Klicken Sie mit der rechten Maustaste, um das
- <application>XMMS</application>-Menu zu &ouml;ffnen.</para>
- </step>
-
- <step>
- <para>W&auml;hlen Sie <literal>Preference</literal> im
- Untermen&uuml; <literal>Options</literal>.</para>
- </step>
-
- <step>
- <para>&Auml;ndern Sie das Output-Plugin in <quote>Disk
- Writer Plugin</quote>.</para>
- </step>
-
- <step>
- <para>Dr&uuml;cken Sie <literal>Configure</literal>.</para>
- </step>
-
- <step>
- <para>Geben Sie ein Verzeichnis ein (oder w&auml;hlen Sie
- browse), in das Sie die unkomprimierte Datei schreiben
- wollen.</para>
- </step>
-
- <step>
- <para>Laden Sie die MP3-Datei wie gewohnt in
- <application>XMMS</application> mit einer Lautst&auml;rke
- von 100% und einem abgeschalteten EQ.</para>
- </step>
-
- <step>
- <para>Dr&uuml;cken Sie <literal>Play</literal> und es wird
- so aussehen, als spiele <application>XMMS</application>
- die MP3-Datei ab, aber keine Musik ist zu h&ouml;ren. Der
- Player &uuml;berspielt die MP3-Datei in eine Datei.</para>
- </step>
-
- <step>
- <para>Vergessen Sie nicht, das Output Plugin wieder in den
- Ausgangszustand zur&uuml;ckzusetzen um wieder MP3-Dateien
- anh&ouml;ren zu k&ouml;nnen.</para>
- </step>
- </procedure>
-
- <para>Mit <application>mpg123</application> nach stdout schreiben:</para>
-
- <procedure>
- <step>
- <para>Geben Sie mpg123 -s
- <replaceable>audio01.mp3</replaceable> &gt; audio01.pcm
- ein</para>
- </step>
- </procedure>
-
- <para><application>XMMS</application> schreibt die Datei in dem
- WAV-Formal w&auml;hrend <application>mpg123</application> die
- MP3-Datei in rohe PCM Audiodaten umwandelt. Beide Formate
- k&ouml;nnen von <application>cdrecord</application> oder
- <application>burncd</application> verwendet werden, um Audio
- CDs zu schreiben.</para>
-
- <para>Lesen Sie <xref linkend="creating-cds"> in diesem Handbuch,
- um mehr Informationen zur Benutzung von CD-Brennern mit FreeBSD zu
- erhalten.</para>
- </sect2>
- </sect1>
-</chapter>
-
-<!--
- Local Variables:
- mode: sgml
- sgml-declaration: "../chapter.decl"
- sgml-indent-data: t
- sgml-omittag: nil
- sgml-always-quote-attributes: t
- sgml-parent-document: ("../book.sgml" "part" "chapter")
- End:
--->
-
diff --git a/en/handbook/contrib/chapter.sgml b/en/handbook/contrib/chapter.sgml
deleted file mode 100644
index 9a41073467..0000000000
--- a/en/handbook/contrib/chapter.sgml
+++ /dev/null
@@ -1,5796 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $Id: chapter.sgml,v 1.92 2000-03-19 06:20:31 vanilla Exp $
--->
-
-<chapter id="contrib">
- <title>Contributing to FreeBSD</title>
-
- <para><emphasis>Contributed by &a.jkh;.</emphasis></para>
-
- <para>So you want to contribute something to FreeBSD? That is great! We can
- always use the help, and FreeBSD is one of those systems that
- <emphasis>relies</emphasis> on the contributions of its user base in order
- to survive. Your contributions are not only appreciated, they are vital
- to FreeBSD's continued growth!</para>
-
- <para>Contrary to what some people might also have you believe, you do not
- need to be a hot-shot programmer or a close personal friend of the FreeBSD
- core team in order to have your contributions accepted. The FreeBSD
- Project's development is done by a large and growing number of
- international contributors whose ages and areas of technical expertise
- vary greatly, and there is always more work to be done than there are
- people available to do it.</para>
-
- <para>Since the FreeBSD project is responsible for an entire operating
- system environment (and its installation) rather than just a kernel or a
- few scattered utilities, our <filename>TODO</filename> list also spans a
- very wide range of tasks, from documentation, beta testing and
- presentation to highly specialized types of kernel development. No matter
- what your skill level, there is almost certainly something you can do to
- help the project!</para>
-
- <para>Commercial entities engaged in FreeBSD-related enterprises are also
- encouraged to contact us. Need a special extension to make your product
- work? You will find us receptive to your requests, given that they are not
- too outlandish. Working on a value-added product? Please let us know! We
- may be able to work cooperatively on some aspect of it. The free software
- world is challenging a lot of existing assumptions about how software is
- developed, sold, and maintained throughout its life cycle, and we urge you
- to at least give it a second look.</para>
-
- <sect1>
- <title>What Is Needed</title>
-
- <para>The following list of tasks and sub-projects represents something of
- an amalgam of the various core team <filename>TODO</filename> lists and
- user requests we have collected over the last couple of months. Where
- possible, tasks have been ranked by degree of urgency. If you are
- interested in working on one of the tasks you see here, send mail to the
- coordinator listed by clicking on their names. If no coordinator has
- been appointed, maybe you would like to volunteer?</para>
-
- <sect2>
- <title>High priority tasks</title>
-
- <para>The following tasks are considered to be urgent, usually because
- they represent something that is badly broken or sorely needed:</para>
-
- <orderedlist>
- <listitem>
- <para>3-stage boot issues. Overall coordination: &a.hackers;</para>
-
- <itemizedlist>
- <listitem>
- <para>Do WinNT compatible drive tagging so that the 3rd stage
- can provide an accurate mapping of BIOS geometries for
- disks.</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>Filesystem problems. Overall coordination: &a.fs;</para>
-
- <itemizedlist>
- <listitem>
- <para>Fix the MSDOS file system.</para>
- </listitem>
-
- <listitem>
- <para>Clean up and document the nullfs filesystem code.
- Coordinator: &a.eivind;</para>
- </listitem>
-
- <listitem>
- <para>Fix the union file system. Coordinator: &a.dg;</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>Implement Int13 vm86 disk driver. Coordinator:
- &a.hackers;</para>
- </listitem>
-
- <listitem>
- <para>New bus architecture. Coordinator: &a.newbus;</para>
-
- <itemizedlist>
- <listitem>
- <para>Port existing ISA drivers to new architecture.</para>
- </listitem>
-
- <listitem>
- <para>Move all interrupt-management code to appropriate parts of
- the bus drivers.</para>
- </listitem>
-
- <listitem>
- <para>Port PCI subsystem to new architecture. Coordinator:
- &a.dfr;</para>
- </listitem>
-
- <listitem>
- <para>Figure out the right way to handle removable devices and
- then use that as a substrate on which PC-Card and CardBus
- support can be implemented.</para>
- </listitem>
-
- <listitem>
- <para>Resolve the probe/attach priority issue once and for
- all.</para>
- </listitem>
-
- <listitem>
- <para>Move any remaining buses over to the new
- architecture.</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>Kernel issues. Overall coordination: &a.hackers;</para>
- </listitem>
-
- <listitem>
- <para>Add more pro-active security infrastructure. Overall
- coordination: &a.security;</para>
-
- <itemizedlist>
- <listitem>
- <para>Build something like Tripwire(TM) into the kernel, with a
- remote and local part. There are a number of cryptographic
- issues to getting this right; contact the coordinator for
- details. Coordinator: &a.eivind;</para>
- </listitem>
-
- <listitem>
- <para>Make the entire kernel use <literal>suser()</literal>
- instead of comparing to 0. It is presently using about half
- of each. Coordinator: &a.eivind;</para>
- </listitem>
-
- <listitem>
- <para>Split securelevels into different parts, to allow an
- administrator to throw away those privileges he can throw
- away. Setting the overall securelevel needs to have the same
- effect as now, obviously. Coordinator: &a.eivind;</para>
- </listitem>
-
- <listitem>
- <para>Make it possible to upload a list of &ldquo;allowed
- program&rdquo; to BPF, and then block BPF from accepting other
- programs. This would allow BPF to be used e.g. for DHCP,
- without allowing an attacker to start snooping the local
- network.</para>
- </listitem>
-
- <listitem>
- <para>Update the security checker script. We should at least
- grab all the checks from the other BSD derivatives, and add
- checks that a system with securelevel increased also have
- reasonable flags on the relevant parts. Coordinator:
- &a.eivind;</para>
- </listitem>
-
- <listitem>
- <para>Add authorization infrastructure to the kernel, to allow
- different authorization policies. Part of this could be done
- by modifying <literal>suser()</literal>. Coordinator:
- &a.eivind;</para>
- </listitem>
-
- <listitem>
- <para>Add code to the NFS layer so that you cannot
- <literal>chdir("..")</literal> out of an NFS partition. E.g.,
- <filename>/usr</filename> is a UFS partition with
- <filename>/usr/src</filename> NFS exported. Now it is
- possible to use the NFS filehandle for
- <filename>/usr/src</filename> to get access to
- <filename>/usr</filename>.</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </orderedlist>
- </sect2>
-
- <sect2>
- <title>Medium priority tasks</title>
-
- <para>The following tasks need to be done, but not with any particular
- urgency:</para>
-
- <orderedlist>
- <listitem>
- <para>Full KLD based driver support/Configuration Manager.</para>
-
- <itemizedlist>
- <listitem>
- <para>Write a configuration manager (in the 3rd stage boot?)
- that probes your hardware in a sane manner, keeps only the
- KLDs required for your hardware, etc.</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>PCMCIA/PCCARD. Coordinators: &a.msmith; and &a.phk;</para>
-
- <itemizedlist>
- <listitem>
- <para>Documentation!</para>
- </listitem>
-
- <listitem>
- <para>Reliable operation of the pcic driver (needs
- testing).</para>
- </listitem>
-
- <listitem>
- <para>Recognizer and handler for <filename>sio.c</filename>
- (mostly done).</para>
- </listitem>
-
- <listitem>
- <para>Recognizer and handler for <filename>ed.c</filename>
- (mostly done).</para>
- </listitem>
-
- <listitem>
- <para>Recognizer and handler for <filename>ep.c</filename>
- (mostly done).</para>
- </listitem>
-
- <listitem>
- <para>User-mode recognizer and handler (partially done).</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>Advanced Power Management. Coordinators: &a.msmith; and
- &a.phk;</para>
-
- <itemizedlist>
- <listitem>
- <para>APM sub-driver (mostly done).</para>
- </listitem>
-
- <listitem>
- <para>IDE/ATA disk sub-driver (partially done).</para>
- </listitem>
-
- <listitem>
- <para>syscons/pcvt sub-driver.</para>
- </listitem>
-
- <listitem>
- <para>Integration with the PCMCIA/PCCARD drivers
- (suspend/resume).</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </orderedlist>
- </sect2>
-
- <sect2>
- <title>Low priority tasks</title>
-
- <para>The following tasks are purely cosmetic or represent such an
- investment of work that it is not likely that anyone will get them
- done anytime soon:</para>
-
- <para>The first N items are from Terry Lambert
- <email>terry@lambert.org</email></para>
-
- <orderedlist>
- <listitem>
- <para>NetWare Server (protected mode ODI driver) loader and
- subservices to allow the use of ODI card drivers supplied with
- network cards. The same thing for NDIS drivers and NetWare SCSI
- drivers.</para>
- </listitem>
-
- <listitem>
- <para>An "upgrade system" option that works on Linux boxes instead
- of just previous rev FreeBSD boxes.</para>
- </listitem>
-
- <listitem>
- <para>Symmetric Multiprocessing with kernel preemption (requires
- kernel preemption).</para>
- </listitem>
-
- <listitem>
- <para>A concerted effort at support for portable computers. This is
- somewhat handled by changing PCMCIA bridging rules and power
- management event handling. But there are things like detecting
- internal vs. external display and picking a different screen
- resolution based on that fact, not spinning down the disk if the
- machine is in dock, and allowing dock-based cards to disappear
- without affecting the machines ability to boot (same issue for
- PCMCIA).</para>
- </listitem>
- </orderedlist>
- </sect2>
-
- <sect2>
- <title>Smaller tasks</title>
-
- <para>Most of the tasks listed in the previous sections require either a
- considerable investment of time or an in-depth knowledge of the
- FreeBSD kernel (or both). However, there are also many useful tasks
- which are suitable for &quot;weekend hackers&quot;, or people without
- programming skills.</para>
-
- <orderedlist>
- <listitem>
- <para>If you run FreeBSD-current and have a good Internet
- connection, there is a machine <hostid
- role="fqdn">current.FreeBSD.org</hostid> which builds a full
- release once a day &mdash; every now and again, try and install
- the latest release from it and report any failures in the
- process.</para>
- </listitem>
-
- <listitem>
- <para>Read the freebsd-bugs mailing list. There might be a
- problem you can comment constructively on or with patches you
- can test. Or you could even try to fix one of the problems
- yourself.</para>
- </listitem>
-
- <listitem>
- <para>Read through the FAQ and Handbook periodically. If anything
- is badly explained, out of date or even just completely wrong, let
- us know. Even better, send us a fix (SGML is not difficult to
- learn, but there is no objection to ASCII submissions).</para>
- </listitem>
-
- <listitem>
- <para>Help translate FreeBSD documentation into your native language
- (if not already available) &mdash; just send an email to &a.doc;
- asking if anyone is working on it. Note that you are not
- committing yourself to translating every single FreeBSD document
- by doing this &mdash; in fact, the documentation most in need of
- translation is the installation instructions.</para>
- </listitem>
-
- <listitem>
- <para>Read the freebsd-questions mailing list and &ng.misc
- occasionally (or even regularly). It can be very satisfying to
- share your expertise and help people solve their problems;
- sometimes you may even learn something new yourself! These forums
- can also be a source of ideas for things to work on.</para>
- </listitem>
-
- <listitem>
- <para>If you know of any bugfixes which have been successfully
- applied to -current but have not been merged into -stable after a
- decent interval (normally a couple of weeks), send the committer a
- polite reminder.</para>
- </listitem>
-
- <listitem>
- <para>Move contributed software to <filename>src/contrib</filename>
- in the source tree.</para>
- </listitem>
-
- <listitem>
- <para>Make sure code in <filename>src/contrib</filename> is up to
- date.</para>
- </listitem>
-
- <listitem>
- <para>Look for year 2000 bugs (and fix any you find!)</para>
- </listitem>
-
- <listitem>
- <para>Build the source tree (or just part of it) with extra warnings
- enabled and clean up the warnings.</para>
- </listitem>
-
- <listitem>
- <para>Fix warnings for ports which do deprecated things like using
- gets() or including malloc.h.</para>
- </listitem>
-
- <listitem>
- <para>If you have contributed any ports, send your patches back to
- the original author (this will make your life easier when they
- bring out the next version)</para>
- </listitem>
-
- <listitem>
- <para>Suggest further tasks for this list!</para>
- </listitem>
- </orderedlist>
- </sect2>
-
- <sect2>
- <title>Work through the PR database</title>
-
- <para>The <ulink
- url="http://www.FreeBSD.org/cgi/query-pr-summary.cgi">FreeBSD PR
- list</ulink> shows all the current active problem reports and
- requests for enhancement that have been submitted by FreeBSD users.
- Look through the open PRs, and see if anything there takes your
- interest. Some of these might be very simple tasks, that just need an
- extra pair of eyes to look over them and confirm that the fix in the
- PR is a good one. Others might be much more complex.</para>
-
- <para>Start with the PRs that have not been assigned to anyone else, but
- if one them is assigned to someone else, but it looks like something
- you can handle, e-mail the person it is assigned to and ask if you can
- work on it&mdash;they might already have a patch ready to be tested,
- or further ideas that you can discuss with them.</para>
- </sect2>
- </sect1>
-
- <sect1>
- <title>How to Contribute</title>
-
- <para>Contributions to the system generally fall into one or more of the
- following 6 categories:</para>
-
- <sect2 id="contrib-general">
- <title>Bug reports and general commentary</title>
-
- <para>An idea or suggestion of <emphasis>general</emphasis> technical
- interest should be mailed to the &a.hackers;. Likewise, people with
- an interest in such things (and a tolerance for a
- <emphasis>high</emphasis> volume of mail!) may subscribe to the
- hackers mailing list by sending mail to &a.majordomo;. See <link
- linkend="eresources-mail">mailing lists</link> for more information
- about this and other mailing lists.</para>
-
- <para>If you find a bug or are submitting a specific change, please
- report it using the &man.send-pr.1; program or its <ulink
- URL="http://www.FreeBSD.org/send-pr.html">WEB-based
- equivalent</ulink>. Try to fill-in each field of the bug report.
- Unless they exceed 65KB, include any patches directly in the report.
- When including patches, <emphasis>do not</emphasis> use cut-and-paste
- because cut-and-paste turns tabs into spaces and makes them unusable.
- Consider compressing patches and using &man.uuencode.1; if they exceed
- 20KB. Upload very large submissions to <ulink
- url="ftp://ftp.FreeBSD.org/pub/FreeBSD/incoming/">ftp.FreeBSD.org:/pub/FreeBSD/incoming/</ulink>.</para>
-
- <para>After filing a report, you should receive confirmation along with
- a tracking number. Keep this tracking number so that you can update
- us with details about the problem by sending mail to
- <email>bug-followup@FreeBSD.org</email>. Use the number as the
- message subject, e.g. <literal>"Re: kern/3377"</literal>. Additional
- information for any bug report should be submitted this way.</para>
-
- <para>If you do not receive confirmation in a timely fashion (3 days to
- a week, depending on your email connection) or are, for some reason,
- unable to use the &man.send-pr.1; command, then you may ask
- someone to file it for you by sending mail to the &a.bugs;.</para>
- </sect2>
-
- <sect2>
- <title>Changes to the documentation</title>
-
- <para>Changes to the documentation are overseen by the &a.doc;. Send
- submissions and changes (even small ones are welcome!) using
- <command>send-pr</command> as described in <link
- linkend="contrib-general">Bug Reports and General
- Commentary</link>.</para>
- </sect2>
-
- <sect2>
- <title>Changes to existing source code</title>
-
- <para>An addition or change to the existing source code is a somewhat
- trickier affair and depends a lot on how far out of date you are with
- the current state of the core FreeBSD development. There is a special
- on-going release of FreeBSD known as &ldquo;FreeBSD-current&rdquo;
- which is made available in a variety of ways for the convenience of
- developers working actively on the system. See <link
- linkend="current">Staying current with FreeBSD</link> for more
- information about getting and using FreeBSD-current.</para>
-
- <para>Working from older sources unfortunately means that your changes
- may sometimes be too obsolete or too divergent for easy re-integration
- into FreeBSD. Chances of this can be minimized somewhat by
- subscribing to the &a.announce; and the &a.current; lists, where
- discussions on the current state of the system take place.</para>
-
- <para>Assuming that you can manage to secure fairly up-to-date sources
- to base your changes on, the next step is to produce a set of diffs to
- send to the FreeBSD maintainers. This is done with the &man.diff.1;
- command, with the &ldquo;context diff&rdquo; form
- being preferred. For example:</para>
-
- <para>
- <screen>&prompt.user; <userinput>diff -c oldfile newfile</userinput></screen>
-
- or
-
- <screen>&prompt.user; <userinput>diff -c -r olddir newdir</userinput></screen>
-
- would generate such a set of context diffs for the given source file
- or directory hierarchy. See the man page for &man.diff.1; for more
- details.</para>
-
- <para>Once you have a set of diffs (which you may test with the
- &man.patch.1; command), you should submit them for inclusion with
- FreeBSD. Use the &man.send-pr.1; program as described in <link
- linkend="contrib-general">Bug Reports and General Commentary</link>.
- <emphasis>Do not</emphasis> just send the diffs to the &a.hackers; or
- they will get lost! We greatly appreciate your submission (this is a
- volunteer project!); because we are busy, we may not be able to
- address it immediately, but it will remain in the pr database until we
- do.</para>
-
- <para>If you feel it appropriate (e.g. you have added, deleted, or
- renamed files), bundle your changes into a <command>tar</command> file
- and run the &man.uuencode.1; program on it. Shar archives are also
- welcome.</para>
-
- <para>If your change is of a potentially sensitive nature, e.g. you are
- unsure of copyright issues governing its further distribution or you
- are simply not ready to release it without a tighter review first,
- then you should send it to &a.core; directly rather than submitting it
- with &man.send-pr.1;. The core mailing list reaches a much smaller
- group of people who do much of the day-to-day work on FreeBSD. Note
- that this group is also <emphasis>very busy</emphasis> and so you
- should only send mail to them where it is truly necessary.</para>
-
- <para>Please refer to <command>man 9 intro</command> and <command>man 9
- style</command> for some information on coding style. We would
- appreciate it if you were at least aware of this information before
- submitting code.</para>
- </sect2>
-
- <sect2>
- <title>New code or major value-added packages</title>
-
- <para>In the rare case of a significant contribution of a large body
- work, or the addition of an important new feature to FreeBSD, it
- becomes almost always necessary to either send changes as uuencode'd
- tar files or upload them to our ftp site <ulink
- URL="ftp://ftp.FreeBSD.org/pub/FreeBSD/incoming">ftp://ftp.FreeBSD.org/pub/FreeBSD/incoming</ulink>.</para>
-
- <para>When working with large amounts of code, the touchy subject of
- copyrights also invariably comes up. Acceptable copyrights for code
- included in FreeBSD are:</para>
-
- <orderedlist>
- <listitem>
- <para>The BSD copyright. This copyright is most preferred due to
- its &ldquo;no strings attached&rdquo; nature and general
- attractiveness to commercial enterprises. Far from discouraging
- such commercial use, the FreeBSD Project actively encourages such
- participation by commercial interests who might eventually be
- inclined to invest something of their own into FreeBSD.</para>
- </listitem>
-
- <listitem>
- <para>The GNU Public License, or &ldquo;GPL&rdquo;. This license is
- not quite as popular with us due to the amount of extra effort
- demanded of anyone using the code for commercial purposes, but
- given the sheer quantity of GPL'd code we currently require
- (compiler, assembler, text formatter, etc) it would be silly to
- refuse additional contributions under this license. Code under
- the GPL also goes into a different part of the tree, that being
- <filename>/sys/gnu</filename> or
- <filename>/usr/src/gnu</filename>, and is therefore easily
- identifiable to anyone for whom the GPL presents a problem.</para>
- </listitem>
- </orderedlist>
-
- <para>Contributions coming under any other type of copyright must be
- carefully reviewed before their inclusion into FreeBSD will be
- considered. Contributions for which particularly restrictive
- commercial copyrights apply are generally rejected, though the authors
- are always encouraged to make such changes available through their own
- channels.</para>
-
- <para>To place a &ldquo;BSD-style&rdquo; copyright on your work, include
- the following text at the very beginning of every source code file you
- wish to protect, replacing the text between the <literal>%%</literal>
- with the appropriate information.</para>
-
- <programlisting>
-Copyright (c) %%proper_years_here%%
- %%your_name_here%%, %%your_state%% %%your_zip%%.
- All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer as
- the first lines of this file unmodified.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY %%your_name_here%% ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL %%your_name_here%% BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- &#36;Id&#36;</programlisting>
-
- <para>For your convenience, a copy of this text can be found in
- <filename>/usr/share/examples/etc/bsd-style-copyright</filename>.</para>
- </sect2>
-
- <sect2>
- <title>Money, Hardware or Internet access</title>
-
- <para>We are always very happy to accept donations to further the cause
- of the FreeBSD Project and, in a volunteer effort like ours, a little
- can go a long way! Donations of hardware are also very important to
- expanding our list of supported peripherals since we generally lack
- the funds to buy such items ourselves.</para>
-
- <sect3>
- <title><anchor id="donations">Donating funds</title>
-
- <para>While the FreeBSD Project is not a 501(c)(3) (charitable)
- corporation and hence cannot offer special tax incentives for any
- donations made, any such donations will be gratefully accepted on
- behalf of the project by FreeBSD, Inc.</para>
-
- <para>FreeBSD, Inc. was founded in early 1995 by &a.jkh; and &a.dg;
- with the goal of furthering the aims of the FreeBSD Project and
- giving it a minimal corporate presence. Any and all funds donated
- (as well as any profits that may eventually be realized by FreeBSD,
- Inc.) will be used exclusively to further the project's
- goals.</para>
-
- <para>Please make any checks payable to FreeBSD, Inc., sent in care of
- the following address:</para>
-
- <address>
- <otheraddr>FreeBSD, Inc.</otheraddr>
- <otheraddr>c/o Jordan Hubbard</otheraddr>
- <street>4041 Pike Lane, Suite F</street>
- <city>Concord</city>
- <state>CA</state>, <postcode>94520</postcode>
- </address>
-
- <para>(currently using the Walnut Creek CDROM address until a PO box
- can be opened)</para>
-
- <para>Wire transfers may also be sent directly to:</para>
-
- <address>
- <otheraddr>Bank Of America</otheraddr>
- <otheraddr>Concord Main Office</otheraddr>
- <pob>P.O. Box 37176</pob>
- <city>San Francisco</city>
- <state>CA</state>, <postcode>94137-5176</postcode>
-
- <otheraddr>Routing #: 121-000-358</otheraddr>
- <otheraddr>Account #: 01411-07441 (FreeBSD, Inc.)</otheraddr>
- </address>
-
- <para>Any correspondence related to donations should be sent to &a.jkh,
- either via email or to the FreeBSD, Inc. postal address given above.
- </para>
-
- <para>If you do not wish to be listed in our <link
- linkend="donors">donors</link> section, please specify this when
- making your donation. Thanks!</para>
- </sect3>
-
- <sect3>
- <title>Donating hardware</title>
-
- <para>Donations of hardware in any of the 3 following categories are
- also gladly accepted by the FreeBSD Project:</para>
-
- <itemizedlist>
- <listitem>
- <para>General purpose hardware such as disk drives, memory or
- complete systems should be sent to the FreeBSD, Inc. address
- listed in the <emphasis>donating funds</emphasis>
- section.</para>
- </listitem>
-
- <listitem>
- <para>Hardware for which ongoing compliance testing is desired.
- We are currently trying to put together a testing lab of all
- components that FreeBSD supports so that proper regression
- testing can be done with each new release. We are still lacking
- many important pieces (network cards, motherboards, etc) and if
- you would like to make such a donation, please contact &a.dg;
- for information on which items are still required.</para>
- </listitem>
-
- <listitem>
- <para>Hardware currently unsupported by FreeBSD for which you
- would like to see such support added. Please contact the
- &a.core; before sending such items as we will need to find a
- developer willing to take on the task before we can accept
- delivery of new hardware.</para>
- </listitem>
- </itemizedlist>
- </sect3>
-
- <sect3>
- <title>Donating Internet access</title>
-
- <para>We can always use new mirror sites for FTP, WWW or
- <command>cvsup</command>. If you would like to be such a mirror,
- please contact the FreeBSD project administrators
- <email>admin@FreeBSD.org</email> for more information.</para>
- </sect3>
- </sect2>
- </sect1>
-
- <sect1 id="donors">
- <title>Donors Gallery</title>
-
- <para>The FreeBSD Project is indebted to the following donors and would
- like to publically thank them here!</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>Contributors to the central server
- project:</emphasis></para>
-
- <para>The following individuals and businesses made it possible for
- the FreeBSD Project to build a new central server machine to
- eventually replace <hostid role="fqdn">freefall.FreeBSD.org</hostid>
- by donating the following items:</para>
-
- <itemizedlist>
- <listitem>
- <para>&a.mbarkah and his employer, <ulink URL="http://www.hemi.com">
- Hemisphere Online</ulink>, donated a <emphasis>Pentium Pro
- (P6) 200Mhz CPU</emphasis></para>
- </listitem>
-
- <listitem>
- <para><ulink URL="http://www.asacomputers.com">ASA
- Computers</ulink> donated a <emphasis>Tyan 1662
- motherboard</emphasis>.</para>
- </listitem>
-
- <listitem>
- <para>Joe McGuckin <email>joe@via.net</email> of <ulink
- URL="http://www.via.net">ViaNet Communications</ulink> donated
- a <emphasis>Kingston ethernet controller.</emphasis></para>
- </listitem>
-
- <listitem>
- <para>Jack O'Neill <email>jack@diamond.xtalwind.net</email>
- donated an <emphasis>NCR 53C875 SCSI controller
- card</emphasis>.</para>
- </listitem>
-
- <listitem>
- <para>Ulf Zimmermann <email>ulf@Alameda.net</email> of <ulink
- URL="http://www.Alameda.net">Alameda Networks</ulink> donated
- <emphasis>128MB of memory</emphasis>, a <emphasis>4 Gb disk
- drive and the case.</emphasis></para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para><emphasis>Direct funding:</emphasis></para>
-
- <para>The following individuals and businesses have generously
- contributed direct funding to the project:</para>
-
- <itemizedlist>
- <listitem>
- <para>Annelise Anderson
- <email>ANDRSN@HOOVER.STANFORD.EDU</email></para>
- </listitem>
-
- <listitem>
- <para>&a.dillon</para>
- </listitem>
-
- <listitem>
- <para><ulink URL="http://www.epilogue.com/">Epilogue Technology
- Corporation</ulink></para>
- </listitem>
-
- <listitem>
- <para>&a.sef</para>
- </listitem>
-
- <listitem>
- <para>Don Scott Wilde</para>
- </listitem>
-
- <listitem>
- <para>Gianmarco Giovannelli
- <email>gmarco@masternet.it</email></para>
- </listitem>
-
- <listitem>
- <para>Josef C. Grosch <email>joeg@truenorth.org</email></para>
- </listitem>
-
- <listitem>
- <para>Robert T. Morris</para>
- </listitem>
-
- <listitem>
- <para>&a.chuckr</para>
- </listitem>
-
- <listitem>
- <para>Kenneth P. Stox <email>ken@stox.sa.enteract.com</email> of
- <ulink URL="http://www.imagescape.com">Imaginary Landscape,
- LLC.</ulink></para>
- </listitem>
-
- <listitem>
- <para>Dmitry S. Kohmanyuk <email>dk@dog.farm.org</email></para>
- </listitem>
-
- <listitem>
- <para><ulink URL="http://www.cdrom.co.jp/">Laser5</ulink> of Japan
- (a portion of the profits from sales of their various FreeBSD
- CD-ROMs.</para>
- </listitem>
-
- <listitem>
- <para><ulink URL="http://www.mmjp.or.jp/fuki/">Fuki Shuppan
- Publishing Co.</ulink> donated a portion of their profits from
- <emphasis>Hajimete no FreeBSD</emphasis> (FreeBSD, Getting
- started) to the FreeBSD and XFree86 projects.</para>
- </listitem>
-
- <listitem>
- <para><ulink URL="http://www.ascii.co.jp/">ASCII Corp.</ulink>
- donated a portion of their profits from several FreeBSD-related
- books to the FreeBSD project.</para>
- </listitem>
-
- <listitem>
- <para><ulink URL="http://www.yokogawa.co.jp/">Yokogawa Electric
- Corp</ulink> has generously donated significant funding to the
- FreeBSD project.</para>
- </listitem>
-
- <listitem>
- <para><ulink URL="http://www.buffnet.net/">BuffNET</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink url="http://www.pacificsolutions.com/">Pacific
- Solutions</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink url="http://www.siemens.de/">Siemens AG</ulink>
- via <ulink url="mailto:andre.albsmeier@mchp.siemens.de">Andre
- Albsmeier</ulink></para>
- </listitem>
-
- <listitem>
- <para><ulink url="mailto:ras@interaccess.com">Chris Silva</ulink>
- </para>
- </listitem>
-
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para><emphasis>Hardware contributors:</emphasis></para>
-
- <para>The following individuals and businesses have generously
- contributed hardware for testing and device driver
- development/support:</para>
-
- <itemizedlist>
- <listitem>
- <para>Walnut Creek CDROM for providing the Pentium P5-90 and
- 486/DX2-66 EISA/VL systems that are being used for our
- development work, to say nothing of the network access and other
- donations of hardware resources.</para>
- </listitem>
-
- <listitem>
- <para>TRW Financial Systems, Inc. provided 130 PCs, three 68 GB
- fileservers, twelve Ethernets, two routers and an ATM switch for
- debugging the diskless code.</para>
- </listitem>
-
- <listitem>
- <para>Dermot McDonnell donated the Toshiba XM3401B CDROM drive
- currently used in freefall.</para>
- </listitem>
-
- <listitem>
- <para>&a.chuck; contributed his floppy tape streamer for
- experimental work.</para>
- </listitem>
-
- <listitem>
- <para>Larry Altneu <email>larry@ALR.COM</email>, and &a.wilko;,
- provided Wangtek and Archive QIC-02 tape drives in order to
- improve the <devicename>wt</devicename> driver.</para>
- </listitem>
-
- <listitem>
- <para>Ernst Winter <email>ewinter@lobo.muc.de</email> contributed
- a 2.88 MB floppy drive to the project. This will hopefully
- increase the pressure for rewriting the floppy disk driver.
- <!-- smiley -->;-)</para>
- </listitem>
-
- <listitem>
- <para><ulink URL="http://www.tekram.com">Tekram
- Technologies</ulink> sent one each of their DC-390, DC-390U
- and DC-390F FAST and ULTRA SCSI host adapter cards for
- regression testing of the NCR and AMD drivers with their cards.
- They are also to be applauded for making driver sources for free
- operating systems available from their FTP server <ulink
- URL="ftp://ftp.tekram.com/scsi/FreeBSD">ftp://ftp.tekram.com/scsi/FreeBSD</ulink>.</para>
- </listitem>
-
- <listitem>
- <para><email>Larry M. Augustin</email> contributed not only a
- Symbios Sym8751S SCSI card, but also a set of data books,
- including one about the forthcoming Sym53c895 chip with Ultra-2
- and LVD support, and the latest programming manual with
- information on how to safely use the advanced features of the
- latest Symbios SCSI chips. Thanks a lot!</para>
- </listitem>
-
- <listitem>
- <para>Christoph Kukulies <email>kuku@FreeBSD.org</email> donated
- an FX120 12 speed Mitsumi CDROM drive for IDE CDROM driver
- development.</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para><emphasis>Special contributors:</emphasis></para>
-
- <itemizedlist>
- <listitem>
- <para><ulink URL="http://www.cdrom.com">Walnut Creek CDROM</ulink>
- has donated almost more than we can say (see the <link
- linkend="history">history</link> document for more details).
- In particular, we would like to thank them for the original
- hardware used for <hostid
- role="fqdn">freefall.FreeBSD.org</hostid>, our primary
- development machine, and for <hostid
- role="fqdn">thud.FreeBSD.org</hostid>, a testing and build
- box. We are also indebted to them for funding various
- contributors over the years and providing us with unrestricted
- use of their T1 connection to the Internet.</para>
- </listitem>
-
- <listitem>
- <para>The <ulink URL="http://www.interface-business.de">interface
- business GmbH, Dresden</ulink> has been patiently supporting
- &a.joerg; who has often preferred FreeBSD work over paywork, and
- used to fall back to their (quite expensive) EUnet Internet
- connection whenever his private connection became too slow or
- flakey to work with it...</para>
- </listitem>
-
- <listitem>
- <para><ulink URL="http://www.bsdi.com">Berkeley Software Design,
- Inc.</ulink> has contributed their DOS emulator code to the
- remaining BSD world, which is used in the
- <emphasis>doscmd</emphasis> command.</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- </sect1>
-
- <sect1>
- <title>Core Team Alumni</title>
-
- <para>The following people were members of the FreeBSD core team during
- the periods indicated. We thank them for their past efforts in the
- service of the FreeBSD project.</para>
-
- <para><emphasis>In rough chronological order:</emphasis></para>
-
- <itemizedlist>
- <listitem>
- <para>&a.guido (1995 - 1999)</para>
- </listitem>
-
- <listitem>
- <para>&a.dyson (1993 - 1998)</para>
- </listitem>
-
- <listitem>
- <para>&a.nate (1992 - 1996)</para>
- </listitem>
-
- <listitem>
- <para>&a.rgrimes (1992 - 1995)</para>
- </listitem>
-
- <listitem>
- <para>Andreas Schulz (1992 - 1995)</para>
- </listitem>
-
- <listitem>
- <para>&a.csgr (1993 - 1995)</para>
- </listitem>
-
- <listitem>
- <para>&a.paul (1992 - 1995)</para>
- </listitem>
-
- <listitem>
- <para>&a.smace (1993 - 1994)</para>
- </listitem>
-
- <listitem>
- <para>Andrew Moore (1993 - 1994)</para>
- </listitem>
-
- <listitem>
- <para>Christoph Robitschko (1993 - 1994)</para>
- </listitem>
-
- <listitem>
- <para>J. T. Conklin (1992 - 1993)</para>
- </listitem>
- </itemizedlist>
- </sect1>
-
- <sect1>
- <title>Derived Software Contributors</title>
-
- <para>This software was originally derived from William F. Jolitz's 386BSD
- release 0.1, though almost none of the original 386BSD specific code
- remains. This software has been essentially re-implemented from the
- 4.4BSD-Lite release provided by the Computer Science Research Group
- (CSRG) at the University of California, Berkeley and associated academic
- contributors.</para>
-
- <para>There are also portions of NetBSD and OpenBSD that have been
- integrated into FreeBSD as well, and we would therefore like to thank
- all the contributors to NetBSD and OpenBSD for their work.</para>
- </sect1>
-
- <sect1 id="contrib-additional">
- <title>Additional FreeBSD Contributors</title>
-
- <para>(in alphabetical order by first name):</para>
-
- <itemizedlist>
- <listitem>
- <para>ABURAYA Ryushirou <email>rewsirow@ff.iij4u.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>AMAGAI Yoshiji <email>amagai@nue.org</email></para>
- </listitem>
-
- <listitem>
- <para>Aaron Bornstein <email>aaronb@j51.com</email></para>
- </listitem>
-
- <listitem>
- <para>Aaron Smith <email>aaron@mutex.org</email></para>
- </listitem>
-
- <listitem>
- <para>Achim Patzner <email>ap@noses.com</email></para>
- </listitem>
-
- <listitem>
- <para>Ada T Lim <email>ada@bsd.org</email></para>
- </listitem>
-
- <listitem>
- <para>Adam Baran <email>badam@mw.mil.pl</email></para>
- </listitem>
-
- <listitem>
- <para>Adam Glass <email>glass@postgres.berkeley.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Adam McDougall <email>mcdouga9@egr.msu.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Adrian Colley <email>aecolley@ois.ie</email></para>
- </listitem>
-
- <listitem>
- <para>Adrian Hall <email>adrian@ibmpcug.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Adrian Mariano <email>adrian@cam.cornell.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Adrian Steinmann <email>ast@marabu.ch</email></para>
- </listitem>
-
- <listitem>
- <para>Adam Strohl <email>troll@digitalspark.net</email></para>
- </listitem>
-
- <listitem>
- <para>Adrian T. Filipi-Martin
- <email>atf3r@agate.cs.virginia.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Ajit Thyagarajan <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Akio Morita
- <email>amorita@meadow.scphys.kyoto-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Akira SAWADA <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Akira Watanabe
- <email>akira@myaw.ei.meisei-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Akito Fujita <email>fujita@zoo.ncl.omron.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Alain Kalker
- <email>A.C.P.M.Kalker@student.utwente.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Alan Bawden <email>alan@curry.epilogue.com</email></para>
- </listitem>
-
- <listitem>
- <para>Alec Wolman <email>wolman@cs.washington.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Aled Morris <email>aledm@routers.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Alex <email>garbanzo@hooked.net</email></para>
- </listitem>
-
- <listitem>
- <para>Alex D. Chen
- <email>dhchen@Canvas.dorm7.nccu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Alex G. Bulushev <email>bag@demos.su</email></para>
- </listitem>
-
- <listitem>
- <para>Alex Le Heux <email>alexlh@funk.org</email></para>
- </listitem>
-
- <listitem>
- <para>Alex Perel <email>veers@disturbed.net</email></para>
- </listitem>
-
- <listitem>
- <para>Alexander B. Povolotsky <email>tarkhil@mgt.msk.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Alexander Leidinger
- <email>netchild@wurzelausix.CS.Uni-SB.DE</email></para>
- </listitem>
-
- <listitem>
- <para>Alexander Langer <email>alex@cichlids.com</email></para>
- </listitem>
-
- <listitem>
- <para>Alexandre Snarskii <email>snar@paranoia.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Alistair G. Crooks <email>agc@uts.amdahl.com</email></para>
- </listitem>
-
- <listitem>
- <para>Allan Saddi <email>asaddi@philosophysw.com</email></para>
- </listitem>
-
- <listitem>
- <para>Allen Campbell <email>allenc@verinet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Amakawa Shuhei <email>amakawa@hoh.t.u-tokyo.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Amancio Hasty <email>hasty@star-gate.com</email></para>
- </listitem>
-
- <listitem>
- <para>Amir Farah <email>amir@comtrol.com</email></para>
- </listitem>
-
- <listitem>
- <para>Amy Baron <email>amee@beer.org</email></para>
- </listitem>
-
- <listitem>
- <para>Anatoly A. Orehovsky <email>tolik@mpeks.tomsk.su</email></para>
- </listitem>
-
- <listitem>
- <para>Anatoly Vorobey <email>mellon@pobox.com</email></para>
- </listitem>
-
- <listitem>
- <para>Anders Nordby <email>nickerne@nome.no</email></para>
- </listitem>
-
- <listitem>
- <para>Anders Thulin <email>Anders.X.Thulin@telia.se</email></para>
- </listitem>
-
- <listitem>
- <para>Andras Olah <email>olah@cs.utwente.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Andre Albsmeier
- <email>Andre.Albsmeier@mchp.siemens.de</email></para>
- </listitem>
-
- <listitem>
- <para>Andre Oppermann <email>andre@pipeline.ch</email></para>
- </listitem>
-
- <listitem>
- <para>Andreas Haakh <email>ah@alman.robin.de</email></para>
- </listitem>
-
- <listitem>
- <para>Andreas Kohout <email>shanee@rabbit.augusta.de</email></para>
- </listitem>
-
- <listitem>
- <para>Andreas Lohr <email>andreas@marvin.RoBIN.de</email></para>
- </listitem>
-
- <listitem>
- <para>Andreas Schulz <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Andreas Wetzel <email>mickey@deadline.snafu.de</email></para>
- </listitem>
-
- <listitem>
- <para>Andreas Wrede <email>andreas@planix.com</email></para>
- </listitem>
-
- <listitem>
- <para>Andres Vega Garcia <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Atrens <email>atreand@statcan.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Boothman <email>andrew@cream.org</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Gillham <email>gillham@andrews.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Gordon <email>andrew.gordon@net-tel.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Herbert <email>andrew@werple.apana.org.au</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew J. Korty <email>ajk@purdue.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew L. Moore <email>alm@mclink.com</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew McRae <email>amcrae@cisco.com</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Stevenson <email>andrew@ugh.net.au</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Timonin <email>tim@pool1.convey.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew V. Stesin <email>stesin@elvisti.kiev.ua</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Webster <email>awebster@dataradio.com</email></para>
- </listitem>
-
- <listitem>
- <para>Andrey Zakhvatov <email>andy@icc.surw.chel.su</email></para>
- </listitem>
-
- <listitem>
- <para>Andy Farkas <email>andyf@speednet.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Andy Valencia <email>ajv@csd.mot.com</email></para>
- </listitem>
-
- <listitem>
- <para>Andy Whitcroft <email>andy@sarc.city.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Angelo Turetta <email>ATuretta@stylo.it</email></para>
- </listitem>
-
- <listitem>
- <para>Anthony C. Chavez <email>magus@xmission.com</email></para>
- </listitem>
-
- <listitem>
- <para>Anthony Yee-Hang Chan <email>yeehang@netcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Anton Berezin <email>tobez@plab.ku.dk</email></para>
- </listitem>
-
- <listitem>
- <para>Antti Kaipila <email>anttik@iki.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Are Bryne <email>are.bryne@communique.no</email></para>
- </listitem>
-
- <listitem>
- <para>Ari Suutari <email>ari@suutari.iki.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Arjan de Vet <email>devet@IAEhv.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Arne Henrik Juul <email>arnej@Lise.Unit.NO</email></para>
- </listitem>
-
- <listitem>
- <para>Assar Westerlund <email>assar@sics.se</email></para>
- </listitem>
-
- <listitem>
- <para>Atsushi Furuta <email>furuta@sra.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Atsushi Murai <email>amurai@spec.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Bakul Shah <email>bvs@bitblocks.com</email></para>
- </listitem>
-
- <listitem>
- <para>Barry Bierbauch <email>pivrnec@vszbr.cz</email></para>
- </listitem>
-
- <listitem>
- <para>Barry Lustig <email>barry@ictv.com</email></para>
- </listitem>
-
- <listitem>
- <para>Ben Hutchinson <email>benhutch@xfiles.org.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Ben Jackson <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Ben Smithurst <email>ben@scientia.demon.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Ben Walter <email>bwalter@itachi.swcp.com</email></para>
- </listitem>
-
- <listitem>
- <para>Benjamin Lewis <email>bhlewis@gte.net</email></para>
- </listitem>
-
- <listitem>
- <para>Bernd Rosauer <email>br@schiele-ct.de</email></para>
- </listitem>
-
- <listitem>
- <para>Bill Kish <email>kish@osf.org</email></para>
- </listitem>
-
- <listitem>
- <para>Bill Trost <email>trost@cloud.rain.com</email></para>
- </listitem>
-
- <listitem>
- <para>Blaz Zupan <email>blaz@amis.net</email></para>
- </listitem>
-
- <listitem>
- <para>Bob Van Valzah <email>Bob@whitebarn.com</email></para>
- </listitem>
-
- <listitem>
- <para>Bob Willcox <email>bob@luke.pmr.com</email></para>
- </listitem>
-
- <listitem>
- <para>Boris Staeblow <email>balu@dva.in-berlin.de</email></para>
- </listitem>
-
- <listitem>
- <para>Boyd R. Faulkner <email>faulkner@asgard.bga.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brad Karp <email>karp@eecs.harvard.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Bradley Dunn <email>bradley@dunn.org</email></para>
- </listitem>
-
- <listitem>
- <para>Brandon Fosdick <email>bfoz@glue.umd.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Brandon Gillespie <email>brandon@roguetrader.com</email></para>
- </listitem>
-
- <listitem>
- <para>&a.wlloyd</para>
- </listitem>
-
- <listitem>
- <para>Bob Wilcox <email>bob@obiwan.uucp</email></para>
- </listitem>
-
- <listitem>
- <para>Boyd Faulkner <email>faulkner@mpd.tandem.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brent J. Nordquist <email>bjn@visi.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brett Lymn <email>blymn@mulga.awadi.com.AU</email></para>
- </listitem>
-
- <listitem>
- <para>Brett Taylor
- <email>brett@peloton.physics.montana.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Brian Campbell <email>brianc@pobox.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brian Clapper <email>bmc@willscreek.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brian Cully <email>shmit@kublai.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brian Handy
- <email>handy@lambic.space.lockheed.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brian Litzinger <email>brian@MediaCity.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brian McGovern <email>bmcgover@cisco.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brian Moore <email>ziff@houdini.eecs.umich.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Brian R. Haug <email>haug@conterra.com</email></para>
- </listitem>
-
- <listitem>
- <para>Brian Tao <email>taob@risc.org</email></para>
- </listitem>
-
- <listitem>
- <para>Brion Moss <email>brion@queeg.com</email></para>
- </listitem>
-
- <listitem>
- <para>Bruce A. Mah <email>bmah@ca.sandia.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Bruce Albrecht <email>bruce@zuhause.mn.org</email></para>
- </listitem>
-
- <listitem>
- <para>Bruce Gingery <email>bgingery@gtcs.com</email></para>
- </listitem>
-
- <listitem>
- <para>Bruce J. Keeler <email>loodvrij@gridpoint.com</email></para>
- </listitem>
-
- <listitem>
- <para>Bruce Murphy <email>packrat@iinet.net.au</email></para>
- </listitem>
-
- <listitem>
- <para>Bruce Walter <email>walter@fortean.com</email></para>
- </listitem>
-
- <listitem>
- <para>Carey Jones <email>mcj@acquiesce.org</email></para>
- </listitem>
-
- <listitem>
- <para>Carl Fongheiser <email>cmf@netins.net</email></para>
- </listitem>
-
- <listitem>
- <para>Carl Mascott <email>cmascott@world.std.com</email></para>
- </listitem>
-
- <listitem>
- <para>Casper <email>casper@acc.am</email></para>
- </listitem>
-
- <listitem>
- <para>Castor Fu <email>castor@geocast.com</email></para>
- </listitem>
-
- <listitem>
- <para>Cejka Rudolf <email>cejkar@dcse.fee.vutbr.cz</email></para>
- </listitem>
-
- <listitem>
- <para>Chain Lee <email>chain@110.net</email></para>
- </listitem>
-
- <listitem>
- <para>Charles Hannum <email>mycroft@ai.mit.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Charles Henrich <email>henrich@msu.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Charles Mott <email>cmott@srv.net</email></para>
- </listitem>
-
- <listitem>
- <para>Charles Owens <email>owensc@enc.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Chet Ramey <email>chet@odin.INS.CWRU.Edu</email></para>
- </listitem>
-
- <listitem>
- <para>Chia-liang Kao <email>clkao@CirX.ORG</email></para>
- </listitem>
-
- <listitem>
- <para>Chiharu Shibata <email>chi@bd.mbn.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Chip Norkus <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Choi Jun Ho <email>junker@jazz.snu.ac.kr</email></para>
- </listitem>
-
- <listitem>
- <para>Chris Csanady <email>cc@tarsier.ca.sandia.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Chris Dabrowski <email>chris@vader.org</email></para>
- </listitem>
-
- <listitem>
- <para>Chris Dillon <email>cdillon@wolves.k12.mo.us</email></para>
- </listitem>
-
- <listitem>
- <para>Chris Shenton
- <email>cshenton@angst.it.hq.nasa.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Chris Stenton <email>jacs@gnome.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Chris Timmons <email>skynyrd@opus.cts.cwu.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Chris Torek <email>torek@ee.lbl.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Christian Gusenbauer
- <email>cg@fimp01.fim.uni-linz.ac.at</email></para>
- </listitem>
-
- <listitem>
- <para>Christian Haury <email>Christian.Haury@sagem.fr</email></para>
- </listitem>
-
- <listitem>
- <para>Christian Weisgerber
- <email>naddy@bigeye.rhein-neckar.de</email></para>
- </listitem>
-
- <listitem>
- <para>Christoph P. Kukulies <email>kuku@FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Christoph Robitschko
- <email>chmr@edvz.tu-graz.ac.at</email></para>
- </listitem>
-
- <listitem>
- <para>Christoph Weber-Fahr
- <email>wefa@callcenter.systemhaus.net</email></para>
- </listitem>
-
- <listitem>
- <para>Christopher G. Demetriou
- <email>cgd@postgres.berkeley.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Christopher T. Johnson
- <email>cjohnson@neunacht.netgsi.com</email></para>
- </listitem>
-
- <listitem>
- <para>Chrisy Luke <email>chrisy@flix.net</email></para>
- </listitem>
-
- <listitem>
- <para>Chuck Hein <email>chein@cisco.com</email></para>
- </listitem>
-
- <listitem>
- <para>Clive Lin <email>clive@CiRX.ORG</email></para>
- </listitem>
-
- <listitem>
- <para>Colman Reilly <email>careilly@tcd.ie</email></para>
- </listitem>
-
- <listitem>
- <para>Conrad Sabatier <email>conrads@neosoft.com</email></para>
- </listitem>
-
- <listitem>
- <para>Coranth Gryphon <email>gryphon@healer.com</email></para>
- </listitem>
-
- <listitem>
- <para>Cornelis van der Laan
- <email>nils@guru.ims.uni-stuttgart.de</email></para>
- </listitem>
-
- <listitem>
- <para>Cove Schneider <email>cove@brazil.nbn.com</email></para>
- </listitem>
-
- <listitem>
- <para>Craig Leres <email>leres@ee.lbl.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Craig Loomis <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Craig Metz <email>cmetz@inner.net</email></para>
- </listitem>
-
- <listitem>
- <para>Craig Spannring <email>cts@internetcds.com</email></para>
- </listitem>
-
- <listitem>
- <para>Craig Struble <email>cstruble@vt.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Cristian Ferretti <email>cfs@riemann.mat.puc.cl</email></para>
- </listitem>
-
- <listitem>
- <para>Curt Mayer <email>curt@toad.com</email></para>
- </listitem>
-
- <listitem>
- <para>Cy Schubert <email>cschuber@uumail.gov.bc.ca</email></para>
- </listitem>
-
- <listitem>
- <para>DI. Christian Gusenbauer
- <email>cg@scotty.edvz.uni-linz.ac.at</email></para>
- </listitem>
-
- <listitem>
- <para>Dai Ishijima <email>ishijima@tri.pref.osaka.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Damian Hamill <email>damian@cablenet.net</email></para>
- </listitem>
-
- <listitem>
- <para>Dan Cross <email>tenser@spitfire.ecsel.psu.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Dan Lukes <email>dan@obluda.cz</email></para>
- </listitem>
-
- <listitem>
- <para>Dan Nelson <email>dnelson@emsphone.com</email></para>
- </listitem>
-
- <listitem>
- <para>Dan Walters <email>hannibal@cyberstation.net</email></para>
- </listitem>
-
- <listitem>
- <para>Daniel M. Eischen
- <email>deischen@iworks.InterWorks.org</email></para>
- </listitem>
-
- <listitem>
- <para>Daniel O'Connor <email>doconnor@gsoft.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Daniel Poirot <email>poirot@aio.jsc.nasa.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Daniel Rock <email>rock@cs.uni-sb.de</email></para>
- </listitem>
-
- <listitem>
- <para>Danny Egen <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Danny J. Zerkel <email>dzerkel@phofarm.com</email></para>
- </listitem>
-
- <listitem>
- <para>Darren Reed <email>avalon@coombs.anu.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Adkins <email>adkin003@tc.umn.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Andersen <email>angio@aros.net</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Blizzard <email>dblizzar@sprynet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Bodenstab <email>imdave@synet.net</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Burgess <email>burgess@hrd769.brooks.af.mil</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Chapeskie <email>dchapes@ddm.on.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Cornejo <email>dave@dogwood.com</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Edmondson <email>davided@sco.com</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Glowacki <email>dglo@ssec.wisc.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Marquardt <email>marquard@austin.ibm.com</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Tweten <email>tweten@FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>David A. Adkins <email>adkin003@tc.umn.edu</email></para>
- </listitem>
-
- <listitem>
- <para>David A. Bader <email>dbader@umiacs.umd.edu</email></para>
- </listitem>
-
- <listitem>
- <para>David Borman <email>dab@bsdi.com</email></para>
- </listitem>
-
- <listitem>
- <para>David Dawes <email>dawes@XFree86.org</email></para>
- </listitem>
-
- <listitem>
- <para>David Filo <email>filo@yahoo.com</email></para>
- </listitem>
-
- <listitem>
- <para>David Holland <email>dholland@eecs.harvard.edu</email></para>
- </listitem>
-
- <listitem>
- <para>David Holloway <email>daveh@gwythaint.tamis.com</email></para>
- </listitem>
-
- <listitem>
- <para>David Horwitt <email>dhorwitt@ucsd.edu</email></para>
- </listitem>
-
- <listitem>
- <para>David Hovemeyer <email>daveho@infocom.com</email></para>
- </listitem>
-
- <listitem>
- <para>David Jones <email>dej@qpoint.torfree.net</email></para>
- </listitem>
-
- <listitem>
- <para>David Kelly <email>dkelly@tomcat1.tbe.com</email></para>
- </listitem>
-
- <listitem>
- <para>David Kulp <email>dkulp@neomorphic.com</email></para>
- </listitem>
-
- <listitem>
- <para>David L. Nugent <email>davidn@blaze.net.au</email></para>
- </listitem>
-
- <listitem>
- <para>David Leonard <email>d@scry.dstc.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>David Malone <email>dwmalone@maths.tcd.ie</email></para>
- </listitem>
-
- <listitem>
- <para>David Muir Sharnoff <email>muir@idiom.com</email></para>
- </listitem>
-
- <listitem>
- <para>David S. Miller <email>davem@jenolan.rutgers.edu</email></para>
- </listitem>
-
- <listitem>
- <para>David Wolfskill <email>dhw@whistle.com</email></para>
- </listitem>
-
- <listitem>
- <para>Dean Gaudet <email>dgaudet@arctic.org</email></para>
- </listitem>
-
- <listitem>
- <para>Dean Huxley <email>dean@fsa.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Denis Fortin <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Dennis Glatting
- <email>dennis.glatting@software-munitions.com</email></para>
- </listitem>
-
- <listitem>
- <para>Denton Gentry <email>denny1@home.com</email></para>
- </listitem>
-
- <listitem>
- <para>Derek Inksetter <email>derek@saidev.com</email></para>
- </listitem>
-
- <listitem>
- <para>Dima Sivachenko <email>dima@Chg.RU</email></para>
- </listitem>
-
- <listitem>
- <para>Dirk Keunecke <email>dk@panda.rhein-main.de</email></para>
- </listitem>
-
- <listitem>
- <para>Dirk Nehrling <email>nerle@pdv.de</email></para>
- </listitem>
-
- <listitem>
- <para>Dmitry Khrustalev <email>dima@xyzzy.machaon.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Dmitry Kohmanyuk <email>dk@farm.org</email></para>
- </listitem>
-
- <listitem>
- <para>Dom Mitchell <email>dom@myrddin.demon.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Dominik Brettnacher <email>domi@saargate.de</email></para>
- </listitem>
-
- <listitem>
- <para>Don Croyle <email>croyle@gelemna.ft-wayne.in.us</email></para>
- </listitem>
-
- <listitem>
- <para>&a.whiteside;</para>
- </listitem>
-
- <listitem>
- <para>Don Morrison <email>dmorrisn@u.washington.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Don Yuniskis <email>dgy@rtd.com</email></para>
- </listitem>
-
- <listitem>
- <para>Donald Maddox <email>dmaddox@conterra.com</email></para>
- </listitem>
-
- <listitem>
- <para>Doug Barton <email>studded@dal.net</email></para>
- </listitem>
-
- <listitem>
- <para>Douglas Ambrisko <email>ambrisko@whistle.com</email></para>
- </listitem>
-
- <listitem>
- <para>Douglas Carmichael <email>dcarmich@mcs.com</email></para>
- </listitem>
-
- <listitem>
- <para>Douglas Crosher <email>dtc@scrooge.ee.swin.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Drew Derbyshire <email>ahd@kew.com</email></para>
- </listitem>
-
- <listitem>
- <para>Duncan Barclay <email>dmlb@ragnet.demon.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Dustin Sallings <email>dustin@spy.net</email></para>
- </listitem>
-
- <listitem>
- <para>Eckart "Isegrim" Hofmann
- <email>Isegrim@Wunder-Nett.org</email></para>
- </listitem>
-
- <listitem>
- <para>Ed Gold
- <email>vegold01@starbase.spd.louisville.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Ed Hudson <email>elh@p5.spnet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Edward Wang <email>edward@edcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Edwin Groothus <email>edwin@nwm.wan.philips.com</email></para>
- </listitem>
-
- <listitem>
- <para>Eiji-usagi-MATSUmoto <email>usagi@clave.gr.jp</email></para>
- </listitem>
-
- <listitem>
- <para>ELISA Font Project</para>
- </listitem>
-
- <listitem>
- <para>Elmar Bartel
- <email>bartel@informatik.tu-muenchen.de</email></para>
- </listitem>
-
- <listitem>
- <para>Eric A. Griff <email>eagriff@global2000.net</email></para>
- </listitem>
-
- <listitem>
- <para>Eric Blood <email>eblood@cs.unr.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Eric J. Haug <email>ejh@slustl.slu.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Eric J. Schwertfeger <email>eric@cybernut.com</email></para>
- </listitem>
-
- <listitem>
- <para>Eric L. Hernes <email>erich@lodgenet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Eric P. Scott <email>eps@sirius.com</email></para>
- </listitem>
-
- <listitem>
- <para>Eric Sprinkle <email>eric@ennovatenetworks.com</email></para>
- </listitem>
-
- <listitem>
- <para>Erich Stefan Boleyn <email>erich@uruk.org</email></para>
- </listitem>
-
- <listitem>
- <para>Erik E. Rantapaa <email>rantapaa@math.umn.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Erik H. Moe <email>ehm@cris.com</email></para>
- </listitem>
-
- <listitem>
- <para>Ernst Winter <email>ewinter@lobo.muc.de</email></para>
- </listitem>
-
- <listitem>
- <para>Espen Skoglund <email>espensk@stud.cs.uit.no></email></para>
- </listitem>
-
- <listitem>
- <para>Eugene M. Kim <email>astralblue@usa.net</email></para>
- </listitem>
-
- <listitem>
- <para>Eugene Radchenko <email>genie@qsar.chem.msu.su</email></para>
- </listitem>
-
- <listitem>
- <para>Evan Champion <email>evanc@synapse.net</email></para>
- </listitem>
-
- <listitem>
- <para>Faried Nawaz <email>fn@Hungry.COM</email></para>
- </listitem>
-
- <listitem>
- <para>Flemming Jacobsen <email>fj@tfs.com</email></para>
- </listitem>
-
- <listitem>
- <para>Fong-Ching Liaw <email>fong@juniper.net</email></para>
- </listitem>
-
- <listitem>
- <para>Francis M J Hsieh <email>mjshieh@life.nthu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Frank Bartels <email>knarf@camelot.de</email></para>
- </listitem>
-
- <listitem>
- <para>Frank Chen Hsiung Chan
- <email>frankch@waru.life.nthu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Frank Durda IV <email>uhclem@nemesis.lonestar.org</email></para>
- </listitem>
-
- <listitem>
- <para>Frank MacLachlan <email>fpm@n2.net</email></para>
- </listitem>
-
- <listitem>
- <para>Frank Mayhar <email>frank@exit.com</email></para>
- </listitem>
-
- <listitem>
- <para>Frank Nobis <email>fn@Radio-do.de</email></para>
- </listitem>
-
- <listitem>
- <para>Frank Volf <email>volf@oasis.IAEhv.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Frank ten Wolde <email>franky@pinewood.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Frank van der Linden <email>frank@fwi.uva.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Fred Cawthorne <email>fcawth@jjarray.umn.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Fred Gilham <email>gilham@csl.sri.com</email></para>
- </listitem>
-
- <listitem>
- <para>Fred Templin <email>templin@erg.sri.com</email></para>
- </listitem>
-
- <listitem>
- <para>Frederick Earl Gray <email>fgray@rice.edu</email></para>
- </listitem>
-
- <listitem>
- <para>FUJIMOTO Kensaku
- <email>fujimoto@oscar.elec.waseda.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>FUJISHIMA Satsuki <email>k5@respo.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>FURUSAWA Kazuhisa
- <email>furusawa@com.cs.osakafu-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Gabor Kincses <email>gabor@acm.org</email></para>
- </listitem>
-
- <listitem>
- <para>Gabor Zahemszky <email>zgabor@CoDe.hu</email></para>
- </listitem>
-
- <listitem>
- <para>G. Adam Stanislav<email>adam@whizkidtech.net</email></para>
- </listitem>
-
- <listitem>
- <para>Garance A Drosehn <email>gad@eclipse.its.rpi.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Gareth McCaughan <email>gjm11@dpmms.cam.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Gary A. Browning <email>gab10@griffcd.amdahl.com</email></para>
- </listitem>
-
- <listitem>
- <para>Gary Howland <email>gary@hotlava.com</email></para>
- </listitem>
-
- <listitem>
- <para>Gary J. <email>garyj@rks32.pcs.dec.com</email></para>
- </listitem>
-
- <listitem>
- <para>Gary Kline <email>kline@thought.org</email></para>
- </listitem>
-
- <listitem>
- <para>Gaspar Chilingarov <email>nightmar@lemming.acc.am</email></para>
- </listitem>
-
- <listitem>
- <para>Gea-Suan Lin <email>gsl@tpts4.seed.net.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Geoff Rehmet <email>csgr@alpha.ru.ac.za</email></para>
- </listitem>
-
- <listitem>
- <para>Georg Wagner <email>georg.wagner@ubs.com</email></para>
- </listitem>
-
- <listitem>
- <para>Gerard Roudier <email>groudier@club-internet.fr</email></para>
- </listitem>
-
- <listitem>
- <para>Gianmarco Giovannelli
- <email>gmarco@giovannelli.it</email></para>
- </listitem>
-
- <listitem>
- <para>Gil Kloepfer Jr. <email>gil@limbic.ssdl.com</email></para>
- </listitem>
-
- <listitem>
- <para>Gilad Rom <email>rom_glsa@ein-hashofet.co.il</email></para>
- </listitem>
-
- <listitem>
- <para>Ginga Kawaguti
- <email>ginga@amalthea.phys.s.u-tokyo.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Giles Lean <email>giles@nemeton.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Glen Foster <email>gfoster@gfoster.com</email></para>
- </listitem>
-
- <listitem>
- <para>Glenn Johnson <email>gljohns@bellsouth.net</email></para>
- </listitem>
-
- <listitem>
- <para>Godmar Back <email>gback@facility.cs.utah.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Goran Hammarback <email>goran@astro.uu.se</email></para>
- </listitem>
-
- <listitem>
- <para>Gord Matzigkeit <email>gord@enci.ucalgary.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Gordon Greeff <email>gvg@uunet.co.za</email></para>
- </listitem>
-
- <listitem>
- <para>Graham Wheeler <email>gram@cdsec.com</email></para>
- </listitem>
-
- <listitem>
- <para>Greg A. Woods <email>woods@zeus.leitch.com</email></para>
- </listitem>
-
- <listitem>
- <para>Greg Ansley <email>gja@ansley.com</email></para>
- </listitem>
-
- <listitem>
- <para>Greg Troxel <email>gdt@ir.bbn.com</email></para>
- </listitem>
-
- <listitem>
- <para>Greg Ungerer <email>gerg@stallion.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Gregory Bond <email>gnb@itga.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Gregory D. Moncreaff
- <email>moncrg@bt340707.res.ray.com</email></para>
- </listitem>
-
- <listitem>
- <para>Guy Harris <email>guy@netapp.com</email></para>
- </listitem>
-
- <listitem>
- <para>Guy Helmer <email>ghelmer@cs.iastate.edu</email></para>
- </listitem>
-
- <listitem>
- <para>HAMADA Naoki <email>hamada@astec.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>HONDA Yasuhiro
- <email>honda@kashio.info.mie-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>HOSOBUCHI Noriyuki <email>hoso@buchi.tama.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Hannu Savolainen <email>hannu@voxware.pp.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Hans Huebner <email>hans@artcom.de</email></para>
- </listitem>
-
- <listitem>
- <para>Hans Petter Bieker <email>zerium@webindex.no</email></para>
- </listitem>
-
- <listitem>
- <para>Hans Zuidam <email>hans@brandinnovators.com</email></para>
- </listitem>
-
- <listitem>
- <para>Harlan Stenn <email>Harlan.Stenn@pfcs.com</email></para>
- </listitem>
-
- <listitem>
- <para>Harold Barker <email>hbarker@dsms.com</email></para>
- </listitem>
-
- <listitem>
- <para>Havard Eidnes
- <email>Havard.Eidnes@runit.sintef.no</email></para>
- </listitem>
-
- <listitem>
- <para>Heikki Suonsivu <email>hsu@cs.hut.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Heiko W. Rupp <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Helmut F. Wirth <email>hfwirth@ping.at</email></para>
- </listitem>
-
- <listitem>
- <para>Henrik Vestergaard Draboel
- <email>hvd@terry.ping.dk</email></para>
- </listitem>
-
- <listitem>
- <para>Herb Peyerl <email>hpeyerl@NetBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Hideaki Ohmon <email>ohmon@tom.sfc.keio.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Hidekazu Kuroki <email>hidekazu@cs.titech.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Hideki Yamamoto <email>hyama@acm.org</email></para>
- </listitem>
-
- <listitem>
- <para>Hideyuki Suzuki
- <email>hideyuki@sat.t.u-tokyo.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Hirayama Issei <email>iss@mail.wbs.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Hiroaki Sakai <email>sakai@miya.ee.kagu.sut.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Hiroharu Tamaru <email>tamaru@ap.t.u-tokyo.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Hironori Ikura <email>hikura@kaisei.org</email></para>
- </listitem>
-
- <listitem>
- <para>Hiroshi Nishikawa <email>nis@pluto.dti.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Hiroya Tsubakimoto <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Holger Veit <email>Holger.Veit@gmd.de</email></para>
- </listitem>
-
- <listitem>
- <para>Holm Tiffe <email>holm@geophysik.tu-freiberg.de</email></para>
- </listitem>
-
- <listitem>
- <para>Horance Chou
- <email>horance@freedom.ie.cycu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Horihiro Kumagai <email>kuma@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>HOTARU-YA <email>hotaru@tail.net</email></para>
- </listitem>
-
- <listitem>
- <para>Hr.Ladavac <email>lada@ws2301.gud.siemens.co.at</email></para>
- </listitem>
-
- <listitem>
- <para>Hubert Feyrer <email>hubertf@NetBSD.ORG</email></para>
- </listitem>
-
- <listitem>
- <para>Hugh F. Mahon <email>hugh@nsmdserv.cnd.hp.com</email></para>
- </listitem>
-
- <listitem>
- <para>Hugh Mahon <email>h_mahon@fc.hp.com</email></para>
- </listitem>
-
- <listitem>
- <para>Hung-Chi Chu <email>hcchu@r350.ee.ntu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>IMAI Takeshi <email>take-i@ceres.dti.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>IMAMURA Tomoaki
- <email>tomoak-i@is.aist-nara.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Ian Dowse <email>iedowse@maths.tcd.ie</email></para>
- </listitem>
-
- <listitem>
- <para>Ian Holland <email>ianh@tortuga.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Ian Struble <email>ian@broken.net</email></para>
- </listitem>
-
- <listitem>
- <para>Ian Vaudrey <email>i.vaudrey@bigfoot.com</email></para>
- </listitem>
-
- <listitem>
- <para>Igor Khasilev <email>igor@jabber.paco.odessa.ua</email></para>
- </listitem>
-
- <listitem>
- <para>Igor Roshchin <email>str@giganda.komkon.org</email></para>
- </listitem>
-
- <listitem>
- <para>Igor Sviridov <email>siac@ua.net</email></para>
- </listitem>
-
- <listitem>
- <para>Igor Vinokurov <email>igor@zynaps.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Ikuo Nakagawa <email>ikuo@isl.intec.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Ilya V. Komarov <email>mur@lynx.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Issei Suzuki <email>issei@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Itsuro Saito <email>saito@miv.t.u-tokyo.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>J. Bryant <email>jbryant@argus.flash.net</email></para>
- </listitem>
-
- <listitem>
- <para>J. David Lowe <email>lowe@saturn5.com</email></para>
- </listitem>
-
- <listitem>
- <para>J. Han <email>hjh@best.com</email></para>
- </listitem>
-
- <listitem>
- <para>J. Hawk <email>jhawk@MIT.EDU</email></para>
- </listitem>
-
- <listitem>
- <para>J.T. Conklin <email>jtc@cygnus.com</email></para>
- </listitem>
-
- <listitem>
- <para>J.T. Jang <email>keith@email.gcn.net.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Jack <email>jack@zeus.xtalwind.net</email></para>
- </listitem>
-
- <listitem>
- <para>Jacob Bohn Lorensen <email>jacob@jblhome.ping.mk</email></para>
- </listitem>
-
- <listitem>
- <para>Jagane D Sundar <email>jagane@netcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jake Burkholder <email>jake@checker.org</email></para>
- </listitem>
-
- <listitem>
- <para>Jake Hamby <email>jehamby@lightside.com</email></para>
- </listitem>
-
- <listitem>
- <para>James Clark <email>jjc@jclark.com</email></para>
- </listitem>
-
- <listitem>
- <para>James D. Stewart <email>jds@c4systm.com</email></para>
- </listitem>
-
- <listitem>
- <para>James Jegers <email>jimj@miller.cs.uwm.edu</email></para>
- </listitem>
-
- <listitem>
- <para>James Raynard
- <email>fhackers@jraynard.demon.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>James T. Liu <email>jtliu@phlebas.rockefeller.edu</email></para>
- </listitem>
-
- <listitem>
- <para>James da Silva <email>jds@cs.umd.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Jan Conard
- <email>charly@fachschaften.tu-muenchen.de</email></para>
- </listitem>
-
- <listitem>
- <para>Jan Koum <email>jkb@FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Janick Taillandier
- <email>Janick.Taillandier@ratp.fr</email></para>
- </listitem>
-
- <listitem>
- <para>Janusz Kokot <email>janek@gaja.ipan.lublin.pl</email></para>
- </listitem>
-
- <listitem>
- <para>Jarle Greipsland <email>jarle@idt.unit.no</email></para>
- </listitem>
-
- <listitem>
- <para>Jason Garman <email>init@risen.org</email></para>
- </listitem>
-
- <listitem>
- <para>Jason Thorpe <email>thorpej@NetBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Jason Wright <email>jason@OpenBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Jason Young
- <email>doogie@forbidden-donut.anet-stl.com</email></para>
- </listitem>
-
- <listitem>
- <para>Javier Martin Rueda <email>jmrueda@diatel.upm.es</email></para>
- </listitem>
-
- <listitem>
- <para>Jay Fenlason <email>hack@datacube.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jaye Mathisen <email>mrcpu@cdsnet.net</email></para>
- </listitem>
-
- <listitem>
- <para>Jeff Bartig <email>jeffb@doit.wisc.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Jeff Forys <email>jeff@forys.cranbury.nj.us</email></para>
- </listitem>
-
- <listitem>
- <para>Jeff Kletsky <email>Jeff@Wagsky.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jeffrey Evans <email>evans@scnc.k12.mi.us</email></para>
- </listitem>
-
- <listitem>
- <para>Jeffrey Wheat <email>jeff@cetlink.net</email></para>
- </listitem>
-
- <listitem>
- <para>Jens Schweikhardt <email>schweikh@noc.dfn.d</email></para>
- </listitem>
-
- <listitem>
- <para>Jeremy Allison <email>jallison@whistle.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jeremy Chatfield <email>jdc@xinside.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jeremy Lea <email>reg@shale.csir.co.za</email></para>
- </listitem>
-
- <listitem>
- <para>Jeremy Prior <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Jeroen Ruigrok/Asmodai <email>asmodai@wxs.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Jesse Rosenstock <email>jmr@ugcs.caltech.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Jian-Da Li <email>jdli@csie.nctu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Babb <email>babb@FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Binkley <email>jrb@cs.pdx.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Carroll <email>jim@carroll.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Flowers <email>jflowers@ezo.net</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Leppek <email>jleppek@harris.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Lowe <email>james@cs.uwm.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Mattson <email>jmattson@sonic.net</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Mercer <email>jim@komodo.reptiles.org</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Wilson <email>wilson@moria.cygnus.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jimbo Bahooli
- <email>griffin@blackhole.iceworld.org</email></para>
- </listitem>
-
- <listitem>
- <para>Jin Guojun <email>jin@george.lbl.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Joachim Kuebart <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Joao Carlos Mendes Luis <email>jonny@jonny.eng.br</email></para>
- </listitem>
-
- <listitem>
- <para>Jochen Pohl <email>jpo.drs@sni.de</email></para>
- </listitem>
-
- <listitem>
- <para>Joe "Marcus" Clarke <email>marcus@miami.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Joe Abley <email>jabley@clear.co.nz</email></para>
- </listitem>
-
- <listitem>
- <para>Joe Jih-Shian Lu <email>jslu@dns.ntu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Joe Orthoefer <email>j_orthoefer@tia.net</email></para>
- </listitem>
-
- <listitem>
- <para>Joe Traister <email>traister@mojozone.org</email></para>
- </listitem>
-
- <listitem>
- <para>Joel Faedi <email>Joel.Faedi@esial.u-nancy.fr</email></para>
- </listitem>
-
- <listitem>
- <para>Joel Ray Holveck <email>joelh@gnu.org</email></para>
- </listitem>
-
- <listitem>
- <para>Joel Sutton <email>sutton@aardvark.apana.org.au</email></para>
- </listitem>
-
- <listitem>
- <para>Johan Granlund <email>johan@granlund.nu</email></para>
- </listitem>
-
- <listitem>
- <para>Johan Karlsson <email>k@numeri.campus.luth.se</email></para>
- </listitem>
-
- <listitem>
- <para>Johan Larsson <email>johan@moon.campus.luth.se</email></para>
- </listitem>
-
- <listitem>
- <para>Johann Tonsing <email>jtonsing@mikom.csir.co.za</email></para>
- </listitem>
-
- <listitem>
- <para>Johannes Helander <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Johannes Stille <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>John Baldwin <email>jobaldwi@vt.edu</email></para>
- </listitem>
-
- <listitem>
- <para>John Beckett <email>jbeckett@southern.edu</email></para>
- </listitem>
-
- <listitem>
- <para>John Beukema <email>jbeukema@hk.super.net</email></para>
- </listitem>
-
- <listitem>
- <para>John Brezak <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>John Capo <email>jc@irbs.com</email></para>
- </listitem>
-
- <listitem>
- <para>John F. Woods <email>jfw@jfwhome.funhouse.com</email></para>
- </listitem>
-
- <listitem>
- <para>John Goerzen
- <email>jgoerzen@alexanderwohl.complete.org</email></para>
- </listitem>
-
- <listitem>
- <para>John Hay <email>jhay@mikom.csir.co.za</email></para>
- </listitem>
-
- <listitem>
- <para>John Heidemann <email>johnh@isi.edu</email></para>
- </listitem>
-
- <listitem>
- <para>John Hood <email>cgull@owl.org</email></para>
- </listitem>
-
- <listitem>
- <para>John Kohl <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>John Lind <email>john@starfire.mn.org</email></para>
- </listitem>
-
- <listitem>
- <para>John Mackin <email>john@physiol.su.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>John P <email>johnp@lodgenet.com</email></para>
- </listitem>
-
- <listitem>
- <para>John Perry <email>perry@vishnu.alias.net</email></para>
- </listitem>
-
- <listitem>
- <para>John Preisler <email>john@vapornet.com</email></para>
- </listitem>
-
- <listitem>
- <para>John Rochester <email>jr@cs.mun.ca</email></para>
- </listitem>
-
- <listitem>
- <para>John Sadler <email>john_sadler@alum.mit.edu</email></para>
- </listitem>
-
- <listitem>
- <para>John Saunders <email>john@pacer.nlc.net.au</email></para>
- </listitem>
-
- <listitem>
- <para>John W. DeBoskey <email>jwd@unx.sas.com</email></para>
- </listitem>
-
- <listitem>
- <para>John Wehle <email>john@feith.com</email></para>
- </listitem>
-
- <listitem>
- <para>John Woods <email>jfw@eddie.mit.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Jon Morgan <email>morgan@terminus.trailblazer.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jonathan H N Chin <email>jc254@newton.cam.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Jonathan Hanna
- <email>jh@pc-21490.bc.rogers.wave.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Jorge Goncalves <email>j@bug.fe.up.pt</email></para>
- </listitem>
-
- <listitem>
- <para>Jorge M. Goncalves <email>ee96199@tom.fe.up.pt</email></para>
- </listitem>
-
- <listitem>
- <para>Jos Backus <email>jbackus@plex.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Jose M. Alcaide <email>jose@we.lc.ehu.es</email></para>
- </listitem>
-
- <listitem>
- <para>Jose Marques <email>jose@nobody.org</email></para>
- </listitem>
-
- <listitem>
- <para>Josef Grosch
- <email>jgrosch@superior.mooseriver.com</email></para>
- </listitem>
-
- <listitem>
- <para>Josef Karthauser <email>joe@uk.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Joseph Stein <email>joes@wstein.com</email></para>
- </listitem>
-
- <listitem>
- <para>Josh Gilliam <email>josh@quick.net</email></para>
- </listitem>
-
- <listitem>
- <para>Josh Tiefenbach <email>josh@ican.net</email></para>
- </listitem>
-
- <listitem>
- <para>Juergen Lock <email>nox@jelal.hb.north.de</email></para>
- </listitem>
-
- <listitem>
- <para>Juha Inkari <email>inkari@cc.hut.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Jukka A. Ukkonen <email>jua@iki.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Julian Assange <email>proff@suburbia.net</email></para>
- </listitem>
-
- <listitem>
- <para>Julian Coleman <email>j.d.coleman@ncl.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>&a.jhs</para>
- </listitem>
-
- <listitem>
- <para>Julian Jenkins <email>kaveman@magna.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Junichi Satoh <email>junichi@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Junji SAKAI <email>sakai@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Junya WATANABE <email>junya-w@remus.dti.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>K.Higashino <email>a00303@cc.hc.keio.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>KUNISHIMA Takeo <email>kunishi@c.oka-pu.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Kai Vorma <email>vode@snakemail.hut.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Kaleb S. Keithley <email>kaleb@ics.com</email></para>
- </listitem>
-
- <listitem>
- <para>Kaneda Hiloshi <email>vanitas@ma3.seikyou.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Kapil Chowksey <email>kchowksey@hss.hns.com</email></para>
- </listitem>
-
- <listitem>
- <para>Karl Denninger <email>karl@mcs.com</email></para>
- </listitem>
-
- <listitem>
- <para>Karl Dietz <email>Karl.Dietz@triplan.com</email></para>
- </listitem>
-
- <listitem>
- <para>Karl Lehenbauer <email>karl@NeoSoft.com</email></para>
- </listitem>
-
- <listitem>
- <para>Kato Takenori
- <email>kato@eclogite.eps.nagoya-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Kawanobe Koh <email>kawanobe@st.rim.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Kazuhiko Kiriyama <email>kiri@kiri.toba-cmt.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Kazuo Horikawa <email>horikawa@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Kees Jan Koster <email>kjk1@ukc.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Keith Bostic <email>bostic@bostic.com</email></para>
- </listitem>
-
- <listitem>
- <para>Keith E. Walker <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Keith Moore <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Keith Sklower <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Kelly Yancey <email>kbyanc@posi.net</email></para>
- </listitem>
-
- <listitem>
- <para>Ken Hornstein <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Ken Key <email>key@cs.utk.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Ken Mayer <email>kmayer@freegate.com</email></para>
- </listitem>
-
- <listitem>
- <para>Kenji Saito <email>marukun@mx2.nisiq.net</email></para>
- </listitem>
-
- <listitem>
- <para>Kenji Tomita <email>tommyk@da2.so-net.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Kenneth Furge <email>kenneth.furge@us.endress.com</email></para>
- </listitem>
-
- <listitem>
- <para>Kenneth Monville <email>desmo@bandwidth.org</email></para>
- </listitem>
-
- <listitem>
- <para>Kenneth R. Westerback <email>krw@tcn.net</email></para>
- </listitem>
-
- <listitem>
- <para>Kenneth Stailey <email>kstailey@gnu.ai.mit.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Kent Talarico <email>kent@shipwreck.tsoft.net</email></para>
- </listitem>
-
- <listitem>
- <para>Kent Vander Velden <email>graphix@iastate.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Kentaro Inagaki <email>JBD01226@niftyserve.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Kevin Bracey <email>kbracey@art.acorn.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Kevin Day <email>toasty@dragondata.com</email></para>
- </listitem>
-
- <listitem>
- <para>Kevin Lahey <email>kml@nas.nasa.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Kevin Lo<email>kevlo@hello.com.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Kevin Street <email>street@iname.com</email></para>
- </listitem>
-
- <listitem>
- <para>Kevin Van Maren <email>vanmaren@fast.cs.utah.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Kiroh HARADA <email>kiroh@kh.rim.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Klaus Klein <email>kleink@layla.inka.de</email></para>
- </listitem>
-
- <listitem>
- <para>Klaus-J. Wolf <email>Yanestra@t-online.de</email></para>
- </listitem>
-
- <listitem>
- <para>Koichi Sato <email>copan@ppp.fastnet.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Kostya Lukin <email>lukin@okbmei.msk.su</email></para>
- </listitem>
-
- <listitem>
- <para>Kouichi Hirabayashi <email>kh@mogami-wire.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Kurt D. Zeilenga <email>Kurt@Boolean.NET</email></para>
- </listitem>
-
- <listitem>
- <para>Kurt Olsen <email>kurto@tiny.mcs.usu.edu</email></para>
- </listitem>
-
- <listitem>
- <para>L. Jonas Olsson
- <email>ljo@ljo-slip.DIALIN.CWRU.Edu</email></para>
- </listitem>
-
- <listitem>
- <para>Lars K&ouml;ller
- <email>Lars.Koeller@Uni-Bielefeld.DE</email></para>
- </listitem>
-
- <listitem>
- <para>Larry Altneu <email>larry@ALR.COM</email></para>
- </listitem>
-
- <listitem>
- <para>Laurence Lopez <email>lopez@mv.mv.com</email></para>
- </listitem>
-
- <listitem>
- <para>Lee Cremeans <email>lcremean@tidalwave.net</email></para>
- </listitem>
-
- <listitem>
- <para>Liang Tai-hwa
- <email>avatar@www.mmlab.cse.yzu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Lon Willett <email>lon%softt.uucp@math.utah.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Louis A. Mamakos <email>louie@TransSys.COM</email></para>
- </listitem>
-
- <listitem>
- <para>Louis Mamakos <email>loiue@TransSys.com</email></para>
- </listitem>
-
- <listitem>
- <para>Lucas James <email>Lucas.James@ldjpc.apana.org.au</email></para>
- </listitem>
-
- <listitem>
- <para>Lyndon Nerenberg <email>lyndon@orthanc.com</email></para>
- </listitem>
-
- <listitem>
- <para>M.C. Wong <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>MANTANI Nobutaka <email>nobutaka@nobutaka.com</email></para>
- </listitem>
-
- <listitem>
- <para>MIHIRA Sanpei Yoshiro <email>sanpei@sanpei.org</email></para>
- </listitem>
-
- <listitem>
- <para>MITA Yoshio <email>mita@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>MITSUNAGA Noriaki
- <email>mitchy@er.ams.eng.osaka-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>MOROHOSHI Akihiko <email>moro@race.u-tokyo.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Magnus Enbom <email>dot@tinto.campus.luth.se</email></para>
- </listitem>
-
- <listitem>
- <para>Mahesh Neelakanta <email>mahesh@gcomm.com</email></para>
- </listitem>
-
- <listitem>
- <para>Makoto MATSUSHITA <email>matusita@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Makoto WATANABE
- <email>watanabe@zlab.phys.nagoya-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Malte Lance <email>malte.lance@gmx.net</email></para>
- </listitem>
-
- <listitem>
- <para>Manu Iyengar
- <email>iyengar@grunthos.pscwa.psca.com</email></para>
- </listitem>
-
- <listitem>
- <para>Marc Frajola <email>marc@dev.com</email></para>
- </listitem>
-
- <listitem>
- <para>Marc Ramirez <email>mrami@mramirez.sy.yale.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Marc Slemko <email>marcs@znep.com</email></para>
- </listitem>
-
- <listitem>
- <para>Marc van Kempen <email>wmbfmk@urc.tue.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Marc van Woerkom <email>van.woerkom@netcologne.de</email></para>
- </listitem>
-
- <listitem>
- <para>Marcel Moolenaar <email>marcel@scc.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Mario Sergio Fujikawa Ferreira
- <email>lioux@gns.com.br</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Andrews <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Cammidge <email>mark@gmtunx.ee.uct.ac.za</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Diekhans <email>markd@grizzly.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Huizer <email>xaa@stack.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Mark J. Taylor <email>mtaylor@cybernet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Krentel <email>krentel@rice.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Mayo <email>markm@vmunix.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Thompson <email>thompson@tgsoft.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Tinguely <email>tinguely@plains.nodak.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Treacy <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Valentine <email>mark@linus.demon.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Martin Birgmeier</para>
- </listitem>
-
- <listitem>
- <para>Martin Ibert <email>mib@ppe.bb-data.de</email></para>
- </listitem>
-
- <listitem>
- <para>Martin Kammerhofer <email>dada@sbox.tu-graz.ac.at</email></para>
- </listitem>
-
- <listitem>
- <para>Martin Renters <email>martin@tdc.on.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Martti Kuparinen
- <email>martti.kuparinen@ericsson.com</email></para>
- </listitem>
-
- <listitem>
- <para>Masachika ISHIZUKA
- <email>ishizuka@isis.min.ntt.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Mas.TAKEMURA <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Masafumi NAKANE <email>max@wide.ad.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Masahiro Sekiguchi
- <email>seki@sysrap.cs.fujitsu.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Masanobu Saitoh <email>msaitoh@spa.is.uec.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Masanori Kanaoka <email>kana@saijo.mke.mei.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Masanori Kiriake <email>seiken@ARGV.AC</email></para>
- </listitem>
-
- <listitem>
- <para>Masatoshi TAMURA
- <email>tamrin@shinzan.kuee.kyoto-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Mats Lofkvist <email>mal@algonet.se</email></para>
- </listitem>
-
- <listitem>
- <para>Matt Bartley <email>mbartley@lear35.cytex.com</email></para>
- </listitem>
-
- <listitem>
- <para>Matt Thomas <email>matt@3am-software.com</email></para>
- </listitem>
-
- <listitem>
- <para>Matt White <email>mwhite+@CMU.EDU</email></para>
- </listitem>
-
- <listitem>
- <para>Matthew C. Mead <email>mmead@Glock.COM</email></para>
- </listitem>
-
- <listitem>
- <para>Matthew Cashdollar <email>mattc@rfcnet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Matthew Flatt <email>mflatt@cs.rice.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Matthew Fuller <email>fullermd@futuresouth.com</email></para>
- </listitem>
-
- <listitem>
- <para>Matthew Stein <email>matt@bdd.net</email></para>
- </listitem>
-
- <listitem>
- <para>Matthias Pfaller <email>leo@dachau.marco.de</email></para>
- </listitem>
-
- <listitem>
- <para>Matthias Scheler <email>tron@netbsd.org</email></para>
- </listitem>
-
- <listitem>
- <para>Mattias Gronlund
- <email>Mattias.Gronlund@sa.erisoft.se</email></para>
- </listitem>
-
- <listitem>
- <para>Mattias Pantzare <email>pantzer@ludd.luth.se</email></para>
- </listitem>
-
- <listitem>
- <para>Maurice Castro
- <email>maurice@planet.serc.rmit.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>Max Euston <email>meuston@jmrodgers.com</email></para>
- </listitem>
-
- <listitem>
- <para>Max Khon <email>fjoe@husky.iclub.nsu.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Maxim Bolotin <email>max@rsu.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Maxim V. Sobolev <email>sobomax@altavista.net</email></para>
- </listitem>
-
- <listitem>
- <para>Micha Class
- <email>michael_class@hpbbse.bbn.hp.com</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Butler <email>imb@scgt.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Butschky <email>butsch@computi.erols.com</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Clay <email>mclay@weareb.org</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Elbel <email>me@FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Galassi <email>nerd@percival.rain.com</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Hancock <email>michaelh@cet.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Hohmuth <email>hohmuth@inf.tu-dresden.de</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Perlman <email>canuck@caam.rice.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Petry <email>petry@netwolf.NetMasters.com</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Reifenberger <email>root@totum.plaut.de</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Sardo <email>jaeger16@yahoo.com</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Searle <email>searle@longacre.demon.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Michal Listos <email>mcl@Amnesiac.123.org</email></para>
- </listitem>
-
- <listitem>
- <para>Michio Karl Jinbo
- <email>karl@marcer.nagaokaut.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Miguel Angel Sagreras
- <email>msagre@cactus.fi.uba.ar</email></para>
- </listitem>
-
- <listitem>
- <para>Mihoko Tanaka <email>m_tonaka@pa.yokogawa.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Mika Nystrom <email>mika@cs.caltech.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Mikael Hybsch <email>micke@dynas.se</email></para>
- </listitem>
-
- <listitem>
- <para>Mikael Karpberg
- <email>karpen@ocean.campus.luth.se</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Del <email>repenting@hotmail.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Durian <email>durian@plutotech.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Durkin <email>mdurkin@tsoft.sf-bay.org</email></para>
- </listitem>
-
- <listitem>
- <para>Mike E. Matsnev <email>mike@azog.cs.msu.su</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Evans <email>mevans@candle.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Grupenhoff <email>kashmir@umiacs.umd.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Hibler <email>mike@marker.cs.utah.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Karels <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Mike McGaughey <email>mmcg@cs.monash.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Meyer <email>mwm@shiva.the-park.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Mitchell <email>mitchell@ref.tfs.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Murphy <email>mrm@alpharel.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Peck <email>mike@binghamton.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Spengler <email>mks@msc.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Mikhail A. Sokolov <email>mishania@demos.su</email></para>
- </listitem>
-
- <listitem>
- <para>Mikhail Teterin <email>mi@aldan.ziplink.net</email></para>
- </listitem>
-
- <listitem>
- <para>Ming-I Hseh <email>PA@FreeBSD.ee.Ntu.edu.TW</email></para>
- </listitem>
-
- <listitem>
- <para>Mitsuru IWASAKI <email>iwasaki@pc.jaring.my</email></para>
- </listitem>
-
- <listitem>
- <para>Mitsuru Yoshida <email>mitsuru@riken.go.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Monte Mitzelfelt <email>monte@gonefishing.org</email></para>
- </listitem>
-
- <listitem>
- <para>Morgan Davis <email>root@io.cts.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mostyn Lewis <email>mostyn@mrl.com</email></para>
- </listitem>
-
- <listitem>
- <para>Motomichi Matsuzaki <email>mzaki@e-mail.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Motoyuki Kasahara <email>m-kasahr@sra.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Motoyuki Konno <email>motoyuki@snipe.rim.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Murray Stokely <email>murray@cdrom.com</email></para>
- </listitem>
-
- <listitem>
- <para>N.G.Smith <email>ngs@sesame.hensa.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>NAGAO Tadaaki <email>nagao@cs.titech.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>NAKAJI Hiroyuki
- <email>nakaji@tutrp.tut.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>NAKAMURA Kazushi <email>nkazushi@highway.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>NAKAMURA Motonori
- <email>motonori@econ.kyoto-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>NIIMI Satoshi <email>sa2c@and.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>NOKUBI Hirotaka <email>h-nokubi@yyy.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Nadav Eiron <email>nadav@barcode.co.il</email></para>
- </listitem>
-
- <listitem>
- <para>Nanbor Wang <email>nw1@cs.wustl.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Naofumi Honda
- <email>honda@Kururu.math.sci.hokudai.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Naoki Hamada <email>nao@tom-yam.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Narvi <email>narvi@haldjas.folklore.ee</email></para>
- </listitem>
-
- <listitem>
- <para>Nathan Ahlstrom <email>nrahlstr@winternet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Nathan Dorfman <email>nathan@rtfm.net</email></para>
- </listitem>
-
- <listitem>
- <para>Neal Fachan <email>kneel@ishiboo.com</email></para>
- </listitem>
-
- <listitem>
- <para>Neil Blakey-Milner <email>nbm@rucus.ru.ac.za</email></para>
- </listitem>
-
- <listitem>
- <para>Niall Smart <email>rotel@indigo.ie</email></para>
- </listitem>
-
- <listitem>
- <para>Nick Barnes <email>Nick.Barnes@pobox.com</email></para>
- </listitem>
-
- <listitem>
- <para>Nick Handel <email>nhandel@NeoSoft.com</email></para>
- </listitem>
-
- <listitem>
- <para>Nick Hilliard <email>nick@foobar.org</email></para>
- </listitem>
-
- <listitem>
- <para>&a.nsayer;</para>
- </listitem>
-
- <listitem>
- <para>Nick Williams <email>njw@cs.city.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Nickolay N. Dudorov <email>nnd@itfs.nsk.su</email></para>
- </listitem>
-
- <listitem>
- <para>Niklas Hallqvist <email>niklas@filippa.appli.se</email></para>
- </listitem>
-
- <listitem>
- <para>Nisha Talagala <email>nisha@cs.berkeley.edu</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>ZW6T-KND@j.asahi-net.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>adrian@virginia.edu</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>alex@elvisti.kiev.ua</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>anto@netscape.net</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>bobson@egg.ics.nitch.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>bovynf@awe.be</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>burg@is.ge.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>chris@gnome.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>colsen@usa.net</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>coredump@nervosa.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>dannyman@arh0300.urh.uiuc.edu</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>davids@SECNET.COM</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>derek@free.org</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>devet@adv.IAEhv.nl</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>djv@bedford.net</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>dvv@sprint.net</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>enami@ba2.so-net.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>flash@eru.tubank.msk.su</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>flash@hway.ru</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>fn@pain.csrv.uidaho.edu</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>gclarkii@netport.neosoft.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>gordon@sheaky.lonestar.org</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>graaf@iae.nl</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>greg@greg.rim.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>grossman@cygnus.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>gusw@fub46.zedat.fu-berlin.de</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>hfir@math.rochester.edu</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>hnokubi@yyy.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>iaint@css.tuu.utas.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>invis@visi.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>ishisone@sra.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>iverson@lionheart.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>jpt@magic.net</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>junker@jazz.snu.ac.kr</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>k-sugyou@ccs.mt.nec.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>kenji@reseau.toyonaka.osaka.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>kfurge@worldnet.att.net</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>lh@aus.org</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>lhecking@nmrc.ucc.ie</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>mrgreen@mame.mu.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>nakagawa@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>ohki@gssm.otsuka.tsukuba.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>owaki@st.rim.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>pechter@shell.monmouth.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>pete@pelican.pelican.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>pritc003@maroon.tc.umn.edu</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>risner@stdio.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>roman@rpd.univ.kiev.ua</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>root@ns2.redline.ru</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>root@uglabgw.ug.cs.sunysb.edu</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>stephen.ma@jtec.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>sumii@is.s.u-tokyo.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>takas-su@is.aist-nara.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>tamone@eig.unige.ch</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>tjevans@raleigh.ibm.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>tony-o@iij.ad.jp amurai@spec.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>torii@tcd.hitachi.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>uenami@imasy.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>uhlar@netlab.sk</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>vode@hut.fi</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>wlloyd@mpd.ca</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>wlr@furball.wellsfargo.com</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>wmbfmk@urc.tue.nl</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>yamagata@nwgpc.kek.jp</email></para>
- </listitem>
-
- <listitem>
- <para>No Name <email>ziggy@ryan.org</email></para>
- </listitem>
-
- <listitem>
- <para>Nobuhiro Yasutomi <email>nobu@psrc.isac.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Nobuyuki Koganemaru
- <email>kogane@koganemaru.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Norio Suzuki <email>nosuzuki@e-mail.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Noritaka Ishizumi <email>graphite@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Noriyuki Soda <email>soda@sra.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Oh Junseon <email>hollywar@mail.holywar.net</email></para>
- </listitem>
-
- <listitem>
- <para>Olaf Wagner <email>wagner@luthien.in-berlin.de</email></para>
- </listitem>
-
- <listitem>
- <para>Oleg Sharoiko <email>os@rsu.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Oleg V. Volkov <email>rover@lglobus.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Oliver Breuninger <email>ob@seicom.NET</email></para>
- </listitem>
-
- <listitem>
- <para>Oliver Friedrichs <email>oliver@secnet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Oliver Fromme
- <email>oliver.fromme@heim3.tu-clausthal.de</email></para>
- </listitem>
-
- <listitem>
- <para>Oliver Laumann
- <email>net@informatik.uni-bremen.de</email></para>
- </listitem>
-
- <listitem>
- <para>Oliver Oberdorf <email>oly@world.std.com</email></para>
- </listitem>
-
- <listitem>
- <para>Olof Johansson <email>offe@ludd.luth.se</email></para>
- </listitem>
-
- <listitem>
- <para>Osokin Sergey aka oZZ <email>ozz@FreeBSD.org.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Pace Willisson <email>pace@blitz.com</email></para>
- </listitem>
-
- <listitem>
- <para>Paco Rosich <email>rosich@modico.eleinf.uv.es</email></para>
- </listitem>
-
- <listitem>
- <para>Palle Girgensohn <email>girgen@partitur.se</email></para>
- </listitem>
-
- <listitem>
- <para>Parag Patel <email>parag@cgt.com</email></para>
- </listitem>
-
- <listitem>
- <para>Pascal Pederiva <email>pascal@zuo.dec.com</email></para>
- </listitem>
-
- <listitem>
- <para>Pasvorn Boonmark <email>boonmark@juniper.net</email></para>
- </listitem>
-
- <listitem>
- <para>Patrick Gardella <email>patrick@cre8tivegroup.com</email></para>
- </listitem>
-
- <listitem>
- <para>Patrick Hausen <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Antonov <email>apg@demos.su</email></para>
- </listitem>
-
- <listitem>
- <para>Paul F. Werkowski <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Fox <email>pgf@foxharp.boston.ma.us</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Koch <email>koch@thehub.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Kranenburg <email>pk@NetBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Mackerras <email>paulus@cs.anu.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Popelka <email>paulp@uts.amdahl.com</email></para>
- </listitem>
-
- <listitem>
- <para>Paul S. LaFollette, Jr. <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Saab <email>paul@mu.org</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Sandys <email>myj@nyct.net</email></para>
- </listitem>
-
- <listitem>
- <para>Paul T. Root <email>proot@horton.iaces.com</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Vixie <email>paul@vix.com</email></para>
- </listitem>
-
- <listitem>
- <para>Paulo Menezes <email>paulo@isr.uc.pt</email></para>
- </listitem>
-
- <listitem>
- <para>Paulo Menezes <email>pm@dee.uc.pt</email></para>
- </listitem>
-
- <listitem>
- <para>Pedro A M Vazquez <email>vazquez@IQM.Unicamp.BR</email></para>
- </listitem>
-
- <listitem>
- <para>Pedro Giffuni <email>giffunip@asme.org</email></para>
- </listitem>
-
- <listitem>
- <para>Pete Bentley <email>pete@demon.net</email></para>
- </listitem>
-
- <listitem>
- <para>Peter Childs <email>pjchilds@imforei.apana.org.au</email></para>
- </listitem>
-
- <listitem>
- <para>Peter Cornelius <email>pc@inr.fzk.de</email></para>
- </listitem>
-
- <listitem>
- <para>Peter Haight <email>peterh@prognet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Peter Jeremy <email>perer.jeremy@alcatel.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Peter M. Chen <email>pmchen@eecs.umich.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Peter Much <email>peter@citylink.dinoex.sub.org</email></para>
- </listitem>
-
- <listitem>
- <para>Peter Olsson <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Peter Philipp <email>pjp@bsd-daemon.net</email></para>
- </listitem>
-
- <listitem>
- <para>Peter Stubbs <email>PETERS@staidan.qld.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>Phil Maker <email>pjm@cs.ntu.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>Phil Sutherland
- <email>philsuth@mycroft.dialix.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Phil Taylor <email>phil@zipmail.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Philip Musumeci <email>philip@rmit.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>Pierre Y. Dampure <email>pierre.dampure@k2c.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Pius Fischer <email>pius@ienet.com</email></para>
- </listitem>
-
- <listitem>
- <para>Pomegranate <email>daver@flag.blackened.net</email></para>
- </listitem>
-
- <listitem>
- <para>Powerdog Industries
- <email>kevin.ruddy@powerdog.com</email></para>
- </listitem>
-
- <listitem>
- <para>R. Kym Horsell</para>
- </listitem>
-
- <listitem>
- <para>Rajesh Vaidheeswarran <email>rv@fore.com</email></para>
- </listitem>
-
- <listitem>
- <para>Ralf Friedl <email>friedl@informatik.uni-kl.de</email></para>
- </listitem>
-
- <listitem>
- <para>Randal S. Masutani <email>randal@comtest.com</email></para>
- </listitem>
-
- <listitem>
- <para>Randall Hopper <email>rhh@ct.picker.com</email></para>
- </listitem>
-
- <listitem>
- <para>Randall W. Dean <email>rwd@osf.org</email></para>
- </listitem>
-
- <listitem>
- <para>Randy Bush <email>rbush@bainbridge.verio.net</email></para>
- </listitem>
-
- <listitem>
- <para>Reinier Bezuidenhout
- <email>rbezuide@mikom.csir.co.za</email></para>
- </listitem>
-
- <listitem>
- <para>Remy Card <email>Remy.Card@masi.ibp.fr</email></para>
- </listitem>
-
- <listitem>
- <para>Ricardas Cepas <email>rch@richard.eu.org</email></para>
- </listitem>
-
- <listitem>
- <para>Riccardo Veraldi <email>veraldi@cs.unibo.it</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Henderson <email>richard@atheist.tamu.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Hwang <email>rhwang@bigpanda.com</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Kiss <email>richard@homemail.com</email></para>
- </listitem>
-
- <listitem>
- <para>Richard J Kuhns <email>rjk@watson.grauel.com</email></para>
- </listitem>
-
- <listitem>
- <para>Richard M. Neswold
- <email>rneswold@drmemory.fnal.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Seaman, Jr. <email>dick@tar.com</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Stallman <email>rms@gnu.ai.mit.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Straka <email>straka@user1.inficad.com</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Tobin <email>richard@cogsci.ed.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Wackerbarth <email>rkw@Dataplex.NET</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Winkel <email>rich@math.missouri.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Richard Wiwatowski <email>rjwiwat@adelaide.on.net</email></para>
- </listitem>
-
- <listitem>
- <para>Rick Macklem <email>rick@snowhite.cis.uoguelph.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Rick Macklin <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Rob Austein <email>sra@epilogue.com</email></para>
- </listitem>
-
- <listitem>
- <para>Rob Mallory <email>rmallory@qualcomm.com</email></para>
- </listitem>
-
- <listitem>
- <para>Rob Snow <email>rsnow@txdirect.net</email></para>
- </listitem>
-
- <listitem>
- <para>Robert Crowe <email>bob@speakez.com</email></para>
- </listitem>
-
- <listitem>
- <para>Robert D. Thrush <email>rd@phoenix.aii.com</email></para>
- </listitem>
-
- <listitem>
- <para>Robert Eckardt
- <email>roberte@MEP.Ruhr-Uni-Bochum.de</email></para>
- </listitem>
-
- <listitem>
- <para>Robert Sanders <email>rsanders@mindspring.com</email></para>
- </listitem>
-
- <listitem>
- <para>Robert Sexton <email>robert@kudra.com</email></para>
- </listitem>
-
- <listitem>
- <para>Robert Shady <email>rls@id.net</email></para>
- </listitem>
-
- <listitem>
- <para>Robert Swindells <email>swindellsr@genrad.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Robert Watson <email>robert@cyrus.watson.org</email></para>
- </listitem>
-
- <listitem>
- <para>Robert Withrow <email>witr@rwwa.com</email></para>
- </listitem>
-
- <listitem>
- <para>Robert Yoder <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Robin Carey
- <email>robin@mailgate.dtc.rankxerox.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Roger Hardiman <email>roger@cs.strath.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Roland Jesse <email>jesse@cs.uni-magdeburg.de</email></para>
- </listitem>
-
- <listitem>
- <para>Ron Bickers <email>rbickers@intercenter.net</email></para>
- </listitem>
-
- <listitem>
- <para>Ron Lenk <email>rlenk@widget.xmission.com</email></para>
- </listitem>
-
- <listitem>
- <para>Ronald Kuehn <email>kuehn@rz.tu-clausthal.de</email></para>
- </listitem>
-
- <listitem>
- <para>Rudolf Cejka <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Ruslan Belkin <email>rus@home2.UA.net</email></para>
- </listitem>
-
- <listitem>
- <para>Ruslan Ermilov <email>ru@ucb.crimea.ua</email></para>
- </listitem>
-
- <listitem>
- <para>Ruslan Shevchenko <email>rssh@cam.grad.kiev.ua</email></para>
- </listitem>
-
- <listitem>
- <para>Russell L. Carter <email>rcarter@pinyon.org</email></para>
- </listitem>
-
- <listitem>
- <para>Russell Vincent <email>rv@groa.uct.ac.za</email></para>
- </listitem>
-
- <listitem>
- <para>Ryan Younce <email>ryany@pobox.com</email></para>
- </listitem>
-
- <listitem>
- <para>Ryuichiro IMURA <email>imura@cs.titech.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>SANETO Takanori <email>sanewo@strg.sony.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>SAWADA Mizuki <email>miz@qb3.so-net.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>SUGIMURA Takashi <email>sugimura@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>SURANYI Peter
- <email>suranyip@jks.is.tsukuba.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Sakai Hiroaki <email>sakai@miya.ee.kagu.sut.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Sakari Jalovaara <email>sja@tekla.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Sam Hartman <email>hartmans@mit.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Samuel Lam <email>skl@ScalableNetwork.com</email></para>
- </listitem>
-
- <listitem>
- <para>Samuele Zannoli <email>zannoli@cs.unibo.it</email></para>
- </listitem>
-
- <listitem>
- <para>Sander Vesik <email>sander@haldjas.folklore.ee</email></para>
- </listitem>
-
- <listitem>
- <para>Sandro Sigala <email>ssigala@globalnet.it</email></para>
- </listitem>
-
- <listitem>
- <para>Sascha Blank <email>blank@fox.uni-trier.de</email></para>
- </listitem>
-
- <listitem>
- <para>Sascha Wildner <email>swildner@channelz.GUN.de</email></para>
- </listitem>
-
- <listitem>
- <para>Satoh Junichi <email>junichi@astec.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Scot Elliott <email>scot@poptart.org</email></para>
- </listitem>
-
- <listitem>
- <para>Scot W. Hetzel <email>hetzels@westbend.net</email></para>
- </listitem>
-
- <listitem>
- <para>Scott A. Kenney <email>saken@rmta.ml.org</email></para>
- </listitem>
-
- <listitem>
- <para>Scott Blachowicz
- <email>scott.blachowicz@seaslug.org</email></para>
- </listitem>
-
- <listitem>
- <para>Scott Burris <email>scott@pita.cns.ucla.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Scott Hazen Mueller <email>scott@zorch.sf-bay.org</email></para>
- </listitem>
-
- <listitem>
- <para>Scott Michel <email>scottm@cs.ucla.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Scott Mitchel <email>scott@uk.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Scott Reynolds <email>scott@clmqt.marquette.mi.us</email></para>
- </listitem>
-
- <listitem>
- <para>Sebastian Strollo <email>seb@erix.ericsson.se</email></para>
- </listitem>
-
- <listitem>
- <para>Serge A. Babkin <email>babkin@hq.icb.chel.su</email></para>
- </listitem>
-
- <listitem>
- <para>Serge V. Vakulenko <email>vak@zebub.msk.su</email></para>
- </listitem>
-
- <listitem>
- <para>Sergei Chechetkin
- <email>csl@whale.sunbay.crimea.ua</email></para>
- </listitem>
-
- <listitem>
- <para>Sergei S. Laskavy <email>laskavy@pc759.cs.msu.su</email></para>
- </listitem>
-
- <listitem>
- <para>Sergey Gershtein <email>sg@mplik.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Sergey Kosyakov <email>ks@itp.ac.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Sergey Potapov <email>sp@alkor.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Sergey Shkonda <email>serg@bcs.zp.ua</email></para>
- </listitem>
-
- <listitem>
- <para>Sergey V.Dorokhov <email>svd@kbtelecom.nalnet.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Sergio Lenzi <email>lenzi@bsi.com.br</email></para>
- </listitem>
-
- <listitem>
- <para>Shaun Courtney <email>shaun@emma.eng.uct.ac.za</email></para>
- </listitem>
-
- <listitem>
- <para>Shawn M. Carey <email>smcarey@mailbox.syr.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Shigio Yamaguchi <email>shigio@tamacom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Shinya Esu <email>esu@yk.rim.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Shuichi Tanaka <email>stanaka@bb.mbn.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Shunsuke Akiyama <email>akiyama@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Simon <email>simon@masi.ibp.fr</email></para>
- </listitem>
-
- <listitem>
- <para>Simon Burge <email>simonb@telstra.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Simon J Gerraty <email>sjg@melb.bull.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Simon Marlow <email>simonm@dcs.gla.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Simon Shapiro <email>shimon@simon-shapiro.org</email></para>
- </listitem>
-
- <listitem>
- <para>Sin'ichiro MIYATANI <email>siu@phaseone.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Slaven Rezic <email>eserte@cs.tu-berlin.de</email></para>
- </listitem>
-
- <listitem>
- <para>Soochon Radee <email>slr@mitre.org</email></para>
- </listitem>
-
- <listitem>
- <para>Soren Dayton <email>csdayton@midway.uchicago.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Soren Dossing <email>sauber@netcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Soren S. Jorvang <email>soren@dt.dk</email></para>
- </listitem>
-
- <listitem>
- <para>Stefan Bethke <email>stb@hanse.de</email></para>
- </listitem>
-
- <listitem>
- <para>Stefan Eggers <email>seggers@semyam.dinoco.de</email></para>
- </listitem>
-
- <listitem>
- <para>Stefan Moeding <email>s.moeding@ndh.net</email></para>
- </listitem>
-
- <listitem>
- <para>Stefan Petri <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Stefan `Sec` Zehl <email>sec@42.org</email></para>
- </listitem>
-
- <listitem>
- <para>Steinar Haug <email>sthaug@nethelp.no</email></para>
- </listitem>
-
- <listitem>
- <para>Stephane E. Potvin <email>sepotvin@videotron.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Stephane Legrand <email>stephane@lituus.fr</email></para>
- </listitem>
-
- <listitem>
- <para>Stephen Clawson
- <email>sclawson@marker.cs.utah.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Stephen F. Combs <email>combssf@salem.ge.com</email></para>
- </listitem>
-
- <listitem>
- <para>Stephen Farrell <email>stephen@farrell.org</email></para>
- </listitem>
-
- <listitem>
- <para>Stephen Hocking <email>sysseh@devetir.qld.gov.au</email></para>
- </listitem>
-
- <listitem>
- <para>Stephen J. Roznowski <email>sjr@home.net</email></para>
- </listitem>
-
- <listitem>
- <para>Stephen McKay <email>syssgm@devetir.qld.gov.au</email></para>
- </listitem>
-
- <listitem>
- <para>Stephen Melvin <email>melvin@zytek.com</email></para>
- </listitem>
-
- <listitem>
- <para>Steve Bauer <email>sbauer@rock.sdsmt.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Steve Coltrin <email>spcoltri@io.com</email></para>
- </listitem>
-
- <listitem>
- <para>Steve Deering <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Steve Gerakines <email>steve2@genesis.tiac.net</email></para>
- </listitem>
-
- <listitem>
- <para>Steve Gericke <email>steveg@comtrol.com</email></para>
- </listitem>
-
- <listitem>
- <para>Steve Piette <email>steve@simon.chi.il.US</email></para>
- </listitem>
-
- <listitem>
- <para>Steve Schwarz <email>schwarz@alpharel.com</email></para>
- </listitem>
-
- <listitem>
- <para>Steven G. Kargl
- <email>kargl@troutmask.apl.washington.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Steven H. Samorodin <email>samorodi@NUXI.com</email></para>
- </listitem>
-
- <listitem>
- <para>Steven McCanne <email>mccanne@cs.berkeley.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Steven Plite <email>splite@purdue.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Steven Wallace <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Stuart Henderson
- <email>stuart@internationalschool.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Sue Blake <email>sue@welearn.com.au</email></para>
- </listitem>
-
- <listitem>
- <para>Sugimoto Sadahiro <email>ixtl@komaba.utmc.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Sugiura Shiro <email>ssugiura@duo.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Sujal Patel <email>smpatel@wam.umd.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Sune Stjerneby <email>stjerneby@usa.net</email></para>
- </listitem>
-
- <listitem>
- <para>Suzuki Yoshiaki
- <email>zensyo@ann.tama.kawasaki.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Tadashi Kumano <email>kumano@strl.nhk.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Taguchi Takeshi <email>taguchi@tohoku.iij.ad.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takahiro Yugawa <email>yugawa@orleans.rim.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takanori Watanabe
- <email>takawata@shidahara1.planet.sci.kobe-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takashi Mega <email>mega@minz.org</email></para>
- </listitem>
-
- <listitem>
- <para>Takashi Uozu <email>j1594016@ed.kagu.sut.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takayuki Ariga <email>a00821@cc.hc.keio.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takeru NAIKI <email>naiki@bfd.es.hokudai.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takeshi Amaike <email>amaike@iri.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takeshi MUTOH <email>mutoh@info.nara-k.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takeshi Ohashi
- <email>ohashi@mickey.ai.kyutech.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takeshi WATANABE
- <email>watanabe@crayon.earth.s.kobe-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Takuya SHIOZAKI
- <email>tshiozak@makino.ise.chuo-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Tatoku Ogaito <email>tacha@tera.fukui-med.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Tatsumi HOSOKAWA <email>hosokawa@jp.FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Ted Buswell <email>tbuswell@mediaone.net</email></para>
- </listitem>
-
- <listitem>
- <para>Ted Faber <email>faber@isi.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Ted Lemon <email>mellon@isc.org</email></para>
- </listitem>
-
- <listitem>
- <para>Terry Lambert <email>terry@lambert.org</email></para>
- </listitem>
-
- <listitem>
- <para>Terry Lee <email>terry@uivlsi.csl.uiuc.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Tetsuya Furukawa <email>tetsuya@secom-sis.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Theo de Raadt <email>deraadt@OpenBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas <email>thomas@mathematik.uni-Bremen.de</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas D. Dean <email>tomdean@ix.netcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas David Rivers <email>rivers@dignus.com</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas G. McWilliams <email>tgm@netcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas Gellekum
- <email>thomas@ghpc8.ihf.rwth-aachen.de</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas Graichen
- <email>graichen@omega.physik.fu-berlin.de</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas K&ouml;nig
- <email>Thomas.Koenig@ciw.uni-karlsruhe.de</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas Ptacek <email>unknown</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas A. Stephens <email>tas@stephens.org</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas Stromberg <email>tstrombe@rtci.com</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas Valentino Crimi
- <email>tcrimi+@andrew.cmu.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Thomas Wintergerst <email>thomas@lemur.nord.de</email></para>
- </listitem>
-
- <listitem>
- <para>&THORN;&oacute;r&eth;ur &Iacute;varsson
- <email>totii@est.is</email></para>
- </listitem>
-
- <listitem>
- <para>Tim Kientzle <email>kientzle@netcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Tim Singletary
- <email>tsingle@sunland.gsfc.nasa.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Tim Wilkinson <email>tim@sarc.city.ac.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Timo J. Rinne <email>tri@iki.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Todd Miller <email>millert@openbsd.org</email></para>
- </listitem>
-
- <listitem>
- <para>Tom <email>root@majestix.cmr.no</email></para>
- </listitem>
-
- <listitem>
- <para>Tom <email>tom@sdf.com</email></para>
- </listitem>
-
- <listitem>
- <para>Tom Gray - DCA <email>dcasba@rain.org</email></para>
- </listitem>
-
- <listitem>
- <para>Tom Jobbins <email>tom@tom.tj</email></para>
- </listitem>
-
- <listitem>
- <para>Tom Pusateri <email>pusateri@juniper.net</email></para>
- </listitem>
-
- <listitem>
- <para>Tom Rush <email>tarush@mindspring.com</email></para>
- </listitem>
-
- <listitem>
- <para>Tom Samplonius <email>tom@misery.sdf.com</email></para>
- </listitem>
-
- <listitem>
- <para>Tomohiko Kurahashi
- <email>kura@melchior.q.t.u-tokyo.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Tony Kimball <email>alk@Think.COM</email></para>
- </listitem>
-
- <listitem>
- <para>Tony Li <email>tli@jnx.com</email></para>
- </listitem>
-
- <listitem>
- <para>Tony Lynn <email>wing@cc.nsysu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Tony Maher <email>tonym@angis.org.au</email></para>
- </listitem>
-
- <listitem>
- <para>Torbjorn Granlund <email>tege@matematik.su.se</email></para>
- </listitem>
-
- <listitem>
- <para>Toshihiko ARAI <email>toshi@tenchi.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Toshihiko SHIMOKAWA <email>toshi@tea.forus.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Toshihiro Kanda <email>candy@kgc.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Toshiomi Moriki
- <email>Toshiomi.Moriki@ma1.seikyou.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Trefor S. <email>trefor@flevel.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Trevor Blackwell <email>tlb@viaweb.com</email></para>
- </listitem>
-
- <listitem>
- <para>URATA Shuichiro <email>s-urata@nmit.tmg.nec.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Udo Schweigert <email>ust@cert.siemens.de</email></para>
- </listitem>
-
- <listitem>
- <para>Ugo Paternostro <email>paterno@dsi.unifi.it</email></para>
- </listitem>
-
- <listitem>
- <para>Ulf Kieber <email>kieber@sax.de</email></para>
- </listitem>
-
- <listitem>
- <para>Ulli Linzen <email>ulli@perceval.camelot.de</email></para>
- </listitem>
-
- <listitem>
- <para>Ustimenko Semen <email>semen@iclub.nsu.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Uwe Arndt <email>arndt@mailhost.uni-koblenz.de</email></para>
- </listitem>
-
- <listitem>
- <para>Vadim Chekan <email>vadim@gc.lviv.ua</email></para>
- </listitem>
-
- <listitem>
- <para>Vadim Kolontsov <email>vadim@tversu.ac.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Vadim Mikhailov <email>mvp@braz.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Van Jacobson <email>van@ee.lbl.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Vasily V. Grechishnikov
- <email>bazilio@ns1.ied-vorstu.ac.ru</email></para>
- </listitem>
-
- <listitem>
- <para>Vasim Valejev <email>vasim@uddias.diaspro.com</email></para>
- </listitem>
-
- <listitem>
- <para>Vernon J. Schryver <email>vjs@mica.denver.sgi.com</email></para>
- </listitem>
-
- <listitem>
- <para>Vic Abell <email>abe@cc.purdue.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Ville Eerola <email>ve@sci.fi</email></para>
- </listitem>
-
- <listitem>
- <para>Vincent Poy <email>vince@venus.gaianet.net</email></para>
- </listitem>
-
- <listitem>
- <para>Vincenzo Capuano
- <email>VCAPUANO@vmprofs.esoc.esa.de</email></para>
- </listitem>
-
- <listitem>
- <para>Virgil Champlin <email>champlin@pa.dec.com</email></para>
- </listitem>
-
- <listitem>
- <para>Vladimir A. Jakovenko
- <email>vovik@ntu-kpi.kiev.ua</email></para>
- </listitem>
-
- <listitem>
- <para>Vladimir Kushnir <email>kushn@mail.kar.net</email></para>
- </listitem>
-
- <listitem>
- <para>Vsevolod Lobko <email>seva@alex-ua.com</email></para>
- </listitem>
-
- <listitem>
- <para>W. Gerald Hicks <email>wghicks@bellsouth.net</email></para>
- </listitem>
-
- <listitem>
- <para>W. Richard Stevens <email>rstevens@noao.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Walt Howard <email>howard@ee.utah.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Warren Toomey <email>wkt@csadfa.cs.adfa.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Wayne Scott <email>wscott@ichips.intel.com</email></para>
- </listitem>
-
- <listitem>
- <para>Werner Griessl
- <email>werner@btp1da.phy.uni-bayreuth.de</email></para>
- </listitem>
-
- <listitem>
- <para>Wes Santee <email>wsantee@wsantee.oz.net</email></para>
- </listitem>
-
- <listitem>
- <para>Wietse Venema <email>wietse@wzv.win.tue.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Wilfredo Sanchez <email>wsanchez@apple.com</email></para>
- </listitem>
-
- <listitem>
- <para>Wiljo Heinen <email>wiljo@freeside.ki.open.de</email></para>
- </listitem>
-
- <listitem>
- <para>Wilko Bulte <email>wilko@yedi.iaf.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Will Andrews <email>andrews@technologist.com</email></para>
- </listitem>
-
- <listitem>
- <para>Willem Jan Withagen <email>wjw@surf.IAE.nl</email></para>
- </listitem>
-
- <listitem>
- <para>William Jolitz <email>withheld</email></para>
- </listitem>
-
- <listitem>
- <para>William Liao <email>william@tale.net</email></para>
- </listitem>
-
- <listitem>
- <para>Wojtek Pilorz
- <email>wpilorz@celebris.bdk.lublin.pl</email></para>
- </listitem>
-
- <listitem>
- <para>Wolfgang Helbig <email>helbig@ba-stuttgart.de</email></para>
- </listitem>
-
- <listitem>
- <para>Wolfgang Solfrank <email>ws@tools.de</email></para>
- </listitem>
-
- <listitem>
- <para>Wolfgang Stanglmeier <email>wolf@FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Wu Ching-hong <email>woju@FreeBSD.ee.Ntu.edu.TW</email></para>
- </listitem>
-
- <listitem>
- <para>Yarema <email>yds@ingress.com</email></para>
- </listitem>
-
- <listitem>
- <para>Yaroslav Terletsky <email>ts@polynet.lviv.ua</email></para>
- </listitem>
-
- <listitem>
- <para>Yasuhito FUTATSUKI <email>futatuki@fureai.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yasuhiro Fukama <email>yasuf@big.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yen-Shuo Su <email>yssu@CCCA.NCTU.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Ying-Chieh Liao <email>ijliao@csie.NCTU.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>Yixin Jin <email>yjin@rain.cs.ucla.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Yoshiaki Uchikawa <email>yoshiaki@kt.rim.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yoshihiko OHTA <email>yohta@bres.tsukuba.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yoshihisa NAKAGAWA
- <email>y-nakaga@ccs.mt.nec.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yoshikazu Goto <email>gotoh@ae.anritsu.co.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yoshimasa Ohnishi
- <email>ohnishi@isc.kyutech.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yoshishige Arai <email>ryo2@on.rim.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yuichi MATSUTAKA <email>matutaka@osa.att.ne.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yujiro MIYATA
- <email>miyata@bioele.nuee.nagoya-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yukihiro Nakai <email>nacai@iname.com</email></para>
- </listitem>
-
- <listitem>
- <para>Yusuke Nawano <email>azuki@azkey.org</email></para>
- </listitem>
-
- <listitem>
- <para>Yuu Yashiki <email>s974123@cc.matsuyama-u.ac.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Yuval Yarom <email>yval@cs.huji.ac.il</email></para>
- </listitem>
-
- <listitem>
- <para>Yves Fonk <email>yves@cpcoup5.tn.tudelft.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Yves Fonk <email>yves@dutncp8.tn.tudelft.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Zach Heilig <email>zach@gaffaneys.com</email></para>
- </listitem>
-
- <listitem>
- <para>Zahemszhky Gabor <email>zgabor@code.hu</email></para>
- </listitem>
-
- <listitem>
- <para>Zhong Ming-Xun <email>zmx@mail.CDPA.nsysu.edu.tw</email></para>
- </listitem>
-
- <listitem>
- <para>arci <email>vega@sophia.inria.fr</email></para>
- </listitem>
-
- <listitem>
- <para>der Mouse <email>mouse@Collatz.McRCIM.McGill.EDU</email></para>
- </listitem>
-
- <listitem>
- <para>frf <email>frf@xocolatl.com</email></para>
- </listitem>
-
- <listitem>
- <para>Ege Rekk <email>aagero@aage.priv.no</email></para>
- </listitem>
- </itemizedlist>
- </sect1>
-
- <sect1>
- <title>386BSD Patch Kit Patch Contributors</title>
-
- <para>(in alphabetical order by first name):</para>
-
- <itemizedlist>
- <listitem>
- <para>Adam Glass <email>glass@postgres.berkeley.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Adrian Hall <email>adrian@ibmpcug.co.uk</email></para>
- </listitem>
-
- <listitem>
- <para>Andrey A. Chernov <email>ache@astral.msk.su</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Herbert <email>andrew@werple.apana.org.au</email></para>
- </listitem>
-
- <listitem>
- <para>Andrew Moore <email>alm@netcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Andy Valencia <email>ajv@csd.mot.com</email>
- <email>jtk@netcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Arne Henrik Juul <email>arnej@Lise.Unit.NO</email></para>
- </listitem>
-
- <listitem>
- <para>Bakul Shah <email>bvs@bitblocks.com</email></para>
- </listitem>
-
- <listitem>
- <para>Barry Lustig <email>barry@ictv.com</email></para>
- </listitem>
-
- <listitem>
- <para>Bob Wilcox <email>bob@obiwan.uucp</email></para>
- </listitem>
-
- <listitem>
- <para>Branko Lankester</para>
- </listitem>
-
- <listitem>
- <para>Brett Lymn <email>blymn@mulga.awadi.com.AU</email></para>
- </listitem>
-
- <listitem>
- <para>Charles Hannum <email>mycroft@ai.mit.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Chris G. Demetriou
- <email>cgd@postgres.berkeley.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Chris Torek <email>torek@ee.lbl.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Christoph Robitschko
- <email>chmr@edvz.tu-graz.ac.at</email></para>
- </listitem>
-
- <listitem>
- <para>Daniel Poirot <email>poirot@aio.jsc.nasa.gov</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Burgess <email>burgess@hrd769.brooks.af.mil</email></para>
- </listitem>
-
- <listitem>
- <para>Dave Rivers <email>rivers@ponds.uucp</email></para>
- </listitem>
-
- <listitem>
- <para>David Dawes <email>dawes@physics.su.OZ.AU</email></para>
- </listitem>
-
- <listitem>
- <para>David Greenman <email>dg@Root.COM</email></para>
- </listitem>
-
- <listitem>
- <para>Eric J. Haug <email>ejh@slustl.slu.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Felix Gaehtgens
- <email>felix@escape.vsse.in-berlin.de</email></para>
- </listitem>
-
- <listitem>
- <para>Frank Maclachlan <email>fpm@crash.cts.com</email></para>
- </listitem>
-
- <listitem>
- <para>Gary A. Browning <email>gab10@griffcd.amdahl.com</email></para>
- </listitem>
-
- <listitem>
- <para>Gary Howland <email>gary@hotlava.com</email></para>
- </listitem>
-
- <listitem>
- <para>Geoff Rehmet <email>csgr@alpha.ru.ac.za</email></para>
- </listitem>
-
- <listitem>
- <para>Goran Hammarback <email>goran@astro.uu.se</email></para>
- </listitem>
-
- <listitem>
- <para>Guido van Rooij <email>guido@gvr.org</email></para>
- </listitem>
-
- <listitem>
- <para>Guy Harris <email>guy@auspex.com</email></para>
- </listitem>
-
- <listitem>
- <para>Havard Eidnes
- <email>Havard.Eidnes@runit.sintef.no</email></para>
- </listitem>
-
- <listitem>
- <para>Herb Peyerl <email>hpeyerl@novatel.cuc.ab.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Holger Veit <email>Holger.Veit@gmd.de</email></para>
- </listitem>
-
- <listitem>
- <para>Ishii Masahiro, R. Kym Horsell</para>
- </listitem>
-
- <listitem>
- <para>J.T. Conklin <email>jtc@cygnus.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jagane D Sundar <email>jagane@netcom.com</email></para>
- </listitem>
-
- <listitem>
- <para>James Clark <email>jjc@jclark.com</email></para>
- </listitem>
-
- <listitem>
- <para>James Jegers <email>jimj@miller.cs.uwm.edu</email></para>
- </listitem>
-
- <listitem>
- <para>James W. Dolter</para>
- </listitem>
-
- <listitem>
- <para>James da Silva <email>jds@cs.umd.edu</email> et al</para>
- </listitem>
-
- <listitem>
- <para>Jay Fenlason <email>hack@datacube.com</email></para>
- </listitem>
-
- <listitem>
- <para>Jim Wilson <email>wilson@moria.cygnus.com</email></para>
- </listitem>
-
- <listitem>
- <para>J&ouml;rg Lohse
- <email>lohse@tech7.informatik.uni-hamburg.de</email></para>
- </listitem>
-
- <listitem>
- <para>J&ouml;rg Wunsch
- <email>joerg_wunsch@uriah.heep.sax.de</email></para>
- </listitem>
-
- <listitem>
- <para>John Dyson</para>
- </listitem>
-
- <listitem>
- <para>John Woods <email>jfw@eddie.mit.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Jordan K. Hubbard <email>jkh@whisker.hubbard.ie</email></para>
- </listitem>
-
- <listitem>
- <para>Julian Elischer <email>julian@dialix.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Julian Stacey <email>jhs@FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Karl Dietz <email>Karl.Dietz@triplan.com</email></para>
- </listitem>
-
- <listitem>
- <para>Karl Lehenbauer <email>karl@NeoSoft.com</email>
- <email>karl@one.neosoft.com</email></para>
- </listitem>
-
- <listitem>
- <para>Keith Bostic <email>bostic@toe.CS.Berkeley.EDU</email></para>
- </listitem>
-
- <listitem>
- <para>Ken Hughes</para>
- </listitem>
-
- <listitem>
- <para>Kent Talarico <email>kent@shipwreck.tsoft.net</email></para>
- </listitem>
-
- <listitem>
- <para>Kevin Lahey <email>kml%rokkaku.UUCP@mathcs.emory.edu</email>
- <email>kml@mosquito.cis.ufl.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Marc Frajola <email>marc@dev.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mark Tinguely <email>tinguely@plains.nodak.edu</email>
- <email>tinguely@hookie.cs.ndsu.NoDak.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Martin Renters <email>martin@tdc.on.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Clay <email>mclay@weareb.org</email></para>
- </listitem>
-
- <listitem>
- <para>Michael Galassi <email>nerd@percival.rain.com</email></para>
- </listitem>
-
- <listitem>
- <para>Mike Durkin <email>mdurkin@tsoft.sf-bay.org</email></para>
- </listitem>
-
- <listitem>
- <para>Naoki Hamada <email>nao@tom-yam.or.jp</email></para>
- </listitem>
-
- <listitem>
- <para>Nate Williams <email>nate@bsd.coe.montana.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Nick Handel <email>nhandel@NeoSoft.com</email>
- <email>nick@madhouse.neosoft.com</email></para>
- </listitem>
-
- <listitem>
- <para>Pace Willisson <email>pace@blitz.com</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Kranenburg <email>pk@cs.few.eur.nl</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Mackerras <email>paulus@cs.anu.edu.au</email></para>
- </listitem>
-
- <listitem>
- <para>Paul Popelka <email>paulp@uts.amdahl.com</email></para>
- </listitem>
-
- <listitem>
- <para>Peter da Silva <email>peter@NeoSoft.com</email></para>
- </listitem>
-
- <listitem>
- <para>Phil Sutherland
- <email>philsuth@mycroft.dialix.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Poul-Henning Kamp<email>phk@FreeBSD.org</email></para>
- </listitem>
-
- <listitem>
- <para>Ralf Friedl <email>friedl@informatik.uni-kl.de</email></para>
- </listitem>
-
- <listitem>
- <para>Rick Macklem <email>root@snowhite.cis.uoguelph.ca</email></para>
- </listitem>
-
- <listitem>
- <para>Robert D. Thrush <email>rd@phoenix.aii.com</email></para>
- </listitem>
-
- <listitem>
- <para>Rodney W. Grimes <email>rgrimes@cdrom.com</email></para>
- </listitem>
-
- <listitem>
- <para>Sascha Wildner <email>swildner@channelz.GUN.de</email></para>
- </listitem>
-
- <listitem>
- <para>Scott Burris <email>scott@pita.cns.ucla.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Scott Reynolds <email>scott@clmqt.marquette.mi.us</email></para>
- </listitem>
-
- <listitem>
- <para>Sean Eric Fagan <email>sef@kithrup.com</email></para>
- </listitem>
-
- <listitem>
- <para>Simon J Gerraty <email>sjg@melb.bull.oz.au</email>
- <email>sjg@zen.void.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Stephen McKay <email>syssgm@devetir.qld.gov.au</email></para>
- </listitem>
-
- <listitem>
- <para>Terry Lambert <email>terry@icarus.weber.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Terry Lee <email>terry@uivlsi.csl.uiuc.edu</email></para>
- </listitem>
-
- <listitem>
- <para>Tor Egge <email>Tor.Egge@idi.ntnu.no</email></para>
- </listitem>
-
- <listitem>
- <para>Warren Toomey <email>wkt@csadfa.cs.adfa.oz.au</email></para>
- </listitem>
-
- <listitem>
- <para>Wiljo Heinen <email>wiljo@freeside.ki.open.de</email></para>
- </listitem>
-
- <listitem>
- <para>William Jolitz <email>withheld</email></para>
- </listitem>
-
- <listitem>
- <para>Wolfgang Solfrank <email>ws@tools.de</email></para>
- </listitem>
-
- <listitem>
- <para>Wolfgang Stanglmeier <email>wolf@dentaro.GUN.de</email></para>
- </listitem>
-
- <listitem>
- <para>Yuval Yarom <email>yval@cs.huji.ac.il</email></para>
- </listitem>
- </itemizedlist>
- </sect1>
-</chapter>
-
-<!--
- Local Variables:
- mode: sgml
- sgml-declaration: "../chapter.decl"
- sgml-indent-data: t
- sgml-omittag: nil
- sgml-always-quote-attributes: t
- sgml-parent-document: ("../handbook.sgml" "part" "chapter")
- End:
--->
-
diff --git a/en_US.ISO8859-1/books/arch-handbook/Makefile b/en_US.ISO8859-1/books/arch-handbook/Makefile
deleted file mode 100644
index 588f1e0b13..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# $FreeBSD$
-#
-# Build the FreeBSD Developers' Handbook.
-#
-
-MAINTAINER=murray@FreeBSD.org
-
-DOC?= book
-
-FORMATS?= html-split
-
-HAS_INDEX= true
-
-INSTALL_COMPRESSED?= gz
-INSTALL_ONLY_COMPRESSED?=
-
-# Images
-IMAGES= sockets/layers.eps sockets/sain.eps sockets/sainfill.eps sockets/sainlsb.eps sockets/sainmsb.eps sockets/sainserv.eps sockets/serv.eps sockets/serv2.eps sockets/slayers.eps
-
-#
-# SRCS lists the individual SGML files that make up the document. Changes
-# to any of these files will force a rebuild
-#
-
-# SGML content
-SRCS= book.sgml
-SRCS+= dma/chapter.sgml
-SRCS+= driverbasics/chapter.sgml
-SRCS+= introduction/chapter.sgml
-SRCS+= ipv6/chapter.sgml
-SRCS+= isa/chapter.sgml
-SRCS+= jail/chapter.sgml
-SRCS+= kerneldebug/chapter.sgml
-SRCS+= kobj/chapter.sgml
-SRCS+= l10n/chapter.sgml
-SRCS+= locking/chapter.sgml
-SRCS+= pci/chapter.sgml
-SRCS+= policies/chapter.sgml
-SRCS+= scsi/chapter.sgml
-SRCS+= secure/chapter.sgml
-SRCS+= sockets/chapter.sgml
-SRCS+= sound/chapter.sgml
-SRCS+= sysinit/chapter.sgml
-SRCS+= tools/chapter.sgml
-SRCS+= usb/chapter.sgml
-SRCS+= vm/chapter.sgml
-SRCS+= x86/chapter.sgml
-
-# Entities
-
-DOC_PREFIX?= ${.CURDIR}/../../..
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/en_US.ISO8859-1/books/arch-handbook/book.sgml b/en_US.ISO8859-1/books/arch-handbook/book.sgml
deleted file mode 100644
index 5cf43b0a06..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/book.sgml
+++ /dev/null
@@ -1,311 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
-<!ENTITY % bookinfo PUBLIC "-//FreeBSD//ENTITIES DocBook BookInfo Entities//EN">
-%bookinfo;
-<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN">
-%man;
-<!ENTITY % chapters SYSTEM "chapters.ent"> %chapters;
-<!ENTITY % authors PUBLIC "-//FreeBSD//ENTITIES DocBook Author Entities//EN"> %authors
-<!ENTITY % mailing-lists PUBLIC "-//FreeBSD//ENTITIES DocBook Mailing List Entities//EN"> %mailing-lists;
-<!ENTITY % chap.index "IGNORE">
-]>
-
-<book>
- <bookinfo>
- <title>FreeBSD Developers' Handbook</title>
-
- <corpauthor>The FreeBSD Documentation Project</corpauthor>
-
- <pubdate>August 2000</pubdate>
-
- <copyright>
- <year>2000</year>
- <year>2001</year>
- <year>2002</year>
- <holder>The FreeBSD Documentation Project</holder>
- </copyright>
-
- &bookinfo.legalnotice;
-
- <abstract>
- <para>Welcome to the Developers' Handbook. This manual is a
- <emphasis>work in progress</emphasis> and is the work of many
- individuals. Many sections do not yet exist and some of those
- that do exist need to be updated. If you are interested in
- helping with this project, send email to the &a.doc;.</para>
-
- <para>The latest version of this document is always available
- from the <ulink URL="../../../../index.html">FreeBSD World
- Wide Web server</ulink>. It may also be downloaded in a
- variety of formats and compression options from the <ulink
- url="ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/">FreeBSD FTP
- server</ulink> or one of the numerous <ulink
- url="../handbook/mirrors-ftp.html">mirror
- sites</ulink>.</para>
- </abstract>
- </bookinfo>
-
- <part id="Basics">
- <title>Basics</title>
-
- &chap.introduction;
- &chap.tools;
- &chap.secure;
- &chap.l10n;
- &chap.policies;
-
- </part>
-
- <part id="ipc">
- <title>Interprocess Communication</title>
-
- <chapter id="signals">
- <title>* Signals</title>
-
- <para>Signals, pipes, semaphores, message queues, shared memory,
- ports, sockets, doors</para>
-
- </chapter>
-
- &chap.sockets;
- &chap.ipv6;
-
- </part>
-
- <part id="kernel">
- <title>Kernel</title>
-
- <chapter id="kernelhistory">
- <title>* History of the Unix Kernel</title>
-
- <para>Some history of the Unix/BSD kernel, system calls, how
- processes work, blocking, scheduling, threads (kernel),
- context switching, signals, interrupts, modules, etc.</para>
-
- <para></para>
- </chapter>
-
- &chap.locking;
- &chap.kobj;
- &chap.jail;
- &chap.sysinit;
- &chap.vm;
- &chap.dma;
- &chap.kerneldebug;
-
- <chapter id="ufs">
- <title>* UFS</title>
-
- <para>UFS, FFS, Ext2FS, JFS, inodes, buffer cache, labeling,
- locking, metadata, soft-updates, LFS, portalfs, procfs,
- vnodes, memory sharing, memory objects, TLBs, caching</para>
-
- </chapter>
-
- <chapter id="afs">
- <title>* AFS</title>
-
- <para>AFS, NFS, SANs, etc.</para>
-
- </chapter>
-
- <chapter id="syscons">
- <title>* Syscons</title>
-
- <para>Syscons, tty, PCVT, serial console, screen savers,
- etc.</para>
-
- </chapter>
-
- <chapter id="compatibility">
- <title>* Compatibility Layers</title>
-
- <sect1 id="linux">
- <title>* Linux</title>
-
- <para>Linux, SVR4, etc.</para>
- </sect1>
-
- </chapter>
- </part>
-
- <part id="devicedrivers">
- <title>Device Drivers</title>
-
- &chap.driverbasics;
- &chap.isa;
- &chap.pci;
- &chap.scsi;
- &chap.usb;
-
- <chapter id="newbus">
- <title>* NewBus</title>
-
- <para>This chapter will talk about the FreeBSD NewBus
- architecture.</para>
- </chapter>
-
- &chap.snd;
-
- </part>
-
- <part id="architectures">
- <title>Architectures</title>
-
- &chap.x86;
-
- <chapter id="alpha">
- <title>* Alpha</title>
-
- <para>Talk about the architectural specifics of
- FreeBSD/alpha.</para>
-
- <para>Explanation of alignment errors, how to fix, how to
- ignore.</para>
-
- <para>Example assembly language code for FreeBSD/alpha.</para>
- </chapter>
-
- <chapter id="ia64">
- <title>* IA-64</title>
-
- <para>Talk about the architectural specifics of
- FreeBSD/ia64.</para>
-
- </chapter>
- </part>
-
- <part id="appendices">
- <title>Appendices</title>
-
- <bibliography>
-
- <biblioentry id="COD" xreflabel="1">
- <authorgroup>
- <author>
- <firstname>Dave</firstname>
- <othername role="MI">A</othername>
- <surname>Patterson</surname>
- </author>
- <author>
- <firstname>John</firstname>
- <othername role="MI">L</othername>
- <surname>Hennessy</surname>
- </author>
- </authorgroup>
- <copyright><year>1998</year><holder>Morgan Kaufmann Publishers,
- Inc.</holder></copyright>
- <isbn>1-55860-428-6</isbn>
- <publisher>
- <publishername>Morgan Kaufmann Publishers, Inc.</publishername>
- </publisher>
- <title>Computer Organization and Design</title>
- <subtitle>The Hardware / Software Interface</subtitle>
- <pagenums>1-2</pagenums>
- </biblioentry>
-
- <biblioentry xreflabel="2">
- <authorgroup>
- <author>
- <firstname>W.</firstname>
- <othername role="Middle">Richard</othername>
- <surname>Stevens</surname>
- </author>
- </authorgroup>
- <copyright><year>1993</year><holder>Addison Wesley Longman,
- Inc.</holder></copyright>
- <isbn>0-201-56317-7</isbn>
- <publisher>
- <publishername>Addison Wesley Longman, Inc.</publishername>
- </publisher>
- <title>Advanced Programming in the Unix Environment</title>
- <pagenums>1-2</pagenums>
- </biblioentry>
-
- <biblioentry xreflabel="3">
- <authorgroup>
- <author>
- <firstname>Marshall</firstname>
- <othername role="Middle">Kirk</othername>
- <surname>McKusick</surname>
- </author>
- <author>
- <firstname>Keith</firstname>
- <surname>Bostic</surname>
- </author>
- <author>
- <firstname>Michael</firstname>
- <othername role="MI">J</othername>
- <surname>Karels</surname>
- </author>
- <author>
- <firstname>John</firstname>
- <othername role="MI">S</othername>
- <surname>Quarterman</surname>
- </author>
- </authorgroup>
- <copyright><year>1996</year><holder>Addison-Wesley Publishing Company,
- Inc.</holder></copyright>
- <isbn>0-201-54979-4</isbn>
- <publisher>
- <publishername>Addison-Wesley Publishing Company, Inc.</publishername>
- </publisher>
- <title>The Design and Implementation of the 4.4 BSD Operating System</title>
- <pagenums>1-2</pagenums>
- </biblioentry>
-
- <biblioentry id="Phrack" xreflabel="4">
- <authorgroup>
- <author>
- <firstname>Aleph</firstname>
- <surname>One</surname>
- </author>
- </authorgroup>
- <title>Phrack 49; "Smashing the Stack for Fun and Profit"</title>
- </biblioentry>
-
- <biblioentry id="StackGuard" xreflabel="5">
- <authorgroup>
- <author>
- <firstname>Chrispin</firstname>
- <surname>Cowan</surname>
- </author>
- <author>
- <firstname>Calton</firstname>
- <surname>Pu</surname>
- </author>
- <author>
- <firstname>Dave</firstname>
- <surname>Maier</surname>
- </author>
- </authorgroup>
- <title>StackGuard; Automatic Adaptive Detection and Prevention of
- Buffer-Overflow Attacks</title>
- </biblioentry>
-
- <biblioentry id="OpenBSD" xreflabel="6">
- <authorgroup>
- <author>
- <firstname>Todd</firstname>
- <surname>Miller</surname>
- </author>
- <author>
- <firstname>Theo</firstname>
- <surname>de Raadt</surname>
- </author>
- </authorgroup>
- <title>strlcpy and strlcat -- consistent, safe string copy and
- concatenation.</title>
- </biblioentry>
-
- </bibliography>
-
- <![ %chap.index; [ &chap.index; ]]>
- </part>
-
-</book>
diff --git a/en_US.ISO8859-1/books/arch-handbook/chapters.ent b/en_US.ISO8859-1/books/arch-handbook/chapters.ent
deleted file mode 100644
index da3682e830..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/chapters.ent
+++ /dev/null
@@ -1,45 +0,0 @@
-<!--
- Creates entities for each chapter in the FreeBSD Developer's
- Handbook. Each entity is named chap.foo, where foo is the value
- of the id attribute on that chapter, and corresponds to the name of
- the directory in which that chapter's .sgml file is stored.
-
- Chapters should be listed in the order in which they are referenced.
-
- $FreeBSD$
--->
-
-<!-- Part one -->
-<!ENTITY chap.introduction SYSTEM "introduction/chapter.sgml">
-<!ENTITY chap.tools SYSTEM "tools/chapter.sgml">
-<!ENTITY chap.secure SYSTEM "secure/chapter.sgml">
-<!ENTITY chap.l10n SYSTEM "l10n/chapter.sgml">
-<!ENTITY chap.policies SYSTEM "policies/chapter.sgml">
-
-<!-- Part two - IPC -->
-<!ENTITY chap.sockets SYSTEM "sockets/chapter.sgml">
-<!ENTITY chap.ipv6 SYSTEM "ipv6/chapter.sgml">
-
-<!-- Part three - Kernel -->
-<!ENTITY chap.kobj SYSTEM "kobj/chapter.sgml">
-<!ENTITY chap.sysinit SYSTEM "sysinit/chapter.sgml">
-<!ENTITY chap.locking SYSTEM "locking/chapter.sgml">
-<!ENTITY chap.vm SYSTEM "vm/chapter.sgml">
-<!ENTITY chap.dma SYSTEM "dma/chapter.sgml">
-<!ENTITY chap.kerneldebug SYSTEM "kerneldebug/chapter.sgml">
-<!ENTITY chap.jail SYSTEM "jail/chapter.sgml">
-
-<!-- Part four - Device Drivers -->
-<!ENTITY chap.driverbasics SYSTEM "driverbasics/chapter.sgml">
-<!ENTITY chap.isa SYSTEM "isa/chapter.sgml">
-<!ENTITY chap.pci SYSTEM "pci/chapter.sgml">
-<!ENTITY chap.scsi SYSTEM "scsi/chapter.sgml">
-<!ENTITY chap.usb SYSTEM "usb/chapter.sgml">
-<!ENTITY chap.snd SYSTEM "sound/chapter.sgml">
-
-<!-- Part five - Architectures -->
-<!ENTITY chap.x86 SYSTEM "x86/chapter.sgml">
-
-<!-- Part six - Appendices -->
-<!ENTITY chap.bibliography SYSTEM "bibliography/chapter.sgml">
-<!ENTITY chap.index SYSTEM "index.sgml">
diff --git a/en_US.ISO8859-1/books/arch-handbook/driverbasics/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/driverbasics/chapter.sgml
deleted file mode 100644
index b5294e63fc..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/driverbasics/chapter.sgml
+++ /dev/null
@@ -1,390 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="driverbasics">
- <title>Writing FreeBSD Device Drivers</title>
-
- <para>This chapter was written by &a.murray; with selections from a
- variety of sources including the intro(4) manual page by
- &a.joerg;.</para>
-
- <sect1>
- <title>Introduction</title>
- <para>This chapter provides a brief introduction to writing device
- drivers for FreeBSD. A device in this context is a term used
- mostly for hardware-related stuff that belongs to the system,
- like disks, printers, or a graphics display with its keyboard.
- A device driver is the software component of the operating
- system that controls a specific device. There are also
- so-called pseudo-devices where a device driver emulates the
- behavior of a device in software without any particular
- underlying hardware. Device drivers can be compiled into the
- system statically or loaded on demand through the dynamic kernel
- linker facility `kld'.</para>
-
- <para>Most devices in a Unix-like operating system are accessed
- through device-nodes, sometimes also called special files.
- These files are usually located under the directory
- <filename>/dev</filename> in the filesystem hierarchy. Until
- devfs is fully integrated into FreeBSD, each device node must be
- created statically and independent of the existence of the
- associated device driver. Most device nodes on the system are
- created by running <command>MAKEDEV</command>.</para>
-
- <para>Device drivers can roughly be broken down into two
- categories; character and network device drivers.</para>
-
- </sect1>
-
- <sect1>
- <title>Dynamic Kernel Linker Facility - KLD</title>
-
- <para>The kld interface allows system administrators to
- dynamically add and remove functionality from a running system.
- This allows device driver writers to load their new changes into
- a running kernel without constantly rebooting to test
- changes.</para>
-
- <para>The kld interface is used through the following
- privileged commands:
-
- <itemizedlist>
- <listitem><simpara><command>kldload</command> - loads a new kernel
- module</simpara></listitem>
- <listitem><simpara><command>kldunload</command> - unloads a kernel
- module</simpara></listitem>
- <listitem><simpara><command>kldstat</command> - lists the currently loaded
- modules</simpara></listitem>
- </itemizedlist>
- </para>
-
- <para>Skeleton Layout of a kernel module</para>
-
-<programlisting>/*
- * KLD Skeleton
- * Inspired by Andrew Reiter's Daemonnews article
- */
-
-#include &lt;sys/types.h&gt;
-#include &lt;sys/module.h&gt;
-#include &lt;sys/systm.h&gt; /* uprintf */
-#include &lt;sys/errno.h&gt;
-#include &lt;sys/param.h&gt; /* defines used in kernel.h */
-#include &lt;sys/kernel.h&gt; /* types used in module initialization */
-
-/*
- * Load handler that deals with the loading and unloading of a KLD.
- */
-
-static int
-skel_loader(struct module *m, int what, void *arg)
-{
- int err = 0;
-
- switch (what) {
- case MOD_LOAD: /* kldload */
- uprintf("Skeleton KLD loaded.\n");
- break;
- case MOD_UNLOAD:
- uprintf("Skeleton KLD unloaded.\n");
- break;
- default:
- err = EINVAL;
- break;
- }
- return(err);
-}
-
-/* Declare this module to the rest of the kernel */
-
-static moduledata_t skel_mod = {
- "skel",
- skel_loader,
- NULL
-};
-
-DECLARE_MODULE(skeleton, skel_mod, SI_SUB_KLD, SI_ORDER_ANY);</programlisting>
-
-
- <sect2>
- <title>Makefile</title>
-
- <para>FreeBSD provides a makefile include that you can use to
- quickly compile your kernel addition.</para>
-
- <programlisting>SRCS=skeleton.c
-KMOD=skeleton
-
-.include &lt;bsd.kmod.mk&gt;</programlisting>
-
- <para>Simply running <command>make</command> with this makefile
- will create a file <filename>skeleton.ko</filename> that can
- be loaded into your system by typing:
-<screen>&prompt.root; kldload -v ./skeleton.ko</screen>
- </para>
- </sect2>
- </sect1>
-
- <sect1>
- <title>Accessing a device driver</title>
-
- <para>Unix provides a common set of system calls for user
- applications to use. The upper layers of the kernel dispatch
- these calls to the corresponding device driver when a user
- accesses a device node. The <command>/dev/MAKEDEV</command>
- script makes most of the device nodes for your system but if you
- are doing your own driver development it may be necessary to
- create your own device nodes with <command>mknod</command>.
- </para>
-
- <sect2>
- <title>Creating static device nodes</title>
-
- <para>The <command>mknod</command> command requires four
- arguments to create a device node. You must specify the name
- of the device node, the type of device, the major number of
- the device, and the minor number of the device.</para>
- </sect2>
-
- <sect2>
- <title>Dynamic device nodes</title>
-
- <para>The device filesystem, or devfs, provides access to the
- kernel's device namespace in the global filesystem namespace.
- This eliminates the problems of potentially having a device
- driver without a static device node, or a device node without
- an installed device driver. Devfs is still a work in
- progress, but it is already working quite nicely.</para>
- </sect2>
-
- </sect1>
-
- <sect1>
- <title>Character Devices</title>
-
- <para>A character device driver is one that transfers data
- directly to and from a user process. This is the most common
- type of device driver and there are plenty of simple examples in
- the source tree.</para>
-
- <para>This simple example pseudo-device remembers whatever values
- you write to it and can then supply them back to you when you
- read from it.</para>
-
- <programlisting>/*
- * Simple `echo' pseudo-device KLD
- *
- * Murray Stokely
- */
-
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-
-#include &lt;sys/types.h&gt;
-#include &lt;sys/module.h&gt;
-#include &lt;sys/systm.h&gt; /* uprintf */
-#include &lt;sys/errno.h&gt;
-#include &lt;sys/param.h&gt; /* defines used in kernel.h */
-#include &lt;sys/kernel.h&gt; /* types used in module initialization */
-#include &lt;sys/conf.h&gt; /* cdevsw struct */
-#include &lt;sys/uio.h&gt; /* uio struct */
-#include &lt;sys/malloc.h&gt;
-
-#define BUFFERSIZE 256
-
-/* Function prototypes */
-d_open_t echo_open;
-d_close_t echo_close;
-d_read_t echo_read;
-d_write_t echo_write;
-
-/* Character device entry points */
-static struct cdevsw echo_cdevsw = {
- echo_open,
- echo_close,
- echo_read,
- echo_write,
- noioctl,
- nopoll,
- nommap,
- nostrategy,
- "echo",
- 33, /* reserved for lkms - /usr/src/sys/conf/majors */
- nodump,
- nopsize,
- D_TTY,
- -1
-};
-
-typedef struct s_echo {
- char msg[BUFFERSIZE];
- int len;
-} t_echo;
-
-/* vars */
-static dev_t sdev;
-static int len;
-static int count;
-static t_echo *echomsg;
-
-MALLOC_DECLARE(M_ECHOBUF);
-MALLOC_DEFINE(M_ECHOBUF, "echobuffer", "buffer for echo module");
-
-/*
- * This function acts is called by the kld[un]load(2) system calls to
- * determine what actions to take when a module is loaded or unloaded.
- */
-
-static int
-echo_loader(struct module *m, int what, void *arg)
-{
- int err = 0;
-
- switch (what) {
- case MOD_LOAD: /* kldload */
- sdev = make_dev(<literal>&</literal>echo_cdevsw,
- 0,
- UID_ROOT,
- GID_WHEEL,
- 0600,
- "echo");
- /* kmalloc memory for use by this driver */
- /* malloc(256,M_ECHOBUF,M_WAITOK); */
- MALLOC(echomsg, t_echo *, sizeof(t_echo), M_ECHOBUF, M_WAITOK);
- printf("Echo device loaded.\n");
- break;
- case MOD_UNLOAD:
- destroy_dev(sdev);
- FREE(echomsg,M_ECHOBUF);
- printf("Echo device unloaded.\n");
- break;
- default:
- err = EINVAL;
- break;
- }
- return(err);
-}
-
-int
-echo_open(dev_t dev, int oflags, int devtype, struct proc *p)
-{
- int err = 0;
-
- uprintf("Opened device \"echo\" successfully.\n");
- return(err);
-}
-
-int
-echo_close(dev_t dev, int fflag, int devtype, struct proc *p)
-{
- uprintf("Closing device \"echo.\"\n");
- return(0);
-}
-
-/*
- * The read function just takes the buf that was saved via
- * echo_write() and returns it to userland for accessing.
- * uio(9)
- */
-
-int
-echo_read(dev_t dev, struct uio *uio, int ioflag)
-{
- int err = 0;
- int amt;
-
- /* How big is this read operation? Either as big as the user wants,
- or as big as the remaining data */
- amt = MIN(uio->uio_resid, (echomsg->len - uio->uio_offset > 0) ? echomsg->len - uio->uio_offset : 0);
- if ((err = uiomove(echomsg->msg + uio->uio_offset,amt,uio)) != 0) {
- uprintf("uiomove failed!\n");
- }
-
- return err;
-}
-
-/*
- * echo_write takes in a character string and saves it
- * to buf for later accessing.
- */
-
-int
-echo_write(dev_t dev, struct uio *uio, int ioflag)
-{
- int err = 0;
-
- /* Copy the string in from user memory to kernel memory */
- err = copyin(uio->uio_iov->iov_base, echomsg->msg, MIN(uio->uio_iov->iov_len,BUFFERSIZE));
-
- /* Now we need to null terminate */
- *(echomsg->msg + MIN(uio->uio_iov->iov_len,BUFFERSIZE)) = 0;
- /* Record the length */
- echomsg->len = MIN(uio->uio_iov->iov_len,BUFFERSIZE);
-
- if (err != 0) {
- uprintf("Write failed: bad address!\n");
- }
-
- count++;
- return(err);
-}
-
-DEV_MODULE(echo,echo_loader,NULL);</programlisting>
-
- <para>To install this driver you will first need to make a node on
- your filesystem with a command such as:</para>
-
- <screen>&prompt.root; mknod /dev/echo c 33 0</screen>
-
- <para>With this driver loaded you should now be able to type
- something like:</para>
-
- <screen>&prompt.root; echo -n "Test Data" > /dev/echo
-&prompt.root; cat /dev/echo
-Test Data</screen>
-
- <para>Real hardware devices in the next chapter..</para>
-
- <para>Additional Resources
- <itemizedlist>
- <listitem><simpara><ulink
- url="http://www.daemonnews.org/200010/blueprints.html">Dynamic
- Kernel Linker (KLD) Facility Programming Tutorial</ulink> -
- <ulink url="http://www.daemonnews.org/">Daemonnews</ulink> October 2000</simpara></listitem>
- <listitem><simpara><ulink
- url="http://www.daemonnews.org/200007/newbus-intro.html">How
- to Write Kernel Drivers with NEWBUS</ulink> - <ulink
- url="http://www.daemonnews.org/">Daemonnews</ulink> July
- 2000</simpara></listitem>
- </itemizedlist>
- </para>
- </sect1>
-
- <sect1>
- <title>Network Drivers</title>
-
- <para>Drivers for network devices do not use device nodes in order
- to be accessed. Their selection is based on other decisions
- made inside the kernel and instead of calling open(), use of a
- network device is generally introduced by using the system call
- socket(2).</para>
-
- <para>man ifnet(), loopback device, Bill Paul's drivers,
- etc..</para>
-
- </sect1>
-
-</chapter>
-
-<!--
- Local Variables:
- mode: sgml
- sgml-declaration: "../chapter.decl"
- sgml-indent-data: t
- sgml-omittag: nil
- sgml-always-quote-attributes: t
- sgml-parent-document: ("../book.sgml" "part" "chapter")
- End:
--->
diff --git a/en_US.ISO8859-1/books/arch-handbook/isa/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/isa/chapter.sgml
deleted file mode 100644
index f48cd1ac06..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/isa/chapter.sgml
+++ /dev/null
@@ -1,2483 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="isa-driver">
- <title>ISA device drivers</title>
-
- <para>
- <emphasis>
- This chapter was written by &a.babkin; Modifications for the
- handbook made by &a.murray;, &a.wylie;, and &a.logo;.
- </emphasis>
- </para>
-
- <sect1>
- <title>Synopsis</title>
-
- <para>This chapter introduces the issues relevant to writing a
- driver for an ISA device. The pseudo-code presented here is
- rather detailed and reminiscent of the real code but is still
- only pseudo-code. It avoids the details irrelevant to the
- subject of the discussion. The real-life examples can be found
- in the source code of real drivers. In particular the drivers
- <literal>ep</literal> and <literal>aha</literal> are good sources of information.</para>
- </sect1>
-
- <sect1>
- <title>Basic information</title>
-
- <para>A typical ISA driver would need the following include
- files:</para>
-
-<programlisting>#include &lt;sys/module.h&gt;
-#include &lt;sys/bus.h&gt;
-#include &lt;machine/bus.h&gt;
-#include &lt;machine/resource.h&gt;
-#include &lt;sys/rman.h&gt;
-
-#include &lt;isa/isavar.h&gt;
-#include &lt;isa/pnpvar.h&gt;</programlisting>
-
- <para>They describe the things specific to the ISA and generic
- bus subsystem.</para>
-
- <para>The bus subsystem is implemented in an object-oriented
- fashion, its main structures are accessed by associated method
- functions.</para>
-
- <para>The list of bus methods implemented by an ISA driver is like
- one for any other bus. For a hypothetical driver named <quote>xxx</quote>
- they would be:</para>
-
- <itemizedlist>
- <listitem>
- <para><function>static void xxx_isa_identify (driver_t *,
- device_t);</function> Normally used for bus drivers, not
- device drivers. But for ISA devices this method may have
- special use: if the device provides some device-specific
- (non-PnP) way to auto-detect devices this routine may
- implement it.</para>
- </listitem>
-
- <listitem>
- <para><function>static int xxx_isa_probe (device_t
- dev);</function> Probe for a device at a known (or PnP)
- location. This routine can also accommodate device-specific
- auto-detection of parameters for partially configured
- devices.</para>
- </listitem>
-
- <listitem>
- <para><function>static int xxx_isa_attach (device_t
- dev);</function> Attach and initialize device.</para>
- </listitem>
-
- <listitem>
- <para><function>static int xxx_isa_detach (device_t
- dev);</function> Detach device before unloading the driver
- module.</para>
- </listitem>
-
- <listitem>
- <para><function>static int xxx_isa_shutdown (device_t
- dev);</function> Execute shutdown of the device before
- system shutdown.</para>
- </listitem>
-
- <listitem>
- <para><function>static int xxx_isa_suspend (device_t
- dev);</function> Suspend the device before the system goes
- to the power-save state. May also abort transition to the
- power-save state.</para>
- </listitem>
-
- <listitem>
- <para><function>static int xxx_isa_resume (device_t
- dev);</function> Resume the device activity after return
- from power-save state.</para>
- </listitem>
-
- </itemizedlist>
-
- <para><function>xxx_isa_probe()</function> and
- <function>xxx_isa_attach()</function> are mandatory, the rest of
- the routines are optional, depending on the device's
- needs.</para>
-
- <para>The driver is linked to the system with the following set of
- descriptions.</para>
-
-<programlisting> /* table of supported bus methods */
- static device_method_t xxx_isa_methods[] = {
- /* list all the bus method functions supported by the driver */
- /* omit the unsupported methods */
- DEVMETHOD(device_identify, xxx_isa_identify),
- DEVMETHOD(device_probe, xxx_isa_probe),
- DEVMETHOD(device_attach, xxx_isa_attach),
- DEVMETHOD(device_detach, xxx_isa_detach),
- DEVMETHOD(device_shutdown, xxx_isa_shutdown),
- DEVMETHOD(device_suspend, xxx_isa_suspend),
- DEVMETHOD(device_resume, xxx_isa_resume),
-
- { 0, 0 }
- };
-
- static driver_t xxx_isa_driver = {
- "xxx",
- xxx_isa_methods,
- sizeof(struct xxx_softc),
- };
-
-
- static devclass_t xxx_devclass;
-
- DRIVER_MODULE(xxx, isa, xxx_isa_driver, xxx_devclass,
- load_function, load_argument);</programlisting>
-
- <para>Here struct <structname>xxx_softc</structname> is a
- device-specific structure that contains private driver data
- and descriptors for the driver's resources. The bus code
- automatically allocates one softc descriptor per device as
- needed.</para>
-
- <para>If the driver is implemented as a loadable module then
- <function>load_function()</function> is called to do
- driver-specific initialization or clean-up when the driver is
- loaded or unloaded and load_argument is passed as one of its
- arguments. If the driver does not support dynamic loading (in
- other words it must always be linked into kernel) then these
- values should be set to 0 and the last definition would look
- like:</para>
-
- <programlisting> DRIVER_MODULE(xxx, isa, xxx_isa_driver,
- xxx_devclass, 0, 0);</programlisting>
-
- <para>If the driver is for a device which supports PnP then a
- table of supported PnP IDs must be defined. The table
- consists of a list of PnP IDs supported by this driver and
- human-readable descriptions of the hardware types and models
- having these IDs. It looks like:</para>
-
-<programlisting> static struct isa_pnp_id xxx_pnp_ids[] = {
- /* a line for each supported PnP ID */
- { 0x12345678, "Our device model 1234A" },
- { 0x12345679, "Our device model 1234B" },
- { 0, NULL }, /* end of table */
- };</programlisting>
-
- <para>If the driver does not support PnP devices it still needs
- an empty PnP ID table, like:</para>
-
-<programlisting> static struct isa_pnp_id xxx_pnp_ids[] = {
- { 0, NULL }, /* end of table */
- };</programlisting>
-
- </sect1>
-
- <sect1>
- <title>Device_t pointer</title>
-
- <para><structname>Device_t</structname> is the pointer type for
- the device structure. Here we consider only the methods
- interesting from the device driver writer's standpoint. The
- methods to manipulate values in the device structure
- are:</para>
-
- <itemizedlist>
-
- <listitem><para><function>device_t
- device_get_parent(dev)</function> Get the parent bus of a
- device.</para></listitem>
-
- <listitem><para><function>driver_t
- device_get_driver(dev)</function> Get pointer to its driver
- structure.</para></listitem>
-
- <listitem><para><function>char
- *device_get_name(dev)</function> Get the driver name, such
- as <literal>"xxx"</literal> for our example.</para></listitem>
-
- <listitem><para><function>int device_get_unit(dev)</function>
- Get the unit number (units are numbered from 0 for the
- devices associated with each driver).</para></listitem>
-
- <listitem><para><function>char
- *device_get_nameunit(dev)</function> Get the device name
- including the unit number, such as <quote>xxx0</quote>, <quote>xxx1</quote> and so
- on.</para></listitem>
-
- <listitem><para><function>char
- *device_get_desc(dev)</function> Get the device
- description. Normally it describes the exact model of device
- in human-readable form.</para></listitem>
-
- <listitem><para><function>device_set_desc(dev,
- desc)</function> Set the description. This makes the device
- description point to the string desc which may not be
- deallocated or changed after that.</para></listitem>
-
- <listitem><para><function>device_set_desc_copy(dev,
- desc)</function> Set the description. The description is
- copied into an internal dynamically allocated buffer, so the
- string desc may be changed afterwards without adverse
- effects.</para></listitem>
-
- <listitem><para><function>void
- *device_get_softc(dev)</function> Get pointer to the device
- descriptor (struct <structname>xxx_softc</structname>)
- associated with this device.</para></listitem>
-
- <listitem><para><function>u_int32_t
- device_get_flags(dev)</function> Get the flags specified for
- the device in the configuration file.</para></listitem>
-
- </itemizedlist>
-
- <para>A convenience function <function>device_printf(dev, fmt,
- ...)</function> may be used to print the messages from the
- device driver. It automatically prepends the unitname and
- colon to the message.</para>
-
- <para>The device_t methods are implemented in the file
- <filename>kern/bus_subr.c</filename>.</para>
-
- </sect1>
-
- <sect1>
- <title>Configuration file and the order of identifying and probing
- during auto-configuration</title>
-
- <para>The ISA devices are described in the kernel configuration file
- like:</para>
-
- <programlisting>device xxx0 at isa? port 0x300 irq 10 drq 5
- iomem 0xd0000 flags 0x1 sensitive</programlisting>
-
- <para>The values of port, IRQ and so on are converted to the
- resource values associated with the device. They are optional,
- depending on the device's needs and abilities for
- auto-configuration. For example, some devices do not need DRQ
- at all and some allow the driver to read the IRQ setting from
- the device configuration ports. If a machine has multiple ISA
- buses the exact bus may be specified in the configuration
- line, like <literal>isa0</literal> or <literal>isa1</literal>, otherwise the device would be
- searched for on all the ISA buses.</para>
-
- <para><literal>sensitive</literal> is a resource requesting that this device must
- be probed before all non-sensitive devices. It is supported
- but does not seem to be used in any current driver.</para>
-
- <para>For legacy ISA devices in many cases the drivers are still
- able to detect the configuration parameters. But each device
- to be configured in the system must have a config line. If two
- devices of some type are installed in the system but there is
- only one configuration line for the corresponding driver, ie:
- <programlisting>device xxx0 at isa?</programlisting> then only
- one device will be configured.</para>
-
- <para>But for the devices supporting automatic identification by
- the means of Plug-n-Play or some proprietary protocol one
- configuration line is enough to configure all the devices in
- the system, like the one above or just simply:</para>
-
- <programlisting>device xxx at isa?</programlisting>
-
- <para>If a driver supports both auto-identified and legacy
- devices and both kinds are installed at once in one machine
- then it is enough to describe in the config file the legacy
- devices only. The auto-identified devices will be added
- automatically.</para>
-
- <para>When an ISA bus is auto-configured the events happen as
- follows:</para>
-
- <para>All the drivers' identify routines (including the PnP
- identify routine which identifies all the PnP devices) are
- called in random order. As they identify the devices they add
- them to the list on the ISA bus. Normally the drivers'
- identify routines associate their drivers with the new
- devices. The PnP identify routine does not know about the
- other drivers yet so it does not associate any with the new
- devices it adds.</para>
-
- <para>The PnP devices are put to sleep using the PnP protocol to
- prevent them from being probed as legacy devices.</para>
-
- <para>The probe routines of non-PnP devices marked as
- <literal>sensitive</literal> are called. If probe for a device went
- successfully, the attach routine is called for it.</para>
-
- <para>The probe and attach routines of all non-PNP devices are
- called likewise.</para>
-
- <para>The PnP devices are brought back from the sleep state and
- assigned the resources they request: I/O and memory address
- ranges, IRQs and DRQs, all of them not conflicting with the
- attached legacy devices.</para>
-
- <para>Then for each PnP device the probe routines of all the
- present ISA drivers are called. The first one that claims the
- device gets attached. It is possible that multiple drivers
- would claim the device with different priority; in this case, the
- highest-priority driver wins. The probe routines must call
- <function>ISA_PNP_PROBE()</function> to compare the actual PnP
- ID with the list of the IDs supported by the driver and if the
- ID is not in the table return failure. That means that
- absolutely every driver, even the ones not supporting any PnP
- devices must call <function>ISA_PNP_PROBE()</function>, at
- least with an empty PnP ID table to return failure on unknown
- PnP devices.</para>
-
- <para>The probe routine returns a positive value (the error
- code) on error, zero or negative value on success.</para>
-
- <para>The negative return values are used when a PnP device
- supports multiple interfaces. For example, an older
- compatibility interface and a newer advanced interface which
- are supported by different drivers. Then both drivers would
- detect the device. The driver which returns a higher value in
- the probe routine takes precedence (in other words, the driver
- returning 0 has highest precedence, returning -1 is next,
- returning -2 is after it and so on). In result the devices
- which support only the old interface will be handled by the
- old driver (which should return -1 from the probe routine)
- while the devices supporting the new interface as well will be
- handled by the new driver (which should return 0 from the
- probe routine). If multiple drivers return the same value then
- the one called first wins. So if a driver returns value 0 it
- may be sure that it won the priority arbitration.</para>
-
- <para>The device-specific identify routines can also assign not
- a driver but a class of drivers to the device. Then all the
- drivers in the class are probed for this device, like the case
- with PnP. This feature is not implemented in any existing
- driver and is not considered further in this document.</para>
-
- <para>Because the PnP devices are disabled when probing the
- legacy devices they will not be attached twice (once as legacy
- and once as PnP). But in case of device-dependent identify
- routines it is the responsibility of the driver to make sure
- that the same device will not be attached by the driver twice:
- once as legacy user-configured and once as
- auto-identified.</para>
-
- <para>Another practical consequence for the auto-identified
- devices (both PnP and device-specific) is that the flags can
- not be passed to them from the kernel configuration file. So
- they must either not use the flags at all or use the flags
- from the device unit 0 for all the auto-identified devices or
- use the sysctl interface instead of flags.</para>
-
- <para>Other unusual configurations may be accommodated by
- accessing the configuration resources directly with functions
- of families <function>resource_query_*()</function> and
- <function>resource_*_value()</function>. Their implementations
- are located in <filename>kern/subr_bus.h</filename>. The old IDE disk driver
- <filename>i386/isa/wd.c</filename> contains examples of such use. But the standard
- means of configuration must always be preferred. Leave parsing
- the configuration resources to the bus configuration
- code.</para>
-
- </sect1>
-
- <sect1>
- <title>Resources</title>
-
- <para>The information that a user enters into the kernel
- configuration file is processed and passed to the kernel as
- configuration resources. This information is parsed by the bus
- configuration code and transformed into a value of structure
- device_t and the bus resources associated with it. The drivers
- may access the configuration resources directly using
- functions resource_* for more complex cases of
- configuration. However, generally this is neither needed nor recommended,
- so this issue is not discussed further here.</para>
-
- <para>The bus resources are associated with each device. They
- are identified by type and number within the type. For the ISA
- bus the following types are defined:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>SYS_RES_IRQ</emphasis> - interrupt
- number</para>
- </listitem>
-
- <listitem>
- <para><emphasis>SYS_RES_DRQ</emphasis> - ISA DMA channel
- number</para>
- </listitem>
-
- <listitem>
- <para><emphasis>SYS_RES_MEMORY</emphasis> - range of
- device memory mapped into the system memory space
- </para>
- </listitem>
-
- <listitem>
- <para><emphasis>SYS_RES_IOPORT</emphasis> - range of
- device I/O registers</para>
- </listitem>
- </itemizedlist>
-
- <para>The enumeration within types starts from 0, so if a device
- has two memory regions it would have resources of type
- SYS_RES_MEMORY numbered 0 and 1. The resource type has
- nothing to do with the C language type, all the resource
- values have the C language type <literal>unsigned long</literal> and must be
- cast as necessary. The resource numbers do not have to be
- contiguous, although for ISA they normally would be. The
- permitted resource numbers for ISA devices are:</para>
-
- <programlisting> IRQ: 0-1
- DRQ: 0-1
- MEMORY: 0-3
- IOPORT: 0-7</programlisting>
-
- <para>All the resources are represented as ranges, with a start
- value and count. For IRQ and DRQ resources the count would
- normally be equal to 1. The values for memory refer to the
- physical addresses.</para>
-
- <para>Three types of activities can be performed on
- resources:</para>
-
- <itemizedlist>
- <listitem><para>set/get</para></listitem>
- <listitem><para>allocate/release</para></listitem>
- <listitem><para>activate/deactivate</para></listitem>
- </itemizedlist>
-
- <para>Setting sets the range used by the resource. Allocation
- reserves the requested range that no other driver would be
- able to reserve it (and checking that no other driver reserved
- this range already). Activation makes the resource accessible
- to the driver by doing whatever is necessary for that (for
- example, for memory it would be mapping into the kernel
- virtual address space).</para>
-
- <para>The functions to manipulate resources are:</para>
-
- <itemizedlist>
- <listitem>
- <para><function>int bus_set_resource(device_t dev, int type,
- int rid, u_long start, u_long count)</function></para>
-
- <para>Set a range for a resource. Returns 0 if successful,
- error code otherwise. Normally, this function will
- return an error only if one of <literal>type</literal>,
- <literal>rid</literal>, <literal>start</literal> or
- <literal>count</literal> has a value that falls out of the
- permitted range.</para>
-
- <itemizedlist>
- <listitem>
- <para> dev - driver's device</para>
- </listitem>
- <listitem>
- <para> type - type of resource, SYS_RES_* </para>
- </listitem>
- <listitem>
- <para> rid - resource number (ID) within type </para>
- </listitem>
- <listitem>
- <para> start, count - resource range </para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para><function>int bus_get_resource(device_t dev, int type,
- int rid, u_long *startp, u_long *countp)</function></para>
-
- <para>Get the range of resource. Returns 0 if successful,
- error code if the resource is not defined yet.</para>
- </listitem>
-
- <listitem>
- <para><function>u_long bus_get_resource_start(device_t dev,
- int type, int rid) u_long bus_get_resource_count (device_t
- dev, int type, int rid)</function></para>
-
- <para>Convenience functions to get only the start or
- count. Return 0 in case of error, so if the resource start
- has 0 among the legitimate values it would be impossible
- to tell if the value is 0 or an error occurred. Luckily,
- no ISA resources for add-on drivers may have a start value
- equal to 0.</para>
- </listitem>
-
- <listitem>
- <para><function>void bus_delete_resource(device_t dev, int
- type, int rid)</function></para>
- <para> Delete a resource, make it undefined.</para>
- </listitem>
-
- <listitem>
- <para><function>struct resource *
- bus_alloc_resource(device_t dev, int type, int *rid,
- u_long start, u_long end, u_long count, u_int
- flags)</function></para>
-
- <para>Allocate a resource as a range of count values not
- allocated by anyone else, somewhere between start and
- end. Alas, alignment is not supported. If the resource
- was not set yet it is automatically created. The special
- values of start 0 and end ~0 (all ones) means that the
- fixed values previously set by
- <function>bus_set_resource()</function> must be used
- instead: start and count as themselves and
- end=(start+count), in this case if the resource was not
- defined before then an error is returned. Although rid is
- passed by reference it is not set anywhere by the resource
- allocation code of the ISA bus. (The other buses may use a
- different approach and modify it).</para>
- </listitem>
- </itemizedlist>
-
- <para>Flags are a bitmap, the flags interesting for the caller
- are:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>RF_ACTIVE</emphasis> - causes the resource
- to be automatically activated after allocation.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>RF_SHAREABLE</emphasis> - resource may be
- shared at the same time by multiple drivers.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>RF_TIMESHARE</emphasis> - resource may be
- time-shared by multiple drivers, i.e. allocated at the
- same time by many but activated only by one at any given
- moment of time.</para>
- </listitem>
-<!-- XXXDONT KNOW IT THESE SHOULD BE TWO SEPERATE LISTS OR NOT -->
- <listitem>
- <para>Returns 0 on error. The allocated values may be
- obtained from the returned handle using methods
- <function>rhand_*()</function>.</para>
- </listitem>
- <listitem>
- <para><function>int bus_release_resource(device_t dev, int
- type, int rid, struct resource *r)</function></para>
- </listitem>
-
- <listitem>
- <para>Release the resource, r is the handle returned by
- <function>bus_alloc_resource()</function>. Returns 0 on
- success, error code otherwise.</para>
- </listitem>
-
- <listitem>
- <para><function>int bus_activate_resource(device_t dev, int
- type, int rid, struct resource *r)</function>
- <function>int bus_deactivate_resource(device_t dev, int
- type, int rid, struct resource *r)</function></para>
- </listitem>
-
- <listitem>
- <para>Activate or deactivate resource. Return 0 on success,
- error code otherwise. If the resource is time-shared and
- currently activated by another driver then EBUSY is
- returned.</para>
- </listitem>
-
- <listitem>
- <para><function>int bus_setup_intr(device_t dev, struct
- resource *r, int flags, driver_intr_t *handler, void *arg,
- void **cookiep)</function> <function>int
- bus_teardown_intr(device_t dev, struct resource *r, void
- *cookie)</function></para>
- </listitem>
-
- <listitem>
- <para>Associate or de-associate the interrupt handler with a
- device. Return 0 on success, error code otherwise.</para>
- </listitem>
-
- <listitem>
- <para>r - the activated resource handler describing the
- IRQ</para>
- <para>flags - the interrupt priority level, one of:</para>
-
- <itemizedlist>
- <listitem>
- <para><function>INTR_TYPE_TTY</function> - terminals and
- other likewise character-type devices. To mask them
- use <function>spltty()</function>.</para>
- </listitem>
- <listitem>
- <para><function>(INTR_TYPE_TTY |
- INTR_TYPE_FAST)</function> - terminal type devices
- with small input buffer, critical to the data loss on
- input (such as the old-fashioned serial ports). To
- mask them use <function>spltty()</function>.</para>
- </listitem>
- <listitem>
- <para><function>INTR_TYPE_BIO</function> - block-type
- devices, except those on the CAM controllers. To mask
- them use <function>splbio()</function>.</para>
- </listitem>
- <listitem>
- <para><function>INTR_TYPE_CAM</function> - CAM (Common
- Access Method) bus controllers. To mask them use
- <function>splcam()</function>.</para>
- </listitem>
- <listitem>
- <para><function>INTR_TYPE_NET</function> - network
- interface controllers. To mask them use
- <function>splimp()</function>.</para>
- </listitem>
- <listitem>
- <para><function>INTR_TYPE_MISC</function> -
- miscellaneous devices. There is no other way to mask
- them than by <function>splhigh()</function> which
- masks all interrupts.</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
-
- <para>When an interrupt handler executes all the other
- interrupts matching its priority level will be masked. The
- only exception is the MISC level for which no other interrupts
- are masked and which is not masked by any other
- interrupt.</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>handler</emphasis> - pointer to the handler
- function, the type driver_intr_t is defined as <function>void
- driver_intr_t(void *)</function></para>
- </listitem>
- <listitem>
- <para><emphasis>arg</emphasis> - the argument passed to the
- handler to identify this particular device. It is cast
- from void* to any real type by the handler. The old
- convention for the ISA interrupt handlers was to use the
- unit number as argument, the new (recommended) convention
- is using a pointer to the device softc structure.</para>
- </listitem>
- <listitem>
- <para><emphasis>cookie[p]</emphasis> - the value received
- from <function>setup()</function> is used to identify the
- handler when passed to
- <function>teardown()</function></para>
- </listitem>
- </itemizedlist>
-
- <para>A number of methods are defined to operate on the resource
- handlers (struct resource *). Those of interest to the device
- driver writers are:</para>
-
- <itemizedlist>
- <listitem>
- <para><function>u_long rman_get_start(r) u_long
- rman_get_end(r)</function> Get the start and end of
- allocated resource range.</para>
- </listitem>
- <listitem>
- <para><function>void *rman_get_virtual(r)</function> Get
- the virtual address of activated memory resource.</para>
- </listitem>
- </itemizedlist>
-
- </sect1>
-
- <sect1>
- <title>Bus memory mapping</title>
-
- <para>In many cases data is exchanged between the driver and the
- device through the memory. Two variants are possible:</para>
-
- <para>(a) memory is located on the device card</para>
- <para>(b) memory is the main memory of the computer</para>
-
- <para>In case (a) the driver always copies the data back and
- forth between the on-card memory and the main memory as
- necessary. To map the on-card memory into the kernel virtual
- address space the physical address and length of the on-card
- memory must be defined as a SYS_RES_MEMORY resource. That
- resource can then be allocated and activated, and its virtual
- address obtained using
- <function>rman_get_virtual()</function>. The older drivers
- used the function <function>pmap_mapdev()</function> for this
- purpose, which should not be used directly any more. Now it is
- one of the internal steps of resource activation.</para>
-
- <para>Most of the ISA cards will have their memory configured
- for physical location somewhere in range 640KB-1MB. Some of
- the ISA cards require larger memory ranges which should be
- placed somewhere under 16MB (because of the 24-bit address
- limitation on the ISA bus). In that case if the machine has
- more memory than the start address of the device memory (in
- other words, they overlap) a memory hole must be configured at
- the address range used by devices. Many BIOSes allow
- configuration of a memory hole of 1MB starting at 14MB or
- 15MB. FreeBSD can handle the memory holes properly if the BIOS
- reports them properly (this feature may be broken on old BIOSes).</para>
-
- <para>In case (b) just the address of the data is sent to
- the device, and the device uses DMA to actually access the
- data in the main memory. Two limitations are present: First,
- ISA cards can only access memory below 16MB. Second, the
- contiguous pages in virtual address space may not be
- contiguous in physical address space, so the device may have
- to do scatter/gather operations. The bus subsystem provides
- ready solutions for some of these problems, the rest has to be
- done by the drivers themselves.</para>
-
- <para>Two structures are used for DMA memory allocation,
- bus_dma_tag_t and bus_dmamap_t. Tag describes the properties
- required for the DMA memory. Map represents a memory block
- allocated according to these properties. Multiple maps may be
- associated with the same tag.</para>
-
- <para>Tags are organized into a tree-like hierarchy with
- inheritance of the properties. A child tag inherits all the
- requirements of its parent tag, and may make them more strict
- but never more loose.</para>
-
- <para>Normally one top-level tag (with no parent) is created for
- each device unit. If multiple memory areas with different
- requirements are needed for each device then a tag for each of
- them may be created as a child of the parent tag.</para>
-
- <para>The tags can be used to create a map in two ways.</para>
-
- <para>First, a chunk of contiguous memory conformant with the
- tag requirements may be allocated (and later may be
- freed). This is normally used to allocate relatively
- long-living areas of memory for communication with the
- device. Loading of such memory into a map is trivial: it is
- always considered as one chunk in the appropriate physical
- memory range.</para>
-
- <para>Second, an arbitrary area of virtual memory may be loaded
- into a map. Each page of this memory will be checked for
- conformance to the map requirement. If it conforms then it is
- left at its original location. If it is not then a fresh
- conformant <quote>bounce page</quote> is allocated and used as intermediate
- storage. When writing the data from the non-conformant
- original pages they will be copied to their bounce pages first
- and then transferred from the bounce pages to the device. When
- reading the data would go from the device to the bounce pages
- and then copied to their non-conformant original pages. The
- process of copying between the original and bounce pages is
- called synchronization. This is normally used on a per-transfer
- basis: buffer for each transfer would be loaded, transfer done
- and buffer unloaded.</para>
-
- <para>The functions working on the DMA memory are:</para>
-
- <itemizedlist>
- <listitem>
- <para><function>int bus_dma_tag_create(bus_dma_tag_t parent,
- bus_size_t alignment, bus_size_t boundary, bus_addr_t
- lowaddr, bus_addr_t highaddr, bus_dma_filter_t *filter, void
- *filterarg, bus_size_t maxsize, int nsegments, bus_size_t
- maxsegsz, int flags, bus_dma_tag_t *dmat)</function></para>
-
- <para>Create a new tag. Returns 0 on success, the error code
- otherwise.</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>parent</emphasis> - parent tag, or NULL to
- create a top-level tag <emphasis>alignment</emphasis> -
- required physical alignment of the memory area to be
- allocated for this tag. Use value 1 for <quote>no specific
- alignment</quote>. Applies only to the future
- <function>bus_dmamem_alloc()</function> but not
- <function>bus_dmamap_create()</function> calls.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>boundary</emphasis> - physical address
- boundary that must not be crossed when allocating the
- memory. Use value 0 for <quote>no boundary</quote>. Applies only to
- the future <function>bus_dmamem_alloc()</function> but
- not <function>bus_dmamap_create()</function> calls.
- Must be power of 2. If the memory is planned to be used
- in non-cascaded DMA mode (i.e. the DMA addresses will be
- supplied not by the device itself but by the ISA DMA
- controller) then the boundary must be no larger than
- 64KB (64*1024) due to the limitations of the DMA
- hardware.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>lowaddr, highaddr</emphasis> - the names
- are slightly misleading; these values are used to limit
- the permitted range of physical addresses used to
- allocate the memory. The exact meaning varies depending
- on the planned future use:</para>
-
- <itemizedlist>
- <listitem>
- <para>For <function>bus_dmamem_alloc()</function> all
- the addresses from 0 to lowaddr-1 are considered
- permitted, the higher ones are forbidden.</para>
- </listitem>
-
- <listitem>
- <para>For <function>bus_dmamap_create()</function> all
- the addresses outside the inclusive range [lowaddr;
- highaddr] are considered accessible. The addresses
- of pages inside the range are passed to the filter
- function which decides if they are accessible. If no
- filter function is supplied then all the range is
- considered unaccessible.</para>
- </listitem>
-
- <listitem>
- <para>For the ISA devices the normal values (with no
- filter function) are:</para>
- <para>lowaddr = BUS_SPACE_MAXADDR_24BIT</para>
- <para>highaddr = BUS_SPACE_MAXADDR</para>
- </listitem>
- </itemizedlist>
-
- </listitem>
-
- <listitem>
- <para><emphasis>filter, filterarg</emphasis> - the filter
- function and its argument. If NULL is passed for filter
- then the whole range [lowaddr, highaddr] is considered
- unaccessible when doing
- <function>bus_dmamap_create()</function>. Otherwise the
- physical address of each attempted page in range
- [lowaddr; highaddr] is passed to the filter function
- which decides if it is accessible. The prototype of the
- filter function is: <function>int filterfunc(void *arg,
- bus_addr_t paddr)</function>. It must return 0 if the
- page is accessible, non-zero otherwise.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>maxsize</emphasis> - the maximal size of
- memory (in bytes) that may be allocated through this
- tag. In case it is difficult to estimate or could be
- arbitrarily big, the value for ISA devices would be
- BUS_SPACE_MAXSIZE_24BIT.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>nsegments</emphasis> - maximal number of
- scatter-gather segments supported by the device. If
- unrestricted then the value BUS_SPACE_UNRESTRICTED
- should be used. This value is recommended for the parent
- tags, the actual restrictions would then be specified
- for the descendant tags. Tags with nsegments equal to
- BUS_SPACE_UNRESTRICTED may not be used to actually load
- maps, they may be used only as parent tags. The
- practical limit for nsegments seems to be about 250-300,
- higher values will cause kernel stack overflow (the hardware
- can not normally support that many
- scatter-gather buffers anyway).</para>
- </listitem>
-
- <listitem>
- <para><emphasis>maxsegsz</emphasis> - maximal size of a
- scatter-gather segment supported by the device. The
- maximal value for ISA device would be
- BUS_SPACE_MAXSIZE_24BIT.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>flags</emphasis> - a bitmap of flags. The
- only interesting flags are:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>BUS_DMA_ALLOCNOW</emphasis> - requests
- to allocate all the potentially needed bounce pages
- when creating the tag.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>BUS_DMA_ISA</emphasis> - mysterious
- flag used only on Alpha machines. It is not defined
- for the i386 machines. Probably it should be used
- by all the ISA drivers for Alpha machines but it
- looks like there are no such drivers yet.</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para><emphasis>dmat</emphasis> - pointer to the storage
- for the new tag to be returned.</para>
- </listitem>
-
- </itemizedlist>
-
- </listitem>
-
- <listitem> <!-- Second entry in list alpha -->
- <para><function>int bus_dma_tag_destroy(bus_dma_tag_t
- dmat)</function></para>
-
- <para>Destroy a tag. Returns 0 on success, the error code
- otherwise.</para>
-
- <para>dmat - the tag to be destroyed.</para>
-
- </listitem>
-
- <listitem> <!-- Third entry in list alpha -->
- <para><function>int bus_dmamem_alloc(bus_dma_tag_t dmat,
- void** vaddr, int flags, bus_dmamap_t
- *mapp)</function></para>
-
- <para>Allocate an area of contiguous memory described by the
- tag. The size of memory to be allocated is tag's maxsize.
- Returns 0 on success, the error code otherwise. The result
- still has to be loaded by
- <function>bus_dmamap_load()</function> before being used to get
- the physical address of the memory.</para>
-
-<!-- XXX What it is Wylie, I got to here -->
-
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>dmat</emphasis> - the tag
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>vaddr</emphasis> - pointer to the storage
- for the kernel virtual address of the allocated area
- to be returned.
- </para>
- </listitem>
- <listitem>
- <para>
- flags - a bitmap of flags. The only interesting flag is:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>BUS_DMA_NOWAIT</emphasis> - if the
- memory is not immediately available return the
- error. If this flag is not set then the routine
- is allowed to sleep until the memory
- becomes available.
- </para>
- </listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <para>
- <emphasis>mapp</emphasis> - pointer to the storage
- for the new map to be returned.
- </para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem> <!-- Fourth entry in list alpha -->
- <para>
- <function>void bus_dmamem_free(bus_dma_tag_t dmat, void
- *vaddr, bus_dmamap_t map)</function>
- </para>
- <para>
- Free the memory allocated by
- <function>bus_dmamem_alloc()</function>. At present,
- freeing of the memory allocated with ISA restrictions is
- not implemented. Because of this the recommended model
- of use is to keep and re-use the allocated areas for as
- long as possible. Do not lightly free some area and then
- shortly allocate it again. That does not mean that
- <function>bus_dmamem_free()</function> should not be
- used at all: hopefully it will be properly implemented
- soon.
- </para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>dmat</emphasis> - the tag
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>vaddr</emphasis> - the kernel virtual
- address of the memory
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>map</emphasis> - the map of the memory (as
- returned from
- <function>bus_dmamem_alloc()</function>)
- </para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem> <!-- The fifth entry in list alpha -->
- <para>
- <function>int bus_dmamap_create(bus_dma_tag_t dmat, int
- flags, bus_dmamap_t *mapp)</function>
- </para>
- <para>
- Create a map for the tag, to be used in
- <function>bus_dmamap_load()</function> later. Returns 0
- on success, the error code otherwise.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>dmat</emphasis> - the tag
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>flags</emphasis> - theoretically, a bit map
- of flags. But no flags are defined yet, so at present
- it will be always 0.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>mapp</emphasis> - pointer to the storage
- for the new map to be returned
- </para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem> <!-- Sixth entry in the alpha list -->
- <para>
- <function>int bus_dmamap_destroy(bus_dma_tag_t dmat,
- bus_dmamap_t map)</function>
- </para>
- <para>
- Destroy a map. Returns 0 on success, the error code otherwise.
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- dmat - the tag to which the map is associated
- </para>
- </listitem>
- <listitem>
- <para>
- map - the map to be destroyed
- </para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem> <!-- Seventh entry in list alpha -->
- <para>
- <function>int bus_dmamap_load(bus_dma_tag_t dmat,
- bus_dmamap_t map, void *buf, bus_size_t buflen,
- bus_dmamap_callback_t *callback, void *callback_arg, int
- flags)</function>
- </para>
- <para>
- Load a buffer into the map (the map must be previously
- created by <function>bus_dmamap_create()</function> or
- <function>bus_dmamem_alloc()</function>). All the pages
- of the buffer are checked for conformance to the tag
- requirements and for those not conformant the bounce
- pages are allocated. An array of physical segment
- descriptors is built and passed to the callback
- routine. This callback routine is then expected to
- handle it in some way. The number of bounce buffers in
- the system is limited, so if the bounce buffers are
- needed but not immediately available the request will be
- queued and the callback will be called when the bounce
- buffers will become available. Returns 0 if the callback
- was executed immediately or EINPROGRESS if the request
- was queued for future execution. In the latter case the
- synchronization with queued callback routine is the
- responsibility of the driver.
- </para>
- <!--<blockquote>-->
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>dmat</emphasis> - the tag
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>map</emphasis> - the map
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>buf</emphasis> - kernel virtual address of
- the buffer
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>buflen</emphasis> - length of the buffer
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>callback</emphasis>,<function>
- callback_arg</function> - the callback function and
- its argument
- </para>
- </listitem>
- </itemizedlist>
- <!--</blockquote>-->
- <para>
- The prototype of callback function is:
- </para>
- <para>
- <function>void callback(void *arg, bus_dma_segment_t
- *seg, int nseg, int error)</function>
- </para>
- <!-- <blockquote> -->
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>arg</emphasis> - the same as callback_arg
- passed to <function>bus_dmamap_load()</function>
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>seg</emphasis> - array of the segment
- descriptors
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>nseg</emphasis> - number of descriptors in
- array
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>error</emphasis> - indication of the
- segment number overflow: if it is set to EFBIG then
- the buffer did not fit into the maximal number of
- segments permitted by the tag. In this case only the
- permitted number of descriptors will be in the
- array. Handling of this situation is up to the
- driver: depending on the desired semantics it can
- either consider this an error or split the buffer in
- two and handle the second part separately
- </para>
- </listitem>
- </itemizedlist>
- <!-- </blockquote> -->
- <para>
- Each entry in the segments array contains the fields:
- </para>
-
- <!-- <blockquote> -->
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>ds_addr</emphasis> - physical bus address
- of the segment
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>ds_len</emphasis> - length of the segment
- </para>
- </listitem>
- </itemizedlist>
- <!-- </blockquote>-->
- </listitem>
-
- <listitem> <!-- Eighth entry in alpha list -->
- <para>
- <function>void bus_dmamap_unload(bus_dma_tag_t dmat,
- bus_dmamap_t map)</function>
- </para>
- <para>unload the map.
- </para>
- <!-- <blockquote> -->
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>dmat</emphasis> - tag
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>map</emphasis> - loaded map
- </para>
- </listitem>
- </itemizedlist>
- <!-- </blockquote> -->
- </listitem>
-
- <listitem> <!-- Ninth entry list alpha -->
- <para>
- <function>void bus_dmamap_sync (bus_dma_tag_t dmat,
- bus_dmamap_t map, bus_dmasync_op_t op)</function>
- </para>
- <para>
- Synchronise a loaded buffer with its bounce pages before
- and after physical transfer to or from device. This is
- the function that does all the necessary copying of data
- between the original buffer and its mapped version. The
- buffers must be synchronized both before and after doing
- the transfer.
- </para>
- <!-- <blockquote> -->
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>dmat</emphasis> - tag
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>map</emphasis> - loaded map
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>op</emphasis> - type of synchronization
- operation to perform:
- </para>
- </listitem>
- </itemizedlist>
- <!-- <blockquote> -->
- <itemizedlist>
- <listitem>
- <para>
- <function>BUS_DMASYNC_PREREAD</function> - before
- reading from device into buffer
- </para>
- </listitem>
- <listitem>
- <para>
- <function>BUS_DMASYNC_POSTREAD</function> - after
- reading from device into buffer
- </para>
- </listitem>
- <listitem>
- <para>
- <function>BUS_DMASYNC_PREWRITE</function> - before
- writing the buffer to device
- </para>
- </listitem>
- <listitem>
- <para>
- <function>BUS_DMASYNC_POSTWRITE</function> - after
- writing the buffer to device
- </para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist> <!-- End of list alpha -->
-<!-- </blockquote>
-</blockquote> -->
-
- <para>
- As of now PREREAD and POSTWRITE are null operations but that
- may change in the future, so they must not be ignored in the
- driver. Synchronization is not needed for the memory
- obtained from <function>bus_dmamem_alloc()</function>.
- </para>
- <para>
- Before calling the callback function from
- <function>bus_dmamap_load()</function> the segment array is
- stored in the stack. And it gets pre-allocated for the
- maximal number of segments allowed by the tag. Because of
- this the practical limit for the number of segments on i386
- architecture is about 250-300 (the kernel stack is 4KB minus
- the size of the user structure, size of a segment array
- entry is 8 bytes, and some space must be left). Because the
- array is allocated based on the maximal number this value
- must not be set higher than really needed. Fortunately, for
- most of hardware the maximal supported number of segments is
- much lower. But if the driver wants to handle buffers with a
- very large number of scatter-gather segments it should do
- that in portions: load part of the buffer, transfer it to
- the device, load next part of the buffer, and so on.
- </para>
- <para>
- Another practical consequence is that the number of segments
- may limit the size of the buffer. If all the pages in the
- buffer happen to be physically non-contiguous then the
- maximal supported buffer size for that fragmented case would
- be (nsegments * page_size). For example, if a maximal number
- of 10 segments is supported then on i386 maximal guaranteed
- supported buffer size would be 40K. If a higher size is
- desired then special tricks should be used in the driver.
- </para>
- <para>
- If the hardware does not support scatter-gather at all or
- the driver wants to support some buffer size even if it is
- heavily fragmented then the solution is to allocate a
- contiguous buffer in the driver and use it as intermediate
- storage if the original buffer does not fit.
- </para>
- <para>
- Below are the typical call sequences when using a map depend
- on the use of the map. The characters -> are used to show
- the flow of time.
- </para>
- <para>
- For a buffer which stays practically fixed during all the
- time between attachment and detachment of a device:</para>
- <para>
- bus_dmamem_alloc -> bus_dmamap_load -> ...use buffer... ->
- -> bus_dmamap_unload -> bus_dmamem_free
- </para>
-
- <para>For a buffer that changes frequently and is passed from
- outside the driver:
-
- <!-- XXX is this correct? -->
- <programlisting> bus_dmamap_create ->
- -> bus_dmamap_load -> bus_dmamap_sync(PRE...) -> do transfer ->
- -> bus_dmamap_sync(POST...) -> bus_dmamap_unload ->
- ...
- -> bus_dmamap_load -> bus_dmamap_sync(PRE...) -> do transfer ->
- -> bus_dmamap_sync(POST...) -> bus_dmamap_unload ->
- -> bus_dmamap_destroy </programlisting>
-
- </para>
- <para>
- When loading a map created by
- <function>bus_dmamem_alloc()</function> the passed address
- and size of the buffer must be the same as used in
- <function>bus_dmamem_alloc()</function>. In this case it is
- guaranteed that the whole buffer will be mapped as one
- segment (so the callback may be based on this assumption)
- and the request will be executed immediately (EINPROGRESS
- will never be returned). All the callback needs to do in
- this case is to save the physical address.
- </para>
- <para>
- A typical example would be:
- </para>
-
- <programlisting> static void
- alloc_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error)
- {
- *(bus_addr_t *)arg = seg[0].ds_addr;
- }
-
- ...
- int error;
- struct somedata {
- ....
- };
- struct somedata *vsomedata; /* virtual address */
- bus_addr_t psomedata; /* physical bus-relative address */
- bus_dma_tag_t tag_somedata;
- bus_dmamap_t map_somedata;
- ...
-
- error=bus_dma_tag_create(parent_tag, alignment,
- boundary, lowaddr, highaddr, /*filter*/ NULL, /*filterarg*/ NULL,
- /*maxsize*/ sizeof(struct somedata), /*nsegments*/ 1,
- /*maxsegsz*/ sizeof(struct somedata), /*flags*/ 0,
- &#38;tag_somedata);
- if(error)
- return error;
-
- error = bus_dmamem_alloc(tag_somedata, &#38;vsomedata, /* flags*/ 0,
- &#38;map_somedata);
- if(error)
- return error;
-
- bus_dmamap_load(tag_somedata, map_somedata, (void *)vsomedata,
- sizeof (struct somedata), alloc_callback,
- (void *) &#38;psomedata, /*flags*/0); </programlisting>
-
- <para>
- Looks a bit long and complicated but that is the way to do
- it. The practical consequence is: if multiple memory areas
- are allocated always together it would be a really good idea
- to combine them all into one structure and allocate as one
- (if the alignment and boundary limitations permit).
- </para>
- <para>
- When loading an arbitrary buffer into the map created by
- <function>bus_dmamap_create()</function> special measures
- must be taken to synchronize with the callback in case it
- would be delayed. The code would look like:
- </para>
-
- <programlisting> {
- int s;
- int error;
-
- s = splsoftvm();
- error = bus_dmamap_load(
- dmat,
- dmamap,
- buffer_ptr,
- buffer_len,
- callback,
- /*callback_arg*/ buffer_descriptor,
- /*flags*/0);
- if (error == EINPROGRESS) {
- /*
- * Do whatever is needed to ensure synchronization
- * with callback. Callback is guaranteed not to be started
- * until we do splx() or tsleep().
- */
- }
- splx(s);
- } </programlisting>
-
- <para>
- Two possible approaches for the processing of requests are:
- </para>
- <para>
- 1. If requests are completed by marking them explicitly as
- done (such as the CAM requests) then it would be simpler to
- put all the further processing into the callback driver
- which would mark the request when it is done. Then not much
- extra synchronization is needed. For the flow control
- reasons it may be a good idea to freeze the request queue
- until this request gets completed.
- </para>
- <para>
- 2. If requests are completed when the function returns (such
- as classic read or write requests on character devices) then
- a synchronization flag should be set in the buffer
- descriptor and <function>tsleep()</function> called. Later
- when the callback gets called it will do its processing and
- check this synchronization flag. If it is set then the
- callback should issue a wakeup. In this approach the
- callback function could either do all the needed processing
- (just like the previous case) or simply save the segments
- array in the buffer descriptor. Then after callback
- completes the calling function could use this saved segments
- array and do all the processing.
-
- </para>
- </sect1>
-<!--_________________________________________________________________________-->
-<!--~~~~~~~~~~~~~~~~~~~~END OF SECTION~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
-
- <sect1>
- <title>DMA</title>
- <!-- Section Marked up by Wylie -->
- <para>
- The Direct Memory Access (DMA) is implemented in the ISA bus
- through the DMA controller (actually, two of them but that is
- an irrelevant detail). To make the early ISA devices simple
- and cheap the logic of the bus control and address
- generation was concentrated in the DMA controller.
- Fortunately, FreeBSD provides a set of functions that mostly
- hide the annoying details of the DMA controller from the
- device drivers.
- </para>
-
- <para>
- The simplest case is for the fairly intelligent
- devices. Like the bus master devices on PCI they can
- generate the bus cycles and memory addresses all by
- themselves. The only thing they really need from the DMA
- controller is bus arbitration. So for this purpose they
- pretend to be cascaded slave DMA controllers. And the only
- thing needed from the system DMA controller is to enable the
- cascaded mode on a DMA channel by calling the following
- function when attaching the driver:
- </para>
-
- <para>
- <function>void isa_dmacascade(int channel_number)</function>
- </para>
-
- <para>
- All the further activity is done by programming the
- device. When detaching the driver no DMA-related functions
- need to be called.
- </para>
-
- <para>
- For the simpler devices things get more complicated. The
- functions used are:
- </para>
-
- <itemizedlist>
-
- <listitem>
- <para>
- <function>int isa_dma_acquire(int chanel_number)</function>
- </para>
- <para>
- Reserve a DMA channel. Returns 0 on success or EBUSY
- if the channel was already reserved by this or a
- different driver. Most of the ISA devices are not able
- to share DMA channels anyway, so normally this
- function is called when attaching a device. This
- reservation was made redundant by the modern interface
- of bus resources but still must be used in addition to
- the latter. If not used then later, other DMA routines
- will panic.
- </para>
- </listitem>
-
- <listitem>
- <para>
- <function>int isa_dma_release(int chanel_number)</function>
- </para>
- <para>
- Release a previously reserved DMA channel. No
- transfers must be in progress when the channel is
- released (in addition the device must not try to
- initiate transfer after the channel is released).
- </para>
- </listitem>
-
- <listitem>
- <para>
- <function>void isa_dmainit(int chan, u_int
- bouncebufsize)</function>
- </para>
- <para>
- Allocate a bounce buffer for use with the specified
- channel. The requested size of the buffer can not exceed
- 64KB. This bounce buffer will be automatically used
- later if a transfer buffer happens to be not
- physically contiguous or outside of the memory
- accessible by the ISA bus or crossing the 64KB
- boundary. If the transfers will be always done from
- buffers which conform to these conditions (such as
- those allocated by
- <function>bus_dmamem_alloc()</function> with proper
- limitations) then <function>isa_dmainit()</function>
- does not have to be called. But it is quite convenient
- to transfer arbitrary data using the DMA controller.
- The bounce buffer will automatically care of the
- scatter-gather issues.
- </para>
- <!-- <blockquote> -->
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>chan</emphasis> - channel number
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>bouncebufsize</emphasis> - size of the
- bounce buffer in bytes
- </para>
- </listitem>
- </itemizedlist>
-<!-- </blockquote> -->
-<!--</para> -->
- </listitem>
-
- <listitem>
- <para>
- <function>void isa_dmastart(int flags, caddr_t addr, u_int
- nbytes, int chan)</function>
- </para>
- <para>
- Prepare to start a DMA transfer. This function must be
- called to set up the DMA controller before actually
- starting transfer on the device. It checks that the
- buffer is contiguous and falls into the ISA memory
- range, if not then the bounce buffer is automatically
- used. If bounce buffer is required but not set up by
- <function>isa_dmainit()</function> or too small for
- the requested transfer size then the system will
- panic. In case of a write request with bounce buffer
- the data will be automatically copied to the bounce
- buffer.
- </para>
- </listitem>
- <listitem>
- <para>flags - a bitmask determining the type of operation to
- be done. The direction bits B_READ and B_WRITE are mutually
- exclusive.
- </para>
- <!-- <blockquote> -->
- <itemizedlist>
- <listitem>
- <para>
- B_READ - read from the ISA bus into memory
- </para>
- </listitem>
- <listitem>
- <para>
- B_WRITE - write from the memory to the ISA bus
- </para>
- </listitem>
- <listitem>
- <para>
- B_RAW - if set then the DMA controller will remember
- the buffer and after the end of transfer will
- automatically re-initialize itself to repeat transfer
- of the same buffer again (of course, the driver may
- change the data in the buffer before initiating
- another transfer in the device). If not set then the
- parameters will work only for one transfer, and
- <function>isa_dmastart()</function> will have to be
- called again before initiating the next
- transfer. Using B_RAW makes sense only if the bounce
- buffer is not used.
- </para>
- </listitem>
- </itemizedlist>
-<!-- </blockquote> -->
- </listitem>
- <listitem>
- <para>
- addr - virtual address of the buffer
- </para>
- </listitem>
- <listitem>
- <para>
- nbytes - length of the buffer. Must be less or equal to
- 64KB. Length of 0 is not allowed: the DMA controller will
- understand it as 64KB while the kernel code will
- understand it as 0 and that would cause unpredictable
- effects. For channels number 4 and higher the length must
- be even because these channels transfer 2 bytes at a
- time. In case of an odd length the last byte will not be
- transferred.
- </para>
- </listitem>
- <listitem>
- <para>
- chan - channel number
- </para>
- </listitem>
-
- <listitem>
- <para>
- <function>void isa_dmadone(int flags, caddr_t addr, int
- nbytes, int chan)</function>
- </para>
- <para>
- Synchronize the memory after device reports that transfer
- is done. If that was a read operation with a bounce buffer
- then the data will be copied from the bounce buffer to the
- original buffer. Arguments are the same as for
- <function>isa_dmastart()</function>. Flag B_RAW is
- permitted but it does not affect
- <function>isa_dmadone()</function> in any way.
- </para>
- </listitem>
-
- <listitem>
- <para>
- <function>int isa_dmastatus(int channel_number)</function>
- </para>
- <para>
- Returns the number of bytes left in the current transfer
- to be transferred. In case the flag B_READ was set in
- <function>isa_dmastart()</function> the number returned
- will never be equal to zero. At the end of transfer it
- will be automatically reset back to the length of
- buffer. The normal use is to check the number of bytes
- left after the device signals that the transfer is
- completed. If the number of bytes is not 0 then something
- probably went wrong with that transfer.
- </para>
- </listitem>
-
- <listitem>
- <para>
- <function>int isa_dmastop(int channel_number)</function>
- </para>
- <para>
- Aborts the current transfer and returns the number of
- bytes left untransferred.
- </para>
- </listitem>
- </itemizedlist>
- </sect1>
-
- <sect1>
- <title>xxx_isa_probe</title>
- <!-- Section marked up by Wylie -->
-
- <para>
- This function probes if a device is present. If the driver
- supports auto-detection of some part of device configuration
- (such as interrupt vector or memory address) this
- auto-detection must be done in this routine.
- </para>
-
- <para>
- As for any other bus, if the device cannot be detected or
- is detected but failed the self-test or some other problem
- happened then it returns a positive value of error. The
- value ENXIO must be returned if the device is not
- present. Other error values may mean other conditions. Zero
- or negative values mean success. Most of the drivers return
- zero as success.
- </para>
-
- <para>
- The negative return values are used when a PnP device
- supports multiple interfaces. For example, an older
- compatibility interface and a newer advanced interface which
- are supported by different drivers. Then both drivers would
- detect the device. The driver which returns a higher value
- in the probe routine takes precedence (in other words, the
- driver returning 0 has highest precedence, one returning -1
- is next, one returning -2 is after it and so on). In result
- the devices which support only the old interface will be
- handled by the old driver (which should return -1 from the
- probe routine) while the devices supporting the new
- interface as well will be handled by the new driver (which
- should return 0 from the probe routine).
- </para>
-
- <para>
- The device descriptor struct xxx_softc is allocated by the
- system before calling the probe routine. If the probe
- routine returns an error the descriptor will be
- automatically deallocated by the system. So if a probing
- error occurs the driver must make sure that all the
- resources it used during probe are deallocated and that
- nothing keeps the descriptor from being safely
- deallocated. If the probe completes successfully the
- descriptor will be preserved by the system and later passed
- to the routine <function>xxx_isa_attach()</function>. If a
- driver returns a negative value it can not be sure that it
- will have the highest priority and its attach routine will
- be called. So in this case it also must release all the
- resources before returning and if necessary allocate them
- again in the attach routine. When
- <function>xxx_isa_probe()</function> returns 0 releasing the
- resources before returning is also a good idea and a
- well-behaved driver should do so. But in cases where there is
- some problem with releasing the resources the driver is
- allowed to keep resources between returning 0 from the probe
- routine and execution of the attach routine.
- </para>
-
- <para>
- A typical probe routine starts with getting the device
- descriptor and unit:
- </para>
-
- <programlisting> struct xxx_softc *sc = device_get_softc(dev);
- int unit = device_get_unit(dev);
- int pnperror;
- int error = 0;
-
- sc->dev = dev; /* link it back */
- sc->unit = unit; </programlisting>
-
- <para>
- Then check for the PnP devices. The check is carried out by
- a table containing the list of PnP IDs supported by this
- driver and human-readable descriptions of the device models
- corresponding to these IDs.
- </para>
-
- <programlisting>
- pnperror=ISA_PNP_PROBE(device_get_parent(dev), dev,
- xxx_pnp_ids); if(pnperror == ENXIO) return ENXIO;
- </programlisting>
-
- <para>
- The logic of ISA_PNP_PROBE is the following: If this card
- (device unit) was not detected as PnP then ENOENT will be
- returned. If it was detected as PnP but its detected ID does
- not match any of the IDs in the table then ENXIO is
- returned. Finally, if it has PnP support and it matches on
- of the IDs in the table, 0 is returned and the appropriate
- description from the table is set by
- <function>device_set_desc()</function>.
- </para>
-
- <para>
- If a driver supports only PnP devices then the condition
- would look like:
- </para>
-
- <programlisting> if(pnperror != 0)
- return pnperror; </programlisting>
-
- <para>
- No special treatment is required for the drivers which do not
- support PnP because they pass an empty PnP ID table and will
- always get ENXIO if called on a PnP card.
- </para>
-
- <para>
- The probe routine normally needs at least some minimal set
- of resources, such as I/O port number to find the card and
- probe it. Depending on the hardware the driver may be able
- to discover the other necessary resources automatically. The
- PnP devices have all the resources pre-set by the PnP
- subsystem, so the driver does not need to discover them by
- itself.
- </para>
-
- <para>
- Typically the minimal information required to get access to
- the device is the I/O port number. Then some devices allow
- to get the rest of information from the device configuration
- registers (though not all devices do that). So first we try
- to get the port start value:
- </para>
-
- <programlisting> sc->port0 = bus_get_resource_start(dev,
- SYS_RES_IOPORT, 0 /*rid*/); if(sc->port0 == 0) return ENXIO;
- </programlisting>
-
- <para>
- The base port address is saved in the structure softc for
- future use. If it will be used very often then calling the
- resource function each time would be prohibitively slow. If
- we do not get a port we just return an error. Some device
- drivers can instead be clever and try to probe all the
- possible ports, like this:
- </para>
-
- <programlisting>
- /* table of all possible base I/O port addresses for this device */
- static struct xxx_allports {
- u_short port; /* port address */
- short used; /* flag: if this port is already used by some unit */
- } xxx_allports = {
- { 0x300, 0 },
- { 0x320, 0 },
- { 0x340, 0 },
- { 0, 0 } /* end of table */
- };
-
- ...
- int port, i;
- ...
-
- port = bus_get_resource_start(dev, SYS_RES_IOPORT, 0 /*rid*/);
- if(port !=0 ) {
- for(i=0; xxx_allports[i].port!=0; i++) {
- if(xxx_allports[i].used || xxx_allports[i].port != port)
- continue;
-
- /* found it */
- xxx_allports[i].used = 1;
- /* do probe on a known port */
- return xxx_really_probe(dev, port);
- }
- return ENXIO; /* port is unknown or already used */
- }
-
- /* we get here only if we need to guess the port */
- for(i=0; xxx_allports[i].port!=0; i++) {
- if(xxx_allports[i].used)
- continue;
-
- /* mark as used - even if we find nothing at this port
- * at least we won't probe it in future
- */
- xxx_allports[i].used = 1;
-
- error = xxx_really_probe(dev, xxx_allports[i].port);
- if(error == 0) /* found a device at that port */
- return 0;
- }
- /* probed all possible addresses, none worked */
- return ENXIO;</programlisting>
-
- <para>
- Of course, normally the driver's
- <function>identify()</function> routine should be used for
- such things. But there may be one valid reason why it may be
- better to be done in <function>probe()</function>: if this
- probe would drive some other sensitive device crazy. The
- probe routines are ordered with consideration of the
- <literal>sensitive</literal> flag: the sensitive devices get probed first and
- the rest of the devices later. But the
- <function>identify()</function> routines are called before
- any probes, so they show no respect to the sensitive devices
- and may upset them.
- </para>
-
- <para>
- Now, after we got the starting port we need to set the port
- count (except for PnP devices) because the kernel does not
- have this information in the configuration file.
- </para>
-
- <programlisting>
- if(pnperror /* only for non-PnP devices */
- &#38;&#38; bus_set_resource(dev, SYS_RES_IOPORT, 0, sc->port0,
- XXX_PORT_COUNT)&lt;0)
- return ENXIO;</programlisting>
-
- <para>
- Finally allocate and activate a piece of port address space
- (special values of start and end mean <quote>use those we set by
- <function>bus_set_resource()</function></quote>):
- </para>
-
- <programlisting>
- sc->port0_rid = 0;
- sc->port0_r = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &#38;sc->port0_rid,
- /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);
-
- if(sc->port0_r == NULL)
- return ENXIO;</programlisting>
-
- <para>
- Now having access to the port-mapped registers we can poke
- the device in some way and check if it reacts like it is
- expected to. If it does not then there is probably some
- other device or no device at all at this address.
- </para>
-
- <para>
- Normally drivers do not set up the interrupt handlers until
- the attach routine. Instead they do probes in the polling
- mode using the <function>DELAY()</function> function for
- timeout. The probe routine must never hang forever, all the
- waits for the device must be done with timeouts. If the
- device does not respond within the time it is probably broken
- or misconfigured and the driver must return error. When
- determining the timeout interval give the device some extra
- time to be on the safe side: although
- <function>DELAY()</function> is supposed to delay for the
- same amount of time on any machine it has some margin of
- error, depending on the exact CPU.
- </para>
-
- <para>
- If the probe routine really wants to check that the
- interrupts really work it may configure and probe the
- interrupts too. But that is not recommended.
- </para>
-
- <programlisting>
- /* implemented in some very device-specific way */
- if(error = xxx_probe_ports(sc))
- goto bad; /* will deallocate the resources before returning */
- </programlisting>
-
- <para>
- The function <function>xxx_probe_ports()</function> may also
- set the device description depending on the exact model of
- device it discovers. But if there is only one supported
- device model this can be as well done in a hardcoded way.
- Of course, for the PnP devices the PnP support sets the
- description from the table automatically.
- </para>
-
-
- <programlisting> if(pnperror)
- device_set_desc(dev, "Our device model 1234");
- </programlisting>
-
- <para>
- Then the probe routine should either discover the ranges of
- all the resources by reading the device configuration
- registers or make sure that they were set explicitly by the
- user. We will consider it with an example of on-board
- memory. The probe routine should be as non-intrusive as
- possible, so allocation and check of functionality of the
- rest of resources (besides the ports) would be better left
- to the attach routine.
- </para>
-
- <para>
- The memory address may be specified in the kernel
- configuration file or on some devices it may be
- pre-configured in non-volatile configuration registers. If
- both sources are available and different, which one should
- be used? Probably if the user bothered to set the address
- explicitly in the kernel configuration file they know what
- they are doing and this one should take precedence. An
- example of implementation could be:
- </para>
- <programlisting>
- /* try to find out the config address first */
- sc->mem0_p = bus_get_resource_start(dev, SYS_RES_MEMORY, 0 /*rid*/);
- if(sc->mem0_p == 0) { /* nope, not specified by user */
- sc->mem0_p = xxx_read_mem0_from_device_config(sc);
-
-
- if(sc->mem0_p == 0)
- /* can't get it from device config registers either */
- goto bad;
- } else {
- if(xxx_set_mem0_address_on_device(sc) &lt; 0)
- goto bad; /* device does not support that address */
- }
-
- /* just like the port, set the memory size,
- * for some devices the memory size would not be constant
- * but should be read from the device configuration registers instead
- * to accommodate different models of devices. Another option would
- * be to let the user set the memory size as "msize" configuration
- * resource which will be automatically handled by the ISA bus.
- */
- if(pnperror) { /* only for non-PnP devices */
- sc->mem0_size = bus_get_resource_count(dev, SYS_RES_MEMORY, 0 /*rid*/);
- if(sc->mem0_size == 0) /* not specified by user */
- sc->mem0_size = xxx_read_mem0_size_from_device_config(sc);
-
- if(sc->mem0_size == 0) {
- /* suppose this is a very old model of device without
- * auto-configuration features and the user gave no preference,
- * so assume the minimalistic case
- * (of course, the real value will vary with the driver)
- */
- sc->mem0_size = 8*1024;
- }
-
- if(xxx_set_mem0_size_on_device(sc) &lt; 0)
- goto bad; /* device does not support that size */
-
- if(bus_set_resource(dev, SYS_RES_MEMORY, /*rid*/0,
- sc->mem0_p, sc->mem0_size)&lt;0)
- goto bad;
- } else {
- sc->mem0_size = bus_get_resource_count(dev, SYS_RES_MEMORY, 0 /*rid*/);
- } </programlisting>
-
- <para>
- Resources for IRQ and DRQ are easy to check by analogy.
- </para>
-
- <para>
- If all went well then release all the resources and return success.
- </para>
-
- <programlisting> xxx_free_resources(sc);
- return 0;</programlisting>
-
- <para>
- Finally, handle the troublesome situations. All the
- resources should be deallocated before returning. We make
- use of the fact that before the structure softc is passed to
- us it gets zeroed out, so we can find out if some resource
- was allocated: then its descriptor is non-zero.
- </para>
-
- <programlisting> bad:
-
- xxx_free_resources(sc);
- if(error)
- return error;
- else /* exact error is unknown */
- return ENXIO;</programlisting>
-
- <para>
- That would be all for the probe routine. Freeing of
- resources is done from multiple places, so it is moved to a
- function which may look like:
- </para>
-
-<programlisting>static void
- xxx_free_resources(sc)
- struct xxx_softc *sc;
- {
- /* check every resource and free if not zero */
-
- /* interrupt handler */
- if(sc->intr_r) {
- bus_teardown_intr(sc->dev, sc->intr_r, sc->intr_cookie);
- bus_release_resource(sc->dev, SYS_RES_IRQ, sc->intr_rid,
- sc->intr_r);
- sc->intr_r = 0;
- }
-
- /* all kinds of memory maps we could have allocated */
- if(sc->data_p) {
- bus_dmamap_unload(sc->data_tag, sc->data_map);
- sc->data_p = 0;
- }
- if(sc->data) { /* sc->data_map may be legitimately equal to 0 */
- /* the map will also be freed */
- bus_dmamem_free(sc->data_tag, sc->data, sc->data_map);
- sc->data = 0;
- }
- if(sc->data_tag) {
- bus_dma_tag_destroy(sc->data_tag);
- sc->data_tag = 0;
- }
-
- ... free other maps and tags if we have them ...
-
- if(sc->parent_tag) {
- bus_dma_tag_destroy(sc->parent_tag);
- sc->parent_tag = 0;
- }
-
- /* release all the bus resources */
- if(sc->mem0_r) {
- bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->mem0_rid,
- sc->mem0_r);
- sc->mem0_r = 0;
- }
- ...
- if(sc->port0_r) {
- bus_release_resource(sc->dev, SYS_RES_IOPORT, sc->port0_rid,
- sc->port0_r);
- sc->port0_r = 0;
- }
- }</programlisting>
-
- </sect1>
-
- <sect1>
- <title>xxx_isa_attach</title>
- <!-- Section Marked up by Wylie -->
-
- <para>The attach routine actually connects the driver to the
- system if the probe routine returned success and the system
- had chosen to attach that driver. If the probe routine
- returned 0 then the attach routine may expect to receive the
- device structure softc intact, as it was set by the probe
- routine. Also if the probe routine returns 0 it may expect
- that the attach routine for this device shall be called at
- some point in the future. If the probe routine returns a
- negative value then the driver may make none of these
- assumptions.
- </para>
-
- <para>The attach routine returns 0 if it completed successfully or
- error code otherwise.
- </para>
-
- <para>The attach routine starts just like the probe routine,
- with getting some frequently used data into more accessible
- variables.
- </para>
-
- <programlisting> struct xxx_softc *sc = device_get_softc(dev);
- int unit = device_get_unit(dev);
- int error = 0;</programlisting>
-
- <para>Then allocate and activate all the necessary
- resources. Because normally the port range will be released
- before returning from probe, it has to be allocated
- again. We expect that the probe routine had properly set all
- the resource ranges, as well as saved them in the structure
- softc. If the probe routine had left some resource allocated
- then it does not need to be allocated again (which would be
- considered an error).
- </para>
-
- <programlisting> sc->port0_rid = 0;
- sc->port0_r = bus_alloc_resource(dev, SYS_RES_IOPORT, &#38;sc->port0_rid,
- /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);
-
- if(sc->port0_r == NULL)
- return ENXIO;
-
- /* on-board memory */
- sc->mem0_rid = 0;
- sc->mem0_r = bus_alloc_resource(dev, SYS_RES_MEMORY, &#38;sc->mem0_rid,
- /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);
-
- if(sc->mem0_r == NULL)
- goto bad;
-
- /* get its virtual address */
- sc->mem0_v = rman_get_virtual(sc->mem0_r);</programlisting>
-
- <para>The DMA request channel (DRQ) is allocated likewise. To
- initialize it use functions of the
- <function>isa_dma*()</function> family. For example:
- </para>
-
- <para><function>isa_dmacascade(sc->drq0);</function></para>
-
- <para>The interrupt request line (IRQ) is a bit
- special. Besides allocation the driver's interrupt handler
- should be associated with it. Historically in the old ISA
- drivers the argument passed by the system to the interrupt
- handler was the device unit number. But in modern drivers
- the convention suggests passing the pointer to structure
- softc. The important reason is that when the structures
- softc are allocated dynamically then getting the unit number
- from softc is easy while getting softc from the unit number is
- difficult. Also this convention makes the drivers for
- different buses look more uniform and allows them to share
- the code: each bus gets its own probe, attach, detach and
- other bus-specific routines while the bulk of the driver
- code may be shared among them.
- </para>
-
- <programlisting>
- sc->intr_rid = 0;
- sc->intr_r = bus_alloc_resource(dev, SYS_RES_MEMORY, &#38;sc->intr_rid,
- /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);
-
- if(sc->intr_r == NULL)
- goto bad;
-
- /*
- * XXX_INTR_TYPE is supposed to be defined depending on the type of
- * the driver, for example as INTR_TYPE_CAM for a CAM driver
- */
- error = bus_setup_intr(dev, sc->intr_r, XXX_INTR_TYPE,
- (driver_intr_t *) xxx_intr, (void *) sc, &#38;sc->intr_cookie);
- if(error)
- goto bad;
-
- </programlisting>
-
-
- <para>If the device needs to make DMA to the main memory then
- this memory should be allocated like described before:
- </para>
-
- <programlisting> error=bus_dma_tag_create(NULL, /*alignment*/ 4,
- /*boundary*/ 0, /*lowaddr*/ BUS_SPACE_MAXADDR_24BIT,
- /*highaddr*/ BUS_SPACE_MAXADDR, /*filter*/ NULL, /*filterarg*/ NULL,
- /*maxsize*/ BUS_SPACE_MAXSIZE_24BIT,
- /*nsegments*/ BUS_SPACE_UNRESTRICTED,
- /*maxsegsz*/ BUS_SPACE_MAXSIZE_24BIT, /*flags*/ 0,
- &#38;sc->parent_tag);
- if(error)
- goto bad;
-
- /* many things get inherited from the parent tag
- * sc->data is supposed to point to the structure with the shared data,
- * for example for a ring buffer it could be:
- * struct {
- * u_short rd_pos;
- * u_short wr_pos;
- * char bf[XXX_RING_BUFFER_SIZE]
- * } *data;
- */
- error=bus_dma_tag_create(sc->parent_tag, 1,
- 0, BUS_SPACE_MAXADDR, 0, /*filter*/ NULL, /*filterarg*/ NULL,
- /*maxsize*/ sizeof(* sc->data), /*nsegments*/ 1,
- /*maxsegsz*/ sizeof(* sc->data), /*flags*/ 0,
- &#38;sc->data_tag);
- if(error)
- goto bad;
-
- error = bus_dmamem_alloc(sc->data_tag, &#38;sc->data, /* flags*/ 0,
- &#38;sc->data_map);
- if(error)
- goto bad;
-
- /* xxx_alloc_callback() just saves the physical address at
- * the pointer passed as its argument, in this case &#38;sc->data_p.
- * See details in the section on bus memory mapping.
- * It can be implemented like:
- *
- * static void
- * xxx_alloc_callback(void *arg, bus_dma_segment_t *seg,
- * int nseg, int error)
- * {
- * *(bus_addr_t *)arg = seg[0].ds_addr;
- * }
- */
- bus_dmamap_load(sc->data_tag, sc->data_map, (void *)sc->data,
- sizeof (* sc->data), xxx_alloc_callback, (void *) &#38;sc->data_p,
- /*flags*/0);</programlisting>
-
-
- <para>After all the necessary resources are allocated the
- device should be initialized. The initialization may include
- testing that all the expected features are functional.</para>
-
- <programlisting> if(xxx_initialize(sc) &lt; 0)
- goto bad; </programlisting>
-
-
- <para>The bus subsystem will automatically print on the
- console the device description set by probe. But if the
- driver wants to print some extra information about the
- device it may do so, for example:</para>
-
- <programlisting>
- device_printf(dev, "has on-card FIFO buffer of %d bytes\n", sc->fifosize);
- </programlisting>
-
- <para>If the initialization routine experiences any problems
- then printing messages about them before returning error is
- also recommended.</para>
-
- <para>The final step of the attach routine is attaching the
- device to its functional subsystem in the kernel. The exact
- way to do it depends on the type of the driver: a character
- device, a block device, a network device, a CAM SCSI bus
- device and so on.</para>
-
- <para>If all went well then return success.</para>
-
- <programlisting> error = xxx_attach_subsystem(sc);
- if(error)
- goto bad;
-
- return 0; </programlisting>
-
- <para>Finally, handle the troublesome situations. All the
- resources should be deallocated before returning an
- error. We make use of the fact that before the structure
- softc is passed to us it gets zeroed out, so we can find out
- if some resource was allocated: then its descriptor is
- non-zero.</para>
-
- <programlisting> bad:
-
- xxx_free_resources(sc);
- if(error)
- return error;
- else /* exact error is unknown */
- return ENXIO;</programlisting>
-
- <para>That would be all for the attach routine.</para>
-
- </sect1>
-
-
- <sect1>
- <title>xxx_isa_detach</title>
-
- <para>
- If this function is present in the driver and the driver is
- compiled as a loadable module then the driver gets the
- ability to be unloaded. This is an important feature if the
- hardware supports hot plug. But the ISA bus does not support
- hot plug, so this feature is not particularly important for
- the ISA devices. The ability to unload a driver may be
- useful when debugging it, but in many cases installation of
- the new version of the driver would be required only after
- the old version somehow wedges the system and a reboot will be
- needed anyway, so the efforts spent on writing the detach
- routine may not be worth it. Another argument that
- unloading would allow upgrading the drivers on a production
- machine seems to be mostly theoretical. Installing a new
- version of a driver is a dangerous operation which should
- never be performed on a production machine (and which is not
- permitted when the system is running in secure mode). Still,
- the detach routine may be provided for the sake of
- completeness.
- </para>
-
- <para>
- The detach routine returns 0 if the driver was successfully
- detached or the error code otherwise.
- </para>
-
- <para>
- The logic of detach is a mirror of the attach. The first
- thing to do is to detach the driver from its kernel
- subsystem. If the device is currently open then the driver
- has two choices: refuse to be detached or forcibly close and
- proceed with detach. The choice used depends on the ability
- of the particular kernel subsystem to do a forced close and
- on the preferences of the driver's author. Generally the
- forced close seems to be the preferred alternative.
- <programlisting> struct xxx_softc *sc = device_get_softc(dev);
- int error;
-
- error = xxx_detach_subsystem(sc);
- if(error)
- return error;</programlisting>
- </para>
- <para>
- Next the driver may want to reset the hardware to some
- consistent state. That includes stopping any ongoing
- transfers, disabling the DMA channels and interrupts to
- avoid memory corruption by the device. For most of the
- drivers this is exactly what the shutdown routine does, so
- if it is included in the driver we can just call it.
- </para>
- <para><function>xxx_isa_shutdown(dev);</function></para>
-
- <para>
- And finally release all the resources and return success.
- <programlisting> xxx_free_resources(sc);
- return 0;</programlisting>
-
- </para>
- </sect1>
-
- <sect1>
- <title>xxx_isa_shutdown</title>
-
- <para>
- This routine is called when the system is about to be shut
- down. It is expected to bring the hardware to some
- consistent state. For most of the ISA devices no special
- action is required, so the function is not really necessary
- because the device will be re-initialized on reboot
- anyway. But some devices have to be shut down with a special
- procedure, to make sure that they will be properly detected
- after soft reboot (this is especially true for many devices
- with proprietary identification protocols). In any case
- disabling DMA and interrupts in the device registers and
- stopping any ongoing transfers is a good idea. The exact
- action depends on the hardware, so we do not consider it here
- in any detail.
- </para>
- </sect1>
-
- <sect1>
- <title>xxx_intr</title>
-
- <para>
- The interrupt handler is called when an interrupt is
- received which may be from this particular device. The ISA
- bus does not support interrupt sharing (except in some special
- cases) so in practice if the interrupt handler is called
- then the interrupt almost for sure came from its
- device. Still, the interrupt handler must poll the device
- registers and make sure that the interrupt was generated by
- its device. If not it should just return.
- </para>
-
- <para>
- The old convention for the ISA drivers was getting the
- device unit number as an argument. This is obsolete, and the
- new drivers receive whatever argument was specified for them
- in the attach routine when calling
- <function>bus_setup_intr()</function>. By the new convention
- it should be the pointer to the structure softc. So the
- interrupt handler commonly starts as:
- </para>
-
- <programlisting>
- static void
- xxx_intr(struct xxx_softc *sc)
- {
-
- </programlisting>
-
- <para>
- It runs at the interrupt priority level specified by the
- interrupt type parameter of
- <function>bus_setup_intr()</function>. That means that all
- the other interrupts of the same type as well as all the
- software interrupts are disabled.
- </para>
-
- <para>
- To avoid races it is commonly written as a loop:
- </para>
-
- <programlisting>
- while(xxx_interrupt_pending(sc)) {
- xxx_process_interrupt(sc);
- xxx_acknowledge_interrupt(sc);
- } </programlisting>
-
- <para>
- The interrupt handler has to acknowledge interrupt to the
- device only but not to the interrupt controller, the system
- takes care of the latter.
- </para>
-
- </sect1>
-</chapter>
diff --git a/en_US.ISO8859-1/books/arch-handbook/jail/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/jail/chapter.sgml
deleted file mode 100644
index 3aae2cbbed..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/jail/chapter.sgml
+++ /dev/null
@@ -1,611 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="jail">
- <chapterinfo>
- <author><firstname>Evan Sarmiento</firstname>
- <affiliation><address><email>evms@cs.bu.edu</email></address>
- </affiliation>
- </author>
- <copyright>
- <year>2001</year>
- <holder role="mailto:evms@cs.bu.edu">Evan Sarmiento</holder>
- </copyright>
- </chapterinfo>
- <title>The Jail Subsystem</title>
-
- <para>On most UNIX systems, root has omnipotent power. This promotes
- insecurity. If an attacker were to gain root on a system, he would
- have every function at his fingertips. In FreeBSD there are
- sysctls which dilute the power of root, in order to minimize the
- damage caused by an attacker. Specifically, one of these functions
- is called secure levels. Similarly, another function which is
- present from FreeBSD 4.0 and onward, is a utility called
- &man.jail.8;. <application>Jail</application> chroots an
- environment and sets certain restrictions on processes which are
- forked from within. For example, a jailed process cannot affect
- processes outside of the jail, utilize certain system calls, or
- inflict any damage on the main computer.</para>
-
- <para><application>Jail</application> is becoming the new security
- model. People are running potentially vulnerable servers such as
- Apache, BIND, and sendmail within jails, so that if an attacker
- gains root within the <application>Jail</application>, it is only
- an annoyance, and not a devastation. This article focuses on the
- internals (source code) of <application>Jail</application> and
- <application>Jail</application> NG. It will also suggest
- improvements upon the jail code base which are already being
- worked on. If you are looking for a how-to on setting up a
- <application>Jail</application>, I suggest you look at my other
- article in Sys Admin Magazine, May 2001, entitled "Securing
- FreeBSD using <application>Jail</application>."</para>
-
- <sect1>
- <title>Architecture</title>
-
- <para>
- <application>Jail</application> consists of two realms: the
- user-space program, jail, and the code implemented within the
- kernel: the <literal>jail()</literal> system call and associated
- restrictions. I will be discussing the user-space program and
- then how jail is implemented within the kernel.</para>
-
- <sect2>
- <title>Userland code</title>
-
- <para>The source for the user-land jail is located in
- <filename>/usr/src/usr.sbin/jail</filename>, consisting of
- one file, <filename>jail.c</filename>. The program takes these
- arguments: the path of the jail, hostname, ip address, and the
- command to be executed.</para>
-
- <sect3>
- <title>Data Structures</title>
-
- <para>In <filename>jail.c</filename>, the first thing I would
- note is the declaration of an important structure
- <literal>struct jail j</literal>; which was included from
- <filename>/usr/include/sys/jail.h</filename>.
-
- <para>The definition of the jail structure is:</para>
-
-<programlisting><filename>/usr/include/sys/jail.h</filename>:
-
-struct jail {
- u_int32_t version;
- char *path;
- char *hostname;
- u_int32_t ip_number;
-};</programlisting>
-
- <para>As you can see, there is an entry for each of the
- arguments passed to the jail program, and indeed, they are
- set during it's execution.</para>
-
- <programlisting><filename>/usr/src/usr.sbin/jail.c</filename>
-j.version = 0;
-j.path = argv[1];
-j.hostname = argv[2];</programlisting>
-
- </sect3>
-
- <sect3>
- <title>Networking</title>
-
- <para>One of the arguments passed to the Jail program is an IP
- address with which the jail can be accessed over the
- network. Jail translates the ip address given into network
- byte order and then stores it in j (the jail structure).</para>
-
- <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename>:
-struct in.addr in;
-...
-i = inet.aton(argv[3], <![CDATA[&in]]>);
-...
-j.ip_number = ntohl(in.s.addr);</programlisting>
-
- <para>The
- <citerefentry><refentrytitle>inet_aton</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- function "interprets the specified character string as an
- Internet address, placing the address into the structure
- provided." The ip number node in the jail structure is set
- only when the ip address placed onto the in structure by
- inet aton is translated into network byte order by
- <function>ntohl()</function>.</para>
-
- </sect3>
-
- <sect3>
- <title>Jailing The Process</title>
-
- <para>Finally, the userland program jails the process, and
- executes the command specified. Jail now becomes an
- imprisoned process itself and forks a child process which
- then executes the command given using &man.execv.3;
-
- <programlisting><filename>/usr/src/sys/usr.sbin/jail/jail.c</filename>
-i = jail(<![CDATA[&j]]>);
-...
-i = execv(argv[4], argv + 4);</programlisting>
-
- <para>As you can see, the jail function is being called, and
- its argument is the jail structure which has been filled
- with the arguments given to the program. Finally, the
- program you specify is executed. I will now discuss how Jail
- is implemented within the kernel.</para>
- </sect3>
- </sect2>
-
- <sect2>
- <title>Kernel Space</title>
-
- <para>We will now be looking at the file
- <filename>/usr/src/sys/kern/kern_jail.c</filename>. This is
- the file where the jail system call, appropriate sysctls, and
- networking functions are defined.</para>
-
- <sect3>
- <title>sysctls</title>
-
- <para>In <filename>kern_jail.c</filename>, the following
- sysctls are defined:</para>
-
- <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename>
-
-int jail_set_hostname_allowed = 1;
-SYSCTL_INT(_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW,
- <![CDATA[&jail]]>_set_hostname_allowed, 0,
- "Processes in jail can set their hostnames");
-
-int jail_socket_unixiproute_only = 1;
-SYSCTL_INT(_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW,
- <![CDATA[&jail]]>_socket_unixiproute_only, 0,
- "Processes in jail are limited to creating UNIX/IPv4/route sockets only
-");
-
-int jail_sysvipc_allowed = 0;
-SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
- <![CDATA[&jail]]>_sysvipc_allowed, 0,
- "Processes in jail can use System V IPC primitives");</programlisting>
-
- <para>Each of these sysctls can be accessed by the user
- through the sysctl program. Throughout the kernel, these
- specific sysctls are recognized by their name. For example,
- the name of the first sysctl is
- <literal>jail.set.hostname.allowed</literal>.</para>
- </sect3>
-
- <sect3>
- <title>&man.jail.2; system call</title>
-
- <para>Like all system calls, the &man.jail.2; system call takes
- two arguments, <literal>struct proc *p</literal> and
- <literal>struct jail_args
- *uap</literal>. <literal>p</literal> is a pointer to a proc
- structure which describes the calling process. In this
- context, uap is a pointer to a structure which specifies the
- arguments given to &man.jail.2; from the userland program
- <filename>jail.c</filename>. When I described the userland
- program before, you saw that the &man.jail.2; system call was
- given a jail structure as its own argument.</para>
-
- <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename>
-int
-jail(p, uap)
- struct proc *p;
- struct jail_args /* {
- syscallarg(struct jail *) jail;
- } */ *uap;</programlisting>
-
- <para>Therefore, <literal>uap->jail</literal> would access the
- jail structure which was passed to the system call. Next,
- the system call copies the jail structure into kernel space
- using the <literal>copyin()</literal>
- function. <literal>copyin()</literal> takes three arguments:
- the data which is to be copied into kernel space,
- <literal>uap->jail</literal>, where to store it,
- <literal>j</literal> and the size of the storage. The jail
- structure <literal>uap->jail</literal> is copied into kernel
- space and stored in another jail structure,
- <literal>j</literal>.</para>
-
- <programlisting><filename>/usr/src/sys/kern/kern_jail.c: </filename>
-error = copyin(uap->jail, <![CDATA[&j]]>, sizeof j);</programlisting>
-
- <para>There is another important structure defined in
- jail.h. It is the prison structure
- (<literal>pr</literal>). The prison structure is used
- exclusively within kernel space. The &man.jail.2; system call
- copies everything from the jail structure onto the prison
- structure. Here is the definition of the prison structure.</para>
-
- <programlisting><filename>/usr/include/sys/jail.h</filename>:
-struct prison {
- int pr_ref;
- char pr_host[MAXHOSTNAMELEN];
- u_int32_t pr_ip;
- void *pr_linux;
-};</programlisting>
-
- <para>The jail() system call then allocates memory for a
- pointer to a prison structure and copies data between the two
- structures.</para>
-
- <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>:
- MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK);
- bzero((caddr_t)pr, sizeof *pr);
- error = copyinstr(j.hostname, <![CDATA[&pr->pr_host]]>, sizeof pr->pr_host, 0);
- if (error)
- goto bail;</programlisting>
-
- <para>Finally, the jail system call chroots the path
- specified. The chroot function is given two arguments. The
- first is p, which represents the calling process, the second
- is a pointer to the structure chroot args. The structure
- chroot args contains the path which is to be chrooted. As
- you can see, the path specified in the jail structure is
- copied to the chroot args structure and used.</para>
-
- <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>:
-ca.path = j.path;
-error = chroot(p, <![CDATA[&ca]]>);</programlisting>
-
- <para>These next three lines in the source are very important,
- as they specify how the kernel recognizes a process as
- jailed. Each process on a Unix system is described by its
- own proc structure. You can see the whole proc structure in
- <filename>/usr/include/sys/proc.h</filename>. For example,
- the p argument in any system call is actually a pointer to
- that process' proc structure, as stated before. The proc
- structure contains nodes which can describe the owner's
- identity (<literal>p_cred</literal>), the process resource
- limits (<literal>p_limit</literal>), and so on. In the
- definition of the process structure, there is a pointer to a
- prison structure. (<literal>p_prison</literal>).</para>
-
- <programlisting><filename>/usr/include/sys/proc.h: </filename>
-struct proc {
-...
-struct prison *p_prison;
-...
-};</programlisting>
-
- <para>In <filename>kern_jail.c</filename>, the function then
- copies the pr structure, which is filled with all the
- information from the original jail structure, over to the
- <literal>p->p_prison</literal> structure. It then does a
- bitwise OR of <literal>p->p_flag</literal> with the constant
- <literal>P_JAILED</literal>, meaning that the calling
- process is now recognized as jailed. The parent process of
- each process, forked within the jail, is the program jail
- itself, as it calls the &man.jail.2; system call. When the
- program is executed through execve, it inherits the
- properties of its parents proc structure, therefore it has
- the <literal>p->p_flag</literal> set, and the
- <literal>p->p_prison</literal> structure is filled.</para>
-
- <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>
-p->p.prison = pr;
-p->p.flag --= P.JAILED;</programlisting>
-
- <para>When a process is forked from a parent process, the
- &man.fork.2; system call deals differently with imprisoned
- processes. In the fork system call, there are two pointers
- to a <literal>proc</literal> structure <literal>p1</literal>
- and <literal>p2</literal>. <literal>p1</literal> points to
- the parent's <literal>proc</literal> structure and p2 points
- to the child's unfilled <literal>proc</literal>
- structure. After copying all relevant data between the
- structures, &man.fork.2; checks if the structure
- <literal>p->p_prison</literal> is filled on
- <literal>p2</literal>. If it is, it increments the
- <literal>pr.ref</literal> by one, and sets the
- <literal>p_flag</literal> to one on the child process.</para>
-
- <programlisting><filename>/usr/src/sys/kern/kern_fork.c</filename>:
-if (p2->p_prison) {
- p2->p_prison->pr_ref++;
- p2->p_flag |= P_JAILED;
-}</programlisting>
-
- </sect3>
- </sect2>
- </sect1>
-
- <sect1>
- <title>Restrictions</title>
-
- <para>Throughout the kernel there are access restrictions relating
- to jailed processes. Usually, these restrictions only check if
- the process is jailed, and if so, returns an error. For
- example:</para>
-
- <programlisting>if (p->p_prison)
- return EPERM;</programlisting>
-
- <sect2>
- <title>SysV IPC</title>
-
- <para>System V IPC is based on messages. Processes can send each
- other these messages which tell them how to act. The functions
- which deal with messages are: <literal>msgsys</literal>,
- <literal>msgctl</literal>, <literal>msgget</literal>,
- <literal>msgsend</literal> and <literal>msgrcv</literal>.
- Earlier, I mentioned that there were certain sysctls you could
- turn on or off in order to affect the behavior of Jail. One of
- these sysctls was <literal>jail_sysvipc_allowed</literal>. On
- most systems, this sysctl is set to 0. If it were set to 1, it
- would defeat the whole purpose of having a jail; privleged
- users from within the jail would be able to affect processes
- outside of the environment. The difference between a message
- and a signal is that the message only consists of the signal
- number.</para>
-
- <para><filename>/usr/src/sys/kern/sysv_msg.c</filename>:</para>
-
- <itemizedlist>
- <listitem> <para>&man.msgget.3;: msgget returns (and possibly
- creates) a message descriptor that designates a message queue
- for use in other system calls.</para></listitem>
-
- <listitem> <para>&man.msgctl.3;: Using this function, a process
- can query the status of a message
- descriptor.</para></listitem>
-
- <listitem> <para>&man.msgsnd.3;: msgsnd sends a message to a
- process.</para></listitem>
-
- <listitem> <para>&man.msgrcv.3;: a process receives messages using
- this function</para></listitem>
-
- </itemizedlist>
-
- <para>In each of these system calls, there is this
- conditional:</para>
-
- <programlisting><filename>/usr/src/sys/kern/sysv msg.c</filename>:
-if (!jail.sysvipc.allowed && p->p_prison != NULL)
- return (ENOSYS);</programlisting>
-
- <para>Semaphore system calls allow processes to synchronize
- execution by doing a set of operations atomically on a set of
- semaphores. Basically semaphores provide another way for
- processes lock resources. However, process waiting on a
- semaphore, that is being used, will sleep until the resources
- are relinquished. The following semaphore system calls are
- blocked inside a jail: <literal>semsys</literal>,
- <literal>semget</literal>, <literal>semctl</literal> and
- <literal>semop</literal>.</para>
-
- <para><filename>/usr/src/sys/kern/sysv_sem.c</filename>:</para>
-
- <itemizedlist>
- <listitem>
- <para>&man.semctl.2;<literal>(id, num, cmd, arg)</literal>:
- Semctl does the specified cmd on the semaphore queue
- indicated by id.</para></listitem>
-
- <listitem>
- <para>&man.semget.2;<literal>(key, nsems, flag)</literal>:
- Semget creates an array of semaphores, corresponding to
- key.</para>
-
- <para><literal>Key and flag take on the same meaning as they
- do in msgget.</literal></para></listitem>
-
- <listitem><para>&man.semop.2;<literal>(id, ops, num)</literal>:
- Semop does the set of semaphore operations in the array of
- structures ops, to the set of semaphores identified by
- id.</para></listitem>
- </itemizedlist>
-
- <para>System V IPC allows for processes to share
- memory. Processes can communicate directly with each other by
- sharing parts of their virtual address space and then reading
- and writing data stored in the shared memory. These system
- calls are blocked within a jailed environment: <literal>shmdt,
- shmat, oshmctl, shmctl, shmget</literal>, and
- <literal>shmsys</literal>.</para>
-
- <para><filename>/usr/src/sys/kern/sysv shm.c</filename>:</para>
-
- <itemizedlist>
- <listitem><para>&man.shmctl.2;<literal>(id, cmd, buf)</literal>:
- shmctl does various control operations on the shared memory
- region identified by id.</para></listitem>
-
- <listitem><para>&man.shmget.2;<literal>(key, size,
- flag)</literal>: shmget accesses or creates a shared memory
- region of size bytes.</para></listitem>
-
- <listitem><para>&man.shmat.2;<literal>(id, addr, flag)</literal>:
- shmat attaches a shared memory region identified by id to the
- address space of a process.</para></listitem>
-
- <listitem><para>&man.shmdt.2;<literal>(addr)</literal>: shmdt
- detaches the shared memory region previously attached at
- addr.</para></listitem>
-
- </itemizedlist>
- </sect2>
-
- <sect2>
- <title>Sockets</title>
-
- <para>Jail treats the &man.socket.2; system call and related
- lower-level socket functions in a special manner. In order to
- determine whether a certain socket is allowed to be created,
- it first checks to see if the sysctl
- <literal>jail.socket.unixiproute.only</literal> is set. If
- set, sockets are only allowed to be created if the family
- specified is either <literal>PF_LOCAL</literal>,
- <literal>PF_INET</literal> or
- <literal>PF_ROUTE</literal>. Otherwise, it returns an
- error.</para>
-
- <programlisting><filename>/usr/src/sys/kern/uipc_socket.c</filename>:
-int socreate(dom, aso, type, proto, p)
-...
-register struct protosw *prp;
-...
-{
- if (p->p_prison && jail_socket_unixiproute_only &&
- prp->pr_domain->dom_family != PR_LOCAL && prp->pr_domain->dom_family != PF_INET
- && prp->pr_domain->dom_family != PF_ROUTE)
- return (EPROTONOSUPPORT);
-...
-}</programlisting>
-
- </sect2>
-
- <sect2>
- <title>Berkeley Packet Filter</title>
-
- <para>The Berkeley Packet Filter provides a raw interface to
- data link layers in a protocol independent fashion. The
- function <literal>bpfopen()</literal> opens an Ethernet
- device. There is a conditional which disallows any jailed
- processes from accessing this function.</para>
-
- <programlisting><filename>/usr/src/sys/net/bpf.c</filename>:
-static int bpfopen(dev, flags, fmt, p)
-...
-{
- if (p->p_prison)
- return (EPERM);
-...
-}</programlisting>
-
- </sect2>
-
- <sect2>
- <title>Protocols</title>
-
- <para>There are certain protocols which are very common, such as
- TCP, UDP, IP and ICMP. IP and ICMP are on the same level: the
- network layer 2. There are certain precautions which are
- taken in order to prevent a jailed process from binding a
- protocol to a certain port only if the <literal>nam</literal>
- parameter is set. nam is a pointer to a sockaddr structure,
- which describes the address on which to bind the service. A
- more exact definition is that sockaddr "may be used as a
- template for reffering to the identifying tag and length of
- each address"[2]. In the function in
- <literal>pcbbind</literal>, <literal>sin</literal> is a
- pointer to a sockaddr.in structure, which contains the port,
- address, length and domain family of the socket which is to be
- bound. Basically, this disallows any processes from jail to be
- able to specify the domain family.</para>
-
- <programlisting><filename>/usr/src/sys/kern/netinet/in_pcb.c</filename>:
-int in.pcbbind(int, nam, p)
-...
- struct sockaddr *nam;
- struct proc *p;
-{
- ...
- struct sockaddr.in *sin;
- ...
- if (nam) {
- sin = (struct sockaddr.in *)nam;
- ...
- if (sin->sin_addr.s_addr != INADDR_ANY)
- if (prison.ip(p, 0, <![CDATA[&sin]]>->sin.addr.s_addr))
- return (EINVAL);
- ....
- }
-...
-}</programlisting>
-
- <para>You might be wondering what function
- <literal>prison_ip()</literal> does. prison.ip is given three
- arguments, the current process (represented by
- <literal>p</literal>), any flags, and an ip address. It
- returns 1 if the ip address belongs to a jail or 0 if it does
- not. As you can see from the code, if it is indeed an ip
- address belonging to a jail, the protcol is not allowed to
- bind to a certain port.</para>
-
- <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename>
-int prison_ip(struct proc *p, int flag, u_int32_t *ip) {
- u_int32_t tmp;
-
- if (!p->p_prison)
- return (0);
- if (flag)
- tmp = *ip;
- else tmp = ntohl (*ip);
-
- if (tmp == INADDR_ANY) {
- if (flag)
- *ip = p->p_prison->pr_ip;
- else *ip = htonl(p->p_prison->pr_ip);
- return (0);
- }
-
- if (p->p_prison->pr_ip != tmp)
- return (1);
- return (0);
-}</programlisting>
-
- <para>Jailed users are not allowed to bind services to an ip
- which does not belong to the jail. The restriction is also
- written within the function <literal>in_pcbbind</literal>:</para>
-
- <programlisting><filename>/usr/src/sys/net inet/in_pcb.c</filename>
- if (nam) {
- ...
- lport = sin->sin.port;
- ... if (lport) {
- ...
- if (p && p->p_prison)
- prison = 1;
- if (prison &&
- prison_ip(p, 0, <![CDATA[&sin]]>->sin_addr.s_addr))
- return (EADDRNOTAVAIL);</programlisting>
-
- </sect2>
-
- <sect2>
- <title>Filesystem</title>
-
- <para>Even root users within the jail are not allowed to set any
- file flags, such as immutable, append, and no unlink flags, if
- the securelevel is greater than 0.</para>
-
- <programlisting>/usr/src/sys/ufs/ufs/ufs_vnops.c:
-int ufs.setattr(ap)
- ...
-{
- if ((cred->cr.uid == 0) && (p->prison == NULL)) {
- if ((ip->i_flags
- & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) &&
- securelevel > 0)
- return (EPERM);
-}</programlisting>
-
- </sect2>
-
- </sect1>
-
- <sect1>
- <title>Jail NG</title>
-
- <para>Jail NG is a "from-scratch re-implementation of Jail" by
- Robert Watson, a FreeBSD committer. Some of the new features
- include the ability to add processes to a jail, an improved
- management tool, and per-jail sysctls. For example, you could
- have <literal>sysvipc_permitted</literal> set on one jail while
- another jail may be allowed to use System V IPC. You can
- download the kernel patches and utilities for Jail NG from his
- website at:
- <ulink
- url="http://www.watson.org/~robert/jailng/"></ulink>.</para>
-
- </sect1>
-
-</chapter>
-
diff --git a/en_US.ISO8859-1/books/arch-handbook/kobj/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/kobj/chapter.sgml
deleted file mode 100644
index f8fd4d9851..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/kobj/chapter.sgml
+++ /dev/null
@@ -1,298 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="kernel-objects">
- <title>Kernel Objects</title>
-
- <para>Kernel Objects, or <firstterm>Kobj</firstterm> provides an
- object-oriented C programming system for the kernel. As such the
- data being operated on carries the description of how to operate
- on it. This allows operations to be added and removed from an
- interface at run time and without breaking binary
- compatibility.</para>
-
- <sect1>
- <title>Terminology</title>
-
- <variablelist>
- <varlistentry>
- <term>Object</term>
- <listitem><para>A set of data - data structure - data
- allocation.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Method</term>
- <listitem>
- <para>An operation - function.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Class</term>
- <listitem>
- <para>One or more methods.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Interface</term>
- <listitem>
- <para>A standard set of one or more methods.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </sect1>
-
- <sect1>
- <title>Kobj Operation</title>
-
- <para>Kobj works by generating descriptions of methods. Each
- description holds a unique id as well as a default function. The
- description's address is used to uniquely identify the method
- within a class' method table.</para>
-
- <para>A class is built by creating a method table associating one
- or more functions with method descriptions. Before use the class
- is compiled. The compilation allocates a cache and associates it
- with the class. A unique id is assigned to each method
- description within the method table of the class if not already
- done so by another referencing class compilation. For every
- method to be used a function is generated by script to qualify
- arguments and automatically reference the method description for
- a lookup. The generated function looks up the method by using
- the unique id associated with the method description as a hash
- into the cache associated with the object's class. If the method
- is not cached the generated function proceeds to use the class'
- table to find the method. If the method is found then the
- associated function within the class is used; otherwise, the
- default function associated with the method description is
- used.</para>
-
- <para>These indirections can be visualized as the
- following:</para>
-
- <programlisting>object->cache<->class</programlisting>
-
- </sect1>
-
- <sect1>
- <title>Using Kobj</title>
-
- <sect2>
- <title>Structures</title>
-
- <programlisting>struct kobj_method</programlisting>
- </sect2>
-
- <sect2>
- <title>Functions</title>
-
- <programlisting>void kobj_class_compile(kobj_class_t cls);
-void kobj_class_compile_static(kobj_class_t cls, kobj_ops_t ops);
-void kobj_class_free(kobj_class_t cls);
-kobj_t kobj_create(kobj_class_t cls, struct malloc_type *mtype, int mflags);
-void kobj_init(kobj_t obj, kobj_class_t cls);
-void kobj_delete(kobj_t obj, struct malloc_type *mtype);</programlisting>
- </sect2>
-
- <sect2>
- <title>Macros</title>
-
- <programlisting>KOBJ_CLASS_FIELDS
-KOBJ_FIELDS
-DEFINE_CLASS(name, methods, size)
-KOBJMETHOD(NAME, FUNC)</programlisting>
- </sect2>
-
- <sect2>
- <title>Headers</title>
-
- <programlisting>&lt;sys/param.h>
-&lt;sys/kobj.h></programlisting>
- </sect2>
-
- <sect2>
- <title>Creating an interface template</title>
-
- <para>The first step in using Kobj is to create an
- Interface. Creating the interface involves creating a template
- that the script
- <filename>src/sys/kern/makeobjops.pl</filename> can use to
- generate the header and code for the method declarations and
- method lookup functions.</para>
-
- <para>Within this template the following keywords are used:
- <literal>#include</literal>, <literal>INTERFACE</literal>,
- <literal>CODE</literal>, <literal>METHOD</literal>,
- <literal>STATICMETHOD</literal>, and
- <literal>DEFAULT</literal>.</para>
-
- <para>The <literal>#include</literal> statement and what follows
- it is copied verbatim to the head of the generated code
- file.</para>
-
- <para>For example:</para>
-
- <programlisting>#include &lt;sys/foo.h></programlisting>
-
- <para>The <literal>INTERFACE</literal> keyword is used to define
- the interface name. This name is concatenated with each method
- name as [interface name]_[method name]. Its syntax is
- INTERFACE [interface name];.</para>
-
- <para>For example:</para>
-
- <programlisting>INTERFACE foo;</programlisting>
-
- <para>The <literal>CODE</literal> keyword copies its arguments
- verbatim into the code file. Its syntax is
- <literal>CODE { [whatever] };</literal></para>
-
- <para>For example:</para>
-
- <programlisting>CODE {
- struct foo * foo_alloc_null(struct bar *)
- {
- return NULL;
-}
-};</programlisting>
-
- <para>The <literal>METHOD</literal> keyword describes a method. Its syntax is
- <literal>METHOD [return type] [method name] { [object [,
- arguments]] };</literal></para>
-
- <para>For example:</para>
-
- <programlisting>METHOD int bar {
- struct object *;
- struct foo *;
- struct bar;
-};</programlisting>
-
- <para>The <literal>DEFAULT</literal> keyword may follow the
- <literal>METHOD</literal> keyword. It extends the
- <literal>METHOD</literal> key word to include the default
- function for method. The extended syntax is
- <literal>METHOD [return type] [method name] {
- [object; [other arguments]] }DEFAULT [default
- function];</literal></para>
-
- <para>For example:</para>
-
- <programlisting>METHOD int bar {
- struct object *;
- struct foo *;
- int bar;
-} DEFAULT foo_hack;</programlisting>
-
- <para>The <literal>STATICMETHOD</literal> keyword is used like
- the <literal>METHOD</literal> keyword except the kobj data is not
- at the head of the object structure so casting to kobj_t would
- be incorrect. Instead <literal>STATICMETHOD</literal> relies on the Kobj data being
- referenced as 'ops'. This is also useful for calling
- methods directly out of a class's method table.</para>
-
- <para>Other complete examples:</para>
-
- <programlisting>src/sys/kern/bus_if.m
-src/sys/kern/device_if.m</programlisting>
-
- </sect2>
-
- <sect2>
- <title>Creating a Class</title>
-
- <para>The second step in using Kobj is to create a class. A
- class consists of a name, a table of methods, and the size of
- objects if Kobj's object handling facilities are used. To
- create the class use the macro
- <function>DEFINE_CLASS()</function>. To create the method
- table create an array of kobj_method_t terminated by a NULL
- entry. Each non-NULL entry may be created using the macro
- <function>KOBJMETHOD()</function>.</para>
-
- <para>For example:</para>
-
- <programlisting>DEFINE_CLASS(fooclass, foomethods, sizeof(struct foodata));
-
-kobj_method_t foomethods[] = {
- KOBJMETHOD(bar_doo, foo_doo),
- KOBJMETHOD(bar_foo, foo_foo),
- { NULL, NULL}
-};</programlisting>
-
- <para>The class must be <quote>compiled</quote>. Depending on
- the state of the system at the time that the class is to be
- initialized a statically allocated cache, <quote>ops
- table</quote> have to be used. This can be accomplished by
- declaring a <structname>struct kobj_ops</structname> and using
- <function>kobj_class_compile_static();</function> otherwise,
- <function>kobj_class_compile()</function> should be used.</para>
- </sect2>
-
- <sect2>
- <title>Creating an Object</title>
-
- <para>The third step in using Kobj involves how to define the
- object. Kobj object creation routines assume that Kobj data is
- at the head of an object. If this in not appropriate you will
- have to allocate the object yourself and then use
- <function>kobj_init()</function> on the Kobj portion of it;
- otherwise, you may use <function>kobj_create()</function> to
- allocate and initialize the Kobj portion of the object
- automatically. <function>kobj_init()</function> may also be
- used to change the class that an object uses.</para>
-
- <para>To integrate Kobj into the object you should use the macro
- KOBJ_FIELDS.</para>
-
- <para>For example</para>
-
- <programlisting>struct foo_data {
- KOBJ_FIELDS;
- foo_foo;
- foo_bar;
-};</programlisting>
- </sect2>
-
- <sect2>
- <title>Calling Methods</title>
-
- <para>The last step in using Kobj is to simply use the generated
- functions to use the desired method within the object's
- class. This is as simple as using the interface name and the
- method name with a few modifications. The interface name
- should be concatenated with the method name using a '_'
- between them, all in upper case.</para>
-
- <para>For example, if the interface name was foo and the method
- was bar then the call would be:</para>
-
- <programlisting>[return value = ] FOO_BAR(object [, other parameters]);</programlisting>
-
- </sect2>
-
- <sect2>
- <title>Cleaning Up</title>
-
- <para>When an object allocated through
- <function>kobj_create()</function> is no longer needed
- <function>kobj_delete()</function> may be called on it, and
- when a class is no longer being used
- <function>kobj_class_free()</function> may be called on it.</para>
- </sect2>
- </sect1>
-</chapter>
-
-<!--
- Local Variables:
- mode: sgml
- sgml-declaration: "../chapter.decl"
- sgml-indent-data: t
- sgml-omittag: nil
- sgml-always-quote-attributes: t
- sgml-parent-document: ("../book.sgml" "part" "chapter")
- End:
--->
diff --git a/en_US.ISO8859-1/books/arch-handbook/locking/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/locking/chapter.sgml
deleted file mode 100644
index 00501a8d2f..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/locking/chapter.sgml
+++ /dev/null
@@ -1,333 +0,0 @@
-<!--
- The FreeBSD Documentation Project
- The FreeBSD SMP Next Generation Project
-
- $FreeBSD$
--->
-
-<chapter id="locking">
- <title>Locking Notes</title>
-
- <para><emphasis>This chapter is maintained by the FreeBSD SMP Next
- Generation Project. Please direct any comments or suggestions
- to its &a.smp;.</emphasis></para>
-
-
- <para>This document outlines the locking used in the FreeBSD kernel
- to permit effective multi-processing within the kernel. Locking
- can be achieved via several means. Data structures can be
- protected by mutexes or &man.lockmgr.9; locks. A few variables
- are protected simply by always using atomic operations to access
- them.</para>
-
- <sect1>
- <title>Mutexes</title>
-
- <para>A mutex is simply a lock used to guarantee mutual exclusion.
- Specifically, a mutex may only be owned by one entity at a time.
- If another entity wishes to obtain a mutex that is already
- owned, it must wait until the mutex is released. In the FreeBSD
- kernel, mutexes are owned by processes.</para>
-
- <para>Mutexes may be recursively acquired, but they are intended
- to be held for a short period of time. Specifically, one may
- not sleep while holding a mutex. If you need to hold a lock
- across a sleep, use a &man.lockmgr.9; lock.</para>
-
- <para>Each mutex has several properties of interest:</para>
-
- <variablelist>
- <varlistentry>
- <term>Variable Name</term>
- <listitem>
- <para>The name of the <type>struct mtx</type> variable in
- the kernel source.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Logical Name</term>
- <listitem>
- <para>The name of the mutex assigned to it by
- <function>mtx_init</function>. This name is displayed in
- KTR trace messages and witness errors and warnings and is
- used to distinguish mutexes in the witness code.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Type</term>
- <listitem>
- <para>The type of the mutex in terms of the
- <constant>MTX_*</constant> flags. The meaning for each
- flag is related to its meaning as documented in
- &man.mutex.9;.</para>
-
- <variablelist>
- <varlistentry>
- <term><constant>MTX_DEF</constant></term>
- <listitem>
- <para>A sleep mutex</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><constant>MTX_SPIN</constant></term>
- <listitem>
- <para>A spin mutex</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><constant>MTX_COLD</constant></term>
- <listitem>
- <para>This mutex is initialized very early. Thus, it
- must be declared via
- <function>MUTEX_DECLARE</function>, and the
- <constant>MTX_COLD</constant> flag must be passed to
- <function>mtx_init</function>.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><constant>MTX_TOPHALF</constant></term>
- <listitem>
- <para>This spin mutex does not disable
- interrupts.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><constant>MTX_NORECURSE</constant></term>
- <listitem>
- <para>This mutex is not allowed to recurse.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Protectees</term>
- <listitem>
- <para>A list of data structures or data structure members
- that this entry protects. For data structure members, the
- name will be in the form of
- <structname/structure name/.<structfield/member name/.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>Dependent Functions</term>
- <listitem>
- <para>Functions that can only be called if this mutex is
- held.</para>
- </listitem>
- </varlistentry>
- </variablelist>
-
- <table frame="all" colsep="1" rowsep="1" pgwide="1">
- <title>Mutex List</title>
-
- <tgroup cols="5">
- <thead>
- <row>
- <entry>Variable Name</entry>
- <entry>Logical Name</entry>
- <entry>Type</entry>
- <entry>Protectees</entry>
- <entry>Dependent Functions</entry>
- </row>
- </thead>
-
- <!-- The scheduler lock -->
- <tbody>
- <row>
- <entry>sched_lock</entry>
- <entry><quote>sched lock</quote></entry>
- <entry>
- <constant>MTX_SPIN</constant> |
- <constant>MTX_COLD</constant>
- </entry>
- <entry>
- <varname>_gmonparam</varname>,
- <varname>cnt.v_swtch</varname>,
- <varname>cp_time</varname>,
- <varname>curpriority</varname>,
- <structname/mtx/.<structfield/mtx_blocked/,
- <structname/mtx/.<structfield/mtx_contested/,
- <structname/proc/.<structfield/p_contested/,
- <structname/proc/.<structfield/p_blocked/,
- <structname/proc/.<structfield/p_flag/
- (<constant>P_PROFIL</constant> XXX,
- <constant>P_INMEM</constant>,
- <constant>P_SINTR</constant>,
- <constant>P_TIMEOUT</constant>,
- <constant>P_SWAPINREQ</constant> XXX,
- <constant>P_INMEN</constant> XXX),
- <structname/proc/.<structfield/p_nice/,
- <structname/proc/.<structfield/p_procq/,
- <structname/proc/.<structfield/p_blocked/,
- <structname/proc/.<structfield/p_estcpu/,
- <structname/proc/.<structfield/p_nativepri/,
- <structname/proc/.<structfield/p_priority/,
- <structname/proc/.<structfield/p_usrpri/,
- <structname/proc/.<structfield/p_rtprio/,
- <structname/proc/.<structfield/p_rqindex/,
- <structname/proc/.<structfield/p_stats->p_prof/,
- <structname/proc/.<structfield/p_stats->p_ru/,
- <structname/proc/.<structfield/p_stat/,
- <structname/proc/.<structfield/p_cpticks/
- <structname/proc/.<structfield/p_iticks/,
- <structname/proc/.<structfield/p_uticks/,
- <structname/proc/.<structfield/p_sticks/,
- <structname/proc/.<structfield/p_swtime/,
- <structname/proc/.<structfield/p_slptime/,
- <structname/proc/.<structfield/p_runtime/,
- <structname/proc/.<structfield/p_pctcpu/,
- <structname/proc/.<structfield/p_oncpu/,
- <structname/proc/.<structfield/p_asleep/,
- <structname/proc/.<structfield/p_wchan/,
- <structname/proc/.<structfield/p_wmesg/,
- <structname/proc/.<structfield/p_slpq/,
- <structname/proc/.<structfield/p_vmspace/
- (XXX - in <function>statclock</function>),
- <varname>pscnt</varname>,
- <varname>slpque</varname>,
- <varname>itqueuebits</varname>,
- <varname>itqueues</varname>,
- <varname>rtqueuebits</varname>,
- <varname>rtqueues</varname>,
- <varname>queuebits</varname>,
- <varname>queues</varname>,
- <varname>idqueuebits</varname>,
- <varname>idqueues</varname>,
- <varname>switchtime</varname>,
- </entry>
- <entry>
- <function>setrunqueue</function>,
- <function>remrunqueue</function>,
- <function>mi_switch</function>,
- <function>chooseproc</function>,
- <function>schedclock</function>,
- <function>resetpriority</function>,
- <function>updatepri</function>,
- <function>maybe_resched</function>,
- <function>cpu_switch</function>,
- <function>cpu_throw</function>
- </entry>
- </row>
-
- <!-- The vm86 pcb lock -->
- <row>
- <entry>vm86pcb_lock</entry>
- <entry><quote>vm86pcb lock</quote></entry>
- <entry>
- <constant>MTX_DEF</constant> |
- <constant>MTX_COLD</constant>
- </entry>
- <entry>
- <varname>vm86pcb</varname>
- </entry>
- <entry>
- <function>vm86_bioscall</function>
- </entry>
- </row>
-
- <!-- Giant -->
- <row>
- <entry>Giant</entry>
- <entry><quote>Giant</quote></entry>
- <entry>
- <constant>MTX_DEF</constant> |
- <constant>MTX_COLD</constant>
- </entry>
- <entry>nearly everything</entry>
- <entry>lots</entry>
- </row>
-
- <!-- The callout lock -->
- <row>
- <entry>callout_lock</entry>
- <entry><quote>callout lock</quote></entry>
- <entry>
- <constant>MTX_SPIN</constant>
- </entry>
- <entry>
- <varname>callfree</varname>,
- <varname>callwheel</varname>,
- <varname>nextsoftcheck</varname>,
- <structname/proc/.<structfield/p_itcallout/,
- <structname/proc/.<structfield/p_slpcallout/,
- <varname>softticks</varname>,
- <varname>ticks</varname>
- </entry>
- <entry>
- </entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </sect1>
-
- <sect1>
- <title>Lock Manager Locks</title>
-
- <para>Locks that are provided via the &man.lockmgr.9; interface
- are lock manager locks. These locks are reader-writer locks and
- may be held by a sleeping process.</para>
-
- <table>
- <title>&man.lockmgr.9; Lock List</title>
-
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Variable Name</entry>
- <entry>Protectees</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry><varname>allproc_lock</varname></entry>
- <entry>
- <varname>allproc</varname>
- <varname>zombproc</varname>
- <varname>pidhashtbl</varname>
- <structname/proc/.<structfield/p_list/
- <structname/proc/.<structfield/p_hash/
- <varname>nextpid</varname>
- </entry>
- <entry><varname>proctree_lock</varname></entry>
- <entry>
- <structname/proc/.<structfield/p_children/
- <structname/proc/.<structfield/p_sibling/
- </entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </sect1>
-
- <sect1>
- <title>Atomically Protected Variables</title>
-
- <para>An atomically protected variable is a special variable that
- is not protected by an explicit lock. Instead, all data
- accesses to the variables use special atomic operations as
- described in &man.atomic.9;. Very few variables are treated
- this way, although other synchronization primitives such as
- mutexes are implemented with atomically protected
- variables.</para>
-
- <itemizedlist>
- <listitem>
- <para><varname>astpending</varname></para>
- </listitem>
-
- <listitem>
- <para><structname/mtx/.<structfield/mtx_lock/</para>
- </listitem>
- </itemizedlist>
- </sect1>
-</chapter>
diff --git a/en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml
deleted file mode 100644
index 15146dc9e9..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml
+++ /dev/null
@@ -1,369 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="pci">
- <title>PCI Devices</title>
-
- <para>This chapter will talk about the FreeBSD mechanisms for
- writing a device driver for a device on a PCI bus.</para>
-
- <sect1>
- <title>Probe and Attach</title>
-
- <para>Information here about how the PCI bus code iterates through
- the unattached devices and see if a newly loaded kld will attach
- to any of them.</para>
-
-<programlisting>/*
- * Simple KLD to play with the PCI functions.
- *
- * Murray Stokely
- */
-
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-
-#include &lt;sys/types.h&gt;
-#include &lt;sys/module.h&gt;
-#include &lt;sys/systm.h&gt; /* uprintf */
-#include &lt;sys/errno.h&gt;
-#include &lt;sys/param.h&gt; /* defines used in kernel.h */
-#include &lt;sys/kernel.h&gt; /* types used in module initialization */
-#include &lt;sys/conf.h&gt; /* cdevsw struct */
-#include &lt;sys/uio.h&gt; /* uio struct */
-#include &lt;sys/malloc.h&gt;
-#include &lt;sys/bus.h&gt; /* structs, prototypes for pci bus stuff */
-
-#include &lt;pci/pcivar.h&gt; /* For get_pci macros! */
-
-/* Function prototypes */
-d_open_t mypci_open;
-d_close_t mypci_close;
-d_read_t mypci_read;
-d_write_t mypci_write;
-
-/* Character device entry points */
-
-static struct cdevsw mypci_cdevsw = {
- mypci_open,
- mypci_close,
- mypci_read,
- mypci_write,
- noioctl,
- nopoll,
- nommap,
- nostrategy,
- "mypci",
- 36, /* reserved for lkms - /usr/src/sys/conf/majors */
- nodump,
- nopsize,
- D_TTY,
- -1
-};
-
-/* vars */
-static dev_t sdev;
-
-/* We're more interested in probe/attach than with
- open/close/read/write at this point */
-
-int
-mypci_open(dev_t dev, int oflags, int devtype, struct proc *p)
-{
- int err = 0;
-
- uprintf("Opened device \"mypci\" successfully.\n");
- return(err);
-}
-
-int
-mypci_close(dev_t dev, int fflag, int devtype, struct proc *p)
-{
- int err=0;
-
- uprintf("Closing device \"mypci.\"\n");
- return(err);
-}
-
-int
-mypci_read(dev_t dev, struct uio *uio, int ioflag)
-{
- int err = 0;
-
- uprintf("mypci read!\n");
- return err;
-}
-
-int
-mypci_write(dev_t dev, struct uio *uio, int ioflag)
-{
- int err = 0;
-
- uprintf("mypci write!\n");
- return(err);
-}
-
-/* PCI Support Functions */
-
-/*
- * Return identification string if this is device is ours.
- */
-static int
-mypci_probe(device_t dev)
-{
- uprintf("MyPCI Probe\n"
- "Vendor ID : 0x%x\n"
- "Device ID : 0x%x\n",pci_get_vendor(dev),pci_get_device(dev));
-
- if (pci_get_vendor(dev) == 0x11c1) {
- uprintf("We've got the Winmodem, probe successful!\n");
- return 0;
- }
-
- return ENXIO;
-}
-
-/* Attach function is only called if the probe is successful */
-
-static int
-mypci_attach(device_t dev)
-{
- uprintf("MyPCI Attach for : deviceID : 0x%x\n",pci_get_vendor(dev));
- sdev = make_dev(<literal>&</literal>mypci_cdevsw,
- 0,
- UID_ROOT,
- GID_WHEEL,
- 0600,
- "mypci");
- uprintf("Mypci device loaded.\n");
- return ENXIO;
-}
-
-/* Detach device. */
-
-static int
-mypci_detach(device_t dev)
-{
- uprintf("Mypci detach!\n");
- return 0;
-}
-
-/* Called during system shutdown after sync. */
-
-static int
-mypci_shutdown(device_t dev)
-{
- uprintf("Mypci shutdown!\n");
- return 0;
-}
-
-/*
- * Device suspend routine.
- */
-static int
-mypci_suspend(device_t dev)
-{
- uprintf("Mypci suspend!\n");
- return 0;
-}
-
-/*
- * Device resume routine.
- */
-
-static int
-mypci_resume(device_t dev)
-{
- uprintf("Mypci resume!\n");
- return 0;
-}
-
-static device_method_t mypci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, mypci_probe),
- DEVMETHOD(device_attach, mypci_attach),
- DEVMETHOD(device_detach, mypci_detach),
- DEVMETHOD(device_shutdown, mypci_shutdown),
- DEVMETHOD(device_suspend, mypci_suspend),
- DEVMETHOD(device_resume, mypci_resume),
-
- { 0, 0 }
-};
-
-static driver_t mypci_driver = {
- "mypci",
- mypci_methods,
- 0,
- /* sizeof(struct mypci_softc), */
-};
-
-static devclass_t mypci_devclass;
-
-DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);</programlisting>
-
- <para>Additional Resources
- <itemizedlist>
- <listitem><simpara><ulink url="http://www.pcisig.org/">PCI
- Special Interest Group</ulink></simpara></listitem>
-
- <listitem><simpara>PCI System Architecture, Fourth Edition by
- Tom Shanley, et al.</simpara></listitem>
-
- </itemizedlist>
- </para>
- </sect1>
-
- <sect1>
- <title>Bus Resources</title>
-
- <para>FreeBSD provides an object-oriented mechanism for requesting
- 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
- devices need to acquire resources from their parent bus (such as
- memory segments, interrupt lines, or DMA channels).</para>
-
- <sect2>
- <title>Base Address Registers</title>
-
- <para>To do anything particularly useful with a PCI device you
- will need to obtain the <emphasis>Base Address
- Registers</emphasis> (BARs) from the PCI Configuration space.
- The PCI-specific details of obtaining the BAR is abstracted in
- the <function>bus_alloc_resource()</function> function.</para>
-
- <para>For example, a typical driver might have something similar
- to this in the <function>attach()</function> function:</para>
-
-<programlisting> sc->bar0id = 0x10;
- sc->bar0res = bus_alloc_resource(dev, SYS_RES_MEMORY, &amp;(sc->bar0id),
- 0, ~0, 1, RF_ACTIVE);
- if (sc->bar0res == NULL) {
- uprintf("Memory allocation of PCI base register 0 failed!\n");
- error = ENXIO;
- goto fail1;
- }
-
- sc->bar1id = 0x14;
- sc->bar1res = bus_alloc_resource(dev, SYS_RES_MEMORY, &amp;(sc->bar1id),
- 0, ~0, 1, RF_ACTIVE);
- if (sc->bar1res == NULL) {
- uprintf("Memory allocation of PCI base register 1 failed!\n");
- error = ENXIO;
- goto fail2;
- }
- sc->bar0_bt = rman_get_bustag(sc->bar0res);
- sc->bar0_bh = rman_get_bushandle(sc->bar0res);
- sc->bar1_bt = rman_get_bustag(sc->bar1res);
- sc->bar1_bh = rman_get_bushandle(sc->bar1res);
-
-</programlisting>
-
- <para>Handles for each base address register are kept in the
- <structname>softc</structname> structure so that they can be
- used to write to the device later.</para>
-
- <para>These handles can then be used to read or write from the
- device registers with the <function>bus_space_*</function>
- functions. For example, a driver might contain a shorthand
- function to read from a board specific register like this:</para>
-
-<programlisting>uint16_t
-board_read(struct ni_softc *sc, uint16_t address) {
- return bus_space_read_2(sc->bar1_bt, sc->bar1_bh, address);
-}
-</programlisting>
-
- <para>Similarly, one could write to the registers with:</para>
-
-<programlisting>void
-board_write(struct ni_softc *sc, uint16_t address, uint16_t value) {
- bus_space_write_2(sc->bar1_bt, sc->bar1_bh, address, value);
-}
-</programlisting>
-
- <para>These functions exist in 8bit, 16bit, and 32bit versions
- and you should use
- <function>bus_space_{read|write}_{1|2|4}</function>
- accordingly.</para>
-
- </sect2>
- <sect2>
- <title>Interrupts</title>
-
- <para>Interrupts are allocated from the object-oriented bus code
- in a way similar to the memory resources. First an IRQ
- resource must be allocated from the parent bus, and then the
- interrupt handler must be setup to deal with this IRQ.</para>
-
- <para>Again, a sample from a device
- <function>attach()</function> function says more than
- words.</para>
-
-<programlisting>/* Get the IRQ resource */
-
- sc->irqid = 0x0;
- sc->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &amp;(sc->irqid),
- 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
- if (sc->irqres == NULL) {
- uprintf("IRQ allocation failed!\n");
- error = ENXIO;
- goto fail3;
- }
-
- /* Now we should setup the interrupt handler */
-
- error = bus_setup_intr(dev, sc->irqres, INTR_TYPE_MISC,
- my_handler, sc, &amp;(sc->handler));
- if (error) {
- printf("Couldn't set up irq\n");
- goto fail4;
- }
-
- sc->irq_bt = rman_get_bustag(sc->irqres);
- sc->irq_bh = rman_get_bushandle(sc->irqres);
-</programlisting>
-
- </sect2>
-
- <sect2>
- <title>DMA</title>
- <para>On the PC, peripherals that want to do bus-mastering DMA
- must deal with physical addresses. This is a problem since
- FreeBSD uses virtual memory and deals almost exclusively with
- virtual addresses. Fortunately, there is a function,
- <function>vtophys()</function> to help.</para>
-
-<programlisting>#include &lt;vm/vm.h&gt;
-#include &lt;vm/pmap.h&gt;
-
-#define vtophys(virtual_address) (...)
-</programlisting>
-
- <para>The solution is a bit different on the alpha however, and
- what we really want is a function called
- <function>vtobus()</function>.</para>
-
-<programlisting>#if defined(__alpha__)
-#define vtobus(va) alpha_XXX_dmamap((vm_offset_t)va)
-#else
-#define vtobus(va) vtophys(va)
-#endif
-</programlisting>
-
- </sect2>
-
- <sect2>
- <title>Deallocating Resources</title>
-
- <para>It is very important to deallocate all of the resources
- that were allocated during <function>attach()</function>.
- Care must be taken to deallocate the correct stuff even on a
- failure condition so that the system will remain usable while
- your driver dies.</para>
-
- </sect2>
- </sect1>
-
-</chapter>
diff --git a/en_US.ISO8859-1/books/arch-handbook/scsi/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/scsi/chapter.sgml
deleted file mode 100644
index fa00f66106..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/scsi/chapter.sgml
+++ /dev/null
@@ -1,1983 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="scsi">
- <title>Common Access Method SCSI Controllers</title>
-
- <para><emphasis>This chapter was written by &a.babkin;
- Modifications for the handbook made by
- &a.murray;.</emphasis></para>
-
- <sect1>
- <title>Synopsis</title>
-
- <para>This document assumes that the reader has a general
- understanding of device drivers in FreeBSD and of the SCSI
- protocol. Much of the information in this document was
- extracted from the drivers:</para>
-
- <itemizedlist>
-
- <listitem><para>ncr (<filename>/sys/pci/ncr.c</filename>) by
- Wolfgang Stanglmeier and Stefan Esser</para></listitem>
-
- <listitem><para>sym (<filename>/sys/pci/sym.c</filename>) by
- Gerard Roudier</para></listitem>
-
- <listitem><para>aic7xxx
- (<filename>/sys/dev/aic7xxx/aic7xxx.c</filename>) by Justin
- T. Gibbs</para></listitem>
-
- </itemizedlist>
-
- <para>and from the CAM code itself (by Justing T. Gibbs, see
- <filename>/sys/cam/*</filename>). When some solution looked the
- most logical and was essentially verbatim extracted from the code
- by Justin Gibbs, I marked it as <quote>recommended</quote>.</para>
-
- <para>The document is illustrated with examples in
- pseudo-code. Although sometimes the examples have many details
- and look like real code, it is still pseudo-code. It was written
- to demonstrate the concepts in an understandable way. For a real
- driver other approaches may be more modular and efficient. It
- also abstracts from the hardware details, as well as issues that
- would cloud the demonstrated concepts or that are supposed to be
- described in the other chapters of the developers handbook. Such
- details are commonly shown as calls to functions with descriptive
- names, comments or pseudo-statements. Fortunately real life
- full-size examples with all the details can be found in the real
- drivers.</para>
-
- </sect1>
-
- <sect1>
- <title>General architecture</title>
-
- <para>CAM stands for Common Access Method. It is a generic way to
- address the I/O buses in a SCSI-like way. This allows a
- separation of the generic device drivers from the drivers
- controlling the I/O bus: for example the disk driver becomes able
- to control disks on both SCSI, IDE, and/or any other bus so the
- disk driver portion does not have to be rewritten (or copied and
- modified) for every new I/O bus. Thus the two most important
- active entities are:</para>
-
- <itemizedlist>
- <listitem><para><emphasis>Peripheral Modules</emphasis> - a
- driver for peripheral devices (disk, tape, CDROM,
- etc.)</para></listitem>
- <listitem><para><emphasis>SCSI Interface Modules </emphasis>(SIM)
- - a Host Bus Adapter drivers for connecting to an I/O bus such
- as SCSI or IDE.</para></listitem>
- </itemizedlist>
-
- <para>A peripheral driver receives requests from the OS, converts
- them to a sequence of SCSI commands and passes these SCSI
- commands to a SCSI Interface Module. The SCSI Interface Module
- is responsible for passing these commands to the actual hardware
- (or if the actual hardware is not SCSI but, for example, IDE
- then also converting the SCSI commands to the native commands of
- the hardware).</para>
-
- <para>Because we are interested in writing a SCSI adapter driver
- here, from this point on we will consider everything from the
- SIM standpoint.</para>
-
- <para>A typical SIM driver needs to include the following
- CAM-related header files:</para>
-
-<programlisting>#include &lt;cam/cam.h&gt;
-#include &lt;cam/cam_ccb.h&gt;
-#include &lt;cam/cam_sim.h&gt;
-#include &lt;cam/cam_xpt_sim.h&gt;
-#include &lt;cam/cam_debug.h&gt;
-#include &lt;cam/scsi/scsi_all.h&gt;</programlisting>
-
- <para>The first thing each SIM driver must do is register itself
- with the CAM subsystem. This is done during the driver's
- <function>xxx_attach()</function> function (here and further
- xxx_ is used to denote the unique driver name prefix). The
- <function>xxx_attach()</function> function itself is called by
- the system bus auto-configuration code which we do not describe
- here.</para>
-
- <para>This is achieved in multiple steps: first it is necessary to
- allocate the queue of requests associated with this SIM:</para>
-
-<programlisting> struct cam_devq *devq;
-
- if(( devq = cam_simq_alloc(SIZE) )==NULL) {
- error; /* some code to handle the error */
- }</programlisting>
-
- <para>Here SIZE is the size of the queue to be allocated, maximal
- number of requests it could contain. It is the number of requests
- that the SIM driver can handle in parallel on one SCSI
- card. Commonly it can be calculated as:</para>
-
-<programlisting>SIZE = NUMBER_OF_SUPPORTED_TARGETS * MAX_SIMULTANEOUS_COMMANDS_PER_TARGET</programlisting>
-
- <para>Next we create a descriptor of our SIM:</para>
-
-<programlisting> struct cam_sim *sim;
-
- if(( sim = cam_sim_alloc(action_func, poll_func, driver_name,
- softc, unit, max_dev_transactions,
- max_tagged_dev_transactions, devq) )==NULL) {
- cam_simq_free(devq);
- error; /* some code to handle the error */
- }</programlisting>
-
- <para>Note that if we are not able to create a SIM descriptor we
- free the <structname>devq</structname> also because we can do
- nothing else with it and we want to conserve memory.</para>
-
- <para>If a SCSI card has multiple SCSI buses on it then each bus
- requires its own <structname>cam_sim</structname>
- structure.</para>
-
- <para>An interesting question is what to do if a SCSI card has
- more than one SCSI bus, do we need one
- <structname>devq</structname> structure per card or per SCSI
- bus? The answer given in the comments to the CAM code is:
- either way, as the driver's author prefers.</para>
-
- <para>The arguments are:
- <itemizedlist>
-
- <listitem><para><function>action_func</function> - pointer to
- the driver's <function>xxx_action</function> function.
- <funcSynopsis><funcPrototype>
- <funcDef>static void
- <function>xxx_action</function>
- </funcDef>
- <paramdef>
- <parameter>struct cam_sim *sim</parameter>,
- <parameter>union ccb *ccb</parameter>
- </paramdef>
- </funcPrototype></funcSynopsis>
- </para></listitem>
-
- <listitem><para><function>poll_func</function> - pointer to
- the driver's <function>xxx_poll()</function>
- <funcSynopsis><funcPrototype>
- <funcDef>static void
- <function>xxx_poll</function>
- </funcDef>
- <paramdef>
- <parameter>struct cam_sim *sim</parameter>
- </paramdef>
- </funcPrototype></funcSynopsis>
- </para></listitem>
-
- <listitem><para>driver_name - the name of the actual driver,
- such as <quote>ncr</quote> or <quote>wds</quote>.</para></listitem>
-
- <listitem><para><structName>softc</structName> - pointer to the
- driver's internal descriptor for this SCSI card. This
- pointer will be used by the driver in future to get private
- data.</para></listitem>
-
- <listitem><para>unit - the controller unit number, for example
- for controller <quote>wds0</quote> this number will be
- 0</para></listitem>
-
- <listitem><para>max_dev_transactions - maximal number of
- simultaneous transactions per SCSI target in the non-tagged
- mode. This value will be almost universally equal to 1, with
- possible exceptions only for the non-SCSI cards. Also the
- drivers that hope to take advantage by preparing one
- transaction while another one is executed may set it to 2
- but this does not seem to be worth the
- complexity.</para></listitem>
-
- <listitem><para>max_tagged_dev_transactions - the same thing,
- but in the tagged mode. Tags are the SCSI way to initiate
- multiple transactions on a device: each transaction is
- assigned a unique tag and the transaction is sent to the
- device. When the device completes some transaction it sends
- back the result together with the tag so that the SCSI
- adapter (and the driver) can tell which transaction was
- completed. This argument is also known as the maximal tag
- depth. It depends on the abilities of the SCSI
- adapter.</para></listitem>
- </itemizedlist>
- </para>
-
- <para>Finally we register the SCSI buses associated with our SCSI
- adapter:</para>
-
-<programlisting> if(xpt_bus_register(sim, bus_number) != CAM_SUCCESS) {
- cam_sim_free(sim, /*free_devq*/ TRUE);
- error; /* some code to handle the error */
- }</programlisting>
-
- <para>If there is one <structName>devq</structName> structure per
- SCSI bus (i.e. we consider a card with multiple buses as
- multiple cards with one bus each) then the bus number will
- always be 0, otherwise each bus on the SCSI card should be get a
- distinct number. Each bus needs its own separate structure
- cam_sim.</para>
-
- <para>After that our controller is completely hooked to the CAM
- system. The value of <structName>devq</structName> can be
- discarded now: sim will be passed as an argument in all further
- calls from CAM and devq can be derived from it.</para>
-
- <para>CAM provides the framework for such asynchronous
- events. Some events originate from the lower levels (the SIM
- drivers), some events originate from the peripheral drivers,
- some events originate from the CAM subsystem itself. Any driver
- can register callbacks for some types of the asynchronous
- events, so that it would be notified if these events
- occur.</para>
-
- <para>A typical example of such an event is a device reset. Each
- transaction and event identifies the devices to which it applies
- by the means of <quote>path</quote>. The target-specific events normally
- occur during a transaction with this device. So the path from
- that transaction may be re-used to report this event (this is
- safe because the event path is copied in the event reporting
- routine but not deallocated nor passed anywhere further). Also
- it is safe to allocate paths dynamically at any time including
- the interrupt routines, although that incurs certain overhead,
- and a possible problem with this approach is that there may be
- no free memory at that time. For a bus reset event we need to
- define a wildcard path including all devices on the bus. So we
- can create the path for the future bus reset events in advance
- and avoid problems with the future memory shortage:</para>
-
-<programlisting> struct cam_path *path;
-
- if(xpt_create_path(&amp;path, /*periph*/NULL,
- cam_sim_path(sim), CAM_TARGET_WILDCARD,
- CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
- xpt_bus_deregister(cam_sim_path(sim));
- cam_sim_free(sim, /*free_devq*/TRUE);
- error; /* some code to handle the error */
- }
-
- softc->wpath = path;
- softc->sim = sim;</programlisting>
-
- <para>As you can see the path includes:</para>
-
- <itemizedlist>
- <listitem><para>ID of the peripheral driver (NULL here because we have
- none)</para></listitem>
-
- <listitem><para>ID of the SIM driver
- (<function>cam_sim_path(sim)</function>)</para></listitem>
-
- <listitem><para>SCSI target number of the device (CAM_TARGET_WILDCARD
- means <quote>all devices</quote>)</para></listitem>
-
- <listitem><para>SCSI LUN number of the subdevice (CAM_LUN_WILDCARD means
- <quote>all LUNs</quote>)</para></listitem>
- </itemizedlist>
-
- <para>If the driver can not allocate this path it will not be able to
- work normally, so in that case we dismantle that SCSI
- bus.</para>
-
- <para>And we save the path pointer in the
- <structName>softc</structName> structure for future use. After
- that we save the value of sim (or we can also discard it on the
- exit from <function>xxx_probe()</function> if we wish).</para>
-
- <para>That is all for a minimalistic initialization. To do things
- right there is one more issue left. </para>
-
- <para>For a SIM driver there is one particularly interesting
- event: when a target device is considered lost. In this case
- resetting the SCSI negotiations with this device may be a good
- idea. So we register a callback for this event with CAM. The
- request is passed to CAM by requesting CAM action on a CAM
- control block for this type of request:</para>
-
-<programlisting> struct ccb_setasync csa;
-
- xpt_setup_ccb(&amp;csa.ccb_h, path, /*priority*/5);
- csa.ccb_h.func_code = XPT_SASYNC_CB;
- csa.event_enable = AC_LOST_DEVICE;
- csa.callback = xxx_async;
- csa.callback_arg = sim;
- xpt_action((union ccb *)&amp;csa);</programlisting>
-
- <para>Now we take a look at the <function>xxx_action()</function>
- and <function>xxx_poll()</function> driver entry points.</para>
-
- <para>
- <funcSynopsis><funcPrototype>
- <funcDef>static void
- <function>xxx_action</function>
- </funcDef>
- <paramdef>
- <parameter>struct cam_sim *sim</parameter>,
- <parameter>union ccb *ccb</parameter>
- </paramdef>
- </funcPrototype></funcSynopsis>
- </para>
-
- <para>Do some action on request of the CAM subsystem. Sim
- describes the SIM for the request, CCB is the request
- itself. CCB stands for <quote>CAM Control Block</quote>. It is a union of
- many specific instances, each describing arguments for some type
- of transactions. All of these instances share the CCB header
- where the common part of arguments is stored.</para>
-
- <para>CAM supports the SCSI controllers working in both initiator
- (<quote>normal</quote>) mode and target (simulating a SCSI device) mode. Here
- we only consider the part relevant to the initiator mode.</para>
-
- <para>There are a few function and macros (in other words,
- methods) defined to access the public data in the struct sim:</para>
-
- <itemizedlist>
- <listitem><para><function>cam_sim_path(sim)</function> - the
- path ID (see above)</para></listitem>
-
- <listitem><para><function>cam_sim_name(sim)</function> - the
- name of the sim</para></listitem>
-
- <listitem><para><function>cam_sim_softc(sim)</function> - the
- pointer to the softc (driver private data)
- structure</para></listitem>
-
- <listitem><para><function> cam_sim_unit(sim)</function> - the
- unit number</para></listitem>
-
- <listitem><para><function> cam_sim_bus(sim)</function> - the bus
- ID</para></listitem>
- </itemizedlist>
-
- <para>To identify the device, <function>xxx_action()</function> can
- get the unit number and pointer to its structure softc using
- these functions.</para>
-
- <para>The type of request is stored in
- <structField>ccb-&gt;ccb_h.func_code</structField>. So generally
- <function>xxx_action()</function> consists of a big
- switch:</para>
-
-<programlisting> struct xxx_softc *softc = (struct xxx_softc *) cam_sim_softc(sim);
- struct ccb_hdr *ccb_h = &amp;ccb->ccb_h;
- int unit = cam_sim_unit(sim);
- int bus = cam_sim_bus(sim);
-
- switch(ccb_h->func_code) {
- case ...:
- ...
- default:
- ccb_h->status = CAM_REQ_INVALID;
- xpt_done(ccb);
- break;
- }</programlisting>
-
- <para>As can be seen from the default case (if an unknown command
- was received) the return code of the command is set into
- <structField>ccb-&gt;ccb_h.status</structField> and the completed
- CCB is returned back to CAM by calling
- <function>xpt_done(ccb)</function>. </para>
-
- <para><function>xpt_done()</function> does not have to be called
- from <function>xxx_action()</function>: For example an I/O
- request may be enqueued inside the SIM driver and/or its SCSI
- controller. Then when the device would post an interrupt
- signaling that the processing of this request is complete
- <function>xpt_done()</function> may be called from the interrupt
- handling routine.</para>
-
- <para>Actually, the CCB status is not only assigned as a return
- code but a CCB has some status all the time. Before CCB is
- passed to the <function>xxx_action()</function> routine it gets
- the status CCB_REQ_INPROG meaning that it is in progress. There
- are a surprising number of status values defined in
- <filename>/sys/cam/cam.h</filename> which should be able to
- represent the status of a request in great detail. More
- interesting yet, the status is in fact a <quote>bitwise or</quote> of an
- enumerated status value (the lower 6 bits) and possible
- additional flag-like bits (the upper bits). The enumerated
- values will be discussed later in more detail. The summary of
- them can be found in the Errors Summary section. The possible
- status flags are:</para>
-
- <itemizedlist>
-
- <listitem><para><emphasis>CAM_DEV_QFRZN</emphasis> - if the
- SIM driver gets a serious error (for example, the device does
- not respond to the selection or breaks the SCSI protocol) when
- processing a CCB it should freeze the request queue by calling
- <function>xpt_freeze_simq()</function>, return the other
- enqueued but not processed yet CCBs for this device back to
- the CAM queue, then set this flag for the troublesome CCB and
- call <function>xpt_done()</function>. This flag causes the CAM
- subsystem to unfreeze the queue after it handles the
- error.</para></listitem>
-
- <listitem><para><emphasis>CAM_AUTOSNS_VALID</emphasis> - if
- the device returned an error condition and the flag
- CAM_DIS_AUTOSENSE is not set in CCB the SIM driver must
- execute the REQUEST SENSE command automatically to extract the
- sense (extended error information) data from the device. If
- this attempt was successful the sense data should be saved in
- the CCB and this flag set.</para></listitem>
-
- <listitem><para><emphasis>CAM_RELEASE_SIMQ</emphasis> - like
- CAM_DEV_QFRZN but used in case there is some problem (or
- resource shortage) with the SCSI controller itself. Then all
- the future requests to the controller should be stopped by
- <function>xpt_freeze_simq()</function>. The controller queue
- will be restarted after the SIM driver overcomes the shortage
- and informs CAM by returning some CCB with this flag
- set.</para></listitem>
-
- <listitem><para><emphasis>CAM_SIM_QUEUED</emphasis> - when SIM
- puts a CCB into its request queue this flag should be set (and
- removed when this CCB gets dequeued before being returned back
- to CAM). This flag is not used anywhere in the CAM code now,
- so its purpose is purely diagnostic.</para></listitem>
-
- </itemizedlist>
-
- <para>The function <function>xxx_action()</function> is not
- allowed to sleep, so all the synchronization for resource access
- must be done using SIM or device queue freezing. Besides the
- aforementioned flags the CAM subsystem provides functions
- <function>xpt_release_simq()</function> and
- <function>xpt_release_devq()</function> to unfreeze the queues
- directly, without passing a CCB to CAM.</para>
-
- <para>The CCB header contains the following fields:</para>
-
- <itemizedlist>
-
- <listitem><para><emphasis>path</emphasis> - path ID for the
- request</para></listitem>
-
- <listitem><para><emphasis>target_id</emphasis> - target device
- ID for the request</para></listitem>
-
- <listitem><para><emphasis>target_lun</emphasis> - LUN ID of
- the target device</para></listitem>
-
- <listitem><para><emphasis>timeout</emphasis> - timeout
- interval for this command, in milliseconds</para></listitem>
-
- <listitem><para><emphasis>timeout_ch</emphasis> - a
- convenience place for the SIM driver to store the timeout handle
- (the CAM subsystem itself does not make any assumptions about
- it)</para></listitem>
-
- <listitem><para><emphasis>flags</emphasis> - various bits of
- information about the request spriv_ptr0, spriv_ptr1 - fields
- reserved for private use by the SIM driver (such as linking to
- the SIM queues or SIM private control blocks); actually, they
- exist as unions: spriv_ptr0 and spriv_ptr1 have the type (void
- *), spriv_field0 and spriv_field1 have the type unsigned long,
- sim_priv.entries[0].bytes and sim_priv.entries[1].bytes are byte
- arrays of the size consistent with the other incarnations of the
- union and sim_priv.bytes is one array, twice
- bigger.</para></listitem>
-
- </itemizedlist>
-
- <para>The recommended way of using the SIM private fields of CCB
- is to define some meaningful names for them and use these
- meaningful names in the driver, like:</para>
-
-<programlisting>#define ccb_some_meaningful_name sim_priv.entries[0].bytes
-#define ccb_hcb spriv_ptr1 /* for hardware control block */</programlisting>
-
- <para>The most common initiator mode requests are:</para>
- <itemizedlist>
- <listitem><para><emphasis>XPT_SCSI_IO</emphasis> - execute an
- I/O transaction</para>
-
- <para>The instance <quote>struct ccb_scsiio csio</quote> of the union ccb is
- used to transfer the arguments. They are:</para>
-
- <itemizedlist>
- <listitem><para><emphasis>cdb_io</emphasis> - pointer to
- the SCSI command buffer or the buffer
- itself</para></listitem>
-
- <listitem><para><emphasis>cdb_len</emphasis> - SCSI
- command length</para></listitem>
-
- <listitem><para><emphasis>data_ptr</emphasis> - pointer to
- the data buffer (gets a bit complicated if scatter/gather is
- used)</para></listitem>
-
- <listitem><para><emphasis>dxfer_len</emphasis> - length of
- the data to transfer</para></listitem>
-
- <listitem><para><emphasis>sglist_cnt</emphasis> - counter
- of the scatter/gather segments</para></listitem>
-
- <listitem><para><emphasis>scsi_status</emphasis> - place
- to return the SCSI status</para></listitem>
-
- <listitem><para><emphasis>sense_data</emphasis> - buffer
- for the SCSI sense information if the command returns an
- error (the SIM driver is supposed to run the REQUEST SENSE
- command automatically in this case if the CCB flag
- CAM_DIS_AUTOSENSE is not set)</para></listitem>
-
- <listitem><para><emphasis>sense_len</emphasis> - the
- length of that buffer (if it happens to be higher than size
- of sense_data the SIM driver must silently assume the
- smaller value) resid, sense_resid - if the transfer of data
- or SCSI sense returned an error these are the returned
- counters of the residual (not transferred) data. They do not
- seem to be especially meaningful, so in a case when they are
- difficult to compute (say, counting bytes in the SCSI
- controller's FIFO buffer) an approximate value will do as
- well. For a successfully completed transfer they must be set
- to zero.</para></listitem>
-
- <listitem><para><emphasis>tag_action</emphasis> - the kind
- of tag to use:
-
- <itemizedlist>
- <listitem><para>CAM_TAG_ACTION_NONE - do not use tags for this
- transaction</para></listitem>
- <listitem><para>MSG_SIMPLE_Q_TAG, MSG_HEAD_OF_Q_TAG,
- MSG_ORDERED_Q_TAG - value equal to the appropriate tag
- message (see /sys/cam/scsi/scsi_message.h); this gives only
- the tag type, the SIM driver must assign the tag value
- itself</para></listitem>
- </itemizedlist>
-
- </para></listitem>
-
- </itemizedlist>
-
- <para>The general logic of handling this request is the
- following:</para>
-
- <para>The first thing to do is to check for possible races, to
- make sure that the command did not get aborted when it was
- sitting in the queue:</para>
-
-<programlisting> struct ccb_scsiio *csio = &amp;ccb->csio;
-
- if ((ccb_h->status &amp; CAM_STATUS_MASK) != CAM_REQ_INPROG) {
- xpt_done(ccb);
- return;
- }</programlisting>
-
- <para>Also we check that the device is supported at all by our
- controller:</para>
-
-<programlisting> if(ccb_h->target_id > OUR_MAX_SUPPORTED_TARGET_ID
- || cch_h->target_id == OUR_SCSI_CONTROLLERS_OWN_ID) {
- ccb_h->status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
- if(ccb_h->target_lun > OUR_MAX_SUPPORTED_LUN) {
- ccb_h->status = CAM_LUN_INVALID;
- xpt_done(ccb);
- return;
- }</programlisting>
-
- <para>Then allocate whatever data structures (such as
- card-dependent hardware control block) we need to process this
- request. If we ca not then freeze the SIM queue and remember
- that we have a pending operation, return the CCB back and ask
- CAM to re-queue it. Later when the resources become available
- the SIM queue must be unfrozen by returning a ccb with the
- CAM_SIMQ_RELEASE bit set in its status. Otherwise, if all went
- well, link the CCB with the hardware control block (HCB) and
- mark it as queued.</para>
-
-<programlisting> struct xxx_hcb *hcb = allocate_hcb(softc, unit, bus);
-
- if(hcb == NULL) {
- softc->flags |= RESOURCE_SHORTAGE;
- xpt_freeze_simq(sim, /*count*/1);
- ccb_h->status = CAM_REQUEUE_REQ;
- xpt_done(ccb);
- return;
- }
-
- hcb->ccb = ccb; ccb_h->ccb_hcb = (void *)hcb;
- ccb_h->status |= CAM_SIM_QUEUED;</programlisting>
-
- <para>Extract the target data from CCB into the hardware control
- block. Check if we are asked to assign a tag and if yes then
- generate an unique tag and build the SCSI tag messages. The
- SIM driver is also responsible for negotiations with the
- devices to set the maximal mutually supported bus width,
- synchronous rate and offset.</para>
-
-<programlisting> hcb->target = ccb_h->target_id; hcb->lun = ccb_h->target_lun;
- generate_identify_message(hcb);
- if( ccb_h->tag_action != CAM_TAG_ACTION_NONE )
- generate_unique_tag_message(hcb, ccb_h->tag_action);
- if( !target_negotiated(hcb) )
- generate_negotiation_messages(hcb);</programlisting>
-
- <para>Then set up the SCSI command. The command storage may be
- specified in the CCB in many interesting ways, specified by
- the CCB flags. The command buffer can be contained in CCB or
- pointed to, in the latter case the pointer may be physical or
- virtual. Since the hardware commonly needs physical address we
- always convert the address to the physical one.</para>
-
- <para>A NOT-QUITE RELATED NOTE: Normally this is done by a call
- to vtophys(), but for the PCI device (which account for most
- of the SCSI controllers now) drivers' portability to the Alpha
- architecture the conversion must be done by vtobus() instead
- due to special Alpha quirks. [IMHO it would be much better to
- have two separate functions, vtop() and ptobus() then vtobus()
- would be a simple superposition of them.] In case if a
- physical address is requested it is OK to return the CCB with
- the status CAM_REQ_INVALID, the current drivers do that. But
- it is also possible to compile the Alpha-specific piece of
- code, as in this example (there should be a more direct way to
- do that, without conditional compilation in the drivers). If
- necessary a physical address can be also converted or mapped
- back to a virtual address but with big pain, so we do not do
- that.</para>
-
-<programlisting> if(ccb_h->flags &amp; CAM_CDB_POINTER) {
- /* CDB is a pointer */
- if(!(ccb_h->flags &amp; CAM_CDB_PHYS)) {
- /* CDB pointer is virtual */
- hcb->cmd = vtobus(csio->cdb_io.cdb_ptr);
- } else {
- /* CDB pointer is physical */
-#if defined(__alpha__)
- hcb->cmd = csio->cdb_io.cdb_ptr | alpha_XXX_dmamap_or ;
-#else
- hcb->cmd = csio->cdb_io.cdb_ptr ;
-#endif
- }
- } else {
- /* CDB is in the ccb (buffer) */
- hcb->cmd = vtobus(csio->cdb_io.cdb_bytes);
- }
- hcb->cmdlen = csio->cdb_len;</programlisting>
-
- <para>Now it is time to set up the data. Again, the data storage
- may be specified in the CCB in many interesting ways,
- specified by the CCB flags. First we get the direction of the
- data transfer. The simplest case is if there is no data to
- transfer:</para>
-
-<programlisting> int dir = (ccb_h->flags &amp; CAM_DIR_MASK);
-
- if (dir == CAM_DIR_NONE)
- goto end_data;</programlisting>
-
- <para>Then we check if the data is in one chunk or in a
- scatter-gather list, and the addresses are physical or
- virtual. The SCSI controller may be able to handle only a
- limited number of chunks of limited length. If the request
- hits this limitation we return an error. We use a special
- function to return the CCB to handle in one place the HCB
- resource shortages. The functions to add chunks are
- driver-dependent, and here we leave them without detailed
- implementation. See description of the SCSI command (CDB)
- handling for the details on the address-translation issues.
- If some variation is too difficult or impossible to implement
- with a particular card it is OK to return the status
- CAM_REQ_INVALID. Actually, it seems like the scatter-gather
- ability is not used anywhere in the CAM code now. But at least
- the case for a single non-scattered virtual buffer must be
- implemented, it is actively used by CAM.</para>
-
-<programlisting> int rv;
-
- initialize_hcb_for_data(hcb);
-
- if((!(ccb_h->flags &amp; CAM_SCATTER_VALID)) {
- /* single buffer */
- if(!(ccb_h->flags &amp; CAM_DATA_PHYS)) {
- rv = add_virtual_chunk(hcb, csio->data_ptr, csio->dxfer_len, dir);
- }
- } else {
- rv = add_physical_chunk(hcb, csio->data_ptr, csio->dxfer_len, dir);
- }
- } else {
- int i;
- struct bus_dma_segment *segs;
- segs = (struct bus_dma_segment *)csio->data_ptr;
-
- if ((ccb_h->flags &amp; CAM_SG_LIST_PHYS) != 0) {
- /* The SG list pointer is physical */
- rv = setup_hcb_for_physical_sg_list(hcb, segs, csio->sglist_cnt);
- } else if (!(ccb_h->flags &amp; CAM_DATA_PHYS)) {
- /* SG buffer pointers are virtual */
- for (i = 0; i < csio->sglist_cnt; i++) {
- rv = add_virtual_chunk(hcb, segs[i].ds_addr,
- segs[i].ds_len, dir);
- if (rv != CAM_REQ_CMP)
- break;
- }
- } else {
- /* SG buffer pointers are physical */
- for (i = 0; i < csio->sglist_cnt; i++) {
- rv = add_physical_chunk(hcb, segs[i].ds_addr,
- segs[i].ds_len, dir);
- if (rv != CAM_REQ_CMP)
- break;
- }
- }
- }
- if(rv != CAM_REQ_CMP) {
- /* we expect that add_*_chunk() functions return CAM_REQ_CMP
- * if they added a chunk successfully, CAM_REQ_TOO_BIG if
- * the request is too big (too many bytes or too many chunks),
- * CAM_REQ_INVALID in case of other troubles
- */
- free_hcb_and_ccb_done(hcb, ccb, rv);
- return;
- }
- end_data:</programlisting>
-
- <para>If disconnection is disabled for this CCB we pass this
- information to the hcb:</para>
-
-<programlisting> if(ccb_h->flags &amp; CAM_DIS_DISCONNECT)
- hcb_disable_disconnect(hcb);</programlisting>
-
- <para>If the controller is able to run REQUEST SENSE command all
- by itself then the value of the flag CAM_DIS_AUTOSENSE should
- also be passed to it, to prevent automatic REQUEST SENSE if the
- CAM subsystem does not want it.</para>
-
- <para>The only thing left is to set up the timeout, pass our hcb
- to the hardware and return, the rest will be done by the
- interrupt handler (or timeout handler).</para>
-
-<programlisting> ccb_h->timeout_ch = timeout(xxx_timeout, (caddr_t) hcb,
- (ccb_h->timeout * hz) / 1000); /* convert milliseconds to ticks */
- put_hcb_into_hardware_queue(hcb);
- return;</programlisting>
-
- <para>And here is a possible implementation of the function
- returning CCB:</para>
-
-<programlisting> static void
- free_hcb_and_ccb_done(struct xxx_hcb *hcb, union ccb *ccb, u_int32_t status)
- {
- struct xxx_softc *softc = hcb->softc;
-
- ccb->ccb_h.ccb_hcb = 0;
- if(hcb != NULL) {
- untimeout(xxx_timeout, (caddr_t) hcb, ccb->ccb_h.timeout_ch);
- /* we're about to free a hcb, so the shortage has ended */
- if(softc->flags &amp; RESOURCE_SHORTAGE) {
- softc->flags &amp;= ~RESOURCE_SHORTAGE;
- status |= CAM_RELEASE_SIMQ;
- }
- free_hcb(hcb); /* also removes hcb from any internal lists */
- }
- ccb->ccb_h.status = status |
- (ccb->ccb_h.status &amp; ~(CAM_STATUS_MASK|CAM_SIM_QUEUED));
- xpt_done(ccb);
- }</programlisting>
- </listitem>
-
- <listitem><para><emphasis>XPT_RESET_DEV</emphasis> - send the SCSI <quote>BUS
- DEVICE RESET</quote> message to a device</para>
-
- <para>There is no data transferred in CCB except the header and
- the most interesting argument of it is target_id. Depending on
- the controller hardware a hardware control block just like for
- the XPT_SCSI_IO request may be constructed (see XPT_SCSI_IO
- request description) and sent to the controller or the SCSI
- controller may be immediately programmed to send this RESET
- message to the device or this request may be just not supported
- (and return the status CAM_REQ_INVALID). Also on completion of
- the request all the disconnected transactions for this target
- must be aborted (probably in the interrupt routine).</para>
-
- <para>Also all the current negotiations for the target are lost on
- reset, so they might be cleaned too. Or they clearing may be
- deferred, because anyway the target would request re-negotiation
- on the next transaction.</para></listitem>
-
- <listitem><para><emphasis>XPT_RESET_BUS</emphasis> - send the RESET signal
- to the SCSI bus</para>
-
- <para>No arguments are passed in the CCB, the only interesting
- argument is the SCSI bus indicated by the struct sim
- pointer.</para>
-
- <para>A minimalistic implementation would forget the SCSI
- negotiations for all the devices on the bus and return the
- status CAM_REQ_CMP.</para>
-
- <para>The proper implementation would in addition actually reset
- the SCSI bus (possible also reset the SCSI controller) and mark
- all the CCBs being processed, both those in the hardware queue
- and those being disconnected, as done with the status
- CAM_SCSI_BUS_RESET. Like:</para>
-
-<programlisting> int targ, lun;
- struct xxx_hcb *h, *hh;
- struct ccb_trans_settings neg;
- struct cam_path *path;
-
- /* The SCSI bus reset may take a long time, in this case its completion
- * should be checked by interrupt or timeout. But for simplicity
- * we assume here that it's really fast.
- */
- reset_scsi_bus(softc);
-
- /* drop all enqueued CCBs */
- for(h = softc->first_queued_hcb; h != NULL; h = hh) {
- hh = h->next;
- free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET);
- }
-
- /* the clean values of negotiations to report */
- neg.bus_width = 8;
- neg.sync_period = neg.sync_offset = 0;
- neg.valid = (CCB_TRANS_BUS_WIDTH_VALID
- | CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID);
-
- /* drop all disconnected CCBs and clean negotiations */
- for(targ=0; targ <= OUR_MAX_SUPPORTED_TARGET; targ++) {
- clean_negotiations(softc, targ);
-
- /* report the event if possible */
- if(xpt_create_path(&amp;path, /*periph*/NULL,
- cam_sim_path(sim), targ,
- CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
- xpt_async(AC_TRANSFER_NEG, path, &amp;neg);
- xpt_free_path(path);
- }
-
- for(lun=0; lun <= OUR_MAX_SUPPORTED_LUN; lun++)
- for(h = softc->first_discon_hcb[targ][lun]; h != NULL; h = hh) {
- hh=h->next;
- free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET);
- }
- }
-
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
-
- /* report the event */
- xpt_async(AC_BUS_RESET, softc->wpath, NULL);
- return;</programlisting>
-
- <para>Implementing the SCSI bus reset as a function may be a good
- idea because it would be re-used by the timeout function as a
- last resort if the things go wrong.</para></listitem>
-
- <listitem><para><emphasis>XPT_ABORT</emphasis> - abort the specified
- CCB</para>
-
- <para>The arguments are transferred in the instance <quote>struct
- ccb_abort cab</quote> of the union ccb. The only argument field in it
- is:</para>
-
- <para><emphasis>abort_ccb</emphasis> - pointer to the CCB to be
- aborted</para>
-
- <para>If the abort is not supported just return the status
- CAM_UA_ABORT. This is also the easy way to minimally implement
- this call, return CAM_UA_ABORT in any case.</para>
-
- <para>The hard way is to implement this request honestly. First
- check that abort applies to a SCSI transaction:</para>
-
-<programlisting> struct ccb *abort_ccb;
- abort_ccb = ccb->cab.abort_ccb;
-
- if(abort_ccb->ccb_h.func_code != XPT_SCSI_IO) {
- ccb->ccb_h.status = CAM_UA_ABORT;
- xpt_done(ccb);
- return;
- }</programlisting>
-
- <para>Then it is necessary to find this CCB in our queue. This can
- be done by walking the list of all our hardware control blocks
- in search for one associated with this CCB:</para>
-
-<programlisting> struct xxx_hcb *hcb, *h;
-
- hcb = NULL;
-
- /* We assume that softc->first_hcb is the head of the list of all
- * HCBs associated with this bus, including those enqueued for
- * processing, being processed by hardware and disconnected ones.
- */
- for(h = softc->first_hcb; h != NULL; h = h->next) {
- if(h->ccb == abort_ccb) {
- hcb = h;
- break;
- }
- }
-
- if(hcb == NULL) {
- /* no such CCB in our queue */
- ccb->ccb_h.status = CAM_PATH_INVALID;
- xpt_done(ccb);
- return;
- }
-
- hcb=found_hcb;</programlisting>
-
- <para>Now we look at the current processing status of the HCB. It
- may be either sitting in the queue waiting to be sent to the
- SCSI bus, being transferred right now, or disconnected and
- waiting for the result of the command, or actually completed by
- hardware but not yet marked as done by software. To make sure
- that we do not get in any races with hardware we mark the HCB as
- being aborted, so that if this HCB is about to be sent to the
- SCSI bus the SCSI controller will see this flag and skip
- it.</para>
-
-<programlisting> int hstatus;
-
- /* shown as a function, in case special action is needed to make
- * this flag visible to hardware
- */
- set_hcb_flags(hcb, HCB_BEING_ABORTED);
-
- abort_again:
-
- hstatus = get_hcb_status(hcb);
- switch(hstatus) {
- case HCB_SITTING_IN_QUEUE:
- remove_hcb_from_hardware_queue(hcb);
- /* FALLTHROUGH */
- case HCB_COMPLETED:
- /* this is an easy case */
- free_hcb_and_ccb_done(hcb, abort_ccb, CAM_REQ_ABORTED);
- break;</programlisting>
-
- <para>If the CCB is being transferred right now we would like to
- signal to the SCSI controller in some hardware-dependent way
- that we want to abort the current transfer. The SCSI controller
- would set the SCSI ATTENTION signal and when the target responds
- to it send an ABORT message. We also reset the timeout to make
- sure that the target is not sleeping forever. If the command
- would not get aborted in some reasonable time like 10 seconds
- the timeout routine would go ahead and reset the whole SCSI bus.
- Because the command will be aborted in some reasonable time we
- can just return the abort request now as successfully completed,
- and mark the aborted CCB as aborted (but not mark it as done
- yet).</para>
-
-<programlisting> case HCB_BEING_TRANSFERRED:
- untimeout(xxx_timeout, (caddr_t) hcb, abort_ccb->ccb_h.timeout_ch);
- abort_ccb->ccb_h.timeout_ch =
- timeout(xxx_timeout, (caddr_t) hcb, 10 * hz);
- abort_ccb->ccb_h.status = CAM_REQ_ABORTED;
- /* ask the controller to abort that HCB, then generate
- * an interrupt and stop
- */
- if(signal_hardware_to_abort_hcb_and_stop(hcb) < 0) {
- /* oops, we missed the race with hardware, this transaction
- * got off the bus before we aborted it, try again */
- goto abort_again;
- }
-
- break;</programlisting>
-
- <para>If the CCB is in the list of disconnected then set it up as
- an abort request and re-queue it at the front of hardware
- queue. Reset the timeout and report the abort request to be
- completed.</para>
-
-<programlisting> case HCB_DISCONNECTED:
- untimeout(xxx_timeout, (caddr_t) hcb, abort_ccb->ccb_h.timeout_ch);
- abort_ccb->ccb_h.timeout_ch =
- timeout(xxx_timeout, (caddr_t) hcb, 10 * hz);
- put_abort_message_into_hcb(hcb);
- put_hcb_at_the_front_of_hardware_queue(hcb);
- break;
- }
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- return;</programlisting>
-
- <para>That is all for the ABORT request, although there is one more
- issue. Because the ABORT message cleans all the ongoing
- transactions on a LUN we have to mark all the other active
- transactions on this LUN as aborted. That should be done in the
- interrupt routine, after the transaction gets aborted.</para>
-
- <para>Implementing the CCB abort as a function may be quite a good
- idea, this function can be re-used if an I/O transaction times
- out. The only difference would be that the timed out transaction
- would return the status CAM_CMD_TIMEOUT for the timed out
- request. Then the case XPT_ABORT would be small, like
- that:</para>
-
-<programlisting> case XPT_ABORT:
- struct ccb *abort_ccb;
- abort_ccb = ccb->cab.abort_ccb;
-
- if(abort_ccb->ccb_h.func_code != XPT_SCSI_IO) {
- ccb->ccb_h.status = CAM_UA_ABORT;
- xpt_done(ccb);
- return;
- }
- if(xxx_abort_ccb(abort_ccb, CAM_REQ_ABORTED) < 0)
- /* no such CCB in our queue */
- ccb->ccb_h.status = CAM_PATH_INVALID;
- else
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- return;</programlisting>
- </listitem>
-
- <listitem><para><emphasis>XPT_SET_TRAN_SETTINGS</emphasis> - explicitly
- set values of SCSI transfer settings</para>
-
- <para>The arguments are transferred in the instance <quote>struct ccb_trans_setting cts</quote>
-of the union ccb:</para>
-
- <itemizedlist>
- <listitem><para><emphasis>valid</emphasis> - a bitmask showing
- which settings should be updated:</para></listitem>
-
- <listitem><para><emphasis>CCB_TRANS_SYNC_RATE_VALID</emphasis>
- - synchronous transfer rate</para></listitem>
-
- <listitem><para><emphasis>CCB_TRANS_SYNC_OFFSET_VALID</emphasis>
- - synchronous offset</para></listitem>
-
- <listitem><para><emphasis>CCB_TRANS_BUS_WIDTH_VALID</emphasis>
- - bus width</para></listitem>
-
- <listitem><para><emphasis>CCB_TRANS_DISC_VALID</emphasis> -
- set enable/disable disconnection</para></listitem>
-
- <listitem><para><emphasis>CCB_TRANS_TQ_VALID</emphasis> - set
- enable/disable tagged queuing</para></listitem>
-
- <listitem><para><emphasis>flags</emphasis> - consists of two
- parts, binary arguments and identification of
- sub-operations. The binary arguments are:</para>
- <itemizedlist>
- <listitem><para><emphasis>CCB_TRANS_DISC_ENB</emphasis> - enable disconnection</para></listitem>
- <listitem><para><emphasis>CCB_TRANS_TAG_ENB</emphasis> -
- enable tagged queuing</para></listitem>
- </itemizedlist>
- </listitem>
-
- <listitem><para>the sub-operations are:</para>
- <itemizedlist>
- <listitem><para><emphasis>CCB_TRANS_CURRENT_SETTINGS</emphasis>
- - change the current negotiations</para></listitem>
-
- <listitem><para><emphasis>CCB_TRANS_USER_SETTINGS</emphasis>
- - remember the desired user values sync_period, sync_offset -
- self-explanatory, if sync_offset==0 then the asynchronous mode
- is requested bus_width - bus width, in bits (not
- bytes)</para></listitem>
- </itemizedlist>
- </listitem>
-
- </itemizedlist>
-
- <para>Two sets of negotiated parameters are supported, the user
- settings and the current settings. The user settings are not
- really used much in the SIM drivers, this is mostly just a piece
- of memory where the upper levels can store (and later recall)
- its ideas about the parameters. Setting the user parameters
- does not cause re-negotiation of the transfer rates. But when
- the SCSI controller does a negotiation it must never set the
- values higher than the user parameters, so it is essentially the
- top boundary.</para>
-
- <para>The current settings are, as the name says,
- current. Changing them means that the parameters must be
- re-negotiated on the next transfer. Again, these <quote>new current
- settings</quote> are not supposed to be forced on the device, just they
- are used as the initial step of negotiations. Also they must be
- limited by actual capabilities of the SCSI controller: for
- example, if the SCSI controller has 8-bit bus and the request
- asks to set 16-bit wide transfers this parameter must be
- silently truncated to 8-bit transfers before sending it to the
- device.</para>
-
- <para>One caveat is that the bus width and synchronous parameters
- are per target while the disconnection and tag enabling
- parameters are per lun.</para>
-
- <para>The recommended implementation is to keep 3 sets of
- negotiated (bus width and synchronous transfer)
- parameters:</para>
-
- <itemizedlist>
- <listitem><para><emphasis>user</emphasis> - the user set, as
- above</para></listitem>
-
- <listitem><para><emphasis>current</emphasis> - those actually
- in effect</para></listitem>
-
- <listitem><para><emphasis>goal</emphasis> - those requested by
- setting of the <quote>current</quote> parameters</para></listitem>
- </itemizedlist>
-
- <para>The code looks like:</para>
-
-<programlisting> struct ccb_trans_settings *cts;
- int targ, lun;
- int flags;
-
- cts = &amp;ccb->cts;
- targ = ccb_h->target_id;
- lun = ccb_h->target_lun;
- flags = cts->flags;
- if(flags &amp; CCB_TRANS_USER_SETTINGS) {
- if(flags &amp; CCB_TRANS_SYNC_RATE_VALID)
- softc->user_sync_period[targ] = cts->sync_period;
- if(flags &amp; CCB_TRANS_SYNC_OFFSET_VALID)
- softc->user_sync_offset[targ] = cts->sync_offset;
- if(flags &amp; CCB_TRANS_BUS_WIDTH_VALID)
- softc->user_bus_width[targ] = cts->bus_width;
-
- if(flags &amp; CCB_TRANS_DISC_VALID) {
- softc->user_tflags[targ][lun] &amp;= ~CCB_TRANS_DISC_ENB;
- softc->user_tflags[targ][lun] |= flags &amp; CCB_TRANS_DISC_ENB;
- }
- if(flags &amp; CCB_TRANS_TQ_VALID) {
- softc->user_tflags[targ][lun] &amp;= ~CCB_TRANS_TQ_ENB;
- softc->user_tflags[targ][lun] |= flags &amp; CCB_TRANS_TQ_ENB;
- }
- }
- if(flags &amp; CCB_TRANS_CURRENT_SETTINGS) {
- if(flags &amp; CCB_TRANS_SYNC_RATE_VALID)
- softc->goal_sync_period[targ] =
- max(cts->sync_period, OUR_MIN_SUPPORTED_PERIOD);
- if(flags &amp; CCB_TRANS_SYNC_OFFSET_VALID)
- softc->goal_sync_offset[targ] =
- min(cts->sync_offset, OUR_MAX_SUPPORTED_OFFSET);
- if(flags &amp; CCB_TRANS_BUS_WIDTH_VALID)
- softc->goal_bus_width[targ] = min(cts->bus_width, OUR_BUS_WIDTH);
-
- if(flags &amp; CCB_TRANS_DISC_VALID) {
- softc->current_tflags[targ][lun] &amp;= ~CCB_TRANS_DISC_ENB;
- softc->current_tflags[targ][lun] |= flags &amp; CCB_TRANS_DISC_ENB;
- }
- if(flags &amp; CCB_TRANS_TQ_VALID) {
- softc->current_tflags[targ][lun] &amp;= ~CCB_TRANS_TQ_ENB;
- softc->current_tflags[targ][lun] |= flags &amp; CCB_TRANS_TQ_ENB;
- }
- }
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- return;</programlisting>
-
- <para>Then when the next I/O request will be processed it will
- check if it has to re-negotiate, for example by calling the
- function target_negotiated(hcb). It can be implemented like
- this:</para>
-
-<programlisting> int
- target_negotiated(struct xxx_hcb *hcb)
- {
- struct softc *softc = hcb->softc;
- int targ = hcb->targ;
-
- if( softc->current_sync_period[targ] != softc->goal_sync_period[targ]
- || softc->current_sync_offset[targ] != softc->goal_sync_offset[targ]
- || softc->current_bus_width[targ] != softc->goal_bus_width[targ] )
- return 0; /* FALSE */
- else
- return 1; /* TRUE */
- }</programlisting>
-
- <para>After the values are re-negotiated the resulting values must
- be assigned to both current and goal parameters, so for future
- I/O transactions the current and goal parameters would be the
- same and <function>target_negotiated()</function> would return
- TRUE. When the card is initialized (in
- <function>xxx_attach()</function>) the current negotiation
- values must be initialized to narrow asynchronous mode, the goal
- and current values must be initialized to the maximal values
- supported by controller.</para></listitem>
-
- <listitem><para><emphasis>XPT_GET_TRAN_SETTINGS</emphasis> - get values of
- SCSI transfer settings</para>
-
- <para>This operations is the reverse of
- XPT_SET_TRAN_SETTINGS. Fill up the CCB instance <quote>struct
- ccb_trans_setting cts</quote> with data as requested by the flags
- CCB_TRANS_CURRENT_SETTINGS or CCB_TRANS_USER_SETTINGS (if both
- are set then the existing drivers return the current
- settings). Set all the bits in the valid field.</para></listitem>
-
- <listitem><para><emphasis>XPT_CALC_GEOMETRY</emphasis> - calculate logical
- (BIOS) geometry of the disk</para>
-
- <para>The arguments are transferred in the instance <quote>struct
- ccb_calc_geometry ccg</quote> of the union ccb:</para>
-
- <itemizedlist>
-
- <listitem><para><emphasis>block_size</emphasis> - input, block
- (A.K.A sector) size in bytes</para></listitem>
-
- <listitem><para><emphasis>volume_size</emphasis> - input,
- volume size in bytes</para></listitem>
-
- <listitem><para><emphasis>cylinders</emphasis> - output,
- logical cylinders</para></listitem>
-
- <listitem><para><emphasis>heads</emphasis> - output, logical
- heads</para></listitem>
-
- <listitem><para><emphasis>secs_per_track</emphasis> - output,
- logical sectors per track</para></listitem>
-
- </itemizedlist>
-
- <para>If the returned geometry differs much enough from what the
- SCSI controller BIOS thinks and a disk on this SCSI controller
- is used as bootable the system may not be able to boot. The
- typical calculation example taken from the aic7xxx driver
- is:</para>
-
-<programlisting> struct ccb_calc_geometry *ccg;
- u_int32_t size_mb;
- u_int32_t secs_per_cylinder;
- int extended;
-
- ccg = &amp;ccb->ccg;
- size_mb = ccg->volume_size
- / ((1024L * 1024L) / ccg->block_size);
- extended = check_cards_EEPROM_for_extended_geometry(softc);
-
- if (size_mb > 1024 &amp;&amp; extended) {
- ccg->heads = 255;
- ccg->secs_per_track = 63;
- } else {
- ccg->heads = 64;
- ccg->secs_per_track = 32;
- }
- secs_per_cylinder = ccg->heads * ccg->secs_per_track;
- ccg->cylinders = ccg->volume_size / secs_per_cylinder;
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- return;</programlisting>
-
- <para>This gives the general idea, the exact calculation depends
- on the quirks of the particular BIOS. If BIOS provides no way
- set the <quote>extended translation</quote> flag in EEPROM this flag should
- normally be assumed equal to 1. Other popular geometries
- are:</para>
-
-<programlisting> 128 heads, 63 sectors - Symbios controllers
- 16 heads, 63 sectors - old controllers</programlisting>
-
- <para>Some system BIOSes and SCSI BIOSes fight with each other
- with variable success, for example a combination of Symbios
- 875/895 SCSI and Phoenix BIOS can give geometry 128/63 after
- power up and 255/63 after a hard reset or soft reboot.</para>
- </listitem>
-
- <listitem><para><emphasis>XPT_PATH_INQ</emphasis> - path inquiry, in other
- words get the SIM driver and SCSI controller (also known as HBA
- - Host Bus Adapter) properties</para>
-
- <para>The properties are returned in the instance <quote>struct
-ccb_pathinq cpi</quote> of the union ccb:</para>
-
- <itemizedlist>
-
- <listitem><para>version_num - the SIM driver version number, now
- all drivers use 1</para></listitem>
-
- <listitem><para>hba_inquiry - bitmask of features supported by
- the controller:</para></listitem>
-
- <listitem><para>PI_MDP_ABLE - supports MDP message (something
- from SCSI3?)</para></listitem>
-
- <listitem><para>PI_WIDE_32 - supports 32 bit wide
- SCSI</para></listitem>
-
- <listitem><para>PI_WIDE_16 - supports 16 bit wide
- SCSI</para></listitem>
-
- <listitem><para>PI_SDTR_ABLE - can negotiate synchronous
- transfer rate</para></listitem>
-
- <listitem><para>PI_LINKED_CDB - supports linked
- commands</para></listitem>
-
- <listitem><para>PI_TAG_ABLE - supports tagged
- commands</para></listitem>
-
- <listitem><para>PI_SOFT_RST - supports soft reset alternative
- (hard reset and soft reset are mutually exclusive within a
- SCSI bus)</para></listitem>
-
- <listitem><para>target_sprt - flags for target mode support, 0
- if unsupported</para></listitem>
-
- <listitem><para>hba_misc - miscellaneous controller
- features:</para></listitem>
-
- <listitem><para>PIM_SCANHILO - bus scans from high ID to low
- ID</para></listitem>
-
- <listitem><para>PIM_NOREMOVE - removable devices not included in
- scan</para></listitem>
-
- <listitem><para>PIM_NOINITIATOR - initiator role not
- supported</para></listitem>
-
- <listitem><para>PIM_NOBUSRESET - user has disabled initial BUS
- RESET</para></listitem>
-
- <listitem><para>hba_eng_cnt - mysterious HBA engine count,
- something related to compression, now is always set to
- 0</para></listitem>
-
- <listitem><para>vuhba_flags - vendor-unique flags, unused
- now</para></listitem>
-
- <listitem><para>max_target - maximal supported target ID (7 for
- 8-bit bus, 15 for 16-bit bus, 127 for Fibre
- Channel)</para></listitem>
-
- <listitem><para>max_lun - maximal supported LUN ID (7 for older
- SCSI controllers, 63 for newer ones)</para></listitem>
-
- <listitem><para>async_flags - bitmask of installed Async
- handler, unused now</para></listitem>
-
- <listitem><para>hpath_id - highest Path ID in the subsystem,
- unused now</para></listitem>
-
- <listitem><para>unit_number - the controller unit number,
- cam_sim_unit(sim)</para></listitem>
-
- <listitem><para>bus_id - the bus number,
- cam_sim_bus(sim)</para></listitem>
-
- <listitem><para>initiator_id - the SCSI ID of the controller
- itself</para></listitem>
-
- <listitem><para>base_transfer_speed - nominal transfer speed in
- KB/s for asynchronous narrow transfers, equals to 3300 for
- SCSI</para></listitem>
-
- <listitem><para>sim_vid - SIM driver's vendor id, a
- zero-terminated string of maximal length SIM_IDLEN including
- the terminating zero</para></listitem>
-
- <listitem><para>hba_vid - SCSI controller's vendor id, a
- zero-terminated string of maximal length HBA_IDLEN including
- the terminating zero</para></listitem>
-
- <listitem><para>dev_name - device driver name, a zero-terminated
- string of maximal length DEV_IDLEN including the terminating
- zero, equal to cam_sim_name(sim)</para></listitem>
-
- </itemizedlist>
-
- <para>The recommended way of setting the string fields is using
- strncpy, like:</para>
-
-<programlisting> strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);</programlisting>
-
- <para>After setting the values set the status to CAM_REQ_CMP and mark the
-CCB as done.</para>
- </listitem>
- </itemizedlist>
-
- </sect1>
-
- <sect1>
- <title>Polling</title>
-
- <funcSynopsis><funcPrototype>
- <funcDef>static void
- <function>xxx_poll</function>
- </funcDef>
- <paramdef>
- <parameter>struct cam_sim *sim</parameter>
- </paramdef>
- </funcPrototype></funcSynopsis>
-
- <para>The poll function is used to simulate the interrupts when
- the interrupt subsystem is not functioning (for example, when
- the system has crashed and is creating the system dump). The CAM
- subsystem sets the proper interrupt level before calling the
- poll routine. So all it needs to do is to call the interrupt
- routine (or the other way around, the poll routine may be doing
- the real action and the interrupt routine would just call the
- poll routine). Why bother about a separate function then?
- Because of different calling conventions. The
- <function>xxx_poll</function> routine gets the struct cam_sim
- pointer as its argument when the PCI interrupt routine by common
- convention gets pointer to the struct
- <structName>xxx_softc</structName> and the ISA interrupt routine
- gets just the device unit number. So the poll routine would
- normally look as:</para>
-
-<programlisting>static void
-xxx_poll(struct cam_sim *sim)
-{
- xxx_intr((struct xxx_softc *)cam_sim_softc(sim)); /* for PCI device */
-}</programlisting>
-
- <para>or</para>
-
-<programlisting>static void
-xxx_poll(struct cam_sim *sim)
-{
- xxx_intr(cam_sim_unit(sim)); /* for ISA device */
-}</programlisting>
-
- </sect1>
-
- <sect1>
- <title>Asynchronous Events</title>
-
- <para>If an asynchronous event callback has been set up then the
- callback function should be defined.</para>
-
-<programlisting>static void
-ahc_async(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)</programlisting>
-
- <itemizedlist>
- <listitem><para>callback_arg - the value supplied when registering the
- callback</para></listitem>
-
- <listitem><para>code - identifies the type of event</para></listitem>
-
- <listitem><para>path - identifies the devices to which the event
- applies</para></listitem>
-
- <listitem><para>arg - event-specific argument</para></listitem>
- </itemizedlist>
-
- <para>Implementation for a single type of event, AC_LOST_DEVICE,
- looks like:</para>
-
-<programlisting> struct xxx_softc *softc;
- struct cam_sim *sim;
- int targ;
- struct ccb_trans_settings neg;
-
- sim = (struct cam_sim *)callback_arg;
- softc = (struct xxx_softc *)cam_sim_softc(sim);
- switch (code) {
- case AC_LOST_DEVICE:
- targ = xpt_path_target_id(path);
- if(targ <= OUR_MAX_SUPPORTED_TARGET) {
- clean_negotiations(softc, targ);
- /* send indication to CAM */
- neg.bus_width = 8;
- neg.sync_period = neg.sync_offset = 0;
- neg.valid = (CCB_TRANS_BUS_WIDTH_VALID
- | CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID);
- xpt_async(AC_TRANSFER_NEG, path, &amp;neg);
- }
- break;
- default:
- break;
- }</programlisting>
-
- </sect1>
-
- <sect1>
- <title>Interrupts</title>
-
- <para>The exact type of the interrupt routine depends on the type
- of the peripheral bus (PCI, ISA and so on) to which the SCSI
- controller is connected.</para>
-
- <para>The interrupt routines of the SIM drivers run at the
- interrupt level splcam. So <function>splcam()</function> should
- be used in the driver to synchronize activity between the
- interrupt routine and the rest of the driver (for a
- multiprocessor-aware driver things get yet more interesting but
- we ignore this case here). The pseudo-code in this document
- happily ignores the problems of synchronization. The real code
- must not ignore them. A simple-minded approach is to set
- <function>splcam()</function> on the entry to the other routines
- and reset it on return thus protecting them by one big critical
- section. To make sure that the interrupt level will be always
- restored a wrapper function can be defined, like:</para>
-
-<programlisting> static void
- xxx_action(struct cam_sim *sim, union ccb *ccb)
- {
- int s;
- s = splcam();
- xxx_action1(sim, ccb);
- splx(s);
- }
-
- static void
- xxx_action1(struct cam_sim *sim, union ccb *ccb)
- {
- ... process the request ...
- }</programlisting>
-
- <para>This approach is simple and robust but the problem with it
- is that interrupts may get blocked for a relatively long time
- and this would negatively affect the system's performance. On
- the other hand the functions of the <function>spl()</function>
- family have rather high overhead, so vast amount of tiny
- critical sections may not be good either.</para>
-
- <para>The conditions handled by the interrupt routine and the
- details depend very much on the hardware. We consider the set of
- <quote>typical</quote> conditions.</para>
-
- <para>First, we check if a SCSI reset was encountered on the bus
- (probably caused by another SCSI controller on the same SCSI
- bus). If so we drop all the enqueued and disconnected requests,
- report the events and re-initialize our SCSI controller. It is
- important that during this initialization the controller will not
- issue another reset or else two controllers on the same SCSI bus
- could ping-pong resets forever. The case of fatal controller
- error/hang could be handled in the same place, but it will
- probably need also sending RESET signal to the SCSI bus to reset
- the status of the connections with the SCSI devices.</para>
-
-<programlisting> int fatal=0;
- struct ccb_trans_settings neg;
- struct cam_path *path;
-
- if( detected_scsi_reset(softc)
- || (fatal = detected_fatal_controller_error(softc)) ) {
- int targ, lun;
- struct xxx_hcb *h, *hh;
-
- /* drop all enqueued CCBs */
- for(h = softc->first_queued_hcb; h != NULL; h = hh) {
- hh = h->next;
- free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET);
- }
-
- /* the clean values of negotiations to report */
- neg.bus_width = 8;
- neg.sync_period = neg.sync_offset = 0;
- neg.valid = (CCB_TRANS_BUS_WIDTH_VALID
- | CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID);
-
- /* drop all disconnected CCBs and clean negotiations */
- for(targ=0; targ <= OUR_MAX_SUPPORTED_TARGET; targ++) {
- clean_negotiations(softc, targ);
-
- /* report the event if possible */
- if(xpt_create_path(&amp;path, /*periph*/NULL,
- cam_sim_path(sim), targ,
- CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
- xpt_async(AC_TRANSFER_NEG, path, &amp;neg);
- xpt_free_path(path);
- }
-
- for(lun=0; lun <= OUR_MAX_SUPPORTED_LUN; lun++)
- for(h = softc->first_discon_hcb[targ][lun]; h != NULL; h = hh) {
- hh=h->next;
- if(fatal)
- free_hcb_and_ccb_done(h, h->ccb, CAM_UNREC_HBA_ERROR);
- else
- free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET);
- }
- }
-
- /* report the event */
- xpt_async(AC_BUS_RESET, softc->wpath, NULL);
-
- /* re-initialization may take a lot of time, in such case
- * its completion should be signaled by another interrupt or
- * checked on timeout - but for simplicity we assume here that
- * it's really fast
- */
- if(!fatal) {
- reinitialize_controller_without_scsi_reset(softc);
- } else {
- reinitialize_controller_with_scsi_reset(softc);
- }
- schedule_next_hcb(softc);
- return;
- }</programlisting>
-
- <para>If interrupt is not caused by a controller-wide condition
- then probably something has happened to the current hardware
- control block. Depending on the hardware there may be other
- non-HCB-related events, we just do not consider them here. Then
- we analyze what happened to this HCB:</para>
-
-<programlisting> struct xxx_hcb *hcb, *h, *hh;
- int hcb_status, scsi_status;
- int ccb_status;
- int targ;
- int lun_to_freeze;
-
- hcb = get_current_hcb(softc);
- if(hcb == NULL) {
- /* either stray interrupt or something went very wrong
- * or this is something hardware-dependent
- */
- handle as necessary;
- return;
- }
-
- targ = hcb->target;
- hcb_status = get_status_of_current_hcb(softc);</programlisting>
-
- <para>First we check if the HCB has completed and if so we check
- the returned SCSI status.</para>
-
-<programlisting> if(hcb_status == COMPLETED) {
- scsi_status = get_completion_status(hcb);</programlisting>
-
- <para>Then look if this status is related to the REQUEST SENSE
- command and if so handle it in a simple way.</para>
-
-<programlisting> if(hcb->flags &amp; DOING_AUTOSENSE) {
- if(scsi_status == GOOD) { /* autosense was successful */
- hcb->ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
- free_hcb_and_ccb_done(hcb, hcb->ccb, CAM_SCSI_STATUS_ERROR);
- } else {
- autosense_failed:
- free_hcb_and_ccb_done(hcb, hcb->ccb, CAM_AUTOSENSE_FAIL);
- }
- schedule_next_hcb(softc);
- return;
- }</programlisting>
-
- <para>Else the command itself has completed, pay more attention to
- details. If auto-sense is not disabled for this CCB and the
- command has failed with sense data then run REQUEST SENSE
- command to receive that data.</para>
-
-<programlisting> hcb->ccb->csio.scsi_status = scsi_status;
- calculate_residue(hcb);
-
- if( (hcb->ccb->ccb_h.flags &amp; CAM_DIS_AUTOSENSE)==0
- &amp;&amp; ( scsi_status == CHECK_CONDITION
- || scsi_status == COMMAND_TERMINATED) ) {
- /* start auto-SENSE */
- hcb->flags |= DOING_AUTOSENSE;
- setup_autosense_command_in_hcb(hcb);
- restart_current_hcb(softc);
- return;
- }
- if(scsi_status == GOOD)
- free_hcb_and_ccb_done(hcb, hcb->ccb, CAM_REQ_CMP);
- else
- free_hcb_and_ccb_done(hcb, hcb->ccb, CAM_SCSI_STATUS_ERROR);
- schedule_next_hcb(softc);
- return;
- }</programlisting>
-
- <para>One typical thing would be negotiation events: negotiation
- messages received from a SCSI target (in answer to our
- negotiation attempt or by target's initiative) or the target is
- unable to negotiate (rejects our negotiation messages or does
- not answer them).</para>
-
-<programlisting> switch(hcb_status) {
- case TARGET_REJECTED_WIDE_NEG:
- /* revert to 8-bit bus */
- softc->current_bus_width[targ] = softc->goal_bus_width[targ] = 8;
- /* report the event */
- neg.bus_width = 8;
- neg.valid = CCB_TRANS_BUS_WIDTH_VALID;
- xpt_async(AC_TRANSFER_NEG, hcb->ccb.ccb_h.path_id, &amp;neg);
- continue_current_hcb(softc);
- return;
- case TARGET_ANSWERED_WIDE_NEG:
- {
- int wd;
-
- wd = get_target_bus_width_request(softc);
- if(wd <= softc->goal_bus_width[targ]) {
- /* answer is acceptable */
- softc->current_bus_width[targ] =
- softc->goal_bus_width[targ] = neg.bus_width = wd;
-
- /* report the event */
- neg.valid = CCB_TRANS_BUS_WIDTH_VALID;
- xpt_async(AC_TRANSFER_NEG, hcb->ccb.ccb_h.path_id, &amp;neg);
- } else {
- prepare_reject_message(hcb);
- }
- }
- continue_current_hcb(softc);
- return;
- case TARGET_REQUESTED_WIDE_NEG:
- {
- int wd;
-
- wd = get_target_bus_width_request(softc);
- wd = min (wd, OUR_BUS_WIDTH);
- wd = min (wd, softc->user_bus_width[targ]);
-
- if(wd != softc->current_bus_width[targ]) {
- /* the bus width has changed */
- softc->current_bus_width[targ] =
- softc->goal_bus_width[targ] = neg.bus_width = wd;
-
- /* report the event */
- neg.valid = CCB_TRANS_BUS_WIDTH_VALID;
- xpt_async(AC_TRANSFER_NEG, hcb->ccb.ccb_h.path_id, &amp;neg);
- }
- prepare_width_nego_rsponse(hcb, wd);
- }
- continue_current_hcb(softc);
- return;
- }</programlisting>
-
- <para>Then we handle any errors that could have happened during
- auto-sense in the same simple-minded way as before. Otherwise we
- look closer at the details again.</para>
-
-<programlisting> if(hcb->flags &amp; DOING_AUTOSENSE)
- goto autosense_failed;
-
- switch(hcb_status) {</programlisting>
-
- <para>The next event we consider is unexpected disconnect. Which
- is considered normal after an ABORT or BUS DEVICE RESET message
- and abnormal in other cases.</para>
-
-<programlisting> case UNEXPECTED_DISCONNECT:
- if(requested_abort(hcb)) {
- /* abort affects all commands on that target+LUN, so
- * mark all disconnected HCBs on that target+LUN as aborted too
- */
- for(h = softc->first_discon_hcb[hcb->target][hcb->lun];
- h != NULL; h = hh) {
- hh=h->next;
- free_hcb_and_ccb_done(h, h->ccb, CAM_REQ_ABORTED);
- }
- ccb_status = CAM_REQ_ABORTED;
- } else if(requested_bus_device_reset(hcb)) {
- int lun;
-
- /* reset affects all commands on that target, so
- * mark all disconnected HCBs on that target+LUN as reset
- */
-
- for(lun=0; lun <= OUR_MAX_SUPPORTED_LUN; lun++)
- for(h = softc->first_discon_hcb[hcb->target][lun];
- h != NULL; h = hh) {
- hh=h->next;
- free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET);
- }
-
- /* send event */
- xpt_async(AC_SENT_BDR, hcb->ccb->ccb_h.path_id, NULL);
-
- /* this was the CAM_RESET_DEV request itself, it's completed */
- ccb_status = CAM_REQ_CMP;
- } else {
- calculate_residue(hcb);
- ccb_status = CAM_UNEXP_BUSFREE;
- /* request the further code to freeze the queue */
- hcb->ccb->ccb_h.status |= CAM_DEV_QFRZN;
- lun_to_freeze = hcb->lun;
- }
- break;</programlisting>
-
- <para>If the target refuses to accept tags we notify CAM about
- that and return back all commands for this LUN:</para>
-
-<programlisting> case TAGS_REJECTED:
- /* report the event */
- neg.flags = 0 &amp; ~CCB_TRANS_TAG_ENB;
- neg.valid = CCB_TRANS_TQ_VALID;
- xpt_async(AC_TRANSFER_NEG, hcb->ccb.ccb_h.path_id, &amp;neg);
-
- ccb_status = CAM_MSG_REJECT_REC;
- /* request the further code to freeze the queue */
- hcb->ccb->ccb_h.status |= CAM_DEV_QFRZN;
- lun_to_freeze = hcb->lun;
- break;</programlisting>
-
- <para>Then we check a number of other conditions, with processing
- basically limited to setting the CCB status:</para>
-
-<programlisting> case SELECTION_TIMEOUT:
- ccb_status = CAM_SEL_TIMEOUT;
- /* request the further code to freeze the queue */
- hcb->ccb->ccb_h.status |= CAM_DEV_QFRZN;
- lun_to_freeze = CAM_LUN_WILDCARD;
- break;
- case PARITY_ERROR:
- ccb_status = CAM_UNCOR_PARITY;
- break;
- case DATA_OVERRUN:
- case ODD_WIDE_TRANSFER:
- ccb_status = CAM_DATA_RUN_ERR;
- break;
- default:
- /* all other errors are handled in a generic way */
- ccb_status = CAM_REQ_CMP_ERR;
- /* request the further code to freeze the queue */
- hcb->ccb->ccb_h.status |= CAM_DEV_QFRZN;
- lun_to_freeze = CAM_LUN_WILDCARD;
- break;
- }</programlisting>
-
- <para>Then we check if the error was serious enough to freeze the
- input queue until it gets proceeded and do so if it is:</para>
-
-<programlisting> if(hcb->ccb->ccb_h.status &amp; CAM_DEV_QFRZN) {
- /* freeze the queue */
- xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
-
- /* re-queue all commands for this target/LUN back to CAM */
-
- for(h = softc->first_queued_hcb; h != NULL; h = hh) {
- hh = h->next;
-
- if(targ == h->targ
- &amp;&amp; (lun_to_freeze == CAM_LUN_WILDCARD || lun_to_freeze == h->lun) )
- free_hcb_and_ccb_done(h, h->ccb, CAM_REQUEUE_REQ);
- }
- }
- free_hcb_and_ccb_done(hcb, hcb->ccb, ccb_status);
- schedule_next_hcb(softc);
- return;</programlisting>
-
- <para>This concludes the generic interrupt handling although
- specific controllers may require some additions.</para>
-
- </sect1>
-
- <sect1>
- <title>Errors Summary</title>
-
- <para>When executing an I/O request many things may go wrong. The
- reason of error can be reported in the CCB status with great
- detail. Examples of use are spread throughout this document. For
- completeness here is the summary of recommended responses for
- the typical error conditions:</para>
-
- <itemizedlist>
-
- <listitem><para><emphasis>CAM_RESRC_UNAVAIL</emphasis> - some
- resource is temporarily unavailable and the SIM driver cannot
- generate an event when it will become available. An example of
- this resource would be some intra-controller hardware resource
- for which the controller does not generate an interrupt when
- it becomes available.</para></listitem>
-
- <listitem><para><emphasis>CAM_UNCOR_PARITY</emphasis> -
- unrecovered parity error occurred</para></listitem>
-
- <listitem><para><emphasis>CAM_DATA_RUN_ERR</emphasis> - data
- overrun or unexpected data phase (going in other direction
- than specified in CAM_DIR_MASK) or odd transfer length for
- wide transfer</para></listitem>
-
- <listitem><para><emphasis>CAM_SEL_TIMEOUT</emphasis> - selection
- timeout occurred (target does not respond)</para></listitem>
-
- <listitem><para><emphasis>CAM_CMD_TIMEOUT</emphasis> - command
- timeout occurred (the timeout function ran)</para></listitem>
-
- <listitem><para><emphasis>CAM_SCSI_STATUS_ERROR</emphasis> - the
- device returned error</para></listitem>
-
- <listitem><para><emphasis>CAM_AUTOSENSE_FAIL</emphasis> - the
- device returned error and the REQUEST SENSE COMMAND
- failed</para></listitem>
-
- <listitem><para><emphasis>CAM_MSG_REJECT_REC</emphasis> - MESSAGE
- REJECT message was received</para></listitem>
-
- <listitem><para><emphasis>CAM_SCSI_BUS_RESET</emphasis> - received
- SCSI bus reset</para></listitem>
-
- <listitem><para><emphasis>CAM_REQ_CMP_ERR</emphasis> -
- <quote>impossible</quote> SCSI phase occurred or something else as weird or
- just a generic error if further detail is not
- available</para></listitem>
-
- <listitem><para><emphasis>CAM_UNEXP_BUSFREE</emphasis> -
- unexpected disconnect occurred</para></listitem>
-
- <listitem><para><emphasis>CAM_BDR_SENT</emphasis> - BUS DEVICE
- RESET message was sent to the target</para></listitem>
-
- <listitem><para><emphasis>CAM_UNREC_HBA_ERROR</emphasis> -
- unrecoverable Host Bus Adapter Error</para></listitem>
-
- <listitem><para><emphasis>CAM_REQ_TOO_BIG</emphasis> - the request
- was too large for this controller</para></listitem>
-
- <listitem><para><emphasis>CAM_REQUEUE_REQ</emphasis> - this
- request should be re-queued to preserve transaction ordering.
- This typically occurs when the SIM recognizes an error that
- should freeze the queue and must place other queued requests
- for the target at the sim level back into the XPT
- queue. Typical cases of such errors are selection timeouts,
- command timeouts and other like conditions. In such cases the
- troublesome command returns the status indicating the error,
- the and the other commands which have not be sent to the bus
- yet get re-queued.</para></listitem>
-
- <listitem><para><emphasis>CAM_LUN_INVALID</emphasis> - the LUN
- ID in the request is not supported by the SCSI
- controller</para></listitem>
-
- <listitem><para><emphasis>CAM_TID_INVALID</emphasis> - the
- target ID in the request is not supported by the SCSI
- controller</para></listitem>
- </itemizedlist>
- </sect1>
-
- <sect1>
- <title>Timeout Handling</title>
-
- <para>When the timeout for an HCB expires that request should be
- aborted, just like with an XPT_ABORT request. The only
- difference is that the returned status of aborted request should
- be CAM_CMD_TIMEOUT instead of CAM_REQ_ABORTED (that is why
- implementation of the abort better be done as a function). But
- there is one more possible problem: what if the abort request
- itself will get stuck? In this case the SCSI bus should be
- reset, just like with an XPT_RESET_BUS request (and the idea
- about implementing it as a function called from both places
- applies here too). Also we should reset the whole SCSI bus if a
- device reset request got stuck. So after all the timeout
- function would look like:</para>
-
-<programlisting>static void
-xxx_timeout(void *arg)
-{
- struct xxx_hcb *hcb = (struct xxx_hcb *)arg;
- struct xxx_softc *softc;
- struct ccb_hdr *ccb_h;
-
- softc = hcb->softc;
- ccb_h = &amp;hcb->ccb->ccb_h;
-
- if(hcb->flags &amp; HCB_BEING_ABORTED
- || ccb_h->func_code == XPT_RESET_DEV) {
- xxx_reset_bus(softc);
- } else {
- xxx_abort_ccb(hcb->ccb, CAM_CMD_TIMEOUT);
- }
-}</programlisting>
-
- <para>When we abort a request all the other disconnected requests
- to the same target/LUN get aborted too. So there appears a
- question, should we return them with status CAM_REQ_ABORTED or
- CAM_CMD_TIMEOUT? The current drivers use CAM_CMD_TIMEOUT. This
- seems logical because if one request got timed out then probably
- something really bad is happening to the device, so if they
- would not be disturbed they would time out by themselves.</para>
-
- </sect1>
-
-</chapter>
diff --git a/en_US.ISO8859-1/books/arch-handbook/sound/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/sound/chapter.sgml
deleted file mode 100644
index 38f39f1e78..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/sound/chapter.sgml
+++ /dev/null
@@ -1,687 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="oss">
- <chapterinfo>
- <authorgroup>
- <author>
- <firstname>Jean-Francois</firstname>
- <surname>Dockes</surname>
- <contrib>Contributed by </contrib>
- </author>
- </authorgroup>
- <!-- 23 November 2001 -->
- </chapterinfo>
-
- <title>Sound subsystem</title>
-
- <sect1>
- <title>Introduction</title>
-
- <para>The FreeBSD sound subsystem cleanly separates generic sound
- handling issues from device-specific ones. This makes it easier
- to add support for new hardware.</para>
-
- <para>The &man.pcm.4; framework is the central piece of the sound
- subsystem. It mainly implements the following elements:</para>
-
- <itemizedlist>
- <listitem>
- <para>A system call interface (read, write, ioctls) to
- digitized sound and mixer functions. The ioctl command set
- is compatible with the legacy <emphasis>OSS</emphasis> or
- <emphasis>Voxware</emphasis> interface, allowing common
- multimedia applications to be ported without
- modification.</para>
- <listitem>
- <para>Common code for processing sound data (format
- conversions, virtual channels).</para>
- </listitem>
- <listitem>
- <para>A uniform software interface to hardware-specific audio
- interface modules.</para>
- </listitem>
- <listitem>
- <para>Additional support for some common hardware interfaces
- (ac97), or shared hardware-specific code (ex: ISA DMA
- routines).</para>
- </listitem>
- </itemizedlist>
-
- <para>The support for specific sound cards is implemented by
- hardware-specific drivers, which provide channel and mixer interfaces
- to plug into the generic <devicename>pcm</devicename> code.</para>
-
- <para>In this chapter, the term <devicename>pcm</devicename> will
- refer to the central, common part of the sound driver, as
- opposed to the hardware-specific modules.</para>
-
- <para>The prospective driver writer will of course want to start
- from an existing module and use the code as the ultimate
- reference. But, while the sound code is nice and clean, it is
- also mostly devoid of comments. This document tries to give an
- overview of the framework interface and answer some questions
- that may arise while adapting the existing code.</para>
-
- <para>As an alternative, or in addition to starting from a working
- example, you can find a commented driver template at
- <ulink url="http://people.freebsd.org/~cg/template.c">
- http://people.freebsd.org/~cg/template.c</ulink></para>
-
- </sect1>
-
- <sect1>
- <title>Files</title>
-
- <para>All the relevant code currently (FreeBSD 4.4) lives in
- <filename>/usr/src/sys/dev/sound/</filename>, except for the
- public ioctl interface definitions, found in
- <filename>/usr/src/sys/sys/soundcard.h</filename></para>
-
- <para>Under <filename>/usr/src/sys/dev/sound/</filename>, the
- <filename>pcm/</filename> directory holds the central code,
- while the <filename>isa/</filename> and
- <filename>pci/</filename> directories have the drivers for ISA
- and PCI boards.</para>
-
- </sect1>
-
- <sect1 id="pcm-probe-and-attach">
- <title>Probing, attaching, etc.</title>
-
- <para>Sound drivers probe and attach in almost the same way as any
- hardware driver module. You might want to look at the <link
- linkend="isa-driver"> ISA</link> or <link
- linkend="pci">PCI</link> specific sections of the handbook for
- more information.</para>
-
- <para>However, sound drivers differ in some ways:</para>
-
- <itemizedlist>
-
- <listitem>
- <para>They declare themselves as <devicename>pcm</devicename>
- class devices, with a <structname>struct
- snddev_info</structname> device private structure:</para>
-
- <programlisting> static driver_t xxx_driver = {
- "pcm",
- xxx_methods,
- sizeof(struct snddev_info)
- };
-
- DRIVER_MODULE(snd_xxxpci, pci, xxx_driver, pcm_devclass, 0, 0);
- MODULE_DEPEND(snd_xxxpci, snd_pcm, PCM_MINVER, PCM_PREFVER,PCM_MAXVER);</programlisting>
-
- <para>Most sound drivers need to store additional private
- information about their device. A private data structure is
- usually allocated in the attach routine. Its address is
- passed to <devicename>pcm</devicename> by the calls to
- <function>pcm_register()</function> and
- <function>mixer_init()</function>.
- <devicename>pcm</devicename> later passes back this address
- as a parameter in calls to the sound driver
- interfaces.</para>
- </listitem>
-
- <listitem>
- <para>The sound driver attach routine should declare its MIXER
- or AC97 interface to <devicename>pcm</devicename> by calling
- <function>mixer_init()</function>. For a MIXER interface,
- this causes in turn a call to <link linkend="xxxmixer-init">
- <function>xxxmixer_init()</function></link>.</para>
- </listitem>
-
- <listitem>
- <para>The sound driver attach routine declares its general
- CHANNEL configuration to <devicename>pcm</devicename> by
- calling <function>pcm_register(dev, sc, nplay,
- nrec)</function>, where <varname>sc</varname> is the address
- for the device data structure, used in further calls from
- <devicename>pcm</devicename>, and <varname>nplay</varname>
- and <varname>nrec</varname> are the number of play and
- record channels.</para>
- </listitem>
-
- <listitem>
- <para>The sound driver attach routine declares each of its
- channel objects by calls to
- <function>pcm_addchan()</function>. This sets up the
- channel glue in <devicename>pcm</devicename> and causes in
- turn a call to
- <link linkend="xxxchannel-init">
- <function>xxxchannel_init()</function></link>.</para>
- </listitem>
-
- <listitem>
- <para>The sound driver detach routine should call
- <function>pcm_unregister()</function> before releasing its
- resources.</para>
- </listitem>
- </itemizedlist>
-
- <para>There are two possible methods to handle non-PnP devices:</para>
- <itemizedlist>
- <listitem>
- <para>Use a <function>device_identify()</function> method
- (example: <filename>sound/isa/es1888.c</filename>). The
- <function>device_identify()</function> method probes for the
- hardware at known addresses and, if it finds a supported
- device, creates a new pcm device which is then passed to
- probe/attach.</para>
- </listitem>
- <listitem>
- <para>Use a custom kernel configuration with appropriate hints
- for pcm devices (example:
- <filename>sound/isa/mss.c</filename>).</para>
- </listitem>
- </itemizedlist>
-
- <para><devicename>pcm</devicename> drivers should implement
- <function>device_suspend</function>,
- <function>device_resume</function> and
- <function>device_shutdown</function> routines, so that power
- management and module unloading function correctly.</para>
-
- </sect1>
-
- <sect1>
- <title>Interfaces</title>
-
- <para>The interface between the <devicename>pcm</devicename> core
- and the sound drivers is defined in terms of <link
- linkend="kernel-objects">kernel objects</link>.</para>
-
- <para>There are two main interfaces that a sound driver will
- usually provide: <emphasis>CHANNEL</emphasis> and either
- <emphasis>MIXER</emphasis> or <emphasis>AC97</emphasis>.</para>
-
- <para>The <emphasis>AC97</emphasis> interface is a very small
- hardware access (register read/write) interface, implemented by
- drivers for hardware with an AC97 codec. In this case, the
- actual MIXER interface is provided by the shared AC97 code in
- <devicename>pcm</devicename>.</para>
-
- <sect2>
- <title>The CHANNEL interface</title>
-
- <sect3>
- <title>Common notes for function parameters</title>
-
- <para>Sound drivers usually have a private data structure to
- describe their device, and one structure for each play and
- record data channel that it supports.</para>
-
- <para>For all CHANNEL interface functions, the first parameter
- is an opaque pointer.</para>
-
- <para>The second parameter is a pointer to the private
- channel data structure, except for
- <function>channel_init()</function> which has a pointer to the
- private device structure (and returns the channel pointer
- for further use by <devicename>pcm</devicename>).</para>
-
- </sect3>
-
- <sect3>
- <title>Overview of data transfer operations</title>
-
- <para>For sound data transfers, the
- <devicename>pcm</devicename> core and the sound drivers
- communicate through a shared memory area, described by a
- <structname>struct snd_dbuf</structname>.</para>
-
- <para><structname>struct snd_dbuf</structname> is private to
- <devicename>pcm</devicename>, and sound drivers obtain
- values of interest by calls to accessor functions
- (<function>sndbuf_getxxx()</function>).</para>
-
- <para>The shared memory area has a size of
- <function>sndbuf_getsize()</function> and is divided into
- fixed size blocks of <function>sndbuf_getblksz()</function>
- bytes.</para>
-
- <para>When playing, the general transfer mechanism is as
- follows (reverse the idea for recording):</para>
-
- <itemizedlist>
- <listitem>
- <para><devicename>pcm</devicename> initially fills up the
- buffer, then calls the sound driver's <link
- linkend="channel-trigger">
- <function>xxxchannel_trigger()</function></link>
- function with a parameter of PCMTRIG_START.</para>
- </listitem>
-
- <listitem>
- <para>The sound driver then arranges to repeatedly
- transfer the whole memory area
- (<function>sndbuf_getbuf()</function>,
- <function>sndbuf_getsize()</function>) to the device, in
- blocks of <function>sndbuf_getblksz()</function> bytes.
- It calls back the <function>chn_intr()</function>
- <devicename>pcm</devicename> function for each
- transferred block (this will typically happen at
- interrupt time).</para>
- </listitem>
-
- <listitem>
- <para><function>chn_intr()</function> arranges to copy new
- data to the area that was transferred to the device (now
- free), and make appropriate updates to the
- <structname>snd_dbuf</structname> structure.</para>
- </listitem>
-
- </itemizedlist>
-
- <sect3 id="xxxchannel-init">
- <title>channel_init</title>
-
- <para><function>xxxchannel_init()</function> is called to
- initialize each of the play or record channels. The calls
- are initiated from the sound driver attach routine. (See
- the <link linkend="pcm-probe-and-attach">probe and attach
- section</link>).</para>
-
- <programlisting> static void *
- xxxchannel_init(kobj_t obj, void *data,
- struct snd_dbuf *b, struct pcm_channel *c, int dir)<co id="co-chinit-params">
- {
- struct xxx_info *sc = data;
- struct xxx_chinfo *ch;
- ...
- return ch;<co id="co-chinit-return">
- }</programlisting>
-
- <calloutlist>
-
- <callout arearefs="co-chinit-params">
- <para><varname>b</varname> is the address for the channel
- <structname>struct snd_dbuf</structname>. It should be
- initialized in the function by calling
- <function>sndbuf_alloc()</function>. The buffer size to
- use is normally a small multiple of the 'typical' unit
- transfer size for your device.</para>
-
- <para><varname>c</varname> is the
- <devicename>pcm</devicename> channel control structure
- pointer. This is an opaque object. The function should
- store it in the local channel structure, to be used in
- later calls to <devicename>pcm</devicename> (ie:
- <function>chn_intr(c)</function>).</para>
-
- <para><varname>dir</varname> indicates the channel
- direction (<literal>PCMDIR_PLAY</literal> or
- <literal>PCMDIR_REC</literal>).</para>
- </callout>
-
- <callout arearefs="co-chinit-return">
- <para>The function should return a pointer to the private
- area used to control this channel. This will be passed
- as a parameter to other channel interface calls.</para>
- </callout>
-
- </calloutlist>
-
- </sect3>
-
- <sect3>
- <title>channel_setformat</title>
-
- <para><function>xxxchannel_setformat()</function> should set
- up the hardware for the specified channel for the specified
- sound format.</para>
-
- <programlisting> static int
- xxxchannel_setformat(kobj_t obj, void *data, u_int32_t format)<co id="co-chsetformat-params">
- {
- struct xxx_chinfo *ch = data;
- ...
- return 0;
- }</programlisting>
-
- <calloutlist>
- <callout arearefs="co-chsetformat-params">
- <para><varname>format</varname> is specified as an
- <literal>AFMT_XXX value</literal>
- (<filename>soundcard.h</filename>).</para>
- </callout>
-
- </calloutlist>
- </sect3>
-
- <sect3>
- <title>channel_setspeed</title>
-
- <para><function>xxxchannel_setspeed()</function> sets up the
- channel hardware for the specified sampling speed, and
- returns the possibly adjusted speed.</para>
-
- <programlisting> static int
- xxxchannel_setspeed(kobj_t obj, void *data, u_int32_t speed)
- {
- struct xxx_chinfo *ch = data;
- ...
- return speed;
- }</programlisting>
-
- </sect3>
-
- <sect3>
- <title>channel_setblocksize</title>
-
- <para><function>xxxchannel_setblocksize()</function> sets the
- block size, which is the size of unit transactions between
- <devicename>pcm</devicename> and the sound driver, and
- between the sound driver and the device. Typically, this
- would be the number of bytes transferred before an interrupt
- occurs. During a transfer, the sound driver should call
- <devicename>pcm</devicename>'s
- <function>chn_intr()</function> every time this size has
- been transferred.</para>
-
- <para>Most sound drivers only take note of the block size
- here, to be used when an actual transfer will be
- started.</para>
-
- <programlisting> static int
- xxxchannel_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
- {
- struct xxx_chinfo *ch = data;
- ...
- return blocksize;<co id="co-chsetblocksize-return">
- }</programlisting>
-
- <calloutlist>
- <callout arearefs="co-chsetblocksize-return">
- <para>The function returns the possibly adjusted block
- size. In case the block size is indeed changed,
- <function>sndbuf_resize()</function> should be called to
- adjust the buffer.</para>
-
- </callout>
- </calloutlist>
-
- </sect3>
-
- <sect3 id="channel-trigger">
- <title>channel_trigger</title>
-
- <para><function>xxxchannel_trigger()</function> is called by
- <devicename>pcm</devicename> to control data transfer
- operations in the driver.</para>
-
- <programlisting> static int
- xxxchannel_trigger(kobj_t obj, void *data, int go)<co id="co-chtrigger-params">
- {
- struct xxx_chinfo *ch = data;
- ...
- return 0;
- }</programlisting>
-
- <calloutlist>
- <callout arearefs="co-chtrigger-params">
- <para><varname>go</varname> defines the action for the
- current call. The possible values are:</para>
- <itemizedlist>
-
- <listitem>
- <para><literal>PCMTRIG_START</literal>: the driver
- should start a data transfer from or to the channel
- buffer. If needed, the buffer base and size can be
- retrieved through
- <function>sndbuf_getbuf()</function> and
- <function>sndbuf_getsize()</function>.</para>
- </listitem>
-
- <listitem>
- <para><literal>PCMTRIG_EMLDMAWR</literal> /
- <literal>PCMTRIG_EMLDMARD</literal>: this tells the
- driver that the input or output buffer may have been
- updated. Most drivers just ignore these
- calls.</para>
- </listitem>
-
- <listitem>
- <para><literal>PCMTRIG_STOP</literal> /
- <literal>PCMTRIG_ABORT</literal>: the driver should
- stop the current transfer.</para>
- </listitem>
- </itemizedlist>
-
- </callout>
- </calloutlist>
-
- <note><para>If the driver uses ISA DMA,
- <function>sndbuf_isadma()</function> should be called before
- performing actions on the device, and will take care of the
- DMA chip side of things.</para>
- </note>
-
- </sect3>
-
- <sect3>
- <title>channel_getptr</title>
-
- <para><function>xxxchannel_getptr()</function> returns the
- current offset in the transfer buffer. This will typically
- be called by <function>chn_intr()</function>, and this is how
- <devicename>pcm</devicename> knows where it can transfer
- new data.</para>
-
- </sect3>
-
- <sect3>
- <title>channel_free</title>
-
- <para><function>xxxchannel_free()</function> is called to free
- up channel resources, for example when the driver is
- unloaded, and should be implemented if the channel data
- structures are dynamically allocated or if
- <function>sndbuf_alloc()</function> was not used for buffer
- allocation.</para>
-
- </sect3>
-
- <sect3>
- <title>channel_getcaps</title>
-
- <programlisting> struct pcmchan_caps *
- xxxchannel_getcaps(kobj_t obj, void *data)
- {
- return &amp;xxx_caps;<co id="co-chgetcaps-return">
- }</programlisting>
-
- <calloutlist>
-
- <callout arearefs="co-chgetcaps-return">
- <para>The routine returns a pointer to a (usually
- statically-defined) <structname>pcmchan_caps</structname>
- structure (defined in
- <filename>sound/pcm/channel.h</filename>. The structure holds
- the minimum and maximum sampling frequencies, and the
- accepted sound formats. Look at any sound driver for an
- example.</para>
- </callout>
-
- </calloutlist>
-
- </sect3>
-
- <sect3>
- <title>More functions</title>
-
- <para><function>channel_reset()</function>,
- <function>channel_resetdone()</function>, and
- <function>channel_notify()</function> are for special purposes
- and should not be implemented in a driver without discussing
- it with the authorities (&a.cg;).</para>
-
- <para><function>channel_setdir()</function> is deprecated.</para>
- </sect3>
-
- </sect2>
-
- <sect2>
- <title>The MIXER interface</title>
-
- <sect3 id="xxxmixer-init">
- <title>mixer_init</title>
-
- <para><function>xxxmixer_init()</function> initializes the
- hardware and tells <devicename>pcm</devicename> what mixer
- devices are available for playing and recording</para>
-
- <programlisting> static int
- xxxmixer_init(struct snd_mixer *m)
- {
- struct xxx_info *sc = mix_getdevinfo(m);
- u_int32_t v;
-
- [Initialize hardware]
-
- [Set appropriate bits in v for play mixers]<co id="co-mxini-sd">
- mix_setdevs(m, v);
- [Set appropriate bits in v for record mixers]
- mix_setrecdevs(m, v)
-
- return 0;
- }</programlisting>
-
- <calloutlist>
- <callout arearefs="co-mxini-sd">
- <para>Set bits in an integer value and call
- <function>mix_setdevs()</function> and
- <function>mix_setrecdevs()</function> to tell
- <devicename>pcm</devicename> what devices exist.</para>
- </callout>
- </calloutlist>
-
- <para>Mixer bits definitions can be found in
- <filename>soundcard.h</filename>
- (<literal>SOUND_MASK_XXX</literal> values and
- <literal>SOUND_MIXER_XXX</literal> bit shifts).</para>
-
- </sect3>
-
- <sect3>
- <title>mixer_set</title>
-
- <para><function>xxxmixer_set()</function> sets the volume
- level for one mixer device.</para>
-
- <programlisting> static int
- xxxmixer_set(struct snd_mixer *m, unsigned dev,
- unsigned left, unsigned right)<co id="co-mxset-params">
- {
- struct sc_info *sc = mix_getdevinfo(m);
- [set volume level]
- return left | (right << 8);<co id="co-mxset-return">
- }</programlisting>
-
- <calloutlist>
- <callout arearefs="co-mxset-params">
- <para>The device is specified as a SOUND_MIXER_XXX
- value</para> <para>The volume values are specified in
- range [0-100]. A value of zero should mute the
- device.</para>
- </callout>
-
- <callout arearefs="co-mxset-return">
- <para>As the hardware levels probably won't match the
- input scale, and some rounding will occur, the routine
- returns the actual level values (in range 0-100) as
- shown.</para>
- </callout>
- </calloutlist>
-
- </sect3>
-
- <sect3>
- <title>mixer_setrecsrc</title>
-
- <para><function>xxxmixer_setrecsrc()</function> sets the
- recording source device.</para>
-
- <programlisting> static int
- xxxmixer_setrecsrc(struct snd_mixer *m, u_int32_t src)<co id="co-mxsr-params">
- {
- struct xxx_info *sc = mix_getdevinfo(m);
-
- [look for non zero bit(s) in src, set up hardware]
-
- [update src to reflect actual action]
- return src;<co id="co-mxsr-return">
- }</programlisting>
-
- <calloutlist>
- <callout arearefs="co-mxsr-params">
- <para>The desired recording devices are specified as a
- bit field</para>
- </callout>
-
- <callout arearefs="co-mxsr-return">
- <para>The actual devices set for recording are returned.
- Some drivers can only set one device for recording. The
- function should return -1 if an error occurs.</para>
- </callout>
- </calloutlist>
- </sect3>
-
- <sect3>
- <title>mixer_uninit, mixer_reinit</title>
-
- <para><function>xxxmixer_uninit()</function> should ensure
- that all sound is muted and if possible mixer hardware
- should be powered down </para>
-
- <para><function>xxxmixer_reinit()</function> should ensure
- that the mixer hardware is powered up and any settings not
- controlled by <function>mixer_set()</function> or
- <function>mixer_setrecsrc()</function> are restored.</para>
-
- </sect3>
- </sect2>
-
- <sect2>
- <title>The AC97 interface</title>
-
- <para>The <emphasis>AC97</emphasis> interface is implemented
- by drivers with an AC97 codec. It only has three methods:</para>
-
- <itemizedlist>
-
- <listitem><para><function>xxxac97_init()</function> returns
- the number of ac97 codecs found.</para>
- </listitem>
-
- <listitem><para><function>ac97_read()</function> and
- <function>ac97_write()</function> read or write a specified
- register.</para>
- </listitem>
-
- </itemizedlist>
-
- <para>The <emphasis>AC97</emphasis> interface is used by the
- AC97 code in <devicename>pcm</devicename> to perform higher
- level operations. Look at
- <filename>sound/pci/maestro3.c</filename> or many others under
- <filename>sound/pci/</filename> for an example.</para>
-
- </sect2>
- </sect1>
-</chapter>
-
-<!--
- Local Variables:
- mode: sgml
- sgml-declaration: "../chapter.decl"
- sgml-indent-data: t
- sgml-omittag: nil
- sgml-always-quote-attributes: t
- sgml-parent-document: ("../book.sgml" "part" "chapter")
- End:
--->
diff --git a/en_US.ISO8859-1/books/arch-handbook/sysinit/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/sysinit/chapter.sgml
deleted file mode 100644
index 1b8a0b4cdb..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/sysinit/chapter.sgml
+++ /dev/null
@@ -1,161 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="sysinit">
- <title>The Sysinit Framework</title>
-
- <para>Sysinit is the framework for a generic call sort and dispatch
- mechanism. FreeBSD currently uses it for the dynamic
- initialization of the kernel. Sysinit allows FreeBSD's kernel
- subsystems to be reordered, and added, removed, and replaced at
- kernel link time when the kernel or one of its modules is loaded
- without having to edit a statically ordered initialization routing
- and recompile the kernel. This system also allows kernel modules,
- currently called <firstterm>KLD's</firstterm>, to be separately
- compiled, linked, and initialized at boot time and loaded even
- later while the system is already running. This is accomplished
- using the <quote>kernel linker</quote> and <quote>linker
- sets</quote>.</para>
-
- <sect1>
- <title>Terminology</title>
-
- <variablelist>
- <varlistentry>
- <term>Linker Set</term>
- <listitem>
- <para>A linker technique in which the linker gathers
- statically declared data throughout a program's source files
- into a single contiguously addressable unit of
- data.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </sect1>
-
- <sect1>
- <title>Sysinit Operation</title>
-
- <para>Sysinit relies on the ability of the linker to take static
- data declared at multiple locations throughout a program's
- source and group it together as a single contiguous chunk of
- data. This linker technique is called a <quote>linker
- set</quote>. Sysinit uses two linker sets to maintain two data
- sets containing each consumer's call order, function, and a
- pointer to the data to pass to that function.</para>
-
- <para>Sysinit uses two priorities when ordering the functions for
- execution. The first priority is a subsystem ID giving an
- overall order Sysinit's dispatch of functions. Current predeclared
- ID's are in <filename>&lt;sys/kernel.h></filename> in the enum
- list <literal>sysinit_sub_id</literal>. The second priority used
- is an element order within the subsystem. Current predeclared
- subsystem element orders are in
- <filename>&lt;sys/kernel.h></filename> in the enum list
- <literal>sysinit_elem_order</literal>.</para>
-
- <para>There are currently two uses for Sysinit. Function dispatch
- at system startup and kernel module loads, and function dispatch
- at system shutdown and kernel module unload.</para>
- </sect1>
-
-
- <sect1>
- <title>Using Sysinit</title>
-
- <sect2>
- <title>Interface</title>
-
- <sect3>
- <title>Headers</title>
-
- <programlisting>&lt;sys/kernel.h></programlisting>
- </sect3>
-
- <sect3>
- <title>Macros</title>
-
- <programlisting>SYSINIT(uniquifier, subsystem, order, func, ident)
- SYSUNINIT(uniquifier, subsystem, order, func, ident)</programlisting>
- </sect3>
- </sect2>
-
- <sect2>
- <title>Startup</title>
-
- <para>The <literal>SYSINIT()</literal> macro creates the
- necessary sysinit data in Sysinit's startup data set for
- Sysinit to sort and dispatch a function at system startup and
- module load. <literal>SYSINIT()</literal> takes a uniquifier
- that Sysinit uses identify the particular function dispatch
- data, the subsystem order, the subsystem element order, the
- function to call, and the data to pass the function. All
- functions must take a constant pointer argument.
- </para>
-
- <para>For example:</para>
-
- <programlisting>#include &lt;sys/kernel.h>
-
-void foo_null(void *unused)
-{
- foo_doo();
-}
-SYSINIT(foo_null, SI_SUB_FOO, SI_ORDER_FOO, NULL);
-
-struct foo foo_voodoo = {
- FOO_VOODOO;
-}
-
-void foo_arg(void *vdata)
-{
- struct foo *foo = (struct foo *)vdata;
- foo_data(foo);
-}
-SYSINIT(foo_arg, SI_SUB_FOO, SI_ORDER_FOO, foo_voodoo);
- </programlisting>
- </sect2>
-
- <sect2>
- <title>Shutdown</title>
-
- <para>The <literal>SYSUNINIT()</literal> macro behaves similarly
- to the <literal>SYSINIT()</literal> macro except that it adds
- the Sysinit data to Sysinit's shutdown data set.</para>
-
- <para>For example:</para>
-
- <programlisting>#include &lt;sys/kernel.h>
-
-void foo_cleanup(void *unused)
-{
- foo_kill();
-}
-SYSUNINIT(foo_cleanup, SI_SUB_FOO, SI_ORDER_FOO, NULL);
-
-struct foo_stack foo_stack = {
- FOO_STACK_VOODOO;
-}
-
-void foo_flush(void *vdata)
-{
-}
-SYSUNINIT(foo_flush, SI_SUB_FOO, SI_ORDER_FOO, foo_stack);
- </programlisting>
- </sect2>
- </sect1>
-</chapter>
-
-<!--
- Local Variables:
- mode: sgml
- sgml-declaration: "../chapter.decl"
- sgml-indent-data: t
- sgml-omittag: nil
- sgml-always-quote-attributes: t
- sgml-parent-document: ("../book.sgml" "part" "chapter")
- End:
--->
diff --git a/en_US.ISO8859-1/books/arch-handbook/usb/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/usb/chapter.sgml
deleted file mode 100644
index 3a483a1cf7..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/usb/chapter.sgml
+++ /dev/null
@@ -1,623 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="usb">
- <title>USB Devices</title>
-
- <para><emphasis>This chapter was written by &a.nhibma;. Modifications made for
- the handbook by &a.murray;.</emphasis></para>
-
- <sect1>
- <title>Introduction</title>
-
- <para>The Universal Serial Bus (USB) is a new way of attaching
- devices to personal computers. The bus architecture features
- two-way communication and has been developed as a response to
- devices becoming smarter and requiring more interaction with the
- host. USB support is included in all current PC chipsets and is
- therefore available in all recently built PCs. Apple's
- introduction of the USB-only iMac has been a major incentive for
- hardware manufacturers to produce USB versions of their devices.
- The future PC specifications specify that all legacy connectors
- on PCs should be replaced by one or more USB connectors,
- providing generic plug and play capabilities. Support for USB
- hardware was available at a very early stage in NetBSD and was
- developed by Lennart Augustsson for the NetBSD project. The
- code has been ported to FreeBSD and we are currently maintaining
- a shared code base. For the implementation of the USB subsystem
- a number of features of USB are important.</para>
-
- <para><emphasis>Lennart Augustsson has done most of the implementation of
- the USB support for the NetBSD project. Many thanks for this
- incredible amount of work. Many thanks also to Ardy and Dirk for
- their comments and proofreading of this paper.</emphasis></para>
-
- <itemizedlist>
-
- <listitem><para>Devices connect to ports on the computer
- directly or on devices called hubs, forming a treelike device
- structure.</para></listitem>
-
- <listitem><para>The devices can be connected and disconnected at
- run time.</para></listitem>
-
- <listitem><para>Devices can suspend themselves and trigger
- resumes of the host system</para></listitem>
-
- <listitem><para>As the devices can be powered from the bus, the
- host software has to keep track of power budgets for each
- hub.</para></listitem>
-
- <listitem><para>Different quality of service requirements by the
- different device types together with the maximum of 126
- devices that can be connected to the same bus, require proper
- scheduling of transfers on the shared bus to take full
- advantage of the 12Mbps bandwidth available. (over 400Mbps
- with USB 2.0)</para></listitem>
-
- <listitem><para>Devices are intelligent and contain easily
- accessible information about themselves</para></listitem>
-
- </itemizedlist>
-
- <para>The development of drivers for the USB subsystem and devices
- connected to it is supported by the specifications that have
- been developed and will be developed. These specifications are
- publicly available from the USB home pages. Apple has been very
- strong in pushing for standards based drivers, by making drivers
- for the generic classes available in their operating system
- MacOS and discouraging the use of separate drivers for each new
- device. This chapter tries to collate essential information for a
- basic understanding of the present implementation of the USB
- stack in FreeBSD/NetBSD. It is recommended however to read it
- together with the relevant specifications mentioned in the
- references below.</para>
-
- <sect2>
- <title>Structure of the USB Stack</title>
-
- <para>The USB support in FreeBSD can be split into three
- layers. The lowest layer contains the host controller driver,
- providing a generic interface to the hardware and its scheduling
- facilities. It supports initialisation of the hardware,
- scheduling of transfers and handling of completed and/or failed
- transfers. Each host controller driver implements a virtual hub
- providing hardware independent access to the registers
- controlling the root ports on the back of the machine.</para>
-
- <para>The middle layer handles the device connection and
- disconnection, basic initialisation of the device, driver
- selection, the communication channels (pipes) and does
- resource management. This services layer also controls the
- default pipes and the device requests transferred over
- them.</para>
-
- <para>The top layer contains the individual drivers supporting
- specific (classes of) devices. These drivers implement the
- protocol that is used over the pipes other than the default
- pipe. They also implement additional functionality to make the
- device available to other parts of the kernel or userland. They
- use the USB driver interface (USBDI) exposed by the services
- layer.</para>
- </sect2>
- </sect1>
-
- <sect1 id="usb-hc">
- <title>Host Controllers</title>
-
- <para>The host controller (HC) controls the transmission of
- packets on the bus. Frames of 1 millisecond are used. At the
- start of each frame the host controller generates a Start of
- Frame (SOF) packet.</para>
-
- <para>The SOF packet is used to synchronise to the start of the
- frame and to keep track of the frame number. Within each frame
- packets are transferred, either from host to device (out) or
- from device to host (in). Transfers are always initiated by the
- host (polled transfers). Therefore there can only be one host
- per USB bus. Each transfer of a packet has a status stage in
- which the recipient of the data can return either ACK
- (acknowledge reception), NAK (retry), STALL (error condition) or
- nothing (garbled data stage, device not available or
- disconnected). Section 8.5 of the <ulink
- url="http://www.usb.org/developers/docs.html">USB
- specification</ulink> explains the details of packets in more
- detail. Four different types of transfers can occur on a USB
- bus: control, bulk, interrupt and isochronous. The types of
- transfers and their characteristics are described below (`Pipes'
- subsection).</para>
-
- <para>Large transfers between the device on the USB bus and the
- device driver are split up into multiple packets by the host
- controller or the HC driver.</para>
-
- <para>Device requests (control transfers) to the default endpoints
- are special. They consist of two or three phases: SETUP, DATA
- (optional) and STATUS. The set-up packet is sent to the
- device. If there is a data phase, the direction of the data
- packet(s) is given in the set-up packet. The direction in the
- status phase is the opposite of the direction during the data
- phase, or IN if there was no data phase. The host controller
- hardware also provides registers with the current status of the
- root ports and the changes that have occurred since the last
- reset of the status change register. Access to these registers
- is provided through a virtualised hub as suggested in the USB
- specification [ 2]. The virtual hub must comply with the hub
- device class given in chapter 11 of that specification. It must
- provide a default pipe through which device requests can be sent
- to it. It returns the standard andhub class specific set of
- descriptors. It should also provide an interrupt pipe that
- reports changes happening at its ports. There are currently two
- specifications for host controllers available: <ulink
- url="http://developer.intel.com/design/USB/UHCI11D.htm">Universal
- Host Controller Interface</ulink> (UHCI; Intel) and <ulink
- url="http://www.compaq.com/productinfo/development/openhci.html">Open
- Host Controller Interface</ulink> (OHCI; Compaq, Microsoft,
- National Semiconductor). The UHCI specification has been
- designed to reduce hardware complexity by requiring the host
- controller driver to supply a complete schedule of the transfers
- for each frame. OHCI type controllers are much more independent
- by providing a more abstract interface doing alot of work
- themselves. </para>
-
- <sect2>
- <title>UHCI</title>
-
- <para>The UHCI host controller maintains a framelist with 1024
- pointers to per frame data structures. It understands two
- different data types: transfer descriptors (TD) and queue
- heads (QH). Each TD represents a packet to be communicated to
- or from a device endpoint. QHs are a means to groupTDs (and
- QHs) together.</para>
-
- <para>Each transfer consists of one or more packets. The UHCI
- driver splits large transfers into multiple packets. For every
- transfer, apart from isochronous transfers, a QH is
- allocated. For every type of transfer these QHs are collected
- at a QH for that type. Isochronous transfers have to be
- executed first because of the fixed latency requirement and
- are directly referred to by the pointer in the framelist. The
- last isochronous TD refers to the QH for interrupt transfers
- for that frame. All QHs for interrupt transfers point at the
- QH for control transfers, which in turn points at the QH for
- bulk transfers. The following diagram gives a graphical
- overview of this:</para>
-
- <para>This results in the following schedule being run in each
- frame. After fetching the pointer for the current frame from
- the framelist the controller first executes the TDs for all
- the isochronous packets in that frame. The last of these TDs
- refers to the QH for the interrupt transfers for
- thatframe. The host controller will then descend from that QH
- to the QHs for the individual interrupt transfers. After
- finishing that queue, the QH for the interrupt transfers will
- refer the controller to the QH for all control transfers. It
- will execute all the subqueues scheduled there, followed by
- all the transfers queued at the bulk QH. To facilitate the
- handling of finished or failed transfers different types of
- interrupts are generated by the hardware at the end of each
- frame. In the last TD for a transfer the Interrupt-On
- Completion bit is set by the HC driver to flag an interrupt
- when the transfer has completed. An error interrupt is flagged
- if a TD reaches its maximum error count. If the short packet
- detect bit is set in a TD and less than the set packet length
- is transferred this interrupt is flagged to notify
- the controller driver of the completed transfer. It is the host
- controller driver's task to find out which transfer has
- completed or produced an error. When called the interrupt
- service routine will locate all the finished transfers and
- call their callbacks.</para>
-
- <para>See for a more elaborate description the <ulink
- url="http://developer.intel.com/design/USB/UHCI11D.htm">UHCI
- specification.</ulink></para>
-
- </sect2>
-
- <sect2>
- <title>OHCI</title>
-
- <para>Programming an OHCI host controller is much simpler. The
- controller assumes that a set of endpoints is available, and
- is aware of scheduling priorities and the ordering of the
- types of transfers in a frame. The main data structure used by
- the host controller is the endpoint descriptor (ED) to which
- aqueue of transfer descriptors (TDs) is attached. The ED
- contains the maximum packet size allowed for an endpoint and
- the controller hardware does the splitting into packets. The
- pointers to the data buffers are updated after each transfer
- and when the start and end pointer are equal, the TD is
- retired to the done-queue. The four types of endpoints have
- their own queues. Control and bulk endpoints are queued each at
- their own queue. Interrupt EDs are queued in a tree, with the
- level in the tree defining the frequency at which they
- run.</para>
-
- <para>framelist interruptisochronous control bulk</para>
-
- <para>The schedule being run by the host controller in each
- frame looks as follows. The controller will first run the
- non-periodic control and bulk queues, up to a time limit set
- by the HC driver. Then the interrupt transfers for that frame
- number are run, by using the lower five bits of the frame
- number as an index into level 0 of the tree of interrupts
- EDs. At the end of this tree the isochronous EDs are connected
- and these are traversed subsequently. The isochronous TDs
- contain the frame number of the first frame the transfer
- should be run in. After all the periodic transfers have been
- run, the control and bulk queues are traversed
- again. Periodically the interrupt service routine is called to
- process the done queue and call the callbacks for each
- transfer and reschedule interrupt and isochronous
- endpoints.</para>
-
- <para>See for a more elaborate description the <ulink
- url="http://www.compaq.com/productinfo/development/openhci.html">
- OHCI specification</ulink>. Services layer The middle layer
- provides access to the device in a controlled way and
- maintains resources in use by the different drivers and the
- services layer. The layer takes care of the following
- aspects:</para>
-
- <itemizedlist>
- <listitem><para>The device configuration
- information</para></listitem>
- <listitem><para>The pipes to communicate with a
- device</para></listitem>
- <listitem><para>Probing and attaching and detaching form a
- device.</para></listitem>
- </itemizedlist>
-
- </sect2>
- </sect1>
-
- <sect1 id="usb-dev">
- <title>USB Device Information</title>
-
- <sect2>
- <title>Device configuration information</title>
-
- <para>Each device provides different levels of configuration
- information. Each device has one or more configurations, of
- which one is selected during probe/attach. A configuration
- provides power and bandwidth requirements. Within each
- configuration there can be multiple interfaces. A device
- interface is a collection of endpoints. For example USB
- speakers can have an interface for the audio data (Audio
- Class) and an interface for the knobs, dials and buttons (HID
- Class). All interfaces in a configuration are active at the
- same time and can be attached to by different drivers. Each
- interface can have alternates, providing different quality of
- service parameters. In for example cameras this is used to
- provide different frame sizes and numbers of frames per
- second.</para>
-
- <para>Within each interface 0 or more endpoints can be
- specified. Endpoints are the unidirectional access points for
- communicating with a device. They provide buffers to
- temporarily store incoming or outgoing data from the
- device. Each endpoint has a unique address within
- a configuration, the endpoint's number plus its direction. The
- default endpoint, endpoint 0, is not part of any interface and
- available in all configurations. It is managed by the services
- layer and not directly available to device drivers.</para>
-
- <para>Level 0 Level 1 Level 2 Slot 0</para>
- <para>Slot 3 Slot 2 Slot 1</para>
- <para>(Only 4 out of 32 slots shown)</para>
-
- <para>This hierarchical configuration information is described
- in the device by a standard set of descriptors (see section 9.6
- of the USB specification [ 2]). They can be requested through
- the Get Descriptor Request. The services layer caches these
- descriptors to avoid unnecessary transfers on the USB
- bus. Access to the descriptors is provided through function
- calls.</para>
-
- <itemizedlist>
- <listitem><para>Device descriptors: General information about
- the device, like Vendor, Product and Revision Id, supported
- device class, subclass and protocol if applicable, maximum
- packet size for the default endpoint, etc.</para></listitem>
-
- <listitem><para>Configuration descriptors: The number of
- interfaces in this configuration, suspend and resume
- functionality supported and power
- requirements.</para></listitem>
-
- <listitem><para>Interface descriptors: interface class,
- subclass and protocol if applicable, number of alternate
- settings for the interface and the number of
- endpoints.</para></listitem>
-
- <listitem><para>Endpoint descriptors: Endpoint address,
- direction and type, maximum packet size supported and
- polling frequency if type is interrupt endpoint. There is no
- descriptor for the default endpoint (endpoint 0) and it is
- never counted in an interface descriptor.</para></listitem>
-
- <listitem><para>String descriptors: In the other descriptors
- string indices are supplied for some fields.These can be
- used to retrieve descriptive strings, possibly in multiple
- languages.</para></listitem>
-
- </itemizedlist>
-
- <para>Class specifications can add their own descriptor types
- that are available through the GetDescriptor Request.</para>
-
- <para>Pipes Communication to end points on a device flows
- through so-called pipes. Drivers submit transfers to endpoints
- to a pipe and provide a callback to be called on completion or
- failure of the transfer (asynchronous transfers) or wait for
- completion (synchronous transfer). Transfers to an endpoint
- are serialised in the pipe. A transfer can either complete,
- fail or time-out (if a time-out has been set). There are two
- types of time-outs for transfers. Time-outs can happen due to
- time-out on the USBbus (milliseconds). These time-outs are
- seen as failures and can be due to disconnection of the
- device. A second form of time-out is implemented in software
- and is triggered when a transfer does not complete within a
- specified amount of time (seconds). These are caused by a
- device acknowledging negatively (NAK) the transferred
- packets. The cause for this is the device not being ready to
- receive data, buffer under- or overrun or protocol
- errors.</para>
-
- <para>If a transfer over a pipe is larger than the maximum
- packet size specified in the associated endpoint descriptor,
- the host controller (OHCI) or the HC driver (UHCI) will split
- the transfer into packets of maximum packet size, with the
- last packet possibly smaller than the maximum
- packet size.</para>
-
- <para>Sometimes it is not a problem for a device to return less
- data than requested. For example abulk-in-transfer to a modem
- might request 200 bytes of data, but the modem has only 5
- bytes available at that time. The driver can set the short
- packet (SPD) flag. It allows the host controller to accept a
- packet even if the amount of data transferred is less than
- requested. This flag is only valid for in-transfers, as the
- amount of data to be sent to a device is always known
- beforehand. If an unrecoverable error occurs in a device
- during a transfer the pipe is stalled. Before any more data is
- accepted or sent the driver needs to resolve the cause of the
- stall and clear the endpoint stall condition through send the
- clear endpoint halt device request over the default
- pipe. The default endpoint should never stall.</para>
-
- <para>There are four different types of endpoints and
- corresponding pipes: - Control pipe / default pipe: There is
- one control pipe per device, connected to the default endpoint
- (endpoint 0). The pipe carries the device requests and
- associated data. The difference between transfers over the
- default pipe and other pipes is that the protocol for
- the transfers is described in the USB specification [ 2]. These
- requests are used to reset and configure the device. A basic
- set of commands that must be supported by each device is
- provided in chapter 9 of the USB specification [ 2]. The
- commands supported on this pipe can be extended by a device
- class specification to support additional
- functionality.</para>
-
- <itemizedlist>
- <listitem><para>Bulk pipe: This is the USB equivalent to a raw
- transmission medium.</para></listitem>
- <listitem><para>Interrupt pipe: The host sends a request for
- data to the device and if the device has nothing to send, it
- will NAK the data packet. Interrupt transfers are scheduled
- at a frequency specified when creating the
- pipe.</para></listitem>
-
- <listitem><para>Isochronous pipe: These pipes are intended for
- isochronous data, for example video or audio streams, with
- fixed latency, but no guaranteed delivery. Some support for
- pipes of this type is available in the current
- implementation. Packets in control, bulk and interrupt
- transfers are retried if an error occurs during transmission
- or the device acknowledges the packet negatively (NAK) due to
- for example lack of buffer space to store the incoming
- data. Isochronous packets are however not retried in case of
- failed delivery or NAK of a packet as this might violate the
- timing constraints.</para></listitem>
- </itemizedlist>
-
- <para>The availability of the necessary bandwidth is calculated
- during the creation of the pipe. Transfers are scheduled within
- frames of 1 millisecond. The bandwidth allocation within a
- frame is prescribed by the USB specification, section 5.6 [
- 2]. Isochronous and interrupt transfers are allowed to consume
- up to 90% of the bandwidth within a frame. Packets for control
- and bulk transfers are scheduled after all isochronous and
- interrupt packets and will consume all the remaining
- bandwidth.</para>
-
- <para>More information on scheduling of transfers and bandwidth
- reclamation can be found in chapter 5of the USB specification
- [ 2], section 1.3 of the UHCI specification [ 3] and section
- 3.4.2 of the OHCI specification [4].</para>
-
- </sect2>
- </sect1>
-
- <sect1 id="usb-devprobe">
- <title>Device probe and attach</title>
-
- <para>After the notification by the hub that a new device has been
- connected, the service layer switches on the port, providing the
- device with 100 mA of current. At this point the device is in
- its default state and listening to device address 0. The
- services layer will proceed to retrieve the various descriptors
- through the default pipe. After that it will send a Set Address
- request to move the device away from the default device address
- (address 0). Multiple device drivers might be able to support
- the device. For example a modem driver might be able to support
- an ISDN TA through the AT compatibility interface. A driver for
- that specific model of the ISDN adapter might however be able to
- provide much better support for this device. To support this
- flexibility, the probes return priorities indicating their level
- of support. Support for a specific revision of a product ranks
- the highest and the generic driver the lowest priority. It might
- also be that multiple drivers could attach to one device if
- there are multiple interfaces within one configuration. Each
- driver only needs to support a subset of the interfaces.</para>
-
- <para>The probing for a driver for a newly attached device checks
- first for device specific drivers. If not found, the probe code
- iterates over all supported configurations until a driver
- attaches in a configuration. To support devices with multiple
- drivers on different interfaces, the probe iterates over all
- interfaces in a configuration that have not yet been claimed by
- a driver. Configurations that exceed the power budget for the
- hub are ignored. During attach the driver should initialise the
- device to its proper state, but not reset it, as this will make
- the device disconnect itself from the bus and restart the
- probing process for it. To avoid consuming unnecessary bandwidth
- should not claim the interrupt pipe at attach time, but
- should postpone allocating the pipe until the file is opened and
- the data is actually used. When the file is closed the pipe
- should be closed again, even though the device might still be
- attached.</para>
-
- <sect2>
- <title>Device disconnect and detach</title>
-
- <para>A device driver should expect to receive errors during any
- transaction with the device. The design of USB supports and
- encourages the disconnection of devices at any point in
- time. Drivers should make sure that they do the right thing
- when the device disappears.</para>
-
- <para>Furthermore a device that has been disconnected and
- reconnected will not be reattached at the same device
- instance. This might change in the future when more devices
- support serial numbers (see the device descriptor) or other
- means of defining an identity for a device have been
- developed.</para>
-
- <para>The disconnection of a device is signaled by a hub in the
- interrupt packet delivered to the hub driver. The status
- change information indicates which port has seen a connection
- change. The device detach method for all device drivers for
- the device connected on that port are called and the structures
- cleaned up. If the port status indicates that in the mean time
- a device has been connected to that port, the procedure for
- probing and attaching the device will be started. A device
- reset will produce a disconnect-connect sequence on the hub
- and will be handled as described above.</para>
-
- </sect2>
- </sect1>
-
- <sect1 id="usb-protocol">
- <title>USB Drivers Protocol Information</title>
-
- <para>The protocol used over pipes other than the default pipe is
- undefined by the USB specification. Information on this can be
- found from various sources. The most accurate source is the
- developer's section on the USB home pages [ 1]. From these pages
- a growing number of deviceclass specifications are
- available. These specifications specify what a compliant device
- should look like from a driver perspective, basic functionality
- it needs to provide and the protocol that is to be used over the
- communication channels. The USB specification [ 2] includes the
- description of the Hub Class. A class specification for Human
- Interface Devices (HID) has been created to cater for keyboards,
- tablets, bar-code readers, buttons, knobs, switches, etc. A
- third example is the class specification for mass storage
- devices. For a full list of device classes see the developers
- section on the USB home pages [ 1].</para>
-
- <para>For many devices the protocol information has not yet been
- published however. Information on the protocol being used might
- be available from the company making the device. Some companies
- will require you to sign a Non -Disclosure Agreement (NDA)
- before giving you the specifications. This in most cases
- precludes making the driver open source.</para>
-
- <para>Another good source of information is the Linux driver
- sources, as a number of companies have started to provide drivers
- for Linux for their devices. It is always a good idea to contact
- the authors of those drivers for their source of
- information.</para>
-
- <para>Example: Human Interface Devices The specification for the
- Human Interface Devices like keyboards, mice, tablets, buttons,
- dials,etc. is referred to in other device class specifications
- and is used in many devices.</para>
-
- <para>For example audio speakers provide endpoints to the digital
- to analogue converters and possibly an extra pipe for a
- microphone. They also provide a HID endpoint in a separate
- interface for the buttons and dials on the front of the
- device. The same is true for the monitor control class. It is
- straightforward to build support for these interfaces through
- the available kernel and userland libraries together with the
- HID class driver or the generic driver. Another device that
- serves as an example for interfaces within one configuration
- driven by different device drivers is a cheap keyboard with
- built-in legacy mouse port. To avoid having the cost of
- including the hardware for a USB hub in the device,
- manufacturers combined the mouse data received from the PS/2 port
- on the back of the keyboard and the key presses from the keyboard
- into two separate interfaces in the same configuration. The
- mouse and keyboard drivers each attach to the appropriate
- interface and allocate the pipes to the two independent
- endpoints.</para>
-
- <para>Example: Firmware download Many devices that have been
- developed are based on a general purpose processor with
- an additional USB core added to it. Because the development of
- drivers and firmware for USB devices is still very new, many
- devices require the downloading of the firmware after they
- have been connected.</para>
-
- <para>The procedure followed is straightforward. The device
- identifies itself through a vendor and product Id. The first
- driver probes and attaches to it and downloads the firmware into
- it. After that the device soft resets itself and the driver is
- detached. After a short pause the device announces its presence
- on the bus. The device will have changed its
- vendor/product/revision Id to reflect the fact that it has been
- supplied with firmware and as a consequence a second driver will
- probe it and attach to it.</para>
-
- <para>An example of these types of devices is the ActiveWire I/O
- board, based on the EZ-USB chip. For this chip a generic firmware
- downloader is available. The firmware downloaded into the
- ActiveWire board changes the revision Id. It will then perform a
- soft reset of the USB part of the EZ-USB chip to disconnect from
- the USB bus and again reconnect.</para>
-
- <para>Example: Mass Storage Devices Support for mass storage
- devices is mainly built around existing protocols. The Iomega
- USB Zipdrive is based on the SCSI version of their drive. The
- SCSI commands and status messages are wrapped in blocks and
- transferred over the bulk pipes to and from the device,
- emulating a SCSI controller over the USB wire. ATAPI and UFI
- commands are supported in a similar fashion.</para>
-
- <para>The Mass Storage Specification supports 2 different types of
- wrapping of the command block.The initial attempt was based on
- sending the command and status through the default pipe and
- using bulk transfers for the data to be moved between the host
- and the device. Based on experience a second approach was
- designed that was based on wrapping the command and status
- blocks and sending them over the bulk out and in endpoint. The
- specification specifies exactly what has to happen when and what
- has to be done in case an error condition is encountered. The
- biggest challenge when writing drivers for these devices is to
- fit USB based protocol into the existing support for mass storage
- devices. CAM provides hooks to do this in a fairly straight
- forward way. ATAPI is less simple as historically the IDE
- interface has never had many different appearances.</para>
-
- <para>The support for the USB floppy from Y-E Data is again less
- straightforward as a new command set has been designed.</para>
-
- </sect1>
-
-</chapter>
diff --git a/en_US.ISO8859-1/books/arch-handbook/vm/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/vm/chapter.sgml
deleted file mode 100644
index b48098aa00..0000000000
--- a/en_US.ISO8859-1/books/arch-handbook/vm/chapter.sgml
+++ /dev/null
@@ -1,255 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="vm">
- <title>Virtual Memory System</title>
-
- <sect1 id="internals-vm">
- <title>The FreeBSD VM System</title>
-
- <para><emphasis>Contributed by &a.dillon;. 6 Feb 1999</emphasis></para>
-
- <sect2>
- <title>Management of physical
- memory&mdash;<literal>vm_page_t</literal></title>
-
- <para>Physical memory is managed on a page-by-page basis through the
- <literal>vm_page_t</literal> structure. Pages of physical memory are
- categorized through the placement of their respective
- <literal>vm_page_t</literal> structures on one of several paging
- queues.</para>
-
- <para>A page can be in a wired, active, inactive, cache, or free state.
- Except for the wired state, the page is typically placed in a doubly
- link list queue representing the state that it is in. Wired pages
- are not placed on any queue.</para>
-
- <para>FreeBSD implements a more involved paging queue for cached and
- free pages in order to implement page coloring. Each of these states
- involves multiple queues arranged according to the size of the
- processor's L1 and L2 caches. When a new page needs to be allocated,
- FreeBSD attempts to obtain one that is reasonably well aligned from
- the point of view of the L1 and L2 caches relative to the VM object
- the page is being allocated for.</para>
-
- <para>Additionally, a page may be held with a reference count or locked
- with a busy count. The VM system also implements an <quote>ultimate
- locked</quote> state for a page using the PG_BUSY bit in the page's
- flags.</para>
-
- <para>In general terms, each of the paging queues operates in a LRU
- fashion. A page is typically placed in a wired or active state
- initially. When wired, the page is usually associated with a page
- table somewhere. The VM system ages the page by scanning pages in a
- more active paging queue (LRU) in order to move them to a less-active
- paging queue. Pages that get moved into the cache are still
- associated with a VM object but are candidates for immediate reuse.
- Pages in the free queue are truly free. FreeBSD attempts to minimize
- the number of pages in the free queue, but a certain minimum number of
- truly free pages must be maintained in order to accommodate page
- allocation at interrupt time.</para>
-
- <para>If a process attempts to access a page that does not exist in its
- page table but does exist in one of the paging queues (such as the
- inactive or cache queues), a relatively inexpensive page reactivation
- fault occurs which causes the page to be reactivated. If the page
- does not exist in system memory at all, the process must block while
- the page is brought in from disk.</para>
-
- <para>FreeBSD dynamically tunes its paging queues and attempts to
- maintain reasonable ratios of pages in the various queues as well as
- attempts to maintain a reasonable breakdown of clean vs. dirty pages.
- The amount of rebalancing that occurs depends on the system's memory
- load. This rebalancing is implemented by the pageout daemon and
- involves laundering dirty pages (syncing them with their backing
- store), noticing when pages are activity referenced (resetting their
- position in the LRU queues or moving them between queues), migrating
- pages between queues when the queues are out of balance, and so forth.
- FreeBSD's VM system is willing to take a reasonable number of
- reactivation page faults to determine how active or how idle a page
- actually is. This leads to better decisions being made as to when to
- launder or swap-out a page.</para>
- </sect2>
-
- <sect2>
- <title>The unified buffer
- cache&mdash;<literal>vm_object_t</literal></title>
-
- <para>FreeBSD implements the idea of a generic <quote>VM object</quote>.
- VM objects can be associated with backing store of various
- types&mdash;unbacked, swap-backed, physical device-backed, or
- file-backed storage. Since the filesystem uses the same VM objects to
- manage in-core data relating to files, the result is a unified buffer
- cache.</para>
-
- <para>VM objects can be <emphasis>shadowed</emphasis>. That is, they
- can be stacked on top of each other. For example, you might have a
- swap-backed VM object stacked on top of a file-backed VM object in
- order to implement a MAP_PRIVATE mmap()ing. This stacking is also
- used to implement various sharing properties, including
- copy-on-write, for forked address spaces.</para>
-
- <para>It should be noted that a <literal>vm_page_t</literal> can only be
- associated with one VM object at a time. The VM object shadowing
- implements the perceived sharing of the same page across multiple
- instances.</para>
- </sect2>
-
- <sect2>
- <title>Filesystem I/O&mdash;<literal>struct buf</literal></title>
-
- <para>vnode-backed VM objects, such as file-backed objects, generally
- need to maintain their own clean/dirty info independent from the VM
- system's idea of clean/dirty. For example, when the VM system decides
- to synchronize a physical page to its backing store, the VM system
- needs to mark the page clean before the page is actually written to
- its backing store. Additionally, filesystems need to be able to map
- portions of a file or file metadata into KVM in order to operate on
- it.</para>
-
- <para>The entities used to manage this are known as filesystem buffers,
- <literal>struct buf</literal>'s, or
- <literal>bp</literal>'s. When a filesystem needs to operate on a
- portion of a VM object, it typically maps part of the object into a
- struct buf and the maps the pages in the struct buf into KVM. In the
- same manner, disk I/O is typically issued by mapping portions of
- objects into buffer structures and then issuing the I/O on the buffer
- structures. The underlying vm_page_t's are typically busied for the
- duration of the I/O. Filesystem buffers also have their own notion of
- being busy, which is useful to filesystem driver code which would
- rather operate on filesystem buffers instead of hard VM pages.</para>
-
- <para>FreeBSD reserves a limited amount of KVM to hold mappings from
- struct bufs, but it should be made clear that this KVM is used solely
- to hold mappings and does not limit the ability to cache data.
- Physical data caching is strictly a function of
- <literal>vm_page_t</literal>'s, not filesystem buffers. However,
- since filesystem buffers are used to placehold I/O, they do inherently
- limit the amount of concurrent I/O possible. However, as there are usually a
- few thousand filesystem buffers available, this is not usually a
- problem.</para>
- </sect2>
-
- <sect2>
- <title>Mapping Page Tables - vm_map_t, vm_entry_t</title>
-
- <para>FreeBSD separates the physical page table topology from the VM
- system. All hard per-process page tables can be reconstructed on the
- fly and are usually considered throwaway. Special page tables such as
- those managing KVM are typically permanently preallocated. These page
- tables are not throwaway.</para>
-
- <para>FreeBSD associates portions of vm_objects with address ranges in
- virtual memory through <literal>vm_map_t</literal> and
- <literal>vm_entry_t</literal> structures. Page tables are directly
- synthesized from the
- <literal>vm_map_t</literal>/<literal>vm_entry_t</literal>/
- <literal>vm_object_t</literal> hierarchy. Recall that I mentioned
- that physical pages are only directly associated with a
- <literal>vm_object</literal>; that is not quite true.
- <literal>vm_page_t</literal>'s are also linked into page tables that
- they are actively associated with. One <literal>vm_page_t</literal>
- can be linked into several <emphasis>pmaps</emphasis>, as page tables
- are called. However, the hierarchical association holds, so all
- references to the same page in the same object reference the same
- <literal>vm_page_t</literal> and thus give us buffer cache unification
- across the board.</para>
- </sect2>
-
- <sect2>
- <title>KVM Memory Mapping</title>
-
- <para>FreeBSD uses KVM to hold various kernel structures. The single
- largest entity held in KVM is the filesystem buffer cache. That is,
- mappings relating to <literal>struct buf</literal> entities.</para>
-
- <para>Unlike Linux, FreeBSD does <emphasis>not</emphasis> map all of physical memory into
- KVM. This means that FreeBSD can handle memory configurations up to
- 4G on 32 bit platforms. In fact, if the mmu were capable of it,
- FreeBSD could theoretically handle memory configurations up to 8TB on
- a 32 bit platform. However, since most 32 bit platforms are only
- capable of mapping 4GB of ram, this is a moot point.</para>
-
- <para>KVM is managed through several mechanisms. The main mechanism
- used to manage KVM is the <emphasis>zone allocator</emphasis>. The
- zone allocator takes a chunk of KVM and splits it up into
- constant-sized blocks of memory in order to allocate a specific type
- of structure. You can use <command>vmstat -m</command> to get an
- overview of current KVM utilization broken down by zone.</para>
- </sect2>
-
- <sect2>
- <title>Tuning the FreeBSD VM system</title>
-
- <para>A concerted effort has been made to make the FreeBSD kernel
- dynamically tune itself. Typically you do not need to mess with
- anything beyond the <option>maxusers</option> and
- <option>NMBCLUSTERS</option> kernel config options. That is, kernel
- compilation options specified in (typically)
- <filename>/usr/src/sys/i386/conf/<replaceable>CONFIG_FILE</replaceable></filename>.
- A description of all available kernel configuration options can be
- found in <filename>/usr/src/sys/i386/conf/LINT</filename>.</para>
-
- <para>In a large system configuration you may wish to increase
- <option>maxusers</option>. Values typically range from 10 to 128.
- Note that raising <option>maxusers</option> too high can cause the
- system to overflow available KVM resulting in unpredictable operation.
- It is better to leave <option>maxusers</option> at some reasonable number and add other
- options, such as <option>NMBCLUSTERS</option>, to increase specific
- resources.</para>
-
- <para>If your system is going to use the network heavily, you may want
- to increase <option>NMBCLUSTERS</option>. Typical values range from
- 1024 to 4096.</para>
-
- <para>The <literal>NBUF</literal> parameter is also traditionally used
- to scale the system. This parameter determines the amount of KVA the
- system can use to map filesystem buffers for I/O. Note that this
- parameter has nothing whatsoever to do with the unified buffer cache!
- This parameter is dynamically tuned in 3.0-CURRENT and later kernels
- and should generally not be adjusted manually. We recommend that you
- <emphasis>not</emphasis> try to specify an <literal>NBUF</literal>
- parameter. Let the system pick it. Too small a value can result in
- extremely inefficient filesystem operation while too large a value can
- starve the page queues by causing too many pages to become wired
- down.</para>
-
- <para>By default, FreeBSD kernels are not optimized. You can set
- debugging and optimization flags with the
- <literal>makeoptions</literal> directive in the kernel configuration.
- Note that you should not use <option>-g</option> unless you can
- accommodate the large (typically 7 MB+) kernels that result.</para>
-
- <programlisting>makeoptions DEBUG="-g"
-makeoptions COPTFLAGS="-O -pipe"</programlisting>
-
- <para>Sysctl provides a way to tune kernel parameters at run-time. You
- typically do not need to mess with any of the sysctl variables,
- especially the VM related ones.</para>
-
- <para>Run time VM and system tuning is relatively straightforward.
- First, use softupdates on your UFS/FFS filesystems whenever possible.
- <filename>/usr/src/sys/ufs/ffs/README.softupdates</filename> contains
- instructions (and restrictions) on how to configure it.</para>
-
- <para>Second, configure sufficient swap. You should have a swap
- partition configured on each physical disk, up to four, even on your
- <quote>work</quote> disks. You should have at least 2x the swap space
- as you have main memory, and possibly even more if you do not have a
- lot of memory. You should also size your swap partition based on the
- maximum memory configuration you ever intend to put on the machine so
- you do not have to repartition your disks later on. If you want to be
- able to accommodate a crash dump, your first swap partition must be at
- least as large as main memory and <filename>/var/crash</filename> must
- have sufficient free space to hold the dump.</para>
-
- <para>NFS-based swap is perfectly acceptable on -4.x or later systems,
- but you must be aware that the NFS server will take the brunt of the
- paging load.</para>
- </sect2>
- </sect1>
-
-</chapter>
diff --git a/en_US.ISO8859-1/books/handbook/basics/disk-layout.kil b/en_US.ISO8859-1/books/handbook/basics/disk-layout.kil
deleted file mode 100644
index 85820c2878..0000000000
--- a/en_US.ISO8859-1/books/handbook/basics/disk-layout.kil
+++ /dev/null
Binary files differ
diff --git a/en_US.ISO8859-1/books/handbook/basics/example-dir1.dot b/en_US.ISO8859-1/books/handbook/basics/example-dir1.dot
deleted file mode 100644
index f259e8377d..0000000000
--- a/en_US.ISO8859-1/books/handbook/basics/example-dir1.dot
+++ /dev/null
@@ -1,7 +0,0 @@
-// $FreeBSD$
-
-digraph directory {
- root [label="Root\n/"];
- root -> "A1/";
- root -> "A2/";
-}
diff --git a/en_US.ISO8859-1/books/handbook/basics/example-dir2.dot b/en_US.ISO8859-1/books/handbook/basics/example-dir2.dot
deleted file mode 100644
index b846c82399..0000000000
--- a/en_US.ISO8859-1/books/handbook/basics/example-dir2.dot
+++ /dev/null
@@ -1,8 +0,0 @@
-// $FreeBSD$
-
-digraph directory {
- root [label="Root\n/"];
- root -> "A1/" -> "B1/";
- "A1/" -> "B2/";
- root -> "A2/";
-}
diff --git a/en_US.ISO8859-1/books/handbook/basics/example-dir3.dot b/en_US.ISO8859-1/books/handbook/basics/example-dir3.dot
deleted file mode 100644
index 178a3a91bb..0000000000
--- a/en_US.ISO8859-1/books/handbook/basics/example-dir3.dot
+++ /dev/null
@@ -1,8 +0,0 @@
-// $FreeBSD$
-
-digraph directory {
- root [label="Root\n/"];
- root -> "A1/";
- root -> "A2/" -> "B1/";
- "A2/" -> "B2/";
-}
diff --git a/en_US.ISO8859-1/books/handbook/basics/example-dir4.dot b/en_US.ISO8859-1/books/handbook/basics/example-dir4.dot
deleted file mode 100644
index 82d12b421a..0000000000
--- a/en_US.ISO8859-1/books/handbook/basics/example-dir4.dot
+++ /dev/null
@@ -1,9 +0,0 @@
-// $FreeBSD$
-
-digraph directory {
- root [label="Root\n/"];
- root -> "A1/";
- root -> "A2/" -> "B1/" -> "C1/";
- "B1/" -> "C2/";
- "A2/" -> "B2/";
-}
diff --git a/en_US.ISO8859-1/books/handbook/basics/example-dir5.dot b/en_US.ISO8859-1/books/handbook/basics/example-dir5.dot
deleted file mode 100644
index f5aa6e01dc..0000000000
--- a/en_US.ISO8859-1/books/handbook/basics/example-dir5.dot
+++ /dev/null
@@ -1,9 +0,0 @@
-// $FreeBSD$
-
-digraph directory {
- root [label="Root\n/"];
- root -> "A1/" -> "C1/";
- "A1/" -> "C2/";
- root -> "A2/" -> "B1/";
- "A2/" -> "B2/";
-}
diff --git a/en_US.ISO8859-1/books/handbook/mirrors/chapter.sgml b/en_US.ISO8859-1/books/handbook/mirrors/chapter.sgml
index 095e68843e..5dd5284d73 100644
--- a/en_US.ISO8859-1/books/handbook/mirrors/chapter.sgml
+++ b/en_US.ISO8859-1/books/handbook/mirrors/chapter.sgml
@@ -77,7 +77,7 @@
<address>
<otheraddr>Hinner EDV</otheraddr>
<street>St. Augustinus-Str. 10</street>
- <postcode>D-81825</postcode> <city>Mnchen</city>
+ <postcode>D-81825</postcode> <city>M&uuml;nchen</city>
<country>Germany</country>
Phone: <phone>(089) 428 419</phone>
WWW: <otheraddr><ulink url="http://www.hinner.de/linux/freebsd.html">http://www.hinner.de/linux/freebsd.html</ulink></otheraddr>
@@ -139,14 +139,31 @@
<para>FreeBSD is available on DVD from:</para>
- <address>
- <otheraddr>FreeBSD Services Ltd</otheraddr>
- <street>11 Lapwing Close</street>
- <city>Bicester</city>
- <postcode>OX26 6XR</postcode>
- <country>United Kingdom</country>
- WWW: <otheraddr><ulink url="http://www.freebsd-services.com/">http://www.freebsd-services.com/</ulink></otheraddr>
- </address>
+ <itemizedlist>
+ <listitem>
+ <address>
+ <otheraddr>FreeBSD Mall, Inc.</otheraddr>
+ <street>3623 Sanford Street</street>
+ <city>Concord</city>, <state>CA</state> <postcode>94520-1405</postcode>
+ <country>USA</country>
+ Phone: <phone>+1 925 674-0783</phone>
+ Fax: <fax>+1 925 674-0821</fax>
+ Email: <email>info@freebsdmall.com</email>
+ WWW: <otheraddr><ulink url="http://www.freebsdmall.com/">http://www.freebsdmall.com/</ulink></otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ <otheraddr>FreeBSD Services Ltd</otheraddr>
+ <street>11 Lapwing Close</street>
+ <city>Bicester</city>
+ <postcode>OX26 6XR</postcode>
+ <country>United Kingdom</country>
+ WWW: <otheraddr><ulink url="http://www.freebsd-services.com/">http://www.freebsd-services.com/</ulink></otheraddr>
+ </address>
+ </listitem>
+ </itemizedlist>
</sect1>
<sect1 id="mirrors-ftp">
@@ -1103,7 +1120,7 @@
<para>The <command>cvs login</command> command, stores the passwords
that are used for authenticating to the CVS server in a file
called <filename>.cvspass</filename> in your
- <literal>HOME</literal> directory. If this file doesn't exist,
+ <envar>HOME</envar> directory. If this file doesn't exist,
you might get an error when trying to use <command>cvs
login</command> for the first time. Just make an empty
<filename>.cvspass</filename> file, and retry to login.</para>
@@ -2005,7 +2022,7 @@ src-all</programlisting>
</listitem>
</itemizedlist>
<sect3>
- <title>The refuse File</title>
+ <title>The <filename>refuse</filename> File</title>
<para>As mentioned above, <application>CVSup</application> uses
a <emphasis>pull method</emphasis>. Basically, this means that
@@ -2027,28 +2044,28 @@ src-all</programlisting>
saying <emphasis>ports-all</emphasis>). However, since the doc
and www trees do not have language-specific collections, you
must use one of <application>CVSup</application>'s many nifty
- features; the <emphasis>refuse file</emphasis>.</para>
+ features; the <filename>refuse</filename> file.</para>
- <para>The <emphasis>refuse file</emphasis> essentially tells
+ <para>The <filename>refuse</filename> file essentially tells
<application>CVSup</application> that it should not take every
single file from a collection; in other words, it tells the
client to <emphasis>refuse</emphasis> certain files from the
- server. The refuse file can be found (or, if you do not yet
+ server. The <filename>refuse</filename> file can be found (or, if you do not yet
have one, should be placed) in
<filename><replaceable>base</replaceable>/sup/refuse</filename>.
<replaceable>base</replaceable> is defined in your supfile; by
default, <replaceable>base</replaceable> is
<filename>/usr/local/etc/cvsup</filename>,
- which means that by default the refuse file is in
+ which means that by default the <filename>refuse</filename> file is in
<filename>/usr/local/etc/cvsup/sup/refuse</filename>.</para>
- <para>The refuse file has a very simple format; it simply
+ <para>The <filename>refuse</filename> file has a very simple format; it simply
contains the names of files or directories that you do not wish
to download. For example, if you cannot speak any languages other
than English and some German, and you do not feel the need to use
the German applications (or applications for any other
languages, except for English), you can put the following in your
- <emphasis>refuse file</emphasis>:</para>
+ <filename>refuse</filename> file:</para>
<screen>ports/chinese
ports/french
@@ -2076,13 +2093,13 @@ doc/zh_TW.Big5</screen>
URL="ftp://ftp.FreeBSD.org/pub/FreeBSD/FreeBSD-current/">FreeBSD
FTP server</ulink>). Note that the name
of the repository is the first <quote>directory</quote> in the
- <emphasis>refuse file</emphasis>.</para>
+ <filename>refuse</filename> file.</para>
<para>With this very useful feature, those users who are on
slow links or pay by the minute for their Internet connection
will be able to save valuable time as they will no longer need
to download files that they will never use. For more
- information on <emphasis>refuse files</emphasis> and other neat
+ information on <filename>refuse</filename> files and other neat
features of <application>CVSup</application>, please view its
manual page.</para>
</sect3>
@@ -3832,6 +3849,22 @@ doc/zh_TW.Big5</screen>
<variablelist>
<varlistentry>
+ <term>RELENG_4_6_2_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.6.2</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_6_1_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.6.1</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>RELENG_4_6_0_RELEASE</term>
<listitem>
diff --git a/en_US.ISO8859-1/books/handbook/multimedia/Makefile b/en_US.ISO8859-1/books/handbook/multimedia/Makefile
deleted file mode 100644
index 0ea7f84352..0000000000
--- a/en_US.ISO8859-1/books/handbook/multimedia/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Build the Handbook with just the content from this chapter.
-#
-# $FreeBSD$
-#
-
-CHAPTERS= sound/chapter.sgml
-
-VPATH= ..
-
-MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
-
-DOC_PREFIX?= ${.CURDIR}/../../../..
-
-.include "../Makefile"
diff --git a/en_US.ISO8859-1/books/handbook/multimedia/chapter.sgml b/en_US.ISO8859-1/books/handbook/multimedia/chapter.sgml
deleted file mode 100644
index fc05ff119d..0000000000
--- a/en_US.ISO8859-1/books/handbook/multimedia/chapter.sgml
+++ /dev/null
@@ -1,589 +0,0 @@
-<!--
- The FreeBSD Documentation Project
-
- $FreeBSD$
--->
-
-<chapter id="sound">
- <chapterinfo>
- <authorgroup>
- <author>
- <firstname>Moses</firstname>
- <surname>Moore</surname>
- <contrib>Contributed by </contrib>
- </author>
- </authorgroup>
- <!-- 20 November 2000 -->
- </chapterinfo>
-
- <title>Sound</title>
-
- <sect1 id="sound-synopsis">
- <title>Synopsis</title>
-
- <para>FreeBSD supports a wide variety of sound cards, allowing you
- to enjoy high fidelity output from your computer. This includes
- the ability to record and playback audio in the MPEG Audio Layer
- 3 (MP3), WAV, and Ogg Vorbis formats as well as many other
- formats. The FreeBSD Ports Collection also contains
- applications allowing you to edit your recorded audio, add sound
- effects, and control attached MIDI devices.</para>
-
- <para>After reading this chapter, you will know:</para>
- <itemizedlist>
- <listitem><para>How to locate your sound card.</para></listitem>
- <listitem><para>How to configure your system so that your sound card is
- recognized.</para></listitem>
- <listitem><para>Methods to test that your card is working using
- sample applications.</para></listitem>
- <listitem><para>How to troubleshoot your sound setup.</para></listitem>
- <listitem><para>How to playback and encode MP3s.</para></listitem>
- <listitem><para>How to rip CD audio tracks into data files.</para></listitem>
- </itemizedlist>
-
- <para>Before reading this chapter, you should:</para>
-
- <itemizedlist>
- <listitem><para>Know how to configure and install a new kernel (<xref
- linkend="kernelconfig">).</para></listitem>
- </itemizedlist>
- </sect1>
-
- <sect1 id="sound-device">
- <title>Locating the Correct Device</title>
-
- <indexterm><primary>PCI</primary></indexterm>
- <indexterm><primary>ISA</primary></indexterm>
- <indexterm><primary>sound cards</primary></indexterm>
- <para>Before you begin, you should know the model of the card you
- have, the chip it uses, and whether it is a PCI or ISA card.
- FreeBSD supports a wide variety of both PCI and ISA cards. If
- you do not see your card in the following list, check the
- &man.pcm.4; manual page. This is not a complete list; however,
- it does list some of the most common cards.</para>
-
- <itemizedlist>
- <listitem>
- <para>Crystal 4237, 4236, 4232, 4231</para>
- </listitem>
-
- <listitem>
- <para>Yamaha OPL-SAx</para>
- </listitem>
-
- <listitem>
- <para>OPTi931</para>
- </listitem>
-
- <listitem>
- <para>Ensoniq AudioPCI 1370/1371</para>
- </listitem>
-
- <listitem>
- <para>ESS Solo-1/1E</para>
- </listitem>
-
- <listitem>
- <para>NeoMagic 256AV/ZX</para>
- </listitem>
-
- <listitem>
- <para>Sound Blaster Pro, 16, 32, AWE64, AWE128, Live</para>
- </listitem>
-
- <listitem>
- <para>Creative ViBRA16</para>
- </listitem>
-
- <listitem>
- <para>Advanced Asound 100, 110, and Logic ALS120</para>
- </listitem>
-
- <listitem>
- <para>ES 1868, 1869, 1879, 1888</para>
- </listitem>
-
- <listitem>
- <para>Gravis UltraSound</para>
- </listitem>
-
- <listitem>
- <para>Aureal Vortex 1 or 2</para>
- </listitem>
- </itemizedlist>
-
- <indexterm>
- <primary>kernel</primary>
- <secondary>configuration</secondary>
- </indexterm>
-
- <para>To use your sound device, you will need to load the proper
- device driver. This may be accomplished in one of two ways.
- The easiest way is to simply load a kernel module for your sound
- card with &man.kldload.8;. Alternatively, you may statically
- compile in support for your sound card in your kernel. The
- sections below provide the information you need to add support
- for your hardware in this manner. For more information about
- recompiling your kernel, please see <xref
- linkend="kernelconfig">.</para>
-
- <sect2>
- <title>Creative, Advance, and ESS Sound Cards</title>
-
- <para>If you have one of the above cards, you will need to
- add:</para>
-
- <programlisting>device pcm</programlisting>
-
- <para>to your kernel configuration file. If you have a PnP ISA
- card, you will also need to add:</para>
-
- <programlisting>device sbc</programlisting>
-
- <para>For a non-PnP ISA card, add:</para>
-
- <programlisting>device pcm
-device sbc0 at isa? port 0x220 irq 5 drq 1 flags 0x15</programlisting>
-
- <para>to your kernel configuration file. The settings shown
- above are the defaults. You may need to change the IRQ or the
- other settings to match your card. See the &man.sbc.4; manual
- page for more information.</para>
-
- <note>
- <para>The Sound Blaster Live is not supported under FreeBSD 4.0
- without a patch, which this section will not cover. It is
- recommended that you update to the latest -STABLE before
- trying to use this card.</para>
- </note>
- </sect2>
-
- <sect2>
- <title>Gravis UltraSound Cards</title>
-
- <para>For a PnP ISA card, you will need to add:</para>
-
- <programlisting>device pcm
-device gusc</programlisting>
-
- <para>to your kernel configuration file. If you have a non-PnP
- ISA card, you will need to add:</para>
-
- <programlisting>device pcm
-device gus0 at isa? port 0x220 irq 5 drq 1 flags 0x13</programlisting>
-
- <para>to your kernel configuration file. You may need to change
- the IRQ or the other settings to match your card. See the
- &man.gusc.4; manual page for more information.</para>
- </sect2>
-
- <sect2>
- <title>Crystal Sound Cards</title>
-
- <para>For Crystal cards, you will need to add:</para>
-
- <programlisting>device pcm
-device csa</programlisting>
-
- <para>to your kernel configuration file.</para>
- </sect2>
-
- <sect2>
- <title>Generic Support</title>
-
- <para>For PnP ISA or PCI cards, you will need to add:</para>
-
- <programlisting>device pcm</programlisting>
-
- <para>to your kernel configuration file. If you have a non-PnP
- ISA sound card that does not have a bridge driver, you will
- need to add:</para>
-
- <programlisting>device pcm0 at isa? irq 10 drq 1 flags 0x0</programlisting>
-
- <para>to your kernel configuration file. You may need to change
- the IRQ or the other settings to match your card.</para>
-
- </sect2>
-
- <sect2>
- <title>Onboard Sound</title>
-
- <para>Some systems with built-in motherboard sound devices may
- require the following option in your kernel
- configuration:</para>
-
- <programlisting>options PNPBIOS</programlisting>
- </sect2>
- </sect1>
-
- <sect1 id="sound-devicenodes">
- <title>Creating and Testing the Device Nodes</title>
-
- <indexterm><primary>device nodes</primary></indexterm>
- <para>After you reboot, log in and run <command>dmesg | grep
- pcm</command> as shown below:</para>
-
- <screen>&prompt.root; dmesg | grep pcm
-pcm0: &lt;SB16 DSP 4.11&gt; on sbc0</screen>
-
- <para>The output from your system may look different. If no
- <devicename>pcm</devicename> devices show up, something went
- wrong earlier. If that happens, go through your kernel
- configuration file again and make sure you chose the correct
- device. Consult the troubleshooting section for additional
- options.</para>
-
- <para>If the previous command returned
- <devicename>pcm0</devicename>, you will have to run the
- following as <username>root</username>:</para>
-
- <screen>&prompt.root; cd /dev
-&prompt.root; sh MAKEDEV snd0</screen>
-
- <para>If the command returned <devicename>pcm1</devicename>,
- follow the same steps as shown above, replacing
- <devicename>snd0</devicename> with
- <devicename>snd1</devicename>.</para>
-
- <note>
- <para>The above commands will <emphasis>not</emphasis> create a
- <devicename>/dev/snd</devicename> device!</para>
- </note>
-
- <para><command>MAKEDEV</command> will create a group of device
- nodes, including:</para>
-
- <informaltable frame="none">
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Device</entry>
- <entry>Description</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry><devicename>/dev/audio</devicename></entry>
- <entry>SPARC-compatible audio device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/dsp</devicename></entry>
- <entry>Digitized voice device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/dspW</devicename></entry>
- <entry>Like <devicename>/dev/dsp</devicename>, but 16 bits
- per sample</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/midi</devicename></entry>
- <entry>Raw midi access device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/mixer</devicename></entry>
- <entry>Control port mixer device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/music</devicename></entry>
- <entry>Level 2 sequencer interface</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/sequencer</devicename></entry>
- <entry>Sequencer device</entry>
- </row>
-
- <row>
- <entry><devicename>/dev/pss</devicename></entry>
- <entry>Programmable device interface</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
-
- <para>If all goes well, you should now have a functioning sound
- card. You may want to install an application such as
- <filename role="package">audio/mpg123</filename> to listen to audio files.</para>
-
- <sect2>
- <title>Common Problems</title>
-
- <informaltable>
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Error</entry>
- <entry>Solution</entry>
- </row>
- </thead>
- <indexterm><primary>device node</primary></indexterm>
-
- <tbody>
- <row>
- <entry><errorname>unsupported subdevice XX</errorname></entry>
- <entry><para>One or more of the device nodes was not created
- correctly. Repeat the steps above.</para></entry>
- </row>
-
- <indexterm><primary>I/O port</primary></indexterm>
- <row>
- <entry><errorname>sb_dspwr(XX) timed out</errorname></entry>
- <entry><para>The I/O port is not set correctly.</para></entry>
- </row>
-
- <indexterm><primary>IRQ</primary></indexterm>
- <row>
- <entry><errorname>bad irq XX</errorname></entry>
- <entry><para>The IRQ is set incorrectly. Make sure that
- the set IRQ and the sound IRQ are the same.</para></entry>
- </row>
-
- <row>
- <entry><errorname>xxx: gus pcm not attached, out of
- memory</errorname></entry>
- <entry><para>There is not enough available memory to use
- the device.</para></entry>
- </row>
-
- <indexterm><primary>DSP</primary></indexterm>
- <row>
- <entry><errorname>xxx: can't open /dev/dsp!</errorname></entry>
- <entry><para>Check with <command>fstat | grep dsp</command>
- if another application is holding the device open.
- Noteworthy troublemakers are <application>esound</application> and <application>KDE</application>'s sound
- support.</para></entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- </sect2>
- </sect1>
-
- <sect1 id="sound-mp3">
- <sect1info>
- <authorgroup>
- <author>
- <firstname>Chern</firstname>
- <surname>Lee</surname>
- <contrib>Contributed by </contrib>
- </author>
- </authorgroup>
- <!-- 11 Sept 2001 -->
- </sect1info>
-
- <title>MP3 Audio</title>
-
- <para>MP3 (MPEG Layer 3 Audio) accomplishes near CD-quality sound,
- leaving no reason to let your FreeBSD workstation fall short of
- its offerings.</para>
-
- <sect2 id="mp3-players">
- <title>MP3 Players</title>
-
- <para>By far, the most popular XFree86 MP3 player is
- <application>XMMS</application> (X Multimedia System).
- <application>Winamp</application>
- skins can be used with <application>XMMS</application> since the
- GUI is almost identical to that of Nullsoft's
- <application>Winamp</application>.
- <application>XMMS</application> also has native plug-in
- support.</para>
-
- <para><application>XMMS</application> can be installed from the
- <filename role="package">audio/xmms</filename> port or package.</para>
-
- <para><application>XMMS'</application> interface is intuitive,
- with a playlist, graphic equalizer, and more. Those familiar
- with <application>Winamp</application> will find
- <application>XMMS</application> simple to use.</para>
-
- <para>The <filename role="package">audio/mpg123</filename> port is an alternative,
- command-line MP3 player.</para>
-
- <para><application>mpg123</application> can be run by specifying
- the sound device and the MP3 file on the command line, as
- shown below:</para>
-
- <screen>&prompt.root; mpg123 -a <replaceable>/dev/dsp1.0</replaceable> Foobar-GreatestHits.mp3
-High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2 and 3.
-Version 0.59r (1999/Jun/15). Written and copyrights by Michael Hipp.
-Uses code from various people. See 'README' for more!
-THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!
-
-
-
-
-
-Playing MPEG stream from BT - Foobar-GreastHits.mp3 ...
-MPEG 1.0 layer III, 128 kbit/s, 44100 Hz joint-stereo
-</screen>
-
- <para><literal>/dev/dsp1.0</literal> should be replaced with the
- <devicename>dsp</devicename> device entry on your system.</para>
-
- </sect2>
-
- <sect2 id="rip-cd">
- <title>Ripping CD Audio Tracks</title>
-
- <para>Before encoding a CD or CD track to MP3, the audio data on
- the CD must be ripped onto the hard drive. This is done by
- copying the raw CDDA (CD Digital Audio) data to WAV
- files.</para>
-
- <para>The <command>cdda2wav</command> tool, which is a part of
- the <filename role="package">sysutils/cdrtools</filename> suite, is used for ripping
- audio information of CDs and the information associated with
- it.</para>
-
- <para>With the audio CD in the drive, the following command can
- be issued (as <username>root</username>) to rip an entire CD
- into individual (per track) WAV files:</para>
-
- <screen>&prompt.root; cdda2wav -D <replaceable>0,1,0</replaceable> -B</screen>
-
- <para>The <option>-D <replaceable>0,1,0</replaceable></option>
- indicates the SCSI device <devicename>0,1,0</devicename>,
- which corresponds to the output of <command>cdrecord
- -scanbus</command>.</para>
-
- <para>To rip individual tracks, make use of the
- <option>-t</option> option as shown:</para>
-
- <screen>&prompt.root; cdda2wav -D <replaceable>0,1,0</replaceable> -t 7</screen>
-
- <para>This example rips track seven of the audio CDROM. To rip
- a range of tracks, for example, track one to seven, specify a
- range:</para>
-
- <screen>&prompt.root; cdda2wav -D <replaceable>0,1,0</replaceable> -t 1+7</screen>
-
- <para><application>cdda2wav</application> will also support
- ATAPI (IDE) CDROM drives. To rip from an IDE drive, specify
- the device name in place of the SCSI unit numbers. For
- example, to rip track 7 from an IDE drive:</para>
-
- <screen>&prompt.root; cdda2wav -D <replaceable>/dev/acd0a</replaceable> -t 7</screen>
-
- </sect2>
-
- <sect2 id="mp3-encoding">
- <title>Encoding MP3s</title>
-
- <para>Nowadays, the mp3 encoder of choice is
- <application>lame</application>.
- <application>Lame</application> can be found at
- <filename role="package">audio/lame</filename> in the ports tree.</para>
-
- <para>Using the ripped WAV files, the following command will
- convert <filename>audio01.wav</filename> to
- <filename>audio01.mp3</filename>:</para>
-
- <screen>&prompt.root; lame -h -b <replaceable>128</replaceable> \
---tt "<replaceable>Foo Song Title</replaceable>" \
---ta "<replaceable>FooBar Artist</replaceable>" \
---tl "<replaceable>FooBar Album</replaceable>" \
---ty "<replaceable>2001</replaceable>" \
---tc "<replaceable>Ripped and encoded by Foo</replaceable>" \
---tg "<replaceable>Genre</replaceable>" \
-<replaceable>audio01.wav audio01.mp3</replaceable></screen>
-
- <para>128 kbits seems to be the standard MP3 bitrate in use.
- Many enjoy the higher quality 160, or 192. The higher the
- bitrate, the more disk space the resulting MP3 will
- consume--but the quality will be higher. The
- <option>-h</option> option turns on the <quote>higher quality
- but a little slower</quote> mode. The options beginning with
- <option>--t</option> indicate ID3 tags, which usually contain
- song information, to be embedded within the MP3 file.
- Additional encoding options can be found by consulting the
- lame manual page.</para>
- </sect2>
-
- <sect2 id="mp3-decoding">
- <title>Decoding MP3s</title>
-
- <para>In order to burn an audio CD from MP3s, they must be
- converted to a non-compressed WAV format. Both
- <application>XMMS</application> and
- <application>mpg123</application> support the output of MP3 to
- an uncompressed file format.</para>
-
- <para>Writing to Disk in <application>XMMS</application>:</para>
-
- <procedure>
- <step>
- <para>Launch <application>XMMS</application>.</para>
- </step>
-
- <step>
- <para>Right-click on the window to bring up the
- <application>XMMS</application> menu.</para>
- </step>
-
- <step>
- <para>Select <literal>Preference</literal> under
- <literal>Options</literal>.</para>
- </step>
-
- <step>
- <para>Change the Output Plugin to <quote>Disk Writer
- Plugin</quote>.</para>
- </step>
-
- <step>
- <para>Press <literal>Configure</literal>.</para>
- </step>
-
- <step>
- <para>Enter (or choose browse) a directory to write the
- uncompressed files to.</para>
- </step>
-
- <step>
- <para>Load the MP3 file into <application>XMMS</application>
- as usual, with volume at 100% and EQ settings turned
- off.</para>
- </step>
-
- <step>
- <para>Press <literal>Play</literal> &mdash;
- <application>XMMS</application> will appear as if it is
- playing the MP3, but no music will be heard. It is
- actually playing the MP3 to a file.</para>
- </step>
-
- <step>
- <para>Be sure to set the default Output Plugin back to what
- it was before in order to listen to MP3s again.</para>
- </step>
- </procedure>
-
- <para>Writing to stdout in <application>mpg123</application>:</para>
-
- <procedure>
- <step>
- <para>Run mpg123 -s <replaceable>audio01.mp3</replaceable>
- &gt; audio01.pcm</para>
- </step>
- </procedure>
-
- <para><application>XMMS</application> writes a file in the WAV
- format, while <application>mpg123</application> converts the
- MP3 into raw PCM audio data. Both of these formats can be
- used with <application>cdrecord</application> or
- <application>burncd</application> to create audio
- CDROMs.</para>
-
- <para>Read <xref linkend="creating-cds"> for more information on using a
- CD burner in FreeBSD.</para>
- </sect2>
- </sect1>
-</chapter>
diff --git a/ja_JP.eucJP/books/handbook/multimedia/Makefile b/ja_JP.eucJP/books/handbook/multimedia/Makefile
deleted file mode 100644
index 2487a8c522..0000000000
--- a/ja_JP.eucJP/books/handbook/multimedia/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Build the Handbook with just the content from this chapter.
-#
-# $FreeBSD$
-#
-# Original revision: 1.1
-
-CHAPTERS= sound/chapter.sgml
-
-VPATH= ..
-
-MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
-
-DOC_PREFIX?= ${.CURDIR}/../../../..
-
-.include "../Makefile"
diff --git a/ja_JP.eucJP/books/handbook/multimedia/chapter.sgml b/ja_JP.eucJP/books/handbook/multimedia/chapter.sgml
deleted file mode 100644
index 991d5a72f4..0000000000
--- a/ja_JP.eucJP/books/handbook/multimedia/chapter.sgml
+++ /dev/null
@@ -1,397 +0,0 @@
-<!--
- The FreeBSD Documentation Project
- The FreeBSD Japanese Documentation Project
-
- Original revision: 1.16
- $FreeBSD$
--->
-
-<chapter id="sound">
- <chapterinfo>
- <authorgroup>
- <author>
- <firstname>Moses</firstname>
- <surname>Moore</surname>
- <contrib></contrib>
- </author>
- </authorgroup>
- <!-- 20 November 2000 -->
- </chapterinfo>
-
- <title></title>
-
- <sect1>
- <title>ξϤǤ</title>
-
- <para>Free