## Automatically generated incremental diff
## From:   linux-2.4.17-pre4
## To:     linux-2.4.17-pre5
## Robot:  $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $

diff -urN linux-2.4.17-pre4/CREDITS linux/CREDITS
--- linux-2.4.17-pre4/CREDITS	Thu Dec  6 10:52:25 2001
+++ linux/CREDITS	Thu Dec  6 10:53:03 2001
@@ -2512,7 +2512,7 @@
 S: Australia
 
 N: Gerard Roudier
-E: groudier@iplus.fr
+E: groudier@free.fr
 D: Contributed to asynchronous read-ahead improvement
 S: 21 Rue Carnot
 S: 95170 Deuil La Barre
diff -urN linux-2.4.17-pre4/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.4.17-pre4/Documentation/Configure.help	Thu Dec  6 10:52:25 2001
+++ linux/Documentation/Configure.help	Thu Dec  6 10:53:03 2001
@@ -2,10 +2,10 @@
 #	Eric S. Raymond <mailto:esr@thyrsus.com>
 #	Steven Cole <mailto:elenstev@mesatop.com>
 #
-# Merged version 2.49: Current with 2.4.15-pre1 and 2.4.13-ac8.
+# Merged version 2.66: current with 2.4.17-pre2/2.5.1-pre5.
 #
 # This version of the Linux kernel configuration help texts
-# corresponds to the kernel versions 2.4.x.
+# corresponds to kernel versions 2.4.x and 2.5.x.
 #
 # Translations of this file available on the WWW:
 #
@@ -14,11 +14,13 @@
 #   - Russian, by <mailto:kaf@linux.nevod.perm.su>, at
 #     <http://nevod.perm.su/service/linux/doc/kernel/Configure.help>
 #   - French, by Pierre Tane <mailto:tanep@bigfoot.com>, at
-#     <http://www.traduc.org/kernelfr>
+#     <http://www.traduc.org/kernelfr/>
 #   - Polish, by Dominik Mierzejewski <mailto:dmierzej@elka.pw.edu.pl>, at
 #     <http://home.elka.pw.edu.pl/~dmierzej/linux/kernel/>
-#   - German, by SuSE, at <http://www.suse.de/~ke/kernel>. This patch
+#   - German, by SuSE, at <http://www.suse.de/~ke/kernel/>. This patch
 #     also includes infrastructure to support different languages.
+#   - Catalan, by Antoni Bella <mailto:bella5@teleline.es>, at
+#     <http://www.terra.es/personal7/bella5/traduccions.htm>
 #
 # To access a document on the WWW, you need to have a direct Internet
 # connection and a browser program such as netscape or lynx. If you
@@ -133,8 +135,8 @@
 
   See also the <file:Documentation/smp.tex>,
   <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
-  <file:Documentation/nmi_watchdog.txt> and the SMP-FAQ on the WWW at
-  <http://www.irisa.fr/prive/mentre/smp-faq/>.
+  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
+  <http://www.linuxdoc.org/docs.html#howto>.
 
   If you don't know what to do here, say N.
 
@@ -239,7 +241,7 @@
   You will need a new lynxer.elf file to flash your firmware with - send
   email to Martin.Bligh@us.ibm.com
 
-IO-APIC Support on Uniprocessors
+IO-APIC support on uniprocessors
 CONFIG_X86_UP_IOAPIC
   An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an
   SMP-capable replacement for PC-style interrupt controllers. Most
@@ -374,7 +376,7 @@
   Select this if you have a 32-bit processor and more than 4
   gigabytes of physical RAM.
 
-Normal PC floppy disk support
+Normal floppy disk support
 CONFIG_BLK_DEV_FD
   If you want to use the floppy disk drive(s) of your PC under Linux,
   say Y. Information about this driver, especially important for IBM
@@ -577,7 +579,7 @@
 
   To fine-tune ATA/IDE drive/interface parameters for improved
   performance, look for the hdparm package at
-  <http://www.ibiblio.org/pub/Linux/system/hardware>.
+  <ftp://ibiblio.org/pub/Linux/system/hardware/>.
 
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -666,12 +668,9 @@
   CD-ROM drive, you can say N to all other CD-ROM options, but be sure
   to say Y or M to "ISO 9660 CD-ROM file system support".
 
-  Read the CD-ROM-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto> and
-  <file:Documentation/cdrom/ide-cd>. Note that older versions of lilo
-  (the Linux boot loader) cannot properly deal with IDE/ATAPI CD-ROMs,
-  so install lilo-16 or higher, available from
-  <ftp://metalab.unc.edu/pub/Linux/system/boot/lilo>.
+  Note that older versions of LILO (LInux LOader) cannot properly deal
+  with IDE/ATAPI CD-ROMs, so install LILO 16 or higher, available from
+  <ftp://brun.dyndns.org/pub/linux/lilo/>.
 
   If you want to compile the driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -820,7 +819,7 @@
   for these drives, but you can change that by saying Y to the
   following question "Use DMA by default when available". You can get
   the latest version of the hdparm utility from
-  <ftp://metalab.unc.edu/pub/Linux/system/hardware/>.
+  <ftp://ibiblio.org/pub/Linux/system/hardware/>.
 
   Read the comments at the beginning of <file:drivers/ide/ide-dma.c>
   and the file <file:Documentation/ide.txt> for more information.
@@ -914,7 +913,7 @@
 
 Pacific Digital A-DMA support (EXPERIMENTAL)
 CONFIG_BLK_DEV_PDC_ADMA
-  Please read the comments at the top of <file:drivers/ide/pdcadma.c>.
+  Please read the comments at the top of <file:drivers/ide/ide-pci.c>.
 
 3ware Hardware ATA-RAID support
 CONFIG_BLK_DEV_3W_XXXX_RAID
@@ -973,7 +972,7 @@
 
   SAY N!
 
-AMD Viper support
+AMD Viper (7401/7409/7411) chipset support
 CONFIG_BLK_DEV_AMD74XX
   This driver ensures (U)DMA support for the AMD756/760 Viper
   chipsets.
@@ -984,7 +983,7 @@
 
   If unsure, say N.
 
-AMD Viper ATA-66 Override (WIP)
+AMD Viper ATA-66 Override support (WIP)
 CONFIG_AMD74XX_OVERRIDE
   This option auto-forces the ata66 flag.
   This effect can be also invoked by calling "idex=ata66"
@@ -1118,11 +1117,13 @@
 
 Special UDMA Feature
 CONFIG_PDC202XX_BURST
-  For PDC20246, PDC20262, PDC20265 and PDC20267 Ultra DMA chipsets.
-  Designed originally for PDC20246/Ultra33 that has BIOS setup
-  failures when using 3 or more cards.
+  This option causes the pdc202xx driver to enable UDMA modes on the
+  PDC202xx even when the PDC202xx BIOS has not done so.
 
-  Unknown for PDC20265/PDC20267 Ultra DMA 100.
+  It was originally designed for the PDC20246/Ultra33, whose BIOS will
+  only setup UDMA on the first two PDC20246 cards.  It has also been
+  used succesfully on a PDC20265/Ultra100, allowing use of UDMA modes
+  when the PDC20265 BIOS has been disabled (for faster boot up).
 
   Please read the comments at the top of
   <file:drivers/ide/pdc202xx.c>.
@@ -1251,15 +1252,6 @@
   <file:Documentation/ide.txt> and <file:drivers/ide/pdc4030.c> files
   for more info.
 
-# This is for Linus's tree.
-QDI QD6580 support
-CONFIG_BLK_DEV_QD6580
-  This driver is enabled at runtime using the "ide0=qd6580" kernel
-  boot parameter.  It permits faster I/O speeds to be set.  See the
-  <file:Documentation/ide.txt> and <file:drivers/ide/qd6580.c> for
-  more info.
-
-# This is for Alan's tree.  Note the name difference.
 QDI QD65XX support
 CONFIG_BLK_DEV_QD65XX
   This driver is enabled at runtime using the "ide0=qd65xx" kernel
@@ -1488,7 +1480,7 @@
 CONFIG_PARIDE_PG
   This option enables a special high-level driver for generic ATAPI
   devices connected through a parallel port. The driver allows user
-  programs, such as cdrecord, to send ATAPI commands directly to a
+  programs, such as cdrtools, to send ATAPI commands directly to a
   device.
 
   If you chose to build PARIDE support into your kernel, you may
@@ -1502,7 +1494,7 @@
   This driver implements an API loosely related to the generic SCSI
   driver. See <file:include/linux/pg.h>. for details.
 
-  You can obtain the most recent version of cdrecord from
+  You can obtain the most recent version of cdrtools from
   <ftp://ftp.fokus.gmd.de/pub/unix/cdrecord/>. Versions 1.6.1a3 and
   later fully support this driver.
 
@@ -1603,7 +1595,7 @@
   (low speed) adapter that is used in some portable hard drives. If
   you chose to build PARIDE support into your kernel, you may answer Y
   here to build in the protocol driver, otherwise you should answer M
-  to build it as a loadable module. The module will be called ktti.o.
+  to build it as a loadable module. The module will be called fit2.o.
   You must also have a high-level driver for the type of device that
   you want to support.
 
@@ -1716,9 +1708,9 @@
   controller, you do not need to say Y here.
 
   More information about Software RAID on Linux is contained in the
-  Software-RAID mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. There you will also
-  learn where to get the supporting user space utilities raidtools.
+  Software RAID mini-HOWTO, available from
+  <http://www.linuxdoc.org/docs.html#howto>. There you will also learn
+  where to get the supporting user space utilities raidtools.
 
   If unsure, say N.
 
@@ -1811,7 +1803,6 @@
 
   If unsure, say N.
 
-# AC tree only
 Support for IDE Raid controllers
 CONFIG_BLK_DEV_ATARAID
   Say Y or M if you have an IDE Raid controller and want linux
@@ -1824,7 +1815,6 @@
   has its own Raid drivers, which you should use if you need better
   performance.
 
-# AC tree only
 Support Promise software RAID (Fasttrak(tm))
 CONFIG_BLK_DEV_ATARAID_PDC
   Say Y or M if you have a Promise Fasttrak (tm) Raid controller
@@ -1835,7 +1825,6 @@
   If you choose to compile this as a module, the module will be called
   pdcraid.o.
 
-# AC tree only
 Highpoint 370 software RAID
 CONFIG_BLK_DEV_ATARAID_HPT
   Say Y or M if you have a Highpoint HPT 370 Raid controller
@@ -1851,19 +1840,19 @@
   This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
   kernel that runs on these, say Y here. For details about Linux on
   the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  <http://oss.sgi.com/mips>.
+  <http://oss.sgi.com/mips/>.
 
 Support for Algorithmics P4032 (EXPERIMENTAL)
 CONFIG_ALGOR_P4032
   This is an evaluation board of the British company Algorithmics.
   The board uses the R4300 and a R5230 CPUs.  For more information
-  about this board see <http://www.algor.co.uk>.
+  about this board see <http://www.algor.co.uk/>.
 
 Support for BAGET MIPS series
 CONFIG_BAGET_MIPS
   This enables support for the Baget, a Russian embedded system.  For
   more details about the Baget see the Linux/MIPS FAQ on
-  <http://oss.sgi.com/mips>.
+  <http://oss.sgi.com/mips/>.
 
 Baget AMD LANCE support
 CONFIG_BAGETLANCE
@@ -1874,8 +1863,8 @@
 Support for DECstations
 CONFIG_DECSTATION
   This enables support for DEC's MIPS based workstations.  For details
-  see the Linux/MIPS FAQ on <http://oss.sgi.com/mips> and the
-  DECstation porting pages on <http://decstation.unix-ag.org>.
+  see the Linux/MIPS FAQ on <http://oss.sgi.com/mips/> and the
+  DECstation porting pages on <http://decstation.unix-ag.org/>.
 
   If you have one of the following DECstation Models you definitely
   want to choose R4xx0 for the CPU Type:
@@ -1904,7 +1893,7 @@
 Support for the Momentum Computer Ocelot SBC
 CONFIG_MOMENCO_OCELOT
   The Ocelot is a MIPS-based Single Board Computer (SBC) made by
-  Momentum Computer <http://www.momenco.com>.
+  Momentum Computer <http://www.momenco.com/>.
 
 Support for NEC DDB Vrc-5074
 CONFIG_DDB5074
@@ -1917,7 +1906,7 @@
   evaluation board.
 
   Features : kernel debugging, serial terminal, NFS root fs, on-board
-  ether port (Need an additional patch at <http://linux.junsun.net>),
+  ether port (Need an additional patch at <http://linux.junsun.net/>),
   USB, AC97, PCI, PCI VGA card & framebuffer console, IDE controller,
   PS2 keyboard, PS2 mouse, etc.
 
@@ -1927,7 +1916,7 @@
   evaluation board.
 
   Features : kernel debugging, serial terminal, NFS root fs, on-board
-  ether port (Need an additional patch at <http://linux.junsun.net>),
+  ether port (Need an additional patch at <http://linux.junsun.net/>),
   USB, AC97, PCI, etc.
 
 Support for MIPS Atlas board
@@ -1953,7 +1942,7 @@
   This is a machine with a R4000 100 MHz CPU. To compile a Linux
   kernel that runs on these, say Y here. For details about Linux on
   the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  <http://oss.sgi.com/mips>.
+  <http://oss.sgi.com/mips/>.
 
 Enable Qtronix 990P Keyboard Support
 CONFIG_QTRONIX_KEYBOARD
@@ -1965,7 +1954,7 @@
   This is a machine with a R4000 100 MHz CPU. To compile a Linux
   kernel that runs on these, say Y here. For details about Linux on
   the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
-  <http://oss.sgi.com/mips>.
+  <http://oss.sgi.com/mips/>.
 
 Support for SNI RM200 PCI
 CONFIG_SNI_RM200_PCI
@@ -1974,13 +1963,13 @@
   Technology and now in turn merged with Fujitsu.  Say Y here to
   support this machine type.
 
-Support for SGI IP22
+Support for SGI-IP22 (Indy/Indigo2)
 CONFIG_SGI_IP22
   This are the SGI Indy, Challenge S and Indigo2, as well as certain
   OEM variants like the Tandem CMN B006S. To compile a Linux kernel
   that runs on these, say Y here.
 
-Support for SGI IP27
+Support for SGI IP27 (Origin200/2000)
 CONFIG_SGI_IP27
   This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
   workstations.  To compile a Linux kernel that runs on these, say Y
@@ -2036,13 +2025,26 @@
   DZ11-family serial controllers for VAXstations, including the
   DC7085, M7814, and M7819.
 
-
 TURBOchannel support
 CONFIG_TC
   TurboChannel is a DEC (now Compaq) bus for Alpha and MIPS processors.
   Documentation on writing device drivers for TurboChannel is available at:
   <http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PS3HD-TET1_html/TITLE.html>.
 
+# Choice: galileo_clock
+75
+CONFIG_SYSCLK_75
+  Configure the kernel for clock speed of your Galileo board.  
+  The choices are 75MHz, 83.3MHz, and 100MHz.
+
+83.3
+CONFIG_SYSCLK_83
+  Configure the Galileo kernel for a clock speed of 83.3 MHz.
+
+100
+CONFIG_SYSCLK_100
+  Configure the Galileo kernel for a clock speed of 100 MHz.
+
 Z85C30 Serial Support
 CONFIG_ZS
   Documentation on the Zilog 85C350 serial communications controller
@@ -2072,7 +2074,7 @@
 CONFIG_PCMCIA_NINJA_SCSI
   If you intend to attach this type of PCMCIA SCSI host adapter to
   your computer, say Y here and read
-  <file:Documentation/README.nsp_cs>.
+  <file:Documentation/README.nsp_cs.eng>.
 
   This driver is also available as a module called nsp_cs.o ( =
   code which can be inserted in and removed from the running kernel
@@ -2197,7 +2199,7 @@
   Access).  This option is for configuring high-end multiprocessor
   server machines.  If in doubt, say N.
 
-CPU type
+R41xx
 CONFIG_CPU_VR41XX
   The options selects support for the NEC VR41xx series of processors.
   Only choose this option if you have one of these processors as a
@@ -2209,7 +2211,7 @@
   Saying yes here allows you to select support for various features
   your CPU may or may not have.  Most people should say N here.
 
-ll/sc Instructions available
+ll and sc instructions available
 CONFIG_CPU_HAS_LLSC
   MIPS R4000 series and later provide the Load Linked (ll)
   and Store Conditional (sc) instructions. More information is
@@ -2219,7 +2221,7 @@
   for better performance, N if you don't know.  You must say Y here
   for multiprocessor machines.
 
-lld and scd instructions
+lld and scd instructions available
 CONFIG_CPU_HAS_LLDSCD
   Say Y here if your CPU has the lld and scd instructions, the 64-bit
   equivalents of ll and sc.  Say Y here for better performance, N if
@@ -2263,7 +2265,7 @@
   of which are given in <file:Documentation/Changes>.
 
   For a general introduction to Linux networking, it is highly
-  recommended to read the NET-3-HOWTO, available from
+  recommended to read the NET-HOWTO, available from
   <http://www.linuxdoc.org/docs.html#howto>.
 
 Socket filtering
@@ -2352,7 +2354,7 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
-IRC Send/Chat support
+IRC Send/Chat protocol support
 CONFIG_IP_NF_IRC
   There is a commonly-used extension to IRC called
   Direct Client-to-Client Protocol (DCC).  This enables users to send
@@ -2436,7 +2438,7 @@
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt.  If unsure, say `N'.
 
-length match support
+LENGTH match support
 CONFIG_IP_NF_MATCH_LENGTH
   This option allows you to match the length of a packet against a
   specific value or range of values.
@@ -2658,6 +2660,23 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+Multiple port match support
+CONFIG_IP6_NF_MATCH_MULTIPORT
+  Multiport matching allows you to match TCP or UDP packets based on
+  a series of source or destination ports: normally a rule can only
+  match a single range of ports.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+Owner match support
+CONFIG_IP6_NF_MATCH_OWNER
+  Packet owner matching allows you to match locally-generated packets
+  based on who created them: the user, group, process or session.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
 Packet filtering
 CONFIG_IP6_NF_FILTER
   Packet filtering defines a table `filter', which has a series of
@@ -2724,6 +2743,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+LOG target support
+CONFIG_IP6_NF_TARGET_LOG
+  This option adds a `LOG' target, which allows you to create rules in
+  any iptables table which records the packet header to the syslog.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
 SYN flood protection
 CONFIG_SYN_COOKIES
   Normal TCP/IP networking is open to an attack known as "SYN
@@ -2776,7 +2803,7 @@
 
   To find out what type of Alpha system you have, you may want to
   check out the Linux/Alpha FAQ, accessible on the WWW from
-  <http://www.alphalinux.org>. In summary:
+  <http://www.alphalinux.org/>. In summary:
 
   Alcor/Alpha-XLT     AS 600
   Alpha-XL            XL-233, XL-266
@@ -2955,13 +2982,18 @@
 CONFIG_ALPHA_GAMMA
   Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx.
 
+EV67 (or later) CPU (speed > 600MHz)?
+CONFIG_ALPHA_EV67
+  Is this a machine based on the EV67 core?  If in doubt, select N here
+  and the machine will be treated as an EV6.
+
 Use SRM as bootloader
 CONFIG_ALPHA_SRM
   There are two different types of booting firmware on Alphas: SRM,
   which is command line driven, and ARC, which uses menus and arrow
   keys. Details about the Linux/Alpha booting process are contained in
   the Linux/Alpha FAQ, accessible on the WWW from
-  <http://www.alphalinux.org>.
+  <http://www.alphalinux.org/>.
 
   The usual way to load Linux on an Alpha machine is to use MILO
   (a bootloader that lets you pass command line parameters to the
@@ -3130,7 +3162,7 @@
 
   The user level application needed to use this driver can be found at
   the IBM Linux Technology Center (LTC) web site:
-  http://www.ibm.com/linux/ltc/
+  <http://www.ibm.com/linux/ltc/>.
 
   If you own one of the above IBM Thinkpads which has the Mwave chipset
   in it, say Y.
@@ -3300,7 +3332,7 @@
 
   When in doubt, say Y.
 
-PCI Hotplug support
+Generic PCI hotplug support
 CONFIG_HOTPLUG_PCI
   Say Y here if you have a motherboard with a PCI Hotplug controller.
   This allows you to add and remove PCI cards while the machine is
@@ -3314,7 +3346,7 @@
 
   When in doubt, say N.
 
-PCI Compaq Hotplug controller
+Compaq PCI Hotplug driver
 CONFIG_HOTPLUG_PCI_COMPAQ
   Say Y here if you have a motherboard with a Compaq PCI Hotplug
   controller.
@@ -3505,7 +3537,7 @@
   example, used on modern desktops as well as laptops, is USB.
 
   Enable HOTPLUG and KMOD, and build a modular kernel.  Get agent
-  software (at <http://linux-hotplug.sourceforge.net>) and install it.
+  software (at <http://linux-hotplug.sourceforge.net/>) and install it.
   Then your kernel will automatically call out to a user mode "policy
   agent" (/sbin/hotplug) to load modules and set up software needed
   to use devices as you hotplug them.
@@ -3547,6 +3579,12 @@
 
   If unsure, say Y.
 
+i82092 compatible bridge support
+CONFIG_I82092
+  This provides support for the Intel I82092AA PCI-to-PCMCIA bridge device,
+  found in some older laptops and more commonly in evaluation boards for the
+  chip.
+
 i82365 compatible host bridge support
 CONFIG_I82365
   Say Y here to include support for ISA-bus PCMCIA host bridges that
@@ -3625,7 +3663,6 @@
   don't understand what this means or are not a kernel hacker, just
   leave it at its default value ELF.
 
-# Choice: kcore
 Select a.out format for /proc/kcore
 CONFIG_KCORE_AOUT
   Not necessary unless you're using a very out-of-date binutils
@@ -3748,7 +3785,7 @@
   The module will be called envctrl.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-# Choice: x86
+# Choice: x86type
 Processor family
 CONFIG_M386
   This is the processor type of your CPU. This information is used for
@@ -3821,7 +3858,7 @@
 
   The program SVGATextMode can be used to utilize SVGA video cards to
   their full potential in text mode. Download it from
-  <ftp://metalab.unc.edu/pub/Linux/utils/console>.
+  <ftp://ibiblio.org/pub/Linux/utils/console/>.
 
   Say Y.
 
@@ -4053,21 +4090,18 @@
   module will be called aty128fb.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-# AC tree only
 Maxine (Personal DECstation) onboard framebuffer support
 CONFIG_FB_MAXINE
   Say Y here to directly support the on-board framebuffer in the
   Maxine (5000/20, /25, /33) version of the DECstation.  There is a
   page dedicated to Linux on DECstations at <http://decstation.unix-ag.org/>.
 
-# AC tree only
 PMAG-BA TURBOchannel framebuffer support
 CONFIG_FB_PMAG_BA
   Say Y here to directly support the on-board PMAG-BA framebuffer in
   the 5000/1xx versions of the DECstation.  There is a page dedicated
   to Linux on DECstations at <http://decstation.unix-ag.org/>.
 
-# AC tree only
 PMAGB-B TURBOchannel framebuffer support
 CONFIG_FB_PMAGB_B
   Say Y here to directly support the on-board PMAGB-B framebuffer in
@@ -4079,10 +4113,32 @@
   Say Y here if you intend to run this kernel on a FutureTV (nee Nexus
   Electronics) StrongARM PCI card.
 
-P720T
-CONFIG_ARCH_P720T
-  Say Y here if you intend to run this kernel on the ARM Prospector
-  720T.
+ANAKIN Vehicle Telematics Platform
+CONFIG_ARCH_ANAKIN
+  The Anakin is a StrongArm based SA110 - 2 DIN Vehicle Telematics Platform.
+  64MB SDRAM - 4 Mb Flash - Compact Flash Interface - 1 MB VRAM
+
+  On board peripherals:
+        * Front display: 400x234 16 bit TFT touchscreen
+        * External independent second screen interface
+        * CAN controller SJA1000
+        * USB host controller
+        * 6 channel video codec with hardware overlay
+        * Smartcard reader
+        * IrDa
+
+  Modules interfaced over the Multi Media Extension slots:
+        * A communication card
+                Wavecom GPRS modem
+                uBlock GPS
+                Bosch DAB module
+        * An audio card ( 4 * 40W, AC97 Codec, I2S)
+
+Altera Excalibur XA10 Dev Board
+ARCH_CAMELOT
+  This enables support for Altera's Excalibur XA10 development board.
+  If you would like to build your kernel to run on one of these boards
+  then you must say 'Y' here. Otherwise say 'N'
 
 Link-Up Systems LCD support
 CONFIG_FB_L7200
@@ -4306,10 +4362,8 @@
   a module, say M here and read <file:Documentation/modules.txt>.
 
   You can pass several parameters to the driver at boot time or at
-  module load time. The parameters look like "video=matrox:XXX", where
-  the meaning of XXX can be found at the end of the main source file
-  (<file:drivers/video/matroxfb.c>). Please see
-  <file:Documentation/fb/matroxfb.txt>.
+  module load time. The parameters look like "video=matrox:XXX", and
+  are described in <file:Documentation/fb/matroxfb.txt>.
 
 Matrox Millennium I/II support
 CONFIG_FB_MATROX_MILLENIUM
@@ -4372,7 +4426,7 @@
 
   The driver starts in monitor mode and you must use the matroxset
   tool (available at
-  <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest>) to switch it to
+  <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to
   PAL or NTSC or to swap primary and secondary head outputs.
   Secondary head driver also always start in 640x480 resolution, you
   must use fbset to change it.
@@ -4394,7 +4448,7 @@
 
   The driver starts in monitor mode and currently does not support
   output in TV modes.  You must use the matroxset tool (available
-  at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest>) to swap
+  at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to swap
   primary and secondary head outputs.  Secondary head driver always
   start in 640x480 resolution and you must use fbset to change it.
 
@@ -4504,19 +4558,17 @@
   This is the frame buffer device driver for the Hitachi HD64461 LCD
   frame buffer card.
 
-SIS 630/540 display support
+SIS acceleration
 CONFIG_FB_SIS
   This is the frame buffer device driver for the SiS 630 and 640 Super
   Socket 7 UMA cards.  Specs available at <http://www.sis.com.tw/>.
 
-# AC tree only
 SIS 630/540/730 support
 CONFIG_FB_SIS_300
   This is the frame buffer device driver for the SiS 630 and related
   Super Socket 7 UMA cards.  Specs available at
   <http://www.sis.com.tw/>.
 
-# AC tree only
 SIS 315H/315 support
 CONFIG_FB_SIS_315
   This is the frame buffer device driver for the SiS 315 graphics
@@ -4570,7 +4622,6 @@
   is at
   <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
 
-# AC tree only
 ATI Radeon display support
 CONFIG_FB_RADEON
   Choose this option if you want to use an ATI Radeon graphics card as
@@ -4697,7 +4748,8 @@
   drive, PLIP link (Parallel Line Internet Protocol is mainly used to
   create a mini network by connecting the parallel ports of two local
   machines) etc., then you need to say Y here; please read
-  <file:Documentation/parport.txt> and drivers/parport/BUGS-parport.
+  <file:Documentation/parport.txt> and
+  <file:drivers/parport/BUGS-parport>.
 
   For extensive information about drivers for many devices attaching
   to the parallel port see <http://www.torque.net/linux-pp.html> on
@@ -4729,7 +4781,7 @@
 
   If unsure, say Y.
 
-Parallel+serial PCI card support
+Parallel+serial PCI multi-IO card support
 CONFIG_PARPORT_SERIAL
   This adds support for multi-IO PCI cards that have parallel and
   serial ports.  You should say Y or M here.  If you say M, the module
@@ -5179,7 +5231,7 @@
   used for local networks of Windows machines.  You need it if you
   want to access Novell NetWare file or print servers using the Linux
   Novell client ncpfs (available from
-  <ftp://metalab.unc.edu/pub/Linux/system/filesystems/>) or from
+  <ftp://platan.vc.cvut.cz/pub/linux/ncpfs/>) or from
   within the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO,
   available from <http://www.linuxdoc.org/docs.html#howto>).  In order
   to do the former, you'll also have to say Y to "NCP file system
@@ -5191,8 +5243,8 @@
 
   To turn your Linux box into a fully featured NetWare file server and
   IPX router, say Y here and fetch either lwared from
-  <ftp://metalab.unc.edu/pub/Linux/system/network/daemons/> or
-  mars_nwe from <ftp://ftp.gwdg.de/pub/linux/misc/ncpfs>. For more
+  <ftp://ibiblio.org/pub/Linux/system/network/daemons/> or
+  mars_nwe from <ftp://www.compu-art.de/mars_nwe/>. For more
   information, read the IPX-HOWTO available from
   <http://www.linuxdoc.org/docs.html#howto>.
 
@@ -5228,7 +5280,7 @@
   'special' sockets to sockets listening on the primary network is
   disabled. This might break existing applications, especially RIP/SAP
   daemons. A RIP/SAP daemon that works well with the full internal net
-  can be found on <ftp://ftp.gwdg.de/pub/linux/misc/ncpfs>.
+  can be found on <ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/>.
 
   If you don't know what you are doing, say N.
 
@@ -5296,7 +5348,7 @@
   network link driver", "Routing messages" and "Network packet
   filtering".  The first two are required to allow configuration via
   rtnetlink (currently you need Alexey Kuznetsov's iproute2 package
-  from <ftp://ftp.inr.ac.ru>). The "Network packet filtering" option
+  from <ftp://ftp.inr.ac.ru/>). The "Network packet filtering" option
   will be required for the forthcoming routing daemon to work.
 
   See <file:Documentation/networking/decnet.txt> for more information.
@@ -5417,9 +5469,8 @@
 Amateur Radio support
 CONFIG_HAMRADIO
   If you want to connect your Linux box to an amateur radio, answer Y
-  here. You want to read <http://www.tapr.org/tapr/html/pkthome.html>
-  and the HAM-HOWTO and the AX25-HOWTO, both available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  here. You want to read <http://www.tapr.org/tapr/html/pkthome.html> and
+  the AX25-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>.
 
   Note that the answer to this question won't directly affect the
   kernel: saying N will just cause the configurator to skip all
@@ -5626,7 +5677,7 @@
   connect to a parallel interface. The driver supports the picpar and
   par96 designs. To configure the driver, use the sethdlc utility
   available in the standard ax25 utilities package. For information on
-  the modems, see <http://www.baycom.de> and the file
+  the modems, see <http://www.baycom.de/> and the file
   <file:Documentation/networking/baycom.txt>.
 
   If you want to compile this driver as a module ( = code which can be
@@ -5640,7 +5691,7 @@
   connect to a parallel interface. The driver supports the EPP
   designs. To configure the driver, use the sethdlc utility available
   in the standard ax25 utilities package. For information on the
-  modems, see <http://www.baycom.de> and the file
+  modems, see <http://www.baycom.de/> and the file
   <file:Documentation/networking/baycom.txt>.
 
   If you want to compile this driver as a module ( = code which can be
@@ -5659,7 +5710,7 @@
   driver and still provided in case this driver does not work with
   your serial interface chip. To configure the driver, use the sethdlc
   utility available in the standard ax25 utilities package. For
-  information on the modems, see <http://www.baycom.de> and
+  information on the modems, see <http://www.baycom.de/> and
   <file:Documentation/networking/baycom.txt>.
 
   If you want to compile this driver as a module ( = code which can be
@@ -5676,7 +5727,7 @@
   the full-duplex driver. This driver is depreciated.  To configure
   the driver, use the sethdlc utility available in the standard ax25
   utilities package. For information on the modems, see
-  <http://www.baycom.de> and
+  <http://www.baycom.de/> and
   <file:Documentation/networking/baycom.txt>.
 
   If you want to compile this driver as a module ( = code which can be
@@ -5853,7 +5904,7 @@
    - etc...
 
   For more informations, please refer to:
-    <http://www.freshmeat.net/projects/etherdivert>
+    <http://diverter.sourceforge.net/>
     <http://perso.wanadoo.fr/magpie/EtherDivert.html>
 
   If unsure, say N.
@@ -6191,7 +6242,7 @@
   control memory (128K-1KVC, 512K-4KVC), the size of the packet
   memory (128K, 512K, 1M), and the PHY type (Single/Multi mode OC3,
   UTP155, UTP25, DS3 and E3). Go to:
-  	www.iphase.com/products/ClassSheet.cfm?ClassID=ATM
+  	<http://www.iphase.com/products/ClassSheet.cfm?ClassID=ATM>
   for more info about the cards. Say Y (or M to compile as a module
   named iphase.o) here if you have one of these cards.
 
@@ -6204,7 +6255,7 @@
   messages is controlled by a bitmap. This may be specified as a
   module argument (kernel command line argument as well?), changed
   dynamically using an ioctl (Get the debug utility, iadbg, from
-  <ftp://ftp.iphase.com/pub/atm/pci>).
+  <ftp://ftp.iphase.com/pub/atm/pci/>).
 
   See the file <file:drivers/atm/iphase.h> for the meanings of the
   bits in the mask.
@@ -6213,6 +6264,13 @@
   speed of the driver, and the size of your syslog files! When
   inactive, they will have only a modest impact on performance.
 
+Efficient Networks Speedstream 3010
+CONFIG_ATM_LANAI
+  Supports ATM cards based on the Efficient Networks "Lanai"
+  chipset such as the Speedstream 3010 and the ENI-25p.  The
+  Speedstream 3060 is currently not supported since we don't
+  have the code to drive the on-board Alcatel DSL chipset (yet).
+
 Linux telephony support
 CONFIG_PHONE
   Say Y here if you have a telephony card, which for example allows
@@ -6331,6 +6389,13 @@
   the performances of the driver, and the size of your syslog files!
   Keep the debugging level to 0 during normal operations.
 
+PPP over ATM
+CONFIG_PPPOATM
+  Support PPP (Point to Point Protocol) encapsulated in ATM frames.
+  This implementation does not yet comply with section 8 of RFC2364,
+  which can lead to bad results idf the ATM peer loses state and 
+  changes its encapsulation unilaterally.
+
 Fusion MPT device support
 CONFIG_FUSION
   LSI Logic Fusion(TM) Message Passing Technology (MPT) device support
@@ -6456,12 +6521,6 @@
   You also need to say Y here if you want support for the parallel
   port version of the 100 MB IOMEGA ZIP drive.
 
-  Please read the SCSI-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>. The
-  SCSI-Programming-HOWTO contains information about how to add or
-  remove an SCSI device from a running Linux machine without
-  rebooting.
-
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
   The module will be called scsi_mod.o.  If you want to compile it as
@@ -6539,7 +6598,7 @@
   tape drives (ADR-x0) that supports the standard SCSI-2 commands for
   tapes (QIC-157) and can be driven by the standard driver st.
   For more information, you may have a look at the SCSI-HOWTO
-  <ftp://metalab.unc.edu/pub/Linux/docs/HOWTO>  and
+  <http://www.linuxdoc.org/docs.html#howto>  and
   <file:drivers/scsi/README.osst>  in the kernel source.
   More info on the OnStream driver may be found on
   <http://linux1.onstream.nl/test/>
@@ -6594,12 +6653,12 @@
   directly, so you need some additional software which knows how to
   talk to these devices using the SCSI protocol:
 
-  For scanners, look at SANE (<http://www.mostang.com/sane>). For CD
-  writer software look at cdrecord
+  For scanners, look at SANE (<http://www.mostang.com/sane/>). For CD
+  writer software look at Cdrtools
   (<http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/cdrecord.html>)
-  and for burning a "disk at once": cdrdao
-  (<http://www.ping.de/sites/daneb/cdrdao.html>). Cdparanoia is a high
-  quality digital reader of audio CDs (<http://www.xiph.org/paranoia>).
+  and for burning a "disk at once": CDRDAO
+  (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
+  quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
   For other devices, it's possible that you'll have to write the
   driver software yourself. Please read the file
   <file:Documentation/scsi-generic.txt> for more information.
@@ -6610,17 +6669,6 @@
   <file:Documentation/scsi.txt>. The module will be called sg.o. If unsure,
   say N.
 
-Enable extra checks in SCSI queueing code
-CONFIG_SCSI_DEBUG_QUEUES
-  This option turns on a lot of additional consistency checking for
-  the new queueing code. This will adversely affect performance, but
-  it is likely that bugs will be caught sooner if this is turned on.
-  This will typically cause the kernel to panic if an error is
-  detected, but it would have probably crashed if the panic weren't
-  there. Comments/questions/problems to linux-scsi mailing list
-  please. See <http://www.andante.org/scsi_queue.html> for more
-  up-to-date information.
-
 Probe all LUNs on each SCSI device
 CONFIG_SCSI_MULTI_LUN
   If you have a SCSI device that supports more than one LUN (Logical
@@ -6734,7 +6782,7 @@
   intended to replace the previous aic7xxx driver maintained by Doug
   Ledford since Doug is no longer maintaining that driver.
 
-Adaptec I2O RAID controllers
+Adaptec I2O RAID support
 CONFIG_SCSI_DPT_I2O
   This driver supports all of Adaptec's I2O based RAID controllers as 
   well as the DPT SmartRaid V cards.  This is an Adaptec maintained
@@ -6907,10 +6955,10 @@
   This is support for BusLogic MultiMaster and FlashPoint SCSI Host
   Adapters. Consult the SCSI-HOWTO, available from
   <http://www.linuxdoc.org/docs.html#howto>, and the files
-  README.BusLogic and README.FlashPoint in drivers/scsi for more
-  information. If this driver does not work correctly without
-  modification, please contact the author, Leonard N. Zubkoff, by
-  email to lnz@dandelion.com.
+  <file:drivers/scsi/README.BusLogic> and
+  <file:drivers/scsi/README.FlashPoint> for more information. If this
+  driver does not work correctly without modification, please contact
+  the author, Leonard N. Zubkoff, by email to lnz@dandelion.com.
 
   You can also build this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -7087,7 +7135,7 @@
   Unless you have an NCR manufactured machine, the chances are that
   you do not have this SCSI card, so say N.
 
-HP LASI SCSI support for 53c700
+HP LASI SCSI support for 53c700/710
 CONFIG_SCSI_LASI700
   This is a driver for the lasi baseboard in some parisc machines
   which is based on the 53c700 chip.  Will also support LASI subsystems
@@ -7152,7 +7200,7 @@
   If your system has problems using this new major version of the
   SYM53C8XX driver, you may switch back to driver version 1.
 
-  Please read drivers/scsi/sym53c8xx_2/Documentation.txt for more
+  Please read <file:drivers/scsi/sym53c8xx_2/Documentation.txt> for more
   information.
 
 PCI DMA addressing mode
@@ -7693,7 +7741,7 @@
 NCR53c406a SCSI support
 CONFIG_SCSI_NCR53C406A
   This is support for the NCR53c406a SCSI host adapter.  For user
-  configurable parameters, check out <file:drivers/scsi/NCR53c406.c>
+  configurable parameters, check out <file:drivers/scsi/NCR53c406a.c>
   in the kernel source.  Also read the SCSI-HOWTO, available from
   <http://www.linuxdoc.org/docs.html#howto>.
 
@@ -7799,13 +7847,14 @@
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called megaraid.o.
 
-Intel/ICP (former GDT SCSI Disk Array) RAID Controller Support
+Intel/ICP (former GDT SCSI Disk Array) RAID Controller support
 CONFIG_SCSI_GDTH
   Formerly called GDT SCSI Disk Array Controller Support.
  
   This is a driver for RAID/SCSI Disk Array Controllers (EISA/ISA/PCI) 
   manufactured by Intel/ICP vortex (an Intel Company). It is documented
-  in the kernel source in drivers/scsi/gdth.c and drivers/scsi/gdth.h. 
+  in the kernel source in <file:drivers/scsi/gdth.c> and
+  <file:drivers/scsi/gdth.h.>
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -8088,7 +8137,7 @@
 #  say M here and read <file:Documentation/modules.txt>.  The module
 #  will be called aic5800.o.
 #
-OHCI-1394 support
+OHCI-1394 (Open Host Controller Interface) support
 CONFIG_IEEE1394_OHCI1394
   Enable this driver if you have an IEEE 1394 controller based on the
   OHCI-1394 specification. The current driver is only tested with OHCI
@@ -8218,8 +8267,8 @@
 
   Normally, your access provider has to support SLIP in order for you
   to be able to use it, but there is now a SLIP emulator called SLiRP
-  around (available via FTP (user: anonymous) from
-  <ftp://metalab.unc.edu/pub/Linux/system/network/serial/>) which
+  around (available from
+  <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
   allows you to use SLIP over a regular dial up shell connection. If
   you plan to use SLiRP, make sure to say Y to CSLIP, below. The
   NET-3-HOWTO, available from
@@ -8244,7 +8293,7 @@
   on both ends. Ask your access provider if you are not sure and
   answer Y, just in case. You will still be able to use plain SLIP. If
   you plan to use SLiRP, the SLIP emulator (available from
-  <ftp://metalab.unc.edu/pub/Linux/system/network/serial/>) which
+  <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
   allows you to use SLIP over a regular dial up shell connection, you
   definitely want to say Y here. The NET-3-HOWTO, available from
   <http://www.linuxdoc.org/docs.html#howto>, explains how to configure
@@ -8381,7 +8430,7 @@
 
   This driver requires a specially patched pppd daemon.  The patch to
   pppd, along with binaries of a patched pppd package can be found at:
-  <http://www.shoshin.uwaterloo.ca/~mostrows>.
+  <http://www.shoshin.uwaterloo.ca/~mostrows/>.
 
 Wireless LAN (non-hamradio)
 CONFIG_NET_RADIO
@@ -8403,7 +8452,7 @@
 
   Some user-level drivers for scarab devices which don't require
   special kernel support are available from
-  <ftp://shadow.cabi.net/pub/Linux>.
+  <ftp://shadow.cabi.net/pub/Linux/>.
 
 STRIP (Metricom Starmode radio IP)
 CONFIG_STRIP
@@ -8663,6 +8712,19 @@
   a module, say M here and read <file:Documentation/modules.txt>.  If
   unsure, say N.
 
+Asix AX88190 PCMCIA support
+CONFIG_PCMCIA_AXNET
+  Say Y here if you intend to attach an Asix AX88190-based PCMCIA
+  (PC-card) Fast Ethernet card to your computer.  These cards are
+  nearly NE2000 compatible but need a separate driver due to a few
+  misfeatures.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called axnet_cs.o.  If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.  If
+  unsure, say N.
+
 New Media PCMCIA support
 CONFIG_PCMCIA_NMCLAN
   Say Y here if you intend to attach a New Media Ethernet or LiveWire
@@ -8718,7 +8780,7 @@
   The module will be called ibmtr_cs.o.  If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
-Xircom Tulip-like CardBus support
+Xircom Tulip-like CardBus support (old driver)
 CONFIG_PCMCIA_XIRTULIP
   This driver is for the Digital "Tulip" Ethernet CardBus adapters.
   It should work with most DEC 21*4*-based chips/ethercards, as well
@@ -8762,12 +8824,6 @@
   configure your card and that /etc/pcmcia/wireless.opts works :
   <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
 
-Apple Airport support (built-in)
-CONFIG_APPLE_AIRPORT
-  Enable support for the Apple Airport card (which is essentially a
-  Lucent Orinoco card with a non-standard interface) built into some
-  newer Apple Macintosh machines.
-
 Hermes 802.11b in PLX9052 based PCI adaptor support
 CONFIG_PLX_HERMES
   Enable support for PCMCIA cards supported by the "Hermes" (aka
@@ -8849,7 +8905,8 @@
 CONFIG_APPLE_AIRPORT
   Say Y here to support the Airport 802.11b wireless Ethernet hardware
   built into the Macintosh iBook and other recent PowerPC-based
-  Macintosh machines.
+  Macintosh machines. This is essentially a Lucent Orinoco card with 
+  a non-standard interface
 
 Xircom Netwave AirSurfer wireless support
 CONFIG_PCMCIA_NETWAVE
@@ -8994,7 +9051,7 @@
   of the Cisco HDLC/PPP driver (syncppp.c).
   The SyncLink WAN driver (in character devices) must also be enabled.
 
-FarSync T-Series support
+FarSync T-Series X.21 (and V.35/V.24) cards
 CONFIG_FARSYNC
   This driver supports the FarSync T-Series X.21 (and V.35/V.24) cards
   from FarSite Communications Ltd.
@@ -9097,7 +9154,7 @@
   the price of an external router.  If you have one of those cards and
   wish to use your Linux box as a WAN router, say Y here and also to
   the WAN driver for your card, below.  You will then need the
-  wan-tools package which is available from <ftp://ftp.sangoma.com>.
+  wan-tools package which is available from <ftp://ftp.sangoma.com/>.
   Read <file:Documentation/networking/wan-router.txt> for more
   information.
 
@@ -9479,7 +9536,7 @@
   up. Look at the <http://www.fi.muni.cz/~kas/cosa/> for more
   information about the cards (including the pointer to the user-space
   utilities). You can also read the comment at the top of the
-  <file:drivers/net/cosa.c> for details about the cards and the driver
+  <file:drivers/net/wan/cosa.c> for details about the cards and the driver
   itself.
 
   The driver will be compiled as a module ( = code which can be
@@ -9491,7 +9548,7 @@
 CONFIG_DSCC4
   This is a driver for Etinc PCISYNC boards based on the Infineon
   (ex. Siemens) DSCC4 chipset. It is supposed to work with the four
-  ports card. Take a look at <http://www.cogenit.fr/dscc4>
+  ports card. Take a look at <http://www.cogenit.fr/dscc4/>
   for further informations about the driver and his configuration.
 
   The driver will be compiled as a module ( = code which can be
@@ -9518,7 +9575,7 @@
   additional external hardware.
 
   To change setting such as syncPPP vs cisco HDLC or clock source you
-  will need lmcctl.  It is available at <ftp://ftp.lanmedia.com>.
+  will need lmcctl.  It is available at <ftp://ftp.lanmedia.com/>.
 
   This code is also available as a module called lmc.o ( = code
   which can be inserted in and removed from the running kernel
@@ -9563,12 +9620,12 @@
   module will be called sbni.o).
 
   You can find more information and last versions of drivers and
-  utilities at <http://www.granch.ru>. If you have any question you
+  utilities at <http://www.granch.ru/>. If you have any question you
   can send email to sbni@granch.ru.
 
   Say N if unsure.
 
-SBNI Adapters Multiline feature
+SBNI multiple-line feature support
 CONFIG_SBNI_MULTILINE
   Schedule traffic for some parallel lines, via SBNI12 adapters.
   If you have two computers connected with two parallel lines it's
@@ -9586,7 +9643,7 @@
   Router".
 
   You will need the wan-tools package which is available from
-  <ftp://ftp.sangoma.com>. Read
+  <ftp://ftp.sangoma.com/>. Read
   <file:Documentation/networking/wan-router.txt> for more information.
 
   Note that the answer to this question won't directly affect the
@@ -9595,7 +9652,7 @@
 
 Sangoma WANPIPE(tm) multiprotocol cards
 CONFIG_VENDOR_SANGOMA
-  WANPIPE from Sangoma Technologies Inc. (<http://www.sangoma.com>)
+  WANPIPE from Sangoma Technologies Inc. (<http://www.sangoma.com/>)
   is a family of intelligent multiprotocol WAN adapters with data
   transfer rates up to 4Mbps. They are also known as Synchronous
   Data Link Adapters (SDLA) and are designated as S514-PCI or
@@ -9683,7 +9740,7 @@
 
   Read <file:Documentation/networking/comx.txt> for help on
   configuring and using COMX interfaces.  Further info on these cards
-  can be found at <http://www.itc.hu> or <info@itc.hu>.
+  can be found at <http://www.itc.hu/> or <info@itc.hu>.
 
   You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
   use this driver.
@@ -9777,8 +9834,8 @@
 
 Cyclom 2X(tm) multiprotocol cards
 CONFIG_CYCLADES_SYNC
-  Cyclom 2X from Cyclades Corporation (<http://www.cyclades.com> and
-  <http://www.cyclades.com.br)> is an intelligent multiprotocol WAN
+  Cyclom 2X from Cyclades Corporation (<http://www.cyclades.com/> and
+  <http://www.cyclades.com.br/>) is an intelligent multiprotocol WAN
   adapter with data transfer rates up to 512 Kbps. These cards support
   the X.25 and SNA related protocols. If you have one or more of these
   cards, say Y to this option. The next questions will ask you about
@@ -9787,10 +9844,10 @@
 
   While no documentation is available at this time please grab the
   wanconfig tarball in
-  <http://www.conectiva.com.br/~acme/cycsyn-devel> (with minor changes
+  <http://www.conectiva.com.br/~acme/cycsyn-devel/> (with minor changes
   to make it compile with the current wanrouter include files; efforts
   are being made to use the original package available at
-  <ftp://ftp.sangoma.com>).
+  <ftp://ftp.sangoma.com/>).
 
   Feel free to contact me or the cycsyn-devel mailing list at
   acme@conectiva.com.br and cycsyn-devel@bazar.conectiva.com.br for
@@ -10267,15 +10324,7 @@
   is a 10Mbit/sec Ethernet controller.  Product overview and specs at
   <http://www.national.com/pf/DP/DP83902A.html>.
 
-CompactFlash Connection Area
-CONFIG_CF_AREA5
-  If your board has "Directly Connected" CompactFlash, You should
-  select the area where your CF is connected to.
-
-  - "Area5" if CompactFlash is connected to Area 5 (0x14000000)
-  - "Area6" if it is connected to Area 6 (0x18000000)
-
-  "Area6" will work for most boards. For ADX, select "Area5".
+  If unsure, say N.
 
 3COM cards
 CONFIG_NET_VENDOR_3COM
@@ -10622,7 +10671,7 @@
   module, say M here and read <file:Documentation/modules.txt> as well
   as <file:Documentation/networking/net-modules.txt>.
 
-EtherExpressPro support/EtherExpress 10 (i82595) support
+EtherExpressPro and EtherExpress 10 (i82595) support
 CONFIG_EEXPRESS_PRO
   If you have a network (Ethernet) card of this type, say Y. This
   driver supports intel i82595{FX,TX} based boards. Note however
@@ -10766,10 +10815,7 @@
   driver and as a module ( = code which can be inserted in and removed
   from the running kernel whenever you want).  If you want to compile
   it as a module, say M here and read <file:Documentation/modules.txt>
-  as well as <file:Documentation/networking/net-modules.txt>.
-  If you plan to use more than one network card under linux, read the
-  Multiple-Ethernet-mini-HOWTO, available from
-  <ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini>.  The only
+  as well as <file:Documentation/networking/net-modules.txt>. The only
   currently supported card is the IBM LAN Adapter/A for Ethernet.  It
   will both support 16K and 32K memory windows, however a 32K window
   gives a better security against packet losses.  Usage of multiple
@@ -10893,6 +10939,13 @@
 
   If unsure, say N.
 
+Use PCI shared memory for NIC registers
+CONFIG_TULIP_MMIO
+  Use PCI shared memory for the NIC registers, rather than going through 
+  the Tulip's PIO (programmed I/O ports).  Faster, but could produce 
+  obscure bugs if your mainboard has memory controller timing issues.
+  If in doubt, say N.
+
 Digi Intl. RightSwitch SE-X support
 CONFIG_DGRS
   This is support for the Digi International RightSwitch series of
@@ -10936,7 +10989,7 @@
 CONFIG_FEALNX
   Say Y here to support the Mysom MTD-800 family of PCI-based Ethernet
   cards. Specifications and data at
-  <http:www.myson.com.hk/mtd/datasheet>.
+  <http://www.myson.com.hk/mtd/datasheet/>.
 
 ICL EtherTeam 16i/32 support
 CONFIG_ETH16I
@@ -10980,10 +11033,21 @@
   a module, say M here and read <file:Documentation/modules.txt> as
   well as <file:Documentation/networking/net-modules.txt>.
 
+VIA Rhine MMIO support (EXPERIMENTAL)
+CONFIG_VIA_RHINE_MMIO
+  This instructs the driver to use PCI shared memory (MMIO) instead of
+  programmed I/O ports (PIO). Enabling this gives an improvement in
+  processing time in parts of the driver.
+
+  It is not known if this works reliably on all "rhine" based cards,
+  but it has been tested successfully on some DFE-530TX adapters.
+
+  If unsure, say N.
+
 Davicom DM910x/DM980x support
 CONFIG_DM9102
   This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from
-  Davicom (<http://www.davicom.com.tw>).  If you have such a network
+  Davicom (<http://www.davicom.com.tw/>).  If you have such a network
   (Ethernet) card, say Y.  Some information is contained in the file
   <file:Documentation/networking/dmfe.txt>.
 
@@ -11168,8 +11232,7 @@
   Wake On Lan, and PCI 100/16/4 adapters.
 
   If you have such an adapter, say Y and read the Token-Ring
-  mini-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>.
+  mini-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -11178,15 +11241,14 @@
 
   Also read <file:Documentation/networking/olympic.txt> or check the
   Linux Token Ring Project site for the latest information at
-  <http://www.linuxtr.net>.
+  <http://www.linuxtr.net/>.
 
 IBM Lanstreamer chipset PCI adapter support
 CONFIG_IBMLS
   This is support for IBM Lanstreamer PCI Token Ring Cards.
 
   If you have such an adapter, say Y and read the Token-Ring
-  mini-HOWTO available via FTP (user:anonymous) from
-  <ftp://metalab.unc/edu/pub/Linux/docs/HOWTO>.
+  mini-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>.
 
   This driver is also available as a modules ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -11337,7 +11399,7 @@
   say Y to "QoS and/or fair queueing" above.
 
   To set up and configure shaper devices, you need the shapecfg
-  program, available from <ftp://shadow.cabi.net/pub/Linux> in the
+  program, available from <ftp://shadow.cabi.net/pub/Linux/> in the
   shaper package.
 
   This driver is also available as a module ( = code which can be
@@ -11598,7 +11660,7 @@
   Say Y here only if you have two CD-ROM controller cards of this type
   (usually only if you have more than four drives).  You should enter
   the parameters for the second, third and fourth interface card into
-  <file:include/linux/sbpcd.h> before compiling the new kernel.  Read
+  <file:drivers/cdrom/sbpcd.h> before compiling the new kernel.  Read
   the file <file:Documentation/cdrom/sbpcd>.
 
 Matsushita/Panasonic, ... third CD-ROM controller support
@@ -11883,7 +11945,7 @@
   <linux-mtd@lists.infradead.org> if you want to help to make it more
   reliable.
 
-Common Flash Interface (CFI) support
+Detect flash chips by Common Flash Interface (CFI) probe
 CONFIG_MTD_CFI
   The Common Flash Interface specification was developed by Intel,
   AMD and other flash manufactures that provides a universal method
@@ -11940,7 +12002,7 @@
   If your flash chips are interleaved in fours - i.e. you have four
   flash chips addressed by each bus cycle, then say 'Y'.
 
-# Choice: mtd_swap_data
+# Choice: mtd_data_swap
 Flash cmd/query data swapping
 CONFIG_MTD_CFI_NOSWAP
   This option defines the way in which the CPU attempts to arrange
@@ -12080,7 +12142,7 @@
   PNC-2000 is the name of Network Camera product from PHOTRON
   Ltd. in Japan. It uses CFI-compliant flash.
 
-Flash chip mapping on RPXlite PPC board
+Flash chip mapping on RPXlite or CLLF PPC board
 CONFIG_MTD_RPXLITE
   The RPXLite PowerPC board has CFI-compliant chips mapped in
   a strange sparse mapping. This 'mapping' driver supports that
@@ -12156,26 +12218,26 @@
   allow a window into the flash.  Both CFI and JEDEC probes are
   called.
 
-Physical start location of flash mapping
+Physical start location of flash chip mapping
 CONFIG_MTD_CSTM_MIPS_IXX_START
   This is the physical memory location that the MTD driver will
   use for the flash chips on your particular target board. 
   Refer to the memory map which should hopefully be in the 
   documentation for your board.
 
-Physical length of flash mapping
+Physical length of flash chip mapping
 CONFIG_MTD_CSTM_MIPS_IXX_LEN
   This is the total length that the MTD driver will use for the 
   flash chips on your particular board.  Refer to the memory
   map which should hopefully be in the documentation for your
   board.
 
-Physical bus width of flash mapping
+Physical bus width of flash mapping in bytes
 CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH
   This is the total bus width of the mapping of the flash chips
   on your particular board.
 
-Flash chip mapping on Mixcom piggyback card
+JEDEC Flash device mapped on Mixcom piggyback card
 CONFIG_MTD_MIXMEM
   This supports the paging arrangement for access to flash chips
   on the MixCOM piggyback card, allowing the flash chip drivers
@@ -12184,14 +12246,14 @@
   you probably want to enable this mapping driver. More info is at
   <http://www.itc.hu/>.
 
-Flash chip mapping on Octagon 5066 SBC
+JEDEC Flash device mapped on Octagon 5066 SBC
 CONFIG_MTD_OCTAGON
   This provides a 'mapping' driver which supports the way in which
   the flash chips are connected in the Octagon-5066 Single Board
   Computer. More information on the board is available at
   <http://www.octagonsystems.com/Products/5066/5066.html>.
 
-Flash chip mapping on Tempustech VMAX SBC301
+JEDEC Flash device mapped on Tempustech VMAX SBC301
 CONFIG_MTD_VMAX
   This provides a 'mapping' driver which supports the way in which
   the flash chips are connected in the Tempustech VMAX SBC301 Single
@@ -12362,7 +12424,7 @@
   allocating space from Linux's available memory. Otherwise, leave 
   this set to zero. Most people will want to leave this as zero.
 
-Flash chip mapping on the Flaga Digital Module
+CFI Flash device mapping on the Flaga Digital Module
 CONFIG_MTD_CFI_FLAGADM
   Mapping for the Flaga digital module.  If you donīt have one, ignore
   this setting.
@@ -12373,6 +12435,100 @@
   NVRAM on the Momenco Ocelot board.  If you have one of these boards
   and would like access to either of these, say 'Y'.
 
+Support for absent chips in bus mapping
+CONFIG_MTD_ABSENT
+  This option enables support for a dummy probing driver used to
+  allocated placeholder MTD devices on systems that have socketed
+  or removable media.  Use of this driver as a fallback chip probe
+  preserves the expected registration order of MTD device nodes on
+  the system regardless of media presence.  Device nodes created
+  with this driver will return -ENODEV upon access.
+
+MTD emulation using block device
+CONFIG_MTD_BLKMTD
+  This driver allows a block device to appear as an MTD. It would
+  generally be used in the following cases:
+
+    Using Compact Flash as an MTD, these usually present themselves to
+    the system as an ATA drive.
+    Testing MTD users (eg JFFS2) on large media and media that might
+    be removed during a write (using the floppy drive).
+
+Cirrus CDB89712 evaluation board mappings
+CONFIG_MTD_CDB89712
+  This enables access to the flash or ROM chips on the CDB89712 board.
+  If you have such a board, say 'Y'.
+
+Detect non-CFI AMD/JEDEC-compatible flash chips
+CONFIG_MTD_JEDECPROBE
+  This option enables JEDEC-style probing of flash chips which are not
+  compatible with the Common Flash Interface, but will use the common
+  CFI-targetted flash drivers for any chips which are identified which
+  are in fact compatible in all but the probe method. This actually
+  covers most AMD/Fujitsu-compatible chips, and will shortly cover also
+  non-CFI Intel chips (that code is in MTD CVS and should shortly be sent
+  for inclusion in Linus' tree)
+
+BIOS flash chip on Intel L440GX boards
+CONFIG_MTD_L440GX
+  Support for treating the BIOS flash chip on Intel L440GX motherboards
+  as an MTD device - with this you can reprogram your BIOS.
+
+  BE VERY CAREFUL.
+
+28F160xx flash driver for LART
+CONFIG_MTD_LART
+  This enables the flash driver for LART. Please note that you do
+  not need any mapping/chip driver for LART. This one does it all
+  for you, so go disable all of those if you enabled some of them (:
+
+Older (theoretically obsoleted now) drivers for non-CFI chips
+CONFIG_MTD_OBSOLETE_CHIPS
+  This option does not enable any code directly, but will allow you to
+  select some other chip drivers which are now considered obsolete,
+  because the generic CONFIG_JEDEC_PROBE code above should now detect
+  the chips which are supported by these drivers, and allow the generic
+  CFI-compatible drivers to drive the chips. Say 'N' here unless you have
+  already tried the CONFIG_JEDEC_PROBE method and reported its failure
+  to the MTD mailing list at <linux-mtd@lists.infradead.org>
+
+CFI Flash device mapped on Hitachi SolutionEngine
+CONFIG_MTD_SOLUTIONENGINE
+  This enables access to the flash chips on the Hitachi SolutionEngine and
+  similar boards. Say 'Y' if you are building a kernel for such a board.
+
+CFI Flash device mapped on TQM8XXL PPC board
+CONFIG_MTD_TQM8XXL
+  The TQM8xxL PowerPC board has up to two banks of CFI-compliant
+  chips, currently uses AMD one. This 'mapping' driver supports
+  that arrangement, allowing the CFI probe and command set driver
+  code to communicate with the chips on the TQM8xxL board. More at
+  <http://www.denx.de/embedded-ppc-en.html>.
+
+Darkness
+CONFIG_MEMORY_SET
+  This is an option about which you will never be asked a question.
+  Therefore, I conclude that you do not exist - go away.
+
+  There is a grue here.
+
+Physical memory size
+CONFIG_MEMORY_SIZE
+  This sets the default memory size assumed by your SH kernel. It can
+  be overridden as normal by the 'mem=' argument on the kernel command
+  line. If unsure, consult your board specifications or just leave it
+  as 0x00400000 which was the default value before this became
+  configurable.
+
+Cache and PCI noncoherent
+CONFIG_SH_PCIDMA_NONCOHERENT
+  Enable this option if your platform does not have a CPU cache which
+  remains coherent with PCI DMA. It is safest to say 'Y', although you
+  will see better performance if you can say 'N', because the PCI DMA
+  code will not have to flush the CPU's caches. If you have a PCI host
+  bridge integrated with your SH CPU, refer carefully to the chip specs
+  to see if you can say 'N' here. Otherwise, leave it as 'Y'.
+
 USB (Universal Serial Bus) support
 CONFIG_USB
   Universal Serial Bus (USB) is a specification for a serial bus
@@ -12417,7 +12573,7 @@
 
   If you have an APC UPS, say Y; otherwise say N.
 
-USB long timeout
+USB long timeout for slow-responding devices (some MGE Ellipse UPSes)
 CONFIG_USB_LONG_TIMEOUT
   This option makes the standard time out a bit longer.  Basically,
   some devices are just slow to respond, so this makes usb more
@@ -12558,7 +12714,7 @@
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
   The module will be called aiptek.o. If you want to compile it as a
-  module, say M here and read Documentation/modules.txt.
+  module, say M here and read <file:Documentation/modules.txt>.
 
 Use input layer for ADB devices
 CONFIG_INPUT_ADBHID
@@ -12719,7 +12875,7 @@
 CONFIG_USB_SERIAL_VISOR
   Say Y here if you want to connect to your HandSpring Visor, Palm
   m500 or m505 through its USB docking station. See
-  <http://usbvisor.sourceforge.net> for more information on using this
+  <http://usbvisor.sourceforge.net/> for more information on using this
   driver.
 
   This code is also available as a module ( = code which can be
@@ -12755,7 +12911,7 @@
   converter device. The implementation I have is called the USC-1000.
   This driver has also be tested with the 245 and 232 devices.
 
-  See  http://ftdi-usb-sio.sourceforge.net for more
+  See <http://ftdi-usb-sio.sourceforge.net/> for more
   information on this driver and the device.
 
   This code is also available as a module ( = code which can be
@@ -12987,12 +13143,12 @@
   The module will be called ov511.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-USB Communication Class Ethernet driver
+USB Communication Class Ethernet device support
 CONFIG_USB_CDCETHER
   This driver supports devices conforming to the Communication Device
   Class Ethernet Control Model.  This is used in some cable modems.
   For more details on the specification, get the Communication Device
-  Class specification from <http://www.usb.org>.
+  Class specification from <http://www.usb.org/>.
 
   This driver should work with the following devices:
         * Ericsson PipeRider (all variants)
@@ -13056,7 +13212,7 @@
   The module will be called pegasus.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-USB KLSI KL5USB101-based Ethernet device support '
+USB KLSI KL5USB101-based Ethernet device support
 CONFIG_USB_KAWETH
   Say Y here if you want to use one of the following 10Mbps only
   USB Ethernet adapters based on the KLSI KL5KUSB101B chipset:
@@ -13119,7 +13275,7 @@
   Say Y here if you want to connect this type of still camera to your
   computer's USB port.  See <file:Documentation/usb/dc2xx.txt> for
   more information; some non-Kodak cameras may also work with this
-  driver, given application support (such as <http://www.gPhoto.org>).
+  driver, given application support (such as <http://www.gphoto.org/>).
 
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -13130,7 +13286,7 @@
 CONFIG_USB_MDC800
   Say Y here if you want to connect this type of still camera to
   your computer's USB port. This driver can be used with gphoto 0.4.3
-  and higher (look at <http://www.gphoto.org>).
+  and higher (look at <http://www.gphoto.org/>).
   To use it create a device node with "mknod /dev/mustek c 180 32" and
   configure it in your software.
 
@@ -13154,7 +13310,7 @@
   Say Y here in order to have the USB Mass Storage code generate
   verbose debugging messages.
 
-ISD-200 USB/ATA driver
+ISD-200 USB/ATA Bridge support
 CONFIG_USB_STORAGE_ISD200
   Say Y here if you want to use USB Mass Store devices based
   on the In-Systems Design ISD-200 USB/ATA bridge.
@@ -13234,7 +13390,7 @@
 DABUSB driver
 CONFIG_USB_DABUSB
   A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
-  brought to you by the DAB-Team (<http://dab.in.tum.de>).  This
+  brought to you by the DAB-Team (<http://dab.in.tum.de/>).  This
   driver can be taken as an example for URB-based bulk, control, and
   isochronous transactions. URB's are explained in
   <file:Documentation/usb/URB.txt>.
@@ -13274,7 +13430,7 @@
   reader, details at <http://www.microtechint.com/zio/index.html>.
   This driver treats the flash card as a removable storage device.
 
-Sandisk SDDR-09 SmartMedia reader support
+SanDisk SDDR-09 (and other SmartMedia) support
 CONFIG_USB_STORAGE_SDDR09
   Say Y here to include additional code to support the Sandisk SDDR-09
   SmartMedia reader in the USB Mass Storage driver.
@@ -13472,7 +13628,7 @@
   running UML to exchange packets with its host over one of the
   host's Ethertap devices, such as /dev/tap0.  Additional running
   UMLs can use additional Ethertap devices, one per running UML.
-  While the UML believes its on a (multi-device, broadcast) virtual
+  While the UML believes it's on a (multi-device, broadcast) virtual
   Ethernet network, it's in fact communicating over a point-to-point
   link with the host.
 
@@ -13557,7 +13713,7 @@
   and work. SANE 1.0.4 or newer is needed to make use of your scanner.
   This driver can be compiled as a module.
 
-HP 53xx and Minolta Dual Scanner support
+HP53xx and Minolta Dual Scanner support
 CONFIG_USB_HPUSBSCSI
   Say Y here if you want support for the HP 53xx series of scanners
   and the Minolta Scan Dual. This driver is experimental.
@@ -13567,7 +13723,7 @@
 CONFIG_USB_BLUETOOTH
   Say Y here if you want to connect a USB Bluetooth device to your
   computer's USB port. You will need the Bluetooth stack (available
-  at <http://developer.axis.com/software/index.shtml)> to fully use
+  at <http://developer.axis.com/software/index.shtml>) to fully use
   the device.
 
   This code is also available as a module ( = code which can be
@@ -13596,14 +13752,14 @@
 Reiserfs support
 CONFIG_REISERFS_FS
   Stores not just filenames but the files themselves in a balanced
-  tree.  Uses journaling.
+  tree.  Uses journalling.
 
   Balanced trees are more efficient than traditional file system
   architectural foundations.
 
   In general, ReiserFS is as fast as ext2, but is very efficient with
   large directories and small files.  Additional patches are needed
-  for NFS and quotas, please see <http://www.reiserfs.org> for links.
+  for NFS and quotas, please see <http://www.reiserfs.org/> for links.
 
   It is more easily extended to have features currently found in
   database and keyword search systems than block allocation based file
@@ -13611,7 +13767,7 @@
   plugins consistent with our motto ``It takes more than a license to
   make source code open.''
 
-  Read <http://www.reiserfs.org> to learn more about reiserfs.
+  Read <http://www.reiserfs.org/> to learn more about reiserfs.
 
   Sponsored by Threshold Networks, Emusic.com, and Bigstorage.com.
 
@@ -13639,15 +13795,6 @@
   everyone but ReiserFS developers and people fine-tuning reiserfs or
   tracing problems should say N.
 
-Publish some reiserfs-specific info under /proc/fs/reiserfs
-CONFIG_REISERFS_PROC_INFO
-  Create under /proc/fs/reiserfs hierarchy of files, displaying
-  various ReiserFS statistics and internal data on the expense of
-  making your kernel or module slightly larger (+8K). This also increases 
-  amount of kernel memory required for each mount. Almost everyone
-  but ReiserFS developers and people fine-tuning reiserfs or tracing
-  problems should say NO.
-
 Second extended fs support
 CONFIG_EXT2_FS
   This is the de facto standard Linux file system (method to organize
@@ -13677,10 +13824,10 @@
   directories on ext2 file systems, use chattr ("man chattr").
 
   Ext2fs partitions can be read from within DOS using the ext2tool
-  command line tool package (available via FTP (user: anonymous) from
-  <ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2>) and from
+  command line tool package (available from
+  <ftp://ibiblio.org/pub/Linux/system/filesystems/ext2/>) and from
   within Windows NT using the ext2nt command line tool package from
-  <ftp://metalab.unc.edu/pub/Linux/utils/dos>.  Explore2fs is a
+  <ftp://ibiblio.org/pub/Linux/utils/dos/>.  Explore2fs is a
   graphical explorer for ext2fs partitions which runs on Windows 95
   and Windows NT and includes experimental write support; it is
   available from
@@ -13694,13 +13841,13 @@
   be compiled as a module, and so this could be dangerous.  Most
   everyone wants to say Y here.
 
-Ext3 journaling file system support (EXPERIMENTAL)
+Ext3 journalling file system support (EXPERIMENTAL)
 CONFIG_EXT3_FS
-  This is the journaling version of the Second extended file system
+  This is the journalling version of the Second extended file system
   (often called ext3), the de facto standard Linux file system
   (method to organize files on a storage device) for hard disks.
 
-  The journaling code included in this driver means you do not have
+  The journalling code included in this driver means you do not have
   to run e2fsck (file system checker) on your file systems after a
   crash.  The journal keeps track of any changes that were being made
   at the time the system crashed, and can ensure that your file system
@@ -13728,7 +13875,7 @@
 
 Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
 CONFIG_JBD
-  This is a generic journaling layer for block devices.  It is
+  This is a generic journalling layer for block devices.  It is
   currently used by the ext3 file system, but it could also be used to
   add journal support to other file systems or block devices such as
   RAID or LVM.
@@ -13861,7 +14008,7 @@
   which allows for long filenames in unicode format (unicode is the
   new 16 bit character code, successor to ASCII, which encodes the
   characters of almost all languages of the world; see
-  <http://www.unicode.org> for more information).  Say Y here if you
+  <http://www.unicode.org/> for more information).  Say Y here if you
   want to be able to read Joliet CD-ROMs under Linux.
 
 Transparent decompression extension
@@ -13946,7 +14093,7 @@
   Linux, you can either use the DOS emulator DOSEMU, described in the
   DOSEMU-HOWTO, available from
   <http://www.linuxdoc.org/docs.html#howto>, or try dmsdosfs in
-  <ftp://metalab.unc.edu/pub/Linux/system/filesystems/dosfs>. If you
+  <ftp://ibiblio.org/pub/Linux/system/filesystems/dosfs/>. If you
   intend to use dosemu with a non-compressed MSDOS partition, say Y
   here) and MSDOS floppies. This means that file access becomes
   transparent, i.e. the MSDOS files look and behave just like all
@@ -14121,8 +14268,9 @@
   level IP autoconfiguration" above and to "Root file system on NFS"
   below. You cannot compile this driver as a module in this case.
   There are two packages designed for booting diskless machines over
-  the net: netboot and etherboot, both available via FTP from
-  <ftp://metalab.unc.edu/pub/Linux/system/boot/Ethernet/>.
+  the net: netboot, available from
+  <http://ftp1.sourceforge.net/netboot/>, and Etherboot,
+  available from <http://ftp1.sourceforge.net/etherboot/>.
 
   If you don't know what all this is about, say N.
 
@@ -14245,7 +14393,7 @@
   a set of kernel modules that lets you run SCO, Xenix, Wyse,
   UnixWare, Dell Unix and System V programs under Linux.  It is
   available via FTP (user: ftp) from
-  <ftp://ftp.openlinux.org/pub/people/hch/linux-abi>).
+  <ftp://ftp.openlinux.org/pub/people/hch/linux-abi/>).
   NOTE: that will work only for binaries from Intel-based systems;
   PDP ones will have to wait until somebody ports Linux to -11 ;-)
 
@@ -14374,7 +14522,7 @@
   automounter (amd), which is a pure user space daemon.
 
   To use the automounter you need the user-space tools from
-  <ftp://ftp.kernel.org/pub/linux/daemons/autofs/testing-v4>; you also
+  <ftp://ftp.kernel.org/pub/linux/daemons/autofs/testing-v4/>; you also
   want to answer Y to "NFS file system support", below.
 
   If you want to compile this as a module ( = code which can be
@@ -14405,7 +14553,7 @@
 
 Journalling Flash File System (JFFS) support
 CONFIG_JFFS_FS
-  JFFS is the Journaling Flash File System developed by Axis
+  JFFS is the Journalling Flash File System developed by Axis
   Communications in Sweden, aimed at providing a crash/powerdown-safe
   file system for disk-less embedded devices. Further information is
   available at (<http://developer.axis.com/software/jffs/>).
@@ -14438,6 +14586,11 @@
   If reporting bugs, please try to have available a full dump of the
   messages at debug level 1 while the misbehaviour was occurring.
 
+JFFS stats available in /proc filesystem
+CONFIG_JFFS_PROC_FS
+  Enabling this option will cause statistics from mounted JFFS file systems
+  to be made available to the user in the /proc/fs/jffs/ directory.
+
 UFS file system support (read-only)
 CONFIG_UFS_FS
   BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD,
@@ -14522,7 +14675,7 @@
   Say Y here if you would like to use hard disks under Linux which
   were partitioned on a Macintosh.
 
-Windows' Logical Disk Manager (Dynamic Disk) support (EXPERIMENTAL)
+Windows Logical Disk Manager (Dynamic Disk) support (EXPERIMENTAL)
 CONFIG_LDM_PARTITION
   Say Y here if you would like to use hard disks under Linux which
   were partitioned using Windows 2000's or XP's Logical Disk Manager.
@@ -14538,11 +14691,11 @@
   XP.
 
   Technical documentation to accompany this driver is available from:
-  <http://linux-ntfs.sf.net/ldm>.
+  <http://linux-ntfs.sf.net/ldm/>.
 
   If unsure, say N.
 
-Windows' LDM extra logging
+Windows LDM extra logging
 CONFIG_LDM_DEBUG
   Say Y here if you would like LDM to log verbosely.  This could be
   helpful if the driver doesn't work as expected and you'd like to
@@ -14666,7 +14819,6 @@
   Note that the experimental "/dev file system support"
   (CONFIG_DEVFS_FS)  is a more general facility.
 
-# This is for Linus's tree
 FreeVxFS file system support (VERITAS VxFS(TM) compatible)
 CONFIG_VXFS_FS
   FreeVxFS is a file system driver that support the VERITAS VxFS(TM)
@@ -14685,25 +14837,6 @@
   module, say M here and read <file:Documentation/modules.txt>.  If
   unsure, say N. 
 
-# This is for Alan's tree.  Note the name difference.
-FreeVxFS file system support (VERITAS VxFS(TM) compatible)
-CONFIG_FREEVXFS_FS
-  FreeVxFS is a file system driver that support the VERITAS VxFS(TM)
-  file system format.  VERITAS VxFS(TM) is the standard file system
-  of SCO UnixWare (and possibly others) and optionally available
-  for Sunsoft Solaris, HP-UX and many other operating systems.
-  Currently only readonly access is supported.
-
-  NOTE: the file system type as used by mount(1), mount(2) and
-        fstab(5) is 'vxfs' as it describes the filesystem format, not
-        the actual driver.
-
-  This file system is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want).
-  The module is called freevxfs.o.  If you want to compile it as a
-  module, say M here and read <file:Documentation/modules.txt>.  If
-  unsure, say N.
-
 UnixWare slices support
 CONFIG_UNIXWARE_DISKLABEL
   Like some systems, UnixWare uses its own slice table inside a
@@ -14737,8 +14870,8 @@
   Note: if you just want your box to act as an SMB *server* and make
   files and printing services available to Windows clients (which need
   to have a TCP/IP stack), you don't need to say Y here; you can use
-  the program samba (available via FTP (user: anonymous) in
-  <ftp://metalab.unc.edu/pub/Linux/system/network/samba>) for that.
+  the program SAMBA (available from <ftp://ftp.samba.org/pub/samba/>)
+  for that.
 
   General information about how to connect Linux, Windows machines and
   Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
@@ -14787,14 +14920,14 @@
   client and server.  Servers are currently user level, i.e. they need
   no kernel support.  Please read
   <file:Documentation/filesystems/coda.txt> and check out the Coda
-  home page <http://www.coda.cs.cmu.edu>.
+  home page <http://www.coda.cs.cmu.edu/>.
 
   If you want to compile the coda client support as a module ( = code
   which can be inserted in and removed from the running kernel
   whenever you want), say M here and read
   <file:Documentation/modules.txt>.  The module will be called coda.o.
 
-InterMezzo file system support (experimental, replicating fs)
+InterMezzo file system support (replicating fs)
 CONFIG_INTERMEZZO_FS
   InterMezzo is a networked file system with disconnected operation
   and kernel level write back caching.  It is most often used for
@@ -14803,7 +14936,7 @@
 
   If you say Y or M your kernel or module will provide InterMezzo
   support.  You will also need a file server daemon, which you can get
-  from <http://www.inter-mezzo.org>.
+  from <http://www.inter-mezzo.org/>.
 
 NCP file system support (to mount NetWare volumes)
 CONFIG_NCP_FS
@@ -15374,6 +15507,7 @@
   Enable Ethernet support via the Motorola MPC8xx serial
   commmunications controller.
 
+# Choice: scc_ethernet
 Ethernet on SCC1
 CONFIG_SCC1_ENET
   Use MPC8xx serial communications controller 1 to drive Ethernet
@@ -15455,7 +15589,7 @@
 CONFIG_ADB_IOP
   The I/O Processor (IOP) is an Apple custom IC designed to provide
   intelligent support for I/O controllers.  It is described at
-  <http://www.angelfire.com/ca2/dev68k/iopdesc.html;> to enable direct
+  <http://www.angelfire.com/ca2/dev68k/iopdesc.html> to enable direct
   support for it, say 'Y' here.
 
 Mac II style Apple Desktop Bus support
@@ -16150,7 +16284,7 @@
   <file:Documentation/modules.txt>.
   The module will be called i2c-dev.o.
 
-I2C /proc support
+I2C /proc interface (required for hardware sensors)
 CONFIG_I2C_PROC
   This provides support for i2c device entries in the /proc filesystem.
   The entries will be found in /proc/sys/dev/sensors.
@@ -16164,9 +16298,7 @@
   Say Y here if your machine has a bus mouse as opposed to a serial
   mouse. Most people have a regular serial MouseSystem or
   Microsoft mouse (made by Logitech) that plugs into a COM port
-  (rectangular with 9 or 25 pins). These people say N here. If you
-  have something else, read the Busmouse-HOWTO, available from
-  <http://www.linuxdoc.org/docs.html#howto>, and say Y here.
+  (rectangular with 9 or 25 pins). These people say N here. 
 
   If you have a laptop, you either have to check the documentation or
   experiment a bit to find out whether the trackball is a serial mouse
@@ -16231,8 +16363,8 @@
   When using a PS/2 mouse, you can get problems if you want to use the
   mouse both on the Linux console and under X. Using the "-R" option
   of the Linux mouse managing program gpm (available from
-  <ftp://metalab.unc.edu/pub/Linux/system/mouse>) solves this
-  problem, or you can get the "mconv2" utility from the same location.
+  <ftp://gnu.systemy.it/pub/gpm/>) solves this problem, or you can get
+  the "mconv2" utility from <ftp://ibiblio.org/pub/Linux/system/mouse/>.
 
 C&T 82C710 mouse port support (as on TI Travelmate)
 CONFIG_82C710_MOUSE
@@ -16351,7 +16483,7 @@
   Note that the Ftape-HOWTO is out of date (sorry) and documents the
   older version 2.08 of this software but still contains useful
   information.  There is a web page with more recent documentation at
-  <http://www.math1.rwth-aachen.de/~heine/ftape/>.  This page
+  <http://www.instmath.rwth-aachen.de/~heine/ftape/>.  This page
   always contains the latest release of the ftape driver and useful
   information (backup software, ftape related patches and
   documentation, FAQ).  Note that the file system interface has
@@ -16387,7 +16519,7 @@
   file <file:Documentation/ftape.txt> contains a short description of
   the most important changes in the file system interface compared to
   previous versions of ftape.  The ftape home page
-  <http://www-math.math.rwth-aachen.de/~LBFM/claus/ftape/> contains
+  <http://www.instmath.rwth-aachen.de/~heine/ftape/> contains
   further information.
 
   IMPORTANT NOTE: zftape can read archives created by previous
@@ -16630,7 +16762,7 @@
   introduced in XFree86 4.0. If you say Y here, you need to select
   the module that's right for your graphics card from the list below.
   These modules provide support for synchronization, security, and
-  DMA transfers. Please see <http://dri.sourceforge.net> for more
+  DMA transfers. Please see <http://dri.sourceforge.net/> for more
   details.  You should also select and configure AGP
   (/dev/agpgart) support.
 
@@ -17096,9 +17228,9 @@
   in the kernel source.
 
   The watchdog is usually used together with the watchdog daemon
-  which is available via FTP (user: anonymous) from
-  <ftp://tsx-11.mit.edu/pub/linux/sources/sbin/>. This daemon can also
-  monitor NFS connections and can reboot the machine when the process
+  which is available from
+  <ftp://ibiblio.org/pub/Linux/system/daemons/watchdog/>. This daemon can
+  also monitor NFS connections and can reboot the machine when the process
   table is full.
 
   If unsure, say N.
@@ -17172,7 +17304,7 @@
   and if it does, it reboots your computer after a certain amount of
   time. This driver is like the WDT501 driver but for different
   hardware. Please read <file:Documentation/pcwd-watchdog.txt>. The PC
-  watchdog cards can be ordered from <http://www.berkprod.com>.
+  watchdog cards can be ordered from <http://www.berkprod.com/>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17407,7 +17539,6 @@
   The module will be called nvram.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-# Linus tree only
 Joystick support
 CONFIG_JOYSTICK
   If you have a joystick, 6dof controller, gamepad, steering wheel,
@@ -17415,18 +17546,17 @@
   enable generic support for these controllers. You will also need to
   say Y or M to at least one of the hardware specific drivers. This
   will make the controllers available as /dev/input/jsX devices.
-  Please read the file <file:Documentation/joystick.txt> which
+  Please read the file <file:Documentation/input/joystick.txt> which
   contains more information and the location of the joystick package
   that you'll need.
 
-# AC tree only
 Game port support
 CONFIG_INPUT_GAMEPORT
   Gameport support is for the standard 15-pin PC gameport.  If you
   have a joystick, gamepad, gameport card, a soundcard with a gameport
   or anything else that uses the gameport, say Y or M here and also to
   at least one of the hardware specific drivers.
-  Please read the file <file:Documentation/joystick.txt> which
+  Please read the file <file:Documentation/input/joystick.txt> which
   contains more information and the location of the joystick package
   that you'll need if you use the gameport with a joystick.
 
@@ -17439,7 +17569,7 @@
 CONFIG_INPUT_NS558
   Say Y here if you have an ISA or PnP gameport.
   For more information on how to use the driver please read
-  <file:Documentation/joystick.txt>.
+  <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17450,7 +17580,7 @@
 CONFIG_INPUT_LIGHTNING
   Say Y here if you have a PDPI Lightning 4 gamecard. For more
   information on how to use the driver please read
-  <file:Documentation/joystick.txt>.
+  <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17472,7 +17602,7 @@
 CONFIG_INPUT_PCIGAME
   Say Y here if you have a Trident 4DWave DX/NX or Aureal Vortex 1/2
   card. For more information on how to use the driver please read
-  <file:Documentation/joystick.txt>.
+  <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17483,7 +17613,7 @@
 CONFIG_INPUT_EMU10K1
   Say Y here if you have a SoundBlaster Live! card and want to use
   its gameport.  For more information on how to use the driver
-  please read <file:Documentation/joystick.txt>.
+  please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17498,7 +17628,7 @@
   additional hats and buttons compatible with CH Flightstick Pro,
   ThrustMaster FCS, 6 and 8 button gamepads, or Saitek Cyborg
   joysticks.  For more information on how to use the driver please
-  read <file:Documentation/joystick.txt>.
+  read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17509,7 +17639,7 @@
 CONFIG_INPUT_A3D
   Say Y here if you have an FPGaming or MadCatz controller using the
   A3D protocol over the PC gameport.  For more information on how to
-  use the driver please read <file:Documentation/joystick.txt>.
+  use the driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17520,7 +17650,7 @@
 CONFIG_INPUT_ADI
   Say Y here if you have a Logitech controller using the ADI
   protocol over the PC gameport. For more information on how to use
-  the driver please read <file:Documentation/joystick.txt>.
+  the driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17531,7 +17661,7 @@
 CONFIG_INPUT_COBRA
   Say Y here if you have a Creative Labs Blaster Cobra gamepad.
   For more information on how to use the driver please read
-  <file:Documentation/joystick.txt>.
+  <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17542,7 +17672,7 @@
 CONFIG_INPUT_GF2K
   Say Y here if you have a Genius Flight2000 or MaxFighter digitally
   communicating joystick or gamepad.  For more information on how to
-  use the driver please read <file:Documentation/joystick.txt>.
+  use the driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17553,7 +17683,7 @@
 CONFIG_INPUT_GRIP
   Say Y here if you have a Gravis controller using the GrIP protocol
   over the PC gameport.  For more information on how to use the driver
-  please read <file:Documentation/joystick.txt>.
+  please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17564,7 +17694,7 @@
 CONFIG_INPUT_INTERACT
   Say Y hereif you have an InterAct gameport or joystick
   communicating digitally over the gameport.  For more information on
-  how to use the driver please read <file:Documentation/joystick.txt>.
+  how to use the driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17576,7 +17706,7 @@
   Say Y here if you have a ThrustMaster controller using the
   DirectConnect (BSP) protocol over the PC gameport.  For more
   information on how to use the driver please read
-  <file:Documentation/joystick.txt>.
+  <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17587,7 +17717,7 @@
 CONFIG_INPUT_SIDEWINDER
   Say Y here if you have a Microsoft controller using the Digital
   Overdrive protocol over PC gameport.  For more information on how to
-  use the driver please read <file:Documentation/joystick.txt>.
+  use the driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17599,7 +17729,7 @@
   Say Y here and to the Serial port input line discipline option if
   you plan to use a joystick that communicates over the serial (COM)
   port.  For more information on how to use the driver please read
-  <file:Documentation/joystick.txt>.
+  <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17610,7 +17740,7 @@
 CONFIG_INPUT_SERPORT
   Say Y here if you plan to use a joystick that communicates over the
   serial (COM) port.  For more information on how to use the driver
-  please read <file:Documentation/joystick.txt>.
+  please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17621,7 +17751,7 @@
 CONFIG_INPUT_WARRIOR
   Say Y here if you have a Logitech WingMan Warrior joystick connected
   to your computer's serial port.  For more information on how to use
-  the driver please read <file:Documentation/joystick.txt>.
+  the driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17632,7 +17762,7 @@
 CONFIG_INPUT_MAGELLAN
   Say Y here if you have a Magellan or Space Mouse 6DOF controller
   connected to your computer's serial port.  For more information on
-  how to use the driver please read <file:Documentation/joystick.txt>.
+  how to use the driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17644,7 +17774,7 @@
   Say Y here if you have a SpaceOrb 360 or SpaceBall Avenger 6DOF
   controller connected to your computer's serial port.  For more
   information on how to use the driver please read
-  <file:Documentation/joystick.txt>.
+  <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17655,7 +17785,7 @@
 CONFIG_INPUT_SPACEBALL
   Say Y here if you have a SpaceTec SpaceBall 4000 FLX controller
   connected to your computer's serial port.  For more information on
-  how to use the driver please read <file:Documentation/joystick.txt>.
+  how to use the driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17666,7 +17796,7 @@
 CONFIG_INPUT_STINGER
   Say Y here if you have a Gravis Stinger connected to one of your
   serial ports.  For more information on how to use the driver please
-  read <file:Documentation/joystick.txt>.
+  read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17677,7 +17807,7 @@
 CONFIG_INPUT_IFORCE_232
   Say Y here if you have an I-Force joystick or steering wheel
   connected to your serial (COM) port.  For more information on how
-  to use the driver please read <file:Documentation/joystick.txt>.
+  to use the driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17688,7 +17818,7 @@
 CONFIG_INPUT_IFORCE_USB
   Say Y here if you have an I-Force joystick or steering wheel
   connected to your USB port.  For more information on how to use the
-  driver please read <file:Documentation/joystick.txt>.
+  driver please read <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17701,8 +17831,8 @@
   gamepad, Sega Saturn gamepad, or a Multisystem -- Atari, Amiga,
   Commodore, Amstrad CPC joystick connected to your parallel port.
   For more information on how to use the driver please read
-  <file:Documentation/joystick.txt> and
-  <file:Documentation/joystick-parport.txt>.
+  <file:Documentation/input/joystick.txt> and
+  <file:Documentation/input/joystick-parport.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17716,8 +17846,8 @@
   Sony PlayStation gamepad or a Multisystem -- Atari, Amiga,
   Commodore, Amstrad CPC joystick connected to your parallel port.
   For more information on how to use the driver please read
-  <file:Documentation/joystick.txt> and
-  <file:Documentation/joystick-parport.txt>.
+  <file:Documentation/input/joystick.txt> and
+  <file:Documentation/input/joystick-parport.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17729,8 +17859,8 @@
   Say Y here if you have the TurboGraFX interface by Steffen Schwenke,
   and want to use it with Multisystem -- Atari, Amiga, Commodore,
   Amstrad CPC joystick.  For more information on how to use the driver
-  please read <file:Documentation/joystick.txt> and
-  <file:Documentation/joystick-parport.txt>.
+  please read <file:Documentation/input/joystick.txt> and
+  <file:Documentation/input/joystick-parport.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -17741,7 +17871,7 @@
 CONFIG_INPUT_AMIJOY
   Say Y here if you have an Amiga with a digital joystick connected
   to it.  For more information on how to use the driver please read
-  <file:Documentation/joystick.txt>.
+  <file:Documentation/input/joystick.txt>.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -18314,7 +18444,7 @@
   questions.
 
   Read the <file:Documentation/sound/README.OSS> file and the head of
-  <file:drivers/sound/lowlevel/aedsp16.c> as well as
+  <file:drivers/sound/aedsp16.c> as well as
   <file:Documentation/sound/AudioExcelDSP16> to get more information
   about this driver and its configuration.
 
@@ -18373,12 +18503,20 @@
   or the CMI8378 chipset.  Data on these chips are available at
   <http://www.cmedia.com.tw/>.
 
+  A userspace utility to control some internal registers of these
+  chips is available at
+  <http://member.nifty.ne.jp/Breeze/softwares/unix/cmictl-e.html>.
+
 Support CMI8738 based audio cards
 CONFIG_SOUND_CMPCI_CM8738
   Say Y or M if you have a PCI sound card using the CMI8338
   or the CMI8378 chipset.  Data on this chip is available at
   <http://www.cmedia.com.tw/doc8738.htm>.
 
+  A userspace utility to control some internal registers of these
+  chips is available at
+  <http://member.nifty.ne.jp/Breeze/softwares/unix/cmictl-e.html>.
+
 Enable joystick
 CONFIG_SOUND_CMPCI_JOYSTICK
   Say here in order to enable the joystick port on a sound crd using
@@ -18396,13 +18534,19 @@
   "The 8738 Audio SPDIF In/Out Technical Data" on the technical
   support page at <http://www.cmedia.com.tw/>.
 
+  A userspace utility to control even more internal registers of these
+  chips is available at
+  <http://member.nifty.ne.jp/Breeze/softwares/unix/cmictl-e.html>.
+  This package will among other things help you enable SPDIF 
+  out/in/loop/monitor.
+
 Creative SBLive! (EMU10K1) based PCI sound cards
 CONFIG_SOUND_EMU10K1
   Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
   such as the Creative SBLive!, SB PCI512 or Emu-APS.
 
   For more information on this driver and the degree of support for the
-  different card models please check <http://opensource.creative.com>.
+  different card models please check <http://opensource.creative.com/>.
 
   It is now possible to load dsp microcode patches into the EMU10K1
   chip.  These patches are used to implement real time sound
@@ -18411,7 +18555,7 @@
   Userspace tools to create new patches and load/unload them can be
   found at <http://opensource.creative.com/dist.html>.
 
-Creative EMU10K1 MIDI
+Creative SBLive! (EMU10K1) MIDI
 CONFIG_MIDI_EMU10K1
   Say Y if you want to be able to use the OSS /dev/sequencer
   interface.  This code is still experimental.
@@ -18635,7 +18779,7 @@
 
 Support for ITE 8172G board
 CONFIG_MIPS_ITE8172
-  Ths is an evaluation board made by ITE (http://www.ite.com.tw/)
+  Ths is an evaluation board made by ITE <http://www.ite.com.tw/>
   with ATX form factor that utilizes a MIPS R5000 to work with its
   ITE8172G companion internet appliance chip. The MIPS core can be
   either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build
@@ -18664,20 +18808,21 @@
   website at <http://www.realitydiluted.com/projects/nino/index.html>
   will have more information.
 
-Model-500/510
-CONFIG_NINO_16MB
-  Say Y here to build a kernel specifically for Nino 500/501 color
-  Palm PCs from Philips (INCOMPLETE).
+# Choice: nino_model
+CONFIG_NINO_4MB
+  Say Y here to build a kernel specifically for Nino Palm PCs with
+  4MB of memory. These include models 300/301/302/319.
 
 Model-200/210/312/320/325/350/390
 CONFIG_NINO_8MB
   Say Y here to build a kernel specifically for Nino Palm PCs with
   8MB of memory. These include models 200/210/312/320/325/350/390.
 
+Model-500/510
+CONFIG_NINO_16MB
+  Say Y here to build a kernel specifically for Nino 500/501 color
+  Palm PCs from Philips (INCOMPLETE).
 Model-300/301/302/319
-CONFIG_NINO_4MB
-  Say Y here to build a kernel specifically for Nino Palm PCs with
-  4MB of memory. These include models 300/301/302/319.
 
 Low-level debugging
 CONFIG_LL_DEBUG
@@ -19123,7 +19268,7 @@
   This enables the PCMCIA client driver for the Sedlbauer Speed Star
   and Speed Star II cards.
 
-ST5481 USB ISDN adapter
+ST5481 USB ISDN modem
 CONFIG_HISAX_ST5481
   This enables the driver for ST5481 based USB ISDN adapters,
   e.g. the BeWan Gazel 128 USB
@@ -19149,7 +19294,7 @@
   can be inserted in and removed from the running kernel whenever you
   want, details in <file:Documentation/modules.txt>); the module will
   be called sc.o.  See <file:Documentation/isdn/README.sc> and
-  <http://www.spellcast.com> for more information.
+  <http://www.spellcast.com/> for more information.
 
 Eicon active card support
 CONFIG_ISDN_DRV_EICON
@@ -19291,7 +19436,7 @@
   This enables support for the Auvertech TurboPAM ISDN-card.
   For running this card, additional firmware is necessary, which has
   to be downloaded into the card using a utility which is distributed
-  separately from the Auvertech's web site: <http://www.auvertech.fr>.
+  separately from the Auvertech's web site: <http://www.auvertech.fr/>.
 
   Please redirect all support questions to support@auvertech.fr.
 
@@ -19486,7 +19631,7 @@
   It was designed as a replacement for cables and other short-range
   technologies like IrDA.  Bluetooth operates in personal area range
   that typically extends up to 10 meters.  More information about
-  Bluetooth can be found at <http://www.bluetooth.com>.
+  Bluetooth can be found at <http://www.bluetooth.com/>.
 
   Linux Bluetooth subsystem consist of several layers:
                HCI Core (device and connection manager, scheduler)
@@ -19499,7 +19644,7 @@
   To use Linux Bluetooth subsystem, you will need several user-space
   utilities like hciconfig and hcid.  These utilities and updates to
   Bluetooth kernel modules are provided in the BlueZ package.
-  For more information, see <http://bluez.sf.net>.
+  For more information, see <http://bluez.sourceforge.net/>.
 
   If you want to compile HCI Core as module (hci.o) say M here.
 
@@ -19541,62 +19686,6 @@
 # The following options are for Linux when running on the Hitachi
 # SuperH family of RISC microprocessors.
 
-CPU Selection
-CONFIG_CPU_SUBTYPE_SH7707
-  This is the type of your Hitachi SuperH processor. This information is
-  used for optimizing and configuration purposes.
-
-  - "SH7707" for SH7707
-  - "SH7708" for SH7708, SH7708S, SH7708R
-  - "SH7709" for SH7707, SH7709, SH7709A, and SH7729.
-  - "SH7750" for SH7750, SH7750S
-  - "SH7751" for SH7751
-  - "ST40STB1" for ST40STB1
-
-Target machine selection
-CONFIG_SH_GENERIC
-  This is machine type of your target.
-
-  - "Generic" for Generic kernel which might support all of them
-  - "SolutionEngine" for Hitachi SolutionEngine (7709A, 7750, 7750S)
-  - "SolutionEngine7751" for Hitachi SolutionEngine (7751)
-  - "STB1_Harp" for STMicroelectronics HARP
-  - "STB1_Overdrive" for STMicroelectronics Overdrive
-  - "HP620" for HP 'Jornada' 620
-  - "HP680" for HP 'Jornada' 680
-  - "HP690" for HP 'Jornada' 690
-  - "CqREEK" for CQ Publishing CqREEK SH-4
-  - "DMIDA" for DMIDA, industrial data assistant
-  - "EC3104" for Compaq Aero 8000
-  - "Dreamcast" for SEGA Dreamcast
-  - "CAT68701" for CAT 68701 Evaluation Board (SH7708)
-  - "BigSur" for Big Sur Evaluation Board
-  - "SH2000" for SH2000 Evaluation Board (SH7709A)
-  - "ADX" for A&D ADX
-  - "BareCPU" for Bare CPU board such as CqREEK SH-3
-
-  If unsure, select "BareCPU".
-
-Physical memory start address
-CONFIG_MEMORY_START
-  Computers built with Hitachi SuperH processors always
-  map the ROM starting at address zero.  But the processor
-  does not specify the range that RAM takes.  RAM is usually
-  mapped starting at 0c000000, but it may be elsewhere.
-
-  You should set this value to the address of the lowest
-  RAM location.
-
-  A value of 0c000000 will work for most boards.
-
-Directly Connected Compact Flash support
-CONFIG_CF_ENABLER
-  If your board has "Directly Connected" CompactFlash at area 5 or 6, 
-  you may want to enable this option.  Then, you can use CF as
-  primary IDE drive (only tested for SanDisk).
-
-  If in doubt, press "n".
-
 SuperH RTC support
 CONFIG_SH_RTC
   Selecting this option will allow the Linux kernel to emulate
@@ -19611,38 +19700,7 @@
 
   If unsure, say N.
 
-SuperH SCI (serial) support
-CONFIG_SH_SCI
-  Selecting this option will allow the Linux kernel to transfer
-  data over SCI (Serial Communication Interface) and/or SCIF
-  which are built into the Hitachi SuperH processor.
-
-  If unsure, say N.
-
-Use LinuxSH standard BIOS
-CONFIG_SH_STANDARD_BIOS
-  Say Y here if your target has the gdb-sh-stub package from
-  www.m17n.org (or any conforming standard LinuxSH BIOS) in FLASH
-  or EPROM.  The kernel will use standard BIOS calls during boot
-  for various housekeeping tasks.  Note this does not work with
-  WindowsCE machines.  If unsure, say N.
-
-Early printk support
-CONFIG_SH_EARLY_PRINTK
-  If you say Y here, the kernel printk routine will begin output to
-  the console much earlier in the boot process, before the serial
-  console is initialised, instead of buffering output.  Standard
-  LinuxSH BIOS calls are used for the output.  This helps when
-  debugging fatal problems early in the boot sequence.  This is only
-  useful for kernel hackers.  If unsure, say N.
-  
-National Semiconductor DP83902AV 'ST-NIC' support
-CONFIG_STNIC
-  If you have a network adaptor with National Semiconductor DP83902AV, 
-  say Y or M (for module).
-
-  If unsure, say N.
-
+# Choice: cf_area
 CompactFlash Connection Area
 CONFIG_CF_AREA5
   If your board has "Directly Connected" CompactFlash, You should
@@ -19724,6 +19782,12 @@
   Q60. Select your CPU below.  For 68LC060 don't forget to enable FPU
   emulation.
 
+Q40/Q60 IDE interface support
+CONFIG_BLK_DEV_Q40IDE
+  Enable the on-board IDE controller in the Q40/Q60.  This should
+  normally be on; disable it only if you are running a custom hard
+  drive subsystem through an expansion card.
+
 Sun 3 support
 CONFIG_SUN3
   This option enables support for the Sun 3 series of workstations.
@@ -20332,7 +20396,7 @@
 
   If in doubt, say N.
 
-# Choice: Machine type
+# Choice: ppc4xxtype
 Oak
 CONFIG_OAK
   Select Oak if you have an IBM 403GCX "Oak" Evaluation Board.
@@ -20377,13 +20441,14 @@
 
   If in doubt, say N here.
 
-MPC8xx IDE support
+MPC8xx direct IDE support on PCMCIA port
 CONFIG_BLK_DEV_MPC8xx_IDE
   This option provides support for IDE on Motorola MPC8xx Systems.
   Please see 'Type of MPC8xx IDE interface' for details.
 
   If unsure, say N.
 
+# Choice: mpc8xxtype
 Type of MPC8xx IDE interface
 CONFIG_IDE_8xx_PCCARD
   Select how the IDE devices are connected to the MPC8xx system:
@@ -20444,7 +20509,7 @@
   <http://www.synergymicro.com/PressRel/97_10_15.html>.
 
   Select APUS if configuring for a PowerUP Amiga.  More information is
-  available at: <http://linux-apus.sourceforge.net>.
+  available at: <http://linux-apus.sourceforge.net/>.
 
 Synergy-Gemini
 CONFIG_GEMINI
@@ -20456,124 +20521,9 @@
 CONFIG_APUS
   Select APUS if configuring for a PowerUP Amiga.
   More information is available at:
-  <http://linux-apus.sourceforge.net>.
-
-Embedded 8xx Board Type
-CONFIG_RPXLITE
-  RPX-Lite:
-    Embedded Planet RPX Lite
-
-  RPX-Classic:
-    Embedded Planet RPX Classic Low-fat.
+  <http://linux-apus.sourceforge.net/>.
 
-  BSE-IP: 
-    Bright Star Engineering ip-Engine.
-
-  TQM823L:
-  TQM850L:
-  TQM855L:
-  TQM860L:
-    MPC8xx based family of mini modules, half credit card size,
-    up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports,
-    2 x CAN bus interface, ...
-      Manufacturer: TQ Components, www.tq-group.de
-      Date of Release: October (?) 1999
-      End of Life: not yet :-)
-      URL:
-      - module: http://www.denx.de/PDF/TQM8xxLHWM201.pdf
-      - starter kit: http://www.denx.de/PDF/STK8xxLHWM201.pdf
-      - images: http://www.denx.de/embedded-ppc-en.html
-
-  FPS850L:
-    FingerPrint Sensor System (based on TQM850L)
-      Manufacturer: IKENDI AG, http://www.ikendi.com/
-      Date of Release: November 1999
-      End of life: end 2000 ?
-      URL: see TQM850L
-
-  SPD823TS:
-    MPC823 based board used in the "Tele Server" product
-    Manufacturer: Speech Design, http://www.speech-design.de/
-    Date of Release: Mid 2000 (?)
-    End of life: -
-    URL: http://www.speech-design.de/
-         select "English", then "Teleteam Solutions", then "TeleServer"
-
-  IVMS8:
-    MPC860 based board used in the "Integrated Voice Mail System",
-    Small Version (8 voice channels)
-    Manufacturer: Speech Design, http://www.speech-design.de/
-    Date of Release: December 2000 (?)
-    End of life: -
-    URL: http://www.speech-design.de/
-
-  IVML24:
-    MPC860 based board used in the "Integrated Voice Mail System", 
-    Large Version (24 voice channels)
-    Manufacturer: Speech Design, http://www.speech-design.de/
-    Date of Release: March 2001  (?)
-    End of life: -
-    URL: http://www.speech-design.de/
-
-  SM850:
-    Service Module (based on TQM850L)
-    Manufacturer: Dependable Computer Systems, http://www.decomsys.com/
-    Date of Release: end 2000 (?)
-    End of life: mid 2001 (?)
-    URL: http://www.tz-mikroelektronik.de/ServiceModule/index.html
-
-  HERMES:
-    Hermes-Pro ISDN/LAN router with integrated 8 x hub
-    Manufacturer: Multidata Gesellschaft für Datentechnik und Informatik
-      http://www.multidata.de/
-    Date of Release: 2000 (?)
-    End of life: -
-    URL: http://www.multidata.de/english/products/hpro.htm
-
-  IP860:	
-    VMEBus IP (Industry Pack) carrier board with MPC860
-    Manufacturer: MicroSys GmbH, http://www.microsys.de/
-    Date of Release: ?
-    End of life: -
-    URL: http://www.microsys.de/html/ip860.html
-
-  PCU_E:
-    PCU = Peripheral Controller Unit, Extended
-    Manufacturer: Siemens AG, ICN (Information and Communication Networks)
-    	http://www.siemens.de/page/1,3771,224315-1-999_2_226207-0,00.html
-    Date of Release: April 2001
-    End of life: August 2001
-    URL: n. a.
-
-Embedded 82xx Board Type
-CONFIG_EST8260
-  EST8260: Wind River System, Inc. EST SBC8260
-
-  TQM8260:
-    MPC8260 based module, little larger than credit card,
-    up to 128 MB global + 64 MB local RAM, 32 MB Flash,
-    32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet,
-    2 x serial ports, ...
-      Manufacturer: TQ Components, www.tq-group.de
-      Date of Release: June 2001
-      End of Life: not yet :-)
-      URL: http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf
-
-  PM826:
-    Modular system with MPC8260 CPU
-    Manufacturer: MicroSys GmbH, http://www.microsys.de/
-    Date of Release: mid 2001
-    End of life: -
-    URL: http://www.microsys.de/html/pm826.html
-
-  CU824:
-    VMEBus Board with PCI extension with MPC8240 CPU
-    Manufacturer: MicroSys GmbH, http://www.microsys.de/
-    Date of Release: early 2001 (?)
-    End of life: -
-    URL: http://www.microsys.de/html/cu824.html
-
-AltiVec Kernel Support
+AltiVec kernel support
 CONFIG_ALTIVEC
   This option enables kernel support for the Altivec extensions to the
   PowerPC processor. The kernel currently supports saving and restoring
@@ -20645,26 +20595,97 @@
   change the screen brightness.
 
 # Choice: ppc8xxtype
-RPX-Lite
+Embedded 8xx Board Type
 CONFIG_RPXLITE
   Single-board computers based around the PowerPC MPC8xx chips and
   intended for embedded applications.  The following types are
   supported:
 
-    RPX-Lite    -- PC104 form-factor SBC based on the MPC823
-    RPX-Classic -- Credit-card-size SBC based on the MPC 860
-    BSE-IP      -- Bright Star Engineering BSE-IP SBC
-    TQM823L     -- TQM823L SBC from TQ Components
-    TQM850L     -- TQM850L SBC from TQ Components
-    TQM855L     -- TQM855L SBC from TQ Components
-    TQM860L     -- TQM860L SBC from TQ Components
-    FPS850L	-- FingerPrint Sensor from TQ Components
-    TQM860      -- TQM860 SBC from IKENDI AG
-    SPD823TS	-- Speech Design TeleServer from Speech Design
-    IVMS8	-- Integrated VoiceMail SBC from Speech Design
-    SM850       -- Service Module 850 from Dependable Computer Systems
-    MBX         -- MBX821 and MBX860 SBCs
-    Wincept     -- Wincept SBCs for thin-client machines
+  RPX-Lite:
+    Embedded Planet RPX Lite. PC104 form-factor SBC based on the MPC823.
+
+  RPX-Classic:
+    Embedded Planet RPX Classic Low-fat. Credit-card-size SBC based on 
+    the MPC 860
+
+  BSE-IP: 
+    Bright Star Engineering ip-Engine.
+
+  TQM823L:
+  TQM850L:
+  TQM855L:
+  TQM860L:
+    MPC8xx based family of mini modules, half credit card size,
+    up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports,
+    2 x CAN bus interface, ...
+      Manufacturer: TQ Components, www.tq-group.de
+      Date of Release: October (?) 1999
+      End of Life: not yet :-)
+      URL:
+      - module: <http://www.denx.de/PDF/TQM8xxLHWM201.pdf>
+      - starter kit: <http://www.denx.de/PDF/STK8xxLHWM201.pdf>
+      - images: <http://www.denx.de/embedded-ppc-en.html>
+
+  FPS850L:
+    FingerPrint Sensor System (based on TQM850L)
+      Manufacturer: IKENDI AG, <http://www.ikendi.com/>
+      Date of Release: November 1999
+      End of life: end 2000 ?
+      URL: see TQM850L
+
+  SPD823TS:
+    MPC823 based board used in the "Tele Server" product
+    Manufacturer: Speech Design, <http://www.speech-design.de/>
+    Date of Release: Mid 2000 (?)
+    End of life: -
+    URL: <http://www.speech-design.de/>
+         select "English", then "Teleteam Solutions", then "TeleServer"
+
+  IVMS8:
+    MPC860 based board used in the "Integrated Voice Mail System",
+    Small Version (8 voice channels)
+    Manufacturer: Speech Design, <http://www.speech-design.de/>
+    Date of Release: December 2000 (?)
+    End of life: -
+    URL: <http://www.speech-design.de/>
+
+  IVML24:
+    MPC860 based board used in the "Integrated Voice Mail System", 
+    Large Version (24 voice channels)
+    Manufacturer: Speech Design, <http://www.speech-design.de/>
+    Date of Release: March 2001  (?)
+    End of life: -
+    URL: <http://www.speech-design.de/>
+
+  SM850:
+    Service Module (based on TQM850L)
+    Manufacturer: Dependable Computer Systems, <http://www.decomsys.com/>
+    Date of Release: end 2000 (?)
+    End of life: mid 2001 (?)
+    URL: <http://www.tz-mikroelektronik.de/ServiceModule/index.html>
+
+  HERMES:
+    Hermes-Pro ISDN/LAN router with integrated 8 x hub
+    Manufacturer: Multidata Gesellschaft für Datentechnik und Informatik
+      <http://www.multidata.de/>
+    Date of Release: 2000 (?)
+    End of life: -
+    URL: <http://www.multidata.de/english/products/hpro.htm>
+
+  IP860:	
+    VMEBus IP (Industry Pack) carrier board with MPC860
+    Manufacturer: MicroSys GmbH, <http://www.microsys.de/>
+    Date of Release: ?
+    End of life: -
+    URL: <http://www.microsys.de/html/ip860.html>
+
+  PCU_E:
+    PCU = Peripheral Controller Unit, Extended
+    Manufacturer: Siemens AG, ICN (Information and Communication Networks)
+    	<http://www.siemens.de/page/1,3771,224315-1-999_2_226207-0,00.html>
+    Date of Release: April 2001
+    End of life: August 2001
+    URL: n. a.
 
 RPX-Classic
 CONFIG_RPXCLASSIC
@@ -20792,7 +20813,7 @@
 #         Manufacturer: MicroSys GmbH, <http://www.microsys.de/>
 #         Date of Release: early 2001 (?)
 #         End of life: -
-#         URL: <http://www.microsys.de/html/cu824.html
+#         URL: <http://www.microsys.de/html/cu824.html>
 #
 # PM826:
 #         Modular system with MPC8260 CPU
@@ -20811,13 +20832,39 @@
 #         End of life: -
 #         URL: n. a.o
 
-Support for EST8260
+# Choice: ppc82xxtype
+Embedded 82xx Board Type
 CONFIG_EST8260
-  The EST8260 is a single-board computer manufactured by Wind River
-  Systems, Inc. (formerly Embedded Support Tools Corp.) and based on
-  the MPC8260.  Wind River Systems has a website at
-  <http://www.windriver.com/>, but the EST8260 cannot be found on it
-  and has probably been discontinued or rebadged.
+  EST8260:
+    The EST8260 is a single-board computer manufactured by Wind River
+    Systems, Inc. (formerly Embedded Support Tools Corp.) and based on
+    the MPC8260.  Wind River Systems has a website at
+    <http://www.windriver.com/>, but the EST8260 cannot be found on it
+    and has probably been discontinued or rebadged.
+
+  TQM8260:
+    MPC8260 based module, little larger than credit card,
+    up to 128 MB global + 64 MB local RAM, 32 MB Flash,
+    32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet,
+    2 x serial ports, ...
+      Manufacturer: TQ Components, www.tq-group.de
+      Date of Release: June 2001
+      End of Life: not yet :-)
+      URL: <http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf>
+
+  PM826:
+    Modular system with MPC8260 CPU
+    Manufacturer: MicroSys GmbH, <http://www.microsys.de/>
+    Date of Release: mid 2001
+    End of life: -
+    URL: <http://www.microsys.de/html/pm826.html>
+
+  CU824:
+    VMEBus Board with PCI extension with MPC8240 CPU
+    Manufacturer: MicroSys GmbH, http://www.microsys.de/
+    Date of Release: early 2001 (?)
+    End of life: -
+    URL: <http://www.microsys.de/html/cu824.html>
 
 ADB raw keycode support
 CONFIG_MAC_ADBKEYCODES
@@ -20831,6 +20878,13 @@
 
   If unsure, say Y here.
 
+I2C/SPI Microcode Patch
+CONFIG_UCODE_PATCH
+  Motorola releases microcode updates for their 8xx CPM modules.  The
+  microcode update file has updates for IIC, SMC and USB.  Currently only
+  the USB update is available by default, if the MPC8xx USB option is
+  enabled.  If in doubt, say 'N' here.
+
 Mouse button 2+3 emulation support
 CONFIG_MAC_EMUMOUSEBTN
   This provides generic support for emulating the 2nd and 3rd mouse
@@ -20974,7 +21028,7 @@
   Support for audio/video capture and overlay devices and FM radio
   cards. The exact capabilities of each device vary. User tools for
   this are available from
-  <ftp://ftp.uk.linux.org/pub/linux/video4linux>.
+  <ftp://ftp.uk.linux.org/pub/linux/video4linux/>.
 
   If you are interested in writing a driver for such an audio/video
   device or user software interacting with such a driver, please read
@@ -21214,7 +21268,7 @@
 Guillemot MAXI Radio FM 2000 Radio Card
 CONFIG_RADIO_MAXIRADIO
   Choose Y here if you have this radio card.  This card may also be
-  found as Gemtek PCI FM.
+  found as GemTek PCI FM.
 
   In order to control your radio card, you will need to use programs
   that are compatible with the Video For Linux API.  Information on
@@ -21245,10 +21299,10 @@
 CONFIG_RADIO_GEMTEK_PORT
   Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is
   0x34c, if you haven't changed the jumper setting on the card. On
-  Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O
+  Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM GemTek), the I/O
   port is 0x28c.
 
-Gemtek PCI Radio
+GemTek PCI Radio Card support
 CONFIG_RADIO_GEMTEK_PCI
   Choose Y here if you have this PCI FM radio card.
 
@@ -21326,7 +21380,7 @@
   whenever you want). If you want to compile it as a module, say M
   here and read <file:Documentation/modules.txt>.
 
-BT878 Audio DMA
+BT878 audio DMA
 CONFIG_SOUND_BT878
   Audio DMA support for bt878 based grabber boards.  As you might have
   already noticed, bt878 is listed with two functions in /proc/pci.
@@ -21360,7 +21414,7 @@
   Miro DC10 and DC30 video capture cards).
 
 Include support for Iomega Buz
-CONFIG_VIDEO_BUZ
+CONFIG_VIDEO_ZORAN_BUZ
   Say Y here to include support for the Iomega Buz video card.  There
   is a Buz/Linux homepage at <http://www.lysator.liu.se/~gz/buz/>.
 
@@ -21453,7 +21507,7 @@
   it as a module, say M here and read
   <file:Documentation/modules.txt>.
 
-Sony Vaio Picturebook Motion Eye Video for Linux
+Sony Vaio Picturebook Motion Eye Video For Linux
 CONFIG_VIDEO_MEYE
   This is the video4linux driver for the Motion Eye camera found
   in the Vaio Picturebook laptops. Please read the material in
@@ -21516,16 +21570,16 @@
   attached to another IBM mainframe operation system (OS/390, 
   VM/ESA, VSE/ESA).
 
-ECKD devices
+Support for ECKD hard disks
 CONFIG_DASD_ECKD
-  ECKD devices are the most commonly used devices. you should enable
-  this option unless you are very sure to have no ECKD device.
+  ECKD devices are the most commonly used devices. You should enable
+  this option unless you are very sure you have no ECKD device.
 
 CKD devices
 CONFIG_DASD_CKD
   CKD devices are currently unsupported.
 
-FBA devices
+Support for FBA hard disks
 CONFIG_DASD_FBA
   FBA devices are currently unsupported.
 
@@ -21538,25 +21592,23 @@
   CONFIG_IPLABE.
 
 Support for 3215 line mode terminal
-CONFIG_3215
-  Include support for IBM 3215 line-mode terminals.  Can't be used
-  if 3270 console support is chosen.
+CONFIG_TN3215
+  Include support for IBM 3215 line-mode terminals.
 
 Support for console on 3215 line mode terminal
-CONFIG_3215_CONSOLE
-  Include support for using an IBM 3215 line-mode terminal as the
-  Linux system console.  Can't be used if 3270 console support is
-  chosen.
+CONFIG_TN3215_CONSOLE
+  Include support for using an IBM 3215 line-mode terminal as a
+  Linux system console.
 
 Support for 3270 line mode terminal
-CONFIG_3270
+CONFIG_TN3270
   Include support for IBM 3270 line-mode terminals.
 
 Support for console on 3270 line mode terminal
-CONFIG_3270_CONSOLE
-  Include support for using an IBM 3270 line-mode terminal as the
-  Linux system console.  Excludes using 3215s.  Available only if 3270
-  support is compiled in statically.
+CONFIG_TN3270_CONSOLE
+  Include support for using an IBM 3270 line-mode terminal as a Linux
+  system console.  Available only if 3270 support is compiled in
+  statically.
 
 Support for HWC line mode terminal
 CONFIG_HWC
@@ -21807,7 +21859,7 @@
   There are no product plans beyond the current research
   prototypes at this time.  Information is available at:
 
-  <http://crl.research.compaq.com/projects/personalserver>
+  <http://crl.research.compaq.com/projects/personalserver/>
 
   If you have any questions or comments about the  Compaq Personal
   Server, send e-mail to skiff@crl.dec.com.
@@ -21858,6 +21910,12 @@
   Say Y if configuring for an Intrinsyc CerfBoard.
   Say N otherwise.
 
+FlexaNet
+CONFIG_SA1100_FLEXANET
+  Say Y here if you intend to run this kernel on the FlexaNet
+  handheld instruments. Information about this machine can be
+  found at: <http://www.flexanet.com/>.
+
 nanoEngine
 CONFIG_SA1100_NANOENGINE
   The nanoEngine is a StrongARM 1110-based single board computer
@@ -21884,6 +21942,38 @@
   <http://www.visuaide.com/pagevictor.en.html> for information on
   this system.
 
+# Choice: cerf_ram
+Cerf on-board RAM size
+CONFIG_SA1100_CERF_8MB
+   Declare the size of the CerfBoard's on-board RAM.
+   Alternatives are 8, 16, 32, and 64MB.
+
+16MB
+CONFIG_SA1100_CERF_16MB
+   Declare that the CerfBoard has 16MB RAM.
+
+32MB
+CONFIG_SA1100_CERF_32MB
+   Declare that the CerfBoard has 32MB RAM.
+
+64MB
+CONFIG_SA1100_CERF_64MB
+   Declare that the CerfBoard has 64MB RAM.
+
+# Choice: cerf_flash
+Cerf flash memory size
+CONFIG_SA1100_CERF_FLASH_8MB
+  Tell the Cerf kernel the size of on-board memory.  The choices
+  are 8MB, 16MB, or 32MB.
+
+16MB
+CONFIG_SA1100_CERF_FLASH_16MB
+  Configure the Cerf kernel to expect 16MB of flash memory.
+
+32MB
+CONFIG_SA1100_CERF_FLASH_32MB
+  Configure the Cerf kernel to expect 32MB of flash memory.
+
 Support ARM610 processor
 CONFIG_CPU_ARM610
   The ARM610 is the successor to the ARM3 processor
@@ -22245,11 +22335,6 @@
   no management frames, simple fixed header).
   Ultra is available as a special socket : socket(AF_IRDA, SOCK_DGRAM, 1);
 
-IrDA protocol options
-CONFIG_IRDA_OPTIONS
-  Say Y here if you want to configure any of the following IrDA
-  options.
-
 IrDA cache last LSAP
 CONFIG_IRDA_CACHE_LAST_LSAP
   Say Y here if you want IrLMP to cache the last LSAP used.  This
@@ -22261,47 +22346,35 @@
 IrDA Fast RRs
 CONFIG_IRDA_FAST_RR
   Say Y here is you want IrLAP to send fast RR (Receive Ready) frames
-  when acting as a primary station. This will make IrLAP send out a RR
-  frame immediately when receiving a frame if its own transmit queue
-  is currently empty. This will give a lot of speed improvement when
-  receiving much data since the secondary station will not have to
-  wait the max. turn around time before it is allowed to transmit the
-  next time. If the transmit queue of the secondary is also empty the
-  primary will back off waiting longer for sending out the RR frame
-  until the timeout reaches the normal value. Enabling this option
-  will make the IR-diode burn more power and thus reduce your battery
-  life.
+  when acting as a primary station.
+  Disabling this option will make latency over IrDA very bad. Enabling
+  this option will make the IrDA stack send more packet than strictly
+  necessary, thus reduce your battery life (but not that much).
+
+  Fast RR will make IrLAP send out a RR frame immediately when
+  receiving a frame if its own transmit queue is currently empty. This
+  will give a lot of speed improvement when receiving much data since
+  the secondary station will not have to wait the max. turn around
+  time (usually 500ms) before it is allowed to transmit the next time.
+  If the transmit queue of the secondary is also empty, the primary will
+  start backing-off before sending another RR frame, waiting longer
+  each time until the back-off reaches the max. turn around time.
+  This back-off increase in controlled via
+  /proc/sys/net/irda/fast_poll_increase
 
-  If unsure, say N.
+  If unsure, say Y.
 
 IrDA debugging information
 CONFIG_IRDA_DEBUG
   Say Y here if you want the IrDA subsystem to write debug information
   to your syslog. You can change the debug level in
   /proc/sys/net/irda/debug .
+  When this option is enabled, the IrDA also perform many extra internal
+  verifications which will usually prevent the kernel to crash in case of
+  bugs.
 
   If unsure, say Y (since it makes it easier to find the bugs).
 
-IrLAP compression support
-CONFIG_IRDA_COMPRESSION
-  Compression is _not_ part of the IrDA(tm) protocol specification,
-  but it's working great! Linux is the first to try out compression
-  support at the IrLAP layer. This means that you will only benefit
-  from compression if you are running a Linux <-> Linux configuration.
-
-  If you say Y here, you also need to say Y or M to a compression
-  protocol below.
-
-IrLAP Deflate compression
-CONFIG_IRDA_DEFLATE
-  Say Y here if you want to build support for the Deflate compression
-  protocol. The deflate compression (GZIP) is exactly
-  the same as the one used by the PPP protocol.
-
-  If you want to compile this compression support as a module, say M
-  here and read <file:Documentation/modules.txt>.  The module will be
-  called irda_deflate.o.
-
 IrLAN protocol
 CONFIG_IRLAN
   Say Y here if you want to build support for the IrLAN protocol.  If
@@ -22399,7 +22472,7 @@
   <file:Documentation/modules.txt>.  The module will be called
   nsc-ircc.o.
 
-National Semiconductor DP83820 series driver
+National Semiconductor DP83820 support
 CONFIG_NS83820
   This is a driver for the National Semiconductor DP83820 series
   of gigabit ethernet MACs.  Cards using this chipset include
@@ -22423,7 +22496,7 @@
   here and read <file:Documentation/modules.txt>.  The module will be
   called smc-ircc.o.
 
-ALi M5123 FIR Controller Driver
+ALi M5123 FIR controller driver
 CONFIG_ALI_FIR
   Say Y here if you want to build support for the ALi M5123 FIR
   Controller.  The ALi M5123 FIR Controller is embedded in ALi M1543C,
@@ -22434,7 +22507,7 @@
   <file:Documentation/modules.txt>.  The module will be called
   ali-ircc.o.
 
-VLSI 82C147 PCI-IrDA Controller Driver
+VLSI 82C147 PCI-IrDA SIR/MIR/FIR Controller driver
 CONFIG_VLSI_FIR
   Say Y here if you want to build support for the VLSI 82C147
   PCI-IrDA Controller. This controller is used by the HP OmniBook 800
@@ -22645,6 +22718,7 @@
 CONFIG_ETRAX_FLASH_BUSWIDTH
   Width in bytes of the Flash bus (1, 2 or 4). Is usually 2.
 
+# Choice: crisleds
 LED configuration on PA
 CONFIG_ETRAX_PA_LEDS
   The Etrax network driver is responsible for flashing LED's when
@@ -23129,6 +23203,7 @@
 CONFIG_ETRAX_I2C_EEPROM_8KB
   Use a 8kB EEPROM.
 
+# Choice: etrax_eeprom
 Etrax100 I2C EEPROM (NVRAM) size/probe
 CONFIG_ETRAX_I2C_EEPROM_PROBE
   Specifies size or auto probe of the EEPROM size.
@@ -23176,7 +23251,7 @@
 CONFIG_ETRAX_IDE_CSPE1_16_RESET
   Configures the pin used to reset the IDE bus.
 
-Etrax 100 ATA/IDE support
+Delay for drives to regain consciousness
 CONFIG_ETRAX_IDE_DELAY
   Sets the time to wait for disks to regain consciousness after reset.
 
@@ -23184,6 +23259,7 @@
 CONFIG_ETRAX_IDE_G27_RESET
   Configures the pin used to reset the IDE bus.
 
+# Choice: ide_reset
 IDE reset on PB Bit 7
 CONFIG_ETRAX_IDE_PB7_RESET
   Configures the pin used to reset the IDE bus.
@@ -23502,7 +23578,7 @@
   this.  If in doubt, say Y.
 
 /proc/efi/vars support
-CONFIG_IA64_EFIVARS
+CONFIG_EFI_VARS
   If you say Y here, you are able to get EFI (Extensible Firmware
   Interface) variable information in /proc/efi/vars.  You may read,
   write, create, and destroy EFI variables through this interface.
@@ -23535,7 +23611,7 @@
   allocation as well as poisoning memory on free to catch use of freed
   memory.
 
-Memory mapped I/O debug support
+Memory mapped I/O debugging
 CONFIG_DEBUG_IOVIRT
   Say Y here to get warned whenever an attempt is made to do I/O on
   obviously invalid addresses such as those generated when ioremap()
@@ -23659,7 +23735,7 @@
   each of the machines below is described by a machine vector.
 
   Select SolutionEngine if configuring for a Hitachi SH7709
-  or SH7750 evalutation board.
+  or SH7750/7750S evalutation board.
 
   Select Overdrive if configuring for a ST407750 Overdrive board.
   More information at
@@ -23667,34 +23743,43 @@
 
   Select HP620 if configuring for a HP Jornada HP620.
   More information (hardware only) at
-  <http://www.hp.com/jornada>.
+  <http://www.hp.com/jornada/>.
 
   Select HP680 if configuring for a HP Jornada HP680.
   More information (hardware only) at
-  <http://www.hp.com/jornada/products/680>.
+  <http://www.hp.com/jornada/products/680/>.
 
   Select HP690 if configuring for a HP Jornada HP690.
   More information (hardware only) at
-  <http://www.hp.com/jornada/products/680>.
+  <http://www.hp.com/jornada/products/680/>.
 
   Select CqREEK if configuring for a CqREEK SH7708 or SH7750.
   More information at
   <http://sources.redhat.com/ecos/hardware.html#SuperH>.
 
   Select DMIDA if configuring for a DataMyte 4000 Industrial
-  Digital Assistant. More information at <http://www.dmida.com>.
+  Digital Assistant. More information at <http://www.dmida.com/>.
 
   Select EC3104 if configuring for a system with an Eclipse
-  International EC3104 chip, e.g. the Harris AD2000.
+  International EC3104 chip, e.g. the Harris AD2000 or Compaq Aero 8000.
 
   Select Dreamcast if configuring for a SEGA Dreamcast.
   More information at
-  <http://www.m17n.org/linux-sh/dreamcast>.  There is a
+  <http://www.m17n.org/linux-sh/dreamcast/>.  There is a
   Dreamcast project is at <http://linuxdc.sourceforge.net/>.
 
   Select BareCPU if you know what this means, and it applies
   to your system.
 
+# These may have to be merged in when we go to CML2:
+#  - "SolutionEngine7751" for Hitachi SolutionEngine (7751)
+#  - "STB1_Harp" for STMicroelectronics HARP
+#  - "CqREEK" for CQ Publishing CqREEK SH-4
+#  - "CAT68701" for CAT 68701 Evaluation Board (SH7708)
+#  - "BigSur" for Big Sur Evaluation Board
+#  - "SH2000" for SH2000 Evaluation Board (SH7709A)
+#  - "ADX" for A&D ADX
+
 SolutionEngine
 CONFIG_SH_SOLUTION_ENGINE
   Select SolutionEngine if configuring for a Hitachi SH7709
@@ -23715,19 +23800,19 @@
 CONFIG_SH_HP620
   Select HP620 if configuring for a HP jornada HP620.
   More information (hardware only) at
-  <http://www.hp.com/jornada>.
+  <http://www.hp.com/jornada/>.
 
 HP680
 CONFIG_SH_HP680
   Select HP680 if configuring for a HP Jornada HP680.
   More information (hardware only) at
-  <http://www.hp.com/jornada/products/680>.
+  <http://www.hp.com/jornada/products/680/>.
 
 HP690
 CONFIG_SH_HP690
   Select HP690 if configuring for a HP Jornada HP690.
   More information (hardware only)
-  at <http://www.hp.com/jornada/products/680>.
+  at <http://www.hp.com/jornada/products/680/>.
 
 CqREEK
 CONFIG_SH_CQREEK
@@ -23738,7 +23823,7 @@
 DMIDA
 CONFIG_SH_DMIDA
   Select DMIDA if configuring for a DataMyte 4000 Industrial
-  Digital Assistant. More information at <http://www.dmida.com>.
+  Digital Assistant. More information at <http://www.dmida.com/>.
 
 EC3104
 CONFIG_SH_EC3104
@@ -23749,7 +23834,7 @@
 CONFIG_SH_DREAMCAST
   Select Dreamcast if configuring for a SEGA Dreamcast.
   More information at
-  <http://www.m17n.org/linux-sh/dreamcast>.  There is a
+  <http://www.m17n.org/linux-sh/dreamcast/>.  There is a
   Dreamcast project is at <http://linuxdc.sourceforge.net/>.
 
 BareCPU
@@ -23766,7 +23851,8 @@
 # Choice: superhtype
 SH7707
 CONFIG_CPU_SUBTYPE_SH7707
-  Select the type of SuperH processor you have.
+  Select the type of SuperH processor you have. This information is
+  used for optimizing and configuration purposes.
 
   Select SH7707 if you have a  60 Mhz SH-3 HD6417707 CPU.
 
@@ -23777,6 +23863,10 @@
 
   Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
 
+  Select SH7751 if you have a SH7751
+
+  Select ST40STB1 if you have a ST40STB1
+
 SH7708
 CONFIG_CPU_SUBTYPE_SH7708
   Select SH7708 if you have a  60 Mhz SH-3 HD6417708S or
@@ -23792,7 +23882,11 @@
 
 Physical memory start address
 CONFIG_MEMORY_START
-  The physical memory start address will be automatically
+  Computers built with Hitachi SuperH processors always
+  map the ROM starting at address zero.  But the processor
+  does not specify the range that RAM takes.  
+
+  The physical memory (RAM) start address will be automatically
   set to 08000000, unless you selected one of the following
   processor types: SolutionEngine, Overdrive, HP620, HP680, HP690,
   in which case the start address will be set to 0c000000.
@@ -23850,15 +23944,15 @@
   The default setting of the HD64465 IO base address is 0xb0000000.
 
   Do not change this unless you know what you are doing.
-
+  
 Early printk support
 CONFIG_SH_EARLY_PRINTK
-  Say Y here to redirect kernel messages to the serial port
+  Say Y here to redirect kernel printk messages to the serial port
   used by the SH-IPL bootloader, starting very early in the boot
   process and ending when the kernel's serial console is initialised.
   This option is only useful porting the kernel to a new machine,
   when the kernel may crash or hang before the serial console is
-  initialised.
+  initialised. If unsure, say N.
 
 SuperH SCI (serial) support
 CONFIG_SH_SCI
@@ -23912,7 +24006,7 @@
 #
 # This is used by Emacs' spell checker ispell.el:
 #
-# LocalWords:  CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp metalab
+# LocalWords:  CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp ibiblio
 # LocalWords:  unc edu docs emu README kB BLK DEV FD Thinkpad fd MFM RLL IDE gz
 # LocalWords:  cdrom diskless netboot nfs xzvf ATAPI MB ide pavia rubini pl pd
 # LocalWords:  HD CD-ROMs IDECD NEC MITSUMI filesystem XT XD PCI BIOS cezar ATEN
@@ -23958,7 +24052,7 @@
 # LocalWords:  bsd comp SPARCstation le SunOS ie Gracilis PackeTwin PT pt LU FX
 # LocalWords:  FX TEAC CR LCS mS ramdisk IDETAPE cmd fperllo encis tcfs unisa
 # LocalWords:  Vertos Genoa Funai hsfs NCP NetWare tgz APM apm ioctls UltraLite
-# LocalWords:  TravelMate CDT LCD backlight VC RPC Mips AXP barlow cdrecord pg
+# LocalWords:  TravelMate CDT LCD backlight VC RPC Mips AXP barlow cdrtools pg
 # LocalWords:  PMAX MILO Alphas Multia Tseng linuxelf endian mipsel mips drv HT
 # LocalWords:  kerneld callouts AdvanSys advansys Admin WDT DataStor EP verden
 # LocalWords:  wdt hdb hdc bugfix SiS vlb Acculogic CSA DTC dtc Holtek ht QDI
diff -urN linux-2.4.17-pre4/Documentation/DMA-mapping.txt linux/Documentation/DMA-mapping.txt
--- linux-2.4.17-pre4/Documentation/DMA-mapping.txt	Fri Oct 12 15:35:53 2001
+++ linux/Documentation/DMA-mapping.txt	Thu Dec  6 10:53:03 2001
@@ -60,6 +60,9 @@
 might be mapped somewhere entirely different than the rest of physical
 memory.
 
+Also, this means that you cannot take the return of a kmap()
+call and DMA to/from that.  This is similar to vmalloc().
+
 What about block I/O and networking buffers?  The block I/O and
 networking subsystems make sure that the buffers they use are valid
 for you to DMA from/to.
diff -urN linux-2.4.17-pre4/Documentation/cachetlb.txt linux/Documentation/cachetlb.txt
--- linux-2.4.17-pre4/Documentation/cachetlb.txt	Sun Oct 21 10:40:36 2001
+++ linux/Documentation/cachetlb.txt	Thu Dec  6 10:53:03 2001
@@ -275,7 +275,7 @@
 	for example, uses this technique.
 
 	The "address" parameter tells the virtual address where the
-	user will ultimately this page mapped.
+	user will ultimately have this page mapped.
 
 	If D-cache aliasing is not an issue, these two routines may
 	simply call memcpy/memset directly and do nothing more.
diff -urN linux-2.4.17-pre4/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog
--- linux-2.4.17-pre4/Documentation/filesystems/devfs/ChangeLog	Thu Dec  6 10:52:25 2001
+++ linux/Documentation/filesystems/devfs/ChangeLog	Thu Dec  6 10:53:03 2001
@@ -1815,3 +1815,7 @@
 - Fixed bug in <devfsd_close>: was dereferencing freed pointer
 
 - Added process group check for devfsd privileges
+===============================================================================
+Changes for patch v199.3
+
+- Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>
diff -urN linux-2.4.17-pre4/Documentation/filesystems/tmpfs.txt linux/Documentation/filesystems/tmpfs.txt
--- linux-2.4.17-pre4/Documentation/filesystems/tmpfs.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/filesystems/tmpfs.txt	Thu Dec  6 10:53:03 2001
@@ -0,0 +1,102 @@
+Tmpfs is a file system which keeps all files in virtual memory.
+
+
+Everything in tmpfs is temporary in the sense that no files will be
+created on your hard drive. If you unmount a tmpfs instance,
+everything stored therein is lost.
+
+tmpfs puts everything into the kernel internal caches and grows and
+shrinks to accommodate the files it contains and is able to swap
+unneeded pages out to swap space. It has maximum size limits which can
+be adjusted on the fly via 'mount -o remount ...'
+
+If you compare it to ramfs (which was the template to create tmpfs)
+you gain swapping and limit checking. Another similar thing is the RAM
+disk (/dev/ram*), which simulates a fixed size hard disk in physical
+RAM, where you have to create an ordinary filesystem on top. Ramdisks
+cannot swap and you do not have the possibility to resize them. 
+
+Since tmpfs lives completely in the page cache and on swap, all tmpfs
+pages currently in memory will show up as cached. It will not show up
+as shared or something like that. Further on you can check the actual
+RAM+swap use of a tmpfs instance with df(1) and du(1).
+
+
+tmpfs has the following uses:
+
+1) There is always a kernel internal mount which you will not see at
+   all. This is used for shared anonymous mappings and SYSV shared
+   memory. 
+
+   This mount does not depend on CONFIG_TMPFS. If CONFIG_TMPFS is not
+   set, the user visible part of tmpfs is not build. But the internal
+   mechanisms are always present.
+
+2) glibc 2.2 and above expects tmpfs to be mounted at /dev/shm for
+   POSIX shared memory (shm_open, shm_unlink). Adding the following
+   line to /etc/fstab should take care of this:
+
+	tmpfs	/dev/shm	tmpfs	defaults	0 0
+
+   Remember to create the directory that you intend to mount tmpfs on
+   if necessary (/dev/shm is automagically created if you use devfs).
+
+   This mount is _not_ needed for SYSV shared memory. The internal
+   mount is used for that. (In the 2.3 kernel versions it was
+   necessary to mount the predecessor of tmpfs (shm fs) to use SYSV
+   shared memory)
+
+3) Some people (including me) find it very convenient to mount it
+   e.g. on /tmp and /var/tmp and have a big swap partition. But be
+   aware: loop mounts of tmpfs files do not work due to the internal
+   design. So mkinitrd shipped by most distributions will fail with a
+   tmpfs /tmp.
+
+4) And probably a lot more I do not know about :-)
+
+
+tmpfs has a couple of mount options:
+
+size:	   The limit of allocated bytes for this tmpfs instance. The 
+           default is half of your physical RAM without swap. If you
+	   oversize your tmpfs instances the machine will deadlock
+	   since the OOM handler will not be able to free that memory.
+nr_blocks: The same as size, but in blocks of PAGECACHE_SIZE.
+nr_inodes: The maximum number of inodes for this instance. The default
+           is half of the number of your physical RAM pages.
+
+These parameters accept a suffix k, m or g for kilo, mega and giga and
+can be changed on remount.
+
+To specify the initial root directory you can use the following mount
+options:
+
+mode:	The permissions as an octal number
+uid:	The user id 
+gid:	The group id
+
+These options do not have any effect on remount. You can change these
+parameters with chmod(1), chown(1) and chgrp(1) on a mounted filesystem.
+
+
+So 'mount -t tmpfs -o size=10G,nr_inodes=10k,mode=700 tmpfs /mytmpfs'
+will give you tmpfs instance on /mytmpfs which can allocate 10GB
+RAM/SWAP in 10240 inodes and it is only accessible by root.
+
+
+TODOs:
+
+1) give the size option a percent semantic: If you give a mount option
+   size=50% the tmpfs instance should be able to grow to 50 percent of
+   RAM + swap. So the instance should adapt automatically if you add
+   or remove swap space.
+2) loop mounts: This is difficult since loop.c relies on the readpage
+   operation. This operation gets a page from the caller to be filled
+   with the content of the file at that position. But tmpfs always has
+   the page and thus cannot copy the content to the given page. So it
+   cannot provide this operation. The VM had to be changed seriously
+   to achieve this.
+3) Show the number of tmpfs RAM pages. (As shared?)
+
+Author:
+   Christoph Rohland <cr@sap.com>, 1.12.01
diff -urN linux-2.4.17-pre4/Documentation/networking/decnet.txt linux/Documentation/networking/decnet.txt
--- linux-2.4.17-pre4/Documentation/networking/decnet.txt	Thu Dec  6 10:52:25 2001
+++ linux/Documentation/networking/decnet.txt	Thu Dec  6 10:53:03 2001
@@ -4,20 +4,9 @@
 1) Other documentation....
 
    o Project Home Pages
-       http://www.sucs.swan.ac.uk/~rohan/DECnet/index.html - Kernel info
+       http://www.chygwyn.com/DECnet/                      - Kernel info
        http://linux-decnet.sourceforge.net/                - Userland tools
-
-   o FTP sites
-       ftp://ftp.sucs.swan.ac.uk/pub/Linux/DECnet/
-                - Swansea University Computer Society DECnet Archive
-                  (contains kernel patches and info)
-                - Mirror of userland tools on ftp.dreamtime.org
-                - Mirror of Alexey Kuznetsov's iproute2 package and
-                  other utilities
-
-       ftp://linux-decnet.sourceforge.net/pub/linux-decnet/ 
-                - Patrick Caulfield's archive of userland tools and
-                  Eduardo Serrat's kernel patches
+       http://www.sourceforge.net/projects/linux-decnet/   - Status page
 
 2) Configuring the kernel
 
@@ -32,6 +21,12 @@
 
     CONFIG_DECNET_ROUTER (to be able to add/delete routes)
     CONFIG_NETFILTER (will be required for the DECnet routing daemon)
+
+    CONFIG_DECNET_ROUTE_FWMARK is optional
+
+Don't turn on SIOCGIFCONF support for DECnet unless you are really sure
+that you need it, in general you won't and it can cause ifconfig to
+malfunction.
 
 3) Command line options
 
diff -urN linux-2.4.17-pre4/MAINTAINERS linux/MAINTAINERS
--- linux-2.4.17-pre4/MAINTAINERS	Thu Dec  6 10:52:25 2001
+++ linux/MAINTAINERS	Thu Dec  6 10:53:03 2001
@@ -932,6 +932,12 @@
 W:     http://www.sistina.com/lvm
 S:     Maintained 
 
+LSILOGIC/SYMBIOS/NCR 53C8XX and 53C1010 PCI-SCSI drivers
+P:	Gerard Roudier
+M:	groudier@free.fr
+L:	linux-scsi@vger.kernel.org
+S:	Maintained
+
 M68K
 P:	Jes Sorensen
 M:	jes@trained-monkey.org
diff -urN linux-2.4.17-pre4/Makefile linux/Makefile
--- linux-2.4.17-pre4/Makefile	Thu Dec  6 10:52:25 2001
+++ linux/Makefile	Thu Dec  6 10:53:03 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 17
-EXTRAVERSION = -pre4
+EXTRAVERSION = -pre5
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.17-pre4/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- linux-2.4.17-pre4/arch/i386/kernel/setup.c	Mon Nov 19 15:16:13 2001
+++ linux/arch/i386/kernel/setup.c	Thu Dec  6 10:53:03 2001
@@ -1280,9 +1280,28 @@
 			}
 			break;
 
-		case 6:	/* An Athlon/Duron. We can trust the BIOS probably */
-			mcheck_init(c);
-			break;		
+		case 6: /* An Athlon/Duron */
+ 			mcheck_init(c);
+ 
+			/* Bit 15 of Athlon specific MSR 15, needs to be 0
+ 			 * to enable SSE on Palomino/Morgan CPU's.
+			 * If the BIOS didn't enable it already, enable it
+			 * here.
+			 */
+			if (c->x86_model == 6 || c->x86_model == 7) {
+				if (!test_bit(X86_FEATURE_XMM,
+					      &c->x86_capability)) {
+					printk(KERN_INFO
+					       "Enabling Disabled K7/SSE Support...\n");
+					rdmsr(MSR_K7_HWCR, l, h);
+					l &= ~0x00008000;
+					wrmsr(MSR_K7_HWCR, l, h);
+					set_bit(X86_FEATURE_XMM,
+                                                &c->x86_capability);
+				}
+			}
+			break;
+
 	}
 
 	display_cacheinfo(c);
@@ -2193,7 +2212,56 @@
 
 	if ( p )
 		strcpy(c->x86_model_id, p);
+	
+#ifdef CONFIG_SMP
+	if (test_bit(X86_FEATURE_HT, &c->x86_capability[0])) {
+		extern	int phys_proc_id[NR_CPUS];
+		
+		u32 	eax, ebx, ecx, edx;
+		int 	index_lsb, index_msb, tmp;
+		int	initial_apic_id;
+		int 	cpu = smp_processor_id();
+
+		cpuid(1, &eax, &ebx, &ecx, &edx);
+		smp_num_siblings = (ebx & 0xff0000) >> 16;
+
+		if (smp_num_siblings == 1) {
+			printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
+		} else if (smp_num_siblings > 1 ) {
+			index_lsb = 0;
+			index_msb = 31;
+			/*
+			 * At this point we only support two siblings per
+			 * processor package.
+			 */
+#define NR_SIBLINGS	2
+			if (smp_num_siblings != NR_SIBLINGS) {
+				printk(KERN_WARNING "CPU: Unsuppored number of the siblings %d", smp_num_siblings);
+				smp_num_siblings = 1;
+				goto too_many_siblings;
+			}
+			tmp = smp_num_siblings;
+			while ((tmp & 1) == 0) {
+				tmp >>=1 ;
+				index_lsb++;
+			}
+			tmp = smp_num_siblings;
+			while ((tmp & 0x80000000 ) == 0) {
+				tmp <<=1 ;
+				index_msb--;
+			}
+			if (index_lsb != index_msb )
+				index_msb++;
+			initial_apic_id = ebx >> 24 & 0xff;
+			phys_proc_id[cpu] = initial_apic_id >> index_msb;
 
+			printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
+                               phys_proc_id[cpu]);
+		}
+
+	}
+too_many_siblings:
+#endif
 	/* Enable MCA if available */
 	mcheck_init(c);
 }
@@ -2699,7 +2767,7 @@
 	        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
 	        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
 	        "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-	        "fxsr", "sse", "sse2", "ss", NULL, "tm", "ia64", NULL,
+	        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
 
 		/* AMD-defined */
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff -urN linux-2.4.17-pre4/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
--- linux-2.4.17-pre4/arch/i386/kernel/smpboot.c	Wed Nov 21 10:35:48 2001
+++ linux/arch/i386/kernel/smpboot.c	Thu Dec  6 10:53:03 2001
@@ -56,6 +56,10 @@
 /* Total count of live CPUs */
 int smp_num_cpus = 1;
 
+/* Number of siblings per CPU package */
+int smp_num_siblings = 1;
+int __initdata phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
+
 /* Bitmask of currently online CPUs */
 unsigned long cpu_online_map;
 
@@ -971,6 +975,8 @@
 /* Where the IO area was mapped on multiquad, always 0 otherwise */
 void *xquad_portio = NULL;
 
+int cpu_sibling_map[NR_CPUS] __cacheline_aligned;
+
 void __init smp_boot_cpus(void)
 {
 	int apicid, cpu, bit;
@@ -1162,6 +1168,34 @@
 		printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
 	Dprintk("Boot done.\n");
 
+	/*
+	 * If Hyper-Threading is avaialble, construct cpu_sibling_map[], so
+	 * that we can tell the sibling CPU efficiently.
+	 */
+	if (test_bit(X86_FEATURE_HT, boot_cpu_data.x86_capability)
+	    && smp_num_siblings > 1) {
+		for (cpu = 0; cpu < NR_CPUS; cpu++)
+			cpu_sibling_map[cpu] = NO_PROC_ID;
+		
+		for (cpu = 0; cpu < smp_num_cpus; cpu++) {
+			int 	i;
+			
+			for (i = 0; i < smp_num_cpus; i++) {
+				if (i == cpu)
+					continue;
+				if (phys_proc_id[cpu] == phys_proc_id[i]) {
+					cpu_sibling_map[cpu] = i;
+					printk("cpu_sibling_map[%d] = %d\n", cpu, cpu_sibling_map[cpu]);
+					break;
+				}
+			}
+			if (cpu_sibling_map[cpu] == NO_PROC_ID) {
+				smp_num_siblings = 1;
+				printk(KERN_WARNING "WARNING: No sibling found for CPU %d.\n", cpu);
+			}
+		}
+	}
+	     
 #ifndef CONFIG_VISWS
 	/*
 	 * Here we can be sure that there is an IO-APIC in the system. Let's
diff -urN linux-2.4.17-pre4/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- linux-2.4.17-pre4/arch/sparc/kernel/process.c	Tue Nov 13 09:16:05 2001
+++ linux/arch/sparc/kernel/process.c	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/*  $Id: process.c,v 1.157 2001/11/13 00:57:05 davem Exp $
+/*  $Id: process.c,v 1.158 2001/11/26 23:45:00 davem Exp $
  *  linux/arch/sparc/kernel/process.c
  *
  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -285,37 +285,29 @@
 	show_regwindow((struct reg_window *)regs->u_regs[14]);
 }
 
-#if NOTUSED
-void show_thread(struct thread_struct *thread)
+void show_trace_task(struct task_struct *tsk)
 {
-	int i;
-
-	printk("uwinmask:          0x%08lx  kregs:             0x%08lx\n", thread->uwinmask, (unsigned long)thread->kregs);
-	show_regs(thread->kregs);
-	printk("ksp:               0x%08lx  kpc:               0x%08lx\n", thread->ksp, thread->kpc);
-	printk("kpsr:              0x%08lx  kwim:              0x%08lx\n", thread->kpsr, thread->kwim);
-	printk("fork_kpsr:         0x%08lx  fork_kwim:         0x%08lx\n", thread->fork_kpsr, thread->fork_kwim);
-
-	for (i = 0; i < NSWINS; i++) {
-		if (!thread->rwbuf_stkptrs[i])
-			continue;
-		printk("reg_window[%d]:\n", i);
-		printk("stack ptr:         0x%08lx\n", thread->rwbuf_stkptrs[i]);
-		show_regwindow(&thread->reg_window[i]);
-	}
-	printk("w_saved:           0x%08lx\n", thread->w_saved);
-
-	/* XXX missing: float_regs */
-	printk("fsr:               0x%08lx  fpqdepth:          0x%08lx\n", thread->fsr, thread->fpqdepth);
-	/* XXX missing: fpqueue */
+	unsigned long pc, fp;
+	unsigned long task_base = (unsigned long) tsk;
+	struct reg_window *rw;
+	int count = 0;
 
-	printk("flags:             0x%08lx  current_ds:        0x%08lx\n", thread->flags, thread->current_ds.seg);
-	
-	show_regwindow((struct reg_window *)thread->ksp);
+	if (!tsk)
+		return;
 
-	/* XXX missing: core_exec */
+	fp = tsk->thread.ksp;
+	do {
+		/* Bogus frame pointer? */
+		if (fp < (task_base + sizeof(struct task_struct)) ||
+		    fp >= (task_base + (PAGE_SIZE << 1)))
+			break;
+		rw = (struct reg_window *) fp;
+		pc = rw->ins[7];
+		printk("[%08lx] ", pc);
+		fp = rw->ins[6];
+	} while (++count < 16);
+	printk("\n");
 }
-#endif
 
 /*
  * Free current thread data structures etc..
diff -urN linux-2.4.17-pre4/arch/sparc64/config.in linux/arch/sparc64/config.in
--- linux-2.4.17-pre4/arch/sparc64/config.in	Thu Dec  6 10:52:25 2001
+++ linux/arch/sparc64/config.in	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.155 2001/11/17 00:15:27 davem Exp $
+# $Id: config.in,v 1.156 2001/11/30 00:17:32 davem Exp $
 # For a description of the syntax of this configuration file,
 # see the Configure script.
 #
@@ -31,6 +31,8 @@
 # Identify this as a Sparc64 build
 define_bool CONFIG_SPARC64 y
 
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
 # Global things across all Sun machines.
 define_bool CONFIG_HAVE_DEC_LOCK y
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
@@ -89,7 +91,6 @@
 mainmenu_option next_comment
 comment 'Console drivers'
 bool 'PROM console' CONFIG_PROM_CONSOLE
-bool 'Support Frame buffer devices' CONFIG_FB
 source drivers/video/Config.in
 endmenu
 
diff -urN linux-2.4.17-pre4/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- linux-2.4.17-pre4/arch/sparc64/defconfig	Thu Dec  6 10:52:25 2001
+++ linux/arch/sparc64/defconfig	Thu Dec  6 10:53:03 2001
@@ -22,6 +22,7 @@
 CONFIG_VT_CONSOLE=y
 CONFIG_SMP=y
 CONFIG_SPARC64=y
+CONFIG_HOTPLUG=y
 CONFIG_HAVE_DEC_LOCK=y
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -84,7 +85,6 @@
 # Console drivers
 #
 CONFIG_PROM_CONSOLE=y
-CONFIG_FB=y
 
 #
 # Frame-buffer support
diff -urN linux-2.4.17-pre4/arch/sparc64/kernel/entry.S linux/arch/sparc64/kernel/entry.S
--- linux-2.4.17-pre4/arch/sparc64/kernel/entry.S	Thu Dec  6 10:52:25 2001
+++ linux/arch/sparc64/kernel/entry.S	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.138 2001/11/14 17:24:36 davem Exp $
+/* $Id: entry.S,v 1.141 2001/12/05 23:56:32 davem Exp $
  * arch/sparc64/kernel/entry.S:  Sparc64 trap low-level entry points.
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -483,7 +483,11 @@
 	ldxa		[%g7 + %g0] ASI_INTR_R, %g7
 	stxa		%g0, [%g0] ASI_INTR_RECEIVE
 	membar		#Sync
-	jmpl		%g3, %g0
+	ba,pt		%xcc, 1f
+	 nop
+
+	.align		32
+1:	jmpl		%g3, %g0
 	 nop
 
 do_ivec_spurious:
@@ -1620,6 +1624,11 @@
 	 *
 	 * Note with time_t changes to the timeval type, I must now use
 	 * nucleus atomic quad 128-bit loads.
+	 *
+	 * If xtime was stored recently, I've seen crap from the
+	 * quad load on Cheetah.  Putting a membar SYNC before
+	 * the quad load seems to make the problem go away. -DaveM
+	 * (we should nop out workarounds like this on spitfire)
 	 */
 	sethi	%hi(timer_tick_offset), %g3
 	sethi	%hi(xtime), %g2
@@ -1631,6 +1640,7 @@
 	sethi	%hi(0x003e0014), %o1
 	srlx	%o2, 32, %o2
 	or	%o1, %lo(0x003e0014), %o1
+	membar	#Sync
 	ldda	[%g2] ASI_NUCLEUS_QUAD_LDD, %o4
 	cmp	%o2, %o1
 	bne,pt	%xcc, 2f
@@ -1639,6 +1649,7 @@
 	 rd	%asr24, %o1
 2:	rd	%tick, %o1
 3:	ldx	[%g1], %g7
+	membar	#Sync
 	ldda	[%g2] ASI_NUCLEUS_QUAD_LDD, %o2
 	xor	%o4, %o2, %o2
 	xor	%o5, %o3, %o3
diff -urN linux-2.4.17-pre4/arch/sparc64/kernel/head.S linux/arch/sparc64/kernel/head.S
--- linux-2.4.17-pre4/arch/sparc64/kernel/head.S	Sat Oct  6 08:50:28 2001
+++ linux/arch/sparc64/kernel/head.S	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.82 2001/10/04 23:37:04 davem Exp $
+/* $Id: head.S,v 1.86 2001/12/05 01:02:16 davem Exp $
  * head.S: Initial boot code for the Sparc64 port of Linux.
  *
  * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -201,7 +201,7 @@
 	 add	%l0, (1 << 3), %l0
 
 	/* Now lock the TTE we created into ITLB-0 and DTLB-0,
-	 * entry 15.
+	 * entry 15 (and maybe 14 too).
 	 */
 	sethi	%hi(KERNBASE), %g3
 	set	(0 << 16) | (15 << 3), %g7
@@ -215,6 +215,29 @@
 	membar	#Sync
 	flush	%g3
 	membar	#Sync
+	sethi	%hi(_end), %g3			/* Check for bigkernel case */
+	or	%g3, %lo(_end), %g3
+	srl	%g3, 23, %g3			/* Check if _end > 8M */
+	brz,pt	%g3, 1f
+	 sethi	%hi(KERNBASE), %g3		/* Restore for fixup code below */
+	sethi	%hi(0x400000), %g3
+	or	%g3, %lo(0x400000), %g3
+	add	%g5, %g3, %g5			/* New tte data */
+	andn	%g5, (_PAGE_G), %g5
+	sethi	%hi(KERNBASE+0x400000), %g3
+	or	%g3, %lo(KERNBASE+0x400000), %g3
+	set	(0 << 16) | (14 << 3), %g7
+	stxa	%g3, [%l7] ASI_DMMU
+	membar	#Sync
+	stxa	%g5, [%g7] ASI_DTLB_DATA_ACCESS
+	membar	#Sync
+	stxa	%g3, [%l7] ASI_IMMU
+	membar	#Sync
+	stxa	%g5, [%g7] ASI_ITLB_DATA_ACCESS
+	membar	#Sync
+	flush	%g3
+	membar	#Sync
+	sethi	%hi(KERNBASE), %g3		/* Restore for fixup code below */
 	ba,pt	%xcc, 1f
 	 nop
 
@@ -345,7 +368,7 @@
 
 
 	/* PROM never puts any TLB entries into the MMU with the lock bit
-	 * set.  So we gladly use tlb entry 63 for KERNBASE.
+	 * set.  So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too.
 	 */
 
 	sethi	%hi(KERNBASE), %g3
@@ -358,7 +381,28 @@
 	membar	#Sync
 	flush	%g3
 	membar	#Sync
-	ba,pt	%xcc, 1f
+	sethi	%hi(_end), %g3			/* Check for bigkernel case */
+	or	%g3, %lo(_end), %g3
+	srl	%g3, 23, %g3			/* Check if _end > 8M */
+	brz,pt	%g3, 2f
+	 sethi	%hi(KERNBASE), %g3		/* Restore for fixup code below */
+	sethi	%hi(0x400000), %g3
+	or	%g3, %lo(0x400000), %g3
+	add	%g5, %g3, %g5			/* New tte data */
+	andn	%g5, (_PAGE_G), %g5
+	sethi	%hi(KERNBASE+0x400000), %g3
+	or	%g3, %lo(KERNBASE+0x400000), %g3
+	mov	(62 << 3), %g7
+	stxa	%g3, [%l7] ASI_DMMU
+	stxa	%g5, [%g7] ASI_DTLB_DATA_ACCESS
+	membar	#Sync
+	stxa	%g3, [%l7] ASI_IMMU
+	stxa	%g5, [%g7] ASI_ITLB_DATA_ACCESS
+	membar	#Sync
+	flush	%g3
+	membar	#Sync
+	sethi	%hi(KERNBASE), %g3		/* Restore for fixup code below */
+2:	ba,pt	%xcc, 1f
 	 nop
 1:
 	set	sun4u_init, %g2
diff -urN linux-2.4.17-pre4/arch/sparc64/kernel/rtrap.S linux/arch/sparc64/kernel/rtrap.S
--- linux-2.4.17-pre4/arch/sparc64/kernel/rtrap.S	Wed Oct 17 14:16:39 2001
+++ linux/arch/sparc64/kernel/rtrap.S	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.56 2001/10/13 00:14:34 kanoj Exp $
+/* $Id: rtrap.S,v 1.57 2001/12/06 00:16:11 davem Exp $
  * rtrap.S: Preparing for return from trap on Sparc V9.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -18,14 +18,13 @@
 #define		RTRAP_PSTATE_IRQOFF	(PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV)
 #define		RTRAP_PSTATE_AG_IRQOFF	(PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
 
-#if 0
-#define		RTRAP_CHECK		call rtrap_check;  add %sp, (STACK_BIAS+REGWIN_SZ), %o0;
-#else
-#define		RTRAP_CHECK
-#endif
+		/* Register %l6 keeps track of whether we are returning
+		 * from a system call or not.  It is cleared if we call
+		 * do_signal, and it must not be otherwise modified until
+		 * we fully commit to returning to userspace.
+		 */
 
 		.text
-
 		.align			32
 __handle_softirq:
 		call			do_softirq
@@ -34,42 +33,101 @@
 		 nop
 __handle_preemption:
 		call			schedule
-		 nop
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		ba,pt			%xcc, __handle_preemption_continue
-		 nop
+		 wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
+
 __handle_user_windows:
-		wrpr			%g0, RTRAP_PSTATE, %pstate
 		call			fault_in_user_windows
-		 nop
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		ba,pt			%xcc, __handle_user_windows_continue
+		 wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
+		/* Redo sched+sig checks */
+		ldx			[%g6 + AOFF_task_need_resched], %l0
+		brz,pt			%l0, 1f
+		 nop
+		call			schedule
+
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
+		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
+1:		lduw			[%g6 + AOFF_task_sigpending], %l0
+		brz,pt			%l0, __handle_user_windows_continue
 		 nop
+		clr			%o0
+		mov			%l5, %o2
+		mov			%l6, %o3
+
+		add			%sp, STACK_BIAS + REGWIN_SZ, %o1
+		call			do_signal
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
+		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
+		clr			%l6
+		/* Signal delivery can modify pt_regs tstate, so we must
+		 * reload it.
+		 */
+		ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
+		sethi			%hi(0xf << 20), %l4
+		and			%l1, %l4, %l4
+
+		ba,pt			%xcc, __handle_user_windows_continue
+		 andn			%l1, %l4, %l1
 __handle_perfctrs:
-		/* Don't forget to preserve user window invariants. */
-		wrpr			%g0, RTRAP_PSTATE, %pstate
 		call			update_perfctrs
-		 nop
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		ldub			[%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2
-		brz,pt			%o2, __handle_perfctrs_continue
-		 sethi			%hi(TSTATE_PEF), %l6
-		wrpr			%g0, RTRAP_PSTATE, %pstate
+		brz,pt			%o2, 1f
+		 nop
 
+		/* Redo userwin+sched+sig checks */
 		call			fault_in_user_windows
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
+		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
+1:		ldx			[%g6 + AOFF_task_need_resched], %l0
+		brz,pt			%l0, 1f
 		 nop
+		call			schedule
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
+
+		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
+1:		lduw			[%g6 + AOFF_task_sigpending], %l0
+		brz,pt			%l0, __handle_perfctrs_continue
+		 sethi			%hi(TSTATE_PEF), %o0
+		clr			%o0
+		mov			%l5, %o2
+		mov			%l6, %o3
+		add			%sp, STACK_BIAS + REGWIN_SZ, %o1
+
+		call			do_signal
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
+		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
+		clr			%l6
+		/* Signal delivery can modify pt_regs tstate, so we must
+		 * reload it.
+		 */
+		ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
+		sethi			%hi(0xf << 20), %l4
+		and			%l1, %l4, %l4
+		andn			%l1, %l4, %l1
+
 		ba,pt			%xcc, __handle_perfctrs_continue
-		 nop
+		 sethi			%hi(TSTATE_PEF), %o0
 __handle_userfpu:
 		rd			%fprs, %l5
 		andcc			%l5, FPRS_FEF, %g0
+		sethi			%hi(TSTATE_PEF), %o0
 		be,a,pn			%icc, __handle_userfpu_continue
-		 andn			%l1, %l6, %l1
+		 andn			%l1, %o0, %l1
 		ba,a,pt			%xcc, __handle_userfpu_continue
+
 __handle_signal:
 		clr			%o0
 		mov			%l5, %o2
 		mov			%l6, %o3
+		add			%sp, STACK_BIAS + REGWIN_SZ, %o1
 		call			do_signal
-		 add			%sp, STACK_BIAS + REGWIN_SZ, %o1
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
+		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		clr			%l6
 
 		/* Signal delivery can modify pt_regs tstate, so we must
@@ -99,29 +157,43 @@
 		and			%l1, %l4, %l4
 		bne,pn			%icc, to_kernel
 		 andn			%l1, %l4, %l1
-to_user:	ldx			[%g6 + AOFF_task_need_resched], %l0
 
-		brnz,pn			%l0, __handle_preemption
+		/* We must hold IRQs off and atomically test schedule+signal
+		 * state, then hold them off all the way back to userspace.
+		 * If we are returning to kernel, none of this matters.
+		 *
+		 * If we do not do this, there is a window where we would do
+		 * the tests, later the signal/resched event arrives but we do
+		 * not process it since we are still in kernel mode.  It would
+		 * take until the next local IRQ before the signal/resched
+		 * event would be handled.
+		 *
+		 * This also means that if we have to deal with performance
+		 * counters or user windows, we have to redo all of these
+		 * sched+signal checks with IRQs disabled.
+		 */
+to_user:	wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 __handle_preemption_continue:
+		ldx			[%g6 + AOFF_task_need_resched], %l0
+		brnz,pn			%l0, __handle_preemption
 		 lduw			[%g6 + AOFF_task_sigpending], %l0
 		brnz,pn			%l0, __handle_signal
 		 nop
 __handle_signal_continue:
-check_user_wins:
-		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		ldub			[%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2
 		brnz,pn			%o2, __handle_user_windows
-		 sethi			%hi(TSTATE_PEF), %l6
-
+		 nop
 __handle_user_windows_continue:
-		RTRAP_CHECK
 		ldub			[%g6 + AOFF_task_thread + AOFF_thread_flags], %l5
 		andcc			%l5, SPARC_FLAG_PERFCTR, %g0
+		sethi			%hi(TSTATE_PEF), %o0
 		bne,pn			%xcc, __handle_perfctrs
 __handle_perfctrs_continue:
-		 andcc			%l1, %l6, %g0
+		 andcc			%l1, %o0, %g0
+
+		/* This fpdepth clear is neccessary for non-syscall rtraps only */
 		bne,pn			%xcc, __handle_userfpu
-		 stb			%g0, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] ! This is neccessary for non-syscall rtraps only
+		 stb			%g0, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth]
 __handle_userfpu_continue:
 
 rt_continue:	ldx			[%sp + PTREGS_OFF + PT_V9_G1], %g1
diff -urN linux-2.4.17-pre4/arch/sparc64/kernel/smp.c linux/arch/sparc64/kernel/smp.c
--- linux-2.4.17-pre4/arch/sparc64/kernel/smp.c	Thu Dec  6 10:52:25 2001
+++ linux/arch/sparc64/kernel/smp.c	Thu Dec  6 10:53:03 2001
@@ -137,6 +137,15 @@
 {
 	int cpuid = hard_smp_processor_id();
 	unsigned long pstate;
+	extern int bigkernel;
+	extern unsigned long kern_locked_tte_data;
+
+	if (bigkernel) {
+		prom_dtlb_load(sparc64_highest_locked_tlbent()-1, 
+			kern_locked_tte_data + 0x400000, KERNBASE + 0x400000);
+		prom_itlb_load(sparc64_highest_locked_tlbent()-1, 
+			kern_locked_tte_data + 0x400000, KERNBASE + 0x400000);
+	}
 
 	inherit_locked_prom_mappings(0);
 
diff -urN linux-2.4.17-pre4/arch/sparc64/kernel/sys_sparc.c linux/arch/sparc64/kernel/sys_sparc.c
--- linux-2.4.17-pre4/arch/sparc64/kernel/sys_sparc.c	Tue Oct 30 15:08:11 2001
+++ linux/arch/sparc64/kernel/sys_sparc.c	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.54 2001/10/28 20:49:13 davem Exp $
+/* $Id: sys_sparc.c,v 1.55 2001/11/29 22:52:03 davem Exp $
  * linux/arch/sparc64/kernel/sys_sparc.c
  *
  * This file contains various random system calls that
@@ -255,27 +255,15 @@
 
 asmlinkage int sparc64_personality(unsigned long personality)
 {
-	unsigned long ret, trying, orig_ret;
+	int ret;
 
-	trying = ret = personality;
-
-	if (current->personality == PER_LINUX32 &&
-	    trying == PER_LINUX)
-		trying = ret = PER_LINUX32;
-
-	/* For PER_LINUX32 we want to retain &default_exec_domain.  */
-	if (trying == PER_LINUX32)
+	if (current->personality == PER_LINUX32 && personality == PER_LINUX)
+		personality = PER_LINUX32;
+	ret = sys_personality(personality);
+	if (ret == PER_LINUX32)
 		ret = PER_LINUX;
 
-	orig_ret = ret;
-	ret = sys_personality(ret);
-
-	if (orig_ret == PER_LINUX && trying == PER_LINUX32) {
-		current->personality = PER_LINUX32;
-		ret = PER_LINUX;
-	}
-
-	return (int) ret;
+	return ret;
 }
 
 /* Linux version of mmap */
diff -urN linux-2.4.17-pre4/arch/sparc64/kernel/ttable.S linux/arch/sparc64/kernel/ttable.S
--- linux-2.4.17-pre4/arch/sparc64/kernel/ttable.S	Mon Oct  1 09:19:56 2001
+++ linux/arch/sparc64/kernel/ttable.S	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/* $Id: ttable.S,v 1.35 2001/09/21 02:14:39 kanoj Exp $
+/* $Id: ttable.S,v 1.36 2001/11/28 23:32:16 davem Exp $
  * ttable.S: Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions.
  *
  * Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu)
@@ -15,11 +15,13 @@
 sparc64_ttable_tl0:
 tl0_resv000:	BOOT_KERNEL BTRAP(0x1) BTRAP(0x2) BTRAP(0x3)
 tl0_resv004:	BTRAP(0x4)  BTRAP(0x5) BTRAP(0x6) BTRAP(0x7)
-tl0_iax:	TRAP_NOSAVE(__do_instruction_access_exception)
+tl0_iax:	membar #Sync
+		TRAP_NOSAVE_7INSNS(__do_instruction_access_exception)
 tl0_resv009:	BTRAP(0x9)
 tl0_iae:	TRAP(do_iae)
 tl0_resv00b:	BTRAP(0xb) BTRAP(0xc) BTRAP(0xd) BTRAP(0xe) BTRAP(0xf)
-tl0_ill:	TRAP(do_illegal_instruction)
+tl0_ill:	membar #Sync
+		TRAP_7INSNS(do_illegal_instruction)
 tl0_privop:	TRAP(do_privop)
 tl0_resv012:	BTRAP(0x12) BTRAP(0x13) BTRAP(0x14) BTRAP(0x15) BTRAP(0x16) BTRAP(0x17)
 tl0_resv018:	BTRAP(0x18) BTRAP(0x19) BTRAP(0x1a) BTRAP(0x1b) BTRAP(0x1c) BTRAP(0x1d)
diff -urN linux-2.4.17-pre4/arch/sparc64/lib/blockops.S linux/arch/sparc64/lib/blockops.S
--- linux-2.4.17-pre4/arch/sparc64/lib/blockops.S	Mon Oct  1 09:19:56 2001
+++ linux/arch/sparc64/lib/blockops.S	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.36 2001/09/24 21:44:03 davem Exp $
+/* $Id: blockops.S,v 1.41 2001/12/05 06:05:35 davem Exp $
  * blockops.S: UltraSparc block zero optimized routines.
  *
  * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
@@ -17,10 +17,9 @@
 	fmovd	%reg4, %f56; 	fmovd	%reg5, %f58;		\
 	fmovd	%reg6, %f60; 	fmovd	%reg7, %f62;
 
-#define	TLBTEMP_BASE	(8 * 1024 * 1024)
 #define	DCACHE_SIZE	(PAGE_SIZE * 2)
-#define TLBTEMP_ENT1	(61 << 3)
-#define TLBTEMP_ENT2	(62 << 3)
+#define TLBTEMP_ENT1	(60 << 3)
+#define TLBTEMP_ENT2	(61 << 3)
 #define TLBTEMP_ENTSZ	(1 << 3)
 
 #if (PAGE_SHIFT == 13) || (PAGE_SHIFT == 19)
@@ -110,7 +109,7 @@
 	or		%g2, %g3, %g2
 	add		%o0, %o3, %o0
 	add		%o0, %o1, %o1
-#define FIX_INSN_1	0x96102068 /* mov (13 << 3), %o3 */
+#define FIX_INSN_1	0x96102060 /* mov (12 << 3), %o3 */
 cheetah_patch_1:
 	mov		TLBTEMP_ENT1, %o3
 	rdpr		%pstate, %g3
@@ -134,6 +133,7 @@
 	stxa		%g0, [%o5] ASI_DMMU
 	membar		#Sync
 
+	ldxa		[%o3] ASI_DTLB_DATA_ACCESS, %g0
 	ldxa		[%o3] ASI_DTLB_DATA_ACCESS, %o5
 	stxa		%o0, [%o2] ASI_DMMU
 	stxa		%g1, [%o3] ASI_DTLB_DATA_ACCESS
@@ -152,6 +152,7 @@
 	stxa		%g0, [%g7] ASI_DMMU
 	membar		#Sync
 
+	ldxa		[%o3] ASI_DTLB_DATA_ACCESS, %g0
 	ldxa		[%o3] ASI_DTLB_DATA_ACCESS, %g7
 	stxa		%o1, [%o2] ASI_DMMU
 	stxa		%g2, [%o3] ASI_DTLB_DATA_ACCESS
@@ -169,9 +170,10 @@
 	 nop
 
 cheetah_copy_user_page:
-	mov		121, %o2			! A0 Group
+	sethi		%hi((PAGE_SIZE/64)-7), %o2	! A0 Group
 	prefetch	[%o1 + 0x000], #one_read	! MS
-	prefetch	[%o1 + 0x040], #one_read	! MS Group
+	or		%o2, %lo((PAGE_SIZE/64)-7), %o2	! A1 Group
+	prefetch	[%o1 + 0x040], #one_read	! MS
 	prefetch	[%o1 + 0x080], #one_read	! MS Group
 	prefetch	[%o1 + 0x0c0], #one_read	! MS Group
 	ldd		[%o1 + 0x000], %f0		! MS Group
@@ -402,7 +404,7 @@
 	or		%g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3
 	or		%g1, %g3, %g1
 	add		%o0, %o3, %o0
-#define FIX_INSN_2	0x96102070 /* mov (14 << 3), %o3 */
+#define FIX_INSN_2	0x96102068 /* mov (13 << 3), %o3 */
 cheetah_patch_2:
 	mov		TLBTEMP_ENT2, %o3
 	rdpr		%pstate, %g3
@@ -420,6 +422,7 @@
 	stxa		%g0, [%g7] ASI_DMMU
 	membar		#Sync
 
+	ldxa		[%o3] ASI_DTLB_DATA_ACCESS, %g0
 	ldxa		[%o3] ASI_DTLB_DATA_ACCESS, %g7
 	stxa		%o0, [%o2] ASI_DMMU
 	stxa		%g1, [%o3] ASI_DTLB_DATA_ACCESS
@@ -430,8 +433,9 @@
 clear_page_common:
 	membar		#StoreLoad | #StoreStore | #LoadStore	! LSU	Group
 	fzero		%f0				! FPA	Group
-	mov		PAGE_SIZE/256, %o1		! IEU0
+	sethi		%hi(PAGE_SIZE/256), %o1		! IEU0
 	fzero		%f2				! FPA	Group
+	or		%o1, %lo(PAGE_SIZE/256), %o1	! IEU0
 	faddd		%f0, %f2, %f4			! FPA	Group
 	fmuld		%f0, %f2, %f6			! FPM
 	faddd		%f0, %f2, %f8			! FPA	Group
diff -urN linux-2.4.17-pre4/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- linux-2.4.17-pre4/arch/sparc64/mm/init.c	Thu Dec  6 10:52:25 2001
+++ linux/arch/sparc64/mm/init.c	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.205 2001/11/19 19:03:08 davem Exp $
+/*  $Id: init.c,v 1.207 2001/11/30 06:55:39 davem Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -63,6 +63,8 @@
 
 struct page *mem_map_zero;
 
+int bigkernel = 0;
+
 int do_check_pgt_cache(int low, int high)
 {
         int freed = 0;
@@ -505,6 +507,10 @@
 		   (unsigned long) KERNBASE,
 		   prom_get_mmu_ihandle());
 
+	if (bigkernel)
+		remap_func(((tte_data + 0x400000) & _PAGE_PADDR),
+			(unsigned long) KERNBASE + 0x400000, prom_get_mmu_ihandle());
+
 	/* Flush out that temporary mapping. */
 	spitfire_flush_dtlb_nucleus_page(0x0);
 	spitfire_flush_itlb_nucleus_page(0x0);
@@ -512,6 +518,12 @@
 	/* Now lock us back into the TLBs via OBP. */
 	prom_dtlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);
 	prom_itlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);
+	if (bigkernel) {
+		prom_dtlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, 
+								tte_vaddr + 0x400000);
+		prom_itlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, 
+								tte_vaddr + 0x400000);
+	}
 
 	/* Re-read translations property. */
 	if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) {
@@ -528,6 +540,8 @@
 			unsigned long avoid_start = (unsigned long) KERNBASE;
 			unsigned long avoid_end = avoid_start + (4 * 1024 * 1024);
 
+			if (bigkernel)
+				avoid_end += (4 * 1024 * 1024);
 			if (vaddr < avoid_start) {
 				unsigned long top = vaddr + size;
 
@@ -714,7 +728,8 @@
 		}
 	}
 	if (tlb_type == spitfire) {
-		for (i = 0; i < SPITFIRE_HIGHEST_LOCKED_TLBENT; i++) {
+		int high = SPITFIRE_HIGHEST_LOCKED_TLBENT - bigkernel;
+		for (i = 0; i < high; i++) {
 			unsigned long data;
 
 			/* Spitfire Errata #32 workaround */
@@ -752,7 +767,7 @@
 			}
 		}
 
-		for (i = 0; i < SPITFIRE_HIGHEST_LOCKED_TLBENT; i++) {
+		for (i = 0; i < high; i++) {
 			unsigned long data;
 
 			/* Spitfire Errata #32 workaround */
@@ -790,7 +805,9 @@
 			}
 		}
 	} else if (tlb_type == cheetah) {
-		for (i = 0; i < CHEETAH_HIGHEST_LOCKED_TLBENT; i++) {
+		int high = CHEETAH_HIGHEST_LOCKED_TLBENT - bigkernel;
+
+		for (i = 0; i < high; i++) {
 			unsigned long data;
 
 			data = cheetah_get_ldtlb_data(i);
@@ -814,7 +831,7 @@
 			}
 		}
 
-		for (i = 0; i < CHEETAH_HIGHEST_LOCKED_TLBENT; i++) {
+		for (i = 0; i < high; i++) {
 			unsigned long data;
 
 			data = cheetah_get_litlb_data(i);
@@ -1282,6 +1299,8 @@
 	set_bit(0, mmu_context_bmap);
 
 	real_end = (unsigned long)&_end;
+	if ((real_end > ((unsigned long)KERNBASE + 0x400000)))
+		bigkernel = 1;
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (sparc_ramdisk_image)
 		real_end = (PAGE_ALIGN(real_end) + PAGE_ALIGN(sparc_ramdisk_size));
diff -urN linux-2.4.17-pre4/arch/sparc64/mm/modutil.c linux/arch/sparc64/mm/modutil.c
--- linux-2.4.17-pre4/arch/sparc64/mm/modutil.c	Tue Aug 28 07:09:44 2001
+++ linux/arch/sparc64/mm/modutil.c	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/*  $Id: modutil.c,v 1.9 2001/08/14 22:10:56 davem Exp $
+/*  $Id: modutil.c,v 1.11 2001/12/05 06:05:35 davem Exp $
  *  arch/sparc64/mm/modutil.c
  *
  *  Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -10,10 +10,6 @@
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
-
-#define  MODULES_VADDR	0x0000000001000000ULL  /* Where to map modules */
-#define  MODULES_LEN	0x000000007f000000ULL
-#define  MODULES_END	0x0000000080000000ULL
 
 static struct vm_struct * modvmlist = NULL;
 
diff -urN linux-2.4.17-pre4/arch/sparc64/mm/ultra.S linux/arch/sparc64/mm/ultra.S
--- linux-2.4.17-pre4/arch/sparc64/mm/ultra.S	Thu Dec  6 10:52:25 2001
+++ linux/arch/sparc64/mm/ultra.S	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.69 2001/11/15 10:37:14 davem Exp $
+/* $Id: ultra.S,v 1.70 2001/11/29 16:42:10 kanoj Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
@@ -117,7 +117,7 @@
 	wrpr		%g1, PSTATE_IE, %pstate
 	mov		TLB_TAG_ACCESS, %g3
 	/* XXX Spitfire dependency... */
-	mov		(62 << 3), %g2
+	mov		((SPITFIRE_HIGHEST_LOCKED_TLBENT-1) << 3), %g2
 
 	/* Spitfire Errata #32 workaround. */
 	mov		0x8, %o4
@@ -642,7 +642,7 @@
 	stx		%g0, [%g4 + %lo(errata32_hwbug)]
 
 2:	add		%g2, 1, %g2
-	cmp		%g2, 63
+	cmp		%g2, SPITFIRE_HIGHEST_LOCKED_TLBENT
 	ble,pt		%icc, 1b
 	 sll		%g2, 3, %g3
 	flush		%g6
diff -urN linux-2.4.17-pre4/drivers/block/floppy.c linux/drivers/block/floppy.c
--- linux-2.4.17-pre4/drivers/block/floppy.c	Thu Oct 25 13:58:34 2001
+++ linux/drivers/block/floppy.c	Thu Dec  6 10:53:03 2001
@@ -4498,3 +4498,5 @@
 	}
 }
 #endif
+
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.17-pre4/drivers/block/loop.c linux/drivers/block/loop.c
--- linux-2.4.17-pre4/drivers/block/loop.c	Mon Nov 19 14:48:02 2001
+++ linux/drivers/block/loop.c	Thu Dec  6 10:53:03 2001
@@ -640,6 +640,10 @@
 
 	if (S_ISBLK(inode->i_mode)) {
 		lo_device = inode->i_rdev;
+		if (lo_device == dev) {
+			error = -EBUSY;
+			goto out;
+		}
 	} else if (S_ISREG(inode->i_mode)) {
 		struct address_space_operations *aops = inode->i_mapping->a_ops;
 		/*
diff -urN linux-2.4.17-pre4/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c
--- linux-2.4.17-pre4/drivers/block/paride/pf.c	Thu Oct 25 13:58:35 2001
+++ linux/drivers/block/paride/pf.c	Thu Dec  6 10:53:03 2001
@@ -733,7 +733,8 @@
 	for (k=0;k<len;k++) 
 	   if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
 		l=targ[j++]=buf[k+offs];
-	if (l==0x20) j--; targ[j]=0;
+	if (l==0x20) j--;
+	targ[j]=0;
 }
 
 static int xl( char *buf, int offs )
diff -urN linux-2.4.17-pre4/drivers/block/paride/pg.c linux/drivers/block/paride/pg.c
--- linux-2.4.17-pre4/drivers/block/paride/pg.c	Thu Oct 11 09:04:57 2001
+++ linux/drivers/block/paride/pg.c	Thu Dec  6 10:53:03 2001
@@ -491,7 +491,8 @@
 	for (k=0;k<len;k++) 
 	   if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
 		l=targ[j++]=buf[k+offs];
-	if (l==0x20) j--; targ[j]=0;
+	if (l==0x20) j--;
+	targ[j]=0;
 }
 
 static int pg_identify( int unit, int log )
diff -urN linux-2.4.17-pre4/drivers/block/paride/pseudo.h linux/drivers/block/paride/pseudo.h
--- linux-2.4.17-pre4/drivers/block/paride/pseudo.h	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/pseudo.h	Thu Dec  6 10:53:03 2001
@@ -102,7 +102,7 @@
 		spin_unlock_irqrestore(&ps_spinlock,flags);
 		return;
 	}
-        if (!ps_ready || ps_ready() || (jiffies >= ps_timeout)) {
+        if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) {
                 ps_continuation = NULL;
         	spin_unlock_irqrestore(&ps_spinlock,flags);
                 con();
@@ -131,7 +131,7 @@
 	        spin_unlock_irqrestore(&ps_spinlock,flags);
 		return;
 	}
-        if (!ps_ready || ps_ready() || (jiffies >= ps_timeout)) {
+        if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) {
                 ps_continuation = NULL;
 	        spin_unlock_irqrestore(&ps_spinlock,flags);
                 con();
diff -urN linux-2.4.17-pre4/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c
--- linux-2.4.17-pre4/drivers/block/paride/pt.c	Thu Oct 11 09:04:57 2001
+++ linux/drivers/block/paride/pt.c	Thu Dec  6 10:53:03 2001
@@ -577,7 +577,8 @@
 	for (k=0;k<len;k++) 
 	   if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
 		l=targ[j++]=buf[k+offs];
-	if (l==0x20) j--; targ[j]=0;
+	if (l==0x20) j--;
+	targ[j]=0;
 }
 
 static int xn( char *buf, int offs, int size )
diff -urN linux-2.4.17-pre4/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
--- linux-2.4.17-pre4/drivers/char/agp/agpgart_be.c	Fri Nov 16 10:11:22 2001
+++ linux/drivers/char/agp/agpgart_be.c	Thu Dec  6 10:53:03 2001
@@ -409,8 +409,18 @@
 	 *        AGP devices and collect their data.
 	 */
 
-	while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8,
-					device)) != NULL) {
+
+	pci_for_each_dev(device)
+	{
+		/*
+		 *	Enable AGP devices. Most will be VGA display but
+		 *	some may be coprocessors on non VGA devices too
+		 */
+		 
+		if((((device->class >> 16) & 0xFF) != PCI_BASE_CLASS_DISPLAY) &&
+			(device->class != (PCI_CLASS_PROCESSOR_CO << 8)))
+			continue;
+
 		pci_read_config_dword(device, 0x04, &scratch);
 
 		if (!(scratch & 0x00100000))
diff -urN linux-2.4.17-pre4/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.4.17-pre4/drivers/ide/ide-disk.c	Tue Nov 20 21:35:28 2001
+++ linux/drivers/ide/ide-disk.c	Thu Dec  6 10:53:03 2001
@@ -858,8 +858,10 @@
 		}
 		/* We must remove proc entries defined in this module.
 		   Otherwise we oops while accessing these entries */
+#ifdef CONFIG_PROC_FS
 		if (drive->proc)
 			ide_remove_proc_entries(drive->proc, idedisk_proc);
+#endif
 	}
 	ide_unregister_module(&idedisk_module);
 }
diff -urN linux-2.4.17-pre4/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.4.17-pre4/drivers/ide/ide-floppy.c	Thu Oct 11 09:14:32 2001
+++ linux/drivers/ide/ide-floppy.c	Thu Dec  6 10:53:03 2001
@@ -2071,8 +2071,10 @@
 		}
 		/* We must remove proc entries defined in this module.
 		   Otherwise we oops while accessing these entries */
+#ifdef CONFIG_PROC_FS
 		if (drive->proc)
 			ide_remove_proc_entries(drive->proc, idefloppy_proc);
+#endif
 	}
 	ide_unregister_module(&idefloppy_module);
 }
diff -urN linux-2.4.17-pre4/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- linux-2.4.17-pre4/drivers/isdn/hisax/config.c	Thu Dec  6 10:52:26 2001
+++ linux/drivers/isdn/hisax/config.c	Thu Dec  6 10:53:03 2001
@@ -338,7 +338,7 @@
 
 #define EMPTY_CARD	{0, DEFAULT_PROTO, {0, 0, 0, 0}, NULL}
 
-struct IsdnCard cards[] = {
+struct IsdnCard cards[HISAX_MAX_CARDS] = {
 	FIRST_CARD,
 	EMPTY_CARD,
 	EMPTY_CARD,
@@ -349,14 +349,15 @@
 	EMPTY_CARD,
 };
 
-static char HiSaxID[64] __devinitdata = { 0, };
+#define HISAX_IDSIZE (HISAX_MAX_CARDS*8)
+static char HiSaxID[HISAX_IDSIZE] __devinitdata = { 0, };
 
 char *HiSax_id __devinitdata = HiSaxID;
 #ifdef MODULE
 /* Variables for insmod */
-static int type[8] __devinitdata = { 0, };
-static int protocol[8] __devinitdata = { 0, };
-static int io[8] __devinitdata = { 0, };
+static int type[HISAX_MAX_CARDS] __devinitdata = { 0, };
+static int protocol[HISAX_MAX_CARDS] __devinitdata = { 0, };
+static int io[HISAX_MAX_CARDS] __devinitdata = { 0, };
 #undef IO0_IO1
 #ifdef CONFIG_HISAX_16_3
 #define IO0_IO1
@@ -366,25 +367,30 @@
 #define IO0_IO1
 #endif
 #ifdef IO0_IO1
-static int io0[8] __devinitdata = { 0, };
-static int io1[8] __devinitdata = { 0, };
+static int io0[HISAX_MAX_CARDS] __devinitdata = { 0, };
+static int io1[HISAX_MAX_CARDS] __devinitdata = { 0, };
 #endif
-static int irq[8] __devinitdata = { 0, };
-static int mem[8] __devinitdata = { 0, };
+static int irq[HISAX_MAX_CARDS] __devinitdata = { 0, };
+static int mem[HISAX_MAX_CARDS] __devinitdata = { 0, };
 static char *id __devinitdata = HiSaxID;
 
+/* string magic */
+#define h1(s) h2(s)
+#define h2(s) #s
+#define PARM_PARA "1-"h1(HISAX_MAX_CARDS)"i"
+
 MODULE_DESCRIPTION("ISDN4Linux: Driver for passive ISDN cards");
 MODULE_AUTHOR("Karsten Keil");
 MODULE_LICENSE("GPL");
-MODULE_PARM(type, "1-8i");
-MODULE_PARM(protocol, "1-8i");
-MODULE_PARM(io, "1-8i");
-MODULE_PARM(irq, "1-8i");
-MODULE_PARM(mem, "1-8i");
+MODULE_PARM(type, PARM_PARA);
+MODULE_PARM(protocol, PARM_PARA);
+MODULE_PARM(io, PARM_PARA);
+MODULE_PARM(irq, PARM_PARA);
+MODULE_PARM(mem, PARM_PARA);
 MODULE_PARM(id, "s");
 #ifdef IO0_IO1
-MODULE_PARM(io0, "1-8i");
-MODULE_PARM(io1, "1-8i");
+MODULE_PARM(io0, PARM_PARA);
+MODULE_PARM(io1, PARM_PARA);
 #endif
 #endif /* MODULE */
 
@@ -476,12 +482,14 @@
 		i++;
 	}
 	if (str && *str) {
-		strcpy(HiSaxID, str);
-		HiSax_id = HiSaxID;
-	} else {
+		if (strlen(str) < HISAX_IDSIZE)
+			strcpy(HiSaxID, str);
+		else
+			printk(KERN_WARNING "HiSax: ID too long!")
+	} else
 		strcpy(HiSaxID, "HiSax");
-		HiSax_id = HiSaxID;
-	}
+
+	HiSax_id = HiSaxID;
 	return 1;
 }
 
diff -urN linux-2.4.17-pre4/drivers/net/8139too.c linux/drivers/net/8139too.c
--- linux-2.4.17-pre4/drivers/net/8139too.c	Mon Nov 26 05:29:17 2001
+++ linux/drivers/net/8139too.c	Thu Dec  6 10:53:03 2001
@@ -1636,23 +1636,24 @@
 	struct rtl8139_private *tp = dev->priv;
 	void *ioaddr = tp->mmio_addr;
 	unsigned int entry;
+	unsigned int len = skb->len;
 
 	/* Calculate the next Tx descriptor entry. */
 	entry = tp->cur_tx % NUM_TX_DESC;
 
-	if (likely(skb->len < TX_BUF_SIZE)) {
+	if (likely(len < TX_BUF_SIZE)) {
 		skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
 		dev_kfree_skb(skb);
 	} else {
 		dev_kfree_skb(skb);
 		tp->stats.tx_dropped++;
 		return 0;
-  	}
+	}
 
 	/* Note: the chip doesn't have auto-pad! */
 	spin_lock_irq(&tp->lock);
 	RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
-		   tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
+		   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
 
 	dev->trans_start = jiffies;
 
@@ -1663,8 +1664,8 @@
 		netif_stop_queue (dev);
 	spin_unlock_irq(&tp->lock);
 
-	DPRINTK ("%s: Queued Tx packet at %p size %u to slot %d.\n",
-		 dev->name, skb->data, skb->len, entry);
+	DPRINTK ("%s: Queued Tx packet size %u to slot %d.\n",
+		 dev->name, len, entry);
 
 	return 0;
 }
diff -urN linux-2.4.17-pre4/drivers/net/sungem.c linux/drivers/net/sungem.c
--- linux-2.4.17-pre4/drivers/net/sungem.c	Sun Oct 21 10:36:54 2001
+++ linux/drivers/net/sungem.c	Thu Dec  6 10:53:03 2001
@@ -1,7 +1,15 @@
-/* $Id: sungem.c,v 1.30 2001/10/17 06:55:10 davem Exp $
+/* $Id: sungem.c,v 1.43 2001/12/05 08:40:54 davem Exp $
  * sungem.c: Sun GEM ethernet driver.
  *
  * Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com)
+ * 
+ * Support for Apple GMAC and assorted PHYs by
+ * Benjamin Herrenscmidt (benh@kernel.crashing.org)
+ * 
+ * TODO: 
+ *  - Get rid of all those nasty mdelay's and replace them
+ * with schedule_timeout.
+ *  - Implement WOL
  */
 
 #include <linux/module.h>
@@ -23,11 +31,15 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
 
 #ifdef __sparc__
 #include <asm/idprom.h>
@@ -45,15 +57,33 @@
 
 #include "sungem.h"
 
+#define DRV_NAME	"sungem"
+#define DRV_VERSION	"0.96"
+#define DRV_RELDATE	"11/17/01"
+#define DRV_AUTHOR	"David S. Miller (davem@redhat.com)"
+
 static char version[] __devinitdata =
-        "sungem.c:v0.95 16/Oct/01 David S. Miller (davem@redhat.com)\n";
+        DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
 
-MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
+MODULE_AUTHOR(DRV_AUTHOR);
 MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver");
 MODULE_LICENSE("GPL");
 
 MODULE_PARM(gem_debug, "i");
 MODULE_PARM_DESC(gem_debug, "(ignored)");
+MODULE_PARM(link_mode, "i");
+
+static int link_mode;
+
+static u16 link_modes[] __devinitdata = {
+	BMCR_ANENABLE,			/* 0 : autoneg */
+	0,				/* 1 : 10bt half duplex */
+	BMCR_SPEED100,			/* 2 : 100bt half duplex */
+	BMCR_SPD2, /* verify this */	/* 3 : 1000bt half duplex */
+	BMCR_FULLDPLX,			/* 4 : 10bt full duplex */
+	BMCR_SPEED100|BMCR_FULLDPLX,	/* 5 : 100bt full duplex */
+	BMCR_SPD2|BMCR_FULLDPLX		/* 6 : 1000bt full duplex */
+};
 
 #define GEM_MODULE_NAME	"gem"
 #define PFX GEM_MODULE_NAME ": "
@@ -73,7 +103,7 @@
 	 * they only support 10/100 speeds. -DaveM
 	 * 
 	 * Apple's GMAC does support gigabit on machines with
-	 * the BCM5400 or 5401 PHYs. -BenH
+	 * the BCM54xx PHYs. -BenH
 	 */
 	{ PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_RIO_GEM,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
@@ -362,10 +392,6 @@
 	return 1;
 }
 
-static void gem_stop(struct gem *, unsigned long);
-static void gem_init_rings(struct gem *, int);
-static void gem_init_hw(struct gem *);
-
 /* All non-normal interrupt conditions get serviced here.
  * Returns non-zero if we should just exit the interrupt
  * handler right now (ie. if we reset the card which invalidates
@@ -418,9 +444,9 @@
 	return 0;
 
 do_reset:
-	gem_stop(gp, gp->regs);
-	gem_init_rings(gp, 1);
-	gem_init_hw(gp);
+	gp->reset_task_pending = 1;
+	schedule_task(&gp->reset_task);
+
 	return 1;
 }
 
@@ -627,6 +653,10 @@
 	struct gem *gp = dev->priv;
 
 	printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
+	if (!gp->hw_running) {
+		printk("%s: hrm.. hw not running !\n", dev->name);
+		return;
+	}
 	printk(KERN_ERR "%s: TX_STATE[%08x:%08x:%08x]\n",
 	       dev->name,
 	       readl(gp->regs + TXDMA_CFG),
@@ -640,13 +670,19 @@
 
 	spin_lock_irq(&gp->lock);
 
-	gem_stop(gp, gp->regs);
-	gem_init_rings(gp, 1);
-	gem_init_hw(gp);
+	gp->reset_task_pending = 1;
+	schedule_task(&gp->reset_task);
 
 	spin_unlock_irq(&gp->lock);
+}
 
-	netif_wake_queue(dev);
+static __inline__ int gem_intme(int entry)
+{
+	/* Algorithm: IRQ every 1/2 of descriptors. */
+	if (!(entry & ((TX_RING_SIZE>>1)-1)))
+		return 1;
+
+	return 0;
 }
 
 static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -690,15 +726,22 @@
 					~PAGE_MASK),
 				       len, PCI_DMA_TODEVICE);
 		ctrl |= TXDCTRL_SOF | TXDCTRL_EOF | len;
+		if (gem_intme(entry))
+			ctrl |= TXDCTRL_INTME;
 		txd->buffer = cpu_to_le64(mapping);
 		txd->control_word = cpu_to_le64(ctrl);
 		entry = NEXT_TX(entry);
 	} else {
 		struct gem_txd *txd;
 		u32 first_len;
+		u64 intme;
 		dma_addr_t first_mapping;
 		int frag, first_entry = entry;
 
+		intme = 0;
+		if (gem_intme(entry))
+			intme |= TXDCTRL_INTME;
+
 		/* We must give this initial chunk to the device last.
 		 * Otherwise we could race with the device.
 		 */
@@ -727,11 +770,15 @@
 			txd->buffer = cpu_to_le64(mapping);
 			txd->control_word = cpu_to_le64(this_ctrl | len);
 
+			if (gem_intme(entry))
+				intme |= TXDCTRL_INTME;
+
 			entry = NEXT_TX(entry);
 		}
 		txd = &gp->init_block->txd[first_entry];
 		txd->buffer = cpu_to_le64(first_mapping);
-		txd->control_word = cpu_to_le64(ctrl | TXDCTRL_SOF | first_len);
+		txd->control_word =
+			cpu_to_le64(ctrl | TXDCTRL_SOF | intme | first_len);
 	}
 
 	gp->tx_new = entry;
@@ -761,18 +808,19 @@
 		return -EINVAL;
 
 	spin_lock_irq(&gp->lock);
-	gem_stop(gp, gp->regs);
 	dev->mtu = new_mtu;
-	gem_init_rings(gp, 1);
-	gem_init_hw(gp);
+	gp->reset_task_pending = 1;
+	schedule_task(&gp->reset_task);
 	spin_unlock_irq(&gp->lock);
 
+	flush_scheduled_tasks();
+
 	return 0;
 }
 
 #define STOP_TRIES 32
 
-static void gem_stop(struct gem *gp, unsigned long regs)
+static void gem_stop(struct gem *gp)
 {
 	int limit;
 	u32 val;
@@ -781,13 +829,13 @@
 	writel(0xffffffff, gp->regs + GREG_IMASK);
 
 	/* Reset the chip */
-	writel(GREG_SWRST_TXRST | GREG_SWRST_RXRST, regs + GREG_SWRST);
+	writel(GREG_SWRST_TXRST | GREG_SWRST_RXRST, gp->regs + GREG_SWRST);
 
 	limit = STOP_TRIES;
 
 	do {
 		udelay(20);
-		val = readl(regs + GREG_SWRST);
+		val = readl(gp->regs + GREG_SWRST);
 		if (limit-- <= 0)
 			break;
 	} while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST));
@@ -810,6 +858,9 @@
 	val = readl(gp->regs + MAC_RXCFG);
 	writel(val | MAC_RXCFG_ENAB, gp->regs + MAC_RXCFG);
 
+	(void) readl(gp->regs + MAC_RXCFG);
+	udelay(100);
+
 	writel(GREG_STAT_TXDONE, gp->regs + GREG_IMASK);
 
 	writel(RX_RING_SIZE - 4, gp->regs + RXDMA_KICK);
@@ -828,6 +879,88 @@
 	{ 1, 0, 1 },	/* 1000BT */
 };
 
+static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
+{
+	u16 ctl;
+	
+	/* Setup link parameters */
+	if (!ep)
+		goto start_aneg;
+	if (ep->autoneg == AUTONEG_ENABLE) {
+		/* TODO: parse ep->advertising */
+		gp->link_advertise |= (ADVERTISE_10HALF | ADVERTISE_10FULL);
+		gp->link_advertise |= (ADVERTISE_100HALF | ADVERTISE_100FULL);
+		/* Can I advertise gigabit here ? I'd need BCM PHY docs... */
+		gp->link_cntl = BMCR_ANENABLE;
+	} else {
+		gp->link_cntl = 0;
+		if (ep->speed == SPEED_100)
+			gp->link_cntl |= BMCR_SPEED100;
+		else if (ep->speed == SPEED_1000 && gp->gigabit_capable)
+			/* Hrm... check if this is right... */
+			gp->link_cntl |= BMCR_SPD2;
+		if (ep->duplex == DUPLEX_FULL)
+			gp->link_cntl |= BMCR_FULLDPLX;
+	}
+
+start_aneg:
+	spin_lock_irq(&gp->lock);
+	if (!gp->hw_running) {
+		spin_unlock_irq(&gp->lock);
+		return;
+	}
+
+	/* Configure PHY & start aneg */
+	ctl = phy_read(gp, MII_BMCR);
+	ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE);
+	ctl |= gp->link_cntl;
+	if (ctl & BMCR_ANENABLE) {
+		ctl |= BMCR_ANRESTART;
+		gp->lstate = link_aneg;
+	} else {
+		gp->lstate = link_force_ok;
+	}
+	phy_write(gp, MII_BMCR, ctl);
+
+	gp->timer_ticks = 0;
+	gp->link_timer.expires = jiffies + ((12 * HZ) / 10);
+	add_timer(&gp->link_timer);
+	spin_unlock_irq(&gp->lock);
+}
+
+static void gem_read_mii_link_mode(struct gem *gp, int *fd, int *spd, int *pause)
+{
+	u32 val;
+
+	*fd = 0;
+	*spd = 10;
+	*pause = 0;
+	
+	if (gp->phy_mod == phymod_bcm5400 ||
+	    gp->phy_mod == phymod_bcm5401 ||
+	    gp->phy_mod == phymod_bcm5411) {
+		int link_mode;	
+
+	    	val = phy_read(gp, MII_BCM5400_AUXSTATUS);
+		link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
+			     MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT);
+		*fd = phy_BCM5400_link_table[link_mode][0];
+		*spd = phy_BCM5400_link_table[link_mode][2] ?
+			1000 :
+			(phy_BCM5400_link_table[link_mode][1] ? 100 : 10);
+		val = phy_read(gp, MII_LPA);
+		if (val & LPA_PAUSE)
+			*pause = 1;
+	} else {
+		val = phy_read(gp, MII_LPA);
+
+		if (val & (LPA_10FULL | LPA_100FULL))
+			*fd = 1;
+		if (val & (LPA_100FULL | LPA_100HALF))
+			*spd = 100;
+	}
+}
+
 /* A link-up condition has occurred, initialize and enable the
  * rest of the chip.
  */
@@ -842,32 +975,13 @@
 
 	if (gp->phy_type == phy_mii_mdio0 ||
 	    gp->phy_type == phy_mii_mdio1) {
-		if (gp->lstate == aneg_wait) {
-			if (gp->phy_mod == phymod_bcm5400 ||
-			    gp->phy_mod == phymod_bcm5401 ||
-			    gp->phy_mod == phymod_bcm5411) {
-				int link_mode;	
-		    		val = phy_read(gp, PHY_BCM5400_AUXSTATUS);
-		    		link_mode = (val & PHY_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
-		    			PHY_BCM5400_AUXSTATUS_LINKMODE_SHIFT;
-		    		full_duplex = phy_BCM5400_link_table[link_mode][0];
-		    		speed = phy_BCM5400_link_table[link_mode][2] ? 1000
-		    			: (phy_BCM5400_link_table[link_mode][1] ? 100 : 10);
-					val = phy_read(gp, PHY_LPA);
-					if (val & PHY_LPA_PAUSE)
-						pause = 1;	
-			} else {
-				val = phy_read(gp, PHY_LPA);
-				if (val & (PHY_LPA_10FULL | PHY_LPA_100FULL))
-					full_duplex = 1;
-				if (val & (PHY_LPA_100FULL | PHY_LPA_100HALF))
-					speed = 100;
-			}
-		} else {
-			val = phy_read(gp, PHY_CTRL);
-			if (val & PHY_CTRL_FDPLX)
+		val = phy_read(gp, MII_BMCR);
+		if (val & BMCR_ANENABLE)
+			gem_read_mii_link_mode(gp, &full_duplex, &speed, &pause);
+		else {
+			if (val & BMCR_FULLDPLX)
 				full_duplex = 1;
-			if (val & PHY_CTRL_SPD100)
+			if (val & BMCR_SPEED100)
 				speed = 100;
 		}
 	} else {
@@ -944,56 +1058,142 @@
 
 static int gem_mdio_link_not_up(struct gem *gp)
 {
-	if (gp->lstate == aneg_wait) {
-		u16 val = phy_read(gp, PHY_CTRL);
+	if (gp->lstate == link_force_ret) {
+		printk(KERN_INFO "%s: Autoneg failed again, keeping"
+			" forced mode\n", gp->dev->name);
+		phy_write(gp, MII_BMCR, gp->link_fcntl);
+		gp->timer_ticks = 5;
+		gp->lstate = link_force_ok;
+	} else if (gp->lstate == link_aneg) {
+		u16 val = phy_read(gp, MII_BMCR);
 
 		/* Try forced modes. */
-		val &= ~(PHY_CTRL_ANRES | PHY_CTRL_ANENAB);
-		val &= ~(PHY_CTRL_FDPLX);
-		val |= PHY_CTRL_SPD100;
-		phy_write(gp, PHY_CTRL, val);
-		gp->timer_ticks = 0;
-		gp->lstate = force_wait;
-		return 1;
+		val &= ~(BMCR_ANRESTART | BMCR_ANENABLE);
+		val &= ~(BMCR_FULLDPLX);
+		val |= BMCR_SPEED100;
+		phy_write(gp, MII_BMCR, val);
+		gp->timer_ticks = 5;
+		gp->lstate = link_force_try;
 	} else {
 		/* Downgrade from 100 to 10 Mbps if necessary.
 		 * If already at 10Mbps, warn user about the
 		 * situation every 10 ticks.
 		 */
-		u16 val = phy_read(gp, PHY_CTRL);
-		if (val & PHY_CTRL_SPD100) {
-			val &= ~PHY_CTRL_SPD100;
-			phy_write(gp, PHY_CTRL, val);
-			gp->timer_ticks = 0;
-			return 1;
+		u16 val = phy_read(gp, MII_BMCR);
+		if (val & BMCR_SPEED100) {
+			val &= ~BMCR_SPEED100;
+			phy_write(gp, MII_BMCR, val);
+			gp->timer_ticks = 5;
 		} else {
-			printk(KERN_ERR "%s: Link down, cable problem?\n",
-			       gp->dev->name);
-			val |= (PHY_CTRL_ANRES | PHY_CTRL_ANENAB);
-			phy_write(gp, PHY_CTRL, val);
-			gp->timer_ticks = 1;
-			gp->lstate = aneg_wait;
 			return 1;
 		}
 	}
+	return 0;
+}
+
+static void gem_init_rings(struct gem *, int);
+static void gem_init_hw(struct gem *, int);
+
+static void gem_reset_task(void *data)
+{
+	struct gem *gp = (struct gem *) data;
+
+	/* The link went down, we reset the ring, but keep
+	 * DMA stopped. Todo: Use this function for reset
+	 * on error as well.
+	 */
+	if (gp->hw_running && gp->opened) {
+		/* Make sure we don't get interrupts or tx packets */
+		spin_lock_irq(&gp->lock);
+
+		netif_stop_queue(gp->dev);
+
+		writel(0xffffffff, gp->regs + GREG_IMASK);
+
+		spin_unlock_irq(&gp->lock);
+
+		/* Reset the chip & rings */
+		gem_stop(gp);
+		gem_init_rings(gp, 0);
+		gem_init_hw(gp, 0);
+
+		netif_wake_queue(gp->dev);
+	}
+	gp->reset_task_pending = 0;
 }
 
 static void gem_link_timer(unsigned long data)
 {
 	struct gem *gp = (struct gem *) data;
-	int restart_timer = 0;
 
-	gp->timer_ticks++;
+	if (!gp->hw_running)
+		return;
+
+	/* If the link of task is still pending, we just
+	 * reschedule the link timer
+	 */
+	if (gp->reset_task_pending)
+		goto restart;
+	    	
+	spin_lock_irq(&gp->lock);
 	if (gp->phy_type == phy_mii_mdio0 ||
 	    gp->phy_type == phy_mii_mdio1) {
-		u16 val = phy_read(gp, PHY_STAT);
+		u16 val = phy_read(gp, MII_BMSR);
+		int up;
 
-		if (val & PHY_STAT_LSTAT) {
-			gem_set_link_modes(gp);
-		} else if (gp->timer_ticks < 10) {
-			restart_timer = 1;
+		/* When using autoneg, we really wait for ANEGCOMPLETE or we may
+		 * get a "transcient" incorrect link state
+		 */
+#if 0
+		{
+			u16 cntl = phy_read(gp, MII_BMCR);
+			if (cntl & BMCR_ANENABLE)
+				up = (val & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS)) == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS);
+			else
+				up = (val & BMSR_LSTATUS) != 0;
+		}
+#else
+		up = (val & BMSR_LSTATUS) != 0;
+#endif
+		if (up) {
+			/* Ok, here we got a link. If we had it due to a forced
+			 * fallback, and we were configured for autoneg, we do
+			 * retry a short autoneg pass. If you know your hub is
+			 * broken, use ethtool ;)
+			 */
+			if (gp->lstate == link_force_try && (gp->link_cntl & BMCR_ANENABLE)) {
+				gp->lstate = link_force_ret;
+				gp->link_fcntl = phy_read(gp, MII_BMCR);
+				gp->timer_ticks = 5;
+				printk(KERN_INFO "%s: Got link after fallback, retrying autoneg"
+				       " once...\n", gp->dev->name);
+				phy_write(gp, MII_BMCR,
+					  gp->link_fcntl | BMCR_ANENABLE | BMCR_ANRESTART);
+			} else if (gp->lstate != link_up) {
+				gp->lstate = link_up;
+				if (gp->opened)
+					gem_set_link_modes(gp);
+			}
 		} else {
-			restart_timer = gem_mdio_link_not_up(gp);
+			int restart = 0;
+
+			/* If the link was previously up, we restart the
+			 * whole process
+			 */
+			if (gp->lstate == link_up) {
+				gp->lstate = link_down;
+				printk(KERN_INFO "%s: Link down\n", gp->dev->name);
+				gp->reset_task_pending = 1;
+				schedule_task(&gp->reset_task);
+				restart = 1;
+			} else if (++gp->timer_ticks > 10)
+				restart = gem_mdio_link_not_up(gp);
+
+			if (restart) {
+				spin_unlock_irq(&gp->lock);
+				gem_begin_auto_negotiation(gp, NULL);
+				return;
+			}
 		}
 	} else {
 		u32 val = readl(gp->regs + PCS_MIISTAT);
@@ -1001,17 +1201,17 @@
 		if (!(val & PCS_MIISTAT_LS))
 			val = readl(gp->regs + PCS_MIISTAT);
 
-		if ((val & PCS_MIISTAT_LS) == 0) {
-			restart_timer = 1;
-		} else {
-			gem_set_link_modes(gp);
+		if ((val & PCS_MIISTAT_LS) != 0) {
+			gp->lstate = link_up;
+			if (gp->opened)
+				gem_set_link_modes(gp);
 		}
 	}
 
-	if (restart_timer) {
-		gp->link_timer.expires = jiffies + ((12 * HZ) / 10);
-		add_timer(&gp->link_timer);
-	}
+restart:
+	gp->link_timer.expires = jiffies + ((12 * HZ) / 10);
+	add_timer(&gp->link_timer);
+	spin_unlock_irq(&gp->lock);
 }
 
 static void gem_clean_rings(struct gem *gp)
@@ -1108,66 +1308,72 @@
 	}
 }
 
-static int
-gem_reset_one_mii_phy(struct gem *gp, int phy_addr)
+static int gem_reset_one_mii_phy(struct gem *gp, int phy_addr)
 {
 	u16 val;
 	int limit = 10000;
 	
-	val = __phy_read(gp, PHY_CTRL, phy_addr);
-	val &= ~PHY_CTRL_ISO;
-	val |= PHY_CTRL_RST;
-	__phy_write(gp, PHY_CTRL, val, phy_addr);
+	val = __phy_read(gp, MII_BMCR, phy_addr);
+	val &= ~BMCR_ISOLATE;
+	val |= BMCR_RESET;
+	__phy_write(gp, MII_BMCR, val, phy_addr);
 
 	udelay(100);
 
 	while (limit--) {
-		val = __phy_read(gp, PHY_CTRL, phy_addr);
-		if ((val & PHY_CTRL_RST) == 0)
+		val = __phy_read(gp, MII_BMCR, phy_addr);
+		if ((val & BMCR_RESET) == 0)
 			break;
 		udelay(10);
 	}
-	if ((val & PHY_CTRL_ISO) && limit > 0)
-		__phy_write(gp, PHY_CTRL, val & ~PHY_CTRL_ISO, phy_addr);
+	if ((val & BMCR_ISOLATE) && limit > 0)
+		__phy_write(gp, MII_BMCR, val & ~BMCR_ISOLATE, phy_addr);
 	
 	return (limit <= 0);
 }
 
-static void
-gem_init_bcm5400_phy(struct gem *gp)
+static void gem_init_bcm5201_phy(struct gem *gp)
+{
+	u16 data;
+
+	data = phy_read(gp, MII_BCM5201_MULTIPHY);
+	data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE;
+	phy_write(gp, MII_BCM5201_MULTIPHY, data);
+}
+
+static void gem_init_bcm5400_phy(struct gem *gp)
 {
 	u16 data;
 
 	/* Configure for gigabit full duplex */
-	data = phy_read(gp, PHY_BCM5400_AUXCONTROL);
-	data |= PHY_BCM5400_AUXCONTROL_PWR10BASET;
-	phy_write(gp, PHY_BCM5400_AUXCONTROL, data);
-	
-	data = phy_read(gp, PHY_BCM5400_GB_CONTROL);
-	data |= PHY_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
-	phy_write(gp, PHY_BCM5400_GB_CONTROL, data);
+	data = phy_read(gp, MII_BCM5400_AUXCONTROL);
+	data |= MII_BCM5400_AUXCONTROL_PWR10BASET;
+	phy_write(gp, MII_BCM5400_AUXCONTROL, data);
+	
+	data = phy_read(gp, MII_BCM5400_GB_CONTROL);
+	data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+	phy_write(gp, MII_BCM5400_GB_CONTROL, data);
 	
 	mdelay(10);
 
 	/* Reset and configure cascaded 10/100 PHY */
 	gem_reset_one_mii_phy(gp, 0x1f);
 	
-	data = __phy_read(gp, PHY_BCM5201_MULTIPHY, 0x1f);
-	data |= PHY_BCM5201_MULTIPHY_SERIALMODE;
-	__phy_write(gp, PHY_BCM5201_MULTIPHY, data, 0x1f);
+	data = __phy_read(gp, MII_BCM5201_MULTIPHY, 0x1f);
+	data |= MII_BCM5201_MULTIPHY_SERIALMODE;
+	__phy_write(gp, MII_BCM5201_MULTIPHY, data, 0x1f);
 
-	data = phy_read(gp, PHY_BCM5400_AUXCONTROL);
-	data &= ~PHY_BCM5400_AUXCONTROL_PWR10BASET;
-	phy_write(gp, PHY_BCM5400_AUXCONTROL, data);
+	data = phy_read(gp, MII_BCM5400_AUXCONTROL);
+	data &= ~MII_BCM5400_AUXCONTROL_PWR10BASET;
+	phy_write(gp, MII_BCM5400_AUXCONTROL, data);
 }
 
-static void
-gem_init_bcm5401_phy(struct gem *gp)
+static void gem_init_bcm5401_phy(struct gem *gp)
 {
 	u16 data;
 	int rev;
 
-	rev = phy_read(gp, PHY_ID1) & 0x000f;
+	rev = phy_read(gp, MII_PHYSID2) & 0x000f;
 	if (rev == 0 || rev == 3) {
 		/* Some revisions of 5401 appear to need this
 		 * initialisation sequence to disable, according
@@ -1191,22 +1397,21 @@
 	}
 	
 	/* Configure for gigabit full duplex */
-	data = phy_read(gp, PHY_BCM5400_GB_CONTROL);
-	data |= PHY_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
-	phy_write(gp, PHY_BCM5400_GB_CONTROL, data);
+	data = phy_read(gp, MII_BCM5400_GB_CONTROL);
+	data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+	phy_write(gp, MII_BCM5400_GB_CONTROL, data);
 
 	mdelay(1);
 
 	/* Reset and configure cascaded 10/100 PHY */
 	gem_reset_one_mii_phy(gp, 0x1f);
 	
-	data = __phy_read(gp, PHY_BCM5201_MULTIPHY, 0x1f);
-	data |= PHY_BCM5201_MULTIPHY_SERIALMODE;
-	__phy_write(gp, PHY_BCM5201_MULTIPHY, data, 0x1f);
+	data = __phy_read(gp, MII_BCM5201_MULTIPHY, 0x1f);
+	data |= MII_BCM5201_MULTIPHY_SERIALMODE;
+	__phy_write(gp, MII_BCM5201_MULTIPHY, data, 0x1f);
 }
 
-static void
-gem_init_bcm5411_phy(struct gem *gp)
+static void gem_init_bcm5411_phy(struct gem *gp)
 {
 	u16 data;
 
@@ -1220,20 +1425,30 @@
 	/* Here, Apple seems to want to reset it, do
 	 * it as well
 	 */
-	phy_write(gp, PHY_CTRL, PHY_CTRL_RST);
+	phy_write(gp, MII_BMCR, BMCR_RESET);
 
 	/* Start autoneg */
-	phy_write(gp, PHY_CTRL,
-		  (PHY_CTRL_ANENAB | PHY_CTRL_FDPLX |
-		   PHY_CTRL_ANRES | PHY_CTRL_SPD2));
-
-	data = phy_read(gp, PHY_BCM5400_GB_CONTROL);
-	data |= PHY_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
-	phy_write(gp, PHY_BCM5400_GB_CONTROL, data);
+	phy_write(gp, MII_BMCR,
+		  (BMCR_ANENABLE | BMCR_FULLDPLX |
+		   BMCR_ANRESTART | BMCR_SPD2));
+
+	data = phy_read(gp, MII_BCM5400_GB_CONTROL);
+	data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+	phy_write(gp, MII_BCM5400_GB_CONTROL, data);
 }
 
 static void gem_init_phy(struct gem *gp)
 {
+	u32 mifcfg;
+
+	if (!gp->wake_on_lan && gp->phy_mod == phymod_bcm5201)
+		phy_write(gp, MII_BCM5201_INTERRUPT, 0);
+
+	/* Revert MIF CFG setting done on stop_phy */
+	mifcfg = readl(gp->regs + MIF_CFG);
+	mifcfg &= ~MIF_CFG_BBMODE;
+	writel(mifcfg, gp->regs + MIF_CFG);
+	
 #ifdef CONFIG_ALL_PPC
 	if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
 		int i;
@@ -1241,7 +1456,7 @@
 		pmac_call_feature(PMAC_FTR_GMAC_PHY_RESET, gp->of_node, 0, 0);
 		for (i = 0; i < 32; i++) {
 			gp->mii_phy_addr = i;
-			if (phy_read(gp, PHY_CTRL) != 0xffff)
+			if (phy_read(gp, MII_BMCR) != 0xffff)
 				break;
 		}
 		if (i == 32) {
@@ -1277,54 +1492,68 @@
 		/* Take PHY out of isloate mode and reset it. */
 		gem_reset_one_mii_phy(gp, gp->mii_phy_addr);
 
-		phy_id = (phy_read(gp, PHY_ID0) << 16 | phy_read(gp, PHY_ID1))
+		phy_id = (phy_read(gp, MII_PHYSID1) << 16 | phy_read(gp, MII_PHYSID2))
 			 	& 0xfffffff0;
 		printk(KERN_INFO "%s: MII PHY ID: %x ", gp->dev->name, phy_id);
 		switch(phy_id) {
-			case 0x406210:
-				gp->phy_mod = phymod_bcm5201;
-				printk("BCM 5201\n");
-				break;
-			case 0x4061e0:
-				printk("BCM 5221\n");
-				gp->phy_mod = phymod_bcm5221;
-				break;
-			case 0x206040:
-				printk("BCM 5400\n");
-				gp->phy_mod = phymod_bcm5400;
-				gem_init_bcm5400_phy(gp);
-				break;
-			case 0x206050:
-				printk("BCM 5401\n");
-				gp->phy_mod = phymod_bcm5401;
-				gem_init_bcm5401_phy(gp);
-				break;
-			case 0x206070:
-				printk("BCM 5411\n");
-				gp->phy_mod = phymod_bcm5411;
-				gem_init_bcm5411_phy(gp);
-				break;
-			default:
-				printk("Generic\n");
-				gp->phy_mod = phymod_generic;
+		case 0x406210:
+			gp->phy_mod = phymod_bcm5201;
+			gem_init_bcm5201_phy(gp);
+			printk("BCM 5201\n");
+			break;
+
+		case 0x4061e0:
+			printk("BCM 5221\n");
+			gp->phy_mod = phymod_bcm5221;
+			break;
+
+		case 0x206040:
+			printk("BCM 5400\n");
+			gp->phy_mod = phymod_bcm5400;
+			gem_init_bcm5400_phy(gp);
+			gp->gigabit_capable = 1;
+			break;
+
+		case 0x206050:
+			printk("BCM 5401\n");
+			gp->phy_mod = phymod_bcm5401;
+			gem_init_bcm5401_phy(gp);
+			gp->gigabit_capable = 1;
+			break;
+
+		case 0x206070:
+			printk("BCM 5411\n");
+			gp->phy_mod = phymod_bcm5411;
+			gem_init_bcm5411_phy(gp);
+			gp->gigabit_capable = 1;
+			break;
+
+		case 0x18074c0:
+			printk("Lucent\n");
+			gp->phy_mod = phymod_generic;
+			break;
+
+		case 0x437420:
+			printk("Enable Semiconductor\n");
+			gp->phy_mod = phymod_generic;
+			break;
+
+		default:
+			printk("Unknown\n");
+			gp->phy_mod = phymod_generic;
+			break;
 		};
 
 		/* Init advertisement and enable autonegotiation. */
-		val = phy_read(gp, PHY_CTRL);
-		val &= ~PHY_CTRL_ANENAB;
-		phy_write(gp, PHY_CTRL, val);
+		val = phy_read(gp, MII_BMCR);
+		val &= ~BMCR_ANENABLE;
+		phy_write(gp, MII_BMCR, val);
 		udelay(10);
 		
-		phy_write(gp, PHY_ADV,
-			  phy_read(gp, PHY_ADV) |
-			  (PHY_ADV_10HALF | PHY_ADV_10FULL |
-			   PHY_ADV_100HALF | PHY_ADV_100FULL));
-
-		val = phy_read(gp, PHY_CTRL);
-		val |= PHY_CTRL_ANENAB;
-		phy_write(gp, PHY_CTRL, val);
-		val |= PHY_CTRL_ANRES;
-		phy_write(gp, PHY_CTRL, val);
+		phy_write(gp, MII_ADVERTISE,
+			  phy_read(gp, MII_ADVERTISE) |
+			  (ADVERTISE_10HALF | ADVERTISE_10FULL |
+			   ADVERTISE_100HALF | ADVERTISE_100FULL));
 	} else {
 		u32 val;
 		int limit;
@@ -1379,6 +1608,7 @@
 		else
 			val |= PCS_SCTRL_LOOP;
 		writel(val, gp->regs + PCS_SCTRL);
+		gp->gigabit_capable = 1;
 	}
 }
 
@@ -1392,7 +1622,7 @@
 
 	writel(desc_dma >> 32, gp->regs + TXDMA_DBHI);
 	writel(desc_dma & 0xffffffff, gp->regs + TXDMA_DBLOW);
-	desc_dma += (TX_RING_SIZE * sizeof(struct gem_txd));
+	desc_dma += (INIT_BLOCK_TX_RING_SIZE * sizeof(struct gem_txd));
 
 	writel(0, gp->regs + TXDMA_KICK);
 
@@ -1410,12 +1640,12 @@
 	writel(val, gp->regs + RXDMA_PTHRESH);
 
 	if (readl(gp->regs + GREG_BIFCFG) & GREG_BIFCFG_M66EN)
-		writel(((6 & RXDMA_BLANK_IPKTS) |
-			((4 << 12) & RXDMA_BLANK_ITIME)),
+		writel(((5 & RXDMA_BLANK_IPKTS) |
+			((8 << 12) & RXDMA_BLANK_ITIME)),
 		       gp->regs + RXDMA_BLANK);
 	else
-		writel(((6 & RXDMA_BLANK_IPKTS) |
-			((2 << 12) & RXDMA_BLANK_ITIME)),
+		writel(((5 & RXDMA_BLANK_IPKTS) |
+			((4 << 12) & RXDMA_BLANK_ITIME)),
 		       gp->regs + RXDMA_BLANK);
 }
 
@@ -1551,18 +1781,20 @@
 	writel(0, gp->regs + MAC_MCCFG);
 	writel(0, gp->regs + MAC_XIFCFG);
 
-	writel((MAC_TXSTAT_URUN | MAC_TXSTAT_MPE |
-		MAC_TXSTAT_NCE | MAC_TXSTAT_ECE |
-		MAC_TXSTAT_LCE | MAC_TXSTAT_FCE |
-		MAC_TXSTAT_DTE | MAC_TXSTAT_PCE), gp->regs + MAC_TXMASK);
-	writel((MAC_RXSTAT_OFLW | MAC_RXSTAT_FCE |
-		MAC_RXSTAT_ACE | MAC_RXSTAT_CCE |
-		MAC_RXSTAT_LCE | MAC_RXSTAT_VCE), gp->regs + MAC_RXMASK);
-	writel(0, gp->regs + MAC_MCMASK);
+	/* Setup MAC interrupts.  We want to get all of the interesting
+	 * counter expiration events, but we do not want to hear about
+	 * normal rx/tx as the DMA engine tells us that.
+	 */
+	writel(MAC_TXSTAT_XMIT, gp->regs + MAC_TXMASK);
+	writel(MAC_RXSTAT_RCV, gp->regs + MAC_RXMASK);
+
+	/* Don't enable even the PAUSE interrupts for now, we
+	 * make no use of those events other than to record them.
+	 */
+	writel(0xffffffff, gp->regs + MAC_MCMASK);
 }
 
-static void
-gem_init_pause_thresholds(struct gem* gp)
+static void gem_init_pause_thresholds(struct gem *gp)
 {
 	/* Calculate pause thresholds.  Setting the OFF threshold to the
 	 * full RX fifo size effectively disables PAUSE generation which
@@ -1580,11 +1812,7 @@
 	}
 
 	{
-		u32 cfg = readl(gp->regs + GREG_BIFCFG);
-
-		/* XXX Why do I do this? -DaveM XXX */
-		cfg |= GREG_BIFCFG_B64DIS;
-		writel(cfg, gp->regs + GREG_BIFCFG);
+		u32 cfg;
 
 		cfg  = GREG_CFG_IBURST;
 		cfg |= ((31 << 1) & GREG_CFG_TXDMALIM);
@@ -1598,21 +1826,15 @@
 	struct pci_dev *pdev = gp->pdev;
 	u32 mif_cfg;
 
-	/* On Apple's sungem, we can't realy on registers as the chip
+	/* On Apple's sungem, we can't rely on registers as the chip
 	 * was been powered down by the firmware. We do the PHY lookup
 	 * when the interface is opened and we configure the driver
 	 * with known values.
 	 */
 	if (pdev->vendor == PCI_VENDOR_ID_APPLE) {
 		gp->phy_type = phy_mii_mdio0;
-		mif_cfg = readl(gp->regs + MIF_CFG);
-		mif_cfg &= ~MIF_CFG_PSELECT;
-		writel(mif_cfg, gp->regs + MIF_CFG);
-		writel(PCS_DMODE_MGM, gp->regs + PCS_DMODE);
-		writel(MAC_XIFCFG_OE, gp->regs + MAC_XIFCFG);
 		gp->tx_fifo_sz = readl(gp->regs + TXDMA_FSZ) * 64;
 		gp->rx_fifo_sz = readl(gp->regs + RXDMA_FSZ) * 64;
-		gem_init_pause_thresholds(gp);
 		return 0;
 	}
 
@@ -1651,7 +1873,7 @@
 
 		for (i = 0; i < 32; i++) {
 			gp->mii_phy_addr = i;
-			if (phy_read(gp, PHY_CTRL) != 0xffff)
+			if (phy_read(gp, MII_BMCR) != 0xffff)
 				break;
 		}
 		if (i == 32) {
@@ -1685,12 +1907,10 @@
 		}
 	}
 
-	gem_init_pause_thresholds(gp);
-
 	return 0;
 }
 
-static void gem_init_hw(struct gem *gp)
+static void gem_init_hw(struct gem *gp, int restart_link)
 {
 	/* On Apple's gmac, I initialize the PHY only after
 	 * setting up the chip. It appears the gigabit PHYs
@@ -1698,18 +1918,28 @@
 	 * the chip is not running, I suspect it might not
 	 * be clocked at that point. --BenH
 	 */
-	if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
-		gem_check_invariants(gp);
-		gp->hw_running = 1;
-	}
-	gem_init_phy(gp);
+	if (restart_link)
+		gem_init_phy(gp);
 	gem_init_dma(gp);
 	gem_init_mac(gp);
+	gem_init_pause_thresholds(gp);
 
-	gp->timer_ticks = 0;
-	gp->lstate = aneg_wait;
-	gp->link_timer.expires = jiffies + ((12 * HZ) / 10);
-	add_timer(&gp->link_timer);
+	spin_lock_irq(&gp->lock);
+	if (restart_link) {
+		/* Default aneg parameters */
+		gp->timer_ticks = 0;
+		gp->lstate = link_down;
+
+		spin_unlock_irq(&gp->lock);
+
+		/* Can I advertise gigabit here ? I'd need BCM PHY docs... */
+		gem_begin_auto_negotiation(gp, NULL);
+	} else {
+		if (gp->lstate == link_up)
+			gem_set_link_modes(gp);
+
+		spin_unlock_irq(&gp->lock);
+	}
 }
 
 #ifdef CONFIG_ALL_PPC
@@ -1717,10 +1947,10 @@
  * setup properly. There appear to be no need to restore the
  * base addresses.
  */
-static void
-gem_apple_powerup(struct gem* gp)
+static void gem_apple_powerup(struct gem *gp)
 {
 	u16 cmd;
+	u32 mif_cfg;
 
 	pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 1);
 
@@ -1731,31 +1961,162 @@
     	pci_write_config_word(gp->pdev, PCI_COMMAND, cmd);
     	pci_write_config_byte(gp->pdev, PCI_LATENCY_TIMER, 6);
     	pci_write_config_byte(gp->pdev, PCI_CACHE_LINE_SIZE, 8);
+
+	mdelay(1);
+	
+	mif_cfg = readl(gp->regs + MIF_CFG);
+	mif_cfg &= ~(MIF_CFG_PSELECT|MIF_CFG_POLL|MIF_CFG_BBMODE|MIF_CFG_MDI1);
+	mif_cfg |= MIF_CFG_MDI0;
+	writel(mif_cfg, gp->regs + MIF_CFG);
+	writel(PCS_DMODE_MGM, gp->regs + PCS_DMODE);
+	writel(MAC_XIFCFG_OE, gp->regs + MAC_XIFCFG);
+
+	mdelay(1);
 }
 
 /* Turn off the chip's clock */
-static void
-gem_apple_powerdown(struct gem* gp)
+static void gem_apple_powerdown(struct gem *gp)
 {
 	pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 0);
 }
+
+#endif /* CONFIG_ALL_PPC */
+
+static void gem_stop_phy(struct gem *gp)
+{
+	u32 mifcfg;
+
+	if (!gp->wake_on_lan && gp->phy_mod == phymod_bcm5201)
+		phy_write(gp, MII_BCM5201_INTERRUPT, 0);
+
+	/* Make sure we aren't polling PHY status change. We
+	 * don't currently use that feature though
+	 */
+	mifcfg = readl(gp->regs + MIF_CFG);
+	mifcfg &= ~MIF_CFG_POLL;
+	writel(mifcfg, gp->regs + MIF_CFG);
+
+	/* Here's a strange hack used by both MacOS 9 and X */
+	phy_write(gp, MII_LPA, phy_read(gp, MII_LPA));
+
+	if (gp->wake_on_lan) {
+		/* Setup wake-on-lan */
+	} else
+		writel(0, gp->regs + MAC_RXCFG);
+	writel(0, gp->regs + MAC_TXCFG);
+	writel(0, gp->regs + MAC_XIFCFG);
+	writel(0, gp->regs + TXDMA_CFG);
+	writel(0, gp->regs + RXDMA_CFG);
+
+	if (!gp->wake_on_lan) {
+		gem_stop(gp);
+		writel(MAC_TXRST_CMD, gp->regs + MAC_TXRST);
+		writel(MAC_RXRST_CMD, gp->regs + MAC_RXRST);
+		if (gp->phy_mod == phymod_bcm5400 || gp->phy_mod == phymod_bcm5401 ||
+		    gp->phy_mod == phymod_bcm5411) {
+#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
+			phy_write(gp, MII_BMCR, BMCR_PDOWN);
+#endif
+		} else if (gp->phy_mod == phymod_bcm5201 || gp->phy_mod == phymod_bcm5221) {
+#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
+			u16 val = phy_read(gp, MII_BCM5201_AUXMODE2)
+			phy_write(gp, MII_BCM5201_AUXMODE2,
+				  val & ~MII_BCM5201_AUXMODE2_LOWPOWER);
+#endif				
+			phy_write(gp, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE);
+		}
+
+		/* According to Apple, we must set the MDIO pins to this begnign
+		 * state or we may 1) eat more current, 2) damage some PHYs
+		 */
+		writel(mifcfg | MIF_CFG_BBMODE, gp->regs + MIF_CFG);
+		writel(0, gp->regs + MIF_BBCLK);
+		writel(0, gp->regs + MIF_BBDATA);
+		writel(0, gp->regs + MIF_BBOENAB);
+		writel(MAC_XIFCFG_GMII | MAC_XIFCFG_LBCK, gp->regs + MAC_XIFCFG);
+		(void) readl(gp->regs + MAC_XIFCFG);
+	}
+}
+
+/* Shut down the chip, must be called with pm_sem held.  */
+static void gem_shutdown(struct gem *gp)
+{
+	/* Make us not-running to avoid timers respawning */
+	gp->hw_running = 0;
+
+	/* Stop the link timer */
+	del_timer_sync(&gp->link_timer);
+
+	/* Stop the reset task */
+	while (gp->reset_task_pending)
+		schedule();
+	
+	/* Actually stop the chip */
+	if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
+		gem_stop_phy(gp);
+	else
+		gem_stop(gp);
+
+#ifdef CONFIG_ALL_PPC
+	/* Power down the chip */
+	if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
+		gem_apple_powerdown(gp);
 #endif /* CONFIG_ALL_PPC */
+}
+
+static void gem_pm_task(void *data)
+{
+	struct gem *gp = (struct gem *) data;
+
+	/* We assume if we can't lock the pm_sem, then open() was
+	 * called again (or suspend()), and we can safely ignore
+	 * the PM request
+	 */
+	if (down_trylock(&gp->pm_sem))
+		return;
+
+	/* Driver was re-opened or already shut down */
+	if (gp->opened || !gp->hw_running) {
+		up(&gp->pm_sem);
+		return;
+	}
+
+	gem_shutdown(gp);
+
+	up(&gp->pm_sem);
+}
+
+static void gem_pm_timer(unsigned long data)
+{
+	struct gem *gp = (struct gem *) data;
+
+	schedule_task(&gp->pm_task);
+}
 
 static int gem_open(struct net_device *dev)
 {
 	struct gem *gp = dev->priv;
-	unsigned long regs = gp->regs;
+	int hw_was_up = gp->hw_running;
 
-	del_timer(&gp->link_timer);
+	down(&gp->pm_sem);
 
+	/* Stop the PM timer/task */
+	del_timer(&gp->pm_timer);
+	flush_scheduled_tasks();
+
+	if (!gp->hw_running) {
 #ifdef CONFIG_ALL_PPC
-	/* First, we need to bring up the chip */
-	if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
-		gem_apple_powerup(gp);
+		/* First, we need to bring up the chip */
+		if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
+			gem_apple_powerup(gp);
+			gem_check_invariants(gp);
+		}
 #endif /* CONFIG_ALL_PPC */
+		/* Reset the chip */
+		gem_stop(gp);
 
-	/* Reset the chip */
-	gem_stop(gp, regs);
+		gp->hw_running = 1;
+	}
 
 	/* We can now request the interrupt as we know it's masked
 	 * on the controller
@@ -1763,9 +2124,14 @@
 	if (request_irq(gp->pdev->irq, gem_interrupt,
 			SA_SHIRQ, dev->name, (void *)dev)) {
 #ifdef CONFIG_ALL_PPC
-		if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
+		if (!hw_was_up && gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
 			gem_apple_powerdown(gp);
 #endif /* CONFIG_ALL_PPC */
+		/* Fire the PM timer that will shut us down in about 10 seconds */
+		gp->pm_timer.expires = jiffies + 10*HZ;
+		add_timer(&gp->pm_timer);
+		up(&gp->pm_sem);
+
 		return -EAGAIN;
 	}
 
@@ -1773,7 +2139,11 @@
 	gem_init_rings(gp, 0);
 
 	/* Init & setup chip hardware */
-	gem_init_hw(gp);
+	gem_init_hw(gp, !hw_was_up);
+
+	gp->opened = 1;
+
+	up(&gp->pm_sem);
 
 	return 0;
 }
@@ -1782,17 +2152,110 @@
 {
 	struct gem *gp = dev->priv;
 
-	del_timer(&gp->link_timer);
-	gem_stop(gp, gp->regs);
+	/* Make sure we don't get distracted by suspend/resume */
+	down(&gp->pm_sem);
+
+	/* Stop traffic, mark us closed */
+	spin_lock_irq(&gp->lock);
+
+	gp->opened = 0;	
+	writel(0xffffffff, gp->regs + GREG_IMASK);
+	netif_stop_queue(dev);
+
+	spin_unlock_irq(&gp->lock);
+
+	/* Stop chip */
+	gem_stop(gp);
+
+	/* Get rid of rings */
 	gem_clean_rings(gp);
-	gp->hw_running = 0;
+
+	/* Bye, the pm timer will finish the job */
+	free_irq(gp->pdev->irq, (void *) dev);
+
+	/* Fire the PM timer that will shut us down in about 10 seconds */
+	gp->pm_timer.expires = jiffies + 10*HZ;
+	add_timer(&gp->pm_timer);
+
+	up(&gp->pm_sem);
+	
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int gem_suspend(struct pci_dev *pdev, u32 state)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct gem *gp = dev->priv;
+
+	/* We hold the PM semaphore during entire driver
+	 * sleep time
+	 */
+	down(&gp->pm_sem);
+
+	printk(KERN_INFO "%s: suspending, WakeOnLan %s\n",
+	       dev->name, gp->wake_on_lan ? "enabled" : "disabled");
+	
+	/* If the driver is opened, we stop the DMA */
+	if (gp->opened) {
+		/* Stop traffic, mark us closed */
+		netif_device_detach(dev);
+
+		spin_lock_irq(&gp->lock);
+
+		writel(0xffffffff, gp->regs + GREG_IMASK);
+
+		spin_unlock_irq(&gp->lock);
+
+		/* Stop chip */
+		gem_stop(gp);
+
+		/* Get rid of ring buffers */
+		gem_clean_rings(gp);
+
+		if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
+			disable_irq(gp->pdev->irq);
+	}
+
+	if (gp->hw_running) {
+		/* Kill PM timer if any */
+		del_timer_sync(&gp->pm_timer);
+		flush_scheduled_tasks();
+
+		gem_shutdown(gp);
+	}
+
+	return 0;
+}
+
+static int gem_resume(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct gem *gp = dev->priv;
+
+	printk(KERN_INFO "%s: resuming\n", dev->name);
+
+	if (gp->opened) {
 #ifdef CONFIG_ALL_PPC
-	if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
-		gem_apple_powerdown(gp);
+		/* First, we need to bring up the chip */
+		if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
+			gem_apple_powerup(gp);
+			gem_check_invariants(gp);
+		}
 #endif /* CONFIG_ALL_PPC */
-	free_irq(gp->pdev->irq, (void *)dev);
+		gem_stop(gp);
+		gp->hw_running = 1;
+		gem_init_rings(gp, 0);
+		gem_init_hw(gp, 1);
+		netif_device_attach(dev);
+		if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
+			enable_irq(gp->pdev->irq);
+	}
+	up(&gp->pm_sem);
+
 	return 0;
 }
+#endif /* CONFIG_PM */
 
 static struct net_device_stats *gem_get_stats(struct net_device *dev)
 {
@@ -1908,12 +2371,219 @@
 		writel(hash_table[15], gp->regs + MAC_HASH15);
 	}
 
+	/* Hrm... we may walk on the reset task here... */
 	netif_wake_queue(dev);
 }
 
+/* Eventually add support for changing the advertisement
+ * on autoneg.
+ */
+static int gem_ethtool_ioctl(struct net_device *dev, void *ep_user)
+{
+	struct gem *gp = dev->priv;
+	u16 bmcr;
+	int full_duplex, speed, pause;
+	struct ethtool_cmd ecmd;
+
+	if (copy_from_user(&ecmd, ep_user, sizeof(ecmd)))
+		return -EFAULT;
+		
+	switch(ecmd.cmd) {
+        case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = { cmd: ETHTOOL_GDRVINFO };
+
+		strncpy(info.driver, DRV_NAME, ETHTOOL_BUSINFO_LEN);
+		strncpy(info.version, DRV_VERSION, ETHTOOL_BUSINFO_LEN);
+		info.fw_version[0] = '\0';
+		strncpy(info.bus_info, gp->pdev->slot_name, ETHTOOL_BUSINFO_LEN);
+		info.regdump_len = 0; /*SUNGEM_NREGS;*/
+
+		if (copy_to_user(ep_user, &info, sizeof(info)))
+			return -EFAULT;
+
+		return 0;
+	}
+
+	case ETHTOOL_GSET:
+		ecmd.supported =
+			(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+			 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+			 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
+
+		if (gp->gigabit_capable)
+			ecmd.supported |=
+				(SUPPORTED_1000baseT_Half |
+				 SUPPORTED_1000baseT_Full);
+
+		/* XXX hardcoded stuff for now */
+		ecmd.port = PORT_MII;
+		ecmd.transceiver = XCVR_EXTERNAL;
+		ecmd.phy_address = 0; /* XXX fixed PHYAD */
+
+		/* Record PHY settings if HW is on. */
+		if (gp->hw_running) {
+			bmcr = phy_read(gp, MII_BMCR);
+			gem_read_mii_link_mode(gp, &full_duplex, &speed, &pause);
+		} else
+			bmcr = 0;
+		if (bmcr & BMCR_ANENABLE) {
+			ecmd.autoneg = AUTONEG_ENABLE;
+			ecmd.speed = speed == 10 ? SPEED_10 : (speed == 1000 ? SPEED_1000 : SPEED_100);
+			ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+		} else {
+			ecmd.autoneg = AUTONEG_DISABLE;
+			ecmd.speed =
+				(bmcr & BMCR_SPEED100) ?
+				SPEED_100 : SPEED_10;
+			ecmd.duplex =
+				(bmcr & BMCR_FULLDPLX) ?
+				DUPLEX_FULL : DUPLEX_HALF;
+		}
+		if (copy_to_user(ep_user, &ecmd, sizeof(ecmd)))
+			return -EFAULT;
+		return 0;
+
+	case ETHTOOL_SSET:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		/* Verify the settings we care about. */
+		if (ecmd.autoneg != AUTONEG_ENABLE &&
+		    ecmd.autoneg != AUTONEG_DISABLE)
+			return -EINVAL;
+
+		if (ecmd.autoneg == AUTONEG_DISABLE &&
+		    ((ecmd.speed != SPEED_100 &&
+		      ecmd.speed != SPEED_10) ||
+		     (ecmd.duplex != DUPLEX_HALF &&
+		      ecmd.duplex != DUPLEX_FULL)))
+			return -EINVAL;
+
+		/* Apply settings and restart link process */
+		if (gp->hw_running)
+			del_timer(&gp->link_timer);
+		gem_begin_auto_negotiation(gp, &ecmd);
+		return 0;
+
+	case ETHTOOL_NWAY_RST:
+		if ((gp->link_cntl & BMCR_ANENABLE) == 0)
+			return -EINVAL;
+		if (gp->hw_running)
+			del_timer(&gp->link_timer);
+		gem_begin_auto_negotiation(gp, NULL);
+		return 0;
+
+	case ETHTOOL_GWOL:
+	case ETHTOOL_SWOL:
+		break; /* todo */
+
+	/* get link status */
+	case ETHTOOL_GLINK: {
+		struct ethtool_value edata = { cmd: ETHTOOL_GLINK };
+
+		edata.data = (gp->lstate == link_up);
+		if (copy_to_user(ep_user, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+
+	/* get message-level */
+	case ETHTOOL_GMSGLVL: {
+		struct ethtool_value edata = { cmd: ETHTOOL_GMSGLVL };
+
+		edata.data = gem_debug;
+		if (copy_to_user(ep_user, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+
+	/* set message-level */
+	case ETHTOOL_SMSGLVL: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, ep_user, sizeof(edata)))
+			return -EFAULT;
+		gem_debug = edata.data;
+		return 0;
+	}
+
+#if 0
+	case ETHTOOL_GREGS: {
+		struct ethtool_regs regs;
+		u32 *regbuf;
+		int r = 0;
+
+		if (copy_from_user(&regs, useraddr, sizeof(regs)))
+			return -EFAULT;
+		
+		if (regs.len > SUNGEM_NREGS) {
+			regs.len = SUNGEM_NREGS;
+		}
+		regs.version = 0;
+		if (copy_to_user(useraddr, &regs, sizeof(regs)))
+			return -EFAULT;
+
+		if (!gp->hw_running)
+			return -ENODEV;
+		useraddr += offsetof(struct ethtool_regs, data);
+
+		/* Use kmalloc to avoid bloating the stack */
+		regbuf = kmalloc(4 * SUNGEM_NREGS, GFP_KERNEL);
+		if (!regbuf)
+			return -ENOMEM;
+		spin_lock_irq(&np->lock);
+		gem_get_regs(gp, regbuf);
+		spin_unlock_irq(&np->lock);
+
+		if (copy_to_user(useraddr, regbuf, regs.len*sizeof(u32)))
+			r = -EFAULT;
+		kfree(regbuf);
+		return r;
+	}
+#endif	
+	};
+
+	return -EOPNOTSUPP;
+}
+
 static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-	return -EINVAL;
+	struct gem *gp = dev->priv;
+	struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+	int rc = -EOPNOTSUPP;
+	
+	/* Hold the PM semaphore while doing ioctl's or we may collide
+	 * with open/close and power management and oops.
+	 */
+	down(&gp->pm_sem);
+	
+	switch (cmd) {
+	case SIOCETHTOOL:
+		rc = gem_ethtool_ioctl(dev, ifr->ifr_data);
+		break;
+
+	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
+		data->phy_id = gp->mii_phy_addr;
+		/* Fallthrough... */
+
+	case SIOCGMIIREG:		/* Read MII PHY register. */
+		data->val_out = __phy_read(gp, data->reg_num & 0x1f, data->phy_id & 0x1f);
+		rc = 0;
+		break;
+
+	case SIOCSMIIREG:		/* Write MII PHY register. */
+		if (!capable(CAP_NET_ADMIN)) {
+			rc = -EPERM;
+		} else {
+			__phy_write(gp, data->reg_num & 0x1f, data->val_in, data->phy_id & 0x1f);
+			rc = 0;
+		}
+		break;
+	};
+
+	up(&gp->pm_sem);
+	
+	return rc;
 }
 
 static int __devinit gem_get_device_address(struct gem *gp)
@@ -2030,6 +2700,26 @@
 	gp->dev = dev;
 
 	spin_lock_init(&gp->lock);
+	init_MUTEX(&gp->pm_sem);
+
+	init_timer(&gp->link_timer);
+	gp->link_timer.function = gem_link_timer;
+	gp->link_timer.data = (unsigned long) gp;
+
+	init_timer(&gp->pm_timer);
+	gp->pm_timer.function = gem_pm_timer;
+	gp->pm_timer.data = (unsigned long) gp;
+
+	INIT_TQUEUE(&gp->pm_task, gem_pm_task, gp);
+	INIT_TQUEUE(&gp->reset_task, gem_reset_task, gp);
+	
+	/* Default link parameters */
+	if (link_mode >= 0 && link_mode <= 6)
+		gp->link_cntl = link_modes[link_mode];
+	else
+		gp->link_cntl = BMCR_ANENABLE;
+	gp->lstate = link_down;
+	gp->timer_ticks = 0;
 
 	gp->regs = (unsigned long) ioremap(gemreg_base, gemreg_len);
 	if (gp->regs == 0UL) {
@@ -2038,9 +2728,26 @@
 		goto err_out_free_mmio_res;
 	}
 
-	/* On Apple's, we might not access the hardware at that point */
+	/* On Apple, we power the chip up now in order for check
+	 * invariants to work, but also because the firmware might
+	 * not have properly shut down the PHY.
+	 */
+#ifdef CONFIG_ALL_PPC
+	if (pdev->vendor == PCI_VENDOR_ID_APPLE) {
+		gem_apple_powerup(gp);
+		if (gem_check_invariants(gp))
+			goto err_out_iounmap;
+		gem_stop(gp);
+		gp->hw_running = 1;
+		gem_init_phy(gp);
+		gem_begin_auto_negotiation(gp, NULL);
+	}
+#endif
+	/* Non Apple hardware, we just reset the chip and check
+	 * for invariants
+	 */
 	if (pdev->vendor != PCI_VENDOR_ID_APPLE) {
-		gem_stop(gp, gp->regs);
+		gem_stop(gp);
 		if (gem_check_invariants(gp))
 			goto err_out_iounmap;
 		gp->hw_running = 1;
@@ -2074,10 +2781,6 @@
 		       i == 5 ? ' ' : ':');
 	printk("\n");
 
-	init_timer(&gp->link_timer);
-	gp->link_timer.function = gem_link_timer;
-	gp->link_timer.data = (unsigned long) gp;
-
 	dev->open = gem_open;
 	dev->stop = gem_close;
 	dev->hard_start_xmit = gem_start_xmit;
@@ -2095,9 +2798,20 @@
 	if (pci_using_dac)
 		dev->features |= NETIF_F_HIGHDMA;
 
+	/* Fire the PM timer that will shut us down in about 10 seconds */
+	gp->pm_timer.expires = jiffies + 10*HZ;
+	add_timer(&gp->pm_timer);
+
 	return 0;
 
 err_out_iounmap:
+	down(&gp->pm_sem);
+	/* Stop the PM timer & task */
+	del_timer_sync(&gp->pm_timer);
+	flush_scheduled_tasks();
+	if (gp->hw_running)
+		gem_shutdown(gp);
+	up(&gp->pm_sem);
 	iounmap((void *) gp->regs);
 
 err_out_free_mmio_res:
@@ -2120,6 +2834,14 @@
 
 		unregister_netdev(dev);
 
+		down(&gp->pm_sem);
+		/* Stop the PM timer & task */
+		del_timer_sync(&gp->pm_timer);
+		flush_scheduled_tasks();
+		if (gp->hw_running)
+			gem_shutdown(gp);
+		up(&gp->pm_sem);
+
 		pci_free_consistent(pdev,
 				    sizeof(struct gem_init_block),
 				    gp->init_block,
@@ -2127,9 +2849,6 @@
 		iounmap((void *) gp->regs);
 		release_mem_region(pci_resource_start(pdev, 0),
 				   pci_resource_len(pdev, 0));
-#ifdef CONFIG_ALL_PPC
-		pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 0);
-#endif		
 		kfree(dev);
 
 		pci_set_drvdata(pdev, NULL);
@@ -2141,6 +2860,10 @@
 	id_table:	gem_pci_tbl,
 	probe:		gem_init_one,
 	remove:		gem_remove_one,
+#ifdef CONFIG_PM
+	suspend:	gem_suspend,
+	resume:		gem_resume,
+#endif /* CONFIG_PM */
 };
 
 static int __init gem_init(void)
diff -urN linux-2.4.17-pre4/drivers/net/sungem.h linux/drivers/net/sungem.h
--- linux-2.4.17-pre4/drivers/net/sungem.h	Sun Oct 21 10:36:54 2001
+++ linux/drivers/net/sungem.h	Thu Dec  6 10:53:03 2001
@@ -1,4 +1,4 @@
-/* $Id: sungem.h,v 1.8 2001/10/17 05:55:39 davem Exp $
+/* $Id: sungem.h,v 1.10 2001/11/29 03:57:33 davem Exp $
  * sungem.h: Definitions for Sun GEM ethernet driver.
  *
  * Copyright (C) 2000 David S. Miller (davem@redhat.com)
@@ -753,64 +753,38 @@
 #define PROM_SIZE	0x0fffffUL	/* Size of ROM			*/
 #define PROM_END	0x200000UL	/* End of ROM			*/
 
-/* MII phy registers */
-#define PHY_CTRL	0x00
-#define PHY_STAT	0x01
-#define PHY_ID0		0x02
-#define PHY_ID1		0x03
-#define PHY_ADV		0x04
-#define PHY_LPA		0x05
-
-#define PHY_CTRL_SPD2	0x0040		/* Gigabit enable? (bcm5411)	*/
-#define PHY_CTRL_FDPLX	0x0100		/* Full duplex			*/
-#define PHY_CTRL_ISO	0x0400		/* Isloate MII from PHY		*/
-#define PHY_CTRL_ANRES	0x0200		/* Auto-negotiation restart	*/
-#define PHY_CTRL_ANENAB	0x1000		/* Auto-negotiation enable	*/
-#define PHY_CTRL_SPD100	0x2000		/* Select 100Mbps		*/
-#define PHY_CTRL_RST	0x8000		/* Reset PHY			*/
-
-#define PHY_STAT_LSTAT	0x0004		/* Link status			*/
-#define PHY_STAT_ANEGC	0x0020		/* Auto-negotiation complete	*/
-
-#define PHY_ADV_10HALF	0x0020
-#define PHY_ADV_10FULL	0x0040
-#define PHY_ADV_100HALF	0x0080
-#define PHY_ADV_100FULL	0x0100
-
-#define PHY_LPA_10HALF	0x0020
-#define PHY_LPA_10FULL	0x0040
-#define PHY_LPA_100HALF	0x0080
-#define PHY_LPA_100FULL	0x0100
-#define PHY_LPA_PAUSE	0x0400
-#define PHY_LPA_FAULT	0x2000
+/* MII definitions missing from mii.h */
+
+#define BMCR_SPD2	0x0040		/* Gigabit enable? (bcm5411)	*/
+#define LPA_PAUSE	0x0400
 
 /* More PHY registers (specific to Broadcom models) */
 
 /* MII BCM5201 MULTIPHY interrupt register */
-#define PHY_BCM5201_INTERRUPT			0x1A
-#define PHY_BCM5201_INTERRUPT_INTENABLE		0x4000
+#define MII_BCM5201_INTERRUPT			0x1A
+#define MII_BCM5201_INTERRUPT_INTENABLE		0x4000
 
-#define PHY_BCM5201_AUXMODE2			0x1B
-#define PHY_BCM5201_AUXMODE2_LOWPOWER		0x0008
+#define MII_BCM5201_AUXMODE2			0x1B
+#define MII_BCM5201_AUXMODE2_LOWPOWER		0x0008
 
-#define PHY_BCM5201_MULTIPHY                    0x1E
+#define MII_BCM5201_MULTIPHY                    0x1E
 
 /* MII BCM5201 MULTIPHY register bits */
-#define PHY_BCM5201_MULTIPHY_SERIALMODE         0x0002
-#define PHY_BCM5201_MULTIPHY_SUPERISOLATE       0x0008
+#define MII_BCM5201_MULTIPHY_SERIALMODE         0x0002
+#define MII_BCM5201_MULTIPHY_SUPERISOLATE       0x0008
 
 /* MII BCM5400 1000-BASET Control register */
-#define PHY_BCM5400_GB_CONTROL			0x09
-#define PHY_BCM5400_GB_CONTROL_FULLDUPLEXCAP	0x0200
+#define MII_BCM5400_GB_CONTROL			0x09
+#define MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP	0x0200
 
 /* MII BCM5400 AUXCONTROL register */
-#define PHY_BCM5400_AUXCONTROL                  0x18
-#define PHY_BCM5400_AUXCONTROL_PWR10BASET       0x0004
+#define MII_BCM5400_AUXCONTROL                  0x18
+#define MII_BCM5400_AUXCONTROL_PWR10BASET       0x0004
 
 /* MII BCM5400 AUXSTATUS register */
-#define PHY_BCM5400_AUXSTATUS                   0x19
-#define PHY_BCM5400_AUXSTATUS_LINKMODE_MASK     0x0700
-#define PHY_BCM5400_AUXSTATUS_LINKMODE_SHIFT    8  
+#define MII_BCM5400_AUXSTATUS                   0x19
+#define MII_BCM5400_AUXSTATUS_LINKMODE_MASK     0x0700
+#define MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT    8  
 
 /* When it can, GEM internally caches 4 aligned TX descriptors
  * at a time, so that it can use full cacheline DMA reads.
@@ -936,9 +910,21 @@
 
 #define RX_COPY_THRESHOLD  256
 
+#if TX_RING_SIZE < 128
+#define INIT_BLOCK_TX_RING_SIZE		128
+#else
+#define INIT_BLOCK_TX_RING_SIZE		TX_RING_SIZE
+#endif
+
+#if RX_RING_SIZE < 128
+#define INIT_BLOCK_RX_RING_SIZE		128
+#else
+#define INIT_BLOCK_RX_RING_SIZE		RX_RING_SIZE
+#endif
+
 struct gem_init_block {
-	struct gem_txd	txd[TX_RING_SIZE];
-	struct gem_rxd	rxd[RX_RING_SIZE];
+	struct gem_txd	txd[INIT_BLOCK_TX_RING_SIZE];
+	struct gem_rxd	rxd[INIT_BLOCK_RX_RING_SIZE];
 };
 
 enum gem_phy_type {
@@ -958,9 +944,12 @@
 };
 
 enum link_state {
-	aneg_wait,
-	force_wait,
-	aneg_up,
+	link_down = 0,	/* No link, will retry */
+	link_aneg,	/* Autoneg in progress */
+	link_force_try,	/* Try Forced link speed */
+	link_force_ret,	/* Forced mode worked, retrying autoneg */
+	link_force_ok,	/* Stay in forced mode */
+	link_up		/* Link is up */
 };
 
 struct gem {
@@ -973,6 +962,10 @@
 	 * (ie. not power managed)
 	 */
 	int hw_running;
+	int opened;
+	struct semaphore pm_sem;
+	struct tq_struct pm_task;
+	struct timer_list pm_timer;
 
 	struct gem_init_block *init_block;
 
@@ -988,14 +981,22 @@
 	int			rx_pause_off;
 	int			rx_pause_on;
 	int			mii_phy_addr;
+	int			gigabit_capable;
 
+	/* Autoneg & PHY control */
+	int			link_cntl;
+	int			link_advertise;
+	int			link_fcntl;
+	enum link_state		lstate;
+	struct timer_list	link_timer;
+	int			timer_ticks;
+	int			wake_on_lan;
+	struct tq_struct	reset_task;
+	volatile int		reset_task_pending;
+	
 	/* Diagnostic counters and state. */
 	u64 pause_entered;
 	u16 pause_last_time_recvd;
-
-	struct timer_list link_timer;
-	int timer_ticks;
-	enum link_state lstate;
 
 	dma_addr_t gblock_dvma;
 	struct pci_dev *pdev;
diff -urN linux-2.4.17-pre4/drivers/parport/ChangeLog linux/drivers/parport/ChangeLog
--- linux-2.4.17-pre4/drivers/parport/ChangeLog	Mon Nov 12 09:45:32 2001
+++ linux/drivers/parport/ChangeLog	Thu Dec  6 10:53:03 2001
@@ -1,3 +1,9 @@
+2001-12-06  Tim Waugh  <twaugh@redhat.com>
+
+	* ieee1284_ops.c (parport_ieee1284_ecp_read_data): Mask off
+	PARPORT_CONTROL_AUTOFD as well.  Bug spotted by Joe
+	<joeja@mindspring.com>.
+
 2001-11-12  Tim Waugh  <twaugh@redhat.com>
 
 	* parport_pc.c (init_module): Warn when parameters are ignored.
diff -urN linux-2.4.17-pre4/drivers/parport/Config.in linux/drivers/parport/Config.in
--- linux-2.4.17-pre4/drivers/parport/Config.in	Sun Nov 11 10:09:33 2001
+++ linux/drivers/parport/Config.in	Thu Dec  6 10:53:03 2001
@@ -24,9 +24,13 @@
          bool '    Use FIFO/DMA if available (EXPERIMENTAL)' CONFIG_PARPORT_PC_FIFO
          bool '    SuperIO chipset support (EXPERIMENTAL)' CONFIG_PARPORT_PC_SUPERIO
       fi
-   fi
-   if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
-	 dep_tristate '    Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PCMCIA
+      if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
+         if [ "$CONFIG_PARPORT_PC" = "y" ]; then
+            dep_tristate '    Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PCMCIA
+         else
+            dep_tristate '    Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PARPORT_PC
+         fi
+      fi
    fi
    if [ "$CONFIG_ARM" = "y" ]; then
       dep_tristate '  Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT
diff -urN linux-2.4.17-pre4/drivers/parport/ieee1284_ops.c linux/drivers/parport/ieee1284_ops.c
--- linux-2.4.17-pre4/drivers/parport/ieee1284_ops.c	Thu Oct 25 00:07:39 2001
+++ linux/drivers/parport/ieee1284_ops.c	Thu Dec  6 10:53:03 2001
@@ -514,7 +514,8 @@
 
 	/* Set HostAck low to start accepting data. */
 	ctl = parport_read_control (port);
-	ctl &= ~(PARPORT_CONTROL_STROBE | PARPORT_CONTROL_INIT);
+	ctl &= ~(PARPORT_CONTROL_STROBE | PARPORT_CONTROL_INIT |
+		 PARPORT_CONTROL_AUTOFD);
 	parport_write_control (port,
 			       ctl | PARPORT_CONTROL_AUTOFD);
 	while (count < len) {
diff -urN linux-2.4.17-pre4/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c
--- linux-2.4.17-pre4/drivers/scsi/NCR5380.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/scsi/NCR5380.c	Thu Dec  6 10:53:04 2001
@@ -364,78 +364,36 @@
 	const char *name;
 } signals[] = { {
 
-		SR_DBP, "PARITY"
-}, {
-	SR_RST, "RST"
-}, {
-	SR_BSY, "BSY"
-},
-{
-	SR_REQ, "REQ"
-}, {
-	SR_MSG, "MSG"
-}, {
-	SR_CD, "CD"
-}, {
-	SR_IO, "IO"
-},
-{
-	SR_SEL, "SEL"
-}, {
-	0, NULL
-}
-},
-
-basrs[] = { {
-		BASR_ATN, "ATN"
-}, {
-	BASR_ACK, "ACK"
-}, {
-	0, NULL
-}
-},
-
-icrs[] = { {
-		ICR_ASSERT_RST, "ASSERT RST"
-}, {
-	ICR_ASSERT_ACK, "ASSERT ACK"
-},
-{
-	ICR_ASSERT_BSY, "ASSERT BSY"
-}, {
-	ICR_ASSERT_SEL, "ASSERT SEL"
-},
-{
-	ICR_ASSERT_ATN, "ASSERT ATN"
-}, {
-	ICR_ASSERT_DATA, "ASSERT DATA"
-},
-{
-	0, NULL
-}
-},
-
-mrs[] = { {
-		MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"
-}, {
-	MR_TARGET, "MODE TARGET"
-},
-{
-	MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"
-}, {
-	MR_ENABLE_PAR_INTR,
-	    "MODE PARITY INTR"
-}, {
-	MR_MONITOR_BSY, "MODE MONITOR BSY"
-},
-{
-	MR_DMA_MODE, "MODE DMA"
-}, {
-	MR_ARBITRATE, "MODE ARBITRATION"
-},
-{
-	0, NULL
-}
+SR_DBP, "PARITY"}, {
+SR_RST, "RST"}, {
+SR_BSY, "BSY"}, {
+SR_REQ, "REQ"}, {
+SR_MSG, "MSG"}, {
+SR_CD, "CD"}, {
+SR_IO, "IO"}, {
+SR_SEL, "SEL"}, {
+0, NULL}
+}, basrs[] = { {
+BASR_ATN, "ATN"}, {
+BASR_ACK, "ACK"}, {
+0, NULL}
+}, icrs[] = { {
+ICR_ASSERT_RST, "ASSERT RST"}, {
+ICR_ASSERT_ACK, "ASSERT ACK"}, {
+ICR_ASSERT_BSY, "ASSERT BSY"}, {
+ICR_ASSERT_SEL, "ASSERT SEL"}, {
+ICR_ASSERT_ATN, "ASSERT ATN"}, {
+ICR_ASSERT_DATA, "ASSERT DATA"}, {
+0, NULL}
+}, mrs[] = { {
+MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, {
+MR_TARGET, "MODE TARGET"}, {
+MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, {
+MR_ENABLE_PAR_INTR, "MODE PARITY INTR"}, {
+MR_MONITOR_BSY, "MODE MONITOR BSY"}, {
+MR_DMA_MODE, "MODE DMA"}, {
+MR_ARBITRATE, "MODE ARBITRATION"}, {
+0, NULL}
 };
 
 /*
@@ -485,22 +443,13 @@
 } phases[] = {
 
 	{
-		PHASE_DATAOUT, "DATAOUT"
-	}, {
-		PHASE_DATAIN, "DATAIN"
-	}, {
-		PHASE_CMDOUT, "CMDOUT"
-	},
-	{
-		PHASE_STATIN, "STATIN"
-	}, {
-		PHASE_MSGOUT, "MSGOUT"
-	}, {
-		PHASE_MSGIN, "MSGIN"
-	},
-	{
-		PHASE_UNKNOWN, "UNKNOWN"
-	}
+	PHASE_DATAOUT, "DATAOUT"}, {
+	PHASE_DATAIN, "DATAIN"}, {
+	PHASE_CMDOUT, "CMDOUT"}, {
+	PHASE_STATIN, "STATIN"}, {
+	PHASE_MSGOUT, "MSGOUT"}, {
+	PHASE_MSGIN, "MSGIN"}, {
+	PHASE_UNKNOWN, "UNKNOWN"}
 };
 
 /* 
@@ -520,11 +469,9 @@
 
 	status = NCR5380_read(STATUS_REG);
 	if (!(status & SR_REQ))
-		printk("scsi%d : REQ not asserted, phase unknown.\n",
-		       instance->host_no);
+		printk("scsi%d : REQ not asserted, phase unknown.\n", instance->host_no);
 	else {
-		for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
-		     (phases[i].value != (status & PHASE_MASK)); ++i);
+		for (i = 0; (phases[i].value != PHASE_UNKNOWN) && (phases[i].value != (status & PHASE_MASK)); ++i);
 		printk("scsi%d : phase %s\n", instance->host_no, phases[i].name);
 	}
 }
@@ -621,20 +568,20 @@
 static int should_disconnect(unsigned char cmd)
 {
 	switch (cmd) {
-		case READ_6:
-		    case WRITE_6:
-		    case SEEK_6:
-		    case READ_10:
-		    case WRITE_10:
-		    case SEEK_10:
-		    return DISCONNECT_TIME_TO_DATA;
-		case FORMAT_UNIT:
-		    case SEARCH_HIGH:
-		    case SEARCH_LOW:
-		    case SEARCH_EQUAL:
-		    return DISCONNECT_LONG;
-		default:
-		    return DISCONNECT_NONE;
+	case READ_6:
+	case WRITE_6:
+	case SEEK_6:
+	case READ_10:
+	case WRITE_10:
+	case SEEK_10:
+		return DISCONNECT_TIME_TO_DATA;
+	case FORMAT_UNIT:
+	case SEARCH_HIGH:
+	case SEARCH_LOW:
+	case SEARCH_EQUAL:
+		return DISCONNECT_LONG;
+	default:
+		return DISCONNECT_NONE;
 	}
 }
 
@@ -653,16 +600,13 @@
 		restore_flags(flags);
 		return -1;
 	}
-	for (prev = &expires_first, tmp = expires_first; tmp;
-		prev = &(((struct NCR5380_hostdata *) tmp->hostdata)->next_timer), 
-		tmp = ((struct NCR5380_hostdata *) tmp->hostdata)->next_timer)
-		if (((struct NCR5380_hostdata *)instance->hostdata)->time_expires < 
-			((struct NCR5380_hostdata *)tmp->hostdata)->time_expires) 
+	for (prev = &expires_first, tmp = expires_first; tmp; prev = &(((struct NCR5380_hostdata *) tmp->hostdata)->next_timer), tmp = ((struct NCR5380_hostdata *) tmp->hostdata)->next_timer)
+		if (((struct NCR5380_hostdata *) instance->hostdata)->time_expires < ((struct NCR5380_hostdata *) tmp->hostdata)->time_expires)
 			break;
 
 	((struct NCR5380_hostdata *) instance->hostdata)->next_timer = tmp;
 	*prev = instance;
-   
+
 	mod_timer(&usleep_timer, ((struct NCR5380_hostdata *) expires_first->hostdata)->time_expires);
 	restore_flags(flags);
 	return 0;
@@ -675,9 +619,7 @@
 	struct Scsi_Host *instance;
 	save_flags(flags);
 	cli();
-	for (; expires_first &&
-		time_before_eq(((struct NCR5380_hostdata *)expires_first->hostdata)->time_expires, jiffies); )
-	{
+	for (; expires_first && time_before_eq(((struct NCR5380_hostdata *) expires_first->hostdata)->time_expires, jiffies);) {
 		instance = ((struct NCR5380_hostdata *) expires_first->hostdata)->next_timer;
 		((struct NCR5380_hostdata *) expires_first->hostdata)->next_timer = NULL;
 		((struct NCR5380_hostdata *) expires_first->hostdata)->time_expires = 0;
@@ -685,9 +627,8 @@
 	}
 
 	del_timer(&usleep_timer);
-	if (expires_first) 
-	{
-		usleep_timer.expires = ((struct NCR5380_hostdata *)expires_first->hostdata)->time_expires;
+	if (expires_first) {
+		usleep_timer.expires = ((struct NCR5380_hostdata *) expires_first->hostdata)->time_expires;
 		add_timer(&usleep_timer);
 	}
 	restore_flags(flags);
@@ -738,8 +679,7 @@
 static int __init NCR5380_probe_irq(struct Scsi_Host *instance, int possible)
 {
 	NCR5380_local_declare();
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
-	instance->hostdata;
+	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	unsigned long timeout;
 	int trying_irqs, i, mask;
 	NCR5380_setup(instance);
@@ -765,10 +705,9 @@
 	NCR5380_write(TARGET_COMMAND_REG, 0);
 	NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
-		      ICR_ASSERT_SEL);
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
 
-	while (probe_irq == IRQ_NONE && time_before(jiffies,timeout))
+	while (probe_irq == IRQ_NONE && time_before(jiffies, timeout))
 		barrier();
 
 	NCR5380_write(SELECT_ENABLE_REG, 0);
@@ -846,16 +785,14 @@
 	char *start;
 	int len;
 
-	printk("NCR5380 : coroutine is%s running.\n",
-	       main_running ? "" : "n't");
+	printk("NCR5380 : coroutine is%s running.\n", main_running ? "" : "n't");
 
 #ifdef NDEBUG
 	NCR5380_print(instance);
 	NCR5380_print_phase(instance);
 #endif
 
-	len = NCR5380_proc_info(pr_bfr, &start, 0, sizeof(pr_bfr),
-				instance->host_no, 0);
+	len = NCR5380_proc_info(pr_bfr, &start, 0, sizeof(pr_bfr), instance->host_no, 0);
 	pr_bfr[len] = 0;
 	printk("\n%s\n", pr_bfr);
 }
@@ -886,9 +823,7 @@
 #ifndef NCR5380_proc_info
 static
 #endif
-int NCR5380_proc_info(
-			     char *buffer, char **start, off_t offset,
-			     int length, int hostno, int inout)
+int NCR5380_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
 {
 	unsigned long flags;
 	char *pos = buffer;
@@ -896,8 +831,7 @@
 	struct NCR5380_hostdata *hostdata;
 	Scsi_Cmnd *ptr;
 
-	for (instance = first_instance; instance &&
-	     instance->host_no != hostno; instance = instance->next);
+	for (instance = first_instance; instance && instance->host_no != hostno; instance = instance->next);
 	if (!instance)
 		return (-ESRCH);
 	hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -935,12 +869,10 @@
 		SPRINTF("IRQ: %d.\n", instance->irq);
 
 #ifdef DTC_PUBLIC_RELEASE
-	SPRINTF("Highwater I/O busy_spin_counts -- write: %d  read: %d\n",
-		dtc_wmaxi, dtc_maxi);
+	SPRINTF("Highwater I/O busy_spin_counts -- write: %d  read: %d\n", dtc_wmaxi, dtc_maxi);
 #endif
 #ifdef PAS16_PUBLIC_RELEASE
-	SPRINTF("Highwater I/O busy_spin_counts -- write: %d  read: %d\n",
-		pas_wmaxi, pas_maxi);
+	SPRINTF("Highwater I/O busy_spin_counts -- write: %d  read: %d\n", pas_wmaxi, pas_maxi);
 #endif
 	save_flags(flags);
 	cli();
@@ -948,16 +880,13 @@
 	if (!hostdata->connected)
 		SPRINTF("scsi%d: no currently connected command\n", instance->host_no);
 	else
-		pos = lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected,
-				       pos, buffer, length);
+		pos = lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, pos, buffer, length);
 	SPRINTF("scsi%d: issue_queue\n", instance->host_no);
-	for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr;
-	     ptr = (Scsi_Cmnd *) ptr->host_scribble)
+	for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
 		pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
 
 	SPRINTF("scsi%d: disconnected_queue\n", instance->host_no);
-	for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
-	     ptr = (Scsi_Cmnd *) ptr->host_scribble)
+	for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
 		pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
 
 	restore_flags(flags);
@@ -972,16 +901,14 @@
 static
 char *lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, char *pos, char *buffer, int length)
 {
-	SPRINTF("scsi%d : destination target %d, lun %d\n",
-		cmd->host->host_no, cmd->target, cmd->lun);
+	SPRINTF("scsi%d : destination target %d, lun %d\n", cmd->host->host_no, cmd->target, cmd->lun);
 	SPRINTF("        command = ");
 	pos = lprint_command(cmd->cmnd, pos, buffer, length);
 	return (pos);
 }
 
 static
-char *lprint_command(unsigned char *command,
-		     char *pos, char *buffer, int length)
+char *lprint_command(unsigned char *command, char *pos, char *buffer, int length)
 {
 	int i, s;
 	pos = lprint_opcode(command[0], pos, buffer, length);
@@ -1017,8 +944,7 @@
 	NCR5380_local_declare();
 	int i, pass;
 	unsigned long timeout;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
-	instance->hostdata;
+	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	/* 
 	 * On NCR53C400 boards, NCR5380 registers are mapped 8 past 
@@ -1078,9 +1004,7 @@
 #ifndef AUTOSENSE
 	if ((instance->cmd_per_lun > 1) || instance->can_queue > 1)
 		)
-		    printk("scsi%d : WARNING : support for multiple outstanding commands enabled\n"
-			   "         without AUTOSENSE option, contingent allegiance conditions may\n"
-		"         be incorrectly cleared.\n", instance->host_no);
+		    printk("scsi%d : WARNING : support for multiple outstanding commands enabled\n" "         without AUTOSENSE option, contingent allegiance conditions may\n" "         be incorrectly cleared.\n", instance->host_no);
 #endif				/* def AUTOSENSE */
 
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1106,30 +1030,25 @@
 	 * failing, do a hard reset of the SCSI bus 
 	 */
 
-	for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) &&
-	     pass <= 6; ++pass) {
+	for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
 		switch (pass) {
 		case 1:
 		case 3:
 		case 5:
-			printk("scsi%d: SCSI bus busy, waiting up to five seconds\n",
-			       instance->host_no);
+			printk("scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no);
 			timeout = jiffies + 5 * HZ;
-			while (time_before(jiffies,timeout) && (NCR5380_read(STATUS_REG) & SR_BSY));
+			while (time_before(jiffies, timeout) && (NCR5380_read(STATUS_REG) & SR_BSY));
 			break;
 		case 2:
-			printk("scsi%d: bus busy, attempting abort\n",
-			       instance->host_no);
+			printk("scsi%d: bus busy, attempting abort\n", instance->host_no);
 			do_abort(instance);
 			break;
 		case 4:
-			printk("scsi%d: bus busy, attempting reset\n",
-			       instance->host_no);
+			printk("scsi%d: bus busy, attempting reset\n", instance->host_no);
 			do_reset(instance);
 			break;
 		case 6:
-			printk("scsi%d: bus locked solid or invalid override\n",
-			       instance->host_no);
+			printk("scsi%d: bus locked solid or invalid override\n", instance->host_no);
 		}
 	}
 }
@@ -1158,16 +1077,14 @@
 #endif
 int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) {
 	struct Scsi_Host *instance = cmd->host;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
-	 instance->hostdata;
+	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	Scsi_Cmnd *tmp;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
 	switch (cmd->cmnd[0]) {
-		case WRITE_6:
-		    case WRITE_10:
-		    printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
-			   instance->host_no);
+	case WRITE_6:
+	case WRITE_10:
+		printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->host_no);
 		cmd->result = (DID_ERROR << 16);
 		done(cmd);
 		return 0;
@@ -1176,8 +1093,7 @@
 
 #ifdef NCR5380_STATS
 #if 0
-	if (!hostdata->connected && !hostdata->issue_queue &&
-	    !hostdata->disconnected_queue) {
+	if (!hostdata->connected && !hostdata->issue_queue && !hostdata->disconnected_queue) {
 		hostdata->timebase = jiffies;
 	}
 #endif
@@ -1185,17 +1101,17 @@
 	if (cmd->request_bufflen > NCR5380_STAT_LIMIT)
 #endif
 		switch (cmd->cmnd[0]) {
-			case WRITE:
-			    case WRITE_6:
-			    case WRITE_10:
-			    hostdata->time_write[cmd->target] -= (jiffies - hostdata->timebase);
+		case WRITE:
+		case WRITE_6:
+		case WRITE_10:
+			hostdata->time_write[cmd->target] -= (jiffies - hostdata->timebase);
 			hostdata->bytes_write[cmd->target] += cmd->request_bufflen;
 			hostdata->pendingw++;
 			break;
-			case READ:
-			    case READ_6:
-			    case READ_10:
-			    hostdata->time_read[cmd->target] -= (jiffies - hostdata->timebase);
+		case READ:
+		case READ_6:
+		case READ_10:
+			hostdata->time_read[cmd->target] -= (jiffies - hostdata->timebase);
 			hostdata->bytes_read[cmd->target] += cmd->request_bufflen;
 			hostdata->pendingr++;
 			break;
@@ -1225,14 +1141,12 @@
 		cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
 		hostdata->issue_queue = cmd;
 	} else {
-		for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->host_scribble;
-		     tmp = (Scsi_Cmnd *) tmp->host_scribble);
+		for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (Scsi_Cmnd *) tmp->host_scribble);
 		LIST(cmd, tmp);
 		tmp->host_scribble = (unsigned char *) cmd;
 	}
 #if (NDEBUG & NDEBUG_QUEUES)
-	printk("scsi%d : command added to %s of queue\n", instance->host_no,
-	       (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
+	printk("scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 #endif
 
 /* Run the coroutine if it isn't already running. */
@@ -1271,22 +1185,21 @@
 	 * this should prevent any race conditions.
 	 */
 
-	spin_unlock_irq(&io_request_lock);
-	
-	save_flags(flags);
-	
+	 spin_unlock_irq(&io_request_lock);
+
+	 save_flags(flags);
+
 	do {
 		cli();		/* Freeze request queues */
 		done = 1;
-		for (instance = first_instance; instance &&
-		     instance->hostt == the_template; instance = instance->next) {
-			 hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-			 cli();
+		for (instance = first_instance; instance && instance->hostt == the_template; instance = instance->next) {
+			hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+			cli();
 #ifdef USLEEP
 			if (!hostdata->connected && !hostdata->selecting) {
 #else
 			if (!hostdata->connected) {
-#endif			
+#endif
 #if (NDEBUG & NDEBUG_MAIN)
 				printk("scsi%d : not connected\n", instance->host_no);
 #endif
@@ -1300,9 +1213,7 @@
 				if ((tmp == prev) && tmp)
 					printk(" LOOP\n");	/* else printk("\n"); */
 #endif
-				for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
-				     prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
-				     tmp->host_scribble) {
+				for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble) {
 
 #if (NDEBUG & NDEBUG_LISTS)
 					if (prev != tmp)
@@ -1329,8 +1240,7 @@
 						 *   issue queue so we can keep trying. 
 						 */
 #if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
-						printk("scsi%d : main() : command for target %d lun %d removed from issue_queue\n",
-						       instance->host_no, tmp->target, tmp->lun);
+						printk("scsi%d : main() : command for target %d lun %d removed from issue_queue\n", instance->host_no, tmp->target, tmp->lun);
 #endif
 
 						/*
@@ -1344,19 +1254,18 @@
 						 * with failures we will restart.
 						 */
 #ifdef USLEEP
-						hostdata->selecting = 0; /* RvC: have to preset this
-							to indicate a new command is being performed */
+						hostdata->selecting = 0;	/* RvC: have to preset this
+										   to indicate a new command is being performed */
 #endif
 
 						if (!NCR5380_select(instance, tmp,
-						/* 
-						 * REQUEST SENSE commands are issued without tagged
-						 * queueing, even on SCSI-II devices because the 
-						 * contingent allegiance condition exists for the 
-						 * entire unit.
-						 */
-								    (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE :
-							     TAG_NEXT)) {
+								    /* 
+								     * REQUEST SENSE commands are issued without tagged
+								     * queueing, even on SCSI-II devices because the 
+								     * contingent allegiance condition exists for the 
+								     * entire unit.
+								     */
+								    (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE : TAG_NEXT)) {
 							break;
 						} else {
 							cli();
@@ -1367,30 +1276,23 @@
 							done = 0;
 							restore_flags(flags);
 #if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
-							printk("scsi%d : main(): select() failed, returned to issue_queue\n",
-							       instance->host_no);
+							printk("scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
 #endif
 						}
 					}	/* if target/lun is not busy */
 				}	/* for */
 			}	/* if (!hostdata->connected) */
 #ifdef USLEEP
-			if (hostdata->selecting) 
-			{
-				tmp = (Scsi_Cmnd *)hostdata->selecting;
-				if (!NCR5380_select(instance, tmp, 
-					(tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE : TAG_NEXT)) 
-				{
+			if (hostdata->selecting) {
+				tmp = (Scsi_Cmnd *) hostdata->selecting;
+				if (!NCR5380_select(instance, tmp, (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE : TAG_NEXT)) {
 					/* Ok ?? */
-				}
-				else
-				{
+				} else {
 					/* RvC: device failed, so we wait a long time
-					this is needed for Mustek scanners, that
-					do not respond to commands immediately
-					after a scan */
-					printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n",
-						instance->host_no, tmp->target);
+					   this is needed for Mustek scanners, that
+					   do not respond to commands immediately
+					   after a scan */
+					printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->target);
 					cli();
 					LIST(tmp, hostdata->issue_queue);
 					tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
@@ -1398,9 +1300,9 @@
 					restore_flags(flags);
 
 					hostdata->time_expires = jiffies + USLEEP_WAITLONG;
-					NCR5380_set_timer (instance);
+					NCR5380_set_timer(instance);
 				}
-			} /* if hostdata->selecting */
+			}	/* if hostdata->selecting */
 #endif
 			if (hostdata->connected
 #ifdef REAL_DMA
@@ -1412,8 +1314,7 @@
 			    ) {
 				restore_flags(flags);
 #if (NDEBUG & NDEBUG_MAIN)
-				printk("scsi%d : main() : performing information transfer\n",
-				       instance->host_no);
+				printk("scsi%d : main() : performing information transfer\n", instance->host_no);
 #endif
 				NCR5380_information_transfer(instance);
 #if (NDEBUG & NDEBUG_MAIN)
@@ -1425,7 +1326,7 @@
 		}		/* for instance */
 	} while (!done);
 	spin_lock_irq(&io_request_lock);
-  /* 	cli();*/
+	/*    cli(); */
 	main_running = 0;
 }
 
@@ -1458,8 +1359,7 @@
 #endif
 	do {
 		done = 1;
-		for (instance = first_instance; instance && (instance->hostt ==
-				the_template); instance = instance->next)
+		for (instance = first_instance; instance && (instance->hostt == the_template); instance = instance->next)
 			if (instance->irq == irq) {
 
 				/* Look for pending interrupts */
@@ -1470,8 +1370,7 @@
 #if (NDEBUG & NDEBUG_INTR)
 					NCR5380_print(instance);
 #endif
-					if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
-					    (SR_SEL | SR_IO)) {
+					if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
 						done = 0;
 						restore_flags(flags);
 #if (NDEBUG & NDEBUG_INTR)
@@ -1502,14 +1401,11 @@
 						 * the current setting of the MODE register.
 						 */
 
-						if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr &
-						BASR_END_DMA_TRANSFER) ||
-											  !(basr & BASR_PHASE_MATCH))) {
+						if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) {
 							int transfered;
 
 							if (!hostdata->connected)
-								panic("scsi%d : received end of DMA interrupt with no connected cmd\n",
-								      instance->hostno);
+								panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno);
 
 							transfered = (hostdata->dmalen - NCR5380_dma_residual(instance));
 							hostdata->connected->SCp.this_residual -= transferred;
@@ -1522,13 +1418,11 @@
 								unsigned long timeout = jiffies + NCR_TIMEOUT;
 
 								spin_unlock_irq(&io_request_lock);
-								while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK
-								       && time_before(jiffies, timeout));
+								while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK && time_before(jiffies, timeout));
 								spin_lock_irq(&io_request_lock);
-								
-								if (time_after_eq(jiffies, timeout) )
-									printk("scsi%d: timeout at NCR5380.c:%d\n",
-									       host->host_no, __LINE__);
+
+								if (time_after_eq(jiffies, timeout))
+									printk("scsi%d: timeout at NCR5380.c:%d\n", host->host_no, __LINE__);
 							}
 #else				/* NCR_TIMEOUT */
 							while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK);
@@ -1559,26 +1453,21 @@
 	 NCR5380_intr(irq, dev_id, regs);
 	 spin_unlock_irqrestore(&io_request_lock, flags);
 }
-
 #endif
-
 #ifdef NCR5380_STATS
 static void collect_stats(struct NCR5380_hostdata *hostdata, Scsi_Cmnd * cmd) {
 #ifdef NCR5380_STAT_LIMIT
 	if (cmd->request_bufflen > NCR5380_STAT_LIMIT)
 #endif
 		switch (cmd->cmnd[0]) {
-			case WRITE:
-			    case WRITE_6:
-			    case WRITE_10:
-			    hostdata->time_write[cmd->target] += (jiffies - hostdata->timebase);
+		case WRITE:
+		case WRITE_6:
+		case WRITE_10:
+			hostdata->time_write[cmd->target] += (jiffies - hostdata->timebase);
 			/*hostdata->bytes_write[cmd->target] += cmd->request_bufflen; */
 			hostdata->pendingw--;
 			break;
-			case READ:
-			case READ_6:
-			case READ_10:
-			hostdata->time_read[cmd->target] += (jiffies - hostdata->timebase);
+			case READ:case READ_6:case READ_10:hostdata->time_read[cmd->target] += (jiffies - hostdata->timebase);
 			/*hostdata->bytes_read[cmd->target] += cmd->request_bufflen; */
 			hostdata->pendingr--;
 			break;
@@ -1614,8 +1503,7 @@
  *
  *      If failed (no target) : cmd->scsi_done() will be called, and the 
  *              cmd->result host byte set to DID_BAD_TARGET.
- */
-static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag) {
+ */ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag) {
 	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	unsigned char tmp[3], phase;
@@ -1627,42 +1515,39 @@
 	unsigned char value;
 #endif
 
-	NCR5380_setup(instance);
+	 NCR5380_setup(instance);
 
 #ifdef USLEEP
 
-	if (hostdata->selecting) 
-	{
+	if (hostdata->selecting) {
 		goto part2;	/* RvC: sorry prof. Dijkstra, but it keeps the
 				   rest of the code nearly the same */
 	}
 #endif
-
-	 hostdata->restart_select = 0;
+	hostdata->restart_select = 0;
 #if defined (NDEBUG) && (NDEBUG & NDEBUG_ARBITRATION)
-	 NCR5380_print(instance);
-	 printk("scsi%d : starting arbitration, id = %d\n", instance->host_no,
-		instance->this_id);
+	NCR5380_print(instance);
+	printk("scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
 #endif
-	 save_flags(flags);
-	 cli();
+	save_flags(flags);
+	cli();
 
 	/* 
 	 * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
 	 * data bus during SELECTION.
 	 */
 
-	 NCR5380_write(TARGET_COMMAND_REG, 0);
+	NCR5380_write(TARGET_COMMAND_REG, 0);
 
 
 	/* 
 	 * Start arbitration.
 	 */
 
-	 NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
-	 NCR5380_write(MODE_REG, MR_ARBITRATE);
+	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
+	NCR5380_write(MODE_REG, MR_ARBITRATE);
 
-	 restore_flags(flags);
+	restore_flags(flags);
 
 	/* Wait for arbitration logic to complete */
 #if NCR_TIMEOUT
@@ -1672,11 +1557,11 @@
 		spin_unlock_irq(&io_request_lock);
 
 		while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
-		       && time_before(jiffies,timeout));
+		       && time_before(jiffies, timeout));
 
 		spin_lock_irq(&io_request_lock);
-		       
-		if (time_after_eq(jiffies,timeout)) {
+
+		if (time_after_eq(jiffies, timeout)) {
 			printk("scsi: arbitration timeout at %d\n", __LINE__);
 			NCR5380_write(MODE_REG, MR_BASE);
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
@@ -1688,9 +1573,9 @@
 #endif
 
 #if (NDEBUG & NDEBUG_ARBITRATION)
-	 printk("scsi%d : arbitration complete\n", instance->host_no);
+	printk("scsi%d : arbitration complete\n", instance->host_no);
 /* Avoid GCC 2.4.5 asm needs to many reloads error */
-	 __asm__("nop");
+	__asm__("nop");
 #endif
 
 	/* 
@@ -1700,33 +1585,28 @@
 	 *
 	 */
 
-	 udelay(3);
+	udelay(3);
 
 	/* Check for lost arbitration */
-	if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-	     (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
-	  (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
+	if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 #if (NDEBUG & NDEBUG_ARBITRATION)
-		printk("scsi%d : lost arbitration, deasserting MR_ARBITRATE\n",
-		       instance->host_no);
+		printk("scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
 #endif
 		return -1;
 	}
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
 
 	if (!(hostdata->flags & FLAG_DTC3181E) &&
-		/* RvC: DTC3181E has some trouble with this
-		 *	so we simply removed it. Seems to work with
-		 *	only Mustek scanner attached
-		 */
-		(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) 
-	{
+	    /* RvC: DTC3181E has some trouble with this
+	     *      so we simply removed it. Seems to work with
+	     *      only Mustek scanner attached
+	     */
+	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 #if (NDEBUG & NDEBUG_ARBITRATION)
-		printk("scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n",
-		       instance->host_no);
+		printk("scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no);
 #endif
 		return -1;
 	}
@@ -1755,8 +1635,7 @@
 	 * phase immediately after selection.
 	 */
 
-	NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY |
-		     ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+	NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL));
 	NCR5380_write(MODE_REG, MR_BASE);
 
 	/* 
@@ -1772,8 +1651,7 @@
 	udelay(1);		/* wingel -- wait two bus deskew delay >2*45ns */
 
 	/* Reset BSY */
-	NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA |
-				       ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+	NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL));
 
 	/* 
 	 * Something weird happens when we cease to drive BSY - looks
@@ -1812,39 +1690,35 @@
 	 */
 
 #ifdef USLEEP
-	hostdata->select_time = 0; /* we count the clock ticks at which we polled */
+	hostdata->select_time = 0;	/* we count the clock ticks at which we polled */
 	hostdata->selecting = cmd;
 
-part2:
-    	/* RvC: here we enter after a sleeping period, or immediately after
-		execution of part 1
-		we poll only once ech clock tick */
+      part2:
+	/* RvC: here we enter after a sleeping period, or immediately after
+	   execution of part 1
+	   we poll only once ech clock tick */
 	value = NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO);
 
-	if (!value && (hostdata->select_time < 25)) 
-	{
+	if (!value && (hostdata->select_time < 25)) {
 		/* RvC: we still must wait for a device response */
-		hostdata->select_time++; /* after 25 ticks the device has failed */
+		hostdata->select_time++;	/* after 25 ticks the device has failed */
 		hostdata->time_expires = jiffies + 1;
 		NCR5380_set_timer(instance);
 		return 0;	/* RvC: we return here with hostdata->selecting set,
 				   to go to sleep */
 	}
 
-	hostdata->selecting = 0; /* clear this pointer, because we passed the
-				waiting period */
+	hostdata->selecting = 0;	/* clear this pointer, because we passed the
+					   waiting period */
 #else
 	spin_unlock_irq(&io_request_lock);
-	while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) &
-					(SR_BSY | SR_IO)));
+	while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO)));
 	spin_lock_irq(&io_request_lock);
 #endif
-	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
-	    (SR_SEL | SR_IO)) {
+	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_reselect(instance);
-		printk("scsi%d : reselection after won arbitration?\n",
-		       instance->host_no);
+		printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
@@ -1877,8 +1751,7 @@
 		cmd->scsi_done(cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 #if (NDEBUG & NDEBUG_SELECTION)
-		printk("scsi%d : target did not respond within 250ms\n",
-		       instance->host_no);
+		printk("scsi%d : target did not respond within 250ms\n", instance->host_no);
 #endif
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return 0;
@@ -1908,7 +1781,7 @@
 		spin_unlock_irq(&io_request_lock);
 		while (!(NCR5380_read(STATUS_REG) & SR_REQ) && time_before(jiffies, timeout));
 		spin_lock_irq(&io_request_lock);
-		
+
 		if (time_after_eq(jiffies, timeout)) {
 			printk("scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
@@ -1920,8 +1793,7 @@
 #endif				/* def NCR_TIMEOUT */
 
 #if (NDEBUG & NDEBUG_SELECTION)
-	printk("scsi%d : target %d selected, going into MESSAGE OUT phase.\n",
-	       instance->host_no, cmd->target);
+	printk("scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->target);
 #endif
 	tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun);
 #ifdef SCSI2
@@ -1992,20 +1864,19 @@
  * counts, we will always do a pseudo DMA or DMA transfer.
  */
 
-static int NCR5380_transfer_pio(struct Scsi_Host *instance,
-		unsigned char *phase, int *count, unsigned char **data) {
+static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
 	NCR5380_local_declare();
 	register unsigned char p = *phase, tmp;
 	register int c = *count;
 	register unsigned char *d = *data;
 #ifdef USLEEP
 	/*
-	 *	RvC: some administrative data to process polling time
+	 *      RvC: some administrative data to process polling time
 	 */
 	int break_allowed = 0;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 #endif
-	NCR5380_setup(instance);
+	 NCR5380_setup(instance);
 
 #if (NDEBUG & NDEBUG_PIO)
 	if (!(p & SR_IO))
@@ -2024,15 +1895,12 @@
 
 #ifdef USLEEP
 	/* RvC: don't know if this is necessary, but other SCSI I/O is short
-	 *	so breaks are not necessary there
+	 *      so breaks are not necessary there
 	 */
-	if ((p == PHASE_DATAIN) || (p == PHASE_DATAOUT)) 
-	{
+	if ((p == PHASE_DATAIN) || (p == PHASE_DATAOUT)) {
 		break_allowed = 1;
 	}
 #endif
-
-
 	do {
 		/* 
 		 * Wait for assertion of REQ, after which the phase bits will be 
@@ -2041,21 +1909,19 @@
 
 #ifdef USLEEP
 		/* RvC: we simply poll once, after that we stop temporarily
-		 *	and let the device buffer fill up
-		 *	if breaking is not allowed, we keep polling as long as needed
+		 *      and let the device buffer fill up
+		 *      if breaking is not allowed, we keep polling as long as needed
 		 */
 
-		while ( !((tmp = NCR5380_read(STATUS_REG)) & SR_REQ) &&
-			!break_allowed );
-		if (!(tmp & SR_REQ)) 
-		{
+		while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ) && !break_allowed);
+		if (!(tmp & SR_REQ)) {
 			/* timeout condition */
 			hostdata->time_expires = jiffies + USLEEP_SLEEP;
-			NCR5380_set_timer (instance);
+			NCR5380_set_timer(instance);
 			break;
 		}
 #else
-		while ( !((tmp = NCR5380_read(STATUS_REG)) & SR_REQ) ); 
+		while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ));
 #endif
 
 #if (NDEBUG & NDEBUG_HANDSHAKE)
@@ -2070,8 +1936,9 @@
 #endif
 			break;
 		}
-		/* Do actual transfer from SCSI bus to / from memory */ if (!(p & SR_IO))
-			 NCR5380_write(OUTPUT_DATA_REG, *d);
+		/* Do actual transfer from SCSI bus to / from memory */
+		if (!(p & SR_IO))
+			NCR5380_write(OUTPUT_DATA_REG, *d);
 		else
 			*d = NCR5380_read(CURRENT_SCSI_DATA_REG);
 
@@ -2086,21 +1953,17 @@
 
 		if (!(p & SR_IO)) {
 			if (!((p & SR_MSG) && c > 1)) {
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-					      ICR_ASSERT_DATA);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
 #if (NDEBUG & NDEBUG_PIO)
 				NCR5380_print(instance);
 #endif
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				       ICR_ASSERT_DATA | ICR_ASSERT_ACK);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ACK);
 			} else {
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				       ICR_ASSERT_DATA | ICR_ASSERT_ATN);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN);
 #if (NDEBUG & NDEBUG_PIO)
 				NCR5380_print(instance);
 #endif
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-					      ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
 			}
 		} else {
 #if (NDEBUG & NDEBUG_PIO)
@@ -2159,8 +2022,7 @@
 
 	 save_flags(flags);
 	 cli();
-	 NCR5380_write(TARGET_COMMAND_REG,
-		 PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
+	 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
 	 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
 	 udelay(25);
 	 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -2198,8 +2060,7 @@
 	 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
 	if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-			      ICR_ASSERT_ACK);
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
 		while (NCR5380_read(STATUS_REG) & SR_REQ);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 	}
@@ -2238,8 +2099,7 @@
  */
 
 
-static int NCR5380_transfer_dma(struct Scsi_Host *instance,
-		unsigned char *phase, int *count, unsigned char **data) {
+static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
 	NCR5380_local_declare();
 	register int c = *count;
 	register unsigned char p = *phase;
@@ -2264,25 +2124,23 @@
 		return -1;
 	}
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-#ifdef READ_OVERRUNS 
-	if (p & SR_IO) { c -= 2; }
+#ifdef READ_OVERRUNS
+	if (p & SR_IO) {
+		c -= 2;
+	}
 #endif
 #if (NDEBUG & NDEBUG_DMA)
-printk("scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n",
-       instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" :
-       "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
+	printk("scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
 #endif
-hostdata->dma_len = (p & SR_IO) ?
-NCR5380_dma_read_setup(instance, d, c) :
-NCR5380_dma_write_setup(instance, d, c);
+	hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c);
 #endif
 
-NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
+	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
 #ifdef REAL_DMA
-NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
+	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
 #elif defined(REAL_DMA_POLL)
-NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
+	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
 #else
 	/*
 	 * Note : on my sample board, watch-dog timeouts occurred when interrupts
@@ -2291,20 +2149,18 @@
 	 */
 
 #if defined(PSEUDO_DMA) && !defined(UNSAFE)
-save_flags(flags);
-cli();
+	save_flags(flags);
+	cli();
 #endif
 	/* KLL May need eop and parity in 53c400 */
-if (hostdata->flags & FLAG_NCR53C400)
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_PAR_CHECK
-		  | MR_ENABLE_PAR_INTR | MR_ENABLE_EOP_INTR | MR_DMA_MODE
-		      | MR_MONITOR_BSY);
-else
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
+	if (hostdata->flags & FLAG_NCR53C400)
+		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_PAR_CHECK | MR_ENABLE_PAR_INTR | MR_ENABLE_EOP_INTR | MR_DMA_MODE | MR_MONITOR_BSY);
+	else
+		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
 #endif				/* def REAL_DMA */
 
 #if (NDEBUG & NDEBUG_DMA) & 0
-printk("scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
+	printk("scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
 #endif
 
 /* 
@@ -2316,32 +2172,29 @@
  * is the problem?
  */
 
-if (p & SR_IO)
-{
+	if (p & SR_IO) {
 #ifndef FOO
-udelay(1);
+		udelay(1);
 #endif
-NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
-} else {
+		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
+	} else {
 #ifndef FOO
-	udelay(1);
+		udelay(1);
 #endif
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
 #ifndef FOO
-	udelay(1);
+		udelay(1);
 #endif
-	NCR5380_write(START_DMA_SEND_REG, 0);
+		NCR5380_write(START_DMA_SEND_REG, 0);
 #ifndef FOO
-	udelay(1);
+		udelay(1);
 #endif
-}
+	}
 
 #if defined(REAL_DMA_POLL)
-do {
-	tmp = NCR5380_read(BUS_AND_STATUS_REG);
-} while ((tmp & BASR_PHASE_MATCH) && !(tmp & (BASR_BUSY_ERROR |
-
-					      BASR_END_DMA_TRANSFER)));
+	do {
+		tmp = NCR5380_read(BUS_AND_STATUS_REG);
+	} while ((tmp & BASR_PHASE_MATCH) && !(tmp & (BASR_BUSY_ERROR | BASR_END_DMA_TRANSFER)));
 
 /*
    At this point, either we've completed DMA, or we have a phase mismatch,
@@ -2379,172 +2232,149 @@
    request.
  */
 
-if (p & SR_IO) {
+	if (p & SR_IO) {
 #ifdef READ_OVERRUNS
-	udelay(10);
-	if (((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) ==
-	     (BASR_PHASE_MATCH | BASR_ACK))) {
-		saved_data = NCR5380_read(INPUT_DATA_REGISTER);
-		overrun = 1;
-	}
+		udelay(10);
+		if (((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) == (BASR_PHASE_MATCH | BASR_ACK))) {
+			saved_data = NCR5380_read(INPUT_DATA_REGISTER);
+			overrun = 1;
+		}
 #endif
-} else {
-	int limit = 100;
-	while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) ||
-	       (NCR5380_read(STATUS_REG) & SR_REQ)) {
-		if (!(tmp & BASR_PHASE_MATCH))
-			break;
-		if (--limit < 0)
-			break;
+	} else {
+		int limit = 100;
+		while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) || (NCR5380_read(STATUS_REG) & SR_REQ)) {
+			if (!(tmp & BASR_PHASE_MATCH))
+				break;
+			if (--limit < 0)
+				break;
+		}
 	}
-}
 
 
 #if (NDEBUG & NDEBUG_DMA)
-printk("scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n",
-       instance->host_no, tmp, NCR5380_read(STATUS_REG));
+	printk("scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n", instance->host_no, tmp, NCR5380_read(STATUS_REG));
 #endif
 
-NCR5380_write(MODE_REG, MR_BASE);
-NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	NCR5380_write(MODE_REG, MR_BASE);
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
-residue = NCR5380_dma_residual(instance);
-c -= residue;
-*count -= c;
-*data += c;
-*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
+	residue = NCR5380_dma_residual(instance);
+	c -= residue;
+	*count -= c;
+	*data += c;
+	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 
 #ifdef READ_OVERRUNS
-if (*phase == p && (p & SR_IO) && residue == 0)
-{
-if (overrun) {
+	if (*phase == p && (p & SR_IO) && residue == 0) {
+		if (overrun) {
 #if (NDEBUG & NDEBUG_DMA)
-	printk("Got an input overrun, using saved byte\n");
+			printk("Got an input overrun, using saved byte\n");
 #endif
-	**data = saved_data;
-	*data += 1;
-	*count -= 1;
-	cnt = toPIO = 1;
-} else {
-	printk("No overrun??\n");
-	cnt = toPIO = 2;
-}
+			**data = saved_data;
+			*data += 1;
+			*count -= 1;
+			cnt = toPIO = 1;
+		} else {
+			printk("No overrun??\n");
+			cnt = toPIO = 2;
+		}
 #if (NDEBUG & NDEBUG_DMA)
-printk("Doing %d-byte PIO to 0x%X\n", cnt, *data);
+		printk("Doing %d-byte PIO to 0x%X\n", cnt, *data);
 #endif
-NCR5380_transfer_pio(instance, phase, &cnt, data);
-*count -= toPIO - cnt;
-}
+		NCR5380_transfer_pio(instance, phase, &cnt, data);
+		*count -= toPIO - cnt;
+	}
 #endif
 
 #if (NDEBUG & NDEBUG_DMA)
-printk("Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n",
-       *data, *count, *(*data + *count - 1), *(*data + *count));
+	printk("Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count));
 #endif
-return 0;
+	return 0;
 
 #elif defined(REAL_DMA)
-return 0;
+	return 0;
 #else				/* defined(REAL_DMA_POLL) */
-if (p & SR_IO) {
+	if (p & SR_IO) {
 #ifdef DMA_WORKS_RIGHT
-	foo = NCR5380_pread(instance, d, c);
+		foo = NCR5380_pread(instance, d, c);
 #else
-	int diff = 1;
-	if (hostdata->flags & FLAG_NCR53C400) {
-		diff = 0;
-	}
-	if (!(foo = NCR5380_pread(instance, d, c - diff))) {
-		/*
-		 * We can't disable DMA mode after successfully transferring 
-		 * what we plan to be the last byte, since that would open up
-		 * a race condition where if the target asserted REQ before 
-		 * we got the DMA mode reset, the NCR5380 would have latched
-		 * an additional byte into the INPUT DATA register and we'd
-		 * have dropped it.
-		 * 
-		 * The workaround was to transfer one fewer bytes than we 
-		 * intended to with the pseudo-DMA read function, wait for 
-		 * the chip to latch the last byte, read it, and then disable
-		 * pseudo-DMA mode.
-		 * 
-		 * After REQ is asserted, the NCR5380 asserts DRQ and ACK.
-		 * REQ is deasserted when ACK is asserted, and not reasserted
-		 * until ACK goes false.  Since the NCR5380 won't lower ACK
-		 * until DACK is asserted, which won't happen unless we twiddle
-		 * the DMA port or we take the NCR5380 out of DMA mode, we 
-		 * can guarantee that we won't handshake another extra 
-		 * byte.
-		 */
+		int diff = 1;
+		if (hostdata->flags & FLAG_NCR53C400) {
+			diff = 0;
+		}
+		if (!(foo = NCR5380_pread(instance, d, c - diff))) {
+			/*
+			 * We can't disable DMA mode after successfully transferring 
+			 * what we plan to be the last byte, since that would open up
+			 * a race condition where if the target asserted REQ before 
+			 * we got the DMA mode reset, the NCR5380 would have latched
+			 * an additional byte into the INPUT DATA register and we'd
+			 * have dropped it.
+			 * 
+			 * The workaround was to transfer one fewer bytes than we 
+			 * intended to with the pseudo-DMA read function, wait for 
+			 * the chip to latch the last byte, read it, and then disable
+			 * pseudo-DMA mode.
+			 * 
+			 * After REQ is asserted, the NCR5380 asserts DRQ and ACK.
+			 * REQ is deasserted when ACK is asserted, and not reasserted
+			 * until ACK goes false.  Since the NCR5380 won't lower ACK
+			 * until DACK is asserted, which won't happen unless we twiddle
+			 * the DMA port or we take the NCR5380 out of DMA mode, we 
+			 * can guarantee that we won't handshake another extra 
+			 * byte.
+			 */
 
-		if (!(hostdata->flags & FLAG_NCR53C400)) {
-			while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ));
-			/* Wait for clean handshake */
-			while (NCR5380_read(STATUS_REG) & SR_REQ);
-			d[c - 1] = NCR5380_read(INPUT_DATA_REG);
+			if (!(hostdata->flags & FLAG_NCR53C400)) {
+				while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ));
+				/* Wait for clean handshake */
+				while (NCR5380_read(STATUS_REG) & SR_REQ);
+				d[c - 1] = NCR5380_read(INPUT_DATA_REG);
+			}
 		}
-	}
 #endif
-} else {
+	} else {
 #ifdef DMA_WORKS_RIGHT
-	foo = NCR5380_pwrite(instance, d, c);
+		foo = NCR5380_pwrite(instance, d, c);
 #else
-	int timeout;
+		int timeout;
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("About to pwrite %d bytes\n", c);
-#endif
-	if (!(foo = NCR5380_pwrite(instance, d, c))) {
-		/*
-		 * Wait for the last byte to be sent.  If REQ is being asserted for 
-		 * the byte we're interested, we'll ACK it and it will go false.  
-		 */
-		if (!(hostdata->flags & FLAG_HAS_LAST_BYTE_SENT)) {
-			timeout = 20000;
-#if 1
-#if 1
-			while (!(NCR5380_read(BUS_AND_STATUS_REG) &
-			 BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) &
-				       BASR_PHASE_MATCH));
-#else
-			if (NCR5380_read(STATUS_REG) & SR_REQ) {
-				for (; timeout &&
-				     !(NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK);
-				     --timeout);
-				for (; timeout && (NCR5380_read(STATUS_REG) & SR_REQ);
-				     --timeout);
-			}
+		printk("About to pwrite %d bytes\n", c);
 #endif
+		if (!(foo = NCR5380_pwrite(instance, d, c))) {
+			/*
+			 * Wait for the last byte to be sent.  If REQ is being asserted for 
+			 * the byte we're interested, we'll ACK it and it will go false.  
+			 */
+			if (!(hostdata->flags & FLAG_HAS_LAST_BYTE_SENT)) {
+				timeout = 20000;
+				while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH));
 
 
 #if (NDEBUG & NDEBUG_LAST_BYTE_SENT)
-			if (!timeout)
-				printk("scsi%d : timed out on last byte\n",
-				       instance->host_no);
+				if (!timeout)
+					printk("scsi%d : timed out on last byte\n", instance->host_no);
 #endif
 
 
-			if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) {
-				hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
-				if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) {
-					hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT;
+				if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) {
+					hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
+					if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) {
+						hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT;
 #if (NDEBUG & NDEBUG_LAST_BYTE_SENT)
-					printk("scsi%d : last bit sent works\n",
-					       instance->host_no);
+						printk("scsi%d : last bit sent works\n", instance->host_no);
 #endif
+					}
 				}
-			}
-		} else {
+			} else {
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-			printk("Waiting for LASTBYTE\n");
+				printk("Waiting for LASTBYTE\n");
 #endif
-			while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
+				while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-			printk("Got LASTBYTE\n");
-#endif
-		}
-#else
-			udelay(5);
+				printk("Got LASTBYTE\n");
 #endif
+			}
 		}
 #endif
 	}
@@ -2613,7 +2443,7 @@
 	unsigned long poll_time = jiffies + USLEEP_POLL;
 #endif
 
-	NCR5380_setup(instance);
+	 NCR5380_setup(instance);
 
 	while (1) {
 		tmp = NCR5380_read(STATUS_REG);
@@ -2629,20 +2459,17 @@
 			if (sink && (phase != PHASE_MSGOUT)) {
 				NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-					      ICR_ASSERT_ACK);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
 				while (NCR5380_read(STATUS_REG) & SR_REQ);
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-					      ICR_ASSERT_ATN);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 				sink = 0;
 				continue;
 			}
 			switch (phase) {
-				case PHASE_DATAIN:
-				    case PHASE_DATAOUT:
+			case PHASE_DATAIN:
+			case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
-				    printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n",
-					   instance->host_no);
+				printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n", instance->host_no);
 				sink = 1;
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
@@ -2660,9 +2487,7 @@
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
 					cmd->SCp.ptr = cmd->SCp.buffer->address;
 #if (NDEBUG & NDEBUG_INFORMATION)
-					printk("scsi%d : %d bytes and %d buffers left\n",
-					       instance->host_no, cmd->SCp.this_residual,
-					       cmd->SCp.buffers_residual);
+					printk("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual);
 #endif
 				}
 				/*
@@ -2684,9 +2509,7 @@
 				 * We supplement these 2 if's with the flag.
 				 */
 #ifdef NCR5380_dma_xfer_len
-				if (!cmd->device->borken &&
-				!(hostdata->flags & FLAG_NO_PSEUDO_DMA) &&
-				    (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {
+				if (!cmd->device->borken && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {
 #else
 				transfersize = cmd->transfersize;
 
@@ -2695,27 +2518,21 @@
 					transfersize = 512;
 #endif				/* LIMIT_TRANSFERSIZE */
 
-				if (!cmd->device->borken && transfersize &&
-				!(hostdata->flags & FLAG_NO_PSEUDO_DMA) &&
-				    cmd->SCp.this_residual && !(cmd->SCp.this_residual %
-							 transfersize)) {
+				if (!cmd->device->borken && transfersize && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && cmd->SCp.this_residual && !(cmd->SCp.this_residual % transfersize)) {
 					/* Limit transfers to 32K, for xx400 & xx406
 					 * pseudoDMA that transfers in 128 bytes blocks. */
 					if (transfersize > 32 * 1024)
 						transfersize = 32 * 1024;
 #endif
 					len = transfersize;
-					if (NCR5380_transfer_dma(instance, &phase,
-								 &len, (unsigned char **) &cmd->SCp.ptr)) {
+					if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) {
 						/*
 						 * If the watchdog timer fires, all future accesses to this
 						 * device will use the polled-IO.
 						 */
-						printk("scsi%d : switching target %d lun %d to slow handshake\n",
-						       instance->host_no, cmd->target, cmd->lun);
+						printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->target, cmd->lun);
 						cmd->device->borken = 1;
-						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-							 ICR_ASSERT_ATN);
+						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
@@ -2725,12 +2542,11 @@
 						cmd->SCp.this_residual -= transfersize - len;
 				} else
 #endif				/* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
-					NCR5380_transfer_pio(instance, &phase,
-							     (int *) &cmd->SCp.this_residual, (unsigned char **)
-							  &cmd->SCp.ptr);
+					NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **)
+							     &cmd->SCp.ptr);
 				break;
-				case PHASE_MSGIN:
-				    len = 1;
+			case PHASE_MSGIN:
+				len = 1;
 				data = &tmp;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				cmd->SCp.Message = tmp;
@@ -2747,14 +2563,13 @@
 					 * next_link, done() is called as with unlinked commands.
 					 */
 #ifdef LINKED
-					case LINKED_CMD_COMPLETE:
-					    case LINKED_FLG_CMD_COMPLETE:
+				case LINKED_CMD_COMPLETE:
+				case LINKED_FLG_CMD_COMPLETE:
 					/* Accept message by clearing ACK */
-					    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
 #if (NDEBUG & NDEBUG_LINKED)
-					printk("scsi%d : target %d lun %d linked command complete.\n",
-					       instance->host_no, cmd->target, cmd->lun);
+					printk("scsi%d : target %d lun %d linked command complete.\n", instance->host_no, cmd->target, cmd->lun);
 #endif
 					/* 
 					 * Sanity check : A linked command should only terminate with
@@ -2763,8 +2578,7 @@
 					 */
 
 					if (!cmd->next_link) {
-						printk("scsi%d : target %d lun %d linked command complete, no next_link\n"
-						       instance->host_no, cmd->target, cmd->lun);
+						printk("scsi%d : target %d lun %d linked command complete, no next_link\n" instance->host_no, cmd->target, cmd->lun);
 						sink = 1;
 						do_abort(instance);
 						return;
@@ -2774,8 +2588,7 @@
 					cmd->next_link->tag = cmd->tag;
 					cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
 #if (NDEBUG & NDEBUG_LINKED)
-					printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n",
-					       instance->host_no, cmd->target, cmd->lun);
+					printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->target, cmd->lun);
 #endif
 #ifdef NCR5380_STATS
 					collect_stats(hostdata, cmd);
@@ -2784,15 +2597,14 @@
 					cmd = hostdata->connected;
 					break;
 #endif				/* def LINKED */
-					case ABORT:
-					    case COMMAND_COMPLETE:
+				case ABORT:
+				case COMMAND_COMPLETE:
 					/* Accept message by clearing ACK */
-					    sink = 1;
+					sink = 1;
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					hostdata->connected = NULL;
 #if (NDEBUG & NDEBUG_QUEUES)
-					printk("scsi%d : command for target %d, lun %d completed\n",
-					       instance->host_no, cmd->target, cmd->lun);
+					printk("scsi%d : command for target %d, lun %d completed\n", instance->host_no, cmd->target, cmd->lun);
 #endif
 					hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
 
@@ -2818,12 +2630,10 @@
 						cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
 
 #ifdef AUTOSENSE
-					if ((cmd->cmnd[0] != REQUEST_SENSE) &&
-					    (cmd->SCp.Status == CHECK_CONDITION)) {
+					if ((cmd->cmnd[0] != REQUEST_SENSE) && (cmd->SCp.Status == CHECK_CONDITION)) {
 						unsigned long flags;
 #if (NDEBUG & NDEBUG_AUTOSENSE)
-						printk("scsi%d : performing request sense\n",
-						       instance->host_no);
+						printk("scsi%d : performing request sense\n", instance->host_no);
 #endif
 						cmd->cmnd[0] = REQUEST_SENSE;
 						cmd->cmnd[1] &= 0xe0;
@@ -2865,20 +2675,20 @@
 					while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
 						barrier();
 					return;
-					case MESSAGE_REJECT:
+				case MESSAGE_REJECT:
 					/* Accept message by clearing ACK */
-					    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					switch (hostdata->last_message) {
-						case HEAD_OF_QUEUE_TAG:
-						    case ORDERED_QUEUE_TAG:
-						    case SIMPLE_QUEUE_TAG:
-						    cmd->device->tagged_queue = 0;
+					case HEAD_OF_QUEUE_TAG:
+					case ORDERED_QUEUE_TAG:
+					case SIMPLE_QUEUE_TAG:
+						cmd->device->tagged_queue = 0;
 						hostdata->busy[cmd->target] |= (1 << cmd->lun);
 						break;
-						default:
-						    break;
+					default:
+						break;
 					}
-					case DISCONNECT: {
+				case DISCONNECT:{
 						unsigned long flags;
 						/* Accept message by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -2892,9 +2702,7 @@
 						hostdata->disconnected_queue = cmd;
 						restore_flags(flags);
 #if (NDEBUG & NDEBUG_QUEUES)
-						printk("scsi%d : command for target %d lun %d was moved from connected to"
-						       "  the disconnected_queue\n", instance->host_no,
-						  cmd->target, cmd->lun);
+						printk("scsi%d : command for target %d lun %d was moved from connected to" "  the disconnected_queue\n", instance->host_no, cmd->target, cmd->lun);
 #endif
 						/* 
 						 * Restore phase bits to 0 so an interrupted selection, 
@@ -2922,12 +2730,12 @@
 					 * disconnecting, and we have to break spec to remain 
 					 * compatible.
 					 */
-					case SAVE_POINTERS:
-					    case RESTORE_POINTERS:
+				case SAVE_POINTERS:
+				case RESTORE_POINTERS:
 					/* Accept message by clearing ACK */
-					    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					break;
-					case EXTENDED_MESSAGE:
+				case EXTENDED_MESSAGE:
 /* 
  * Extended messages are sent in the following format :
  * Byte         
@@ -2940,13 +2748,12 @@
  * Start the extended message buffer with the EXTENDED_MESSAGE
  * byte, since print_msg() wants the whole thing.  
  */
-					    extended_msg[0] = EXTENDED_MESSAGE;
+					extended_msg[0] = EXTENDED_MESSAGE;
 					/* Accept first byte by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
 #if (NDEBUG & NDEBUG_EXTENDED)
-					printk("scsi%d : receiving extended message\n",
-					       instance->host_no);
+					printk("scsi%d : receiving extended message\n", instance->host_no);
 #endif
 
 					len = 2;
@@ -2955,13 +2762,10 @@
 					NCR5380_transfer_pio(instance, &phase, &len, &data);
 
 #if (NDEBUG & NDEBUG_EXTENDED)
-					printk("scsi%d : length=%d, code=0x%02x\n",
-					       instance->host_no, (int) extended_msg[1],
-					       (int) extended_msg[2]);
+					printk("scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]);
 #endif
 
-					if (!len && extended_msg[1] <=
-					    (sizeof(extended_msg) - 1)) {
+					if (!len && extended_msg[1] <= (sizeof(extended_msg) - 1)) {
 						/* Accept third byte by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 						len = extended_msg[1] - 1;
@@ -2971,24 +2775,21 @@
 						NCR5380_transfer_pio(instance, &phase, &len, &data);
 
 #if (NDEBUG & NDEBUG_EXTENDED)
-						printk("scsi%d : message received, residual %d\n",
-						 instance->host_no, len);
+						printk("scsi%d : message received, residual %d\n", instance->host_no, len);
 #endif
 
 						switch (extended_msg[2]) {
-							case EXTENDED_SDTR:
-							    case EXTENDED_WDTR:
-							    case EXTENDED_MODIFY_DATA_POINTER:
-							    case EXTENDED_EXTENDED_IDENTIFY:
-							    tmp = 0;
+						case EXTENDED_SDTR:
+						case EXTENDED_WDTR:
+						case EXTENDED_MODIFY_DATA_POINTER:
+						case EXTENDED_EXTENDED_IDENTIFY:
+							tmp = 0;
 						}
 					} else if (len) {
-						printk("scsi%d: error receiving extended message\n",
-						       instance->host_no);
+						printk("scsi%d: error receiving extended message\n", instance->host_no);
 						tmp = 0;
 					} else {
-						printk("scsi%d: extended message code %02x length %d is too long\n",
-						       instance->host_no, extended_msg[2], extended_msg[1]);
+						printk("scsi%d: extended message code %02x length %d is too long\n", instance->host_no, extended_msg[2], extended_msg[1]);
 						tmp = 0;
 					}
 					/* Fall through to reject message */
@@ -2997,26 +2798,23 @@
 					 * If we get something weird that we aren't expecting, 
 					 * reject it.
 					 */
-					default:
-					    if (!tmp) {
+				default:
+					if (!tmp) {
 						printk("scsi%d: rejecting message ", instance->host_no);
 						print_msg(extended_msg);
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
-						printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n",
-						       instance->host_no, tmp, cmd->target, cmd->lun);
+						printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, cmd->target, cmd->lun);
 					else
-						printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n",
-						       instance->host_no, extended_msg[1], extended_msg[0], cmd->target, cmd->lun);
+						printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n", instance->host_no, extended_msg[1], extended_msg[0], cmd->target, cmd->lun);
 
 					msgout = MESSAGE_REJECT;
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-						      ICR_ASSERT_ATN);
+					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 					break;
 				}	/* switch (tmp) */
 				break;
-				case PHASE_MSGOUT:
-				    len = 1;
+			case PHASE_MSGOUT:
+				len = 1;
 				data = &msgout;
 				hostdata->last_message = msgout;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
@@ -3033,54 +2831,47 @@
 				}
 				msgout = NOP;
 				break;
-				case PHASE_CMDOUT:
-				    len = cmd->cmd_len;
+			case PHASE_CMDOUT:
+				len = cmd->cmd_len;
 				data = cmd->cmnd;
 				/* 
 				 * XXX for performance reasons, on machines with a 
 				 * PSEUDO-DMA architecture we should probably 
 				 * use the dma transfer function.  
 				 */
-				NCR5380_transfer_pio(instance, &phase, &len,
-						     &data);
+				NCR5380_transfer_pio(instance, &phase, &len, &data);
 #ifdef USLEEP
-				if (!cmd->device->disconnect &&
-					should_disconnect(cmd->cmnd[0])) 
-				{
+				if (!cmd->device->disconnect && should_disconnect(cmd->cmnd[0])) {
 					hostdata->time_expires = jiffies + USLEEP_SLEEP;
 #if (NDEBUG & NDEBUG_USLEEP)
-					printk("scsi%d : issued command, sleeping until %ul\n", instance->host_no,
-					       hostdata->time_expires);
+					printk("scsi%d : issued command, sleeping until %ul\n", instance->host_no, hostdata->time_expires);
 #endif
 					NCR5380_set_timer(instance);
 					return;
 				}
 #endif				/* def USLEEP */
 				break;
-				case PHASE_STATIN:
-				    len = 1;
+			case PHASE_STATIN:
+				len = 1;
 				data = &tmp;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				cmd->SCp.Status = tmp;
 				break;
-				default:
-				    printk("scsi%d : unknown phase\n", instance->host_no);
+			default:
+				printk("scsi%d : unknown phase\n", instance->host_no);
 #ifdef NDEBUG
 				NCR5380_print(instance);
 #endif
 			}	/* switch(phase) */
 		}		/* if (tmp * SR_REQ) */
 #ifdef USLEEP
-		else 
-		{
+		else {
 			/* RvC: go to sleep if polling time expired
 			 */
-			if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time))
-			{
+			if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) {
 				hostdata->time_expires = jiffies + USLEEP_SLEEP;
 #if (NDEBUG & NDEBUG_USLEEP)
-				printk("scsi%d : poll timed out, sleeping until %ul\n", instance->host_no,
-				       hostdata->time_expires);
+				printk("scsi%d : poll timed out, sleeping until %ul\n", instance->host_no, hostdata->time_expires);
 #endif
 				NCR5380_set_timer(instance);
 				return;
@@ -3159,8 +2950,7 @@
 
 
 	if (!msg[0] & 0x80) {
-		printk("scsi%d : expecting IDENTIFY message, got ",
-		       instance->host_no);
+		printk("scsi%d : expecting IDENTIFY message, got ", instance->host_no);
 		print_msg(msg);
 		abort = 1;
 	} else {
@@ -3184,8 +2974,7 @@
 		 */
 
 
-		for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL;
-		 tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
+		for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
 			if ((target_mask == (1 << tmp->target)) && (lun == tmp->lun)
 #ifdef SCSI2
 			    && (tag == tmp->tag)
@@ -3203,11 +2992,9 @@
 			}
 		if (!tmp) {
 #ifdef SCSI2
-			printk("scsi%d : warning : target bitmask %02x lun %d tag %d not in disconnect_queue.\n",
-			       instance->host_no, target_mask, lun, tag);
+			printk("scsi%d : warning : target bitmask %02x lun %d tag %d not in disconnect_queue.\n", instance->host_no, target_mask, lun, tag);
 #else
-			printk("scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n",
-			       instance->host_no, target_mask, lun);
+			printk("scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n", instance->host_no, target_mask, lun);
 #endif
 			/* 
 			 * Since we have an established nexus that we can't do anything with,
@@ -3222,8 +3009,7 @@
 	} else {
 		hostdata->connected = tmp;
 #if (NDEBUG & NDEBUG_RESELECTION)
-		printk("scsi%d : nexus established, target = %d, lun = %d, tag = %d\n",
-		     instance->host_no, tmp->target, tmp->lun, tmp->tag);
+		printk("scsi%d : nexus established, target = %d, lun = %d, tag = %d\n", instance->host_no, tmp->target, tmp->lun, tmp->tag);
 #endif
 	}
 }
@@ -3243,8 +3029,7 @@
 #ifdef REAL_DMA
 static void NCR5380_dma_complete(NCR5380_instance * instance) {
 	NCR5380_local_declare();
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *
-					     instance->hostdata);
+	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata * instance->hostdata);
 	int transferred;
 	NCR5380_setup(instance);
 
@@ -3320,8 +3105,7 @@
 
 #if (NDEBUG & NDEBUG_ABORT)
 	printk("scsi%d : abort called\n", instance->host_no);
-	printk("        basr 0x%X, sr 0x%X\n",
-	     NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
+	printk("        basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
 #endif
 
 #if 0
@@ -3365,10 +3149,7 @@
 	/* KLL */
 	printk("scsi%d : abort going into loop.\n", instance->host_no);
 #endif
-	for (prev = (Scsi_Cmnd **) & (hostdata->issue_queue),
-	     tmp = (Scsi_Cmnd *) hostdata->issue_queue;
-	     tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp =
-	     (Scsi_Cmnd *) tmp->host_scribble)
+	for (prev = (Scsi_Cmnd **) & (hostdata->issue_queue), tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp = (Scsi_Cmnd *) tmp->host_scribble)
 		if (cmd == tmp) {
 			REMOVE(5, *prev, tmp, tmp->host_scribble);
 			(*prev) = (Scsi_Cmnd *) tmp->host_scribble;
@@ -3376,8 +3157,7 @@
 			tmp->result = DID_ABORT << 16;
 			restore_flags(flags);
 #if (NDEBUG & NDEBUG_ABORT)
-			printk("scsi%d : abort removed command from issue queue.\n",
-			       instance->host_no);
+			printk("scsi%d : abort removed command from issue queue.\n", instance->host_no);
 #endif
 			tmp->done(tmp);
 			return SCSI_ABORT_SUCCESS;
@@ -3431,8 +3211,7 @@
  * it from the disconnected queue.
  */
 
-	for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp;
-	     tmp = (Scsi_Cmnd *) tmp->host_scribble)
+	for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; tmp = (Scsi_Cmnd *) tmp->host_scribble)
 		if (cmd == tmp) {
 			restore_flags(flags);
 #if (NDEBUG & NDEBUG_ABORT)
@@ -3449,10 +3228,7 @@
 			do_abort(instance);
 
 			cli();
-			for (prev = (Scsi_Cmnd **) & (hostdata->disconnected_queue),
-			tmp = (Scsi_Cmnd *) hostdata->disconnected_queue;
-			     tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp =
-			     (Scsi_Cmnd *) tmp->host_scribble)
+			for (prev = (Scsi_Cmnd **) & (hostdata->disconnected_queue), tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp = (Scsi_Cmnd *) tmp->host_scribble)
 				if (cmd == tmp) {
 					REMOVE(5, *prev, tmp, tmp->host_scribble);
 					*prev = (Scsi_Cmnd *) tmp->host_scribble;
@@ -3474,8 +3250,7 @@
  */
 
 	restore_flags(flags);
-	printk("scsi%d : warning : SCSI command probably completed successfully\n"
-	       "         before abortion\n", instance->host_no);
+	printk("scsi%d : warning : SCSI command probably completed successfully\n" "         before abortion\n", instance->host_no);
 	return SCSI_ABORT_NOT_RUNNING;
 }
 
diff -urN linux-2.4.17-pre4/drivers/scsi/NCR5380.h linux/drivers/scsi/NCR5380.h
--- linux-2.4.17-pre4/drivers/scsi/NCR5380.h	Tue Feb 13 13:15:04 2001
+++ linux/drivers/scsi/NCR5380.h	Thu Dec  6 10:53:04 2001
@@ -62,8 +62,8 @@
  * bit in the INITIATOR COMMAND register is set.
  */
 
-#define OUTPUT_DATA_REG         0       /* wo DATA lines on SCSI bus */
-#define CURRENT_SCSI_DATA_REG   0       /* ro same */
+#define OUTPUT_DATA_REG         0	/* wo DATA lines on SCSI bus */
+#define CURRENT_SCSI_DATA_REG   0	/* ro same */
 
 #define INITIATOR_COMMAND_REG	1	/* rw */
 #define ICR_ASSERT_RST		0x80	/* rw Set to assert RST  */
@@ -116,7 +116,7 @@
  * Note : a set bit indicates an active signal, driven by us or another 
  * device.
  */
-#define SR_RST			0x80	
+#define SR_RST			0x80
 #define SR_BSY			0x40
 #define SR_REQ			0x20
 #define SR_MSG			0x10
@@ -159,17 +159,17 @@
 /* Write any value to this register to start an ini mode DMA receive */
 #define START_DMA_INITIATOR_RECEIVE_REG 7	/* wo */
 
-#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8      /* rw */
+#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8	/* rw */
 
-#define CSR_RESET              0x80    /* wo  Resets 53c400 */
-#define CSR_53C80_REG          0x80    /* ro  5380 registers busy */
-#define CSR_TRANS_DIR          0x40    /* rw  Data transfer direction */
-#define CSR_SCSI_BUFF_INTR     0x20    /* rw  Enable int on transfer ready */
-#define CSR_53C80_INTR         0x10    /* rw  Enable 53c80 interrupts */
-#define CSR_SHARED_INTR        0x08    /* rw  Interrupt sharing */
-#define CSR_HOST_BUF_NOT_RDY   0x04    /* ro  Is Host buffer ready */
-#define CSR_SCSI_BUF_RDY       0x02    /* ro  SCSI buffer read */
-#define CSR_GATED_53C80_IRQ    0x01    /* ro  Last block xferred */
+#define CSR_RESET              0x80	/* wo  Resets 53c400 */
+#define CSR_53C80_REG          0x80	/* ro  5380 registers busy */
+#define CSR_TRANS_DIR          0x40	/* rw  Data transfer direction */
+#define CSR_SCSI_BUFF_INTR     0x20	/* rw  Enable int on transfer ready */
+#define CSR_53C80_INTR         0x10	/* rw  Enable 53c80 interrupts */
+#define CSR_SHARED_INTR        0x08	/* rw  Interrupt sharing */
+#define CSR_HOST_BUF_NOT_RDY   0x04	/* ro  Is Host buffer ready */
+#define CSR_SCSI_BUF_RDY       0x02	/* ro  SCSI buffer read */
+#define CSR_GATED_53C80_IRQ    0x01	/* ro  Last block xferred */
 
 #if 0
 #define CSR_BASE CSR_SCSI_BUFF_INTR | CSR_53C80_INTR
@@ -178,13 +178,13 @@
 #endif
 
 /* Number of 128-byte blocks to be transferred */
-#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7      /* rw */
+#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7	/* rw */
 
 /* Resume transfer after disconnect */
-#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6      /* wo */
+#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6	/* wo */
 
 /* Access to host buffer stack */
-#define C400_HOST_BUFFER         NCR53C400_register_offset-4      /* rw */
+#define C400_HOST_BUFFER         NCR53C400_register_offset-4	/* rw */
 
 
 /* Note : PHASE_* macros are based on the values of the STATUS register */
@@ -203,8 +203,8 @@
  * the target register so we can get phase mismatch interrupts on DMA 
  * transfers.
  */
- 
-#define PHASE_SR_TO_TCR(phase) ((phase) >> 2)	
+
+#define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
 
 /*
  * The internal should_disconnect() function returns these based on the 
@@ -220,7 +220,7 @@
  * These are "special" values for the tag parameter passed to NCR5380_select.
  */
 
-#define TAG_NEXT	-1 	/* Use next free tag */
+#define TAG_NEXT	-1	/* Use next free tag */
 #define TAG_NONE	-2	/* 
 				 * Establish I_T_L nexus instead of I_T_L_Q
 				 * even on SCSI-II devices.
@@ -235,7 +235,7 @@
 #define DMA_NONE	255
 #define IRQ_AUTO	254
 #define DMA_AUTO	254
-#define PORT_AUTO	0xffff		/* autoprobe io port for 53c400a */
+#define PORT_AUTO	0xffff	/* autoprobe io port for 53c400a */
 
 #define FLAG_HAS_LAST_BYTE_SENT		1	/* NCR53c81 or better */
 #define FLAG_CHECK_LAST_BYTE_SENT	2	/* Only test once */
@@ -245,134 +245,134 @@
 
 #ifndef ASM
 struct NCR5380_hostdata {
-    NCR5380_implementation_fields;		/* implementation specific */
-    unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
-    unsigned char targets_present;		/* targets we have connected
-						   to, so we can call a select
-						   failure a retryable condition */
-    volatile unsigned char busy[8];		/* index = target, bit = lun */
+	NCR5380_implementation_fields;	/* implementation specific */
+	unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
+	unsigned char targets_present;	/* targets we have connected
+					   to, so we can call a select
+					   failure a retryable condition */
+	volatile unsigned char busy[8];	/* index = target, bit = lun */
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-    volatile int dma_len;			/* requested length of DMA */
+	volatile int dma_len;	/* requested length of DMA */
 #endif
-    volatile unsigned char last_message;	/* last message OUT */
-    volatile Scsi_Cmnd *connected;		/* currently connected command */
-    volatile Scsi_Cmnd *issue_queue;		/* waiting to be issued */
-    volatile Scsi_Cmnd *disconnected_queue;	/* waiting for reconnect */
-    volatile int restart_select;		/* we have disconnected,
-						   used to restart 
-						   NCR5380_select() */
-    volatile unsigned aborted:1;		/* flag, says aborted */
-    int flags;
+	volatile unsigned char last_message;	/* last message OUT */
+	volatile Scsi_Cmnd *connected;	/* currently connected command */
+	volatile Scsi_Cmnd *issue_queue;	/* waiting to be issued */
+	volatile Scsi_Cmnd *disconnected_queue;	/* waiting for reconnect */
+	volatile int restart_select;	/* we have disconnected,
+					   used to restart 
+					   NCR5380_select() */
+	volatile unsigned aborted:1;	/* flag, says aborted */
+	int flags;
 #ifdef USLEEP
-    unsigned long time_expires;			/* in jiffies, set prior to sleeping */
-    struct Scsi_Host *next_timer;
-    int select_time;				/* timer in select for target response */
-    volatile Scsi_Cmnd *selecting;
+	unsigned long time_expires;	/* in jiffies, set prior to sleeping */
+	struct Scsi_Host *next_timer;
+	int select_time;	/* timer in select for target response */
+	volatile Scsi_Cmnd *selecting;
 #endif
 #ifdef NCR5380_STATS
-    unsigned timebase;				/* Base for time calcs */
-    long time_read[8];				/* time to do reads */
-    long time_write[8];				/* time to do writes */
-    unsigned long bytes_read[8];		/* bytes read */
-    unsigned long bytes_write[8];		/* bytes written */
-    unsigned pendingr;
-    unsigned pendingw;
+	unsigned timebase;	/* Base for time calcs */
+	long time_read[8];	/* time to do reads */
+	long time_write[8];	/* time to do writes */
+	unsigned long bytes_read[8];	/* bytes read */
+	unsigned long bytes_write[8];	/* bytes written */
+	unsigned pendingr;
+	unsigned pendingw;
 #endif
 };
 
 #ifdef __KERNEL__
-static struct Scsi_Host *first_instance;		/* linked list of 5380's */
+static struct Scsi_Host *first_instance;	/* linked list of 5380's */
 
 #if defined(AUTOPROBE_IRQ)
-static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible);
+static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
 #endif
-static void NCR5380_init (struct Scsi_Host *instance, int flags);
-static void NCR5380_information_transfer (struct Scsi_Host *instance);
+static void NCR5380_init(struct Scsi_Host *instance, int flags);
+static void NCR5380_information_transfer(struct Scsi_Host *instance);
 #ifndef DONT_USE_INTR
-static void NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs);
-static void do_NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs);
+static void NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs);
+static void do_NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs);
 #endif
-static void NCR5380_main (void);
-static void NCR5380_print_options (struct Scsi_Host *instance);
-static void NCR5380_print_phase (struct Scsi_Host *instance);
-static void NCR5380_print (struct Scsi_Host *instance);
+static void NCR5380_main(void);
+static void NCR5380_print_options(struct Scsi_Host *instance);
+static void NCR5380_print_phase(struct Scsi_Host *instance);
+static void NCR5380_print(struct Scsi_Host *instance);
 #ifndef NCR5380_abort
 static
 #endif
-int NCR5380_abort (Scsi_Cmnd *cmd);
+int NCR5380_abort(Scsi_Cmnd * cmd);
 #ifndef NCR5380_reset
 static
 #endif
-int NCR5380_reset (Scsi_Cmnd *cmd, unsigned int reset_flags);
+int NCR5380_reset(Scsi_Cmnd * cmd, unsigned int reset_flags);
 #ifndef NCR5380_queue_command
-static 
+static
 #endif
-int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
+int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
 
 
-static void NCR5380_reselect (struct Scsi_Host *instance);
-static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag);
+static void NCR5380_reselect(struct Scsi_Host *instance);
+static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag);
 #if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
-static int NCR5380_transfer_dma (struct Scsi_Host *instance,
-	unsigned char *phase, int *count, unsigned char **data);
+static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
 #endif
-static int NCR5380_transfer_pio (struct Scsi_Host *instance,
-	unsigned char *phase, int *count, unsigned char **data);
+static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
 
 #if (defined(REAL_DMA) || defined(REAL_DMA_POLL))
 
 #if defined(i386) || defined(__alpha__)
 
-static __inline__ int NCR5380_pc_dma_setup (struct Scsi_Host *instance,
-	unsigned char *ptr, unsigned int count, unsigned char mode) {
-    unsigned limit;
-    unsigned long bus_addr = virt_to_bus(ptr);
-
-    if (instance->dma_channel <=3) {
-	if (count > 65536)
-	    count = 65536;
-	limit = 65536 - (bus_addr & 0xFFFF);
-    } else {
-	if (count > 65536 * 2) 
-	    count = 65536 * 2;
-	limit = 65536* 2 - (bus_addr & 0x1FFFF);
-    }
-
-    if (count > limit) count = limit;
-
-    if ((count & 1) || (bus_addr & 1))
-	panic ("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
-    cli();
-    disable_dma(instance->dma_channel);
-    clear_dma_ff(instance->dma_channel);
-    set_dma_addr(instance->dma_channel, bus_addr);
-    set_dma_count(instance->dma_channel, count);
-    set_dma_mode(instance->dma_channel, mode);
-    enable_dma(instance->dma_channel);
-    sti();
-    return count;
+static __inline__ int NCR5380_pc_dma_setup(struct Scsi_Host *instance, unsigned char *ptr, unsigned int count, unsigned char mode)
+{
+	unsigned limit;
+	unsigned long bus_addr = virt_to_bus(ptr);
+
+	if (instance->dma_channel <= 3) {
+		if (count > 65536)
+			count = 65536;
+		limit = 65536 - (bus_addr & 0xFFFF);
+	} else {
+		if (count > 65536 * 2)
+			count = 65536 * 2;
+		limit = 65536 * 2 - (bus_addr & 0x1FFFF);
+	}
+
+	if (count > limit)
+		count = limit;
+
+	if ((count & 1) || (bus_addr & 1))
+		panic("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
+	cli();
+	disable_dma(instance->dma_channel);
+	clear_dma_ff(instance->dma_channel);
+	set_dma_addr(instance->dma_channel, bus_addr);
+	set_dma_count(instance->dma_channel, count);
+	set_dma_mode(instance->dma_channel, mode);
+	enable_dma(instance->dma_channel);
+	sti();
+	return count;
 }
 
-static __inline__ int NCR5380_pc_dma_write_setup (struct Scsi_Host *instance,
-    unsigned char *src, unsigned int count) {
-    return NCR5380_pc_dma_setup (instance, src, count, DMA_MODE_WRITE);
+static __inline__ int NCR5380_pc_dma_write_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
+{
+	return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_WRITE);
 }
 
-static __inline__ int NCR5380_pc_dma_read_setup (struct Scsi_Host *instance,
-    unsigned char *src, unsigned int count) {
-    return NCR5380_pc_dma_setup (instance, src, count, DMA_MODE_READ);
+static __inline__ int NCR5380_pc_dma_read_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
+{
+	return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_READ);
 }
 
-static __inline__ int NCR5380_pc_dma_residual (struct Scsi_Host *instance) {
-    register int tmp;
-    cli();
-    clear_dma_ff(instance->dma_channel);
-    tmp = get_dma_residue(instance->dma_channel);
-    sti();
-    return tmp;
+static __inline__ int NCR5380_pc_dma_residual(struct Scsi_Host *instance)
+{
+	register int tmp;
+	cli();
+	clear_dma_ff(instance->dma_channel);
+	tmp = get_dma_residue(instance->dma_channel);
+	sti();
+	return tmp;
 }
-#endif /* defined(i386) || defined(__alpha__) */
-#endif /* defined(REAL_DMA)  */
-#endif /* __KERNEL__ */
-#endif /* ndef ASM */
-#endif /* NCR5380_H */
+#endif				/* defined(i386) || defined(__alpha__) */
+#endif				/* defined(REAL_DMA)  */
+#endif				/* __KERNEL__ */
+#endif				/* ndef ASM */
+#endif				/* NCR5380_H */
diff -urN linux-2.4.17-pre4/drivers/scsi/README.ncr53c8xx linux/drivers/scsi/README.ncr53c8xx
--- linux-2.4.17-pre4/drivers/scsi/README.ncr53c8xx	Thu Jul  5 11:28:17 2001
+++ linux/drivers/scsi/README.ncr53c8xx	Thu Dec  6 10:53:04 2001
@@ -1,6 +1,6 @@
 The Linux NCR53C8XX/SYM53C8XX drivers README file
 
-Written by Gerard Roudier <groudier@club-internet.fr>
+Written by Gerard Roudier <groudier@free.fr>
 21 Rue Carnot
 95170 DEUIL LA BARRE - FRANCE
 
@@ -87,7 +87,7 @@
 
 The initial Linux ncr53c8xx driver has been a port of the ncr driver from 
 FreeBSD that has been achieved in November 1995 by:
-          Gerard Roudier              <groudier@club-internet.fr>
+          Gerard Roudier              <groudier@free.fr>
 
 The original driver has been written for 386bsd and FreeBSD by:
           Wolfgang Stanglmeier        <wolf@cologne.de>
@@ -1287,7 +1287,7 @@
 be sure I will receive it.  Obviously, a bug in the driver code is
 possible.
 
-     My email address: Gerard Roudier <groudier@club-internet.fr>
+     My email address: Gerard Roudier <groudier@free.fr>
 
 Allowing disconnections is important if you use several devices on
 your SCSI bus but often causes problems with buggy devices.
diff -urN linux-2.4.17-pre4/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- linux-2.4.17-pre4/drivers/scsi/g_NCR5380.c	Sun Sep 30 12:26:07 2001
+++ linux/drivers/scsi/g_NCR5380.c	Thu Dec  6 10:53:04 2001
@@ -77,7 +77,7 @@
  * 	IRQ line if overridden on the command line.
  *     
  */
- 
+
 /*
  * $Log: generic_NCR5380.c,v $
  */
@@ -124,24 +124,25 @@
 #include <linux/isapnp.h>
 
 #define NCR_NOT_SET 0
-static int ncr_irq=NCR_NOT_SET;
-static int ncr_dma=NCR_NOT_SET;
-static int ncr_addr=NCR_NOT_SET;
-static int ncr_5380=NCR_NOT_SET;
-static int ncr_53c400=NCR_NOT_SET;
-static int ncr_53c400a=NCR_NOT_SET;
-static int dtc_3181e=NCR_NOT_SET;
+static int ncr_irq = NCR_NOT_SET;
+static int ncr_dma = NCR_NOT_SET;
+static int ncr_addr = NCR_NOT_SET;
+static int ncr_5380 = NCR_NOT_SET;
+static int ncr_53c400 = NCR_NOT_SET;
+static int ncr_53c400a = NCR_NOT_SET;
+static int dtc_3181e = NCR_NOT_SET;
 
 static struct override {
 	NCR5380_implementation_fields;
-    int irq;
-    int dma;
-    int board;	/* Use NCR53c400, Ricoh, etc. extensions ? */
-} overrides 
-#ifdef GENERIC_NCR5380_OVERRIDE 
-    [] __initdata = GENERIC_NCR5380_OVERRIDE;
+	int irq;
+	int dma;
+	int board;		/* Use NCR53c400, Ricoh, etc. extensions ? */
+} overrides
+#ifdef GENERIC_NCR5380_OVERRIDE
+[] __initdata = GENERIC_NCR5380_OVERRIDE;
 #else
-    [1] __initdata = {{0,},};
+[1] __initdata = { {
+0,},};
 #endif
 
 #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
@@ -157,45 +158,46 @@
  *
  */
 
-static void __init internal_setup(int board, char *str, int *ints){
-    static int commandline_current = 0;
-    switch (board) {
-    case BOARD_NCR5380:
-	if (ints[0] != 2 && ints[0] != 3) {
-	    printk("generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
-	    return;
-	}
-	break;
-    case BOARD_NCR53C400:
-	if (ints[0] != 2) {
-	    printk("generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
-	    return;
-	}
-	break;
-    case BOARD_NCR53C400A:
-	if (ints[0] != 2) {
-	    printk("generic_NCR53C400A_setup : usage ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n");
-	    return;
-	}
-	break;
-    case BOARD_DTC3181E:
-	if (ints[0] != 2) {
-	    printk("generic_DTC3181E_setup : usage dtc3181e=" STRVAL(NCR5380_map_name) ",irq\n");
-	    return;
-	}
-	break;
-    }
-
-    if (commandline_current < NO_OVERRIDES) {
-	overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type)ints[1];
-	overrides[commandline_current].irq = ints[2];
-	if (ints[0] == 3) 
-	    overrides[commandline_current].dma = ints[3];
-	else 
-	    overrides[commandline_current].dma = DMA_NONE;
-	overrides[commandline_current].board = board;
-	    ++commandline_current;
-    }
+static void __init internal_setup(int board, char *str, int *ints)
+{
+	static int commandline_current = 0;
+	switch (board) {
+	case BOARD_NCR5380:
+		if (ints[0] != 2 && ints[0] != 3) {
+			printk("generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
+			return;
+		}
+		break;
+	case BOARD_NCR53C400:
+		if (ints[0] != 2) {
+			printk("generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
+			return;
+		}
+		break;
+	case BOARD_NCR53C400A:
+		if (ints[0] != 2) {
+			printk("generic_NCR53C400A_setup : usage ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n");
+			return;
+		}
+		break;
+	case BOARD_DTC3181E:
+		if (ints[0] != 2) {
+			printk("generic_DTC3181E_setup : usage dtc3181e=" STRVAL(NCR5380_map_name) ",irq\n");
+			return;
+		}
+		break;
+	}
+
+	if (commandline_current < NO_OVERRIDES) {
+		overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type) ints[1];
+		overrides[commandline_current].irq = ints[2];
+		if (ints[0] == 3)
+			overrides[commandline_current].dma = ints[3];
+		else
+			overrides[commandline_current].dma = DMA_NONE;
+		overrides[commandline_current].board = board;
+		++commandline_current;
+	}
 }
 
 /*
@@ -207,8 +209,9 @@
  * 	equal to the number of ints.
  */
 
-void __init generic_NCR5380_setup (char *str, int *ints){
-    internal_setup (BOARD_NCR5380, str, ints);
+void __init generic_NCR5380_setup(char *str, int *ints)
+{
+	internal_setup(BOARD_NCR5380, str, ints);
 }
 
 /*
@@ -220,8 +223,9 @@
  * 	equal to the number of ints.
  */
 
-void __init generic_NCR53C400_setup (char *str, int *ints){
-    internal_setup (BOARD_NCR53C400, str, ints);
+void __init generic_NCR53C400_setup(char *str, int *ints)
+{
+	internal_setup(BOARD_NCR53C400, str, ints);
 }
 
 /*
@@ -233,8 +237,9 @@
  * 	equal to the number of ints.
  */
 
-void generic_NCR53C400A_setup (char *str, int *ints) {
-    internal_setup (BOARD_NCR53C400A, str, ints);
+void generic_NCR53C400A_setup(char *str, int *ints)
+{
+	internal_setup(BOARD_NCR53C400A, str, ints);
 }
 
 /*
@@ -246,8 +251,9 @@
  * 	equal to the number of ints.
  */
 
-void generic_DTC3181E_setup (char *str, int *ints) {
-    internal_setup (BOARD_DTC3181E, str, ints);
+void generic_DTC3181E_setup(char *str, int *ints)
+{
+	internal_setup(BOARD_DTC3181E, str, ints);
 }
 
 /* 
@@ -262,202 +268,197 @@
  *
  */
 
-int __init generic_NCR5380_detect(Scsi_Host_Template * tpnt){
-    static int current_override = 0;
-    int count, i;
-    u_int *ports;
-    u_int ncr_53c400a_ports[] = {0x280, 0x290, 0x300, 0x310, 0x330,
-    		     		0x340, 0x348, 0x350, 0};
-    u_int dtc_3181e_ports[] = {0x220, 0x240, 0x280, 0x2a0, 0x2c0,
-    			     0x300, 0x320, 0x340, 0};
-    int flags = 0;
-    struct Scsi_Host *instance;
-
-    if (ncr_irq != NCR_NOT_SET)
-	overrides[0].irq=ncr_irq;
-    if (ncr_dma != NCR_NOT_SET)
-	overrides[0].dma=ncr_dma;
-    if (ncr_addr != NCR_NOT_SET)
-	overrides[0].NCR5380_map_name=(NCR5380_map_type)ncr_addr;
-    if (ncr_5380 != NCR_NOT_SET)
-	overrides[0].board=BOARD_NCR5380;
-    else if (ncr_53c400 != NCR_NOT_SET)
-	overrides[0].board=BOARD_NCR53C400;
-    else if (ncr_53c400a != NCR_NOT_SET)
-        overrides[0].board=BOARD_NCR53C400A;
-    else if (dtc_3181e != NCR_NOT_SET)
-        overrides[0].board=BOARD_DTC3181E;
-
-    if (!current_override && isapnp_present()) {
-	    struct pci_dev *dev = NULL;
-	    count = 0;
-	    while ((dev = isapnp_find_dev(NULL, ISAPNP_VENDOR('D','T','C'), ISAPNP_FUNCTION(0x436e), dev))) {
-		    if (count >= NO_OVERRIDES)
-			    break;
-		    if (!dev->active && dev->prepare(dev) < 0) {
-			    printk(KERN_ERR "dtc436e probe: prepare failed\n");
-			    continue;
-		    }
-		    if (!(dev->resource[0].flags & IORESOURCE_IO))
-			    continue;
-		    if (!dev->active && dev->activate(dev) < 0) {
-			    printk(KERN_ERR "dtc436e probe: activate failed\n");
-			    continue;
-		    }
-		    if (dev->irq_resource[0].flags & IORESOURCE_IRQ)
-			    overrides[count].irq=dev->irq_resource[0].start;
-		    else
-			    overrides[count].irq=IRQ_NONE;
-		    if (dev->dma_resource[0].flags & IORESOURCE_DMA)
-			    overrides[count].dma=dev->dma_resource[0].start;
-		    else
-			    overrides[count].dma=DMA_NONE;
-		    overrides[count].NCR5380_map_name=(NCR5380_map_type)dev->resource[0].start;
-		    overrides[count].board=BOARD_DTC3181E;
-		    count++;
-	    }
-    }
-
-    tpnt->proc_name = "g_NCR5380";
-
-    for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
-	if (!(overrides[current_override].NCR5380_map_name))
-	    continue;
-
-	ports = 0;
-	switch (overrides[current_override].board) {
-	case BOARD_NCR5380:
-	    flags = FLAG_NO_PSEUDO_DMA;
-	    break;
-	case BOARD_NCR53C400:
-	    flags = FLAG_NCR53C400;
-	    break;
-	case BOARD_NCR53C400A:
-	    flags = FLAG_NO_PSEUDO_DMA;
-            ports = ncr_53c400a_ports;
-	    break;
-	case BOARD_DTC3181E:
-	    flags = FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E;
-	    ports = dtc_3181e_ports;
-	    break;
+int __init generic_NCR5380_detect(Scsi_Host_Template * tpnt)
+{
+	static int current_override = 0;
+	int count, i;
+	u_int *ports;
+	u_int ncr_53c400a_ports[] = { 0x280, 0x290, 0x300, 0x310, 0x330,
+		0x340, 0x348, 0x350, 0
+	};
+	u_int dtc_3181e_ports[] = { 0x220, 0x240, 0x280, 0x2a0, 0x2c0,
+		0x300, 0x320, 0x340, 0
+	};
+	int flags = 0;
+	struct Scsi_Host *instance;
+
+	if (ncr_irq != NCR_NOT_SET)
+		overrides[0].irq = ncr_irq;
+	if (ncr_dma != NCR_NOT_SET)
+		overrides[0].dma = ncr_dma;
+	if (ncr_addr != NCR_NOT_SET)
+		overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
+	if (ncr_5380 != NCR_NOT_SET)
+		overrides[0].board = BOARD_NCR5380;
+	else if (ncr_53c400 != NCR_NOT_SET)
+		overrides[0].board = BOARD_NCR53C400;
+	else if (ncr_53c400a != NCR_NOT_SET)
+		overrides[0].board = BOARD_NCR53C400A;
+	else if (dtc_3181e != NCR_NOT_SET)
+		overrides[0].board = BOARD_DTC3181E;
+
+	if (!current_override && isapnp_present()) {
+		struct pci_dev *dev = NULL;
+		count = 0;
+		while ((dev = isapnp_find_dev(NULL, ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e), dev))) {
+			if (count >= NO_OVERRIDES)
+				break;
+			if (!dev->active && dev->prepare(dev) < 0) {
+				printk(KERN_ERR "dtc436e probe: prepare failed\n");
+				continue;
+			}
+			if (!(dev->resource[0].flags & IORESOURCE_IO))
+				continue;
+			if (!dev->active && dev->activate(dev) < 0) {
+				printk(KERN_ERR "dtc436e probe: activate failed\n");
+				continue;
+			}
+			if (dev->irq_resource[0].flags & IORESOURCE_IRQ)
+				overrides[count].irq = dev->irq_resource[0].start;
+			else
+				overrides[count].irq = IRQ_NONE;
+			if (dev->dma_resource[0].flags & IORESOURCE_DMA)
+				overrides[count].dma = dev->dma_resource[0].start;
+			else
+				overrides[count].dma = DMA_NONE;
+			overrides[count].NCR5380_map_name = (NCR5380_map_type) dev->resource[0].start;
+			overrides[count].board = BOARD_DTC3181E;
+			count++;
+		}
 	}
 
+	tpnt->proc_name = "g_NCR5380";
+
+	for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
+		if (!(overrides[current_override].NCR5380_map_name))
+			continue;
+
+		ports = 0;
+		switch (overrides[current_override].board) {
+		case BOARD_NCR5380:
+			flags = FLAG_NO_PSEUDO_DMA;
+			break;
+		case BOARD_NCR53C400:
+			flags = FLAG_NCR53C400;
+			break;
+		case BOARD_NCR53C400A:
+			flags = FLAG_NO_PSEUDO_DMA;
+			ports = ncr_53c400a_ports;
+			break;
+		case BOARD_DTC3181E:
+			flags = FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E;
+			ports = dtc_3181e_ports;
+			break;
+		}
+
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-	if (ports) {
-	    /* wakeup sequence for the NCR53C400A and DTC3181E*/
+		if (ports) {
+			/* wakeup sequence for the NCR53C400A and DTC3181E */
 
-	    /* Disable the adapter and look for a free io port */
-	    outb(0x59, 0x779);
-	    outb(0xb9, 0x379);
-	    outb(0xc5, 0x379);
-	    outb(0xae, 0x379);
-	    outb(0xa6, 0x379);
-	    outb(0x00, 0x379);
-
-	    if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
-	        for(i=0; ports[i]; i++) {
-	            if (overrides[current_override].NCR5380_map_name == ports[i])
-	                break;
-	        }
-	    else
-	        for(i=0; ports[i]; i++) {
-	            if ((!check_region(ports[i], 16)) && (inb(ports[i]) == 0xff))
-	                break;
-		}
-	    if (ports[i]) {
-	        outb(0x59, 0x779);
-	        outb(0xb9, 0x379);
-	        outb(0xc5, 0x379);
-	        outb(0xae, 0x379);
-	        outb(0xa6, 0x379);
-	        outb(0x80 | i, 0x379);          /* set io port to be used */
-        	outb(0xc0, ports[i] + 9);
-	        if (inb(ports[i] + 9) != 0x80)
-	            continue;
-	        else
-	            overrides[current_override].NCR5380_map_name=ports[i];
-	    } else
-	        continue;
-	}
+			/* Disable the adapter and look for a free io port */
+			outb(0x59, 0x779);
+			outb(0xb9, 0x379);
+			outb(0xc5, 0x379);
+			outb(0xae, 0x379);
+			outb(0xa6, 0x379);
+			outb(0x00, 0x379);
+
+			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
+				for (i = 0; ports[i]; i++) {
+					if (overrides[current_override].NCR5380_map_name == ports[i])
+						break;
+			} else
+				for (i = 0; ports[i]; i++) {
+					if ((!check_region(ports[i], 16)) && (inb(ports[i]) == 0xff))
+						break;
+				}
+			if (ports[i]) {
+				outb(0x59, 0x779);
+				outb(0xb9, 0x379);
+				outb(0xc5, 0x379);
+				outb(0xae, 0x379);
+				outb(0xa6, 0x379);
+				outb(0x80 | i, 0x379);	/* set io port to be used */
+				outb(0xc0, ports[i] + 9);
+				if (inb(ports[i] + 9) != 0x80)
+					continue;
+				else
+					overrides[current_override].NCR5380_map_name = ports[i];
+			} else
+				continue;
+		}
 
-	request_region(overrides[current_override].NCR5380_map_name,
-					NCR5380_region_size, "ncr5380");
+		request_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380");
 #else
-	if(check_mem_region(overrides[current_override].NCR5380_map_name,
-		NCR5380_region_size))
-		continue;
-	request_mem_region(overrides[current_override].NCR5380_map_name,
-					NCR5380_region_size, "ncr5380");
+		if (check_mem_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size))
+			continue;
+		request_mem_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380");
 #endif
-	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
-	if(instance == NULL)
-	{
+		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
+		if (instance == NULL) {
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-		release_region(overrides[current_override].NCR5380_map_name,
-	                                        NCR5380_region_size);
+			release_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size);
 #else
-		release_mem_region(overrides[current_override].NCR5380_map_name,
-	                                  	NCR5380_region_size);
+			release_mem_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size);
 #endif
-		continue;
-	}
-	
-	instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
-
-	NCR5380_init(instance, flags);
+			continue;
+		}
 
-	if (overrides[current_override].irq != IRQ_AUTO)
-	    instance->irq = overrides[current_override].irq;
-	else 
-	    instance->irq = NCR5380_probe_irq(instance, 0xffff);
+		instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
 
-	if (instance->irq != IRQ_NONE) 
-	    if (request_irq(instance->irq, do_generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) {
-		printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
-		    instance->host_no, instance->irq);
-		instance->irq = IRQ_NONE;
-	    } 
+		NCR5380_init(instance, flags);
 
-	if (instance->irq == IRQ_NONE) {
-	    printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
-	    printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
-	}
+		if (overrides[current_override].irq != IRQ_AUTO)
+			instance->irq = overrides[current_override].irq;
+		else
+			instance->irq = NCR5380_probe_irq(instance, 0xffff);
+
+		if (instance->irq != IRQ_NONE)
+			if (request_irq(instance->irq, do_generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) {
+				printk("scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
+				instance->irq = IRQ_NONE;
+			}
+
+		if (instance->irq == IRQ_NONE) {
+			printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+			printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
+		}
 
-	printk("scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int)instance->NCR5380_instance_name);
-	if (instance->irq == IRQ_NONE)
-	    printk (" interrupts disabled");
-	else 
-	    printk (" irq %d", instance->irq);
-	printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
-	    CAN_QUEUE, CMD_PER_LUN, GENERIC_NCR5380_PUBLIC_RELEASE);
-	NCR5380_print_options(instance);
-	printk("\n");
+		printk("scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int) instance->NCR5380_instance_name);
+		if (instance->irq == IRQ_NONE)
+			printk(" interrupts disabled");
+		else
+			printk(" irq %d", instance->irq);
+		printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, GENERIC_NCR5380_PUBLIC_RELEASE);
+		NCR5380_print_options(instance);
+		printk("\n");
 
-	++current_override;
-	++count;
-    }
-    return count;
+		++current_override;
+		++count;
+	}
+	return count;
 }
 
-const char * generic_NCR5380_info (struct Scsi_Host* host) {
-    static const char string[]="Generic NCR5380/53C400 Driver";
-    return string;
+const char *generic_NCR5380_info(struct Scsi_Host *host)
+{
+	static const char string[] = "Generic NCR5380/53C400 Driver";
+	return string;
 }
 
-int generic_NCR5380_release_resources(struct Scsi_Host * instance)
+int generic_NCR5380_release_resources(struct Scsi_Host *instance)
 {
-    NCR5380_local_declare();
+	NCR5380_local_declare();
 
-    NCR5380_setup(instance);
+	NCR5380_setup(instance);
 
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-    release_region(instance->NCR5380_instance_name, NCR5380_region_size);
+	release_region(instance->NCR5380_instance_name, NCR5380_region_size);
 #else
-    release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size);
-#endif    
+	release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size);
+#endif
 
-    if (instance->irq != IRQ_NONE)
-	free_irq(instance->irq, NULL);
+	if (instance->irq != IRQ_NONE)
+		free_irq(instance->irq, NULL);
 
 	return 0;
 }
@@ -485,112 +486,109 @@
 
 int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
 {
-  int size = disk->capacity;
-  ip[0] = 64;
-  ip[1] = 32;
-  ip[2] = size >> 11;
-  return 0;
+	int size = disk->capacity;
+	ip[0] = 64;
+	ip[1] = 32;
+	ip[2] = size >> 11;
+	return 0;
 }
 #endif
 
 #if NCR53C400_PSEUDO_DMA
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,    int len)
+static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
 {
-    int blocks = len / 128;
-    int start = 0;
-    int bl;
+	int blocks = len / 128;
+	int start = 0;
+	int bl;
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-    int i;
-#endif 
+	int i;
+#endif
 
-    NCR5380_local_declare();
+	NCR5380_local_declare();
 
-    NCR5380_setup(instance);
+	NCR5380_setup(instance);
 
 #if (NDEBUG & NDEBUG_C400_PREAD)
-    printk("53C400r: About to read %d blocks for %d bytes\n", blocks, len);
+	printk("53C400r: About to read %d blocks for %d bytes\n", blocks, len);
 #endif
 
-    NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
-    NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
-    while (1) {
-    
+	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
+	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+	while (1) {
+
 #if (NDEBUG & NDEBUG_C400_PREAD)
-	printk("53C400r: %d blocks left\n", blocks);
+		printk("53C400r: %d blocks left\n", blocks);
 #endif
 
-	if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
 #if (NDEBUG & NDEBUG_C400_PREAD)
-	    if (blocks)
-		printk("53C400r: blocks still == %d\n", blocks);
-	    else
-		printk("53C400r: Exiting loop\n");
+			if (blocks)
+				printk("53C400r: blocks still == %d\n", blocks);
+			else
+				printk("53C400r: Exiting loop\n");
 #endif
-	    break;
-	}
-
+			break;
+		}
 #if 1
-	if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
-	    printk("53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
-	    return -1;
-	}
+		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+			printk("53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
+			return -1;
+		}
 #endif
 
 #if (NDEBUG & NDEBUG_C400_PREAD)
-	printk("53C400r: Waiting for buffer, bl=%d\n", bl);
+		printk("53C400r: Waiting for buffer, bl=%d\n", bl);
 #endif
 
-	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
-	    ;
+		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
 #if (NDEBUG & NDEBUG_C400_PREAD)
-	printk("53C400r: Transferring 128 bytes\n");
+		printk("53C400r: Transferring 128 bytes\n");
 #endif
 
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-	for (i=0; i<128; i++)
-	    dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
+		for (i = 0; i < 128; i++)
+			dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
 #else
-	/* implies CONFIG_SCSI_G_NCR5380_MEM */
-	isa_memcpy_fromio(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
+		/* implies CONFIG_SCSI_G_NCR5380_MEM */
+		isa_memcpy_fromio(dst + start, NCR53C400_host_buffer + NCR5380_map_name, 128);
 #endif
-	start+=128;
-	blocks--;
-    }
+		start += 128;
+		blocks--;
+	}
 
-    if (blocks) {
+	if (blocks) {
 #if (NDEBUG & NDEBUG_C400_PREAD)
-	printk("53C400r: EXTRA: Waiting for buffer\n");
+		printk("53C400r: EXTRA: Waiting for buffer\n");
 #endif
-	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
-	    ;
+		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
 
 #if (NDEBUG & NDEBUG_C400_PREAD)
-	printk("53C400r: Transferring EXTRA 128 bytes\n");
+		printk("53C400r: Transferring EXTRA 128 bytes\n");
 #endif
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-	for (i=0; i<128; i++)
-	    dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
+		for (i = 0; i < 128; i++)
+			dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
 #else
-	/* implies CONFIG_SCSI_G_NCR5380_MEM */
-	isa_memcpy_fromio(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
+		/* implies CONFIG_SCSI_G_NCR5380_MEM */
+		isa_memcpy_fromio(dst + start, NCR53C400_host_buffer + NCR5380_map_name, 128);
 #endif
-	start+=128;
-	blocks--;
-    }
+		start += 128;
+		blocks--;
+	}
 #if (NDEBUG & NDEBUG_C400_PREAD)
-    else
-	printk("53C400r: No EXTRA required\n");
+	else
+		printk("53C400r: No EXTRA required\n");
 #endif
 
 #if (NDEBUG & NDEBUG_C400_PREAD)
-    printk("53C400r: Final values: blocks=%d   start=%d\n", blocks, start);
+	printk("53C400r: Final values: blocks=%d   start=%d\n", blocks, start);
 #endif
 
-    if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
-	printk("53C400r: no 53C80 gated irq after transfer");
+	if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
+		printk("53C400r: no 53C80 gated irq after transfer");
 #if (NDEBUG & NDEBUG_C400_PREAD)
-    else
-	printk("53C400r: Got 53C80 interrupt and tried to clear it\n");
+	else
+		printk("53C400r: Got 53C80 interrupt and tried to clear it\n");
 #endif
 
 /* DON'T DO THIS - THEY NEVER ARRIVE!
@@ -599,299 +597,287 @@
 	;
 */
 
-    if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
-	printk("53C400r: no end dma signal\n");
+	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
+		printk("53C400r: no end dma signal\n");
 #if (NDEBUG & NDEBUG_C400_PREAD)
-    else
-	printk("53C400r: end dma as expected\n");
+	else
+		printk("53C400r: end dma as expected\n");
 #endif
 
-    NCR5380_write(MODE_REG, MR_BASE);
-    NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-    return 0;
+	NCR5380_write(MODE_REG, MR_BASE);
+	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+	return 0;
 }
-		
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,    int len)
+
+static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
 {
-    int blocks = len / 128;
-    int start = 0;
-    int i;
-    int bl;
-    NCR5380_local_declare();
+	int blocks = len / 128;
+	int start = 0;
+	int i;
+	int bl;
+	NCR5380_local_declare();
 
-    NCR5380_setup(instance);
+	NCR5380_setup(instance);
 
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-    printk("53C400w: About to write %d blocks for %d bytes\n", blocks, len);
+	printk("53C400w: About to write %d blocks for %d bytes\n", blocks, len);
 #endif
 
-    NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
-    NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
-    while (1) {
-	if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
-	    printk("53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
-	    return -1;
-	}
+	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
+	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+	while (1) {
+		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+			printk("53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
+			return -1;
+		}
 
-	if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-	    if (blocks)
-		printk("53C400w: exiting loop, blocks still == %d\n", blocks);
-	    else
-		printk("53C400w: exiting loop\n");
+			if (blocks)
+				printk("53C400w: exiting loop, blocks still == %d\n", blocks);
+			else
+				printk("53C400w: exiting loop\n");
 #endif
-	    break;
-	}
-
+			break;
+		}
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("53C400w: %d blocks left\n", blocks);
+		printk("53C400w: %d blocks left\n", blocks);
 
-	printk("53C400w: waiting for buffer, bl=%d\n", bl);
+		printk("53C400w: waiting for buffer, bl=%d\n", bl);
 #endif
-	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
-	    ;
+		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
 
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("53C400w: transferring 128 bytes\n");
+		printk("53C400w: transferring 128 bytes\n");
 #endif
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-	for (i=0; i<128; i++)
-	    NCR5380_write(C400_HOST_BUFFER, src[start+i]);
+		for (i = 0; i < 128; i++)
+			NCR5380_write(C400_HOST_BUFFER, src[start + i]);
 #else
-	/* implies CONFIG_SCSI_G_NCR5380_MEM */
-	isa_memcpy_toio(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
+		/* implies CONFIG_SCSI_G_NCR5380_MEM */
+		isa_memcpy_toio(NCR53C400_host_buffer + NCR5380_map_name, src + start, 128);
 #endif
-	start+=128;
-	blocks--;
-    }
-    if (blocks) {
+		start += 128;
+		blocks--;
+	}
+	if (blocks) {
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("53C400w: EXTRA waiting for buffer\n");
+		printk("53C400w: EXTRA waiting for buffer\n");
 #endif
-	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
-	    ;
+		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
 
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("53C400w: transferring EXTRA 128 bytes\n");
+		printk("53C400w: transferring EXTRA 128 bytes\n");
 #endif
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-	for (i=0; i<128; i++)
-	    NCR5380_write(C400_HOST_BUFFER, src[start+i]);
+		for (i = 0; i < 128; i++)
+			NCR5380_write(C400_HOST_BUFFER, src[start + i]);
 #else
-	/* implies CONFIG_SCSI_G_NCR5380_MEM */
-	isa_memcpy_toio(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
+		/* implies CONFIG_SCSI_G_NCR5380_MEM */
+		isa_memcpy_toio(NCR53C400_host_buffer + NCR5380_map_name, src + start, 128);
 #endif
-	start+=128;
-	blocks--;
-    }
+		start += 128;
+		blocks--;
+	}
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-    else
-	printk("53C400w: No EXTRA required\n");
+	else
+		printk("53C400w: No EXTRA required\n");
 #endif
-    
+
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-    printk("53C400w: Final values: blocks=%d   start=%d\n", blocks, start);
+	printk("53C400w: Final values: blocks=%d   start=%d\n", blocks, start);
 #endif
 
 #if 0
-    printk("53C400w: waiting for registers to be available\n");
-    THEY NEVER DO!
-    while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
-	;
-    printk("53C400w: Got em\n");
+	printk("53C400w: waiting for registers to be available\n");
+	THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG);
+	printk("53C400w: Got em\n");
 #endif
 
-    /* Let's wait for this instead - could be ugly */
-    /* All documentation says to check for this. Maybe my hardware is too
-     * fast. Waiting for it seems to work fine! KLL
-     */
-    while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
-	;
+	/* Let's wait for this instead - could be ugly */
+	/* All documentation says to check for this. Maybe my hardware is too
+	 * fast. Waiting for it seems to work fine! KLL
+	 */
+	while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ));
 
-    /*
-     * I know. i is certainly != 0 here but the loop is new. See previous
-     * comment.
-     */
-    if (i) {
+	/*
+	 * I know. i is certainly != 0 here but the loop is new. See previous
+	 * comment.
+	 */
+	if (i) {
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("53C400w: got 53C80 gated irq (last block)\n");
+		printk("53C400w: got 53C80 gated irq (last block)\n");
 #endif
-	if (!((i=NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
-	    printk("53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n",i);
+		if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
+			printk("53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-	else
-	    printk("53C400w: Got END OF DMA\n");
+		else
+			printk("53C400w: Got END OF DMA\n");
 #endif
-    }
-    else
-	printk("53C400w: no 53C80 gated irq after transfer (last block)\n");
+	} else
+		printk("53C400w: no 53C80 gated irq after transfer (last block)\n");
 
 #if 0
-    if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
-	printk("53C400w: no end dma signal\n");
-    }
+	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
+		printk("53C400w: no end dma signal\n");
+	}
 #endif
 
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-    printk("53C400w: waiting for last byte...\n");
+	printk("53C400w: waiting for last byte...\n");
 #endif
-    while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
-    	;
+	while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
 
 #if (NDEBUG & NDEBUG_C400_PWRITE)
-    printk("53C400w:     got last byte.\n");
-    printk("53C400w: pwrite exiting with status 0, whoopee!\n");
+	printk("53C400w:     got last byte.\n");
+	printk("53C400w: pwrite exiting with status 0, whoopee!\n");
 #endif
-    return 0;
+	return 0;
 }
-#endif /* PSEUDO_DMA */
+#endif				/* PSEUDO_DMA */
 
 #include "NCR5380.c"
 
 #define PRINTP(x) len += sprintf(buffer+len, x)
 #define ANDP ,
 
-static int sprint_opcode(char* buffer, int len, int opcode) {
-    int start = len;
-    PRINTP("0x%02x " ANDP opcode);
-    return len-start;
-}
-
-static int sprint_command (char* buffer, int len, unsigned char *command) {
-    int i,s,start=len;
-    len += sprint_opcode(buffer, len, command[0]);
-    for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-	PRINTP("%02x " ANDP command[i]);
-    PRINTP("\n");
-    return len-start;
-}
-
-static int sprint_Scsi_Cmnd (char* buffer, int len, Scsi_Cmnd *cmd) {
-    int start = len;
-    PRINTP("host number %d destination target %d, lun %d\n" ANDP
-       cmd->host->host_no ANDP
-       cmd->target ANDP
-       cmd->lun);
-    PRINTP("        command = ");
-    len += sprint_command (buffer, len, cmd->cmnd);
-    return len-start;
-}
-
-int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout)
-{
-    int len = 0;
-    NCR5380_local_declare();
-    unsigned long flags;
-    unsigned char status;
-    int i;
-    struct Scsi_Host *scsi_ptr;
-    Scsi_Cmnd *ptr;
-    struct NCR5380_hostdata *hostdata;
+static int sprint_opcode(char *buffer, int len, int opcode)
+{
+	int start = len;
+	PRINTP("0x%02x " ANDP opcode);
+	return len - start;
+}
+
+static int sprint_command(char *buffer, int len, unsigned char *command)
+{
+	int i, s, start = len;
+	len += sprint_opcode(buffer, len, command[0]);
+	for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
+		PRINTP("%02x " ANDP command[i]);
+	PRINTP("\n");
+	return len - start;
+}
+
+static int sprint_Scsi_Cmnd(char *buffer, int len, Scsi_Cmnd * cmd)
+{
+	int start = len;
+	PRINTP("host number %d destination target %d, lun %d\n" ANDP cmd->host->host_no ANDP cmd->target ANDP cmd->lun);
+	PRINTP("        command = ");
+	len += sprint_command(buffer, len, cmd->cmnd);
+	return len - start;
+}
+
+int generic_NCR5380_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
+{
+	int len = 0;
+	NCR5380_local_declare();
+	unsigned long flags;
+	unsigned char status;
+	int i;
+	struct Scsi_Host *scsi_ptr;
+	Scsi_Cmnd *ptr;
+	struct NCR5380_hostdata *hostdata;
 #ifdef NCR5380_STATS
-    Scsi_Device *dev;
-    extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
+	Scsi_Device *dev;
+	extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
 #endif
-    save_flags(flags);
-    cli();
+	save_flags(flags);
+	cli();
 
-    for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next)
-	if (scsi_ptr->host_no == hostno)
-	    break;
-    NCR5380_setup(scsi_ptr);
-    hostdata = (struct NCR5380_hostdata *)scsi_ptr->hostdata;
-
-    PRINTP("SCSI host number %d : %s\n" ANDP scsi_ptr->host_no ANDP scsi_ptr->hostt->name);
-    PRINTP("Generic NCR5380 driver version %d\n" ANDP GENERIC_NCR5380_PUBLIC_RELEASE);
-    PRINTP("NCR5380 core version %d\n" ANDP NCR5380_PUBLIC_RELEASE);
+	for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr = scsi_ptr->next)
+		if (scsi_ptr->host_no == hostno)
+			break;
+	NCR5380_setup(scsi_ptr);
+	hostdata = (struct NCR5380_hostdata *) scsi_ptr->hostdata;
+
+	PRINTP("SCSI host number %d : %s\n" ANDP scsi_ptr->host_no ANDP scsi_ptr->hostt->name);
+	PRINTP("Generic NCR5380 driver version %d\n" ANDP GENERIC_NCR5380_PUBLIC_RELEASE);
+	PRINTP("NCR5380 core version %d\n" ANDP NCR5380_PUBLIC_RELEASE);
 #ifdef NCR53C400
-    PRINTP("NCR53C400 extension version %d\n" ANDP NCR53C400_PUBLIC_RELEASE);
-    PRINTP("NCR53C400 card%s detected\n" ANDP  (((struct NCR5380_hostdata *)scsi_ptr->hostdata)->flags & FLAG_NCR53C400)?"":" not");
+	PRINTP("NCR53C400 extension version %d\n" ANDP NCR53C400_PUBLIC_RELEASE);
+	PRINTP("NCR53C400 card%s detected\n" ANDP(((struct NCR5380_hostdata *) scsi_ptr->hostdata)->flags & FLAG_NCR53C400) ? "" : " not");
 # if NCR53C400_PSEUDO_DMA
-    PRINTP("NCR53C400 pseudo DMA used\n");
+	PRINTP("NCR53C400 pseudo DMA used\n");
 # endif
 #else
-    PRINTP("NO NCR53C400 driver extensions\n");
+	PRINTP("NO NCR53C400 driver extensions\n");
 #endif
-    PRINTP("Using %s mapping at %s 0x%lx, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name);
-    if (scsi_ptr->irq == IRQ_NONE)
-	PRINTP("no interrupt\n");
-    else
-	PRINTP("on interrupt %d\n" ANDP scsi_ptr->irq);
+	PRINTP("Using %s mapping at %s 0x%lx, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name);
+	if (scsi_ptr->irq == IRQ_NONE)
+		PRINTP("no interrupt\n");
+	else
+		PRINTP("on interrupt %d\n" ANDP scsi_ptr->irq);
 
 #ifdef NCR5380_STATS
-    if (hostdata->connected || hostdata->issue_queue || hostdata->disconnected_queue)
-	PRINTP("There are commands pending, transfer rates may be crud\n");
-    if (hostdata->pendingr)
-	PRINTP("  %d pending reads" ANDP hostdata->pendingr);
-    if (hostdata->pendingw)
-	PRINTP("  %d pending writes" ANDP hostdata->pendingw);
-    if (hostdata->pendingr || hostdata->pendingw)
-	PRINTP("\n");
-    for (dev = scsi_ptr->host_queue; dev; dev=dev->next) {
-	    unsigned long br = hostdata->bytes_read[dev->id];
-	    unsigned long bw = hostdata->bytes_write[dev->id];
-	    long tr = hostdata->time_read[dev->id] / HZ;
-	    long tw = hostdata->time_write[dev->id] / HZ;
-
-	    PRINTP("  T:%d %s " ANDP dev->id ANDP (dev->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(int)dev->type] : "Unknown");
-	    for (i=0; i<8; i++)
-		if (dev->vendor[i] >= 0x20)
-		    *(buffer+(len++)) = dev->vendor[i];
-	    *(buffer+(len++)) = ' ';
-	    for (i=0; i<16; i++)
-		if (dev->model[i] >= 0x20)
-		    *(buffer+(len++)) = dev->model[i];
-	    *(buffer+(len++)) = ' ';
-	    for (i=0; i<4; i++)
-		if (dev->rev[i] >= 0x20)
-		    *(buffer+(len++)) = dev->rev[i];
-	    *(buffer+(len++)) = ' ';
-				    
-	    PRINTP("\n%10ld kb read    in %5ld secs" ANDP br/1024 ANDP tr);
-	    if (tr)
-		PRINTP(" @ %5ld bps" ANDP br / tr); 
-
-	    PRINTP("\n%10ld kb written in %5ld secs" ANDP bw/1024 ANDP tw);
-	    if (tw)
-		PRINTP(" @ %5ld bps" ANDP bw / tw); 
-	    PRINTP("\n");
-    }
-#endif
-	
-    status = NCR5380_read(STATUS_REG);
-    if (!(status & SR_REQ))
-	PRINTP("REQ not asserted, phase unknown.\n");
-    else {
-	for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
-		    (phases[i].value != (status & PHASE_MASK)); ++i)
-	    ;
-	PRINTP("Phase %s\n" ANDP phases[i].name);
-    }
-
-    if (!hostdata->connected) {
-	PRINTP("No currently connected command\n");
-    } else {
-	len += sprint_Scsi_Cmnd (buffer, len, (Scsi_Cmnd *) hostdata->connected);
-    }
-
-    PRINTP("issue_queue\n");
-
-    for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr;
-		ptr = (Scsi_Cmnd *) ptr->host_scribble)
-	len += sprint_Scsi_Cmnd (buffer, len, ptr);
-
-    PRINTP("disconnected_queue\n");
-
-    for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
-		ptr = (Scsi_Cmnd *) ptr->host_scribble)
-	len += sprint_Scsi_Cmnd (buffer, len, ptr);
-	
-    *start = buffer + offset;
-    len -= offset;
-    if (len > length)
-	    len = length;
-    restore_flags(flags);
-    return len;
+	if (hostdata->connected || hostdata->issue_queue || hostdata->disconnected_queue)
+		PRINTP("There are commands pending, transfer rates may be crud\n");
+	if (hostdata->pendingr)
+		PRINTP("  %d pending reads" ANDP hostdata->pendingr);
+	if (hostdata->pendingw)
+		PRINTP("  %d pending writes" ANDP hostdata->pendingw);
+	if (hostdata->pendingr || hostdata->pendingw)
+		PRINTP("\n");
+	for (dev = scsi_ptr->host_queue; dev; dev = dev->next) {
+		unsigned long br = hostdata->bytes_read[dev->id];
+		unsigned long bw = hostdata->bytes_write[dev->id];
+		long tr = hostdata->time_read[dev->id] / HZ;
+		long tw = hostdata->time_write[dev->id] / HZ;
+
+		PRINTP("  T:%d %s " ANDP dev->id ANDP(dev->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(int) dev->type] : "Unknown");
+		for (i = 0; i < 8; i++)
+			if (dev->vendor[i] >= 0x20)
+				*(buffer + (len++)) = dev->vendor[i];
+		*(buffer + (len++)) = ' ';
+		for (i = 0; i < 16; i++)
+			if (dev->model[i] >= 0x20)
+				*(buffer + (len++)) = dev->model[i];
+		*(buffer + (len++)) = ' ';
+		for (i = 0; i < 4; i++)
+			if (dev->rev[i] >= 0x20)
+				*(buffer + (len++)) = dev->rev[i];
+		*(buffer + (len++)) = ' ';
+
+		PRINTP("\n%10ld kb read    in %5ld secs" ANDP br / 1024 ANDP tr);
+		if (tr)
+			PRINTP(" @ %5ld bps" ANDP br / tr);
+
+		PRINTP("\n%10ld kb written in %5ld secs" ANDP bw / 1024 ANDP tw);
+		if (tw)
+			PRINTP(" @ %5ld bps" ANDP bw / tw);
+		PRINTP("\n");
+	}
+#endif
+
+	status = NCR5380_read(STATUS_REG);
+	if (!(status & SR_REQ))
+		PRINTP("REQ not asserted, phase unknown.\n");
+	else {
+		for (i = 0; (phases[i].value != PHASE_UNKNOWN) && (phases[i].value != (status & PHASE_MASK)); ++i);
+		PRINTP("Phase %s\n" ANDP phases[i].name);
+	}
+
+	if (!hostdata->connected) {
+		PRINTP("No currently connected command\n");
+	} else {
+		len += sprint_Scsi_Cmnd(buffer, len, (Scsi_Cmnd *) hostdata->connected);
+	}
+
+	PRINTP("issue_queue\n");
+
+	for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
+		len += sprint_Scsi_Cmnd(buffer, len, ptr);
+
+	PRINTP("disconnected_queue\n");
+
+	for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
+		len += sprint_Scsi_Cmnd(buffer, len, ptr);
+
+	*start = buffer + offset;
+	len -= offset;
+	if (len > length)
+		len = length;
+	restore_flags(flags);
+	return len;
 }
 
 #undef PRINTP
@@ -903,7 +889,7 @@
 #include <linux/module.h>
 #include "scsi_module.c"
 
-#ifdef MODULE 
+#ifdef MODULE
 
 MODULE_PARM(ncr_irq, "i");
 MODULE_PARM(ncr_dma, "i");
@@ -917,42 +903,42 @@
 
 static int __init do_NCR5380_setup(char *str)
 {
-        int ints[10];
+	int ints[10];
 
-        get_options(str, sizeof(ints)/sizeof(int), ints);
-        generic_NCR5380_setup(str,ints);
+	get_options(str, sizeof(ints) / sizeof(int), ints);
+	generic_NCR5380_setup(str, ints);
 
-        return 1;
+	return 1;
 }
 
 static int __init do_NCR53C400_setup(char *str)
 {
-        int ints[10];
+	int ints[10];
 
-        get_options(str, sizeof(ints)/sizeof(int), ints);
-        generic_NCR53C400_setup(str,ints);
+	get_options(str, sizeof(ints) / sizeof(int), ints);
+	generic_NCR53C400_setup(str, ints);
 
-        return 1;
+	return 1;
 }
 
 static int __init do_NCR53C400A_setup(char *str)
 {
-        int ints[10];
+	int ints[10];
 
-        get_options(str, sizeof(ints)/sizeof(int), ints);
-        generic_NCR53C400A_setup(str,ints);
+	get_options(str, sizeof(ints) / sizeof(int), ints);
+	generic_NCR53C400A_setup(str, ints);
 
-        return 1;
+	return 1;
 }
 
 static int __init do_DTC3181E_setup(char *str)
 {
-        int ints[10];
+	int ints[10];
 
-        get_options(str, sizeof(ints)/sizeof(int), ints);
-        generic_DTC3181E_setup(str,ints);
+	get_options(str, sizeof(ints) / sizeof(int), ints);
+	generic_DTC3181E_setup(str, ints);
 
-        return 1;
+	return 1;
 }
 
 __setup("ncr5380=", do_NCR5380_setup);
@@ -962,10 +948,9 @@
 
 static struct isapnp_device_id id_table[] __devinitdata = {
 	{
-		ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('D','T','C'), ISAPNP_FUNCTION(0x436e), 
-		0
-	},
+	 ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+	 ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e),
+	 0},
 	{0}
 };
 
@@ -974,4 +959,3 @@
 
 
 #endif
-
diff -urN linux-2.4.17-pre4/drivers/scsi/g_NCR5380.h linux/drivers/scsi/g_NCR5380.h
--- linux-2.4.17-pre4/drivers/scsi/g_NCR5380.h	Thu Jul 19 21:08:20 2001
+++ linux/drivers/scsi/g_NCR5380.h	Thu Dec  6 10:53:04 2001
@@ -47,16 +47,15 @@
 int generic_NCR5380_abort(Scsi_Cmnd *);
 int generic_NCR5380_detect(Scsi_Host_Template *);
 int generic_NCR5380_release_resources(struct Scsi_Host *);
-int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 int generic_NCR5380_reset(Scsi_Cmnd *, unsigned int);
-int notyet_generic_proc_info (char *buffer ,char **start, off_t offset,
-                     int length, int hostno, int inout);
-const char* generic_NCR5380_info(struct Scsi_Host *);
+int notyet_generic_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout);
+const char *generic_NCR5380_info(struct Scsi_Host *);
 #ifdef BIOSPARAM
 int generic_NCR5380_biosparam(Disk *, kdev_t, int *);
 #endif
 
-int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout);
+int generic_NCR5380_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout);
 
 #ifndef NULL
 #define NULL 0
@@ -114,7 +113,7 @@
 #define NCR5380_read(reg) (inb(NCR5380_map_name + (reg)))
 #define NCR5380_write(reg, value) (outb((value), (NCR5380_map_name + (reg))))
 
-#else 
+#else
 /* therefore CONFIG_SCSI_G_NCR5380_MEM */
 
 #define NCR5380_map_config memory
@@ -164,7 +163,6 @@
 #define BOARD_NCR53C400A 2
 #define BOARD_DTC3181E	3
 
-#endif /* else def HOSTS_C */
-#endif /* ndef ASM */
-#endif /* GENERIC_NCR5380_H */
-
+#endif				/* else def HOSTS_C */
+#endif				/* ndef ASM */
+#endif				/* GENERIC_NCR5380_H */
diff -urN linux-2.4.17-pre4/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
--- linux-2.4.17-pre4/drivers/scsi/ncr53c8xx.c	Sun Sep 30 12:26:07 2001
+++ linux/drivers/scsi/ncr53c8xx.c	Thu Dec  6 10:53:04 2001
@@ -22,7 +22,7 @@
 **  This driver has been ported to Linux from the FreeBSD NCR53C8XX driver
 **  and is currently maintained by
 **
-**          Gerard Roudier              <groudier@club-internet.fr>
+**          Gerard Roudier              <groudier@free.fr>
 **
 **  Being given that this driver originates from the FreeBSD version, and
 **  in order to keep synergy on both, any suggested enhancements and corrections
@@ -63,7 +63,7 @@
 **  August 18 1997 by Cort <cort@cs.nmt.edu>:
 **     Support for Power/PC (Big Endian).
 **
-**  June 20 1998 by Gerard Roudier <groudier@club-internet.fr>:
+**  June 20 1998 by Gerard Roudier
 **     Support for up to 64 tags per lun.
 **     O(1) everywhere (C and SCRIPTS) for normal cases.
 **     Low PCI traffic for command handling when on-chip RAM is present.
diff -urN linux-2.4.17-pre4/drivers/scsi/ncr53c8xx.h linux/drivers/scsi/ncr53c8xx.h
--- linux-2.4.17-pre4/drivers/scsi/ncr53c8xx.h	Tue Mar  6 19:34:25 2001
+++ linux/drivers/scsi/ncr53c8xx.h	Thu Dec  6 10:53:04 2001
@@ -22,7 +22,7 @@
 **  This driver has been ported to Linux from the FreeBSD NCR53C8XX driver
 **  and is currently maintained by
 **
-**          Gerard Roudier              <groudier@club-internet.fr>
+**          Gerard Roudier              <groudier@free.fr>
 **
 **  Being given that this driver originates from the FreeBSD version, and
 **  in order to keep synergy on both, any suggested enhancements and corrections
diff -urN linux-2.4.17-pre4/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- linux-2.4.17-pre4/drivers/scsi/scsi.c	Fri Nov  9 14:05:06 2001
+++ linux/drivers/scsi/scsi.c	Thu Dec  6 10:53:04 2001
@@ -769,11 +769,13 @@
  		  int timeout, int retries)
 {
 	DECLARE_COMPLETION(wait);
+	request_queue_t *q = &SRpnt->sr_device->request_queue;
 	
 	SRpnt->sr_request.waiting = &wait;
 	SRpnt->sr_request.rq_status = RQ_SCSI_BUSY;
 	scsi_do_req (SRpnt, (void *) cmnd,
 		buffer, bufflen, scsi_wait_done, timeout, retries);
+	generic_unplug_device(q);
 	wait_for_completion(&wait);
 	SRpnt->sr_request.waiting = NULL;
 	if( SRpnt->sr_command != NULL )
diff -urN linux-2.4.17-pre4/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- linux-2.4.17-pre4/drivers/scsi/scsi_scan.c	Tue Nov 13 17:35:16 2001
+++ linux/drivers/scsi/scsi_scan.c	Thu Dec  6 10:53:04 2001
@@ -155,6 +155,7 @@
 	{"EMC", "SYMMETRIX", "*", BLIST_SPARSELUN},
 	{"CMD", "CRA-7280", "*", BLIST_SPARSELUN},   // CMD RAID Controller
 	{"CNSI", "G7324", "*", BLIST_SPARSELUN},     // Chaparral G7324 RAID
+	{"CNSi", "G8324", "*", BLIST_SPARSELUN},     // Chaparral G8324 RAID
 	{"Zzyzx", "RocketStor 500S", "*", BLIST_SPARSELUN},
 	{"Zzyzx", "RocketStor 2000", "*", BLIST_SPARSELUN},
 	{"SONY", "TSL",       "*", BLIST_FORCELUN},  // DDS3 & DDS4 autoloaders
@@ -500,6 +501,7 @@
 	Scsi_Request * SRpnt;
 	int bflags, type = -1;
 	extern devfs_handle_t scsi_devfs_handle;
+	int scsi_level;
 
 	SDpnt->host = shpnt;
 	SDpnt->id = dev;
@@ -672,6 +674,7 @@
 	    (SDpnt->scsi_level == 1 &&
 	     (scsi_result[3] & 0x0f) == 1))
 		SDpnt->scsi_level++;
+	scsi_level = SDpnt->scsi_level;
 
 	/*
 	 * Accommodate drivers that want to sleep when they should be in a polling
@@ -749,6 +752,7 @@
 	SDpnt->queue_depth = 1;
 	SDpnt->host = shpnt;
 	SDpnt->online = TRUE;
+	SDpnt->scsi_level = scsi_level;
 
 	/*
 	 * Register the queue for the device.  All I/O requests will come
diff -urN linux-2.4.17-pre4/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- linux-2.4.17-pre4/drivers/scsi/sg.c	Sun Nov  4 09:31:57 2001
+++ linux/drivers/scsi/sg.c	Thu Dec  6 10:53:04 2001
@@ -19,9 +19,9 @@
  */
 #include <linux/config.h>
 #ifdef CONFIG_PROC_FS
- static char sg_version_str[] = "Version: 3.1.20 (20010814)";
+ static char sg_version_str[] = "Version: 3.1.22 (20011128)";
 #endif
- static int sg_version_num = 30120; /* 2 digits for each component */
+ static int sg_version_num = 30122; /* 2 digits for each component */
 /*
  *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
  *      - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -82,6 +82,8 @@
 #include <linux/iobuf.h>
 #endif
 
+#define SG_NEW_KIOVEC 0	/* use alloc_kiovec(), not alloc_kiovec_sz() */
+
 int sg_big_buff = SG_DEF_RESERVED_SIZE;
 /* N.B. This variable is readable and writeable via
    /proc/scsi/sg/def_reserved_size . Each time sg_open() is called a buffer
@@ -135,10 +137,10 @@
 typedef struct sg_scatter_hold  /* holding area for scsi scatter gather info */
 {
     unsigned short k_use_sg;    /* Count of kernel scatter-gather pieces */
-    unsigned short sglist_len;  /* size of malloc'd scatter-gather list */
+    unsigned short sglist_len;  /* size of malloc'd scatter-gather list ++ */
     unsigned bufflen;           /* Size of (aggregate) data buffer */
     unsigned b_malloc_len;      /* actual len malloc'ed in buffer */
-    void * buffer;              /* Data buffer or scatter list,12 bytes each*/
+    void * buffer;              /* Data buffer or scatter list + mem_src_arr */
     struct kiobuf * kiobp;      /* for direct IO information */
     char mapped;                /* indicates kiobp has locked pages */
     char buffer_mem_src;        /* heap whereabouts of 'buffer' */
@@ -181,6 +183,7 @@
     char cmd_q;         /* 1 -> allow command queuing, 0 -> don't */
     char next_cmd_len;  /* 0 -> automatic (def), >0 -> use on next write() */
     char keep_orphan;   /* 0 -> drop orphan (def), 1 -> keep for read() */
+    char mmap_called;   /* 0 -> mmap() never called on this fd */
 } Sg_fd; /* 2760 bytes long on i386 */
 
 typedef struct sg_device /* holds the state of each scsi generic device */
@@ -202,7 +205,8 @@
 static int sg_start_req(Sg_request * srp);
 static void sg_finish_rem_req(Sg_request * srp);
 static int sg_build_indi(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size);
-static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp);
+static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
+			 int tablesize);
 static ssize_t sg_new_read(Sg_fd * sfp, char * buf, size_t count,
 			   Sg_request * srp);
 static ssize_t sg_new_write(Sg_fd * sfp, const char * buf, size_t count,
@@ -232,13 +236,14 @@
 static Sg_request * sg_add_request(Sg_fd * sfp);
 static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
 static int sg_res_in_use(Sg_fd * sfp);
-static void sg_clr_srpnt(Scsi_Request * SRpnt);
 static int sg_ms_to_jif(unsigned int msecs);
-static unsigned sg_jif_to_ms(int jifs);
+static inline unsigned sg_jif_to_ms(int jifs);
 static int sg_allow_access(unsigned char opcode, char dev_type);
 static int sg_build_dir(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
 static void sg_unmap_and(Sg_scatter_hold * schp, int free_also);
 static Sg_device * sg_get_dev(int dev);
+static inline int sg_alloc_kiovec(int nr, struct kiobuf **bufp, int *szp);
+static inline void sg_free_kiovec(int nr, struct kiobuf **bufp, int *szp);
 #ifdef CONFIG_PROC_FS
 static int sg_last_dev(void);
 #endif
@@ -617,6 +622,20 @@
 	sg_remove_request(sfp, srp);
 	return -ENOSYS;
     }
+    if (hp->flags & SG_FLAG_MMAP_IO) {
+    	if (hp->dxfer_len > sfp->reserve.bufflen) {
+	    sg_remove_request(sfp, srp);
+	    return -ENOMEM;	/* MMAP_IO size must fit in reserve buffer */
+	}
+	if (hp->flags & SG_FLAG_DIRECT_IO) {
+	    sg_remove_request(sfp, srp);
+	    return -EINVAL;	/* either MMAP_IO or DIRECT_IO (not both) */
+	}
+	if (sg_res_in_use(sfp)) {
+	    sg_remove_request(sfp, srp);
+	    return -EBUSY;	/* reserve buffer already being used */
+	}
+    }
     timeout = sg_ms_to_jif(srp->header.timeout);
     if ((! hp->cmdp) || (hp->cmd_len < 6) || (hp->cmd_len > sizeof(cmnd))) {
 	sg_remove_request(sfp, srp);
@@ -717,7 +736,9 @@
 		(void *)SRpnt->sr_buffer, hp->dxfer_len,
 		sg_cmd_done_bh, timeout, SG_DEFAULT_RETRIES);
     /* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,1)
     generic_unplug_device(q);
+#endif
     return 0;
 }
 
@@ -851,7 +872,7 @@
         result = get_user(val, (int *)arg);
         if (result) return result;
         if (val != sfp->reserve.bufflen) {
-            if (sg_res_in_use(sfp))
+            if (sg_res_in_use(sfp) || sfp->mmap_called)
                 return -EBUSY;
             sg_remove_scat(&sfp->reserve);
             sg_build_reserve(sfp, val);
@@ -1032,6 +1053,139 @@
     return (retval < 0) ? retval : 0;
 }
 
+static void sg_rb_correct4mmap(Sg_scatter_hold * rsv_schp, int startFinish)
+{
+    void * page_ptr;
+    struct page * page;
+    int k, m;
+
+    SCSI_LOG_TIMEOUT(3, printk("sg_rb_correct4mmap: startFinish=%d, "
+			   "scatg=%d\n", startFinish, rsv_schp->k_use_sg)); 
+    /* N.B. correction _not_ applied to base page of aech allocation */
+    if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
+        struct scatterlist * sclp = rsv_schp->buffer;
+
+        for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
+	    for (m = PAGE_SIZE; m < sclp->length; m += PAGE_SIZE) {
+		page_ptr = (unsigned char *)sclp->address + m;
+		page = virt_to_page(page_ptr);
+		if (startFinish)
+		    get_page(page);	/* increment page count */
+		else {
+		    if (page_count(page) > 0)
+			put_page_testzero(page); /* decrement page count */
+		}
+	    }
+        }
+    }
+    else { /* reserve buffer is just a single allocation */
+	for (m = PAGE_SIZE; m < rsv_schp->bufflen; m += PAGE_SIZE) {
+	    page_ptr = (unsigned char *)rsv_schp->buffer + m;
+	    page = virt_to_page(page_ptr);
+	    if (startFinish)
+		get_page(page);	/* increment page count */
+	    else {
+		if (page_count(page) > 0)
+		    put_page_testzero(page); /* decrement page count */
+	    }
+	}
+    }
+}
+
+static struct page * sg_vma_nopage(struct vm_area_struct *vma, 
+				   unsigned long addr, int unused)
+{
+    Sg_fd * sfp;
+    struct page * page = NOPAGE_SIGBUS;
+    void * page_ptr = NULL;
+    unsigned long offset;
+    Sg_scatter_hold * rsv_schp;
+
+    if ((NULL == vma) || (! (sfp = (Sg_fd *)vma->vm_private_data)))
+	return page;
+    rsv_schp = &sfp->reserve;
+    offset = addr - vma->vm_start;
+    if (offset >= rsv_schp->bufflen)
+	return page;
+    SCSI_LOG_TIMEOUT(3, printk("sg_vma_nopage: offset=%lu, scatg=%d\n", 
+			       offset, rsv_schp->k_use_sg));
+    if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
+        int k;
+        unsigned long sa = vma->vm_start;
+        unsigned long len;
+        struct scatterlist * sclp = rsv_schp->buffer;
+
+        for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
+             ++k, ++sclp) {
+            len = vma->vm_end - sa;
+            len = (len < sclp->length) ? len : sclp->length;
+	    if (offset < len) {
+		page_ptr = (unsigned char *)sclp->address + offset;
+		page = virt_to_page(page_ptr);
+		get_page(page);	/* increment page count */
+		break;
+	    }
+            sa += len;
+	    offset -= len;
+        }
+    }
+    else { /* reserve buffer is just a single allocation */
+        page_ptr = (unsigned char *)rsv_schp->buffer + offset;
+	page = virt_to_page(page_ptr);
+	get_page(page);	/* increment page count */
+    }
+    return page;
+}
+
+static struct vm_operations_struct sg_mmap_vm_ops = {
+    nopage : sg_vma_nopage,
+};
+
+static int sg_mmap(struct file * filp, struct vm_area_struct *vma)
+{
+    Sg_fd * sfp;
+    unsigned long req_sz = vma->vm_end - vma->vm_start;
+    Sg_scatter_hold * rsv_schp;
+
+    if ((! filp) || (! vma) || (! (sfp = (Sg_fd *)filp->private_data)))
+        return -ENXIO;
+    SCSI_LOG_TIMEOUT(3, printk("sg_mmap starting, vm_start=%p, len=%d\n", 
+			       (void *)vma->vm_start, (int)req_sz));
+    if (vma->vm_pgoff)
+    	return -EINVAL;		/* want no offset */
+    rsv_schp = &sfp->reserve;
+    if (req_sz > rsv_schp->bufflen)
+    	return -ENOMEM;		/* cannot map more than reserved buffer */
+
+    if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
+    	int k;
+	unsigned long sa = vma->vm_start;
+	unsigned long len;
+	struct scatterlist * sclp = rsv_schp->buffer;
+
+	for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end); 
+	     ++k, ++sclp) {
+	    if ((unsigned long)sclp->address & (PAGE_SIZE - 1))
+	    	return -EFAULT;     /* non page aligned memory ?? */
+	    len = vma->vm_end - sa;
+	    len = (len < sclp->length) ? len : sclp->length;
+	    sa += len;
+	}
+    }
+    else { /* reserve buffer is just a single allocation */
+    	if ((unsigned long)rsv_schp->buffer & (PAGE_SIZE - 1))
+	    return -EFAULT;	/* non page aligned memory ?? */
+    }
+    if (0 == sfp->mmap_called) {
+    	sg_rb_correct4mmap(rsv_schp, 1);  /* do only once per fd lifetime */
+	sfp->mmap_called = 1;
+    }
+    vma->vm_flags |= (VM_RESERVED | VM_IO);
+    vma->vm_private_data = sfp;
+    vma->vm_ops = &sg_mmap_vm_ops;
+    return 0;
+}
+
 /* This function is a "bottom half" handler that is called by the
  * mid level when a command is completed (or has failed). */
 static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
@@ -1078,7 +1232,14 @@
     srp->data.sglist_len = SRpnt->sr_sglist_len;
     srp->data.bufflen = SRpnt->sr_bufflen;
     srp->data.buffer = SRpnt->sr_buffer;
-    sg_clr_srpnt(SRpnt);
+    /* now clear out request structure */
+    SRpnt->sr_use_sg = 0;
+    SRpnt->sr_sglist_len = 0;
+    SRpnt->sr_bufflen = 0;
+    SRpnt->sr_buffer = NULL;
+    SRpnt->sr_underflow = 0;
+    SRpnt->sr_request.rq_dev = MKDEV(0, 0);  /* "sg" _disowns_ request blk */
+
     srp->my_cmdp = NULL;
     srp->done = 1;
     read_unlock(&sg_dev_arr_lock);
@@ -1154,6 +1315,7 @@
 	poll:		sg_poll,
 	ioctl:		sg_ioctl,
 	open:		sg_open,
+	mmap:		sg_mmap,
 	release:	sg_release,
 	fasync:		sg_fasync,
 };
@@ -1178,7 +1340,7 @@
     if(!sg_registered) {
 	if (devfs_register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))
         {
-            printk("Unable to get major %d for generic SCSI device\n",
+            printk(KERN_ERR "Unable to get major %d for generic SCSI device\n",
                    SCSI_GENERIC_MAJOR);
 	    write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
             return 1;
@@ -1191,7 +1353,7 @@
     sg_dev_arr = (Sg_device **)kmalloc(sg_template.dev_max * 
     					sizeof(Sg_device *), GFP_ATOMIC);
     if (NULL == sg_dev_arr) {
-        printk("sg_init: no space for sg_dev_arr\n");
+        printk(KERN_ERR "sg_init: no space for sg_dev_arr\n");
 	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
         return 1;
     }
@@ -1214,8 +1376,8 @@
 	    sg_big_buff = tmp;
 	return 1;
     } else {
-	printk("sg_def_reserved_size : usage sg_def_reserved_size=n "
-	       "(n could be 65536, 131072 or 262144)\n");
+	printk(KERN_WARNING "sg_def_reserved_size : usage "
+	    "sg_def_reserved_size=n (n could be 65536, 131072 or 262144)\n");
 	return 0;
     }
 }
@@ -1240,7 +1402,7 @@
 	if (NULL == tmp_da) {
 	    scsidp->attached--;
 	    write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
-	    printk("sg_attach: device array cannot be resized\n");
+	    printk(KERN_ERR "sg_attach: device array cannot be resized\n");
 	    return 1;
 	}
 	memset(tmp_da, 0, tmp_dev_max * sizeof(Sg_device *));
@@ -1255,7 +1417,7 @@
     if (k > MINORMASK) {
 	scsidp->attached--;
 	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
-	printk("Unable to attach sg device <%d, %d, %d, %d>"
+	printk(KERN_WARNING "Unable to attach sg device <%d, %d, %d, %d>"
 	       " type=%d, minor number exceed %d\n", scsidp->host->host_no, 
 	       scsidp->channel, scsidp->id, scsidp->lun, scsidp->type,
 	       MINORMASK);
@@ -1268,7 +1430,7 @@
     if (NULL == sdp) {
 	scsidp->attached--;
 	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
-	printk("sg_attach: Sg_device cannot be allocated\n");
+	printk(KERN_ERR "sg_attach: Sg_device cannot be allocated\n");
 	return 1;
     }
 
@@ -1295,8 +1457,8 @@
 	case TYPE_WORM:
 	case TYPE_TAPE: break;
 	default:
-	    printk("Attached scsi generic sg%d at scsi%d, channel %d, id %d,"
-		   " lun %d,  type %d\n", k, scsidp->host->host_no, 
+	    printk(KERN_NOTICE "Attached scsi generic sg%d at scsi%d, channel"
+	    	   " %d, id %d, lun %d,  type %d\n", k, scsidp->host->host_no, 
 		   scsidp->channel, scsidp->id, scsidp->lun, scsidp->type);
     }
     return 0;
@@ -1373,7 +1535,10 @@
 
 MODULE_AUTHOR("Douglas Gilbert");
 MODULE_DESCRIPTION("SCSI generic (sg) driver");
+
+#ifdef MODULE_LICENSE
 MODULE_LICENSE("GPL");
+#endif
 
 MODULE_PARM(def_reserved_size, "i");
 MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
@@ -1420,9 +1585,8 @@
 	if (res <= 0)   /* -ve -> error, 0 -> done, 1 -> try indirect */
 	    return res;
     }
-    if ((! sg_res_in_use(sfp)) && (dxfer_len <= rsv_schp->bufflen)) {
+    if ((! sg_res_in_use(sfp)) && (dxfer_len <= rsv_schp->bufflen))
 	sg_link_reserve(sfp, srp, dxfer_len);
-    }
     else {
 	res = sg_build_indi(req_schp, sfp, dxfer_len);
         if (res) {
@@ -1448,23 +1612,24 @@
     sg_remove_request(sfp, srp);
 }
 
-static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp)
+static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
+			 int tablesize)
 {
     int mem_src, ret_sz;
-    int sg_bufflen = PAGE_SIZE;
     int elem_sz = sizeof(struct scatterlist) + sizeof(char);
-    int mx_sc_elems = (sg_bufflen / elem_sz) - 1;
+    /* scatter gather array, followed by mem_src_arr (array of chars) */
+    int sg_bufflen = tablesize * elem_sz;
+    int mx_sc_elems = tablesize;
 
     mem_src = SG_HEAP_KMAL;
-    schp->buffer = (struct scatterlist *)sg_malloc(sfp, sg_bufflen,
-						   &ret_sz, &mem_src);
-    schp->buffer_mem_src = (char)mem_src;
+    schp->buffer = sg_malloc(sfp, sg_bufflen, &ret_sz, &mem_src);
     if (! schp->buffer)
 	return -ENOMEM;
     else if (ret_sz != sg_bufflen) {
 	sg_bufflen = ret_sz;
-	mx_sc_elems = (sg_bufflen / elem_sz) - 1;
+	mx_sc_elems = sg_bufflen / elem_sz;
     }
+    schp->buffer_mem_src = (char)mem_src;
     schp->sglist_len = sg_bufflen;
     memset(schp->buffer, 0, sg_bufflen);
     return mx_sc_elems; /* number of scat_gath elements allocated */
@@ -1473,13 +1638,15 @@
 static void sg_unmap_and(Sg_scatter_hold * schp, int free_also)
 {
 #ifdef SG_ALLOW_DIO_CODE
+    int nbhs = 0;
+
     if (schp && schp->kiobp) {
 	if (schp->mapped) {
 	    unmap_kiobuf(schp->kiobp);
 	    schp->mapped = 0;
 	}
 	if (free_also) {
-	    free_kiovec(1, &schp->kiobp);
+	    sg_free_kiovec(1, &schp->kiobp, &nbhs);
 	    schp->kiobp = NULL;
 	}
     }
@@ -1497,10 +1664,12 @@
     sg_io_hdr_t * hp = &srp->header;
     Sg_scatter_hold * schp = &srp->data;
     int sg_tablesize = sfp->parentdp->sg_tablesize;
+    int nbhs = 0;
 
-    res = alloc_kiovec(1, &schp->kiobp);
+    res = sg_alloc_kiovec(1, &schp->kiobp, &nbhs);
     if (0 != res) {
-	SCSI_LOG_TIMEOUT(5, printk("sg_build_dir: alloc_kiovec res=%d\n", res));
+	SCSI_LOG_TIMEOUT(5, printk("sg_build_dir: sg_alloc_kiovec res=%d\n", 
+			 res));
 	return 1;
     }
     res = map_user_kiobuf((SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0,
@@ -1530,7 +1699,7 @@
 	hp->info |= SG_INFO_DIRECT_IO;
 	return 0;
     }
-    mx_sc_elems = sg_build_sgat(schp, sfp);
+    mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
     if (mx_sc_elems <= 1) {
 	sg_unmap_and(schp, 1);
 	sg_remove_scat(schp);
@@ -1538,13 +1707,15 @@
     }
     mem_src_arr = schp->buffer + (mx_sc_elems * sizeof(struct scatterlist));
     for (k = 0, sclp = schp->buffer, rem_sz = dxfer_len;
-	 (k < sg_tablesize) && (rem_sz > 0) && (k < mx_sc_elems);
+	 (rem_sz > 0) && (k < mx_sc_elems);
 	 ++k, ++sclp) {
 	offset = (0 == k) ? kp->offset : 0;
 	num = (rem_sz > (PAGE_SIZE - offset)) ? (PAGE_SIZE - offset) :
 						rem_sz;
 	sclp->address = page_address(kp->maplist[k]) + offset;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
 	sclp->page = NULL;
+#endif
 	sclp->length = num;
 	mem_src_arr[k] = SG_USER_MEM;
 	rem_sz -= num;
@@ -1612,14 +1783,14 @@
 	char * mem_src_arr;
 
         /* N.B. ret_sz and mem_src carried into this block ... */
-	mx_sc_elems = sg_build_sgat(schp, sfp);
+	mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
 	if (mx_sc_elems < 0)
 	    return mx_sc_elems; /* most likely -ENOMEM */
 	mem_src_arr = schp->buffer +
 		      (mx_sc_elems * sizeof(struct scatterlist));
 
 	for (k = 0, sclp = schp->buffer, rem_sz = blk_size;
-	     (k < sg_tablesize) && (rem_sz > 0) && (k < mx_sc_elems);
+	     (rem_sz > 0) && (k < mx_sc_elems);
              ++k, rem_sz -= ret_sz, ++sclp) {
 	    if (first)
                 first = 0;
@@ -1631,7 +1802,9 @@
                     break;
             }
             sclp->address = p;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
 	    sclp->page = NULL;
+#endif
             sclp->length = ret_sz;
 	    mem_src_arr[k] = mem_src;
 
@@ -1667,7 +1840,8 @@
 	if (schp->bufflen < num_xfer)
 	    num_xfer = schp->bufflen;
     }
-    if ((num_xfer <= 0) || (new_interface && (SG_FLAG_NO_DXFER & hp->flags)))
+    if ((num_xfer <= 0) || 
+    	(new_interface && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
 	return 0;
 
     SCSI_LOG_TIMEOUT(4,
@@ -1769,7 +1943,7 @@
 static char * sg_get_sgat_msa(Sg_scatter_hold * schp)
 {
     int elem_sz = sizeof(struct scatterlist) + sizeof(char);
-    int mx_sc_elems = (schp->sglist_len / elem_sz) - 1;
+    int mx_sc_elems = schp->sglist_len / elem_sz;
     return schp->buffer + (sizeof(struct scatterlist) * mx_sc_elems);
 }
 
@@ -1789,7 +1963,9 @@
                        k, sclp->address, sclp->length, mem_src));
             sg_free(sclp->address, sclp->length, mem_src);
             sclp->address = NULL;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
 	    sclp->page = NULL;
+#endif
             sclp->length = 0;
         }
 	sg_free(schp->buffer, schp->sglist_len, schp->buffer_mem_src);
@@ -1817,7 +1993,8 @@
 	if (schp->bufflen < num_xfer)
 	    num_xfer = schp->bufflen;
     }
-    if ((num_xfer <= 0) || (new_interface && (SG_FLAG_NO_DXFER & hp->flags)))
+    if ((num_xfer <= 0) || 
+    	(new_interface && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
 	return 0;
 
     SCSI_LOG_TIMEOUT(4,
@@ -2192,6 +2369,8 @@
     if (sfp->reserve.bufflen > 0) {
     SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp:    bufflen=%d, k_use_sg=%d\n",
 	     (int)sfp->reserve.bufflen, (int)sfp->reserve.k_use_sg));
+	if (sfp->mmap_called)
+	    sg_rb_correct4mmap(&sfp->reserve, 0); /* undo correction */
 	sg_remove_scat(&sfp->reserve);
     }
     sfp->parentdp = NULL;
@@ -2240,7 +2419,7 @@
 	/* MOD_INC's to inhibit unloading sg and associated adapter driver */
 	if (sg_template.module)
 	    __MOD_INC_USE_COUNT(sg_template.module);
-	 if (sdp->device->host->hostt->module)
+	if (sdp->device->host->hostt->module)
 	    __MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
         SCSI_LOG_TIMEOUT(1, printk(
           "sg_remove_sfp: worrisome, %d writes pending\n", dirty));
@@ -2315,7 +2494,8 @@
         if (retSzp) *retSzp = resSz;
     }
     else
-        printk("sg_low_malloc: bad mem_src=%d, rqSz=%df\n", mem_src, rqSz);
+        printk(KERN_ERR "sg_low_malloc: bad mem_src=%d, rqSz=%df\n", 
+	       mem_src, rqSz);
     return resp;
 }
 
@@ -2350,7 +2530,7 @@
             if (resp && retSzp) *retSzp = size;
             break;
         case SG_HEAP_KMAL:
-            l_ms = SG_HEAP_PAGE;
+            l_ms = SG_HEAP_KMAL; /* was SG_HEAP_PAGE */
             resp = sg_low_malloc(size, low_dma, l_ms, 0);
             if (resp)
                 break;
@@ -2369,6 +2549,15 @@
     return resp;
 }
 
+static inline int sg_alloc_kiovec(int nr, struct kiobuf **bufp, int *szp)
+{
+#if SG_NEW_KIOVEC
+    return alloc_kiovec_sz(nr, bufp, szp);
+#else
+    return alloc_kiovec(nr, bufp);
+#endif
+}
+
 static void sg_low_free(char * buff, int size, int mem_src)
 {
     if (! buff) return;
@@ -2396,7 +2585,7 @@
     case SG_USER_MEM:
 	break; /* nothing to do */
     default:
-	printk("sg_low_free: bad mem_src=%d, buff=0x%p, rqSz=%d\n",
+	printk(KERN_ERR "sg_low_free: bad mem_src=%d, buff=0x%p, rqSz=%d\n",
                mem_src, buff, size);
 	break;
     }
@@ -2412,14 +2601,13 @@
         sg_low_free(buff, size, mem_src);
 }
 
-static void sg_clr_srpnt(Scsi_Request * SRpnt)
+static inline void sg_free_kiovec(int nr, struct kiobuf **bufp, int *szp)
 {
-    SRpnt->sr_use_sg = 0;
-    SRpnt->sr_sglist_len = 0;
-    SRpnt->sr_bufflen = 0;
-    SRpnt->sr_buffer = NULL;
-    SRpnt->sr_underflow = 0;
-    SRpnt->sr_request.rq_dev = MKDEV(0, 0);  /* "sg" _disowns_ command blk */
+#if SG_NEW_KIOVEC
+    free_kiovec_sz(nr, bufp, szp);
+#else
+    free_kiovec(nr, bufp);
+#endif
 }
 
 static int sg_ms_to_jif(unsigned int msecs)
@@ -2431,7 +2619,7 @@
 					       : (((int)msecs / 1000) * HZ);
 }
 
-static unsigned sg_jif_to_ms(int jifs)
+static inline unsigned sg_jif_to_ms(int jifs)
 {
     if (jifs <= 0)
 	return 0U;
@@ -2481,8 +2669,8 @@
     if (sg_dev_arr && (dev >= 0))
     {
 	read_lock_irqsave(&sg_dev_arr_lock, iflags);
-    if (dev < sg_template.dev_max)
-    	sdp = sg_dev_arr[dev];
+	if (dev < sg_template.dev_max)
+	    sdp = sg_dev_arr[dev];
 	read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
     }
     return sdp;
@@ -2675,7 +2863,7 @@
 {
     Sg_device * sdp;
     const sg_io_hdr_t * hp;
-    int j, max_dev;
+    int j, max_dev, new_interface;
 
     if (NULL == sg_dev_arr) {
 	PRINT_PROC("sg_dev_arr NULL, driver not initialized\n");
@@ -2722,8 +2910,10 @@
 			   (int)fp->keep_orphan, (int)fp->closed);
 		for (m = 0; (srp = sg_get_nth_request(fp, m)); ++m) {
 		    hp = &srp->header;
+		    new_interface = (hp->interface_id == '\0') ? 0 : 1;
 /* stop indenting so far ... */
-	PRINT_PROC(srp->res_used ? "     rb>> " :
+	PRINT_PROC(srp->res_used ? ((new_interface && 
+	    (SG_FLAG_MMAP_IO & hp->flags)) ? "     mmap>> " : "     rb>> ") :
 	    ((SG_INFO_DIRECT_IO_MASK & hp->info) ? "     dio>> " : "     "));
 	blen = srp->my_cmdp ? srp->my_cmdp->sr_bufflen : srp->data.bufflen;
 	usg = srp->my_cmdp ? srp->my_cmdp->sr_use_sg : srp->data.k_use_sg;
@@ -2733,8 +2923,8 @@
 	if (srp->done)
 	    PRINT_PROC(" dur=%d", hp->duration);
 	else
-	    PRINT_PROC(" t_o/elap=%d/%d", ((hp->interface_id == '\0') ?
-			sg_jif_to_ms(fp->timeout) : hp->timeout),
+	    PRINT_PROC(" t_o/elap=%d/%d", new_interface ? hp->timeout :
+			sg_jif_to_ms(fp->timeout),
 		  sg_jif_to_ms(hp->duration ? (jiffies - hp->duration) : 0));
 	PRINT_PROC("ms sgat=%d op=0x%02x\n", usg, (int)srp->data.cmd_opcode);
 /* reset indenting */
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx.c	Wed Oct 17 14:16:39 2001
+++ linux/drivers/scsi/sym53c8xx.c	Thu Dec  6 10:53:04 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
 **  High Performance device driver for the Symbios 53C896 controller.
 **
-**  Copyright (C) 1998-2000  Gerard Roudier <groudier@club-internet.fr>
+**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
 **
 **  This driver also supports all the Symbios 53C8XX controller family, 
 **  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
@@ -32,7 +32,7 @@
 **  The Linux port of the FreeBSD ncr driver has been achieved in 
 **  november 1995 by:
 **
-**          Gerard Roudier              <groudier@club-internet.fr>
+**          Gerard Roudier              <groudier@free.fr>
 **
 **  Being given that this driver originates from the FreeBSD version, and
 **  in order to keep synergy on both, any suggested enhancements and corrections
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx.h linux/drivers/scsi/sym53c8xx.h
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx.h	Thu Nov 22 11:49:48 2001
+++ linux/drivers/scsi/sym53c8xx.h	Thu Dec  6 10:53:04 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
 **  High Performance device driver for the Symbios 53C896 controller.
 **
-**  Copyright (C) 1998-2000  Gerard Roudier <groudier@club-internet.fr>
+**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
 **
 **  This driver also supports all the Symbios 53C8XX controller family, 
 **  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
@@ -32,7 +32,7 @@
 **  The Linux port of the FreeBSD ncr driver has been achieved in 
 **  november 1995 by:
 **
-**          Gerard Roudier              <groudier@club-internet.fr>
+**          Gerard Roudier              <groudier@free.fr>
 **
 **  Being given that this driver originates from the FreeBSD version, and
 **  in order to keep synergy on both, any suggested enhancements and corrections
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/ChangeLog.txt linux/drivers/scsi/sym53c8xx_2/ChangeLog.txt
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/ChangeLog.txt	Fri Nov  9 15:22:54 2001
+++ linux/drivers/scsi/sym53c8xx_2/ChangeLog.txt	Thu Dec  6 10:53:04 2001
@@ -128,3 +128,21 @@
 	* version sym-2.1.16-20011028
 	- Slightly simplify driver configuration.
 	- Prepare a new patch against linux-2.4.13.
+
+Sat Nov 17 10:00 2001 Gerard Roudier 
+	* version sym-2.1.17
+	- Fix a couple of gcc/gcc3 warnings.
+	- Allocate separately from the HCB the array for CCBs hashed by DSA.
+	  All driver memory allocations are now not greater than 1 PAGE 
+	  even on PPC64 / 4KB PAGE surprising setup.
+
+Sat Dec 01 18:00 2001 Gerard Roudier 
+	* version sym-2.1.17a
+	- Use u_long instead of U32 for the IO base cookie. This is more 
+	  consistent with what archs are expecting.
+	- Use MMIO per default for Power PC instead of some fake normal IO,
+	  as Paul Mackerras stated that MMIO works fine now on this arch.
+
+
+
+
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym53c8xx.h linux/drivers/scsi/sym53c8xx_2/sym53c8xx.h
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym53c8xx.h	Fri Nov  9 15:22:54 2001
+++ linux/drivers/scsi/sym53c8xx_2/sym53c8xx.h	Thu Dec  6 10:53:04 2001
@@ -130,17 +130,17 @@
 #if !defined(HOSTS_C)
 
 /*
- *  Use normal IO if configured. Forced for alpha and powerpc.
- *  Powerpc fails copying to on-chip RAM using memcpy_toio().
+ *  Use normal IO if configured.
+ *  Normal IO forced for alpha.
  *  Forced to MMIO for sparc.
  */
 #if defined(__alpha__)
 #define	SYM_CONF_IOMAPPED
-#elif defined(__powerpc__)
-#define	SYM_CONF_IOMAPPED
-#define SYM_OPT_NO_BUS_MEMORY_MAPPING
 #elif defined(__sparc__)
 #undef SYM_CONF_IOMAPPED
+/* #elif defined(__powerpc__) */
+/* #define	SYM_CONF_IOMAPPED */
+/* #define SYM_OPT_NO_BUS_MEMORY_MAPPING */
 #elif defined(CONFIG_SCSI_SYM53C8XX_IOMAPPED)
 #define	SYM_CONF_IOMAPPED
 #endif
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_glue.c linux/drivers/scsi/sym53c8xx_2/sym_glue.c
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_glue.c	Fri Nov  9 15:22:54 2001
+++ linux/drivers/scsi/sym53c8xx_2/sym_glue.c	Thu Dec  6 10:53:04 2001
@@ -2456,8 +2456,8 @@
 	u_char pci_fix_up = SYM_SETUP_PCI_FIX_UP;
 	u_char revision;
 	u_int irq;
-	u_long base, base_2, io_port; 
-	u_long base_c, base_2_c; 
+	u_long base, base_2, base_io; 
+	u_long base_c, base_2_c, io_port; 
 	int i;
 	sym_chip *chip;
 
@@ -2474,7 +2474,7 @@
 	device_id = PciDeviceId(pdev);
 	irq	  = PciIrqLine(pdev);
 
-	i = pci_get_base_address(pdev, 0, &io_port);
+	i = pci_get_base_address(pdev, 0, &base_io);
 	io_port = pci_get_base_cookie(pdev, 0);
 
 	base_c = pci_get_base_cookie(pdev, i);
@@ -2492,9 +2492,9 @@
 	/*
 	 *  If user excluded this chip, donnot initialize it.
 	 */
-	if (io_port) {
+	if (base_io) {
 		for (i = 0 ; i < 8 ; i++) {
-			if (sym_driver_setup.excludes[i] == io_port)
+			if (sym_driver_setup.excludes[i] == base_io)
 				return -1;
 		}
 	}
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_glue.h linux/drivers/scsi/sym53c8xx_2/sym_glue.h
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_glue.h	Thu Nov 22 10:41:14 2001
+++ linux/drivers/scsi/sym53c8xx_2/sym_glue.h	Thu Dec  6 10:53:04 2001
@@ -77,7 +77,6 @@
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/time.h>
@@ -463,7 +462,7 @@
 
 	vm_offset_t	mmio_va;	/* MMIO kernel virtual address	*/
 	vm_offset_t	ram_va;		/* RAM  kernel virtual address	*/
-	u32		io_port;	/* IO port address		*/
+	u_long		io_port;	/* IO port address cookie	*/
 	u_short		io_ws;		/* IO window size		*/
 	int		irq;		/* IRQ number			*/
 
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_hipd.c linux/drivers/scsi/sym53c8xx_2/sym_hipd.c
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_hipd.c	Fri Nov  9 15:22:54 2001
+++ linux/drivers/scsi/sym53c8xx_2/sym_hipd.c	Thu Dec  6 10:53:04 2001
@@ -50,7 +50,7 @@
  * SUCH DAMAGE.
  */
 
-#define SYM_DRIVER_NAME	"sym-2.1.16a"
+#define SYM_DRIVER_NAME	"sym-2.1.17a"
 
 #ifdef __FreeBSD__
 #include <dev/sym/sym_glue.h>
@@ -4691,6 +4691,7 @@
 	OUTL_DSP (SCRIPTA_BA (np, clrack));
 	return;
 out_stuck:
+	return;
 }
 
 /*
@@ -5226,6 +5227,7 @@
 
 	return;
 fail:
+	return;
 }
 
 /*
@@ -5788,6 +5790,13 @@
 		goto attach_failed;
 
 	/*
+	 *  Allocate the array of lists of CCBs hashed by DSA.
+	 */
+	np->ccbh = sym_calloc(sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH");
+	if (!np->ccbh)
+		goto attach_failed;
+
+	/*
 	 *  Initialyze the CCB free and busy queues.
 	 */
 	sym_que_init(&np->free_ccbq);
@@ -5978,6 +5987,8 @@
 			sym_mfree_dma(cp, sizeof(*cp), "CCB");
 		}
 	}
+	if (np->ccbh)
+		sym_mfree(np->ccbh, sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH");
 
 	if (np->badluntbl)
 		sym_mfree_dma(np->badluntbl, 256,"BADLUNTBL");
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_hipd.h linux/drivers/scsi/sym53c8xx_2/sym_hipd.h
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_hipd.h	Fri Nov  9 15:22:54 2001
+++ linux/drivers/scsi/sym53c8xx_2/sym_hipd.h	Thu Dec  6 10:53:04 2001
@@ -1068,7 +1068,8 @@
 	/*
 	 *  CCB lists and queue.
 	 */
-	ccb_p ccbh[CCB_HASH_SIZE];	/* CCB hashed by DSA value	*/
+	ccb_p *ccbh;			/* CCBs hashed by DSA value	*/
+					/* CCB_HASH_SIZE lists of CCBs	*/
 	SYM_QUEHEAD	free_ccbq;	/* Queue of available CCBs	*/
 	SYM_QUEHEAD	busy_ccbq;	/* Queue of busy CCBs		*/
 
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_nvram.c linux/drivers/scsi/sym53c8xx_2/sym_nvram.c
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx_2/sym_nvram.c	Fri Nov  9 15:22:54 2001
+++ linux/drivers/scsi/sym53c8xx_2/sym_nvram.c	Thu Dec  6 10:53:04 2001
@@ -505,10 +505,10 @@
 	return retv;
 }
 
-#undef SET_BIT 0
-#undef CLR_BIT 1
-#undef SET_CLK 2
-#undef CLR_CLK 3
+#undef SET_BIT
+#undef CLR_BIT
+#undef SET_CLK
+#undef CLR_CLK
 
 /*
  *  Try reading Symbios NVRAM.
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx_comm.h linux/drivers/scsi/sym53c8xx_comm.h
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx_comm.h	Fri Oct 12 15:35:54 2001
+++ linux/drivers/scsi/sym53c8xx_comm.h	Thu Dec  6 10:53:04 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
 **  High Performance device driver for the Symbios 53C896 controller.
 **
-**  Copyright (C) 1998-2000  Gerard Roudier <groudier@club-internet.fr>
+**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
 **
 **  This driver also supports all the Symbios 53C8XX controller family, 
 **  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
@@ -32,7 +32,7 @@
 **  The Linux port of the FreeBSD ncr driver has been achieved in 
 **  november 1995 by:
 **
-**          Gerard Roudier              <groudier@club-internet.fr>
+**          Gerard Roudier              <groudier@free.fr>
 **
 **  Being given that this driver originates from the FreeBSD version, and
 **  in order to keep synergy on both, any suggested enhancements and corrections
diff -urN linux-2.4.17-pre4/drivers/scsi/sym53c8xx_defs.h linux/drivers/scsi/sym53c8xx_defs.h
--- linux-2.4.17-pre4/drivers/scsi/sym53c8xx_defs.h	Thu Nov 22 11:49:36 2001
+++ linux/drivers/scsi/sym53c8xx_defs.h	Thu Dec  6 10:53:04 2001
@@ -1,7 +1,7 @@
 /******************************************************************************
 **  High Performance device driver for the Symbios 53C896 controller.
 **
-**  Copyright (C) 1998-2000  Gerard Roudier <groudier@club-internet.fr>
+**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
 **
 **  This driver also supports all the Symbios 53C8XX controller family, 
 **  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
@@ -32,7 +32,7 @@
 **  The Linux port of the FreeBSD ncr driver has been achieved in 
 **  november 1995 by:
 **
-**          Gerard Roudier              <groudier@club-internet.fr>
+**          Gerard Roudier              <groudier@free.fr>
 **
 **  Being given that this driver originates from the FreeBSD version, and
 **  in order to keep synergy on both, any suggested enhancements and corrections
diff -urN linux-2.4.17-pre4/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- linux-2.4.17-pre4/drivers/sound/ymfpci.c	Thu Dec  6 10:52:26 2001
+++ linux/drivers/sound/ymfpci.c	Thu Dec  6 10:53:04 2001
@@ -39,8 +39,6 @@
  *    native synthesizer through a playback slot.
  *  - Use new 2.3.x cache coherent PCI DMA routines instead of virt_to_bus.
  *  - Make the thing big endian compatible. ALSA has it done.
- *  - 2001/10/25 Since Civ:CTP forced redzone outside of pre-set fragments,
- *    all ioctls that report free space lie a little. Adjust their returns.
  *  - 2001/11/29 ac97_save_state
  */
 
@@ -158,7 +156,7 @@
 			schedule_timeout(1);
 		}
 	} while (end_time - (signed long)jiffies >= 0);
-	printk("ymfpci_codec_ready: codec %i is not ready [0x%x]\n",
+	printk(KERN_ERR "ymfpci_codec_ready: codec %i is not ready [0x%x]\n",
 	    secondary, ymfpci_readw(codec, reg));
 	return -EBUSY;
 }
@@ -407,7 +405,7 @@
 	dmabuf->ready = 1;
 
 #if 0
-	printk("prog_dmabuf: rate %d format 0x%x,"
+	printk(KERN_DEBUG "prog_dmabuf: rate %d format 0x%x,"
 	    " numfrag %d fragsize %d dmasize %d\n",
 	       state->format.rate, state->format.format, dmabuf->numfrag,
 	       dmabuf->fragsize, dmabuf->dmasize);
@@ -618,7 +616,7 @@
 		dmabuf->hwptr = pos;
 
 		if (dmabuf->count == 0) {
-			printk("ymfpci%d: %d: strain: hwptr %d\n",
+			printk(KERN_ERR "ymfpci%d: %d: strain: hwptr %d\n",
 			    codec->dev_audio, voice->number, dmabuf->hwptr);
 			ymf_playback_trigger(codec, ypcm, 0);
 		}
@@ -636,7 +634,7 @@
 				/*
 				 * Lost interrupt or other screwage.
 				 */
-				printk("ymfpci%d: %d: lost: delta %d"
+				printk(KERN_ERR "ymfpci%d: %d: lost: delta %d"
 				    " hwptr %d swptr %d distance %d count %d\n",
 				    codec->dev_audio, voice->number, delta,
 				    dmabuf->hwptr, swptr, distance, dmabuf->count);
@@ -644,10 +642,10 @@
 				/*
 				 * Normal end of DMA.
 				 */
-//				printk("ymfpci%d: %d: done: delta %d"
-//				    " hwptr %d swptr %d distance %d count %d\n",
-//				    codec->dev_audio, voice->number, delta,
-//				    dmabuf->hwptr, swptr, distance, dmabuf->count);
+				YMFDBGI("ymfpci%d: %d: done: delta %d"
+				    " hwptr %d swptr %d distance %d count %d\n",
+				    codec->dev_audio, voice->number, delta,
+				    dmabuf->hwptr, swptr, distance, dmabuf->count);
 			}
 			played = dmabuf->count;
 			if (ypcm->running) {
@@ -1511,6 +1509,7 @@
 	unsigned long flags;
 	audio_buf_info abinfo;
 	count_info cinfo;
+	int redzone;
 	int val;
 
 	switch (cmd) {
@@ -1734,9 +1733,12 @@
 		dmabuf = &state->wpcm.dmabuf;
 		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
 			return val;
+		redzone = ymf_calc_lend(state->format.rate);
+		redzone <<= state->format.shift;
+		redzone *= 3;
 		spin_lock_irqsave(&state->unit->reg_lock, flags);
 		abinfo.fragsize = dmabuf->fragsize;
-		abinfo.bytes = dmabuf->dmasize - dmabuf->count;
+		abinfo.bytes = dmabuf->dmasize - dmabuf->count - redzone;
 		abinfo.fragstotal = dmabuf->numfrag;
 		abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
 		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
@@ -1777,9 +1779,6 @@
 		cinfo.bytes = dmabuf->total_bytes;
 		cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
 		cinfo.ptr = dmabuf->hwptr;
-		/* XXX fishy - breaks invariant  count=hwptr-swptr */
-		if (dmabuf->mapped)
-			dmabuf->count &= dmabuf->fragsize-1;
 		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
 		YMFDBGX("ymf_ioctl: GETIPTR ptr %d bytes %d\n",
 		    cinfo.ptr, cinfo.bytes);
@@ -1794,9 +1793,6 @@
 		cinfo.bytes = dmabuf->total_bytes;
 		cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
 		cinfo.ptr = dmabuf->hwptr;
-		/* XXX fishy - breaks invariant  count=swptr-hwptr */
-		if (dmabuf->mapped)
-			dmabuf->count &= dmabuf->fragsize-1;
 		spin_unlock_irqrestore(&state->unit->reg_lock, flags);
 		YMFDBGX("ymf_ioctl: GETOPTR ptr %d bytes %d\n",
 		    cinfo.ptr, cinfo.bytes);
@@ -2393,7 +2389,7 @@
 	codec->codec_write = ymfpci_codec_write;
 
 	if (ac97_probe_codec(codec) == 0) {
-		printk("ymfpci: ac97_probe_codec failed\n");
+		printk(KERN_ERR "ymfpci: ac97_probe_codec failed\n");
 		goto out_kfree;
 	}
 
diff -urN linux-2.4.17-pre4/drivers/video/aty/atyfb_base.c linux/drivers/video/aty/atyfb_base.c
--- linux-2.4.17-pre4/drivers/video/aty/atyfb_base.c	Thu Dec  6 10:52:26 2001
+++ linux/drivers/video/aty/atyfb_base.c	Thu Dec  6 10:53:04 2001
@@ -274,8 +274,12 @@
 static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
 #endif
 
+#ifdef CONFIG_FB_ATY_GX
 static char m64n_gx[] __initdata = "mach64GX (ATI888GX00)";
 static char m64n_cx[] __initdata = "mach64CX (ATI888CX00)";
+#endif /* CONFIG_FB_ATY_GX */
+
+#ifdef CONFIG_FB_ATY_CT
 static char m64n_ct[] __initdata = "mach64CT (ATI264CT)";
 static char m64n_et[] __initdata = "mach64ET (ATI264ET)";
 static char m64n_vta3[] __initdata = "mach64VTA3 (ATI264VT)";
@@ -298,7 +302,7 @@
 static char m64n_ltp_p[] __initdata = "3D RAGE LT PRO (PCI)";
 static char m64n_mob_p[] __initdata = "3D RAGE Mobility (PCI)";
 static char m64n_mob_a[] __initdata = "3D RAGE Mobility (AGP)";
-
+#endif /* CONFIG_FB_ATY_CT */
 
 static const struct {
     u16 pci_id, chip_type;
@@ -360,14 +364,22 @@
 #endif /* CONFIG_FB_ATY_CT */
 };
 
+#if defined(CONFIG_FB_ATY_GX) || defined(CONFIG_FB_ATY_CT)
 static char ram_dram[] __initdata = "DRAM";
+#endif /* CONFIG_FB_ATY_GX || CONFIG_FB_ATY_CT */
+
+#ifdef CONFIG_FB_ATY_GX
 static char ram_vram[] __initdata = "VRAM";
+#endif /* CONFIG_FB_ATY_GX */
+
+#ifdef CONFIG_FB_ATY_CT
 static char ram_edo[] __initdata = "EDO";
 static char ram_sdram[] __initdata = "SDRAM";
 static char ram_sgram[] __initdata = "SGRAM";
 static char ram_wram[] __initdata = "WRAM";
 static char ram_off[] __initdata = "OFF";
 static char ram_resv[] __initdata = "RESV";
+#endif /* CONFIG_FB_ATY_CT */
 
 #ifdef CONFIG_FB_ATY_GX
 static char *aty_gx_ram[8] __initdata = {
@@ -2133,8 +2145,8 @@
 #if defined(CONFIG_PCI)
     struct pci_dev *pdev = NULL;
     struct fb_info_aty *info;
-    unsigned long addr, raddr, res_start, res_size;
-    int i, aux_app;
+    unsigned long addr, res_start, res_size;
+    int i;
 #ifdef __sparc__
     extern void (*prom_palette) (int);
     extern int con_is_present(void);
@@ -2148,11 +2160,16 @@
 	return -ENXIO;
 #else
     u16 tmp;
+    int aux_app;
+    unsigned long raddr;
 #endif
 
     while ((pdev = pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) {
 	if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
-	    struct resource *rp, *rrp;
+	    struct resource *rp;
+#ifndef __sparc__
+	    struct resource *rrp;
+#endif
 
 	    for (i = sizeof(aty_chips)/sizeof(*aty_chips)-1; i >= 0; i--)
 		if (pdev->device == aty_chips[i].pci_id)
diff -urN linux-2.4.17-pre4/fs/devfs/base.c linux/fs/devfs/base.c
--- linux-2.4.17-pre4/fs/devfs/base.c	Thu Dec  6 10:52:26 2001
+++ linux/fs/devfs/base.c	Thu Dec  6 10:53:04 2001
@@ -576,6 +576,9 @@
 	       Fixed bug in <devfsd_close>: was dereferencing freed pointer.
 	       Added process group check for devfsd privileges.
   v1.4
+    20011204   Richard Gooch <rgooch@atnf.csiro.au>
+	       Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>.
+  v1.5
 */
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -608,7 +611,7 @@
 #include <asm/bitops.h>
 #include <asm/atomic.h>
 
-#define DEVFS_VERSION            "1.4 (20011203)"
+#define DEVFS_VERSION            "1.5 (20011204)"
 
 #define DEVFS_NAME "devfs"
 
@@ -1394,13 +1397,16 @@
 
 static int devfsd_notify_de (struct devfs_entry *de,
 			     unsigned short type, umode_t mode,
-			     uid_t uid, gid_t gid, struct fs_info *fs_info)
+			     uid_t uid, gid_t gid, struct fs_info *fs_info,
+			     int atomic)
 {
     struct devfsd_buf_entry *entry;
     struct devfs_entry *curr;
 
     if ( !( fs_info->devfsd_event_mask & (1 << type) ) ) return (FALSE);
-    if ( ( entry = kmem_cache_alloc (devfsd_buf_cache, 0) ) == NULL )
+    if ( ( entry = kmem_cache_alloc (devfsd_buf_cache,
+				     atomic ? SLAB_ATOMIC : SLAB_KERNEL) )
+	 == NULL )
     {
 	atomic_inc (&fs_info->devfsd_overrun_count);
 	return (FALSE);
@@ -1433,7 +1439,7 @@
 static void devfsd_notify (struct devfs_entry *de,unsigned short type,int wait)
 {
     if (devfsd_notify_de (de, type, de->mode, current->euid,
-			  current->egid, &fs_info) && wait)
+			  current->egid, &fs_info, 0) && wait)
 	wait_for_devfsd_finished (&fs_info);
 }   /*  End Function devfsd_notify  */
 
@@ -1783,7 +1789,7 @@
 	printk ("%s: devfs_mk_dir(%s): de: %p dir: %p \"%s\"\n",
 		DEVFS_NAME, name, de, dir, dir->name);
 #endif
-    devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, DEVFS_FL_NONE);
+    devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, 0);
     devfs_put (dir);
     return de;
 }   /*  End Function devfs_mk_dir  */
@@ -2289,7 +2295,7 @@
     buf->namelen = namelen;
     buf->u.name = name;
     if ( !devfsd_notify_de (buf, DEVFSD_NOTIFY_LOOKUP, 0,
-			    current->euid, current->egid, fs_info) )
+			    current->euid, current->egid, fs_info, 0) )
 	return -ENOENT;
     /*  Possible success  */
     return 0;
@@ -2420,7 +2426,7 @@
     if ( ( iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID) ) &&
 	 !is_devfsd_or_child (fs_info) )
 	devfsd_notify_de (de, DEVFSD_NOTIFY_CHANGE, inode->i_mode,
-			  inode->i_uid, inode->i_gid, fs_info);
+			  inode->i_uid, inode->i_gid, fs_info, 0);
     return 0;
 }   /*  End Function devfs_notify_change  */
 
@@ -2660,7 +2666,7 @@
     }
     if ( df->aopen_notify && !is_devfsd_or_child (fs_info) )
 	devfsd_notify_de (de, DEVFSD_NOTIFY_ASYNC_OPEN, inode->i_mode,
-			  current->euid, current->egid, fs_info);
+			  current->euid, current->egid, fs_info, 0);
     return 0;
 }   /*  End Function devfs_open  */
 
@@ -2775,7 +2781,7 @@
     de->u.fcb.open = FALSE;
     if (de->u.fcb.aopen_notify)
 	devfsd_notify_de (de, DEVFSD_NOTIFY_CLOSE, inode->i_mode,
-			  current->euid, current->egid, fs_info);
+			  current->euid, current->egid, fs_info, 1);
     if (!de->u.fcb.auto_owner) return 0;
     /*  Change the ownership/protection back  */
     inode->i_mode = (de->mode & S_IFMT) | S_IRUGO | S_IWUGO;
@@ -2932,7 +2938,7 @@
     if (!unhooked) return -ENOENT;
     if ( !is_devfsd_or_child (fs_info) )
 	devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
-			  inode->i_uid, inode->i_gid, fs_info);
+			  inode->i_uid, inode->i_gid, fs_info, 0);
     free_dentry (de);
     devfs_put (de);
     return 0;
@@ -2973,7 +2979,7 @@
     d_instantiate (dentry, inode);
     if ( !is_devfsd_or_child (fs_info) )
 	devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
-			  inode->i_uid, inode->i_gid, fs_info);
+			  inode->i_uid, inode->i_gid, fs_info, 0);
     return 0;
 }   /*  End Function devfs_symlink  */
 
@@ -3007,7 +3013,7 @@
     d_instantiate (dentry, inode);
     if ( !is_devfsd_or_child (fs_info) )
 	devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
-			  inode->i_uid, inode->i_gid, fs_info);
+			  inode->i_uid, inode->i_gid, fs_info, 0);
     return 0;
 }   /*  End Function devfs_mkdir  */
 
@@ -3036,7 +3042,7 @@
     if (err) return err;
     if ( !is_devfsd_or_child (fs_info) )
 	devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
-			  inode->i_uid, inode->i_gid, fs_info);
+			  inode->i_uid, inode->i_gid, fs_info, 0);
     free_dentry (de);
     devfs_put (de);
     return 0;
@@ -3082,7 +3088,7 @@
     d_instantiate (dentry, inode);
     if ( !is_devfsd_or_child (fs_info) )
 	devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
-			  inode->i_uid, inode->i_gid, fs_info);
+			  inode->i_uid, inode->i_gid, fs_info, 0);
     return 0;
 }   /*  End Function devfs_mknod  */
 
diff -urN linux-2.4.17-pre4/fs/reiserfs/bitmap.c linux/fs/reiserfs/bitmap.c
--- linux-2.4.17-pre4/fs/reiserfs/bitmap.c	Thu Dec  6 10:52:26 2001
+++ linux/fs/reiserfs/bitmap.c	Thu Dec  6 10:53:04 2001
@@ -84,7 +84,7 @@
    to free a list of blocks at once. -Hans */
 				/* I wonder if it would be less modest
                                    now that we use journaling. -Hans */
-void reiserfs_free_block (struct reiserfs_transaction_handle *th, unsigned long block)
+static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsigned long block)
 {
     struct super_block * s = th->t_super;
     struct reiserfs_super_block * rs;
@@ -92,9 +92,6 @@
     struct buffer_head ** apbh;
     int nr, offset;
 
-  RFALSE(!s, "vs-4060: trying to free block on nonexistent device");
-  RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block");
-
   PROC_INFO_INC( s, free_block );
 
   rs = SB_DISK_SUPER_BLOCK (s);
@@ -110,9 +107,6 @@
 	  return;
   }
 
-  /* mark it before we clear it, just in case */
-  journal_mark_freed(th, s, block) ;
-
   reiserfs_prepare_for_journal(s, apbh[nr], 1 ) ;
 
   /* clear bit for the given block in bit map */
@@ -131,7 +125,26 @@
   s->s_dirt = 1;
 }
 
+void reiserfs_free_block (struct reiserfs_transaction_handle *th, 
+                          unsigned long block) {
+    struct super_block * s = th->t_super;
+
+    RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
+    RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block");
+    /* mark it before we clear it, just in case */
+    journal_mark_freed(th, s, block) ;
+    _reiserfs_free_block(th, block) ;
+}
+
+/* preallocated blocks don't need to be run through journal_mark_freed */
+void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th, 
+                          unsigned long block) {
+    struct super_block * s = th->t_super;
 
+    RFALSE(!s, "vs-4060: trying to free block on nonexistent device");
+    RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block");
+    _reiserfs_free_block(th, block) ;
+}
 
 /* beginning from offset-th bit in bmap_nr-th bitmap block,
    find_forward finds the closest zero bit. It returns 1 and zero
@@ -409,7 +422,6 @@
     ** has allocated it.  loop around and try again
     */
     if (reiserfs_test_and_set_le_bit (j, SB_AP_BITMAP (s)[i]->b_data)) {
-	reiserfs_warning("vs-4150: reiserfs_new_blocknrs, block not free");
 	reiserfs_restore_prepared_buffer(s, SB_AP_BITMAP(s)[i]) ;
 	amount_needed++ ;
 	continue ;
@@ -495,12 +507,7 @@
     ** to be grouped towards the start of the border
     */
     border = le32_to_cpu(INODE_PKEY(p_s_inode)->k_dir_id) % (SB_BLOCK_COUNT(th->t_super) - bstart - 1) ;
-  } else {
-    /* why would we want to delcare a local variable to this if statement
-    ** name border????? -chris
-    ** unsigned long border = 0;
-    */
-    if (!reiserfs_hashed_relocation(th->t_super)) {
+  } else if (!reiserfs_hashed_relocation(th->t_super)) {
       hash_in = le32_to_cpu((INODE_PKEY(p_s_inode))->k_dir_id);
 				/* I wonder if the CPU cost of the
                                    hash will obscure the layout
@@ -510,7 +517,6 @@
       
       hash_out = keyed_hash(((char *) (&hash_in)), 4);
       border = hash_out % (SB_BLOCK_COUNT(th->t_super) - bstart - 1) ;
-    }
   }
   border += bstart ;
   allocated[0] = 0 ; /* important.  Allows a check later on to see if at
@@ -666,11 +672,13 @@
 static void __discard_prealloc (struct reiserfs_transaction_handle * th,
 				struct inode * inode)
 {
+  unsigned long save = inode->u.reiserfs_i.i_prealloc_block ;
   while (inode->u.reiserfs_i.i_prealloc_count > 0) {
-    reiserfs_free_block(th,inode->u.reiserfs_i.i_prealloc_block);
+    reiserfs_free_prealloc_block(th,inode->u.reiserfs_i.i_prealloc_block);
     inode->u.reiserfs_i.i_prealloc_block++;
     inode->u.reiserfs_i.i_prealloc_count --;
   }
+  inode->u.reiserfs_i.i_prealloc_block = save ; 
   list_del (&(inode->u.reiserfs_i.i_prealloc_list));
 }
 
diff -urN linux-2.4.17-pre4/fs/reiserfs/buffer2.c linux/fs/reiserfs/buffer2.c
--- linux-2.4.17-pre4/fs/reiserfs/buffer2.c	Fri Nov  9 14:18:25 2001
+++ linux/fs/reiserfs/buffer2.c	Thu Dec  6 10:53:04 2001
@@ -2,15 +2,6 @@
  *  Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README  
  */
 
-
-/*
- * Contains code from
- *
- *  linux/include/linux/lock.h and linux/fs/buffer.c /linux/fs/minix/fsync.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/locks.h>
@@ -21,12 +12,8 @@
 /*
  *  wait_buffer_until_released
  *  reiserfs_bread
- *  reiserfs_getblk
- *  get_new_buffer
  */
 
-
-
 /* when we allocate a new block (get_new_buffer, get_empty_nodes) and
    get buffer for it, it is possible that it is held by someone else
    or even by this process. In this function we wait until all other
@@ -47,7 +34,6 @@
     }
     run_task_queue(&tq_disk);
     current->policy |= SCHED_YIELD;
-    /*current->counter = 0;*/
     schedule();
   }
   if (repeat_counter > 30000000) {
@@ -63,7 +49,6 @@
    then it creates a new buffer and schedules I/O to read the
    block. */
 /* The function is NOT SCHEDULE-SAFE! */
-
 struct buffer_head  * reiserfs_bread (struct super_block *super, int n_block, int n_size) 
 {
     struct buffer_head  *result;
@@ -75,277 +60,4 @@
 	      PROC_INFO_INC( super, bread_miss ) );
     return result;
 }
-
-/* This function looks for a buffer which contains a given block.  If
-   the block is in cache it returns it, otherwise it returns a new
-   buffer which is not uptodate.  This is called by reiserfs_bread and
-   other functions. Note that get_new_buffer ought to be called this
-   and this ought to be called get_new_buffer, since this doesn't
-   actually get the block off of the disk. */
-/* The function is NOT SCHEDULE-SAFE! */
-
-struct buffer_head  * reiserfs_getblk (kdev_t n_dev, int n_block, int n_size)
-{
-    return getblk (n_dev, n_block, n_size);
-}
-
-#ifdef NEW_GET_NEW_BUFFER
-
-/* returns one buffer with a blocknr near blocknr. */
-static int get_new_buffer_near_blocknr(
-                   struct super_block *  p_s_sb,
-                   int blocknr,
-                   struct buffer_head ** pp_s_new_bh,
-                   struct path         * p_s_path 
-                   ) {
-  unsigned      long n_new_blocknumber = 0;
-  int           n_ret_value,
-                n_repeat = CARRY_ON;
-
-#ifdef CONFIG_REISERFS_CHECK
-  int repeat_counter = 0;
-  
-  if (!blocknr)
-    printk ("blocknr passed to get_new_buffer_near_blocknr was 0");
-#endif
-
-
-  if ( (n_ret_value = reiserfs_new_blocknrs (p_s_sb, &n_new_blocknumber,
-                                             blocknr, 1)) == NO_DISK_SPACE )
-    return NO_DISK_SPACE;
-  
-  *pp_s_new_bh = reiserfs_getblk(p_s_sb->s_dev, n_new_blocknumber, p_s_sb->s_blocksize);
-  if ( buffer_uptodate(*pp_s_new_bh) ) {
-
-    RFALSE( buffer_dirty(*pp_s_new_bh) || (*pp_s_new_bh)->b_dev == NODEV,
-	    "PAP-14080: invalid uptodate buffer %b for the new block", 
-	    *pp_s_new_bh);
-
-    /* Free path buffers to prevent deadlock. */
-    /* It is possible that this process has the buffer, which this function is getting, already in
-       its path, and is responsible for double incrementing the value of b_count.  If we recalculate
-       the path after schedule we can avoid risking an endless loop.  This problematic situation is
-       possible in a multiple processing environment.  Suppose process 1 has acquired a path P; then
-       process 2 balanced and remove block A from the tree.  Process 1 continues and runs
-       get_new_buffer, that returns buffer with block A. If node A was on the path P, then it will
-       have b_count == 2. If we now will simply wait in while ( (*pp_s_new_bh)->b_count > 1 ) we get
-       into an endless loop, as nobody will release this buffer and the current process holds buffer
-       twice. That is why we do decrement_counters_in_path(p_s_path) before waiting until b_count
-       becomes 1. (it there were other processes holding node A, then eventually we will get a
-       moment, when all of them released a buffer). */
-    if ( atomic_read (&((*pp_s_new_bh)->b_count)) > 1  ) {
-      decrement_counters_in_path(p_s_path);
-      n_ret_value |= SCHEDULE_OCCURRED;
-    }
-
-    while ( atomic_read (&((*pp_s_new_bh)->b_count)) > 1 ) {
-
-#ifdef REISERFS_INFO
-      printk("get_new_buffer() calls schedule to decrement b_count\n");
-#endif
-
-#ifdef CONFIG_REISERFS_CHECK
-      if ( ! (++repeat_counter % 10000) )
-	printk("get_new_buffer(%u): counter(%d) too big", current->pid, repeat_counter);
-#endif
-
-      current->counter = 0;
-      schedule();
-    }
-
-#ifdef CONFIG_REISERFS_CHECK
-    if ( buffer_dirty(*pp_s_new_bh) || (*pp_s_new_bh)->b_dev == NODEV ) {
-      print_buffer_head(*pp_s_new_bh,"get_new_buffer");
-      reiserfs_panic(p_s_sb, "PAP-14090: get_new_buffer: invalid uptodate buffer %b for the new block(case 2)", *pp_s_new_bh);
-    }
-#endif
-
-  }
-  else {
-    ;
-
-    RFALSE( atomic_read (&((*pp_s_new_bh)->b_count)) != 1,
-	    "PAP-14100: not uptodate buffer %b for the new block has b_count more than one",
-	    *pp_s_new_bh);
-
-  }
-  return (n_ret_value | n_repeat);
-}
-
-
-/* returns the block number of the last unformatted node, assumes p_s_key_to_search.k_offset is a byte in the tail of
-   the file, Useful for when you want to append to a file, and convert a direct item into an unformatted node near the
-   last unformatted node of the file.  Putting the unformatted node near the direct item is potentially very bad to do.
-   If there is no unformatted node in the file, then we return the block number of the direct item.  */
-/* The function is NOT SCHEDULE-SAFE! */
-inline int get_last_unformatted_node_blocknr_of_file(  struct key * p_s_key_to_search, struct super_block * p_s_sb,
-                                                       struct buffer_head * p_s_bh
-                                                       struct path * p_unf_search_path, struct inode * p_s_inode)
-
-{
-  struct key unf_key_to_search;
-  struct item_head * p_s_ih;
-  int n_pos_in_item;
-  struct buffer_head * p_indirect_item_bh;
-
-      copy_key(&unf_key_to_search,p_s_key_to_search);
-      unf_key_to_search.k_uniqueness = TYPE_INDIRECT;
-      unf_key_to_search.k_offset = p_s_inode->u.reiserfs_i.i_first_direct_byte - 1;
-
-        /* p_s_key_to_search->k_offset -  MAX_ITEM_LEN(p_s_sb->s_blocksize); */
-      if (search_for_position_by_key (p_s_sb, &unf_key_to_search, p_unf_search_path, &n_pos_in_item) == POSITION_FOUND)
-        {
-          p_s_ih = B_N_PITEM_HEAD(p_indirect_item_bh = PATH_PLAST_BUFFER(p_unf_search_path), PATH_LAST_POSITION(p_unf_search_path));
-          return (B_I_POS_UNFM_POINTER(p_indirect_item_bh, p_s_ih, n_pos_in_item));
-        }
-     /*  else */
-      printk("reiser-1800: search for unformatted node failed, p_s_key_to_search->k_offset = %u,  unf_key_to_search.k_offset = %u, MAX_ITEM_LEN(p_s_sb->s_blocksize) = %ld, debug this\n", p_s_key_to_search->k_offset, unf_key_to_search.k_offset,  MAX_ITEM_LEN(p_s_sb->s_blocksize) );
-      print_buffer_head(PATH_PLAST_BUFFER(p_unf_search_path), "the buffer holding the item before the key we failed to find");
-      print_block_head(PATH_PLAST_BUFFER(p_unf_search_path), "the block head");
-      return 0;                         /* keeps the compiler quiet */
-}
-
-
-                                /* hasn't been out of disk space tested  */
-/* The function is NOT SCHEDULE-SAFE! */
-static int get_buffer_near_last_unf ( struct super_block * p_s_sb, struct key * p_s_key_to_search,
-                                                 struct inode *  p_s_inode,  struct buffer_head * p_s_bh, 
-                                                 struct buffer_head ** pp_s_un_bh, struct path * p_s_search_path)
-{
-  int unf_blocknr = 0, /* blocknr from which we start search for a free block for an unformatted node, if 0
-                          then we didn't find an unformatted node though we might have found a file hole */
-      n_repeat = CARRY_ON;
-  struct key unf_key_to_search;
-  struct path unf_search_path;
-
-  copy_key(&unf_key_to_search,p_s_key_to_search);
-  unf_key_to_search.k_uniqueness = TYPE_INDIRECT;
-  
-  if (
-      (p_s_inode->u.reiserfs_i.i_first_direct_byte > 4095) /* i_first_direct_byte gets used for all sorts of
-                                                              crap other than what the name indicates, thus
-                                                              testing to see if it is 0 is not enough */
-      && (p_s_inode->u.reiserfs_i.i_first_direct_byte < MAX_KEY_OFFSET) /* if there is no direct item then
-                                                                           i_first_direct_byte = MAX_KEY_OFFSET */
-      )
-    {
-                                /* actually, we don't want the last unformatted node, we want the last unformatted node
-                                   which is before the current file offset */
-      unf_key_to_search.k_offset = ((p_s_inode->u.reiserfs_i.i_first_direct_byte -1) < unf_key_to_search.k_offset) ? p_s_inode->u.reiserfs_i.i_first_direct_byte -1 :  unf_key_to_search.k_offset;
-
-      while (unf_key_to_search.k_offset > -1)
-        {
-                                /* This is our poorly documented way of initializing paths. -Hans */
-          init_path (&unf_search_path);
-                                /* get the blocknr from which we start the search for a free block. */
-          unf_blocknr = get_last_unformatted_node_blocknr_of_file(  p_s_key_to_search, /* assumes this points to the file tail */
-                                                                    p_s_sb,     /* lets us figure out the block size */
-                                                                    p_s_bh, /* if there is no unformatted node in the file,
-                                                                               then it returns p_s_bh->b_blocknr */
-                                                                    &unf_search_path,
-                                                                    p_s_inode
-                                                                    );
-/*        printk("in while loop: unf_blocknr = %d,  *pp_s_un_bh = %p\n", unf_blocknr, *pp_s_un_bh); */
-          if (unf_blocknr) 
-            break;
-          else                  /* release the path and search again, this could be really slow for huge
-                                   holes.....better to spend the coding time adding compression though.... -Hans */
-            {
-                                /* Vladimir, is it a problem that I don't brelse these buffers ?-Hans */
-              decrement_counters_in_path(&unf_search_path);
-              unf_key_to_search.k_offset -= 4096;
-            }
-        }
-      if (unf_blocknr) {
-        n_repeat |= get_new_buffer_near_blocknr(p_s_sb, unf_blocknr, pp_s_un_bh, p_s_search_path);
-      }
-      else {                    /* all unformatted nodes are holes */
-        n_repeat |= get_new_buffer_near_blocknr(p_s_sb, p_s_bh->b_blocknr, pp_s_un_bh, p_s_search_path); 
-      }
-    }
-  else {                        /* file has no unformatted nodes */
-    n_repeat |= get_new_buffer_near_blocknr(p_s_sb, p_s_bh->b_blocknr, pp_s_un_bh, p_s_search_path);
-/*     printk("in else: unf_blocknr = %d,  *pp_s_un_bh = %p\n", unf_blocknr, *pp_s_un_bh); */
-/*     print_path (0,  p_s_search_path); */
-  }
-
-  return n_repeat;
-}
-
-#endif /* NEW_GET_NEW_BUFFER */
-
-
-#ifdef OLD_GET_NEW_BUFFER
-
-/* The function is NOT SCHEDULE-SAFE! */
-int get_new_buffer(
-		   struct reiserfs_transaction_handle *th, 
-		   struct buffer_head *  p_s_bh,
-		   struct buffer_head ** pp_s_new_bh,
-		   struct path	       * p_s_path
-		   ) {
-  unsigned	long n_new_blocknumber = 0;
-  int		n_repeat;
-  struct super_block *	 p_s_sb = th->t_super;
-
-  if ( (n_repeat = reiserfs_new_unf_blocknrs (th, &n_new_blocknumber, p_s_bh->b_blocknr)) == NO_DISK_SPACE )
-    return NO_DISK_SPACE;
-  
-  *pp_s_new_bh = reiserfs_getblk(p_s_sb->s_dev, n_new_blocknumber, p_s_sb->s_blocksize);
-  if (atomic_read (&(*pp_s_new_bh)->b_count) > 1) {
-    /* Free path buffers to prevent deadlock which can occur in the
-       situation like : this process holds p_s_path; Block
-       (*pp_s_new_bh)->b_blocknr is on the path p_s_path, but it is
-       not necessary, that *pp_s_new_bh is in the tree; process 2
-       could remove it from the tree and freed block
-       (*pp_s_new_bh)->b_blocknr. Reiserfs_new_blocknrs in above
-       returns block (*pp_s_new_bh)->b_blocknr. Reiserfs_getblk gets
-       buffer for it, and it has b_count > 1. If we now will simply
-       wait in while ( (*pp_s_new_bh)->b_count > 1 ) we get into an
-       endless loop, as nobody will release this buffer and the
-       current process holds buffer twice. That is why we do
-       decrement_counters_in_path(p_s_path) before waiting until
-       b_count becomes 1. (it there were other processes holding node
-       pp_s_new_bh, then eventually we will get a moment, when all of
-       them released a buffer). */
-    decrement_counters_in_path(p_s_path);
-    wait_buffer_until_released (*pp_s_new_bh);
-    n_repeat |= SCHEDULE_OCCURRED;
-  }
-
-  RFALSE( atomic_read (&((*pp_s_new_bh)->b_count)) != 1 || 
-	  buffer_dirty (*pp_s_new_bh),
-	  "PAP-14100: not free or dirty buffer %b for the new block", 
-	  *pp_s_new_bh);
-
-  return n_repeat;
-}
-
-#endif /* OLD_GET_NEW_BUFFER */
-
-
-#ifdef GET_MANY_BLOCKNRS
-                                /* code not yet functional */
-get_next_blocknr (
-                  unsigned long *       p_blocknr_array,          /* we get a whole bunch of blocknrs all at once for
-                                                                     the write.  This is better than getting them one at
-                                                                     a time.  */
-                  unsigned long **      p_blocknr_index,        /* pointer to current offset into the array. */
-                  unsigned long        blocknr_array_length
-)
-{
-  unsigned long return_value;
-
-  if (*p_blocknr_index < p_blocknr_array + blocknr_array_length) {
-    return_value = **p_blocknr_index;
-    **p_blocknr_index = 0;
-    *p_blocknr_index++;
-    return (return_value);
-  }
-  else
-    {
-      kfree (p_blocknr_array);
-    }
-}
-#endif /* GET_MANY_BLOCKNRS */
 
diff -urN linux-2.4.17-pre4/fs/reiserfs/dir.c linux/fs/reiserfs/dir.c
--- linux-2.4.17-pre4/fs/reiserfs/dir.c	Tue Oct 30 15:11:34 2001
+++ linux/fs/reiserfs/dir.c	Thu Dec  6 10:53:04 2001
@@ -22,22 +22,6 @@
     fsync:	reiserfs_dir_fsync,
 };
 
-/*
- * directories can handle most operations...
- */
-struct inode_operations reiserfs_dir_inode_operations = {
-  //&reiserfs_dir_operations,	/* default_file_ops */
-    create:	reiserfs_create,
-    lookup:	reiserfs_lookup,
-    link:	reiserfs_link,
-    unlink:	reiserfs_unlink,
-    symlink:	reiserfs_symlink,
-    mkdir:	reiserfs_mkdir,
-    rmdir:	reiserfs_rmdir,
-    mknod:	reiserfs_mknod,
-    rename:	reiserfs_rename,
-};
-
 int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
   lock_kernel();
   reiserfs_commit_for_inode(dentry->d_inode) ;
@@ -186,7 +170,7 @@
 	}
 	
 	/* directory continues in the right neighboring block */
-	set_cpu_key_k_offset (&pos_key, le_key_k_offset (ITEM_VERSION_1, rkey));
+	set_cpu_key_k_offset (&pos_key, le_key_k_offset (KEY_FORMAT_3_5, rkey));
 
     } /* while */
 
@@ -197,4 +181,72 @@
     pathrelse (&path_to_entry);
     reiserfs_check_path(&path_to_entry) ;
     return 0;
+}
+
+/* compose directory item containing "." and ".." entries (entries are
+   not aligned to 4 byte boundary) */
+/* the last four params are LE */
+void make_empty_dir_item_v1 (char * body, __u32 dirid, __u32 objid,
+			     __u32 par_dirid, __u32 par_objid)
+{
+    struct reiserfs_de_head * deh;
+
+    memset (body, 0, EMPTY_DIR_SIZE_V1);
+    deh = (struct reiserfs_de_head *)body;
+    
+    /* direntry header of "." */
+    put_deh_offset( &(deh[0]), DOT_OFFSET );
+    /* these two are from make_le_item_head, and are are LE */
+    deh[0].deh_dir_id = dirid;
+    deh[0].deh_objectid = objid;
+    deh[0].deh_state = 0; /* Endian safe if 0 */
+    put_deh_location( &(deh[0]), EMPTY_DIR_SIZE_V1 - strlen( "." ));
+    mark_de_visible(&(deh[0]));
+  
+    /* direntry header of ".." */
+    put_deh_offset( &(deh[1]), DOT_DOT_OFFSET);
+    /* key of ".." for the root directory */
+    /* these two are from the inode, and are are LE */
+    deh[1].deh_dir_id = par_dirid;
+    deh[1].deh_objectid = par_objid;
+    deh[1].deh_state = 0; /* Endian safe if 0 */
+    put_deh_location( &(deh[1]), deh_location( &(deh[0]) ) - strlen( ".." ) );
+    mark_de_visible(&(deh[1]));
+
+    /* copy ".." and "." */
+    memcpy (body + deh_location( &(deh[0]) ), ".", 1);
+    memcpy (body + deh_location( &(deh[1]) ), "..", 2);
+}
+
+/* compose directory item containing "." and ".." entries */
+void make_empty_dir_item (char * body, __u32 dirid, __u32 objid,
+			  __u32 par_dirid, __u32 par_objid)
+{
+    struct reiserfs_de_head * deh;
+
+    memset (body, 0, EMPTY_DIR_SIZE);
+    deh = (struct reiserfs_de_head *)body;
+    
+    /* direntry header of "." */
+    put_deh_offset( &(deh[0]), DOT_OFFSET );
+    /* these two are from make_le_item_head, and are are LE */
+    deh[0].deh_dir_id = dirid;
+    deh[0].deh_objectid = objid;
+    deh[0].deh_state = 0; /* Endian safe if 0 */
+    put_deh_location( &(deh[0]), EMPTY_DIR_SIZE - ROUND_UP( strlen( "." ) ) );
+    mark_de_visible(&(deh[0]));
+  
+    /* direntry header of ".." */
+    put_deh_offset( &(deh[1]), DOT_DOT_OFFSET );
+    /* key of ".." for the root directory */
+    /* these two are from the inode, and are are LE */
+    deh[1].deh_dir_id = par_dirid;
+    deh[1].deh_objectid = par_objid;
+    deh[1].deh_state = 0; /* Endian safe if 0 */
+    put_deh_location( &(deh[1]), deh_location( &(deh[0])) - ROUND_UP( strlen( ".." ) ) );
+    mark_de_visible(&(deh[1]));
+
+    /* copy ".." and "." */
+    memcpy (body + deh_location( &(deh[0]) ), ".", 1);
+    memcpy (body + deh_location( &(deh[1]) ), "..", 2);
 }
diff -urN linux-2.4.17-pre4/fs/reiserfs/do_balan.c linux/fs/reiserfs/do_balan.c
--- linux-2.4.17-pre4/fs/reiserfs/do_balan.c	Fri Nov  9 14:18:25 2001
+++ linux/fs/reiserfs/do_balan.c	Thu Dec  6 10:53:04 2001
@@ -274,13 +274,6 @@
     int pos_in_item;
     int zeros_num;
 
-#if 0
-    if (tb->insert_size [0] % 4) {
-	reiserfs_panic (tb->tb_sb, "balance_leaf: wrong insert_size %d", 
-			tb->insert_size [0]);
-    }
-#endif
-
     PROC_INFO_INC( tb -> tb_sb, balance_at[ 0 ] );
 
     /* Make balance in case insert_size[0] < 0 */
diff -urN linux-2.4.17-pre4/fs/reiserfs/file.c linux/fs/reiserfs/file.c
--- linux-2.4.17-pre4/fs/reiserfs/file.c	Fri Oct 12 14:20:42 2001
+++ linux/fs/reiserfs/file.c	Thu Dec  6 10:53:04 2001
@@ -33,7 +33,7 @@
 
     /* fast out for when nothing needs to be done */
     if ((atomic_read(&inode->i_count) > 1 ||
-         !inode->u.reiserfs_i.i_pack_on_close || 
+         !(inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) || 
          !tail_has_to_be_packed(inode))       && 
 	inode->u.reiserfs_i.i_prealloc_count <= 0) {
 	return 0;
@@ -50,7 +50,7 @@
     journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
 
     if (atomic_read(&inode->i_count) <= 1 &&
-	inode->u.reiserfs_i.i_pack_on_close &&
+	(inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) &&
         tail_has_to_be_packed (inode)) {
 	/* if regular file is released by last holder and it has been
 	   appended (we append by unformatted node only) or its direct
@@ -97,10 +97,16 @@
 	/* version 2 items will be caught by the s_maxbytes check
 	** done for us in vmtruncate
 	*/
-        if (inode_items_version(inode) == ITEM_VERSION_1 && 
+	if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
 	    attr->ia_size > MAX_NON_LFS)
             return -EFBIG ;
     }
+
+    if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
+	 ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
+	(get_inode_sd_version (inode) == STAT_DATA_V1))
+		/* stat data of format v3.5 has 16 bit uid and gid */
+	    return -EINVAL;
 
     error = inode_change_ok(inode, attr) ;
     if (!error)
diff -urN linux-2.4.17-pre4/fs/reiserfs/fix_node.c linux/fs/reiserfs/fix_node.c
--- linux-2.4.17-pre4/fs/reiserfs/fix_node.c	Fri Nov  9 14:18:25 2001
+++ linux/fs/reiserfs/fix_node.c	Thu Dec  6 10:53:04 2001
@@ -806,7 +806,7 @@
     RFALSE( ! *p_n_blocknr,
 	    "PAP-8135: reiserfs_new_blocknrs failed when got new blocks");
 
-    p_s_new_bh = reiserfs_getblk(p_s_sb->s_dev, *p_n_blocknr, p_s_sb->s_blocksize);
+    p_s_new_bh = getblk(p_s_sb->s_dev, *p_n_blocknr, p_s_sb->s_blocksize);
     if (atomic_read (&(p_s_new_bh->b_count)) > 1) {
 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
 /*
@@ -2021,23 +2021,6 @@
   // entry would eat 2 byte of virtual node space
   return sb->s_blocksize;
 
-#if 0
-  size = sizeof (struct virtual_node) + sizeof (struct virtual_item);
-  ih = B_N_PITEM_HEAD (bh, 0);
-  nr_items = B_NR_ITEMS (bh);
-  for (i = 0; i < nr_items; i ++, ih ++) {
-    /* each item occupies some space in virtual node */
-    size += sizeof (struct virtual_item);
-    if (is_direntry_le_ih (ih))
-      /* each entry and new one occupeis 2 byte in the virtual node */
-      size += (ih_entry_count(ih) + 1) * sizeof( __u16 );
-  }
-  
-  /* 1 bit for each bitmap block to note whether bitmap block was
-     dirtied in the operation */
- /* size += (SB_BMAP_NR (sb) * 2 / 8 + 4);*/
-  return size;
-#endif
 }
 
 
@@ -2342,15 +2325,6 @@
 	reiserfs_panic (p_s_tb->tb_sb, "PAP-8320: fix_nodes: S[0] (%b %z) is not uptodate "
 			"at the beginning of fix_nodes or not in tree (mode %c)", p_s_tbS0, p_s_tbS0, n_op_mode);
     }
-
-    // FIXME: new items have to be of 8 byte multiples. Including new
-    // directory items those look like old ones
-    /*
-    if (p_s_tb->insert_size[0] % 8)
-	reiserfs_panic (p_s_tb->tb_sb, "vs-: fix_nodes: incorrect insert_size %d, "
-			"mode %c",
-			p_s_tb->insert_size[0], n_op_mode);
-    */
 
     /* Check parameters. */
     switch (n_op_mode) {
diff -urN linux-2.4.17-pre4/fs/reiserfs/inode.c linux/fs/reiserfs/inode.c
--- linux-2.4.17-pre4/fs/reiserfs/inode.c	Thu Dec  6 10:52:26 2001
+++ linux/fs/reiserfs/inode.c	Thu Dec  6 10:53:04 2001
@@ -17,6 +17,8 @@
 #define GET_BLOCK_READ_DIRECT 4  /* read the tail if indirect item not found */
 #define GET_BLOCK_NO_ISEM     8 /* i_sem is not held, don't preallocate */
 
+static int reiserfs_get_block (struct inode * inode, long block,
+			       struct buffer_head * bh_result, int create);
 //
 // initially this function was derived from minix or ext2's analog and
 // evolved as the prototype did
@@ -40,11 +42,13 @@
 
 	reiserfs_delete_object (&th, inode);
 	pop_journal_writer(windex) ;
-	reiserfs_release_objectid (&th, inode->i_ino);
 
 	journal_end(&th, inode->i_sb, jbegin_count) ;
 
-	up (&inode->i_sem); 
+        up (&inode->i_sem);
+
+        /* all items of file are deleted, so we can remove "save" link */
+	remove_save_link (inode, 0/* not truncate */);
     } else {
 	/* no object items are in the tree */
 	;
@@ -72,9 +76,9 @@
 void make_cpu_key (struct cpu_key * key, const struct inode * inode, loff_t offset,
 	      int type, int length )
 {
-  _make_cpu_key (key, inode_items_version (inode), le32_to_cpu (INODE_PKEY (inode)->k_dir_id),
-	  	   le32_to_cpu (INODE_PKEY (inode)->k_objectid), 
-		   offset, type, length);
+  _make_cpu_key (key, get_inode_item_key_version (inode), le32_to_cpu (INODE_PKEY (inode)->k_dir_id),
+		 le32_to_cpu (INODE_PKEY (inode)->k_objectid), 
+		 offset, type, length);
 }
 
 
@@ -215,9 +219,9 @@
 // files which were created in the earlier version can not be longer,
 // than 2 gb
 //
-int file_capable (struct inode * inode, long block)
+static int file_capable (struct inode * inode, long block)
 {
-    if (inode_items_version (inode) != ITEM_VERSION_1 || // it is new file.
+    if (get_inode_item_key_version (inode) != KEY_FORMAT_3_5 || // it is new file.
 	block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb
 	return 1;
 
@@ -511,8 +515,8 @@
 // determine which parts are derivative, if any, understanding that
 // there are only so many ways to code to a given interface.
 //
-int reiserfs_get_block (struct inode * inode, long block,
-			struct buffer_head * bh_result, int create)
+static int reiserfs_get_block (struct inode * inode, long block,
+			       struct buffer_head * bh_result, int create)
 {
     int repeat, retval;
     unsigned long tag;
@@ -540,7 +544,7 @@
 				/* bad.... */
     lock_kernel() ;
     th.t_trans_id = 0 ;
-    version = inode_items_version (inode);
+    version = get_inode_item_key_version (inode);
 
     if (block < 0) {
 	unlock_kernel();
@@ -564,7 +568,7 @@
 	return ret;
     }
 
-    inode->u.reiserfs_i.i_pack_on_close = 1 ;
+    inode->u.reiserfs_i.i_flags |= i_pack_on_close_mask;
 
     windex = push_journal_writer("reiserfs_get_block") ;
   
@@ -880,7 +884,8 @@
 	struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
 	unsigned long blocks;
 
-	inode_items_version (inode) = ITEM_VERSION_1;
+	set_inode_item_key_version (inode, KEY_FORMAT_3_5);
+        set_inode_sd_version (inode, STAT_DATA_V1);
 	inode->i_mode  = sd_v1_mode(sd);
 	inode->i_nlink = sd_v1_nlink(sd);
 	inode->i_uid   = sd_v1_uid(sd);
@@ -929,13 +934,13 @@
             inode->i_generation = sd_v2_generation(sd);
 
 	if (S_ISDIR (inode->i_mode) || S_ISLNK (inode->i_mode))
-	    inode_items_version (inode) = ITEM_VERSION_1;
+	    set_inode_item_key_version (inode, KEY_FORMAT_3_5);
 	else
-	    inode_items_version (inode) = ITEM_VERSION_2;
+            set_inode_item_key_version (inode, KEY_FORMAT_3_6);
     }
 
     /* nopack = 0, by default */
-    inode->u.reiserfs_i.nopack = 0;
+    inode->u.reiserfs_i.i_flags &= ~i_nopack_mask;
 
     pathrelse (path);
     if (S_ISREG (inode->i_mode)) {
@@ -1115,7 +1120,7 @@
 
     /* set version 1, version 2 could be used too, because stat data
        key is the same in both versions */
-    key.version = ITEM_VERSION_1;
+    key.version = KEY_FORMAT_3_5;
     key.on_disk_key.k_dir_id = dirino;
     key.on_disk_key.k_objectid = inode->i_ino;
     key.on_disk_key.u.k_offset_v1.k_offset = SD_OFFSET;
@@ -1186,7 +1191,7 @@
 }
 
 struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data,
-                                     int len, int fhtype, int parent) {
+				     int len, int fhtype, int parent) {
     struct cpu_key key ;
     struct inode *inode = NULL ;
     struct list_head *lp;
@@ -1327,26 +1332,6 @@
     }
 }
 
-void reiserfs_dirty_inode (struct inode * inode) {
-    struct reiserfs_transaction_handle th ;
-
-    if (inode->i_sb->s_flags & MS_RDONLY) {
-        reiserfs_warning("clm-6006: writing inode %lu on readonly FS\n", 
-	                  inode->i_ino) ;
-        return ;
-    }
-    lock_kernel() ;
-
-    /* this is really only used for atime updates, so they don't have
-    ** to be included in O_SYNC or fsync
-    */
-    journal_begin(&th, inode->i_sb, 1) ;
-    reiserfs_update_sd (&th, inode);
-    journal_end(&th, inode->i_sb, 1) ;
-    unlock_kernel() ;
-}
-
-
 /* FIXME: no need any more. right? */
 int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode)
 {
@@ -1369,20 +1354,20 @@
     struct cpu_key key;
     int retval;
     
-    _make_cpu_key (&key, ITEM_VERSION_1, le32_to_cpu (ih->ih_key.k_dir_id),
+    _make_cpu_key (&key, KEY_FORMAT_3_5, le32_to_cpu (ih->ih_key.k_dir_id),
 		   le32_to_cpu (ih->ih_key.k_objectid), DOT_OFFSET, TYPE_DIRENTRY, 3/*key length*/);
     
     /* compose item head for new item. Directories consist of items of
        old type (ITEM_VERSION_1). Do not set key (second arg is 0), it
        is done by reiserfs_new_inode */
     if (old_format_only (sb)) {
-	make_le_item_head (ih, 0, ITEM_VERSION_1, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
+	make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
 	
 	make_empty_dir_item_v1 (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
 				INODE_PKEY (dir)->k_dir_id, 
 				INODE_PKEY (dir)->k_objectid );
     } else {
-	make_le_item_head (ih, 0, ITEM_VERSION_1, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
+	make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
 	
 	make_empty_dir_item (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
 		   		INODE_PKEY (dir)->k_dir_id, 
@@ -1418,12 +1403,12 @@
     struct cpu_key key;
     int retval;
 
-    _make_cpu_key (&key, ITEM_VERSION_1, 
+    _make_cpu_key (&key, KEY_FORMAT_3_5, 
 		   le32_to_cpu (ih->ih_key.k_dir_id), 
 		   le32_to_cpu (ih->ih_key.k_objectid),
 		   1, TYPE_DIRECT, 3/*key length*/);
 
-    make_le_item_head (ih, 0, ITEM_VERSION_1, 1, TYPE_DIRECT, item_len, 0/*free_space*/);
+    make_le_item_head (ih, 0, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0/*free_space*/);
 
     /* look for place in the tree for new item */
     retval = search_item (sb, &key, path);
@@ -1494,13 +1479,13 @@
       inode->i_generation = ++event;
 #endif
     if (old_format_only (sb))
-	make_le_item_head (&ih, 0, ITEM_VERSION_1, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
+	make_le_item_head (&ih, 0, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
     else
-	make_le_item_head (&ih, 0, ITEM_VERSION_2, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
+	make_le_item_head (&ih, 0, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
 
 
     /* key to search for correct place for new stat data */
-    _make_cpu_key (&key, ITEM_VERSION_2, le32_to_cpu (ih.ih_key.k_dir_id),
+    _make_cpu_key (&key, KEY_FORMAT_3_6, le32_to_cpu (ih.ih_key.k_dir_id),
 		   le32_to_cpu (ih.ih_key.k_objectid), SD_OFFSET, TYPE_STAT_DATA, 3/*key length*/);
 
     /* find proper place for inserting of stat data */
@@ -1536,9 +1521,16 @@
 
     INIT_LIST_HEAD(&inode->u.reiserfs_i.i_prealloc_list) ;
 
-    if (old_format_only (sb))
+    if (old_format_only (sb)) {
+	if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) {
+	    pathrelse (&path_to_key);
+	    /* i_uid or i_gid is too big to be stored in stat data v3.5 */
+	    iput (inode);
+	    *err = -EINVAL;
+	    return NULL;
+	}
 	inode2sd_v1 (&sd, inode);
-    else
+    } else
 	inode2sd (&sd, inode);
 
     // these do not go to on-disk stat data
@@ -1551,10 +1543,14 @@
     // format, other new objects will consist of new items)
     memcpy (INODE_PKEY (inode), &(ih.ih_key), KEY_SIZE);
     if (old_format_only (sb) || S_ISDIR(mode) || S_ISLNK(mode))
-	inode_items_version (inode) = ITEM_VERSION_1;
+        set_inode_item_key_version (inode, KEY_FORMAT_3_5);
     else
-	inode_items_version (inode) = ITEM_VERSION_2;
-
+        set_inode_item_key_version (inode, KEY_FORMAT_3_6);
+    if (old_format_only (sb))
+	set_inode_sd_version (inode, STAT_DATA_V1);
+    else
+	set_inode_sd_version (inode, STAT_DATA_V2);
+    
     /* insert the stat data into the tree */
     retval = reiserfs_insert_item (th, &path_to_key, &key, &ih, (char *)(&sd));
     if (retval) {
@@ -1714,12 +1710,23 @@
     ** because the truncate might pack the item anyway 
     ** (it will unmap bh if it packs).
     */
-    journal_begin(&th, p_s_inode->i_sb,  JOURNAL_PER_BALANCE_CNT * 2 ) ;
+    /* it is enough to reserve space in transaction for 2 balancings:
+       one for "save" link adding and another for the first
+       cut_from_item. 1 is for update_sd */
+    journal_begin(&th, p_s_inode->i_sb,  JOURNAL_PER_BALANCE_CNT * 2 + 1 ) ;
     reiserfs_update_inode_transaction(p_s_inode) ;
     windex = push_journal_writer("reiserfs_vfs_truncate_file") ;
+    if (update_timestamps)
+           /* we are doing real truncate: if the system crashes before the last
+              transaction of truncating gets committed - on reboot the file
+              either appears truncated properly or not truncated at all */
+           add_save_link (&th, p_s_inode, 1);
     reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
     pop_journal_writer(windex) ;
-    journal_end(&th, p_s_inode->i_sb,  JOURNAL_PER_BALANCE_CNT * 2 ) ;
+    journal_end(&th, p_s_inode->i_sb,  JOURNAL_PER_BALANCE_CNT * 2 + 1 ) ;
+
+    if (update_timestamps)
+       remove_save_link (p_s_inode, 1/* truncate */);
 
     if (page) {
         length = offset & (blocksize - 1) ;
diff -urN linux-2.4.17-pre4/fs/reiserfs/ioctl.c linux/fs/reiserfs/ioctl.c
--- linux-2.4.17-pre4/fs/reiserfs/ioctl.c	Sat Sep  8 12:05:32 2001
+++ linux/fs/reiserfs/ioctl.c	Thu Dec  6 10:53:04 2001
@@ -46,7 +46,7 @@
         return -EINVAL ;
     }
     /* ioctl already done */
-    if (inode->u.reiserfs_i.nopack) {
+    if (inode->u.reiserfs_i.i_flags & i_nopack_mask) {
         return 0 ;
     }
     lock_kernel();
@@ -59,7 +59,7 @@
     write_from = inode->i_size & (blocksize - 1) ;
     /* if we are on a block boundary, we are already unpacked.  */
     if ( write_from == 0) {
-	inode->u.reiserfs_i.nopack = 1;
+	inode->u.reiserfs_i.i_flags |= i_nopack_mask;
 	goto out ;
     }
 
@@ -79,7 +79,7 @@
 
     /* conversion can change page contents, must flush */
     flush_dcache_page(page) ;
-    inode->u.reiserfs_i.nopack = 1;
+    inode->u.reiserfs_i.i_flags |= i_nopack_mask;
     kunmap(page) ; /* mapped by prepare_write */
 
 out_unlock:
diff -urN linux-2.4.17-pre4/fs/reiserfs/journal.c linux/fs/reiserfs/journal.c
--- linux-2.4.17-pre4/fs/reiserfs/journal.c	Thu Dec  6 10:52:26 2001
+++ linux/fs/reiserfs/journal.c	Thu Dec  6 10:53:04 2001
@@ -92,6 +92,8 @@
 static int flush_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) ;
 static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall)  ;
 static int can_dirty(struct reiserfs_journal_cnode *cn) ;
+static int remove_from_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_head *bh, int remove_freed);
+static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks);
 
 static void init_journal_hash(struct super_block *p_s_sb) {
   memset(SB_JOURNAL(p_s_sb)->j_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
@@ -1697,7 +1699,7 @@
   /* step three, starting at the oldest transaction, replay */
   if (last_flush_start > 0) {
     oldest_start = last_flush_start ;
-    oldest_trans_id = last_flush_trans_id ;
+    oldest_trans_id = last_flush_trans_id + 1 ;
   } 
   cur_dblock = oldest_start ;
   if (oldest_trans_id)  {
@@ -1717,6 +1719,8 @@
     }
     cur_dblock = reiserfs_get_journal_block(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start ;
     replay_count++ ;
+   if (cur_dblock == oldest_start)
+        break;
   }
 
   if (oldest_trans_id == 0) {
@@ -2083,7 +2087,7 @@
 }
 
 
-int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
+static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
   return do_journal_begin_r(th, p_s_sb, nblocks, 1) ;
 }
 
@@ -2238,7 +2242,7 @@
 **
 ** returns 1 if it cleaned and relsed the buffer. 0 otherwise
 */
-int remove_from_transaction(struct super_block *p_s_sb, unsigned long blocknr, int already_cleaned) {
+static int remove_from_transaction(struct super_block *p_s_sb, unsigned long blocknr, int already_cleaned) {
   struct buffer_head *bh ;
   struct reiserfs_journal_cnode *cn ;
   int ret = 0;
@@ -2279,7 +2283,7 @@
 }
 
 /* removes from a specific journal list hash */
-int remove_from_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_head *bh, int remove_freed) {
+static int remove_from_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_head *bh, int remove_freed) {
   remove_journal_hash(SB_JOURNAL(s)->j_list_hash_table, jl, bh, remove_freed) ;
   return 0 ;
 }
@@ -2341,20 +2345,6 @@
 int show_reiserfs_locks(void) {
 
   dump_journal_writers() ;
-#if 0 /* debugging code for when we are compiled static don't delete */
-  p_s_sb = sb_entry(super_blocks.next);
-  while (p_s_sb != sb_entry(&super_blocks)) {
-    if (reiserfs_is_super(p_s_sb)) {
-printk("journal lock is %d, join lock is %d, writers %d must wait is %d\n", 
-        atomic_read(&(SB_JOURNAL(p_s_sb)->j_wlock)),
-        atomic_read(&(SB_JOURNAL(p_s_sb)->j_jlock)),
-	atomic_read(&(SB_JOURNAL(p_s_sb)->j_wcount)),
-	SB_JOURNAL(p_s_sb)->j_must_wait) ;
-	printk("used cnodes %d, free cnodes %d\n", SB_JOURNAL(p_s_sb)->j_cnode_used, SB_JOURNAL(p_s_sb)->j_cnode_free) ;
-    }
-    p_s_sb = sb_entry(p_s_sb->s_list.next);
-  }
-#endif
   return 0 ;
 }
 
diff -urN linux-2.4.17-pre4/fs/reiserfs/lbalance.c linux/fs/reiserfs/lbalance.c
--- linux-2.4.17-pre4/fs/reiserfs/lbalance.c	Tue Oct 30 15:11:34 2001
+++ linux/fs/reiserfs/lbalance.c	Thu Dec  6 10:53:04 2001
@@ -63,7 +63,7 @@
 
 	/* form item header */
 	memcpy (&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
-	put_ih_version( &new_ih, ITEM_VERSION_1 );
+	put_ih_version( &new_ih, KEY_FORMAT_3_5 );
 	/* calculate item len */
 	put_ih_item_len( &new_ih, DEH_SIZE * copy_count + copy_records_len );
 	put_ih_entry_count( &new_ih, 0 );
@@ -78,7 +78,7 @@
 		set_le_ih_k_offset (&new_ih, U32_MAX);
 		/* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */
 	    }
-	    set_le_key_k_type (ITEM_VERSION_1, &(new_ih.ih_key), TYPE_DIRENTRY);
+	    set_le_key_k_type (KEY_FORMAT_3_5, &(new_ih.ih_key), TYPE_DIRENTRY);
 	}
     
 	/* insert item into dest buffer */
diff -urN linux-2.4.17-pre4/fs/reiserfs/namei.c linux/fs/reiserfs/namei.c
--- linux-2.4.17-pre4/fs/reiserfs/namei.c	Fri Nov  9 14:18:25 2001
+++ linux/fs/reiserfs/namei.c	Thu Dec  6 10:53:04 2001
@@ -17,17 +17,6 @@
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
 
-				/* there should be an overview right
-                                   here, as there should be in every
-                                   conceptual grouping of code.  This
-                                   should be combined with dir.c and
-                                   called dir.c (naming will become
-                                   too large to be called one file in
-                                   a few years), stop senselessly
-                                   imitating the incoherent
-                                   structuring of code used by other
-                                   filesystems.  */
-
 #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
 #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--;
 
@@ -105,7 +94,7 @@
 	BUG ();
 
     /* store key of the found entry */
-    de->de_entry_key.version = ITEM_VERSION_1;
+    de->de_entry_key.version = KEY_FORMAT_3_5;
     de->de_entry_key.on_disk_key.k_dir_id = le32_to_cpu (de->de_ih->ih_key.k_dir_id);
     de->de_entry_key.on_disk_key.k_objectid = le32_to_cpu (de->de_ih->ih_key.k_objectid);
     set_cpu_key_k_offset (&(de->de_entry_key), deh_offset (deh));
@@ -347,7 +336,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry)
+static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry)
 {
     int retval;
     struct inode * inode = 0;
@@ -373,7 +362,6 @@
     return NULL;
 }
 
-
 //
 // a portion of this function, particularly the VFS interface portion,
 // was derived from minix or ext2's analog and evolved as the
@@ -518,7 +506,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
+static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
 {
     int retval;
     struct inode * inode;
@@ -574,7 +562,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
+static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
     int retval;
     struct inode * inode;
@@ -629,7 +617,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
+static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
 {
     int retval;
     struct inode * inode;
@@ -708,17 +696,20 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
+static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
 {
     int retval;
     struct inode * inode;
     int windex ;
     struct reiserfs_transaction_handle th ;
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
+    int jbegin_count; 
     INITIALIZE_PATH (path);
     struct reiserfs_dir_entry de;
 
 
+    /* we will be doing 2 balancings and update 2 stat data */
+    jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
+
     journal_begin(&th, dir->i_sb, jbegin_count) ;
     windex = push_journal_writer("reiserfs_rmdir") ;
 
@@ -762,6 +753,9 @@
     dir->i_blocks = ((dir->i_size + 511) >> 9);
     reiserfs_update_sd (&th, dir);
 
+    /* prevent empty directory from getting lost */
+    add_save_link (&th, inode, 0/* not truncate */);
+
     pop_journal_writer(windex) ;
     journal_end(&th, dir->i_sb, jbegin_count) ;
     reiserfs_check_path(&path) ;
@@ -785,7 +779,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
+static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
 {
     int retval;
     struct inode * inode;
@@ -793,7 +787,13 @@
     INITIALIZE_PATH (path);
     int windex ;
     struct reiserfs_transaction_handle th ;
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
+    int jbegin_count;
+
+    inode = dentry->d_inode;
+
+    /* in this transaction we can be doing at max two balancings and update
+       two stat datas */
+    jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
 
     journal_begin(&th, dir->i_sb, jbegin_count) ;
     windex = push_journal_writer("reiserfs_unlink") ;
@@ -803,7 +803,6 @@
 	retval = -ENOENT;
 	goto end_unlink;
     }
-    inode = dentry->d_inode;
 
     reiserfs_update_inode_transaction(inode) ;
     reiserfs_update_inode_transaction(dir) ;
@@ -834,6 +833,10 @@
     dir->i_ctime = dir->i_mtime = CURRENT_TIME;
     reiserfs_update_sd (&th, dir);
 
+    if (!inode->i_nlink)
+       /* prevent file from getting lost */
+       add_save_link (&th, inode, 0/* not truncate */);
+
     pop_journal_writer(windex) ;
     journal_end(&th, dir->i_sb, jbegin_count) ;
     reiserfs_check_path(&path) ;
@@ -855,7 +858,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const char * symname)
+static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const char * symname)
 {
     int retval;
     struct inode * inode;
@@ -932,7 +935,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
+static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
 {
     int retval;
     struct inode *inode = old_dentry->d_inode;
@@ -1032,8 +1035,8 @@
  * one path. If it holds 2 or more, it can get into endless waiting in
  * get_empty_nodes or its clones 
  */
-int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
-		     struct inode * new_dir, struct dentry *new_dentry)
+static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
+			    struct inode * new_dir, struct dentry *new_dentry)
 {
     int retval;
     INITIALIZE_PATH (old_entry_path);
@@ -1044,8 +1047,13 @@
     struct inode * old_inode, * new_inode;
     int windex ;
     struct reiserfs_transaction_handle th ;
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
+    int jbegin_count ; 
+
 
+    /* two balancings: old name removal, new name insertion or "save" link,
+       stat data updates: old directory and new directory and maybe block
+       containing ".." of renamed directory */
+    jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3;
 
     old_inode = old_dentry->d_inode;
     new_inode = new_dentry->d_inode;
@@ -1096,8 +1104,8 @@
 	// FIXME: is it possible, that new_inode == 0 here? If yes, it
 	// is not clear how does ext2 handle that
 	if (!new_inode) {
-	    printk ("reiserfs_rename: new entry is found, new inode == 0\n");
-	    BUG ();
+	    reiserfs_panic (old_dir->i_sb,
+			    "vs-7050: new entry is found, new inode == 0\n");
 	}
     } else if (retval) {
 	pop_journal_writer(windex) ;
@@ -1164,13 +1172,6 @@
 	    reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);
 	    if (S_ISDIR(old_inode->i_mode))
 		reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);
-#if 0
-	    // FIXME: do we need this? shouldn't we simply continue?
-	    run_task_queue(&tq_disk);
-	    current->policy |= SCHED_YIELD;
-	    /*current->counter = 0;*/
-	    schedule();
-#endif
 	    continue;
 	}
 
@@ -1195,29 +1196,25 @@
     if (new_inode) {
 	// adjust link number of the victim
 	if (S_ISDIR(new_inode->i_mode)) {
-	  DEC_DIR_INODE_NLINK(new_inode)
+	    new_inode->i_nlink  = 0;
 	} else {
-	  new_inode->i_nlink--;
+	    new_inode->i_nlink--;
 	}
 	new_inode->i_ctime = CURRENT_TIME;
     }
 
     if (S_ISDIR(old_inode->i_mode)) {
-      //if (dot_dot_de.de_bh) {
-	// adjust ".." of renamed directory
+	// adjust ".." of renamed directory 
 	set_ino_in_dir_entry (&dot_dot_de, INODE_PKEY (new_dir));
 	journal_mark_dirty (&th, new_dir->i_sb, dot_dot_de.de_bh);
-
-	DEC_DIR_INODE_NLINK(old_dir)
-	if (new_inode) {
-	    if (S_ISDIR(new_inode->i_mode)) {
-		DEC_DIR_INODE_NLINK(new_inode)
-	    } else {
-	        new_inode->i_nlink--;
-	    }
-	} else {
-	    INC_DIR_INODE_NLINK(new_dir)
-	}
+	
+        if (!new_inode)
+	    /* there (in new_dir) was no directory, so it got new link
+	       (".."  of renamed directory) */
+	    INC_DIR_INODE_NLINK(new_dir);
+		
+	/* old directory lost one link - ".. " of renamed directory */
+	DEC_DIR_INODE_NLINK(old_dir);
     }
 
     // looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse
@@ -1228,18 +1225,40 @@
     // anybody, but it will panic if will not be able to find the
     // entry. This needs one more clean up
     if (reiserfs_cut_from_item (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, 0) < 0)
-	reiserfs_warning ("vs-: reiserfs_rename: coudl not cut old name. Fsck later?\n");
+	reiserfs_warning ("vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?\n");
 
     old_dir->i_size -= DEH_SIZE + old_de.de_entrylen;
     old_dir->i_blocks = ((old_dir->i_size + 511) >> 9);
 
     reiserfs_update_sd (&th, old_dir);
     reiserfs_update_sd (&th, new_dir);
-    if (new_inode)
+
+    if (new_inode) {
+	if (new_inode->i_nlink == 0)
+	    add_save_link (&th, new_inode, 0/* not truncate */);
 	reiserfs_update_sd (&th, new_inode);
+    }
 
     pop_journal_writer(windex) ;
     journal_end(&th, old_dir->i_sb, jbegin_count) ;
     return 0;
 }
+
+
+
+/*
+ * directories can handle most operations...
+ */
+struct inode_operations reiserfs_dir_inode_operations = {
+  //&reiserfs_dir_operations,	/* default_file_ops */
+    create:	reiserfs_create,
+    lookup:	reiserfs_lookup,
+    link:	reiserfs_link,
+    unlink:	reiserfs_unlink,
+    symlink:	reiserfs_symlink,
+    mkdir:	reiserfs_mkdir,
+    rmdir:	reiserfs_rmdir,
+    mknod:	reiserfs_mknod,
+    rename:	reiserfs_rename,
+};
 
diff -urN linux-2.4.17-pre4/fs/reiserfs/objectid.c linux/fs/reiserfs/objectid.c
--- linux-2.4.17-pre4/fs/reiserfs/objectid.c	Fri Nov  9 14:18:25 2001
+++ linux/fs/reiserfs/objectid.c	Thu Dec  6 10:53:04 2001
@@ -162,7 +162,7 @@
 	i += 2;
     }
 
-    reiserfs_warning ("vs-15010: reiserfs_release_objectid: tried to free free object id (%lu)", 
+    reiserfs_warning ("vs-15011: reiserfs_release_objectid: tried to free free object id (%lu)\n", 
 		      ( long unsigned ) objectid_to_release);
 }
 
diff -urN linux-2.4.17-pre4/fs/reiserfs/prints.c linux/fs/reiserfs/prints.c
--- linux-2.4.17-pre4/fs/reiserfs/prints.c	Fri Nov  9 14:18:25 2001
+++ linux/fs/reiserfs/prints.c	Thu Dec  6 10:53:04 2001
@@ -109,7 +109,7 @@
 static void sprintf_item_head (char * buf, struct item_head * ih)
 {
     if (ih) {
-	sprintf (buf, "%s", (ih_version (ih) == ITEM_VERSION_2) ? "*NEW* " : "*OLD*");
+	sprintf (buf, "%s", (ih_version (ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*");
 	sprintf_le_key (buf + strlen (buf), &(ih->ih_key));
 	sprintf (buf + strlen (buf), ", item_len %d, item_location %d, "
 		 "free_space(entry_count) %d",
diff -urN linux-2.4.17-pre4/fs/reiserfs/resize.c linux/fs/reiserfs/resize.c
--- linux-2.4.17-pre4/fs/reiserfs/resize.c	Sat Sep  8 12:05:32 2001
+++ linux/fs/reiserfs/resize.c	Thu Dec  6 10:53:04 2001
@@ -111,7 +111,7 @@
 	    for (i = 0; i < bmap_nr; i++)
 		bitmap[i] = SB_AP_BITMAP(s)[i];
 	    for (i = bmap_nr; i < bmap_nr_new; i++) {
-		bitmap[i] = reiserfs_getblk(s->s_dev, i * s->s_blocksize * 8, s->s_blocksize);
+		bitmap[i] = getblk(s->s_dev, i * s->s_blocksize * 8, s->s_blocksize);
 		memset(bitmap[i]->b_data, 0, sb->s_blocksize);
 		reiserfs_test_and_set_le_bit(0, bitmap[i]->b_data);
 
diff -urN linux-2.4.17-pre4/fs/reiserfs/stree.c linux/fs/reiserfs/stree.c
--- linux-2.4.17-pre4/fs/reiserfs/stree.c	Thu Dec  6 10:52:26 2001
+++ linux/fs/reiserfs/stree.c	Thu Dec  6 10:53:04 2001
@@ -225,7 +225,7 @@
     
     // find out version of the key
     to->version = le_key_version (from);
-    if (to->version == ITEM_VERSION_1) {
+    if (to->version == KEY_FORMAT_3_5) {
 	to->on_disk_key.u.k_offset_v1.k_offset = le32_to_cpu (from->u.k_offset_v1.k_offset);
 	to->on_disk_key.u.k_offset_v1.k_uniqueness = le32_to_cpu (from->u.k_offset_v1.k_uniqueness);
     } else {
@@ -604,7 +604,7 @@
     if (blocknr == 0)
 	return;
 
-    bh = reiserfs_getblk (s->s_dev, blocknr, s->s_blocksize);
+    bh = getblk (s->s_dev, blocknr, s->s_blocksize);
   
     if (!buffer_uptodate (bh)) {
 	ll_rw_block (READA, 1, &bh);
@@ -727,7 +727,11 @@
 	    continue;
 	}
 
-	RFALSE( ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb),
+        /* only check that the key is in the buffer if p_s_key is not
+           equal to the MAX_KEY. Latter case is only possible in
+           "finish_unfinished()" processing during mount. */
+        RFALSE( COMP_KEYS( &MAX_KEY, p_s_key ) && 
+                ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb),
 		"PAP-5130: key is not in the buffer");
 #ifdef CONFIG_REISERFS_CHECK
 	if ( cur_tb ) {
@@ -917,7 +921,7 @@
     }
 	
     // new file gets truncated
-    if (inode_items_version (inode) == ITEM_VERSION_2) {
+    if (get_inode_item_key_version (inode) == KEY_FORMAT_3_6) {
 	// 
 	round_len = ROUND_UP (new_file_length); 
 	/* this was n_new_file_length < le_ih ... */
@@ -1314,8 +1318,8 @@
 
 
 /* this deletes item which never gets split */
-static void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
-					struct key * key)
+void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
+				 struct key * key)
 {
     struct tree_balance tb;
     INITIALIZE_PATH (path);
@@ -1329,13 +1333,13 @@
     while (1) {
 	retval = search_item (th->t_super, &cpu_key, &path);
 	if (retval == IO_ERROR) {
-	    reiserfs_warning ("vs-: reiserfs_delete_solid_item: "
+	    reiserfs_warning ("vs-5350: reiserfs_delete_solid_item: "
 			      "i/o failure occurred trying to delete %K\n", &cpu_key);
 	    break;
 	}
 	if (retval != ITEM_FOUND) {
 	    pathrelse (&path);
-	    reiserfs_warning ("vs-: reiserfs_delete_solid_item: %k not found",
+	    reiserfs_warning ("vs-5355: reiserfs_delete_solid_item: %k not found",
 			      key);
 	    break;
 	}
@@ -1355,7 +1359,7 @@
 	}
 
 	// IO_ERROR, NO_DISK_SPACE, etc
-	reiserfs_warning ("vs-: reiserfs_delete_solid_item: "
+	reiserfs_warning ("vs-5360: reiserfs_delete_solid_item: "
 			  "could not delete %K due to fix_nodes failure\n", &cpu_key);
 	unfix_nodes (&tb);
 	break;
@@ -1372,15 +1376,6 @@
     /* for directory this deletes item containing "." and ".." */
     reiserfs_do_truncate (th, inode, NULL, 0/*no timestamp updates*/);
     
-    /* delete stat data */
-    /* this debug code needs to go away.  Trying to find a truncate race
-    ** -- clm -- 4/1/2000
-    */
-#if 0
-    if (inode->i_nlink != 0) {
-        reiserfs_warning("clm-4001: deleting inode with link count==%d\n", inode->i_nlink) ;
-    }
-#endif
 #if defined( USE_INODE_GENERATION_COUNTER )
     if( !old_format_only ( th -> t_super ) )
       {
@@ -1417,7 +1412,7 @@
     */
     if (atomic_read(&p_s_inode->i_count) > 1 || 
         !tail_has_to_be_packed (p_s_inode) || 
-	!page || p_s_inode->u.reiserfs_i.nopack) {
+        !page || (p_s_inode->u.reiserfs_i.i_flags & i_nopack_mask)) {
 	// leave tail in an unformatted node	
 	*p_c_mode = M_SKIP_BALANCING;
 	cut_bytes = n_block_size - (n_new_file_size & (n_block_size - 1));
@@ -1619,7 +1614,7 @@
 	** be flushed before the transaction commits, so we don't need to 
 	** deal with it here.
 	*/
-	p_s_inode->u.reiserfs_i.i_pack_on_close = 0 ;
+	p_s_inode->u.reiserfs_i.i_flags &= ~i_pack_on_close_mask;
     }
     return n_ret_value;
 }
@@ -1628,14 +1623,14 @@
 static void truncate_directory (struct reiserfs_transaction_handle *th, struct inode * inode)
 {
     if (inode->i_nlink)
-	reiserfs_warning ("vs-5655: truncate_directory: link count != 0");
+	reiserfs_warning ("vs-5655: truncate_directory: link count != 0\n");
 
-    set_le_key_k_offset (ITEM_VERSION_1, INODE_PKEY (inode), DOT_OFFSET);
-    set_le_key_k_type (ITEM_VERSION_1, INODE_PKEY (inode), TYPE_DIRENTRY);
+    set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), DOT_OFFSET);
+    set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_DIRENTRY);
     reiserfs_delete_solid_item (th, INODE_PKEY (inode));
 
-    set_le_key_k_offset (ITEM_VERSION_1, INODE_PKEY (inode), SD_OFFSET);
-    set_le_key_k_type (ITEM_VERSION_1, INODE_PKEY (inode), TYPE_STAT_DATA);    
+    set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), SD_OFFSET);
+    set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_STAT_DATA);    
 }
 
 
@@ -1708,6 +1703,7 @@
 	pathrelse(&s_search_path);
 	return;
     }
+
     /* Update key to search for the last file item. */
     set_cpu_key_k_offset (&s_item_key, n_file_size);
 
@@ -1744,7 +1740,6 @@
 
 	  if (update_timestamps) {
 	      p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME;
-	      // FIXME: sd gets wrong size here
 	  } 
 	  reiserfs_update_sd(th, p_s_inode) ;
 
diff -urN linux-2.4.17-pre4/fs/reiserfs/super.c linux/fs/reiserfs/super.c
--- linux-2.4.17-pre4/fs/reiserfs/super.c	Fri Nov  9 14:18:25 2001
+++ linux/fs/reiserfs/super.c	Thu Dec  6 10:53:04 2001
@@ -26,6 +26,9 @@
 char reiserfs_super_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
 char reiser2fs_super_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
 
+static int reiserfs_remount (struct super_block * s, int * flags, char * data);
+static int reiserfs_statfs (struct super_block * s, struct statfs * buf);
+
 //
 // a portion of this function, particularly the VFS interface portion,
 // was derived from minix or ext2's analog and evolved as the
@@ -33,7 +36,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-void reiserfs_write_super (struct super_block * s)
+static void reiserfs_write_super (struct super_block * s)
 {
 
   int dirty = 0 ;
@@ -52,7 +55,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-void reiserfs_write_super_lockfs (struct super_block * s)
+static void reiserfs_write_super_lockfs (struct super_block * s)
 {
 
   int dirty = 0 ;
@@ -73,6 +76,247 @@
   reiserfs_allow_writes(s) ;
 }
 
+extern const struct key  MAX_KEY;
+
+
+/* this is used to delete "save link" when there are no items of a
+   file it points to. It can either happen if unlink is completed but
+   "save unlink" removal, or if file has both unlink and truncate
+   pending and as unlink completes first (because key of "save link"
+   protecting unlink is bigger that a key lf "save link" which
+   protects truncate), so there left no items to make truncate
+   completion on */
+static void remove_save_link_only (struct super_block * s, struct key * key)
+{
+    struct reiserfs_transaction_handle th;
+
+     /* we are going to do one balancing */
+     journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT);
+ 
+     reiserfs_delete_solid_item (&th, key);
+     if (is_direct_le_key (KEY_FORMAT_3_5, key))
+        /* removals are protected by direct items */
+        reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid));
+
+     journal_end (&th, s, JOURNAL_PER_BALANCE_CNT);
+}
+ 
+ 
+/* look for uncompleted unlinks and truncates and complete them */
+static void finish_unfinished (struct super_block * s)
+{
+    INITIALIZE_PATH (path);
+    struct cpu_key max_cpu_key, obj_key;
+    struct key save_link_key;
+    int retval;
+    struct item_head * ih;
+    struct buffer_head * bh;
+    int item_pos;
+    char * item;
+    int done;
+    struct inode * inode;
+    int truncate;
+ 
+ 
+    /* compose key to look for "save" links */
+    max_cpu_key.version = KEY_FORMAT_3_5;
+    max_cpu_key.on_disk_key = MAX_KEY;
+    max_cpu_key.key_length = 3;
+ 
+    done = 0;
+    s -> u.reiserfs_sb.s_is_unlinked_ok = 1;
+    while (1) {
+        retval = search_item (s, &max_cpu_key, &path);
+        if (retval != ITEM_NOT_FOUND) {
+            reiserfs_warning ("vs-2140: finish_unfinished: search_by_key returned %d\n",
+                              retval);
+            break;
+        }
+        
+        bh = get_last_bh (&path);
+        item_pos = get_item_pos (&path);
+        if (item_pos != B_NR_ITEMS (bh)) {
+            reiserfs_warning ("vs-2060: finish_unfinished: wrong position found\n");
+            break;
+        }
+        item_pos --;
+        ih = B_N_PITEM_HEAD (bh, item_pos);
+ 
+        if (le32_to_cpu (ih->ih_key.k_dir_id) != MAX_KEY_OBJECTID)
+            /* there are no "save" links anymore */
+            break;
+ 
+        save_link_key = ih->ih_key;
+        if (is_indirect_le_ih (ih))
+            truncate = 1;
+        else
+            truncate = 0;
+ 
+        /* reiserfs_iget needs k_dirid and k_objectid only */
+        item = B_I_PITEM (bh, ih);
+        obj_key.on_disk_key.k_dir_id = le32_to_cpu (*(__u32 *)item);
+        obj_key.on_disk_key.k_objectid = le32_to_cpu (ih->ih_key.k_objectid);
+	obj_key.on_disk_key.u.k_offset_v1.k_offset = 0;
+	obj_key.on_disk_key.u.k_offset_v1.k_uniqueness = 0;
+	
+        pathrelse (&path);
+ 
+        inode = reiserfs_iget (s, &obj_key);
+        if (!inode) {
+            /* the unlink almost completed, it just did not manage to remove
+	       "save" link and release objectid */
+            reiserfs_warning ("vs-2180: finish_unfinished: iget failed for %K\n",
+                              &obj_key);
+            remove_save_link_only (s, &save_link_key);
+            continue;
+        }
+
+	if (!truncate && inode->i_nlink) {
+	    /* file is not unlinked */
+            reiserfs_warning ("vs-2185: finish_unfinished: file %K is not unlinked\n",
+                              &obj_key);
+            remove_save_link_only (s, &save_link_key);
+            continue;
+	}
+ 
+        if (truncate) {
+            inode -> u.reiserfs_i.i_flags |= i_link_saved_truncate_mask;
+            /* not completed truncate found. New size was committed together
+	       with "save" link */
+            reiserfs_warning ("Truncating %k to %Ld ..",
+                              INODE_PKEY (inode), inode->i_size);
+            reiserfs_truncate_file (inode, 0/*don't update modification time*/);
+            remove_save_link (inode, truncate);
+        } else {
+            inode -> u.reiserfs_i.i_flags |= i_link_saved_unlink_mask;
+            /* not completed unlink (rmdir) found */
+            reiserfs_warning ("Removing %k..", INODE_PKEY (inode));
+            /* removal gets completed in iput */
+        }
+ 
+        iput (inode);
+        reiserfs_warning ("done\n");
+        done ++;
+    }
+    s -> u.reiserfs_sb.s_is_unlinked_ok = 0;
+     
+    pathrelse (&path);
+    if (done)
+        reiserfs_warning ("There were %d uncompleted unlinks/truncates. "
+                          "Completed\n", done);
+}
+ 
+/* to protect file being unlinked from getting lost we "safe" link files
+   being unlinked. This link will be deleted in the same transaction with last
+   item of file. mounting the filesytem we scan all these links and remove
+   files which almost got lost */
+void add_save_link (struct reiserfs_transaction_handle * th,
+		    struct inode * inode, int truncate)
+{
+    INITIALIZE_PATH (path);
+    int retval;
+    struct cpu_key key;
+    struct item_head ih;
+    __u32 link;
+
+    /* file can only get one "save link" of each kind */
+    RFALSE( truncate && 
+	    ( inode -> u.reiserfs_i.i_flags & i_link_saved_truncate_mask ),
+	    "saved link already exists for truncated inode %lx",
+	    ( long ) inode -> i_ino );
+    RFALSE( !truncate && 
+	    ( inode -> u.reiserfs_i.i_flags & i_link_saved_unlink_mask ),
+	    "saved link already exists for unlinked inode %lx",
+	    ( long ) inode -> i_ino );
+
+    /* setup key of "save" link */
+    key.version = KEY_FORMAT_3_5;
+    key.on_disk_key.k_dir_id = MAX_KEY_OBJECTID;
+    key.on_disk_key.k_objectid = inode->i_ino;
+    if (!truncate) {
+	/* unlink, rmdir, rename */
+	set_cpu_key_k_offset (&key, 1 + inode->i_sb->s_blocksize);
+	set_cpu_key_k_type (&key, TYPE_DIRECT);
+
+	/* item head of "safe" link */
+	make_le_item_head (&ih, &key, key.version, 1 + inode->i_sb->s_blocksize, TYPE_DIRECT,
+			   4/*length*/, 0xffff/*free space*/);
+    } else {
+	/* truncate */
+	set_cpu_key_k_offset (&key, 1);
+	set_cpu_key_k_type (&key, TYPE_INDIRECT);
+
+	/* item head of "safe" link */
+	make_le_item_head (&ih, &key, key.version, 1, TYPE_INDIRECT,
+			   4/*length*/, 0/*free space*/);
+    }
+    key.key_length = 3;
+
+    /* look for its place in the tree */
+    retval = search_item (inode->i_sb, &key, &path);
+    if (retval != ITEM_NOT_FOUND) {
+	reiserfs_warning ("vs-2100: add_save_link:"
+			  "search_by_key (%K) returned %d\n", &key, retval);
+	pathrelse (&path);
+	return;
+    }
+
+    /* body of "save" link */
+    link = cpu_to_le32 (INODE_PKEY (inode)->k_dir_id);
+
+    /* put "save" link inot tree */
+    retval = reiserfs_insert_item (th, &path, &key, &ih, (char *)&link);
+    if (retval)
+	reiserfs_warning ("vs-2120: add_save_link: insert_item returned %d\n",
+			  retval);
+    else {
+	if( truncate )
+	    inode -> u.reiserfs_i.i_flags |= i_link_saved_truncate_mask;
+	else
+	    inode -> u.reiserfs_i.i_flags |= i_link_saved_unlink_mask;
+    }
+}
+
+
+/* this opens transaction unlike add_save_link */
+void remove_save_link (struct inode * inode, int truncate)
+{
+    struct reiserfs_transaction_handle th;
+    struct key key;
+ 
+ 
+    /* we are going to do one balancing only */
+    journal_begin (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
+ 
+    /* setup key of "save" link */
+    key.k_dir_id = cpu_to_le32 (MAX_KEY_OBJECTID);
+    key.k_objectid = INODE_PKEY (inode)->k_objectid;
+    if (!truncate) {
+        /* unlink, rmdir, rename */
+        set_le_key_k_offset (KEY_FORMAT_3_5, &key,
+			     1 + inode->i_sb->s_blocksize);
+        set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_DIRECT);
+    } else {
+        /* truncate */
+        set_le_key_k_offset (KEY_FORMAT_3_5, &key, 1);
+        set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_INDIRECT);
+    }
+ 
+    if( ( truncate && 
+          ( inode -> u.reiserfs_i.i_flags & i_link_saved_truncate_mask ) ) ||
+        ( !truncate && 
+          ( inode -> u.reiserfs_i.i_flags & i_link_saved_unlink_mask ) ) )
+	reiserfs_delete_solid_item (&th, &key);
+    if (!truncate) {
+	reiserfs_release_objectid (&th, inode->i_ino);
+	inode -> u.reiserfs_i.i_flags &= ~i_link_saved_unlink_mask;
+    } else
+	inode -> u.reiserfs_i.i_flags &= ~i_link_saved_truncate_mask;
+ 
+    journal_end (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
+}
+
+
 //
 // a portion of this function, particularly the VFS interface portion,
 // was derived from minix or ext2's analog and evolved as the
@@ -80,7 +324,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-void reiserfs_put_super (struct super_block * s)
+static void reiserfs_put_super (struct super_block * s)
 {
   int i;
   struct reiserfs_transaction_handle th ;
@@ -123,6 +367,26 @@
   return;
 }
 
+/* we don't mark inodes dirty, we just log them */
+static void reiserfs_dirty_inode (struct inode * inode) {
+    struct reiserfs_transaction_handle th ;
+
+    if (inode->i_sb->s_flags & MS_RDONLY) {
+        reiserfs_warning("clm-6006: writing inode %lu on readonly FS\n", 
+	                  inode->i_ino) ;
+        return ;
+    }
+    lock_kernel() ;
+
+    /* this is really only used for atime updates, so they don't have
+    ** to be included in O_SYNC or fsync
+    */
+    journal_begin(&th, inode->i_sb, 1) ;
+    reiserfs_update_sd (&th, inode);
+    journal_end(&th, inode->i_sb, 1) ;
+    unlock_kernel() ;
+}
+
 struct super_operations reiserfs_sops = 
 {
   read_inode: reiserfs_read_inode,
@@ -231,7 +495,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-int reiserfs_remount (struct super_block * s, int * flags, char * data)
+static int reiserfs_remount (struct super_block * s, int * flags, char * data)
 {
   struct reiserfs_super_block * rs;
   struct reiserfs_transaction_handle th ;
@@ -284,6 +548,10 @@
   /* this will force a full flush of all journal lists */
   SB_JOURNAL(s)->j_must_wait = 1 ;
   journal_end(&th, s, 10) ;
+
+  if (!( *flags & MS_RDONLY ) )
+    finish_unfinished( s );
+
   return 0;
 }
 
@@ -608,7 +876,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent)
+static struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent)
 {
     int size;
     struct inode *root_inode;
@@ -744,6 +1012,10 @@
 
 	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
 	journal_end(&th, s, 1) ;
+	
+	/* look for files which were to be removed in previous session */
+	finish_unfinished (s);
+
 	s->s_dirt = 0;
     } else {
 	struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
@@ -792,7 +1064,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-int reiserfs_statfs (struct super_block * s, struct statfs * buf)
+static int reiserfs_statfs (struct super_block * s, struct statfs * buf)
 {
   struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
   
@@ -835,6 +1107,7 @@
 	reiserfs_proc_info_global_done();
         unregister_filesystem(&reiserfs_fs_type);
 }
+
 
 module_init(init_reiserfs_fs) ;
 module_exit(exit_reiserfs_fs) ;
diff -urN linux-2.4.17-pre4/fs/reiserfs/tail_conversion.c linux/fs/reiserfs/tail_conversion.c
--- linux-2.4.17-pre4/fs/reiserfs/tail_conversion.c	Tue Oct 30 15:11:34 2001
+++ linux/fs/reiserfs/tail_conversion.c	Thu Dec  6 10:53:04 2001
@@ -240,7 +240,7 @@
 
 
     /* Set direct item header to insert. */
-    make_le_item_head (&s_ih, 0, inode_items_version (p_s_inode), pos1 + 1,
+    make_le_item_head (&s_ih, 0, get_inode_item_key_version (p_s_inode), pos1 + 1,
 		       TYPE_DIRECT, round_tail_len, 0xffff/*ih_free_space*/);
 
     /* we want a pointer to the first byte of the tail in the page.
diff -urN linux-2.4.17-pre4/include/asm-i386/cpufeature.h linux/include/asm-i386/cpufeature.h
--- linux-2.4.17-pre4/include/asm-i386/cpufeature.h	Sun Nov 12 21:55:50 2000
+++ linux/include/asm-i386/cpufeature.h	Thu Dec  6 10:53:04 2001
@@ -40,6 +40,7 @@
 #define X86_FEATURE_XMM		(0*32+25) /* Streaming SIMD Extensions */
 #define X86_FEATURE_XMM2	(0*32+26) /* Streaming SIMD Extensions-2 */
 #define X86_FEATURE_SELFSNOOP	(0*32+27) /* CPU self snoop */
+#define X86_FEATURE_HT		(0*32+28) /* Hyper-Threading */
 #define X86_FEATURE_ACC		(0*32+29) /* Automatic clock control */
 #define X86_FEATURE_IA64	(0*32+30) /* IA-64 processor */
 
diff -urN linux-2.4.17-pre4/include/asm-i386/msr.h linux/include/asm-i386/msr.h
--- linux-2.4.17-pre4/include/asm-i386/msr.h	Sat Sep  1 11:01:28 2001
+++ linux/include/asm-i386/msr.h	Thu Dec  6 10:53:04 2001
@@ -81,6 +81,7 @@
 
 #define MSR_K7_EVNTSEL0			0xC0010000
 #define MSR_K7_PERFCTR0			0xC0010004
+#define MSR_K7_HWCR			0xC0010015
 
 /* Centaur-Hauls/IDT defined MSRs. */
 #define MSR_IDT_FCR1			0x107
diff -urN linux-2.4.17-pre4/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- linux-2.4.17-pre4/include/asm-i386/smp.h	Thu Nov 22 11:46:19 2001
+++ linux/include/asm-i386/smp.h	Thu Dec  6 10:53:04 2001
@@ -57,6 +57,9 @@
 extern unsigned long cpu_online_map;
 extern volatile unsigned long smp_invalidate_needed;
 extern int pic_mode;
+extern int smp_num_siblings;
+extern int cpu_sibling_map[];
+
 extern void smp_flush_tlb(void);
 extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
 extern void smp_send_reschedule(int cpu);
diff -urN linux-2.4.17-pre4/include/asm-sparc64/pgtable.h linux/include/asm-sparc64/pgtable.h
--- linux-2.4.17-pre4/include/asm-sparc64/pgtable.h	Tue Nov 13 09:16:05 2001
+++ linux/include/asm-sparc64/pgtable.h	Thu Dec  6 10:53:04 2001
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.152 2001/11/12 09:43:39 davem Exp $
+/* $Id: pgtable.h,v 1.154 2001/12/05 06:05:36 davem Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -19,6 +19,23 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 
+/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 16MB).
+ * The page copy blockops use 0x1000000 to 0x18000000 (16MB --> 24MB).
+ * The PROM resides in an area spanning 0xf0000000 to 0x100000000.
+ * The vmalloc area spans 0x140000000 to 0x200000000.
+ * There is a single static kernel PMD which maps from 0x0 to address
+ * 0x400000000.
+ */
+#define	TLBTEMP_BASE		0x0000000001000000
+#define MODULES_VADDR		0x0000000002000000
+#define MODULES_LEN		0x000000007e000000
+#define MODULES_END		0x0000000080000000
+#define VMALLOC_START		0x0000000140000000
+#define VMALLOC_VMADDR(x)	((unsigned long)(x))
+#define VMALLOC_END		0x0000000200000000
+#define LOW_OBP_ADDRESS		0x00000000f0000000
+#define HI_OBP_ADDRESS		0x0000000100000000
+
 /* XXX All of this needs to be rethought so we can take advantage
  * XXX cheetah's full 64-bit virtual address space, ie. no more hole
  * XXX in the middle like on spitfire. -DaveM
@@ -77,13 +94,6 @@
 				 (1) : (PTRS_PER_PGD)))
 #define FIRST_USER_PGD_NR	0
 
-/* NOTE: TLB miss handlers depend heavily upon where this is. */
-#define VMALLOC_START		0x0000000140000000UL
-#define VMALLOC_VMADDR(x)	((unsigned long)(x))
-#define VMALLOC_END		0x0000000200000000UL
-#define LOW_OBP_ADDRESS		0xf0000000UL
-#define HI_OBP_ADDRESS		0x100000000UL
-
 #define pte_ERROR(e)	__builtin_trap()
 #define pmd_ERROR(e)	__builtin_trap()
 #define pgd_ERROR(e)	__builtin_trap()
@@ -290,8 +300,6 @@
 #define swp_entry_to_pte(x)		((pte_t) { (x).val })
 
 extern unsigned long prom_virt_to_phys(unsigned long, int *);
-#define LOW_OBP_ADDRESS		0xf0000000UL
-#define HI_OBP_ADDRESS		0x100000000UL
 
 extern __inline__ unsigned long
 sun4u_get_pte (unsigned long addr)
diff -urN linux-2.4.17-pre4/include/asm-sparc64/smplock.h linux/include/asm-sparc64/smplock.h
--- linux-2.4.17-pre4/include/asm-sparc64/smplock.h	Thu Mar 23 12:50:09 2000
+++ linux/include/asm-sparc64/smplock.h	Thu Dec  6 10:53:04 2001
@@ -9,7 +9,9 @@
 
 extern spinlock_t kernel_flag;
 
-#define kernel_locked()		spin_is_locked(&kernel_flag)
+#define kernel_locked()			\
+	(spin_is_locked(&kernel_flag) &&\
+	 (current->lock_depth >= 0))
 
 /*
  * Release global kernel lock and global interrupt lock
diff -urN linux-2.4.17-pre4/include/asm-sparc64/spitfire.h linux/include/asm-sparc64/spitfire.h
--- linux-2.4.17-pre4/include/asm-sparc64/spitfire.h	Mon Oct  1 09:19:56 2001
+++ linux/include/asm-sparc64/spitfire.h	Thu Dec  6 10:53:04 2001
@@ -1,4 +1,4 @@
-/* $Id: spitfire.h,v 1.16 2001/09/24 21:17:57 kanoj Exp $
+/* $Id: spitfire.h,v 1.18 2001/11/29 16:42:10 kanoj Exp $
  * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -32,6 +32,8 @@
 #define VIRT_WATCHPOINT		0x0000000000000038
 #define PHYS_WATCHPOINT		0x0000000000000040
 
+#define SPITFIRE_HIGHEST_LOCKED_TLBENT	(64 - 1)
+
 #ifndef __ASSEMBLY__
 
 enum ultra_tlb_layout {
@@ -43,7 +45,6 @@
 
 #define SPARC64_USE_STICK	(tlb_type == cheetah)
 
-#define SPITFIRE_HIGHEST_LOCKED_TLBENT	(64 - 1)
 #define CHEETAH_HIGHEST_LOCKED_TLBENT	(16 - 1)
 
 #define L1DCACHE_SIZE		0x4000
@@ -357,12 +358,17 @@
  * 2 way assosciative, and holds 512 entries.  The fourth TLB is for
  * instruction accesses to 8K non-locked translations, is 2 way
  * assosciative, and holds 128 entries.
+ *
+ * Cheetah has some bug where bogus data can be returned from
+ * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes
+ * the problem for me. -DaveM
  */
 extern __inline__ unsigned long cheetah_get_ldtlb_data(int entry)
 {
 	unsigned long data;
 
-	__asm__ __volatile__("ldxa	[%1] %2, %0"
+	__asm__ __volatile__("ldxa	[%1] %2, %%g0\n\t"
+			     "ldxa	[%1] %2, %0"
 			     : "=r" (data)
 			     : "r" ((0 << 16) | (entry << 3)),
 			     "i" (ASI_DTLB_DATA_ACCESS));
@@ -374,7 +380,8 @@
 {
 	unsigned long data;
 
-	__asm__ __volatile__("ldxa	[%1] %2, %0"
+	__asm__ __volatile__("ldxa	[%1] %2, %%g0\n\t"
+			     "ldxa	[%1] %2, %0"
 			     : "=r" (data)
 			     : "r" ((0 << 16) | (entry << 3)),
 			     "i" (ASI_ITLB_DATA_ACCESS));
@@ -430,7 +437,8 @@
 {
 	unsigned long data;
 
-	__asm__ __volatile__("ldxa	[%1] %2, %0"
+	__asm__ __volatile__("ldxa	[%1] %2, %%g0\n\t"
+			     "ldxa	[%1] %2, %0"
 			     : "=r" (data)
 			     : "r" ((2 << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS));
 
@@ -461,7 +469,8 @@
 {
 	unsigned long data;
 
-	__asm__ __volatile__("ldxa	[%1] %2, %0"
+	__asm__ __volatile__("ldxa	[%1] %2, %%g0\n\t"
+			     "ldxa	[%1] %2, %0"
 			     : "=r" (data)
 			     : "r" ((2 << 16) | (entry << 3)),
                                "i" (ASI_ITLB_DATA_ACCESS));
diff -urN linux-2.4.17-pre4/include/asm-sparc64/ttable.h linux/include/asm-sparc64/ttable.h
--- linux-2.4.17-pre4/include/asm-sparc64/ttable.h	Thu Apr 12 12:10:25 2001
+++ linux/include/asm-sparc64/ttable.h	Thu Dec  6 10:53:04 2001
@@ -1,4 +1,4 @@
-/* $Id: ttable.h,v 1.16 2001/03/28 10:56:34 davem Exp $ */
+/* $Id: ttable.h,v 1.17 2001/11/28 23:32:16 davem Exp $ */
 #ifndef _SPARC64_TTABLE_H
 #define _SPARC64_TTABLE_H
 
@@ -29,6 +29,15 @@
 	 clr	%l6;					\
 	nop;
 
+#define TRAP_7INSNS(routine)				\
+	sethi	%hi(109f), %g7;				\
+	ba,pt	%xcc, etrap;				\
+109:	 or	%g7, %lo(109b), %g7;			\
+	call	routine;				\
+	 add	%sp, STACK_BIAS + REGWIN_SZ, %o0;	\
+	ba,pt	%xcc, rtrap;				\
+	 clr	%l6;
+
 #define TRAP_SAVEFPU(routine)				\
 	sethi	%hi(109f), %g7;				\
 	ba,pt	%xcc, do_fptrap;			\
@@ -43,6 +52,11 @@
 	ba,pt	%xcc, routine;				\
 	 nop;						\
 	nop; nop; nop; nop; nop; nop;
+	
+#define TRAP_NOSAVE_7INSNS(routine)			\
+	ba,pt	%xcc, routine;				\
+	 nop;						\
+	nop; nop; nop; nop; nop;
 	
 #define TRAPTL1(routine)				\
 	sethi	%hi(109f), %g7;				\
diff -urN linux-2.4.17-pre4/include/linux/reiserfs_fs.h linux/include/linux/reiserfs_fs.h
--- linux-2.4.17-pre4/include/linux/reiserfs_fs.h	Fri Nov  9 14:18:25 2001
+++ linux/include/linux/reiserfs_fs.h	Thu Dec  6 10:53:04 2001
@@ -52,48 +52,17 @@
 
 */
 
-				/* Vladimir, what is the story with
-                                   new_get_new_buffer nowadays?  I
-                                   want a complete explanation written
-                                   here. */
-
-/* NEW_GET_NEW_BUFFER will try to allocate new blocks better */
-/*#define NEW_GET_NEW_BUFFER*/
-#define OLD_GET_NEW_BUFFER
-
-				/* Vladimir, what about this one too? */
-/* if this is undefined, all inode changes get into stat data immediately, if it can be found in RAM */
-#define DIRTY_LATER
-
-/* enable journalling */
-#define ENABLE_JOURNAL
-
 #define USE_INODE_GENERATION_COUNTER
 
-
-#ifdef __KERNEL__
-
-/* #define REISERFS_CHECK */
-
 #define REISERFS_PREALLOCATE
-#endif
 #define PREALLOCATION_SIZE 8
 
-/* if this is undefined, all inode changes get into stat data
-   immediately, if it can be found in RAM */
-#define DIRTY_LATER
-
-
-/*#define READ_LOCK_REISERFS*/
-
-
 /* n must be power of 2 */
 #define _ROUND_UP(x,n) (((x)+(n)-1u) & ~((n)-1u))
 
 // to be ok for alpha and others we have to align structures to 8 byte
 // boundary.
 // FIXME: do not change 4 by anything else: there is code which relies on that
-				/* what 4? -Hans */
 #define ROUND_UP(x) _ROUND_UP(x,8LL)
 
 /* debug levels.  Right now, CONFIG_REISERFS_CHECK means print all debug
@@ -148,22 +117,17 @@
 		      strlen ( reiser2fs_super_magic_string)));
 }
 
-				/* ReiserFS leaves the first 64k unused,
-                                   so that partition labels have enough
-                                   space.  If someone wants to write a
-                                   fancy bootloader that needs more than
-                                   64k, let us know, and this will be
-                                   increased in size.  This number must
-                                   be larger than than the largest block
-                                   size on any platform, or code will
-                                   break.  -Hans */
+/* ReiserFS leaves the first 64k unused, so that partition labels have
+   enough space.  If someone wants to write a fancy bootloader that
+   needs more than 64k, let us know, and this will be increased in size.
+   This number must be larger than than the largest block size on any
+   platform, or code will break.  -Hans */
 #define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
 #define REISERFS_FIRST_BLOCK unused_define
 
 /* the spot for the super in versions 3.5 - 3.5.10 (inclusive) */
 #define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)
 
-
 // reiserfs internal error code (used by search_by_key adn fix_nodes))
 #define CARRY_ON      0
 #define REPEAT_SEARCH -1
@@ -172,53 +136,54 @@
 #define NO_BALANCING_NEEDED  (-4)
 #define NO_MORE_UNUSED_CONTIGUOUS_BLOCKS (-5)
 
-//#define SCHEDULE_OCCURRED  	1
-//#define PATH_INCORRECT    	2
-
-//#define NO_DISK_SPACE        (-1)
-
-
-
 typedef unsigned long b_blocknr_t;
 typedef __u32 unp_t;
 
-				/* who is responsible for this
-                                   completely uncommented struct? */
 struct unfm_nodeinfo {
-				/* This is what? */
     unp_t unfm_nodenum;
-				/* now this I know what it is, and
-                                   most of the people on our project
-                                   know what it is, but I bet nobody
-                                   new I hire will have a clue. */
     unsigned short unfm_freespace;
 };
 
 
-/* when reiserfs_file_write is called with a byte count >= MIN_PACK_ON_CLOSE,
-** it sets the inode to pack on close, and when extending the file, will only
-** use unformatted nodes.
-**
-** This is a big speed up for the journal, which is badly hurt by direct->indirect
-** conversions (they must be logged).
-*/
-#define MIN_PACK_ON_CLOSE		512
+/* there are two formats of keys: 3.5 and 3.6
+ */
+#define KEY_FORMAT_3_5 0
+#define KEY_FORMAT_3_6 1
 
-// this says about version of all items (but stat data) the object
-// consists of
-#define inode_items_version(inode) ((inode)->u.reiserfs_i.i_version)
-
-
-  /* This is an aggressive tail suppression policy, I am hoping it
-     improves our benchmarks. The principle behind it is that
-     percentage space saving is what matters, not absolute space
-     saving.  This is non-intuitive, but it helps to understand it if
-     you consider that the cost to access 4 blocks is not much more
-     than the cost to access 1 block, if you have to do a seek and
-     rotate.  A tail risks a non-linear disk access that is
-     significant as a percentage of total time cost for a 4 block file
-     and saves an amount of space that is less significant as a
-     percentage of space, or so goes the hypothesis.  -Hans */
+/* there are two stat datas */
+#define STAT_DATA_V1 0
+#define STAT_DATA_V2 1
+
+/** this says about version of key of all items (but stat data) the
+    object consists of */
+#define get_inode_item_key_version( inode )                                    \
+    (((inode)->u.reiserfs_i.i_flags & i_item_key_version_mask) ? KEY_FORMAT_3_6 : KEY_FORMAT_3_5)
+
+#define set_inode_item_key_version( inode, version )                           \
+         ({ if((version)==KEY_FORMAT_3_6)                                      \
+                (inode)->u.reiserfs_i.i_flags |= i_item_key_version_mask;      \
+            else                                                               \
+                (inode)->u.reiserfs_i.i_flags &= ~i_item_key_version_mask; })
+
+#define get_inode_sd_version(inode)                                            \
+    (((inode)->u.reiserfs_i.i_flags & i_stat_data_version_mask) ? STAT_DATA_V2 : STAT_DATA_V1)
+
+#define set_inode_sd_version(inode, version)                                   \
+         ({ if((version)==STAT_DATA_V2)                                        \
+                (inode)->u.reiserfs_i.i_flags |= i_stat_data_version_mask;     \
+            else                                                               \
+                (inode)->u.reiserfs_i.i_flags &= ~i_stat_data_version_mask; })
+
+/* This is an aggressive tail suppression policy, I am hoping it
+   improves our benchmarks. The principle behind it is that percentage
+   space saving is what matters, not absolute space saving.  This is
+   non-intuitive, but it helps to understand it if you consider that the
+   cost to access 4 blocks is not much more than the cost to access 1
+   block, if you have to do a seek and rotate.  A tail risks a
+   non-linear disk access that is significant as a percentage of total
+   time cost for a 4 block file and saves an amount of space that is
+   less significant as a percentage of space, or so goes the hypothesis.
+   -Hans */
 #define STORE_TAIL_IN_UNFM(n_file_size,n_tail_size,n_block_size) \
 (\
   (!(n_tail_size)) || \
@@ -246,21 +211,6 @@
 /***************************************************************************/
 
 //
-// we do support for old format of reiserfs: the problem is to
-// distinuquish keys with 32 bit offset and keys with 60 bit ones. On
-// leaf level we use ih_version of struct item_head (was
-// ih_reserved). For all old items it is set to 0
-// (ITEM_VERSION_1). For new items it is ITEM_VERSION_2. On internal
-// levels we have to know version of item key belongs to.
-//
-#define ITEM_VERSION_1 0
-#define ITEM_VERSION_2 1
-
-
-/* loff_t - long long */
-
-
-//
 // directories use this key as well as old files
 //
 struct offset_v1 {
@@ -341,18 +291,11 @@
 		       indirect2direct conversion */
 };
 
-
-
-
-
-
-
- /* Our function for comparing keys can compare keys of different
-    lengths.  It takes as a parameter the length of the keys it is to
-    compare.  These defines are used in determining what is to be
-    passed to it as that parameter. */
+/* Our function for comparing keys can compare keys of different
+   lengths.  It takes as a parameter the length of the keys it is to
+   compare.  These defines are used in determining what is to be passed
+   to it as that parameter. */
 #define REISERFS_FULL_KEY_LEN     4
-
 #define REISERFS_SHORT_KEY_LEN    2
 
 /* The result of the key compare */
@@ -362,7 +305,6 @@
 #define KEY_FOUND 1
 #define KEY_NOT_FOUND 0
 
-
 #define KEY_SIZE (sizeof(struct key))
 #define SHORT_KEY_SIZE (sizeof (__u32) + sizeof (__u32))
 
@@ -387,8 +329,6 @@
 #define GOTO_PREVIOUS_ITEM 2
 #define NAME_FOUND_INVISIBLE 3
 
-
-
 /*  Everything in the filesystem is stored as a set of items.  The
     item head contains the key of the item, its free space (for
     indirect items) and specifies the location of the item itself
@@ -396,37 +336,28 @@
 
 struct item_head
 {
-  struct key ih_key; 	/* Everything in the tree is found by searching for it based on its key.*/
-
-				/* This is bloat, this should be part
-                                   of the item not the item
-                                   header. -Hans */
-  union {
-    __u16 ih_free_space_reserved; /* The free space in the last unformatted node of an indirect item if this
-				     is an indirect item.  This equals 0xFFFF iff this is a direct item or
-				     stat data item. Note that the key, not this field, is used to determine
-				     the item type, and thus which field this union contains. */
-    __u16 ih_entry_count; /* Iff this is a directory item, this field equals the number of directory
-				      entries in the directory item. */
-  } __attribute__ ((__packed__)) u;
-  __u16 ih_item_len;           /* total size of the item body */
-  __u16 ih_item_location;      /* an offset to the item body within the block */
-				/* I thought we were going to use this
-                                   for having lots of item types? Why
-                                   don't you use this for item type
-                                   not item version.  That is how you
-                                   talked me into this field a year
-                                   ago, remember?  I am still not
-                                   convinced it needs to be 16 bits
-                                   (for at least many years), but at
-                                   least I can sympathize with that
-                                   hope. Change the name from version
-                                   to type, and tell people not to use
-                                   FFFF in case 16 bits is someday too
-                                   small and needs to be extended:-). */
-  __u16 ih_version;	       /* 0 for all old items, 2 for new
-                                  ones. Highest bit is set by fsck
-                                  temporary, cleaned after all done */
+	/* Everything in the tree is found by searching for it based on
+	 * its key.*/
+	struct key ih_key; 	
+	union {
+		/* The free space in the last unformatted node of an
+		   indirect item if this is an indirect item.  This
+		   equals 0xFFFF iff this is a direct item or stat data
+		   item. Note that the key, not this field, is used to
+		   determine the item type, and thus which field this
+		   union contains. */
+		__u16 ih_free_space_reserved; 
+		/* Iff this is a directory item, this field equals the
+		   number of directory entries in the directory item. */
+		__u16 ih_entry_count; 
+	} __attribute__ ((__packed__)) u;
+	__u16 ih_item_len;           /* total size of the item body */
+	__u16 ih_item_location;      /* an offset to the item body
+				      * within the block */
+	__u16 ih_version;	     /* 0 for all old items, 2 for new
+					ones. Highest bit is set by fsck
+					temporary, cleaned after all
+					done */
 } __attribute__ ((__packed__));
 /* size of item header     */
 #define IH_SIZE (sizeof(struct item_head))
@@ -446,8 +377,8 @@
 
 #define unreachable_item(ih) (ih_version(ih) & (1 << 15))
 
-#define get_ih_free_space(ih) (ih_version (ih) == ITEM_VERSION_2 ? 0 : ih_free_space (ih))
-#define set_ih_free_space(ih,val) put_ih_free_space((ih), ((ih_version(ih) == ITEM_VERSION_2) ? 0 : (val)))
+#define get_ih_free_space(ih) (ih_version (ih) == KEY_FORMAT_3_6 ? 0 : ih_free_space (ih))
+#define set_ih_free_space(ih,val) put_ih_free_space((ih), ((ih_version(ih) == KEY_FORMAT_3_6) ? 0 : (val)))
 
 /* these operate on indirect items, where you've got an array of ints
 ** at a possibly unaligned location.  These are a noop on ia32
@@ -476,6 +407,9 @@
 #define V1_DIRENTRY_UNIQUENESS 500
 #define V1_ANY_UNIQUENESS 555 // FIXME: comment is required
 
+extern void reiserfs_warning (const char * fmt, ...);
+/* __attribute__( ( format ( printf, 1, 2 ) ) ); */
+
 //
 // here are conversion routines
 //
@@ -487,14 +421,11 @@
     case V1_INDIRECT_UNIQUENESS: return TYPE_INDIRECT;
     case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT;
     case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY;
+    default:
+	    reiserfs_warning( "vs-500: unknown uniqueness %d\n", uniqueness);
+	case V1_ANY_UNIQUENESS:
+	    return TYPE_ANY;
     }
-/*
-    if (uniqueness != V1_ANY_UNIQUENESS) {
-	printk ("uniqueness %d\n", uniqueness);
-	BUG (); 
-    }
-*/
-    return TYPE_ANY;
 }
 
 static inline __u32 type2uniqueness (int type) CONSTF;
@@ -505,15 +436,13 @@
     case TYPE_INDIRECT: return V1_INDIRECT_UNIQUENESS;
     case TYPE_DIRECT: return V1_DIRECT_UNIQUENESS;
     case TYPE_DIRENTRY: return V1_DIRENTRY_UNIQUENESS;
+    default:
+	    reiserfs_warning( "vs-501: unknown type %d\n", type);
+	case TYPE_ANY:
+	    return V1_ANY_UNIQUENESS;
     }
-    /*
-    if (type != TYPE_ANY)
-	BUG ();
-    */
-    return V1_ANY_UNIQUENESS;
 }
 
-
 //
 // key is pointer to on disk key which is stored in le, result is cpu,
 // there is no way to get version of object from key, so, provide
@@ -521,7 +450,7 @@
 //
 static inline loff_t le_key_k_offset (int version, const struct key * key)
 {
-    return (version == ITEM_VERSION_1) ?
+    return (version == KEY_FORMAT_3_5) ?
         le32_to_cpu( key->u.k_offset_v1.k_offset ) :
 	offset_v2_k_offset( &(key->u.k_offset_v2) );
 }
@@ -533,7 +462,7 @@
 
 static inline loff_t le_key_k_type (int version, const struct key * key)
 {
-    return (version == ITEM_VERSION_1) ?
+    return (version == KEY_FORMAT_3_5) ?
         uniqueness2type( le32_to_cpu( key->u.k_offset_v1.k_uniqueness)) :
 	offset_v2_k_type( &(key->u.k_offset_v2) );
 }
@@ -546,20 +475,21 @@
 
 static inline void set_le_key_k_offset (int version, struct key * key, loff_t offset)
 {
-    (version == ITEM_VERSION_1) ?
+    (version == KEY_FORMAT_3_5) ?
         (key->u.k_offset_v1.k_offset = cpu_to_le32 (offset)) : /* jdm check */
 	(set_offset_v2_k_offset( &(key->u.k_offset_v2), offset ));
 }
+
+
 static inline void set_le_ih_k_offset (struct item_head * ih, loff_t offset)
 {
     set_le_key_k_offset (ih_version (ih), &(ih->ih_key), offset);
 }
 
 
-
 static inline void set_le_key_k_type (int version, struct key * key, int type)
 {
-    (version == ITEM_VERSION_1) ?
+    (version == KEY_FORMAT_3_5) ?
         (key->u.k_offset_v1.k_uniqueness = cpu_to_le32(type2uniqueness(type))):
 	(set_offset_v2_k_type( &(key->u.k_offset_v2), type ));
 }
@@ -589,21 +519,21 @@
 //
 static inline loff_t cpu_key_k_offset (const struct cpu_key * key)
 {
-    return (key->version == ITEM_VERSION_1) ?
+    return (key->version == KEY_FORMAT_3_5) ?
         key->on_disk_key.u.k_offset_v1.k_offset :
 	key->on_disk_key.u.k_offset_v2.k_offset;
 }
 
 static inline loff_t cpu_key_k_type (const struct cpu_key * key)
 {
-    return (key->version == ITEM_VERSION_1) ?
+    return (key->version == KEY_FORMAT_3_5) ?
         uniqueness2type (key->on_disk_key.u.k_offset_v1.k_uniqueness) :
 	key->on_disk_key.u.k_offset_v2.k_type;
 }
 
 static inline void set_cpu_key_k_offset (struct cpu_key * key, loff_t offset)
 {
-    (key->version == ITEM_VERSION_1) ?
+    (key->version == KEY_FORMAT_3_5) ?
         (key->on_disk_key.u.k_offset_v1.k_offset = offset) :
 	(key->on_disk_key.u.k_offset_v2.k_offset = offset);
 }
@@ -611,14 +541,15 @@
 
 static inline void set_cpu_key_k_type (struct cpu_key * key, int type)
 {
-    (key->version == ITEM_VERSION_1) ?
+    (key->version == KEY_FORMAT_3_5) ?
         (key->on_disk_key.u.k_offset_v1.k_uniqueness = type2uniqueness (type)):
 	(key->on_disk_key.u.k_offset_v2.k_type = type);
 }
 
+
 static inline void cpu_key_k_offset_dec (struct cpu_key * key)
 {
-    if (key->version == ITEM_VERSION_1)
+    if (key->version == KEY_FORMAT_3_5)
 	key->on_disk_key.u.k_offset_v1.k_offset --;
     else
 	key->on_disk_key.u.k_offset_v2.k_offset --;
@@ -761,7 +692,7 @@
 } __attribute__ ((__packed__));
 
 #define SD_V1_SIZE              (sizeof(struct stat_data_v1))
-#define stat_data_v1(ih)        (ih_version (ih) == ITEM_VERSION_1)
+#define stat_data_v1(ih)        (ih_version (ih) == KEY_FORMAT_3_5)
 #define sd_v1_mode(sdp)         (le16_to_cpu((sdp)->sd_mode))
 #define set_sd_v1_mode(sdp,v)   ((sdp)->sd_mode = cpu_to_le16(v))
 #define sd_v1_nlink(sdp)        (le16_to_cpu((sdp)->sd_nlink))
@@ -815,11 +746,11 @@
   } __attribute__ ((__packed__)) u;
 } __attribute__ ((__packed__));
 //
-// this is 40 bytes long
+// this is 44 bytes long
 //
 #define SD_SIZE (sizeof(struct stat_data))
 #define SD_V2_SIZE              SD_SIZE
-#define stat_data_v2(ih)        (ih_version (ih) == ITEM_VERSION_2)
+#define stat_data_v2(ih)        (ih_version (ih) == KEY_FORMAT_3_6)
 #define sd_v2_mode(sdp)         (le16_to_cpu((sdp)->sd_mode))
 #define set_sd_v2_mode(sdp,v)   ((sdp)->sd_mode = cpu_to_le16(v))
 /* sd_reserved */
@@ -949,76 +880,10 @@
 #define de_visible(deh)	    	    test_bit_unaligned (DEH_Visible, &((deh)->deh_state))
 #define de_hidden(deh)	    	    !test_bit_unaligned (DEH_Visible, &((deh)->deh_state))
 
-/* compose directory item containing "." and ".." entries (entries are
-   not aligned to 4 byte boundary) */
-/* the last four params are LE */
-static inline void make_empty_dir_item_v1 (char * body,
-                                           __u32 dirid, __u32 objid,
-					   __u32 par_dirid, __u32 par_objid)
-{
-    struct reiserfs_de_head * deh;
-
-    memset (body, 0, EMPTY_DIR_SIZE_V1);
-    deh = (struct reiserfs_de_head *)body;
-    
-    /* direntry header of "." */
-    put_deh_offset( &(deh[0]), DOT_OFFSET );
-    /* these two are from make_le_item_head, and are are LE */
-    deh[0].deh_dir_id = dirid;
-    deh[0].deh_objectid = objid;
-    deh[0].deh_state = 0; /* Endian safe if 0 */
-    put_deh_location( &(deh[0]), EMPTY_DIR_SIZE_V1 - strlen( "." ));
-    mark_de_visible(&(deh[0]));
-  
-    /* direntry header of ".." */
-    put_deh_offset( &(deh[1]), DOT_DOT_OFFSET);
-    /* key of ".." for the root directory */
-    /* these two are from the inode, and are are LE */
-    deh[1].deh_dir_id = par_dirid;
-    deh[1].deh_objectid = par_objid;
-    deh[1].deh_state = 0; /* Endian safe if 0 */
-    put_deh_location( &(deh[1]), deh_location( &(deh[0]) ) - strlen( ".." ) );
-    mark_de_visible(&(deh[1]));
-
-    /* copy ".." and "." */
-    memcpy (body + deh_location( &(deh[0]) ), ".", 1);
-    memcpy (body + deh_location( &(deh[1]) ), "..", 2);
-}
-
-/* compose directory item containing "." and ".." entries */
-static inline void make_empty_dir_item (char * body,
-                                        __u32 dirid, __u32 objid,
-					__u32 par_dirid, __u32 par_objid)
-{
-    struct reiserfs_de_head * deh;
-
-    memset (body, 0, EMPTY_DIR_SIZE);
-    deh = (struct reiserfs_de_head *)body;
-    
-    /* direntry header of "." */
-    put_deh_offset( &(deh[0]), DOT_OFFSET );
-    /* these two are from make_le_item_head, and are are LE */
-    deh[0].deh_dir_id = dirid;
-    deh[0].deh_objectid = objid;
-    deh[0].deh_state = 0; /* Endian safe if 0 */
-    put_deh_location( &(deh[0]), EMPTY_DIR_SIZE - ROUND_UP( strlen( "." ) ) );
-    mark_de_visible(&(deh[0]));
-  
-    /* direntry header of ".." */
-    put_deh_offset( &(deh[1]), DOT_DOT_OFFSET );
-    /* key of ".." for the root directory */
-    /* these two are from the inode, and are are LE */
-    deh[1].deh_dir_id = par_dirid;
-    deh[1].deh_objectid = par_objid;
-    deh[1].deh_state = 0; /* Endian safe if 0 */
-    put_deh_location( &(deh[1]), deh_location( &(deh[0])) - ROUND_UP( strlen( ".." ) ) );
-    mark_de_visible(&(deh[1]));
-
-    /* copy ".." and "." */
-    memcpy (body + deh_location( &(deh[0]) ), ".", 1);
-    memcpy (body + deh_location( &(deh[1]) ), "..", 2);
-}
-
+extern void make_empty_dir_item_v1 (char * body, __u32 dirid, __u32 objid,
+				    __u32 par_dirid, __u32 par_objid);
+extern void make_empty_dir_item (char * body, __u32 dirid, __u32 objid,
+				 __u32 par_dirid, __u32 par_objid);
 
 /* array of the entry headers */
  /* get item body */
@@ -1059,13 +924,9 @@
 // two entries per block (at least)
 //#define REISERFS_MAX_NAME_LEN(block_size) 
 //((block_size - BLKH_SIZE - IH_SIZE - DEH_SIZE * 2) / 2)
-
-// two entries per block (at least)
 #define REISERFS_MAX_NAME_LEN(block_size) 255
 
 
-
-
 /* this structure is used for operations on directory entries. It is
    not a disk structure. */
 /* When reiserfs_find_entry or search_by_entry_key find directory
@@ -1258,23 +1119,17 @@
 
 // in in-core inode key is stored on le form
 #define INODE_PKEY(inode) ((struct key *)((inode)->u.reiserfs_i.i_key))
-//#define mark_tail_converted(inode) (atomic_set(&((inode)->u.reiserfs_i.i_converted),1))
-//#define unmark_tail_converted(inode) (atomic_set(&((inode)->u.reiserfs_i.i_converted), 0))
-//#define is_tail_converted(inode) (atomic_read(&((inode)->u.reiserfs_i.i_converted)))
-
-
 
 #define MAX_UL_INT 0xffffffff
 #define MAX_INT    0x7ffffff
 #define MAX_US_INT 0xffff
 
-///#define TOO_LONG_LENGTH		(~0ULL)
-
 // reiserfs version 2 has max offset 60 bits. Version 1 - 32 bit offset
 #define U32_MAX (~(__u32)0)
+
 static inline loff_t max_reiserfs_offset (const struct inode * inode)
 {
-    if (inode_items_version (inode) == ITEM_VERSION_1)
+    if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5)
 	return (loff_t)U32_MAX;
 
     return (loff_t)((~(__u64)0) >> 4);
@@ -1307,13 +1162,6 @@
 /*                  FIXATE NODES                                           */
 /***************************************************************************/
 
-//#define VI_TYPE_STAT_DATA 1
-//#define VI_TYPE_DIRECT 2
-//#define VI_TYPE_INDIRECT 4
-//#define VI_TYPE_DIRECTORY 8
-//#define VI_TYPE_FIRST_DIRECTORY_ITEM 16
-//#define VI_TYPE_INSERTED_DIRECTORY_ITEM 32
-
 #define VI_TYPE_LEFT_MERGEABLE 1
 #define VI_TYPE_RIGHT_MERGEABLE 2
 
@@ -1536,11 +1384,7 @@
 
 #define COMP_KEYS comp_keys
 #define COMP_SHORT_KEYS comp_short_keys
-#define keys_of_same_object comp_short_keys
-
-/*#define COMP_KEYS(p_s_key1, p_s_key2)		comp_keys((unsigned long *)(p_s_key1), (unsigned long *)(p_s_key2))
-#define COMP_SHORT_KEYS(p_s_key1, p_s_key2)	comp_short_keys((unsigned long *)(p_s_key1), (unsigned long *)(p_s_key2))*/
-
+/*#define keys_of_same_object comp_short_keys*/
 
 /* number of blocks pointed to by the indirect item */
 #define I_UNFM_NUM(p_s_ih)	( ih_item_len(p_s_ih) / UNFM_P_SIZE )
@@ -1675,18 +1519,12 @@
 int journal_mark_freed(struct reiserfs_transaction_handle *, struct super_block *, unsigned long blocknr) ;
 int push_journal_writer(char *w) ;
 int pop_journal_writer(int windex) ;
-int journal_lock_dobalance(struct super_block *p_s_sb) ;
-int journal_unlock_dobalance(struct super_block *p_s_sb) ;
 int journal_transaction_should_end(struct reiserfs_transaction_handle *, int) ;
 int reiserfs_in_journal(struct super_block *p_s_sb, kdev_t dev, unsigned long bl, int size, int searchall, unsigned long *next) ;
 int journal_begin(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
-int journal_join(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
 struct super_block *reiserfs_get_super(kdev_t dev) ;
 void flush_async_commits(struct super_block *p_s_sb) ;
 
-int remove_from_transaction(struct super_block *p_s_sb, unsigned long blocknr, int already_cleaned) ;
-int remove_from_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_head *bh, int remove_freed) ;
-
 int buffer_journaled(const struct buffer_head *bh) ;
 int mark_buffer_journal_new(struct buffer_head *bh) ;
 int reiserfs_sync_all_buffers(kdev_t dev, int wait) ;
@@ -1725,6 +1563,10 @@
   return 0 ;
 }
 
+void add_save_link (struct reiserfs_transaction_handle * th,
+					struct inode * inode, int truncate);
+void remove_save_link (struct inode * inode, int truncate);
+
 /* objectid.c */
 __u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th);
 void reiserfs_release_objectid (struct reiserfs_transaction_handle *th, __u32 objectid_to_release);
@@ -1762,16 +1604,16 @@
     
     type = offset_v2_k_type( &(key->u.k_offset_v2));
     if (type != TYPE_DIRECT && type != TYPE_INDIRECT && type != TYPE_DIRENTRY)
-	return ITEM_VERSION_1;
+	return KEY_FORMAT_3_5;
 
-    return ITEM_VERSION_2;
+    return KEY_FORMAT_3_6;
 	
 }
 
 
 static inline void copy_key (struct key *to, const struct key *from)
 {
-  memcpy (to, from, KEY_SIZE);
+    memcpy (to, from, KEY_SIZE);
 }
 
 
@@ -1815,17 +1657,12 @@
 			  struct inode * inode, 
 			  struct buffer_head  * p_s_un_bh);
 
-
+void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
+                                                                struct key * key);
 void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
 void reiserfs_do_truncate (struct reiserfs_transaction_handle *th, 
 			   struct  inode * p_s_inode, struct page *, 
 			   int update_timestamps);
-//
-//void lock_inode_to_convert (struct inode * p_s_inode);
-//void unlock_inode_after_convert (struct inode * p_s_inode);
-//void increment_i_read_sync_counter (struct inode * p_s_inode);
-//void decrement_i_read_sync_counter (struct inode * p_s_inode);
-
 
 #define block_size(inode) ((inode)->i_sb->s_blocksize)
 #define file_size(inode) ((inode)->i_size)
@@ -1834,19 +1671,18 @@
 #define tail_has_to_be_packed(inode) (!dont_have_tails ((inode)->i_sb) &&\
 !STORE_TAIL_IN_UNFM(file_size (inode), tail_size(inode), block_size (inode)))
 
-/*
-int get_buffer_by_range (struct super_block * p_s_sb, struct key * p_s_range_begin, struct key * p_s_range_end, 
-			 struct buffer_head ** pp_s_buf, unsigned long * p_n_objectid);
-int get_buffers_from_range (struct super_block * p_s_sb, struct key * p_s_range_start, struct key * p_s_range_end, 
-                            struct buffer_head ** p_s_range_buffers,
-			    int n_max_nr_buffers_to_return);
-*/
-
 void padd_item (char * item, int total_length, int length);
 
-
 /* inode.c */
 
+void reiserfs_read_inode (struct inode * inode) ;
+void reiserfs_read_inode2(struct inode * inode, void *p) ;
+void reiserfs_delete_inode (struct inode * inode);
+void reiserfs_write_inode (struct inode * inode, int) ;
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data,
+									 int len, int fhtype, int parent);
+int reiserfs_dentry_to_fh(struct dentry *dentry, __u32 *data, int *lenp, int need_parent);
+
 int reiserfs_prepare_write(struct file *, struct page *, unsigned, unsigned) ;
 void reiserfs_truncate_file(struct inode *, int update_timestamps) ;
 void make_cpu_key (struct cpu_key * cpu_key, const struct inode * inode, loff_t offset,
@@ -1854,24 +1690,9 @@
 void make_le_item_head (struct item_head * ih, const struct cpu_key * key, 
 			int version,
 			loff_t offset, int type, int length, int entry_count);
-/*void store_key (struct key * key);
-void forget_key (struct key * key);*/
-int reiserfs_get_block (struct inode * inode, long block,
-			struct buffer_head * bh_result, int create);
 struct inode * reiserfs_iget (struct super_block * s, 
 			      const struct cpu_key * key);
-void reiserfs_read_inode (struct inode * inode) ;
-void reiserfs_read_inode2(struct inode * inode, void *p) ;
-void reiserfs_delete_inode (struct inode * inode);
-extern int reiserfs_notify_change(struct dentry * dentry, struct iattr * attr);
-void reiserfs_write_inode (struct inode * inode, int) ;
 
-/* nfsd support functions */
-struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *fh, int len, int fhtype, int parent);
-int reiserfs_dentry_to_fh(struct dentry *, __u32 *fh, int *lenp, int need_parent);
-
-/* we don't mark inodes dirty, we just log them */
-void reiserfs_dirty_inode (struct inode * inode) ;
 
 struct inode * reiserfs_new_inode (struct reiserfs_transaction_handle *th, 
 				   const struct inode * dir, int mode, 
@@ -1879,36 +1700,12 @@
 				   struct dentry *dentry, struct inode *inode, int * err);
 int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode);
 void reiserfs_update_sd (struct reiserfs_transaction_handle *th, struct inode * inode);
-int reiserfs_inode_setattr(struct dentry *,  struct iattr * attr);
 
 /* namei.c */
 inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
 int search_by_entry_key (struct super_block * sb, const struct cpu_key * key, 
 			 struct path * path, 
 			 struct reiserfs_dir_entry * de);
-struct dentry * reiserfs_lookup (struct inode * dir, struct dentry *dentry);
-int reiserfs_create (struct inode * dir, struct dentry *dentry,	int mode);
-int reiserfs_mknod (struct inode * dir_inode, struct dentry *dentry, int mode, int rdev);
-int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode);
-int reiserfs_rmdir (struct inode * dir,	struct dentry *dentry);
-int reiserfs_unlink (struct inode * dir, struct dentry *dentry);
-int reiserfs_symlink (struct inode * dir, struct dentry *dentry, const char * symname);
-int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry *dentry);
-int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir, struct dentry *new_dentry);
-
-/* super.c */
-inline void reiserfs_mark_buffer_dirty (struct buffer_head * bh, int flag);
-inline void reiserfs_mark_buffer_clean (struct buffer_head * bh);
-void reiserfs_write_super (struct super_block * s);
-void reiserfs_put_super (struct super_block * s);
-int reiserfs_remount (struct super_block * s, int * flags, char * data);
-/*int read_super_block (struct super_block * s, int size);
-int read_bitmaps (struct super_block * s);
-int read_old_bitmaps (struct super_block * s);
-int read_old_super_block (struct super_block * s, int size);*/
-struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent);
-int reiserfs_statfs (struct super_block * s, struct statfs * buf);
-
 /* procfs.c */
 
 #if defined( CONFIG_PROC_FS ) && defined( CONFIG_REISERFS_PROC_INFO )
@@ -2006,8 +1803,6 @@
 /* prints.c */
 void reiserfs_panic (struct super_block * s, const char * fmt, ...)
 __attribute__ ( ( noreturn ) );/* __attribute__( ( format ( printf, 2, 3 ) ) ) */
-void reiserfs_warning (const char * fmt, ...);
-/* __attribute__( ( format ( printf, 1, 2 ) ) ); */
 void reiserfs_debug (struct super_block *s, int level, const char * fmt, ...);
 /* __attribute__( ( format ( printf, 3, 4 ) ) ); */
 void print_virtual_node (struct virtual_node * vn);
@@ -2099,83 +1894,6 @@
 #define reiserfs_test_and_clear_le_bit ext2_clear_bit
 #define reiserfs_test_le_bit           ext2_test_bit
 #define reiserfs_find_next_zero_le_bit ext2_find_next_zero_bit
-
-
-//
-// this was totally copied from from linux's
-// find_first_zero_bit and changed a bit
-//
-
-#ifdef __i386__
-
-static __inline__ int 
-find_first_nonzero_bit(const void * addr, unsigned size) {
-  int res;
-  int __d0;
-  void *__d1;
-
-
-  if (!size) {
-    return (0);
-  }
-  __asm__ __volatile__ (
-	  "cld\n\t"
-	  "xorl %%eax,%%eax\n\t"
-	  "repe; scasl\n\t"
-	  "je 1f\n\t"
-	  "movl -4(%%edi),%%eax\n\t"
-	  "subl $4, %%edi\n\t"
-	  "bsfl %%eax,%%eax\n\t"
-	  "1:\tsubl %%edx,%%edi\n\t"
-	  "shll $3,%%edi\n\t"
-	  "addl %%edi,%%eax"
-	  :"=a" (res),
-	  "=c"(__d0), "=D"(__d1)
-	  :"1" ((size + 31) >> 5), "d" (addr), "2" (addr));
-  return (res);
-}
-
-#else /* __i386__ */
-
-static __inline__ int find_next_nonzero_bit(const void * addr, unsigned size, 
-											unsigned offset)
-{
-	unsigned int * p = ((unsigned int *) addr) + (offset >> 5);
-	unsigned int result = offset & ~31UL;
-	unsigned int tmp;
-
-	if (offset >= size)
-		return size;
-	size -= result;
-	offset &= 31UL;
-	if (offset) {
-		tmp = *p++;
-		/* set to zero first offset bits */
-		tmp &= ~(~0UL >> (32-offset));
-		if (size < 32)
-			goto found_first;
-		if (tmp != 0U)
-			goto found_middle;
-		size -= 32;
-		result += 32;
-	}
-	while (size >= 32) {
-		if ((tmp = *p++) != 0U)
-			goto found_middle;
-		result += 32;
-		size -= 32;
-	}
-	if (!size)
-		return result;
-	tmp = *p;
-found_first:
-found_middle:
-	return result + ffs(tmp);
-}
-
-#define find_first_nonzero_bit(addr,size) find_next_nonzero_bit((addr), (size), 0)
-
-#endif /* 0 */
 
 /* sometimes reiserfs_truncate may require to allocate few new blocks
    to perform indirect2direct conversion. People probably used to
diff -urN linux-2.4.17-pre4/include/linux/reiserfs_fs_i.h linux/include/linux/reiserfs_fs_i.h
--- linux-2.4.17-pre4/include/linux/reiserfs_fs_i.h	Thu Nov 22 11:46:19 2001
+++ linux/include/linux/reiserfs_fs_i.h	Thu Dec  6 10:53:04 2001
@@ -3,50 +3,47 @@
 
 #include <linux/list.h>
 
+/** bitmasks for i_flags field in reiserfs-specific part of inode */
+typedef enum {
+    /** this says what format of key do all items (but stat data) of
+	an object have.  If this is set, that format is 3.6 otherwise
+	- 3.5 */
+    i_item_key_version_mask    =  0x0001,
+    /** If this is unset, object has 3.5 stat data, otherwise, it has
+	3.6 stat data with 64bit size, 32bit nlink etc. */
+    i_stat_data_version_mask   =  0x0002,
+    /** file might need tail packing on close */
+    i_pack_on_close_mask       =  0x0004,
+    /** don't pack tail of file */
+    i_nopack_mask              =  0x0008,
+    /** If those is set, "safe link" was created for this file during
+	truncate or unlink. Safe link is used to avoid leakage of disk
+	space on crash with some files open, but unlinked. */
+    i_link_saved_unlink_mask   =  0x0010,
+    i_link_saved_truncate_mask =  0x0020
+} reiserfs_inode_flags;
+
+
 struct reiserfs_inode_info {
-  __u32 i_key [4];/* key is still 4 32 bit integers */
+    __u32 i_key [4];/* key is still 4 32 bit integers */
   
-				/* this comment will be totally
-                                   cryptic to readers not familiar
-                                   with 3.5/3.6 format conversion, and
-                                   it does not consider that that 3.6
-                                   might not be the last version */
-  int i_version;  // this says whether file is old or new
-
-  int i_pack_on_close ; // file might need tail packing on close 
-
-  __u32 i_first_direct_byte; // offset of first byte stored in direct item.
-
-				/* My guess is this contains the first
-                                   unused block of a sequence of
-                                   blocks plus the length of the
-                                   sequence, which I think is always
-                                   at least two at the time of the
-                                   preallocation.  I really prefer
-                                   allocate on flush conceptually.....
-
-				   You know, it really annoys me when
-				   code is this badly commented that I
-				   have to guess what it does.
-				   Neither I nor anyone else has time
-				   for guessing what your
-				   datastructures mean.  -Hans */
-  //For preallocation
-  int i_prealloc_block;
-  int i_prealloc_count;
-  struct list_head i_prealloc_list;	/* per-transaction list of inodes which
-				 * have preallocated blocks */
-				/* I regret that you think the below
-                                   is a comment you should make.... -Hans */
-  //nopack-attribute
-  int nopack;
+    /** transient inode flags that are never stored on disk. Bitmasks
+	for this field are defined above. */
+    __u32 i_flags;
+
+    __u32 i_first_direct_byte; // offset of first byte stored in direct item.
+
+    int i_prealloc_block; /* first unused block of a sequence of unused blocks */
+    int i_prealloc_count; /* length of that sequence */
+    struct list_head i_prealloc_list;	/* per-transaction list of inodes which
+					 * have preallocated blocks */
   
-  /* we use these for fsync or O_SYNC to decide which transaction needs
-  ** to be committed in order for this inode to be properly flushed
-  */
-  unsigned long i_trans_id ;
-  unsigned long i_trans_index ;
+    /* we use these for fsync or O_SYNC to decide which transaction
+    ** needs to be committed in order for this inode to be properly
+    ** flushed */
+    unsigned long i_trans_id ;
+    unsigned long i_trans_index ;
 };
 
-
 #endif
+
diff -urN linux-2.4.17-pre4/include/linux/shmem_fs.h linux/include/linux/shmem_fs.h
--- linux-2.4.17-pre4/include/linux/shmem_fs.h	Wed Oct 10 07:53:57 2001
+++ linux/include/linux/shmem_fs.h	Thu Dec  6 10:53:04 2001
@@ -11,7 +11,7 @@
  * swapper address space.
  *
  * We have to move it here, since not every user of fs.h is including
- * mm.h, but m.h is including fs.h via sched .h :-/
+ * mm.h, but mm.h is including fs.h via sched .h :-/
  */
 typedef struct {
 	unsigned long val;
diff -urN linux-2.4.17-pre4/include/linux/socket.h linux/include/linux/socket.h
--- linux-2.4.17-pre4/include/linux/socket.h	Thu Nov 22 11:46:18 2001
+++ linux/include/linux/socket.h	Thu Dec  6 10:53:04 2001
@@ -156,6 +156,7 @@
 #define AF_IRDA		23	/* IRDA sockets			*/
 #define AF_PPPOX	24	/* PPPoX sockets		*/
 #define AF_WANPIPE	25	/* Wanpipe API Sockets */
+#define AF_LLC		26	/* Linux LLC			*/
 #define AF_BLUETOOTH	31	/* Bluetooth sockets 		*/
 #define AF_MAX		32	/* For now.. */
 
@@ -187,6 +188,7 @@
 #define PF_IRDA		AF_IRDA
 #define PF_PPPOX	AF_PPPOX
 #define PF_WANPIPE	AF_WANPIPE
+#define PF_LLC		AF_LLC
 #define PF_BLUETOOTH	AF_BLUETOOTH
 #define PF_MAX		AF_MAX
 
@@ -237,6 +239,8 @@
 #define SOL_ATM		264	/* ATM layer (cell level) */
 #define SOL_AAL		265	/* ATM Adaption Layer (packet level) */
 #define SOL_IRDA        266
+#define SOL_NETBEUI	267
+#define SOL_LLC		268
 
 /* IPX options */
 #define IPX_TYPE	1
diff -urN linux-2.4.17-pre4/include/scsi/sg.h linux/include/scsi/sg.h
--- linux-2.4.17-pre4/include/scsi/sg.h	Fri Sep  7 09:28:37 2001
+++ linux/include/scsi/sg.h	Thu Dec  6 10:53:04 2001
@@ -11,9 +11,20 @@
 Version 2 and 3 extensions to driver:
 *       Copyright (C) 1998 - 2001 Douglas Gilbert
 
-    Version: 3.1.20 (20010814)
+    Version: 3.1.22 (20011128)
     This version is for 2.4 series kernels.
 
+    Changes since 3.1.21 (20011029)
+    	- add support for SG_FLAG_MMAP_IO [permit mmap() on sg devices]
+    	- update documentation pointers in this header
+    	- put KERNEL_VERSION macros around code that breaks early 2.4 series
+    	- switch back to alloc_kiovec()
+    Changes since 3.1.20 (20010814)
+	- use alloc_kiovec_sz() to speed dio [set num_buffer_heads==0]
+	- changes to cope with larger scatter gather element sizes
+	- clean up some printk()s
+	- add MODULE_LICENSE("GPL") [in a 3.1.20 subversion]
+	- fix race around generic_unplug_device() [in a 3.1.20 subversion]
     Changes since 3.1.19 (20010623)
 	- add SG_GET_ACCESS_COUNT ioctl 
 	- make open() increment and close() decrement access_count
@@ -33,56 +44,57 @@
 Map of SG verions to the Linux kernels in which they appear:
        ----------        ----------------------------------
        original          all kernels < 2.2.6
-       2.1.38            2.2.16
-       2.1.39            2.2.17 - 2.2.19
+       2.1.40            2.2.20
        3.0.x             optional version 3 sg driver for 2.2 series
-       3.1.17            2.4.0 ++
+       3.1.17++          2.4.0++
 
 Major new features in SG 3.x driver (cf SG 2.x drivers)
 	- SG_IO ioctl() combines function if write() and read()
 	- new interface (sg_io_hdr_t) but still supports old interface
-	- scatter/gather in user space and direct IO supported
+	- scatter/gather in user space, direct IO, and mmap supported
 
- The term "indirect IO" refers a method by which data is DMAed into kernel
- buffers from the hardware and afterwards is transferred into the user
- space (or vice versa if you are writing). Transfer speeds of up to 20 to
- 30MBytes/sec have been measured using indirect IO. For faster throughputs
- "direct IO" which cuts out the double handling of data is required.
- Direct IO is supported by the SG 3.x drivers on 2.4 series Linux kernels
- and requires the use of the new interface.
-
- Requests for direct IO with the new interface will automatically fall back
- to indirect IO mode if they cannot be fulfilled. An example of such a case
- is an ISA SCSI adapter which is only capable of DMAing to the lower 16MB of
- memory due to the architecture of ISA. The 'info' field in the new
- interface indicates whether a direct or indirect data transfer took place.
-
- Obtaining memory for the kernel buffers used in indirect IO is done by
- first checking if the "reserved buffer" for the current file descriptor
- is available and large enough. If these conditions are _not_ met then
- kernel memory is obtained on a per SCSI command basis. This corresponds
- to a write(), read() sequence or a SG_IO ioctl() call. Further, the
- kernel memory that is suitable for DMA may be constrained by the
- architecture of the SCSI adapter (e.g. ISA adapters).
+ The normal action of this driver is to use the adapter (HBA) driver to DMA
+ data into kernel buffers and then use the CPU to copy the data into the 
+ user space (vice versa for writes). That is called "indirect" IO due to 
+ the double handling of data. There are two methods offered to remove the
+ redundant copy: 1) direct IO which uses the kernel kiobuf mechanism and 
+ 2) using the mmap() system call to map the reserve buffer (this driver has 
+ one reserve buffer per fd) into the user space. Both have their advantages.
+ In terms of absolute speed mmap() is faster. If speed is not a concern, 
+ indirect IO should be fine. Read the documentation for more information.
 
  ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' may be
          needed. That pseudo file's content is defaulted to 0. **
+ 
+ Historical note: this SCSI pass-through driver has been known as "sg" for 
+ a decade. In broader kernel discussions "sg" is used to refer to scatter
+ gather techniques. The context should clarify which "sg" is referred to.
 
  Documentation
  =============
- A web site for SG device drivers can be found at:
+ A web site for the SG device driver can be found at:
 	http://www.torque.net/sg  [alternatively check the MAINTAINERS file]
- The main documents are still based on 2.x versions:
+ The documentation for the sg version 3 driver can be found at:
+ 	http://www.torque.net/sg/p/sg_v3_ho.html
+ This is a rendering from DocBook source [change the extension to "sgml"
+ or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon).
+
+ The older, version 2 documents discuss the original sg interface in detail:
 	http://www.torque.net/sg/p/scsi-generic.txt
 	http://www.torque.net/sg/p/scsi-generic_long.txt
- Documentation on the changes and additions in 3.x version of the sg driver
- can be found at: http://www.torque.net/sg/p/scsi-generic_v3.txt
  A version of this document (potentially out of date) may also be found in
  the kernel source tree, probably at:
         /usr/src/linux/Documentation/scsi-generic.txt .
- Utility and test programs are available at the sg web site.
+
+ Utility and test programs are available at the sg web site. They are 
+ bundled as sg_utils (for the lk 2.2 series) and sg3_utils (for the
+ lk 2.4 series).
+
+ There is a HOWTO on the Linux SCSI subsystem in the lk 2.4 series at:
+ 	http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO
 */
 
+
 /* New interface introduced in the 3.x SG drivers follows */
 
 typedef struct sg_iovec /* same structure as used by readv() Linux system */
@@ -120,19 +132,20 @@
 } sg_io_hdr_t;  /* 64 bytes long (on i386) */
 
 /* Use negative values to flag difference from original sg_header structure */
-#define SG_DXFER_NONE -1        /* e.g. a SCSI Test Unit Ready command */
-#define SG_DXFER_TO_DEV -2      /* e.g. a SCSI WRITE command */
-#define SG_DXFER_FROM_DEV -3    /* e.g. a SCSI READ command */
-#define SG_DXFER_TO_FROM_DEV -4 /* treated like SG_DXFER_FROM_DEV with the
+#define SG_DXFER_NONE (-1)      /* e.g. a SCSI Test Unit Ready command */
+#define SG_DXFER_TO_DEV (-2)    /* e.g. a SCSI WRITE command */
+#define SG_DXFER_FROM_DEV (-3)  /* e.g. a SCSI READ command */
+#define SG_DXFER_TO_FROM_DEV (-4) /* treated like SG_DXFER_FROM_DEV with the
 				   additional property than during indirect
 				   IO the user buffer is copied into the
 				   kernel buffers before the transfer */
-#define SG_DXFER_UNKNOWN -5     /* Unknown data direction */
+#define SG_DXFER_UNKNOWN (-5)   /* Unknown data direction */
 
 /* following flag values can be "or"-ed together */
 #define SG_FLAG_DIRECT_IO 1     /* default is indirect IO */
-#define SG_FLAG_LUN_INHIBIT 2   /* default is to put device's lun into */
-				/* the 2nd byte of SCSI command */
+#define SG_FLAG_LUN_INHIBIT 2   /* default is overwrite lun in SCSI */
+				/* command block (when <= SCSI_2) */
+#define SG_FLAG_MMAP_IO 4       /* request memory mapped IO */
 #define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */
 				/* user space (debug indirect IO) */
 
diff -urN linux-2.4.17-pre4/kernel/sched.c linux/kernel/sched.c
--- linux-2.4.17-pre4/kernel/sched.c	Wed Nov 21 16:25:48 2001
+++ linux/kernel/sched.c	Thu Dec  6 10:53:04 2001
@@ -262,6 +262,21 @@
 		 * a problem.
 		 */
 		if (tsk == idle_task(cpu)) {
+#if defined(__i386__) && defined(CONFIG_SMP)
+                        /*
+			 * Check if two siblings are idle in the same
+			 * physical package. Use them if found.
+			 */
+			if (smp_num_siblings == 2) {
+				if (cpu_curr(cpu_sibling_map[cpu]) == 
+			            idle_task(cpu_sibling_map[cpu])) {
+					oldest_idle = last_schedule(cpu);
+					target_tsk = tsk;
+					break;
+				}
+				
+                        }
+#endif		
 			if (last_schedule(cpu) < oldest_idle) {
 				oldest_idle = last_schedule(cpu);
 				target_tsk = tsk;
diff -urN linux-2.4.17-pre4/mm/bootmem.c linux/mm/bootmem.c
--- linux-2.4.17-pre4/mm/bootmem.c	Tue Sep 18 14:10:43 2001
+++ linux/mm/bootmem.c	Thu Dec  6 10:53:04 2001
@@ -154,6 +154,12 @@
 	if (align & (align-1))
 		BUG();
 
+	offset = 0;
+	if (align &&
+	    (bdata->node_boot_start & (align - 1UL)) != 0)
+		offset = (align - (bdata->node_boot_start & (align - 1UL)));
+	offset >>= PAGE_SHIFT;
+
 	/*
 	 * We try to allocate bootmem pages above 'goal'
 	 * first, then we try to allocate lower pages.
@@ -165,6 +171,7 @@
 		preferred = 0;
 
 	preferred = ((preferred + align - 1) & ~(align - 1)) >> PAGE_SHIFT;
+	preferred += offset;
 	areasize = (size+PAGE_SIZE-1)/PAGE_SIZE;
 	incr = align >> PAGE_SHIFT ? : 1;
 
@@ -184,7 +191,7 @@
 	fail_block:;
 	}
 	if (preferred) {
-		preferred = 0;
+		preferred = offset;
 		goto restart_scan;
 	}
 	return NULL;
diff -urN linux-2.4.17-pre4/mm/shmem.c linux/mm/shmem.c
--- linux-2.4.17-pre4/mm/shmem.c	Wed Nov 21 09:57:57 2001
+++ linux/mm/shmem.c	Thu Dec  6 10:53:04 2001
@@ -1193,7 +1193,7 @@
 	follow_link:	shmem_follow_link,
 };
 
-static int shmem_parse_options(char *options, int *mode, unsigned long * blocks, unsigned long *inodes)
+static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long * blocks, unsigned long *inodes)
 {
 	char *this_char, *value, *rest;
 
@@ -1205,7 +1205,7 @@
 			*value++ = 0;
 		} else {
 			printk(KERN_ERR 
-			    "shmem_parse_options: No value for option '%s'\n", 
+			    "tmpfs: No value for mount option '%s'\n", 
 			    this_char);
 			return 1;
 		}
@@ -1230,8 +1230,20 @@
 			*mode = simple_strtoul(value,&rest,8);
 			if (*rest)
 				goto bad_val;
+		} else if (!strcmp(this_char,"uid")) {
+			if (!uid)
+				continue;
+			*uid = simple_strtoul(value,&rest,0);
+			if (*rest)
+				goto bad_val;
+		} else if (!strcmp(this_char,"gid")) {
+			if (!gid)
+				continue;
+			*gid = simple_strtoul(value,&rest,0);
+			if (*rest)
+				goto bad_val;
 		} else {
-			printk(KERN_ERR "shmem_parse_options: Bad option %s\n",
+			printk(KERN_ERR "tmpfs: Bad mount option %s\n",
 			       this_char);
 			return 1;
 		}
@@ -1239,7 +1251,7 @@
 	return 0;
 
 bad_val:
-	printk(KERN_ERR "shmem_parse_options: Bad value '%s' for option '%s'\n", 
+	printk(KERN_ERR "tmpfs: Bad value '%s' for mount option '%s'\n", 
 	       value, this_char);
 	return 1;
 
@@ -1251,7 +1263,7 @@
 	unsigned long max_blocks = sbinfo->max_blocks;
 	unsigned long max_inodes = sbinfo->max_inodes;
 
-	if (shmem_parse_options (data, NULL, &max_blocks, &max_inodes))
+	if (shmem_parse_options (data, NULL, NULL, NULL, &max_blocks, &max_inodes))
 		return -EINVAL;
 	return shmem_set_size(sbinfo, max_blocks, max_inodes);
 }
@@ -1268,6 +1280,8 @@
 	struct dentry * root;
 	unsigned long blocks, inodes;
 	int mode   = S_IRWXUGO | S_ISVTX;
+	uid_t uid = current->fsuid;
+	gid_t gid = current->fsgid;
 	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
 	struct sysinfo si;
 
@@ -1279,10 +1293,8 @@
 	blocks = inodes = si.totalram / 2;
 
 #ifdef CONFIG_TMPFS
-	if (shmem_parse_options (data, &mode, &blocks, &inodes)) {
-		printk(KERN_ERR "tmpfs invalid option\n");
+	if (shmem_parse_options (data, &mode, &uid, &gid, &blocks, &inodes))
 		return NULL;
-	}
 #endif
 
 	spin_lock_init (&sbinfo->stat_lock);
@@ -1299,6 +1311,8 @@
 	if (!inode)
 		return NULL;
 
+	inode->i_uid = uid;
+	inode->i_gid = gid;
 	root = d_alloc_root(inode);
 	if (!root) {
 		iput(inode);
diff -urN linux-2.4.17-pre4/mm/slab.c linux/mm/slab.c
--- linux-2.4.17-pre4/mm/slab.c	Thu Dec  6 10:52:26 2001
+++ linux/mm/slab.c	Thu Dec  6 10:53:04 2001
@@ -1282,10 +1282,9 @@
 })
 
 #ifdef CONFIG_SMP
-void* kmem_cache_alloc_batch(kmem_cache_t* cachep, int flags)
+void* kmem_cache_alloc_batch(kmem_cache_t* cachep, cpucache_t* cc, int flags)
 {
 	int batchcount = cachep->batchcount;
-	cpucache_t* cc = cc_data(cachep);
 
 	spin_lock(&cachep->spinlock);
 	while (batchcount--) {
@@ -1334,7 +1333,7 @@
 				objp = cc_entry(cc)[--cc->avail];
 			} else {
 				STATS_INC_ALLOCMISS(cachep);
-				objp = kmem_cache_alloc_batch(cachep,flags);
+				objp = kmem_cache_alloc_batch(cachep,cc,flags);
 				if (!objp)
 					goto alloc_new_slab_nolock;
 			}
@@ -1922,12 +1921,13 @@
 #endif
 #ifdef CONFIG_SMP
 		{
+			cpucache_t *cc = cc_data(cachep);
 			unsigned int batchcount = cachep->batchcount;
 			unsigned int limit;
 
-			if (cc_data(cachep))
-				limit = cc_data(cachep)->limit;
-			 else
+			if (cc)
+				limit = cc->limit;
+			else
 				limit = 0;
 			len += sprintf(page+len, " : %4u %4u",
 					limit, batchcount);
diff -urN linux-2.4.17-pre4/net/8021q/vlan.c linux/net/8021q/vlan.c
--- linux-2.4.17-pre4/net/8021q/vlan.c	Tue Oct 30 15:08:12 2001
+++ linux/net/8021q/vlan.c	Thu Dec  6 10:53:04 2001
@@ -1,11 +1,10 @@
 /*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
+ * INET		802.1Q VLAN
  *		Ethernet-type device handling.
  *
- * Authors:	Ben Greear <greearb@candelatech.com>, <greearb@agcs.com>
+ * Authors:	Ben Greear <greearb@candelatech.com>
+ *              Please send support related email to: vlan@scry.wanfear.com
+ *              VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
  * 
  * Fixes:
  *              Fix for packet capture - Nick Eggleston <nick@dccinc.com>;
@@ -42,7 +41,7 @@
 
 static char vlan_fullname[] = "802.1Q VLAN Support";
 static unsigned int vlan_version = 1;
-static unsigned int vlan_release = 5;
+static unsigned int vlan_release = 6;
 static char vlan_copyright[] = " Ben Greear <greearb@candelatech.com>";
 
 static int vlan_device_event(struct notifier_block *, unsigned long, void *);
@@ -106,6 +105,23 @@
 }
 
 /*
+ * Cleanup of groups before exit
+ */
+
+static void vlan_group_cleanup(void)
+{
+	struct vlan_group *grp = NULL;
+	struct vlan_group *nextgroup;
+
+	for (grp = p802_1Q_vlan_list; (grp != NULL);) {
+		nextgroup = grp->next;
+		kfree(grp);
+		grp = nextgroup;
+	}
+	p802_1Q_vlan_list = NULL;
+}
+
+/*
  *     Module 'remove' entry point.
  *     o delete /proc/net/router directory and static entries.
  */ 
@@ -116,7 +132,7 @@
 
 	dev_remove_pack(&vlan_packet_type);
 	vlan_proc_cleanup();
-
+	vlan_group_cleanup();
 	vlan_ioctl_hook = NULL;
 }
 
@@ -328,6 +344,7 @@
 	/* set up method calls */
 	new_dev->init = vlan_dev_init;
 	new_dev->destructor = vlan_dev_destruct;
+	new_dev->features |= NETIF_F_DYNALLOC ; 
 	    
 	/* new_dev->ifindex = 0;  it will be set when added to
 	 * the global list.
diff -urN linux-2.4.17-pre4/net/8021q/vlan_dev.c linux/net/8021q/vlan_dev.c
--- linux-2.4.17-pre4/net/8021q/vlan_dev.c	Tue Oct 30 15:08:12 2001
+++ linux/net/8021q/vlan_dev.c	Thu Dec  6 10:53:04 2001
@@ -1,11 +1,10 @@
 /*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
+ * INET		802.1Q VLAN
  *		Ethernet-type device handling.
  *
- * Authors:	Ben Greear <greearb@candelatech.com>, <greearb@agcs.com>
+ * Authors:	Ben Greear <greearb@candelatech.com>
+ *              Please send support related email to: vlan@scry.wanfear.com
+ *              VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
  * 
  * Fixes:       Mar 22 2001: Martin Bokaemper <mbokaemper@unispherenetworks.com>
  *                - reset skb->pkt_type on incoming packets when MAC was changed
@@ -512,10 +511,6 @@
 			VLAN_FMEM_DBG("dev->priv free, addr: %p\n", dev->priv);
 			dev->priv = NULL;
 		}
-
-		kfree(dev);
-		VLAN_FMEM_DBG("net_device free, addr: %p\n", dev);
-		dev = NULL;
 	}
 }
 
diff -urN linux-2.4.17-pre4/net/8021q/vlanproc.c linux/net/8021q/vlanproc.c
--- linux-2.4.17-pre4/net/8021q/vlanproc.c	Tue Nov 13 09:19:41 2001
+++ linux/net/8021q/vlanproc.c	Thu Dec  6 10:53:04 2001
@@ -116,7 +116,7 @@
  *	Clean up /proc/net/vlan entries
  */
 
-void __exit vlan_proc_cleanup(void)
+void vlan_proc_cleanup(void)
 {
 	if (proc_vlan_conf)
 		remove_proc_entry(name_conf, proc_vlan_dir);
@@ -462,7 +462,7 @@
 	return 0;
 }
 
-void __exit vlan_proc_cleanup(void)
+void vlan_proc_cleanup(void)
 {
 	return;
 }
diff -urN linux-2.4.17-pre4/net/README linux/net/README
--- linux-2.4.17-pre4/net/README	Mon Jun 11 19:15:27 2001
+++ linux/net/README	Thu Dec  6 10:53:04 2001
@@ -23,4 +23,4 @@
 unix			alan@lxorguk.ukuu.org.uk
 x25			g4klx@g4klx.demon.co.uk
 bluetooth		maxk@qualcomm.com
-
+8021q                   greearb@candelatech.com, vlan@scry.wanfear.com
diff -urN linux-2.4.17-pre4/net/decnet/README linux/net/decnet/README
--- linux-2.4.17-pre4/net/decnet/README	Wed May 26 09:36:36 1999
+++ linux/net/decnet/README	Thu Dec  6 10:53:04 2001
@@ -3,6 +3,6 @@
 
 The documentation for this kernel subsystem is available in the
 Documentation/networking subdirctory of this distribution and also
-on line at http://www.sucs.swan.ac.uk/~rohan/DECnet/index.html.
+on line at http://www.chygwyn.com/DECnet/
 
 Steve Whitehouse <SteveW@ACM.org>
diff -urN linux-2.4.17-pre4/net/decnet/af_decnet.c linux/net/decnet/af_decnet.c
--- linux-2.4.17-pre4/net/decnet/af_decnet.c	Fri Nov  9 14:12:54 2001
+++ linux/net/decnet/af_decnet.c	Thu Dec  6 10:53:04 2001
@@ -36,6 +36,7 @@
  *        Steve Whitehouse: Removed unused code. Fix to use sk->allocation
  *                          when required.
  *       Patrick Caulfield: /proc/net/decnet now has object name/number
+ *        Steve Whitehouse: Fixed local port allocation, hashed sk list
  */
 
 
@@ -139,9 +140,13 @@
 dn_address decnet_address = 0;
 unsigned char decnet_ether_address[ETH_ALEN] = { 0xAA, 0x00, 0x04, 0x00, 0x00, 0x00 };
 
+#define DN_SK_HASH_SHIFT 8
+#define DN_SK_HASH_SIZE (1 << DN_SK_HASH_SHIFT)
+#define DN_SK_HASH_MASK (DN_SK_HASH_SIZE - 1)
+
 static struct proto_ops dn_proto_ops;
 rwlock_t dn_hash_lock = RW_LOCK_UNLOCKED;
-static struct sock *dn_sklist;
+static struct sock *dn_sk_hash[DN_SK_HASH_SIZE];
 static struct sock *dn_wild_sk;
 
 static int __dn_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen, int flags);
@@ -154,18 +159,38 @@
 	if (scp->addr.sdn_flags & SDF_WILD)
 		return dn_wild_sk ? NULL : &dn_wild_sk;
 
-	return &dn_sklist;
+	return &dn_sk_hash[scp->addrloc & DN_SK_HASH_MASK];
+}
+
+/* 
+ * Valid ports are those greater than zero and not already in use.
+ */
+static int check_port(unsigned short port)
+{
+	struct sock *sk = dn_sk_hash[port & DN_SK_HASH_MASK];
+	if (port == 0)
+		return -1;
+	while(sk) {
+		struct dn_scp *scp = DN_SK(sk);
+		if (scp->addrloc == port)
+			return -1;
+		sk = sk->next;
+	}
+	return 0;
 }
 
 static unsigned short port_alloc(struct sock *sk)
 {
 	struct dn_scp *scp = DN_SK(sk);
 static unsigned short port = 0x2000;
+	unsigned short i_port = port;
 
-	if (port == 0)
-		port++;
+	while(check_port(++port) != 0) {
+		if (port == i_port)
+			return 0;
+	}
 
-	scp->addrloc = port++;
+	scp->addrloc = port;
 
 	return 1;
 }
@@ -238,6 +263,48 @@
 	sk->pprev = NULL;
 }
 
+struct sock **listen_hash(struct sockaddr_dn *addr)
+{
+	int i;
+	unsigned hash = addr->sdn_objnum;
+
+	if (hash == 0) {
+		hash = addr->sdn_objnamel;
+		for(i = 0; i < addr->sdn_objnamel; i++) {
+			hash ^= addr->sdn_objname[i];
+			hash ^= (hash << 3);
+		}
+	}
+
+	return &dn_sk_hash[hash & DN_SK_HASH_MASK];
+}
+
+/*
+ * Called to transform a socket from bound (i.e. with a local address)
+ * into a listening socket (doesn't need a local port number) and rehashes
+ * based upon the object name/number.
+ */
+static void dn_rehash_sock(struct sock *sk)
+{
+	struct sock **skp = sk->pprev;
+	struct dn_scp *scp = DN_SK(sk);
+
+	if (scp->addr.sdn_flags & SDF_WILD)
+		return;
+
+	write_lock_bh(&dn_hash_lock);
+	while(*skp != sk)
+		skp = &((*skp)->next);
+	*skp = sk->next;
+
+	DN_SK(sk)->addrloc = 0;
+	skp = listen_hash(&DN_SK(sk)->addr);
+
+	sk->next = *skp;
+	sk->pprev = skp;
+	*skp = sk;
+	write_unlock_bh(&dn_hash_lock);
+}
 
 int dn_sockaddr2username(struct sockaddr_dn *sdn, unsigned char *buf, unsigned char type)
 {
@@ -328,10 +395,11 @@
 
 struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr)
 {
+	struct sock **skp = listen_hash(addr);
 	struct sock *sk;
 
 	read_lock(&dn_hash_lock);
-	for(sk = dn_sklist; sk != NULL; sk = sk->next) {
+	for(sk = *skp; sk != NULL; sk = sk->next) {
 		struct dn_scp *scp = DN_SK(sk);
 		if (sk->state != TCP_LISTEN)
 			continue;
@@ -365,7 +433,8 @@
 	struct dn_scp *scp;
 
 	read_lock(&dn_hash_lock);
-	for(sk = dn_sklist; sk != NULL; sk = sk->next) {
+	sk = dn_sk_hash[cb->dst_port & DN_SK_HASH_MASK];
+	for (; sk != NULL; sk = sk->next) {
 		scp = DN_SK(sk);
 		if (cb->src != dn_saddr2dn(&scp->peer))
 			continue;
@@ -1045,6 +1114,9 @@
 		sizeof(struct optdata_dn));
 
 	lock_sock(newsk);
+	/*
+	 * FIXME: This can fail if we've run out of local ports....
+	 */
 	dn_hash_sock(newsk);
 
 	dn_send_conn_ack(newsk);
@@ -1200,6 +1272,7 @@
 	sk->ack_backlog     = 0;
 	sk->state           = TCP_LISTEN;
 	err                 = 0;
+	dn_rehash_sock(sk);
 
 out:
 	release_sock(sk);
@@ -2063,44 +2136,47 @@
 	char buf2[DN_ASCBUF_LEN];
 	char local_object[DN_MAXOBJL+3];
 	char remote_object[DN_MAXOBJL+3];
+	int i;
 
 	len += sprintf(buffer + len, "Local                                              Remote\n");
 
 	read_lock(&dn_hash_lock);
-	for(sk = dn_sklist; sk != NULL; sk = sk->next) {
-		scp = DN_SK(sk);
-
-		dn_printable_object(&scp->addr, local_object);
-		dn_printable_object(&scp->peer, remote_object);
-
-		len += sprintf(buffer + len,
-				"%6s/%04X %04d:%04d %04d:%04d %01d %-16s %6s/%04X %04d:%04d %04d:%04d %01d %-16s %4s %s\n",
-				dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->addr)), buf1),
-				scp->addrloc,
-				scp->numdat,
-				scp->numoth,
-				scp->ackxmt_dat,
-				scp->ackxmt_oth,
-				scp->flowloc_sw,
-				local_object,
-				dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->peer)), buf2),
-				scp->addrrem,
-				scp->numdat_rcv,
-				scp->numoth_rcv,
-				scp->ackrcv_dat,
-				scp->ackrcv_oth,
-				scp->flowrem_sw,
-				remote_object,
-				dn_state2asc(scp->state),
-				((scp->accept_mode == ACC_IMMED) ? "IMMED" : "DEFER"));
-
-		pos = begin + len;
-		if (pos < offset) {
-			len = 0;
-			begin = pos;
+	for(i = 0; i < DN_SK_HASH_SIZE; i++) {
+		for(sk = dn_sk_hash[i]; sk != NULL; sk = sk->next) {
+			scp = DN_SK(sk);
+
+			dn_printable_object(&scp->addr, local_object);
+			dn_printable_object(&scp->peer, remote_object);
+
+			len += sprintf(buffer + len,
+					"%6s/%04X %04d:%04d %04d:%04d %01d %-16s %6s/%04X %04d:%04d %04d:%04d %01d %-16s %4s %s\n",
+					dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->addr)), buf1),
+					scp->addrloc,
+					scp->numdat,
+					scp->numoth,
+					scp->ackxmt_dat,
+					scp->ackxmt_oth,
+					scp->flowloc_sw,
+					local_object,
+					dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->peer)), buf2),
+					scp->addrrem,
+					scp->numdat_rcv,
+					scp->numoth_rcv,
+					scp->ackrcv_dat,
+					scp->ackrcv_oth,
+					scp->flowrem_sw,
+					remote_object,
+					dn_state2asc(scp->state),
+					((scp->accept_mode == ACC_IMMED) ? "IMMED" : "DEFER"));
+
+			pos = begin + len;
+			if (pos < offset) {
+				len = 0;
+				begin = pos;
+			}
+			if (pos > (offset + length))
+				break;
 		}
-		if (pos > (offset + length))
-			break;
 	}
 	read_unlock(&dn_hash_lock);
 
@@ -2158,7 +2234,7 @@
 MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node");
 #endif
 
-static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.4.9s (C) 1995-2001 Linux DECnet Project Team\n";
+static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.4.15-pre5s (C) 1995-2001 Linux DECnet Project Team\n";
 
 static int __init decnet_init(void)
 {
diff -urN linux-2.4.17-pre4/net/ipv4/netfilter/ip_fw_compat_redir.c linux/net/ipv4/netfilter/ip_fw_compat_redir.c
--- linux-2.4.17-pre4/net/ipv4/netfilter/ip_fw_compat_redir.c	Fri Aug  4 13:07:24 2000
+++ linux/net/ipv4/netfilter/ip_fw_compat_redir.c	Thu Dec  6 10:53:04 2001
@@ -206,6 +206,8 @@
 			}
 			list_prepend(&redirs, redir);
 			init_timer(&redir->destroyme);
+			redir->destroyme.expires = jiffies + 75*HZ;
+			add_timer(&redir->destroyme);
 		}
 		/* In case mangling has changed, rewrite this part. */
 		redir->core = ((struct redir_core)
diff -urN linux-2.4.17-pre4/net/ipv4/netfilter/ipt_unclean.c linux/net/ipv4/netfilter/ipt_unclean.c
--- linux-2.4.17-pre4/net/ipv4/netfilter/ipt_unclean.c	Sun Sep 30 12:26:08 2001
+++ linux/net/ipv4/netfilter/ipt_unclean.c	Thu Dec  6 10:53:04 2001
@@ -257,6 +257,8 @@
 #define	TH_PUSH	0x08
 #define	TH_ACK	0x10
 #define	TH_URG	0x20
+#define	TH_ECE	0x40
+#define	TH_CWR	0x80
 
 /* TCP-specific checks. */
 static int
@@ -328,9 +330,10 @@
 	}
 
 	/* CHECK: TCP flags. */
-	tcpflags = ((u_int8_t *)tcph)[13];
+	tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
 	if (tcpflags != TH_SYN
 	    && tcpflags != (TH_SYN|TH_ACK)
+		&& tcpflags != TH_RST
 	    && tcpflags != (TH_RST|TH_ACK)
 	    && tcpflags != (TH_RST|TH_ACK|TH_PUSH)
 	    && tcpflags != (TH_FIN|TH_ACK)
diff -urN linux-2.4.17-pre4/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- linux-2.4.17-pre4/net/ipv4/tcp_ipv4.c	Thu Dec  6 10:52:26 2001
+++ linux/net/ipv4/tcp_ipv4.c	Thu Dec  6 10:53:04 2001
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_ipv4.c,v 1.236 2001/11/06 22:21:08 davem Exp $
+ * Version:	$Id: tcp_ipv4.c,v 1.237 2001/12/05 08:54:10 davem Exp $
  *
  *		IPv4 specific functions
  *
@@ -754,21 +754,19 @@
 }
 
 static struct open_request *tcp_v4_search_req(struct tcp_opt *tp, 
-					      struct iphdr *iph,
-					      struct tcphdr *th,
-					      struct open_request ***prevp)
+					      struct open_request ***prevp,
+					      __u16 rport,
+					      __u32 raddr, __u32 laddr)
 {
 	struct tcp_listen_opt *lopt = tp->listen_opt;
 	struct open_request *req, **prev;  
-	__u16 rport = th->source;
-	__u32 raddr = iph->saddr;
 
 	for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport)];
 	     (req = *prev) != NULL;
 	     prev = &req->dl_next) {
 		if (req->rmt_port == rport &&
 		    req->af.v4_req.rmt_addr == raddr &&
-		    req->af.v4_req.loc_addr == iph->daddr &&
+		    req->af.v4_req.loc_addr == laddr &&
 		    TCP_INET_FAMILY(req->class->family)) {
 			BUG_TRAP(req->sk == NULL);
 			*prevp = prev;
@@ -939,7 +937,9 @@
 		if (sk->lock.users != 0)
 			goto out;
 
-		req = tcp_v4_search_req(tp, iph, th, &prev); 
+		req = tcp_v4_search_req(tp, &prev,
+					th->dest,
+					iph->daddr, iph->saddr); 
 		if (!req)
 			goto out;
 
@@ -1473,11 +1473,14 @@
 {
 	struct open_request *req, **prev;
 	struct tcphdr *th = skb->h.th;
+	struct iphdr *iph = skb->nh.iph;
 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
 	struct sock *nsk;
 
 	/* Find possible connection requests. */
-	req = tcp_v4_search_req(tp, skb->nh.iph, th, &prev);
+	req = tcp_v4_search_req(tp, &prev,
+				th->source,
+				iph->saddr, iph->daddr);
 	if (req)
 		return tcp_check_req(sk, skb, req, prev);
 
diff -urN linux-2.4.17-pre4/net/packet/af_packet.c linux/net/packet/af_packet.c
--- linux-2.4.17-pre4/net/packet/af_packet.c	Thu Dec  6 10:52:26 2001
+++ linux/net/packet/af_packet.c	Thu Dec  6 10:53:04 2001
@@ -5,7 +5,7 @@
  *
  *		PACKET - implements raw packet sockets.
  *
- * Version:	$Id: af_packet.c,v 1.57 2001/10/30 03:38:37 davem Exp $
+ * Version:	$Id: af_packet.c,v 1.58 2001/11/28 21:02:10 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
diff -urN linux-2.4.17-pre4/net/sunrpc/xprt.c linux/net/sunrpc/xprt.c
--- linux-2.4.17-pre4/net/sunrpc/xprt.c	Mon Oct  8 12:36:07 2001
+++ linux/net/sunrpc/xprt.c	Thu Dec  6 10:53:04 2001
@@ -630,10 +630,14 @@
 			int to_move = cur_len;
 			if (to_move > copied)
 				to_move = copied;
-			if (need_csum)
-				csum = skb_copy_and_csum_bits(skb, offset, cur_ptr,
-							      to_move, csum);
-			else
+			if (need_csum) {
+				unsigned int csum2;
+
+				csum2 = skb_copy_and_csum_bits(skb, offset,
+							       cur_ptr,
+							       to_move, 0);
+				csum = csum_block_add(csum, csum2, offset);
+			} else
 				skb_copy_bits(skb, offset, cur_ptr, to_move);
 			offset += to_move;
 			copied -= to_move;
@@ -647,8 +651,12 @@
 		}
 	}
 	if (need_csum) {
-		if (slack > 0)
-			csum = skb_checksum(skb, offset, slack, csum);
+		if (slack > 0) {
+			unsigned int csum2;
+
+			csum2 = skb_checksum(skb, offset, slack, 0);
+			csum = csum_block_add(csum, csum2, offset);
+		}
 		if ((unsigned short)csum_fold(csum))
 			return -1;
 	}
