diff -u --recursive --new-file linux-2.0.38/CREDITS linux-2.0.39/CREDITS
--- linux-2.0.38/CREDITS	Sun Jun 13 19:20:59 1999
+++ linux-2.0.39/CREDITS	Thu Sep  7 03:20:30 2000
@@ -10,7 +10,7 @@
 ----------
 
 N: Matti Aarnio
-E: mea@utu.fi
+E: mea@nic.funet.fi
 D: LILO for AHA1542, modularized several of drivers/net/,
 D: dynamic SLIP devices, dynamic /proc/net/, true size /proc/ksyms,
 D: and other hacks..
@@ -61,10 +61,11 @@
 D: Adaptec 274x driver
 S: Department of Computer Science
 S: University of Calgary
-S: Calgary, Alberta, Canada
+S: Calgary, Alberta
+S: Canada
 
 N: Ralf Baechle
-E: ralf@gnu.ai.mit.edu
+E: ralf@gnu.org
 P: 1024/AF7B30C1 CF 97 C2 CC 6D AE A7 FE  C8 BA 9C FC 88 DE 32 C3
 D: Linux/MIPS port
 D: Linux/68k hacker
@@ -93,12 +94,8 @@
 S: USA
 
 N: James Banks
-E: james.banks@caldera.com
+E: james@sovereign.org
 D: TLAN network driver
-S: Caldera, Inc.
-S: 633 South 550 East
-S: Provo, UT 84606
-S: USA
 
 N: Peter Bauer
 E: 100136.3530@compuserve.com
@@ -156,18 +153,19 @@
 D: Original author of the Linux networking code
 
 N: Philip Blundell
-E: Philip.Blundell@pobox.com
+E: philb@gnu.org
 D: Device driver hacking (especially EtherExpress16/3C505 net cards)
 D: Some Linux/ARM stuff
-S: 201 Gilbert Road
-S: Cambridge, UK. CB4 3PA
+S: Nexus Eletronics Ltd
+S: 10 St Barnabas Road, Cambridge CB1 2BY
+S: United Kingdom
 
-N: Thomas Bogendoerfer
+N: Thomas Bogendörfer
 E: tsbogend@alpha.franken.de
 D: Lance32 driver
 D: strace for Linux/Alpha
-S: Baumgartenweg 5
-S: 91452 Wilhermsdorf
+S: Schafhofstr. 40
+S: 90556 Cadolzburg
 S: Germany
 
 N: Bill Bogstad
@@ -227,11 +225,11 @@
 S: USA
 
 N: Gordon Chaffee
-E: chaffee@plateau.cs.berkeley.edu
+E: chaffee@cs.berkeley.edu
 W: http://bmrc.berkeley.edu/people/chaffee/
 D: vfat, fat32, joliet, native language support
-S: 3674 Oakwood Terrace #201
-S: Fremont, California 94536
+S: 3700 Warwick Road
+S: Fremont, California 94555
 S: USA
 
 N: Chih-Jen Chang
@@ -240,7 +238,8 @@
 D: IGMP(Internet Group Management Protocol) version 2
 S: 3F, 65 Tajen street
 S: Tamsui town, Taipei county,
-S: Taiwan 251, Republic of China
+S: Taiwan 251
+S: Republic of China
 
 N: Raymond Chen
 E: raymondc@microsoft.com
@@ -259,8 +258,9 @@
 S: USA
 
 N: Juan Jose Ciarlante
+W: http://juanjox.linuxhq.com/
 E: jjciarla@raiz.uncu.edu.ar
-E: juanjo@irriga.uncu.edu.ar
+E: jjo@mendoza.gov.ar
 D: Network driver alias support
 D: IP masq hashing and app modules
 D: IP ip_dynaddr bits 
@@ -276,9 +276,9 @@
 S: Australia
 
 N: Alan Cox
-E: alan@lxorguk.ukuu.org.uk (linux related - except big patches)
-E: iialan@www.uk.linux.org (linux.org.uk/big patches)
-E: alan@cymru.net (commercial CymruNET stuff)
+W: http://roadrunner.swansea.linux.org.uk/alan.shtml
+E: alan@lxorguk.ukuu.org.uk
+E: alan@www.linux.org.uk (linux.org.uk stuff)
 E: Alan.Cox@linux.org (if others fail)
 D: NET2Debugged/NET3 author
 D: Network layer debugging
@@ -287,11 +287,11 @@
 D: Current 3c501 hacker. >>More 3c501 info/tricks wanted<<.
 D: Watchdog timer drivers
 D: Linux/SMP
-S: CymruNet Limited
-S: The Innovation Centre
-S: Singleton Park
-S: Swansea, SA2 8PP
-S: Wales, United Kingdom
+S: c/o Red Hat UK Ltd
+S: Alexandra House
+S: Alexandra Terrace
+S: Guildford, GU1 3DA
+S: United Kingdom
 
 N: Laurence Culhane
 E: loz@holmes.demon.co.uk
@@ -340,7 +340,7 @@
 N: Eddie C. Dost
 E: ecd@skynet.be
 D: Linux/Sparc kernel hacker
-D: New Linux/Sparc maintainer (while davem is at SGI)
+D: Linux/Sparc maintainer
 S: Rue de la Chapelle 51
 S: 4850 Moresnet
 S: Belgium
@@ -398,11 +398,11 @@
 S: Germany
 
 N: Paal-Kristian Engstad
-E: engstad@funcom.com
+E: engstad@intermetrics.com
 D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.)
-S: Oscars gt. 35
-S: N-0258 OSLO
-S: Norway
+S: 17101 Springdale Street #225
+S: Huntington Beach, California 92649
+S: USA
 
 N: Doug Evans
 E: dje@cygnus.com
@@ -410,13 +410,13 @@
 
 N: Rik Faith
 E: faith@cs.unc.edu
-E: r.faith@ieee.org
+E: faith@acm.org
 D: Author: Future Domain TMC-16x0 SCSI driver
 D: Debugging: SCSI code; Cyclades serial driver; APM driver
 D: Debugging: XFree86 Mach 32 server, accelerated server code
 
 N: Jürgen Fischer
-E: fischer@et-inf.fho-emden.de (=?iso-8859-1?q?J=FCrgen?= Fischer)
+E: fischer@norbit.de (=?iso-8859-1?q?J=FCrgen?= Fischer)
 D: Author of Adaptec AHA-152x scsi driver
 S: Schulstraße 18
 S: 26506 Norden
@@ -503,8 +503,7 @@
 S: USA
 
 N: Paul Gortmaker
-E: gpg109@rsphy1.anu.edu.au
-W: http://rsphy1.anu.edu.au/~gpg109
+E: p_gortmaker@yahoo.com
 D: Real Time Clock driver author.
 D: 8390 net driver hacker (ne2000, wd8013, smc-ultra, 3c503, etc.) 
 D: Ethernet-HowTo and BootPrompt-HowTo author.
@@ -513,7 +512,7 @@
 D: Various other random hacks, patches and utilities.
 
 N: John E. Gotts
-E: jgotts@engin.umich.edu
+E: jgotts@linuxsavvy.com
 D: kernel hacker
 S: 8124 Constitution Apt. 7
 S: Sterling Heights, Michigan 48313
@@ -530,9 +529,10 @@
 
 N: Grant Guenther
 E: grant@torque.net
+W: http://www.torque.net/linux-pp.html
 D: Iomega PPA / ZIP driver
-S: 906-1001 Bay St.
-S: Toronto, Ontario, M5S 3A6 
+S: 44 St. Joseph Street, Suite 506
+S: Toronto, Ontario, M4Y 2W4 
 S: Canada
 
 N: Danny ter Haar
@@ -566,19 +566,16 @@
 S: USA
 
 N: Angelo Haritsis
-E: ah@doc.ic.ac.uk
+E: ah@computer.org
 D: kernel patches (serial, watchdog)
 D: xringd, vuzkern, greekXfonts
-S: 58 Henfield Close
-S: London N19 3UL
+S: 77 Clarence Mews
+S: London SE16 1GD
 S: United Kingdom
 
 N: Kai Harrekilde-Petersen
-E: khp@dolphinics.no
+E: khp@olicom.dk
 D: Original author of the ftape-HOWTO, i82078 fdc detection code.
-S: Peder Holters vei 13
-S: 1168 Oslo
-S: Norway
 
 N: Andrew Haylett
 E: ajh@primag.co.uk
@@ -595,9 +592,12 @@
 S: Germany
 
 N: Richard Henderson
-E: richard@gnu.ai.mit.edu
+E: rth@twiddle.net
 E: rth@cygnus.com
 D: Alpha/ELF, gcc, binutils, and glibc
+S: 50 E. Middlefield #10
+S: Mountain View, California 94043
+S: USA
 
 N: Sebastian Hetze
 E: she@lunetix.de
@@ -615,24 +615,23 @@
 S: Germany
 
 N: Dirk Hohndel
-E: hohndel@aib.com
+E: hohndel@suse.de
 D: The XFree86[tm] Project
-S: AIB Software Corporation
-S: 46030 Manekin Plaza, Suite 160
-S: Dulles, Virginia 20166
-S: USA
+S: SuSE Rhein/Main AG
+S: Mergenthalerallee 45-47
+S: 65760 Eschborn
+S: Germany
 
-N: Kenji Tsutomu Hollis
+N: Kenji Hollis
 E: khollis@bitgate.com
-W: http://www.nurk.org/
+W: http://www.bitgate.com/
 D: Berkshire PC Watchdog Driver
-S: PO Box 15
-S: Grants Pass, Oregon 97526
-S: USA
 
 N: Nick Holloway
 E: Nick.Holloway@alfie.demon.co.uk
 E: Nick.Holloway@parallax.co.uk
+W: http://www.alfie.demon.co.uk/
+P: 1024/75C49395 3A F0 E3 4E B7 9F E0 7E  47 A3 B0 D5 68 6A C2 FB
 D: Small patches for kernel, libc
 D: MAKEDEV
 S: 15 Duke Street
@@ -642,14 +641,14 @@
 S: United Kingdom
 
 N: Ron Holt
-E: ron@caldera.com
+E: ron@holt.org
 W: http://www.holt.org/
-P: 1024/1FD44539 DF 4B EB 9F 5B 68 38 9A  40 E3 FB 71 D1 C8 0B 56
+W: http://www.ronholt.com/
 D: Kernel development
 D: Minor kernel modifications to support Wabi and Wine
-S: Caldera, Inc.
-S: 240 West Center St.
-S: Orem, Utah 84059-1920
+S: Holtron Internetics, Inc.
+S: 998 East 900 South, Suite 26
+S: Provo, Utah 84606-5607
 S: USA
 
 N: Rob W. W. Hooft
@@ -708,7 +707,7 @@
 S: USA
 
 N: Bernhard Kaindl
-E: bernhard.kaindl@gmx.net
+E: bkaindl@netway.at
 E: edv@bartelt.via.at
 D: Author of a menu based configuration tool, kmenu, which 
 D: is the predecessor of 'make menuconfig' and 'make xconfig'.
@@ -717,21 +716,22 @@
 S: Austria
 
 N: Fred N. van Kempen
-E: waltje@uwalt.nl.mugnet.org
+E: waltje@linux.com
 D: NET-2
 D: Drivers
 D: Kernel cleanups
-S: Hoefbladhof 27
-S: 2215 DV Voorhout
+S: Korte Heul 95
+S: 1403 ND  BUSSUM
 S: The Netherlands
 
 N: Karl Keyte
-E: kkeyte@koft.rhein-main.de
-E: kkeyte@esoc.esa.de
+E: kkeyte@koft.com
 D: Disk usage statistics and modifications to line printer driver
-S: Erbacher Strasse 6
-S: D-64283 Darmstadt
-S: Germany
+S: 26a Sheen Road
+S: Richmond
+S: Surrey
+S: TW9 1AE
+S: United Kingdom
 
 N: Olaf Kirch
 E: okir@monad.swb.de
@@ -839,9 +839,10 @@
 N: Jamie Lokier
 E: jamie@imbolc.ucc.ie
 D: Reboot-through-BIOS for broken 486 motherboards
-S: 26 Oatlands Road
+S: 11 Goodson Walk
+S: Marston
 S: Oxford
-S: OX2 0ET
+S: OX3 0HX
 S: United Kingdom
 
 N: Mark Lord
@@ -872,16 +873,12 @@
 S: 00200 Helsinki
 S: Finland
 
-N: Kai Mäkisara
-E: Kai.Makisara@metla.fi
-D: SCSI Tape Driver
-
 N: Hamish Macdonald
-E: hamish@border.ocunix.on.ca
+E: hamishm@lucent.com
 D: Linux/68k port
-S: 102-B Valleystream Drive
-S: Nepean, Ontario
-S: Canada K2H-9E1
+S: 32 Clydesdale Avenue
+S: Kanata, Ontario
+S: Canada K2M-2G7
 
 N: Peter MacDonald
 D: SLS distribution
@@ -904,6 +901,10 @@
 S: Halifax, Nova Scotia
 S: Canada B3J 3C8
 
+N: Kai Mäkisara
+E: Kai.Makisara@metla.fi
+D: SCSI Tape Driver
+
 N: Martin Mares
 E: mj@k332.feld.cvut.cz
 W: http://atrey.karlin.mff.cuni.cz/~mj/
@@ -957,13 +958,12 @@
 S: Germany
 
 N: Michael Meskes
-E: meskes@topsystem.de
+E: meskes@debian.org
 P: 1024/04B6E8F5 6C 77 33 CA CC D6 22 03  AB AB 15 A3 AE AD 39 7D
 D: Kernel hacker. Software watchdog daemon.
 D: Maintainer of several Debian packages
-S: topsystem Systemhaus GmbH
-S: Europark A2, Adenauerstr. 20
-S: D-52146 Wuerselen
+S: Th.-Heuss-Str. 61 
+S: D-41812 Erkelenz
 S: Germany
 
 N: Nigel Metheringham
@@ -988,20 +988,21 @@
 S: Australia
 
 N: Pauline Middelink
-E: middelin@polyware.iaf.nl
+E: middelin@polyware.nl
 D: General low-level bug fixes, /proc fixes, identd support
 S: Boterkorfhoek 34
 S: 7546 JA  Enschede
 S: Netherlands
 
 N: David S. Miller
-E: davem@caip.rutgers.edu
+E: davem@redhat.com
 D: Sparc hacker
 D: New Linux-Activists maintainer
 D: Linux Emacs elf/qmagic support + other libc/gcc things
 D: Yee bore de yee bore! ;-)
-S: 2 Bristol Court
-S: East Brunswick, New Jersey 08816
+S: 750 N. Shoreline Blvd.
+S: Apt. #111
+S: Mountain View, California 94043
 S: USA
 
 N: Rick Miller
@@ -1038,6 +1039,7 @@
 S: Germany
 
 N: David Mosberger-Tang
+E: davidm@hpl.hp.com (IA-64 related)
 E: David.Mosberger@acm.org
 D: Linux/Alpha
 S: 35706 Runckel Lane
@@ -1052,7 +1054,7 @@
 S: USA
 
 N: Johan Myreen
-E: jem@vipunen.hut.fi
+E: jem@iki.fi
 D: PS/2 mouse driver writer etc.
 S: Dragonvagen 1 A 13
 S: FIN-00330 Helsingfors
@@ -1104,7 +1106,8 @@
 D: IPX development and support
 
 N: Avery Pennarun
-E: apenwarr@bond.net
+E: apenwarr@worldvisions.ca
+W: http://www.worldvisions.ca/~apenwarr/
 D: ARCnet driver
 D: "make xconfig" improvements
 D: Various minor hacking
@@ -1158,28 +1161,29 @@
 
 N: Eric S. Raymond
 E: esr@thyrsus.com
-W: http://www.ccil.org/~esr/home.html
+W: http://www.tuxedo.org/~esr/
 D: ncurses library co-maintainer
 D: terminfo master file maintainer
 D: Distributions HOWTO editor
 D: Instigator, FHS standard
 D: Keeper of the Jargon File and curator of the Retrocomputing Museum
 D: Author, Emacs VC and GUD modes
-S: 22 South Warren Avenue
+S: 6 Karen Drive
 S: Malvern, Pennsylvania 19355
 S: USA
 
 N: Stefan Reinauer
-E: stepan@home.culture.mipt.ru
-W: http://home.culture.mipt.ru/~stepan
+E: stepan@linux.de
+W: http://www.freiburg.linux.de/~stepan/
 D: Modularized affs and ufs. Minor fixes.
-S: Rebmannsweg 34h
-S: 79539 Loerrach
+S: Schlossbergring 9
+S: 79098 Freiburg
 S: Germany
 
 N: Joerg Reuter
-E: jreuter@lykos.oche.de
-E: dl1bke@db0pra.ampr.org (amateur radio)
+E: jreuter@poboxes.com
+W: http://poboxes.com/jreuter/
+W: http://qsl.net/dl1bke/
 D: Z8530 SCC driver and DAMA Slave for AX.25
 
 N: William E. Roadcap
@@ -1199,8 +1203,8 @@
 S: Germany
 
 N: Stephen Rothwell
-E: Stephen.Rothwell@canb.auug.org.au
-W: http://www.canb.auug.org.au/~sfr
+E: sfr@linuxcare.com
+W: http://linuxcare.com.au/sfr
 P: 1024/BD8C7805 CD A4 9D 01 10 6E 7E 3B  91 88 FA D9 C8 40 AA 02
 D: Boot/setup/build work for setup > 2K
 D: Author, APM driver
@@ -1248,6 +1252,11 @@
 S: S-226 64 LUND
 S: Sweden
 
+N: Henning P. Schmiedehausen
+E: hps@tanstaafl.de
+D: added PCI support to the serial driver
+S: Buckenhof, Germany
+
 N: Peter De Schrijver
 E: stud11@cc4.kuleuven.ac.be
 D: Mitsumi CD-ROM driver patches March version
@@ -1255,11 +1264,6 @@
 S: B2240 Zandhoven
 S: Belgium
 
-N: Henning P. Schmiedehausen
-E: hps@tanstaafl.de
-D: added PCI support to the serial driver
-S: Buckenhof, Germany
-
 N: Martin Schulze
 E: joey@linux.de
 W: http://home.pages.de/~joey/
@@ -1267,12 +1271,13 @@
 D: CD-List, Books-List, Ex-FAQ
 D: Linux-Support, -Mailbox, -Stammtisch
 D: several improvements to system programs
-S: Oldenburg, Germany
+S: Oldenburg
+S: Germany
 
 N: Darren Senn
 E: sinster@darkwater.com
 D: Whatever I notice needs doing (so far: itimers, /proc)
-S: POB 64132
+S: Post Office Box 64132
 S: Sunnyvale, California 94088-4132
 S: USA
 
@@ -1286,14 +1291,12 @@
 S: USA
 
 N: Mike Shaver
-E: shaver@ingenia.com
-W: http://neon.ingenia.com/~shaver/
+E: shaver@hungry.org
+W: http://www.hungry.org/~shaver/
 D: Network hacking, /proc/sys/net
-S: c/o Ingenia Communications Corporation
-S: Suite 4200, CTTC Building
-S: 1125 Colonel By Drive
-S: Ottawa, Ontario
-S: Canada K1S 5R1
+S: 149 Union St.
+S: Kingston, Ontario
+S: Canada K7L 2P4
 
 N: John Shifflett
 E: john@geolog.com
@@ -1315,11 +1318,11 @@
 N: Craig Small
 E: csmall@triode.apana.org.au
 E: vk2xlz@gonzo.vk2xlz.ampr.org (packet radio)
+D: Gracilis PackeTwin device driver
+D: RSPF daemon 
 S: 10 Stockalls Place
 S: Minto, NSW, 2566
 S: Australia
-D: Gracilis PackeTwin device driver
-D: RSPF daemon 
 
 N: Chris Smith
 E: csmith@convex.com
@@ -1351,9 +1354,9 @@
 S: USA
 
 N: Henrik Storner
-E: storner@osiris.ping.dk
-E: storner@olicom.dk
-W: http://eolicom.olicom.dk/~storner/
+E: storner@image.dk
+W: http://www.image.dk/~storner/
+W: http://www.sslug.dk/
 D: Configure script: tristate, bugfixes
 D: vfat/msdos integration, kerneld docs, Linux promotion
 S: Chr. Winthersvej 1 B, st.th.
@@ -1380,11 +1383,12 @@
 S: France
 
 N: Jon Tombs
-E: jon@gtex02.us.es
+E: jon@gte.esi.us.es
+W: http://www.esi.us.es/~jon
 D: NFS mmap()
 D: XF86_S3
 D: Kernel modules
-S: C/ Carlos de Cepeda 36 2-5
+S: C/ Federico Garcia Lorca 1 10-A
 S: Sevilla 41005
 S: Spain
 
@@ -1393,7 +1397,7 @@
 W: http://www.cs.helsinki.fi/~torvalds/
 P: 1024/A86B35C5 96 54 50 29 EC 11 44 7A  BE 67 3C 24 03 13 62 C8
 D: Original kernel hacker
-S: 3665 Benton Street #36
+S: 1050 Woodduck Avenue
 S: Santa Clara, California 95051
 S: USA
 
@@ -1408,11 +1412,12 @@
 S: CANADA K2L 1S2
 
 N: Andrew Tridgell
-E: Andrew.Tridgell@anu.edu.au
+E: tridge@samba.org
+W: http://linuxcare.com.au/tridge/
 D: dosemu, networking, samba
 S: 3 Ballow Crescent
-S: MacGregor A.C.T
-S: 2615 Australia
+S: MacGregor A.C.T 2615
+S: Australia
 
 N: Winfried Trümper
 E: winni@xpilot.org
@@ -1423,6 +1428,17 @@
 S: Tacitusstr. 6
 S: D-50968 Köln
 
+N: Tsu-Sheng Tsao
+E: tsusheng@scf.usc.edu
+D: IGMP(Internet Group Management Protocol) version 2
+S: 2F 14 ALY 31 LN 166 SEC 1 SHIH-PEI RD
+S: Taipei 
+S: Taiwan 112
+S: Republic of China
+S: 24335 Delta Drive
+S: Diamond Bar, California 91765
+S: USA
+
 N: Theodore Ts'o
 E: tytso@mit.edu
 D: Random Linux hacker
@@ -1438,16 +1454,6 @@
 S: Cambridge, Massachusetts 02139
 S: USA
 
-N: Tsu-Sheng Tsao
-E: tsusheng@scf.usc.edu
-D: IGMP(Internet Group Management Protocol) version 2
-S: 2F 14 ALY 31 LN 166 SEC 1 SHIH-PEI RD
-S: Taipei 
-S: Taiwan 112, Republic of China
-S: 24335 Delta Drive
-S: Diamond Bar, California 91765
-S: USA
-
 N: Simmule Turner
 E: sturner@tele-tv.com
 D: Added swapping to filesystem
@@ -1487,7 +1493,7 @@
 S: Australia
 
 N: Jeffrey A. Uphoff
-E: juphoff@nrao.edu
+E: juphoff@transmeta.com
 E: jeff.uphoff@linux.org
 P: 1024/9ED505C5 D7 BB CA AA 10 45 40 1B  16 19 0A C0 38 A0 3E CB
 D: Linux Security/Alert mailing lists' moderator/maintainer.
@@ -1495,9 +1501,9 @@
 D: PAM S/Key module developer.
 D: 'dip' contributor.
 D: AIPS port, astronomical community support.
-S: National Radio Astronomy Observatory
-S: 520 Edgemont Road
-S: Charlottesville, Virginia 22903
+S: Transmeta Corporation
+S: 2540 Mission College Blvd.
+S: Santa Clara, CA 95054
 S: USA
 
 N: Matthias Urlichs
@@ -1534,6 +1540,15 @@
 E: jnweiger@immd4.informatik.uni-erlangen.de
 D: The Linux Support Team Erlangen
 
+N: David Weinehall
+E: tao@acc.umu.se
+W: http://www.acc.umu.se/~tao/
+D: Miscellaneous fixes
+D: Cleanup of the Config-files
+S: Axtorpsvagen 40:20
+S: S-903 37  UMEA
+S: Sweden
+
 N: Matt Welsh
 E: mdw@sunsite.unc.edu
 D: Linux Documentation Project coordinator
@@ -1541,10 +1556,9 @@
 D: Linuxdoc-SGML formatting system
 D: Keithley DAS1200 device driver
 D: Maintainer of sunsite WWW and FTP, moderator c.o.l.answers
-S: Cornell University Computer Science Department
-S: Robotics and Vision Laboratory
-S: 4130 Upson Hall
-S: Ithaca, New York 14850
+S: Computer Science Division
+S: UC Berkeley
+S: Berkeley, CA 94720-1776
 S: USA
 
 N: Greg Wettstein
@@ -1569,8 +1583,8 @@
 S: Germany
 
 N: Marco van Wieringen
-E: mvw@mercury.mcs.nl.mugnet.org
-D: Author of acct and quota
+E: mvw@planets.elm.net
+D: Author of process accounting and diskquota
 S: Breeburgsingel 12
 S: 2135 CN Hoofddorp
 S: The Netherlands
@@ -1646,7 +1660,7 @@
 S: USA
 
 N: Werner Zimmermann
-E: zimmerma@rz.fht-esslingen.de
+E: Werner.Zimmermann@fht-esslingen.de
 D: CDROM driver "aztcd" (Aztech/Okano/Orchid/Wearnes)
 S: Flandernstrasse 101
 S: D-73732 Esslingen
@@ -1663,7 +1677,7 @@
 S: USA
 
 N: Marc Zyngier
-E: maz@gloups.fdn.fr
+E: maz@wild-wind.fr.eu.org
 D: MD driver
 S: 11 rue Victor HUGO
 S: 95560 Montsoult
diff -u --recursive --new-file linux-2.0.38/Documentation/Changes linux-2.0.39/Documentation/Changes
--- linux-2.0.38/Documentation/Changes	Sun Jun 13 19:20:59 1999
+++ linux-2.0.39/Documentation/Changes	Thu Dec 16 08:57:42 1999
@@ -44,7 +44,7 @@
    The most current version should always be available from
 http://cyberbuzz.gatech.edu/kaboom/linux/ as well.
 
-Last updated: February 16, 1998.
+Last updated: December 16, 1999.
 Current Author: Chris Ricker (kaboom@gatech.edu).
 
 Current Releases (the latest necessary for basic functionality, not
@@ -56,7 +56,7 @@
 - PPP daemon		 2.2.0f
 - Dynamic linker (ld.so) 1.7.14
 - GNU CC		 2.7.2.1
-- Binutils		 2.7.0.3
+- Binutils		 2.8.1.0.23
 - Linux C Library	 Stable:  5.2.18, Beta:  5.4.33
 - Linux C++ Library	 2.7.2.1
 - Termcap		 2.0.8
diff -u --recursive --new-file linux-2.0.38/Documentation/CodingStyle linux-2.0.39/Documentation/CodingStyle
--- linux-2.0.38/Documentation/CodingStyle	Tue Dec 29 20:57:33 1998
+++ linux-2.0.39/Documentation/CodingStyle	Thu Dec 30 20:36:13 1999
@@ -8,7 +8,7 @@
 at least consider the points made here. 
 
 First off, I'd suggest printing out a copy of the GNU coding standards,
-and NOT reading it.  Burn them, it's a great symbolic gesture. 
+and NOT read it.  Burn them, it's a great symbolic gesture. 
 
 Anyway, here goes:
 
@@ -59,8 +59,7 @@
 Heretic people all over the world have claimed that this inconsistency
 is ...  well ...  inconsistent, but all right-thinking people know that
 (a) K&R are _right_ and (b) K&R are right.  Besides, functions are
-special anyway (you can't nest them in C (well, you can in gcc, actually,
-but this is horribly nonstandard, so we will ignore it)). 
+special anyway (you can't nest them in C). 
 
 Note that the closing brace is empty on a line of its own, _except_ in
 the cases where it is followed by a continuation of the same statement,
@@ -184,14 +183,8 @@
   "C mode with adjusted defaults for use with the Linux kernel."
   (interactive)
   (c-mode)
-  (setq c-indent-level 8)
-  (setq c-brace-imaginary-offset 0)
-  (setq c-brace-offset -8)
-  (setq c-argdecl-indent 8)
-  (setq c-label-offset -8)
-  (setq c-continued-statement-offset 8)
-  (setq indent-tabs-mode nil)
-  (setq tab-width 8))
+  (c-set-style "K&R")
+  (setq c-basic-offset 8))
 
 This will define the M-x linux-c-mode command.  When hacking on a
 module, if you put the string -*- linux-c -*- somewhere on the first
@@ -217,3 +210,26 @@
 "indent" has a lot of options, and especially when it comes to comment
 re-formatting you may want to take a look at the manual page.  But
 remember: "indent" is not a fix for bad programming. 
+
+
+		Chapter 7: Configuration-files
+
+For configuration options (arch/xxx/config.in, and all the Config.in files),
+somewhat different indentation is used.
+
+An indention level of 3 is used in the code, while the text in the config-
+options should have an indention-level of 2 to indicate dependencies. The
+latter only applies to bool/tristate options. For other options, just use
+common sense. An example:
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   tristate 'Apply nitroglycerine inside the keyboard (DANGEROUS)' CONFIG_BOOM
+   if [ "$CONFIG_BOOM" != "n" ]; then
+      bool '  Output nice messages when you explode' CONFIG_CHEER
+   fi
+fi
+
+Generally, CONFIG_EXPERIMENTAL should surround all options not considered
+stable. All options that are known to trash data (experimental write-
+support for file-systems, for instance) should be denoted (DANGEROUS), other
+Experimental options should be denoted (EXPERIMENTAL).
diff -u --recursive --new-file linux-2.0.38/Documentation/Configure.help linux-2.0.39/Documentation/Configure.help
--- linux-2.0.38/Documentation/Configure.help	Sun Jun 13 19:20:59 1999
+++ linux-2.0.39/Documentation/Configure.help	Wed Jun 28 14:45:46 2000
@@ -878,7 +878,7 @@
   boot time ("man dmesg"), please follow the instructions at the top
   of include/linux/pci.h.
 
-PCI bridge optimization (experimental)
+PCI bridge optimization (EXPERIMENTAL)
 CONFIG_PCI_OPTIMIZE
   This can improve access times for some hardware devices under
   certain BIOSes if your computer uses a PCI bus system. This is
@@ -2513,7 +2513,7 @@
   running kernel whenever you want), say M here and read
   Documentation/modules.txt.
 
-BAYCOM ser12 and par96 driver for AX.25
+BAYCOM ser12 and par96 driver for AX.25 (EXPERIMENTAL)
 CONFIG_BAYCOM
   This is an experimental driver for Baycom style simple amateur radio
   modems that connect to either a serial interface or a parallel
@@ -2525,7 +2525,7 @@
   inserted in and removed from the running kernel whenever you want),
   say M here and read Documentation/modules.txt. This is recommended.
 
-Sound card modem driver for AX.25
+Sound card modem driver for AX.25 (EXPERIMENTAL)
 CONFIG_SOUNDMODEM
   This experimental driver allows a standard SoundBlaster or
   WindowsSoundSystem compatible sound card to be used as a packet
@@ -2591,13 +2591,13 @@
   with many transceiver designs and the fact that the TCM3105 (if
   used) is operated widely outside its specifications.
 
-Sound card modem support for 2666 baud AFSK modulation
+Sound card modem support for 2666 baud AFSK modulation (EXPERIMENTAL)
 CONFIG_SOUNDMODEM_AFSK2666
   This option enables the soundmodem driver 2666 baud AFSK modem.
   This modem is experimental, and not compatible to anything
   else I know of.
 
-Sound card modem support for 4800 baud 8PSK modulation
+Sound card modem support for 4800 baud 8PSK modulation (EXPERIMENTAL)
 CONFIG_SOUNDMODEM_PSK4800
   This option enables the soundmodem driver 4800 baud 8PSK modem.
   This modem is experimental, and not compatible to anything
@@ -3042,7 +3042,7 @@
   If you use FMV-183 or FMV-184 and it is not working, you may need
   to disable Plug & Play mode of the card.
 
-Intel EtherExpress/Pro 100B support'
+Intel EtherExpress/Pro 100B support (EXPERIMENTAL)
 CONFIG_EEXPRESS_PRO100B
   If you have an Intel EtherExpress Pro 100 10/100Mbps PCI Ethernet
   card, answer yes.  As of kernel release 2.0.31 this driver was
@@ -3975,7 +3975,7 @@
   whenever you want), say M here and read Documentation/modules.txt.
   If you haven't heard about all of this before, it's safe to say N.
 
-Kernel automounter support (experimental)
+Kernel automounter support (EXPERIMENTAL)
 CONFIG_AUTOFS_FS
   The automounter is a tool to automatically mount remote filesystems
   on demand.  This implementation is partially kernel-based to reduce
@@ -4194,6 +4194,16 @@
   read Documentation/modules.txt. If you haven't heard about it, it's
   safe to say N. (As of 1.3.9x kernels, this driver's minor numbers
   start at 0 instead of 32.)
+
+Cyclades-Z interrupt mode operation (EXPERIMENTAL)
+CONFIG_CYZ_INTR
+  The Cyclades-Z family of multiport cards allows 2 (two) driver
+  op modes: polling and interrupt. In polling mode, the driver will
+  check the status of the Cyclades-Z ports every certain amount of
+  time (which is called polling cycle and is configurable). In
+  interrupt mode, it will use an interrupt line (IRQ) in order to check
+  the status of the Cyclades-Z ports. The default op mode is polling.
+  If unsure, say N.
 
 Stallion multiport serial support
 CONFIG_STALDRV
diff -u --recursive --new-file linux-2.0.38/Documentation/isdn/README linux-2.0.39/Documentation/isdn/README
--- linux-2.0.38/Documentation/isdn/README	Sun Jun 13 19:20:59 1999
+++ linux-2.0.39/Documentation/isdn/README	Mon Dec 27 22:32:01 1999
@@ -335,7 +335,7 @@
       "manual" is a dial mode created to prevent the unexpected dialouts.
         In this mode, the interface will never make any connections on its
         own. You must explicitly initiate a connection with "isdnctrl dial
-        sdn0". However, after an idle time of no traffic as configured for 
+        isdn0". However, after an idle time of no traffic as configured for 
         the huptimeout value with isdnctrl, the connection _will_ be ended.
         If you don't want any automatic hangup, set the huptimeout value to 0.
         "manual" is the default.
diff -u --recursive --new-file linux-2.0.38/Documentation/modules.txt linux-2.0.39/Documentation/modules.txt
--- linux-2.0.38/Documentation/modules.txt	Tue Dec 29 20:58:25 1998
+++ linux-2.0.39/Documentation/modules.txt	Sun Aug 27 21:54:12 2000
@@ -121,7 +121,7 @@
 
 To use modprobe successfully, you generally place the following
 command in your /etc/rc.d/rc.S script.  (Read more about this in the
-"rc.hints" file in the module utilities package, "modules-x.y.z.tar.gz".)
+"rc.hints" file in the module utilities package, "modutils-x.y.z.tar.gz".)
 
 	/sbin/depmod -a
 
diff -u --recursive --new-file linux-2.0.38/Documentation/oops-tracing.txt linux-2.0.39/Documentation/oops-tracing.txt
--- linux-2.0.38/Documentation/oops-tracing.txt	Wed Sep 11 16:57:13 1996
+++ linux-2.0.39/Documentation/oops-tracing.txt	Wed Dec 29 12:36:45 1999
@@ -1,4 +1,4 @@
-From: Linus Torvalds <torvalds@cs.helsinki.fi>
+From: Linus Torvalds <torvalds@transmeta.com>
 
 How to track down an Oops.. [originally a mail to linux-kernel]
 
diff -u --recursive --new-file linux-2.0.38/MAINTAINERS linux-2.0.39/MAINTAINERS
--- linux-2.0.38/MAINTAINERS	Sun Jun 13 19:20:59 1999
+++ linux-2.0.39/MAINTAINERS	Thu Sep  7 03:21:31 2000
@@ -16,7 +16,8 @@
 	SMC etherpower for that.)
 
 3.	Make sure your changes compile correctly in multiple
-	configurations.
+	configurations. In particular check that changes work both as a
+	module and built into the kernel.
 
 4.	When you are happy with a change make it generally available for
 	testing and await feedback.
@@ -28,7 +29,8 @@
 	job the maintainers (and especially Linus) do is to keep things
 	looking the same. Sometimes this means that the clever hack in
 	your driver to get around a problem actual needs to become a
-	generalised kernel feature ready for next time.
+	generalised kernel feature ready for next time. See
+	Documentation/CodingStyle for guidance here.
 
 	PLEASE try to include any credit lines you want added with the
 	patch. It avoids people being missed off by mistake and makes
@@ -68,100 +70,80 @@
 			it has been replaced by a better system and you
 			should be using that.
 
-EXT2 FILE SYSTEM
-P:	Remy Card
-M:	Remy.Card@linux.org
-L:	linux-kernel@vger.rutgers.edu
-S:	Maintained
-
 3C501 NETWORK DRIVER
 P:	Alan Cox
-M:	net-patches@lxorguk.ukuu.org.uk
-L:	linux-net@vger.rutgers.edu
-S:	Maintained
-
-8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
-P:	Paul Gortmaker
-M:	gpg109@rsphy1.anu.edu.au
-L:	linux-net@vger.rutgers.edu
-S:	Maintained
-
-ETHEREXPRESS-16 NETWORK DRIVER
-P:	Philip Blundell
-M:	pjb27@cam.ac.uk
-L:	linux-net@vger.rutgers.edu
+M:	alan@the.3c501.cabal.tm
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
 3C505 NETWORK DRIVER
 P:	Philip Blundell
-M:	phil@tazenda.demon.co.uk
-L:	linux-net@vger.rutgers.edu
+M:	Philip.Blundell@pobox.com
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
-TLAN NETWORK DRIVER
-P:	James Banks
-M:	james.banks@caldera.com
-L:	linux-net@vger.rutgers.edu
-S:	Supported
-
-DIGI RIGHTSWITCH NETWORK DRIVER
-P:	Rick Richardson
-M:	rick@dgii.com
-L:	linux-net@vger.rutgers.edu
-W:	http://www.dgii.com/linux/
+8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
+P:	Paul Gortmaker
+M:	gpg109@rsphy1.anu.edu.au
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
-WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS
-P:	Jean Tourrilhes
-M:	jt@hplb.hpl.hp.com
+ADVANSYS SCSI DRIVER
+P:	Bob Frey
+M:	linux@advansys.com
+W:	http://www.advansys.com/linux.html
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
-TOKEN-RING NETWORK DRIVER
-P:      Paul Norton
-M:      pnorton@cts.com
-L:      linux-net@vger.rutgers.edu
-S:      Maintained
+AHA152X SCSI DRIVER
+P:	Juergen E. Fischer
+M:	Juergen Fischer <fischer@et-inf.fho-emden.de>
+L:	linux-scsi@vger.kernel.org
+S:	Maintained
 
 APM DRIVER
 P:	Stephen Rothwell
-M:	Stephen.Rothwell@canb.auug.org.au
-L:	linux-laptop@vger.rutgers.edu
+M:	apm@linuxcare.com.au
+L:	linux-laptop@vger.kernel.org
+W:	http://linuxcare.com.au/apm/
 S:	Maintained
 
 APPLETALK NETWORK LAYER
-P:	Alan Cox & University Of Michigan
-M:	net-patches@lxorguk.ukuu.org.uk, Cc: netatalk@umich.edu
-L:	[Someone fill in the netatalk list here]
-S:	Maintained
-
-AX.25 NETWORK LAYER
-P:	Jon Naylor
-M:	jsn@cs.nott.ac.uk
-L:	linux-hams@vger.rutgers.edu
+P:	Jay Schulist
+M:	Jay.Schulist@spacs.k12.wi.us
+L:	linux-atalk@netspace.org
 S:	Maintained
 
-IP MASQUERADING (IPV4)
-P:	Nigel Metheringham
-M:	Nigel.Metheringham@ThePLAnet.net
-L:	masq@indyramp.com
+ARPD SUPPORT
+P:	Jonathan Layes
+M:	layes@loran.com
+L:	linux-net@vger.kernel.org
 S:	Maintained
 
 AX.25 DAMA SLAVE
 P:	Joerg Reuter
 M:	jreuter@poboxes.com
-L:	linux-hams@vger.rutgers.edu
+W:	http://poboxes.com/jreuter/
+W:	http://qsl.net/dl1bke/
+L:	linux-hams@vger.kernel.org
 S:	Maintained
 
-Z8530 SCC DRIVER FOR AX.25
-P:	Joerg Reuter
-M:	jreuter@poboxes.com
-L:	linux-hams@vger.rutgers.edu
+AX.25 NETWORK LAYER
+P:	Matthias Welwarsky
+M:	dg2fef@afthd.tu-darmstadt.de
+L:	linux-hams@vger.kernel.org
 S:	Maintained
 
 BUSLOGIC SCSI DRIVER
 P:	Leonard N. Zubkoff
 M:	Leonard N. Zubkoff <lnz@dandelion.com>
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
+W:	http://www.dandelion.com/Linux/
+S:	Maintained
+
+CREDITS FILE
+P:	John A. Martin
+M:	jam@acm.org
 S:	Maintained
 
 CYCLADES ASYNC MUX DRIVER
@@ -170,126 +152,182 @@
 W:	http://www.cyclades.com/
 S:	Supported
 
+DAC960 RAID DRIVER
+P:	Leonard N. Zubkoff
+M:	Leonard N. Zubkoff <lnz@dandelion.com>
+L:	linux-raid@vger.kernel.org
+S:	Maintained
+
 DC390/AM53C974 SCSI driver
 P:	Kurt Garloff
 M:	kurt@garloff.de
 W:	http://www.garloff.de/kurt/linux/dc390/
 S:	Maintained
 
-DAC960 RAID DRIVER
-P:	Leonard N. Zubkoff
-M:	Leonard N. Zubkoff <lnz@dandelion.com>
-L:	linux-raid@vger.rutgers.edu
+DEVICE NUMBER REGISTRY
+P:	H. Peter Anvin
+M:	hpa@zytor.com
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-EATA ISA/EISA/PCI SCSI DRIVER
-P:	Dario Ballabio
-M:	dario@milano.europe.dg.com
-L:	linux-scsi@vger.rutgers.edu
+DIGIBOARD DRIVER
+P:	Christoph Lameter
+M:	clameter@fuller.edu
+L:	digiboard@list.fuller.edu
 S:	Maintained
 
-U14-34F SCSI DRIVER
-P:	Dario Ballabio
-M:	dario@milano.europe.dg.com
-L:	linux-scsi@vger.rutgers.edu
+DIGI RIGHTSWITCH NETWORK DRIVER
+P:	Rick Richardson
+M:	rick@dgii.com
+L:	linux-net@vger.kernel.org
+W:	http://www.dgii.com/linux/
 S:	Maintained
 
 EATA-DMA SCSI DRIVER
 P:	Michael Neuffer
 M:	mike@i-Connect.Net
-L:	linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu
+L:	linux-eata@i-connect.net, linux-scsi@vger.kernel.org
+S:	Maintained
+
+EATA ISA/EISA/PCI SCSI DRIVER
+P:	Dario Ballabio
+M:	dario@milano.europe.dg.com
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
 EATA-PIO SCSI DRIVER
 P:	Michael Neuffer
 M:	mike@i-Connect.Net
-L:	linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu
+L:	linux-eata@i-connect.net, linux-scsi@vger.kernel.org
+S:	Maintained
+
+ETHEREXPRESS-16 NETWORK DRIVER
+P:	Philip Blundell
+M:	Philip.Blundell@pobox.com
+L:	linux-net@vger.kernel.org
+S:	Maintained
+
+EXT2 FILE SYSTEM
+P:	Remy Card
+M:	Remy.Card@linux.org
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 FILE LOCKING (flock() and fcntl()/lockf())
 P:	Andy Walker
 M:	andy@lysaker.kvaerner.no
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
+FPU EMULATOR
+P:	Bill Metzenthen
+M:	billm@suburbia.net
+W:	http://suburbia.net/~billm/floating-point/emulator/
 S:	Maintained
 
 FRAME RELAY DLCI/FRAD (Sangoma drivers too)
 P:	Mike McLagan
 M:	mike.mclagan@linux.org
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
+S:	Maintained
+
+FTAPE/QIC-117
+P:	Claus-Justus Heine
+M:	claus@momo.math.rwth-aachen.de
+L:	linux-tape@vger.kernel.org
+W:	http://www-math.math.rwth-aachen.de/~LBFM/claus/ftape/
 S:	Maintained
 
 FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
 P:	Rik Faith
 M:	faith@cs.unc.edu
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
 S:	Odd fixes (e.g., new signatures)
 
-SCSI TAPE DRIVER
-P:	Kai Mäkisara
-M:	Kai.Makisara@metla.fi
-L:	linux-scsi@vger.rutgers.edu
-S:	Maintained
-
-FTAPE/QIC-117:
-P:	Claus-Justus Heine
-M:	claus@momo.math.rwth-aachen.de
-L:	linux-tape@vger.rutgers.edu
-S:	Maintained
-
-IPX NETWORK LAYER
-P:	Alan Cox [for the moment]
-M:	net-patches@lxorguk.ukuu.org.uk
-L:	linux-ipx@vger.rutgers.edu [will change]
+GSCD CDROM DRIVER
+P:	Oliver Raupach
+M:	oliver@mm.gop.de
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 IDE DRIVER [GENERAL]
-P:	Mark Lord
-M:	mlord@pobox.com
-L:	linux-kernel@vger.rutgers.edu
-S:	Maintained
+P:	Andre Hedrick
+M:	andre@linux-ide.org
+L:	linux-kernel@vger.kernel.org
+W:	http://linux.kernel.org/pub/linux/kernel/people/hedrick/
+S:	Supported
 
 IDE/ATAPI CDROM DRIVER 
 P:	Jens Axboe
-M:	axboe@image.dk
-P:	Chris Zwilling
-M:	chris@cloudnet.com
-L:	linux-kernel@vger.rutgers.edu
+M:	axboe@suse.de
+L:	linux-kernel@vger.kernel.org
+W:	http://www.kernel.dk
 S:	Maintained
 
 IDE/ATAPI TAPE/FLOPPY DRIVERS
 P:	Gadi Oxman
 M:	Gadi Oxman <gadio@netvision.net.il>
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
+IP MASQUERADING (IPV4)
+P:	Nigel Metheringham
+M:	Nigel.Metheringham@ThePLAnet.net
+L:	masq@indyramp.com
+S:	Maintained
+
+IPX NETWORK LAYER
+P:	Alan Cox [for the moment]
+M:	net-patches@lxorguk.ukuu.org.uk
+L:	linux-ipx@vger.kernel.org [will change]
 S:	Maintained
 
 ISDN SUBSYSTEM [GENERAL]
 P:	Fritz Elfert
 M:	fritz@isdn4linux.de
-L:	isdn4linux@hub-wue.franken.de
+L:	isdn4linux@listserv.isdn4linux.de
 W:	http://www.isdn4linux.de
 S:	Maintained
 
 ISDN SUBSYSTEM HISAX
 P:	Karsten Keil
 M:	keil@isdn4linux.de
-L:	isdn4linux@hub-wue.franken.de
+L:	isdn4linux@listserv.isdn4linux.de
 W:	http://www.isdn4linux.de
 S:	Maintained
 
+KERNEL AUTOMOUNTER (AUTOFS)
+P:	H. Peter Anvin
+M:	hpa@zytor.com
+L:	autofs@linux.kernel.org
+S:	Maintained
+
+LANCE AND LANCE32 NETWORK DRIVER
+P:	Thomas Bogendoerfer
+M:	tsbogend@bigbug.franken.de
+L:	linux-net@vger.kernel.org
+S:	Maintained
+
+MENUCONFIG
+P:	William Roadcap
+M:	roadcapw@titus.org
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 MODULE SUPPORT [GENERAL], KERNELD
 P:	Bjorn Ekwall
 M:	bj0rn@blox.se
 W:	http://www.pi.se/blox/modules/
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-ARPD SUPPORT
-P:	Jonathan Layes
-M:	layes@loran.com
-L:	linux-net@vger.rutgers.edu
+MOUSE AND MISC DEVICES [GENERAL]
+P:	Alessandro Rubini
+M:	rubini@ipvvis.unipv.it
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-NCP FILESYSTEM:
+NCP FILESYSTEM
 P:	Volker Lendecke
 M:	vl@kki.org
 L:	linware@sh.cvut.cz
@@ -298,166 +336,143 @@
 NETROM NETWORK LAYER
 P:	Jon Naylor
 M:	jsn@cs.nott.ac.uk
-L:	linux-hams@vger.rutgers.edu
+L:	linux-hams@vger.kernel.org
 S:	Maintained
 
-NETWORKING [GENERAL]:
+NETWORKING [GENERAL]
 P:	Alan Cox
 M:	net-patches@lxorguk.ukuu.org.uk
-L:	linux-net@vger.rutgers.edu
+L:	linux-net@vger.kernel.org
 S:	Odd Fixes <-> Maintained subject to workloads
 
+NON-IDE/NON-SCSI CDROM DRIVERS [GENERAL] (come on, crew - mark your responsibility)
+P:	Eberhard Moenkeberg
+M:	emoenke@gwdg.de
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 PPP PROTOCOL DRIVERS AND COMPRESSORS
 P:	Al Longyear
-M:	longyear@netcom.com, Cc: longyear@sii.com
-L:	linux-ppp@vger.rutgers.edu
+M:	longyear@pobox.com
+L:	linux-ppp@vger.kernel.org
 S:	Maintained
 
 REAL TIME CLOCK DRIVER
 P:	Paul Gortmaker
-M	gpg109@rsphy1.anu.edu.au
-L:	linux-kernel@vger.rutgers.edu
-S:	Maintained
-
-STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
-P:	Stuart Cheshire
-M:	cheshire@cs.stanford.edu
-W:	http://mosquitonet.Stanford.EDU/strip.html
+M:	p_gortmaker@yahoo.com
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-SMB FILESYSTEM:
-P:	Volker Lendecke
-M:	vl@kki.org
-L:	samba@listproc.anu.edu.au
-S:	Odd Fixes
-
-SMP: (except SPARC)
-P:	Alan Cox
-M:	smp-patches@lxorguk.ukuu.org.uk
-L:	linux-smp@vger.rutgers.edu
+RISCOM8 DRIVER
+P:	Dmitry Gorodchanin
+M:	pgmdsg@ibi.com
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-SPARC:
-P:	David S. Miller
-M:	davem@caip.rutgers.edu
-L:	sparclinux@vger.rutgers.edu
+SBPCD CDROM DRIVER
+P:	Eberhard Moenkeberg
+M:	emoenke@gwdg.de
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
 SCSI SUBSYSTEM
-P:	Leonard N. Zubkoff
-M:	Leonard N. Zubkoff <lnz@dandelion.com>
-L:	linux-scsi@vger.rutgers.edu
-S:	Maintained
+L:	linux-scsi@vger.kernel.org
+S:	Unmaintained
 
-SVGA HANDLING:
-P:	Martin Mares
-M:	mj@k332.feld.cvut.cz
-L:	linux-video@atrey.karlin.mff.cuni.cz
+SCSI TAPE DRIVER
+P:	Kai Mäkisara
+M:	Kai.Makisara@metla.fi
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
-VFAT FILESYSTEM:
-P:	Gordon Chaffee
-M:	chaffee@plateau.cs.berkeley.edu
-L:	linux-kernel@vger.rutgers.edu
-W:	http://www-plateau.cs.berkeley.edu/people/chaffee
+SMB FILESYSTEM
+P:	Andrew Tridgell
+M:	tridge@samba.org
+W:	http://samba.org/
+L:	samba@samba.org
 S:	Maintained
 
-DIGIBOARD DRIVER:
-P:	Christoph Lameter
-M:	clameter@fuller.edu
-L:	digiboard@list.fuller.edu
+SMP (except SPARC)
+P:	Alan Cox
+M:	smp-patches@lxorguk.ukuu.org.uk
+L:	linux-smp@vger.kernel.org
 S:	Maintained
 
-RISCOM8 DRIVER:
-P:	Dmitry Gorodchanin
-M:	pgmdsg@ibi.com
-L:	linux-kernel@vger.rutgers.edu
+SPARC
+P:	David S. Miller
+M:	davem@redhat.com
+L:	sparclinux@vger.kernel.org
 S:	Maintained
 
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
 P:	Roger Wolff
 M:	R.E.Wolff@BitWizard.nl
 M:	io8-linux@specialix.co.uk
-L:	linux-kernel@vger.rutgers.edu ?
+L:	linux-kernel@vger.kernel.org ?
 S:	Supported
 
-MOUSE AND MISC DEVICES [GENERAL]
-P:	Alessandro Rubini
-M:	rubini@ipvvis.unipv.it
-L:	linux-kernel@vger.rutgers.edu
-S:	Maintained
-
-MENUCONFIG:
-P:	William Roadcap
-M:	roadcapw@titus.org
-L:	linux-kernel@vger.rutgers.edu
-S:	Maintained
-
-LANCE AND LANCE32 NETWORK DRIVER
-P:	Thomas Bogendoerfer
-M:	tsbogend@bigbug.franken.de
-L:	linux-net@vger.rutgers.edu
-S:	Maintained
-
-ADVANSYS SCSI DRIVER
-P:	Bob Frey
-M:	Bob Frey <bobf@advansys.com>
-W:	http://www.advansys.com/linux
-S:	Maintained
-
-AHA152X SCSI DRIVER
-P:	Juergen E. Fischer
-M:	Juergen Fischer <fischer@et-inf.fho-emden.de>
-L:	linux-scsi@vger.rutgers.edu
-S:	Maintained
+STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
+W:	http://mosquitonet.Stanford.EDU/strip.html
+S:	Unsupported ?
 
-GSCD CDROM DRIVER
-P:	Oliver Raupach
-M:	oliver@mm.gop.de
-L:	linux-kernel@vger.rutgers.edu
+SVGA HANDLING
+P:	Martin Mares
+M:	mj@atrey.karlin.mff.cuni.cz
+L:	linux-video@atrey.karlin.mff.cuni.cz
 S:	Maintained
 
-SBPCD CDROM DRIVER
-P:	Eberhard Moenkeberg
-M:	emoenke@gwdg.de
-L:	linux-kernel@vger.rutgers.edu
+THE V2.0 KERNEL IN GENERAL
+P:	David Weinehall
+M:	tao@acc.umu.se
+L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-NON-IDE/NON-SCSI CDROM DRIVERS [GENERAL] (come on, crew - mark your responsibility)
-P:	Eberhard Moenkeberg
-M:	emoenke@gwdg.de
-L:	linux-kernel@vger.rutgers.edu
+TLAN NETWORK DRIVER
+P:	Torben Mathiasen
+M:	torben.mathiasen@compaq.com
+L:	tlan@vuser.vu.union.edu
 S:	Maintained
 
-FPU EMULATOR
-P:	Bill Metzenthen
-M:	billm@suburbia.net
-W:	http://suburbia.net/~billm/floating-point/emulator/
-S:	Maintained
+TOKEN-RING NETWORK DRIVER
+P:      Paul Norton
+M:	pnorton@ieee.org
+L:      linux-net@vger.kernel.org
+L:	linux-tr@linuxtr.net
+S:      Maintained
 
-CREDITS FILE
-P:	John A. Martin
-M:	jam@acm.org
+U14-34F SCSI DRIVER
+P:	Dario Ballabio
+M:	dario@milano.europe.dg.com
+L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
-KERNEL AUTOMOUNTER (AUTOFS)
-P:	H. Peter Anvin
-M:	hpa@zytor.com
-L:	autofs@linux.kernel.org
+VFAT FILESYSTEM
+P:	Gordon Chaffee
+M:	chaffee@plateau.cs.berkeley.edu
+L:	linux-kernel@vger.kernel.org
+W:	http://bmrc.berkeley.edu/people/chaffee
 S:	Maintained
 
-DEVICE NUMBER REGISTRY
-P:	H. Peter Anvin
-M:	hpa@zytor.com
-L:	linux-kernel@vger.rutgers.edu
+WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS
+P:	Jean Tourrilhes
+M:	jt@hpl.hp.com
+W:	http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
 S:	Maintained
 
 WD7000 SCSI DRIVER
 P:	Miroslav Zagorac
 M:	zaga@fly.cc.fer.hr
-L:	linux-scsi@vger.rutgers.edu
+L:	linux-scsi@vger.kernel.org
+S:	Maintained
+
+Z8530 SCC DRIVER FOR AX.25
+P:	Joerg Reuter
+M:	jreuter@poboxes.com
+W:	http://poboxes.com/jreuter/
+W:	http://qsl.net/dl1bke/
+L:	linux-hams@vger.kernel.org
 S:	Maintained
 
-REST:
+THE REST
 P:	Linus Torvalds
 S:	Buried alive in email
diff -u --recursive --new-file linux-2.0.38/Makefile linux-2.0.39/Makefile
--- linux-2.0.38/Makefile	Thu Aug 26 00:08:27 1999
+++ linux-2.0.39/Makefile	Wed Dec 15 12:22:10 1999
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 0
-SUBLEVEL = 38
+SUBLEVEL = 39
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
diff -u --recursive --new-file linux-2.0.38/arch/alpha/config.in linux-2.0.39/arch/alpha/config.in
--- linux-2.0.38/arch/alpha/config.in	Thu Jun  4 00:17:46 1998
+++ linux-2.0.39/arch/alpha/config.in	Thu Dec 30 00:08:26 1999
@@ -22,9 +22,9 @@
 comment 'Loadable module support'
 bool 'Enable loadable module support' CONFIG_MODULES
 if [ "$CONFIG_MODULES" = "y" ]; then
-  MODULES=y
-  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-  bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
+   MODULES=y
+   bool 'Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
 fi
 endmenu
 
@@ -32,9 +32,9 @@
 comment 'General setup'
 
 if [ "`uname`" != "Linux" ]; then
-  define_bool CONFIG_CROSSCOMPILE y
+   define_bool CONFIG_CROSSCOMPILE y
 else
-  define_bool CONFIG_NATIVE y
+   define_bool CONFIG_NATIVE y
 fi
 
 choice 'Alpha system type' \
@@ -61,72 +61,61 @@
 	 Ruffian	CONFIG_ALPHA_RUFFIAN		\
 	 Platform2000	CONFIG_ALPHA_P2K" Cabriolet
 
-if [ "$CONFIG_ALPHA_BOOK1" = "y" ]
-then
-	define_bool CONFIG_ALPHA_NONAME y
+if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then
+   define_bool CONFIG_ALPHA_NONAME y
 fi
 if [ "$CONFIG_ALPHA_NONAME" = "y" -o "$CONFIG_ALPHA_EB66" = "y" \
-	-o "$CONFIG_ALPHA_EB66P" = "y" -o "$CONFIG_ALPHA_P2K" = "y" ]
-then
-	define_bool CONFIG_PCI y
-	define_bool CONFIG_ALPHA_EV4 y
-	define_bool CONFIG_ALPHA_LCA y
+	-o "$CONFIG_ALPHA_EB66P" = "y" -o "$CONFIG_ALPHA_P2K" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_ALPHA_EV4 y
+   define_bool CONFIG_ALPHA_LCA y
 fi
 if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
-	-o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_XL" = "y" ]
-then
-	define_bool CONFIG_PCI y
-	define_bool CONFIG_ALPHA_EV4 y
-	define_bool CONFIG_ALPHA_APECS y
+	-o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_XL" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_ALPHA_EV4 y
+   define_bool CONFIG_ALPHA_APECS y
 fi
 if [ "$CONFIG_ALPHA_EB164" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
 	-o "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_XLT" = "y" \
-	-o "$CONFIG_ALPHA_TAKARA" = "y" ]
-then
-	define_bool CONFIG_PCI y
-	define_bool CONFIG_ALPHA_EV5 y
-	define_bool CONFIG_ALPHA_CIA y
-fi
-if [ "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" ]
-then
-	bool 'Pinnacle or Primo CPU daughtercard?' CONFIG_ALPHA_PRIMO
-	if [ "$CONFIG_ALPHA_PRIMO" = "y" ]
-	then
-		define_bool CONFIG_ALPHA_EV5 y
-		define_bool CONFIG_ALPHA_CIA y
-else
-		define_bool CONFIG_ALPHA_EV4 y
-		define_bool CONFIG_ALPHA_APECS y
-	fi
-	define_bool CONFIG_PCI y
-fi
-if [ "$CONFIG_ALPHA_SABLE" = "y" ]
-then
-	bool 'EV5 or EV56 CPU daughtercard?' CONFIG_ALPHA_GAMMA
-	if [ "$CONFIG_ALPHA_GAMMA" = "y" ]
-	then
-		define_bool CONFIG_ALPHA_EV5 y
-else
-		define_bool CONFIG_ALPHA_EV4 y
-	fi
-	define_bool CONFIG_PCI y
-	define_bool CONFIG_ALPHA_T2 y
+	-o "$CONFIG_ALPHA_TAKARA" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_ALPHA_EV5 y
+   define_bool CONFIG_ALPHA_CIA y
+fi
+if [ "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" ]; then
+   bool 'Pinnacle or Primo CPU daughtercard?' CONFIG_ALPHA_PRIMO
+   if [ "$CONFIG_ALPHA_PRIMO" = "y" ]; then
+      define_bool CONFIG_ALPHA_EV5 y
+      define_bool CONFIG_ALPHA_CIA y
+   else
+      define_bool CONFIG_ALPHA_EV4 y
+      define_bool CONFIG_ALPHA_APECS y
+   fi
+   define_bool CONFIG_PCI y
+fi
+if [ "$CONFIG_ALPHA_SABLE" = "y" ]; then
+   bool 'EV5 or EV56 CPU daughtercard?' CONFIG_ALPHA_GAMMA
+   if [ "$CONFIG_ALPHA_GAMMA" = "y" ]; then
+      define_bool CONFIG_ALPHA_EV5 y
+   else
+      define_bool CONFIG_ALPHA_EV4 y
+   fi
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_ALPHA_T2 y
 fi
 if [ "$CONFIG_ALPHA_MIATA" = "y" -o "$CONFIG_ALPHA_LX164" = "y" \
-	 -o "$CONFIG_ALPHA_SX164" = "y" -o "$CONFIG_ALPHA_RUFFIAN" = "y" ]
-then
-	define_bool CONFIG_PCI y
-	define_bool CONFIG_ALPHA_EV5 y
-	define_bool CONFIG_ALPHA_PYXIS y
-fi
-if [ "$CONFIG_ALPHA_JENSEN" = "y" ]
-then
-	define_bool CONFIG_ALPHA_EV4 y
-fi
-if [ "$CONFIG_ALPHA_EV4" = "y" ]
-then
-	# EV45 and older do not support all rounding modes in hw:
-	define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
+	 -o "$CONFIG_ALPHA_SX164" = "y" -o "$CONFIG_ALPHA_RUFFIAN" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_ALPHA_EV5 y
+   define_bool CONFIG_ALPHA_PYXIS y
+fi
+if [ "$CONFIG_ALPHA_JENSEN" = "y" ]; then
+   define_bool CONFIG_ALPHA_EV4 y
+fi
+if [ "$CONFIG_ALPHA_EV4" = "y" ]; then
+   # EV45 and older do not support all rounding modes in hw:
+   define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
 fi
 
 if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
@@ -134,39 +123,36 @@
 	-o "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_ALCOR" = "y" \
 	-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \
 	-o "$CONFIG_ALPHA_NORITAKE" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
-	-o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" ]
-then
-  bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM
-  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-    if [ "$CONFIG_ALPHA_SRM" = "y" ]; then
-      bool '  Use SRM PCI setup' CONFIG_ALPHA_SRM_SETUP
-    fi
-  fi
+	-o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" ]; then
+   bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      if [ "$CONFIG_ALPHA_SRM" = "y" ]; then
+	 bool '  Use SRM PCI setup (EXPERIMENTAL)' CONFIG_ALPHA_SRM_SETUP
+      fi
+   fi
 fi
 if [ "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
-	-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" ]
-then
-	define_bool CONFIG_ALPHA_EISA y
-fi
-if [ "$CONFIG_ALPHA_XL" = "y" ]
-then
-	define_bool CONFIG_ALPHA_AVANTI y
+    -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" ]; then
+   define_bool CONFIG_ALPHA_EISA y
+fi
+if [ "$CONFIG_ALPHA_XL" = "y" ]; then
+   define_bool CONFIG_ALPHA_AVANTI y
 fi
 
 bool 'Kernel GDB support' CONFIG_KGDB
 if [ "$CONFIG_KGDB" = "y" ]; then
-  bool 'Kernel tracing support?' CONFIG_KGDB_TRACING
+   bool '  Kernel tracing support' CONFIG_KGDB_TRACING
 fi
 
 bool 'Echo console messages on /dev/ttyS0 (COM1)' CONFIG_SERIAL_ECHO
 if [ "$CONFIG_PCI" = "y" ]; then
-  bool 'TGA Console Support' CONFIG_TGA_CONSOLE
-  if [ "$CONFIG_TGA_CONSOLE" = "y" ]; then
-    bool 'VGA Console Support' CONFIG_VGA_CONSOLE
-  fi
-  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-    bool 'PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
-  fi
+   bool 'TGA Console Support' CONFIG_TGA_CONSOLE
+   if [ "$CONFIG_TGA_CONSOLE" = "y" ]; then
+      bool '  VGA Console Support' CONFIG_VGA_CONSOLE
+   fi
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool 'PCI bridge optimization (EXPERIMENTAL)' CONFIG_PCI_OPTIMIZE
+   fi
 fi
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
@@ -178,7 +164,7 @@
 source drivers/block/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
-  source net/Config.in
+   source net/Config.in
 fi
 
 mainmenu_option next_comment
@@ -187,19 +173,19 @@
 tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
-  source drivers/scsi/Config.in
+   source drivers/scsi/Config.in
 fi
 endmenu
 
 if [ "$CONFIG_NET" = "y" ]; then
-  mainmenu_option next_comment
-  comment 'Network device support'
+   mainmenu_option next_comment
+   comment 'Network device support'
 
-  bool 'Network device support' CONFIG_NETDEVICES
-  if [ "$CONFIG_NETDEVICES" = "y" ]; then
-    source drivers/net/Config.in
-  fi
-  endmenu
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+   fi
+   endmenu
 fi
 
 mainmenu_option next_comment
@@ -207,7 +193,7 @@
 
 tristate 'ISDN support' CONFIG_ISDN
 if [ "$CONFIG_ISDN" != "n" ]; then
-  source drivers/isdn/Config.in
+   source drivers/isdn/Config.in
 fi
 endmenu
 
@@ -216,7 +202,7 @@
 
 bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
 if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-  source drivers/cdrom/Config.in
+   source drivers/cdrom/Config.in
 fi
 endmenu
 
@@ -229,7 +215,7 @@
 
 tristate 'Sound card support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
-  source drivers/sound/Config.in
+   source drivers/sound/Config.in
 fi
 endmenu
 
@@ -239,10 +225,10 @@
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Kernel profiling support' CONFIG_PROFILE
 if [ "$CONFIG_PROFILE" = "y" ]; then
-  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
 endmenu
 
 if [ "$CONFIG_TGA_CONSOLE" = "n" ]; then
-  define_bool CONFIG_VGA_CONSOLE y
+   define_bool CONFIG_VGA_CONSOLE y
 fi
diff -u --recursive --new-file linux-2.0.38/arch/i386/config.in linux-2.0.39/arch/i386/config.in
--- linux-2.0.38/arch/i386/config.in	Thu Aug 26 00:08:27 1999
+++ linux-2.0.39/arch/i386/config.in	Wed Dec 29 13:54:15 1999
@@ -13,8 +13,8 @@
 comment 'Loadable module support'
 bool 'Enable loadable module support' CONFIG_MODULES
 if [ "$CONFIG_MODULES" = "y" ]; then
-  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-  bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
 fi
 endmenu
 
@@ -28,27 +28,27 @@
 	 Custom		CONFIG_MEM_SPECIAL" Standard
 
 if [ "$CONFIG_MEM_SPECIAL" = "y" ]; then
-	int ' Max physical memory in MB (must be a multiple of 4)' CONFIG_MAX_MEMSIZE 1024
+   int ' Max physical memory in MB (must be a multiple of 4)' CONFIG_MAX_MEMSIZE 1024
 fi
 if [ "$CONFIG_MEM_ENT" = "y" ]; then
-	define_int CONFIG_MAX_MEMSIZE 2048
+   define_int CONFIG_MAX_MEMSIZE 2048
 fi
 if [ "$CONFIG_MEM_STD" = "y" ]; then
-	define_int CONFIG_MAX_MEMSIZE 1024
+   define_int CONFIG_MAX_MEMSIZE 1024
 fi
 bool 'Networking support' CONFIG_NET
 bool 'Limit memory to low 16MB' CONFIG_MAX_16M
 bool 'PCI bios support' CONFIG_PCI
 if [ "$CONFIG_PCI" = "y" ]; then
-  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-    bool '   PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
-  fi
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool '  PCI bridge optimization (EXPERIMENTAL)' CONFIG_PCI_OPTIMIZE
+   fi
 fi
 bool 'System V IPC' CONFIG_SYSVIPC
 tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
+   tristate 'Kernel support for JAVA binaries (EXPERIMENTAL)' CONFIG_BINFMT_JAVA
 fi
 bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
 
@@ -60,17 +60,17 @@
 
 # Conditionally compile MTRR manipulation support
 if [ "$CONFIG_M686" = "y" -o "$CONFIG_M586" = "y" ]; then
-  bool 'Handle buggy SMP BIOSes with bad MTRR setup' CONFIG_MTRR
+   bool 'Handle buggy SMP BIOSes with bad MTRR setup' CONFIG_MTRR
 fi
 
 bool 'Advanced Power Management BIOS support' CONFIG_APM
 if [ "$CONFIG_APM" = "y" ]; then
-  bool '   Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND
-  bool '   Enable PM at boot time' CONFIG_APM_DO_ENABLE
-  bool '   Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
-  bool '   Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
-  bool '   Power off on shutdown' CONFIG_APM_POWER_OFF
-  bool '   Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
+   bool '  Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND
+   bool '  Enable PM at boot time' CONFIG_APM_DO_ENABLE
+   bool '  Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
+   bool '  Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
+   bool '  Power off on shutdown' CONFIG_APM_POWER_OFF
+   bool '  Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
 fi
 
 endmenu
@@ -78,7 +78,7 @@
 source drivers/block/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
-  source net/Config.in
+   source net/Config.in
 fi
 
 mainmenu_option next_comment
@@ -87,19 +87,19 @@
 tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
-  source drivers/scsi/Config.in
+   source drivers/scsi/Config.in
 fi
 endmenu
 
 if [ "$CONFIG_NET" = "y" ]; then
-  mainmenu_option next_comment
-  comment 'Network device support'
+   mainmenu_option next_comment
+   comment 'Network device support'
 
-  bool 'Network device support' CONFIG_NETDEVICES
-  if [ "$CONFIG_NETDEVICES" = "y" ]; then
-    source drivers/net/Config.in
-  fi
-  endmenu
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+   fi
+   endmenu
 fi
 
 mainmenu_option next_comment
@@ -107,7 +107,7 @@
 
 tristate 'ISDN support' CONFIG_ISDN
 if [ "$CONFIG_ISDN" != "n" ]; then
-  source drivers/isdn/Config.in
+   source drivers/isdn/Config.in
 fi
 endmenu
 
@@ -116,7 +116,7 @@
 
 bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
 if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-  source drivers/cdrom/Config.in
+   source drivers/cdrom/Config.in
 fi
 endmenu
 
@@ -129,7 +129,7 @@
 
 tristate 'Sound card support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
-  source drivers/sound/Config.in
+   source drivers/sound/Config.in
 fi
 endmenu
 
@@ -139,6 +139,6 @@
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Kernel profiling support' CONFIG_PROFILE
 if [ "$CONFIG_PROFILE" = "y" ]; then
-  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
 endmenu
diff -u --recursive --new-file linux-2.0.38/arch/m68k/config.in linux-2.0.39/arch/m68k/config.in
--- linux-2.0.38/arch/m68k/config.in	Mon May 20 06:54:26 1996
+++ linux-2.0.39/arch/m68k/config.in	Thu Dec 30 01:54:06 1999
@@ -8,8 +8,8 @@
 comment 'Loadable module support'
 bool 'Enable loadable module support' CONFIG_MODULES
 if [ "$CONFIG_MODULES" = "y" ]; then
-  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-  bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
 fi
 endmenu
 
@@ -17,6 +17,9 @@
 comment 'General setup'
 
 bool 'Amiga support' CONFIG_AMIGA
+if [ "$CONFIG_AMIGA" = "y" ]; then
+   bool '  Amiga AutoConfig Identification' CONFIG_ZORRO
+fi
 bool 'Atari support' CONFIG_ATARI
 bool 'Macintosh support' CONFIG_MAC
 bool '68040 floating point software package' CONFIG_FPSP_040
@@ -26,10 +29,7 @@
 tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 if [ "$CONFIG_BINFMT_ELF" = "y" ]; then
-  bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
-fi
-if [ "$CONFIG_AMIGA" = "y" ]; then
-  bool 'Amiga AutoConfig Identification' CONFIG_ZORRO
+   bool '  Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
 fi
 endmenu
 
@@ -42,23 +42,23 @@
 tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD
 bool 'IDE harddisk support' CONFIG_BLK_DEV_IDE
 if [ "$CONFIG_AMIGA" = "y" ]; then
-bool 'Amiga Cybervision support' CONFIG_FB_CYBER
-bool 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM
+   bool 'Amiga Cybervision support' CONFIG_FB_CYBER
+   bool 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
-bool 'Atari ACSI support' CONFIG_ATARI_ACSI
+   bool 'Atari ACSI support' CONFIG_ATARI_ACSI
 fi
 
 tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
 if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
-  bool '   Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
+   bool '  Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
 fi
 
 tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
 endmenu
 
 if [ "$CONFIG_NET" = "y" ]; then
-  source net/Config.in
+   source net/Config.in
 fi
 
 mainmenu_option next_comment
@@ -67,32 +67,31 @@
 tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
+   comment 'SCSI support type (disk, tape, CDrom)'
 
-comment 'SCSI support type (disk, tape, CDrom)'
-
-dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
-dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
-dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
-dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
-
-comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
-
-bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
-
-bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
-
-mainmenu_option next_comment
-comment 'SCSI low-level drivers'
-
-if [ "$CONFIG_AMIGA" = "y" ]; then
-bool 'A3000 WD33C93A support' CONFIG_A3000_SCSI
-bool 'A2091 WD33C93A support' CONFIG_A2091_SCSI
-bool 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
-fi
-if [ "$CONFIG_ATARI" = "y" ]; then
-dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI
-fi
-#dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI
+   dep_tristate '  SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
+   dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
+   dep_tristate '  SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
+   dep_tristate '  SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
+
+   comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+
+   bool '  Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
+
+   bool '  Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
+
+   mainmenu_option next_comment
+   comment 'SCSI low-level drivers'
+
+  if [ "$CONFIG_AMIGA" = "y" ]; then
+     bool 'A3000 WD33C93A support' CONFIG_A3000_SCSI
+     bool 'A2091 WD33C93A support' CONFIG_A2091_SCSI
+     bool 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
+  fi
+  if [ "$CONFIG_ATARI" = "y" ]; then
+     dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI
+  fi
+  #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI
 endmenu
 
 fi
@@ -105,27 +104,27 @@
 
 bool 'Network device support' CONFIG_NETDEVICES
 if [ "$CONFIG_NETDEVICES" = "y" ]; then
-#
-# Network device configuration
-#
-tristate 'Dummy net driver support' CONFIG_DUMMY
-tristate 'SLIP (serial line) support' CONFIG_SLIP
-if [ "$CONFIG_SLIP" != "n" ]; then
-  bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
-fi
-tristate 'PPP (point-to-point) support' CONFIG_PPP
-if [ ! "$CONFIG_PPP" = "n" ]; then
-  comment 'CCP compressors for PPP are only built as modules.'
-fi
-tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
-if [ "$CONFIG_AMIGA" = "y" ]; then
-  tristate 'Ariadne support' CONFIG_ARIADNE
-  tristate 'A2065 support' CONFIG_A2065
-  tristate 'Hydra support' CONFIG_HYDRA
-fi
-if [ "$CONFIG_ATARI" = "y" ]; then
-  bool 'Atari Lance support' CONFIG_ATARILANCE
-fi
+   #
+   # Network device configuration
+   #
+   tristate '  Dummy net driver support' CONFIG_DUMMY
+   tristate '  SLIP (serial line) support' CONFIG_SLIP
+   if [ "$CONFIG_SLIP" != "n" ]; then
+      bool '    CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
+   fi
+   tristate '  PPP (point-to-point) support' CONFIG_PPP
+   if [ ! "$CONFIG_PPP" = "n" ]; then
+      comment 'CCP compressors for PPP are only built as modules.'
+   fi
+   tristate '  EQL (serial line load balancing) support' CONFIG_EQUALIZER
+   if [ "$CONFIG_AMIGA" = "y" ]; then
+      tristate '  Ariadne support' CONFIG_ARIADNE
+      tristate '  A2065 support' CONFIG_A2065
+      tristate '  Hydra support' CONFIG_HYDRA
+   fi
+   if [ "$CONFIG_ATARI" = "y" ]; then
+      bool '  Atari Lance support' CONFIG_ATARILANCE
+   fi
 fi
 endmenu
 
@@ -138,26 +137,26 @@
 
 bool 'Parallel printer support' CONFIG_PRINTER
 if [ "$CONFIG_AMIGA" = "y" ]; then
-  tristate 'Amiga mouse support' CONFIG_AMIGAMOUSE
+   tristate 'Amiga mouse support' CONFIG_AMIGAMOUSE
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
-  tristate 'Atari mouse support' CONFIG_ATARIMOUSE
+   tristate 'Atari mouse support' CONFIG_ATARIMOUSE
 fi
 if [ "$CONFIG_ATARI" = y ]; then
-  tristate 'Atari MFP serial support' CONFIG_ATARI_MFPSER
-  tristate 'Atari SCC serial support' CONFIG_ATARI_SCC
-  tristate 'Atari MIDI serial support' CONFIG_ATARI_MIDI
+   tristate 'Atari MFP serial support' CONFIG_ATARI_MFPSER
+   tristate 'Atari SCC serial support' CONFIG_ATARI_SCC
+   tristate 'Atari MIDI serial support' CONFIG_ATARI_MIDI
 fi
 if [ "$CONFIG_AMIGA" = y ]; then
-  tristate 'Amiga builtin serial support' CONFIG_AMIGA_BUILTIN_SERIAL
-  bool 'GVP IO-Extender support' CONFIG_GVPIOEXT
-  tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
+   tristate 'Amiga builtin serial support' CONFIG_AMIGA_BUILTIN_SERIAL
+   bool 'GVP IO-Extender support' CONFIG_GVPIOEXT
+   tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
 fi
 bool 'Support for user serial device modules' CONFIG_USERIAL
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
-  bool '   Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
-  bool '   Software Watchdog' CONFIG_SOFT_WATCHDOG
+   bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
+   bool '  Software Watchdog' CONFIG_SOFT_WATCHDOG
 fi
 bool 'Support for user misc device modules' CONFIG_UMISC
 endmenu
@@ -167,7 +166,7 @@
 
 bool 'Sound support' CONFIG_SOUND y
 if [ "$CONFIG_SOUND" != "n" ]; then
-  bool 'Amiga or Atari DMA sound support' CONFIG_DMASOUND y
+   bool '  Amiga or Atari DMA sound support' CONFIG_DMASOUND y
 fi
 endmenu
 
@@ -177,6 +176,6 @@
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Kernel profiling support' CONFIG_PROFILE
 if [ "$CONFIG_PROFILE" = "y" ]; then
-  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
 endmenu
diff -u --recursive --new-file linux-2.0.38/arch/mips/config.in linux-2.0.39/arch/mips/config.in
--- linux-2.0.38/arch/mips/config.in	Sun May  5 08:05:58 1996
+++ linux-2.0.39/arch/mips/config.in	Thu Dec 30 01:57:14 1999
@@ -17,7 +17,7 @@
 if [ "$CONFIG_ACER_PICA_61" = "y" -o \
      "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
      "$CONFIG_OLIVETTI_M700" = "y" ]; then
-	define_bool CONFIG_MIPS_JAZZ y
+   define_bool CONFIG_MIPS_JAZZ y
 fi
 
 choice 'CPU type' \
@@ -32,35 +32,35 @@
      "$CONFIG_CPU_R4X00" = "y" -o \
      "$CONFIG_CPU_R4600" = "y" -o \
      "$CONFIG_CPU_R8000" = "y" ]; then
-	define_bool CONFIG_TLB_SHUTDOWN y
+   define_bool CONFIG_TLB_SHUTDOWN y
 fi
 
 define_bool CONFIG_BINFMT_ELF y
 define_bool CONFIG_BINFMT_AOUT y
 bool 'Compile the kernel into the ELF object format' CONFIG_ELF_KERNEL
 if [ "$CONFIG_ELF_KERNEL" = "y" ]; then
-  bool 'Is your ELF compiler an extra compiler' CONFIG_EXTRA_ELF_COMPILER
+   bool '  Is your ELF compiler an extra compiler' CONFIG_EXTRA_ELF_COMPILER
 fi
 bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
 bool 'Networking support' CONFIG_NET
 #bool 'PCI bios support' CONFIG_PCI
 #if [ "$CONFIG_PCI" = "y" ]; then
-#  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-#    bool '   PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
-#  fi
+#   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+#      bool '  PCI bridge optimization (EXPERIMENTAL)' CONFIG_PCI_OPTIMIZE
+#   fi
 #fi
 bool 'System V IPC' CONFIG_SYSVIPC
 endmenu
 
 mainmenu_option next_comment
 comment 'Loadable module support'
-bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+bool 'Set version information on all module symbols' CONFIG_MODVERSIONS
 endmenu
 
 source drivers/block/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
-  source net/Config.in
+   source net/Config.in
 fi
 
 mainmenu_option next_comment
@@ -69,19 +69,19 @@
 tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
-  source drivers/scsi/Config.in
+   source drivers/scsi/Config.in
 fi
 endmenu
 
 if [ "$CONFIG_NET" = "y" ]; then
-  mainmenu_option next_comment
-  comment 'Network device support'
+   mainmenu_option next_comment
+   comment 'Network device support'
 
-  bool 'Network device support' CONFIG_NETDEVICES
-  if [ "$CONFIG_NETDEVICES" = "y" ]; then
-    source drivers/net/Config.in
-  fi
-  endmenu
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+   fi
+   endmenu
 fi
 
 mainmenu_option next_comment
@@ -89,7 +89,7 @@
 
 bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
 if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-  source drivers/cdrom/Config.in
+   source drivers/cdrom/Config.in
 fi
 endmenu
 
@@ -103,7 +103,7 @@
 
 tristate 'Sound card support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
-  source drivers/sound/Config.in
+   source drivers/sound/Config.in
 fi
 endmenu
 
@@ -113,6 +113,6 @@
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Kernel profiling support' CONFIG_PROFILE
 if [ "$CONFIG_PROFILE" = "y" ]; then
-  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
 endmenu
diff -u --recursive --new-file linux-2.0.38/arch/ppc/config.in linux-2.0.39/arch/ppc/config.in
--- linux-2.0.38/arch/ppc/config.in	Mon May 27 11:00:57 1996
+++ linux-2.0.39/arch/ppc/config.in	Thu Dec 30 01:58:56 1999
@@ -13,8 +13,8 @@
 comment 'Loadable module support'
 bool 'Enable loadable module support' CONFIG_MODULES
 if [ "$CONFIG_MODULES" = "y" ]; then
-  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-  bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
 fi
 endmenu
 
@@ -26,22 +26,22 @@
 bool 'Limit memory to low 16MB' CONFIG_MAX_16M
 bool 'PCI bios support' CONFIG_PCI
 if [ "$CONFIG_PCI" = "y" ]; then
-  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-    bool '   PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
-  fi
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool '  PCI bridge optimization (EXPERIMENTAL)' CONFIG_PCI_OPTIMIZE
+   fi
 fi
 bool 'System V IPC' CONFIG_SYSVIPC
 tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
 tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 if [ "$CONFIG_BINFMT_ELF" = "y" ]; then
-  bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
+   bool '  Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
 fi
 
 source drivers/block/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
-  source net/Config.in
+   source net/Config.in
 fi
 
 mainmenu_option next_comment
@@ -50,19 +50,19 @@
 tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
-  source drivers/scsi/Config.in
+   source drivers/scsi/Config.in
 fi
 endmenu
 
 if [ "$CONFIG_NET" = "y" ]; then
-  mainmenu_option next_comment
-  comment 'Network device support'
+   mainmenu_option next_comment
+   comment 'Network device support'
 
-  bool 'Network device support' CONFIG_NETDEVICES
-  if [ "$CONFIG_NETDEVICES" = "y" ]; then
-    source drivers/net/Config.in
-  fi
-  endmenu
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+   fi
+   endmenu
 fi
 
 mainmenu_option next_comment
@@ -70,7 +70,7 @@
 
 tristate 'ISDN support' CONFIG_ISDN
 if [ "$CONFIG_ISDN" != "n" ]; then
-  source drivers/isdn/Config.in
+   source drivers/isdn/Config.in
 fi
 endmenu
 
@@ -79,7 +79,7 @@
 
 bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
 if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-  source drivers/cdrom/Config.in
+   source drivers/cdrom/Config.in
 fi
 endmenu
 
@@ -92,7 +92,7 @@
 
 tristate 'Sound card support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
-  source drivers/sound/Config.in
+   source drivers/sound/Config.in
 fi
 endmenu
 
@@ -102,6 +102,6 @@
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Kernel profiling support' CONFIG_PROFILE
 if [ "$CONFIG_PROFILE" = "y" ]; then
-  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
 endmenu
diff -u --recursive --new-file linux-2.0.38/arch/sparc/config.in linux-2.0.39/arch/sparc/config.in
--- linux-2.0.38/arch/sparc/config.in	Mon Jul 13 22:47:27 1998
+++ linux-2.0.39/arch/sparc/config.in	Thu Dec 30 02:02:58 1999
@@ -10,16 +10,16 @@
 bool 'Support for AP1000 multicomputer' CONFIG_AP1000
 
 if [ "$CONFIG_AP1000" = "n" ]; then
-	# Global things across all Sun machines.
-	define_bool CONFIG_SBUS y
-	define_bool CONFIG_SBUSCHAR y
-	define_bool CONFIG_SUN_MOUSE y
-	define_bool CONFIG_SERIAL y
-	define_bool CONFIG_SUN_SERIAL y
-	define_bool CONFIG_SUN_KEYBOARD y
-	define_bool CONFIG_SUN_CONSOLE y
-	define_bool CONFIG_SUN_AUXIO y
-	define_bool CONFIG_SUN_IO y
+   # Global things across all Sun machines.
+   define_bool CONFIG_SBUS y
+   define_bool CONFIG_SBUSCHAR y
+   define_bool CONFIG_SUN_MOUSE y
+   define_bool CONFIG_SERIAL y
+   define_bool CONFIG_SUN_SERIAL y
+   define_bool CONFIG_SUN_KEYBOARD y
+   define_bool CONFIG_SUN_CONSOLE y
+   define_bool CONFIG_SUN_AUXIO y
+   define_bool CONFIG_SUN_IO y
 fi
 
 define_bool CONFIG_NET_ALIAS n
@@ -38,21 +38,21 @@
 
 bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
 if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
-  tristate '   Linear (append) mode' CONFIG_MD_LINEAR
-  tristate '   RAID-0 (striping) mode' CONFIG_MD_STRIPED
-  tristate '   RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
-  tristate '   RAID-4/RAID-5 mode' CONFIG_MD_RAID5
+   tristate '  Linear (append) mode' CONFIG_MD_LINEAR
+   tristate '  RAID-0 (striping) mode' CONFIG_MD_STRIPED
+   tristate '  RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
+   tristate '  RAID-4/RAID-5 mode' CONFIG_MD_RAID5
 fi
 
 tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
 if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
-  bool '   Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
+   bool '  Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
 fi
 
 tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
 
 if [ "$CONFIG_NET" = "y" ]; then
-	source net/Config.in
+   source net/Config.in
 fi
 
 mainmenu_option next_comment
@@ -61,45 +61,45 @@
 tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
-	comment 'SCSI support type (disk, tape, CDrom)'
+   comment 'SCSI support type (disk, tape, CDrom)'
 
-	dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
-	dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
-	dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
-	dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
+   dep_tristate '  SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
+   dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
+   dep_tristate '  SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
+   dep_tristate '  SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
 
-	comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+   comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
 
-	bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
+   bool '  Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
 
-	bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
+   bool '  Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
 
-	mainmenu_option next_comment
-	comment 'SCSI low-level drivers'
+   mainmenu_option next_comment
+   comment 'SCSI low-level drivers'
 
-	dep_tristate 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI
+   dep_tristate 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI
 fi
 endmenu
 
 if [ "$CONFIG_NET" = "y" ]; then
-	mainmenu_option next_comment
-	comment 'Network device support'
+   mainmenu_option next_comment
+   comment 'Network device support'
 
-	bool 'Network device support' CONFIG_NETDEVICES
-	if [ "$CONFIG_NETDEVICES" = "y" ]; then
-		tristate 'Dummy net driver support' CONFIG_DUMMY
-		tristate 'SLIP (serial line) support' CONFIG_SLIP
-		if [ "$CONFIG_SLIP" != "n" ]; then
-		  bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
-		  bool ' Keepalive and linefill' CONFIG_SLIP_SMART
-		fi
-		tristate 'PPP (point-to-point) support' CONFIG_PPP
-		if [ ! "$CONFIG_PPP" = "n" ]; then
-		  comment 'CCP compressors for PPP are only built as modules.'
-		fi
-		bool 'Sun LANCE support' CONFIG_SUNLANCE
-	fi
-	endmenu
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      tristate '  Dummy net driver support' CONFIG_DUMMY
+      tristate '  SLIP (serial line) support' CONFIG_SLIP
+      if [ "$CONFIG_SLIP" != "n" ]; then
+	 bool '    CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
+	 bool '    Keepalive and linefill' CONFIG_SLIP_SMART
+      fi
+      tristate '  PPP (point-to-point) support' CONFIG_PPP
+      if [ ! "$CONFIG_PPP" = "n" ]; then
+         comment 'CCP compressors for PPP are only built as modules.'
+      fi
+      bool '  Sun LANCE support' CONFIG_SUNLANCE
+   fi
+   endmenu
 fi
 
 source fs/Config.in
@@ -109,5 +109,5 @@
 
 bool 'Kernel profiling support' CONFIG_PROFILE
 if [ "$CONFIG_PROFILE" = "y" ]; then
-	int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
diff -u --recursive --new-file linux-2.0.38/drivers/block/Config.in linux-2.0.39/drivers/block/Config.in
--- linux-2.0.38/drivers/block/Config.in	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/block/Config.in	Thu Dec 30 19:10:33 1999
@@ -8,40 +8,40 @@
 bool 'Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support' CONFIG_BLK_DEV_IDE
 comment 'Please see Documentation/ide.txt for help/info on IDE drives'
 if [ "$CONFIG_BLK_DEV_IDE" = "n" ]; then
-  bool 'Old harddisk (MFM/RLL/IDE) driver' CONFIG_BLK_DEV_HD_ONLY
+   bool 'Old harddisk (MFM/RLL/IDE) driver' CONFIG_BLK_DEV_HD_ONLY
 else
-  bool '   Use old disk-only driver on primary interface' CONFIG_BLK_DEV_HD_IDE
-  if [ "$CONFIG_BLK_DEV_HD_IDE" != "n" ]; then
-    bool '     Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE
-  fi
-  bool '   Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD
-  bool '   Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE
-  bool '   Include IDE/ATAPI FLOPPY support (new)' CONFIG_BLK_DEV_IDEFLOPPY
-  bool '   SCSI emulation support' CONFIG_BLK_DEV_IDESCSI
-  bool '   Support removable IDE interfaces (PCMCIA)' CONFIG_BLK_DEV_IDE_PCMCIA
-  bool '   CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640
-  if [ "$CONFIG_BLK_DEV_CMD640" = "y" ]; then
-    bool '     CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED
-  fi
-  if [ "$CONFIG_PCI" = "y" ]; then
-    bool '   RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000
-    bool '   Intel 82371 PIIX (Triton I/II) DMA support' CONFIG_BLK_DEV_TRITON
-    if [ "$CONFIG_BLK_DEV_TRITON" = "y" ]; then
-      bool '     Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
-    fi
-  fi
-  bool '   Other IDE chipset support' CONFIG_IDE_CHIPSETS
-  if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
-    comment 'Note: most of these also require special kernel boot parameters'
-    bool '      ALI M14xx       support' CONFIG_BLK_DEV_ALI14XX
-    bool '      DTC-2278        support' CONFIG_BLK_DEV_DTC2278
-    bool '      Holtek HT6560B  support' CONFIG_BLK_DEV_HT6560B
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      bool '      PROMISE DC4030  support (EXPERIMENTAL)' CONFIG_BLK_DEV_PROMISE
-    fi
-    bool '      QDI QD6580      support' CONFIG_BLK_DEV_QD6580
-    bool '      UMC 8672        support' CONFIG_BLK_DEV_UMC8672
-  fi
+   bool '  Use old disk-only driver on primary interface' CONFIG_BLK_DEV_HD_IDE
+   if [ "$CONFIG_BLK_DEV_HD_IDE" != "n" ]; then
+      bool '    Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE
+   fi
+   bool '  Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD
+   bool '  Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE
+   bool '  Include IDE/ATAPI FLOPPY support (new)' CONFIG_BLK_DEV_IDEFLOPPY
+   bool '  SCSI emulation support' CONFIG_BLK_DEV_IDESCSI
+   bool '  Support removable IDE interfaces (PCMCIA)' CONFIG_BLK_DEV_IDE_PCMCIA
+   bool '  CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640
+   if [ "$CONFIG_BLK_DEV_CMD640" = "y" ]; then
+      bool '    CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED
+   fi
+   if [ "$CONFIG_PCI" = "y" ]; then
+      bool '  RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000
+      bool '  Intel 82371 PIIX (Triton I/II) DMA support' CONFIG_BLK_DEV_TRITON
+      if [ "$CONFIG_BLK_DEV_TRITON" = "y" ]; then
+	 bool '    Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
+      fi
+   fi
+   bool '  Other IDE chipset support' CONFIG_IDE_CHIPSETS
+   if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
+      comment 'Note: most of these also require special kernel boot parameters'
+      bool '    ALI M14xx       support' CONFIG_BLK_DEV_ALI14XX
+      bool '    DTC-2278        support' CONFIG_BLK_DEV_DTC2278
+      bool '    Holtek HT6560B  support' CONFIG_BLK_DEV_HT6560B
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	 bool '    PROMISE DC4030  support (EXPERIMENTAL)' CONFIG_BLK_DEV_PROMISE
+      fi
+      bool '    QDI QD6580      support' CONFIG_BLK_DEV_QD6580
+      bool '    UMC 8672        support' CONFIG_BLK_DEV_UMC8672
+   fi
 fi
 
 comment 'Additional Block Devices'
@@ -49,35 +49,35 @@
 tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
 bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
 if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
-  tristate '   Linear (append) mode' CONFIG_MD_LINEAR
-  tristate '   RAID-0 (striping) mode' CONFIG_MD_STRIPED
-  tristate '   RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
-  tristate '   RAID-4/RAID-5 mode' CONFIG_MD_RAID5
+   tristate '  Linear (append) mode' CONFIG_MD_LINEAR
+   tristate '  RAID-0 (striping) mode' CONFIG_MD_STRIPED
+   tristate '  RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
+   tristate '  RAID-4/RAID-5 mode' CONFIG_MD_RAID5
 fi
 tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
 if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
-  bool '   Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
+   bool '  Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
 fi
 tristate 'XT harddisk support' CONFIG_BLK_DEV_XD
 if [ "$CONFIG_PCI" = "y" ]; then
-  bool 'Mylex DAC960 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960
+   bool 'Mylex DAC960 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960
 fi
 
 tristate 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA
 if [ "$CONFIG_BLK_CPQ_DA" = "y" -o "$CONFIG_BLK_CPQ_DA" = "m" ]; then
-  bool '   Support for PCI SMART-2 Controllers' CONFIG_BLK_CPQ_DA_PCI
-  bool '   Support for EISA SMART-2 Controllers' CONFIG_BLK_CPQ_DA_EISA
+   bool '  Support for PCI SMART-2 Controllers' CONFIG_BLK_CPQ_DA_PCI
+   bool '  Support for EISA SMART-2 Controllers' CONFIG_BLK_CPQ_DA_EISA
 fi
 
 tristate 'Parallel port IDE device support' CONFIG_PARIDE 
 if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then
-  source drivers/block/paride/Config.in
+   source drivers/block/paride/Config.in
 fi
 
 if [ "$CONFIG_BLK_DEV_HD_IDE" = "y" -o "$CONFIG_BLK_DEV_HD_ONLY" = "y" ]; then
-  define_bool CONFIG_BLK_DEV_HD y
+   define_bool CONFIG_BLK_DEV_HD y
 else
-  define_bool CONFIG_BLK_DEV_HD n
+   define_bool CONFIG_BLK_DEV_HD n
 fi
 
 endmenu
diff -u --recursive --new-file linux-2.0.38/drivers/block/genhd.c linux-2.0.39/drivers/block/genhd.c
--- linux-2.0.38/drivers/block/genhd.c	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/block/genhd.c	Wed Jun 28 14:48:19 2000
@@ -76,6 +76,10 @@
 	 * This requires special handling here.
 	 */
 	switch (hd->major) {
+		case IDE5_MAJOR:
+			unit += 2;
+		case IDE4_MAJOR:
+			unit += 2;
 		case IDE3_MAJOR:
 			unit += 2;
 		case IDE2_MAJOR:
@@ -158,6 +162,8 @@
 	struct partition *p;
 	unsigned long first_sector, first_size, this_sector, this_size;
 	int mask = (1 << hd->minor_shift) - 1;
+	int loopct = 0;		/* number of links followed
+				   without finding a data partition */
 	int i;
 
 	first_sector = hd->part[MINOR(dev)].start_sect;
@@ -165,6 +171,8 @@
 	this_sector = first_sector;
 
 	while (1) {
+		if (++loopct > 100)
+			return;
 		if ((current_minor & mask) == 0)
 			return;
 		if (!(bh = bread(dev,0,1024)))
@@ -209,6 +217,7 @@
 
 		    add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
 		    current_minor++;
+		    loopct = 0;
 		    if ((current_minor & mask) == 0)
 		      goto done;
 		}
diff -u --recursive --new-file linux-2.0.38/drivers/block/ide.c linux-2.0.39/drivers/block/ide.c
--- linux-2.0.38/drivers/block/ide.c	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/block/ide.c	Wed Sep  6 23:42:53 2000
@@ -283,6 +283,10 @@
  *			to trition.c and added UDMA to current DMA support.
  *			update Promise Ultra33 and added AEC6210U/UF UDMA cards.
  *			add configuration flag to allow booting of either card.
+ * Version 5.53.5	Fixed chipset identifiers.
+ * Version 5.53.6	Added Aladdin IV/V M5229 chipset support.
+ * Version 5.53.7	Added HPT343 basic support with everything at PIO 0.
+ *			This is regardless of DMA capabilties.
  *
  *  Some additional driver compile-time options are in ide.h
  *
@@ -328,9 +332,9 @@
 #define IS_PROMISE_DRIVE (0)	/* auto-NULLs out Promise code */
 #endif /* CONFIG_BLK_DEV_PROMISE */
 
-static const byte	ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
-static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168};
-static const byte	default_irqs[MAX_HWIFS]     = {14, 15, 11, 10};
+static const byte	ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR};
+static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160};
+static const byte	default_irqs[MAX_HWIFS]     = {14, 15, 11, 10, 8, 12};
 static int	idebus_parameter; /* holds the "idebus=" parameter */
 static int	system_bus_speed; /* holds what we think is VESA/PCI bus speed */
 
@@ -606,6 +610,9 @@
  *
  * Returns:	1 if lba_capacity looks sensible
  *		0 otherwise
+ *
+ * Note: we must not change id->cyls here, otherwise a second call
+ * of this routine might no longer find lba_capacity ok.
  */
 static int lba_capacity_is_ok (struct hd_driveid *id)
 {
@@ -614,14 +621,15 @@
 	unsigned long _10_percent = chs_sects / 10;
 
 	/*
-	 * very large drives (8GB+) may lie about the number of cylinders
-	 * This is a split test for drives 8 Gig and Bigger only.
+	 * The ATA spec tells large drives to return
+	 * C/H/S = 16383/16/63 independent of their size.
+	 * Some drives can be jumpered to use 15 heads instead of 16.
 	 */
-	if ((id->lba_capacity >= 16514064) && (id->cyls == 0x3fff) &&
-	    (id->heads == 16) && (id->sectors == 63)) {
-		id->cyls = lba_sects / (16 * 63); /* correct cyls */
+	if (id->cyls == 16383 && id->sectors == 63 &&
+	    (id->heads == 15 || id->heads == 16) &&
+	    id->lba_capacity >= 16383*63*id->heads)
 		return 1;	/* lba_capacity is our only option */
-	}
+
 	/* perform a rough sanity check on lba_sects:  within 10% is "okay" */
 	if ((lba_sects - chs_sects) < _10_percent)
 		return 1;	/* lba_capacity is good */
@@ -638,11 +646,13 @@
 /*
  * current_capacity() returns the capacity (in sectors) of a drive
  * according to its current geometry/LBA settings.
+ *
+ * It also sets select.b.lba.
  */
 static unsigned long current_capacity (ide_drive_t  *drive)
 {
 	struct hd_driveid *id = drive->id;
-	unsigned long capacity = drive->cyl * drive->head * drive->sect;
+	unsigned long capacity;
 
 	if (!drive->present)
 		return 0;
@@ -652,22 +662,14 @@
 #endif /* CONFIG_BLK_DEV_IDEFLOPPY */
 	if (drive->media != ide_disk)
 		return 0x7fffffff;	/* cdrom or tape */
+
 	drive->select.b.lba = 0;
 	/* Determine capacity, and use LBA if the drive properly supports it */
+	capacity = drive->cyl * drive->head * drive->sect;
 	if (id != NULL && (id->capability & 2) && lba_capacity_is_ok(id)) {
 		if (id->lba_capacity >= capacity) {
-			drive->cyl = id->lba_capacity / (drive->head * drive->sect);
 			capacity = id->lba_capacity;
 			drive->select.b.lba = 1;
-#if 0
-			/*
-			 * This is the correct place to perform this task;
-			 * however, we do this later for reporting.
-			 */
-			if (*(int *)&id->cur_capacity0 != id->lba_capacity) {
-				*(int *)&id->cur_capacity0 = id->lba_capacity;
-			}
-#endif
 		}
 	}
 	return (capacity - drive->sect0);
@@ -697,8 +699,9 @@
 			idefloppy_setup(drive);
 #endif /* CONFIG_BLK_DEV_IDEFLOPPY */
 		drive->part[0].nr_sects = current_capacity(drive);
-		if (!drive->present || (drive->media != ide_disk && drive->media != ide_floppy) ||
-		    !drive->part[0].nr_sects) {
+		if (!drive->present
+		    || (drive->media != ide_disk && drive->media != ide_floppy)
+		    || !drive->part[0].nr_sects) {
 			drive->part[0].start_sect = -1; /* skip partition check */
 		}
 	}
@@ -1597,11 +1600,16 @@
 		goto kill_rq;
 	}
 	block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0;
+
 #if FAKE_FDISK_FOR_EZDRIVE
+	/* Yecch - this will shift the entire interval,
+	   possibly killing some innocent following sector */
 	if (block == 0 && drive->remap_0_to_1)
 		block = 1;  /* redirect MBR access to EZ-Drive partn table */
 #endif /* FAKE_FDISK_FOR_EZDRIVE */
+
 	((ide_hwgroup_t *)hwif->hwgroup)->drive = drive;
+
 #if (DISK_RECOVERY_TIME > 0)
 	while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME);
 #endif
@@ -1655,7 +1663,7 @@
 #else
 		do_rw_disk (drive, rq, block); /* simpler and faster */
 		return;
-#endif /* CONFIG_BLK_DEV_IDEATAPI */;
+#endif /* CONFIG_BLK_DEV_IDEATAPI */
 	}
 	do_special(drive);
 	return;
@@ -1764,6 +1772,20 @@
 }
 #endif
 
+#if MAX_HWIFS > 4
+static void do_ide4_request (void)	/* invoked with cli() */
+{
+	do_hwgroup_request (ide_hwifs[4].hwgroup);
+}
+#endif
+
+#if MAX_HWIFS > 5
+static void do_ide5_request (void)	/* invoked with cli() */
+{
+	do_hwgroup_request (ide_hwifs[5].hwgroup);
+}
+#endif
+
 static void timer_expiry (unsigned long data)
 {
 	ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
@@ -2127,7 +2149,8 @@
 	};
 
 	drive->part[0].nr_sects = current_capacity(drive);
-	if ((drive->media != ide_disk && drive->media != ide_floppy) || !drive->part[0].nr_sects)
+	if ((drive->media != ide_disk && drive->media != ide_floppy)
+	    || !drive->part[0].nr_sects)
 		drive->part[0].start_sect = -1;
 	resetup_one_dev(HWIF(drive)->gd, drive->select.b.unit);
 
@@ -2322,10 +2345,18 @@
 					argbuf[3] = args[3];
 				}
 				if (!(err = verify_area(VERIFY_WRITE,(void *)arg, argsize))) {
+					if ((args[0] == WIN_SETFEATURES) &&
+					    (args[1] > 66) &&
+					    (args[2] == 3) &&
+					    ((drive->id->word93 & 0x2000) == 0)) {
+						printk("%s: Speed warnings UDMA 3/4 is not functional.\n", drive->name);
+						goto abort_speed;
+					}
 					rq.buffer = argbuf;
 					err = ide_do_drive_cmd(drive, &rq, ide_wait);
 					memcpy_tofs((void *)arg, argbuf, argsize);
 				}
+abort_speed:
 				if (argsize > 4)
 					kfree(argbuf);
 			}
@@ -2557,6 +2588,7 @@
 	}
 
 	drive->media = ide_disk;
+
 	/* Extract geometry if we did not already have one for the drive */
 	if (!drive->present) {
 		drive->present = 1;
@@ -2565,8 +2597,8 @@
 		drive->sect    = drive->bios_sect = id->sectors;
 	}
 	/* Handle logical geometry translation by the drive */
-	if ((id->field_valid & 1) && id->cur_cyls &&
-		id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) {
+	if ((id->field_valid & 1) && id->cur_cyls && id->cur_heads
+	    && (id->cur_heads <= 16) && id->cur_sectors) {
 		/*
 		 * Extract the physical drive geometry for our use.
 		 * Note that we purposely do *not* update the bios info.
@@ -2593,12 +2625,9 @@
 	/* Use physical geometry if what we have still makes no sense */
 	if ((!drive->head || drive->head > 16) &&
 	    id->heads && id->heads <= 16) {
-		if ((id->lba_capacity > 16514064) || (id->cyls == 0x3fff)) {
-			id->cyls = ((int)(id->lba_capacity/(id->heads * id->sectors)));
-		}
-		drive->cyl  = id->cur_cyls    = id->cyls;
-		drive->head = id->cur_heads   = id->heads;
-		drive->sect = id->cur_sectors = id->sectors;
+		drive->cyl  = id->cyls;
+		drive->head = id->heads;
+		drive->sect = id->sectors;
 	}
 
 	/* calculate drive capacity, and select LBA if possible */
@@ -2608,21 +2637,17 @@
 	 * if possible, give fdisk access to more of the drive,
 	 * by correcting bios_cyls:
 	 */
-	if ((capacity >= (id->cyls * id->heads * id->sectors)) &&
-	    (!drive->forced_geom) && drive->bios_sect && drive->bios_head) {
-		drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head;
-#ifdef DEBUG
-		printk("FDISK Fixing Geometry :: CHS=%d/%d/%d to CHS=%d/%d/%d\n",
-			drive->id->cur_cyls,
-			drive->id->cur_heads,
-			drive->id->cur_sectors,
-			drive->bios_cyl,
-			drive->bios_head,
-			drive->bios_sect);
-#endif
-		drive->id->cur_cyls    = drive->bios_cyl;
-		drive->id->cur_heads   = drive->bios_head;
-		drive->id->cur_sectors = drive->bios_sect;
+	if (capacity > drive->bios_cyl * drive->bios_head * drive->bios_sect
+	    && !drive->forced_geom && drive->bios_sect && drive->bios_head) {
+		int cyl = (capacity / drive->bios_sect) / drive->bios_head;
+		if (cyl <= 65535)
+			drive->bios_cyl = cyl;
+		else {
+			/* OK until 539 GB */
+			drive->bios_sect = 63;
+			drive->bios_head = 255;
+			drive->bios_cyl = capacity / (63*255);
+		}
 	}
 
 	if (!strncmp(id->model, "BMI ", 4) &&
@@ -2657,8 +2682,12 @@
 		capacity/2048L, id->buf_size/2,
 		drive->bios_cyl, drive->bios_head, drive->bios_sect);
 	if (drive->using_dma) {
-		if ((id->field_valid & 4) && (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
-			printk(", UDMA");	/* UDMA BIOS-enabled! */
+		if ((id->field_valid & 4) && (id->word93 & 0x2000) &&
+		    (id->dma_ultra & (id->dma_ultra >>  11) & 3)) {
+			printk(", UDMA(66)");	/* UDMA BIOS-enabled! */
+		} else if ((id->field_valid & 4) &&
+			   (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
+			printk(", UDMA(33)");	/* UDMA BIOS-enabled! */
 		} else if (id->field_valid & 4) {
 			printk(", (U)DMA");	/* Can be BIOS-enabled! */
 		} else {
@@ -2666,18 +2695,6 @@
 		}
 	}
 	printk("\n");
-	if (drive->select.b.lba) {
-		if (*(int *)&id->cur_capacity0 != id->lba_capacity) {
-#ifdef DEBUG
-			printk("     CurSects=%d, LBASects=%d, ",
-				*(int *)&id->cur_capacity0, id->lba_capacity);
-#endif
-			*(int *)&id->cur_capacity0 = id->lba_capacity;
-#ifdef DEBUG
-			printk( "Fixed CurSects=%d\n", *(int *)&id->cur_capacity0);
-#endif
-		}
-	}
 }
 
 /*
@@ -2934,6 +2951,12 @@
  * The only "perfect" way to handle this would be to modify the setup.[cS] code
  * to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info
  * for us during initialization.  I have the necessary docs -- any takers?  -ml
+ * [I did this. But the result is more suited for user space. -aeb]
+ *
+ * Unfortunately the above is far too optimistic. One of the problems is that
+ * drives 1 and 2 may be SCSI disks (even when IDE disks are present), so that
+ * the geometry we read here from BIOS is attributed to the wrong disks.
+ * Eventually the routine below should be removed.
  */
 static void probe_cmos_for_drives (ide_hwif_t *hwif)
 {
@@ -3380,12 +3403,6 @@
  * Returns 1 if the geometry translation was successful.
  */
 
-/*
- * We update the values if the current CHS as determined by the kernel.
- * This now allows for the hdparm tool to read the actual settings of the
- * being used by the kernel.  This removes the need for doing guess
- * translations based on the raw values of the drive.
- */
 int ide_xlate_1024 (kdev_t i_rdev, int xparm, const char *msg)
 {
 	ide_drive_t *drive;
@@ -3397,35 +3414,15 @@
 	if (!drive)
 		return 0;
 
-	if (drive->forced_geom) {
-		/*
-		 * Update the current 3D drive values.
-		 */
-		drive->id->cur_cyls	= drive->bios_cyl;
-		drive->id->cur_heads	= drive->bios_head;
-		drive->id->cur_sectors	= drive->bios_sect;
+	if (drive->forced_geom)
 		return 0;
-	}
 
-	if (xparm > 1 && xparm <= drive->bios_head && drive->bios_sect == 63) {
-		/*
-		 * Update the current 3D drive values.
-		 */
-		drive->id->cur_cyls	= drive->bios_cyl;
-		drive->id->cur_heads	= drive->bios_head;
-		drive->id->cur_sectors	= drive->bios_sect;
+	if (xparm > 1 && xparm <= drive->bios_head && drive->bios_sect == 63)
 		return 0;		/* we already have a translation */
-	}
 
 	printk("%s ", msg);
 
 	if (xparm < 0 && (drive->bios_cyl * drive->bios_head * drive->bios_sect) < (1024 * 16 * 63)) {
-		/*
-		 * Update the current 3D drive values.
-		 */
-		drive->id->cur_cyls	= drive->bios_cyl;
-		drive->id->cur_heads	= drive->bios_head;
-		drive->id->cur_sectors	= drive->bios_sect;
 		return 0;		/* small disk: no translation needed */
 	}
 
@@ -3466,12 +3463,6 @@
 	}
 	drive->part[0].nr_sects = current_capacity(drive);
 	printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect);
-	/*
-	 * Update the current 3D drive values.
-	 */
-	drive->id->cur_cyls	= drive->bios_cyl;
-	drive->id->cur_heads	= drive->bios_head;
-	drive->id->cur_sectors	= drive->bios_sect;
 	return 1;
 }
 
@@ -3635,7 +3626,18 @@
 	save_flags(flags);
 	cli();
 	for (index = 0; !pcibios_find_device (vendor, device, index, &bus, &fn); ++index) {
-		init (bus, fn + func_adj);
+		if ((vendor == PCI_VENDOR_ID_TTI) &&
+		    (device == PCI_DEVICE_ID_TTI_HPT343) && (func_adj)) {
+			unsigned short pcicmd = 0;
+
+			pcibios_read_config_word(bus, fn, PCI_COMMAND, &pcicmd);
+			if (pcicmd & PCI_COMMAND_MEMORY)
+				init (bus, fn);
+			else
+				return;
+		} else {
+			init (bus, fn + func_adj);
+		}
 	}
 	restore_flags(flags);
 }
@@ -3670,17 +3672,22 @@
 		 */
 #ifdef CONFIG_BLK_DEV_OFFBOARD
 		ide_probe_pci (PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, &ide_init_triton, 0);
+		ide_probe_pci (PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, &ide_init_triton, 0);
 		ide_probe_pci (PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, &ide_init_triton, 0);
+		ide_probe_pci (PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343, &ide_init_triton, 1);
 #endif /* CONFIG_BLK_DEV_OFFBOARD */
 		ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_0, &ide_init_triton, 1);
 		ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, &ide_init_triton, 0);
 		ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, &ide_init_triton, 0);
 		ide_probe_pci (PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, &ide_init_triton, 0);
 		ide_probe_pci (PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, &ide_init_triton, 0);
+		ide_probe_pci (PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, &ide_init_triton, 0);
 #ifndef CONFIG_BLK_DEV_OFFBOARD
 		ide_probe_pci (PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, &ide_init_triton, 0);
+		ide_probe_pci (PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, &ide_init_triton, 0);
 		ide_probe_pci (PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, &ide_init_triton, 0);
 #endif /* CONFIG_BLK_DEV_OFFBOARD */
+		ide_probe_pci (PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343, &ide_init_triton, 0);
 #endif /* CONFIG_BLK_DEV_TRITON */
 	}
 #endif /* CONFIG_PCI */
@@ -3726,6 +3733,12 @@
 #endif
 #if MAX_HWIFS > 3
 	case IDE3_MAJOR: rfn = &do_ide3_request; break;
+#endif
+#if MAX_HWIFS > 4
+	case IDE4_MAJOR: rfn = &do_ide4_request; break;
+#endif
+#if MAX_HWIFS > 5
+	case IDE5_MAJOR: rfn = &do_ide5_request; break;
 #endif
 	default:
 		printk("%s: request_fn NOT DEFINED\n", hwif->name);
diff -u --recursive --new-file linux-2.0.38/drivers/block/ide.h linux-2.0.39/drivers/block/ide.h
--- linux-2.0.38/drivers/block/ide.h	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/block/ide.h	Wed Jun 28 14:48:19 2000
@@ -145,7 +145,7 @@
 #define PARTN_MASK	((1<<PARTN_BITS)-1)	/* a useful bit mask */
 #define MAX_DRIVES	2	/* per interface; 2 assumed by lots of code */
 #ifndef MAX_HWIFS
-#define MAX_HWIFS	4	/* an arbitrary, but realistic limit */
+#define MAX_HWIFS	6	/* an arbitrary, but realistic limit */
 #endif
 #define SECTOR_WORDS	(512 / 4)	/* number of 32bit words per sector */
 
@@ -429,7 +429,8 @@
 typedef enum {	ide_unknown,	ide_generic,	ide_triton,
 		ide_cmd640,	ide_dtc2278,	ide_ali14xx,
 		ide_qd6580,	ide_umc8672,	ide_ht6560b,
-		ide_promise,	ide_udma }
+		ide_promise,	ide_hpt343,	ide_udma,
+		ide_ultra66 }
 	hwif_chipset_t;
 
 typedef struct hwif_s {
diff -u --recursive --new-file linux-2.0.38/drivers/block/ll_rw_blk.c linux-2.0.39/drivers/block/ll_rw_blk.c
--- linux-2.0.38/drivers/block/ll_rw_blk.c	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/block/ll_rw_blk.c	Wed Jun 28 14:48:19 2000
@@ -445,6 +445,8 @@
 	     case FLOPPY_MAJOR:
 	     case IDE2_MAJOR:
 	     case IDE3_MAJOR:
+	     case IDE4_MAJOR:
+	     case IDE5_MAJOR:
 		/*
 		 * The scsi disk and cdrom drivers completely remove the request
 		 * from the queue when they start processing an entry.  For this
diff -u --recursive --new-file linux-2.0.38/drivers/block/paride/pseudo.h linux-2.0.39/drivers/block/paride/pseudo.h
--- linux-2.0.38/drivers/block/paride/pseudo.h	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/block/paride/pseudo.h	Mon Jul 10 00:14:29 2000
@@ -1,4 +1,4 @@
-/* 
+/*
         pseudo.h    (c) 1997-8  Grant R. Guenther <grant@torque.net>
                                 Under the terms of the GNU public license.
 
@@ -20,7 +20,7 @@
 	jiffy.  If nice is 0, the test will also be done whenever
 	the scheduler runs (by adding it to a task queue).  If
 	nice is greater than 1, the test will be done once every
-	(nice-1) jiffies. 
+	(nice-1) jiffies.
 
 */
 
@@ -29,7 +29,7 @@
 	1.01	1998.05.03	Switched from cli()/sti() to spinlocks
 	1.02    1998.12.14      Added support for nice > 1
 */
-	
+
 #define PS_VERSION	"1.02"
 
 #include <linux/sched.h>
@@ -52,11 +52,11 @@
 static struct timer_list ps_timer = {0,0,0,0,ps_timer_int};
 static struct tq_struct ps_tq = {0,0,ps_tq_int,NULL};
 
-static void ps_set_intr( void (*continuation)(void), 
+static void ps_set_intr( void (*continuation)(void),
 			 int (*ready)(void),
 			 int timeout, int nice )
-
-{       long	flags;
+{
+	long flags;
 
 	spin_lock_irqsave(&ps_spinlock,flags);
 
@@ -76,7 +76,7 @@
 
         if (!ps_timer_active) {
 		ps_timer_active = 1;
-                ps_timer.expires = jiffies + (ps_nice>0)?(ps_nice-1):0;
+                ps_timer.expires = jiffies + ((ps_nice>0)?(ps_nice-1):0);
                 add_timer(&ps_timer);
         }
 
@@ -84,8 +84,8 @@
 }
 
 static void ps_tq_int( void *data )
-
-{       void (*con)(void);
+{
+	void (*con)(void);
 	long flags;
 
 	spin_lock_irqsave(&ps_spinlock,flags);
@@ -104,7 +104,7 @@
 	}
         if (!ps_ready || ps_ready() || (jiffies >= ps_timeout)) {
                 ps_continuation = NULL;
-        	spin_unlock_irqrestore(&ps_spinlock,flags);
+		spin_unlock_irqrestore(&ps_spinlock,flags);
                 con();
                 return;
                 }
@@ -119,9 +119,9 @@
 }
 
 static void ps_timer_int( unsigned long data)
-
-{       void (*con)(void);
-	long	flags;
+{
+	void (*con)(void);
+	long flags;
 
 	spin_lock_irqsave(&ps_spinlock,flags);
 
@@ -138,10 +138,9 @@
 		return;
 		}
 	ps_timer_active = 1;
-        ps_timer.expires = jiffies + (ps_nice>0)?(ps_nice-1):0;
+        ps_timer.expires = jiffies + ((ps_nice>0)?(ps_nice-1):0);
         add_timer(&ps_timer);
         spin_unlock_irqrestore(&ps_spinlock,flags);
 }
 
 /* end of pseudo.h */
-
diff -u --recursive --new-file linux-2.0.38/drivers/block/proc_array.c linux-2.0.39/drivers/block/proc_array.c
--- linux-2.0.38/drivers/block/proc_array.c	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/block/proc_array.c	Wed Dec 29 12:50:32 1999
@@ -15,11 +15,11 @@
  *            quite a bit, modularized the code.
  * fvk 4/'93  waltje@uwalt.nl.mugnet.org (Fred N. van Kempen)
  *	      Renamed "route_get_info()" to "rt_get_info()" for consistency.
- * Alan Cox (gw4pts@gw4pts.ampr.org) 4/94
+ * Alan Cox (alan@lxorguk.ukuu.org.uk) 4/94
  *	      Dusted off the code and added IPX. Fixed the 4K limit.
  * Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
  *	      /proc/net/snmp.
- * Alan Cox (gw4pts@gw4pts.ampr.org) 1/95
+ * Alan Cox (alan@lxorguk.ukuu.org.uk) 1/95
  *	      Added Appletalk slots
  *
  *  proc diskarray directory handling functions
diff -u --recursive --new-file linux-2.0.38/drivers/block/triton.c linux-2.0.39/drivers/block/triton.c
--- linux-2.0.38/drivers/block/triton.c	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/block/triton.c	Wed Jun 28 14:48:19 2000
@@ -2,7 +2,9 @@
  *  linux/drivers/block/triton.c	Version 1.13  Aug 12, 1996
  *					Version 1.13a June 1998 - new chipsets
  *					Version 1.13b July 1998 - DMA blacklist
+ *					Version 1.14  June 22, 1999
  *
+ *  Copyright (c) 1998-1999  Andre Hedrick
  *  Copyright (c) 1995-1996  Mark Lord
  *  May be copied or modified under the terms of the GNU General Public License
  */
@@ -27,17 +29,24 @@
 
 #include <asm/io.h>
 #include <asm/dma.h>
+#include <asm/irq.h>
 
 #include "ide.h"
 
 #undef DISPLAY_TRITON_TIMINGS	/* define this to display timings */
 #undef DISPLAY_APOLLO_TIMINGS	/* define this for extensive debugging information */
+#undef DISPLAY_ALI15X3_TIMINGS	/* define this for extensive debugging information */
 
-#if defined(CONFIG_PROC_FS) && defined(DISPLAY_APOLLO_TIMINGS)
+#if defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
+#ifdef DISPLAY_APOLLO_TIMINGS
 #include <linux/via_ide_dma.h>
 #endif
+#ifdef DISPLAY_ALI15X3_TIMINGS
+#include <linux/ali_ide_dma.h>
+#endif
+#endif
 
 /*
  * good_dma_drives() lists the model names (from "hdparm -i")
@@ -90,6 +99,7 @@
 #define PRD_ENTRIES	(PAGE_SIZE / (2 * PRD_BYTES))
 #define DEFAULT_BMIBA	0xe800	/* in case BIOS did not init it */
 #define DEFAULT_BMCRBA  0xcc00  /* VIA's default value */
+#define DEFAULT_BMALIBA	0xd400	/* ALI's default value */
 
 /*
  * dma_intr() is the handler for disk read/write DMA interrupts
@@ -194,6 +204,11 @@
 	const char **list;
 	struct hd_driveid *id = drive->id;
 
+	if (HWIF(drive)->chipset == ide_hpt343) {
+		drive->using_dma = 0;	/* no DMA */
+		return 1;	/* DMA disabled */
+	}
+
 	if (id && (id->capability & 1)) {
 		/* Consult the list of known "bad" drives */
 		list = bad_dma_drives;
@@ -204,15 +219,24 @@
 				return 1;	/* DMA disabled */
 			}
 		}
-		/* Enable DMA on any drive that has mode 2 UltraDMA enabled */
-		if (id->field_valid & 4)	/* UltraDMA */
-			if  ((id->dma_ultra & 0x404) == 0x404) {
+		/* Enable DMA on any drive that has mode 4 or 2 UltraDMA enabled */
+		if (id->field_valid & 4) {	/* UltraDMA */
+			/* Enable DMA on any drive that has mode 4 UltraDMA enabled */
+			if (((id->dma_ultra & 0x1010) == 0x1010) &&
+			    (id->word93 & 0x2000) &&
+			    (HWIF(drive)->chipset == ide_ultra66)) {
+				drive->using_dma = 1;
+				return 0;	/* DMA enabled */
+			} else
+			/* Enable DMA on any drive that has mode 2 UltraDMA enabled */
+				if ((id->dma_ultra & 0x404) == 0x404) {
 				drive->using_dma = 1;
 				return 0;	/* DMA enabled */
 			}
+		}
 		/* Enable DMA on any drive that has mode2 DMA enabled */
 		if (id->field_valid & 2)	/* regular DMA */
-			if  ((id->dma_mword & 0x404) == 0x404) {
+			if ((id->dma_mword & 0x404) == 0x404) {
 				drive->using_dma = 1;
 				return 0;	/* DMA enabled */
 			}
@@ -363,6 +387,70 @@
 	return (0);
 }
 
+static int setup_aladdin (byte bus, byte fn)
+{
+	byte confreg0 = 0, confreg1 = 0, progif = 0;
+	int errors = 0;
+
+	if (pcibios_read_config_byte(bus, fn, 0x50, &confreg1))
+		goto veryspecialsettingserror;
+	if (!(confreg1 & 0x02))
+		if (pcibios_write_config_byte(bus, fn, 0x50, confreg1 | 0x02))
+			goto veryspecialsettingserror;
+
+	if (pcibios_read_config_byte(bus, fn, 0x09, &progif))
+		goto veryspecialsettingserror;
+	if (!(progif & 0x40)) {
+		/*
+		 * The way to enable them is to set progif
+		 * writable at 0x4Dh register, and set bit 6
+		 * of progif to 1:
+		 */
+		if (pcibios_read_config_byte(bus, fn, 0x4d, &confreg0))
+			goto veryspecialsettingserror;
+		if (confreg0 & 0x80)
+			if (pcibios_write_config_byte(bus, fn, 0x4d, confreg0 & ~0x80))
+				goto veryspecialsettingserror;
+		if (pcibios_write_config_byte(bus, fn, 0x09, progif | 0x40))
+			goto veryspecialsettingserror;
+		if (confreg0 & 0x80)
+			if (pcibios_write_config_byte(bus, fn, 0x4d, confreg0))
+				errors++;
+	}
+
+	if ((pcibios_read_config_byte(bus, fn, 0x09, &progif)) || (!(progif & 0x40)))
+		goto veryspecialsettingserror;
+
+	printk("ide: ALI15X3: enabled read of IDE channels state (en/dis-abled) %s.\n",
+		errors ? "with Error(s)" : "Succeeded" );
+	return 1;
+veryspecialsettingserror:
+	printk("ide: ALI15X3: impossible to enable read of IDE channels state (en/dis-abled)!\n");
+	return 0;
+}
+
+void set_promise_hpt343_extra (unsigned short device, unsigned int bmiba)
+{
+	switch(device) {
+		case PCI_DEVICE_ID_PROMISE_20246:
+			if(!check_region((bmiba+16), 16))
+				request_region((bmiba+16), 16, "PDC20246");
+			break;
+		case PCI_DEVICE_ID_PROMISE_20262:
+			if (!check_region((bmiba+48), 48))
+				request_region((bmiba+48), 48, "PDC20262");
+			break;
+		case PCI_DEVICE_ID_TTI_HPT343:
+			if(!check_region((bmiba+16), 16))
+				request_region((bmiba+16), 16, "HPT343");
+			break;
+		default:
+			break;
+	}
+}
+
+#define HPT343_PCI_INIT_REG		0x80
+
 /*
  * ide_init_triton() prepares the IDE driver for DMA operation.
  * This routine is called once, from ide.c during driver initialization,
@@ -370,17 +458,20 @@
  */
 void ide_init_triton (byte bus, byte fn)
 {
-	int rc = 0, h;
-	int dma_enabled = 0;
-	unsigned short io[6], count = 0, step_count = 0;
+	byte bridgebus, bridgefn, bridgeset = 0, hpt34x_flag = 0;
+	unsigned char irq = 0;
+	int dma_enabled = 0, rc = 0, h;
+	unsigned short io[6], count = 0, step_count = 0, pass_count = 0;
 	unsigned short pcicmd, vendor, device, class;
 	unsigned int bmiba, timings, reg, tmp;
 	unsigned int addressbios = 0;
+	unsigned long flags;
+	unsigned index;
 
-#ifdef DISPLAY_APOLLO_TIMINGS
+#if defined(DISPLAY_APOLLO_TIMINGS) || defined(DISPLAY_ALI15X3_TIMINGS)
 	bmide_bus = bus;
 	bmide_fn = fn;
-#endif /* DISPLAY_APOLLO_TIMINGS */
+#endif /* DISPLAY_APOLLO_TIMINGS || DISPLAY_ALI15X3_TIMINGS */
 
 /*
  *  We pick up the vendor, device, and class info for selecting the correct
@@ -392,19 +483,61 @@
 	pcibios_read_config_word (bus, fn, PCI_VENDOR_ID, &vendor);
 	pcibios_read_config_word (bus, fn, PCI_DEVICE_ID, &device);
 	pcibios_read_config_word (bus, fn, PCI_CLASS_DEVICE, &class);
+	pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &irq);
 
 	switch(vendor) {
 		case PCI_VENDOR_ID_INTEL:
-                   printk("ide: Intel 82371 (single FIFO) DMA Bus Mastering IDE ");
-                   break;
+			printk("ide: Intel 82371 ");
+			switch(device) {
+				case PCI_DEVICE_ID_INTEL_82371_0:
+					printk("PIIX (single FIFO) ");
+					break;
+				case PCI_DEVICE_ID_INTEL_82371SB_1:
+					printk("PIIX3 (dual FIFO) ");
+					break;
+				case PCI_DEVICE_ID_INTEL_82371AB:
+					printk("PIIX4 (dual FIFO) ");
+					break;
+				default:
+					printk(" (unknown) 0x%04x ", device);
+					break;
+			}
+			printk("DMA Bus Mastering IDE ");
+			break;
 		case PCI_VENDOR_ID_SI:
 			printk("ide: SiS 5513 (dual FIFO) DMA Bus Mastering IDE ");
 			break;
                 case PCI_VENDOR_ID_VIA:
-                   printk("ide: VIA VT82C586B (split FIFO) UDMA Bus Mastering IDE ");
-                   break;
+			printk("ide: VIA VT82C586B (split FIFO) UDMA Bus Mastering IDE ");
+			break;
+		case PCI_VENDOR_ID_TTI:
+			/*PCI_CLASS_STORAGE_UNKNOWN == class */
+			if (device == PCI_DEVICE_ID_TTI_HPT343) {
+				pcibios_write_config_byte(bus, fn, HPT343_PCI_INIT_REG, 0x00);
+				pcibios_read_config_word(bus, fn, PCI_COMMAND, &pcicmd);
+				hpt34x_flag = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
+#if 1
+				if (!hpt34x_flag) {
+					save_flags(flags);
+					cli();
+					pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd & ~PCI_COMMAND_IO);
+					pcibios_read_config_dword(bus, fn, PCI_BASE_ADDRESS_4, &bmiba);
+					pcibios_write_config_dword(bus, fn, PCI_BASE_ADDRESS_0, bmiba | 0x20);
+					pcibios_write_config_dword(bus, fn, PCI_BASE_ADDRESS_1, bmiba | 0x34);
+					pcibios_write_config_dword(bus, fn, PCI_BASE_ADDRESS_2, bmiba | 0x28);
+					pcibios_write_config_dword(bus, fn, PCI_BASE_ADDRESS_3, bmiba | 0x3c);
+					pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd);
+					bmiba = 0;
+					restore_flags(flags);
+				}
+#endif
+				pcibios_write_config_byte(bus, fn, PCI_LATENCY_TIMER, 0x20); 
+				goto hpt343_jump_in;
+			} else {
+				printk("ide: HPTXXX did == 0x%04X unsupport chipset error.\n", device);
+				return;
+			}
 		case PCI_VENDOR_ID_PROMISE:
-			/*	PCI_CLASS_STORAGE_RAID == class	*/
 			/*
 			 *  I have been able to make my Promise Ultra33 UDMA card change class.
 			 *  It has reported as both PCI_CLASS_STORAGE_RAID and PCI_CLASS_STORAGE_IDE.
@@ -414,15 +547,17 @@
 			 *  correction if needed.
 			 *  PDC20246 (primary) PDC20247 (secondary) IDE hwif's.
 			 *
+			 *  PDC20262 Promise Ultra66 UDMA.
+			 *
 			 *  Note that Promise "stories,fibs,..." about this device not being
 			 *  capable of ATAPI and AT devices.
 			 */
-			if (PCI_CLASS_STORAGE_RAID == class) {
-				unsigned char irq1 = 0, irq2 = 0;
-				pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &irq1);
-				pcibios_read_config_byte (bus, fn, (PCI_INTERRUPT_LINE)|0x80, &irq2);
-				if (irq1 != irq2) {
-					pcibios_write_config_byte(bus, fn, (PCI_INTERRUPT_LINE)|0x80, irq1);
+			if (class != PCI_CLASS_STORAGE_IDE) {
+				unsigned char irq_mirror = 0;
+
+				pcibios_read_config_byte(bus, fn, (PCI_INTERRUPT_LINE)|0x80, &irq_mirror);
+				if (irq != irq_mirror) {
+					pcibios_write_config_byte(bus, fn, (PCI_INTERRUPT_LINE)|0x80, irq);
 				}
 			}
 		case PCI_VENDOR_ID_ARTOP:
@@ -436,8 +571,13 @@
 			 *  0x6000 range.  If they are setup in the 0xef00 range it is reported.
 			 *  WHY??? got me.........
 			 */
+hpt343_jump_in:
 			printk("ide: %s UDMA Bus Mastering ",
-				(vendor == PCI_VENDOR_ID_ARTOP) ? "AEC6210" : "PDC20246");
+				(device == PCI_DEVICE_ID_ARTOP_ATP850UF) 		? "AEC6210" :
+				(device == PCI_DEVICE_ID_PROMISE_20246)  		? "PDC20246" :
+				(device == PCI_DEVICE_ID_PROMISE_20262)  		? "PDC20262" :
+				(hpt34x_flag && (device == PCI_DEVICE_ID_TTI_HPT343))	? "HPT345" :
+				(device == PCI_DEVICE_ID_TTI_HPT343)     		? "HPT343" : "UNKNOWN");
 			pcibios_read_config_dword(bus, fn, PCI_ROM_ADDRESS, &addressbios);
 			if (addressbios) {
 				pcibios_write_config_byte(bus, fn, PCI_ROM_ADDRESS, addressbios | PCI_ROM_ADDRESS_ENABLE);
@@ -460,6 +600,15 @@
 					io[count++] = tmp & PCI_BASE_ADDRESS_IO_MASK;
 			}
 			break;
+		case PCI_VENDOR_ID_AL:
+			save_flags(flags);
+			cli();
+			for (index = 0; !pcibios_find_device (PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, index, &bridgebus, &bridgefn); ++index) {
+				bridgeset = setup_aladdin(bus, fn);
+			}
+			restore_flags(flags);
+			printk("ide: ALI15X3 (dual FIFO) DMA Bus Mastering IDE ");
+			break;
 		default:
 			return;
 	}
@@ -491,12 +640,20 @@
 				break;
 			} else {
                                 printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);
-                                if (inb(((vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA : DEFAULT_BMIBA)) != 0xff || !try_again)
+                                if (inb(((vendor == PCI_VENDOR_ID_AL) ? DEFAULT_BMALIBA :
+					 (vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA :
+									DEFAULT_BMIBA)) != 0xff || !try_again)
 					break;
-				printk("ide: setting BM-DMA base register to 0x%04x\n", ((vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA : DEFAULT_BMIBA));
+				printk("ide: setting BM-DMA base register to 0x%04x\n",
+					((vendor == PCI_VENDOR_ID_AL) ? DEFAULT_BMALIBA :
+					 (vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA :
+									DEFAULT_BMIBA));
 				if ((rc = pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd&~1)))
 					goto quit;
-				rc = pcibios_write_config_dword(bus, fn, 0x20, ((vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA : DEFAULT_BMIBA)|1);
+				rc = pcibios_write_config_dword(bus, fn, 0x20,
+					((vendor == PCI_VENDOR_ID_AL) ? DEFAULT_BMALIBA :
+					 (vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA :
+									DEFAULT_BMIBA)|1);
 				if (pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd|5) || rc)
 					goto quit;
 			}
@@ -509,14 +666,17 @@
 	if ((rc = pcibios_read_config_dword(bus, fn,
 		(vendor == PCI_VENDOR_ID_PROMISE) ? 0x50 : 
 		(vendor == PCI_VENDOR_ID_ARTOP) ? 0x54 :
+		(vendor == PCI_VENDOR_ID_SI) ? 0x48 :
+		(vendor == PCI_VENDOR_ID_AL) ? 0x08 :
 		0x40, &timings)))
 		goto quit;
 	/*
-	 * We do a vendor check since the Ultra33 and AEC6210
+	 * We do a vendor check since the Ultra33/66 and AEC6210
 	 * holds their timings in a different location.
 	 */
+#if 0
 	printk("ide: timings == %08x\n", timings);
-
+#endif
 	/*
 	 *  The switch preserves some stuff that was original.
 	 */
@@ -533,9 +693,39 @@
 				goto quit;
 			}
 			break;
+		case PCI_VENDOR_ID_AL:
+			timings <<= 16;
+			timings >>= 24;
+			if (!(timings & 0x30)) {
+				printk("ide: ALI15X3: neither port is enabled\n");
+				goto quit;
+			}
+			break;
 		case PCI_VENDOR_ID_SI:
+			timings <<= 8;
+			timings >>= 24;
+			if (!(timings & 0x06)) {
+				printk("ide: SIS5513: neither port is enabled\n");
+				goto quit;
+			}
+			break;
 		case PCI_VENDOR_ID_PROMISE:
+			printk("    (U)DMA Burst Bit %sABLED " \
+				"Primary %s Mode " \
+				"Secondary %s Mode.\n",
+				(inb(bmiba + 0x001f) & 1) ? "EN" : "DIS",
+				(inb(bmiba + 0x001a) & 1) ? "MASTER" : "PCI",
+				(inb(bmiba + 0x001b) & 1) ? "MASTER" : "PCI" );
+#if 0
+			if (!(inb(bmiba + 0x001f) & 1)) {
+				outb(inb(bmiba + 0x001f)|0x01, (bmiba + 0x001f));
+				printk("    (U)DMA Burst Bit Forced %sABLED.\n",
+					(inb(bmiba + 0x001f) & 1) ? "EN" : "DIS");
+			}
+#endif
+			break;
 		case PCI_VENDOR_ID_ARTOP:
+		case PCI_VENDOR_ID_TTI:
                 default:
                         break;
         }
@@ -545,15 +735,22 @@
 	 */
 	for (h = 0; h < MAX_HWIFS; ++h) {
 		ide_hwif_t *hwif = &ide_hwifs[h];
+		byte channel = ((h == 1) || (h == 3) || (h == 5)) ? 1 : 0;
 
 		/*
 		 *  This prevents the first contoller from accidentally
 		 *  initalizing the hwif's that it does not use and block
 		 *  an off-board ide-pci from getting in the game.
 		 */
-		if (step_count >= 2) {
+		if ((step_count >= 2) || (pass_count >= 2)) {
 			goto quit;
 		}
+
+#if 0
+		if (hwif->chipset == ide_unknown)
+			printk("ide: index == %d channel(%d)\n", h, channel);
+#endif
+
 #ifdef CONFIG_BLK_DEV_OFFBOARD
 		/*
 		 *  This is a forced override for the onboard ide controller
@@ -562,21 +759,14 @@
 		 *  for offboard UDMA upgrades with hard disks, but saving
 		 *  the onboard DMA2 controllers for CDROMS, TAPES, ZIPS, etc...
 		 */
-		if ((vendor == PCI_VENDOR_ID_INTEL) ||
-		    (vendor == PCI_VENDOR_ID_SI) ||
-		    (vendor == PCI_VENDOR_ID_VIA)) {
-			if (h == 2) {
-				hwif->io_base = 0x1f0;
-				hwif->ctl_port = 0x3f6;
-				hwif->irq = 14;
-				hwif->noprobe = 0;
-			}
-			if (h == 3) {
-				hwif->io_base = 0x170;
-				hwif->ctl_port = 0x376;
-				hwif->irq = 15;
-				hwif->noprobe = 0;
-			}
+		if (((vendor == PCI_VENDOR_ID_INTEL) ||
+		     (vendor == PCI_VENDOR_ID_SI) ||
+		     (vendor == PCI_VENDOR_ID_VIA) ||
+		     (vendor == PCI_VENDOR_ID_AL)) && (h >= 2)) {
+			hwif->io_base	= channel ? 0x170 : 0x1f0;
+			hwif->ctl_port	= channel ? 0x376 : 0x3f6;
+			hwif->irq	= channel ? 15 : 14;
+			hwif->noprobe	= 0;
 		}
 #endif /* CONFIG_BLK_DEV_OFFBOARD */
 		/*
@@ -592,6 +782,7 @@
 			byte s_clks, r_clks;
 			unsigned short devid;
 #endif /* DISPLAY_TRITON_TIMINGS */
+			pass_count++;
 			if (hwif->io_base == 0x1f0) {
 				time = timings & 0xffff;
 				if ((time & 0x8000) == 0)	/* interface enabled? */
@@ -637,12 +828,17 @@
 			print_triton_drive_flags (1, (time >> 4) & 0xf);
 #endif /* DISPLAY_TRITON_TIMINGS */
 		} else if (vendor == PCI_VENDOR_ID_SI) {
+			pass_count++;
 			if (hwif->io_base == 0x1f0) {
+				if ((timings & 0x02) == 0)
+					continue;
 				hwif->chipset = ide_triton;
 				if (dma_enabled)
 					init_triton_dma(hwif, bmiba);
 				step_count++;
 			} else if (hwif->io_base == 0x170) {
+				if ((timings & 0x04) == 0)
+					continue;
 				hwif->chipset = ide_triton;
 				if (dma_enabled)
 					init_triton_dma(hwif, bmiba + 8);
@@ -650,9 +846,10 @@
 			} else {
 				continue;
 			}
-		} else if(vendor == PCI_VENDOR_ID_VIA) {
+		} else if (vendor == PCI_VENDOR_ID_VIA) {
+			pass_count++;
 			if (hwif->io_base == 0x1f0) {
-				if((timings & 0x02) == 0)
+				if ((timings & 0x02) == 0)
 					continue;
 				hwif->chipset = ide_triton;
 				if (dma_enabled)
@@ -664,7 +861,7 @@
 #endif /* DISPLAY_APOLLO_TIMINGS */
 				step_count++;
 			} else if (hwif->io_base == 0x170) {
-				if((timings & 0x01) == 0)
+				if ((timings & 0x01) == 0)
 					continue;
 				hwif->chipset = ide_triton;
 				if (dma_enabled)
@@ -675,41 +872,91 @@
 			} else {
 				continue;
 			}
+		} else if (vendor == PCI_VENDOR_ID_AL) {
+			byte ideic, inmir;
+			byte irq_routing_table[] = { -1,  9, 3, 10, 4,  5, 7,  6,
+						      1, 11, 0, 12, 0, 14, 0, 15 };
+
+			if (bridgeset) {
+				pcibios_read_config_byte(bridgebus, bridgefn, 0x58, &ideic);
+				ideic = ideic & 0x03;
+				if ((channel && ideic == 0x03) || (!channel && !ideic)) {
+					pcibios_read_config_byte(bridgebus, bridgefn, 0x44, &inmir);
+					inmir = inmir & 0x0f;
+					hwif->irq = irq_routing_table[inmir];
+				} else if (channel && !(ideic & 0x01)) {
+					pcibios_read_config_byte(bridgebus, bridgefn, 0x75, &inmir);
+					inmir = inmir & 0x0f;
+					hwif->irq = irq_routing_table[inmir];
+				}
+			}
+			pass_count++;
+			if (hwif->io_base == 0x1f0) {
+				if ((timings & 0x20) == 0)
+					continue;
+				hwif->chipset = ide_triton;
+				if (dma_enabled)
+					init_triton_dma(hwif, bmiba);
+				outb(inb(bmiba+2) & 0x60, bmiba+2);
+				if (inb(bmiba+2) & 0x80)
+					printk("ALI15X3: simplex device: DMA forced\n");
+#ifdef DISPLAY_ALI15X3_TIMINGS
+				proc_register_dynamic(&proc_root, &ali_proc_entry);
+#endif /* DISPLAY_ALI15X3_TIMINGS */
+				step_count++;
+			} else if (hwif->io_base == 0x170) {
+				if ((timings & 0x10) == 0)
+					continue;
+				hwif->chipset = ide_triton;
+				if (dma_enabled)
+					init_triton_dma(hwif, bmiba + 8);
+				outb(inb(bmiba+10) & 0x60, bmiba+10);
+				if (inb(bmiba+10) & 0x80)
+					printk("ALI15X3: simplex device: DMA forced\n");
+				step_count++;
+			} else {
+				continue;
+			}
 		} else if ((vendor == PCI_VENDOR_ID_PROMISE) ||
-			   (vendor == PCI_VENDOR_ID_ARTOP)) {
-	/*
-	 *  This silly tmp = h routine allows an off-board ide-pci card to
-	 *  be booted as primary hwifgroup, provided that the onboard
-	 *  controllers are disabled.  If they are active, then we wait our
-	 *  turn for hwif assignment.
-	 */
-			unsigned char irq = 0;
-			pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &irq);
-			if ((h == 0) || (h == 1)) {
-				tmp = h * 2;
+			   (vendor == PCI_VENDOR_ID_ARTOP) ||
+			   (vendor == PCI_VENDOR_ID_TTI)) {
+			pass_count++;
+			if (vendor == PCI_VENDOR_ID_TTI) {
+				if ((!hpt34x_flag) && (h < 2)) {
+					goto quit;
+				} else if (hpt34x_flag) {
+					hwif->io_base	= channel ? (bmiba + 0x28) : (bmiba + 0x20);
+					hwif->ctl_port	= channel ? (bmiba + 0x3e) : (bmiba + 0x36);
+				} else {
+					goto io_temps;
+				}
 			} else {
-				tmp = (h - 2) * 2;
+io_temps:
+				tmp		= channel ? 2 : 0;
+				hwif->io_base	= io[tmp];
+				hwif->ctl_port	= io[tmp + 1] + 2;
 			}
-			hwif->io_base = io[tmp];
-			hwif->ctl_port = io[tmp + 1] + 2;
 			hwif->irq = irq;
 			hwif->noprobe = 0;
 
-			if (vendor == PCI_VENDOR_ID_ARTOP) {
+			if (device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
 				hwif->serialized = 1;
 			}
 
+			if ((vendor == PCI_VENDOR_ID_PROMISE) ||
+			    (vendor == PCI_VENDOR_ID_TTI)) {
+				set_promise_hpt343_extra(device, bmiba);
+			}
+
 			if (dma_enabled) {
-				if (!check_region(bmiba, 8)) {
-					hwif->chipset = ide_udma;
+				if ((!check_region(bmiba, 8)) && (!channel)) {
+					hwif->chipset = ((vendor == PCI_VENDOR_ID_TTI) && !hpt34x_flag) ? ide_hpt343 :
+							 (device == PCI_DEVICE_ID_PROMISE_20262) ? ide_ultra66 : ide_udma;
 					init_triton_dma(hwif, bmiba);
 					step_count++;
-				} else if (!check_region((bmiba + 0x08), 8)) {
-					if ((vendor == PCI_VENDOR_ID_PROMISE) &&
-					    (!check_region(bmiba+16, 16))) {
-						request_region(bmiba+16, 16, "PDC20246");
-					}
-					hwif->chipset = ide_udma;
+				} else if ((!check_region((bmiba + 0x08), 8)) && (channel)) {
+					hwif->chipset = ((vendor == PCI_VENDOR_ID_TTI) && !hpt34x_flag) ? ide_hpt343 :
+							 (device == PCI_DEVICE_ID_PROMISE_20262) ? ide_ultra66 : ide_udma;
 					init_triton_dma(hwif, bmiba + 8);
 					step_count++;
 				} else {
diff -u --recursive --new-file linux-2.0.38/drivers/block/xd.c linux-2.0.39/drivers/block/xd.c
--- linux-2.0.38/drivers/block/xd.c	Thu Jun  4 00:17:47 1998
+++ linux-2.0.39/drivers/block/xd.c	Thu Sep  7 00:46:17 2000
@@ -163,8 +163,6 @@
 static u_short xd_iobase = 0x320;
 static int xd_geo[XD_MAXDRIVES*3] = { 0,0,0,0,0,0 };
 
-static int xd[5];
-
 static volatile int xdc_busy = 0;
 static struct wait_queue *xdc_wait = NULL;
 
diff -u --recursive --new-file linux-2.0.38/drivers/cdrom/Config.in linux-2.0.39/drivers/cdrom/Config.in
--- linux-2.0.38/drivers/cdrom/Config.in	Thu May 16 15:35:39 1996
+++ linux-2.0.39/drivers/cdrom/Config.in	Thu Sep  7 01:09:13 2000
@@ -1,26 +1,26 @@
 #
 # CDROM driver configuration
 #
-tristate 'Aztech/Orchid/Okano/Wearnes/TXC/CyDROM  CDROM support' CONFIG_AZTCD
-tristate 'Goldstar R420 CDROM support' CONFIG_GSCD
-tristate 'Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support' CONFIG_SBPCD
+tristate '  Aztech/Orchid/Okano/Wearnes/TXC/CyDROM  CDROM support' CONFIG_AZTCD
+tristate '  Goldstar R420 CDROM support' CONFIG_GSCD
+tristate '  Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support' CONFIG_SBPCD
 if [ "$CONFIG_SBPCD" = "y" ]; then
-  bool 'Matsushita/Panasonic, ... second CDROM controller support' CONFIG_SBPCD2
-  if [ "$CONFIG_SBPCD2" = "y" ]; then
-    bool 'Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3
-    if [ "$CONFIG_SBPCD3" = "y" ]; then
-      bool 'Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4
-    fi
-  fi
+   bool '    Matsushita/Panasonic, ... second CDROM controller support' CONFIG_SBPCD2
+   if [ "$CONFIG_SBPCD2" = "y" ]; then
+      bool '      Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3
+      if [ "$CONFIG_SBPCD3" = "y" ]; then
+	 bool '        Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4
+      fi
+   fi
 fi
-tristate 'Mitsumi (standard) [no XA/Multisession] CDROM support' CONFIG_MCD
-tristate 'Mitsumi [XA/MultiSession] CDROM support' CONFIG_MCDX
-tristate 'Optics Storage DOLPHIN 8000AT CDROM support' CONFIG_OPTCD
-tristate 'Philips/LMS CM206 CDROM support' CONFIG_CM206
-tristate 'Sanyo CDR-H94A CDROM support' CONFIG_SJCD
-bool 'Soft configurable cdrom interface card support' CONFIG_CDI_INIT
+tristate '  Mitsumi (standard) [no XA/Multisession] CDROM support' CONFIG_MCD
+tristate '  Mitsumi [XA/MultiSession] CDROM support' CONFIG_MCDX
+tristate '  Optics Storage DOLPHIN 8000AT CDROM support' CONFIG_OPTCD
+tristate '  Philips/LMS CM206 CDROM support' CONFIG_CM206
+tristate '  Sanyo CDR-H94A CDROM support' CONFIG_SJCD
+bool '  Soft configurable cdrom interface card support' CONFIG_CDI_INIT
 if [ "$CONFIG_CDI_INIT" = "y" ]; then
-  tristate 'ISP16/MAD16/Mozart soft configurable cdrom interface support' CONFIG_ISP16_CDI
+   tristate '    ISP16/MAD16/Mozart soft configurable cdrom interface support' CONFIG_ISP16_CDI
 fi
-tristate 'Sony CDU31A/CDU33A CDROM support' CONFIG_CDU31A
-tristate 'Sony CDU535 CDROM support' CONFIG_CDU535
+tristate '  Sony CDU31A/CDU33A CDROM support' CONFIG_CDU31A
+tristate '  Sony CDU535 CDROM support' CONFIG_CDU535
diff -u --recursive --new-file linux-2.0.38/drivers/char/Config.in linux-2.0.39/drivers/char/Config.in
--- linux-2.0.38/drivers/char/Config.in	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/char/Config.in	Wed Jun 28 14:47:04 2000
@@ -6,73 +6,76 @@
 
 tristate 'Standard/generic serial support' CONFIG_SERIAL
 if [ "$CONFIG_SERIAL" != "n" ]; then
-	if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-		bool '  PCI serial support' CONFIG_SERIAL_PCI
-	fi
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool '  PCI serial support (EXPERIMENTAL)' CONFIG_SERIAL_PCI
+   fi
 fi
 bool 'Digiboard PC/Xx Support' CONFIG_DIGI
 tristate 'Cyclades async mux support' CONFIG_CYCLADES
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_CYCLADES" != "n" ]; then
+   bool '  Cyclades-Z interrupt mode operation (EXPERIMENTAL)' CONFIG_CYZ_INTR
+fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-	dep_tristate 'Multi-Tech multiport card support' CONFIG_ISI m
+   dep_tristate 'Multi-Tech multiport card support (EXPERIMENTAL)' CONFIG_ISI m
 fi
 bool 'Stallion multiport serial support' CONFIG_STALDRV
 if [ "$CONFIG_STALDRV" = "y" ]; then
-  tristate '  Stallion EasyIO or EC8/32 support' CONFIG_STALLION
-  tristate '  Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION
+   tristate '  Stallion EasyIO or EC8/32 support' CONFIG_STALLION
+   tristate '  Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION
 fi
 tristate 'SDL RISCom/8 card support' CONFIG_RISCOM8
 tristate 'Parallel printer support' CONFIG_PRINTER
 tristate 'Specialix IO8+ card support' CONFIG_SPECIALIX
-if [ "$CONFIG_SPECIALIX" = "y" -o  "$CONFIG_SPECIALIX" = "m" ]; then
-  bool 'Specialix DTR/RTS pin is RTS' CONFIG_SPECIALIX_RTSCTS
+if [ "$CONFIG_SPECIALIX" = "y" -o "$CONFIG_SPECIALIX" = "m" ]; then
+   bool '  Specialix DTR/RTS pin is RTS' CONFIG_SPECIALIX_RTSCTS
 fi 
 
 
 bool 'Mouse Support (not serial mice)' CONFIG_MOUSE
 if [ "$CONFIG_MOUSE" = "y" ]; then
-	tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE
-	tristate 'Logitech busmouse support' CONFIG_BUSMOUSE
-	tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE
-	tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
-	if [ "$CONFIG_PSMOUSE" != "n" ]; then
-	  bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
-	fi
+   tristate '  ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE
+   tristate '  Logitech busmouse support' CONFIG_BUSMOUSE
+   tristate '  Microsoft busmouse support' CONFIG_MS_BUSMOUSE
+   tristate '  PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
+   if [ "$CONFIG_PSMOUSE" != "n" ]; then
+      bool '    C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
+   fi
 fi
 
 bool 'Support for user misc device modules' CONFIG_UMISC
 
 bool 'QIC-02 tape support' CONFIG_QIC02_TAPE
 if [ "$CONFIG_QIC02_TAPE" = "y" ]; then
-  bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF
-  if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then
-    comment 'Edit configuration parameters in ./include/linux/tpqic02.h!'
-  else
-    comment 'Setting runtime QIC-02 configuration is done with qic02conf'
-    comment 'from the tpqic02-support package.  It is available at'
-    comment 'ftp://titus.cfw.com/pub/Linux/util/'
-fi
+   bool '  Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF
+   if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then
+      comment 'Edit configuration parameters in ./include/linux/tpqic02.h!'
+   else
+      comment 'Setting runtime QIC-02 configuration is done with qic02conf'
+      comment 'from the tpqic02-support package.  It is available at'
+      comment 'ftp://titus.cfw.com/pub/Linux/util/'
+   fi
 fi
 
 tristate 'Ftape (QIC-80/Travan) support' CONFIG_FTAPE
 if [ "$CONFIG_FTAPE" != "n" ]; then
-  comment 'Set IObase/IRQ/DMA for ftape in ./drivers/char/ftape/Makefile'
+   comment 'Set IObase/IRQ/DMA for ftape in ./drivers/char/ftape/Makefile'
 fi
 
 if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then
-  bool 'Tadpole ANA H8 Support'	CONFIG_H8
+   bool 'Tadpole ANA H8 Support' CONFIG_H8
 fi
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
-  bool '   Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
-  tristate '   WDT Watchdog timer' CONFIG_WDT
-  if [ "$CONFIG_WDT" != "n" ]; then
-     bool '       WDT501 features' CONFIG_WDT_501
-     if [ "$CONFIG_WDT_501" = "y" ]; then
-         bool '       Fan Tachometer' CONFIG_WDT_501_FAN
-     fi
-  fi
-  tristate '   Software Watchdog' CONFIG_SOFT_WATCHDOG
-  tristate '   Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
+   bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
+   tristate '  WDT Watchdog timer' CONFIG_WDT
+   if [ "$CONFIG_WDT" != "n" ]; then
+      bool '    WDT501 features' CONFIG_WDT_501
+      if [ "$CONFIG_WDT_501" = "y" ]; then
+	 bool '      Fan Tachometer' CONFIG_WDT_501_FAN
+      fi
+   fi
+   tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG
+   tristate '  Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
 fi
 bool 'Enhanced Real Time Clock Support' CONFIG_RTC
 endmenu
diff -u --recursive --new-file linux-2.0.38/drivers/char/cyclades.c linux-2.0.39/drivers/char/cyclades.c
--- linux-2.0.38/drivers/char/cyclades.c	Sun Jun 13 19:21:00 1999
+++ linux-2.0.39/drivers/char/cyclades.c	Wed Jun 28 14:45:47 2000
@@ -1,7 +1,7 @@
 #define BLOCKMOVE
 #define	Z_WAKE
 static char rcsid[] =
-"$Revision: 2.1.2.1 $$Date: 1999/04/08 16:17:18 $";
+"$Revision: 2.1.2.4 $$Date: 1999/07/12 18:00:24 $";
 
 /*
  *  linux/drivers/char/cyclades.c
@@ -21,7 +21,7 @@
  * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
  * and then fixed as suggested by Michael K. Johnson 12/12/92.
  *
- * This version does not support shared irq's.
+ * This version supports shared IRQ's (only for PCI boards).
  *
  * This module exports the following rs232 io functions:
  *   int cy_init(void);
@@ -31,6 +31,29 @@
  *   void cleanup_module(void);
  *
  * $Log: cyclades.c,v $
+ * Revision 2.1.2.4   1999/07/12 18:00:24 ivan
+ * Fixed bug in cy_set_termios that would prevent XON/XOFF flow control
+ * switching from working properly;
+ * The driver now only prints IRQ info for the Cyclades-Z if it's
+ * configured to work in interrupt mode;
+ *
+ * Revision 2.1.2.3   1999/06/28 11:05:57 ivan
+ * Added support for interrupt mode operation for the Z cards;
+ * Removed the driver inactivity control for the Z;
+ * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when 
+ * the Z firmware is not loaded yet;
+ * Replaced the "manual" Z Tx flush buffer by a call to a FW command of 
+ * same functionality;
+ * Implemented workaround for IRQ setting loss on the PCI configuration 
+ * registers after a PCI bridge EEPROM reload (affects PLX9060 only);
+ *
+ * Revision 2.1.2.2   1999/05/21 17:18:05 ivan
+ * Added support to shared IRQ's (only for PCI boards);
+ * Added support for Cobalt Qube2 systems;
+ * IRQ [de]allocation scheme revisited;
+ * Included a PCI bridge reset and EEPROM reload in the board
+ * initialization code (for both Y and Z series).
+ *
  * Revision 2.1.2.1   1999/04/08 16:17:18 ivan
  * cy_wait_until_sent function revisited;
  * Module usage counter scheme revisited;
@@ -518,7 +541,7 @@
    constant in the definition below. No other change is necessary to
    support more boards/ports. */
 
-#define NR_PORTS        128
+#define NR_PORTS        256
 
 #define ZE_V1_NPORTS	64
 #define ZO_V1	0
@@ -600,6 +623,14 @@
 #include <linux/proc_fs.h>
 #endif
 
+#ifdef CONFIG_COBALT_27
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#define	CACHED_TO_UNCACHED(x)	(((unsigned long)(x) & \
+				  (unsigned long)0x1fffffff) + KSEG1)
+#endif
+
 #define __initfunc(__arginit)	__arginit
 #define copy_from_user		memcpy_fromfs
 #define copy_to_user		memcpy_tofs
@@ -636,6 +667,7 @@
 
 struct tty_driver cy_serial_driver, cy_callout_driver;
 
+#ifndef CONFIG_COBALT_27
 static volatile int cy_irq_triggered;
 static volatile int cy_triggered;
 static int cy_wild_int_mask;
@@ -663,6 +695,8 @@
 };
 #define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
 
+#endif /* CONFIG_COBALT_27 */
+
 /* This is the per-card data structure containing address, irq, number of
    channels, etc. This driver supports a maximum of NR_CARDS cards.
 */
@@ -681,12 +715,6 @@
 static struct termios *serial_termios[NR_PORTS];
 static struct termios *serial_termios_locked[NR_PORTS];
 
-/* This is the per-irq data structure,
-   it maps an irq to the corresponding card */
-
-static struct cyclades_card     *IRQ_cards[16];
-
-
 /*
  * tmp_buf is used as a temporary buffer by serial_write.  We need to
  * lock it in case the copy_from_user blocks while swapping in a page,
@@ -791,8 +819,9 @@
 
 static void cy_start(struct tty_struct *);
 static void set_line_char(struct cyclades_port *);
+#ifndef CONFIG_COBALT_27
 static void cy_probe(int, void *, struct pt_regs *);
-static void cyz_poll(unsigned long);
+#endif /* CONFIG_COBALT_27 */
 #ifdef CY_SHOW_STATUS
 static void show_status(int);
 #endif
@@ -813,6 +842,9 @@
 };
 #endif
 
+#ifndef CONFIG_CYZ_INTR
+static void cyz_poll(unsigned long);
+
 /* The Cyclades-Z polling cycle is defined by this variable */
 static long cyz_polling_cycle = CZ_DEF_POLL;
 
@@ -821,6 +853,7 @@
 cyz_timerlist = {
     NULL, NULL, 0, 0, cyz_poll
 };
+#endif /* CONFIG_CYZ_INTR */
 
 /**************************************************
 error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
@@ -862,7 +895,7 @@
         return 0;
 } /* serial_paranoia_check */
 
-
+#ifndef CONFIG_COBALT_27
 /* The following diagnostic routines allow the driver to spew
    information on the screen, even (especially!) during interrupts.
  */
@@ -895,7 +928,7 @@
 static void CP32(long data)
     { CP16((data>>16) & 0xffff); CP16(data & 0xffff); }/* CP32 */
 #endif
-
+#endif /* CONFIG_COBALT_27 */
 
 /*
  * This routine is used by the interrupt handler to schedule
@@ -1009,6 +1042,8 @@
     return(0);
 } /* cyy_issue_cmd */
 
+#ifndef CONFIG_COBALT_27	/* ISA interrupt detection code */
+
 static int probe_ready;
 
 /*
@@ -1204,6 +1239,8 @@
     return;
 } /* cy_probe */
 
+#endif /* CONFIG_COBALT_27 */
+
 /* The real interrupt service routine is called
    whenever the card wants its hand held--chars
    received, out buffer empty, modem change, etc.
@@ -1227,9 +1264,9 @@
   int mdm_change;
   int mdm_status;
 
-    if((cinfo = IRQ_cards[irq]) == 0){
+    if((cinfo = (struct cyclades_card *)dev_id) == 0){
 #ifdef CY_DEBUG_INTERRUPTS
-printk("cy_interrupt: spurious interrupt %d\n\r", irq);
+	printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
 #endif
         return; /* spurious interrupt */
     }
@@ -1261,7 +1298,7 @@
                 }
                 if (status & CySRReceive) { /* reception interrupt */
 #ifdef CY_DEBUG_INTERRUPTS
-printk("cy_interrupt: rcvd intr, chip %d\n\r", chip);
+		    printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
 #endif
                     /* determine the channel & change to that context */
                     save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
@@ -1319,7 +1356,7 @@
 							    TTY_OVERRUN;
                                         *tty->flip.char_buf_ptr++ = 0;
                                         /* If the flip buffer itself is
-                                           overflowing, we still loose
+                                           overflowing, we still lose
                                            the next incoming character.
                                          */
                                         if(tty->flip.count
@@ -1389,7 +1426,7 @@
                        is empty, we know we can always stuff a dozen
                        characters. */
 #ifdef CY_DEBUG_INTERRUPTS
-printk("cy_interrupt: xmit intr, chip %d\n\r", chip);
+		    printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
 #endif
 
                     /* determine the channel & change to that context */
@@ -1687,12 +1724,285 @@
 } /* cyz_update_channel */
 #endif
 
-
+#ifdef CONFIG_CYZ_INTR
 static void
 cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+  struct tty_struct *tty;
+  struct cyclades_card *cinfo;
+  struct cyclades_port *info;
+  static volatile struct FIRM_ID *firm_id;
+  static volatile struct ZFW_CTRL *zfw_ctrl;
+  static volatile struct BOARD_CTRL *board_ctrl;
+  static volatile struct CH_CTRL *ch_ctrl;
+  static volatile struct BUF_CTRL *buf_ctrl;
+  uclong channel;
+  ucchar cmd;
+  uclong param;
+  uclong hw_ver, fw_ver;
+  char data;
+  volatile int char_count, special_count;
+#ifdef BLOCKMOVE
+  int small_count;
+#endif
+  volatile uclong tx_put, tx_get, tx_bufsize;
+  volatile uclong rx_put, rx_get, rx_bufsize;
+
+    if((cinfo = (struct cyclades_card *)dev_id) == 0){
+#ifdef CY_DEBUG_INTERRUPTS
+	printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
+#endif
+        return; /* spurious interrupt */
+    }
+
+	firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
+        if (!ISZLOADED(*cinfo)) {
+#ifdef CY_DEBUG_INTERRUPTS
+	    printk("cyz_interrupt: board not yet loaded (INT %d).\n\r", irq);
+#endif
+	    return;
+	}
+
+	zfw_ctrl = (struct ZFW_CTRL *)
+	           (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
+	board_ctrl = &(zfw_ctrl->board_ctrl);
+	fw_ver = cy_readl(&board_ctrl->fw_version);
+	hw_ver = cy_readl(&((struct RUNTIME_9060 *)
+                            (cinfo->ctl_addr))->mail_box_0);
+
+	while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
+	    special_count = 0;
+	    info = &cy_port[channel + cinfo->first_line];
+            if((tty = info->tty) == 0) continue;
+	    ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
+	    buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
+
+	    switch(cmd){
+	    case C_CM_PR_ERROR:
+		tty->flip.count++;
+		*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+		*tty->flip.char_buf_ptr++ = 0;
+		special_count++;
+	        break;
+	    case C_CM_FR_ERROR:
+		tty->flip.count++;
+		*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+		*tty->flip.char_buf_ptr++ = 0;
+		special_count++;
+	        break;
+	    case C_CM_RXBRK:
+		tty->flip.count++;
+		*tty->flip.flag_buf_ptr++ = TTY_BREAK;
+		*tty->flip.char_buf_ptr++ = 0;
+		special_count++;
+	        break;
+	    case C_CM_MDCD:
+		if (info->flags & ASYNC_CHECK_CD){
+		    if ((fw_ver > 241 ? 
+                          ((u_long)param) : 
+                          cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
+			/* SP("Open Wakeup\n"); */
+			cy_sched_event(info,
+			    Cy_EVENT_OPEN_WAKEUP);
+		    }else if(!((info->flags
+				& ASYNC_CALLOUT_ACTIVE)
+			 &&(info->flags
+			    & ASYNC_CALLOUT_NOHUP))){
+			/* SP("Hangup\n"); */
+			cy_sched_event(info,
+			    Cy_EVENT_HANGUP);
+		    }
+		}
+	        break;
+	    case C_CM_MCTS:
+		if (info->flags & ASYNC_CTS_FLOW) {
+		    if(info->tty->hw_stopped){
+			if( cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD){
+			    /* cy_start isn't used because... 
+			       HW flow is handled by the board */
+			    /* SP("Write Wakeup\n"); */
+			    cy_sched_event(info,
+				Cy_EVENT_WRITE_WAKEUP);
+			}
+		    }else{
+			if(!(cy_readl(&ch_ctrl[channel].rs_status) & C_RS_CTS)){
+			    /* cy_stop isn't used because 
+			       HW flow is handled by the board */
+			    /* SP("Write stop\n"); */
+			}
+		    }
+		}
+	        break;
+	    case C_CM_MRI:
+	        break;
+	    case C_CM_MDSR:
+	        break;
+#ifdef Z_WAKE
+	    case C_CM_IOCTLW:
+		cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
+	        break;
+#endif
+	    case C_CM_RXHIWM:
+	    case C_CM_RXNNDT:
+		/* Reception Interrupt */
+#ifdef CY_DEBUG_INTERRUPTS
+	    printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r", 
+		info->card, channel);
+#endif
+
+	    rx_get = cy_readl(&buf_ctrl->rx_get);
+	    rx_put = cy_readl(&buf_ctrl->rx_put);
+	    rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
+	    if (rx_put >= rx_get)
+	    	char_count = rx_put - rx_get;
+	    else
+	    	char_count = rx_put - rx_get + rx_bufsize;
+
+	    if ( char_count ){
+
+#ifdef CY_ENABLE_MONITORING
+		info->mon.int_count++;
+		info->mon.char_count += char_count;
+		if (char_count > info->mon.char_max)
+		   info->mon.char_max = char_count;
+		info->mon.char_last = char_count;
+#endif
+		info->idle_stats.recv_bytes += char_count;
+		info->idle_stats.recv_idle   = jiffies;
+		if( tty == 0){
+		    /* flush received characters */
+		    rx_get = (rx_get + char_count) & (rx_bufsize - 1);
+		    /* SP("-"); */
+		    info->rflush_count++;
+		}else{
+#ifdef BLOCKMOVE
+		/* we'd like to use memcpy(t, f, n) and memset(s, c, count)
+		   for performance, but because of buffer boundaries, there
+		   may be several steps to the operation */
+		    while(0 < (small_count
+			= cy_min((rx_bufsize - rx_get),
+			         cy_min((TTY_FLIPBUF_SIZE - tty->flip.count),
+				        char_count)))){
+
+			memcpy_fromio(tty->flip.char_buf_ptr,
+			              (char *)(cinfo->base_addr
+				       + cy_readl(&buf_ctrl->rx_bufaddr)
+				       + rx_get),
+			              small_count);
+
+			tty->flip.char_buf_ptr += small_count;
+			memset(tty->flip.flag_buf_ptr,
+			       TTY_NORMAL,
+			       small_count);
+			tty->flip.flag_buf_ptr += small_count;
+			rx_get = (rx_get + small_count) & (rx_bufsize - 1);
+			char_count -= small_count;
+			tty->flip.count += small_count;
+		    }
+#else
+		    while(char_count--){
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE){
+				break;
+			}
+			data = cy_readb(cinfo->base_addr +
+			           cy_readl(&buf_ctrl->rx_bufaddr) + rx_get);
+			rx_get = (rx_get + 1) & (rx_bufsize - 1);
+			tty->flip.count++;
+			*tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+			*tty->flip.char_buf_ptr++ = data;
+		    }
+#endif
+		    queue_task(&tty->flip.tqueue, &tq_timer);
+		}
+		/* Update rx_get */
+		cy_writel(&buf_ctrl->rx_get, rx_get);
+	    }
+		break;
+	    case C_CM_TXBEMPTY:
+	    case C_CM_TXLOWWM:
+	    case C_CM_INTBACK:
+		/* Transmission Interrupt */
+#ifdef CY_DEBUG_INTERRUPTS
+	    printk("cyz_interrupt: xmit intr, card %d, port %ld\n\r", 
+		info->card, channel);
+#endif
+
+	    tx_get = cy_readl(&buf_ctrl->tx_get);
+	    tx_put = cy_readl(&buf_ctrl->tx_put);
+	    tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
+	    if (tx_put >= tx_get)
+	    	char_count = tx_get - tx_put - 1 + tx_bufsize;
+	    else
+	    	char_count = tx_get - tx_put - 1;
+
+	    if ( char_count ){
+
+		if( tty == 0 ){
+		    goto ztxdone;
+		}
+
+		if(info->x_char) { /* send special char */
+		    data = info->x_char;
+
+		    cy_writeb((cinfo->base_addr +
+		              cy_readl(&buf_ctrl->tx_bufaddr) + tx_put), data);
+		    tx_put = (tx_put + 1) & (tx_bufsize - 1);
+		    info->x_char = 0;
+		    char_count--;
+		}
+#ifdef BLOCKMOVE
+		while(0 < (small_count
+		    = cy_min((tx_bufsize - tx_put),
+			     cy_min ((SERIAL_XMIT_SIZE - info->xmit_tail),
+			             cy_min(info->xmit_cnt, char_count))))){
+
+		    memcpy_toio((char *)(cinfo->base_addr
+			         + cy_readl(&buf_ctrl->tx_bufaddr) + tx_put),
+			        &info->xmit_buf[info->xmit_tail],
+			        small_count);
+
+		    tx_put = (tx_put + small_count) & (tx_bufsize - 1);
+		    char_count -= small_count;
+		    info->xmit_cnt -= small_count;
+		    info->xmit_tail =
+		       (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
+		}
+#else
+		while (info->xmit_cnt && char_count){
+		    data = info->xmit_buf[info->xmit_tail];
+		    info->xmit_cnt--;
+		    info->xmit_tail =
+			(info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
+
+		    cy_writeb(cinfo->base_addr +
+		              cy_readl(&buf_ctrl->tx_bufaddr) + tx_put, 
+			      data);
+		    tx_put = (tx_put + 1) & (tx_bufsize - 1);
+		    char_count--;
+		}
+
+#endif
+	    ztxdone:
+		if (info->xmit_cnt < WAKEUP_CHARS) {
+		    cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
+		}
+		/* Update tx_put */
+		cy_writel(&buf_ctrl->tx_put, tx_put);
+	    }
+		break;
+	    case C_CM_FATAL:
+		/* should do something with this !!! */
+	        break;
+	    }
+	    if(special_count){
+		queue_task(&tty->flip.tqueue, &tq_timer);
+	    }
+	}
+
+    return;
 } /* cyz_interrupt */
 
+#else /* CONFIG_CYZ_INTR */
 
 static void
 cyz_poll(unsigned long arg)
@@ -1726,7 +2036,6 @@
 
 	firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
         if (!ISZLOADED(*cinfo)) {
-	    cinfo->inact_ctrl = 0;
 	    continue;
 	}
 
@@ -1737,12 +2046,6 @@
 	hw_ver = cy_readl(&((struct RUNTIME_9060 *)
                             (cinfo->ctl_addr))->mail_box_0);
 
-	/* Enables the firmware inactivity control */
-	if ((fw_ver > 0x00000310L) && (!cinfo->inact_ctrl)) {
-	    param = cyz_issue_cmd( &cy_card[card], 0L, C_CM_TINACT, 0L);
-	    cinfo->inact_ctrl = 1;
-	}
-
 	while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1){
 	    char_count = 0;
 	    info = &cy_port[ channel + cinfo->first_line ];
@@ -1984,17 +2287,13 @@
 	}
 	/* poll every 40 ms */
 	cyz_timerlist.expires = jiffies + cyz_polling_cycle;
-
-	/* refresh inactivity counter */
-	if (cinfo->inact_ctrl) {
-		cy_writel(&board_ctrl->inactivity, (uclong) ZF_TINACT);
-	}
     }
     add_timer(&cyz_timerlist);
 
     return;
 } /* cyz_poll */
 
+#endif /* CONFIG_CYZ_INTR */
 
 /********** End of block of Cyclades-Z specific code *********/
 /***********************************************************/
@@ -2103,12 +2402,27 @@
 
 	cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
 #ifdef Z_WAKE
-	cy_writel(&ch_ctrl[channel].intr_enable, 
-		  C_IN_MDCD|C_IN_MCTS|C_IN_IOCTLW);
+#ifdef CONFIG_CYZ_INTR
+	cy_writel(&ch_ctrl[channel].intr_enable,
+		  C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
+		  C_IN_IOCTLW|
+		  C_IN_MDCD|C_IN_MCTS);
 #else
-	cy_writel(&ch_ctrl[channel].intr_enable, 
+	cy_writel(&ch_ctrl[channel].intr_enable,
+		  C_IN_IOCTLW|
 		  C_IN_MDCD|C_IN_MCTS);
-#endif
+#endif /* CONFIG_CYZ_INTR */
+#else
+#ifdef CONFIG_CYZ_INTR
+	cy_writel(&ch_ctrl[channel].intr_enable,
+		  C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
+		  C_IN_MDCD|C_IN_MCTS);
+#else
+	cy_writel(&ch_ctrl[channel].intr_enable,
+		  C_IN_MDCD|C_IN_MCTS);
+#endif /* CONFIG_CYZ_INTR */
+#endif /* Z_WAKE */
+
 	retval = cyz_issue_cmd( &cy_card[card],
 	    channel, C_CM_IOCTL, 0L);	/* was C_CM_RESET */
 	if (retval != 0){
@@ -2171,11 +2485,21 @@
                cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
 	restore_flags(flags);
     } else {
+#ifdef CONFIG_CYZ_INTR
+	int retval;
+
+	save_flags(flags); cli();
+	    retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, 0L);
+	    if (retval != 0){
+		printk("cyc:start_xmit retval was %x\n", retval);
+	    }
+	restore_flags(flags);
+#else /* CONFIG_CYZ_INTR */
 	/* Don't have to do anything at this time */
+#endif /* CONFIG_CYZ_INTR */
     }
 } /* start_xmit */
 
-
 /*
  * This routine shuts down a serial port; interrupts are disabled,
  * and DTR is dropped if the hangup on close termio flag is on.
@@ -2557,8 +2881,24 @@
 	    } else {
 		printk("Cyclades-Z firmware not yet loaded\n");
 	    }
+	    MOD_DEC_USE_COUNT;
 	    return -ENODEV;
 	}
+#ifdef CONFIG_CYZ_INTR
+	else {
+	    /* In case this Z board is operating in interrupt mode, its
+	       interrupts should be enabled as soon as the first open happens
+	       to one of its ports. */
+	    if (!cy_card[info->card].intr_enabled) {
+		retval = cyz_issue_cmd(&cy_card[info->card],
+					0, C_CM_IRQ_ENBL, 0L);
+		if (retval != 0){
+		    printk("cyc:IRQ enable retval was %x\n", retval);
+		}
+		cy_card[info->card].intr_enabled = 1;
+	    }
+	}
+#endif /* CONFIG_CYZ_INTR */
     }
 #ifdef CY_DEBUG_OTHER
     printk("cyc:cy_open ttyC%d\n", info->line); /* */
@@ -4139,6 +4479,7 @@
 	case CYGETCD1400VER:
 	    ret_val = info->chip_rev;
 	    break;
+#ifndef CONFIG_CYZ_INTR
 	case CYZSETPOLLCYCLE:
             cyz_polling_cycle = (arg * HZ) / 1000;
 	    ret_val = 0;
@@ -4146,6 +4487,7 @@
 	case CYZGETPOLLCYCLE:
             ret_val = (cyz_polling_cycle * 1000) / HZ;
 	    break;
+#endif /* CONFIG_CYZ_INTR */
 	case CYSETWAIT:
     	    info->closing_wait = (unsigned short)arg * HZ/100;
 	    ret_val = 0;
@@ -4254,7 +4596,8 @@
     printk("cyc:cy_set_termios ttyC%d\n", info->line);
 #endif
 
-    if (tty->termios->c_cflag == old_termios->c_cflag)
+    if ((tty->termios->c_cflag == old_termios->c_cflag) &&
+	((tty->termios->c_iflag & IXON) == (old_termios->c_iflag & IXON)))
         return;
     set_line_char(info);
 
@@ -4272,16 +4615,6 @@
     return;
 } /* cy_set_termios */
 
-
-/*
- * void (*set_ldisc)(struct tty_struct *tty);
- *
- * 	This routine allows the tty driver to be notified when the
- * 	device's termios settings have changed.
- * 
- */
-
-
 /* This routine is called by the upper-layer tty layer to signal
    that incoming characters should be throttled because the input
    buffers are close to full.
@@ -4483,7 +4816,7 @@
 cy_flush_buffer(struct tty_struct *tty)
 {
   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  int card, channel;
+  int card, channel, retval;
   unsigned long flags;
                                 
 #ifdef CY_DEBUG_IO
@@ -4501,19 +4834,10 @@
 
     if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board 
 				      buffers as well */
-	static volatile struct FIRM_ID *firm_id;
-	static volatile struct ZFW_CTRL *zfw_ctrl;
-	static volatile struct CH_CTRL *ch_ctrl;
-	static volatile struct BUF_CTRL *buf_ctrl;
-
-	firm_id = (struct FIRM_ID *)(cy_card[card].base_addr + ID_ADDRESS);
-	zfw_ctrl = (struct ZFW_CTRL *) (cy_card[card].base_addr +
-				cy_readl(&firm_id->zfwctrl_addr));
-	ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
-	buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
-
-	while (cy_readl(&buf_ctrl->tx_get) != cy_readl(&buf_ctrl->tx_put))
-		cy_writel(&buf_ctrl->tx_put, cy_readl(&buf_ctrl->tx_get));
+	retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L);
+	if (retval != 0) {
+	    printk("cyc: flush_buffer retval was %x\n", retval);
+	}
     }
     wake_up_interruptible(&tty->write_wait);
     if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
@@ -4639,6 +4963,7 @@
     return chip_number;
 } /* cyy_init_card */
 
+#ifndef CONFIG_COBALT_27
 /*
  * ---------------------------------------------------------------------
  * cy_detect_isa() - Probe for Cyclom-Y/ISA boards.
@@ -4699,7 +5024,7 @@
 
                 /* allocate IRQ */
                 if(request_irq(cy_isa_irq, cyy_interrupt,
-				   SA_INTERRUPT, "cyclomY", NULL))
+				   SA_INTERRUPT, "Cyclom-Y", &cy_card[j]))
                 {
                         printk("Cyclom-Y/ISA found at 0x%lx ",
                                 (unsigned long) cy_isa_address);
@@ -4715,7 +5040,6 @@
                 cy_card[j].bus_index = 0;
                 cy_card[j].first_line = cy_next_channel;
                 cy_card[j].num_chips = cy_isa_nchan/4;
-                IRQ_cards[cy_isa_irq] = &cy_card[j];
                 nboard++;
                         
                 /* print message */
@@ -4730,6 +5054,20 @@
         return(nboard);
 
 } /* cy_detect_isa */
+#endif /* CONFIG_COBALT_27 */
+
+static void plx_init(uclong addr, uclong initctl)
+{
+    /* Reset PLX */
+    cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
+    udelay(100L);
+    cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000);
+
+    /* Reload Config. Registers from EEPROM */
+    cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000);
+    udelay(100L);
+    cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000);
+}
 
 /*
  * ---------------------------------------------------------------------
@@ -4800,6 +5138,12 @@
 		cy_pci_addr0  &= PCI_BASE_ADDRESS_MEM_MASK;
 		cy_pci_addr2  &= PCI_BASE_ADDRESS_MEM_MASK;
 
+		if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) {
+		    printk("  Warning: PCI I/O bit incorrectly set. "
+			   "Ignoring it...\n");
+		    cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
+		}
+
 #if defined(__alpha__)
                 if (device_id  == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
 		    printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
@@ -4817,7 +5161,9 @@
 		cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0 & PAGE_MASK, 
 					PAGE_ALIGN(CyPCI_Yctl)) 
 				+ (cy_pci_addr0 & (PAGE_SIZE-1));
+#ifndef CONFIG_COBALT_27
                 if ((ulong)cy_pci_addr2 >= 0x100000)  /* above 1M? */
+#endif /* CONFIG_COBALT_27 */
                     cy_pci_addr2 = (ulong) ioremap(cy_pci_addr2, CyPCI_Ywin);
 #endif
 
@@ -4855,7 +5201,7 @@
 
                 /* allocate IRQ */
                 if(request_irq(cy_pci_irq, cyy_interrupt,
-		        SA_INTERRUPT, "cyclomY", NULL))
+		        SA_SHIRQ, "Cyclom-Y", &cy_card[j]))
                 {
                         printk("Cyclom-Y/PCI found at 0x%lx ",
 			    (ulong) cy_pci_addr2);
@@ -4871,13 +5217,14 @@
                 cy_card[j].bus_index = 1;
                 cy_card[j].first_line = cy_next_channel;
                 cy_card[j].num_chips = cy_pci_nchan/4;
-                IRQ_cards[cy_pci_irq] = &cy_card[j];
 
 		/* enable interrupts in the PCI interface */
 		plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
                 switch (plx_ver) {
 		    case PLX_9050:
 
+		    plx_init(cy_pci_addr0, 0x50);
+
 		    cy_writew(cy_pci_addr0+0x4c,
 			cy_readw(cy_pci_addr0+0x4c)|0x0040);
 		    break;
@@ -4886,6 +5233,14 @@
 		    case PLX_9080:
 		    default: /* Old boards, use PLX_9060 */
 
+		    plx_init(cy_pci_addr0, 0x6c);
+		    /* For some yet unknown reason, once the PLX9060 reloads 
+		       the EEPROM, the IRQ is lost and, thus, we have to 
+		       re-write it to the PCI config. registers.
+		       This will remain here until we find a permanent fix. */
+		    pcibios_write_config_byte(cyy_bus, cyy_dev_fn,
+					PCI_INTERRUPT_LINE, cy_pci_irq);
+
 		    cy_writew(cy_pci_addr0+0x68,
 			cy_readw(cy_pci_addr0+0x68)|0x0900);
 		    break;
@@ -4921,15 +5276,31 @@
                 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
 #endif
                 cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
+
 #if !defined(__alpha__)
                 cy_pci_addr0 = (unsigned int) ioremap(
                                cy_pci_addr0 & PAGE_MASK,
                                PAGE_ALIGN(CyPCI_Zctl))
                                + (cy_pci_addr0 & (PAGE_SIZE-1));
 #endif
+
+		plx_init(cy_pci_addr0, 0x6c);
+		/* For some yet unknown reason, once the PLX9060 reloads 
+		   the EEPROM, the IRQ is lost and, thus, we have to 
+		   re-write it to the PCI config. registers.
+		   This will remain here until we find a permanent fix. */
+		pcibios_write_config_byte(cyy_bus, cyy_dev_fn,
+				PCI_INTERRUPT_LINE, cy_pci_irq);
+
 		mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *) 
 			   cy_pci_addr0)->mail_box_0);
                 cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
+
+		if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) { 
+		    printk("  Warning: PCI I/O bit incorrectly set. "
+			   "Ignoring it...\n");
+		    cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
+		}
 		if (mailbox == ZE_V1) {
 #if !defined(__alpha__)
                	    cy_pci_addr2 = (unsigned int) ioremap(
@@ -5009,10 +5380,11 @@
 		    return(i);
                 }
 
+#ifdef CONFIG_CYZ_INTR
                 /* allocate IRQ only if board has an IRQ */
-		if( (1 < cy_pci_irq) && (cy_pci_irq < 15) ) {
-		    if(request_irq(cy_pci_irq,cyz_interrupt,
-			SA_INTERRUPT,"cyclomZ",NULL))
+		if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
+		    if(request_irq(cy_pci_irq, cyz_interrupt,
+			SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
 		    {
 			printk("Could not allocate IRQ%d ",
 			    cy_pci_irq);
@@ -5021,6 +5393,7 @@
 			return(i);
 		    }
 		}
+#endif /* CONFIG_CYZ_INTR */
 
 
                 /* set cy_card */
@@ -5030,22 +5403,28 @@
                 cy_card[j].bus_index = 1;
                 cy_card[j].first_line = cy_next_channel;
                 cy_card[j].num_chips = -1;
-                IRQ_cards[cy_pci_irq] = &cy_card[j];
 
                 /* print message */
+#ifdef CONFIG_CYZ_INTR
 		/* don't report IRQ if board is no IRQ */
-		if( (cy_pci_irq < 15) && (cy_pci_irq > 1) ) {
+		if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
 		    printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
 			j+1,(ulong)cy_pci_addr2,
 			(ulong)(cy_pci_addr2 + CyPCI_Zwin - 1),
 			(int)cy_pci_irq);
-		}else{
+		else
+#endif /* CONFIG_CYZ_INTR */
 		    printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
 			j+1,(ulong)cy_pci_addr2,
 			(ulong)(cy_pci_addr2 + CyPCI_Zwin - 1));
-		}
+
                 printk("%d channels starting from port %d.\n",
 		    cy_pci_nchan,cy_next_channel);
+#ifdef CONFIG_CYZ_INTR
+		/* Enable interrupts on the PLX chip */
+		cy_writew(cy_pci_addr0+0x68,
+			cy_readw(cy_pci_addr0+0x68)|0x0900);
+#endif /* CONFIG_CYZ_INTR */
                 cy_next_channel += cy_pci_nchan;
     }
         }
@@ -5065,10 +5444,6 @@
                 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
 	    printk("Cyclades-Z/PCI: New Cyclades-Z board.  FPGA not loaded\n");
 #endif
-	    /* The following clears the firmware id word.  This ensures
-	       that the driver will not attempt to talk to the board
-	       until it has been properly initialized.
-	     */
 		PAUSE
                 /* This must be the new Cyclades-Ze/PCI. */
                 cy_pci_nchan = ZE_V1_NPORTS;
@@ -5093,10 +5468,11 @@
 		    return(i);
                 }
 
+#ifdef CONFIG_CYZ_INTR
                 /* allocate IRQ only if board has an IRQ */
-		if( (1 < cy_pci_irq) && (cy_pci_irq < 15) ) {
-		    if(request_irq(cy_pci_irq,cyz_interrupt,
-			SA_INTERRUPT,"cyclomZ",NULL))
+		if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
+		    if(request_irq(cy_pci_irq, cyz_interrupt,
+			SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
 		    {
 			printk("Could not allocate IRQ%d ",
 			    cy_pci_irq);
@@ -5105,6 +5481,7 @@
 			return(i);
 		    }
 		}
+#endif /* CONFIG_CYZ_INTR */
 
                 /* set cy_card */
                 cy_card[j].base_addr = cy_pci_addr2;
@@ -5113,22 +5490,28 @@
                 cy_card[j].bus_index = 1;
                 cy_card[j].first_line = cy_next_channel;
                 cy_card[j].num_chips = -1;
-                IRQ_cards[cy_pci_irq] = &cy_card[j];
 
                 /* print message */
+#ifdef CONFIG_CYZ_INTR
 		/* don't report IRQ if board is no IRQ */
-		if( (cy_pci_irq < 15) && (cy_pci_irq > 1) ) {
+		if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
 		    printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
 			j+1,(ulong)cy_pci_addr2,
 			(ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1),
 			(int)cy_pci_irq);
-		}else{
+		else
+#endif /* CONFIG_CYZ_INTR */
 		    printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
 			j+1,(ulong)cy_pci_addr2,
 			(ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1));
-		}
+
                 printk("%d channels starting from port %d.\n",
 		    cy_pci_nchan,cy_next_channel);
+#ifdef CONFIG_CYZ_INTR
+		/* Enable interrupts on the PLX chip */
+		cy_writew(cy_pci_addr0+0x68,
+			cy_readw(cy_pci_addr0+0x68)|0x0900);
+#endif /* CONFIG_CYZ_INTR */
                 cy_next_channel += cy_pci_nchan;
         }
 	if (ZeIndex != 0) {
@@ -5299,10 +5682,6 @@
 
     init_bh(CYCLADES_BH, do_cyclades_bh);
 
-    for (i = 0; i < 16; i++) {
-            IRQ_cards[i] = 0;
-    }
-
     for (i = 0; i < NR_CARDS; i++) {
             /* base_addr=0 indicates board not found */
             cy_card[i].base_addr = 0;
@@ -5315,8 +5694,10 @@
        availability of cy_card and cy_port data structures and updating
        the cy_next_channel. */
 
+#ifndef CONFIG_COBALT_27
     /* look for isa boards */
     cy_isa_nboard = cy_detect_isa();
+#endif /* CONFIG_COBALT_27 */
     
     /* look for pci boards */
     cy_pci_nboard = cy_detect_pci();
@@ -5348,6 +5729,7 @@
 		mailbox = cy_readl(&((struct RUNTIME_9060 *)
 			     cy_card[board].ctl_addr)->mail_box_0);
 		nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
+		cinfo->intr_enabled = 0;
                 for (port = cinfo->first_line ;
                      port < cinfo->first_line + nports;
                      port++)
@@ -5471,15 +5853,17 @@
                 }
             }
     }
-    
-    if ( number_z_boards && !cyz_timeron){
-        cyz_timeron++;
+
+#ifndef CONFIG_CYZ_INTR
+    if (number_z_boards && !cyz_timeron){
+	cyz_timeron++;
 	cyz_timerlist.expires = jiffies + 1;
 	add_timer(&cyz_timerlist);
 #ifdef CY_PCI_DEBUG
 	printk("Cyclades-Z polling initialized\n");
 #endif
     }
+#endif /* CONFIG_CYZ_INTR */
 
 #if defined(CONFIG_PROC_FS) && !defined(MODULE)
     proc_register_dynamic(&proc_root, &cyclades_proc_entry);
@@ -5504,10 +5888,12 @@
     int i;
     unsigned long flags;
 
+#ifndef CONFIG_CYZ_INTR
     if (cyz_timeron){
 	cyz_timeron = 0;
 	del_timer(&cyz_timerlist);
     }
+#endif /* CONFIG_CYZ_INTR */
 
     save_flags(flags); cli();
 
@@ -5521,9 +5907,12 @@
 
     for (i = 0; i < NR_CARDS; i++) {
         if (cy_card[i].base_addr != 0
+#ifndef CONFIG_CYZ_INTR
+	    && cy_card[i].num_chips != -1 /* not a Z card */
+#endif /* CONFIG_CYZ_INTR */
 	    && cy_card[i].irq)
         {
-            free_irq(cy_card[i].irq,NULL);
+            free_irq(cy_card[i].irq, &cy_card[i]);
         }
     }
 } /* cleanup_module */
@@ -5532,6 +5921,7 @@
 void
 cy_setup(char *str, int *ints)
 {
+#ifndef CONFIG_COBALT_27
   int i, j;
 
     for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
@@ -5542,6 +5932,7 @@
             cy_isa_addresses[i++] = (unsigned char *)(ints[j]);
         }
     }
+#endif /* CONFIG_COBALT_27 */
 
 } /* cy_setup */
 #endif
diff -u --recursive --new-file linux-2.0.38/drivers/isdn/Config.in linux-2.0.39/drivers/isdn/Config.in
--- linux-2.0.38/drivers/isdn/Config.in	Sun Nov 15 19:32:56 1998
+++ linux-2.0.39/drivers/isdn/Config.in	Mon Feb  7 22:09:39 2000
@@ -2,53 +2,53 @@
 # ISDN device configuration
 #
 if [ "$CONFIG_INET" != "n" ]; then
-  bool 'Support synchronous PPP' CONFIG_ISDN_PPP
-  if [ "$CONFIG_ISDN_PPP" != "n" ]; then
-    bool 'Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
-    bool 'Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
-  fi
-  #bool 'Support dynamic timeout-rules' CONFIG_ISDN_TIMEOUT_RULES
-  #if [ "$CONFIG_ISDN_TIMEOUT_RULES" != "n" ]; then
-  #  bool 'Use masqueraded addresses for rule-matching' CONFIG_ISDN_TIMRU_USE_MASQ
-  #fi
-  #bool 'Support budget-accounting' CONFIG_ISDN_BUDGET
+   bool '  Support synchronous PPP' CONFIG_ISDN_PPP
+   if [ "$CONFIG_ISDN_PPP" != "n" ]; then
+      bool '    Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
+      bool '    Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
+   fi
+#   bool '  Support dynamic timeout-rules' CONFIG_ISDN_TIMEOUT_RULES
+#   if [ "$CONFIG_ISDN_TIMEOUT_RULES" != "n" ]; then
+#      bool '    Use masqueraded addresses for rule-matching' CONFIG_ISDN_TIMRU_USE_MASQ
+#   fi
+#   bool '  Support budget-accounting' CONFIG_ISDN_BUDGET
 fi
-bool 'Support audio via ISDN' CONFIG_ISDN_AUDIO
-dep_tristate 'ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN
-dep_tristate 'isdnloop support' CONFIG_ISDN_DRV_LOOP $CONFIG_ISDN
-dep_tristate 'PCBIT-D support' CONFIG_ISDN_DRV_PCBIT $CONFIG_ISDN
-dep_tristate 'HiSax SiemensChipSet driver support' CONFIG_ISDN_DRV_HISAX $CONFIG_ISDN
+bool '  Support audio via ISDN' CONFIG_ISDN_AUDIO
+dep_tristate '  ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN
+dep_tristate '  isdnloop support' CONFIG_ISDN_DRV_LOOP $CONFIG_ISDN
+dep_tristate '  PCBIT-D support' CONFIG_ISDN_DRV_PCBIT $CONFIG_ISDN
+dep_tristate '  HiSax SiemensChipSet driver support' CONFIG_ISDN_DRV_HISAX $CONFIG_ISDN
 if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
-    bool 'HiSax Support for EURO/DSS1' CONFIG_HISAX_EURO
-    if [ "$CONFIG_HISAX_EURO" != "n" ]; then
-	    bool 'Support for german chargeinfo' CONFIG_DE_AOC
-	    bool 'Disable sending complete' CONFIG_HISAX_NO_SENDCOMPLETE
-	    bool 'Disable sending low layer compatibility' CONFIG_HISAX_NO_LLC
-    fi
-    bool 'HiSax Support for german 1TR6' CONFIG_HISAX_1TR6
-    bool 'HiSax Support for Teles 16.0/8.0' CONFIG_HISAX_16_0
-    bool 'HiSax Support for Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3
-    bool 'HiSax Support for Teles 16.3c' CONFIG_HISAX_TELES3C 
-    bool 'HiSax Support for Teles PCI' CONFIG_HISAX_TELESPCI 
-    bool 'HiSax Support for Teles S0Box' CONFIG_HISAX_S0BOX 
-    bool 'HiSax Support for AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1
-    bool 'HiSax Support for AVM PnP/PCI (Fritz!PnP/PCI)' CONFIG_HISAX_FRITZPCI
-    bool 'HiSax Support for AVM A1 PCMCIA (Fritz)' CONFIG_HISAX_AVM_A1_PCMCIA
-    bool 'HiSax Support for Elsa cards' CONFIG_HISAX_ELSA
-    bool 'HiSax Support for ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2
-    bool 'HiSax Support for Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA
-    bool 'HiSax Support for ASUSCOM cards' CONFIG_HISAX_ASUSCOM
-    bool 'HiSax Support for TELEINT cards' CONFIG_HISAX_TELEINT
-    bool 'HiSax Support for Sedlbauer cards' CONFIG_HISAX_SEDLBAUER
-    bool 'HiSax Support for USR Sportster internal TA' CONFIG_HISAX_SPORTSTER
-    bool 'HiSax Support for MIC card' CONFIG_HISAX_MIC
-    bool 'HiSax Support for NETjet card' CONFIG_HISAX_NETJET
-    bool 'HiSax Support for Niccy PnP/PCI card' CONFIG_HISAX_NICCY
+   bool '  HiSax Support for EURO/DSS1' CONFIG_HISAX_EURO
+   if [ "$CONFIG_HISAX_EURO" != "n" ]; then
+      bool '    Support for german chargeinfo' CONFIG_DE_AOC
+      bool '    Disable sending complete' CONFIG_HISAX_NO_SENDCOMPLETE
+      bool '    Disable sending low layer compatibility' CONFIG_HISAX_NO_LLC
+   fi
+   bool '  HiSax Support for german 1TR6' CONFIG_HISAX_1TR6
+   bool '  HiSax Support for Teles 16.0/8.0' CONFIG_HISAX_16_0
+   bool '  HiSax Support for Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3
+   bool '  HiSax Support for Teles 16.3c' CONFIG_HISAX_TELES3C 
+   bool '  HiSax Support for Teles PCI' CONFIG_HISAX_TELESPCI 
+   bool '  HiSax Support for Teles S0Box' CONFIG_HISAX_S0BOX 
+   bool '  HiSax Support for AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1
+   bool '  HiSax Support for AVM PnP/PCI (Fritz!PnP/PCI)' CONFIG_HISAX_FRITZPCI
+   bool '  HiSax Support for AVM A1 PCMCIA (Fritz)' CONFIG_HISAX_AVM_A1_PCMCIA
+   bool '  HiSax Support for Elsa cards' CONFIG_HISAX_ELSA
+   bool '  HiSax Support for ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2
+   bool '  HiSax Support for Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA
+   bool '  HiSax Support for ASUSCOM cards' CONFIG_HISAX_ASUSCOM
+   bool '  HiSax Support for TELEINT cards' CONFIG_HISAX_TELEINT
+   bool '  HiSax Support for Sedlbauer cards' CONFIG_HISAX_SEDLBAUER
+   bool '  HiSax Support for USR Sportster internal TA' CONFIG_HISAX_SPORTSTER
+   bool '  HiSax Support for MIC card' CONFIG_HISAX_MIC
+   bool '  HiSax Support for NETjet card' CONFIG_HISAX_NETJET
+   bool '  HiSax Support for Niccy PnP/PCI card' CONFIG_HISAX_NICCY
 fi
 if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
-	dep_tristate 'Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN
+   dep_tristate '  Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN
 fi
-dep_tristate 'AVM-B1 with CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN
+dep_tristate '  AVM-B1 with CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN
 if [ "$CONFIG_ISDN_DRV_AVMB1" != "n" ]; then
-    bool 'Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
+   bool '    Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
 fi
diff -u --recursive --new-file linux-2.0.38/drivers/net/Config.in linux-2.0.39/drivers/net/Config.in
--- linux-2.0.38/drivers/net/Config.in	Sun Nov 15 19:33:02 1998
+++ linux-2.0.39/drivers/net/Config.in	Wed Jun 28 14:51:10 2000
@@ -4,148 +4,146 @@
 tristate 'Dummy net driver support' CONFIG_DUMMY
 tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'Frame relay DLCI support (EXPERIMENTAL)' CONFIG_DLCI
-  if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then
-    int '  Max open DLCI' CONFIG_DLCI_COUNT 24
-    int '  Max DLCI per device' CONFIG_DLCI_MAX 8
-    dep_tristate '  SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI
-  fi
+   tristate 'Frame relay DLCI support (EXPERIMENTAL)' CONFIG_DLCI
+   if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then
+      int '  Max open DLCI' CONFIG_DLCI_COUNT 24
+      int '  Max DLCI per device' CONFIG_DLCI_MAX 8
+      dep_tristate '  SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI
+   fi
 fi
 tristate 'PLIP (parallel port) support' CONFIG_PLIP
 tristate 'PPP (point-to-point) support' CONFIG_PPP
-if [ ! "$CONFIG_PPP" = "n" ]; then
-  comment 'CCP compressors for PPP are only built as modules.'
+if [ "$CONFIG_PPP" != "n" ]; then
+   comment '  CCP compressors for PPP are only built as modules.'
 fi
 tristate 'SLIP (serial line) support' CONFIG_SLIP
 if [ "$CONFIG_SLIP" != "n" ]; then
-  bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
-  bool ' Keepalive and linefill' CONFIG_SLIP_SMART
-  bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
+   bool '  CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
+   bool '  Keepalive and linefill' CONFIG_SLIP_SMART
+   bool '  Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
 fi
 bool 'Radio network interfaces' CONFIG_NET_RADIO
 if [ "$CONFIG_NET_RADIO" != "n" ]; then
-  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-    tristate 'BAYCOM ser12 and par96 driver for AX.25' CONFIG_BAYCOM
-    tristate 'Soundcard modem driver for AX.25' CONFIG_SOUNDMODEM
-    if [ "$CONFIG_SOUNDMODEM" != "n" ]; then
-      bool 'Soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC
-      bool 'Soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS
-      bool 'Soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200
-      bool 'Soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7
-      bool 'Soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
-      bool 'Soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666
-      bool 'Soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
-      bool 'Soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800
-      bool 'Soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
-    fi
-  fi
-  tristate 'Serial port KISS driver for AX.25' CONFIG_MKISS
-  tristate 'BPQ Ethernet driver for AX.25' CONFIG_BPQETHER
-  tristate 'Gracilis PackeTwin support for AX.25' CONFIG_PT
-  tristate 'Ottawa PI and PI/2 support for AX.25' CONFIG_PI
-  tristate 'Z8530 SCC KISS emulation driver for AX.25' CONFIG_SCC
-  tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP
-  tristate 'AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate '  BAYCOM ser12 and par96 driver for AX.25 (EXPERIMENTAL)' CONFIG_BAYCOM
+      tristate '  Soundcard modem driver for AX.25 (EXPERIMENTAL)' CONFIG_SOUNDMODEM
+      if [ "$CONFIG_SOUNDMODEM" != "n" ]; then
+	 bool '    Soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC
+	 bool '    Soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS
+	 bool '    Soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200
+	 bool '    Soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7
+	 bool '    Soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
+	 bool '    Soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666
+	 bool '    Soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
+	 bool '    Soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800
+	 bool '    Soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
+      fi
+   fi
+   tristate '  Serial port KISS driver for AX.25' CONFIG_MKISS
+   tristate '  BPQ Ethernet driver for AX.25' CONFIG_BPQETHER
+   tristate '  Gracilis PackeTwin support for AX.25' CONFIG_PT
+   tristate '  Ottawa PI and PI/2 support for AX.25' CONFIG_PI
+   tristate '  Z8530 SCC KISS emulation driver for AX.25' CONFIG_SCC
+   tristate '  STRIP (Metricom starmode radio IP)' CONFIG_STRIP
+   tristate '  AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN
 fi
 #
 #	Ethernet
 #
 bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
 if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
-  bool '3COM ISA, EISA and PCI cards' CONFIG_NET_VENDOR_3COM
-  if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
-    tristate '3c501 support' CONFIG_EL1
-    tristate '3c503 support' CONFIG_EL2
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      tristate '3c505 support' CONFIG_ELPLUS
-      tristate '3c507 support' CONFIG_EL16
-    fi
-    tristate '3c509/3c579 support' CONFIG_EL3
-    tristate '3c515 ISA Fast EtherLink' CONFIG_3C515
-    tristate '3c590/3c900 series (592/595/597/900/905) "Vortex/Boomerang" support' CONFIG_VORTEX
-  fi
-  bool 'Western Digital/SMC ISA and EISA cards' CONFIG_NET_VENDOR_SMC
-  if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
-    tristate 'WD80*3 support' CONFIG_WD80x3
-    tristate 'SMC Ultra support' CONFIG_ULTRA
-    tristate 'SMC Ultra32 support' CONFIG_ULTRA32
-    tristate 'SMC 9194 support' CONFIG_SMC9194
-  fi
-  bool 'PCI Ethernet adapters' CONFIG_NET_PCI
-  if [ "$CONFIG_NET_PCI" = "y" ]; then
-    tristate 'AMD PCI PCnet32 (PCI bus NE2100 cards) support' CONFIG_PCNET32
-    tristate 'Intel EtherExpressPro PCI 10+/100B/100+ support' CONFIG_EEXPRESS_PRO100B
-    tristate 'DE425, DE434, DE435, DE450, DE500 support' CONFIG_DE4X5
-    tristate 'DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP
-    tristate 'Digi Intl. RightSwitch SE-X support' CONFIG_DGRS
-    tristate 'PCI NE2000 support' CONFIG_NE2K_PCI
-    tristate 'Packet Engines Yellowfin Gigabit-NIC support' CONFIG_YELLOWFIN
-    tristate 'RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139
-    tristate 'SMC EPIC/100 (EtherPower II) support' CONFIG_EPIC
-    tristate 'TI ThunderLAN support' CONFIG_TLAN
-    tristate 'VIA Rhine support' CONFIG_VIA_RHINE
-  fi
-  bool 'Other ISA cards' CONFIG_NET_ISA
-  if [ "$CONFIG_NET_ISA" = "y" ]; then
-    tristate 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE
-    tristate 'AT1700 (Fujitsu 86965) support' CONFIG_AT1700
-    tristate 'Cabletron E21xx support' CONFIG_E2100
-    tristate 'DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA
-    tristate 'EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3
-    tristate 'EtherExpress 16 support' CONFIG_EEXPRESS
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO
-      tristate 'FMV-181/182/183/184 support' CONFIG_FMV18X
-    fi
-    tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS
-    tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN
-    tristate 'HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      tristate 'ICL EtherTeam 16i/32 support' CONFIG_ETH16I
-    fi
-    tristate 'NE2000/NE1000 ISA support' CONFIG_NE2000
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      tristate 'NI5210 support' CONFIG_NI52
-      tristate 'NI6510 support' CONFIG_NI65
-    fi
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      bool 'SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005
-    fi
-    bool 'SK_G16 support' CONFIG_SK_G16
-  fi
-  bool 'EISA, VLB and other board controllers' CONFIG_NET_EISA
-  if [ "$CONFIG_NET_EISA" = "y" ]; then
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200
-    fi
-    tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      bool 'Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET
-    fi
-  fi
-  bool 'Pocket and portable adaptors' CONFIG_NET_POCKET
-  if [ "$CONFIG_NET_POCKET" = "y" ]; then
-    tristate 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP
-    tristate 'D-Link DE600 pocket adaptor support' CONFIG_DE600
-    tristate 'D-Link DE620 pocket adaptor support' CONFIG_DE620
-  fi
+   bool '  3COM ISA, EISA and PCI cards' CONFIG_NET_VENDOR_3COM
+   if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
+      tristate '    3c501 "EtherLink" support' CONFIG_EL1
+      tristate '    3c503 "EtherLink II" support' CONFIG_EL2
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	 tristate '    3c505 "EtherLink Plus" (EXPERIMENTAL) support' CONFIG_ELPLUS
+	 tristate '    3c507 "EtherLink 16" (EXPERIMENTAL) support' CONFIG_EL16
+      fi
+      tristate '    3c509/3c579 "EtherLink III" support' CONFIG_EL3
+      tristate '    3c515 ISA "Fast EtherLink"' CONFIG_3C515
+      tristate '    3c590/3c900 series (592/595/597/900/905) "Vortex/Boomerang" support' CONFIG_VORTEX
+   fi
+   bool '  Western Digital/SMC ISA and EISA cards' CONFIG_NET_VENDOR_SMC
+   if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
+      tristate '    WD80*3 support' CONFIG_WD80x3
+      tristate '    SMC Ultra support' CONFIG_ULTRA
+      tristate '    SMC Ultra32 support' CONFIG_ULTRA32
+      tristate '    SMC 9194 support' CONFIG_SMC9194
+   fi
+   bool '  PCI Ethernet adapters' CONFIG_NET_PCI
+   if [ "$CONFIG_NET_PCI" = "y" ]; then
+      tristate '    AMD PCI PCnet32 (PCI bus NE2100 cards) support' CONFIG_PCNET32
+      tristate '    Intel EtherExpressPro PCI 10+/100B/100+ support' CONFIG_EEXPRESS_PRO100B
+      tristate '    DE425, DE434, DE435, DE450, DE500 support' CONFIG_DE4X5
+      tristate '    DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP
+      tristate '    Digi Intl. RightSwitch SE-X support' CONFIG_DGRS
+      tristate '    PCI NE2000 support' CONFIG_NE2K_PCI
+      tristate '    Packet Engines Yellowfin Gigabit-NIC support' CONFIG_YELLOWFIN
+      tristate '    RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139
+      tristate '    SMC EPIC/100 (EtherPower II) support' CONFIG_EPIC
+      tristate '    TI ThunderLAN support' CONFIG_TLAN
+      tristate '    VIA Rhine support' CONFIG_VIA_RHINE
+   fi
+   bool '  Other ISA cards' CONFIG_NET_ISA
+   if [ "$CONFIG_NET_ISA" = "y" ]; then
+      tristate '    AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE
+      tristate '    AT1700 (Fujitsu 86965) support' CONFIG_AT1700
+      tristate '    Cabletron E21xx support' CONFIG_E2100
+      tristate '    DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA
+      tristate '    EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3
+      tristate '    EtherExpress 16 support' CONFIG_EEXPRESS
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	 tristate '    EtherExpressPro support (EXPERIMENTAL)' CONFIG_EEXPRESS_PRO
+	 tristate '    FMV-181/182/183/184 support (EXPERIMENTAL)' CONFIG_FMV18X
+      fi
+      tristate '    HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS
+      tristate '    HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN
+      tristate '    HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	 tristate '    ICL EtherTeam 16i/32 support (EXPERIMENTAL)' CONFIG_ETH16I
+      fi
+      tristate '    NE2000/NE1000 ISA support' CONFIG_NE2000
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	 tristate '    NI5210 support (EXPERIMENTAL)' CONFIG_NI52
+	 tristate '    NI6510 support (EXPERIMENTAL)' CONFIG_NI65
+	 bool '    SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005
+      fi
+      bool '    SK_G16 support' CONFIG_SK_G16
+   fi
+   bool '  EISA, VLB and other board controllers' CONFIG_NET_EISA
+   if [ "$CONFIG_NET_EISA" = "y" ]; then
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	 tristate '    Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200
+      fi
+      tristate '    Apricot Xen-II on board ethernet' CONFIG_APRICOT
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	 bool '    Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET
+      fi
+   fi
+   bool '  Pocket and portable adaptors' CONFIG_NET_POCKET
+   if [ "$CONFIG_NET_POCKET" = "y" ]; then
+      tristate '    AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP
+      tristate '    D-Link DE600 pocket adaptor support' CONFIG_DE600
+      tristate '    D-Link DE620 pocket adaptor support' CONFIG_DE620
+   fi
 fi
 
 bool 'Token Ring driver support' CONFIG_TR
 if [ "$CONFIG_TR" = "y" ]; then
-  tristate 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR
+   tristate '  IBM Tropic chipset based adaptor support' CONFIG_IBMTR
 fi
 bool 'FDDI driver support' CONFIG_FDDI
 if [ "$CONFIG_FDDI" = "y" ]; then
-  bool 'Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX
+   bool '  Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX
 fi
 tristate 'ARCnet support' CONFIG_ARCNET
 if [ "$CONFIG_ARCNET" != "n" ]; then
-  bool '  Enable arc0e (ARCnet "Ether-Encap" packet format)' CONFIG_ARCNET_ETH
-  bool '  Enable arc0s (ARCnet RFC1051 packet format)' CONFIG_ARCNET_1051
+   bool '  Enable arc0e (ARCnet "Ether-Encap" packet format)' CONFIG_ARCNET_ETH
+   bool '  Enable arc0s (ARCnet RFC1051 packet format)' CONFIG_ARCNET_1051
 fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'Traffic Shaper (EXPERIMENTAL)' CONFIG_SHAPER
-  tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI
+   tristate 'Traffic Shaper (EXPERIMENTAL)' CONFIG_SHAPER
+   tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI
 fi
diff -u --recursive --new-file linux-2.0.38/drivers/net/pi2.c linux-2.0.39/drivers/net/pi2.c
--- linux-2.0.38/drivers/net/pi2.c	Sun Jun 13 19:21:01 1999
+++ linux-2.0.39/drivers/net/pi2.c	Thu Sep  7 03:39:40 2000
@@ -1199,7 +1199,7 @@
 }
 
 
-int pi_init(void)
+int pi2_init(void)
 {
     int *port;
     int ioaddr = 0;
@@ -1689,7 +1689,7 @@
 int init_module(void)
 {
     register_symtab(NULL);
-    return pi_init();
+    return pi2_init();
 }
 
 void cleanup_module(void)
diff -u --recursive --new-file linux-2.0.38/drivers/net/plip.c linux-2.0.39/drivers/net/plip.c
--- linux-2.0.38/drivers/net/plip.c	Sun Nov 15 19:33:03 1998
+++ linux-2.0.39/drivers/net/plip.c	Wed Dec 29 12:49:38 1999
@@ -5,7 +5,7 @@
  * Authors:	Donald Becker,  <becker@super.org>
  *		Tommy Thorn, <thorn@daimi.aau.dk>
  *		Tanabe Hiroyasu, <hiro@sanpo.t.u-tokyo.ac.jp>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *		Peter Bauer, <100136.3530@compuserve.com>
  *		Niibe Yutaka, <gniibe@mri.co.jp>
  *
diff -u --recursive --new-file linux-2.0.38/drivers/net/ppp.c linux-2.0.39/drivers/net/ppp.c
--- linux-2.0.38/drivers/net/ppp.c	Sun Jun 13 19:21:01 1999
+++ linux-2.0.39/drivers/net/ppp.c	Tue Apr 25 16:16:37 2000
@@ -780,11 +780,16 @@
 static int
 ppp_tty_open (struct tty_struct *tty)
 {
-	struct ppp *ppp = tty2ppp (tty);
+	struct ppp *ppp;
 	int indx;
+
+	if (!suser())
+		return -EPERM;
+
 /*
  * There should not be an existing table for this slot.
  */
+	ppp = tty2ppp (tty);
 	if (ppp) {
 		if (ppp->flags & SC_DEBUG)
 			printk (KERN_ERR
diff -u --recursive --new-file linux-2.0.38/drivers/net/pt.c linux-2.0.39/drivers/net/pt.c
--- linux-2.0.38/drivers/net/pt.c	Sun Jun 13 19:21:01 1999
+++ linux-2.0.39/drivers/net/pt.c	Thu Sep  7 03:40:01 2000
@@ -494,7 +494,7 @@
 	
 	
 
-int pt_init(void)
+int ptwin_init(void)
 {
     int *port;
     int ioaddr = 0;
@@ -551,7 +551,7 @@
     pt0b.irq = pt0a.irq;	/* IRQ is shared */
     
     return 0;
-} /* pt_init() */
+} /* ptwin_init() */
 
 /*
  * Probe for PT card.  Also initialises the timers
@@ -1785,7 +1785,7 @@
 int init_module(void)
 {
     register_symtab(NULL);
-    return pt_init();
+    return ptwin_init();
 }
 
 void cleanup_module(void)
diff -u --recursive --new-file linux-2.0.38/drivers/net/slip.c linux-2.0.39/drivers/net/slip.c
--- linux-2.0.38/drivers/net/slip.c	Mon Jul 13 22:47:31 1998
+++ linux-2.0.39/drivers/net/slip.c	Tue Apr 25 16:16:37 2000
@@ -698,10 +698,14 @@
 static int
 slip_open(struct tty_struct *tty)
 {
-	struct slip *sl = (struct slip *) tty->disc_data;
+	struct slip *sl;
 	int err;
 
+	if (!suser())
+		return -EPERM;
+
 	/* First make sure we're not already connected. */
+	sl = (struct slip *) tty->disc_data;
 	if (sl && sl->magic == SLIP_MAGIC) {
 		return -EEXIST;
 	}
diff -u --recursive --new-file linux-2.0.38/drivers/net/wavelan.c linux-2.0.39/drivers/net/wavelan.c
--- linux-2.0.38/drivers/net/wavelan.c	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/net/wavelan.c	Tue Apr 25 16:29:43 2000
@@ -324,6 +324,7 @@
 
   return crc_bytes;
 } /* psa_crc */
+#endif	/* SET_PSA_CRC */
 
 /*------------------------------------------------------------------*/
 /*
@@ -334,6 +335,7 @@
 		    u_long	ioaddr,
 		    u_short	hacr)
 {
+#ifdef SET_PSA_CRC
   psa_t		psa;
   u_short	crc;
 
@@ -363,8 +365,8 @@
   if(crc != 0)
     printk(KERN_WARNING "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n", dev->name);
 #endif /* DEBUG_IOCTL_INFO */
-} /* update_psa_checksum */
 #endif	/* SET_PSA_CRC */
+} /* update_psa_checksum */
 
 /*------------------------------------------------------------------*/
 /*
@@ -748,23 +750,23 @@
       unsigned short	ias_addr;
 
       /* Check mc_config command */
-      if((status & AC_SFLD_OK) != 0)
-	printk(KERN_INFO "wv_config_complete(): set_multicast_address failed; status = 0x%x\n",
-	       dev->name, str, status);
+      if((status & AC_SFLD_OK) != AC_SFLD_OK)
+	printk(KERN_INFO "%s: wv_config_complete(): set_multicast_address failed; status = 0x%x\n",
+	       dev->name, status);
 
       /* check ia-config command */
       ias_addr = mcs_addr - sizeof(ac_ias_t);
       obram_read(ioaddr, acoff(ias_addr, ac_status), (unsigned char *)&status, sizeof(status));
-      if((status & AC_SFLD_OK) != 0)
-	printk(KERN_INFO "wv_config_complete(): set_MAC_address; status = 0x%x\n",
-	       dev->name, str, status);
+      if((status & AC_SFLD_OK) != AC_SFLD_OK)
+	printk(KERN_INFO "%s: wv_config_complete(): set_MAC_address failed; status = 0x%x\n",
+	       dev->name, status);
 
       /* Check config command */
       cfg_addr = ias_addr - sizeof(ac_cfg_t);
       obram_read(ioaddr, acoff(cfg_addr, ac_status), (unsigned char *)&status, sizeof(status));
-      if((status & AC_SFLD_OK) != 0)
-	printk(KERN_INFO "wv_config_complete(): configure; status = 0x%x\n",
-	       dev->name, str, status);
+      if((status & AC_SFLD_OK) != AC_SFLD_OK)
+	printk(KERN_INFO "%s: wv_config_complete(): configure failed; status = 0x%x\n",
+	       dev->name, status);
 #endif	/* DEBUG_CONFIG_ERROR */
 
       ret = 1;		/* Ready to be scrapped */
@@ -800,15 +802,15 @@
       /* Read the first transmit buffer */
       obram_read(ioaddr, acoff(lp->tx_first_in_use, ac_status), (unsigned char *)&tx_status, sizeof(tx_status));
 
+      /* If not completed -> exit */
+      if((tx_status & AC_SFLD_C) == 0)
+	break;
+
       /* Hack for reconfiguration... */
       if(tx_status == 0xFFFF)
 	if(!wv_config_complete(dev, ioaddr, lp))
 	  break;	/* Not completed */
 
-      /* If not completed -> exit */
-      if((tx_status & AC_SFLD_C) == 0)
-	break;
-
       /* We now remove this buffer */
       nreaped++;
       --lp->tx_n_in_use;
@@ -841,7 +843,7 @@
 	  lp->stats.tx_packets++;
 	  ncollisions = tx_status & AC_SFLD_MAXCOL;
 	  lp->stats.collisions += ncollisions;
-#ifdef DEBUG_INTERRUPT_INFO
+#ifdef DEBUG_TX_INFO
 	  if(ncollisions > 0)
 	    printk(KERN_DEBUG "%s: wv_complete(): tx completed after %d collisions.\n",
 		   dev->name, ncollisions);
@@ -850,53 +852,49 @@
       else
 	{
 	  lp->stats.tx_errors++;
-#ifndef IGNORE_NORMAL_XMIT_ERRS
 	  if(tx_status & AC_SFLD_S10)
 	    {
 	      lp->stats.tx_carrier_errors++;
-#ifdef DEBUG_INTERRUPT_ERROR
-	      printk(KERN_INFO "%s: wv_complete(): tx error: no CS.\n",
+#ifdef DEBUG_TX_FAIL
+	      printk(KERN_DEBUG "%s: wv_complete(): tx error: no CS.\n",
 		     dev->name);
 #endif
 	    }
-#endif	/* IGNORE_NORMAL_XMIT_ERRS */
 	  if(tx_status & AC_SFLD_S9)
 	    {
 	      lp->stats.tx_carrier_errors++;
-#ifdef DEBUG_INTERRUPT_ERROR
-	      printk(KERN_INFO "%s: wv_complete(): tx error: lost CTS.\n",
+#ifdef DEBUG_TX_FAIL
+	      printk(KERN_DEBUG "%s: wv_complete(): tx error: lost CTS.\n",
 		     dev->name);
 #endif
 	    }
 	  if(tx_status & AC_SFLD_S8)
 	    {
 	      lp->stats.tx_fifo_errors++;
-#ifdef DEBUG_INTERRUPT_ERROR
-	      printk(KERN_INFO "%s: wv_complete(): tx error: slow DMA.\n",
+#ifdef DEBUG_TX_FAIL
+	      printk(KERN_DEBUG "%s: wv_complete(): tx error: slow DMA.\n",
 		     dev->name);
 #endif
 	    }
-#ifndef IGNORE_NORMAL_XMIT_ERRS
 	  if(tx_status & AC_SFLD_S6)
 	    {
 	      lp->stats.tx_heartbeat_errors++;
-#ifdef DEBUG_INTERRUPT_ERROR
-	      printk(KERN_INFO "%s: wv_complete(): tx error: heart beat.\n",
+#ifdef DEBUG_TX_FAIL
+	      printk(KERN_DEBUG "%s: wv_complete(): tx error: heart beat.\n",
 		     dev->name);
 #endif
 	    }
 	  if(tx_status & AC_SFLD_S5)
 	    {
 	      lp->stats.tx_aborted_errors++;
-#ifdef DEBUG_INTERRUPT_ERROR
-	      printk(KERN_INFO "%s: wv_complete(): tx error: too many collisions.\n",
+#ifdef DEBUG_TX_FAIL
+	      printk(KERN_DEBUG "%s: wv_complete(): tx error: too many collisions.\n",
 		     dev->name);
 #endif
 	    }
-#endif	/* IGNORE_NORMAL_XMIT_ERRS */
 	}
 
-#ifdef DEBUG_INTERRUPT_INFO
+#ifdef DEBUG_TX_INFO
       printk(KERN_DEBUG "%s: wv_complete(): tx completed, tx_status 0x%04x\n",
 	     dev->name, tx_status);
 #endif
@@ -1323,21 +1321,21 @@
 	       char *		msg1,		/* Name of the device */
 	       char *		msg2)		/* Name of the function */
 {
-#ifndef DEBUG_PACKET_DUMP
+  int		i;
+  int		maxi;
+
   printk(KERN_DEBUG "%s: %s(): dest %02X:%02X:%02X:%02X:%02X:%02X, length %d\n",
 	 msg1, msg2, p[0], p[1], p[2], p[3], p[4], p[5], length);
   printk(KERN_DEBUG "%s: %s(): src %02X:%02X:%02X:%02X:%02X:%02X, type 0x%02X%02X\n",
 	 msg1, msg2, p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13]);
 
-#else	/* DEBUG_PACKET_DUMP */
-  int		i;
-  int		maxi;
+#ifdef DEBUG_PACKET_DUMP
 
-  printk(KERN_DEBUG "%s: %s(): len=%d, data=\"", msg1, msg2, length);
+  printk(KERN_DEBUG "data=\"");
 
   if((maxi = length) > DEBUG_PACKET_DUMP)
     maxi = DEBUG_PACKET_DUMP;
-  for(i = 0; i < maxi; i++)
+  for(i = 14; i < maxi; i++)
     if(p[i] >= ' ' && p[i] <= '~')
       printk(" %c", p[i]);
     else
@@ -1565,7 +1563,9 @@
 /*------------------------------------------------------------------*/
 /*
  * This function doesn't exist...
+ * (Note : it was a nice way to test the reconfigure stuff...)
  */
+#ifdef SET_MAC_ADDRESS
 static int
 wavelan_set_mac_address(device *	dev,
 			void *		addr)
@@ -1580,6 +1580,7 @@
 
   return 0;
 }
+#endif	/* SET_MAC_ADDRESS */
 
 #ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
 
@@ -1940,10 +1941,8 @@
 	  /* Disable nwid in the mmc (no filtering) */
 	  mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), MMW_LOOPT_SEL_DIS_NWID);
 	}
-#ifdef SET_PSA_CRC
       /* update the Wavelan checksum */
       update_psa_checksum(dev, ioaddr, lp->hacr);
-#endif
       break;
 
     case SIOCGIWNWID:
@@ -2001,10 +2000,8 @@
       psa.psa_thr_pre_set = wrq->u.sensitivity & 0x3F;
       psa_write(ioaddr, lp->hacr, (char *)&psa.psa_thr_pre_set - (char *)&psa,
 	       (unsigned char *) &psa.psa_thr_pre_set, 1);
-#ifdef SET_PSA_CRC
       /* update the Wavelan checksum */
       update_psa_checksum(dev, ioaddr, lp->hacr);
-#endif
       mmc_out(ioaddr, mmwoff(0, mmw_thr_pre_set), psa.psa_thr_pre_set);
       break;
 
@@ -2052,10 +2049,8 @@
 
 	   mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0);
 	 }
-#ifdef SET_PSA_CRC
        /* update the Wavelan checksum */
        update_psa_checksum(dev, ioaddr, lp->hacr);
-#endif
        break;
 
      case SIOCGIWENCODE:
@@ -2269,10 +2264,8 @@
       psa.psa_quality_thr = *(wrq->u.name) & 0x0F;
       psa_write(ioaddr, lp->hacr, (char *)&psa.psa_quality_thr - (char *)&psa,
 	       (unsigned char *)&psa.psa_quality_thr, 1);
-#ifdef SET_PSA_CRC
       /* update the Wavelan checksum */
       update_psa_checksum(dev, ioaddr, lp->hacr);
-#endif
       mmc_out(ioaddr, mmwoff(0, mmw_quality_thr), psa.psa_quality_thr);
       break;
 
@@ -2435,7 +2428,7 @@
 
 #ifdef DEBUG_RX_TRACE
   printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n",
-	 dev->name, fd_p, sksize);
+	 dev->name, buf_off, sksize);
 #endif
 
   /* Allocate buffer for the data */
@@ -2520,6 +2513,8 @@
 {
   u_long	ioaddr = dev->base_addr;
   net_local *	lp = (net_local *)dev->priv;
+  fd_t		fd;
+  rbd_t		rbd;
   int		nreaped = 0;
 
 #ifdef DEBUG_RX_TRACE
@@ -2529,48 +2524,62 @@
   /* Loop on each received packet */
   for(;;)
     {
-      fd_t		fd;
-      rbd_t		rbd;
-      ushort		pkt_len;
-
       obram_read(ioaddr, lp->rx_head, (unsigned char *) &fd, sizeof(fd));
 
-      /* If the current frame is not complete, we have reach the end... */
+      /* Note about the status :
+       * It start up to be 0 (the value we set). Then, when the RU
+       * grab the buffer to prepare for reception, it sets the
+       * FD_STATUS_B flag. When the RU has finished receiving the
+       * frame, it clears FD_STATUS_B, set FD_STATUS_C to indicate
+       * completion and set the other flags to indicate the eventual
+       * errors. FD_STATUS_OK indicates that the reception was OK.
+       */
+
+      /* If the current frame is not complete, we have reached the end. */
       if((fd.fd_status & FD_STATUS_C) != FD_STATUS_C)
-	break;		/* This is how we exit the loop */
+	break;		/* This is how we exit the loop. */
 
       nreaped++;
 
-      /* Check if frame correctly received */
-      if((fd.fd_status & (FD_STATUS_B | FD_STATUS_OK)) !=
-	 (FD_STATUS_B | FD_STATUS_OK))
-	{
-	  /*
-	   * Not sure about this one -- it does not seem
-	   * to be an error so we will keep quiet about it.
-	   */
-#ifndef IGNORE_NORMAL_XMIT_ERRS
-#ifdef DEBUG_RX_ERROR
-	  if((fd.fd_status & FD_STATUS_B) != FD_STATUS_B)
-	    printk(KERN_INFO "%s: wv_receive(): frame not consumed by RU.\n",
-		   dev->name);
-#endif
-#endif	/* IGNORE_NORMAL_XMIT_ERRS */
+      /* Check whether frame was correctly received. */
+      if((fd.fd_status & FD_STATUS_OK) == FD_STATUS_OK)
+	{
+	  /* Does the frame contain a pointer to the data?  Let's check. */
+	  if(fd.fd_rbd_offset != I82586NULL)
+	    {
+	      /* Read the receive buffer descriptor */
+	      obram_read(ioaddr, fd.fd_rbd_offset,
+			 (unsigned char *) &rbd, sizeof(rbd));
 
 #ifdef DEBUG_RX_ERROR
-	  if((fd.fd_status & FD_STATUS_OK) != FD_STATUS_OK)
-	    printk(KERN_INFO "%s: wv_receive(): frame not received successfully.\n",
+	      if((rbd.rbd_status & RBD_STATUS_EOF) != RBD_STATUS_EOF)
+		printk(KERN_INFO "%s: wv_receive(): missing EOF flag.\n",
+		       dev->name);
+
+	      if((rbd.rbd_status & RBD_STATUS_F) != RBD_STATUS_F)
+		printk(KERN_INFO "%s: wv_receive(): missing F flag.\n",
+		       dev->name);
+#endif	/* DEBUG_RX_ERROR */
+
+	      /* Read the packet and transmit to Linux */
+	      wv_packet_read(dev, rbd.rbd_bufl,
+			     rbd.rbd_status & RBD_STATUS_ACNT);
+	    }
+#ifdef DEBUG_RX_ERROR
+	  else	/* if frame has no data */
+	    printk(KERN_INFO "%s: wv_receive(): frame has no data.\n",
 		   dev->name);
 #endif
 	}
-
-      /* Were there problems in processing the frame?  Let's check. */
-      if((fd.fd_status & (FD_STATUS_S6 | FD_STATUS_S7 | FD_STATUS_S8 |
-			  FD_STATUS_S9 | FD_STATUS_S10 | FD_STATUS_S11))
-	 != 0)
+      else	/* If reception was no successful */
 	{
 	  lp->stats.rx_errors++;
 
+#ifdef DEBUG_RX_INFO
+	  printk(KERN_DEBUG "%s: wv_receive(): frame not received successfully (%X).\n",
+		 dev->name, fd.fd_status);
+#endif
+
 #ifdef DEBUG_RX_ERROR
 	  if((fd.fd_status & FD_STATUS_S6) != 0)
 	    printk(KERN_INFO "%s: wv_receive(): no EOF flag.\n", dev->name);
@@ -2579,8 +2588,8 @@
 	  if((fd.fd_status & FD_STATUS_S7) != 0)
 	    {
 	      lp->stats.rx_length_errors++;
-#ifdef DEBUG_RX_ERROR
-	      printk(KERN_INFO "%s: wv_receive(): frame too short.\n",
+#ifdef DEBUG_RX_FAIL
+	      printk(KERN_DEBUG "%s: wv_receive(): frame too short.\n",
 		     dev->name);
 #endif
 	    }
@@ -2588,8 +2597,8 @@
 	  if((fd.fd_status & FD_STATUS_S8) != 0)
 	    {
 	      lp->stats.rx_over_errors++;
-#ifdef DEBUG_RX_ERROR
-	      printk(KERN_INFO "%s: wv_receive(): rx DMA overrun.\n",
+#ifdef DEBUG_RX_FAIL
+	      printk(KERN_DEBUG "%s: wv_receive(): rx DMA overrun.\n",
 		     dev->name);
 #endif
 	    }
@@ -2597,8 +2606,8 @@
 	  if((fd.fd_status & FD_STATUS_S9) != 0)
 	    {
 	      lp->stats.rx_fifo_errors++;
-#ifdef DEBUG_RX_ERROR
-	      printk(KERN_INFO "%s: wv_receive(): ran out of resources.\n",
+#ifdef DEBUG_RX_FAIL
+	      printk(KERN_DEBUG "%s: wv_receive(): ran out of resources.\n",
 		     dev->name);
 #endif
 	    }
@@ -2606,8 +2615,8 @@
 	  if((fd.fd_status & FD_STATUS_S10) != 0)
 	    {
 	      lp->stats.rx_frame_errors++;
-#ifdef DEBUG_RX_ERROR
-	      printk(KERN_INFO "%s: wv_receive(): alignment error.\n",
+#ifdef DEBUG_RX_FAIL
+	      printk(KERN_DEBUG "%s: wv_receive(): alignment error.\n",
 		     dev->name);
 #endif
 	    }
@@ -2615,38 +2624,12 @@
 	  if((fd.fd_status & FD_STATUS_S11) != 0)
 	    {
 	      lp->stats.rx_crc_errors++;
-#ifdef DEBUG_RX_ERROR
-	      printk(KERN_INFO "%s: wv_receive(): CRC error.\n", dev->name);
+#ifdef DEBUG_RX_FAIL
+	      printk(KERN_DEBUG "%s: wv_receive(): CRC error.\n", dev->name);
 #endif
 	    }
 	}
 
-      /* Does the frame contain a pointer to the data?  Let's check. */
-      if(fd.fd_rbd_offset == I82586NULL)
-#ifdef DEBUG_RX_ERROR
-	printk(KERN_INFO "%s: wv_receive(): frame has no data.\n", dev->name);
-#endif
-      else
-	{
-	  obram_read(ioaddr, fd.fd_rbd_offset,
-		     (unsigned char *) &rbd, sizeof(rbd));
-
-#ifdef DEBUG_RX_ERROR
-	  if((rbd.rbd_status & RBD_STATUS_EOF) != RBD_STATUS_EOF)
-	    printk(KERN_INFO "%s: wv_receive(): missing EOF flag.\n",
-		   dev->name);
-
-	  if((rbd.rbd_status & RBD_STATUS_F) != RBD_STATUS_F)
-	    printk(KERN_INFO "%s: wv_receive(): missing F flag.\n",
-		   dev->name);
-#endif
-
-	  pkt_len = rbd.rbd_status & RBD_STATUS_ACNT;
-
-	  /* Read the packet and transmit to Linux */
-	  wv_packet_read(dev, rbd.rbd_bufl, pkt_len);
-	}	/* if frame has data */
-
       fd.fd_status = 0;
       obram_write(ioaddr, fdoff(lp->rx_head, fd_status),
 		  (unsigned char *) &fd.fd_status, sizeof(fd.fd_status));
@@ -2781,7 +2764,7 @@
   /*
    * Data
    */
-  obram_write(ioaddr, buf_addr, buf, clen);
+  obram_write(ioaddr, buf_addr, buf, length);
 
   /*
    * Overwrite the predecessor NOP link
@@ -2967,11 +2950,9 @@
 		(unsigned char *)&psa.psa_quality_thr, 1);
       psa_write(ioaddr, lp->hacr, (char *)&psa.psa_conf_status - (char *)&psa,
 		(unsigned char *)&psa.psa_conf_status, 1);
-#ifdef SET_PSA_CRC
       /* update the Wavelan checksum */
       update_psa_checksum(dev, ioaddr, lp->hacr);
 #endif
-#endif
     }
 
   /* Zero the mmc structure */
@@ -3142,7 +3123,7 @@
 
   if(i <= 0)
     {
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_INFO "%s: wavelan_ru_start(): board not accepting command.\n",
 	     dev->name);
 #endif
@@ -3246,7 +3227,7 @@
 
   if(i <= 0)
     {
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_INFO "%s: wavelan_cu_start(): board not accepting command.\n",
 	     dev->name);
 #endif
@@ -3332,7 +3313,7 @@
 
   if(i <= 0)
     {
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_INFO "%s: wv_82586_start(): iscp_busy timeout.\n",
 	     dev->name);
 #endif
@@ -3352,7 +3333,7 @@
 
   if (i <= 0)
     {
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_INFO "%s: wv_82586_start(): status: expected 0x%02x, got 0x%02x.\n",
 	     dev->name, SCB_ST_CX | SCB_ST_CNA, scb.scb_status);
 #endif
@@ -3373,7 +3354,7 @@
   obram_read(ioaddr, OFFSET_CU, (unsigned char *)&cb, sizeof(cb));
   if(cb.ac_status & AC_SFLD_FAIL)
     {
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_INFO "%s: wv_82586_start(): i82586 Self Test failed.\n",
 	     dev->name);
 #endif
@@ -3654,13 +3635,16 @@
   wv_ints_on(dev);
 
   /* Start card functions */
-  if((wv_ru_start(dev) < 0) ||
-     (wv_cu_start(dev) < 0))
+  if(wv_cu_start(dev) < 0)
     return -1;
 
-  /* Finish configuration */
+  /* Setup the controller and parameters */
   wv_82586_config(dev);
 
+  /* Finish configuration with the receive unit */
+  if(wv_ru_start(dev) < 0)
+    return -1;
+
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name);
 #endif
@@ -3968,7 +3952,7 @@
   /* Check irq */
   if(dev->irq == 0)
     {
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_WARNING "%s: wavelan_open(): no IRQ\n", dev->name);
 #endif
       return -ENXIO;
@@ -3980,7 +3964,7 @@
      (request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN", NULL) != 0))
     {
       irq2dev_map[dev->irq] = (device *) NULL;
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_WARNING "%s: wavelan_open(): invalid IRQ\n", dev->name);
 #endif
       return -EAGAIN;
@@ -3996,7 +3980,7 @@
     {
       free_irq(dev->irq, NULL);
       irq2dev_map[dev->irq] = (device *) NULL;
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_INFO "%s: wavelan_open(): impossible to start the card\n",
 	     dev->name);
 #endif
@@ -4094,10 +4078,8 @@
 #endif
 	  psa_write(ioaddr, HACR_DEFAULT,
 		    psaoff(0, psa_int_req_no), &irq_mask, 1);
-#ifdef SET_PSA_CRC
 	  /* update the Wavelan checksum */
 	  update_psa_checksum(dev, ioaddr, HACR_DEFAULT);
-#endif
 	  wv_hacr_reset(ioaddr);
 	}
     }
@@ -4151,7 +4133,9 @@
   dev->hard_start_xmit = wavelan_packet_xmit;
   dev->get_stats = wavelan_get_stats;
   dev->set_multicast_list = &wavelan_set_multicast_list;
+#ifdef SET_MAC_ADDRESS
   dev->set_mac_address = &wavelan_set_mac_address;
+#endif	/* SET_MAC_ADDRESS */
 
 #ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
   dev->do_ioctl = wavelan_ioctl;
@@ -4207,7 +4191,7 @@
   /* Don't probe at all. */
   if(base_addr < 0)
     {
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_WARNING "%s: wavelan_probe(): invalid base address\n",
 	     dev->name);
 #endif
@@ -4290,7 +4274,7 @@
   /* If probing is asked */
   if(io[0] == 0)
     {
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
       printk(KERN_WARNING "WaveLAN init_module(): doing device probing (bad !)\n");
       printk(KERN_WARNING "Specify base addresses while loading module to correct the problem\n");
 #endif
@@ -4334,7 +4318,7 @@
 	}	/* if there is something at the address */
     }		/* Loop on all addresses. */
 
-#ifdef DEBUG_CONFIG_ERRORS
+#ifdef DEBUG_CONFIG_ERROR
   if(wavelan_list == (net_local *) NULL)
     printk(KERN_WARNING "WaveLAN init_module(): no device found\n");
 #endif
diff -u --recursive --new-file linux-2.0.38/drivers/net/wavelan.p.h linux-2.0.39/drivers/net/wavelan.p.h
--- linux-2.0.38/drivers/net/wavelan.p.h	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/net/wavelan.p.h	Tue Apr 25 16:29:43 2000
@@ -34,11 +34,22 @@
  *	I try to maintain a web page with the Wireless LAN Howto at :
  *		http://www-uk.hpl.hp.com/people/jt/Linux/Wavelan.html
  *
+ * Debugging and options
+ * ---------------------
+ *	You will find below a set of '#define" allowing a very fine control
+ *	on the driver behaviour and the debug messages printed.
+ *	The main options are :
+ *	o SET_PSA_CRC, to have your card correctly recognised by
+ *	  an access point and the Point-to-Point diagnostic tool.
+ *	o USE_PSA_CONFIG, to read configuration from the PSA (EEprom)
+ *	  (otherwise we always start afresh with some defaults)
+ *
  * wavelan.o is darn too big
  * -------------------------
  *	That's true ! There is a very simple way to reduce the driver
  *	object by 33% (yes !). Comment out the following line :
  *		#include <linux/wireless.h>
+ *	Other compile options can also reduce the size of it...
  *
  * Debugging and options
  * ---------------------
@@ -272,7 +283,17 @@
  *	- Correct i82586 configuration parameters
  *	- Encryption initialisation bug (Robert McCormack)
  *	- New mac addresses detected in the probe
- *	- Increase watchdog for busy envirnoments
+ *	- Increase watchdog for busy environments
+ *
+ * Changes made for release in 2.0.38 & 2.2.7 :
+ * ------------------------------------------
+ *	- Correct the reception logic to better report errors and avoid
+ *	  sending bogus packet up the stack
+ *	- Delay RU config to avoid corrupting first received packet
+ *	- Change config completion code (to actually check something)
+ *	- Avoid reading out of bound in skbuf to transmit
+ *	- Rectify a lot of (useless) debugging code
+ *	- Change the way to `#ifdef SET_PSA_CRC'
  *
  * Wishes & dreams :
  * ---------------
@@ -311,6 +332,24 @@
 #include	"i82586.h"
 #include	"wavelan.h"
 
+/************************** DRIVER OPTIONS **************************/
+/*
+ * `#define' or `#undef' the following constant to change the behaviour
+ * of the driver...
+ */
+#undef SET_PSA_CRC		/* Calculate and set the CRC on PSA (slower) */
+#define USE_PSA_CONFIG		/* Use info from the PSA. */
+#undef STRUCT_CHECK		/* Verify padding of structures. */
+#undef EEPROM_IS_PROTECTED	/* doesn't seem to be necessary */
+#define MULTICAST_AVOID		/* Avoid extra multicast (I'm sceptical). */
+#undef SET_MAC_ADDRESS		/* Experimental */
+
+#ifdef WIRELESS_EXT	/* If wireless extensions exist in the kernel */
+/* Warning:  this stuff will slow down the driver. */
+#define WIRELESS_SPY		/* Enable spying addresses. */
+#undef HISTOGRAM		/* Enable histogram of signal level. */
+#endif
+
 /****************************** DEBUG ******************************/
 
 #undef DEBUG_MODULE_TRACE	/* Module insertion/removal */
@@ -320,14 +359,16 @@
 #define DEBUG_INTERRUPT_ERROR	/* problems */
 #undef DEBUG_CONFIG_TRACE	/* Trace the config functions */
 #undef DEBUG_CONFIG_INFO	/* What's going on... */
-#define DEBUG_CONFIG_ERRORS	/* Errors on configuration */
+#define DEBUG_CONFIG_ERROR	/* Errors on configuration */
 #undef DEBUG_TX_TRACE		/* Transmission calls */
 #undef DEBUG_TX_INFO		/* Header of the transmited packet */
-#define DEBUG_TX_ERROR		/* unexpected conditions */
+#undef DEBUG_TX_FAIL		/* Normal failure conditions */
+#define DEBUG_TX_ERROR		/* Unexpected conditions */
 #undef DEBUG_RX_TRACE		/* Transmission calls */
-#undef DEBUG_RX_INFO		/* Header of the transmited packet */
-#define DEBUG_RX_ERROR		/* unexpected conditions */
-#undef DEBUG_PACKET_DUMP	16	/* Dump packet on the screen */
+#undef DEBUG_RX_INFO		/* Header of the received packet */
+#undef DEBUG_RX_FAIL		/* Normal failure conditions */
+#define DEBUG_RX_ERROR		/* Unexpected conditions */
+#undef DEBUG_PACKET_DUMP	32	/* Dump packet on the screen */
 #undef DEBUG_IOCTL_TRACE	/* Misc call by Linux */
 #undef DEBUG_IOCTL_INFO		/* Various debug info */
 #define DEBUG_IOCTL_ERROR	/* What's going wrong */
@@ -339,26 +380,10 @@
 #undef DEBUG_I82586_SHOW	/* Show i82586 status */
 #undef DEBUG_DEVICE_SHOW	/* Show device parameters */
 
-/* Options : */
-#define USE_PSA_CONFIG		/* Use info from the PSA */
-#define SET_PSA_CRC		/* Calculate and set the CRC on PSA */
-#define IGNORE_NORMAL_XMIT_ERRS	/* Don't bother with normal conditions */
-#undef STRUCT_CHECK		/* Verify padding of structures */
-#undef OLDIES			/* Old code (to redo) */
-#undef RECORD_SNR		/* To redo */
-#undef EEPROM_IS_PROTECTED	/* Doesn't seem to be necessary */
-#define MULTICAST_AVOID		/* Avoid extra multicast (I'm sceptical) */
-
-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
-/* Warning : these stuff will slow down the driver... */
-#define WIRELESS_SPY		/* Enable spying addresses */
-#undef HISTOGRAM		/* Enable histogram of sig level... */
-#endif
-
 /************************ CONSTANTS & MACROS ************************/
 
 #ifdef DEBUG_VERSION_SHOW
-static const char	*version	= "wavelan.c : v18 (wireless extensions) 18/2/99\n";
+static const char	*version	= "wavelan.c : v19 (wireless extensions) 20/4/99\n";
 #endif
 
 /* Watchdog temporisation */
diff -u --recursive --new-file linux-2.0.38/drivers/pci/pci.c linux-2.0.39/drivers/pci/pci.c
--- linux-2.0.38/drivers/pci/pci.c	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/pci/pci.c	Wed Jun 28 14:48:19 2000
@@ -210,6 +210,7 @@
 	DEVICE( MOTOROLA,	MOTOROLA_MPC106,"MPC106 Grackle"),
 	DEVICE( MOTOROLA,	MOTOROLA_RAVEN,	"Raven"),
 	DEVICE( PROMISE,	PROMISE_20246,	"IDE UltraDMA/33"),
+	DEVICE(	PROMISE,	PROMISE_20262,	"IDE UltraDMA/66"),
 	DEVICE( PROMISE,	PROMISE_5300,	"DC5030"),
 	DEVICE( N9,		N9_I128,	"Imagine 128"),
 	DEVICE( N9,		N9_I128_2,	"Imagine 128v2"),
@@ -271,8 +272,8 @@
 	DEVICE( WINBOND,	WINBOND_82C105,	"SL82C105"),
 	DEVICE( WINBOND,	WINBOND_83C553,	"W83C553"),
 	DEVICE( DATABOOK,      	DATABOOK_87144,	"DB87144"),
-	DEVICE( PLX,        PLX_SPCOM200, "SPCom 200 PCI serial I/O"),
-	DEVICE( PLX,        PLX_9050,   "PLX9050 PCI <-> IOBus Bridge"),
+	DEVICE( PLX,		PLX_SPCOM200,	"SPCom 200 PCI serial I/O"),
+	DEVICE( PLX,		PLX_9050,	"PLX9050 PCI <-> IOBus Bridge"),
 	DEVICE( PLX,		PLX_9080,	"PCI9080 I2O"),
 	DEVICE( MADGE,		MADGE_MK2,	"Smart 16/4 BM Mk2 Ringnode"),
 	DEVICE( 3COM,		3COM_3C339,	"3C339 TokenRing"),
@@ -297,11 +298,14 @@
 	DEVICE( AL,		AL_M1523,	"M1523"),
 	DEVICE( AL,		AL_M1531,	"M1531 Aladdin IV"),
 	DEVICE( AL,		AL_M1533,	"M1533 Aladdin IV"),
+	DEVICE(	AL,		AL_M1541,	"M1541 Aladdin V"),
+	DEVICE(	AL,		AL_M1543,	"M1543 Aladdin V"),
 	DEVICE( AL,		AL_M3307,	"M3307 MPEG-1 decoder"),
 	DEVICE( AL,		AL_M4803,	"M4803"),
 	DEVICE( AL,		AL_M5219,	"M5219"),
 	DEVICE( AL,		AL_M5229,	"M5229 TXpro"),
 	DEVICE( AL,		AL_M5237,	"M5237 USB"),
+	DEVICE( AL,		AL_M7101,	"M7101 PMU"),
 	DEVICE( SURECOM,	SURECOM_NE34,	"NE-34PCI LAN"),
 	DEVICE( NEOMAGIC,       NEOMAGIC_MAGICGRAPH_NM2070,     "Magicgraph NM2070"),
 	DEVICE( NEOMAGIC,	NEOMAGIC_MAGICGRAPH_128V, "MagicGraph 128V"),
@@ -489,7 +493,7 @@
 	DEVICE( S3,		S3_ViRGE_MXP,	"ViRGE/MX+"),
 	DEVICE( S3,		S3_ViRGE_MXPMV,	"ViRGE/MX+MV"),
 	DEVICE( S3,		S3_SONICVIBES,	"SonicVibes"),
-	DEVICE( DCI,    DCI_PCCOM4,     "PC COM PCI Bus 4 port serial Adapter"),
+	DEVICE( DCI,		DCI_PCCOM4,	"PC COM PCI Bus 4 port serial Adapter"),
 	DEVICE( INTEL,		INTEL_82375,	"82375EB"),
 	BRIDGE( INTEL,		INTEL_82424,	"82424ZX Saturn",	0x00),
 	DEVICE( INTEL,		INTEL_82378,	"82378IB"),
diff -u --recursive --new-file linux-2.0.38/drivers/scsi/Config.in linux-2.0.39/drivers/scsi/Config.in
--- linux-2.0.38/drivers/scsi/Config.in	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/scsi/Config.in	Thu Sep  7 03:58:06 2000
@@ -1,15 +1,15 @@
 comment 'SCSI support type (disk, tape, CD-ROM)'
 
-dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
-dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
-dep_tristate 'SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
-dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
+dep_tristate '  SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
+dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
+dep_tristate '  SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
+dep_tristate '  SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
 
 comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
 
-bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
+bool '  Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
 
-bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
+bool '  Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
 
 mainmenu_option next_comment
 comment 'SCSI low-level drivers'
@@ -21,10 +21,10 @@
 dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
 dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
 if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
-    bool '   Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
-    int  '   Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8
-    bool '   Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N
-    int  '   Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
+   bool '  Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
+   int  '  Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8
+   bool '  Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N
+   int  '  Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
 fi
 dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
 dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI
@@ -32,79 +32,79 @@
 dep_tristate 'AMI MegaRAID support' CONFIG_SCSI_MEGARAID $CONFIG_SCSI
 dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC $CONFIG_SCSI
 if [ "$CONFIG_SCSI_BUSLOGIC" != "n" ]; then
-    bool '  Omit FlashPoint support' CONFIG_SCSI_OMIT_FLASHPOINT
+   bool '  Omit FlashPoint support' CONFIG_SCSI_OMIT_FLASHPOINT
 fi
 dep_tristate 'DTC3180/3280 SCSI support' CONFIG_SCSI_DTC3280 $CONFIG_SCSI
 dep_tristate 'EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support' CONFIG_SCSI_EATA_DMA $CONFIG_SCSI
 dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO $CONFIG_SCSI
 dep_tristate 'EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support' CONFIG_SCSI_EATA $CONFIG_SCSI
-  if [ "$CONFIG_SCSI_EATA" != "n" ]; then
-    bool '  enable tagged command queueing' CONFIG_SCSI_EATA_TAGGED_QUEUE
-    bool '  enable elevator sorting' CONFIG_SCSI_EATA_LINKED_COMMANDS
-    int  '  maximum number of queued commands' CONFIG_SCSI_EATA_MAX_TAGS 16
-  fi
+if [ "$CONFIG_SCSI_EATA" != "n" ]; then
+   bool '  enable tagged command queueing' CONFIG_SCSI_EATA_TAGGED_QUEUE
+   bool '  enable elevator sorting' CONFIG_SCSI_EATA_LINKED_COMMANDS
+   int  '  maximum number of queued commands' CONFIG_SCSI_EATA_MAX_TAGS 16
+fi
 dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN $CONFIG_SCSI
 dep_tristate 'Generic NCR5380/53c400 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 $CONFIG_SCSI
 if [ "$CONFIG_SCSI_GENERIC_NCR5380" != "n" ]; then
-	bool '   Enable NCR53c400 extensions' CONFIG_SCSI_GENERIC_NCR53C400
-	choice 'NCR5380/53c400 mapping method (use Port for T130B)' \
-		"Port CONFIG_SCSI_G_NCR5380_PORT \
-		Memory CONFIG_SCSI_G_NCR5380_MEM" Port
+   bool '   Enable NCR53c400 extensions' CONFIG_SCSI_GENERIC_NCR53C400
+   choice 'NCR5380/53c400 mapping method (use Port for T130B)' \
+	"Port CONFIG_SCSI_G_NCR5380_PORT \
+	Memory CONFIG_SCSI_G_NCR5380_MEM" Port
 fi
 dep_tristate 'Initio 91XX support' CONFIG_SCSI_INITIO $CONFIG_SCSI
 dep_tristate 'Initio INI-A100U2W support' CONFIG_SCSI_INIA100 $CONFIG_SCSI
 dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI
 dep_tristate 'symbios 53c416 SCSI support' CONFIG_SCSI_SYM53C416 $CONFIG_SCSI
 if [ "$CONFIG_PCI" = "y" ]; then
-  dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI
-  if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then
-    bool '   always negotiate synchronous transfers' CONFIG_SCSI_NCR53C7xx_sync
-    bool '   allow FAST-SCSI [10MHz]' CONFIG_SCSI_NCR53C7xx_FAST
-    bool '   allow DISCONNECT' CONFIG_SCSI_NCR53C7xx_DISCONNECT
-  fi
+   dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI
+   if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then
+      bool '  always negotiate synchronous transfers' CONFIG_SCSI_NCR53C7xx_sync
+      bool '  allow FAST-SCSI [10MHz]' CONFIG_SCSI_NCR53C7xx_FAST
+      bool '  allow DISCONNECT' CONFIG_SCSI_NCR53C7xx_DISCONNECT
+   fi
 fi
 if [ "$CONFIG_PCI" = "y" -a "$CONFIG_SCSI_NCR53C7xx" != "y" ]; then
-  dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI
-  if [ "$CONFIG_SCSI_NCR53C8XX" != "n" ]; then
-    int  '  default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8
-    int  '  maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32
-    int  '  synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 20
-    bool '  enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE
-    bool '  use normal IO' CONFIG_SCSI_NCR53C8XX_IOMAPPED
-    if [ "$CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS" = "0" ]; then
-      bool '  not allow targets to disconnect' CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
-    fi
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      bool '  assume boards are SYMBIOS compatible' CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT
-    fi
-  fi
+   dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI
+   if [ "$CONFIG_SCSI_NCR53C8XX" != "n" ]; then
+      int  '  default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8
+      int  '  maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32
+      int  '  synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 20
+      bool '  enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE
+      bool '  use normal IO' CONFIG_SCSI_NCR53C8XX_IOMAPPED
+      if [ "$CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS" = "0" ]; then
+	 bool '  not allow targets to disconnect' CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
+      fi
+      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	 bool '  assume boards are SYMBIOS compatible (EXPERIMENTAL)' CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT
+      fi
+   fi
 fi
 dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI
 if [ "$CONFIG_SCSI_PPA" != "n" ]; then
-    bool '  Buggy EPP chipset support' CONFIG_SCSI_PPA_HAVE_PEDANTIC
+   bool '  Buggy EPP chipset support' CONFIG_SCSI_PPA_HAVE_PEDANTIC
 fi
 dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI
 dep_tristate 'PCI-2000 support' CONFIG_SCSI_PCI2000 $CONFIG_SCSI
-dep_tristate 'PCI2220I support' CONFIG_SCSI_PCI2220I $CONFIG_SCSI
-dep_tristate 'PSI240I support' CONFIG_SCSI_PSI240I $CONFIG_SCSI
+dep_tristate 'PCI-2220i support' CONFIG_SCSI_PCI2220I $CONFIG_SCSI
+dep_tristate 'PSI-240i support' CONFIG_SCSI_PSI240I $CONFIG_SCSI
 dep_tristate 'Qlogic FAS SCSI support' CONFIG_SCSI_QLOGIC_FAS $CONFIG_SCSI
 if [ "$CONFIG_PCI" = "y" ]; then
-  dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
+   dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
 fi
 dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI
 if [ "$CONFIG_PCI" = "y" ]; then
-  dep_tristate 'Tekram DC390(T) and Am53/79C974 SCSI support' CONFIG_SCSI_DC390T $CONFIG_SCSI
-  if [ "$CONFIG_SCSI_DC390T" != "n" ]; then
-    bool '  _omit_ support for non-DC390 adapters' CONFIG_SCSI_DC390T_NOGENSUPP
-  fi
+   dep_tristate 'Tekram DC390(T) and Am53/79C974 SCSI support' CONFIG_SCSI_DC390T $CONFIG_SCSI
+   if [ "$CONFIG_SCSI_DC390T" != "n" ]; then
+      bool '  _omit_ support for non-DC390 adapters' CONFIG_SCSI_DC390T_NOGENSUPP
+   fi
 fi
 dep_tristate 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 $CONFIG_SCSI
 dep_tristate 'Tripace TC-2550x SCSI support' CONFIG_SCSI_TC2550 $CONFIG_SCSI
 dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F $CONFIG_SCSI
-  if [ "$CONFIG_SCSI_U14_34F" != "n" ]; then
-    bool '  enable elevator sorting' CONFIG_SCSI_U14_34F_LINKED_COMMANDS
-    int  '  maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8
-  fi
+if [ "$CONFIG_SCSI_U14_34F" != "n" ]; then
+   bool '  enable elevator sorting' CONFIG_SCSI_U14_34F_LINKED_COMMANDS
+   int  '  maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8
+fi
 dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR $CONFIG_SCSI
 dep_tristate 'GDT SCSI Disk Array Controller support' CONFIG_SCSI_GDTH $CONFIG_SCSI
 #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI
diff -u --recursive --new-file linux-2.0.38/drivers/scsi/pci2000.c linux-2.0.39/drivers/scsi/pci2000.c
--- linux-2.0.38/drivers/scsi/pci2000.c	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/scsi/pci2000.c	Thu Sep  7 03:06:15 2000
@@ -1,7 +1,7 @@
 /*+M*************************************************************************
  * Perceptive Solutions, Inc. PCI-2000 device driver proc support for Linux.
  *
- * Copyright (c) 1997 Perceptive Solutions, Inc.
+ * Copyright (c) 1999 Perceptive Solutions, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,12 +21,15 @@
  *	File Name:		pci2000i.c
  *
  *	Revisions	1.10	Jan-21-1999
- *
  *		- Fixed sign on message to reflect proper controller name.
  *		- Added support for RAID status monitoring and control.
  *
+ *  Revisions	1.11	Mar-22-1999
+ *		- Fixed control timeout to not lock up the entire system if
+ *		  controller goes offline completely.
+ *
  *-M*************************************************************************/
-#define PCI2000_VERSION		"1.10"
+#define PCI2000_VERSION		"1.11"
 
 #include <linux/module.h>
 
@@ -108,13 +111,14 @@
  ****************************************************************/
 static int WaitReady (PADAPTER2000 padapter)
 	{
-	ULONG	timer;
+	ULONG	z;
 
-	timer = jiffies + TIMEOUT_COMMAND;								// calculate the timeout value
-	do	{
+	for ( z = 0;  z < (TIMEOUT_COMMAND * 4);  z++ )
+		{
 		if ( !inb_p (padapter->cmd) )
 			return FALSE;
-		}	while ( timer > jiffies );									// test for timeout
+		udelay (250);
+		};								
 	return TRUE;
 	}
 /****************************************************************
@@ -318,7 +322,7 @@
 	OpDone (SCpnt, DID_OK << 16);
 	}
 /****************************************************************
- *	Name:	Pci2220i_QueueCommand
+ *	Name:	Pci2000_QueueCommand
  *
  *	Description:	Process a queued command from the SCSI manager.
  *
@@ -507,7 +511,7 @@
 			if ( cmd )
 				break;
 		default:
-			DEB (printk ("pci2220i_queuecommand: Unsupported command %02X\n", *cdb));
+			DEB (printk ("pci2000_queuecommand: Unsupported command %02X\n", *cdb));
 			OpDone (SCpnt, DID_ERROR << 16);
 			return 0;
 		}
@@ -534,7 +538,7 @@
 	SCpnt->SCp.Status++;
 	}
 /****************************************************************
- *	Name:	Pci2220i_Command
+ *	Name:	Pci2000_Command
  *
  *	Description:	Process a command from the SCSI manager.
  *
@@ -555,7 +559,7 @@
 	return SCpnt->result;
 	}
 /****************************************************************
- *	Name:	Pci2220i_Detect
+ *	Name:	Pci2000_Detect
  *
  *	Description:	Detect and initialize our boards.
  *
@@ -638,7 +642,7 @@
 	return pci_index;
 	}
 /****************************************************************
- *	Name:	Pci2220i_Abort
+ *	Name:	Pci2000_Abort
  *
  *	Description:	Process the Abort command from the SCSI manager.
  *
@@ -653,7 +657,7 @@
 	return SCSI_ABORT_SNOOZE;
 	}
 /****************************************************************
- *	Name:	Pci2220i_Reset
+ *	Name:	Pci2000_Reset
  *
  *	Description:	Process the Reset command from the SCSI manager.
  *
@@ -675,7 +679,7 @@
 #include "sd.h"
 
 /****************************************************************
- *	Name:	Pci2220i_BiosParam
+ *	Name:	Pci2000_BiosParam
  *
  *	Description:	Process the biosparam request from the SCSI manager to
  *					return C/H/S data.
@@ -709,7 +713,7 @@
 
 #ifdef MODULE
 /* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = PCI2000;
+Scsi_Host_Template driver_template = PCI2220I;
 
 #include "scsi_module.c"
 #endif
diff -u --recursive --new-file linux-2.0.38/drivers/scsi/pci2220i.c linux-2.0.39/drivers/scsi/pci2220i.c
--- linux-2.0.38/drivers/scsi/pci2220i.c	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/scsi/pci2220i.c	Thu Sep  7 03:06:59 2000
@@ -1,7 +1,7 @@
 /*+M*************************************************************************
- * Perceptive Solutions, Inc. PCI-2000 device driver proc support for Linux.
+ * Perceptive Solutions, Inc. PCI-2220I device driver proc support for Linux.
  *
- * Copyright (c) 1997 Perceptive Solutions, Inc.
+ * Copyright (c) 1999 Perceptive Solutions, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,7 +25,6 @@
  *-M*************************************************************************/
 
 #include <linux/module.h>
-
 #include <linux/kernel.h>
 #include <linux/head.h>
 #include <linux/types.h>
@@ -36,46 +35,41 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/kdev_t.h>
+#include <linux/blk.h>
+#include <linux/timer.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <linux/blk.h>
 #include "scsi.h"
 #include "hosts.h"
-
 #include "pci2220i.h"
-#include "psi_dale.h"
 
-#include<linux/stat.h>
+#define	PCI2220I_VERSION		"1.10"
+//#define	READ_CMD				IDE_COMMAND_READ
+//#define	WRITE_CMD				IDE_COMMAND_WRITE
+//#define	MAX_BUS_MASTER_BLOCKS	1		// This is the maximum we can bus master
+#define	READ_CMD				IDE_CMD_READ_MULTIPLE
+#define	WRITE_CMD				IDE_CMD_WRITE_MULTIPLE
+#define	MAX_BUS_MASTER_BLOCKS	SECTORSXFER		// This is the maximum we can bus master
+
 
 struct proc_dir_entry Proc_Scsi_Pci2220i =
-	{ PROC_SCSI_PCI2220I, 7, "pci2220i", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
+	{ PROC_SCSI_PCI2220I, 8, "pci2220i", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
 
 //#define DEBUG 1
 
 #ifdef DEBUG
 #define DEB(x) x
-#define STOP_HERE	{int st;for(st=0;st<100;st++){st=1;}}
+#define STOP_HERE()	{int st;for(st=0;st<100;st++){st=1;}}
 #else
 #define DEB(x)
-#define STOP_HERE
+#define STOP_HERE()
 #endif
 
-#define MAXADAPTER 4	/* Increase this and the sizes of the arrays below, if you need more. */
-
-#define	MAX_BUS_MASTER_BLOCKS	1		// This is the maximum we can bus master for (1024 bytes)
+#define MAXADAPTER 4					// Increase this and the sizes of the arrays below, if you need more.
 
-#define	PORT_DATA				0
-#define	PORT_ERROR				1
-#define	PORT_SECTOR_COUNT		2
-#define	PORT_LBA_0				3
-#define	PORT_LBA_8				4
-#define	PORT_LBA_16				5
-#define	PORT_LBA_24				6
-#define	PORT_STAT_CMD			7
-#define	PORT_STAT_SEL			8
-#define	PORT_FAIL				9
-#define	PORT_ALT_STAT		   	10
 
 typedef struct
 	{
@@ -88,44 +82,245 @@
 	USHORT			cylinders;			// number of cylinders for this device
 	USHORT			spareword;			// placeholder
 	ULONG			blocks;				// number of blocks on device
-	}	OUR_DEVICE, *POUR_DEVICE;
+	DISK_MIRROR		DiskMirror[2];		// RAID status and control
+	ULONG			lastsectorlba[2];	// last addressable sector on the drive
+	USHORT			raid;				// RAID active flag
+	USHORT			mirrorRecon;
+	UCHAR			hotRecon;
+	USHORT			reconCount;
+	}	OUR_DEVICE, *POUR_DEVICE;	
 
 typedef struct
 	{
-	USHORT		 ports[12];
-	USHORT		 regDmaDesc;					// address of the DMA discriptor register for direction of transfer
-	USHORT		 regDmaCmdStat;					// Byte #1 of DMA command status register
-	USHORT		 regDmaAddrPci;					// 32 bit register for PCI address of DMA
-	USHORT		 regDmaAddrLoc;					// 32 bit register for local bus address of DMA
-	USHORT		 regDmaCount;					// 32 bit register for DMA transfer count
-	USHORT		 regDmaMode;						// 32 bit register for DMA mode control
-	USHORT		 regRemap;						// 32 bit local space remap
-	USHORT		 regDesc;						// 32 bit local region descriptor
-	USHORT		 regRange;						// 32 bit local range
-	USHORT		 regIrqControl;					// 16 bit Interrupt enable/disable and status
-	USHORT		 regScratchPad;					// scratch pad I/O base address
-	USHORT		 regBase;						// Base I/O register for data space
-	USHORT		 basePort;						// PLX base I/O port
-	USHORT		 timingMode;					// timing mode currently set for adapter
-	ULONG		 timingAddress;					// address to use on adapter for current timing mode
-	OUR_DEVICE	 device[4];
-	IDE_STRUCT	 ide;
+	USHORT		 regDmaDesc;			// address of the DMA discriptor register for direction of transfer
+	USHORT		 regDmaCmdStat;			// Byte #1 of DMA command status register
+	USHORT		 regDmaAddrPci;			// 32 bit register for PCI address of DMA
+	USHORT		 regDmaAddrLoc;			// 32 bit register for local bus address of DMA
+	USHORT		 regDmaCount;			// 32 bit register for DMA transfer count
+	USHORT		 regDmaMode;			// 32 bit register for DMA mode control
+	USHORT		 regRemap;				// 32 bit local space remap
+	USHORT		 regDesc;				// 32 bit local region descriptor
+	USHORT		 regRange;				// 32 bit local range
+	USHORT		 regIrqControl;			// 16 bit Interrupt enable/disable and status
+	USHORT		 regScratchPad;			// scratch pad I/O base address
+	USHORT		 regBase;				// Base I/O register for data space
+	USHORT		 regData;				// data register I/O address
+	USHORT		 regError;				// error register I/O address
+	USHORT		 regSectCount;			// sector count register I/O address
+	USHORT		 regLba0;				// least significant byte of LBA
+	USHORT		 regLba8;				// next least significant byte of LBA
+	USHORT		 regLba16;				// next most significan byte of LBA
+	USHORT		 regLba24;				// head and most 4 significant bits of LBA
+	USHORT		 regStatCmd;			// status on read and command on write register
+	USHORT		 regStatSel;			// board status on read and spigot select on write register
+	USHORT		 regFail;				// fail bits control register
+	USHORT		 regAltStat;			// alternate status and drive control register
+	USHORT		 basePort;				// PLX base I/O port
+	USHORT		 timingMode;			// timing mode currently set for adapter
+	USHORT		 timingPIO;				// TRUE if PIO timing is active
+	ULONG		 timingAddress;			// address to use on adapter for current timing mode
+	OUR_DEVICE	 device[DALE_MAXDRIVES];
+	DISK_MIRROR	*raidData[8];
 	ULONG		 startSector;
 	USHORT		 sectorCount;
+	UCHAR		 cmd;
 	Scsi_Cmnd	*SCpnt;
 	VOID		*buffer;
+	POUR_DEVICE	 pdev;					// current device opearating on
 	USHORT		 expectingIRQ;
-	USHORT		 readPhase;
+	USHORT		 reconIsStarting;		// indicate hot reconstruct is starting
+	USHORT		 reconOn;				// Hot reconstruct is to be done.
+	USHORT		 reconPhase;			// Hot reconstruct operation is in progress.
+	ULONG		 reconSize;
+	USHORT		 demoFail;				// flag for RAID failure demonstration
+	USHORT		 survivor;
+	USHORT		 failinprog;
+	USHORT		 timeoutReconRetry;
+	struct timer_list	reconTimer;	
+	struct timer_list	timer;
 	}	ADAPTER2220I, *PADAPTER2220I;
 
 #define HOSTDATA(host) ((PADAPTER2220I)&host->hostdata)
 
+#define	RECON_PHASE_READY		0x01
+#define	RECON_PHASE_COPY		0x02
+#define	RECON_PHASE_UPDATE		0x03
+#define	RECON_PHASE_LAST		0x04
+#define	RECON_PHASE_END			0x07	
+#define	RECON_PHASE_MARKING		0x80
+#define	RECON_PHASE_FAILOVER	0xFF
 
 static struct	Scsi_Host 	   *PsiHost[MAXADAPTER] = {NULL,};  // One for each adapter
 static			int				NumAdapters = 0;
-static			IDENTIFY_DATA	identifyData;
 static			SETUP			DaleSetup;
+static			DISK_MIRROR		DiskMirror[2];
+static			ULONG			ModeArray[] = {DALE_DATA_MODE2, DALE_DATA_MODE3, DALE_DATA_MODE4, DALE_DATA_MODE4P};
+static			UCHAR			Buffer[SECTORSXFER * BYTES_PER_SECTOR];
+
+static void ReconTimerExpiry (unsigned long data);
+
+/****************************************************************
+ *	Name:	MuteAlarm	:LOCAL
+ *
+ *	Description:	Mute the audible alarm.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static void MuteAlarm (PADAPTER2220I padapter)
+	{
+	UCHAR	old;
 
+	old = (inb_p (padapter->regStatSel) >> 3) | (inb_p (padapter->regStatSel) & 0x83);
+	outb_p (old | 0x40, padapter->regFail);
+	}
+/****************************************************************
+ *	Name:	WaitReady	:LOCAL
+ *
+ *	Description:	Wait for device ready.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int WaitReady (PADAPTER2220I padapter)
+	{
+	ULONG	z;
+	UCHAR	status;
+
+	for ( z = 0;  z < (TIMEOUT_READY * 4);  z++ )
+		{
+		status = inb_p (padapter->regStatCmd);
+		if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
+			return 0;
+		udelay (250);
+		}
+	return status;
+	}
+/****************************************************************
+ *	Name:	WaitReadyReset	:LOCAL
+ *
+ *	Description:	Wait for device ready.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int WaitReadyReset (PADAPTER2220I padapter)
+	{
+	ULONG	z;
+	UCHAR	status;
+
+	for ( z = 0;  z < (250 * 4);  z++ )				// wait up to 1/4 second
+		{
+		status = inb_p (padapter->regStatCmd);
+		if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
+			{
+			DEB (printk ("\nPCI2220I:  Reset took %ld mSec to be ready", z / 4));
+			return 0;
+			}
+		udelay (250);
+		}
+	DEB (printk ("\nPCI2220I:  Reset took more than 1 Second to come ready, Disk Failure"));
+	return status;
+	}
+/****************************************************************
+ *	Name:	WaitDrq	:LOCAL
+ *
+ *	Description:	Wait for device ready for data transfer.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int WaitDrq (PADAPTER2220I padapter)
+	{
+	ULONG	z;
+	UCHAR	status;
+
+	for ( z = 0;  z < (TIMEOUT_DRQ * 4);  z++ )
+		{
+		status = inb_p (padapter->regStatCmd);
+		if ( status & IDE_STATUS_DRQ )
+			return 0;
+		udelay (250);
+		}
+	return status;
+	}
+/****************************************************************
+ *	Name:	HardReset	:LOCAL
+ *
+ *	Description:	Wait for device ready for data transfer.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *					pdev	 - Pointer to device.
+ *					spigot	 - Spigot number.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int HardReset (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot)
+	{
+	SelectSpigot (padapter, spigot | 0x80);
+	
+	outb_p (0x0E, padapter->regAltStat);					// reset the suvivor
+	udelay (100);											// wait a little	
+	outb_p (0x08, padapter->regAltStat);					// clear the reset
+	udelay (100);
+	outb_p (0xA0, padapter->regLba24);						//Specify drive
+
+	outb_p (pdev->byte6, padapter->regLba24);				// select the drive
+	if ( WaitReadyReset (padapter) )
+		return TRUE;
+	outb_p (SECTORSXFER, padapter->regSectCount);
+	WriteCommand (padapter, IDE_CMD_SET_MULTIPLE);	
+	if ( WaitReady (padapter) )
+		return TRUE;
+	return FALSE;
+	}
+/****************************************************************
+ *	Name:	BusMaster	:LOCAL
+ *
+ *	Description:	Do a bus master I/O.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *					datain	 - TRUE if data read.
+ *					irq		 - TRUE if bus master interrupt expected.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static void BusMaster (PADAPTER2220I padapter, UCHAR datain, UCHAR irq)
+	{
+	ULONG zl;
+	
+	outl (padapter->timingAddress, padapter->regDmaAddrLoc);
+	outl (virt_to_bus (padapter->buffer), padapter->regDmaAddrPci);
+	zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
+	padapter->sectorCount -= zl;
+	zl *= (ULONG)BYTES_PER_SECTOR;
+	padapter->buffer += zl;
+	outl (zl, padapter->regDmaCount);
+	if ( datain )
+		{
+		outb_p (8, padapter->regDmaDesc);						// read operation
+		if ( irq && !padapter->sectorCount )
+			outb_p (5, padapter->regDmaMode);					// interrupt on
+		else
+			outb_p (1, padapter->regDmaMode);					// no interrupt
+		}
+	else
+		{
+		outb_p (0, padapter->regDmaDesc);						// write operation
+		outb_p (1, padapter->regDmaMode);						// no interrupt
+		}
+	outb_p (0x03, padapter->regDmaCmdStat);						// kick the DMA engine in gear
+	}
 /****************************************************************
  *	Name:	WriteData	:LOCAL
  *
@@ -138,114 +333,224 @@
  ****************************************************************/
 static int WriteData (PADAPTER2220I padapter)
 	{
-	ULONG	timer;
-	USHORT *pports = padapter->ports;
+	ULONG	zl;
+	
+	if ( !WaitDrq (padapter) )
+		{
+		if ( padapter->timingPIO )
+			{
+			zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
+			outsw (padapter->regData, padapter->buffer, zl * (BYTES_PER_SECTOR / 2));
+			padapter->sectorCount -= zl;
+			padapter->buffer += zl * BYTES_PER_SECTOR;
+			}
+		else
+			BusMaster (padapter, 0, 0);
+		return 0;
+		}
+	padapter->cmd = 0;												// null out the command byte
+	return 1;
+	}
+/****************************************************************
+ *	Name:	WriteDataBoth	:LOCAL
+ *
+ *	Description:	Write data to device.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *
+ *	Returns:		TRUE if drive does not assert DRQ in time.
+ *
+ ****************************************************************/
+static int WriteDataBoth (PADAPTER2220I padapter)
+	{
+	ULONG	zl;
+	UCHAR	status0, status1;
 
-	timer = jiffies + TIMEOUT_DRQ;								// calculate the timeout value
-	do  {
-		if ( inb_p (pports[PORT_STAT_CMD]) & IDE_STATUS_DRQ )
-			{
-			outb_p (0, padapter->regDmaDesc);							// write operation
-			outl (padapter->timingAddress, padapter->regDmaAddrLoc);
-			outl (virt_to_bus (padapter->buffer), padapter->regDmaAddrPci);
-			outl ((ULONG)padapter->ide.ide.ide[2] * (ULONG)512, padapter->regDmaCount);
-			outb_p (1, padapter->regDmaMode);							// interrupts off
-			outb_p (0x03, padapter->regDmaCmdStat);						// kick the DMA engine in gear
+	SelectSpigot (padapter, 1);
+	status0 = WaitDrq (padapter);
+	if ( !status0 )
+		{
+		SelectSpigot (padapter, 2);
+		status1 = WaitDrq (padapter);
+		if ( !status1 )
+			{
+			SelectSpigot (padapter, 3);
+			if ( padapter->timingPIO )
+				{
+				zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
+				outsw (padapter->regData, padapter->buffer, zl * (BYTES_PER_SECTOR / 2));
+				padapter->sectorCount -= zl;
+				padapter->buffer += zl * BYTES_PER_SECTOR;
+				}
+			else
+				BusMaster (padapter, 0, 0);
 			return 0;
 			}
-		}	while ( timer > jiffies );									// test for timeout
-
-	padapter->ide.ide.ides.cmd = 0;									// null out the command byte
-	return 1;
+		}
+	padapter->cmd = 0;												// null out the command byte
+	if ( status0 )
+		return 1;
+	return 2;
 	}
 /****************************************************************
  *	Name:	IdeCmd	:LOCAL
  *
- *	Description:	Process a queued command from the SCSI manager.
+ *	Description:	Process an IDE command.
  *
  *	Parameters:		padapter - Pointer adapter data structure.
+ *					pdev	 - Pointer to device.
  *
  *	Returns:		Zero if no error or status register contents on error.
  *
  ****************************************************************/
-static UCHAR IdeCmd (PADAPTER2220I padapter)
+static UCHAR IdeCmd (PADAPTER2220I padapter, POUR_DEVICE pdev)
 	{
-	ULONG	timer;
-	USHORT *pports = padapter->ports;
 	UCHAR	status;
 
-	outb_p (padapter->ide.ide.ides.spigot, pports[PORT_STAT_SEL]);	// select the spigot
-	outb_p (padapter->ide.ide.ide[6], pports[PORT_LBA_24]);			// select the drive
-	timer = jiffies + TIMEOUT_READY;							// calculate the timeout value
-	DEB(printk ("\npci2220i Issueing new command: 0x%X",padapter->ide.ide.ides.cmd));
-	do  {
-		status = inb_p (padapter->ports[PORT_STAT_CMD]);
-		if ( status & IDE_STATUS_DRDY )
-			{
-			outb_p (padapter->ide.ide.ide[2], pports[PORT_SECTOR_COUNT]);
-			outb_p (padapter->ide.ide.ide[3], pports[PORT_LBA_0]);
-			outb_p (padapter->ide.ide.ide[4], pports[PORT_LBA_8]);
-			outb_p (padapter->ide.ide.ide[5], pports[PORT_LBA_16]);
-			padapter->expectingIRQ = 1;
-			outb_p (padapter->ide.ide.ide[7], pports[PORT_STAT_CMD]);
-
-			if ( padapter->ide.ide.ides.cmd == IDE_CMD_WRITE_MULTIPLE )
-				return (WriteData (padapter));
-			return 0;
-			}
-		}	while ( timer > jiffies );									// test for timeout
+	SelectSpigot (padapter, pdev->spigot);							// select the spigot
+	outb_p (pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);			// select the drive
+	status = WaitReady (padapter);
+	if ( !status )
+		{
+		outb_p (padapter->sectorCount, padapter->regSectCount);
+		outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
+		outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
+		outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
+		padapter->expectingIRQ = TRUE;
+		WriteCommand (padapter, padapter->cmd);
+		return 0;
+		}
 
-	padapter->ide.ide.ides.cmd = 0;									// null out the command byte
+	padapter->cmd = 0;									// null out the command byte
 	return status;
 	}
 /****************************************************************
- *	Name:	SetupTransfer	:LOCAL
+ *	Name:	IdeCmdBoth	:LOCAL
  *
- *	Description:	Setup a data transfer command.
+ *	Description:	Process an IDE command to both drivers.
  *
  *	Parameters:		padapter - Pointer adapter data structure.
- *					drive	 - Drive/head register upper nibble only.
  *
- *	Returns:		TRUE if no data to transfer.
+ *	Returns:		Zero if no error or spigot of error.
  *
  ****************************************************************/
-static int SetupTransfer (PADAPTER2220I padapter, UCHAR drive)
+static UCHAR IdeCmdBoth (PADAPTER2220I padapter)
 	{
-	if ( padapter->sectorCount )
+	UCHAR	status0;
+	UCHAR	status1;
+
+	SelectSpigot (padapter, 3);										// select the spigots
+	outb_p (padapter->pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);// select the drive
+	SelectSpigot (padapter, 1);
+	status0 = WaitReady (padapter);
+	if ( !status0 )
 		{
-		*(ULONG *)padapter->ide.ide.ides.lba = padapter->startSector;
-		padapter->ide.ide.ide[6] |= drive;
-//		padapter->ide.ide.ides.sectors = ( padapter->sectorCount > SECTORSXFER ) ? SECTORSXFER : padapter->sectorCount;
-		padapter->ide.ide.ides.sectors = ( padapter->sectorCount > MAX_BUS_MASTER_BLOCKS ) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
-		padapter->sectorCount -= padapter->ide.ide.ides.sectors;	// bump the start and count for next xfer
-		padapter->startSector += padapter->ide.ide.ides.sectors;
-		return 0;
+		SelectSpigot (padapter, 2);
+		status1 = WaitReady (padapter);
+		if ( !status1 )
+			{
+			SelectSpigot (padapter, 3);
+			outb_p (padapter->sectorCount, padapter->regSectCount);
+			outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
+			outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
+			outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
+			padapter->expectingIRQ = TRUE;
+			WriteCommand (padapter, padapter->cmd);
+			return 0;
+			}
+		}
+	padapter->cmd = 0;									// null out the command byte
+	if ( status0 )
+		return 1;
+	return 2;
+	}
+/****************************************************************
+ *	Name:	OpDone	:LOCAL
+ *
+ *	Description:	Complete an operatoin done sequence.
+ *
+ *	Parameters:		padapter - Pointer to host data block.
+ *					spigot	 - Spigot select code.
+ *					device	 - Device byte code.
+ *
+ *	Returns:		Nothing.
+ *
+ ****************************************************************/
+static void OpDone (PADAPTER2220I padapter, ULONG result)
+	{
+	Scsi_Cmnd	   *SCpnt = padapter->SCpnt;
+	
+	if ( padapter->reconPhase )
+		{
+		padapter->reconPhase = 0;
+		if ( padapter->SCpnt )
+			{
+			Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
+			}
+		else
+			{
+			if ( padapter->reconOn )
+				{
+				ReconTimerExpiry ((unsigned long)padapter);
+				}
+			}
 		}
 	else
 		{
-		padapter->ide.ide.ides.cmd = 0;								// null out the command byte
-		padapter->SCpnt = NULL;
-		return 1;
+		padapter->cmd = 0;
+		padapter->SCpnt = NULL;	
+		SCpnt->result = result;
+		SCpnt->scsi_done (SCpnt);
+		if ( padapter->reconOn && !padapter->reconTimer.data )
+			{
+			padapter->reconTimer.expires = jiffies + (HZ / 4);	// start in 1/4 second
+			padapter->reconTimer.data = (unsigned long)padapter;
+			add_timer (&padapter->reconTimer);
+			}
 		}
 	}
 /****************************************************************
+ *	Name:	InlineIdentify	:LOCAL
+ *
+ *	Description:	Do an intline inquiry on a drive.
+ *
+ *	Parameters:		padapter - Pointer to host data block.
+ *					spigot	 - Spigot select code.
+ *					device	 - Device byte code.
+ *
+ *	Returns:		Last addressable sector or zero if none.
+ *
+ ****************************************************************/
+static ULONG InlineIdentify (PADAPTER2220I padapter, UCHAR spigot, UCHAR device)
+	{
+	PIDENTIFY_DATA	pid = (PIDENTIFY_DATA)Buffer;
+
+	SelectSpigot (padapter, spigot | 0x80);						// select the spigot
+	outb_p (device << 4, padapter->regLba24);				// select the drive
+	if ( WaitReady (padapter) )
+		return 0;
+	WriteCommand (padapter, IDE_COMMAND_IDENTIFY);	
+	if ( WaitDrq (padapter) )
+		return 0;
+	insw (padapter->regData, Buffer, sizeof (IDENTIFY_DATA) >> 1);
+	return (pid->LBATotalSectors - 1);
+	}
+/****************************************************************
  *	Name:	DecodeError	:LOCAL
  *
  *	Description:	Decode and process device errors.
  *
- *	Parameters:		pshost - Pointer to host data block.
+ *	Parameters:		padapter - Pointer to adapter data.
  *					status - Status register code.
  *
  *	Returns:		The driver status code.
  *
  ****************************************************************/
-static ULONG DecodeError (struct Scsi_Host *pshost, UCHAR status)
+static ULONG DecodeError (PADAPTER2220I	padapter, UCHAR status)
 	{
-	PADAPTER2220I	padapter = HOSTDATA(pshost);
 	UCHAR			error;
 
 	padapter->expectingIRQ = 0;
-	padapter->SCpnt = NULL;
 	if ( status & IDE_STATUS_WRITE_FAULT )
 		{
 		return DID_PARITY << 16;
@@ -253,7 +558,7 @@
 	if ( status & IDE_STATUS_BUSY )
 		return DID_BUS_BUSY << 16;
 
-	error = inb_p (padapter->ports[PORT_ERROR]);
+	error = inb_p (padapter->regError);
 	DEB(printk ("\npci2220i error register: %x", error));
 	switch ( error )
 		{
@@ -269,6 +574,483 @@
 	return DID_ERROR << 16;
 	}
 /****************************************************************
+ *	Name:	StartTimer	:LOCAL
+ *
+ *	Description:	Start the timer.
+ *
+ *	Parameters:		ipadapter - Pointer adapter data structure.
+ *
+ *	Returns:		Nothing.
+ *
+ ****************************************************************/
+static void StartTimer (PADAPTER2220I padapter)
+	{
+	padapter->timer.expires = jiffies + TIMEOUT_DATA;
+	add_timer (&padapter->timer);
+	}
+/****************************************************************
+ *	Name:	WriteSignature	:LOCAL
+ *
+ *	Description:	Start the timer.
+ *
+ *	Parameters:		padapter - Pointer adapter data structure.
+ *					pdev	 - Pointer to our device.
+ *					spigot	 - Selected spigot.
+ *					index	 - index of mirror signature on device.
+ *
+ *	Returns:		TRUE on any error.
+ *
+ ****************************************************************/
+static int WriteSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot, int index)
+	{
+	ULONG	zl;
+
+	SelectSpigot (padapter, spigot);
+	zl = pdev->lastsectorlba[index];
+	outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);		
+	outb_p (((UCHAR *)&zl)[2], padapter->regLba16);
+	outb_p (((UCHAR *)&zl)[1], padapter->regLba8);
+	outb_p (((UCHAR *)&zl)[0], padapter->regLba0);
+	outb_p (1, padapter->regSectCount);
+
+	WriteCommand (padapter, IDE_COMMAND_WRITE);	
+	if ( WaitDrq (padapter) )
+		return TRUE;
+	StartTimer (padapter);	
+	padapter->expectingIRQ = TRUE;
+	
+	outsw (padapter->regData, Buffer, DISK_MIRROR_POSITION / 2);
+	outsw (padapter->regData, &pdev->DiskMirror[index], sizeof (DISK_MIRROR) / 2);
+	outsw (padapter->regData, Buffer, ((512 - (DISK_MIRROR_POSITION + sizeof (DISK_MIRROR))) / 2));
+	return FALSE;
+	}
+/*******************************************************************************************************
+ *	Name:			InitFailover
+ *
+ *	Description:	This is the beginning of the failover routine
+ *
+ *	Parameters:		SCpnt	 - Pointer to SCSI command structure.
+ *					padapter - Pointer adapter data structure.
+ *					pdev	 - Pointer to our device.
+ *	
+ *	Returns:		TRUE on error.
+ *
+ ******************************************************************************************************/
+static int InitFailover (PADAPTER2220I padapter, POUR_DEVICE pdev)
+	{
+	UCHAR			 spigot;
+	
+	DEB (printk ("\npci2220i:  Initialize failover process - survivor = %d", padapter->survivor));
+	pdev->raid = FALSE;									//initializes system for non raid mode
+	pdev->hotRecon = 0;
+	padapter->reconOn = FALSE;
+	spigot = (padapter->survivor) ? 2 : 1;	
+
+	if ( pdev->DiskMirror[padapter->survivor].status & UCBF_REBUILD )
+		return (TRUE); 	
+
+	if ( HardReset (padapter, pdev, spigot) )
+		return TRUE;
+
+	outb_p (0x3C | spigot, padapter->regFail);			// sound alarm and set fail light		
+	pdev->DiskMirror[padapter->survivor].status = UCBF_MIRRORED | UCBF_SURVIVOR;	//clear present status
+	
+	if ( WriteSignature (padapter, pdev, spigot, padapter->survivor) )
+		return TRUE;
+	padapter->failinprog = TRUE;
+	return FALSE;
+	}
+/****************************************************************
+ *	Name:	TimerExpiry	:LOCAL
+ *
+ *	Description:	Timer expiry routine.
+ *
+ *	Parameters:		data - Pointer adapter data structure.
+ *
+ *	Returns:		Nothing.
+ *
+ ****************************************************************/
+static void TimerExpiry (unsigned long data)
+	{
+	PADAPTER2220I	padapter = (PADAPTER2220I)data;
+	POUR_DEVICE		pdev = padapter->pdev;
+	ULONG			flags;
+	UCHAR			status = IDE_STATUS_BUSY;
+	UCHAR			temp, temp1;
+
+	DEB (printk ("\nPCI2220I: Timeout expired "));
+	save_flags (flags);
+	cli ();
+
+	if ( padapter->failinprog )
+		{
+		DEB (printk ("in failover process"));
+		restore_flags (flags);
+		OpDone (padapter, DecodeError (padapter, inb_p (padapter->regStatCmd)));
+		return;
+		}
+	
+	while ( padapter->reconPhase )
+		{
+		DEB (printk ("in recon phase %X", padapter->reconPhase));
+		if ( --padapter->timeoutReconRetry )
+			{
+			StartTimer (padapter);
+			return;
+			}
+		switch ( padapter->reconPhase )
+			{
+			case RECON_PHASE_MARKING:
+			case RECON_PHASE_LAST:
+				padapter->survivor = (pdev->spigot ^ 3) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 1"));
+				if ( InitFailover (padapter, pdev) )
+					OpDone (padapter, DID_ERROR << 16);
+				return;
+			
+			case RECON_PHASE_READY:
+				OpDone (padapter, DID_ERROR << 16);
+				return;
+
+			case RECON_PHASE_COPY:
+				padapter->survivor = (pdev->spigot) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 2"));
+				if ( InitFailover (padapter, pdev) )
+					OpDone (padapter, DID_ERROR << 16);
+				return;
+
+			case RECON_PHASE_UPDATE:
+				padapter->survivor = (pdev->spigot) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 3"));
+				if ( InitFailover (padapter, pdev) )
+					OpDone (padapter, DID_ERROR << 16);
+				return;
+
+			case RECON_PHASE_END:
+				padapter->survivor = (pdev->spigot) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 4"));
+				if ( InitFailover (padapter, pdev) )
+					OpDone (padapter, DID_ERROR << 16);
+				return;
+			
+			default:
+				return;
+			}
+		}
+	
+	while ( padapter->cmd )
+		{
+		outb_p (0x08, padapter->regDmaCmdStat);					// cancel interrupt from DMA engine
+		if ( pdev->raid )
+			{
+			if ( padapter->cmd == WRITE_CMD )
+				{
+				DEB (printk ("in RAID write operation"));
+				if ( inb_p (padapter->regStatSel) & 1 )
+					{
+					SelectSpigot (padapter, 0x81 ); // Masking the interrupt during spigot select
+					temp = inb_p (padapter->regStatCmd);
+					}
+				else
+					temp = IDE_STATUS_BUSY;
+
+				if ( inb (padapter->regStatSel) & 2 )
+					{
+					SelectSpigot (padapter, 0x82 ); // Masking the interrupt during spigot select
+					temp1 = inb_p (padapter->regStatCmd);
+					}
+				else
+					temp1 = IDE_STATUS_BUSY;
+			
+				if ( (temp & IDE_STATUS_BUSY) || (temp1 & IDE_STATUS_BUSY) )
+					{
+	 				if ( (temp & IDE_STATUS_BUSY) && (temp1 & IDE_STATUS_BUSY) ) 
+						{
+						status = temp;
+						break;
+						}		
+					else	
+						{
+						if (temp & IDE_STATUS_BUSY)
+							padapter->survivor = 1;
+						else
+							padapter->survivor = 0;
+						restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 5"));
+						if ( InitFailover (padapter, pdev) )
+							{
+							status = inb_p (padapter->regStatCmd);
+							break;
+							}
+						return;
+						}
+					}
+				}
+			else
+				{
+				DEB (printk ("in RAID read operation"));
+				padapter->survivor = (pdev->spigot ^ 3) >> 1;
+				restore_flags (flags);
+				DEB (printk ("\npci2220i: FAILURE 6"));
+				if ( InitFailover (padapter, pdev) )
+					{
+					status = inb_p (padapter->regStatCmd);
+					break;
+					}
+				return;
+				}
+			}
+		else
+			{
+			DEB (printk ("in I/O operation"));
+			status = inb_p (padapter->regStatCmd);
+			}
+		break;
+		}
+	
+	restore_flags (flags);
+	OpDone (padapter, DecodeError (padapter, status));
+	}
+/****************************************************************
+ *	Name:			SetReconstruct	:LOCAL
+ *
+ *	Description:	Set the reconstruct up.
+ *
+ *	Parameters:		pdev	- Pointer to device structure.
+ *					index	- Mirror index number.
+ *
+ *	Returns:		Number of sectors on new disk required.
+ *
+ ****************************************************************/
+static LONG SetReconstruct (POUR_DEVICE pdev, int index)
+	{
+	pdev->DiskMirror[index].status = UCBF_MIRRORED;							// setup the flags
+	pdev->DiskMirror[index ^ 1].status = UCBF_MIRRORED | UCBF_REBUILD;
+	pdev->DiskMirror[index ^ 1].reconstructPoint = 0;						// start the reconstruct
+	pdev->reconCount = 1990;												// mark target drive early
+	pdev->hotRecon = 1 >> index;
+	return pdev->DiskMirror[index].reconstructPoint;
+	}
+/****************************************************************
+ *	Name:	ReconTimerExpiry	:LOCAL
+ *
+ *	Description:	Reconstruct timer expiry routine.
+ *
+ *	Parameters:		data - Pointer adapter data structure.
+ *
+ *	Returns:		Nothing.
+ *
+ ****************************************************************/
+static void ReconTimerExpiry (unsigned long data)
+	{
+	PADAPTER2220I	padapter;
+	POUR_DEVICE		pdev;
+	ULONG			testsize = 0;
+	PIDENTIFY_DATA	pid;
+	USHORT			minmode;
+	ULONG			zl;
+	UCHAR			zc;
+
+	padapter = (PADAPTER2220I)data;
+	if ( padapter->SCpnt )
+		return;
+
+	pdev = padapter->device;
+	pid = (PIDENTIFY_DATA)Buffer;
+	padapter->reconTimer.data = 0;
+	padapter->timeoutReconRetry = 2;
+	padapter->pdev = pdev;
+	if ( padapter->reconIsStarting )
+		{
+		padapter->reconIsStarting = FALSE;
+		padapter->reconOn = FALSE;
+		pdev->hotRecon = FALSE;
+
+		if ( (pdev->DiskMirror[0].signature == SIGNATURE) && (pdev->DiskMirror[1].signature == SIGNATURE) &&
+			 (pdev->DiskMirror[0].pairIdentifier == (pdev->DiskMirror[1].pairIdentifier ^ 1)) )
+			{
+			if ( (pdev->DiskMirror[0].status & UCBF_MATCHED) && (pdev->DiskMirror[1].status & UCBF_MATCHED) )
+				{
+				return;
+				}
+
+			if ( pdev->DiskMirror[0].status & UCBF_SURVIVOR )				// is first drive survivor?
+				testsize = SetReconstruct (pdev, 0);
+			else
+				if ( pdev->DiskMirror[1].status & UCBF_SURVIVOR )			// is second drive survivor?
+					testsize = SetReconstruct (pdev, 1);
+
+			if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
+				{
+				if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
+					{
+					pdev->hotRecon = 1;
+					pdev->mirrorRecon = 0;
+					}
+				else
+					{
+					pdev->hotRecon = 2;
+					pdev->mirrorRecon = 1;
+					}
+				}
+			}
+
+		if ( !pdev->hotRecon )
+			return;
+
+		zc = ((inb_p (padapter->regStatSel) >> 3) | inb_p (padapter->regStatSel)) & 0x83;		// mute the alarm
+		outb_p (zc | pdev->hotRecon | 0x40, padapter->regFail);
+
+		while ( 1 )
+			{
+			if ( HardReset (padapter, pdev, pdev->hotRecon) )
+				{
+				DEB (printk ("\npci2220i: sub 1"));
+				break;
+				}
+
+			pdev->lastsectorlba[pdev->mirrorRecon] = InlineIdentify (padapter, pdev->hotRecon, 0);
+
+			if ( pdev->lastsectorlba[pdev->mirrorRecon] < testsize )
+				{
+				DEB (printk ("\npci2220i: sub 2 %ld %ld", pdev->lastsectorlba[pdev->mirrorRecon], testsize));
+				break;
+				}
+
+	        // test LBA and multiper sector transfer compatability
+			if (!pid->SupportLBA || (pid->NumSectorsPerInt < SECTORSXFER) || !pid->Valid_64_70 )
+				{
+				DEB (printk ("\npci2220i: sub 3"));
+				break;
+				}
+
+	        // test PIO/bus matering mode compatability
+			if ( (pid->MinPIOCycleWithoutFlow > 240) && !pid->SupportIORDYDisable && !padapter->timingPIO )
+				{
+				DEB (printk ("\npci2220i: sub 4"));
+				break;
+				}
+
+			if ( pid->MinPIOCycleWithoutFlow <= 120 )	// setup timing mode of drive
+				minmode = 5;
+			else
+				{
+				if ( pid->MinPIOCylceWithFlow <= 150 )
+					minmode = 4;
+				else
+					{
+					if ( pid->MinPIOCylceWithFlow <= 180 )
+						minmode = 3;
+					else
+						{
+						if ( pid->MinPIOCylceWithFlow <= 240 )
+							minmode = 2;
+						else
+							{
+							DEB (printk ("\npci2220i: sub 5"));
+							break;
+							}
+						}
+					}
+				}
+
+			if ( padapter->timingMode > minmode )									// set minimum timing mode
+				padapter->timingMode = minmode;
+			if ( padapter->timingMode >= 2 )
+				padapter->timingAddress	= ModeArray[padapter->timingMode - 2];
+			else
+				padapter->timingPIO = TRUE;
+
+			padapter->reconOn = TRUE;
+			break;
+			}
+
+		if ( !padapter->reconOn )
+			{		
+			pdev->hotRecon = FALSE;
+			padapter->survivor = pdev->mirrorRecon ^ 1;
+			padapter->reconPhase = RECON_PHASE_FAILOVER;
+				DEB (printk ("\npci2220i: FAILURE 7"));
+			InitFailover (padapter, pdev);
+			return;
+			}
+
+		pdev->raid = TRUE;
+	
+		if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
+			return;
+		padapter->reconPhase = RECON_PHASE_MARKING;
+		return;
+		}
+
+	//**********************************
+	// reconstruct copy starts here	
+	//**********************************
+	if ( pdev->reconCount++ > 2000 )
+		{
+		pdev->reconCount = 0;
+		if ( WriteSignature (padapter, pdev, pdev->hotRecon, pdev->mirrorRecon) )
+			{
+			padapter->survivor = pdev->mirrorRecon ^ 1;
+			padapter->reconPhase = RECON_PHASE_FAILOVER;
+				DEB (printk ("\npci2220i: FAILURE 8"));
+			InitFailover (padapter, pdev);
+			return;
+			}
+		padapter->reconPhase = RECON_PHASE_UPDATE;
+		return;
+		}
+
+	zl = pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint;	
+	padapter->reconSize = pdev->DiskMirror[pdev->mirrorRecon ^ 1].reconstructPoint - zl;
+	if ( padapter->reconSize > MAX_BUS_MASTER_BLOCKS )
+		padapter->reconSize = MAX_BUS_MASTER_BLOCKS;
+
+	if ( padapter->reconSize )
+		{
+		SelectSpigot (padapter, 3);										// select the spigots
+		outb_p (pdev->byte6 | ((UCHAR *)(&zl))[3], padapter->regLba24);// select the drive
+		SelectSpigot (padapter, pdev->spigot);
+		if ( WaitReady (padapter) )
+			return;
+
+		SelectSpigot (padapter, pdev->hotRecon);
+		if ( WaitReady (padapter) )
+			{
+			padapter->survivor = pdev->mirrorRecon ^ 1;
+			padapter->reconPhase = RECON_PHASE_FAILOVER;
+				DEB (printk ("\npci2220i: FAILURE 9"));
+			InitFailover (padapter, pdev);
+			return;
+			}
+	
+		SelectSpigot (padapter, 3);
+		outb_p (padapter->reconSize & 0xFF, padapter->regSectCount);
+		outb_p (((UCHAR *)(&zl))[0], padapter->regLba0);
+		outb_p (((UCHAR *)(&zl))[1], padapter->regLba8);
+		outb_p (((UCHAR *)(&zl))[2], padapter->regLba16);
+		padapter->expectingIRQ = TRUE;
+		padapter->reconPhase = RECON_PHASE_READY;
+		SelectSpigot (padapter, pdev->hotRecon);
+		WriteCommand (padapter, WRITE_CMD);
+		StartTimer (padapter);
+		SelectSpigot (padapter, pdev->spigot);
+		WriteCommand (padapter, READ_CMD);
+		return;
+		}
+
+	pdev->DiskMirror[pdev->mirrorRecon].status = UCBF_MIRRORED | UCBF_MATCHED;
+	pdev->DiskMirror[pdev->mirrorRecon ^ 1].status = UCBF_MIRRORED | UCBF_MATCHED;
+	if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
+		return;
+	padapter->reconPhase = RECON_PHASE_LAST;
+	return;
+	}
+/****************************************************************
  *	Name:	Irq_Handler	:LOCAL
  *
  *	Description:	Interrupt handler.
@@ -284,12 +1066,14 @@
 	{
 	struct Scsi_Host   *shost = NULL;	// Pointer to host data block
 	PADAPTER2220I		padapter;		// Pointer to adapter control structure
-	USHORT		 	   *pports;			// I/O port array
+	POUR_DEVICE			pdev;
 	Scsi_Cmnd		   *SCpnt;
 	UCHAR				status;
+	UCHAR				status1;
 	int					z;
+	ULONG				zl;
 
-//	DEB(printk ("\npci2220i recieved interrupt\n"));
+//	DEB (printk ("\npci2220i recieved interrupt\n"));
 
 	for ( z = 0; z < NumAdapters;  z++ )								// scan for interrupt to process
 		{
@@ -310,82 +1094,264 @@
 		}
 
 	padapter = HOSTDATA(shost);
-	pports = padapter->ports;
+	pdev = padapter->pdev;
 	SCpnt = padapter->SCpnt;
 
-	if ( !padapter->expectingIRQ )
+	if ( !padapter->expectingIRQ || !(SCpnt || padapter->reconPhase) )
 		{
 		DEB(printk ("\npci2220i Unsolicited interrupt\n"));
+		STOP_HERE ();
 		return;
 		}
 	padapter->expectingIRQ = 0;
+	outb_p (0x08, padapter->regDmaCmdStat);									// cancel interrupt from DMA engine
 
-	status = inb_p (padapter->ports[PORT_STAT_CMD]);					// read the device status
-	if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-		goto irqerror;
-
-	switch ( padapter->ide.ide.ides.cmd )								// decide how to handle the interrupt
-		{
-		case IDE_CMD_READ_MULTIPLE:
-			if ( padapter->readPhase == 1 )								// is this a bus master channel complete?
-				{
-				DEB(printk ("\npci2220i processing read interrupt cleanup"));
-				outb_p (0x08, padapter->regDmaCmdStat);					// cancel interrupt from DMA engine
-				padapter->buffer += padapter->ide.ide.ides.sectors * 512;
-				if ( SetupTransfer (padapter, padapter->ide.ide.ide[6] & 0xF0) )
-					{
-					SCpnt->result = DID_OK << 16;
-					padapter->SCpnt = NULL;
-					SCpnt->scsi_done (SCpnt);
+	if ( padapter->failinprog )
+		{
+		DEB (printk ("\npci2220i interrupt failover complete"));
+		padapter->failinprog = FALSE;
+		status = inb_p (padapter->regStatCmd);								// read the device status
+		if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+			{
+			DEB (printk ("\npci2220i: interrupt failover error from drive %X", status));
+			padapter->cmd = 0;
+			}
+		else
+			{
+			DEB (printk ("\npci2220i: restarting failed opertation."));
+			pdev->spigot = (padapter->survivor) ? 2 : 1;
+			del_timer (&padapter->timer);
+			if ( padapter->reconPhase )
+				OpDone (padapter, DID_OK << 16);
+			else
+				Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
+			return;		
+			}
+		}
+
+	if ( padapter->reconPhase )
+		{
+		switch ( padapter->reconPhase )
+			{
+			case RECON_PHASE_MARKING:
+			case RECON_PHASE_LAST:
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				del_timer (&padapter->timer);
+				if ( padapter->reconPhase == RECON_PHASE_LAST )
+					{
+					if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+						{
+						padapter->survivor = (pdev->spigot ^ 3) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 10"));
+						if ( InitFailover (padapter, pdev) )
+							OpDone (padapter, DecodeError (padapter, status));
+						return;
+						}
+					if ( WriteSignature (padapter, pdev, pdev->hotRecon, pdev->mirrorRecon) )
+						{
+						padapter->survivor = (pdev->spigot) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 11"));
+						if ( InitFailover (padapter, pdev) )
+							OpDone (padapter, DecodeError (padapter, status));
+						return;
+						}
+					padapter->reconPhase = RECON_PHASE_END;	
 					return;
 					}
-				padapter->readPhase = 0;
-				if ( !(status = IdeCmd (padapter)) )
+				OpDone (padapter, DID_OK << 16);
+				return;
+
+			case RECON_PHASE_READY:
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
 					{
-					DEB (printk ("\npci2220i interrupt complete, waiting for another"));
+					del_timer (&padapter->timer);
+					OpDone (padapter, DecodeError (padapter, status));
 					return;
 					}
-				}
-			if ( status & IDE_STATUS_DRQ )
+				SelectSpigot (padapter, pdev->hotRecon);
+				if ( WaitDrq (padapter) )
+					{
+					del_timer (&padapter->timer);
+					padapter->survivor = (pdev->spigot) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 12"));
+					if ( InitFailover (padapter, pdev) )
+						OpDone (padapter, DecodeError (padapter, status));
+					return;
+					}
+				SelectSpigot (padapter, pdev->spigot | 0x40);
+				padapter->reconPhase = RECON_PHASE_COPY;
+				padapter->expectingIRQ = TRUE;
+				if ( padapter->timingPIO )
+					{
+					insw (padapter->regData, Buffer, padapter->reconSize * (BYTES_PER_SECTOR / 2));
+					}
+				else
+					{
+					outl (padapter->timingAddress, padapter->regDmaAddrLoc);
+					outl (virt_to_bus (Buffer), padapter->regDmaAddrPci);
+					outl (padapter->reconSize * BYTES_PER_SECTOR, padapter->regDmaCount);
+					outb_p (8, padapter->regDmaDesc);						// read operation
+					outb_p (1, padapter->regDmaMode);						// no interrupt
+					outb_p (0x03, padapter->regDmaCmdStat);					// kick the DMA engine in gear
+					}
+				return;
+
+			case RECON_PHASE_COPY:
+				pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint += padapter->reconSize;
+
+			case RECON_PHASE_UPDATE:
+				SelectSpigot (padapter, pdev->hotRecon | 0x80);
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				del_timer (&padapter->timer);
+				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+					{
+					padapter->survivor = (pdev->spigot) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 13"));
+				DEB (printk ("  status = %X  error = %X", status, inb_p (padapter->regError)));
+					if ( InitFailover (padapter, pdev) )
+						OpDone (padapter, DecodeError (padapter, status));
+					return;
+					}
+				OpDone (padapter, DID_OK << 16);
+				return;
+
+			case RECON_PHASE_END:
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				del_timer (&padapter->timer);
+				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+					{
+					padapter->survivor = (pdev->spigot) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 14"));
+					if ( InitFailover (padapter, pdev) )
+						OpDone (padapter, DecodeError (padapter, status));
+					return;
+					}
+				padapter->reconOn = FALSE;
+				pdev->hotRecon = 0;
+				OpDone (padapter, DID_OK << 16);
+				return;
+
+			default:
+				return;
+			}
+		}
+		
+	switch ( padapter->cmd )												// decide how to handle the interrupt
+		{
+		case READ_CMD:
+			if ( padapter->sectorCount )
 				{
-				DEB(printk ("\npci2220i processing read interrupt start bus master cycle"));
-				outb_p (8, padapter->regDmaDesc); 				   		// read operation
-				padapter->readPhase = 1;
-				padapter->expectingIRQ = 1;
-				outl   (padapter->timingAddress, padapter->regDmaAddrLoc);
-				outl   (virt_to_bus (padapter->buffer), padapter->regDmaAddrPci);
-				outl   ((ULONG)padapter->ide.ide.ides.sectors * (ULONG)512, padapter->regDmaCount);
-				outb_p (5, padapter->regDmaMode);				   		// interrupt enable/disable
-				outb_p (0x03, padapter->regDmaCmdStat);			   		// kick the DMA engine in gear
+				status = inb_p (padapter->regStatCmd);						// read the device status
+				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+					{
+					if ( pdev->raid )
+						{
+						padapter->survivor = (pdev->spigot ^ 3) >> 1;
+						del_timer (&padapter->timer);
+				DEB (printk ("\npci2220i: FAILURE 15"));
+						if ( !InitFailover (padapter, pdev) )
+							return;
+						}
+					break;	
+					}
+				if ( padapter->timingPIO )
+					{
+					zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
+					insw (padapter->regData, padapter->buffer, zl * (BYTES_PER_SECTOR / 2));
+					padapter->sectorCount -= zl;
+					padapter->buffer += zl * BYTES_PER_SECTOR;
+					if ( !padapter->sectorCount )
+						{
+						status = 0;
+						break;
+						}
+					}
+				else
+					BusMaster (padapter, 1, 1);
+				padapter->expectingIRQ = TRUE;
 				return;
 				}
+			status = 0;
 			break;
 
-		case IDE_CMD_WRITE_MULTIPLE:
-			DEB(printk ("\npci2220i processing write interrupt cleanup"));
-			padapter->buffer += padapter->ide.ide.ides.sectors * 512;
-			if ( SetupTransfer (padapter, padapter->ide.ide.ide[6] & 0xF0) )
+		case WRITE_CMD:
+			SelectSpigot (padapter, pdev->spigot | 0x80);				
+			status = inb_p (padapter->regStatCmd);								// read the device status
+			if ( pdev->raid )
 				{
-				SCpnt->result = DID_OK << 16;
-				padapter->SCpnt = NULL;
-				SCpnt->scsi_done (SCpnt);
-				return;
+				SelectSpigot (padapter, (pdev->spigot ^ 3) | 0x80);				
+				status1 = inb_p (padapter->regStatCmd);							// read the device status
 				}
-			if ( !(status = IdeCmd (padapter)) )
+			else
+				status1 = 0;
+		
+			if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+				{	
+				if ( pdev->raid && !(status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT)) )
+					{
+					padapter->survivor = (pdev->spigot ^ 3) >> 1;
+					del_timer (&padapter->timer);
+				SelectSpigot (padapter, pdev->spigot | 0x80);
+				DEB (printk ("\npci2220i: FAILURE 16  status = %X  error = %X", status, inb_p (padapter->regError)));
+					if ( !InitFailover (padapter, pdev) )
+						return;
+					}
+				break;
+				}
+			if ( pdev->raid )
 				{
-				DEB (printk ("\npci2220i interrupt complete, waiting for another"));
+				if ( status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
+					{	
+					padapter->survivor = pdev->spigot >> 1;
+					del_timer (&padapter->timer);
+				DEB (printk ("\npci2220i: FAILURE 17  status = %X  error = %X", status1, inb_p (padapter->regError)));
+					if ( !InitFailover (padapter, pdev) )
+						return;
+					status = status1;
+					break;
+					}
+				if ( padapter->sectorCount )
+					{
+					status = WriteDataBoth (padapter);
+					if ( status )
+						{
+						padapter->survivor = (status ^ 3) >> 1;
+						del_timer (&padapter->timer);
+				DEB (printk ("\npci2220i: FAILURE 18"));
+						if ( !InitFailover (padapter, pdev) )
+							return;
+						SelectSpigot (padapter, status | 0x80);				
+						status = inb_p (padapter->regStatCmd);								// read the device status
+						break;
+						}
+					padapter->expectingIRQ = TRUE;
+					return;
+					}
+				status = 0;
+				break;
+				}
+			if ( padapter->sectorCount )	
+				{	
+				SelectSpigot (padapter, pdev->spigot);
+				status = WriteData (padapter);
+				if ( status )
+					break;
+				padapter->expectingIRQ = TRUE;
 				return;
 				}
+			status = 0;
 			break;
 
 		case IDE_COMMAND_IDENTIFY:
 			{
 			PINQUIRYDATA	pinquiryData  = SCpnt->request_buffer;
+			PIDENTIFY_DATA	pid = (PIDENTIFY_DATA)Buffer;
 
-			DEB(printk ("\npci2220i processing verify interrupt cleanup"));
+			status = inb_p (padapter->regStatCmd);
 			if ( status & IDE_STATUS_DRQ )
 				{
-				insw (pports[PORT_DATA], &identifyData, sizeof (identifyData) >> 1);
+				insw (padapter->regData, pid, sizeof (IDENTIFY_DATA) >> 1);
 
 				memset (pinquiryData, 0, SCpnt->request_bufflen);		// Zero INQUIRY data structure.
 				pinquiryData->DeviceType = 0;
@@ -395,8 +1361,8 @@
 				// Fill in vendor identification fields.
 				for ( z = 0;  z < 20;  z += 2 )
 					{
-					pinquiryData->VendorId[z]	  = ((UCHAR *)identifyData.ModelNumber)[z + 1];
-					pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z];
+					pinquiryData->VendorId[z]	  = ((UCHAR *)pid->ModelNumber)[z + 1];
+					pinquiryData->VendorId[z + 1] = ((UCHAR *)pid->ModelNumber)[z];
 					}
 
 				// Initialize unused portion of product id.
@@ -407,30 +1373,32 @@
 				// product revision in INQUIRY data.
 				for ( z = 0;  z < 4;  z += 2 )
 					{
-					pinquiryData->ProductRevisionLevel[z]	 = ((UCHAR *)identifyData.FirmwareRevision)[z + 1];
-					pinquiryData->ProductRevisionLevel[z + 1] = ((UCHAR *)identifyData.FirmwareRevision)[z];
+					pinquiryData->ProductRevisionLevel[z]	 = ((UCHAR *)pid->FirmwareRevision)[z + 1];
+					pinquiryData->ProductRevisionLevel[z + 1] = ((UCHAR *)pid->FirmwareRevision)[z];
 					}
-
-				SCpnt->result = DID_OK << 16;
-				padapter->SCpnt = NULL;
-				SCpnt->scsi_done (SCpnt);
-				return;
+				if ( pdev == padapter->device )
+					*((USHORT *)(&pinquiryData->VendorSpecific)) = DEVICE_DALE_1;
+				
+				status = 0;
 				}
 			break;
 			}
 
 		default:
-			DEB(printk ("\npci2220i no real process here!"));
-			SCpnt->result = DID_OK << 16;
-			padapter->SCpnt = NULL;
-			SCpnt->scsi_done (SCpnt);
-			return;
+			status = 0;
+			break;
 		}
 
-irqerror:;
-	DEB(printk ("\npci2220i error  Device Status: %X\n", status));
-	SCpnt->result = DecodeError (shost, status);
-	SCpnt->scsi_done (SCpnt);
+	del_timer (&padapter->timer);
+	if ( status )
+		{
+		DEB (printk ("\npci2220i Interupt hanlder return error"));
+		zl = DecodeError (padapter, status);
+		}
+	else
+		zl = DID_OK << 16;
+
+	OpDone (padapter, zl);
 	}
 /****************************************************************
  *	Name:	Pci2220i_QueueCommand
@@ -449,121 +1417,182 @@
 	PADAPTER2220I	padapter = HOSTDATA(SCpnt->host);			// Pointer to adapter control structure
 	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->target];// Pointer to device information
 	UCHAR			rc;											// command return code
+	int				z; 
+	PDEVICE_RAID1	pdr;
 
 	SCpnt->scsi_done = done;
-	padapter->ide.ide.ides.spigot = pdev->spigot;
 	padapter->buffer = SCpnt->request_buffer;
-	if (done)
+	padapter->SCpnt = SCpnt;  									// Save this command data
+	if ( !done )
 		{
-		if ( !pdev->device || SCpnt->lun )
-			{
-			SCpnt->result = DID_BAD_TARGET << 16;
-			done (SCpnt);
-			return 0;
-			}
+		printk("pci2220i_queuecommand: %02X: done can't be NULL\n", *cdb);
+		return 0;
 		}
-	else
+	
+	if ( padapter->reconPhase )
+		return 0;
+	if ( padapter->reconTimer.data )
 		{
-		printk("pci2220i_queuecommand: %02X: done can't be NULL\n", *cdb);
+		del_timer (&padapter->reconTimer);
+		padapter->reconTimer.data = 0;
+		}
+		
+	if ( !pdev->device || SCpnt->lun )
+		{
+		OpDone (padapter, DID_BAD_TARGET << 16);
 		return 0;
 		}
 
-	DEB (if(*cdb) printk ("\nCDB: %X-  %X %X %X %X %X %X %X %X %X %X ", SCpnt->cmd_len, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]));
+	
 	switch ( *cdb )
 		{
 		case SCSIOP_INQUIRY:   					// inquiry CDB
 			{
-			padapter->ide.ide.ide[6] = pdev->byte6;
-			padapter->ide.ide.ides.cmd = IDE_COMMAND_IDENTIFY;
+			if ( cdb[2] == SC_MY_RAID )
+				{
+				switch ( cdb[3] ) 
+					{
+					case MY_SCSI_REBUILD:
+						padapter->reconOn = padapter->reconIsStarting = TRUE;
+						OpDone (padapter, DID_OK << 16);
+						break;
+					case MY_SCSI_ALARMMUTE:
+						MuteAlarm (padapter);
+						OpDone (padapter, DID_OK << 16);
+						break;
+					case MY_SCSI_DEMOFAIL:
+						padapter->demoFail = TRUE;				
+						OpDone (padapter, DID_OK << 16);
+						break;
+					default:
+						z = cdb[5];				// get index
+						pdr = (PDEVICE_RAID1)SCpnt->request_buffer;
+						if ( padapter->raidData[z] )
+							{
+							memcpy (&pdr->DiskRaid1, padapter->raidData[z], sizeof (DISK_MIRROR));
+							pdr->TotalSectors = padapter->device[0].blocks;
+							}
+						else
+							memset (pdr, 0, sizeof (DEVICE_RAID1));
+						OpDone (padapter, DID_OK << 16);
+						break;
+					}	
+				return 0;
+				}
+			padapter->cmd = IDE_COMMAND_IDENTIFY;
 			break;
 			}
 
 		case SCSIOP_TEST_UNIT_READY:			// test unit ready CDB
-			SCpnt->result = DID_OK << 16;
-			done (SCpnt);
+			OpDone (padapter, DID_OK << 16);
 			return 0;
-
 		case SCSIOP_READ_CAPACITY:			  	// read capctiy CDB
 			{
 			PREAD_CAPACITY_DATA	pdata = (PREAD_CAPACITY_DATA)SCpnt->request_buffer;
 
 			pdata->blksiz = 0x20000;
 			XANY2SCSI ((UCHAR *)&pdata->blks, pdev->blocks);
-			SCpnt->result = DID_OK << 16;
-			done (SCpnt);
+			OpDone (padapter, DID_OK << 16);
 			return 0;
 			}
-
 		case SCSIOP_VERIFY:						// verify CDB
-			*(ULONG *)padapter->ide.ide.ides.lba = XSCSI2LONG (&cdb[2]);
-			padapter->ide.ide.ide[6] |= pdev->byte6;
-			padapter->ide.ide.ide[2] = (UCHAR)((USHORT)cdb[8] | ((USHORT)cdb[7] << 8));
-			padapter->ide.ide.ides.cmd = IDE_COMMAND_VERIFY;
+			padapter->startSector = XSCSI2LONG (&cdb[2]);
+			padapter->sectorCount = (UCHAR)((USHORT)cdb[8] | ((USHORT)cdb[7] << 8));
+			padapter->cmd = IDE_COMMAND_VERIFY;
 			break;
-
 		case SCSIOP_READ:						// read10 CDB
 			padapter->startSector = XSCSI2LONG (&cdb[2]);
 			padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);
-			SetupTransfer (padapter, pdev->byte6);
-			padapter->ide.ide.ides.cmd = IDE_CMD_READ_MULTIPLE;
-			padapter->readPhase = 0;
+			padapter->cmd = READ_CMD;
 			break;
-
 		case SCSIOP_READ6:						// read6  CDB
 			padapter->startSector = SCSI2LONG (&cdb[1]);
 			padapter->sectorCount = cdb[4];
-			SetupTransfer (padapter, pdev->byte6);
-			padapter->ide.ide.ides.cmd = IDE_CMD_READ_MULTIPLE;
-			padapter->readPhase = 0;
+			padapter->cmd = READ_CMD;
 			break;
-
 		case SCSIOP_WRITE:						// write10 CDB
 			padapter->startSector = XSCSI2LONG (&cdb[2]);
 			padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);
-			SetupTransfer (padapter, pdev->byte6);
-			padapter->ide.ide.ides.cmd = IDE_CMD_WRITE_MULTIPLE;
+			padapter->cmd = WRITE_CMD;
 			break;
 		case SCSIOP_WRITE6:						// write6  CDB
 			padapter->startSector = SCSI2LONG (&cdb[1]);
 			padapter->sectorCount = cdb[4];
-			SetupTransfer (padapter, pdev->byte6);
-			padapter->ide.ide.ides.cmd = IDE_CMD_WRITE_MULTIPLE;
+			padapter->cmd = WRITE_CMD;
 			break;
-
 		default:
 			DEB (printk ("pci2220i_queuecommand: Unsupported command %02X\n", *cdb));
-			SCpnt->result = DID_ERROR << 16;
-			done (SCpnt);
+			OpDone (padapter, DID_ERROR << 16);
 			return 0;
 		}
 
-	padapter->SCpnt = SCpnt;  									// Save this command data
+	if ( padapter->reconPhase )
+		return 0;
+	
+	padapter->pdev = pdev;
 
-	rc = IdeCmd (padapter);
-	if ( rc )
+	while ( padapter->demoFail )
 		{
-		padapter->expectingIRQ = 0;
-		DEB (printk ("pci2220i_queuecommand: %02X, %02X: Device failed to respond for command\n", *cdb, padapter->ide.ide.ides.cmd));
-		SCpnt->result = DID_ERROR << 16;
-		done (SCpnt);
+		padapter->demoFail = FALSE;
+		if ( !pdev->raid || 
+			 (pdev->DiskMirror[0].status & UCBF_SURVIVOR) || 
+			 (pdev->DiskMirror[1].status & UCBF_SURVIVOR) )
+			{
+			break;
+			}
+		if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
+			padapter->survivor = 1;
+		else
+			padapter->survivor = 0;
+				DEB (printk ("\npci2220i: FAILURE 19"));
+		if ( InitFailover (padapter, pdev ) )
+			break;
 		return 0;
 		}
-	if ( padapter->ide.ide.ides.cmd == IDE_CMD_WRITE_MULTIPLE )
+
+	StartTimer (padapter);
+	if ( pdev->raid && (padapter->cmd == WRITE_CMD) )
 		{
-		if ( WriteData (padapter) )
+		rc = IdeCmdBoth (padapter);
+		if ( !rc )
+			rc = WriteDataBoth (padapter);
+		if ( rc )
 			{
+			del_timer (&padapter->timer);
 			padapter->expectingIRQ = 0;
-			DEB (printk ("pci2220i_queuecommand: %02X, %02X: Device failed to accept data\n", *cdb, padapter->ide.ide.ides.cmd));
-			SCpnt->result = DID_ERROR << 16;
-			done (SCpnt);
+			padapter->survivor = (rc ^ 3) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 20"));
+			if ( InitFailover (padapter, pdev) )
+				{
+				OpDone (padapter, DID_ERROR << 16);
+				return 0;
+				}
+			}
+		}
+	else
+		{
+		rc = IdeCmd (padapter, pdev);
+		if ( (padapter->cmd == WRITE_CMD) && !rc )
+			rc = WriteData (padapter);
+		if ( rc )
+			{
+			del_timer (&padapter->timer);
+			padapter->expectingIRQ = 0;
+			if ( pdev->raid )
+				{
+				padapter->survivor = (pdev->spigot ^ 3) >> 1;
+				DEB (printk ("\npci2220i: FAILURE 21"));
+				if ( !InitFailover (padapter, pdev) )
+					return 0;
+				}
+			OpDone (padapter, DID_ERROR << 16);
 			return 0;
 			}
 		}
-	DEB (printk("  now waiting for initial interrupt "));
 	return 0;
 	}
 
-static void internal_done(Scsi_Cmnd * SCpnt)
+static void internal_done(Scsi_Cmnd *SCpnt)
 	{
 	SCpnt->SCp.Status++;
 	}
@@ -579,10 +1608,7 @@
  ****************************************************************/
 int Pci2220i_Command (Scsi_Cmnd *SCpnt)
 	{
-	DEB(printk("pci2220i_command: ..calling pci2220i_queuecommand\n"));
-
 	Pci2220i_QueueCommand (SCpnt, internal_done);
-
     SCpnt->SCp.Status = 0;
 	while (!SCpnt->SCp.Status)
 		barrier ();
@@ -593,7 +1619,7 @@
  *
  *	Description:	Read information from controller Flash memory.
  *
- *	Parameters:		hostdata - Pointer to host interface data structure.
+ *	Parameters:		padapter - Pointer to host interface data structure.
  *					pdata	 - Pointer to data structures.
  *					base	 - base address in Flash.
  *					length	 - lenght of data space in bytes.
@@ -601,25 +1627,24 @@
  *	Returns:		Nothing.
  *
  ****************************************************************/
-VOID ReadFlash (PADAPTER2220I hostdata, VOID *pdata, ULONG base, ULONG length)
+VOID ReadFlash (PADAPTER2220I padapter, VOID *pdata, ULONG base, ULONG length)
 	{
 	ULONG	 oldremap;
 	UCHAR	 olddesc;
 	ULONG	 z;
 	UCHAR	*pd = (UCHAR *)pdata;
 
-	oldremap = inl (hostdata->regRemap);									// save values to restore later
-	olddesc  = inb_p (hostdata->regDesc);
+	oldremap = inl (padapter->regRemap);									// save values to restore later
+	olddesc  = inb_p (padapter->regDesc);
 
-	outl (base | 1, hostdata->regRemap);									// remap to Flash space as specified
-	outb_p (0x40, hostdata->regDesc);										// describe remap region as 8 bit
+	outl (base | 1, padapter->regRemap);									// remap to Flash space as specified
+	outb_p (0x40, padapter->regDesc);										// describe remap region as 8 bit
 	for ( z = 0;  z < length;  z++)											// get "length" data count
-		*pd++ = inb_p (hostdata->regBase + z);								// read in the data
+		*pd++ = inb_p (padapter->regBase + z);								// read in the data
 
-	outl (oldremap, hostdata->regRemap);									// restore remap register values
-	outb_p (olddesc, hostdata->regDesc);
+	outl (oldremap, padapter->regRemap);									// restore remap register values
+	outb_p (olddesc, padapter->regDesc);
 	}
-
 /****************************************************************
  *	Name:	Pci2220i_Detect
  *
@@ -634,11 +1659,14 @@
 	{
 	int					pci_index = 0;
 	struct Scsi_Host   *pshost;
-	PADAPTER2220I	    hostdata;
-	ULONG				modearray[] = {DALE_DATA_MODE2, DALE_DATA_MODE3, DALE_DATA_MODE4, DALE_DATA_MODE4P};
+	PADAPTER2220I	    padapter;
 	int					unit;
 	int					z;
+	USHORT				zs;
+	USHORT				raidon = FALSE;
 	int					setirq;
+	UCHAR				spigot1 = FALSE;
+	UCHAR				spigot2 = FALSE;
 
 	if ( pcibios_present () )
 		{
@@ -650,55 +1678,51 @@
 				break;
 
 			pshost = scsi_register (tpnt, sizeof(ADAPTER2220I));
-			hostdata = HOSTDATA(pshost);
+			padapter = HOSTDATA(pshost);
+			memset (padapter, 0, sizeof (ADAPTER2220I));
 
-			pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &hostdata->basePort);
-			hostdata->basePort &= 0xFFFE;
-			DEB (printk ("\nBase Regs = %#04X", hostdata->basePort));
-			hostdata->regRemap		= hostdata->basePort + RTR_LOCAL_REMAP;				// 32 bit local space remap
-			DEB (printk (" %#04X", hostdata->regRemap));
-			hostdata->regDesc		= hostdata->basePort + RTR_REGIONS;	  				// 32 bit local region descriptor
-			DEB (printk (" %#04X", hostdata->regDesc));
-			hostdata->regRange		= hostdata->basePort + RTR_LOCAL_RANGE;				// 32 bit local range
-			DEB (printk (" %#04X", hostdata->regRange));
-			hostdata->regIrqControl	= hostdata->basePort + RTR_INT_CONTROL_STATUS;		// 16 bit interupt control and status
-			DEB (printk (" %#04X", hostdata->regIrqControl));
-			hostdata->regScratchPad	= hostdata->basePort + RTR_MAILBOX;	  				// 16 byte scratchpad I/O base address
-			DEB (printk (" %#04X", hostdata->regScratchPad));
-
-			pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &hostdata->regBase);
-			hostdata->regBase &= 0xFFFE;
-			for ( z = 0;  z < 9;  z++ )													// build regester address array
-				hostdata->ports[z] = hostdata->regBase + 0x80 + (z * 4);
-			hostdata->ports[PORT_FAIL] = hostdata->regBase + REG_FAIL;
-			hostdata->ports[PORT_ALT_STAT] = hostdata->regBase + REG_ALT_STAT;
-			DEB (printk ("\nPorts ="));
-			DEB (for (z=0;z<11;z++) printk(" %#04X", hostdata->ports[z]););
-
-			hostdata->regDmaDesc	= hostdata->regBase + RTL_DMA1_DESC_PTR;			// address of the DMA discriptor register for direction of transfer
-			DEB (printk ("\nDMA Regs = %#04X", hostdata->regDmaDesc));
-			hostdata->regDmaCmdStat	= hostdata->regBase + RTL_DMA_COMMAND_STATUS + 1;	// Byte #1 of DMA command status register
-			DEB (printk (" %#04X", hostdata->regDmaCmdStat));
-			hostdata->regDmaAddrPci	= hostdata->regBase + RTL_DMA1_PCI_ADDR;			// 32 bit register for PCI address of DMA
-			DEB (printk (" %#04X", hostdata->regDmaAddrPci));
-			hostdata->regDmaAddrLoc	= hostdata->regBase + RTL_DMA1_LOCAL_ADDR;			// 32 bit register for local bus address of DMA
-			DEB (printk (" %#04X", hostdata->regDmaAddrLoc));
-			hostdata->regDmaCount	= hostdata->regBase + RTL_DMA1_COUNT;				// 32 bit register for DMA transfer count
-			DEB (printk (" %#04X", hostdata->regDmaCount));
-			hostdata->regDmaMode	= hostdata->regBase + RTL_DMA1_MODE + 1;			// 32 bit register for DMA mode control
-			DEB (printk (" %#04X", hostdata->regDmaMode));
+			pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &zs);
+			zs &= 0xFFFE;
+			padapter->basePort = zs;
+			padapter->regRemap		= zs + RTR_LOCAL_REMAP;				// 32 bit local space remap
+			padapter->regDesc		= zs + RTR_REGIONS;	  				// 32 bit local region descriptor
+			padapter->regRange		= zs + RTR_LOCAL_RANGE;				// 32 bit local range
+			padapter->regIrqControl	= zs + RTR_INT_CONTROL_STATUS;		// 16 bit interupt control and status
+			padapter->regScratchPad	= zs + RTR_MAILBOX;	  				// 16 byte scratchpad I/O base address
+
+			pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &zs);
+			zs &= 0xFFFE;
+			padapter->regBase		= zs;
+			padapter->regData		= zs + REG_DATA;					// data register I/O address
+			padapter->regError		= zs + REG_ERROR;					// error register I/O address
+			padapter->regSectCount	= zs + REG_SECTOR_COUNT;			// sector count register I/O address
+			padapter->regLba0		= zs + REG_LBA_0;					// least significant byte of LBA
+			padapter->regLba8		= zs + REG_LBA_8;					// next least significant byte of LBA
+			padapter->regLba16		= zs + REG_LBA_16;					// next most significan byte of LBA
+			padapter->regLba24		= zs + REG_LBA_24;					// head and most 4 significant bits of LBA
+			padapter->regStatCmd	= zs + REG_STAT_CMD;				// status on read and command on write register
+			padapter->regStatSel	= zs + REG_STAT_SEL;				// board status on read and spigot select on write register
+			padapter->regFail		= zs + REG_FAIL;
+			padapter->regAltStat	= zs + REG_ALT_STAT;
+
+			padapter->regDmaDesc	= zs + RTL_DMA1_DESC_PTR;			// address of the DMA discriptor register for direction of transfer
+			padapter->regDmaCmdStat	= zs + RTL_DMA_COMMAND_STATUS + 1;	// Byte #1 of DMA command status register
+			padapter->regDmaAddrPci	= zs + RTL_DMA1_PCI_ADDR;			// 32 bit register for PCI address of DMA
+			padapter->regDmaAddrLoc	= zs + RTL_DMA1_LOCAL_ADDR;			// 32 bit register for local bus address of DMA
+			padapter->regDmaCount	= zs + RTL_DMA1_COUNT;				// 32 bit register for DMA transfer count
+			padapter->regDmaMode	= zs + RTL_DMA1_MODE + 1;			// 32 bit register for DMA mode control
 
-			if ( !inb_p (hostdata->regScratchPad + DALE_NUM_DRIVES) )					// if no devices on this board
+			if ( !inb_p (padapter->regScratchPad + DALE_NUM_DRIVES) )	// if no devices on this board
 				goto unregister;
 
 			pcibios_read_config_byte (pci_bus, pci_device_fn, PCI_INTERRUPT_LINE, &pshost->irq);
 			setirq = 1;
-			for ( z = 0;  z < pci_index;  z++ )											// scan for shared interrupts
+			for ( z = 0;  z < pci_index;  z++ )							// scan for shared interrupts
 				{
-				if ( PsiHost[z]->irq == pshost->irq )						// if shared then, don't posses
+				if ( PsiHost[z]->irq == pshost->irq )					// if shared then, don't posses
 					setirq = 0;
 				}
-			if ( setirq )																// if not shared, posses
+			if ( setirq )												// if not shared, posses
 				{
 				if ( request_irq (pshost->irq, Irq_Handler, 0, "pci2220i", NULL) )
 					{
@@ -706,45 +1730,110 @@
 					goto unregister;
 					}
 				}
-			PsiHost[pci_index]	= pshost;												// save SCSI_HOST pointer
+			PsiHost[pci_index]	= pshost;								// save SCSI_HOST pointer
 
-			pshost->unique_id	= hostdata->regBase;
+			pshost->unique_id	= padapter->regBase;
 			pshost->max_id		= 4;
 
-			outb_p (0x01, hostdata->regRange);											// fix our range register because other drivers want to tromp on it
+			outb_p (0x01, padapter->regRange);							// fix our range register because other drivers want to tromp on it
 
-			hostdata->timingMode	= inb_p (hostdata->regScratchPad + DALE_TIMING_MODE);
-			hostdata->timingAddress	= modearray[hostdata->timingMode - 2];
-			ReadFlash (hostdata, &DaleSetup, DALE_FLASH_SETUP, sizeof (SETUP));
-
-			for ( z = 0;  z < inb_p (hostdata->regScratchPad + DALE_NUM_DRIVES);  ++z )
-				{
-				unit = inb_p (hostdata->regScratchPad + DALE_CHANNEL_DEVICE_0 + z) & 0x0F;
-				hostdata->device[unit].device	 = inb_p (hostdata->regScratchPad + DALE_SCRATH_DEVICE_0 + unit);
-				hostdata->device[unit].byte6	 = (UCHAR)(((unit & 1) << 4) | 0xE0);
-				hostdata->device[unit].spigot	 = (UCHAR)(1 << (unit >> 1));
-				hostdata->device[unit].sectors	 = DaleSetup.setupDevice[unit].sectors;
-				hostdata->device[unit].heads	 = DaleSetup.setupDevice[unit].heads;
-				hostdata->device[unit].cylinders = DaleSetup.setupDevice[unit].cylinders;
-				hostdata->device[unit].blocks	 = DaleSetup.setupDevice[unit].blocks;
-				DEB (printk ("\nHOSTDATA->device    = %X", hostdata->device[unit].device));
-				DEB (printk ("\n          byte6     = %X", hostdata->device[unit].byte6));
-				DEB (printk ("\n          spigot    = %X", hostdata->device[unit].spigot));
-				DEB (printk ("\n          sectors   = %X", hostdata->device[unit].sectors));
-				DEB (printk ("\n          heads     = %X", hostdata->device[unit].heads));
-				DEB (printk ("\n          cylinders = %X", hostdata->device[unit].cylinders));
-				DEB (printk ("\n          blocks    = %lX", hostdata->device[unit].blocks));
-				}
-
-			printk("\nPSI-2220I EIDE CONTROLLER: at I/O = %X/%X  IRQ = %d\n", hostdata->basePort, hostdata->regBase, pshost->irq);
-			printk("(C) 1997 Perceptive Solutions, Inc. All rights reserved\n\n");
+			padapter->timingMode = inb_p (padapter->regScratchPad + DALE_TIMING_MODE);
+			if ( padapter->timingMode >= 2 )
+				padapter->timingAddress	= ModeArray[padapter->timingMode - 2];
+			else
+				padapter->timingPIO = TRUE;
+			
+			ReadFlash (padapter, &DaleSetup, DALE_FLASH_SETUP, sizeof (SETUP));
+			for ( z = 0;  z < inb_p (padapter->regScratchPad + DALE_NUM_DRIVES);  ++z )
+				{
+				unit = inb_p (padapter->regScratchPad + DALE_CHANNEL_DEVICE_0 + z) & 0x0F;
+				padapter->device[z].device	 = inb_p (padapter->regScratchPad + DALE_SCRATH_DEVICE_0 + unit);
+				padapter->device[z].byte6	 = (UCHAR)(((unit & 1) << 4) | 0xE0);
+				padapter->device[z].spigot	 = (UCHAR)(1 << (unit >> 1));
+				padapter->device[z].sectors	 = DaleSetup.setupDevice[unit].sectors;
+				padapter->device[z].heads	 = DaleSetup.setupDevice[unit].heads;
+				padapter->device[z].cylinders = DaleSetup.setupDevice[unit].cylinders;
+				padapter->device[z].blocks	 = DaleSetup.setupDevice[unit].blocks;
 
+				if ( !z )
+					{
+					ReadFlash (padapter, &DiskMirror, DALE_FLASH_RAID, sizeof (DiskMirror));
+					DiskMirror[0].status = inb_p (padapter->regScratchPad + DALE_RAID_0_STATUS);		
+					DiskMirror[1].status = inb_p (padapter->regScratchPad + DALE_RAID_1_STATUS);		
+					if ( (DiskMirror[0].signature == SIGNATURE) && (DiskMirror[1].signature == SIGNATURE) &&
+					     (DiskMirror[0].pairIdentifier == (DiskMirror[1].pairIdentifier ^ 1)) )
+						{			 
+						raidon = TRUE;
+						}	
+
+					memcpy (padapter->device[z].DiskMirror, DiskMirror, sizeof (DiskMirror));
+					padapter->raidData[0] = &padapter->device[z].DiskMirror[0];
+					padapter->raidData[2] = &padapter->device[z].DiskMirror[1];
+				
+					if ( raidon )
+						{
+						padapter->device[z].lastsectorlba[0] = InlineIdentify (padapter, 1, 0);
+						padapter->device[z].lastsectorlba[1] = InlineIdentify (padapter, 2, 0);
+						
+						if ( !(DiskMirror[1].status & UCBF_SURVIVOR) && padapter->device[z].lastsectorlba[0] )
+							spigot1 = TRUE;
+						if ( !(DiskMirror[0].status & UCBF_SURVIVOR) && padapter->device[z].lastsectorlba[1] )
+							spigot2 = TRUE;
+						if ( DiskMirror[0].status & UCBF_SURVIVOR & DiskMirror[1].status & UCBF_SURVIVOR )
+							spigot1 = TRUE;
+
+						if ( spigot1 && spigot2 )
+							{
+							padapter->device[z].raid = 1;
+							if ( DiskMirror[0].status & UCBF_REBUILD )
+								padapter->device[z].spigot = 2;
+							else
+								padapter->device[z].spigot = 1;
+							if ( (DiskMirror[0].status & UCBF_REBUILD) || (DiskMirror[1].status & UCBF_REBUILD) )
+								{
+								padapter->reconOn = padapter->reconIsStarting = TRUE;
+								}
+							}
+						else
+							{
+							if ( spigot1 )
+								{
+								if ( DiskMirror[0].status & UCBF_REBUILD )
+									goto unregister;
+								DiskMirror[0].status = UCBF_MIRRORED | UCBF_SURVIVOR;
+								padapter->device[z].spigot = 1;
+								}
+							else
+								{
+								if ( DiskMirror[1].status & UCBF_REBUILD )
+									goto unregister;
+								DiskMirror[1].status = UCBF_MIRRORED | UCBF_SURVIVOR;
+								padapter->device[z].spigot = 2;
+								}
+							if ( DaleSetup.rebootRebuil )
+								padapter->reconOn = padapter->reconIsStarting = TRUE;
+							}
+				
+						break;
+						}
+					}
+				}
+			
+			init_timer (&padapter->timer);
+			padapter->timer.function = TimerExpiry;
+			padapter->timer.data = (unsigned long)padapter;
+			init_timer (&padapter->reconTimer);
+			padapter->reconTimer.function = ReconTimerExpiry;
+			padapter->reconTimer.data = (unsigned long)padapter;
+			printk("\nPCI-2220I EIDE CONTROLLER: at I/O = %X/%X  IRQ = %d\n", padapter->basePort, padapter->regBase, pshost->irq);
+			printk("Version %s, Compiled %s %s\n\n", PCI2220I_VERSION, __DATE__, __TIME__);
 			NumAdapters++;
 			continue;
 unregister:;
 			scsi_unregister (pshost);
 			}
 		}
+	
 	return NumAdapters;
 	}
 /****************************************************************
@@ -759,7 +1848,6 @@
  ****************************************************************/
 int Pci2220i_Abort (Scsi_Cmnd *SCpnt)
 	{
-	DEB (printk ("pci2220i_abort\n"));
 	return SCSI_ABORT_SNOOZE;
 	}
 /****************************************************************
@@ -816,4 +1904,3 @@
 
 #include "scsi_module.c"
 #endif
-
diff -u --recursive --new-file linux-2.0.38/drivers/scsi/pci2220i.h linux-2.0.39/drivers/scsi/pci2220i.h
--- linux-2.0.38/drivers/scsi/pci2220i.h	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/scsi/pci2220i.h	Thu Sep  7 03:07:19 2000
@@ -1,7 +1,7 @@
 /*+M*************************************************************************
- * Perceptive Solutions, Inc. PCI-2000 device driver proc support for Linux.
+ * Perceptive Solutions, Inc. PCI-2220i device driver proc support for Linux.
  *
- * Copyright (c) 1997 Perceptive Solutions, Inc.
+ * Copyright (c) 1999 Perceptive Solutions, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,12 +25,6 @@
  *
  *-M*************************************************************************/
 
-#ifndef _PCI2220I_H
-#define _PCI2220I_H
-
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-
 #ifndef	PSI_EIDE_SCSIOP
 #define	PSI_EIDE_SCSIOP	1
 
@@ -46,11 +40,14 @@
 #define	ULONG		unsigned long
 #define	VOID		void
 
+#include "psi_dale.h"
+
 /************************************************/
 /*		Timeout konstants		 				*/
 /************************************************/
-#define	TIMEOUT_READY				10		// 100 mSec
-#define	TIMEOUT_DRQ					40		// 400 mSec
+#define	TIMEOUT_READY				100			// 100 mSec
+#define	TIMEOUT_DRQ					300			// 300 mSec
+#define	TIMEOUT_DATA				(3 * HZ)	// 3 seconds
 
 /************************************************/
 /*		Misc. macros			 				*/
@@ -76,6 +73,9 @@
 + (((long)(((UCHAR *)up)[2])) <<  8)	\
 + ((long)(((UCHAR *)up)[3])) )
 
+#define	SelectSpigot(padapter,spigot)	outb_p (spigot, padapter->regStatSel)
+#define WriteCommand(padapter,cmd)		outb_p (cmd, padapter->regStatCmd)
+
 /************************************************/
 /*		SCSI CDB operation codes 				*/
 /************************************************/
@@ -163,8 +163,6 @@
 #define	IDE_CMD_READ_MULTIPLE		0xC4
 #define	IDE_CMD_WRITE_MULTIPLE		0xC5
 #define	IDE_CMD_SET_MULTIPLE		0xC6
-#define IDE_COMMAND_WRITE_DMA		0xCA
-#define IDE_COMMAND_READ_DMA		0xC8
 #define IDE_COMMAND_IDENTIFY		0xEC
 
 // IDE status definitions
@@ -187,23 +185,6 @@
 #define	IDE_ERROR_UNC				0x40
 #define	IDE_ERROR_BBK				0x80
 
-//	IDE interface structure
-typedef struct _IDE_STRUCT
-	{
-	union
-		{
-		UCHAR	ide[9];
-		struct
-			{
-			USHORT	data;
-			UCHAR	sectors;
-			UCHAR	lba[4];
-			UCHAR	cmd;
-			UCHAR	spigot;
-			}	ides;
-		} ide;
-	}	IDE_STRUCT;
-
 // SCSI read capacity structure
 typedef	struct _READ_CAPACITY_DATA
 	{
@@ -238,73 +219,64 @@
 	}	INQUIRYDATA, *PINQUIRYDATA;
 
 // IDE IDENTIFY data
+#pragma pack (1)
+#pragma align 1
 typedef struct _IDENTIFY_DATA
 	{
-    USHORT GeneralConfiguration;            // 00
-    USHORT NumberOfCylinders;               // 02
-    USHORT Reserved1;                       // 04
-    USHORT NumberOfHeads;                   // 06
-    USHORT UnformattedBytesPerTrack;        // 08
-    USHORT UnformattedBytesPerSector;       // 0A
-    USHORT SectorsPerTrack;                 // 0C
-    USHORT VendorUnique1[3];                // 0E
-    USHORT SerialNumber[10];                // 14
-    USHORT BufferType;                      // 28
-    USHORT BufferSectorSize;                // 2A
-    USHORT NumberOfEccBytes;                // 2C
-    USHORT FirmwareRevision[4];             // 2E
-    USHORT ModelNumber[20];                 // 36
-    UCHAR  MaximumBlockTransfer;            // 5E
-    UCHAR  VendorUnique2;                   // 5F
-    USHORT DoubleWordIo;                    // 60
-    USHORT Capabilities;                    // 62
-    USHORT Reserved2;                       // 64
-    UCHAR  VendorUnique3;                   // 66
-    UCHAR  PioCycleTimingMode;              // 67
-    UCHAR  VendorUnique4;                   // 68
-    UCHAR  DmaCycleTimingMode;              // 69
-    USHORT TranslationFieldsValid:1;        // 6A
-    USHORT Reserved3:15;
-    USHORT NumberOfCurrentCylinders;        // 6C
-    USHORT NumberOfCurrentHeads;            // 6E
-    USHORT CurrentSectorsPerTrack;          // 70
-    ULONG  CurrentSectorCapacity;           // 72
-    USHORT Reserved4[197];                  // 76
+    USHORT	GeneralConfiguration;		//  0
+    USHORT	NumberOfCylinders;			//  1
+    USHORT	Reserved1;					//  2
+    USHORT	NumberOfHeads;				//  3
+    USHORT	UnformattedBytesPerTrack;	//  4
+    USHORT	UnformattedBytesPerSector;	//  5
+    USHORT	SectorsPerTrack;			//  6
+	USHORT	NumBytesISG;				//  7 Byte Len - inter-sector gap
+	USHORT	NumBytesSync;				//  8          - sync field
+	USHORT	NumWordsVUS;				//  9 Len - Vendor Unique Info
+    USHORT	SerialNumber[10];			// 10
+    USHORT	BufferType;					// 20
+    USHORT	BufferSectorSize;			// 21
+    USHORT	NumberOfEccBytes;			// 22
+    USHORT	FirmwareRevision[4];		// 23
+    USHORT	ModelNumber[20];			// 27
+	USHORT	NumSectorsPerInt	:8;		// 47 Multiple Mode - Sec/Blk
+	USHORT	Reserved2			:8;		// 47
+	USHORT	DoubleWordMode;				// 48 flag for double word mode capable
+	USHORT	VendorUnique1		:8;		// 49
+	USHORT	SupportDMA			:1;		// 49 DMA supported
+	USHORT	SupportLBA			:1;		// 49 LBA supported
+	USHORT	SupportIORDYDisable	:1;		// 49 IORDY can be disabled
+	USHORT	SupportIORDY		:1;		// 49 IORDY supported
+	USHORT	ReservedPsuedoDMA	:1;		// 49 reserved for pseudo DMA mode support
+	USHORT	Reserved3			:3;		// 49
+	USHORT	Reserved4;					// 50
+	USHORT	Reserved5			:8;		// 51 Transfer Cycle Timing - PIO
+	USHORT	PIOCycleTime		:8;		// 51 Transfer Cycle Timing - PIO
+	USHORT	Reserved6			:8;		// 52                       - DMA
+	USHORT	DMACycleTime		:8;		// 52                       - DMA
+	USHORT	Valid_54_58			:1;		// 53 words 54 - 58 are vaild
+	USHORT	Valid_64_70			:1;		// 53 words 64 - 70 are valid
+	USHORT	Reserved7			:14;	// 53
+	USHORT	LogNumCyl;					// 54 Current Translation - Num Cyl
+	USHORT	LogNumHeads;				// 55                       Num Heads
+	USHORT	LogSectorsPerTrack;			// 56                       Sec/Trk
+	ULONG	LogTotalSectors;			// 57                       Total Sec
+	USHORT	CurrentNumSecPerInt	:8;		// 59 current setting for number of sectors per interrupt
+	USHORT	ValidNumSecPerInt	:1;		// 59 Current setting is valid for number of sectors per interrupt
+	USHORT	Reserved8			:7;		// 59
+	ULONG	LBATotalSectors;			// 60 LBA Mode - Sectors
+	USHORT	DMASWordFlags;				// 62
+	USHORT	DMAMWordFlags;				// 63
+	USHORT	AdvancedPIOSupport  :8;		// 64 Flow control PIO transfer modes supported
+	USHORT	Reserved9			:8;		// 64
+	USHORT	MinMultiDMACycle;			// 65 minimum multiword DMA transfer cycle time per word
+	USHORT	RecomendDMACycle;			// 66 Manufacturer's recommende multiword DMA transfer cycle time
+	USHORT	MinPIOCycleWithoutFlow;		// 67 Minimum PIO transfer cycle time without flow control
+	USHORT	MinPIOCylceWithFlow;		// 68 Minimum PIO transfer cycle time with IORDY flow control
+	USHORT	ReservedSpace[256-69];		// 69
 	}	IDENTIFY_DATA, *PIDENTIFY_DATA;
-
-// Identify data without the Reserved4.
-typedef struct _IDENTIFY_DATA2 {
-    USHORT GeneralConfiguration;            // 00
-    USHORT NumberOfCylinders;               // 02
-    USHORT Reserved1;                       // 04
-    USHORT NumberOfHeads;                   // 06
-    USHORT UnformattedBytesPerTrack;        // 08
-    USHORT UnformattedBytesPerSector;       // 0A
-    USHORT SectorsPerTrack;                 // 0C
-    USHORT VendorUnique1[3];                // 0E
-    USHORT SerialNumber[10];                // 14
-    USHORT BufferType;                      // 28
-    USHORT BufferSectorSize;                // 2A
-    USHORT NumberOfEccBytes;                // 2C
-    USHORT FirmwareRevision[4];             // 2E
-    USHORT ModelNumber[20];                 // 36
-    UCHAR  MaximumBlockTransfer;            // 5E
-    UCHAR  VendorUnique2;                   // 5F
-    USHORT DoubleWordIo;                    // 60
-    USHORT Capabilities;                    // 62
-    USHORT Reserved2;                       // 64
-    UCHAR  VendorUnique3;                   // 66
-    UCHAR  PioCycleTimingMode;              // 67
-    UCHAR  VendorUnique4;                   // 68
-    UCHAR  DmaCycleTimingMode;              // 69
-	USHORT TranslationFieldsValid:1;     	// 6A
-    USHORT Reserved3:15;
-    USHORT NumberOfCurrentCylinders;        // 6C
-    USHORT NumberOfCurrentHeads;            // 6E
-    USHORT CurrentSectorsPerTrack;          // 70
-    ULONG  CurrentSectorCapacity;           // 72
-	}	IDENTIFY_DATA2, *PIDENTIFY_DATA2;
-
+#pragma pack ()
+#pragma align 0
 #endif	// PSI_EIDE_SCSIOP
 
 // function prototypes
@@ -322,10 +294,10 @@
 extern struct proc_dir_entry Proc_Scsi_Pci2220i;
 
 #define PCI2220I { NULL, NULL,						\
-			&Proc_Scsi_Pci2220i,/* proc_dir_entry */	\
+			&Proc_Scsi_Pci2220i,/* proc_dir_entry */\
 			NULL,		                			\
 			"PCI-2220I EIDE Disk Controller",		\
-			Pci2220i_Detect,							\
+			Pci2220i_Detect,						\
 			NULL,									\
 			NULL,	 								\
 			Pci2220i_Command,						\
@@ -333,7 +305,7 @@
 			Pci2220i_Abort,							\
 			Pci2220i_Reset,							\
 			NULL,									\
-			Pci2220i_BiosParam,                 		\
+			Pci2220i_BiosParam,                 	\
 			1, 										\
 			-1, 									\
 			SG_NONE,		 						\
@@ -342,4 +314,3 @@
 			0, 										\
 			DISABLE_CLUSTERING }
 
-#endif
diff -u --recursive --new-file linux-2.0.38/drivers/scsi/psi_chip.h linux-2.0.39/drivers/scsi/psi_chip.h
--- linux-2.0.38/drivers/scsi/psi_chip.h	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/scsi/psi_chip.h	Thu Sep  7 03:58:35 2000
@@ -1,5 +1,5 @@
 /*+M*************************************************************************
- * Perceptive Solutions, Inc. PSI-240I device driver proc support for Linux.
+ * Perceptive Solutions, Inc. PSI-240i device driver proc support for Linux.
  *
  * Copyright (c) 1997 Perceptive Solutions, Inc.
  *
@@ -191,4 +191,4 @@
 	SETUP_DEVICE	setupDevice[8];
 	}	SETUP, *PSETUP;
 
-#endif
\ No newline at end of file
+#endif
diff -u --recursive --new-file linux-2.0.38/drivers/scsi/psi_dale.h linux-2.0.39/drivers/scsi/psi_dale.h
--- linux-2.0.38/drivers/scsi/psi_dale.h	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/scsi/psi_dale.h	Thu Sep  7 03:05:17 2000
@@ -1,7 +1,7 @@
 /*+M*************************************************************************
- * Perceptive Solutions, Inc. PCI-2000 device driver proc support for Linux.
+ * Perceptive Solutions, Inc. PCI-2220i device driver proc support for Linux.
  *
- * Copyright (c) 1997 Perceptive Solutions, Inc.
+ * Copyright (c) 1999 Perceptive Solutions, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,13 +21,10 @@
  *	File Name:		psi_dale.h
  *
  *	Description:	This file contains the interface defines and
- *					error codes.
+ *					error codes. 
  *
  *-M*************************************************************************/
 
-#ifndef PSI_DALE
-#define PSI_DALE
-
 /************************************************/
 /*		Dale PCI setup							*/
 /************************************************/
@@ -58,24 +55,24 @@
 /************************************************/
 /*		DALE Register address offsets			*/
 /************************************************/
-#define	REG_DATA				0x80
-#define	REG_ERROR				0x84
-#define	REG_SECTOR_COUNT		0x88
-#define	REG_LBA_0				0x8C
-#define	REG_LBA_8				0x90
-#define	REG_LBA_16				0x94
-#define	REG_LBA_24				0x98
-#define	REG_STAT_CMD			0x9C
-#define	REG_STAT_SEL			0xA0
-#define	REG_FAIL				0xB0
-#define	REG_ALT_STAT			0xB8
-#define	REG_DRIVE_ADRS			0xBC
-
-#define	DALE_DATA_SLOW			0x00040000L
-#define	DALE_DATA_MODE2			0x00040000L
-#define	DALE_DATA_MODE3			0x00050000L
-#define	DALE_DATA_MODE4			0x00060000L
-#define	DALE_DATA_MODE4P		0x00070000L
+#define	REG_DATA						0x80
+#define	REG_ERROR						0x84
+#define	REG_SECTOR_COUNT				0x88
+#define	REG_LBA_0						0x8C
+#define	REG_LBA_8						0x90
+#define	REG_LBA_16						0x94
+#define	REG_LBA_24						0x98
+#define	REG_STAT_CMD					0x9C
+#define	REG_STAT_SEL					0xA0
+#define	REG_FAIL						0xB0
+#define	REG_ALT_STAT					0xB8
+#define	REG_DRIVE_ADRS					0xBC
+
+#define	DALE_DATA_SLOW					0x00040000L
+#define	DALE_DATA_MODE2					0x00040000L
+#define	DALE_DATA_MODE3					0x00050000L
+#define	DALE_DATA_MODE4					0x00060000L
+#define	DALE_DATA_MODE4P				0x00070000L
 
 #define RTR_LOCAL_RANGE					0x000
 #define RTR_LOCAL_REMAP					0x004
@@ -110,52 +107,52 @@
 /************************************************/
 /*		Dale Scratchpad locations				*/
 /************************************************/
-#define	DALE_CHANNEL_DEVICE_0	0		// device channel locations
-#define	DALE_CHANNEL_DEVICE_1	1
-#define	DALE_CHANNEL_DEVICE_2	2
-#define	DALE_CHANNEL_DEVICE_3	3
-
-#define	DALE_SCRATH_DEVICE_0	4		// device type codes
-#define	DALE_SCRATH_DEVICE_1	5
-#define DALE_SCRATH_DEVICE_2	6
-#define	DALE_SCRATH_DEVICE_3	7
-
-#define	DALE_RAID_0_STATUS		8
-#define DALE_RAID_1_STATUS		9
-
-#define	DALE_TIMING_MODE		12		// bus master timing mode (2, 3, 4, 5)
-#define	DALE_NUM_DRIVES			13		// number of addressable drives on this board
-#define	DALE_RAID_ON			14 		// RAID status On
-#define	DALE_LAST_ERROR			15		// Last error code from BIOS
+#define	DALE_CHANNEL_DEVICE_0			0		// device channel locations
+#define	DALE_CHANNEL_DEVICE_1			1
+#define	DALE_CHANNEL_DEVICE_2			2
+#define	DALE_CHANNEL_DEVICE_3			3
+
+#define	DALE_SCRATH_DEVICE_0			4		// device type codes
+#define	DALE_SCRATH_DEVICE_1			5
+#define DALE_SCRATH_DEVICE_2			6
+#define	DALE_SCRATH_DEVICE_3			7
+
+#define	DALE_RAID_0_STATUS				8
+#define DALE_RAID_1_STATUS				9
+
+#define	DALE_TIMING_MODE				12		// bus master timing mode (2, 3, 4, 5)
+#define	DALE_NUM_DRIVES					13		// number of addressable drives on this board
+#define	DALE_RAID_ON					14 		// RAID status On
+#define	DALE_LAST_ERROR					15		// Last error code from BIOS
 
 /************************************************/
 /*		Dale cable select bits					*/
 /************************************************/
-#define	SEL_NONE				0x00
-#define	SEL_1					0x01
-#define	SEL_2					0x02
+#define	SEL_NONE						0x00
+#define	SEL_1							0x01
+#define	SEL_2							0x02
 
 /************************************************/
 /*		Programmable Interrupt Controller		*/
 /************************************************/
-#define	PIC1					0x20				// first 8259 base port address
-#define	PIC2					0xA0				// second 8259 base port address
-#define	INT_OCW1				1					// Operation Control Word 1: IRQ mask
-#define	EOI						0x20				// non-specific end-of-interrupt
+#define	PIC1							0x20		// first 8259 base port address
+#define	PIC2							0xA0		// second 8259 base port address
+#define	INT_OCW1						1			// Operation Control Word 1: IRQ mask
+#define	EOI								0x20		// non-specific end-of-interrupt
 
 /************************************************/
 /*		Device/Geometry controls				*/
 /************************************************/
-#define GEOMETRY_NONE	 	0x0			// No device
-#define GEOMETRY_SET		0x1			// Geometry set
-#define	GEOMETRY_LBA		0x2			// Geometry set in default LBA mode
-#define	GEOMETRY_PHOENIX	0x3			// Geometry set in Pheonix BIOS compatibility mode
-
-#define	DEVICE_NONE			0x0			// No device present
-#define	DEVICE_INACTIVE		0x1			// device present but not registered active
-#define	DEVICE_ATAPI		0x2			// ATAPI device (CD_ROM, Tape, Etc...)
-#define	DEVICE_DASD_NONLBA	0x3			// Non LBA incompatible device
-#define	DEVICE_DASD_LBA		0x4			// LBA compatible device
+#define GEOMETRY_NONE	 			0x0				// No device
+#define GEOMETRY_SET				0x1				// Geometry set
+#define	GEOMETRY_LBA				0x2				// Geometry set in default LBA mode
+#define	GEOMETRY_PHOENIX			0x3				// Geometry set in Pheonix BIOS compatibility mode
+
+#define	DEVICE_NONE					0x0				// No device present
+#define	DEVICE_INACTIVE				0x1				// device present but not registered active
+#define	DEVICE_ATAPI				0x2				// ATAPI device (CD_ROM, Tape, Etc...)
+#define	DEVICE_DASD_NONLBA			0x3				// Non LBA incompatible device
+#define	DEVICE_DASD_LBA				0x4				// LBA compatible device
 
 /************************************************/
 /*		Setup Structure Definitions				*/
@@ -184,4 +181,38 @@
 	SETUP_DEVICE	setupDevice[4];
 	}	SETUP, *PSETUP;
 
-#endif
+/************************************************/
+/*		RAID Structure Definitions				*/
+/************************************************/
+typedef	struct
+	{
+	UCHAR	signature;			// 0x55 our mirror signature
+	UCHAR	status;				// current status bits
+	UCHAR	pairIdentifier;		// unique identifier for pair
+	ULONG	reconstructPoint;	// recontruction point for hot reconstruct
+	}	DISK_MIRROR;
+
+typedef struct	DEVICE_RAID1
+	{
+	long		TotalSectors;
+	DISK_MIRROR DiskRaid1;
+	}	DEVICE_RAID1, *PDEVICE_RAID1;
+
+#define	DISK_MIRROR_POSITION	0x01A8
+#define	SIGNATURE				0x55
+
+#define	MASK_SERIAL_NUMBER	0x0FFE			// mask for serial number matching
+#define	MASK_SERIAL_UNIT	0x0001			// mask for unit portion of serial number
+
+// Status bits
+#define	UCBF_MIRRORED		0x0010								// drive has a pair
+#define	UCBF_MATCHED		0x0020								// drive pair is matched
+#define	UCBF_SURVIVOR		0x0040								// this unit is a survivor of a pair
+#define	UCBF_REBUILD		0x0080								// rebuild in progress on this device
+
+// SCSI controls for RAID
+#define	SC_MY_RAID			0xBF			// our special CDB command byte for Win95... interface
+#define	MY_SCSI_QUERY1		0x32			// byte 1 subcommand to query driver for RAID 1 informatation
+#define	MY_SCSI_REBUILD		0x40			// byte 1 subcommand to reconstruct a mirrored pair
+#define MY_SCSI_DEMOFAIL	0x54			// byte 1 subcommand for RAID failure demonstration
+#define	MY_SCSI_ALARMMUTE	0x60			// byte 1 subcommand to mute any alarm currently on
diff -u --recursive --new-file linux-2.0.38/drivers/scsi/psi_roy.h linux-2.0.39/drivers/scsi/psi_roy.h
--- linux-2.0.38/drivers/scsi/psi_roy.h	Sun Jun 13 19:21:02 1999
+++ linux-2.0.39/drivers/scsi/psi_roy.h	Thu Sep  7 03:05:28 2000
@@ -40,7 +40,7 @@
 #define MAXADAPTER			4			// Increase this and the sizes of the arrays below, if you need more.
 #define	MAX_BUS				2
 #define	MAX_UNITS			16
-#define	TIMEOUT_COMMAND		30 			// number of jiffies for command busy timeout
+#define	TIMEOUT_COMMAND		400			// number of milliSecondos for command busy timeout
 
 /************************************************/
 /*		I/O address offsets						*/
diff -u --recursive --new-file linux-2.0.38/fs/Config.in linux-2.0.39/fs/Config.in
--- linux-2.0.38/fs/Config.in	Sun Jun 13 19:21:03 1999
+++ linux-2.0.39/fs/Config.in	Thu Dec 30 15:26:41 1999
@@ -12,80 +12,81 @@
 
 tristate 'Native language support (Needed for FAT and ISO9660)' CONFIG_NLS
 if [ "$CONFIG_NLS" = "y" -o "$CONFIG_NLS" = "m" ]; then
-  dep_tristate 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS $CONFIG_NLS
+   dep_tristate '  ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS $CONFIG_NLS
 
-  # msdos filesystems
-  dep_tristate 'DOS FAT fs support' CONFIG_FAT_FS $CONFIG_NLS
-  dep_tristate 'MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS
-  dep_tristate 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
-  dep_tristate 'VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS
-  mainmenu_option next_comment
-  comment 'Select available code pages'
-  dep_tristate 'Codepage 437 (United States, Canada)'	CONFIG_NLS_CODEPAGE_437 $CONFIG_NLS
-  dep_tristate 'Codepage 737 (Greek)'			CONFIG_NLS_CODEPAGE_737 $CONFIG_NLS
-  dep_tristate 'Codepage 775 (Baltic Rim)'		CONFIG_NLS_CODEPAGE_775 $CONFIG_NLS
-  dep_tristate 'Codepage 850 (Europe)'			CONFIG_NLS_CODEPAGE_850 $CONFIG_NLS
-  dep_tristate 'Codepage 852 (Central/Eastern Europe)'	CONFIG_NLS_CODEPAGE_852 $CONFIG_NLS
-  dep_tristate 'Codepage 855 (Cyrillic)'		CONFIG_NLS_CODEPAGE_855 $CONFIG_NLS
-  dep_tristate 'Codepage 857 (Turkish)'			CONFIG_NLS_CODEPAGE_857 $CONFIG_NLS
-  dep_tristate 'Codepage 860 (Portugese)'		CONFIG_NLS_CODEPAGE_860 $CONFIG_NLS
-  dep_tristate 'Codepage 861 (Icelandic)'		CONFIG_NLS_CODEPAGE_861 $CONFIG_NLS
-  dep_tristate 'Codepage 862 (Hebrew)'			CONFIG_NLS_CODEPAGE_862 $CONFIG_NLS
-  dep_tristate 'Codepage 863 (Canadian French)'		CONFIG_NLS_CODEPAGE_863 $CONFIG_NLS
-  dep_tristate 'Codepage 864 (Arabic)'			CONFIG_NLS_CODEPAGE_864 $CONFIG_NLS
-  dep_tristate 'Codepage 865 (Nordic European)'		CONFIG_NLS_CODEPAGE_865 $CONFIG_NLS
-  dep_tristate 'Codepage 866 (Cyrillic/Russian)'	CONFIG_NLS_CODEPAGE_866 $CONFIG_NLS
-  dep_tristate 'Codepage 869 (Greek)'			CONFIG_NLS_CODEPAGE_869 $CONFIG_NLS
-  dep_tristate 'Codepage 874 (Thai)'			CONFIG_NLS_CODEPAGE_874 $CONFIG_NLS
-  dep_tristate 'NLS ISO 8859-1 (Latin 1; Western Europe)'    CONFIG_NLS_ISO8859_1    $CONFIG_NLS 
-  dep_tristate 'NLS ISO 8859-2 (Latin 2; Slavic/Central European)'    CONFIG_NLS_ISO8859_2    $CONFIG_NLS
-  dep_tristate 'NLS ISO 8859-3 (Latin 3; Esperanto, Galician, Maltese, Turkish)'    CONFIG_NLS_ISO8859_3    $CONFIG_NLS
-  dep_tristate 'NLS ISO 8859-4 (Latin 4; Estonian, Latvian, Lithuanian)'    CONFIG_NLS_ISO8859_4    $CONFIG_NLS
-  dep_tristate 'NLS ISO 8859-5 (Cyrillic)'    CONFIG_NLS_ISO8859_5    $CONFIG_NLS
-  dep_tristate 'NLS ISO 8859-6 (Arabic)'    CONFIG_NLS_ISO8859_6    $CONFIG_NLS
-  dep_tristate 'NLS ISO 8859-7 (Modern Greek)'    CONFIG_NLS_ISO8859_7    $CONFIG_NLS
-  dep_tristate 'NLS ISO 8859-8 (Hebrew)'    CONFIG_NLS_ISO8859_8    $CONFIG_NLS
-  dep_tristate 'NLS ISO 8859-9 (Latin 5; Turkey)'    CONFIG_NLS_ISO8859_9    $CONFIG_NLS
-  dep_tristate 'NLS ISO 8859-15 (Latin 9; Western European Languages with Euro)' CONFIG_NLS_ISO8859_15 $CONFIG_NLS
-  dep_tristate 'NLS KOI8-R (Russian)'        CONFIG_NLS_KOI8_R       $CONFIG_NLS
-  endmenu
+   # msdos filesystems
+   dep_tristate '  DOS FAT fs support' CONFIG_FAT_FS $CONFIG_NLS
+   dep_tristate '    MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS
+   dep_tristate '      umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
+   dep_tristate '      VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS
+   mainmenu_option next_comment
+   comment 'Select available code pages'
+   dep_tristate 'Codepage 437 (United States, Canada)'	CONFIG_NLS_CODEPAGE_437 $CONFIG_NLS
+   dep_tristate 'Codepage 737 (Greek)'			CONFIG_NLS_CODEPAGE_737 $CONFIG_NLS
+   dep_tristate 'Codepage 775 (Baltic Rim)'		CONFIG_NLS_CODEPAGE_775 $CONFIG_NLS
+   dep_tristate 'Codepage 850 (Europe)'			CONFIG_NLS_CODEPAGE_850 $CONFIG_NLS
+   dep_tristate 'Codepage 852 (Central/Eastern Europe)'	CONFIG_NLS_CODEPAGE_852 $CONFIG_NLS
+   dep_tristate 'Codepage 855 (Cyrillic)'		CONFIG_NLS_CODEPAGE_855 $CONFIG_NLS
+   dep_tristate 'Codepage 857 (Turkish)'		CONFIG_NLS_CODEPAGE_857 $CONFIG_NLS
+   dep_tristate 'Codepage 860 (Portugese)'		CONFIG_NLS_CODEPAGE_860 $CONFIG_NLS
+   dep_tristate 'Codepage 861 (Icelandic)'		CONFIG_NLS_CODEPAGE_861 $CONFIG_NLS
+   dep_tristate 'Codepage 862 (Hebrew)'			CONFIG_NLS_CODEPAGE_862 $CONFIG_NLS
+   dep_tristate 'Codepage 863 (Canadian French)'	CONFIG_NLS_CODEPAGE_863 $CONFIG_NLS
+   dep_tristate 'Codepage 864 (Arabic)'			CONFIG_NLS_CODEPAGE_864 $CONFIG_NLS
+   dep_tristate 'Codepage 865 (Nordic European)'	CONFIG_NLS_CODEPAGE_865 $CONFIG_NLS
+   dep_tristate 'Codepage 866 (Cyrillic/Russian)'	CONFIG_NLS_CODEPAGE_866 $CONFIG_NLS
+   dep_tristate 'Codepage 869 (Greek)'			CONFIG_NLS_CODEPAGE_869 $CONFIG_NLS
+   dep_tristate 'Codepage 874 (Thai)'			CONFIG_NLS_CODEPAGE_874 $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-1 (Latin 1; Western Europe)'    CONFIG_NLS_ISO8859_1    $CONFIG_NLS 
+   dep_tristate 'NLS ISO 8859-2 (Latin 2; Slavic/Central European)'    CONFIG_NLS_ISO8859_2    $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-3 (Latin 3; Esperanto, Galician, Maltese, Turkish)'    CONFIG_NLS_ISO8859_3    $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-4 (Latin 4; Estonian, Latvian, Lithuanian)'    CONFIG_NLS_ISO8859_4    $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-5 (Cyrillic)'    CONFIG_NLS_ISO8859_5    $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-6 (Arabic)'    CONFIG_NLS_ISO8859_6    $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-7 (Modern Greek)'    CONFIG_NLS_ISO8859_7    $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-8 (Hebrew)'    CONFIG_NLS_ISO8859_8    $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-9 (Latin 5; Turkey)'    CONFIG_NLS_ISO8859_9    $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-14 (Latin 8; Celtic)'      CONFIG_NLS_ISO8859_14 $CONFIG_NLS
+   dep_tristate 'NLS ISO 8859-15 (Latin 9; Western European Languages with Euro)' CONFIG_NLS_ISO8859_15 $CONFIG_NLS
+   dep_tristate 'NLS KOI8-R (Russian)'        CONFIG_NLS_KOI8_R       $CONFIG_NLS
+   endmenu
 fi
 
 bool '/proc filesystem support' CONFIG_PROC_FS
 if [ "$CONFIG_INET" = "y" ]; then
-  tristate 'NFS filesystem support' CONFIG_NFS_FS
-  if [ "$CONFIG_NFS_FS" = "y" ]; then
-    bool '   Root file system on NFS' CONFIG_ROOT_NFS
-    if [ "$CONFIG_ROOT_NFS" = "y" ]; then
-      bool '      BOOTP support' CONFIG_RNFS_BOOTP
-      bool '      RARP support' CONFIG_RNFS_RARP
-    fi
-  fi
-  tristate 'SMB filesystem support (to mount WfW shares etc..)' CONFIG_SMB_FS
-  if [ "$CONFIG_SMB_FS" != "n" ]; then
-    bool 'SMB Win95 bug work-around' CONFIG_SMB_WIN95
-  fi
+   tristate 'NFS filesystem support' CONFIG_NFS_FS
+   if [ "$CONFIG_NFS_FS" = "y" ]; then
+      bool '  Root file system on NFS' CONFIG_ROOT_NFS
+      if [ "$CONFIG_ROOT_NFS" = "y" ]; then
+	 bool '    BOOTP support' CONFIG_RNFS_BOOTP
+	 bool '    RARP support' CONFIG_RNFS_RARP
+      fi
+   fi
+   tristate 'SMB filesystem support (to mount WfW shares etc..)' CONFIG_SMB_FS
+   if [ "$CONFIG_SMB_FS" != "n" ]; then
+      bool '  SMB Win95 bug work-around' CONFIG_SMB_WIN95
+   fi
 fi
 if [ "$CONFIG_IPX" != "n" ]; then
-  tristate 'NCP filesystem support (to mount NetWare volumes)' CONFIG_NCP_FS
-  if [ "$CONFIG_NCP_FS" != "n" ]; then
-    source fs/ncpfs/Config.in
-  fi
+   tristate 'NCP filesystem support (to mount NetWare volumes)' CONFIG_NCP_FS
+   if [ "$CONFIG_NCP_FS" != "n" ]; then
+      source fs/ncpfs/Config.in
+   fi
 fi
 tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS
 tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'Kernel automounter support (experimental)' CONFIG_AUTOFS_FS
+   tristate 'Kernel automounter support (EXPERIMENTAL)' CONFIG_AUTOFS_FS
 fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'Amiga FFS filesystem support (EXPERIMENTAL)' CONFIG_AFFS_FS
-  if [ "$CONFIG_AFFS_FS" != "n" ]; then
-    define_bool CONFIG_AMIGA_PARTITION y
-  fi
+   tristate 'Amiga FFS filesystem support (EXPERIMENTAL)' CONFIG_AFFS_FS
+   if [ "$CONFIG_AFFS_FS" != "n" ]; then
+      define_bool CONFIG_AMIGA_PARTITION y
+   fi
 fi
 tristate 'UFS filesystem support (read only)' CONFIG_UFS_FS
 if [ "$CONFIG_UFS_FS" != "n" ]; then
-  bool 'BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL
-  bool 'SMD disklabel (Sun partition tables) support' CONFIG_SMD_DISKLABEL
+   bool '  BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL
+   bool '  SMD disklabel (Sun partition tables) support' CONFIG_SMD_DISKLABEL
 fi
 endmenu
diff -u --recursive --new-file linux-2.0.38/fs/Makefile linux-2.0.39/fs/Makefile
--- linux-2.0.38/fs/Makefile	Sun Jun 13 19:21:03 1999
+++ linux-2.0.39/fs/Makefile	Thu Dec 30 15:41:19 1999
@@ -481,6 +481,22 @@
   endif
 endif
 
+ifeq ($(CONFIG_NLS_ISO8859_10),y)
+NLS += nls_iso8859_10.o
+else
+  ifeq ($(CONFIG_NLS_ISO8859_10),m)
+  M_OBJS += nls_iso8859_10.o
+  endif
+endif
+
+ifeq ($(CONFIG_NLS_ISO8859_14),y)
+NLS += nls_iso8859_14.o
+else
+  ifeq ($(CONFIG_NLS_ISO8859_14),m)
+  M_OBJS += nls_iso8859_14.o
+  endif
+endif
+
 ifeq ($(CONFIG_NLS_ISO8859_15),y)
 NLS += nls_iso8859_15.o
 else
diff -u --recursive --new-file linux-2.0.38/fs/binfmt_elf.c linux-2.0.39/fs/binfmt_elf.c
--- linux-2.0.38/fs/binfmt_elf.c	Thu Jun  4 00:17:49 1998
+++ linux-2.0.39/fs/binfmt_elf.c	Wed Jun 28 14:44:53 2000
@@ -55,6 +55,19 @@
 #define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
 #define ELF_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
 
+/* Amount to offset dynamic executables, such as glibc 2.x's ld.so when 
+ * used from command line.
+ *   Loading at 0x00000000 is not appropriate since it means 
+ * null-pointer-dereferences are not caught. (and obstructs vm86 use.)
+ *   Loading low in general is bad for ld.so, since it or the heap may 
+ * collide with the second executable it loads.
+ *   Loading near MMAP_SEARCH_START is even worse, since the heap will 
+ * start after the executable, and quickly be occluded by shared 
+ * libraries, etc.
+ *   So we load in the top third of virtual memory.
+ */
+#define DYNAMIC_BIAS  PAGE_ALIGN((TASK_SIZE/3)*2)
+
 static struct linux_binfmt elf_format =
 {
 #ifndef MODULE
@@ -197,28 +210,20 @@
 	     interp_elf_ex->e_type != ET_DYN) ||
 	    !elf_check_arch(interp_elf_ex->e_machine) ||
 	    (!interpreter_inode->i_op ||
-	     !interpreter_inode->i_op->default_file_ops->mmap)) {
+	     !interpreter_inode->i_op->default_file_ops->mmap) ||
+	    interp_elf_ex->e_phentsize != sizeof(struct elf_phdr) ||
+	    interp_elf_ex->e_phnum < 1 ||
+	    interp_elf_ex->e_phnum > PAGE_SIZE / sizeof(struct elf_phdr)) {
 		return ~0UL;
 	}
 	/* Now read in all of the header information */
 
-	if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE)
-		 return ~0UL;
-
 	elf_phdata = (struct elf_phdr *)
 	    kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum,
 		    GFP_KERNEL);
 	if (!elf_phdata)
 		return ~0UL;
 
-	/*
-	 * If the size of this structure has changed, then punt, since
-	 * we will be doing the wrong thing.
-	 */
-	if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
-		kfree(elf_phdata);
-		return ~0UL;
-	}
 	retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff,
 			   (char *) elf_phdata,
 		    sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, 1);
@@ -306,6 +311,11 @@
 	kfree(elf_phdata);
 
 	*interp_load_addr = load_addr;
+	/*
+	 * AUDIT: is everything deallocated properly if this happens
+	 * to be ~0UL? We'd better switch to out-of-band error reporting.
+	 * Also for a.out.
+	 */
 	return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
 }
 
@@ -397,7 +407,10 @@
 	     elf_ex.e_type != ET_DYN) ||
 	    (!elf_check_arch(elf_ex.e_machine)) ||
 	    (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
-	     !bprm->inode->i_op->default_file_ops->mmap)) {
+	     !bprm->inode->i_op->default_file_ops->mmap) ||
+	    elf_ex.e_phentsize != sizeof(struct elf_phdr) ||
+	    elf_ex.e_phnum < 1 ||
+	    elf_ex.e_phnum > 0xfff0 / sizeof(struct elf_phdr)) {
 		return -ENOEXEC;
 	}
 	/* Now read in all of the header information */
@@ -434,12 +447,14 @@
 
 	for (i = 0; i < elf_ex.e_phnum; i++) {
 		if (elf_ppnt->p_type == PT_INTERP) {
-			if (elf_interpreter != NULL) {
+			if (elf_interpreter != NULL ||
+			    elf_ppnt->p_filesz < 2 ||
+			    elf_ppnt->p_filesz > PAGE_SIZE) {
 				iput(interpreter_inode);
 				kfree(elf_phdata);
 				kfree(elf_interpreter);
 				sys_close(elf_exec_fileno);
-				return -EINVAL;
+				return -ENOEXEC;
 			}
 			/* This is the program interpreter used for
 			 * shared libraries - for now assume that this
@@ -456,6 +471,7 @@
 			retval = read_exec(bprm->inode, elf_ppnt->p_offset,
 					   elf_interpreter,
 					   elf_ppnt->p_filesz, 1);
+			elf_interpreter[elf_ppnt->p_filesz - 1] = 0;
 			/* If the program interpreter is one of these two,
 			   then assume an iBCS2 image. Otherwise assume
 			   a native linux image. */
@@ -554,7 +570,6 @@
 	current->mm->end_code = 0;
 	current->mm->start_mmap = ELF_START_MMAP;
 	current->mm->mmap = NULL;
-	elf_entry = (unsigned long) elf_ex.e_entry;
 
 	/* Do this so that we can load the interpreter, if need be.  We will
 	   change some of these later */
@@ -562,6 +577,19 @@
 	bprm->p = setup_arg_pages(bprm->p, bprm);
 	current->mm->start_stack = bprm->p;
 
+	/* Bias dynamic executables so they are not loaded at 
+         * 0x00000000.  See comment at DYNAMIC_BIAS define.
+         */
+	if (elf_ex.e_type == ET_DYN)
+        {
+		for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
+			elf_ppnt->p_vaddr += DYNAMIC_BIAS;
+		}
+		elf_ex.e_entry += DYNAMIC_BIAS;
+        }
+
+	elf_entry = (unsigned long) elf_ex.e_entry;
+
 	/* Now we do a little grungy work by mmaping the ELF image into
 	   the correct location in memory.  At this point, we assume that
 	   the image should be loaded at fixed address, not at a variable
@@ -629,14 +657,17 @@
 						    &interp_load_addr);
 
 		iput(interpreter_inode);
-		kfree(elf_interpreter);
 
 		if (elf_entry == ~0UL) {
-			printk("Unable to load interpreter\n");
+			printk("Unable to load interpreter %.128s\n",
+				elf_interpreter);
+			kfree(elf_interpreter);
 			kfree(elf_phdata);
 			send_sig(SIGSEGV, current, 0);
 			return 0;
 		}
+
+		kfree(elf_interpreter);
 	}
 	kfree(elf_phdata);
 
diff -u --recursive --new-file linux-2.0.38/fs/dquot.c linux-2.0.39/fs/dquot.c
--- linux-2.0.38/fs/dquot.c	Mon Jul 13 22:47:34 1998
+++ linux-2.0.39/fs/dquot.c	Tue Apr 25 15:22:16 2000
@@ -143,14 +143,17 @@
 		return;
 	dqstats.pages_allocated++;
 	cnt = PAGE_SIZE / sizeof(struct dquot);
+	memset(dquot, 0, PAGE_SIZE);
 	nr_dquots += cnt;
 	nr_free_dquots += cnt;
 	if (!first_dquot) {
 		dquot->dq_next = dquot->dq_prev = first_dquot = dquot++;
 		cnt--;
 	}
-	for (; cnt; cnt--)
+	for (; cnt; cnt--) {
+		init_waitqueue(&dquot->dq_wait);
 		insert_dquot_free(dquot++);
+	}
 }
 
 /*
@@ -219,11 +222,18 @@
 	short type = dquot->dq_type;
 	struct file *filp = dquot->dq_mnt->mnt_quotas[type];
 	unsigned short fs;
+	struct dqblk wrt_dquot;
 
 	if (!(dquot->dq_flags & DQ_MOD) || (filp == (struct file *)NULL))
 		return;
 	lock_dquot(dquot);
+	if (!dquot->dq_mnt) {	/* Invalidated dquot? */
+		unlock_dquot(dquot);
+		return;
+	}
 	down(&dquot->dq_mnt->mnt_sem);
+	dquot->dq_flags &= ~DQ_MOD;	/* Clear the flag unconditionally - we don't want to loop on error */
+	memcpy(&wrt_dquot, &dquot->dq_dqb, sizeof(struct dqblk));	/* Copy structure so we can unlock it */
 	if (filp->f_op->lseek) {
 		if (filp->f_op->lseek(filp->f_inode, filp,
 		    dqoff(dquot->dq_id), 0) != dqoff(dquot->dq_id)) {
@@ -238,14 +248,13 @@
 		if(p>=0)
 			filp->f_pos = p;
 	}
+	unlock_dquot(dquot);	/* We have to unlock structure as write might need to update it */
 	fs = get_fs();
 	set_fs(KERNEL_DS);
-	if (filp->f_op->write(filp->f_inode, filp,
-	   (char *)&dquot->dq_dqb, sizeof(struct dqblk)) == sizeof(struct dqblk))
-		dquot->dq_flags &= ~DQ_MOD;
+	if (filp->f_op->write(filp->f_inode, filp, (char *)&wrt_dquot, sizeof(struct dqblk)) != sizeof(struct dqblk))
+		printk(KERN_ERR "VFS: write_dquot() failed.\n");
 	up(&dquot->dq_mnt->mnt_sem);
 	set_fs(fs);
-	unlock_dquot(dquot);
 	dqstats.writes++;
 }
 
@@ -286,14 +295,18 @@
 	int i;
 
 	dqstats.syncs++;
+restart:
 	for (i = 0; i < nr_dquots * 2; i++, dquot = dquot->dq_next) {
 		if (dev == NODEV || dquot->dq_count == 0 || dquot->dq_dev != dev)
 			continue;
 		if (type != -1 && dquot->dq_type != type)
 			continue;
+		if (!(dquot->dq_flags & DQ_MOD))	/* It might get modified I know but to restart after each locked dquot... */
+			continue;
 		wait_on_dquot(dquot);
 		if (dquot->dq_flags & DQ_MOD)
 			write_dquot(dquot);
+		goto restart;
 	}
 	return(0);
 }
@@ -306,6 +319,7 @@
 	struct dquot *dquot, *next;
 	int cnt;
 
+restart:
 	next = first_dquot;
 	for (cnt = nr_dquots ; cnt > 0 ; cnt--) {
 		dquot = next;
@@ -316,10 +330,14 @@
 			printk("VFS: dquot busy on removed device %s\n", kdevname(dev));
 			continue;
 		}
-		if (dquot->dq_flags & DQ_MOD)
+		if (dquot->dq_flags & DQ_MOD) {
 			write_dquot(dquot);
+			dqstats.drops++;
+			clear_dquot(dquot);
+			goto restart;	/* As we might block inside of write or clear_dquot */
+		}
 		dqstats.drops++;
-		clear_dquot(dquot);
+		clear_dquot(dquot);	/* Here we can't block - DQ_LOCKED was tested before */
 	}
 }
 
@@ -463,30 +481,34 @@
 	 * checking and doesn't need to be written. It just an empty
 	 * dquot that is put back into the freelist.
 	 */
-	if (dquot->dq_mnt != (struct vfsmount *)NULL) {
-		dqstats.drops++;
-		wait_on_dquot(dquot);
+repeat:
+	if (dquot->dq_mnt) {	/* We can block inside of wait and so we have to check again */
+		if (dquot->dq_flags & DQ_LOCKED) {
+			__wait_on_dquot(dquot);
+			goto repeat;
+		}
+			
 		if (!dquot->dq_count) {
 			printk("VFS: dqput: trying to free free dquot\n");
 			printk("VFS: device %s, dquot of %s %d\n", kdevname(dquot->dq_dev),
 			       quotatypes[dquot->dq_type], dquot->dq_id);
 			return;
 		}
-repeat:
 		if (dquot->dq_count > 1) {
 			dquot->dq_count--;
 			return;
 		}
-		wake_up(&dquot_wait);
 		if (dquot->dq_flags & DQ_MOD) {
 			write_dquot(dquot);	/* we can sleep - so do again */
 			wait_on_dquot(dquot);
 			goto repeat;
 		}
+		dqstats.drops++;
 	}
 	if (dquot->dq_count) {
 		dquot->dq_count--;
 		nr_free_dquots++;
+		wake_up(&dquot_wait);	/* Here the dquot is really free */
 	}
 	return;
 }
@@ -583,6 +605,14 @@
 	put_last_free(dquot);
 	insert_dquot_hash(dquot);
 	read_dquot(dquot);
+	if (!dquot->dq_mnt) {	/* Invalidated in the mean time? */
+	/*
+	 * As quota was turned off we can just return NODQUOT. I know it's
+	 * not perfect as somebody might turn quota on again but...
+	 */
+		dqput(dquot);
+		return NODQUOT;
+	}
 	return(dquot);
 }
 
@@ -959,9 +989,11 @@
 		vfsmnt->mnt_sb->dq_op = (struct dquot_operations *)NULL;
 		reset_dquot_ptrs(dev, cnt);
 		invalidate_dquots(dev, cnt);
+		down(&vfsmnt->mnt_sem);	/* Wait for any pending IO - dquot is not locked on write so we can easily go here during write */
 		close_fp(vfsmnt->mnt_quotas[cnt]);
 		vfsmnt->mnt_quotas[cnt] = (struct file *)NULL;
 		vfsmnt->mnt_iexp[cnt] = vfsmnt->mnt_bexp[cnt] = (time_t)NULL;
+		up(&vfsmnt->mnt_sem);
 	}
 	return(0);
 }
diff -u --recursive --new-file linux-2.0.38/fs/exec.c linux-2.0.39/fs/exec.c
--- linux-2.0.38/fs/exec.c	Mon Jul 13 22:47:34 1998
+++ linux-2.0.39/fs/exec.c	Tue Apr 25 16:16:37 2000
@@ -178,26 +178,51 @@
 
 /*
  * count() counts the number of arguments/envelopes
- *
- * We also do some limited EFAULT checking: this isn't complete, but
- * it does cover most cases. I'll have to do this correctly some day..
  */
-static int count(char ** argv)
+static int count(void *base, int size, int max)
 {
 	int error, i = 0;
-	char ** tmp, *p;
+	void *tmp = base;
+	unsigned long length = 0, chunk = size, limit;
+	int grow = 1;
+
+	if (!tmp) return 0;
+
+	limit = PAGE_SIZE - ((unsigned long)tmp & (PAGE_SIZE - 1));
+	error = verify_area(VERIFY_READ, tmp, limit);
+	if (error) limit = 0;
+
+	do {
+		if (length >= limit)
+		do {
+			if (!grow) {
+				if (chunk <= sizeof(char *))
+					return -EFAULT;
+				chunk >>= 1;
+			}
+			error = verify_area(VERIFY_READ, tmp, chunk);
+			if (error) grow = 0; else {
+				limit += chunk;
+				if (grow) chunk <<= 1;
+			}
+		} while (error);
 
-	if ((tmp = argv) != NULL) {
-		error = verify_area(VERIFY_READ, tmp, sizeof(char *));
-		if (error)
-			return error;
-		while ((p = get_user(tmp++)) != NULL) {
-			i++;
-			error = verify_area(VERIFY_READ, p, 1);
-			if (error)
-				return error;
+		if (size == 1) {
+			do {
+				if (!get_user(((char *)tmp)++)) goto out;
+				if (++i > max) return -E2BIG;
+			} while (i < limit);
+			length = i;
+		} else {
+			do {
+				if (!get_user(((char **)tmp)++)) goto out;
+				if ((length += size) > max) return -E2BIG;
+				i++;
+			} while (length < limit);
 		}
-	}
+	} while (1);
+
+out:
 	return i;
 }
 
@@ -221,12 +246,12 @@
 unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
 		unsigned long p, int from_kmem)
 {
-	char *tmp, *tmp1, *pag = NULL;
+	char *tmp, *pag = NULL;
 	int len, offset = 0;
 	unsigned long old_fs, new_fs;
 
-	if (!p)
-		return 0;	/* bullet-proofing */
+	if ((long)p <= 0)
+		return p;	/* bullet-proofing */
 	new_fs = get_ds();
 	old_fs = get_fs();
 	if (from_kmem==2)
@@ -234,16 +259,16 @@
 	while (argc-- > 0) {
 		if (from_kmem == 1)
 			set_fs(new_fs);
-		if (!(tmp1 = tmp = get_user(argv+argc)))
+		if (!(tmp = get_user(argv+argc)))
 			panic("VFS: argc is wrong");
 		if (from_kmem == 1)
 			set_fs(old_fs);
-		while (get_user(tmp++));
-		len = tmp - tmp1;
-		if (p < len) {	/* this shouldn't happen - 128kB */
+		len = count(tmp, 1, p);
+		if (len < 0 || len >= p) {	/* EFAULT or E2BIG */
 			set_fs(old_fs);
-			return 0;
+			return len < 0 ? len : -E2BIG;
 		}
+		tmp += ++len;
 		while (len) {
 			--p; --tmp; --len;
 			if (--offset < 0) {
@@ -253,7 +278,7 @@
 				if (!(pag = (char *) page[p/PAGE_SIZE]) &&
 				    !(pag = (char *) page[p/PAGE_SIZE] =
 				      (unsigned long *) get_free_page(GFP_USER))) 
-					return 0;
+					return -EFAULT;
 				if (from_kmem==2)
 					set_fs(new_fs);
 
@@ -559,6 +584,27 @@
 			if (!suser())
 				return -EPERM;
 		}
+
+		/*
+		 * Increment the privileged execution counter, so that our
+		 * old children know not to send bad exit_signal's to us.
+		 */
+		if (!++current->priv) {
+			struct task_struct *p;
+
+			/*
+			 * The counter can't really overflow with real-world
+			 * programs (and it has to be the privileged program
+			 * itself that causes the overflow), but we handle
+			 * this case anyway, just for correctness.
+			 */
+			for_each_task(p) {
+				if (p->p_pptr == current) {
+					p->ppriv = 0;
+					current->priv = 1;
+				}
+			}
+		}
 	}
 
 	memset(bprm->buf,0,sizeof(bprm->buf));
@@ -601,6 +647,8 @@
 		bprm->dont_iput = 1;
 		remove_arg_zero(bprm);
 		bprm->p = copy_strings(1, dynloader, bprm->page, bprm->p, 2);
+		if ((long)bprm->p < 0)
+			return (long)bprm->p;
 		bprm->argc++;
 		bprm->loader = bprm->p;
 		retval = open_namei(dynloader[0], 0, 0, &bprm->inode, NULL);
@@ -673,9 +721,9 @@
 	bprm.loader = 0;
 	bprm.exec = 0;
 	bprm.dont_iput = 0;
-	if ((bprm.argc = count(argv)) < 0)
+	if ((bprm.argc = count(argv, sizeof(char *), bprm.p)) < 0)
 		return bprm.argc;
-	if ((bprm.envc = count(envp)) < 0)
+	if ((bprm.envc = count(envp, sizeof(char *), bprm.p)) < 0)
 		return bprm.envc;
 
 	retval = prepare_binprm(&bprm);
@@ -685,8 +733,8 @@
 		bprm.exec = bprm.p;
 		bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
 		bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
-		if (!bprm.p)
-			retval = -E2BIG;
+		if ((long)bprm.p < 0)
+			retval = (long)bprm.p;
 	}
 
 	if(retval>=0)
diff -u --recursive --new-file linux-2.0.38/fs/ext2/balloc.c linux-2.0.39/fs/ext2/balloc.c
--- linux-2.0.38/fs/ext2/balloc.c	Sun Aug 17 01:23:19 1997
+++ linux-2.0.39/fs/ext2/balloc.c	Wed Jun 28 14:44:08 2000
@@ -205,7 +205,7 @@
 	 */
 	if (sb->u.ext2_sb.s_loaded_block_bitmaps > 0 &&
 	    sb->u.ext2_sb.s_block_bitmap_number[0] == block_group &&
-	    sb->u.ext2_sb.s_block_bitmap[block_group]) {
+	    sb->u.ext2_sb.s_block_bitmap[0]) {
 		slot = 0;
 	}
 	/*
@@ -645,6 +645,25 @@
 			 EXT2_BLOCKS_PER_GROUP(sb), map);
 }
 
+static int test_root(int a, int b)
+{
+	if (a == 0)
+		return 1;
+	while (1) {
+		if (a == 1)
+			return 1;
+		if (a % b)
+			return 0;
+		a = a / b;
+	}
+}
+
+int ext2_group_sparse(int group)
+{
+	return (test_root(group, 3) || test_root(group, 5) ||
+		test_root(group, 7));
+}
+
 void ext2_check_blocks_bitmap (struct super_block * sb)
 {
 	struct buffer_head * bh;
@@ -671,16 +690,22 @@
 
 		bh = sb->u.ext2_sb.s_block_bitmap[bitmap_nr];
 
-		if (!test_bit (0, bh->b_data))
-			ext2_error (sb, "ext2_check_blocks_bitmap",
-				    "Superblock in group %d is marked free", i);
-
-		for (j = 0; j < desc_blocks; j++)
-			if (!test_bit (j + 1, bh->b_data))
+		if (!(sb->u.ext2_sb.s_feature_ro_compat &
+		     EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
+		    ext2_group_sparse(i)) {
+			if (!test_bit (0, bh->b_data))
 				ext2_error (sb, "ext2_check_blocks_bitmap",
+					    "Superblock in group %d "
+					    "is marked free", i);
+
+			for (j = 0; j < desc_blocks; j++)
+				if (!test_bit (j + 1, bh->b_data))
+					ext2_error (sb,
+					    "ext2_check_blocks_bitmap",
 					    "Descriptor block #%d in group "
 					    "%d is marked free", j, i);
-
+		}
+		
 		if (!block_in_use (gdp->bg_block_bitmap, sb, bh->b_data))
 			ext2_error (sb, "ext2_check_blocks_bitmap",
 				    "Block bitmap for group %d is marked free",
diff -u --recursive --new-file linux-2.0.38/fs/ext2/dir.c linux-2.0.39/fs/ext2/dir.c
--- linux-2.0.38/fs/ext2/dir.c	Mon Jul 13 22:47:34 1998
+++ linux-2.0.39/fs/ext2/dir.c	Fri Jan 21 16:17:50 2000
@@ -72,7 +72,7 @@
 };
 
 int ext2_check_dir_entry (const char * function, struct inode * dir,
-			  struct ext2_dir_entry * de, struct buffer_head * bh,
+			  struct ext2_dir_entry_2 * de, struct buffer_head * bh,
 			  unsigned long offset)
 {
 	const char * error_msg = NULL;
@@ -104,7 +104,7 @@
 	unsigned long offset, blk;
 	int i, num, stored;
 	struct buffer_head * bh, * tmp, * bha[16];
-	struct ext2_dir_entry * de;
+	struct ext2_dir_entry_2 * de;
 	struct super_block * sb;
 	int err;
 
@@ -173,7 +173,7 @@
 		
 		while (!error && filp->f_pos < inode->i_size 
 		       && offset < sb->s_blocksize) {
-			de = (struct ext2_dir_entry *) (bh->b_data + offset);
+			de = (struct ext2_dir_entry_2 *) (bh->b_data + offset);
 			if (!ext2_check_dir_entry ("ext2_readdir", inode, de,
 						   bh, offset)) {
 				/* On error, skip the f_pos to the
diff -u --recursive --new-file linux-2.0.38/fs/ext2/namei.c linux-2.0.39/fs/ext2/namei.c
--- linux-2.0.38/fs/ext2/namei.c	Thu Jun  4 00:17:49 1998
+++ linux-2.0.39/fs/ext2/namei.c	Fri Jan 21 16:17:50 2000
@@ -36,7 +36,7 @@
  * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
  */
 static int ext2_match (int len, const char * const name,
-		       struct ext2_dir_entry * de)
+		       struct ext2_dir_entry_2 * de)
 {
 	if (!de || !de->inode || len > EXT2_NAME_LEN)
 		return 0;
@@ -61,7 +61,7 @@
  */
 static struct buffer_head * ext2_find_entry (struct inode * dir,
 					     const char * const name, int namelen,
-					     struct ext2_dir_entry ** res_dir)
+					     struct ext2_dir_entry_2 ** res_dir)
 {
 	struct super_block * sb;
 	struct buffer_head * bh_use[NAMEI_RA_SIZE];
@@ -92,7 +92,7 @@
 
 	for (block = 0, offset = 0; offset < dir->i_size; block++) {
 		struct buffer_head * bh;
-		struct ext2_dir_entry * de;
+		struct ext2_dir_entry_2 * de;
 		char * dlimit;
 
 		if ((block % NAMEI_RA_BLOCKS) == 0 && toread) {
@@ -115,7 +115,7 @@
 			break;
 		}
 
-		de = (struct ext2_dir_entry *) bh->b_data;
+		de = (struct ext2_dir_entry_2 *) bh->b_data;
 		dlimit = bh->b_data + sb->s_blocksize;
 		while ((char *) de < dlimit) {
 			if (!ext2_check_dir_entry ("ext2_find_entry", dir,
@@ -130,7 +130,7 @@
 				return bh;
 			}
 			offset += de->rec_len;
-			de = (struct ext2_dir_entry *)
+			de = (struct ext2_dir_entry_2 *)
 				((char *) de + de->rec_len);
 		}
 
@@ -155,7 +155,7 @@
 		 struct inode ** result)
 {
 	unsigned long ino;
-	struct ext2_dir_entry * de;
+	struct ext2_dir_entry_2 * de;
 	struct buffer_head * bh;
 
 	*result = NULL;
@@ -211,13 +211,13 @@
  */
 static struct buffer_head * ext2_add_entry (struct inode * dir,
 					    const char * name, int namelen,
-					    struct ext2_dir_entry ** res_dir,
+					    struct ext2_dir_entry_2 ** res_dir,
 					    int *err)
 {
 	unsigned long offset;
 	unsigned short rec_len;
 	struct buffer_head * bh;
-	struct ext2_dir_entry * de, * de1;
+	struct ext2_dir_entry_2 * de, * de1;
 	struct super_block * sb;
 
 	*err = -EINVAL;
@@ -247,7 +247,7 @@
 		return NULL;
 	rec_len = EXT2_DIR_REC_LEN(namelen);
 	offset = 0;
-	de = (struct ext2_dir_entry *) bh->b_data;
+	de = (struct ext2_dir_entry_2 *) bh->b_data;
 	*err = -ENOSPC;
 	while (1) {
 		if ((char *)de >= sb->s_blocksize + bh->b_data) {
@@ -264,7 +264,7 @@
 
 				ext2_debug ("creating next block\n");
 
-				de = (struct ext2_dir_entry *) bh->b_data;
+				de = (struct ext2_dir_entry_2 *) bh->b_data;
 				de->inode = 0;
 				de->rec_len = sb->s_blocksize;
 				dir->i_size = offset + sb->s_blocksize;
@@ -273,7 +273,7 @@
 
 				ext2_debug ("skipping to next block\n");
 
-				de = (struct ext2_dir_entry *) bh->b_data;
+				de = (struct ext2_dir_entry_2 *) bh->b_data;
 			}
 		}
 		if (!ext2_check_dir_entry ("ext2_add_entry", dir, de, bh,
@@ -291,7 +291,7 @@
 		    (de->rec_len >= EXT2_DIR_REC_LEN(de->name_len) + rec_len)) {
 			offset += de->rec_len;
 			if (de->inode) {
-				de1 = (struct ext2_dir_entry *) ((char *) de +
+				de1 = (struct ext2_dir_entry_2 *) ((char *) de +
 					EXT2_DIR_REC_LEN(de->name_len));
 				de1->rec_len = de->rec_len -
 					EXT2_DIR_REC_LEN(de->name_len);
@@ -300,6 +300,7 @@
 			}
 			de->inode = 0;
 			de->name_len = namelen;
+			de->file_type = 0;
 			memcpy (de->name, name, namelen);
 			/*
 			 * XXX shouldn't update any times until successful
@@ -321,7 +322,7 @@
 			return bh;
 		}
 		offset += de->rec_len;
-		de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
+		de = (struct ext2_dir_entry_2 *) ((char *) de + de->rec_len);
 	}
 	brelse (bh);
 	return NULL;
@@ -331,15 +332,15 @@
  * ext2_delete_entry deletes a directory entry by merging it with the
  * previous entry
  */
-static int ext2_delete_entry (struct ext2_dir_entry * dir,
+static int ext2_delete_entry (struct ext2_dir_entry_2 * dir,
 			      struct buffer_head * bh)
 {
-	struct ext2_dir_entry * de, * pde;
+	struct ext2_dir_entry_2 * de, * pde;
 	int i;
 
 	i = 0;
 	pde = NULL;
-	de = (struct ext2_dir_entry *) bh->b_data;
+	de = (struct ext2_dir_entry_2 *) bh->b_data;
 	while (i < bh->b_size) {
 		if (!ext2_check_dir_entry ("ext2_delete_entry", NULL, 
 					   de, bh, i))
@@ -352,7 +353,7 @@
 		}
 		i += de->rec_len;
 		pde = de;
-		de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
+		de = (struct ext2_dir_entry_2 *) ((char *) de + de->rec_len);
 	}
 	return -ENOENT;
 }
@@ -362,7 +363,7 @@
 {
 	struct inode * inode;
 	struct buffer_head * bh;
-	struct ext2_dir_entry * de;
+	struct ext2_dir_entry_2 * de;
 	int err;
 
 	*result = NULL;
@@ -385,6 +386,9 @@
 		return err;
 	}
 	de->inode = inode->i_ino;
+	if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+				      EXT2_FEATURE_INCOMPAT_FILETYPE))
+		de->file_type = EXT2_FT_REG_FILE;
 	dir->i_version = ++event;
 	dcache_add(dir, de->name, de->name_len, de->inode);
 	mark_buffer_dirty(bh, 1);
@@ -403,7 +407,7 @@
 {
 	struct inode * inode;
 	struct buffer_head * bh;
-	struct ext2_dir_entry * de;
+	struct ext2_dir_entry_2 * de;
 	int err;
 
 	if (!dir)
@@ -427,21 +431,27 @@
 	inode->i_uid = current->fsuid;
 	inode->i_mode = mode;
 	inode->i_op = NULL;
-	if (S_ISREG(inode->i_mode))
+	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ext2_file_inode_operations;
-	else if (S_ISDIR(inode->i_mode)) {
-		inode->i_op = &ext2_dir_inode_operations;
-		if (dir->i_mode & S_ISGID)
-			inode->i_mode |= S_ISGID;
-	}
-	else if (S_ISLNK(inode->i_mode))
-		inode->i_op = &ext2_symlink_inode_operations;
-	else if (S_ISCHR(inode->i_mode))
+		if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+					      EXT2_FEATURE_INCOMPAT_FILETYPE))
+			de->file_type = EXT2_FT_REG_FILE;
+	} else if (S_ISCHR(inode->i_mode)) {
 		inode->i_op = &chrdev_inode_operations;
-	else if (S_ISBLK(inode->i_mode))
+		if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+					      EXT2_FEATURE_INCOMPAT_FILETYPE))
+			de->file_type = EXT2_FT_CHRDEV;
+	} else if (S_ISBLK(inode->i_mode)) {
 		inode->i_op = &blkdev_inode_operations;
-	else if (S_ISFIFO(inode->i_mode)) 
+		if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+					      EXT2_FEATURE_INCOMPAT_FILETYPE))
+			de->file_type = EXT2_FT_BLKDEV;
+	} else if (S_ISFIFO(inode->i_mode)) {
 		init_fifo(inode);
+		if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+					      EXT2_FEATURE_INCOMPAT_FILETYPE))
+			de->file_type = EXT2_FT_FIFO;
+	}
 	if (S_ISBLK(mode) || S_ISCHR(mode))
 		inode->i_rdev = to_kdev_t(rdev);
 	inode->i_dirt = 1;
@@ -471,7 +481,7 @@
 {
 	struct inode * inode;
 	struct buffer_head * bh, * dir_block;
-	struct ext2_dir_entry * de;
+	struct ext2_dir_entry_2 * de;
 	int err;
 
 	if (!dir)
@@ -506,16 +516,22 @@
 		return err;
 	}
 	inode->i_blocks = inode->i_sb->s_blocksize / 512;
-	de = (struct ext2_dir_entry *) dir_block->b_data;
+	de = (struct ext2_dir_entry_2 *) dir_block->b_data;
 	de->inode = inode->i_ino;
 	de->name_len = 1;
 	de->rec_len = EXT2_DIR_REC_LEN(de->name_len);
 	strcpy (de->name, ".");
-	de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
+	if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+				      EXT2_FEATURE_INCOMPAT_FILETYPE))
+		de->file_type = EXT2_FT_DIR;
+	de = (struct ext2_dir_entry_2 *) ((char *) de + de->rec_len);
 	de->inode = dir->i_ino;
 	de->rec_len = inode->i_sb->s_blocksize - EXT2_DIR_REC_LEN(1);
 	de->name_len = 2;
 	strcpy (de->name, "..");
+	if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+				      EXT2_FEATURE_INCOMPAT_FILETYPE))
+		de->file_type = EXT2_FT_DIR;
 	inode->i_nlink = 2;
 	mark_buffer_dirty(dir_block, 1);
 	brelse (dir_block);
@@ -532,6 +548,9 @@
 		return err;
 	}
 	de->inode = inode->i_ino;
+	if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+				      EXT2_FEATURE_INCOMPAT_FILETYPE))
+		de->file_type = EXT2_FT_DIR;
 	dir->i_version = ++event;
 	dcache_add(dir, de->name, de->name_len, de->inode);
 	mark_buffer_dirty(bh, 1);
@@ -554,7 +573,7 @@
 {
 	unsigned long offset;
 	struct buffer_head * bh;
-	struct ext2_dir_entry * de, * de1;
+	struct ext2_dir_entry_2 * de, * de1;
 	struct super_block * sb;
 	int err;
 
@@ -566,8 +585,8 @@
 			      inode->i_ino);
 		return 1;
 	}
-	de = (struct ext2_dir_entry *) bh->b_data;
-	de1 = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
+	de = (struct ext2_dir_entry_2 *) bh->b_data;
+	de1 = (struct ext2_dir_entry_2 *) ((char *) de + de->rec_len);
 	if (de->inode != inode->i_ino || !de1->inode || 
 	    strcmp (".", de->name) || strcmp ("..", de1->name)) {
 	    	ext2_warning (inode->i_sb, "empty_dir",
@@ -577,7 +596,7 @@
 		return 1;
 	}
 	offset = de->rec_len + de1->rec_len;
-	de = (struct ext2_dir_entry *) ((char *) de1 + de1->rec_len);
+	de = (struct ext2_dir_entry_2 *) ((char *) de1 + de1->rec_len);
 	while (offset < inode->i_size ) {
 		if (!bh || (void *) de >= (void *) (bh->b_data + sb->s_blocksize)) {
 			brelse (bh);
@@ -589,7 +608,7 @@
 				offset += sb->s_blocksize;
 				continue;
 			}
-			de = (struct ext2_dir_entry *) bh->b_data;
+			de = (struct ext2_dir_entry_2 *) bh->b_data;
 		}
 		if (!ext2_check_dir_entry ("empty_dir", inode, de, bh,
 					   offset)) {
@@ -601,7 +620,7 @@
 			return 0;
 		}
 		offset += de->rec_len;
-		de = (struct ext2_dir_entry *) ((char *) de + de->rec_len);
+		de = (struct ext2_dir_entry_2 *) ((char *) de + de->rec_len);
 	}
 	brelse (bh);
 	return 1;
@@ -612,7 +631,7 @@
 	int retval;
 	struct inode * inode;
 	struct buffer_head * bh;
-	struct ext2_dir_entry * de;
+	struct ext2_dir_entry_2 * de;
 
 repeat:
 	if (!dir)
@@ -701,7 +720,7 @@
 	int retval;
 	struct inode * inode;
 	struct buffer_head * bh;
-	struct ext2_dir_entry * de;
+	struct ext2_dir_entry_2 * de;
 
 repeat:
 	if (!dir)
@@ -766,7 +785,7 @@
 int ext2_symlink (struct inode * dir, const char * name, int len,
 		  const char * symname)
 {
-	struct ext2_dir_entry * de;
+	struct ext2_dir_entry_2 * de;
 	struct inode * inode = NULL;
 	struct buffer_head * bh = NULL, * name_block = NULL;
 	char * link;
@@ -831,6 +850,9 @@
 		return err;
 	}
 	de->inode = inode->i_ino;
+	if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+				      EXT2_FEATURE_INCOMPAT_FILETYPE))
+		de->file_type = EXT2_FT_SYMLINK;
 	dir->i_version = ++event;
 	dcache_add(dir, de->name, de->name_len, de->inode);
 	mark_buffer_dirty(bh, 1);
@@ -847,7 +869,7 @@
 int ext2_link (struct inode * oldinode, struct inode * dir,
 	       const char * name, int len)
 {
-	struct ext2_dir_entry * de;
+	struct ext2_dir_entry_2 * de;
 	struct buffer_head * bh;
 	int err;
 
@@ -880,6 +902,21 @@
 		return err;
 	}
 	de->inode = oldinode->i_ino;
+	if (EXT2_HAS_INCOMPAT_FEATURE(oldinode->i_sb,
+				      EXT2_FEATURE_INCOMPAT_FILETYPE)) {
+		if (S_ISREG(oldinode->i_mode))
+			de->file_type = EXT2_FT_REG_FILE;
+		else if (S_ISDIR(oldinode->i_mode))
+			de->file_type = EXT2_FT_DIR;
+		else if (S_ISLNK(oldinode->i_mode))
+			de->file_type = EXT2_FT_SYMLINK;
+		else if (S_ISCHR(oldinode->i_mode))
+			de->file_type = EXT2_FT_CHRDEV;
+		else if (S_ISBLK(oldinode->i_mode))
+			de->file_type = EXT2_FT_BLKDEV;
+		else if (S_ISFIFO(oldinode->i_mode))  
+			de->file_type = EXT2_FT_FIFO;
+	}
 	dir->i_version = ++event;
 	dcache_add(dir, de->name, de->name_len, de->inode);
 	mark_buffer_dirty(bh, 1);
@@ -921,12 +958,12 @@
 }
 
 #define PARENT_INO(buffer) \
-	((struct ext2_dir_entry *) ((char *) buffer + \
-	((struct ext2_dir_entry *) buffer)->rec_len))->inode
+	((struct ext2_dir_entry_2 *) ((char *) buffer + \
+	((struct ext2_dir_entry_2 *) buffer)->rec_len))->inode
 
 #define PARENT_NAME(buffer) \
-	((struct ext2_dir_entry *) ((char *) buffer + \
-	((struct ext2_dir_entry *) buffer)->rec_len))->name
+	((struct ext2_dir_entry_2 *) ((char *) buffer + \
+	((struct ext2_dir_entry_2 *) buffer)->rec_len))->name
 
 /*
  * rename uses retrying to avoid race-conditions: at least they should be
@@ -946,7 +983,7 @@
 {
 	struct inode * old_inode, * new_inode;
 	struct buffer_head * old_bh, * new_bh, * dir_bh;
-	struct ext2_dir_entry * old_de, * new_de;
+	struct ext2_dir_entry_2 * old_de, * new_de;
 	int retval;
 
 	goto start_up;
@@ -1060,6 +1097,9 @@
 	 * ok, that's it
 	 */
 	new_de->inode = old_inode->i_ino;
+	if (EXT2_HAS_INCOMPAT_FEATURE(new_dir->i_sb,
+				      EXT2_FEATURE_INCOMPAT_FILETYPE))
+		new_de->file_type = old_de->file_type;
 	dcache_add(new_dir, new_de->name, new_de->name_len, new_de->inode);
 	retval = ext2_delete_entry (old_de, old_bh);
 	if (retval == -ENOENT)
diff -u --recursive --new-file linux-2.0.38/fs/ext2/super.c linux-2.0.39/fs/ext2/super.c
--- linux-2.0.38/fs/ext2/super.c	Sun Jul  7 10:06:53 1996
+++ linux-2.0.39/fs/ext2/super.c	Tue Jul 11 18:41:19 2000
@@ -124,7 +124,7 @@
 	return;
 }
 
-static struct super_operations ext2_sops = { 
+static struct super_operations ext2_sops = {
 	ext2_read_inode,
 	NULL,
 	ext2_write_inode,
@@ -415,22 +415,22 @@
 	if (es->s_rev_level > EXT2_GOOD_OLD_REV) {
 		if (es->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPP) {
 			printk("EXT2-fs: %s: couldn't mount because of "
-			       "unsupported optional features.\n", 
+			       "unsupported optional features.\n",
 			       kdevname(dev));
 			goto failed_mount;
 		}
 		if (!(sb->s_flags & MS_RDONLY) &&
 		    (es->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP)) {
 			printk("EXT2-fs: %s: couldn't mount RDWR because of "
-			       "unsupported optional features.\n", 
+			       "unsupported optional features.\n",
 			       kdevname(dev));
 			goto failed_mount;
 		}
 	}
 	sb->s_blocksize_bits = sb->u.ext2_sb.s_es->s_log_block_size + 10;
 	sb->s_blocksize = 1 << sb->s_blocksize_bits;
-	if (sb->s_blocksize != BLOCK_SIZE && 
-	    (sb->s_blocksize == 1024 || sb->s_blocksize == 2048 ||  
+	if (sb->s_blocksize != BLOCK_SIZE &&
+	    (sb->s_blocksize == 1024 || sb->s_blocksize == 2048 ||
 	     sb->s_blocksize == 4096)) {
 		unsigned long offset;
 
@@ -463,6 +463,9 @@
 			goto failed_mount;
 		}
 	}
+	sb->u.ext2_sb.s_feature_compat = es->s_feature_compat;
+	sb->u.ext2_sb.s_feature_incompat = es->s_feature_incompat;
+	sb->u.ext2_sb.s_feature_ro_compat = es->s_feature_ro_compat;
 	sb->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE <<
 				   es->s_log_frag_size;
 	if (sb->u.ext2_sb.s_frag_size)
@@ -669,7 +672,7 @@
 	else {
 		/*
 		 * Mounting a RDONLY partition read-write, so reread and
-		 * store the current valid flag.  (It may have been changed 
+		 * store the current valid flag.  (It may have been changed
 		 * by e2fsck since we originally mounted the partition.)
 		 */
 		sb->u.ext2_sb.s_mount_state = es->s_state;
@@ -710,6 +713,7 @@
 	unsigned long overhead;
 	unsigned long overhead_per_group;
 	struct statfs tmp;
+	int ngroups, i;
 
 	if (test_opt (sb, MINIX_DF))
 		overhead = 0;
@@ -717,13 +721,35 @@
 		/*
 		 * Compute the overhead (FS structures)
 		 */
-		overhead_per_group = 1 /* super block */ +
-				     sb->u.ext2_sb.s_db_per_group /* descriptors */ +
-				     1 /* block bitmap */ +
-				     1 /* inode bitmap */ +
-				     sb->u.ext2_sb.s_itb_per_group /* inode table */;
-		overhead = sb->u.ext2_sb.s_es->s_first_data_block +
-			   sb->u.ext2_sb.s_groups_count * overhead_per_group;
+
+		/*
+		 * All of the blocks before first_data_block are
+		 * overhead
+		 */
+		overhead = sb->u.ext2_sb.s_es->s_first_data_block;
+
+		/*
+		 * Add the overhead attributed to the superblock and
+		 * block group descriptors.  If this is sparse
+		 * superblocks is turned on, then not all groups have
+		 * this.
+		 */
+		if (sb->u.ext2_sb.s_feature_ro_compat &
+		    EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) {
+			ngroups = 0;
+			for (i=0 ; i < sb->u.ext2_sb.s_groups_count; i++)
+				if (ext2_group_sparse(i))
+					ngroups++;
+		} else
+			ngroups = sb->u.ext2_sb.s_groups_count;
+		overhead += ngroups * (1 + sb->u.ext2_sb.s_db_per_group);
+
+		/*
+		 * Every block group has an inode bitmap, a block
+		 * bitmap, and an inode table.
+		 */
+		overhead += (sb->u.ext2_sb.s_groups_count *
+			     (2 + sb->u.ext2_sb.s_itb_per_group));
 	}
 
 	tmp.f_type = EXT2_SUPER_MAGIC;
diff -u --recursive --new-file linux-2.0.38/fs/ncpfs/Config.in linux-2.0.39/fs/ncpfs/Config.in
--- linux-2.0.38/fs/ncpfs/Config.in	Sun Jun 13 19:21:03 1999
+++ linux-2.0.39/fs/ncpfs/Config.in	Thu Dec 30 22:55:52 1999
@@ -1,9 +1,9 @@
 #
 # NCP Filesystem configuration
 #
-bool     '   Packet singatures' CONFIG_NCPFS_PACKET_SIGNING
-bool     '   Proprietary file locking' CONFIG_NCPFS_IOCTL_LOCKING
-bool     '   Clear remove/delete inhibit when needed' CONFIG_NCPFS_STRONG
-bool     '   Use NFS namespace if available' CONFIG_NCPFS_NFS_NS
-bool     '   Use LONG (OS/2) namespace if available' CONFIG_NCPFS_OS2_NS
-bool     '   Allow mounting of volume subdirectories' CONFIG_NCPFS_MOUNT_SUBDIR
+bool     '  Packet signatures' CONFIG_NCPFS_PACKET_SIGNING
+bool     '  Proprietary file locking' CONFIG_NCPFS_IOCTL_LOCKING
+bool     '  Clear remove/delete inhibit when needed' CONFIG_NCPFS_STRONG
+bool     '  Use NFS namespace if available' CONFIG_NCPFS_NFS_NS
+bool     '  Use LONG (OS/2) namespace if available' CONFIG_NCPFS_OS2_NS
+bool     '  Allow mounting of volume subdirectories' CONFIG_NCPFS_MOUNT_SUBDIR
diff -u --recursive --new-file linux-2.0.38/fs/nls.c linux-2.0.39/fs/nls.c
--- linux-2.0.38/fs/nls.c	Sun Jun 13 19:21:03 1999
+++ linux-2.0.39/fs/nls.c	Thu Dec 30 15:42:15 1999
@@ -455,6 +455,9 @@
 #ifdef CONFIG_NLS_ISO8859_9
 	init_nls_iso8859_9();
 #endif
+#ifdef CONFIG_NLS_ISO8859_14
+	init_nls_iso8859_14();
+#endif
 #ifdef CONFIG_NLS_ISO8859_15
 	init_nls_iso8859_15();
 #endif
diff -u --recursive --new-file linux-2.0.38/fs/nls_iso8859_14.c linux-2.0.39/fs/nls_iso8859_14.c
--- linux-2.0.38/fs/nls_iso8859_14.c	Thu Jan  1 01:00:00 1970
+++ linux-2.0.39/fs/nls_iso8859_14.c	Thu Dec 30 15:44:37 1999
@@ -0,0 +1,311 @@
+/*
+ * linux/fs/nls_iso8859-14.c
+ *
+ * Charset iso8859-14 translation tables.
+ *
+ * Generated automatically from the Unicode and charset table
+ * provided by the Unicode Organisation at
+ * http://www.unicode.org/
+ * The Unicode to charset table has only exact mappings.
+ *
+ * Rhys Jones, Swansea University Computer Society
+ * rhys@sucs.swan.ac.uk
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+
+static struct nls_unicode charset2uni[256] = {
+	/* 0x00*/
+	{0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00},
+	{0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00},
+	{0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00},
+	{0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
+	/* 0x10*/
+	{0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00},
+	{0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00},
+	{0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00},
+	{0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
+	/* 0x20*/
+	{0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00},
+	{0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00},
+	{0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00},
+	{0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00},
+	/* 0x30*/
+	{0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
+	{0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00},
+	{0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00},
+	{0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00},
+	/* 0x40*/
+	{0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00},
+	{0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00},
+	{0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00},
+	{0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00},
+	/* 0x50*/
+	{0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00},
+	{0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00},
+	{0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00},
+	{0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00},
+	/* 0x60*/
+	{0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00},
+	{0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00},
+	{0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00},
+	{0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00},
+	/* 0x70*/
+	{0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00},
+	{0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00},
+	{0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00},
+	{0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00},
+	/* 0x80*/
+	{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+	{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+	{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+	{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+	/* 0x90*/
+	{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+	{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+	{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+	{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+	/* 0xa0*/
+	{0xa0, 0x00}, {0x02, 0x1e}, {0x03, 0x1e}, {0xa3, 0x00},
+	{0x0a, 0x01}, {0x0b, 0x01}, {0x0a, 0x1e}, {0xa7, 0x00},
+	{0x80, 0x1e}, {0xa9, 0x00}, {0x82, 0x1e}, {0x0b, 0x1e},
+	{0xf2, 0x1e}, {0xad, 0x00}, {0xae, 0x00}, {0x78, 0x01},
+	/* 0xb0*/
+	{0x1e, 0x1e}, {0x1f, 0x1e}, {0x20, 0x01}, {0x21, 0x01},
+	{0x40, 0x1e}, {0x41, 0x1e}, {0xb6, 0x00}, {0x56, 0x1e},
+	{0x81, 0x1e}, {0x57, 0x1e}, {0x83, 0x1e}, {0x60, 0x1e},
+	{0xf3, 0x1e}, {0x84, 0x1e}, {0x85, 0x1e}, {0x61, 0x1e},
+	/* 0xc0*/
+	{0xc0, 0x00}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc3, 0x00},
+	{0xc4, 0x00}, {0xc5, 0x00}, {0xc6, 0x00}, {0xc7, 0x00},
+	{0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x00}, {0xcb, 0x00},
+	{0xcc, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, {0xcf, 0x00},
+	/* 0xd0*/
+	{0x74, 0x01}, {0xd1, 0x00}, {0xd2, 0x00}, {0xd3, 0x00},
+	{0xd4, 0x00}, {0xd5, 0x00}, {0xd6, 0x00}, {0x6a, 0x1e},
+	{0xd8, 0x00}, {0xd9, 0x00}, {0xda, 0x00}, {0xdb, 0x00},
+	{0xdc, 0x00}, {0xdd, 0x00}, {0x76, 0x01}, {0xdf, 0x00},
+	/* 0xe0*/
+	{0xe0, 0x00}, {0xe1, 0x00}, {0xe2, 0x00}, {0xe3, 0x00},
+	{0xe4, 0x00}, {0xe5, 0x00}, {0xe6, 0x00}, {0xe7, 0x00},
+	{0xe8, 0x00}, {0xe9, 0x00}, {0xea, 0x00}, {0xeb, 0x00},
+	{0xec, 0x00}, {0xed, 0x00}, {0xee, 0x00}, {0xef, 0x00},
+	/* 0xf0*/
+	{0x75, 0x01}, {0xf1, 0x00}, {0xf2, 0x00}, {0xf3, 0x00},
+	{0xf4, 0x00}, {0xf5, 0x00}, {0xf6, 0x00}, {0x6b, 0x1e},
+	{0xf8, 0x00}, {0xf9, 0x00}, {0xfa, 0x00}, {0xfb, 0x00},
+	{0xfc, 0x00}, {0xfd, 0x00}, {0x77, 0x01}, {0xff, 0x00},
+};
+
+static unsigned char page00[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0xa0, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */
+	0x00, 0xa9, 0x00, 0x00, 0x00, 0xad, 0xae, 0x00, /* 0xa8-0xaf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x00, /* 0xb0-0xb7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
+	0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* 0xd0-0xd7 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
+	0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0x00, /* 0xf0-0xf7 */
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0x00, 0xff, /* 0xf8-0xff */
+};
+
+static unsigned char page01[256] = {
+	0x00, 0x00, 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0xa6, 0xab, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb1, /* 0x18-0x1f */
+	0xb2, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0xb4, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0xb9, /* 0x50-0x57 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+	0xbb, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0xd7, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, 0xde, 0xfe, /* 0x70-0x77 */
+	0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+	0xa8, 0xb8, 0xaa, 0xba, 0xbd, 0xbe, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+	0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+static unsigned char page1e[256] = {
+	0x00, 0x00, 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0xa6, 0xab, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb1, /* 0x18-0x1f */
+	0xb2, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0xb4, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0xb9, /* 0x50-0x57 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+	0xbb, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0xd7, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, 0xde, 0xfe, /* 0x70-0x77 */
+	0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+	0xa8, 0xb8, 0xaa, 0xba, 0xbd, 0xbe, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+	0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+static unsigned char *page_uni2charset[256] = {
+	page00,	page01, NULL,   NULL,   NULL,   NULL,   NULL,   NULL,
+	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
+
+	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
+	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	page1e,	NULL,
+
+	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
+	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
+};
+
+static unsigned char charset2upper[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
+	0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0xa0, 0xa1, 0xa1, 0xa3, 0xa6, 0xa6, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0xa8, 0xa9, 0xaa, 0xa6, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
+	0xb0, 0xb0, 0xb2, 0xb2, 0xb4, 0xb4, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0xa8, 0xb7, 0xaa, 0xbb, 0xac, 0xbd, 0xbd, 0xbb, /* 0xb8-0xbf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xe0-0xe7 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xe8-0xef */
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xf0-0xf7 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xaf, /* 0xf8-0xff */
+};
+
+
+static void inc_use_count(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void dec_use_count(void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+static struct nls_table table = {
+	"iso8859-14",
+	page_uni2charset,
+	charset2uni,
+	inc_use_count,
+	dec_use_count,
+	NULL
+};
+
+int init_nls_iso8859_14(void)
+{
+	return register_nls(&table);
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+	return init_nls_iso8859_14();
+}
+
+
+void cleanup_module(void)
+{
+	unregister_nls(&table);
+	return;
+}
+#endif
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file linux-2.0.38/fs/proc/array.c linux-2.0.39/fs/proc/array.c
--- linux-2.0.38/fs/proc/array.c	Sun Jun 13 19:21:03 1999
+++ linux-2.0.39/fs/proc/array.c	Tue Apr 25 16:16:37 2000
@@ -610,6 +610,7 @@
 			vsize += vma->vm_end - vma->vm_start;
 			vma = vma->vm_next;
 		}
+		if ((current->fsuid == tsk->euid && tsk->dumpable) || suser())
 		if (tsk->kernel_stack_page) {
 			eip = KSTK_EIP(tsk);
 			esp = KSTK_ESP(tsk);
@@ -1026,7 +1027,7 @@
 		case PROC_PID_CMDLINE:
 			return 0;	
 	}
-	if(suser() || current->fsuid == (*p)->euid)
+	if ((current->fsuid == (*p)->euid && (*p)->dumpable) || suser())
 		return 0;
 	return 1;
 }
diff -u --recursive --new-file linux-2.0.38/fs/proc/fd.c linux-2.0.39/fs/proc/fd.c
--- linux-2.0.38/fs/proc/fd.c	Thu Nov 13 05:36:41 1997
+++ linux-2.0.39/fs/proc/fd.c	Tue Apr 25 16:16:37 2000
@@ -86,6 +86,7 @@
 	}
 	iput(dir);
 	fd = 0;
+	if (len > 1 && *name == '0') fd = 0xfffff; else
 	while (len-- > 0) {
 		c = *name - '0';
 		name++;
diff -u --recursive --new-file linux-2.0.38/fs/proc/net.c linux-2.0.39/fs/proc/net.c
--- linux-2.0.38/fs/proc/net.c	Sun Jan 14 15:47:28 1996
+++ linux-2.0.39/fs/proc/net.c	Wed Dec 29 12:39:44 1999
@@ -15,11 +15,11 @@
  *            quite a bit, modularized the code.
  * fvk 4/'93  waltje@uwalt.nl.mugnet.org (Fred N. van Kempen)
  *	      Renamed "route_get_info()" to "rt_get_info()" for consistency.
- * Alan Cox (gw4pts@gw4pts.ampr.org) 4/94
+ * Alan Cox (alan@lxorguk.ukuu.org.uk) 4/94
  *	      Dusted off the code and added IPX. Fixed the 4K limit.
  * Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
  *	      /proc/net/snmp.
- * Alan Cox (gw4pts@gw4pts.ampr.org) 1/95
+ * Alan Cox (alan@lxorguk.ukuu.org.uk) 1/95
  *	      Added Appletalk slots
  *
  *  proc net directory handling functions
diff -u --recursive --new-file linux-2.0.38/fs/proc/root.c linux-2.0.39/fs/proc/root.c
--- linux-2.0.38/fs/proc/root.c	Tue Apr 30 12:09:45 1996
+++ linux-2.0.39/fs/proc/root.c	Tue Apr 25 16:16:37 2000
@@ -466,6 +466,7 @@
 		}
 		pid *= 10;
 		pid += c;
+		if (!pid) break;
 		if (pid & 0xffff0000) {
 			pid = 0;
 			break;
diff -u --recursive --new-file linux-2.0.38/fs/smbfs/sock.c linux-2.0.39/fs/smbfs/sock.c
--- linux-2.0.38/fs/smbfs/sock.c	Mon Sep 15 19:02:41 1997
+++ linux-2.0.39/fs/smbfs/sock.c	Wed Jun 28 15:43:19 2000
@@ -64,12 +64,33 @@
 	return sock->ops->sendmsg(sock, &msg, len, nonblock, flags);
 }
 
+struct data_callback {
+	struct tq_struct cb;
+	struct sock *sk;
+};
+/*
+ * N.B. What happens if we're in here when the socket closes??
+ */
+static void
+found_data(struct sock *sk)
+{
+	/*
+	 * FIXME: copied from sock_def_readable, it should be a call to
+	 * server->data_ready();
+	 */
+	if (!sk->dead) {
+		wake_up_interruptible(sk->sleep);
+		sock_wake_async(sk->socket, 1);
+	}
+}
+
 static void
-smb_data_callback(struct sock *sk, int len)
+smb_data_callback(void *ptr)
 {
-	struct socket *sock = sk->socket;
+	struct data_callback *job = ptr;
+	struct socket *sock = job->sk->socket;
 
-	if (!sk->dead)
+	if (!job->sk->dead)
 	{
 		unsigned char peek_buf[4];
 		int result;
@@ -101,11 +122,27 @@
 		set_fs(fs);
 
 		if (result != -EAGAIN)
-		{
-			wake_up_interruptible(sk->sleep);
-		}
+			found_data(job->sk);
 	}
+	kfree(ptr);
 }
+static void
+smb_data_ready(struct sock *sk, int len)
+{
+	struct data_callback *job;
+	job = kmalloc(sizeof(struct data_callback), GFP_ATOMIC);
+	if (job == 0) {
+		printk("smb_data_ready(): lost SESSION KEEPALIVE due to OOM.\n");
+		found_data(sk);
+		return;
+	}
+	job->cb.next = NULL;
+	job->cb.sync = 0;
+	job->cb.routine = smb_data_callback;
+	job->cb.data = job;
+	job->sk = sk;
+	queue_task(&job->cb, &tq_scheduler);
+ }
 
 int
 smb_catch_keepalive(struct smb_server *server)
@@ -113,6 +150,7 @@
 	struct file *file;
 	struct inode *inode;
 	struct socket *sock;
+	void *data_ready;
 	struct sock *sk;
 
 	if ((server == NULL)
@@ -143,15 +181,18 @@
 	DDPRINTK("smb_catch_keepalive.: sk->d_r = %x, server->d_r = %x\n",
 		 (unsigned int) (sk->data_ready),
 		 (unsigned int) (server->data_ready));
-
-	if (sk->data_ready == smb_data_callback)
-	{
-		printk("smb_catch_keepalive: already done\n");
+        /*
+         * Install the callback atomically to avoid races ...
+         */
+        data_ready = xchg(&sk->data_ready, smb_data_ready);
+        if (data_ready != smb_data_ready)
+        {
+                server->data_ready = data_ready;
+                return 0;
+        } else {
+                printk("smb_catch_keepalive: already done\n");
 		return -EINVAL;
 	}
-	server->data_ready = sk->data_ready;
-	sk->data_ready = smb_data_callback;
-	return 0;
 }
 
 int
@@ -160,6 +201,7 @@
 	struct file *file;
 	struct inode *inode;
 	struct socket *sock;
+	void *data_ready;
 	struct sock *sk;
 
 	if ((server == NULL)
@@ -191,18 +233,20 @@
 		       "server->data_ready == NULL\n");
 		return -EINVAL;
 	}
-	if (sk->data_ready != smb_data_callback)
+	/*
+ 	 * Restore the original callback atomically to avoid races ...
+	 */
+	data_ready = xchg(&sk->data_ready, server->data_ready);
+	server->data_ready = NULL;
+	if (data_ready != smb_data_ready)
 	{
 		printk("smb_dont_catch_keepalive: "
-		       "sk->data_callback != smb_data_callback\n");
+		"sk->data_ready != smb_data_ready\n");
 		return -EINVAL;
 	}
 	DDPRINTK("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
 		 (unsigned int) (sk->data_ready),
 		 (unsigned int) (server->data_ready));
-
-	sk->data_ready = server->data_ready;
-	server->data_ready = NULL;
 	return 0;
 }
 
diff -u --recursive --new-file linux-2.0.38/include/linux/ali_ide_dma.h linux-2.0.39/include/linux/ali_ide_dma.h
--- linux-2.0.38/include/linux/ali_ide_dma.h	Thu Jan  1 01:00:00 1970
+++ linux-2.0.39/include/linux/ali_ide_dma.h	Wed Jun 28 14:48:19 2000
@@ -0,0 +1,210 @@
+/* Aladdin 5229 timings display header file for triton.c.
+   Copyright (c) 1998-99 Michel Aubry
+   Copyright (c) 1999 Andre Hedrick
+*/
+
+
+static int ali_get_info(char *, char **, off_t, int, int);
+
+static struct proc_dir_entry ali_proc_entry = {
+  0, 3, "ali", S_IFREG | S_IRUGO, 1, 0, 0, 0, 0, ali_get_info
+};
+
+/* we save bus, function of chipset here for further debug use */
+static byte bmide_bus, bmide_fn;
+
+static char *fifo[4] = {
+	"FIFO Off",
+	"FIFO On ",
+	"DMA mode",
+	"PIO mode"
+};
+
+static char *udmaT[8] = {
+	"1.5T",
+	"  2T",
+	"2.5T",
+	"  3T",
+	"3.5T",
+	"  4T",
+	"  6T",
+	"  8T"
+};
+
+char *channel_status[8] = {
+	"OK            ",
+	"busy          ",
+	"DRQ           ",
+	"DRQ busy      ",
+	"error         ",
+	"error busy    ",
+	"error DRQ     ",
+	"error DRQ busy"
+};
+
+static int ali_get_info(char *buffer, char **addr, off_t offset, int count, int dummy)
+{
+	byte reg53h, reg5xh, reg5yh, reg5xh1, reg5yh1;
+	unsigned int bibma;
+	byte c0, c1;
+	byte rev, tmp;
+	char *p = buffer;
+	char *q;
+
+	/* fetch rev. */
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x08, &rev);
+	if (rev >= 0xc1)	/* M1543C or newer */
+		udmaT[7] = " ???";
+	else
+		fifo[3]  = "   ???  ";
+
+	/* first fetch bibma: */
+	pcibios_read_config_dword(bmide_bus, bmide_fn, 0x20, &bibma);
+	bibma = (bibma & 0xfff0) ;
+	/*
+	 * at that point bibma+0x2 et bibma+0xa are byte
+	 * registers to investigate:
+	 */
+	c0 = inb((unsigned short)bibma + 0x02);
+	c1 = inb((unsigned short)bibma + 0x0a);
+
+	p += sprintf(p,
+		"\n                                Ali M15x3 Chipset.\n");
+	p += sprintf(p,
+		"                                ------------------\n");
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x78, &reg53h);
+	p += sprintf(p, "PCI Clock: %d.\n", reg53h);
+
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x53, &reg53h);
+	p += sprintf(p,
+		"CD_ROM FIFO:%s, CD_ROM DMA:%s\n",
+		(reg53h & 0x02) ? "Yes" : "No ",
+		(reg53h & 0x01) ? "Yes" : "No " );
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x74, &reg53h);
+	p += sprintf(p,
+		"FIFO Status: contains %d Words, runs%s%s\n\n",
+		(reg53h & 0x3f),
+		(reg53h & 0x40) ? " OVERWR" : "",
+		(reg53h & 0x80) ? " OVERRD." : "." );
+
+	p += sprintf(p,
+		"-------------------primary channel-------------------secondary channel---------\n\n");
+
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x09, &reg53h);
+	p += sprintf(p,
+		"channel status:       %s                               %s\n",
+		(reg53h & 0x20) ? "On " : "Off",
+		(reg53h & 0x10) ? "On " : "Off" );
+
+	p += sprintf(p,
+		"both channels togth:  %s                               %s\n",
+		(c0&0x80) ? "No " : "Yes",
+		(c1&0x80) ? "No " : "Yes" );
+
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x76, &reg53h);
+	p += sprintf(p,
+		"Channel state:        %s                    %s\n",
+		channel_status[reg53h & 0x07],
+		channel_status[(reg53h & 0x70) >> 4] );
+
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x58, &reg5xh);
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5c, &reg5yh);
+	p += sprintf(p,
+		"Add. Setup Timing:    %dT                                %dT\n",
+		(reg5xh & 0x07) ? (reg5xh & 0x07) : 8,
+		(reg5yh & 0x07) ? (reg5yh & 0x07) : 8 );
+
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x59, &reg5xh);
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5d, &reg5yh);
+	p += sprintf(p,
+		"Command Act. Count:   %dT                                %dT\n"
+		"Command Rec. Count:   %dT                               %dT\n\n",
+		(reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8,
+		(reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, 
+		(reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16,
+		(reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16 );
+
+	p += sprintf(p,
+		"----------------drive0-----------drive1------------drive0-----------drive1------\n\n");
+	p += sprintf(p,
+		"DMA enabled:      %s              %s               %s              %s\n",
+		(c0&0x20) ? "Yes" : "No ",
+		(c0&0x40) ? "Yes" : "No ",
+		(c1&0x20) ? "Yes" : "No ",
+		(c1&0x40) ? "Yes" : "No " );
+
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x54, &reg5xh);
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x55, &reg5yh);
+	q = "FIFO threshold:   %2d Words         %2d Words          %2d Words         %2d Words\n";
+	if (rev < 0xc1) {
+		if ((rev == 0x20) && (pcibios_read_config_byte(bmide_bus, bmide_fn, 0x4f, &tmp), (tmp &= 0x20))) {
+			p += sprintf(p, q, 8, 8, 8, 8);
+		} else {
+			p += sprintf(p, q,
+				(reg5xh & 0x03) + 12,
+				((reg5xh & 0x30)>>4) + 12,
+				(reg5yh & 0x03) + 12,
+				((reg5yh & 0x30)>>4) + 12 );
+		}
+	} else {
+		p += sprintf(p, q,
+			(tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4,
+			(tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4,
+			(tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4,
+			(tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4 );
+	}
+
+#if 0
+	p += sprintf(p, 
+		"FIFO threshold:   %2d Words         %2d Words          %2d Words         %2d Words\n",
+		(reg5xh & 0x03) + 12,
+		((reg5xh & 0x30)>>4) + 12,
+		(reg5yh & 0x03) + 12,
+		((reg5yh & 0x30)>>4) + 12 );
+#endif
+
+	p += sprintf(p,
+		"FIFO mode:        %s         %s          %s         %s\n",
+		fifo[((reg5xh & 0x0c) >> 2)],
+		fifo[((reg5xh & 0xc0) >> 6)],
+		fifo[((reg5yh & 0x0c) >> 2)],
+		fifo[((reg5yh & 0xc0) >> 6)] );
+
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5a, &reg5xh);
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5b, &reg5xh1);
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5e, &reg5yh);
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5f, &reg5yh1);
+
+	p += sprintf(p,/*
+		"------------------drive0-----------drive1------------drive0-----------drive1------\n")*/
+		"Dt RW act. Cnt    %dT               %dT                %dT               %dT\n"
+		"Dt RW rec. Cnt    %2dT              %2dT               %2dT              %2dT\n\n",
+		(reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8,
+		(reg5xh1 & 0x70) ? ((reg5xh1 & 0x70) >> 4) : 8,
+		(reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8,
+		(reg5yh1 & 0x70) ? ((reg5yh1 & 0x70) >> 4) : 8,
+		(reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16,
+		(reg5xh1 & 0x0f) ? (reg5xh1 & 0x0f) : 16,
+		(reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16,
+		(reg5yh1 & 0x0f) ? (reg5yh1 & 0x0f) : 16 );
+
+	p += sprintf(p,
+		"-----------------------------------UDMA Timings--------------------------------\n\n");
+
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x56, &reg5xh);
+	pcibios_read_config_byte(bmide_bus, bmide_fn, 0x57, &reg5yh);
+	p += sprintf(p,
+		"UDMA:             %s               %s                %s               %s\n"
+		"UDMA timings:     %s             %s              %s             %s\n\n",
+		(reg5xh & 0x08) ? "OK" : "No",
+		(reg5xh & 0x80) ? "OK" : "No",
+		(reg5yh & 0x08) ? "OK" : "No",
+		(reg5yh & 0x80) ? "OK" : "No",
+		udmaT[(reg5xh & 0x07)],
+		udmaT[(reg5xh & 0x70) >> 4],
+		udmaT[reg5yh & 0x07],
+		udmaT[(reg5yh & 0x70) >> 4] );
+
+	return p-buffer; /* => must be less than 4k! */
+}
+
diff -u --recursive --new-file linux-2.0.38/include/linux/cyclades.h linux-2.0.39/include/linux/cyclades.h
--- linux-2.0.38/include/linux/cyclades.h	Sun Jun 13 19:21:04 1999
+++ linux-2.0.39/include/linux/cyclades.h	Wed Jun 28 14:45:47 2000
@@ -490,7 +490,20 @@
 /****************** ****************** *******************/
 #endif
 
+/* Per card data structure */
+struct cyclades_card {
+    long base_addr;
+    long ctl_addr;
+    int irq;
+    int num_chips;	/* 0 if card absent, -1 if Z/PCI, else Y */
+    int first_line;	/* minor number of first channel on card */
+    int bus_index;	/* address shift - 0 for ISA, 1 for PCI */
+    int	intr_enabled;	/* FW Interrupt flag - 0 disabled, 1 enabled */
+};
 
+struct cyclades_chip {
+  int filler;
+};
 
 
 #ifdef __KERNEL__
@@ -508,22 +521,6 @@
 #define cy_readw(port)  readw(port)
 #define cy_readl(port)  readl(port)
 
-/* Per card data structure */
-
-struct cyclades_card {
-    long base_addr;
-    long ctl_addr;
-    int irq;
-    int num_chips;	/* 0 if card absent, -1 if Z/PCI, else Y */
-    int first_line;	/* minor number of first channel on card */
-    int bus_index;	/* address shift - 0 for ISA, 1 for PCI */
-    int	inact_ctrl;	/* FW Inactivity control - 0 disabled, 1 enabled */
-};
-
-struct cyclades_chip {
-  int filler;
-};
-
 /*
  * This is our internal structure for each serial port's state.
  * 
@@ -567,16 +564,16 @@
 	int			xmit_cnt;
         int                     default_threshold;
         int                     default_timeout;
-	struct tq_struct	tqueue;
+	unsigned long		jiffies[3];
+	unsigned long		rflush_count;
 	struct termios		normal_termios;
 	struct termios		callout_termios;
+        struct cyclades_monitor mon;
+	struct cyclades_idle_stats   idle_stats;
+	struct tq_struct	tqueue;
 	struct wait_queue	*open_wait;
 	struct wait_queue	*close_wait;
 	struct wait_queue	*shutdown_wait;
-        struct cyclades_monitor mon;
-	unsigned long		jiffies[3];
-	unsigned long		rflush_count;
-	struct cyclades_idle_stats   idle_stats;
 };
 
 /*
diff -u --recursive --new-file linux-2.0.38/include/linux/etherdevice.h linux-2.0.39/include/linux/etherdevice.h
--- linux-2.0.38/include/linux/etherdevice.h	Fri Apr 12 09:55:09 1996
+++ linux-2.0.39/include/linux/etherdevice.h	Wed Dec 29 12:42:01 1999
@@ -10,8 +10,8 @@
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
- *		Relocated to include/linux where it belongs by Alan Cox 
- *							<gw4pts@gw4pts.ampr.org>
+ *		Relocated to include/linux where it belongs by Alan Cox
+ *						<alan@lxorguk.ukuu.org.uk>
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
diff -u --recursive --new-file linux-2.0.38/include/linux/ext2_fs.h linux-2.0.39/include/linux/ext2_fs.h
--- linux-2.0.38/include/linux/ext2_fs.h	Thu Nov 13 05:45:40 1997
+++ linux-2.0.39/include/linux/ext2_fs.h	Fri Jan 21 16:17:50 2000
@@ -368,6 +368,15 @@
 	__u32	s_reserved[230];	/* Padding to the end of the block */
 };
 
+#ifdef __KERNEL__
+#define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
+#else
+/* Assume that user mode programs are passing in an ext2fs superblock, not
+ * a kernel struct super_block.  This will allow us to call the feature-test
+ * macros from user land. */
+#define EXT2_SB(sb)	(sb)
+#endif
+
 /*
  * Codes for operating systems
  */
@@ -407,6 +416,35 @@
 };
 
 /*
+ * The new version of the directory entry.  Since EXT2 structures are
+ * stored in intel byte order, and the name_len field could never be
+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
+ * file_type field.
+ */
+struct ext2_dir_entry_2 {
+	__u32	inode;			/* Inode number */
+	__u16	rec_len;		/* Directory entry length */
+	__u8	name_len;		/* Name length */
+	__u8	file_type;
+	char	name[EXT2_NAME_LEN];	/* File name */
+};
+
+/*
+ * Ext2 directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+#define EXT2_FT_UNKNOWN		0
+#define EXT2_FT_REG_FILE	1
+#define EXT2_FT_DIR		2
+#define EXT2_FT_CHRDEV		3
+#define EXT2_FT_BLKDEV 		4
+#define EXT2_FT_FIFO		5
+#define EXT2_FT_SOCK		6
+#define EXT2_FT_SYMLINK		7
+
+#define EXT2_FT_MAX		8
+
+/*
  * EXT2_DIR_PAD defines the directory entries boundaries
  *
  * NOTE: It must be a multiple of 4
@@ -417,11 +455,23 @@
 					 ~EXT2_DIR_ROUND)
 
 /*
- * Feature set definitions --- none are defined as of now
+ * Feature set definitions
  */
+
+#define EXT2_HAS_COMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_compat & (mask) )
+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_incompat & (mask) )
+
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
+
+#define EXT2_FEATURE_INCOMPAT_FILETYPE		0x0002
+
 #define EXT2_FEATURE_COMPAT_SUPP	0
-#define EXT2_FEATURE_INCOMPAT_SUPP	0
-#define EXT2_FEATURE_RO_COMPAT_SUPP	0
+#define EXT2_FEATURE_INCOMPAT_SUPP	EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_RO_COMPAT_SUPP	EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
 
 #ifdef __KERNEL__
 /*
@@ -440,6 +490,7 @@
 extern int ext2_permission (struct inode *, int);
 
 /* balloc.c */
+extern int ext2_group_sparse(int group);
 extern int ext2_new_block (const struct inode *, unsigned long,
 			   __u32 *, __u32 *, int *);
 extern void ext2_free_blocks (const struct inode *, unsigned long,
@@ -452,7 +503,7 @@
 
 /* dir.c */
 extern int ext2_check_dir_entry (const char *, struct inode *,
-				 struct ext2_dir_entry *, struct buffer_head *,
+				 struct ext2_dir_entry_2 *, struct buffer_head *,
 				 unsigned long);
 
 /* file.c */
diff -u --recursive --new-file linux-2.0.38/include/linux/ext2_fs_sb.h linux-2.0.39/include/linux/ext2_fs_sb.h
--- linux-2.0.38/include/linux/ext2_fs_sb.h	Thu Nov 13 05:45:40 1997
+++ linux-2.0.39/include/linux/ext2_fs_sb.h	Fri Jan 21 16:17:51 2000
@@ -60,6 +60,9 @@
 	int s_desc_per_block_bits;
 	int s_inode_size;
 	int s_first_ino;
+	int s_feature_compat;
+	int s_feature_incompat;
+	int s_feature_ro_compat;
 };
 
 #endif	/* _LINUX_EXT2_FS_SB */
diff -u --recursive --new-file linux-2.0.38/include/linux/fddidevice.h linux-2.0.39/include/linux/fddidevice.h
--- linux-2.0.38/include/linux/fddidevice.h	Wed Oct 30 02:42:41 1996
+++ linux-2.0.39/include/linux/fddidevice.h	Wed Dec 29 12:43:09 1999
@@ -12,7 +12,7 @@
  *		fddidevice.h is based on previous trdevice.h work by
  *			Ross Biro, <bir7@leland.Stanford.Edu>
  *			Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *			Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *			Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
diff -u --recursive --new-file linux-2.0.38/include/linux/major.h linux-2.0.39/include/linux/major.h
--- linux-2.0.38/include/linux/major.h	Sun Jun 13 19:21:04 1999
+++ linux-2.0.39/include/linux/major.h	Wed Jun 28 14:48:19 2000
@@ -68,6 +68,10 @@
 #define DAC960_MAJOR	48	/* 48..55 */
 #define RISCOM8_CALLOUT_MAJOR 49
 #define MKISS_MAJOR	55
+
+#define IDE4_MAJOR	56
+#define IDE5_MAJOR	57
+
 #define APBLOCK_MAJOR   60   /* AP1000 Block device */
 #define DDV_MAJOR       61   /* AP1000 DDV block device */
 
diff -u --recursive --new-file linux-2.0.38/include/linux/pci.h linux-2.0.39/include/linux/pci.h
--- linux-2.0.38/include/linux/pci.h	Sun Jun 13 19:21:04 1999
+++ linux-2.0.39/include/linux/pci.h	Wed Jun 28 14:48:20 2000
@@ -451,6 +451,7 @@
 
 #define PCI_VENDOR_ID_PROMISE		0x105a
 #define PCI_DEVICE_ID_PROMISE_20246	0x4d33
+#define PCI_DEVICE_ID_PROMISE_20262	0x4d38
 #define PCI_DEVICE_ID_PROMISE_5300	0x5300
 
 #define PCI_VENDOR_ID_N9		0x105d
@@ -558,7 +559,7 @@
 #define PCI_DEVICE_ID_DATABOOK_87144	0xb106
 
 #define PCI_VENDOR_ID_PLX		0x10b5
-#define PCI_DEVICE_ID_PLX_9050      0x9050
+#define PCI_DEVICE_ID_PLX_9050		0x9050
 #define PCI_DEVICE_ID_PLX_9080		0x9080
 
 #define PCI_DEVICE_ID_PLX_SPCOM200  0x1103
@@ -593,6 +594,8 @@
 #define PCI_DEVICE_ID_AL_M1523		0x1523
 #define PCI_DEVICE_ID_AL_M1531		0x1531
 #define PCI_DEVICE_ID_AL_M1533		0x1533
+#define PCI_DEVICE_ID_AL_M1541		0x1541
+#define PCI_DEVICE_ID_AL_M1543		0x1543
 #define PCI_DEVICE_ID_AL_M3307		0x3307
 #define PCI_DEVICE_ID_AL_M4803		0x5215
 #define PCI_DEVICE_ID_AL_M5219		0x5219
diff -u --recursive --new-file linux-2.0.38/include/linux/sched.h linux-2.0.39/include/linux/sched.h
--- linux-2.0.38/include/linux/sched.h	Tue Dec  2 23:18:11 1997
+++ linux-2.0.39/include/linux/sched.h	Tue Apr 25 16:16:37 2000
@@ -244,6 +244,8 @@
 	struct mm_struct *mm;
 /* signal handlers */
 	struct signal_struct *sig;
+/* privileged execution counters, for exit_signal permission checking */
+	int priv, ppriv;
 #ifdef __SMP__
 	int processor;
 	int last_processor;
@@ -309,6 +311,7 @@
 /* files */	&init_files, \
 /* mm */	&init_mm, \
 /* signals */	&init_signals, \
+/* priv */	0, 0, \
 }
 
 extern struct   mm_struct init_mm;
diff -u --recursive --new-file linux-2.0.38/include/linux/skbuff.h linux-2.0.39/include/linux/skbuff.h
--- linux-2.0.38/include/linux/skbuff.h	Sun Nov 15 19:33:18 1998
+++ linux-2.0.39/include/linux/skbuff.h	Wed Dec 29 12:41:06 1999
@@ -2,7 +2,7 @@
  *	Definitions for the 'struct sk_buff' memory handlers.
  *
  *	Authors:
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *		Florian La Roche, <rzsfl@rz.uni-sb.de>
  *
  *	This program is free software; you can redistribute it and/or
diff -u --recursive --new-file linux-2.0.38/include/linux/trdevice.h linux-2.0.39/include/linux/trdevice.h
--- linux-2.0.38/include/linux/trdevice.h	Sun Mar 24 12:33:25 1996
+++ linux-2.0.39/include/linux/trdevice.h	Wed Dec 29 12:42:41 1999
@@ -10,8 +10,8 @@
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
- *		Relocated to include/linux where it belongs by Alan Cox 
- *							<gw4pts@gw4pts.ampr.org>
+ *		Relocated to include/linux where it belongs by Alan Cox
+ *						<alan@lxorguk.ukuu.org.uk>
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
diff -u --recursive --new-file linux-2.0.38/include/net/ip.h linux-2.0.39/include/net/ip.h
--- linux-2.0.38/include/net/ip.h	Tue Dec  2 23:20:24 1997
+++ linux-2.0.39/include/net/ip.h	Wed Dec 29 12:43:26 1999
@@ -9,7 +9,7 @@
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
diff -u --recursive --new-file linux-2.0.38/include/net/ip_masq.h linux-2.0.39/include/net/ip_masq.h
--- linux-2.0.38/include/net/ip_masq.h	Sun Jun 13 19:21:04 1999
+++ linux-2.0.39/include/net/ip_masq.h	Tue Apr 25 15:01:47 2000
@@ -24,6 +24,8 @@
 #define PORT_MASQ_BEGIN	61000
 #define PORT_MASQ_END	(PORT_MASQ_BEGIN+4096)
 
+#define IP_MASQ_TAB_SIZE 256	/* MUST be a power of 2 */
+
 /*
  * Default timeouts for masquerade functions The control channels now
  * expire the same as TCP channels (other than being updated by
@@ -112,6 +114,18 @@
  */
 
 extern int ip_masq_free_ports[3];
+
+#ifdef CONFIG_IP_MASQUERADE_IPSEC
+/*
+ *	Any application support module that changes the destination
+ *	IP or port *must* rehash if IPsec masq is enabled
+ */
+extern struct ip_masq *ip_masq_m_tab[IP_MASQ_TAB_SIZE];
+extern struct ip_masq *ip_masq_s_tab[IP_MASQ_TAB_SIZE];
+extern struct ip_masq *ip_masq_d_tab[IP_MASQ_TAB_SIZE];
+extern __inline__ int ip_masq_hash(struct ip_masq *ms);
+extern __inline__ int ip_masq_unhash(struct ip_masq *ms);
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
 
 /*
  *	ip_masq initializer (registers symbols and /proc/net entries)
diff -u --recursive --new-file linux-2.0.38/include/net/snmp.h linux-2.0.39/include/net/snmp.h
--- linux-2.0.38/include/net/snmp.h	Tue Jun  6 10:22:18 1995
+++ linux-2.0.39/include/net/snmp.h	Wed Dec 29 12:44:15 1999
@@ -1,8 +1,8 @@
 /*
  *
  *		SNMP MIB entries for the IP subsystem.
- *		
- *		Alan Cox <gw4pts@gw4pts.ampr.org>
+ *
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *
  *		We don't chose to implement SNMP in the kernel (this would
  *		be silly as SNMP is a pain in the backside in places). We do
diff -u --recursive --new-file linux-2.0.38/init/main.c linux-2.0.39/init/main.c
--- linux-2.0.38/init/main.c	Sun Jun 13 19:21:04 1999
+++ linux-2.0.39/init/main.c	Wed Jun 28 14:48:20 2000
@@ -653,6 +653,10 @@
 		{ "hdf",     0x2140 },
 		{ "hdg",     0x2200 },
 		{ "hdh",     0x2240 },
+		{ "hdi",     0x3800 },
+		{ "hdj",     0x3840 },
+		{ "hdk",     0x3900 },
+		{ "hdl",     0x3940 },
 		{ "sda",     0x0800 },
 		{ "sdb",     0x0810 },
 		{ "sdc",     0x0820 },
diff -u --recursive --new-file linux-2.0.38/kernel/exit.c linux-2.0.39/kernel/exit.c
--- linux-2.0.38/kernel/exit.c	Thu Jun  4 00:17:50 1998
+++ linux-2.0.39/kernel/exit.c	Tue Apr 25 16:16:38 2000
@@ -118,7 +118,8 @@
 
 void notify_parent(struct task_struct * tsk, int signal)
 {
-	send_sig(signal, tsk->p_pptr, 1);
+	send_sig(signal, tsk->p_pptr, !signal || signal == SIGCHLD ||
+		tsk->p_pptr->priv == tsk->ppriv);
 	wake_up_interruptible(&tsk->p_pptr->wait_chldexit);
 }
 
diff -u --recursive --new-file linux-2.0.38/kernel/fork.c linux-2.0.39/kernel/fork.c
--- linux-2.0.38/kernel/fork.c	Thu Jun  4 00:17:50 1998
+++ linux-2.0.39/kernel/fork.c	Tue Apr 25 16:16:38 2000
@@ -228,10 +228,23 @@
 int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
 {
 	int nr;
-	int error = -ENOMEM;
+	int error = -EINVAL;
 	unsigned long new_stack;
 	struct task_struct *p;
 
+/*
+ * Disallow unknown clone(2) flags, as well as CLONE_PID, unless we are
+ * the boot up thread.
+ *
+ * Avoid taking any branches in the common case.
+ */
+	if (clone_flags &
+	    (-(signed long)current->pid >> (sizeof(long) * 8 - 1)) &
+	    ~(unsigned long)(CSIGNAL |
+	    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND))
+		goto bad_fork;
+
+	error = -ENOMEM;
 	p = (struct task_struct *) kmalloc(sizeof(*p), GFP_KERNEL);
 	if (!p)
 		goto bad_fork;
@@ -264,6 +277,8 @@
 	p->p_cptr = NULL;
 	init_waitqueue(&p->wait_chldexit);
 	p->signal = 0;
+	p->priv = 0;
+	p->ppriv = current->priv;
 	p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
 	p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
 	init_timer(&p->real_timer);
diff -u --recursive --new-file linux-2.0.38/net/802/fddi.c linux-2.0.39/net/802/fddi.c
--- linux-2.0.38/net/802/fddi.c	Wed Oct 30 03:36:35 1996
+++ linux-2.0.39/net/802/fddi.c	Wed Dec 29 12:44:41 1999
@@ -14,8 +14,8 @@
  *			Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *			Mark Evans, <evansmp@uhura.aston.ac.uk>
  *			Florian La Roche, <rzsfl@rz.uni-sb.de>
- *			Alan Cox, <gw4pts@gw4pts.ampr.org>
- * 
+ *			Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
  *		as published by the Free Software Foundation; either version
diff -u --recursive --new-file linux-2.0.38/net/Config.in linux-2.0.39/net/Config.in
--- linux-2.0.38/net/Config.in	Mon Jul 13 22:47:40 1998
+++ linux-2.0.39/net/Config.in	Thu Dec 30 18:30:09 1999
@@ -7,21 +7,21 @@
 bool 'Network aliasing'  CONFIG_NET_ALIAS
 bool 'TCP/IP networking' CONFIG_INET
 if [ "$CONFIG_INET" = "y" ]; then
-  source net/ipv4/Config.in
+   source net/ipv4/Config.in
 fi
 comment ' '
 tristate 'The IPX protocol' CONFIG_IPX
 tristate 'Appletalk DDP' CONFIG_ATALK
 tristate 'Amateur Radio AX.25 Level 2' CONFIG_AX25
 if [ "$CONFIG_AX25" != "n" ]; then
-  dep_tristate 'Amateur Radio NET/ROM' CONFIG_NETROM $CONFIG_AX25
-  dep_tristate 'Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25
+   dep_tristate '  Amateur Radio NET/ROM' CONFIG_NETROM $CONFIG_AX25
+   dep_tristate '  Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25
 fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE
+   bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE
 fi
 bool 'Kernel/User network link driver' CONFIG_NETLINK
 if [ "$CONFIG_NETLINK" = "y" ]; then
-  bool 'Routing messages' CONFIG_RTNETLINK
+   bool '  Routing messages' CONFIG_RTNETLINK
 fi
 endmenu
diff -u --recursive --new-file linux-2.0.38/net/core/dev.c linux-2.0.39/net/core/dev.c
--- linux-2.0.38/net/core/dev.c	Sun Nov 15 19:33:20 1998
+++ linux-2.0.39/net/core/dev.c	Wed Dec 29 12:47:23 1999
@@ -1,5 +1,5 @@
 /*
- * 	NET3	Protocol independent device support routines.
+ *	NET3	Protocol independent device support routines.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -7,40 +7,44 @@
  *		2 of the License, or (at your option) any later version.
  *
  *	Derived from the non IP parts of dev.c 1.0.19
- * 		Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
+ *		Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *				Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *				Mark Evans, <evansmp@uhura.aston.ac.uk>
  *
  *	Additional Authors:
  *		Florian la Roche <rzsfl@rz.uni-sb.de>
- *		Alan Cox <gw4pts@gw4pts.ampr.org>
+ *		Alan Cox <alan@lxorguk.ukuu.org.uk>
  *		David Hinds <dhinds@allegro.stanford.edu>
  *
  *	Changes:
  *		Alan Cox	:	device private ioctl copies fields back.
- *		Alan Cox	:	Transmit queue code does relevant stunts to
- *					keep the queue safe.
+ *		Alan Cox	:	Transmit queue code does relevant stunts
+ *					to keep the queue safe.
  *		Alan Cox	:	Fixed double lock.
  *		Alan Cox	:	Fixed promisc NULL pointer trap
  *		????????	:	Support the full private ioctl range
- *		Alan Cox	:	Moved ioctl permission check into drivers
+ *		Alan Cox	:	Moved ioctl permission check into
+ :					drivers
  *		Tim Kordas	:	SIOCADDMULTI/SIOCDELMULTI
  *		Alan Cox	:	100 backlog just doesn't cut it when
  *					you start doing multicast video 8)
  *		Alan Cox	:	Rewrote net_bh and list manager.
- *		Alan Cox	: 	Fix ETH_P_ALL echoback lengths.
+ *		Alan Cox	:	Fix ETH_P_ALL echoback lengths.
  *		Alan Cox	:	Took out transmit every packet pass
  *					Saved a few bytes in the ioctl handler
- *		Alan Cox	:	Network driver sets packet type before calling netif_rx. Saves
- *					a function call a packet.
+ *		Alan Cox	:	Network driver sets packet type before
+ *					calling netif_rx. Saves a function
+ *					call a packet.
  *		Alan Cox	:	Hashed net_bh()
  *		Richard Kooijman:	Timestamp fixes.
  *		Alan Cox	:	Wrong field in SIOCGIFDSTADDR
  *		Alan Cox	:	Device lock protection.
- *		Alan Cox	: 	Fixed nasty side effect of device close changes.
- *		Rudi Cilibrasi	:	Pass the right thing to set_mac_address()
- *		Dave Miller	:	32bit quantity for the device lock to make it work out
- *					on a Sparc.
+ *		Alan Cox	:	Fixed nasty side effect of device
+ *					close changes.
+ *		Rudi Cilibrasi	:	Pass the right thing to
+ *					set_mac_address()
+ *		Dave Miller	:	32bit quantity for the device lock
+ *					to make it work out on a Sparc.
  *		Bjorn Ekwall	:	Added KERNELD hack.
  *		Alan Cox	:	Cleaned up the backlog initialise.
  *		Craig Metz	:	SIOCGIFCONF fix if space for under
diff -u --recursive --new-file linux-2.0.38/net/ethernet/eth.c linux-2.0.39/net/ethernet/eth.c
--- linux-2.0.38/net/ethernet/eth.c	Thu Jun  4 00:17:50 1998
+++ linux-2.0.39/net/ethernet/eth.c	Wed Dec 29 12:48:26 1999
@@ -11,16 +11,17 @@
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *		Mark Evans, <evansmp@uhura.aston.ac.uk>
  *		Florian  La Roche, <rzsfl@rz.uni-sb.de>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
- * 
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ *
  * Fixes:
  *		Mr Linux	: Arp problems
  *		Alan Cox	: Generic queue tidyup (very tiny here)
  *		Alan Cox	: eth_header ntohs should be htons
  *		Alan Cox	: eth_rebuild_header missing an htons and
  *				  minor other things.
- *		Tegge		: Arp bug fixes. 
- *		Florian		: Removed many unnecessary functions, code cleanup
+ *		Tegge		: Arp bug fixes.
+ *		Florian		: Removed many unnecessary functions,
+ *				  code cleanup
  *				  and changes for new arp and skbuff.
  *		Alan Cox	: Redid header building to reflect new format.
  *		Alan Cox	: ARP only when compiled with CONFIG_INET
@@ -30,7 +31,8 @@
  *		Alan Cox	: Protect against forwarding explosions with
  *				  older network drivers and IFF_ALLMULTI.
  *	Christer Weinigel	: Better rebuild header message.
- *		Russell King	: eth_header_cache_bind and eth_header_cache_update
+ *		Russell King	: eth_header_cache_bind and
+ *				  eth_header_cache_update
  *				  only compiled if CONFIG_INET is selected
  *
  *		This program is free software; you can redistribute it and/or
diff -u --recursive --new-file linux-2.0.38/net/ipv4/Config.in linux-2.0.39/net/ipv4/Config.in
--- linux-2.0.38/net/ipv4/Config.in	Sun Jun 13 19:21:04 1999
+++ linux-2.0.39/net/ipv4/Config.in	Thu Dec 30 02:20:59 1999
@@ -1,67 +1,67 @@
 #
 # IP configuration
 #
-bool 'IP: forwarding/gatewaying' CONFIG_IP_FORWARD
-bool 'IP: multicasting' CONFIG_IP_MULTICAST
-bool 'IP: syn cookies' CONFIG_SYN_COOKIES
+bool '  IP: forwarding/gatewaying' CONFIG_IP_FORWARD
+bool '  IP: multicasting' CONFIG_IP_MULTICAST
+bool '  IP: syn cookies' CONFIG_SYN_COOKIES
 #if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-#  bool 'IP: rst cookies' CONFIG_RST_COOKIES
+#   bool '  IP: rst cookies (EXPERIMENTAL)' CONFIG_RST_COOKIES
 #fi
 if [ "$CONFIG_FIREWALL" = "y" ]; then
-  bool 'IP: firewalling' CONFIG_IP_FIREWALL
-  if [ "$CONFIG_IP_FIREWALL" = "y" ]; then
-    bool 'IP: firewall packet logging' CONFIG_IP_FIREWALL_VERBOSE
-      bool 'IP: masquerading' CONFIG_IP_MASQUERADE
+   bool '  IP: firewalling' CONFIG_IP_FIREWALL
+   if [ "$CONFIG_IP_FIREWALL" = "y" ]; then
+      bool '    IP: firewall packet logging' CONFIG_IP_FIREWALL_VERBOSE
+      bool '    IP: masquerading' CONFIG_IP_MASQUERADE
       if [ "$CONFIG_IP_MASQUERADE" != "n" ]; then
-        comment 'Protocol-specific masquerading support will be built as modules.'
-        if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then	
-          bool 'IP: ipautofw masquerading (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_IPAUTOFW
-          bool 'IP: MS PPTP masq support (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_PPTP
-          if [ "$CONFIG_IP_MASQUERADE_PPTP" = "y" ]; then	
-            bool 'IP: MS PPTP Call ID masq support (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_PPTP_MULTICLIENT
-            bool 'IP: MS PPTP masq debugging' DEBUG_IP_MASQUERADE_PPTP
-            if [ "$DEBUG_IP_MASQUERADE_PPTP" = "y" ]; then	
-              bool 'IP: MS PPTP masq verbose debugging' DEBUG_IP_MASQUERADE_PPTP_VERBOSE
-            fi
-          fi
-          bool 'IP: IPSEC ESP & ISAKMP masq support (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_IPSEC
-          if [ "$CONFIG_IP_MASQUERADE_IPSEC" = "y" ]; then	
-            int 'IP: IPSEC masq table lifetime (minutes)' CONFIG_IP_MASQUERADE_IPSEC_EXPIRE 30
-            bool 'IP: Disable inbound ESP destination guessing' CONFIG_IP_MASQUERADE_IPSEC_NOGUESS
-            bool 'IP: IPSEC masq debugging' DEBUG_IP_MASQUERADE_IPSEC
-            if [ "$DEBUG_IP_MASQUERADE_IPSEC" = "y" ]; then	
-              bool 'IP: IPSEC masq verbose debugging' DEBUG_IP_MASQUERADE_IPSEC_VERBOSE
-            fi
-          fi
-        fi
-        bool 'IP: ICMP masquerading' CONFIG_IP_MASQUERADE_ICMP
+	 comment 'Protocol-specific masquerading support will be built as modules.'
+	 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then	
+	    bool '      IP: ipautofw masquerading (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_IPAUTOFW
+	    bool '      IP: MS PPTP masq support (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_PPTP
+	    if [ "$CONFIG_IP_MASQUERADE_PPTP" = "y" ]; then	
+	       bool '        IP: MS PPTP Call ID masq support' CONFIG_IP_MASQUERADE_PPTP_MULTICLIENT
+	       bool '        IP: MS PPTP masq debugging' DEBUG_IP_MASQUERADE_PPTP
+	       if [ "$DEBUG_IP_MASQUERADE_PPTP" = "y" ]; then	
+		  bool '          IP: MS PPTP masq verbose debugging' DEBUG_IP_MASQUERADE_PPTP_VERBOSE
+	       fi
+	    fi
+	    bool '      IP: IPSEC ESP & ISAKMP masq support (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_IPSEC
+	    if [ "$CONFIG_IP_MASQUERADE_IPSEC" = "y" ]; then	
+	       int 'IP: IPSEC masq table lifetime (minutes)' CONFIG_IP_MASQUERADE_IPSEC_EXPIRE 30
+	       bool '        IP: Disable inbound ESP destination guessing' CONFIG_IP_MASQUERADE_IPSEC_NOGUESS
+	       bool '        IP: IPSEC masq debugging' DEBUG_IP_MASQUERADE_IPSEC
+	       if [ "$DEBUG_IP_MASQUERADE_IPSEC" = "y" ]; then	
+		  bool '        IP: IPSEC masq verbose debugging' DEBUG_IP_MASQUERADE_IPSEC_VERBOSE
+	       fi
+	    fi
+	 fi
+	 bool '      IP: ICMP masquerading' CONFIG_IP_MASQUERADE_ICMP
       fi
       if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then	
-        bool 'IP: transparent proxy support (EXPERIMENTAL)' CONFIG_IP_TRANSPARENT_PROXY
+	 bool '    IP: transparent proxy support (EXPERIMENTAL)' CONFIG_IP_TRANSPARENT_PROXY
       fi	
-     bool 'IP: always defragment' CONFIG_IP_ALWAYS_DEFRAG
-  fi
+      bool '    IP: always defragment' CONFIG_IP_ALWAYS_DEFRAG
+   fi
+fi
+bool '  IP: accounting' CONFIG_IP_ACCT
+bool '  IP: optimize as router not host' CONFIG_IP_ROUTER
+tristate '  IP: tunneling' CONFIG_NET_IPIP
+if [ "$CONFIG_IP_MULTICAST" = "y" ]; then
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool '  IP: multicast routing (EXPERIMENTAL)' CONFIG_IP_MROUTE
+   fi		
 fi
-bool 'IP: accounting' CONFIG_IP_ACCT
-  bool 'IP: optimize as router not host' CONFIG_IP_ROUTER
-  tristate 'IP: tunneling' CONFIG_NET_IPIP
-  if [ "$CONFIG_IP_MULTICAST" = "y" ]; then
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-        bool 'IP: multicast routing (EXPERIMENTAL)' CONFIG_IP_MROUTE
-      fi		
-  fi
 if [ "$CONFIG_NET_ALIAS" = "y" ]; then
-	tristate 'IP: aliasing support' CONFIG_IP_ALIAS
+   tristate '  IP: aliasing support' CONFIG_IP_ALIAS
 fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  if [ "$CONFIG_NETLINK" = "y" ]; then
-    bool 'IP: ARP daemon support (EXPERIMENTAL)' CONFIG_ARPD
-  fi
+   if [ "$CONFIG_NETLINK" = "y" ]; then
+      bool '  IP: ARP daemon support (EXPERIMENTAL)' CONFIG_ARPD
+   fi
 fi
 comment '(it is safe to leave these untouched)'
-bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP
-tristate 'IP: Reverse ARP' CONFIG_INET_RARP
-bool 'IP: Disable Path MTU Discovery (normally enabled)' CONFIG_NO_PATH_MTU_DISCOVERY
-#bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF
-bool 'IP: Drop source routed frames' CONFIG_IP_NOSR
-bool 'IP: Allow large windows (not recommended if <16Mb of memory)' CONFIG_SKB_LARGE
+bool '  IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP
+tristate '  IP: Reverse ARP' CONFIG_INET_RARP
+bool '  IP: Disable Path MTU Discovery (normally enabled)' CONFIG_NO_PATH_MTU_DISCOVERY
+#bool '  IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF
+bool '  IP: Drop source routed frames' CONFIG_IP_NOSR
+bool '  IP: Allow large windows (not recommended if <16Mb of memory)' CONFIG_SKB_LARGE
diff -u --recursive --new-file linux-2.0.38/net/ipv4/devinet.c linux-2.0.39/net/ipv4/devinet.c
--- linux-2.0.38/net/ipv4/devinet.c	Tue May  7 14:22:30 1996
+++ linux-2.0.39/net/ipv4/devinet.c	Wed Dec 29 12:48:56 1999
@@ -7,16 +7,16 @@
  *		2 of the License, or (at your option) any later version.
  *
  *	Derived from the IP parts of dev.c 1.0.19
- * 		Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
+ *		Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *				Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *				Mark Evans, <evansmp@uhura.aston.ac.uk>
  *
  *	Additional Authors:
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  */
 
 #include <linux/config.h>	/* For CONFIG_IP_CLASSLESS */
- 
+
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
diff -u --recursive --new-file linux-2.0.38/net/ipv4/ip_fw.c linux-2.0.39/net/ipv4/ip_fw.c
--- linux-2.0.38/net/ipv4/ip_fw.c	Tue Dec 29 20:55:12 1998
+++ linux-2.0.39/net/ipv4/ip_fw.c	Mon Dec 27 12:00:03 1999
@@ -505,7 +505,7 @@
 				printk(":%hu", dst_port);
 			printk(" L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu",
 				ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
-				ip->frag_off, ip->ttl);
+				ntohs(ip->frag_off), ip->ttl);
 			for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
 				printk(" O=0x%8.8X", *opt++);
 			printk("\n");
diff -u --recursive --new-file linux-2.0.38/net/ipv4/ip_masq.c linux-2.0.39/net/ipv4/ip_masq.c
--- linux-2.0.38/net/ipv4/ip_masq.c	Sun Jun 13 19:21:04 1999
+++ linux-2.0.39/net/ipv4/ip_masq.c	Tue Apr 25 15:12:46 2000
@@ -1,8 +1,8 @@
 /*
  *
- * 	Masquerading functionality
+ *	Masquerading functionality
  *
- * 	Copyright (c) 1994 Pauline Middelink
+ *	Copyright (c) 1994 Pauline Middelink
  *
  *	See ip_fw.c for original log
  *
@@ -20,8 +20,9 @@
  *	Delian Delchev		:	Added support for ICMP requests and replys
  *	Nigel Metheringham	:	ICMP in ICMP handling, tidy ups, bug fixes, made ICMP optional
  *	Juan Jose Ciarlante	:	re-assign maddr if no packet received from outside
- * 	John D. Hardin		:	Added PPTP and IPSEC protocols
- *	
+ *	John D. Hardin		:	Added PPTP and IPSEC protocols
+ *	Rudolf Lippan		:	dest hashing bugfix
+ *
  */
 
 #include <linux/config.h>
@@ -44,8 +45,6 @@
 #include <net/ip_masq.h>
 #include <linux/ip_fw.h>
 
-#define IP_MASQ_TAB_SIZE 256    /* must be power of 2 */
-
 #ifdef CONFIG_IP_MASQUERADE_PPTP
 /*
  * This is clumsier than it otherwise might be (i.e. the
@@ -301,6 +300,10 @@
         X(ip_masq_set_expire),
         X(ip_masq_free_ports),
 	X(ip_masq_expire),
+#ifdef CONFIG_IP_MASQUERADE_IPSEC
+	X(ip_masq_hash),
+	X(ip_masq_unhash),
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
 	X(ip_masq_out_get_2),
 #include <linux/symtab_end.h>
 };
@@ -445,7 +448,10 @@
  *	returns bool success.
  */
 
-static __inline__ int
+#ifndef CONFIG_IP_MASQUERADE_IPSEC
+static
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
+__inline__ int
 ip_masq_hash(struct ip_masq *ms)
 {
         unsigned hash;
@@ -495,7 +501,10 @@
  *	returns bool success.
  */
 
-static __inline__ int ip_masq_unhash(struct ip_masq *ms)
+#ifndef CONFIG_IP_MASQUERADE_IPSEC
+static
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
+__inline__ int ip_masq_unhash(struct ip_masq *ms)
 {
         unsigned hash;
         struct ip_masq ** ms_p;
@@ -3158,16 +3167,38 @@
                  */
 
                 if ( ms->flags & IP_MASQ_F_NO_DPORT && ms->protocol == IPPROTO_TCP ) {
+#ifdef CONFIG_IP_MASQUERADE_IPSEC
+			unsigned long flags;
+			save_flags(flags);
+			cli();
+			ip_masq_unhash(ms);
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
                         ms->flags &= ~IP_MASQ_F_NO_DPORT;
                         ms->dport = portptr[0];
+#ifdef CONFIG_IP_MASQUERADE_IPSEC
+			ip_masq_hash(ms);
+			restore_flags(flags);
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
+
 #ifdef DEBUG_CONFIG_IP_MASQUERADE
                         printk("ip_fw_demasquerade(): filled dport=%d\n",
                                ntohs(ms->dport));
 #endif
                 }
                 if (ms->flags & IP_MASQ_F_NO_DADDR && ms->protocol == IPPROTO_TCP)  {
+#ifdef CONFIG_IP_MASQUERADE_IPSEC
+			unsigned long flags;
+			save_flags(flags);
+			cli();
+			ip_masq_unhash(ms);
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
                         ms->flags &= ~IP_MASQ_F_NO_DADDR;
                         ms->daddr = iph->saddr;
+#ifdef CONFIG_IP_MASQUERADE_IPSEC
+			ip_masq_hash(ms);
+			restore_flags(flags);
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
+
 #ifdef DEBUG_CONFIG_IP_MASQUERADE
                         printk("ip_fw_demasquerade(): filled daddr=%X\n",
                                ntohs(ms->daddr));
diff -u --recursive --new-file linux-2.0.38/net/ipv4/ip_masq_quake.c linux-2.0.39/net/ipv4/ip_masq_quake.c
--- linux-2.0.38/net/ipv4/ip_masq_quake.c	Sun Nov 15 19:33:21 1998
+++ linux-2.0.39/net/ipv4/ip_masq_quake.c	Tue Apr 25 15:01:47 2000
@@ -85,6 +85,9 @@
 int
 masq_quake_in (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, struct device *dev)
 {
+#ifdef CONFIG_IP_MASQUERADE_IPSEC
+	unsigned long flags;
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
 	struct sk_buff *skb;
 	struct iphdr *iph;
 	struct udphdr *uh;
@@ -155,7 +158,16 @@
 
 	  memcpy(&udp_port, data, 2);
 
+#ifdef CONFIG_IP_MASQUERADE_IPSEC
+	  save_flags(flags);
+	  cli();
+	  ip_masq_unhash(ms);
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
 	  ms->dport = htons(udp_port);
+#ifdef CONFIG_IP_MASQUERADE_IPSEC
+	  ip_masq_hash(ms);
+	  restore_flags(flags);
+#endif /* CONFIG_IP_MASQUERADE_IPSEC */
 
 #if DEBUG_CONFIG_IP_MASQ_QUAKE
 	  printk("Quake_in: in_rewrote UDP port %d \n", udp_port);
diff -u --recursive --new-file linux-2.0.38/net/ipv4/ip_output.c linux-2.0.39/net/ipv4/ip_output.c
--- linux-2.0.38/net/ipv4/ip_output.c	Thu Jun  4 00:17:50 1998
+++ linux-2.0.39/net/ipv4/ip_output.c	Sat Jan 22 01:56:58 2000
@@ -8,9 +8,9 @@
  * Version:	@(#)ip.c	1.0.16b	9/1/93
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
- *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Donald Becker, <becker@super.org>
- *		Alan Cox, <Alan.Cox@linux.org>
+ *		Fred N. van Kempen, <waltje@linux.com>
+ *		Donald Becker, <becker@cesdis.gsfc.nasa.gov>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *		Richard Underwood
  *		Stefan Becker, <stefanb@yello.ping.de>
  *		Jorge Cwik, <jorge@laser.satlink.net>
@@ -19,17 +19,20 @@
  *	See ip_input.c for original log
  *
  *	Fixes:
- *		Alan Cox	:	Missing nonblock feature in ip_build_xmit.
- *		Mike Kilburn	:	htons() missing in ip_build_xmit.
- *		Bradford Johnson:	Fix faulty handling of some frames when 
- *					no route is found.
- *		Alexander Demenshin:	Missing sk/skb free in ip_queue_xmit
+ *			 Alan Cox:	Missing nonblock feature in
+ *					ip_build_xmit
+ *		     Mike Kilburn:	htons() missing in ip_build_xmit
+ *		 Bradford Johnson:	Fix faulty handling of some frames
+ *					when no route is found
+ *	      Alexander Demenshin:	Missing sk/skb free in ip_queue_xmit
  *					(in case if packet not accepted by
  *					output firewall rules)
- *              Elliot Poger    :       Added support for SO_BINDTODEVICE.
- *		Juan Jose Ciarlante:	sk/skb source address rewriting
- * 	Elena Apolinario Fdez de Sousa,:ipmr_forward never received multicast
- *	Juan-Mariano de Goyeneche	traffic generated locally.
+ *		     Elliot Poger:	Added support for SO_BINDTODEVICE
+ *	      Juan Jose Ciarlante:	sk/skb source address rewriting
+ * Elena Apolinario Fdez de Sousa
+ *    + Juan-Mariano de Goyeneche:	ipmr_forward never received multicast
+ *					traffic generated locally
+ *		 Andrea Arcangeli:	Fix for the 65468 bytes ping-exploit
  */
 
 #include <asm/segment.h>
@@ -703,7 +706,12 @@
 
 	if (!sk->ip_hdrincl) {
 		length += sizeof(struct iphdr);
-		if(opt) length += opt->optlen;
+		if (opt) {
+			/* make sure not to exceed maximum packet size */
+			if (0xffff - length < opt->optlen)
+				return -EMSGSIZE;
+			length += opt->optlen;
+		}
 	}
 
 	if(length <= dev->mtu && !MULTICAST(daddr) && daddr!=0xFFFFFFFF && daddr!=dev->pa_brdaddr)
diff -u --recursive --new-file linux-2.0.38/net/ipv4/ip_sockglue.c linux-2.0.39/net/ipv4/ip_sockglue.c
--- linux-2.0.38/net/ipv4/ip_sockglue.c	Sun Jun 13 19:21:04 1999
+++ linux-2.0.39/net/ipv4/ip_sockglue.c	Mon Dec 27 21:57:14 1999
@@ -98,11 +98,20 @@
 static struct device *ip_mc_find_devfor(unsigned long addr)
 {
 	struct device *dev;
-	for(dev = dev_base; dev; dev = dev->next)
-	{
-		if((dev->flags&IFF_UP)&&(dev->flags&IFF_MULTICAST)&&
-			(dev->pa_addr==addr))
-			return dev;
+	for(dev = dev_base; dev; dev = dev->next) {
+		if((dev->flags&IFF_UP)&&(dev->flags&IFF_MULTICAST)) {
+			if(dev->flags&IFF_POINTOPOINT) {
+				/* gated needs this so that Multicast works   */
+				/* PTP interfaces cant be identified uniquely */
+				/* by their protocol address as it can very   */
+				/* likely be the address of eth0!             */
+				if(dev->pa_dstaddr==addr)
+					return dev;
+			} else {
+				 if(dev->pa_addr==addr)
+					return dev;
+			}
+		}
 	}
 
 	return NULL;
diff -u --recursive --new-file linux-2.0.38/net/ipv4/packet.c linux-2.0.39/net/ipv4/packet.c
--- linux-2.0.38/net/ipv4/packet.c	Tue Aug 12 23:15:56 1997
+++ linux-2.0.39/net/ipv4/packet.c	Wed Dec 29 12:49:12 1999
@@ -12,7 +12,7 @@
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *
  * Fixes:	
  *		Alan Cox	:	verify_area() now used correctly
diff -u --recursive --new-file linux-2.0.38/net/ipv4/route.c linux-2.0.39/net/ipv4/route.c
--- linux-2.0.38/net/ipv4/route.c	Mon Jul 13 22:47:41 1998
+++ linux-2.0.39/net/ipv4/route.c	Wed Dec 29 12:31:33 1999
@@ -9,8 +9,8 @@
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
- *		Linus Torvalds, <Linus.Torvalds@helsinki.fi>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ *		Linus Torvalds, <torvalds@transmeta.com>
  *
  * Fixes:
  *		Alan Cox	:	Verify area fixes.
diff -u --recursive --new-file linux-2.0.38/net/ipv4/tcp.c linux-2.0.39/net/ipv4/tcp.c
--- linux-2.0.38/net/ipv4/tcp.c	Thu Aug 26 00:08:27 1999
+++ linux-2.0.39/net/ipv4/tcp.c	Wed Dec 29 12:33:34 1999
@@ -13,8 +13,8 @@
  *		Corey Minyard <wf-rch!minyard@relay.EU.net>
  *		Florian La Roche, <flla@stud.uni-sb.de>
  *		Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
- *		Linus Torvalds, <torvalds@cs.helsinki.fi>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *		Linus Torvalds, <torvalds@transmeta.com>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *		Matthew Dillon, <dillon@apollo.west.oic.com>
  *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
  *		Jorge Cwik, <jorge@laser.satlink.net>
diff -u --recursive --new-file linux-2.0.38/net/ipv4/tcp_input.c linux-2.0.39/net/ipv4/tcp_input.c
--- linux-2.0.38/net/ipv4/tcp_input.c	Thu Aug 26 00:08:27 1999
+++ linux-2.0.39/net/ipv4/tcp_input.c	Tue Apr 25 16:16:38 2000
@@ -13,8 +13,8 @@
  *		Corey Minyard <wf-rch!minyard@relay.EU.net>
  *		Florian La Roche, <flla@stud.uni-sb.de>
  *		Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
- *		Linus Torvalds, <torvalds@cs.helsinki.fi>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *		Linus Torvalds, <torvalds@transmeta.com>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *		Matthew Dillon, <dillon@apollo.west.oic.com>
  *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
  *		Jorge Cwik, <jorge@laser.satlink.net>
@@ -1186,6 +1186,15 @@
 	 *	then we can probably ignore it.
 	 */
 	 
+	if (sk->state == TCP_SYN_RECV) {
+		/*
+		 * Should be the exact sequence number for the handshake
+		 * to succeed, or sequence prediction gets a bit easier.
+		 * Also, "partially-established" connections are bad for
+		 * the rest of our code.
+		 */
+		if (ack != sk->sent_seq) goto uninteresting_ack;
+	} else
 	if (after(ack, sk->sent_seq) || before(ack, sk->rcv_ack_seq)) 
 		goto uninteresting_ack;
 
diff -u --recursive --new-file linux-2.0.38/net/ipv4/tcp_output.c linux-2.0.39/net/ipv4/tcp_output.c
--- linux-2.0.38/net/ipv4/tcp_output.c	Sun Nov 15 19:33:22 1998
+++ linux-2.0.39/net/ipv4/tcp_output.c	Wed Dec 29 12:34:57 1999
@@ -13,8 +13,8 @@
  *		Corey Minyard <wf-rch!minyard@relay.EU.net>
  *		Florian La Roche, <flla@stud.uni-sb.de>
  *		Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
- *		Linus Torvalds, <torvalds@cs.helsinki.fi>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *		Linus Torvalds, <torvalds@transmeta.com>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *		Matthew Dillon, <dillon@apollo.west.oic.com>
  *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
  *		Jorge Cwik, <jorge@laser.satlink.net>
diff -u --recursive --new-file linux-2.0.38/net/ipv4/tcp_timer.c linux-2.0.39/net/ipv4/tcp_timer.c
--- linux-2.0.38/net/ipv4/tcp_timer.c	Tue Aug 12 20:30:35 1997
+++ linux-2.0.39/net/ipv4/tcp_timer.c	Wed Dec 29 12:35:24 1999
@@ -13,8 +13,8 @@
  *		Corey Minyard <wf-rch!minyard@relay.EU.net>
  *		Florian La Roche, <flla@stud.uni-sb.de>
  *		Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
- *		Linus Torvalds, <torvalds@cs.helsinki.fi>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
+ *		Linus Torvalds, <torvalds@transmeta.com>
+ *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
  *		Matthew Dillon, <dillon@apollo.west.oic.com>
  *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
  *		Jorge Cwik, <jorge@laser.satlink.net>
diff -u --recursive --new-file linux-2.0.38/net/ipx/af_ipx.c linux-2.0.39/net/ipx/af_ipx.c
--- linux-2.0.38/net/ipx/af_ipx.c	Thu Jun  4 00:17:50 1998
+++ linux-2.0.39/net/ipx/af_ipx.c	Tue Feb  8 15:48:52 2000
@@ -2,7 +2,7 @@
  *	Implements an IPX socket layer (badly - but I'm working on it).
  *
  *	This code is derived from work by
- *		Ross Biro	: 	Writing the original IP stack
+ *		Ross Biro	:	Writing the original IP stack
  *		Fred Van Kempen :	Tidying up the TCP/IP
  *
  *	Many thanks go to Keith Baker, Institute For Industrial Information
@@ -11,38 +11,39 @@
  *	work I am currently employed to do there.
  *
  *	All the material in this file is subject to the Gnu license version 2.
- *	Neither Alan Cox nor the Swansea University Computer Society admit liability
- *	nor provide warranty for any of this software. This material is provided 
- *	as is and at no charge.		
+ *	Neither Alan Cox nor the Swansea University Computer Society admit
+ *	liability nor provide warranty for any of this software. This material
+ *	is provided as is and at no charge.
  *
- *	Revision 0.21:	Uses the new generic socket option code.
+ *	Revision 0.21:	Uses the new generic socket option code
  *	Revision 0.22:	Gcc clean ups and drop out device registration. Use the
- *			new multi-protocol edition of hard_header 
- *	Revision 0.23:  IPX /proc by Mark Evans.
- *     			Adding a route will overwrite any existing route to the same
- *			network.
+ *			new multi-protocol edition of hard_header
+ *	Revision 0.23:  IPX /proc by Mark Evans
+ *			Adding a route will overwrite any existing route to
+ *			the same network
  *	Revision 0.24:	Supports new /proc with no 4K limit
- *	Revision 0.25:	Add ephemeral sockets, passive local network 
+ *	Revision 0.25:	Add ephemeral sockets, passive local network
  *			identification, support for local net 0 and
  *			multiple datalinks <Greg Page>
- *	Revision 0.26:  Device drop kills IPX routes via it. (needed for modules)
+ *	Revision 0.26:  Device drop kills IPX routes via it (needed for modules)
  *	Revision 0.27:  Autobind <Mark Evans>
  *	Revision 0.28:  Small fix for multiple local networks <Thomas Winder>
  *	Revision 0.29:  Assorted major errors removed <Mark Evans>
  *			Small correction to promisc mode error fix <Alan Cox>
- *			Asynchronous I/O support.
- *			Changed to use notifiers and the newer packet_type stuff.
+ *			Asynchronous I/O support
+ *			Changed to use notifiers and the newer packet_type stuff
  *			Assorted major fixes <Alejandro Liu>
  *	Revision 0.30:	Moved to net/ipx/...	<Alan Cox>
- *			Don't set address length on recvfrom that errors.
- *			Incorrect verify_area.
- *	Revision 0.31:	New sk_buffs. This still needs a lot of testing. <Alan Cox>
+ *			Don't set address length on recvfrom that errors
+ *			Incorrect verify_area
+ *	Revision 0.31:	New sk_buffs. This still needs a lot of testing
+ *			<Alan Cox>
  *	Revision 0.32:  Using sock_alloc_send_skb, firewall hooks. <Alan Cox>
  *			Supports sendmsg/recvmsg
  *	Revision 0.33:	Internal network support, routing changes, uses a
- *			protocol private area for ipx data.
- *	Revision 0.34:	Module support. <Jim Freeman>
- *	Revision 0.35:  Checksum support. <Neil Turton>, hooked in by <Alan Cox>
+ *			protocol private area for ipx data
+ *	Revision 0.34:	Module support <Jim Freeman>
+ *	Revision 0.35:  Checksum support <Neil Turton>, hooked in by <Alan Cox>
  *			Handles WIN95 discovery packets <Volker Lendecke>
  *
  *	Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT
@@ -53,10 +54,10 @@
  *	Jacques Gelinas (jacques@solucorp.qc.ca)
  *
  *
- * 	Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
- *	Neither Greg Page nor Caldera, Inc. admit liability nor provide 
- *	warranty for any of this software. This material is provided 
- *	"AS-IS" and at no charge.		
+ *	Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
+ *	Neither Greg Page nor Caldera, Inc. admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
  */
 
 #include <linux/module.h>
@@ -106,7 +107,7 @@
 static struct datalink_proto	*p8023_datalink = NULL;
 static struct datalink_proto	*pSNAP_datalink = NULL;
 
-static ipx_route 	*ipx_routes = NULL;
+static ipx_route	*ipx_routes = NULL;
 static ipx_interface	*ipx_interfaces = NULL;
 static ipx_interface	*ipx_primary_net = NULL;
 static ipx_interface	*ipx_internal_net = NULL;
@@ -124,7 +125,7 @@
 	}
 	return 0;
 }
-		
+
 static int
 ipxcfg_set_auto_select(char val)
 {
@@ -138,7 +139,7 @@
 ipxcfg_get_config_data(ipx_config_data *arg)
 {
 	ipx_config_data	vals;
-	
+
 	vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces;
 	vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary;
 	memcpy_tofs(arg, &vals, sizeof(vals));
@@ -146,19 +147,19 @@
 }
 
 
-/***********************************************************************************************************************\
-*															*
-*						Handlers for the socket list.						*
-*															*
-\***********************************************************************************************************************/
+/***************************************************************************\
+*									    *
+*			Handlers for the socket list.			    *
+*									    *
+\***************************************************************************/
 
 /*
  *	Note: Sockets may not be removed _during_ an interrupt or inet_bh
  *	handler using this technique. They can be added although we do not
  *	use this facility.
  */
- 
-static void 
+
+static void
 ipx_remove_socket(ipx_socket *sk)
 {
 	ipx_socket	*s;
@@ -167,7 +168,7 @@
 
 	save_flags(flags);
 	cli();
-	
+
 	/* Determine interface with which socket is associated */
 	intrfc = sk->protinfo.af_ipx.intrfc;
 	if (intrfc == NULL) {
@@ -180,7 +181,7 @@
 		intrfc->if_sklist=s->next;
 		restore_flags(flags);
 		return;
-	} 
+	}
 
 	while(s && s->next) {
 		if(s->next==sk) {
@@ -199,8 +200,8 @@
  *	Once it is removed from the queue no interrupt or bottom half will
  *	touch it and we are (fairly 8-) ) safe.
  */
- 
-static void 
+
+static void
 ipx_destroy_socket(ipx_socket *sk)
 {
 	struct sk_buff	*skb;
@@ -209,11 +210,11 @@
 	while((skb=skb_dequeue(&sk->receive_queue))!=NULL) {
 		kfree_skb(skb,FREE_READ);
 	}
-	
+
 	sk_free(sk);
 	MOD_DEC_USE_COUNT;
 }
-	
+
 /* The following code is used to support IPX Interfaces (IPXITF).  An
  * IPX interface is defined by a physical device and a frame type.
  */
@@ -234,8 +235,8 @@
 {
 	ipx_interface	*i;
 
-	for (i=ipx_interfaces; 
-		i && ((i->if_dev!=dev) || (i->if_dlink_type!=datalink)); 
+	for (i=ipx_interfaces;
+		i && ((i->if_dev!=dev) || (i->if_dlink_type!=datalink));
 		i=i->if_next)
 		;
 	return i;
@@ -277,8 +278,8 @@
 {
 	ipx_socket	*s;
 
-	for (s=intrfc->if_sklist; 
-		(s != NULL) && (s->protinfo.af_ipx.port != port); 
+	for (s=intrfc->if_sklist;
+		(s != NULL) && (s->protinfo.af_ipx.port != port);
 		s=s->next)
 		;
 
@@ -303,7 +304,7 @@
 		s = s->next;
 	}
 	return s;
-}	
+}
 #endif
 
 static void ipxrtr_del_routes(ipx_interface *);
@@ -334,11 +335,11 @@
 	if (intrfc == ipx_interfaces) {
 		ipx_interfaces = intrfc->if_next;
 	} else {
-		for (i = ipx_interfaces; 
+		for (i = ipx_interfaces;
 			(i != NULL) && (i->if_next != intrfc);
 			i = i->if_next)
 			;
-		if ((i != NULL) && (i->if_next == intrfc)) 
+		if ((i != NULL) && (i->if_next == intrfc))
 			i->if_next = intrfc->if_next;
 	}
 
@@ -356,7 +357,7 @@
 	return;
 }
 
-static int 
+static int
 ipxitf_device_event(struct notifier_block *notifier, unsigned long event, void *ptr)
 {
 	struct device *dev = ptr;
@@ -366,9 +367,9 @@
 		return NOTIFY_DONE;
 
 	for (i = ipx_interfaces; i != NULL; ) {
-	
+
 		tmp = i->if_next;
-		if (i->if_dev == dev) 
+		if (i->if_dev == dev)
 			ipxitf_down(i);
 		i = tmp;
 
@@ -381,12 +382,12 @@
 {
 	int	retval;
 
-	if((retval = sock_queue_rcv_skb(sock, skb))<0) 
+	if((retval = sock_queue_rcv_skb(sock, skb))<0)
 	{
 		/*
 		 * skb->sk is NULL here, so FREE_WRITE does not hurt
 		 * the sending socket.
-	 	 */
+		 */
 		kfree_skb(skb,FREE_WRITE);
 	}
 	return retval;
@@ -398,7 +399,7 @@
 
 #ifdef CONFIG_IPX_INTERN
 static int
-ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) 
+ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy)
 {
 	ipx_packet	*ipx = (ipx_packet *)(skb->h.raw);
 	ipx_socket	*s;
@@ -462,16 +463,16 @@
 #else
 
 static int
-ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) 
+ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy)
 {
 	ipx_packet	*ipx = (ipx_packet *)(skb->h.raw);
 	ipx_socket	*sock1 = NULL, *sock2 = NULL;
 	struct sk_buff	*skb1 = NULL, *skb2 = NULL;
 
 	if (intrfc == ipx_primary_net
-	  && ntohs(ipx->ipx_dest.sock) == 0x451) 
+	  && ntohs(ipx->ipx_dest.sock) == 0x451)
 	{
-	  /* 
+	  /*
 	   * The packet's target is a NCP connection handler. We want to
 	   * hand it to the correct socket directly within the kernel,
 	   * so that the mars_nwe packet distribution process
@@ -484,25 +485,25 @@
 	  int connection = 0;
 
 	  if (    *((char*)(ipx+1))   == 0x22
-	      &&  *((char*)(ipx+1)+1) == 0x22) 
+	      &&  *((char*)(ipx+1)+1) == 0x22)
 	  {
-	  	/*
+		/*
 		 * The packet is a NCP request
 		 */
 		 connection = ( ((int) *((char*)(ipx+1)+5)) << 8 )
-		 	       | (int) *((char*)(ipx+1)+3);
-	  } 
+			       | (int) *((char*)(ipx+1)+3);
+	  }
 	  else if (    *((char*)(ipx+1))   == 0x77
-		   &&  *((char*)(ipx+1)+1) == 0x77) 
+		   &&  *((char*)(ipx+1)+1) == 0x77)
 	  {
 		/*
 		 * The packet is a BURST packet
 		 */
 		 connection = ( ((int) *((char*)(ipx+1)+9)) << 8 )
-		 	       | (int) *((char*)(ipx+1)+8);
+			       | (int) *((char*)(ipx+1)+8);
 	  }
 
-          if (connection) 
+          if (connection)
 	  {
 	    /*
 	     * Now we have to look for a special NCP connection handling
@@ -515,7 +516,7 @@
 		sock1=sock1->next);;
           }
         }
-        if (sock1 == NULL) 
+        if (sock1 == NULL)
 	{
 		/* No special socket found, forward the packet the
 		 * normal way.
@@ -530,21 +531,21 @@
 	 *	The *SPECIAL* socket list contains: 0x452(SAP), 0x453(RIP) and
 	 *	0x456(Diagnostic).
 	 */
-	 
-	if (ipx_primary_net && (intrfc != ipx_primary_net)) 
+
+	if (ipx_primary_net && (intrfc != ipx_primary_net))
 	{
-		switch (ntohs(ipx->ipx_dest.sock)) 
+		switch (ntohs(ipx->ipx_dest.sock))
 		{
 			case 0x452:
 			case 0x453:
 			case 0x456:
 				/*
 				 *	The appropriate thing to do here is to
-				 * 	dup the packet and route to the primary net
+				 *	dup the packet and route to the primary net
 				 *	interface via ipxitf_send; however, we'll cheat
 				 *	and just demux it here.
 				 */
-				sock2 = ipxitf_find_socket(ipx_primary_net, 
+				sock2 = ipxitf_find_socket(ipx_primary_net,
 					ipx->ipx_dest.sock);
 				break;
 			default:
@@ -552,57 +553,57 @@
 		}
 	}
 
-	/* 
+	/*
 	 *	if there is nothing to do, return. The kfree will
 	 *	cancel any charging.
 	 */
-	 
-	if (sock1 == NULL && sock2 == NULL) 
+
+	if (sock1 == NULL && sock2 == NULL)
 	{
-		if (!copy) 
+		if (!copy)
 			kfree_skb(skb,FREE_WRITE);
 		return 0;
 	}
 
 	/*
 	 * This next segment of code is a little awkward, but it sets it up
-	 * so that the appropriate number of copies of the SKB are made and 
-	 * that skb1 and skb2 point to it (them) so that it (they) can be 
+	 * so that the appropriate number of copies of the SKB are made and
+	 * that skb1 and skb2 point to it (them) so that it (they) can be
 	 * demuxed to sock1 and/or sock2.  If we are unable to make enough
 	 * copies, we do as much as is possible.
 	 */
-	 
-	if (copy) 
+
+	if (copy)
 	{
 		skb1 = skb_clone(skb, GFP_ATOMIC);
-		if (skb1 != NULL) 
+		if (skb1 != NULL)
 			skb1->arp = skb1->free = 1;
-	} 
-	else 
+	}
+	else
 	{
 		skb1 = skb;
 	}
-	
-	if (skb1 == NULL) 
-		return -ENOMEM; 
+
+	if (skb1 == NULL)
+		return -ENOMEM;
 
 	/*
-	 *	Do we need 2 SKBs? 
+	 *	Do we need 2 SKBs?
 	 */
-	 
-	if (sock1 && sock2) 
+
+	if (sock1 && sock2)
 	{
 		skb2 = skb_clone(skb1, GFP_ATOMIC);
-		if (skb2 != NULL) 
+		if (skb2 != NULL)
 			skb2->arp = skb2->free = 1;
 	}
-	else 
+	else
 		skb2 = skb1;
-		
+
 	if (sock1)
 		(void) ipxitf_def_skb_handler(sock1, skb1);
 
-	if (skb2 == NULL) 
+	if (skb2 == NULL)
 		return -ENOMEM;
 
 	if (sock2)
@@ -648,28 +649,28 @@
 	char		dest_node[IPX_NODE_LEN];
 	int		send_to_wire = 1;
 	int		addr_len;
-	
-	/* 
+
+	/*
 	 *	We need to know how many skbuffs it will take to send out this
 	 *	packet to avoid unnecessary copies.
 	 */
-	 
-	if ((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK)) 
+
+	if ((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK))
 		send_to_wire = 0;	/* No non looped */
 
 	/*
-	 *	See if this should be demuxed to sockets on this interface 
+	 *	See if this should be demuxed to sockets on this interface
 	 *
 	 *	We want to ensure the original was eaten or that we only use
 	 *	up clones.
 	 */
-	 
-	if (ipx->ipx_dest.net == intrfc->if_netnum) 
+
+	if (ipx->ipx_dest.net == intrfc->if_netnum)
 	{
 		/*
 		 *	To our own node, loop and free the original.
 		 */
-		if (memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0) 
+		if (memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0)
 		{
 			/*
 			 *	Don't charge sender
@@ -687,7 +688,7 @@
 		/*
 		 *	Broadcast, loop and possibly keep to send on.
 		 */
-		if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) 
+		if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
 		{
 			if (!send_to_wire && skb->sk)
 			{
@@ -695,30 +696,30 @@
 				skb->sk=NULL;
 			}
 			ipxitf_demux_socket(intrfc, skb, send_to_wire);
-			if (!send_to_wire) 
+			if (!send_to_wire)
 				return 0;
 		}
 	}
 
 	/*
-	 *	If the originating net is not equal to our net; this is routed 
+	 *	If the originating net is not equal to our net; this is routed
 	 *	We are still charging the sender. Which is right - the driver
 	 *	free will handle this fairly.
 	 */
-	 
-	if (ipx->ipx_source.net != intrfc->if_netnum) 
+
+	if (ipx->ipx_source.net != intrfc->if_netnum)
 	{
-		if (++(ipx->ipx_tctrl) > ipxcfg_max_hops) 
+		if (++(ipx->ipx_tctrl) > ipxcfg_max_hops)
 			send_to_wire = 0;
 	}
 
-	if (!send_to_wire) 
+	if (!send_to_wire)
 	{
 		/*
 		 *	We do a FREE_WRITE here because this indicates how
-		 *	to treat the socket with which the packet is 
-	 	 *	associated.  If this packet is associated with a
-		 *	socket at all, it must be the originator of the 
+		 *	to treat the socket with which the packet is
+		 *	associated.  If this packet is associated with a
+		 *	socket at all, it must be the originator of the
 		 *	packet.   Routed packets will have no socket associated
 		 *	with them.
 		 */
@@ -727,21 +728,21 @@
 	}
 
 	/*
-	 *	Determine the appropriate hardware address 
+	 *	Determine the appropriate hardware address
 	 */
-	 
+
 	addr_len = dev->addr_len;
-	if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) 
+	if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
 		memcpy(dest_node, dev->broadcast, addr_len);
 	else
 		memcpy(dest_node, &(node[IPX_NODE_LEN-addr_len]), addr_len);
 
 	/*
-	 *	Make any compensation for differing physical/data link size 
+	 *	Make any compensation for differing physical/data link size
 	 */
-	 
+
 	skb = ipxitf_adjust_skbuff(intrfc, skb);
-	if (skb == NULL) 
+	if (skb == NULL)
 		return 0;
 
 	/* set up data link and physical headers */
@@ -749,18 +750,18 @@
 	skb->protocol = htons(ETH_P_IPX);
 	dl->datalink_header(dl, skb, dest_node);
 #if 0
-	/* 
-	 *	Now log the packet just before transmission 
+	/*
+	 *	Now log the packet just before transmission
 	 */
-	 
+
 	dump_pkt("IPX snd:", (ipx_packet *)skb->h.raw);
 	dump_data("ETH hdr:", skb->data, skb->h.raw - skb->data);
 #endif
 
 	/*
-	 *	Send it out 
+	 *	Send it out
 	 */
-	 
+
 	dev_queue_xmit(skb, dev, SOPRI_NORMAL);
 	return 0;
 }
@@ -775,58 +776,74 @@
 static const char * ipx_frame_name(unsigned short);
 static const char * ipx_device_name(ipx_interface *);
 static int ipxrtr_route_skb(struct sk_buff *);
+static int ipxrtr_route_skb_type20(ipx_interface *intrfc, struct sk_buff *);
 
 static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb)
 {
 	ipx_packet	*ipx = (ipx_packet *) (skb->h.raw);
 	ipx_interface	*i;
 
-#ifdef CONFIG_FIREWALL	
+#ifdef CONFIG_FIREWALL
 	/*
 	 *	We firewall first, ask questions later.
 	 */
-	 
+
 	if (call_in_firewall(PF_IPX, skb->dev, ipx, NULL)!=FW_ACCEPT)
 	{
 		kfree_skb(skb, FREE_READ);
 		return 0;
 	}
-	
-#endif	
+
+#endif
 
 	/* See if we should update our network number */
-	if ((intrfc->if_netnum == 0L) && 
+	if ((intrfc->if_netnum == 0L) &&
 		(ipx->ipx_source.net == ipx->ipx_dest.net) &&
-		(ipx->ipx_source.net != 0L)) 
+		(ipx->ipx_source.net != 0L))
 	{
 		/* NB: NetWare servers lie about their hop count so we
 		 * dropped the test based on it.  This is the best way
 		 * to determine this is a 0 hop count packet.
 		 */
-		if ((i=ipxitf_find_using_net(ipx->ipx_source.net))==NULL) 
+		if ((i=ipxitf_find_using_net(ipx->ipx_source.net))==NULL)
 		{
 			intrfc->if_netnum = ipx->ipx_source.net;
 			(void) ipxitf_add_local_route(intrfc);
-		} 
-		else 
+		}
+		else
 		{
 			printk(KERN_WARNING "IPX: Network number collision %lx\n        %s %s and %s %s\n",
-				htonl(ipx->ipx_source.net), 
+				htonl(ipx->ipx_source.net),
 				ipx_device_name(i),
 				ipx_frame_name(i->if_dlink_type),
 				ipx_device_name(intrfc),
 				ipx_frame_name(intrfc->if_dlink_type));
 		}
 	}
+	/*
+	 * "This shouldn't happen, but just in case"
+	 */
+	if (ipx->ipx_tctrl > ipxcfg_max_hops)
+	{
+		kfree_skb(skb, FREE_READ);
+		return 0;
+	}
+
+	/*
+	 * Do the IPX Packet Type 20 routing
+	 */
+	if (ipx->ipx_type == IPX_TYPE_PPROP)
+		return ipxrtr_route_skb_type20(intrfc, skb);
+
 
 	if (ipx->ipx_dest.net == 0L)
 		ipx->ipx_dest.net = intrfc->if_netnum;
 	if (ipx->ipx_source.net == 0L)
 		ipx->ipx_source.net = intrfc->if_netnum;
 
-	if (intrfc->if_netnum != ipx->ipx_dest.net) 
+	if (intrfc->if_netnum != ipx->ipx_dest.net)
 	{
-#ifdef CONFIG_FIREWALL	
+#ifdef CONFIG_FIREWALL
 		/*
 		 *	See if we are allowed to firewall forward
 		 */
@@ -835,18 +852,18 @@
 			kfree_skb(skb, FREE_READ);
 			return 0;
 		}
-#endif		
+#endif
 		/* We only route point-to-point packets. */
 		if (skb->pkt_type == PACKET_HOST)
 			return ipxrtr_route_skb(skb);
-		
+
 		kfree_skb(skb,FREE_READ);
 		return 0;
 	}
 
 	/* see if we should keep it */
-	if ((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0) 
-		|| (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)) 
+	if ((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)
+		|| (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0))
 	{
 		return ipxitf_demux_socket(intrfc, skb, 0);
 	}
@@ -876,7 +893,7 @@
 	return;
 }
 
-static int 
+static int
 ipxitf_create_internal(ipx_interface_definition *idef)
 {
 	ipx_interface	*intrfc;
@@ -920,7 +937,7 @@
 	return 0;
 }
 
-static int 
+static int
 ipxitf_create(ipx_interface_definition *idef)
 {
 	struct device	*dev;
@@ -928,7 +945,7 @@
 	struct datalink_proto	*datalink = NULL;
 	ipx_interface	*intrfc;
 
-	if (idef->ipx_special == IPX_INTERNAL) 
+	if (idef->ipx_special == IPX_INTERNAL)
 		return ipxitf_create_internal(idef);
 
 	if ((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL))
@@ -939,7 +956,7 @@
 		return -EADDRINUSE;
 
 	switch (idef->ipx_dlink_type) {
-	case IPX_FRAME_ETHERII: 
+	case IPX_FRAME_ETHERII:
 		dlink_type = htons(ETH_P_IPX);
 		datalink = pEII_datalink;
 		break;
@@ -964,11 +981,11 @@
 		break;
 	}
 
-	if (datalink == NULL) 
+	if (datalink == NULL)
 		return -EPROTONOSUPPORT;
 
 	dev=dev_get(idef->ipx_device);
-	if (dev==NULL) 
+	if (dev==NULL)
 		return -ENODEV;
 
 	if (!(dev->flags & IFF_UP))
@@ -978,7 +995,7 @@
 	if(dev->addr_len>IPX_NODE_LEN)
 		return -EINVAL;
 
-	if ((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL) 
+	if ((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL)
 	{
 		/* Ok now create */
 		intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
@@ -991,14 +1008,14 @@
 		intrfc->if_sklist = NULL;
 		intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
 		/* Setup primary if necessary */
-		if ((idef->ipx_special == IPX_PRIMARY)) 
+		if ((idef->ipx_special == IPX_PRIMARY))
 			ipx_primary_net = intrfc;
 		intrfc->if_internal = 0;
 		intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length;
 		if(memcmp(idef->ipx_node, "\000\000\000\000\000\000", IPX_NODE_LEN)==0)
 		{
 			memset(intrfc->if_node, 0, IPX_NODE_LEN);
-			memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), 
+			memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]),
 				dev->dev_addr, dev->addr_len);
 		}
 		else
@@ -1007,13 +1024,13 @@
 	}
 
 	/* If the network number is known, add a route */
-	if (intrfc->if_netnum == 0L) 
+	if (intrfc->if_netnum == 0L)
 		return 0;
 
 	return ipxitf_add_local_route(intrfc);
 }
 
-static int 
+static int
 ipxitf_delete(ipx_interface_definition *idef)
 {
 	struct device	*dev = NULL;
@@ -1057,7 +1074,7 @@
 	case ETH_P_802_3: datalink = p8023_datalink; break;
 	default: return NULL;
 	}
-	
+
 	if (dev == NULL)
 		return NULL;
 
@@ -1073,10 +1090,10 @@
 		intrfc->if_sklist = NULL;
 		intrfc->if_internal = 0;
 		intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
-		intrfc->if_ipx_offset = dev->hard_header_len + 
+		intrfc->if_ipx_offset = dev->hard_header_len +
 			datalink->header_length;
 		memset(intrfc->if_node, 0, IPX_NODE_LEN);
-		memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), 
+		memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]),
 			dev->dev_addr, dev->addr_len);
 		ipxitf_insert(intrfc);
 	}
@@ -1084,7 +1101,7 @@
 	return intrfc;
 }
 
-static int 
+static int
 ipxitf_ioctl_real(unsigned int cmd, void *arg)
 {
 	int err;
@@ -1150,7 +1167,7 @@
 	}
 }
 
-static int 
+static int
 ipxitf_ioctl(unsigned int cmd, void *arg)
 {
 	int ret;
@@ -1159,11 +1176,11 @@
 	MOD_DEC_USE_COUNT;
 	return ret;
 }
-/*******************************************************************************************************************\
-*													            *
-*	            			Routing tables for the IPX socket layer				            *
-*														    *
-\*******************************************************************************************************************/
+/***************************************************************************\
+*								            *
+*		Routing tables for the IPX socket layer		            *
+*									    *
+\***************************************************************************/
 
 static ipx_route *
 ipxrtr_lookup(unsigned long net)
@@ -1220,7 +1237,7 @@
 	}
 }
 
-static int 
+static int
 ipxrtr_create(ipx_route_definition *rd)
 {
 	ipx_interface *intrfc;
@@ -1234,7 +1251,7 @@
 }
 
 
-static int 
+static int
 ipxrtr_delete(long net)
 {
 	ipx_route	**r;
@@ -1249,7 +1266,7 @@
 			*r = tmp->ir_next;
 			kfree_s(tmp, sizeof(ipx_route));
 			return 0;
-		} 
+		}
 		r = &(tmp->ir_next);
 	}
 
@@ -1259,13 +1276,13 @@
 /*
  *	Checksum routine for IPX
  */
- 
+
 /* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */
 
-static __u16 ipx_set_checksum(ipx_packet *packet,int length) 
+static __u16 ipx_set_checksum(ipx_packet *packet,int length)
 {
-	/* 
-	 *	NOTE: sum is a net byte order quantity, which optimizes the 
+	/*
+	 *	NOTE: sum is a net byte order quantity, which optimizes the
 	 *	loop. This only works on big and little endian machines. (I
 	 *	don't know of a machine that isn't.)
 	 */
@@ -1279,7 +1296,7 @@
 	__u16 *p=(__u16 *)&packet->ipx_pktsize;
 
 	/*
-	 *	Number of complete words 
+	 *	Number of complete words
 	 */
 
 	__u32 i=length>>1;
@@ -1288,14 +1305,14 @@
 	packet->ipx_tctrl = 0;     /* hop count excluded from checksum calc */
 
 	/*
-	 *	Loop through all complete words except the checksum field 
+	 *	Loop through all complete words except the checksum field
 	 */
 
 	while(--i)
 		sum+=*p++;
 
 	/*
-	 *	Add on the last part word if it exists 
+	 *	Add on the last part word if it exists
 	 */
 
 	if(packet->ipx_pktsize&htons(1))
@@ -1303,22 +1320,22 @@
 
 	packet->ipx_tctrl = hops;
 	/*
-	 *	Do final fixup 
+	 *	Do final fixup
 	 */
-	 
+
 	sum=(sum&0xffff)+(sum>>16);
 
 	/*
-	 *	It's a pity there's no concept of carry in C 
+	 *	It's a pity there's no concept of carry in C
 	 */
 
 	if(sum>=0x10000)
 		sum++;
-		
+
 	return ~sum;
 };
 
- 
+
 /*
  *	Route an outgoing frame from a socket.
  */
@@ -1332,14 +1349,14 @@
 	int ipx_offset;
 	ipx_route *rt = NULL;
 	int err;
-	
+
 	/* Find the appropriate interface on which to send packet */
-	if ((usipx->sipx_network == 0L) && (ipx_primary_net != NULL)) 
+	if ((usipx->sipx_network == 0L) && (ipx_primary_net != NULL))
 	{
 		usipx->sipx_network = ipx_primary_net->if_netnum;
 		intrfc = ipx_primary_net;
-	} 
-	else 
+	}
+	else
 	{
 		rt = ipxrtr_lookup(usipx->sipx_network);
 		if (rt==NULL) {
@@ -1347,7 +1364,7 @@
 		}
 		intrfc = rt->ir_intrfc;
 	}
-	
+
 	ipx_offset = intrfc->if_ipx_offset;
 	size=sizeof(ipx_packet)+len;
 	size += ipx_offset;
@@ -1372,7 +1389,7 @@
 #ifdef CONFIG_IPX_INTERN
 	memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.node, IPX_NODE_LEN);
 #else
-	if ((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452)  
+	if ((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452)
 	{
 		/* RIP/SAP special handling for mars_nwe */
 		ipx->ipx_source.net = intrfc->if_netnum;
@@ -1394,24 +1411,24 @@
 	/*
 	 *	Apply checksum. Not allowed on 802.3 links.
 	 */
-	 
+
 	if(sk->no_check || intrfc->if_dlink_type==IPX_FRAME_8023)
 		ipx->ipx_checksum=0xFFFF;
 	else
 		ipx->ipx_checksum=ipx_set_checksum(ipx, len+sizeof(ipx_packet));
 
-#ifdef CONFIG_FIREWALL	
+#ifdef CONFIG_FIREWALL
 	if(call_out_firewall(PF_IPX, skb->dev, ipx, NULL)!=FW_ACCEPT)
 	{
 		kfree_skb(skb, FREE_WRITE);
 		return -EPERM;
 	}
 #endif
-	
-	return ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? 
+
+	return ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ?
 				rt->ir_router_node : ipx->ipx_dest.node);
 }
-	
+
 static int
 ipxrtr_route_skb(struct sk_buff *skb)
 {
@@ -1426,11 +1443,56 @@
 		return 0;
 	}
 	i = r->ir_intrfc;
-	(void)ipxitf_send(i, skb, (r->ir_routed) ? 
+	(void)ipxitf_send(i, skb, (r->ir_routed) ?
 			r->ir_router_node : ipx->ipx_dest.node);
 	return 0;
 }
 
+static int
+ipxrtr_route_skb_type20(ipx_interface *intrfc, struct sk_buff *skb)
+{
+	ipx_packet *ipx = (ipx_packet *) (skb->h.raw);
+	unsigned long *net_num = (long *) (ipx + 1);
+	ipx_interface *ipx_if;
+	struct sk_buff *skb2;
+	int i;
+
+	if (ipx->ipx_tctrl > 8)
+	{
+		kfree_skb(skb, FREE_READ);
+		return 0;
+	}
+
+	for(i = 0; i < ipx->ipx_tctrl; ++i)
+	if(intrfc->if_netnum == net_num[i])
+	{
+		kfree_skb(skb, FREE_READ);
+		return 0;
+	}
+
+	net_num[i] = intrfc->if_netnum;
+	++ipx->ipx_tctrl;
+
+	for(ipx_if = ipx_interfaces; ipx_if != NULL; ipx_if = ipx_if->if_next)
+	{
+		for(i = 0; i < ipx->ipx_tctrl; ++i)
+		if(ipx_if->if_netnum == net_num[i])
+			break;
+
+		if(i != ipx->ipx_tctrl)
+			continue;
+
+		ipx->ipx_dest.net = ipx_if->if_netnum;
+
+		skb2 = skb_clone(skb, GFP_ATOMIC);
+		ipxrtr_route_skb(skb2);
+	}
+
+	kfree_skb(skb, FREE_READ);
+
+	return 0;
+}
+
 /*
  *	We use a normal struct rtentry for route handling
  */
@@ -1444,19 +1506,19 @@
 	err=verify_area(VERIFY_READ,arg,sizeof(rt));
 	if(err)
 		return err;
-		
+
 	memcpy_fromfs(&rt,arg,sizeof(rt));
-	
+
 	sg=(struct sockaddr_ipx *)&rt.rt_gateway;
 	st=(struct sockaddr_ipx *)&rt.rt_dst;
-	
+
 	if(!(rt.rt_flags&RTF_GATEWAY))
 		return -EINVAL;		/* Direct routes are fixed */
 	if(sg->sipx_family!=AF_IPX)
 		return -EINVAL;
 	if(st->sipx_family!=AF_IPX)
 		return -EINVAL;
-		
+
 	switch(cmd)
 	{
 		case SIOCDELRT:
@@ -1505,22 +1567,22 @@
 
 	/* Theory.. Keep printing in the same place until we pass offset */
 
-	len += sprintf (buffer,"%-11s%-15s%-9s%-11s%s\n", "Network", 
+	len += sprintf (buffer,"%-11s%-15s%-9s%-11s%s\n", "Network",
 		"Node_Address", "Primary", "Device", "Frame_Type");
 	for (i = ipx_interfaces; i != NULL; i = i->if_next) {
 		len += sprintf(buffer+len, "%08lX   ", ntohl(i->if_netnum));
-		len += sprintf (buffer+len,"%02X%02X%02X%02X%02X%02X   ", 
+		len += sprintf (buffer+len,"%02X%02X%02X%02X%02X%02X   ",
 				i->if_node[0], i->if_node[1], i->if_node[2],
 				i->if_node[3], i->if_node[4], i->if_node[5]);
 		len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ?
 			"Yes" : "No");
 		len += sprintf (buffer+len, "%-11s", ipx_device_name(i));
-		len += sprintf (buffer+len, "%s\n", 
+		len += sprintf (buffer+len, "%s\n",
 			ipx_frame_name(i->if_dlink_type));
 
 		/* Are we still dumping unwanted data then discard the record */
 		pos=begin+len;
-		
+
 		if(pos<offset) {
 			len=0;			/* Keep dumping into the buffer start */
 			begin=pos;
@@ -1528,13 +1590,13 @@
 		if(pos>offset+length)		/* We have dumped enough */
 			break;
 	}
-	
+
 	/* The data in question runs from begin to begin+len */
 	*start=buffer+(offset-begin);	/* Start of wanted data */
 	len-=(offset-begin);		/* Remove unwanted header data from length */
 	if(len>length)
 		len=length;		/* Remove unwanted tail data from length */
-	
+
 	return len;
 }
 
@@ -1549,28 +1611,28 @@
 
 	/* Theory.. Keep printing in the same place until we pass offset */
 
-#ifdef CONFIG_IPX_INTERN	
-	len += sprintf (buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address", 
+#ifdef CONFIG_IPX_INTERN
+	len += sprintf (buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
 #else
-	len += sprintf (buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address", 
+	len += sprintf (buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
 #endif
-			"Remote_Address", "Tx_Queue", "Rx_Queue", 
+			"Remote_Address", "Tx_Queue", "Rx_Queue",
 			"State", "Uid");
 	for (i = ipx_interfaces; i != NULL; i = i->if_next) {
 		for (s = i->if_sklist; s != NULL; s = s->next) {
 #ifdef CONFIG_IPX_INTERN
 			len += sprintf(buffer+len,
-				       "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ", 
+				       "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ",
 				 htonl(s->protinfo.af_ipx.intrfc->if_netnum),
 				       s->protinfo.af_ipx.node[0],
-				       s->protinfo.af_ipx.node[1], 
-				       s->protinfo.af_ipx.node[2], 
-				       s->protinfo.af_ipx.node[3], 
-				       s->protinfo.af_ipx.node[4], 
+				       s->protinfo.af_ipx.node[1],
+				       s->protinfo.af_ipx.node[2],
+				       s->protinfo.af_ipx.node[3],
+				       s->protinfo.af_ipx.node[4],
 				       s->protinfo.af_ipx.node[5],
 				       htons(s->protinfo.af_ipx.port));
 #else
-			len += sprintf(buffer+len,"%08lX:%04X  ", 
+			len += sprintf(buffer+len,"%08lX:%04X  ",
 				       htonl(i->if_netnum),
 				       htons(s->protinfo.af_ipx.port));
 #endif
@@ -1578,40 +1640,40 @@
 				len += sprintf(buffer+len, "%-28s", "Not_Connected");
 			} else {
 				len += sprintf (buffer+len,
-					"%08lX:%02X%02X%02X%02X%02X%02X:%04X  ", 
+					"%08lX:%02X%02X%02X%02X%02X%02X:%04X  ",
 					htonl(s->protinfo.af_ipx.dest_addr.net),
 					s->protinfo.af_ipx.dest_addr.node[0],
-					s->protinfo.af_ipx.dest_addr.node[1], 
+					s->protinfo.af_ipx.dest_addr.node[1],
 					s->protinfo.af_ipx.dest_addr.node[2],
-					s->protinfo.af_ipx.dest_addr.node[3], 
+					s->protinfo.af_ipx.dest_addr.node[3],
 					s->protinfo.af_ipx.dest_addr.node[4],
 					s->protinfo.af_ipx.dest_addr.node[5],
 					htons(s->protinfo.af_ipx.dest_addr.sock));
 			}
-			len += sprintf (buffer+len,"%08X  %08X  ", 
+			len += sprintf (buffer+len,"%08X  %08X  ",
 				s->wmem_alloc, s->rmem_alloc);
-			len += sprintf (buffer+len,"%02X     %03d\n", 
+			len += sprintf (buffer+len,"%02X     %03d\n",
 				s->state, SOCK_INODE(s->socket)->i_uid);
-		
+
 			/* Are we still dumping unwanted data then discard the record */
 			pos=begin+len;
-		
+
 			if(pos<offset)
 			{
-				len=0;			/* Keep dumping into the buffer start */
+				len=0;	/* Keep dumping into the buffer start */
 				begin=pos;
 			}
-			if(pos>offset+length)		/* We have dumped enough */
+			if(pos>offset+length)	/* We have dumped enough */
 				break;
 		}
 	}
-	
+
 	/* The data in question runs from begin to begin+len */
 	*start=buffer+(offset-begin);	/* Start of wanted data */
 	len-=(offset-begin);		/* Remove unwanted header data from length */
 	if(len>length)
 		len=length;		/* Remove unwanted tail data from length */
-	
+
 	return len;
 }
 
@@ -1623,16 +1685,16 @@
 	off_t pos=0;
 	off_t begin=0;
 
-	len += sprintf (buffer,"%-11s%-13s%s\n", 
+	len += sprintf (buffer,"%-11s%-13s%s\n",
 			"Network", "Router_Net", "Router_Node");
 	for (rt = ipx_routes; rt != NULL; rt = rt->ir_next)
 	{
 		len += sprintf (buffer+len,"%08lX   ", ntohl(rt->ir_net));
 		if (rt->ir_routed) {
-			len += sprintf (buffer+len,"%08lX     %02X%02X%02X%02X%02X%02X\n", 
-				ntohl(rt->ir_intrfc->if_netnum), 
-				rt->ir_router_node[0], rt->ir_router_node[1], 
-				rt->ir_router_node[2], rt->ir_router_node[3], 
+			len += sprintf (buffer+len,"%08lX     %02X%02X%02X%02X%02X%02X\n",
+				ntohl(rt->ir_intrfc->if_netnum),
+				rt->ir_router_node[0], rt->ir_router_node[1],
+				rt->ir_router_node[2], rt->ir_router_node[3],
 				rt->ir_router_node[4], rt->ir_router_node[5]);
 		} else {
 			len += sprintf (buffer+len, "%-13s%s\n",
@@ -1654,11 +1716,12 @@
 	return len;
 }
 
-/*******************************************************************************************************************\
-*													            *
-*	      Handling for system calls applied via the various interfaces to an IPX socket object		    *
-*														    *
-\*******************************************************************************************************************/
+/***************************************************************************\
+*								            *
+*	Handling for system calls applied via the various interfaces	    *
+*	to an IPX socket object						    *
+*									    *
+\***************************************************************************/
 
 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
@@ -1673,9 +1736,9 @@
 {
 	ipx_socket *sk;
 	int err,opt;
-	
+
 	sk=(ipx_socket *)sock->data;
-	
+
 	if(optval==NULL)
 		return(-EINVAL);
 
@@ -1683,7 +1746,7 @@
 	if(err)
 		return err;
 	opt=get_fs_long((unsigned long *)optval);
-	
+
 	switch(level)
 	{
 		case SOL_IPX:
@@ -1696,7 +1759,7 @@
 					return -EOPNOTSUPP;
 			}
 			break;
-			
+
 		case SOL_SOCKET:
 			return sock_setsockopt(sk,level,optname,optval,optlen);
 
@@ -1711,7 +1774,7 @@
 	ipx_socket *sk;
 	int val=0;
 	int err;
-	
+
 	sk=(ipx_socket *)sock->data;
 
 	switch(level)
@@ -1727,10 +1790,10 @@
 					return -ENOPROTOOPT;
 			}
 			break;
-			
+
 		case SOL_SOCKET:
 			return sock_getsockopt(sk,level,optname,optval,optlen);
-			
+
 		default:
 			return -EOPNOTSUPP;
 	}
@@ -1790,13 +1853,13 @@
 	sk->socket=sock;
 	sk->type=sock->type;
 	sk->mtu=IPX_MTU;
-	sk->no_check = 1;		/* Checksum off by default */	
+	sk->no_check = 1;		/* Checksum off by default */
 	if(sock!=NULL)
 	{
 		sock->data=(void *)sk;
 		sk->sleep=sock->wait;
 	}
-	
+
 	sk->state_change=def_callback1;
 	sk->data_ready=def_callback2;
 	sk->write_space=def_callback1;
@@ -1825,7 +1888,7 @@
 	return(ipx_create(newsock,SOCK_DGRAM));
 }
 
-static unsigned short 
+static unsigned short
 ipx_first_free_socketnum(ipx_interface *intrfc)
 {
 	unsigned short	socketNum = intrfc->if_sknum;
@@ -1842,21 +1905,21 @@
 	intrfc->if_sknum = socketNum;
 	return	ntohs(socketNum);
 }
-	
+
 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
 {
 	ipx_socket *sk;
 	ipx_interface *intrfc;
 	struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr;
-	
+
 	sk=(ipx_socket *)sock->data;
-	
+
 	if(sk->zapped==0)
 		return -EIO;
-		
+
 	if(addr_len!=sizeof(struct sockaddr_ipx))
 		return -EINVAL;
-	
+
 	intrfc = ipxitf_find_using_net(addr->sipx_network);
 	if (intrfc == NULL)
 		return -EADDRNOTAVAIL;
@@ -1894,8 +1957,8 @@
 		{
 			memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, IPX_NODE_LEN);
 		}
-		if (ipxitf_find_internal_socket(intrfc, 
-			sk->protinfo.af_ipx.node, 
+		if (ipxitf_find_internal_socket(intrfc,
+			sk->protinfo.af_ipx.node,
 			sk->protinfo.af_ipx.port) != NULL)
 		{
 			if(sk->debug)
@@ -1911,14 +1974,14 @@
 		 * with the ipx routing ioctl()
 		 */
 
-		memcpy(sk->protinfo.af_ipx.node, intrfc->if_node, 
+		memcpy(sk->protinfo.af_ipx.node, intrfc->if_node,
 			IPX_NODE_LEN);
-		
+
 		if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
 			if(sk->debug)
 				printk("IPX: bind failed because port %X in"
 				       " use.\n", (int)addr->sipx_port);
-			return -EADDRINUSE;	   
+			return -EADDRINUSE;
 		}
 	}
 
@@ -1931,7 +1994,7 @@
 		if(sk->debug)
 			printk("IPX: bind failed because port %X in use.\n",
 				(int)addr->sipx_port);
-		return -EADDRINUSE;	   
+		return -EADDRINUSE;
 	}
 
 #endif
@@ -1948,20 +2011,20 @@
 {
 	ipx_socket *sk=(ipx_socket *)sock->data;
 	struct sockaddr_ipx *addr;
-	
-	sk->state = TCP_CLOSE;	
+
+	sk->state = TCP_CLOSE;
 	sock->state = SS_UNCONNECTED;
 
 	if(addr_len!=sizeof(*addr))
 		return(-EINVAL);
 	addr=(struct sockaddr_ipx *)uaddr;
-	
+
 	if(sk->protinfo.af_ipx.port==0)
 	/* put the autobinding in */
 	{
 		struct sockaddr_ipx uaddr;
 		int ret;
-	
+
 		uaddr.sipx_port = 0;
 		uaddr.sipx_network = 0L;
 #ifdef CONFIG_IPX_INTERN
@@ -1972,7 +2035,7 @@
 				sizeof(struct sockaddr_ipx));
 		if (ret != 0) return (ret);
 	}
-	
+
 	if(ipxrtr_lookup(addr->sipx_network)==NULL)
 		return -ENETUNREACH;
 	sk->protinfo.af_ipx.dest_addr.net=addr->sipx_network;
@@ -2005,11 +2068,11 @@
 	ipx_address *addr;
 	struct sockaddr_ipx sipx;
 	ipx_socket *sk;
-	
+
 	sk=(ipx_socket *)sock->data;
-	
+
 	*uaddr_len = sizeof(struct sockaddr_ipx);
-		
+
 	if(peer) {
 		if(sk->state!=TCP_ESTABLISHED)
 			return -ENOTCONN;
@@ -2023,7 +2086,7 @@
 #ifdef CONFIG_IPX_INTERN
 			memcpy(sipx.sipx_node, sk->protinfo.af_ipx.node, IPX_NODE_LEN);
 #else
-			memcpy(sipx.sipx_node, 
+			memcpy(sipx.sipx_node,
 				sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN);
 #endif
 
@@ -2033,7 +2096,7 @@
 		}
 		sipx.sipx_port = sk->protinfo.af_ipx.port;
 	}
-		
+
 	sipx.sipx_family = AF_IPX;
 	sipx.sipx_type = sk->protinfo.af_ipx.type;
 	memcpy(uaddr,&sipx,sizeof(sipx));
@@ -2102,18 +2165,18 @@
 	/* NULL here for pt means the packet was looped back */
 	ipx_interface	*intrfc;
 	ipx_packet *ipx;
-	
-	
+
+
 	ipx=(ipx_packet *)skb->h.raw;
-	
+
 	/* Too small */
-	
+
 	if(ntohs(ipx->ipx_pktsize)<sizeof(ipx_packet)) {
 		kfree_skb(skb,FREE_READ);
 		return 0;
 	}
-	
-	if(ipx->ipx_checksum!=IPX_NO_CHECKSUM) 
+
+	if(ipx->ipx_checksum!=IPX_NO_CHECKSUM)
 	{
 		if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize))!=ipx->ipx_checksum)
 		{
@@ -2121,13 +2184,13 @@
 			return 0;
 		}
 	}
-	
+
 	/* Determine what local ipx endpoint this is */
 	intrfc = ipxitf_find_using_phys(dev, pt->type);
-	if (intrfc == NULL) 
+	if (intrfc == NULL)
 	{
 		if (ipxcfg_auto_create_interfaces &&
-		    ntohl(ipx->ipx_dest.net)!=0L) 
+		    ntohl(ipx->ipx_dest.net)!=0L)
 		{
 			intrfc = ipxitf_auto_create(dev, pt->type);
 		}
@@ -2150,20 +2213,20 @@
 	struct sockaddr_ipx local_sipx;
 	int retval;
 
-	if (sk->zapped) 
+	if (sk->zapped)
 		return -EIO; /* Socket not bound */
-	if(flags) 
+	if(flags)
 		return -EINVAL;
-		
-	if(usipx) 
+
+	if(usipx)
 	{
-		if(sk->protinfo.af_ipx.port == 0) 
+		if(sk->protinfo.af_ipx.port == 0)
 		{
 			struct sockaddr_ipx uaddr;
 			int ret;
 
 			uaddr.sipx_port = 0;
-			uaddr.sipx_network = 0L; 
+			uaddr.sipx_network = 0L;
 #ifdef CONFIG_IPX_INTERN
 			memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc
 				->if_node, IPX_NODE_LEN);
@@ -2178,7 +2241,7 @@
 		if(usipx->sipx_family != AF_IPX)
 			return -EINVAL;
 	}
-	else 
+	else
 	{
 		if(sk->state!=TCP_ESTABLISHED)
 			return -ENOTCONN;
@@ -2189,9 +2252,9 @@
 		usipx->sipx_network=sk->protinfo.af_ipx.dest_addr.net;
 		memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN);
 	}
-	
+
 	retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, noblock);
-	if (retval < 0) 
+	if (retval < 0)
 		return retval;
 
 	return len;
@@ -2208,10 +2271,10 @@
 	int truesize;
 	struct sk_buff *skb;
 	int er;
-	
+
 	if(sk->err)
 		return sock_error(sk);
-	
+
 	if (sk->zapped)
 		return -EIO;
 
@@ -2219,7 +2282,7 @@
 	skb=skb_recv_datagram(sk,flags,noblock,&er);
 	if(skb==NULL)
 		return er;
-	
+
 	if(addr_len)
 		*addr_len=sizeof(*sipx);
 
@@ -2227,7 +2290,7 @@
 	truesize=ntohs(ipx->ipx_pktsize) - sizeof(ipx_packet);
 	copied = (truesize > size) ? size : truesize;
 	skb_copy_datagram_iovec(skb,sizeof(struct ipx_packet),msg->msg_iov,copied);
-	
+
 	if(sipx)
 	{
 		sipx->sipx_family=AF_IPX;
@@ -2238,7 +2301,7 @@
 	}
 	skb_free_datagram(sk, skb);
 	return(truesize);
-}		
+}
 
 static int ipx_shutdown(struct socket *sk,int how)
 {
@@ -2248,7 +2311,7 @@
 static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
 {
 	ipx_socket *sk=(ipx_socket *)sock->data;
-	
+
 	return datagram_select(sk,sel_type,wait);
 }
 
@@ -2257,7 +2320,7 @@
 	int err;
 	long amount=0;
 	ipx_socket *sk=(ipx_socket *)sock->data;
-	
+
 	switch(cmd)
 	{
 		case TIOCOUTQ:
@@ -2293,7 +2356,7 @@
 				return -EPERM;
 		case SIOCGIFADDR:
 			return(ipxitf_ioctl(cmd,(void *)arg));
-		case SIOCIPXCFGDATA: 
+		case SIOCIPXCFGDATA:
 		{
 			err=verify_area(VERIFY_WRITE,(void *)arg,
 				sizeof(ipx_config_data));
@@ -2343,7 +2406,6 @@
 
 static struct proto_ops ipx_proto_ops = {
 	AF_IPX,
-	
 	ipx_create,
 	ipx_dup,
 	ipx_release,
@@ -2365,7 +2427,7 @@
 
 /* Called by protocol.c on kernel start up */
 
-static struct packet_type ipx_8023_packet_type = 
+static struct packet_type ipx_8023_packet_type =
 
 {
 	0,	/* MUTTER ntohs(ETH_P_8023),*/
@@ -2375,7 +2437,7 @@
 	NULL,
 };
 
-static struct packet_type ipx_dix_packet_type = 
+static struct packet_type ipx_dix_packet_type =
 {
 	0,	/* MUTTER ntohs(ETH_P_IPX),*/
 	NULL,		/* All devices */
@@ -2426,23 +2488,23 @@
 	p8023_datalink = make_8023_client();
 	ipx_8023_packet_type.type=htons(ETH_P_802_3);
 	dev_add_pack(&ipx_8023_packet_type);
-	
+
 	if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL)
 		printk(KERN_CRIT "IPX: Unable to register with 802.2\n");
 
 	if ((p8022tr_datalink = register_8022tr_client(ipx_8022_type, ipx_rcv)) == NULL)
 		printk(KERN_CRIT "IPX: Unable to register with 802.2TR\n");
- 
+
 	if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL)
 		printk(KERN_CRIT "IPX: Unable to register with SNAP\n");
-	
+
 	register_netdevice_notifier(&ipx_dev_notifier);
 #ifdef CONFIG_PROC_FS
 	proc_net_register(&ipx_procinfo);
 	proc_net_register(&ipx_if_procinfo);
 	proc_net_register(&ipx_rt_procinfo);
-#endif	
-		
+#endif
+
 	printk(KERN_INFO "Swansea University Computer Society IPX 0.34 for NET3.035\n");
 	printk(KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
 }
@@ -2452,13 +2514,13 @@
  *
  * Use counts are incremented/decremented when
  * sockets are created/deleted.
- * 
+ *
  * Routes are always associated with an interface, and
  * allocs/frees will remain properly accounted for by
  * their associated interfaces.
- * 
+ *
  * Ergo, before the ipx module can be removed, all IPX
- * sockets be closed from user space. 
+ * sockets be closed from user space.
  */
 
 static void
@@ -2476,7 +2538,7 @@
 	proc_net_unregister(PROC_NET_IPX_ROUTE);
 	proc_net_unregister(PROC_NET_IPX_INTERFACE);
 	proc_net_unregister(PROC_NET_IPX);
-#endif	
+#endif
 
 	unregister_netdevice_notifier(&ipx_dev_notifier);
 
diff -u --recursive --new-file linux-2.0.38/net/unix/af_unix.c linux-2.0.39/net/unix/af_unix.c
--- linux-2.0.38/net/unix/af_unix.c	Thu Jun  4 00:17:50 1998
+++ linux-2.0.39/net/unix/af_unix.c	Mon Jul 24 09:59:39 2000
@@ -29,20 +29,29 @@
  *		Alan Cox	:	Started proper garbage collector
  *		Heiko EiBfeldt	:	Missing verify_area check
  *		Alan Cox	:	Shutdown() bug
+ *	Michael Deutschmann	:	release was writing to the socket
+ *					structure after  freeing it.
  *
  * Known differences from reference BSD that was tested:
  *
  *	[TO FIX]
- *	ECONNREFUSED is not returned from one end of a connected() socket to the
- *		other the moment one end closes.
- *	fstat() doesn't return st_dev=NODEV, and give the blksize as high water mark
- *		and a fake inode identifier (nor the BSD first socket fstat twice bug).
+ *	ECONNREFUSED is not returned from one end of a connected() socket
+ *	to the other the moment one end closes.
+ *
+ *	fstat() doesn't return st_dev=NODEV, and give the blksize as
+ *	high water mark and a fake inode identifier (nor the BSD first socket
+ *	fstat twice bug).
+ *
  *	[NOT TO FIX]
  *	accept() returns a path name even if the connecting socket has closed
- *		in the meantime (BSD loses the path and gives up).
- *	accept() returns 0 length path for an unbound connector. BSD returns 16
- *		and a null first byte in the path (but not for gethost/peername - BSD bug ??)
+ *	in the meantime (BSD loses the path and gives up).
+ *
+ *	accept() returns 0 length path for an unbound connector. BSD returns
+ *	16 and a null first byte in the path (but not for gethost/peername
+ *	- BSD bug ??)
+ *
  *	socketpair(...SOCK_RAW..) doesn't panic the kernel.
+ *
  *	BSD af_unix apparently has connect forgetting to block properly.
  */
 
@@ -79,7 +88,7 @@
 /*
  *	Make sure the unix name is null-terminated.
  */
- 
+
 static inline void unix_mkname(struct sockaddr_un * sunaddr, unsigned long len)
 {
 	if (len >= sizeof(*sunaddr))
@@ -92,11 +101,11 @@
  *	handler using this technique. They can be added although we do not
  *	use this facility.
  */
- 
+
 static void unix_remove_socket(unix_socket *sk)
 {
 	unix_socket **s;
-	
+
 	cli();
 	s=&unix_socket_list;
 
@@ -153,16 +162,16 @@
 		sk_free(sk);
 		return;
 	}
-	
+
 	/*
 	 *	Retry;
 	 */
-	 
+
 	sk->timer.expires=jiffies+10*HZ;	/* No real hurry try it every 10 seconds or so */
 	add_timer(&sk->timer);
 }
-	 
-	 
+
+
 static void unix_delayed_delete(unix_socket *sk)
 {
 	sk->timer.data=(unsigned long)sk;
@@ -170,13 +179,15 @@
 	sk->timer.function=unix_destroy_timer;
 	add_timer(&sk->timer);
 }
-	
+
 static void unix_destroy_socket(unix_socket *sk)
 {
 	struct sk_buff *skb;
 
 	unix_remove_socket(sk);
-	
+
+	sk->socket = NULL;
+
 	while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
 	{
 		if(sk->state==TCP_LISTEN)
@@ -185,7 +196,7 @@
 			osk->state=TCP_CLOSE;
 			kfree_skb(skb, FREE_WRITE);	/* Now surplus - free the skb first before the socket */
 			osk->state_change(osk);		/* So the connect wakes and cleans up (if any) */
-			/* osk will be destroyed when it gets to close or the timer fires */			
+			/* osk will be destroyed when it gets to close or the timer fires */
 		}
 		else
 		{
@@ -193,13 +204,13 @@
 			kfree_skb(skb,FREE_WRITE);
 		}
 	}
-	
+
 	if(sk->protinfo.af_unix.inode!=NULL)
 	{
 		iput(sk->protinfo.af_unix.inode);
 		sk->protinfo.af_unix.inode=NULL;
 	}
-	
+
 	if(--sk->protinfo.af_unix.locks==0 && sk->wmem_alloc==0)
 	{
 		if(sk->protinfo.af_unix.name)
@@ -216,7 +227,7 @@
 /*
  *	Fixme: We need async I/O on AF_UNIX doing next.
  */
- 
+
 static int unix_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	return -EINVAL;
@@ -225,13 +236,13 @@
 /*
  *	Yes socket options work with the new unix domain socketry!!!!!!!
  */
- 
+
 static int unix_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
 {
 	unix_socket *sk=sock->data;
 	if(level!=SOL_SOCKET)
 		return -EOPNOTSUPP;
-	return sock_setsockopt(sk,level,optname,optval,optlen);	
+	return sock_setsockopt(sk,level,optname,optval,optlen);
 }
 
 static int unix_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
@@ -337,12 +348,12 @@
 {
 	unix_socket *sk=sock->data;
 	unix_socket *skpair;
-	
+
 	/* May not have data attached */
-	
+
 	if(sk==NULL)
 		return 0;
-		
+
 	sk->state_change(sk);
 	sk->dead=1;
 	skpair=(unix_socket *)sk->protinfo.af_unix.other;	/* Person we send to (default) */
@@ -355,16 +366,16 @@
 		skpair->protinfo.af_unix.locks--;	/* It may now die */
 	sk->protinfo.af_unix.other=NULL;		/* No pair */
 	unix_destroy_socket(sk);			/* Try to flush out this socket. Throw out buffers at least */
-	unix_gc();					/* Garbage collect fds */	
+	unix_gc();					/* Garbage collect fds */
 
 	/*
-	 *	FIXME: BSD difference: In BSD all sockets connected to use get ECONNRESET and we die on the spot. In
-	 *	Linux we behave like files and pipes do and wait for the last dereference.
+	 * FIXME: BSD difference: In BSD all sockets connected to use get
+	 * ECONNRESET and we die on the spot. In Linux we behave like files
+	 * and pipes do and wait for the last dereference.
 	 */
-	 
+
 	sock->data = NULL;
-	sk->socket = NULL;
-	
+
 	return 0;
 }
 
@@ -375,7 +386,7 @@
 	int err;
 	struct inode *inode;
 	unix_socket *u;
-	
+
 	old_fs=get_fs();
 	set_fs(get_ds());
 	err = open_namei(path, 2, S_IFSOCK, &inode, NULL);
@@ -402,10 +413,10 @@
 	unix_socket *sk=sock->data;
 	int old_fs;
 	int err;
-	
+
 	if(sk->protinfo.af_unix.name)
 		return -EINVAL;		/* Already bound */
-	
+
 	if(addr_len>sizeof(struct sockaddr_un) || addr_len<3 || sunaddr->sun_family!=AF_UNIX)
 		return -EINVAL;
 	unix_mkname(sunaddr, addr_len);
@@ -414,21 +425,21 @@
 	 */
 	if(sk->protinfo.af_unix.inode!=NULL)
 		return -EINVAL;
-	
+
 	sk->protinfo.af_unix.name=kmalloc(addr_len+1, GFP_KERNEL);
 	if(sk->protinfo.af_unix.name==NULL)
 		return -ENOMEM;
 	memcpy(sk->protinfo.af_unix.name, sunaddr->sun_path, addr_len+1);
-	
+
 	old_fs=get_fs();
 	set_fs(get_ds());
-	
+
 	err=do_mknod(sk->protinfo.af_unix.name,S_IFSOCK|S_IRWXUGO,0);
 	if(err==0)
 		err=open_namei(sk->protinfo.af_unix.name, 2, S_IFSOCK, &sk->protinfo.af_unix.inode, NULL);
-	
+
 	set_fs(old_fs);
-	
+
 	if(err<0)
 	{
 		kfree_s(sk->protinfo.af_unix.name,addr_len+1);
@@ -438,9 +449,9 @@
 		else
 			return err;
 	}
-	
+
 	return 0;
-	
+
 }
 
 static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
@@ -471,12 +482,12 @@
 		 *	Drop through the connect up logic to the wait.
 		 */
 	}
-	
+
 	if(addr_len < sizeof(sunaddr->sun_family)+1 || sunaddr->sun_family!=AF_UNIX)
 		return -EINVAL;
-		
+
 	unix_mkname(sunaddr, addr_len);
-		
+
 	if(sk->type==SOCK_DGRAM)
 	{
 		if(sk->protinfo.af_unix.other)
@@ -496,14 +507,14 @@
 		sk->state=TCP_ESTABLISHED;
 		return 0;			/* Done */
 	}
-	
+
 
 	if(sock->state==SS_UNCONNECTED)
 	{
 		/*
 		 *	Now ready to connect
 		 */
-	 
+
 		skb=sock_alloc_send_skb(sk, 0, 0, 0, &err); /* Marker object */
 		if(skb==NULL)
 			return err;
@@ -530,12 +541,12 @@
 		sk->state=TCP_SYN_SENT;
 		sock->state=SS_CONNECTING;
 		sti();
-		other->data_ready(other,0);		/* Wake up ! */		
+		other->data_ready(other,0);		/* Wake up ! */
 	}
-			
-	
+
+
 	/* Wait for an accept */
-	
+
 	cli();
 	while(sk->state==TCP_SYN_SENT)
 	{
@@ -551,11 +562,11 @@
 			return -ERESTARTSYS;
 		}
 	}
-	
+
 	/*
 	 *	Has the other end closed on us ?
 	 */
-	 
+
 	if(sk->state==TCP_CLOSE)
 	{
 		sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
@@ -564,21 +575,21 @@
 		sti();
 		return -ECONNREFUSED;
 	}
-	
+
 	/*
 	 *	Amazingly it has worked
 	 */
-	 
+
 	sock->state=SS_CONNECTED;
 	sti();
 	return 0;
-	
+
 }
 
 static int unix_socketpair(struct socket *a, struct socket *b)
 {
-	unix_socket *ska,*skb;	
-	
+	unix_socket *ska,*skb;
+
 	ska=a->data;
 	skb=b->data;
 
@@ -597,7 +608,7 @@
 	unix_socket *sk=sock->data;
 	unix_socket *newsk, *tsk;
 	struct sk_buff *skb;
-	
+
 	if(sk->type!=SOCK_STREAM)
 	{
 		return -EOPNOTSUPP;
@@ -606,7 +617,7 @@
 	{
 		return -EINVAL;
 	}
-		
+
 	newsk=newsock->data;
 	if(sk->protinfo.af_unix.name!=NULL)
 	{
@@ -615,7 +626,7 @@
 			return -ENOMEM;
 		strcpy(newsk->protinfo.af_unix.name, sk->protinfo.af_unix.name);
 	}
-		
+
 	do
 	{
 		cli();
@@ -657,7 +668,7 @@
 {
 	unix_socket *sk=sock->data;
 	struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
-	
+
 	if(peer)
 	{
 		if(sk->protinfo.af_unix.other==NULL)
@@ -679,7 +690,7 @@
 /*
  *	Support routines for struct cmsghdr handling
  */
- 
+
 static struct cmsghdr *unix_copyrights(void *userp, int len) /* AT&T ? */
 {
 	struct cmsghdr *cm;
@@ -694,7 +705,7 @@
 /*
  *	Return a header block
  */
- 
+
 static void unix_returnrights(void *userp, int len, struct cmsghdr *cm)
 {
 	memcpy_tofs(userp, cm, len);
@@ -705,7 +716,7 @@
  *	Copy file descriptors into system space.
  *	Return number copied or negative error code
  */
- 
+
 static int unix_fd_copy(struct sock *sk, struct cmsghdr *cmsg, struct file **fp)
 {
 	int num=cmsg->cmsg_len-sizeof(struct cmsghdr);
@@ -715,22 +726,22 @@
 	num /= sizeof(int);	/* Odd bytes are forgotten in BSD not errored */
 	if (num >= UNIX_MAX_FD)
 		return -EINVAL;
-	
+
 	/*
 	 *	Verify the descriptors.
 	 */
-	 
+
 	for(i=0; i< num; i++)
 	{
 		int fd;
-		
-		fd = fdp[i];	
+
+		fd = fdp[i];
 		if (fd < 0 || fd >= NR_OPEN)
 			return -EBADF;
 		if (current->files->fd[fd]==NULL)
 			return -EBADF;
 	}
-	
+
         /* add another reference to these files */
 	for(i=0; i< num; i++)
 	{
@@ -738,7 +749,7 @@
 		fp[i]->f_count++;
 		unix_inflight(fp[i]);
 	}
-	
+
 	return num;
 }
 
@@ -778,7 +789,7 @@
 		cmnum = (cmsg->cmsg_len-sizeof(struct cmsghdr)) / sizeof(int);
 		cmfptr = (int *)&cmsg->cmsg_data;
 	}
-	
+
 	fdnum = *(int *)skb->h.filp;
 	fp = (struct file **)(skb->h.filp+sizeof(long));
 
@@ -816,7 +827,7 @@
 {
 	unix_detach_fds(skb,NULL);
 }
-	
+
 /*
  *	Attach the file descriptor array to an sk_buff
  */
@@ -835,7 +846,7 @@
 /*
  *	Send AF_UNIX data.
  */
-		
+
 static int unix_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
 {
 	unix_socket *sk=sock->data;
@@ -856,17 +867,17 @@
 
 	if(flags&MSG_OOB)
 		return -EOPNOTSUPP;
-			
+
 	if(flags)	/* For now */ {
 		return -EINVAL;
 	}
-		
+
 	if(sk->shutdown&SEND_SHUTDOWN)
 	{
 		send_sig(SIGPIPE,current,0);
 		return -EPIPE;
 	}
-	
+
 	if(sunaddr!=NULL)
 	{
 		if(sock->type==SOCK_STREAM)
@@ -887,9 +898,9 @@
 	/*
 	 *	A control message has been attached.
 	 */
-	if(msg->msg_control) 
+	if(msg->msg_control)
 	{
-		struct cmsghdr *cm=unix_copyrights(msg->msg_control, 
+		struct cmsghdr *cm=unix_copyrights(msg->msg_control,
 						msg->msg_controllen);
 		if(cm==NULL || msg->msg_controllen<sizeof(struct cmsghdr) ||
 		   cm->cmsg_type!=SCM_RIGHTS ||
@@ -897,7 +908,7 @@
 		   msg->msg_controllen!=cm->cmsg_len)
 		{
 			kfree(cm);
-		   	return -EINVAL;
+			return -EINVAL;
 		}
 		fpnum=unix_fd_copy(sk,cm,fp);
 		kfree(cm);
@@ -909,10 +920,10 @@
 	while(sent < len)
 	{
 		/*
-		 *	Optimisation for the fact that under 0.01% of X messages typically
-		 *	need breaking up.
+		 * Optimisation for the fact that under 0.01% of X messages
+		 * typically need breaking up.
 		 */
-		 
+
 		size=len-sent;
 
 		if(size>(sk->sndbuf-sizeof(struct sk_buff))/2)	/* Keep two messages in the pipe so it schedules better */
@@ -938,9 +949,9 @@
 		/*
 		 *	Grab a buffer
 		 */
-		 
+
 		skb=sock_alloc_send_skb(sk,size,limit,nonblock, &err);
-		
+
 		if(skb==NULL)
 		{
 			unix_fd_free(sk,fp,fpnum);
@@ -955,7 +966,7 @@
 
 		skb->sk=sk;
 		skb->free=1;
-		
+
 		if(fpnum)
 		{
 			unix_attach_fds(fpnum,fp,skb);
@@ -1026,7 +1037,7 @@
 /*
  *	Sleep until data has arrive. But check for races..
  */
- 
+
 static void unix_data_wait(unix_socket * sk)
 {
 	cli();
@@ -1053,19 +1064,19 @@
 
 	if(flags&MSG_OOB)
 		return -EOPNOTSUPP;
-		
+
 	if(addr_len)
 		*addr_len=0;
-		
+
 	if(sk->err)
 		return sock_error(sk);
 
-	if(msg->msg_control) 
+	if(msg->msg_control)
 	{
-		cm=unix_copyrights(msg->msg_control, 
+		cm=unix_copyrights(msg->msg_control,
 			msg->msg_controllen);
 		if(msg->msg_controllen<sizeof(struct cmsghdr)
-#if 0 
+#if 0
 /*		investigate this further -- Stevens example doesn't seem to care */
 		||
 		   cm->cmsg_type!=SCM_RIGHTS ||
@@ -1076,10 +1087,10 @@
 		{
 			kfree(cm);
 /*			printk("recvmsg: Bad msg_control\n");*/
-		   	return -EINVAL;
+			return -EINVAL;
 		}
 	}
-	
+
 	down(&sk->protinfo.af_unix.readsem);		/* Lock the socket */
 	while(ct--)
 	{
@@ -1087,7 +1098,7 @@
 		sp=iov->iov_base;
 		len=iov->iov_len;
 		iov++;
-		
+
 		while(done<len)
 		{
 			if (copied && (flags & MSG_PEEK))
@@ -1156,9 +1167,9 @@
 {
 	unix_socket *sk=(unix_socket *)sock->data;
 	unix_socket *other=sk->protinfo.af_unix.other;
-	
+
 	mode++;
-	
+
 	if(mode&SEND_SHUTDOWN)
 	{
 		sk->shutdown|=SEND_SHUTDOWN;
@@ -1183,7 +1194,7 @@
 	return 0;
 }
 
-		
+
 static int unix_select(struct socket *sock,  int sel_type, select_table *wait)
 {
 	return datagram_select(sock->data,sel_type,wait);
@@ -1194,10 +1205,10 @@
 	unix_socket *sk=sock->data;
 	int err;
 	long amount=0;
-			
+
 	switch(cmd)
 	{
-	
+
 		case TIOCOUTQ:
 			err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
 			if(err)
@@ -1236,10 +1247,10 @@
 	off_t begin=0;
 	int len=0;
 	unix_socket *s=unix_socket_list;
-	
+
 	len+= sprintf(buffer,"Num       RefCount Protocol Flags    Type St "
 	    "Inode Path\n");
-	
+
 	while(s!=NULL)
 	{
 		len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X %5ld",
@@ -1254,7 +1265,7 @@
 			len+=sprintf(buffer+len, " %s\n", s->protinfo.af_unix.name);
 		else
 			buffer[len++]='\n';
-		
+
 		pos=begin+len;
 		if(pos<offset)
 		{
@@ -1275,7 +1286,7 @@
 
 struct proto_ops unix_proto_ops = {
 	AF_UNIX,
-	
+
 	unix_create,
 	unix_dup,
 	unix_release,
Binary files linux-2.0.38/scripts/lxdialog/.nfs0019ebd000000016 and linux-2.0.39/scripts/lxdialog/.nfs0019ebd000000016 differ
