]> git.hungrycats.org Git - linux/commitdiff
[PATCH] remove Documentation/DocBook/parportbook.tmpl
authorAndrew Morton <akpm@osdl.org>
Mon, 26 Apr 2004 16:03:46 +0000 (09:03 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 26 Apr 2004 16:03:46 +0000 (09:03 -0700)
From: Christoph Hellwig <hch@lst.de>

The partportbook is licensed under the GFDL and Linus agreed to remove
all GFDL licensed files in
http://www.ussg.iu.edu/hypermail/linux/kernel/0306.1/1968.html.

I pinged the author the first time on the 2nd of april but still didn't get
a reply, then send a patch to Linus to remove it last week but linus
ignored it.  Here's the patch again:

Documentation/DocBook/Makefile
Documentation/DocBook/parport-multi.fig [deleted file]
Documentation/DocBook/parport-share.fig [deleted file]
Documentation/DocBook/parport-structure.fig [deleted file]
Documentation/DocBook/parportbook.tmpl [deleted file]

index 90957636b4c83d382ab5e9c5e2e7f418e73d178a..bf212c0211c9ec516a40b6a2a264c759ebad49a4 100644 (file)
@@ -7,11 +7,10 @@
 # list of DOCBOOKS.
 
 DOCBOOKS := wanbook.sgml z8530book.sgml mcabook.sgml videobook.sgml \
-           parportbook.sgml kernel-hacking.sgml \
-           kernel-locking.sgml via-audio.sgml mousedrivers.sgml \
-           deviceiobook.sgml procfs-guide.sgml tulip-user.sgml \
-           writing_usb_driver.sgml scsidrivers.sgml sis900.sgml \
-           kernel-api.sgml journal-api.sgml lsm.sgml usb.sgml \
+           kernel-hacking.sgml kernel-locking.sgml via-audio.sgml \
+           mousedrivers.sgml deviceiobook.sgml procfs-guide.sgml \
+           tulip-user.sgml writing_usb_driver.sgml scsidrivers.sgml \
+           sis900.sgml kernel-api.sgml journal-api.sgml lsm.sgml usb.sgml \
            gadget.sgml libata.sgml
 
 ###
@@ -92,16 +91,6 @@ C-procfs-example = procfs_example.sgml
 C-procfs-example2 = $(addprefix $(obj)/,$(C-procfs-example))
 $(obj)/procfs-guide.sgml: $(C-procfs-example2)
 
-###
-# The parportbook includes a few images.
-# Force them to be build before the books 
-IMG-parportbook := parport-share.fig parport-multi.fig parport-structure.fig
-IMG-parportbook2 := $(addprefix $(obj)/,$(IMG-parportbook))
-EPS-parportbook := $(patsubst %.fig,%.eps, $(IMG-parportbook2))
-PNG-parportbook := $(patsubst %.fig,%.png, $(IMG-parportbook2))
-$(obj)/parportbook.html: $(PNG-parportbook)
-$(obj)/parportbook.ps $(obj)/parportbook.pdf: $(EPS-parportbook) $(PNG-parportbook)
-
 ###
 # Rules to generate postscript, PDF and HTML
 # db2html creates a directory. Generate a html file used for timestamp
@@ -194,8 +183,6 @@ clean-files := $(DOCBOOKS) \
        $(patsubst %.sgml, %.pdf,  $(DOCBOOKS)) \
        $(patsubst %.sgml, %.html, $(DOCBOOKS)) \
        $(patsubst %.sgml, %.9,    $(DOCBOOKS)) \
-       $(patsubst %.fig,%.eps,    $(IMG-parportbook)) \
-       $(patsubst %.fig,%.png,    $(IMG-parportbook)) \
        $(C-procfs-example)
 
 ifneq ($(wildcard $(patsubst %.html,%,$(HTML))),)
diff --git a/Documentation/DocBook/parport-multi.fig b/Documentation/DocBook/parport-multi.fig
deleted file mode 100644 (file)
index e0517b3..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#FIG 3.2
-Landscape
-Center
-Inches
-Letter  
-100.00
-Single
--2
-1200 2
-6 1425 4350 5175 5475
-6 3450 5100 4425 5475
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
-        4425 5475 4425 5100 3450 5100 3450 5475 4425 5475
-4 0 0 50 0 0 12 0.0000 4 135 510 3600 5400 Printer\001
--6
-6 3375 4350 5175 4725
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
-        5175 4725 5175 4350 3375 4350 3375 4725 5175 4725
-4 0 0 50 0 0 12 0.0000 4 180 870 3825 4650 Multiplexor\001
--6
-6 1425 4650 2775 5475
-6 1425 4650 2775 5475
-2 4 0 1 0 7 50 0 -1 0.000 0 0 6 0 0 5
-        2757 5475 2757 4650 1425 4650 1425 5475 2757 5475
-4 0 0 50 0 0 12 0.0000 4 180 735 1725 5100 Computer\001
--6
-2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
-        2775 4875 2700 4875 2700 5025 2775 5025 2775 4875
-2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
-        2775 5175 2700 5175 2700 5325 2775 5325 2775 5175
--6
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
-        2775 4950 3600 4725
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
-        2775 5250 3450 5325
--6
-6 3150 2625 4125 3525
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
-        4125 3075 4125 2625 3150 2625 3150 3075 4125 3075
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
-        3675 3075 3675 3525
-4 0 0 50 0 0 12 0.0000 4 135 510 3300 2925 Printer\001
--6
-6 4275 3450 5250 4350
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
-        5250 3900 5250 3450 4275 3450 4275 3900 5250 3900
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
-        4800 3900 4800 4350
-4 0 0 50 0 0 12 0.0000 4 135 510 4425 3750 Printer\001
--6
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
-        3900 4050 3900 3525 3375 3525 3375 4050 3900 4050
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
-        3675 4050 3675 4350
-2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
-        3600 4350 3750 4350 3750 4425 3600 4425 3600 4350
-2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
-        4725 4350 4875 4350 4875 4425 4725 4425 4725 4350
-4 0 0 50 0 0 12 0.0000 4 135 285 3450 3900 ZIP\001
diff --git a/Documentation/DocBook/parport-share.fig b/Documentation/DocBook/parport-share.fig
deleted file mode 100644 (file)
index fe4f373..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-#FIG 3.2
-Landscape
-Center
-Inches
-Letter  
-100.00
-Single
--2
-1200 2
-0 32 #8e8e8e
-0 33 #8e8e8e
-0 34 #aeaaae
-0 35 #515551
-0 36 #414141
-0 37 #868286
-0 38 #8e8e8e
-0 39 #414141
-0 40 #868286
-0 41 #c7c3c7
-0 42 #e7e3e7
-0 43 #414141
-0 44 #868286
-0 45 #c7c3c7
-0 46 #e7e3e7
-0 47 #868286
-0 48 #c7c3c7
-0 49 #e7e3e7
-6 1200 3000 2250 4950
-6 1275 3150 2175 3675
-6 1312 3487 1837 3637
-2 1 0 1 40 -1 19 0 -1 0.000 2 0 -1 0 0 5
-        1312 3562 1312 3524 1474 3524 1474 3487 1675 3487
-2 1 0 1 40 -1 19 0 -1 0.000 2 0 -1 0 0 3
-        1474 3637 1474 3562 1675 3562
-2 1 0 1 40 -1 19 0 -1 0.000 2 0 -1 0 0 2
-        1675 3524 1837 3524
-2 1 0 1 7 -1 19 0 -1 0.000 2 0 -1 0 0 2
-        1675 3487 1675 3524
-2 1 0 1 7 -1 19 0 -1 0.000 2 0 -1 0 0 2
-        1312 3562 1474 3562
-2 1 0 1 7 -1 19 0 -1 0.000 2 0 -1 0 0 5
-        1474 3637 1675 3637 1675 3562 1837 3562 1837 3524
-2 1 0 1 40 -1 19 0 -1 0.000 2 0 -1 0 0 3
-        1716 3637 1797 3637 1797 3600
-2 1 0 1 7 -1 19 0 -1 0.000 2 0 -1 0 0 3
-        1716 3637 1716 3600 1797 3600
--6
-6 1413 3345 2070 3397
-6 1994 3352 2070 3390
-2 1 0 1 7 40 19 0 -1 0.000 2 0 -1 0 0 3
-        1994 3390 1994 3352 2070 3352
-2 1 0 1 40 -1 19 0 -1 0.000 2 0 -1 0 0 3
-        1994 3390 2070 3390 2070 3352
--6
-6 1531 3353 1643 3389
-2 2 0 0 40 41 19 0 20 0.000 2 0 -1 0 0 5
-        1568 3353 1606 3353 1606 3389 1568 3389 1568 3353
-2 2 0 0 40 39 19 0 20 0.000 2 0 -1 0 0 5
-        1606 3353 1643 3353 1643 3389 1606 3389 1606 3353
-2 2 0 0 40 41 19 0 20 0.000 2 0 -1 0 0 5
-        1568 3353 1531 3353 1531 3389 1568 3389 1568 3353
--6
-6 1413 3345 1465 3397
-1 3 0 0 0 39 18 0 20 0.000 1 0.0000 1439 3371 26 26 1439 3371 1439 3397
-1 3 0 0 40 41 18 0 20 0.000 1 0.0000 1439 3371 15 15 1439 3371 1443 3385
--6
-2 2 0 0 40 7 19 0 20 0.000 2 0 -1 0 0 3
-        1950 3371 1875 3371 1950 3371
-2 2 0 0 40 41 19 0 20 0.000 2 0 -1 0 0 5
-        1945 3384 1896 3384 1896 3357 1945 3357 1945 3384
--6
-6 1350 3183 2100 3300
-2 1 0 1 7 40 19 0 -1 0.000 2 0 -1 0 0 3
-        1350 3300 1350 3183 2100 3183
-2 1 0 1 40 -1 19 0 -1 0.000 2 0 -1 0 0 3
-        1350 3300 2100 3300 2100 3183
--6
-2 1 0 1 7 7 19 0 -1 0.000 2 0 -1 0 0 5
-        1275 3675 1875 3675 1875 3450 2175 3450 2175 3150
-2 1 0 1 40 7 19 0 -1 0.000 2 0 -1 0 0 3
-        1275 3675 1275 3150 2175 3150
--6
-6 1950 3750 2175 3975
-5 1 0 1 7 7 19 0 -1 0.000 0 0 0 0 2038.000 3900.000 1985 3953 1985 3847 2091 3847
-5 1 0 1 40 7 19 0 -1 0.000 0 1 0 0 2038.000 3900.000 1985 3953 2091 3953 2091 3847
--6
-6 1200 4050 1800 4800
-2 1 0 2 40 7 19 0 -1 0.000 2 1 -1 0 0 2
-        1275 4125 1725 4125
-2 1 0 2 40 7 19 0 -1 0.000 2 1 -1 0 0 2
-        1275 4200 1725 4200
-2 1 0 2 40 7 19 0 -1 0.000 2 1 -1 0 0 2
-        1275 4275 1725 4275
-2 1 0 2 40 7 19 0 -1 0.000 2 1 -1 0 0 2
-        1275 4350 1725 4350
-2 1 0 2 40 7 19 0 -1 0.000 2 1 -1 0 0 2
-        1275 4425 1725 4425
-2 1 0 2 40 7 19 0 -1 0.000 2 1 -1 0 0 2
-        1275 4500 1725 4500
-2 1 0 2 40 7 19 0 -1 0.000 2 1 -1 0 0 2
-        1275 4575 1725 4575
-2 1 0 2 40 7 19 0 -1 0.000 2 1 -1 0 0 2
-        1275 4650 1725 4650
-2 1 0 2 40 7 19 0 -1 0.000 2 1 -1 0 0 2
-        1275 4725 1725 4725
--6
-2 2 0 1 0 39 20 0 20 0.000 2 0 -1 0 0 5
-        1200 4950 1425 4950 1425 4911 1200 4911 1200 4950
-2 2 0 1 0 39 20 0 20 0.000 2 0 -1 0 0 5
-        2025 4950 2250 4950 2250 4911 2025 4911 2025 4950
-2 2 0 1 0 42 20 0 20 0.000 2 0 -1 0 0 5
-        1200 4907 2250 4907 2250 3000 1200 3000 1200 4907
--6
-6 2374 3225 3375 4050
-3 2 0 1 0 37 50 0 -1 0.000 0 0 0 3
-        2374 3402 3139 3402 3257 4050
-        0.000 -1.000 0.000
-3 2 0 1 0 37 50 0 -1 0.000 0 0 0 3
-        2374 3461 3096 3437 3198 4050
-        0.000 -1.000 0.000
--6
-2 2 0 1 0 1 50 0 20 0.000 0 0 -1 0 0 5
-        2925 4575 4050 4575 4050 4875 2925 4875 2925 4575
-2 3 0 1 0 32 50 0 20 0.000 0 0 -1 0 0 5
-        1200 3000 1575 2475 2400 2475 2250 3000 1200 3000
-2 3 0 1 0 8 50 0 20 0.000 0 0 -1 0 0 5
-        2925 4575 3000 4200 4050 4200 4050 4575 2925 4575
-2 2 0 1 0 0 50 0 20 0.000 0 0 -1 0 0 5
-        3075 4725 3900 4725 3900 4800 3075 4800 3075 4725
-2 2 0 1 0 46 50 0 20 0.000 0 0 -1 0 0 5
-        4800 3975 6450 3975 6450 4875 4800 4875 4800 3975
-2 2 0 1 0 36 50 0 20 0.000 0 0 -1 0 0 5
-        5025 4575 6225 4575 6225 4725 5025 4725 5025 4575
-2 2 0 1 0 36 50 0 20 0.000 0 0 -1 0 0 5
-        5025 3975 6225 3975 6225 3300 5025 3300 5025 3975
-2 3 0 1 0 37 50 0 20 0.000 0 0 -1 0 0 5
-        4800 3975 4800 3825 5025 3825 5025 3975 4800 3975
-2 3 0 1 0 37 50 0 20 0.000 0 0 -1 0 0 5
-        6225 3825 6375 3825 6450 3975 6225 3975 6225 3825
-2 3 0 1 0 32 50 0 20 0.000 0 0 -1 0 0 5
-        2400 2475 2250 3000 2250 4875 2400 4350 2400 2475
-2 3 0 1 0 37 50 0 -1 0.000 0 0 -1 0 0 6
-        3075 4200 3075 4050 3300 4050 3375 4050 3375 4200 3075 4200
-2 3 0 1 0 37 50 0 -1 0.000 0 0 -1 0 0 6
-        3900 4200 3900 4050 3675 4050 3600 4050 3600 4200 3900 4200
-3 2 0 1 0 37 50 0 -1 0.000 0 0 0 5
-        3705 4050 3825 3675 4185 3390 4590 3615 4800 4035
-        0.000 -1.000 -1.000 -1.000 0.000
-3 2 0 1 0 37 50 0 -1 0.000 0 0 0 5
-        3765 4050 3874 3708 4202 3449 4571 3654 4800 4185
-        0.000 -1.000 -1.000 -1.000 0.000
-4 0 0 50 0 0 12 0.0000 4 180 735 1350 5400 Computer\001
-4 0 0 50 0 0 12 0.0000 4 180 675 3150 5400 Zip drive\001
-4 0 0 50 0 0 12 0.0000 4 135 510 5325 5400 Printer\001
diff --git a/Documentation/DocBook/parport-structure.fig b/Documentation/DocBook/parport-structure.fig
deleted file mode 100644 (file)
index 4299ce6..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#FIG 3.2
-Landscape
-Center
-Inches
-Letter  
-100.00
-Single
--2
-1200 2
-0 32 #414541
-0 33 #8e8e8e
-0 34 #414541
-0 35 #8e8e8e
-0 36 #414541
-0 37 #8e8e8e
-0 38 #414541
-0 39 #8e8e8e
-0 40 #414541
-0 41 #8e8e8e
-0 42 #414541
-0 43 #8e8e8e
-0 44 #414141
-0 45 #868286
-0 46 #c7c3c7
-0 47 #8e8e8e
-0 48 #414141
-0 49 #868286
-0 50 #c7c3c7
-0 51 #e7e3e7
-6 2025 1800 3075 2250
-2 4 0 1 0 7 50 0 -1 0.000 0 0 3 0 0 5
-        3045 2250 3045 1800 2025 1800 2025 2250 3045 2250
-4 0 0 50 0 14 12 0.0000 4 180 210 2400 2100 lp\001
--6
-6 4125 1800 5175 2250
-2 4 0 1 0 7 50 0 -1 0.000 0 0 3 0 0 5
-        5145 2250 5145 1800 4125 1800 4125 2250 5145 2250
-4 0 0 50 0 14 12 0.0000 4 135 315 4425 2100 ppa\001
--6
-6 3225 3075 4275 3525
-6 3375 3225 4125 3450
-4 0 0 50 0 14 12 0.0000 4 165 735 3375 3375 parport\001
--6
-2 4 0 1 0 7 50 0 -1 0.000 0 0 3 0 0 5
-        4245 3525 4245 3075 3225 3075 3225 3525 4245 3525
--6
-6 3000 4350 4500 4800
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
-        4500 4800 4500 4350 3000 4350 3000 4800 4500 4800
-4 0 0 50 0 14 12 0.0000 4 165 1050 3225 4650 parport_pc\001
--6
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
-       1 1 1.00 60.00 120.00
-        2550 2250 3600 3075
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
-       1 1 1.00 60.00 120.00
-        4650 2250 3825 3075
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
-       1 1 1.00 60.00 120.00
-        3750 3525 3750 4350
diff --git a/Documentation/DocBook/parportbook.tmpl b/Documentation/DocBook/parportbook.tmpl
deleted file mode 100644 (file)
index 8e22b01..0000000
+++ /dev/null
@@ -1,2735 +0,0 @@
-<!-- -*- sgml -*- -->
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN"[]>
-
-<book id="ParportGuide">
- <bookinfo>
-  <title>The Linux 2.4 Parallel Port Subsystem</title>
-
-  <authorgroup>
-   <author>
-    <firstname>Tim</firstname>
-    <surname>Waugh</surname>
-    <affiliation>
-     <address>
-      <email>twaugh@redhat.com</email>
-     </address>
-    </affiliation>
-   </author>
-  </authorgroup>
-
-  <copyright>
-   <year>1999-2000</year>
-   <holder>Tim Waugh</holder>
-  </copyright>
-
-  <legalnotice>
-   <para>
-    Permission is granted to copy, distribute and/or modify this
-    document under the terms of the GNU Free Documentation License,
-    Version 1.1 or any later version published by the Free Software
-    Foundation; with no Invariant Sections, with no Front-Cover Texts,
-    and with no Back-Cover Texts.  A copy of the license is included
-    in the section entitled "GNU Free Documentation License".
-   </para>
-  </legalnotice>
- </bookinfo>
-
- <toc></toc>
-
- <chapter id="design">
-  <title>Design goals</title>
-
-  <sect1>
-   <title>The problems</title>
-
-   <para>
-    The first parallel port support for Linux came with the line
-    printer driver, <literal>lp</literal>.  The printer driver is a
-    character special device, and (in Linux 2.0) had support for
-    writing, via <function>write</function>, and configuration and
-    statistics reporting via <function>ioctl</function>.
-   </para>
-
-   <para>
-    The printer driver could be used on any computer that had an IBM
-    PC-compatible parallel port.  Because some architectures have
-    parallel ports that aren't really the same as PC-style ports,
-    other variants of the printer driver were written in order to
-    support Amiga and Atari parallel ports.
-   </para>
-
-   <para>
-    When the Iomega Zip drive was released, and a driver written for
-    it, a problem became apparent.  The Zip drive is a parallel port
-    device that provides a parallel port of its own---it is designed
-    to sit between a computer and an attached printer, with the
-    printer plugged into the Zip drive, and the Zip drive plugged into
-    the computer.
-   </para>
-
-   <para>
-    The problem was that, although printers and Zip drives were both
-    supported, for any given port only one could be used at a time.
-    Only one of the two drivers could be present in the kernel at
-    once.  This was because of the fact that both drivers wanted to
-    drive the same hardware---the parallel port.  When the printer
-    driver initialised, it would call the
-    <function>check_region</function> function to make sure that the
-    IO region associated with the parallel port was free, and then it
-    would call <function>request_region</function> to allocate it.
-    The Zip drive used the same mechanism.  Whichever driver
-    initialised first would gain exclusive control of the parallel
-    port.
-   </para>
-
-   <para>
-    The only way around this problem at the time was to make sure that
-    both drivers were available as loadable kernel modules.  To use
-    the printer, load the printer driver module; then for the Zip
-    drive, unload the printer driver module and load the Zip driver
-    module.
-   </para>
-
-   <para>
-    The net effect was that printing a document that was stored on a
-    Zip drive was a bit of an ordeal, at least if the Zip drive and
-    printer shared a parallel port.  A better solution was
-    needed.
-   </para>
-
-   <para>
-    Zip drives are not the only devices that presented problems for
-    Linux.  There are other devices with pass-through ports, for
-    example parallel port CD-ROM drives.  There are also printers that
-    report their status textually rather than using simple error pins:
-    sending a command to the printer can cause it to report the number
-    of pages that it has ever printed, or how much free memory it has,
-    or whether it is running out of toner, and so on.  The printer
-    driver didn't originally offer any facility for reading back this
-    information (although Carsten Gross added nibble mode readback
-    support for kernel 2.2).
-   </para>
-
-   <para>
-    The IEEE has issued a standards document called IEEE 1284, which
-    documents existing practice for parallel port communications in a
-    variety of modes.  Those modes are: <quote>compatibility</quote>,
-    reverse nibble, reverse byte, ECP and EPP.  Newer devices often
-    use the more advanced modes of transfer (ECP and EPP).  In Linux
-    2.0, the printer driver only supported <quote>compatibility
-    mode</quote> (i.e. normal printer protocol) and reverse nibble
-    mode.
-   </para>
-
-  </sect1>
-
-  <sect1>
-   <title>The solutions</title>
-
-<!-- How they are addressed
-     - sharing model
-     - overview of structure (i.e. port drivers) in 2.2 and 2.3.
-     - IEEE 1284 stuff
-     - whether or not 'platform independence' goal was met
-  -->
-
-   <para>
-    The <literal>parport</literal> code in Linux 2.2 was designed to
-    meet these problems of architectural differences in parallel
-    ports, of port-sharing between devices with pass-through ports,
-    and of lack of support for IEEE 1284 transfer modes.
-   </para>
-
-   <!-- platform differences -->
-
-   <para>
-    There are two layers to the <literal>parport</literal>
-    subsystem, only one of which deals directly with the hardware.
-    The other layer deals with sharing and IEEE 1284 transfer modes.
-    In this way, parallel support for a particular architecture comes
-    in the form of a module which registers itself with the generic
-    sharing layer.
-   </para>
-
-   <!-- sharing model -->
-
-   <para>
-    The sharing model provided by the <literal>parport</literal>
-    subsystem is one of exclusive access.  A device driver, such as
-    the printer driver, must ask the <literal>parport</literal>
-    layer for access to the port, and can only use the port once
-    access has been granted.  When it has finished a
-    <quote>transaction</quote>, it can tell the
-    <literal>parport</literal> layer that it may release the port
-    for other device drivers to use.
-   </para>
-
-   <!-- talk a bit about how drivers can share devices on the same port -->
-
-   <para>
-    Devices with pass-through ports all manage to share a parallel
-    port with other devices in generally the same way.  The device has
-    a latch for each of the pins on its pass-through port.  The normal
-    state of affairs is pass-through mode, with the device copying the
-    signal lines between its host port and its pass-through port.
-    When the device sees a special signal from the host port, it
-    latches the pass-through port so that devices further downstream
-    don't get confused by the pass-through device's conversation with
-    the host parallel port: the device connected to the pass-through
-    port (and any devices connected in turn to it) are effectively cut
-    off from the computer.  When the pass-through device has completed
-    its transaction with the computer, it enables the pass-through
-    port again.
-   </para>
-
-   <mediaobject>
-    <imageobject>
-     <imagedata fileref="parport-share" format="eps">
-    </imageobject>
-    <imageobject>
-     <imagedata fileref="parport-share.png" format="png">
-    </imageobject>
-   </mediaobject>
-
-   <para>
-    This technique relies on certain <quote>special signals</quote>
-    being invisible to devices that aren't watching for them.  This
-    tends to mean only changing the data signals and leaving the
-    control signals alone.  IEEE 1284.3 documents a standard protocol
-    for daisy-chaining devices together with parallel ports.
-   </para>
-
-   <!-- transfer modes -->
-
-   <para>
-    Support for standard transfer modes are provided as operations
-    that can be performed on a port, along with operations for setting
-    the data lines, or the control lines, or reading the status lines.
-    These operations appear to the device driver as function pointers;
-    more later.
-   </para>
-
-  </sect1>
-
- </chapter>
-
- <chapter id="transfermodes">
-  <title>Standard transfer modes</title>
-
-  <!-- Defined by IEEE, but in common use (even though there are widely -->
-  <!-- varying implementations). -->
-
-  <para>
-   The <quote>standard</quote> transfer modes in use over the parallel
-   port are <quote>defined</quote> by a document called IEEE 1284.  It
-   really just codifies existing practice and documents protocols (and
-   variations on protocols) that have been in common use for quite
-   some time.
-  </para>
-
-  <para>
-   The original definitions of which pin did what were set out by
-   Centronics Data Computer Corporation, but only the printer-side
-   interface signals were specified.
-  </para>
-
-  <para>
-   By the early 1980s, IBM's host-side implementation had become the
-   most widely used.  New printers emerged that claimed Centronics
-   compatibility, but although compatible with Centronics they
-   differed from one another in a number of ways.
-  </para>
-
-  <para>
-   As a result of this, when IEEE 1284 was published in 1994, all that
-   it could really do was document the various protocols that are used
-   for printers (there are about six variations on a theme).
-  </para>
-
-  <para>
-   In addition to the protocol used to talk to Centronics-compatible
-   printers, IEEE 1284 defined other protocols that are used for
-   unidirectional peripheral-to-host transfers (reverse nibble and
-   reverse byte) and for fast bidirectional transfers (ECP and
-   EPP).
-  </para>
-
- </chapter>
-
- <chapter id="structure">
-  <title>Structure</title>
-
-<!-- Main structure
-     - sharing core
-     - parports and their IEEE 1284 overrides
-       - IEEE 1284 transfer modes for generic ports
-       - maybe mention muxes here
-     - pardevices
-     - IEEE 1284.3 API
-  -->
-
-  <mediaobject>
-   <imageobject>
-    <imagedata fileref="parport-structure" format="eps">
-   </imageobject>
-   <imageobject>
-    <imagedata fileref="parport-structure.png" format="png">
-   </imageobject>
-  </mediaobject>
-
-  <sect1>
-   <title>Sharing core</title>
-
-   <para>
-    At the core of the <literal>parport</literal> subsystem is the
-    sharing mechanism (see
-    <filename>drivers/parport/share.c</filename>).  This module,
-    <literal>parport</literal>, is responsible for keeping track of
-    which ports there are in the system, which device drivers might be
-    interested in new ports, and whether or not each port is available
-    for use (or if not, which driver is currently using it).
-   </para>
-
-  </sect1>
-
-  <sect1>
-   <title>Parports and their overrides</title>
-
-   <para>
-    The generic <literal>parport</literal> sharing code doesn't
-    directly handle the parallel port hardware.  That is done instead
-    by <quote>low-level</quote> <literal>parport</literal> drivers.
-    The function of a low-level <literal>parport</literal> driver is
-    to detect parallel ports, register them with the sharing code, and
-    provide a list of access functions for each port.
-   </para>
-
-   <para>
-    The most basic access functions that must be provided are ones for
-    examining the status lines, for setting the control lines, and for
-    setting the data lines.  There are also access functions for
-    setting the direction of the data lines; normally they are in the
-    <quote>forward</quote> direction (that is, the computer drives
-    them), but some ports allow switching to <quote>reverse</quote>
-    mode (driven by the peripheral).  There is an access function for
-    examining the data lines once in reverse mode.
-   </para>
-
-  </sect1>
-
-  <sect1>
-   <title>IEEE 1284 transfer modes</title>
-
-   <para>
-    Stacked on top of the sharing mechanism, but still in the
-    <literal>parport</literal> module, are functions for
-    transferring data.  They are provided for the device drivers to
-    use, and are very much like library routines.  Since these
-    transfer functions are provided by the generic
-    <literal>parport</literal> core they must use the <quote>lowest
-    common denominator</quote> set of access functions: they can set
-    the control lines, examine the status lines, and use the data
-    lines.  With some parallel ports the data lines can only be set
-    and not examined, and with other ports accessing the data register
-    causes control line activity; with these types of situations, the
-    IEEE 1284 transfer functions make a best effort attempt to do the
-    right thing.  In some cases, it is not physically possible to use
-    particular IEEE 1284 transfer modes.
-   </para>
-
-   <para>
-    The low-level <literal>parport</literal> drivers also provide
-    IEEE 1284 transfer functions, as names in the access function
-    list.  The low-level driver can just name the generic IEEE 1284
-    transfer functions for this.  Some parallel ports can do IEEE 1284
-    transfers in hardware; for those ports, the low-level driver can
-    provide functions to utilise that feature.
-   </para>
-
-  </sect1>
-
-  <!-- muxes? -->
-
-  <sect1>
-   <title>Pardevices and parport_drivers</title>
-
-   <para>
-    When a parallel port device driver (such as
-    <literal>lp</literal>) initialises it tells the sharing layer
-    about itself using <function>parport_register_driver</function>.
-    The information is put into a <structname>struct
-    parport_driver</structname>, which is put into a linked list.  The
-    information in a <structname>struct parport_driver</structname>
-    really just amounts to some function pointers to callbacks in the
-    parallel port device driver.
-   </para>
-
-   <para>
-    During its initialisation, a low-level port driver tells the
-    sharing layer about all the ports that it has found (using
-    <function>parport_register_port</function>), and the sharing layer
-    creates a <structname>struct parport</structname> for each of
-    them.  Each <structname>struct parport</structname> contains
-    (among other things) a pointer to a <structname>struct
-    parport_operations</structname>, which is a list of function
-    pointers for the various operations that can be performed on a
-    port.  You can think of a <structname>struct parport</structname>
-    as a parallel port <quote>object</quote>, if
-    <quote>object-orientated</quote> programming is your thing.  The
-    <structname>parport</structname> structures are chained in a
-    linked list, whose head is <varname>portlist</varname> (in
-    <filename>drivers/parport/share.c</filename>).
-   </para>
-
-   <para>
-    Once the port has been registered, the low-level port driver
-    announces it.  The <function>parport_announce_port</function>
-    function walks down the list of parallel port device drivers
-    (<structname>struct parport_driver</structname>s) calling the
-    <function>attach</function> function of each (which may block).
-   </para>
-
-   <para>
-    Similarly, a low-level port driver can undo the effect of
-    registering a port with the
-    <function>parport_unregister_port</function> function, and device
-    drivers are notified using the <function>detach</function>
-    callback (which may not block).
-   </para>
-
-   <para>
-    Device drivers can undo the effect of registering themselves with
-    the <function>parport_unregister_driver</function>
-    function.
-   </para>
-
-  </sect1>
-
-  <!-- IEEE 1284.3 API -->
-
-  <sect1>
-   <title>The IEEE 1284.3 API</title>
-
-   <para>
-    The ability to daisy-chain devices is very useful, but if every
-    device does it in a different way it could lead to lots of
-    complications for device driver writers.  Fortunately, the IEEE
-    are standardising it in IEEE 1284.3, which covers daisy-chain
-    devices and port multiplexors.
-   </para>
-
-   <para>
-    At the time of writing, IEEE 1284.3 has not been published, but
-    the draft specifies the on-the-wire protocol for daisy-chaining
-    and multiplexing, and also suggests a programming interface for
-    using it.  That interface (or most of it) has been implemented in
-    the <literal>parport</literal> code in Linux.
-   </para>
-
-   <para>
-    At initialisation of the parallel port <quote>bus</quote>,
-    daisy-chained devices are assigned addresses starting from zero.
-    There can only be four devices with daisy-chain addresses, plus
-    one device on the end that doesn't know about daisy-chaining and
-    thinks it's connected directly to a computer.
-   </para>
-
-   <para>
-    Another way of connecting more parallel port devices is to use a
-    multiplexor.  The idea is to have a device that is connected
-    directly to a parallel port on a computer, but has a number of
-    parallel ports on the other side for other peripherals to connect
-    to (two or four ports are allowed).  The multiplexor switches
-    control to different ports under software control---it is, in
-    effect, a programmable printer switch.
-   </para>
-
-   <para>
-    Combining the ability of daisy-chaining five devices together with
-    the ability to multiplex one parallel port between four gives the
-    potential to have twenty peripherals connected to the same
-    parallel port!
-   </para>
-
-   <para>
-    In addition, of course, a single computer can have multiple
-    parallel ports.  So, each parallel port peripheral in the system
-    can be identified with three numbers, or co-ordinates: the
-    parallel port, the multiplexed port, and the daisy-chain
-    address.
-   </para>
-
-   <mediaobject>
-    <imageobject>
-     <imagedata fileref="parport-multi" format="eps">
-    </imageobject>
-    <imageobject>
-     <imagedata fileref="parport-multi.png" format="png">
-    </imageobject>
-   </mediaobject>
-
-   <para>
-    Each device in the system is numbered at initialisation (by
-    <function>parport_daisy_init</function>).  You can convert between
-    this device number and its co-ordinates with
-    <function>parport_device_num</function> and
-    <function>parport_device_coords</function>.
-   </para>
-
-   <funcsynopsis>
-    <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-    </funcsynopsisinfo>
-    <funcprototype>
-     <funcdef>int <function>parport_device_num</function></funcdef>
-     <paramdef>int <parameter>parport</parameter></paramdef>
-     <paramdef>int <parameter>mux</parameter></paramdef>
-     <paramdef>int <parameter>daisy</parameter></paramdef>
-    </funcprototype>
-   </funcsynopsis>
-
-   <funcsynopsis>
-    <funcprototype>
-     <funcdef>int <function>parport_device_coords</function></funcdef>
-     <paramdef>int <parameter>devnum</parameter></paramdef>
-     <paramdef>int *<parameter>parport</parameter></paramdef>
-     <paramdef>int *<parameter>mux</parameter></paramdef>
-     <paramdef>int *<parameter>daisy</parameter></paramdef>
-    </funcprototype>
-   </funcsynopsis>
-
-   <para>
-    Any parallel port peripheral will be connected directly or
-    indirectly to a parallel port on the system, but it won't have a
-    daisy-chain address if it does not know about daisy-chaining, and
-    it won't be connected through a multiplexor port if there is no
-    multiplexor.  The special co-ordinate value
-    <constant>-1</constant> is used to indicate these cases.
-   </para>
-
-   <para>
-    Two functions are provided for finding devices based on their IEEE
-    1284 Device ID: <function>parport_find_device</function> and
-    <function>parport_find_class</function>.
-   </para>
-
-   <funcsynopsis>
-    <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-    </funcsynopsisinfo>
-    <funcprototype>
-     <funcdef>int <function>parport_find_device</function></funcdef>
-     <paramdef>const char *<parameter>mfg</parameter></paramdef>
-     <paramdef>const char *<parameter>mdl</parameter></paramdef>
-     <paramdef>int <parameter>from</parameter></paramdef>
-    </funcprototype>
-   </funcsynopsis>
-
-   <funcsynopsis>
-    <funcprototype>
-     <funcdef>int <function>parport_find_class</function></funcdef>
-     <paramdef>parport_device_class <parameter>cls</parameter></paramdef>
-     <paramdef>int <parameter>from</parameter></paramdef>
-    </funcprototype>
-   </funcsynopsis>
-
-   <para>
-    These functions take a device number (in addition to some other
-    things), and return another device number.  They walk through the
-    list of detected devices until they find one that matches the
-    requirements, and then return that device number (or
-    <constant>-1</constant> if there are no more such devices).  They
-    start their search at the device after the one in the list with
-    the number given (at <parameter>from</parameter>+1, in other
-    words).
-   </para>
-
-  </sect1>
-
- </chapter>
-
- <chapter id="drivers">
-  <title>Device driver's view</title>
-
-<!-- Cover:
-     - sharing interface, preemption, interrupts, wakeups...
-     - IEEE 1284.3 interface
-     - port operations
-       - why can read data but ctr is faked, etc.
-  -->
-
-<!-- I should take a look at the kernel hackers' guide bit I wrote, -->
-<!-- as that deals with a lot of this.  The main complaint with it  -->
-<!-- was that there weren't enough examples, but 'The printer -->
-<!-- driver' should deal with that later; might be worth mentioning -->
-<!-- in the text. -->
-
-  <para>
-   This section is written from the point of view of the device driver
-   programmer, who might be writing a driver for a printer or a
-   scanner or else anything that plugs into the parallel port.  It
-   explains how to use the <literal>parport</literal> interface to
-   find parallel ports, use them, and share them with other device
-   drivers.
-  </para>
-
-  <para>
-   We'll start out with a description of the various functions that
-   can be called, and then look at a reasonably simple example of
-   their use: the printer driver.
-  </para>
-
-  <para>
-   The interactions between the device driver and the
-   <literal>parport</literal> layer are as follows.  First, the
-   device driver registers its existence with
-   <literal>parport</literal>, in order to get told about any
-   parallel ports that have been (or will be) detected.  When it gets
-   told about a parallel port, it then tells
-   <literal>parport</literal> that it wants to drive a device on
-   that port.  Thereafter it can claim exclusive access to the port in
-   order to talk to its device.
-  </para>
-
-  <para>
-   So, the first thing for the device driver to do is tell
-   <literal>parport</literal> that it wants to know what parallel
-   ports are on the system.  To do this, it uses the
-   <function>parport_register_driver</function> function:
-  </para>
-
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-
-struct parport_driver {
-        const char *name;
-        void (*attach) (struct parport *);
-        void (*detach) (struct parport *);
-        struct parport_driver *next;
-};
-   </funcsynopsisinfo>
-
-   <funcprototype>
-    <funcdef>int <function>parport_register_driver</function></funcdef>
-    <paramdef>struct parport_driver *<parameter>driver</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   In other words, the device driver passes pointers to a couple of
-   functions to <literal>parport</literal>, and
-   <literal>parport</literal> calls <function>attach</function> for
-   each port that's detected (and <function>detach</function> for each
-   port that disappears---yes, this can happen).
-  </para>
-
-  <para>
-   The next thing that happens is that the device driver tells
-   <literal>parport</literal> that it thinks there's a device on the
-   port that it can drive.  This typically will happen in the driver's
-   <function>attach</function> function, and is done with
-   <function>parport_register_device</function>:
-  </para>
-
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-   </funcsynopsisinfo>
-   <funcprototype>
-    <funcdef>struct pardevice *<function>parport_register_device</function></funcdef>
-    <paramdef>struct parport *<parameter>port</parameter></paramdef>
-    <paramdef>const char *<parameter>name</parameter></paramdef>
-    <paramdef>int <parameter>(*pf)</parameter>
-     <funcparams>void *</funcparams></paramdef>
-    <paramdef>void <parameter>(*kf)</parameter>
-     <funcparams>void *</funcparams></paramdef>
-    <paramdef>void <parameter>(*irq_func)</parameter>
-     <funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
-    <paramdef>int <parameter>flags</parameter></paramdef>
-    <paramdef>void *<parameter>handle</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   The <parameter>port</parameter> comes from the parameter supplied
-   to the <function>attach</function> function when it is called, or
-   alternatively can be found from the list of detected parallel ports
-   directly with the (now deprecated)
-   <function>parport_enumerate</function> function.  A better way of
-   doing this is with <function>parport_find_number</function> or
-   <function>parport_find_base</function> functions, which find ports
-   by number and by base I/O address respectively.
-  </para>
-
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-   </funcsynopsisinfo>
-   <funcprototype>
-    <funcdef>struct parport *<function>parport_find_number</function></funcdef>
-    <paramdef>int <parameter>number</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-   </funcsynopsisinfo>
-   <funcprototype>
-    <funcdef>struct parport *<function>parport_find_base</function></funcdef>
-    <paramdef>unsigned long <parameter>base</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   The next three parameters, <parameter>pf</parameter>,
-   <parameter>kf</parameter>, and <parameter>irq_func</parameter>, are
-   more function pointers.  These callback functions get called under
-   various circumstances, and are always given the
-   <parameter>handle</parameter> as one of their parameters.
-  </para>
-
-  <para>
-   The preemption callback, <parameter>pf</parameter>, is called when
-   the driver has claimed access to the port but another device driver
-   wants access.  If the driver is willing to let the port go, it
-   should return zero and the port will be released on its behalf.
-   There is no need to call <function>parport_release</function>.  If
-   <parameter>pf</parameter> gets called at a bad time for letting the
-   port go, it should return non-zero and no action will be taken.  It
-   is good manners for the driver to try to release the port at the
-   earliest opportunity after its preemption callback is
-   called.
-  </para>
-
-  <para>
-   The <quote>kick</quote> callback, <parameter>kf</parameter>, is
-   called when the port can be claimed for exclusive access; that is,
-   <function>parport_claim</function> is guaranteed to succeed inside
-   the <quote>kick</quote> callback.  If the driver wants to claim the
-   port it should do so; otherwise, it need not take any
-   action.
-  </para>
-
-  <para>
-   The <parameter>irq_func</parameter> callback is called,
-   predictably, when a parallel port interrupt is generated.  But it
-   is not the only code that hooks on the interrupt.  The sequence is
-   this: the lowlevel driver is the one that has done
-   <function>request_irq</function>; it then does whatever
-   hardware-specific things it needs to do to the parallel port
-   hardware (for PC-style ports, there is nothing special to do); it
-   then tells the IEEE 1284 code about the interrupt, which may
-   involve reacting to an IEEE 1284 event, depending on the current
-   IEEE 1284 phase; and finally the <parameter>irq_func</parameter>
-   function is called.
-  </para>
-
-  <para>
-   None of the callback functions are allowed to block.
-  </para>
-
-  <para>
-   The <parameter>flags</parameter> are for telling
-   <literal>parport</literal> any requirements or hints that are
-   useful.  The only useful value here (other than
-   <constant>0</constant>, which is the usual value) is
-   <constant>PARPORT_DEV_EXCL</constant>.  The point of that flag is
-   to request exclusive access at all times---once a driver has
-   successfully called <function>parport_register_device</function>
-   with that flag, no other device drivers will be able to register
-   devices on that port (until the successful driver deregisters its
-   device, of course).
-  </para>
-
-  <para>
-   The <constant>PARPORT_DEV_EXCL</constant> flag is for preventing
-   port sharing, and so should only be used when sharing the port with
-   other device drivers is impossible and would lead to incorrect
-   behaviour.  Use it sparingly!
-  </para>
-
-  <para>
-   Devices can also be registered by device drivers based on their
-   device numbers (the same device numbers as in the previous
-   section).
-  </para>
-
-  <para>
-   The <function>parport_open</function> function is similar to
-   <function>parport_register_device</function>, and
-   <function>parport_close</function> is the equivalent of
-   <function>parport_unregister_device</function>.  The difference is
-   that <function>parport_open</function> takes a device number rather
-   than a pointer to a <structname>struct parport</structname>.
-  </para>
-
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-   </funcsynopsisinfo>
-   <funcprototype>
-    <funcdef>struct pardevice *<function>parport_open</function></funcdef>
-    <paramdef>int <parameter>devnum</parameter></paramdef>
-    <paramdef>const char *<parameter>name</parameter></paramdef>
-    <paramdef>int <parameter>(*pf)</parameter>
-     <funcparams>void *</funcparams></paramdef>
-    <paramdef>int <parameter>(*kf)</parameter>
-     <funcparams>void *</funcparams></paramdef>
-    <paramdef>int <parameter>(*irqf)</parameter>
-     <funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
-    <paramdef>int <parameter>flags</parameter></paramdef>
-    <paramdef>void *<parameter>handle</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <funcsynopsis>
-   <funcprototype>
-    <funcdef>void <function>parport_close</function></funcdef>
-    <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <funcsynopsis>
-   <funcprototype>
-    <funcdef>struct pardevice *<function>parport_register_device</function></funcdef>
-    <paramdef>struct parport *<parameter>port</parameter></paramdef>
-    <paramdef>const char *<parameter>name</parameter></paramdef>
-    <paramdef>int <parameter>(*pf)</parameter>
-     <funcparams>void *</funcparams></paramdef>
-    <paramdef>int <parameter>(*kf)</parameter>
-     <funcparams>void *</funcparams></paramdef>
-    <paramdef>int <parameter>(*irqf)</parameter>
-     <funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
-    <paramdef>int <parameter>flags</parameter></paramdef>
-    <paramdef>void *<parameter>handle</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <funcsynopsis>
-   <funcprototype>
-    <funcdef>void <function>parport_unregister_device</function></funcdef>
-    <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   The intended use of these functions is during driver initialisation
-   while the driver looks for devices that it supports, as
-   demonstrated by the following code fragment:
-  </para>
-
-  <programlisting>
-   <![CDATA[
-int devnum = -1;
-while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM,
-                                     devnum)) != -1) {
-    struct pardevice *dev = parport_open (devnum, ...);
-    ...
-}
-   ]]></programlisting>
-
-  <para>
-   Once your device driver has registered its device and been handed a
-   pointer to a <structname>struct pardevice</structname>, the next
-   thing you are likely to want to do is communicate with the device
-   you think is there.  To do that you'll need to claim access to the
-   port.
-  </para>
-
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-   </funcsynopsisinfo>
-   <funcprototype>
-    <funcdef>int <function>parport_claim</function></funcdef>
-    <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <funcsynopsis>
-   <funcprototype>
-    <funcdef>int <function>parport_claim_or_block</function></funcdef>
-    <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <funcsynopsis>
-   <funcprototype>
-    <funcdef>void <function>parport_release</function></funcdef>
-    <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   To claim access to the port, use <function>parport_claim</function>
-   or <function>parport_claim_or_block</function>.  The first of these
-   will not block, and so can be used from interrupt context.  If
-   <function>parport_claim</function> succeeds it will return zero and
-   the port is available to use.  It may fail (returning non-zero) if
-   the port is in use by another driver and that driver is not willing
-   to relinquish control of the port.
-  </para>
-
-  <para>
-   The other function, <function>parport_claim_or_block</function>,
-   will block if necessary to wait for the port to be free.  If it
-   slept, it returns <constant>1</constant>; if it succeeded without
-   needing to sleep it returns <constant>0</constant>.  If it fails it
-   will return a negative error code.
-  </para>
-
-  <para>
-   When you have finished communicating with the device, you can give
-   up access to the port so that other drivers can communicate with
-   their devices.  The <function>parport_release</function> function
-   cannot fail, but it should not be called without the port claimed.
-   Similarly, you should not try to claim the port if you already have
-   it claimed.
-  </para>
-
-  <para>
-   You may find that although there are convenient points for your
-   driver to relinquish the parallel port and allow other drivers to
-   talk to their devices, it would be preferable to keep hold of the
-   port.  The printer driver only needs the port when there is data to
-   print, for example, but a network driver (such as PLIP) could be
-   sent a remote packet at any time.  With PLIP, it is no huge
-   catastrophe if a network packet is dropped, since it will likely be
-   sent again, so it is possible for that kind of driver to share the
-   port with other (pass-through) devices.
-  </para>
-
-  <para>
-   The <function>parport_yield</function> and
-   <function>parport_yield_blocking</function> functions are for
-   marking points in the driver at which other drivers may claim the
-   port and use their devices.  Yielding the port is similar to
-   releasing it and reclaiming it, but is more efficient because
-   nothing is done if there are no other devices needing the port.  In
-   fact, nothing is done even if there are other devices waiting but
-   the current device is still within its <quote>timeslice</quote>.
-   The default timeslice is half a second, but it can be adjusted via
-   a <filename>/proc</filename> entry.
-  </para>
-
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-   </funcsynopsisinfo>
-   <funcprototype>
-    <funcdef>int <function>parport_yield</function></funcdef>
-    <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <funcsynopsis>
-   <funcprototype>
-    <funcdef>int <function>parport_yield_blocking</function></funcdef>
-    <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   The first of these, <function>parport_yield</function>, will not
-   block but as a result may fail.  The return value for
-   <function>parport_yield</function> is the same as for
-   <function>parport_claim</function>.  The blocking version,
-   <function>parport_yield_blocking</function>, has the same return
-   code as <function>parport_claim_or_block</function>.
-  </para>
-
-  <para>
-   Once the port has been claimed, the device driver can use the
-   functions in the <structname>struct parport_operations</structname>
-   pointer in the <structname>struct parport</structname> it has a
-   pointer to.  For example:
-  </para>
-
-  <programlisting>
-   <![CDATA[
-port->ops->write_data (port, d);
-   ]]></programlisting>
-
-  <para>
-   Some of these operations have <quote>shortcuts</quote>.  For
-   instance, <function>parport_write_data</function> is equivalent to
-   the above, but may be a little bit faster (it's a macro that in
-   some cases can avoid needing to indirect through
-   <varname>port</varname> and <varname>ops</varname>).
-  </para>
-
- </chapter>
-
- <chapter id="portdrivers">
-  <title>Port drivers</title>
-
-  <!-- What port drivers are for (i.e. implementing parport objects). -->
-
-  <para>
-   To recap, then:</para>
-
-  <itemizedlist spacing="compact">
-
-   <listitem>
-    <para>
-     The device driver registers itself with <literal>parport</literal>.
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     A low-level driver finds a parallel port and registers it with
-     <literal>parport</literal> (these first two things can happen
-     in either order).  This registration creates a <structname>struct
-     parport</structname> which is linked onto a list of known ports.
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     <literal>parport</literal> calls the
-     <function>attach</function> function of each registered device
-     driver, passing it the pointer to the new <structname>struct
-     parport</structname>.
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     The device driver gets a handle from
-     <literal>parport</literal>, for use with
-     <function>parport_claim</function>/<function>release</function>.
-     This handle takes the form of a pointer to a <structname>struct
-     pardevice</structname>, representing a particular device on the
-     parallel port, and is acquired using
-     <function>parport_register_device</function>.
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     The device driver claims the port using
-     <function>parport_claim</function> (or
-     <function>function_claim_or_block</function>).
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     Then it goes ahead and uses the port.  When finished it releases
-     the port.
-    </para>
-   </listitem>
-
-  </itemizedlist>
-
-  <para>
-   The purpose of the low-level drivers, then, is to detect parallel
-   ports and provide methods of accessing them (i.e. implementing the
-   operations in <structname>struct
-   parport_operations</structname>).
-  </para>
-
-  <!-- Should DocBookise this -->
-  <para>
-   A more complete description of which operation is supposed to do
-   what is available in
-   <filename>Documentation/parport-lowlevel.txt</filename>.
-  </para>
-
- </chapter>
-
- <chapter id="lp">
-  <title>The printer driver</title>
-
-  <!-- Talk the reader through the printer driver. -->
-  <!-- Could even talk about parallel port console here. -->
-
-  <para>
-   The printer driver, <literal>lp</literal> is a character special
-   device driver and a <literal>parport</literal> client.  As a
-   character special device driver it registers a <structname>struct
-   file_operations</structname> using
-   <function>register_chrdev</function>, with pointers filled in for
-   <structfield>write</structfield>, <structfield>ioctl</structfield>,
-   <structfield>open</structfield> and
-   <structfield>release</structfield>.  As a client of
-   <literal>parport</literal>, it registers a <structname>struct
-   parport_driver</structname> using
-   <function>parport_register_driver</function>, so that
-   <literal>parport</literal> knows to call
-   <function>lp_attach</function> when a new parallel port is
-   discovered (and <function>lp_detach</function> when it goes
-   away).
-  </para>
-
-  <para>
-   The parallel port console functionality is also implemented in
-   <filename>drivers/char/lp.c</filename>, but that won't be covered
-   here (it's quite simple though).
-  </para>
-
-  <para>
-   The initialisation of the driver is quite easy to understand (see
-   <function>lp_init</function>).  The <varname>lp_table</varname> is
-   an array of structures that contain information about a specific
-   device (the <structname>struct pardevice</structname> associated
-   with it, for example).  That array is initialised to sensible
-   values first of all.
-  </para>
-
-  <para>
-   Next, the printer driver calls <function>register_chrdev</function>
-   passing it a pointer to <varname>lp_fops</varname>, which contains
-   function pointers for the printer driver's implementation of
-   <function>open</function>, <function>write</function>, and so on.
-   This part is the same as for any character special device
-   driver.
-  </para>
-
-  <para>
-   After successfully registering itself as a character special device
-   driver, the printer driver registers itself as a
-   <literal>parport</literal> client using
-   <function>parport_register_driver</function>.  It passes a pointer
-   to this structure:
-  </para>
-
-  <programlisting>
-   <![CDATA[
-static struct parport_driver lp_driver = {
-        "lp",
-        lp_attach,
-        lp_detach,
-        NULL
-};
-   ]]></programlisting>
-
-  <para>
-   The <function>lp_detach</function> function is not very interesting
-   (it does nothing); the interesting bit is
-   <function>lp_attach</function>.  What goes on here depends on
-   whether the user supplied any parameters.  The possibilities are:
-   no parameters supplied, in which case the printer driver uses every
-   port that is detected; the user supplied the parameter
-   <quote>auto</quote>, in which case only ports on which the device
-   ID string indicates a printer is present are used; or the user
-   supplied a list of parallel port numbers to try, in which case only
-   those are used.
-  </para>
-
-  <para>
-   For each port that the printer driver wants to use (see
-   <function>lp_register</function>), it calls
-   <function>parport_register_device</function> and stores the
-   resulting <structname>struct pardevice</structname> pointer in the
-   <varname>lp_table</varname>.  If the user told it to do so, it then
-   resets the printer.
-  </para>
-
-  <para>
-   The other interesting piece of the printer driver, from the point
-   of view of <literal>parport</literal>, is
-   <function>lp_write</function>.  In this function, the user space
-   process has data that it wants printed, and the printer driver
-   hands it off to the <literal>parport</literal> code to deal with.
-  </para>
-
-  <para>
-   The <literal>parport</literal> functions it uses that we have not
-   seen yet are <function>parport_negotiate</function>,
-   <function>parport_set_timeout</function>, and
-   <function>parport_write</function>.  These functions are part of
-   the IEEE 1284 implementation.
-  </para>
-
-  <para>
-   The way the IEEE 1284 protocol works is that the host tells the
-   peripheral what transfer mode it would like to use, and the
-   peripheral either accepts that mode or rejects it; if the mode is
-   rejected, the host can try again with a different mode.  This is
-   the negotiation phase.  Once the peripheral has accepted a
-   particular transfer mode, data transfer can begin that mode.
-  </para>
-
-  <para>
-   The particular transfer mode that the printer driver wants to use
-   is named in IEEE 1284 as <quote>compatibility</quote> mode, and the
-   function to request a particular mode is called
-   <function>parport_negotiate</function>.
-  </para>
-
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-   </funcsynopsisinfo>
-   <funcprototype>
-    <funcdef>int <function>parport_negotiate</function></funcdef>
-    <paramdef>struct parport *<parameter>port</parameter></paramdef>
-    <paramdef>int <parameter>mode</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   The <parameter>modes</parameter> parameter is a symbolic constant
-   representing an IEEE 1284 mode; in this instance, it is
-   <constant>IEEE1284_MODE_COMPAT</constant>. (Compatibility mode is
-   slightly different to the other modes---rather than being
-   specifically requested, it is the default until another mode is
-   selected.)
-  </para>
-
-  <para>
-   Back to <function>lp_write</function> then.  First, access to the
-   parallel port is secured with
-   <function>parport_claim_or_block</function>.  At this point the
-   driver might sleep, waiting for another driver (perhaps a Zip drive
-   driver, for instance) to let the port go.  Next, it goes to
-   compatibility mode using <function>parport_negotiate</function>.
-  </para>
-
-  <para>
-   The main work is done in the write-loop.  In particular, the line
-   that hands the data over to <literal>parport</literal> reads:
-  </para>
-
-<programlisting>
-<![CDATA[
-        written = parport_write (port, kbuf, copy_size);
-]]></programlisting>
-
-  <para>
-   The <function>parport_write</function> function writes data to the
-   peripheral using the currently selected transfer mode
-   (compatibility mode, in this case).  It returns the number of bytes
-   successfully written:
-  </para>
-
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-   </funcsynopsisinfo>
-   <funcprototype>
-    <funcdef>ssize_t <function>parport_write</function></funcdef>
-    <paramdef>struct parport *<parameter>port</parameter></paramdef>
-    <paramdef>const void *<parameter>buf</parameter></paramdef>
-    <paramdef>size_t <parameter>len</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <funcsynopsis>
-   <funcprototype>
-    <funcdef>ssize_t <function>parport_read</function></funcdef>
-    <paramdef>struct parport *<parameter>port</parameter></paramdef>
-    <paramdef>void *<parameter>buf</parameter></paramdef>
-    <paramdef>size_t <parameter>len</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   (<function>parport_read</function> does what it sounds like, but
-   only works for modes in which reverse transfer is possible.  Of
-   course, <function>parport_write</function> only works in modes in
-   which forward transfer is possible, too.)
-  </para>
-
-  <para>
-   The <parameter>buf</parameter> pointer should be to kernel space
-   memory, and obviously the <parameter>len</parameter> parameter
-   specifies the amount of data to transfer.
-  </para>
-
-  <para>
-   In fact what <function>parport_write</function> does is call the
-   appropriate block transfer function from the <structname>struct
-   parport_operations</structname>:
-  </para>
-
-  <programlisting>
-   <![CDATA[
-struct parport_operations {
-        [...]
-
-        /* Block read/write */
-        size_t (*epp_write_data) (struct parport *port,
-                                  const void *buf,
-                                  size_t len, int flags);
-        size_t (*epp_read_data) (struct parport *port,
-                                 void *buf, size_t len,
-                                 int flags);
-        size_t (*epp_write_addr) (struct parport *port,
-                                  const void *buf,
-                                  size_t len, int flags);
-        size_t (*epp_read_addr) (struct parport *port,
-                                 void *buf, size_t len,
-                                 int flags);
-
-        size_t (*ecp_write_data) (struct parport *port,
-                                  const void *buf,
-                                  size_t len, int flags);
-        size_t (*ecp_read_data) (struct parport *port,
-                                 void *buf, size_t len,
-                                 int flags);
-        size_t (*ecp_write_addr) (struct parport *port,
-                                  const void *buf,
-                                  size_t len, int flags);
-
-        size_t (*compat_write_data) (struct parport *port,
-                                     const void *buf,
-                                     size_t len, int flags);
-        size_t (*nibble_read_data) (struct parport *port,
-                                    void *buf, size_t len,
-                                    int flags);
-        size_t (*byte_read_data) (struct parport *port,
-                                  void *buf, size_t len,
-                                  int flags);
-};
-   ]]></programlisting>
-
-  <para>
-   The transfer code in <literal>parport</literal> will tolerate a
-   data transfer stall only for so long, and this timeout can be
-   specified with <function>parport_set_timeout</function>, which
-   returns the previous timeout:
-  </para>
-
-  <funcsynopsis>
-   <funcsynopsisinfo>
-#include &lt;parport.h&gt;
-   </funcsynopsisinfo>
-   <funcprototype>
-    <funcdef>long <function>parport_set_timeout</function></funcdef>
-    <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-    <paramdef>long <parameter>inactivity</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   This timeout is specific to the device, and is restored on
-   <function>parport_claim</function>.
-  </para>
-
-  <para>
-   The next function to look at is the one that allows processes to
-   read from <filename>/dev/lp0</filename>:
-   <function>lp_read</function>.  It's short, like
-   <function>lp_write</function>.
-  </para>
-
-  <para>
-   The semantics of reading from a line printer device are as follows:
-  </para>
-
-  <itemizedlist>
-   <listitem>
-    <para>
-     Switch to reverse nibble mode.
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     Try to read data from the peripheral using reverse nibble mode,
-     until either the user-provided buffer is full or the peripheral
-     indicates that there is no more data.
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     If there was data, stop, and return it.
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     Otherwise, we tried to read data and there was none.  If the user
-     opened the device node with the <constant>O_NONBLOCK</constant>
-     flag, return.  Otherwise wait until an interrupt occurs on the
-     port (or a timeout elapses).
-    </para>
-   </listitem>
-  </itemizedlist>
-
- </chapter>
-
- <chapter id="ppdev">
-  <title>User-level device drivers</title>
-
-  <!-- ppdev -->
-  <sect1>
-   <title>Introduction to ppdev</title>
-
-   <para>
-    The printer is accessible through <filename>/dev/lp0</filename>;
-    in the same way, the parallel port itself is accessible through
-    <filename>/dev/parport0</filename>.  The difference is in the
-    level of control that you have over the wires in the parallel port
-    cable.
-   </para>
-
-   <para>
-    With the printer driver, a user-space program (such as the printer
-    spooler) can send bytes in <quote>printer protocol</quote>.
-    Briefly, this means that for each byte, the eight data lines are
-    set up, then a <quote>strobe</quote> line tells the printer to
-    look at the data lines, and the printer sets an
-    <quote>acknowledgement</quote> line to say that it got the byte.
-    The printer driver also allows the user-space program to read
-    bytes in <quote>nibble mode</quote>, which is a way of
-    transferring data from the peripheral to the computer half a byte
-    at a time (and so it's quite slow).
-   </para>
-
-   <para>
-    In contrast, the <literal>ppdev</literal> driver (accessed via
-    <filename>/dev/parport0</filename>) allows you to:
-   </para>
-
-   <itemizedlist spacing="compact">
-
-    <listitem>
-     <para>
-      examine status lines,
-     </para>
-    </listitem>
-
-    <listitem>
-     <para>
-      set control lines,
-     </para>
-    </listitem>
-
-    <listitem>
-     <para>
-      set/examine data lines (and control the direction of the data
-      lines),
-     </para>
-    </listitem>
-
-    <listitem>
-     <para>
-      wait for an interrupt (triggered by one of the status lines),
-     </para>
-    </listitem>
-
-    <listitem>
-     <para>
-      find out how many new interrupts have occurred,
-     </para>
-    </listitem>
-
-    <listitem>
-     <para>
-      set up a response to an interrupt,
-     </para>
-    </listitem>
-
-    <listitem>
-     <para>
-      use IEEE 1284 negotiation (for telling peripheral which transfer
-      mode, to use)
-     </para>
-    </listitem>
-
-    <listitem>
-     <para>
-      transfer data using a specified IEEE 1284 mode.
-     </para>
-    </listitem>
-
-   </itemizedlist>
-
-  </sect1>
-
-  <sect1>
-   <title>User-level or kernel-level driver?</title>
-
-   <para>
-    The decision of whether to choose to write a kernel-level device
-    driver or a user-level device driver depends on several factors.
-    One of the main ones from a practical point of view is speed:
-    kernel-level device drivers get to run faster because they are not
-    preemptable, unlike user-level applications.
-   </para>
-
-   <para>
-    Another factor is ease of development.  It is in general easier to
-    write a user-level driver because (a) one wrong move does not
-    result in a crashed machine, (b) you have access to user libraries
-    (such as the C library), and (c) debugging is easier.
-   </para>
-
-  </sect1>
-
-  <sect1>
-   <title>Programming interface</title>
-
-   <para>
-    The <literal>ppdev</literal> interface is largely the same as that
-    of other character special devices, in that it supports
-    <function>open</function>, <function>close</function>,
-    <function>read</function>, <function>write</function>, and
-    <function>ioctl</function>.  The constants for the
-    <function>ioctl</function> commands are in
-    <filename>include/linux/ppdev.h</filename>.
-   </para>
-
-   <sect2>
-    <title>
-     Starting and stopping: <function>open</function> and
-     <function>close</function>
-    </title>
-
-    <para>
-     The device node <filename>/dev/parport0</filename> represents any
-     device that is connected to <filename>parport0</filename>, the
-     first parallel port in the system.  Each time the device node is
-     opened, it represents (to the process doing the opening) a
-     different device.  It can be opened more than once, but only one
-     instance can actually be in control of the parallel port at any
-     time.  A process that has opened
-     <filename>/dev/parport0</filename> shares the parallel port in
-     the same way as any other device driver.  A user-land driver may
-     be sharing the parallel port with in-kernel device drivers as
-     well as other user-land drivers.
-    </para>
-   </sect2>
-
-   <sect2>
-    <title>Control: <function>ioctl</function></title>
-
-    <para>
-     Most of the control is done, naturally enough, via the
-     <function>ioctl</function> call.  Using
-     <function>ioctl</function>, the user-land driver can control both
-     the <literal>ppdev</literal> driver in the kernel and the
-     physical parallel port itself.  The <function>ioctl</function>
-     call takes as parameters a file descriptor (the one returned from
-     opening the device node), a command, and optionally (a pointer
-     to) some data.
-    </para>
-
-    <variablelist>
-     <varlistentry><term><constant>PPCLAIM</constant></term>
-      <listitem>
-
-       <para>
-       Claims access to the port.  As a user-land device driver
-       writer, you will need to do this before you are able to
-       actually change the state of the parallel port in any way.
-       Note that some operations only affect the
-       <literal>ppdev</literal> driver and not the port, such as
-       <constant>PPSETMODE</constant>; they can be performed while
-       access to the port is not claimed.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPEXCL</constant></term>
-      <listitem>
-
-       <para>
-       Instructs the kernel driver to forbid any sharing of the port
-       with other drivers, i.e. it requests exclusivity.  The
-       <constant>PPEXCL</constant> command is only valid when the
-       port is not already claimed for use, and it may mean that the
-       next <constant>PPCLAIM</constant> <function>ioctl</function>
-       will fail: some other driver may already have registered
-       itself on that port.
-       </para>
-
-       <para>
-       Most device drivers don't need exclusive access to the port.
-       It's only provided in case it is really needed, for example
-       for devices where access to the port is required for extensive
-       periods of time (many seconds).
-       </para>
-
-       <para>
-       Note that the <constant>PPEXCL</constant>
-       <function>ioctl</function> doesn't actually claim the port
-       there and then---action is deferred until the
-       <constant>PPCLAIM</constant> <function>ioctl</function> is
-       performed.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPRELEASE</constant></term>
-      <listitem>
-
-       <para>
-       Releases the port.  Releasing the port undoes the effect of
-       claiming the port.  It allows other device drivers to talk to
-       their devices (assuming that there are any).
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPYIELD</constant></term>
-      <listitem>
-
-       <para>
-       Yields the port to another driver.  This
-       <function>ioctl</function> is a kind of short-hand for
-       releasing the port and immediately reclaiming it.  It gives
-       other drivers a chance to talk to their devices, but
-       afterwards claims the port back.  An example of using this
-       would be in a user-land printer driver: once a few characters
-       have been written we could give the port to another device
-       driver for a while, but if we still have characters to send to
-       the printer we would want the port back as soon as possible.
-       </para>
-
-       <para>
-       It is important not to claim the parallel port for too long,
-       as other device drivers will have no time to service their
-       devices.  If your device does not allow for parallel port
-       sharing at all, it is better to claim the parallel port
-       exclusively (see <constant>PPEXCL</constant>).
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPNEGOT</constant></term>
-      <listitem>
-
-       <para>
-       Performs IEEE 1284 negotiation into a particular mode.
-       Briefly, negotiation is the method by which the host and the
-       peripheral decide on a protocol to use when transferring data.
-       </para>
-
-       <para>
-       An IEEE 1284 compliant device will start out in compatibility
-       mode, and then the host can negotiate to another mode (such as
-       ECP).
-       </para>
-
-       <para>
-       The <function>ioctl</function> parameter should be a pointer
-       to an <type>int</type>; values for this are in
-       <filename>incluce/linux/parport.h</filename> and include:
-       </para>
-
-       <itemizedlist spacing="compact">
-       <listitem><para>
-         <constant>IEEE1284_MODE_COMPAT</constant></para></listitem>
-       <listitem><para>
-         <constant>IEEE1284_MODE_NIBBLE</constant></para></listitem>
-       <listitem><para>
-         <constant>IEEE1284_MODE_BYTE</constant></para></listitem>
-       <listitem><para>
-         <constant>IEEE1284_MODE_EPP</constant></para></listitem>
-       <listitem><para>
-         <constant>IEEE1284_MODE_ECP</constant></para></listitem>
-       </itemizedlist>
-
-       <para>
-       The <constant>PPNEGOT</constant> <function>ioctl</function>
-       actually does two things: it performs the on-the-wire
-       negotiation, and it sets the behaviour of subsequent
-       <function>read</function>/<function>write</function> calls so
-       that they use that mode (but see
-       <constant>PPSETMODE</constant>).
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPSETMODE</constant></term>
-      <listitem>
-
-       <para>
-       Sets which IEEE 1284 protocol to use for the
-       <function>read</function> and <function>write</function>
-       calls.
-       </para>
-
-       <para>
-       The <function>ioctl</function> parameter should be a pointer
-       to an <type>int</type>.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPGETMODE</constant></term>
-      <listitem>
-
-       <para>
-       Retrieves the current IEEE 1284 mode to use for
-       <function>read</function> and <function>write</function>.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPGETTIME</constant></term>
-      <listitem>
-
-       <para>
-       Retrieves the time-out value.  The <function>read</function>
-       and <function>write</function> calls will time out if the
-       peripheral doesn't respond quickly enough.  The
-       <constant>PPGETTIME</constant> <function>ioctl</function>
-       retrieves the length of time that the peripheral is allowed to
-       have before giving up.
-       </para>
-
-       <para>
-       The <function>ioctl</function> parameter should be a pointer
-       to a <structname>struct timeval</structname>.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPSETTIME</constant></term>
-      <listitem>
-
-       <para>
-       Sets the time-out.  The <function>ioctl</function> parameter
-       should be a pointer to a <structname>struct
-       timeval</structname>.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPGETMODES</constant></term>
-      <listitem>
-
-       <para>
-       Retrieves the capabilities of the hardware (i.e. the
-       <structfield>modes</structfield> field of the
-       <structname>parport</structname> structure).
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPSETFLAGS</constant></term>
-      <listitem>
-
-       <para>
-       Sets flags on the <literal>ppdev</literal> device which can
-       affect future I/O operations.  Available flags are:
-       </para>
-
-       <itemizedlist spacing="compact">
-       <listitem><para>
-         <constant>PP_FASTWRITE</constant></para></listitem>
-       <listitem><para>
-         <constant>PP_FASTREAD</constant></para></listitem>
-       <listitem><para>
-         <constant>PP_W91284PIC</constant></para></listitem>
-       </itemizedlist>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPWCONTROL</constant></term>
-      <listitem>
-
-       <para>
-       Sets the control lines.  The <function>ioctl</function>
-       parameter is a pointer to an <type>unsigned char</type>, the
-       bitwise OR of the control line values in
-       <filename>include/linux/parport.h</filename>.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPRCONTROL</constant></term>
-      <listitem>
-
-       <para>
-       Returns the last value written to the control register, in the
-       form of an <type>unsigned char</type>: each bit corresponds to
-       a control line (although some are unused).  The
-       <function>ioctl</function> parameter should be a pointer to an
-       <type>unsigned char</type>.
-       </para>
-
-       <para>
-       This doesn't actually touch the hardware; the last value
-       written is remembered in software.  This is because some
-       parallel port hardware does not offer read access to the
-       control register.
-       </para>
-
-       <para>
-       The control lines bits are defined in
-       <filename>include/linux/parport.h</filename>:
-       </para>
-
-       <itemizedlist spacing="compact">
-       <listitem><para>
-         <constant>PARPORT_CONTROL_STROBE</constant></para></listitem>
-         <listitem><para>
-         <constant>PARPORT_CONTROL_AUTOFD</constant></para></listitem>
-         <listitem><para>
-         <constant>PARPORT_CONTROL_SELECT</constant></para></listitem>
-         <listitem><para>
-         <constant>PARPORT_CONTROL_INIT</constant></para></listitem>
-       </itemizedlist>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPFCONTROL</constant></term>
-      <listitem>
-
-       <para>
-       Frobs the control lines.  Since a common operation is to
-       change one of the control signals while leaving the others
-       alone, it would be quite inefficient for the user-land driver
-       to have to use <constant>PPRCONTROL</constant>, make the
-       change, and then use <constant>PPWCONTROL</constant>.  Of
-       course, each driver could remember what state the control
-       lines are supposed to be in (they are never changed by
-       anything else), but in order to provide
-       <constant>PPRCONTROL</constant>, <literal>ppdev</literal>
-       must remember the state of the control lines anyway.
-       </para>
-
-       <para>
-       The <constant>PPFCONTROL</constant> <function>ioctl</function>
-       is for <quote>frobbing</quote> control lines, and is like
-       <constant>PPWCONTROL</constant> but acts on a restricted set
-       of control lines.  The <function>ioctl</function> parameter is
-       a pointer to a <structname>struct
-       ppdev_frob_struct</structname>:
-       </para>
-
-       <programlisting>
-       <![CDATA[
-struct ppdev_frob_struct {
-        unsigned char mask;
-        unsigned char val;
-};
-       ]]>
-       </programlisting>
-
-       <para>
-       The <structfield>mask</structfield> and
-       <structfield>val</structfield> fields are bitwise ORs of
-       control line names (such as in
-       <constant>PPWCONTROL</constant>).  The operation performed by
-       <constant>PPFCONTROL</constant> is:
-       </para>
-
-       <programlisting>
-       <![CDATA[
-       new_ctr = (old_ctr & ~mask) | val;]]>
-       </programlisting>
-
-       <para>
-       In other words, the signals named in
-       <structfield>mask</structfield> are set to the values in
-       <structfield>val</structfield>.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPRSTATUS</constant></term>
-      <listitem>
-
-       <para>
-       Returns an <type>unsigned char</type> containing bits set for
-       each status line that is set (for instance,
-       <constant>PARPORT_STATUS_BUSY</constant>).  The
-       <function>ioctl</function> parameter should be a pointer to an
-       <type>unsigned char</type>.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPDATADIR</constant></term>
-      <listitem>
-
-       <para>
-       Controls the data line drivers.  Normally the computer's
-       parallel port will drive the data lines, but for byte-wide
-       transfers from the peripheral to the host it is useful to turn
-       off those drivers and let the peripheral drive the
-       signals. (If the drivers on the computer's parallel port are
-       left on when this happens, the port might be damaged.)
-       </para>
-
-       <para>
-       This is only needed in conjunction with
-       <constant>PPWDATA</constant> or
-       <constant>PPRDATA</constant>.
-       </para>
-
-       <para>
-       The <function>ioctl</function> parameter is a pointer to an
-       <type>int</type>.  If the <type>int</type> is zero, the
-       drivers are turned on (forward direction); if non-zero, the
-       drivers are turned off (reverse direction).
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPWDATA</constant></term>
-      <listitem>
-
-       <para>
-       Sets the data lines (if in forward mode).  The
-       <function>ioctl</function> parameter is a pointer to an
-       <type>unsigned char</type>.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPRDATA</constant></term>
-      <listitem>
-
-       <para>
-       Reads the data lines (if in reverse mode).  The
-       <function>ioctl</function> parameter is a pointer to an
-       <type>unsigned char</type>.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPCLRIRQ</constant></term>
-      <listitem>
-
-       <para>
-       Clears the interrupt count.  The <literal>ppdev</literal>
-       driver keeps a count of interrupts as they are triggered.
-       <constant>PPCLRIRQ</constant> stores this count in an
-       <type>int</type>, a pointer to which is passed in as the
-       <function>ioctl</function> parameter.
-       </para>
-
-       <para>
-       In addition, the interrupt count is reset to zero.
-       </para>
-
-      </listitem></varlistentry>
-
-     <varlistentry><term><constant>PPWCTLONIRQ</constant></term>
-      <listitem>
-
-       <para>
-       Set a trigger response.  Afterwards when an interrupt is
-       triggered, the interrupt handler will set the control lines as
-       requested.  The <function>ioctl</function> parameter is a
-       pointer to an <type>unsigned char</type>, which is interpreted
-       in the same way as for <constant>PPWCONTROL</constant>.
-       </para>
-
-       <para>
-       The reason for this <function>ioctl</function> is simply
-       speed.  Without this <function>ioctl</function>, responding to
-       an interrupt would start in the interrupt handler, switch
-       context to the user-land driver via <function>poll</function>
-       or <function>select</function>, and then switch context back
-       to the kernel in order to handle
-       <constant>PPWCONTROL</constant>.  Doing the whole lot in the
-       interrupt handler is a lot faster.
-       </para>
-
-      </listitem></varlistentry>
-
-     <!-- PPSETPHASE? -->
-
-    </variablelist>
-
-   </sect2>
-
-   <sect2>
-    <title>Transferring data: <function>read</function> and
-     <function>write</function></title>
-
-    <para>
-     Transferring data using <function>read</function> and
-     <function>write</function> is straightforward.  The data is
-     transferring using the current IEEE 1284 mode (see the
-     <constant>PPSETMODE</constant> <function>ioctl</function>).  For
-     modes which can only transfer data in one direction, only the
-     appropriate function will work, of course.
-    </para>
-   </sect2>
-
-   <sect2>
-    <title>Waiting for events: <function>poll</function> and
-     <function>select</function></title>
-
-    <para>
-     The <literal>ppdev</literal> driver provides user-land device
-     drivers with the ability to wait for interrupts, and this is done
-     using <function>poll</function> (and <function>select</function>,
-     which is implemented in terms of <function>poll</function>).
-    </para>
-
-    <para>
-     When a user-land device driver wants to wait for an interrupt, it
-     sleeps with <function>poll</function>.  When the interrupt
-     arrives, <literal>ppdev</literal> wakes it up (with a
-     <quote>read</quote> event, although strictly speaking there is
-     nothing to actually <function>read</function>).
-    </para>
-
-   </sect2>
-
-  </sect1>
-
-  <sect1>
-   <title>Examples</title>
-
-   <para>
-    Presented here are two demonstrations of how to write a simple
-    printer driver for <literal>ppdev</literal>.  Firstly we will
-    use the <function>write</function> function, and after that we
-    will drive the control and data lines directly.
-   </para>
-
-   <para>
-    The first thing to do is to actually open the device.
-   </para>
-
-   <programlisting><![CDATA[
-int drive_printer (const char *name)
-{
-    int fd;
-    int mode; /* We'll need this later. */
-
-    fd = open (name, O_RDWR);
-    if (fd == -1) {
-        perror ("open");
-        return 1;
-    }
-    ]]></programlisting>
-
-   <para>
-    Here <varname>name</varname> should be something along the lines
-    of <filename>"/dev/parport0"</filename>. (If you don't have any
-    <filename>/dev/parport</filename> files, you can make them with
-    <command>mknod</command>; they are character special device nodes
-    with major 99.)
-   </para>
-
-   <para>
-    In order to do anything with the port we need to claim access to
-    it.
-   </para>
-
-   <programlisting><![CDATA[
-    if (ioctl (fd, PPCLAIM)) {
-        perror ("PPCLAIM");
-        close (fd);
-        return 1;
-    }
-    ]]></programlisting>
-
-   <para>
-    Our printer driver will copy its input (from
-    <varname>stdin</varname>) to the printer, and it can do that it
-    one of two ways.  The first way is to hand it all off to the
-    kernel driver, with the knowledge that the protocol that the
-    printer speaks is IEEE 1284's <quote>compatibility</quote>
-    mode.
-   </para>
-
-   <programlisting><![CDATA[
-    /* Switch to compatibility mode.  (In fact we don't need
-     * to do this, since we start off in compatibility mode
-     * anyway, but this demonstrates PPNEGOT.)
-    mode = IEEE1284_MODE_COMPAT;
-    if (ioctl (fd, PPNEGOT, &mode)) {
-        perror ("PPNEGOT");
-        close (fd);
-        return 1;
-    }
-
-    for (;;) {
-        char buffer[1000];
-        char *ptr = buffer;
-        size_t got;
-
-        got = read (0 /* stdin */, buffer, 1000);
-        if (got < 0) {
-            perror ("read");
-            close (fd);
-            return 1;
-        }
-
-        if (got == 0)
-            /* End of input */
-            break;
-
-        while (got > 0) {
-            int written = write_printer (fd, ptr, got);
-
-            if (written < 0) {
-                perror ("write");
-                close (fd);
-                return 1;
-            }
-
-            ptr += written;
-            got -= written;
-        }
-    }
-    ]]></programlisting>
-
-   <para>
-    The <function>write_printer</function> function is not pictured
-    above.  This is because the main loop that is shown can be used
-    for both methods of driving the printer.  Here is one
-    implementation of <function>write_printer</function>:
-   </para>
-
-   <programlisting><![CDATA[
-ssize_t write_printer (int fd, const void *ptr, size_t count)
-{
-    return write (fd, ptr, count);
-}
-    ]]></programlisting>
-
-   <para>
-    We hand the data to the kernel-level driver (using
-    <function>write</function>) and it handles the printer
-    protocol.
-   </para>
-
-   <para>
-    Now let's do it the hard way!  In this particular example there is
-    no practical reason to do anything other than just call
-    <function>write</function>, because we know that the printer talks
-    an IEEE 1284 protocol.  On the other hand, this particular example
-    does not even need a user-land driver since there is already a
-    kernel-level one; for the purpose of this discussion, try to
-    imagine that the printer speaks a protocol that is not already
-    implemented under Linux.
-   </para>
-
-   <para>
-    So, here is the alternative implementation of
-    <function>write_printer</function> (for brevity, error checking
-    has been omitted):
-   </para>
-
-   <programlisting><![CDATA[
-ssize_t write_printer (int fd, const void *ptr, size_t count)
-{
-    ssize_t wrote = 0;
-
-    while (wrote < count) {
-        unsigned char status, control, data;
-        unsigned char mask = (PARPORT_STATUS_ERROR
-                              | PARPORT_STATUS_BUSY);
-        unsigned char val = (PARPORT_STATUS_ERROR
-                              | PARPORT_STATUS_BUSY);
-        struct ppdev_frob_struct frob;
-        struct timespec ts;
-
-        /* Wait for printer to be ready */
-        for (;;) {
-            ioctl (fd, PPRSTATUS, &status);
-
-            if ((status & mask) == val)
-                break;
-
-            ioctl (fd, PPRELEASE);
-            sleep (1);
-            ioctl (fd, PPCLAIM);
-        }
-
-        /* Set the data lines */
-        data = * ((char *) ptr)++;
-        ioctl (fd, PPWDATA, &data);
-
-        /* Delay for a bit */
-        ts.tv_sec = 0;
-        ts.tv_nsec = 1000;
-        nanosleep (&ts, NULL);
-
-        /* Pulse strobe */
-        frob.mask = PARPORT_CONTROL_STROBE;
-        frob.val = PARPORT_CONTROL_STROBE;
-        ioctl (fd, PPFCONTROL, &frob);
-        nanosleep (&ts, NULL);
-
-        /* End the pulse */
-        frob.val = 0;
-        ioctl (fd, PPFCONTROL, &frob);
-        nanosleep (&ts, NULL);
-
-        wrote++;
-    }
-
-    return wrote;
-}
-    ]]></programlisting>
-
-   <para>
-    To show a bit more of the <literal>ppdev</literal> interface,
-    here is a small piece of code that is intended to mimic the
-    printer's side of printer protocol.
-   </para>
-
-   <programlisting><![CDATA[
-  for (;;)
-    {
-      int irqc;
-      int busy = nAck | nFault;
-      int acking = nFault;
-      int ready = Busy | nAck | nFault;
-      char ch;
-
-      /* Set up the control lines when an interrupt happens. */
-      ioctl (fd, PPWCTLONIRQ, &busy);
-
-      /* Now we're ready. */
-      ioctl (fd, PPWCONTROL, &ready);
-
-      /* Wait for an interrupt. */
-      {
-        fd_set rfds;
-        FD_ZERO (&rfds);
-        FD_SET (fd, &rfds);
-        if (!select (fd + 1, &rfds, NULL, NULL, NULL))
-          /* Caught a signal? */
-          continue;
-      }
-
-      /* We are now marked as busy. */
-
-      /* Fetch the data. */
-      ioctl (fd, PPRDATA, &ch);
-
-      /* Clear the interrupt. */
-      ioctl (fd, PPCLRIRQ, &irqc);
-      if (irqc > 1)
-        fprintf (stderr, "Arghh! Missed %d interrupt%s!\n",
-         irqc - 1, irqc == 2 ? "s" : "");
-
-      /* Ack it. */
-      ioctl (fd, PPWCONTROL, &acking);
-      usleep (2);
-      ioctl (fd, PPWCONTROL, &busy);
-
-      putchar (ch);
-    }
-    ]]></programlisting>
-
-   <para>
-    And here is an example (with no error checking at all) to show how
-    to read data from the port, using ECP mode, with optional
-    negotiation to ECP mode first.
-   </para>
-
-   <programlisting><![CDATA[
-    {
-      int fd, mode;
-      fd = open ("/dev/parport0", O_RDONLY | O_NOCTTY);
-      ioctl (fd, PPCLAIM);
-      mode = IEEE1284_MODE_ECP;
-      if (negotiate_first) {
-        ioctl (fd, PPNEGOT, &mode);
-        /* no need for PPSETMODE */
-      } else {
-        ioctl (fd, PPSETMODE, &mode);
-      }
-
-      /* Now do whatever we want with fd */
-      close (0);
-      dup2 (fd, 0);
-      if (!fork()) {
-        /* child */
-        execlp ("cat", "cat", NULL);
-        exit (1);
-      } else {
-        /* parent */
-        wait (NULL);
-      }
-
-      /* Okay, finished */
-      ioctl (fd, PPRELEASE);
-      close (fd);
-    }
-    ]]></programlisting>
-
-  </sect1>
-
- </chapter>
-
- <appendix id="api">
-  <title>
-   Linux parallel port driver API reference
-  </title>
-
-!Fdrivers/parport/daisy.c parport_device_num
-!Fdrivers/parport/daisy.c parport_device_coords
-!Fdrivers/parport/daisy.c parport_find_device
-!Fdrivers/parport/daisy.c parport_find_class
-!Fdrivers/parport/share.c parport_register_driver
-!Fdrivers/parport/share.c parport_unregister_driver
-!Fdrivers/parport/share.c parport_get_port
-!Fdrivers/parport/share.c parport_put_port
-!Fdrivers/parport/share.c parport_find_number parport_find_base
-!Fdrivers/parport/share.c parport_register_device
-!Fdrivers/parport/share.c parport_unregister_device
-!Fdrivers/parport/daisy.c parport_open
-!Fdrivers/parport/daisy.c parport_close
-!Fdrivers/parport/share.c parport_claim
-!Fdrivers/parport/share.c parport_claim_or_block
-!Fdrivers/parport/share.c parport_release
-!Finclude/linux/parport.h parport_yield
-!Finclude/linux/parport.h parport_yield_blocking
-!Fdrivers/parport/ieee1284.c parport_negotiate
-!Fdrivers/parport/ieee1284.c parport_write
-!Fdrivers/parport/ieee1284.c parport_read
-!Fdrivers/parport/ieee1284.c parport_set_timeout
-
- </appendix>
-
- <appendix>
-  <title>
-   The Linux 2.2 Parallel Port Subsystem
-  </title>
-
-  <para>
-   Although the interface described in this document is largely new
-   with the 2.4 kernel, the sharing mechanism is available in the 2.2
-   kernel as well.  The functions available in 2.2 are:
-  </para>
-
-  <itemizedlist>
-   <listitem>
-    <para>
-     <function>parport_register_device</function>
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     <function>parport_unregister_device</function>
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     <function>parport_claim</function>
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     <function>parport_claim_or_block</function>
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     <function>parport_release</function>
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     <function>parport_yield</function>
-    </para>
-   </listitem>
-
-   <listitem>
-    <para>
-     <function>parport_yield_blocking</function>
-    </para>
-   </listitem>
-  </itemizedlist>
-
-  <para>
-   In addition, negotiation to reverse nibble mode is supported:
-  </para>
-
-  <funcsynopsis>
-   <funcprototype>
-     <funcdef>int <function>parport_ieee1284_nibble_mode_ok</function></funcdef>
-    <paramdef>struct parport *<parameter>port</parameter></paramdef>
-    <paramdef>unsigned char <parameter>mode</parameter></paramdef>
-   </funcprototype>
-  </funcsynopsis>
-
-  <para>
-   The only valid values for <parameter>mode</parameter> are 0 (for
-   reverse nibble mode) and 4 (for Device ID in reverse nibble mode).
-  </para>
-
-  <para>
-   This function is obsoleted by
-   <function>parport_negotiate</function> in Linux 2.4, and has been
-   removed.
-  </para>
- </appendix>
-
- <appendix id="fdl">
-  <title>
-   GNU Free Documentation License
-  </title>
-
-  <literallayout class="monospaced">
-                GNU Free Documentation License
-                   Version 1.1, March 2000
-
- Copyright (C) 2000  Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
-0. PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or other
-written document "free" in the sense of freedom: to assure everyone
-the effective freedom to copy and redistribute it, with or without
-modifying it, either commercially or noncommercially.  Secondarily,
-this License preserves for the author and publisher a way to get
-credit for their work, while not being considered responsible for
-modifications made by others.
-
-This License is a kind of "copyleft", which means that derivative
-works of the document must themselves be free in the same sense.  It
-complements the GNU General Public License, which is a copyleft
-license designed for free software.
-
-We have designed this License in order to use it for manuals for free
-software, because free software needs free documentation: a free
-program should come with manuals providing the same freedoms that the
-software does.  But this License is not limited to software manuals;
-it can be used for any textual work, regardless of subject matter or
-whether it is published as a printed book.  We recommend this License
-principally for works whose purpose is instruction or reference.
-
-
-1. APPLICABILITY AND DEFINITIONS
-
-This License applies to any manual or other work that contains a
-notice placed by the copyright holder saying it can be distributed
-under the terms of this License.  The "Document", below, refers to any
-such manual or work.  Any member of the public is a licensee, and is
-addressed as "you".
-
-A "Modified Version" of the Document means any work containing the
-Document or a portion of it, either copied verbatim, or with
-modifications and/or translated into another language.
-
-A "Secondary Section" is a named appendix or a front-matter section of
-the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall subject
-(or to related matters) and contains nothing that could fall directly
-within that overall subject.  (For example, if the Document is in part a
-textbook of mathematics, a Secondary Section may not explain any
-mathematics.)  The relationship could be a matter of historical
-connection with the subject or with related matters, or of legal,
-commercial, philosophical, ethical or political position regarding
-them.
-
-The "Invariant Sections" are certain Secondary Sections whose titles
-are designated, as being those of Invariant Sections, in the notice
-that says that the Document is released under this License.
-
-The "Cover Texts" are certain short passages of text that are listed,
-as Front-Cover Texts or Back-Cover Texts, in the notice that says that
-the Document is released under this License.
-
-A "Transparent" copy of the Document means a machine-readable copy,
-represented in a format whose specification is available to the
-general public, whose contents can be viewed and edited directly and
-straightforwardly with generic text editors or (for images composed of
-pixels) generic paint programs or (for drawings) some widely available
-drawing editor, and that is suitable for input to text formatters or
-for automatic translation to a variety of formats suitable for input
-to text formatters.  A copy made in an otherwise Transparent file
-format whose markup has been designed to thwart or discourage
-subsequent modification by readers is not Transparent.  A copy that is
-not "Transparent" is called "Opaque".
-
-Examples of suitable formats for Transparent copies include plain
-ASCII without markup, Texinfo input format, LaTeX input format, SGML
-or XML using a publicly available DTD, and standard-conforming simple
-HTML designed for human modification.  Opaque formats include
-PostScript, PDF, proprietary formats that can be read and edited only
-by proprietary word processors, SGML or XML for which the DTD and/or
-processing tools are not generally available, and the
-machine-generated HTML produced by some word processors for output
-purposes only.
-
-The "Title Page" means, for a printed book, the title page itself,
-plus such following pages as are needed to hold, legibly, the material
-this License requires to appear in the title page.  For works in
-formats which do not have any title page as such, "Title Page" means
-the text near the most prominent appearance of the work's title,
-preceding the beginning of the body of the text.
-
-
-2. VERBATIM COPYING
-
-You may copy and distribute the Document in any medium, either
-commercially or noncommercially, provided that this License, the
-copyright notices, and the license notice saying this License applies
-to the Document are reproduced in all copies, and that you add no other
-conditions whatsoever to those of this License.  You may not use
-technical measures to obstruct or control the reading or further
-copying of the copies you make or distribute.  However, you may accept
-compensation in exchange for copies.  If you distribute a large enough
-number of copies you must also follow the conditions in section 3.
-
-You may also lend copies, under the same conditions stated above, and
-you may publicly display copies.
-
-
-3. COPYING IN QUANTITY
-
-If you publish printed copies of the Document numbering more than 100,
-and the Document's license notice requires Cover Texts, you must enclose
-the copies in covers that carry, clearly and legibly, all these Cover
-Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
-the back cover.  Both covers must also clearly and legibly identify
-you as the publisher of these copies.  The front cover must present
-the full title with all words of the title equally prominent and
-visible.  You may add other material on the covers in addition.
-Copying with changes limited to the covers, as long as they preserve
-the title of the Document and satisfy these conditions, can be treated
-as verbatim copying in other respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute Opaque copies of the Document numbering
-more than 100, you must either include a machine-readable Transparent
-copy along with each Opaque copy, or state in or with each Opaque copy
-a publicly-accessible computer-network location containing a complete
-Transparent copy of the Document, free of added material, which the
-general network-using public has access to download anonymously at no
-charge using public-standard network protocols.  If you use the latter
-option, you must take reasonably prudent steps, when you begin
-distribution of Opaque copies in quantity, to ensure that this
-Transparent copy will remain thus accessible at the stated location
-until at least one year after the last time you distribute an Opaque
-copy (directly or through your agents or retailers) of that edition to
-the public.
-
-It is requested, but not required, that you contact the authors of the
-Document well before redistributing any large number of copies, to give
-them a chance to provide you with an updated version of the Document.
-
-
-4. MODIFICATIONS
-
-You may copy and distribute a Modified Version of the Document under
-the conditions of sections 2 and 3 above, provided that you release
-the Modified Version under precisely this License, with the Modified
-Version filling the role of the Document, thus licensing distribution
-and modification of the Modified Version to whoever possesses a copy
-of it.  In addition, you must do these things in the Modified Version:
-
-A. Use in the Title Page (and on the covers, if any) a title distinct
-   from that of the Document, and from those of previous versions
-   (which should, if there were any, be listed in the History section
-   of the Document).  You may use the same title as a previous version
-   if the original publisher of that version gives permission.
-B. List on the Title Page, as authors, one or more persons or entities
-   responsible for authorship of the modifications in the Modified
-   Version, together with at least five of the principal authors of the
-   Document (all of its principal authors, if it has less than five).
-C. State on the Title page the name of the publisher of the
-   Modified Version, as the publisher.
-D. Preserve all the copyright notices of the Document.
-E. Add an appropriate copyright notice for your modifications
-   adjacent to the other copyright notices.
-F. Include, immediately after the copyright notices, a license notice
-   giving the public permission to use the Modified Version under the
-   terms of this License, in the form shown in the Addendum below.
-G. Preserve in that license notice the full lists of Invariant Sections
-   and required Cover Texts given in the Document's license notice.
-H. Include an unaltered copy of this License.
-I. Preserve the section entitled "History", and its title, and add to
-   it an item stating at least the title, year, new authors, and
-   publisher of the Modified Version as given on the Title Page.  If
-   there is no section entitled "History" in the Document, create one
-   stating the title, year, authors, and publisher of the Document as
-   given on its Title Page, then add an item describing the Modified
-   Version as stated in the previous sentence.
-J. Preserve the network location, if any, given in the Document for
-   public access to a Transparent copy of the Document, and likewise
-   the network locations given in the Document for previous versions
-   it was based on.  These may be placed in the "History" section.
-   You may omit a network location for a work that was published at
-   least four years before the Document itself, or if the original
-   publisher of the version it refers to gives permission.
-K. In any section entitled "Acknowledgements" or "Dedications",
-   preserve the section's title, and preserve in the section all the
-   substance and tone of each of the contributor acknowledgements
-   and/or dedications given therein.
-L. Preserve all the Invariant Sections of the Document,
-   unaltered in their text and in their titles.  Section numbers
-   or the equivalent are not considered part of the section titles.
-M. Delete any section entitled "Endorsements".  Such a section
-   may not be included in the Modified Version.
-N. Do not retitle any existing section as "Endorsements"
-   or to conflict in title with any Invariant Section.
-
-If the Modified Version includes new front-matter sections or
-appendices that qualify as Secondary Sections and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant.  To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
-These titles must be distinct from any other section titles.
-
-You may add a section entitled "Endorsements", provided it contains
-nothing but endorsements of your Modified Version by various
-parties--for example, statements of peer review or that the text has
-been approved by an organization as the authoritative definition of a
-standard.
-
-You may add a passage of up to five words as a Front-Cover Text, and a
-passage of up to 25 words as a Back-Cover Text, to the end of the list
-of Cover Texts in the Modified Version.  Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or
-through arrangements made by) any one entity.  If the Document already
-includes a cover text for the same cover, previously added by you or
-by arrangement made by the same entity you are acting on behalf of,
-you may not add another; but you may replace the old one, on explicit
-permission from the previous publisher that added the old one.
-
-The author(s) and publisher(s) of the Document do not by this License
-give permission to use their names for publicity for or to assert or
-imply endorsement of any Modified Version.
-
-
-5. COMBINING DOCUMENTS
-
-You may combine the Document with other documents released under this
-License, under the terms defined in section 4 above for modified
-versions, provided that you include in the combination all of the
-Invariant Sections of all of the original documents, unmodified, and
-list them all as Invariant Sections of your combined work in its
-license notice.
-
-The combined work need only contain one copy of this License, and
-multiple identical Invariant Sections may be replaced with a single
-copy.  If there are multiple Invariant Sections with the same name but
-different contents, make the title of each such section unique by
-adding at the end of it, in parentheses, the name of the original
-author or publisher of that section if known, or else a unique number.
-Make the same adjustment to the section titles in the list of
-Invariant Sections in the license notice of the combined work.
-
-In the combination, you must combine any sections entitled "History"
-in the various original documents, forming one section entitled
-"History"; likewise combine any sections entitled "Acknowledgements",
-and any sections entitled "Dedications".  You must delete all sections
-entitled "Endorsements."
-
-
-6. COLLECTIONS OF DOCUMENTS
-
-You may make a collection consisting of the Document and other documents
-released under this License, and replace the individual copies of this
-License in the various documents with a single copy that is included in
-the collection, provided that you follow the rules of this License for
-verbatim copying of each of the documents in all other respects.
-
-You may extract a single document from such a collection, and distribute
-it individually under this License, provided you insert a copy of this
-License into the extracted document, and follow this License in all
-other respects regarding verbatim copying of that document.
-
-
-
-7. AGGREGATION WITH INDEPENDENT WORKS
-
-A compilation of the Document or its derivatives with other separate
-and independent documents or works, in or on a volume of a storage or
-distribution medium, does not as a whole count as a Modified Version
-of the Document, provided no compilation copyright is claimed for the
-compilation.  Such a compilation is called an "aggregate", and this
-License does not apply to the other self-contained works thus compiled
-with the Document, on account of their being thus compiled, if they
-are not themselves derivative works of the Document.
-
-If the Cover Text requirement of section 3 is applicable to these
-copies of the Document, then if the Document is less than one quarter
-of the entire aggregate, the Document's Cover Texts may be placed on
-covers that surround only the Document within the aggregate.
-Otherwise they must appear on covers around the whole aggregate.
-
-
-8. TRANSLATION
-
-Translation is considered a kind of modification, so you may
-distribute translations of the Document under the terms of section 4.
-Replacing Invariant Sections with translations requires special
-permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections.  You may include a
-translation of this License provided that you also include the
-original English version of this License.  In case of a disagreement
-between the translation and the original English version of this
-License, the original English version will prevail.
-
-
-9. TERMINATION
-
-You may not copy, modify, sublicense, or distribute the Document except
-as expressly provided for under this License.  Any other attempt to
-copy, modify, sublicense or distribute the Document is void, and will
-automatically terminate your rights under this License.  However,
-parties who have received copies, or rights, from you under this
-License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-
-10. FUTURE REVISIONS OF THIS LICENSE
-
-The Free Software Foundation may publish new, revised versions
-of the GNU Free Documentation License from time to time.  Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns. See
-http:///www.gnu.org/copyleft/.
-
-Each version of the License is given a distinguishing version number.
-If the Document specifies that a particular numbered version of this
-License "or any later version" applies to it, you have the option of
-following the terms and conditions either of that specified version or
-of any later version that has been published (not as a draft) by the
-Free Software Foundation.  If the Document does not specify a version
-number of this License, you may choose any version ever published (not
-as a draft) by the Free Software Foundation.
-
-
-ADDENDUM: How to use this License for your documents
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and
-license notices just after the title page:
-
-      Copyright (c)  YEAR  YOUR NAME.
-      Permission is granted to copy, distribute and/or modify this document
-      under the terms of the GNU Free Documentation License, Version 1.1
-      or any later version published by the Free Software Foundation;
-      with the Invariant Sections being LIST THEIR TITLES, with the
-      Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
-      A copy of the license is included in the section entitled "GNU
-      Free Documentation License".
-
-If you have no Invariant Sections, write "with no Invariant Sections"
-instead of saying which ones are invariant.  If you have no
-Front-Cover Texts, write "no Front-Cover Texts" instead of
-"Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU General Public License,
-to permit their use in free software.
-  </literallayout>
- </appendix>
-
-</book>
-<!-- Local Variables: -->
-<!-- sgml-indent-step: 1 -->
-<!-- sgml-indent-data: 1 -->
-<!-- End: -->