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

diff -urN linux-2.4.4-pre4/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.4.4-pre4/Documentation/Configure.help	Mon Dec  3 22:35:44 2001
+++ linux/Documentation/Configure.help	Mon Dec  3 22:35:54 2001
@@ -2462,20 +2462,6 @@
   a module, say M here and read Documentation/modules.txt. If unsure,
   say N.
 
-CardBus serial device support
-CONFIG_PCMCIA_SERIAL_CB
-  Say Y here to enable support for CardBus serial devices, including
-  serial port cards, modems, and the modem functions of multi-function
-  ethernet/modem devices. (CardBus cards are the newer and better 
-  version of PCMCIA- or PC-cards: credit card size devices often 
-  used with laptops.)
-
-  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 serial_cb.o. If you want to compile it as
-  a module, say M here and read Documentation/modules.txt. If unsure,
-  say N.
-
 /dev/agpgart (AGP Support) (EXPERIMENTAL)
 CONFIG_AGP
   AGP (Accelerated Graphics Port) is a bus system mainly used to
diff -urN linux-2.4.4-pre4/Documentation/DMA-mapping.txt linux/Documentation/DMA-mapping.txt
--- linux-2.4.4-pre4/Documentation/DMA-mapping.txt	Tue Mar  6 22:44:15 2001
+++ linux/Documentation/DMA-mapping.txt	Mon Dec  3 22:35:54 2001
@@ -32,6 +32,35 @@
 the dma_addr_t type which should be used everywhere you hold a DMA
 (bus) address returned from the DMA mapping functions.
 
+			 What memory is DMA'able?
+
+The first piece of information you must know is what kernel memory can
+be used with the DMA mapping facilitites.  There has been an unwritten
+set of rules regarding this, and this text is an attempt to finally
+write them down.
+
+If you acquired your memory via the page allocator
+(i.e. __get_free_page*()) or the generic memory allocators
+(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
+that memory using the addresses returned from those routines.
+
+This means specifically that you may _not_ use the memory/addresses
+returned from vmalloc() for DMA.  It is possible to DMA to the
+_underlying_ memory mapped into a vmalloc() area, but this requires
+walking page tables to get the physical addresses, and then
+translating each of those pages back to a kernel address using
+something like __va().
+
+This rule also means that you may not use kernel image addresses
+(ie. items in the kernel's data/text/bss segment, or your driver's)
+nor may you use kernel stack addresses for DMA.  Both of these items
+might be mapped somewhere entirely different than the rest of physical
+memory.
+
+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.
+
 			DMA addressing limitations
 
 Does your device have any DMA addressing limitations?  For example, is
@@ -168,16 +197,21 @@
   optimizations the hardware allows.  To this end, when using
   such mappings you must be explicit about what you want to happen.
 
+Neither type of DMA mapping has alignment restrictions that come
+from PCI, although some devices may have such restrictions.
+
 		 Using Consistent DMA mappings.
 
-To allocate and map a consistent DMA region, you should do:
+To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
+you should do:
 
 	dma_addr_t dma_handle;
 
 	cpu_addr = pci_alloc_consistent(dev, size, &dma_handle);
 
 where dev is a struct pci_dev *. You should pass NULL for PCI like buses
-where devices don't have struct pci_dev (like ISA, EISA).
+where devices don't have struct pci_dev (like ISA, EISA).  This may be
+called in interrupt context. 
 
 This argument is needed because the DMA translations may be bus
 specific (and often is private to the bus which the device is attached
@@ -186,7 +220,9 @@
 Size is the length of the region you want to allocate.
 
 This routine will allocate RAM for that region, so it acts similarly to
-__get_free_pages (but takes size instead of a page order).
+__get_free_pages (but takes size instead of a page order).  If your
+driver needs regions sized smaller than a page, you may prefer using
+the pci_pool interface, described below.
 
 It returns two values: the virtual address which you can use to access
 it from the CPU and dma_handle which you pass to the card.
@@ -205,6 +241,51 @@
 where dev, size are the same as in the above call and cpu_addr and
 dma_handle are the values pci_alloc_consistent returned to you.
 
+If your driver needs lots of smaller memory regions, you can write
+custom code to subdivide pages returned by pci_alloc_consistent,
+or you can use the pci_pool API to do that.  A pci_pool is like
+a kmem_cache, but it uses pci_alloc_consistent not __get_free_pages.
+Also, it understands common hardware constraints for alignment,
+like queue heads needing to be aligned on N byte boundaries.
+
+Create a pci_pool like this:
+
+	struct pci_pool *pool;
+
+	pool = pci_pool_create(name, dev, size, align, alloc, flags);
+
+The "name" is for diagnostics (like a kmem_cache name); dev and size
+are as above.  The device's hardware alignment requirement for this
+type of data is "align" (a power of two).  The flags are SLAB_ flags
+as you'd pass to kmem_cache_create.  Not all flags are understood, but
+SLAB_POISON may help you find driver bugs.  If you call this in a non-
+sleeping context (f.e. in_interrupt is true or while holding SMP
+locks), pass SLAB_ATOMIC.  If your device has no boundary crossing
+restrictions, pass 0 for alloc; passing 4096 says memory allocated
+from this pool must not cross 4KByte boundaries.
+
+Allocate memory from a pci pool like this:
+
+	cpu_addr = pci_pool_alloc(pool, flags, &dma_handle);
+
+flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
+holding SMP locks), SLAB_ATOMIC otherwise.  Like pci_alloc_consistent,
+this returns two values, cpu_addr and dma_handle,
+
+Free memory that was allocated from a pci_pool like this:
+
+	pci_pool_free(pool, cpu_addr, dma_handle);
+
+where pool is what you passed to pci_pool_alloc, and cpu_addr and
+dma_handle are the values pci_pool_alloc returned.
+
+Destroy a pci_pool by calling:
+
+	pci_pool_destroy(pool);
+
+Make sure you've called pci_pool_free for all memory allocated
+from a pool before you destroy the pool.
+
 			DMA Direction
 
 The interfaces described in subsequent portions of this document
@@ -389,9 +470,10 @@
 longer, nor should they use bus_to_virt. Some drivers have to be changed a
 little bit, because there is no longer an equivalent to bus_to_virt in the
 dynamic DMA mapping scheme - you have to always store the DMA addresses
-returned by the pci_alloc_consistent and pci_map_single calls (pci_map_sg
-stores them in the scatterlist itself if the platform supports dynamic DMA
-mapping in hardware) in your driver structures and/or in the card registers.
+returned by the pci_alloc_consistent, pci_pool_alloc, and pci_map_single
+calls (pci_map_sg stores them in the scatterlist itself if the platform
+supports dynamic DMA mapping in hardware) in your driver structures and/or
+in the card registers.
 
 This document, and the API itself, would not be in it's current
 form without the feedback and suggestions from numerous individuals.
diff -urN linux-2.4.4-pre4/Documentation/DocBook/tulip-user.tmpl linux/Documentation/DocBook/tulip-user.tmpl
--- linux-2.4.4-pre4/Documentation/DocBook/tulip-user.tmpl	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/DocBook/tulip-user.tmpl	Mon Dec  3 22:35:54 2001
@@ -0,0 +1,325 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
+
+<book id="TulipUserGuide">
+ <bookinfo>
+  <title>Tulip Driver User's Guide</title>
+  
+  <authorgroup>
+   <author>
+    <firstname>Jeff</firstname>
+    <surname>Garzik</surname>
+    <affiliation>
+     <address>
+      <email>jgarzik@mandrakesoft.com</email>
+     </address>
+    </affiliation>
+   </author>
+  </authorgroup>
+
+  <copyright>
+   <year>2001</year>
+   <holder>Jeff Garzik</holder>
+  </copyright>
+
+  <legalnotice>
+   <para>
+     This documentation is free software; you can redistribute
+     it and/or modify it under the terms of the GNU General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later
+     version.
+   </para>
+      
+   <para>
+     This program is distributed in the hope that it will be
+     useful, but WITHOUT ANY WARRANTY; without even the implied
+     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+     See the GNU General Public License for more details.
+   </para>
+      
+   <para>
+     You should have received a copy of the GNU General Public
+     License along with this program; if not, write to the Free
+     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+     MA 02111-1307 USA
+   </para>
+      
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+ <toc></toc>
+
+  <chapter id="intro">
+    <title>Introduction</title>
+<para>
+The Tulip Ethernet Card Driver
+is maintained by Jeff Garzik (<email>jgarzik@mandrakesoft.com</email>).
+</para>
+
+<para>
+The Tulip driver was developed by Donald Becker and changed by
+Jeff Garzik, Takashi Manabe and a cast of thousands.
+</para>
+
+<para>
+For 2.4.x and later kernels, the Linux Tulip driver is available at
+<ULink URL="http://sourceforge.net/projects/tulip/">http://sourceforge.net/projects/tulip/</ULink>
+</para>
+
+<para>
+	This driver is for the Digital "Tulip" Ethernet adapter interface.
+	It should work with most DEC 21*4*-based chips/ethercards, as well as
+	with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and ASIX.
+</para>
+
+<para>
+        The original author may be reached as becker@scyld.com, or C/O
+        Scyld Computing Corporation,
+        410 Severn Ave., Suite 210,
+        Annapolis MD 21403
+</para>
+
+<para>
+	Additional information on Donald Becker's tulip.c
+	is available at <ULink URL="http://www.scyld.com/network/tulip.html">http://www.scyld.com/network/tulip.html</ULink>
+</para>
+
+  </chapter>
+
+  <chapter id="drvr_compat">
+    <title>Driver Compatibility</title>
+
+<para>
+This device driver is designed for the DECchip "Tulip", Digital's
+single-chip ethernet controllers for PCI (now owned by Intel).
+Supported members of the family
+are the 21040, 21041, 21140, 21140A, 21142, and 21143.  Similar work-alike
+chips from Lite-On, Macronics, ASIX, Compex and other listed below are also
+supported.
+</para>
+
+<para>
+These chips are used on at least 140 unique PCI board designs.  The great
+number of chips and board designs supported is the reason for the
+driver size and complexity.  Almost of the increasing complexity is in the
+board configuration and media selection code.  There is very little
+increasing in the operational critical path length.
+</para>
+  </chapter>
+
+  <chapter id="board_settings">
+    <title>Board-specific Settings</title>
+
+<para>
+PCI bus devices are configured by the system at boot time, so no jumpers
+need to be set on the board.  The system BIOS preferably should assign the
+PCI INTA signal to an otherwise unused system IRQ line.
+</para>
+
+<para>
+Some boards have EEPROMs tables with default media entry.  The factory default
+is usually "autoselect".  This should only be overridden when using
+transceiver connections without link beat e.g. 10base2 or AUI, or (rarely!)
+for forcing full-duplex when used with old link partners that do not do
+autonegotiation.
+</para>
+  </chapter>
+
+  <chapter id="driver_operation">
+    <title>Driver Operation</title>
+
+<sect1><title>Ring buffers</title>
+
+<para>
+The Tulip can use either ring buffers or lists of Tx and Rx descriptors.
+This driver uses statically allocated rings of Rx and Tx descriptors, set at
+compile time by RX/TX_RING_SIZE.  This version of the driver allocates skbuffs
+for the Rx ring buffers at open() time and passes the skb->data field to the
+Tulip as receive data buffers.  When an incoming frame is less than
+RX_COPYBREAK bytes long, a fresh skbuff is allocated and the frame is
+copied to the new skbuff.  When the incoming frame is larger, the skbuff is
+passed directly up the protocol stack and replaced by a newly allocated
+skbuff.
+</para>
+
+<para>
+The RX_COPYBREAK value is chosen to trade-off the memory wasted by
+using a full-sized skbuff for small frames vs. the copying costs of larger
+frames.  For small frames the copying cost is negligible (esp. considering
+that we are pre-loading the cache with immediately useful header
+information).  For large frames the copying cost is non-trivial, and the
+larger copy might flush the cache of useful data.  A subtle aspect of this
+choice is that the Tulip only receives into longword aligned buffers, thus
+the IP header at offset 14 isn't longword aligned for further processing.
+Copied frames are put into the new skbuff at an offset of "+2", thus copying
+has the beneficial effect of aligning the IP header and preloading the
+cache.
+</para>
+
+</sect1>
+
+<sect1><title>Synchronization</title>
+<para>
+The driver runs as two independent, single-threaded flows of control.  One
+is the send-packet routine, which enforces single-threaded use by the
+dev->tbusy flag.  The other thread is the interrupt handler, which is single
+threaded by the hardware and other software.
+</para>
+
+<para>
+The send packet thread has partial control over the Tx ring and 'dev->tbusy'
+flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
+queue slot is empty, it clears the tbusy flag when finished otherwise it sets
+the 'tp->tx_full' flag.
+</para>
+
+<para>
+The interrupt handler has exclusive control over the Rx ring and records stats
+from the Tx ring.  (The Tx-done interrupt can't be selectively turned off, so
+we can't avoid the interrupt overhead by having the Tx routine reap the Tx
+stats.)	 After reaping the stats, it marks the queue entry as empty by setting
+the 'base' to zero.	 Iff the 'tp->tx_full' flag is set, it clears both the
+tx_full and tbusy flags.
+</para>
+
+</sect1>
+
+  </chapter>
+
+  <chapter id="errata">
+    <title>Errata</title>
+
+<para>
+The old DEC databooks were light on details.
+The 21040 databook claims that CSR13, CSR14, and CSR15 should each be the last
+register of the set CSR12-15 written.  Hmmm, now how is that possible?
+</para>
+
+<para>
+The DEC SROM format is very badly designed not precisely defined, leading to
+part of the media selection junkheap below.  Some boards do not have EEPROM
+media tables and need to be patched up.  Worse, other boards use the DEC
+design kit media table when it isn't correct for their board.
+</para>
+
+<para>
+We cannot use MII interrupts because there is no defined GPIO pin to attach
+them.  The MII transceiver status is polled using an kernel timer.
+</para>
+  </chapter>
+
+  <chapter id="changelog">
+    <title>Driver Change History</title>
+
+    <sect1><title>Version 0.9.14 (February 20, 2001)</title>
+    <itemizedlist>
+    <listitem><para>Fix PNIC problems (Manfred Spraul)</para></listitem>
+    <listitem><para>Add new PCI id for Accton comet</para></listitem>
+    <listitem><para>Support Davicom tulips</para></listitem>
+    <listitem><para>Fix oops in eeprom parsing</para></listitem>
+    <listitem><para>Enable workarounds for early PCI chipsets</para></listitem>
+    <listitem><para>IA64, hppa csr0 support</para></listitem>
+    <listitem><para>Support media types 5, 6</para></listitem>
+    <listitem><para>Interpret a bit more of the 21142 SROM extended media type 3</para></listitem>
+    <listitem><para>Add missing delay in eeprom reading</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.11 (November 3, 2000)</title>
+    <itemizedlist>
+    <listitem><para>Eliminate extra bus accesses when sharing interrupts (prumpf)</para></listitem>
+    <listitem><para>Barrier following ownership descriptor bit flip (prumpf)</para></listitem>
+    <listitem><para>Endianness fixes for >14 addresses in setup frames (prumpf)</para></listitem>
+    <listitem><para>Report link beat to kernel/userspace via netif_carrier_*. (kuznet)</para></listitem>
+    <listitem><para>Better spinlocking in set_rx_mode.</para></listitem>
+    <listitem><para>Fix I/O resource request failure error messages (DaveM catch)</para></listitem>
+    <listitem><para>Handle DMA allocation failure.</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.10 (September 6, 2000)</title>
+    <itemizedlist>
+    <listitem><para>Simple interrupt mitigation (via jamal)</para></listitem>
+    <listitem><para>More PCI ids</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.9 (August 11, 2000)</title>
+    <itemizedlist>
+    <listitem><para>More PCI ids</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.8 (July 13, 2000)</title>
+    <itemizedlist>
+    <listitem><para>Correct signed/unsigned comparison for dummy frame index</para></listitem>
+    <listitem><para>Remove outdated references to struct enet_statistics</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.7 (June 17, 2000)</title>
+    <itemizedlist>
+    <listitem><para>Timer cleanups (Andrew Morton)</para></listitem>
+    <listitem><para>Alpha compile fix (somebody?)</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.6 (May 31, 2000)</title>
+    <itemizedlist>
+    <listitem><para>Revert 21143-related support flag patch</para></listitem>
+    <listitem><para>Add HPPA/media-table debugging printk</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.5 (May 30, 2000)</title>
+    <itemizedlist>
+    <listitem><para>HPPA support (willy@puffingroup)</para></listitem>
+    <listitem><para>CSR6 bits and tulip.h cleanup (Chris Smith)</para></listitem>
+    <listitem><para>Improve debugging messages a bit</para></listitem>
+    <listitem><para>Add delay after CSR13 write in t21142_start_nway</para></listitem>
+    <listitem><para>Remove unused ETHER_STATS code</para></listitem>
+    <listitem><para>Convert 'extern inline' to 'static inline' in tulip.h (Chris Smith)</para></listitem>
+    <listitem><para>Update DS21143 support flags in tulip_chip_info[]</para></listitem>
+    <listitem><para>Use spin_lock_irq, not _irqsave/restore, in tulip_start_xmit()</para></listitem>
+    <listitem><para>Add locking to set_rx_mode()</para></listitem>
+    <listitem><para>Fix race with chip setting DescOwned bit (Hal Murray)</para></listitem>
+    <listitem><para>Request 100% of PIO and MMIO resource space assigned to card</para></listitem>
+    <listitem><para>Remove error message from pci_enable_device failure</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.4.3 (April 14, 2000)</title>
+    <itemizedlist>
+    <listitem><para>mod_timer fix (Hal Murray)</para></listitem>
+    <listitem><para>PNIC2 resuscitation (Chris Smith)</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.4.2 (March 21, 2000)</title>
+    <itemizedlist>
+    <listitem><para>Fix 21041 CSR7, CSR13/14/15 handling</para></listitem>
+    <listitem><para>Merge some PCI ids from tulip 0.91x</para></listitem>
+    <listitem><para>Merge some HAS_xxx flags and flag settings from tulip 0.91x</para></listitem>
+    <listitem><para>asm/io.h fix (submitted by many) and cleanup</para></listitem>
+    <listitem><para>s/HAS_NWAY143/HAS_NWAY/</para></listitem>
+    <listitem><para>Cleanup 21041 mode reporting</para></listitem>
+    <listitem><para>Small code cleanups</para></listitem>
+    </itemizedlist>
+    </sect1>
+
+    <sect1><title>Version 0.9.4.1 (March 18, 2000)</title>
+    <itemizedlist>
+    <listitem><para>Finish PCI DMA conversion (davem)</para></listitem>
+    <listitem><para>Do not netif_start_queue() at end of tulip_tx_timeout() (kuznet)</para></listitem>
+    <listitem><para>PCI DMA fix (kuznet)</para></listitem>
+    <listitem><para>eeprom.c code cleanup</para></listitem>
+    <listitem><para>Remove Xircom Tulip crud</para></listitem>
+    </itemizedlist>
+    </sect1>
+  </chapter>
+
+</book>
diff -urN linux-2.4.4-pre4/Documentation/i810_rng.txt linux/Documentation/i810_rng.txt
--- linux-2.4.4-pre4/Documentation/i810_rng.txt	Sun Mar 25 18:24:31 2001
+++ linux/Documentation/i810_rng.txt	Mon Dec  3 22:35:54 2001
@@ -70,6 +70,9 @@
 
 Change history:
 
+	Version 0.9.6:
+	* Internal driver cleanups, prep for 1.0.0 release.
+
 	Version 0.9.5:
 	* Rip out entropy injection via timer.  It never ever worked,
 	  and a better solution (rngd) is now available.
diff -urN linux-2.4.4-pre4/Documentation/isapnp.txt linux/Documentation/isapnp.txt
--- linux-2.4.4-pre4/Documentation/isapnp.txt	Mon Oct  9 17:53:05 2000
+++ linux/Documentation/isapnp.txt	Mon Dec  3 22:35:54 2001
@@ -7,14 +7,14 @@
 Read commands:
 --------------
 
-No comment..
+No comment.
 
 Write commands:
 ---------------
 
-With the write interface you can simply activate or modify the configuration
-for ISA Plug & Play devices. It is mainly useable for drivers which has not
-use the ISA Plug & Play kernel support yet.
+With the write interface you can activate or modify the configuration of
+ISA Plug & Play devices.  It is mainly useful for drivers which have not
+been rewritten to use the ISA Plug & Play kernel support yet.
 
 card <idx> <vendor>	- select PnP device by vendor identification
 csn <CSN>		- select PnP device by CSN
@@ -33,8 +33,8 @@
 Explanation:
 	- variable <idx> begins with zero
 	- variable <CSN> begins with one
-	- <vendor> is in format 'PNP0000'
-	- <logdev> is in format 'PNP0000'
+	- <vendor> is in the standard format 'ABC1234'
+	- <logdev> is in the standard format 'ABC1234'
 
 Example:
 
@@ -58,38 +58,38 @@
 Information for developers
 ==========================
 
-Finding appropriate device
---------------------------
+Finding a device
+----------------
 
 extern struct pci_bus *isapnp_find_card(unsigned short vendor,
                                         unsigned short device,
                                         struct pci_bus *from);
 
-This function finds a ISA PnP card. For the vendor device should
-be used ISAPNP_VENDOR(a,b,c) where a,b,c are characters or integers.
-For the device number should be used ISAPNP_DEVICE(x) macro where x is
-integer value. Both vendor and device numbers can be taken from contents
-of the /proc/isapnp file.
+This function finds an ISA PnP card.  For the vendor argument, the
+ISAPNP_VENDOR(a,b,c) macro should be used, where a,b,c are characters or
+integers.  For the device argument the ISAPNP_DEVICE(x) macro should be
+used, where x is an integer value.  Both vendor and device arguments
+can be taken from contents of the /proc/isapnp file.
 
 extern struct pci_dev *isapnp_find_dev(struct pci_bus *card,
                                        unsigned short vendor,
                                        unsigned short function,
                                        struct pci_dev *from);
 
-This function finds the ISA PnP device. If card is NULL, then
-the global search mode is used (all devices are used for the searching).
-Otherwise only devices which belongs to the specified card are verified.
-For the function number can be used ISAPNP_FUNCTION(x) macro which works
-similarly as the ISAPNP_DEVICE(x) macro.
+This function finds an ISA PnP device. If card is NULL, then the global
+search mode is used (all devices are used for the searching).  Otherwise
+only devices which belong to the specified card are checked.  For the
+function number the ISAPNP_FUNCTION(x) macro can be used; it works
+similarly to the ISAPNP_DEVICE(x) macro.
 
 extern int isapnp_probe_cards(const struct isapnp_card_id *ids,
-			      int (*probe)(struct pci_bus *card,
-					   const struct isapnp_card_id *id));
+                              int (*probe)(struct pci_bus *card,
+                              const struct isapnp_card_id *id));
 
 
-This function is a helper for drivers which requires to use more than
-one device from an ISA PnP card. For each cards is called the probe
-callback with appropriate information.
+This function is a helper for drivers which need to use more than
+one device from an ISA PnP card.  The probe callback is called with
+appropriate arguments for each card.
 
 Example for ids parameter initialization:
 
@@ -109,13 +109,13 @@
 ISAPNP_CARD_TABLE(card_ids);
 
 extern int isapnp_probe_devs(const struct isapnp_device_id *ids,
-			     int (*probe)(struct pci_bus *card,
-					  const struct isapnp_device_id *id));
+                             int (*probe)(struct pci_bus *card,
+                             const struct isapnp_device_id *id));
 
 
-This function is a helper for drivers which requires to use one
-device from an ISA PnP card. For each matched devices is called the probe
-callback with appropriate information.
+This function is a helper for drivers which need to use one
+device from an ISA PnP card.  The probe callback is called with
+appropriate arguments for each matched device.
 
 Example for ids parameter initialization:
 
@@ -129,25 +129,25 @@
 ISA PnP configuration
 =====================
 
-There are two ways how can be ISA PnP interface used.
+There are two ways in which the ISA PnP interface can be used.
 
-First way is lowlevel
----------------------
+First way: low-level
+--------------------
 
-All ISA PNP configuration registers are accessible via lowlevel
+All ISA PNP configuration registers are accessible via the low-level
 isapnp_(read|write)_(byte|word|dword) functions.
 
 The function isapnp_cfg_begin() must be called before any lowlevel function.
 The function isapnp_cfg_end() must be always called after configuration
 otherwise the access to the ISA PnP configuration functions will be blocked.
 
-Second way is auto-configuration
---------------------------------
+Second way: auto-configuration
+------------------------------
 
-This feature gives to the driver the real power of the ISA PnP code.
-Function dev->prepare() initializes the resource members in the device
-structure. This structure contains all resources set to auto configuration
-values after the initialization. The device driver may modify some resources
+This feature gives to the driver the real power of the ISA PnP driver.
+The function dev->prepare() initializes the resource members in the device
+structure.  This structure contains all resources set to auto configuration
+values after the initialization.  The device driver may modify some resources
 to skip the auto configuration for a given resource.
 
 Once the device structure contains all requested resource values, the function
@@ -155,12 +155,12 @@
 with the auto configuration value.
 
 Function dev->activate() does:
-	- resources with the auto configuration value are configured
-	- the auto configuration is created using ISA PnP resource map
-	- the function writes configuration to ISA PnP configuration registers
-	- the function returns to the caller actual used resources
+   - resources with the auto configuration value are configured
+   - the auto configuration is created using ISA PnP resource map
+   - the function writes configuration to ISA PnP configuration registers
+   - the function returns to the caller actual used resources
 
-When the device driver is removing, function dev->deactivate() has to be
+When the device driver is removed, function dev->deactivate() has to be
 called to free all assigned resources.
 
 Example (game port initialization)
diff -urN linux-2.4.4-pre4/Documentation/kernel-parameters.txt linux/Documentation/kernel-parameters.txt
--- linux-2.4.4-pre4/Documentation/kernel-parameters.txt	Fri Mar  2 11:02:15 2001
+++ linux/Documentation/kernel-parameters.txt	Mon Dec  3 22:35:54 2001
@@ -22,6 +22,7 @@
 	HW	Appropriate hardware is enabled.
 	IA-32	IA-32 aka i386 architecture is enabled.
 	IA-64	IA-64 architecture is enabled.
+	ISAPNP  ISA PnP code is enabled.
 	ISDN	Appropriate ISDN support is enabled.
 	JOY 	Appropriate joystick support is enabled.
 	LP	Printer support is enabled.
@@ -246,6 +247,18 @@
 
 	ip=		[PNP]
 
+	isapnp=		[ISAPNP] Specify RDP, reset, pci_scan and verbosity.
+
+	isapnp_reserve_irq= [ISAPNP] Exclude IRQs for the autoconfiguration.
+
+	isapnp_reserve_dma= [ISAPNP] Exclude DMAs for the autoconfiguration.
+
+	isapnp_reserve_io= [ISAPNP] Exclude I/O ports for the autoconfiguration.
+				    Ranges are in pairs (I/O port base and size).
+
+	isapnp_reserve_mem= [ISAPNP] Exclude memory regions for the autoconfiguration.
+				     Ranges are in pairs (memory base and size).
+
 	isp16=		[HW,CD]
 
 	iucv=		[HW,NET] 
@@ -361,6 +374,8 @@
 	nohlt		[BUGS=ARM]
  
 	no-hlt		[BUGS=ix86]
+
+	noisapnp	[ISAPNP] Disables ISA PnP code.
 
 	noinitrd	[RAM] Tells the kernel not to load any configured
 			initial RAM disk.
diff -urN linux-2.4.4-pre4/Documentation/networking/8139too.txt linux/Documentation/networking/8139too.txt
--- linux-2.4.4-pre4/Documentation/networking/8139too.txt	Sun Mar 25 18:24:31 2001
+++ linux/Documentation/networking/8139too.txt	Mon Dec  3 22:35:54 2001
@@ -185,6 +185,24 @@
 Change History
 --------------
 
+Version 0.9.16 - April 14, 2001
+
+* Complete MMIO audit, disable read-after-every-write
+* Update Rx interrupt handling
+* Enable Early Rx thresholds, highly recommended to reduce
+  Rx FIFO overflow
+* Make 8129 support conditional
+* Support for new 2.4.3 kernel APIs
+* More correct PIO/MMIO PCI BAR region size checking
+* Add check for totally dead/missing hardware
+* Disable media timer code to "set full duplex"
+* s/spin_lock_irq/spin_lock_irqsave/
+* Only set AcceptMulticast if more than one mc address
+* Only set rx_mode if changed, in set_rx_mode
+* Only suspend/resume if interface is up
+* Always print out version upon module load, even if no devices found
+
+
 Version 0.9.15 - February 20, 2001
 
 * Call pci_enable_device to wake up/assign resource to device,
diff -urN linux-2.4.4-pre4/Documentation/networking/TODO linux/Documentation/networking/TODO
--- linux-2.4.4-pre4/Documentation/networking/TODO	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/networking/TODO	Mon Dec  3 22:35:54 2001
@@ -0,0 +1,25 @@
+To-do items for network drivers
+-------------------------------
+
+* Move ethernet crc routine to generic code
+
+* (for 2.5) Integrate Jamal Hadi Salim's netdev Rx polling API change
+
+* Audit all net drivers to make sure magic packet / wake-on-lan /
+  similar features are disabled in the driver by default.
+
+* Audit all net drivers to make sure the module always prints out a
+  version string when loaded as a module, but only prints a version
+  string when built into the kernel if a device is detected.
+
+* Add ETHTOOL_GDRVINFO ioctl support to all ethernet drivers.
+
+
+
+To-do items to consider for network drivers
+-------------------------------------------
+* Make a single function which handles the ethtool ioctl for
+  most MII-compatible devices?  Ideally the driver would pass function
+  pointers to its existing mdio_{read,write} functions when calling the
+  generic ioctl handler.
+
diff -urN linux-2.4.4-pre4/Documentation/networking/olympic.txt linux/Documentation/networking/olympic.txt
--- linux-2.4.4-pre4/Documentation/networking/olympic.txt	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/networking/olympic.txt	Mon Dec  3 22:35:54 2001
@@ -3,18 +3,21 @@
 
 Release 0.2.0 - Release    
 	June 8th 1999 Peter De Schrijver & Mike Phillips
-
+Release 0.9.C - Release
+	April 18th 2001 Mike Phillips
 
 Thanks:
 Erik De Cock, Adrian Bridgett and Frank Fiene for their 
-patience and testing.  
-Paul Norton without whose tr.c code we would have had
-a lot more work to do.
+patience and testing.
+Donald Champion for the cardbus support
+Kyle Lucke for the dma api changes.   
+Jonathon Bitner for hardware support. 
+Everybody on linux-tr for their continued support.  
  
 Options:
 
-The driver accepts three options: ringspeed, pkt_buf_sz, and  
-message_level.
+The driver accepts four options: ringspeed, pkt_buf_sz,  
+message_level and network_monitor.
 
 These options can be specified differently for each card found. 
 
@@ -40,6 +43,17 @@
 value will display all soft messages as well.  NB This does not turn 
 debugging messages on, that must be done by modified the source code.
 
+network_monitor: Any non-zero value will provide a quasi network monitoring 
+mode.  All unexpected MAC frames (beaconing etc.) will be received
+by the driver and the source and destination addresses printed. 
+Also an entry will be added in  /proc/net called olympic_tr%d, where tr%d
+is the registered device name, i.e tr0, tr1, etc. This displays low
+level information about the configuration of the ring and the adapter.
+This feature has been designed for network administrators to assist in 
+the diagnosis of network / ring problems. (This used to OLYMPIC_NETWORK_MONITOR,
+but has now changed to allow each adapter to be configured differently and
+to alleviate the necessity to re-compile olympic to turn the option on).
+
 Multi-card:
 
 The driver will detect multiple cards and will work with shared interrupts,
@@ -60,16 +74,6 @@
 building routers, gateway's etc, you could start to use a lot of memory
 real fast.
 
-Network Monitor Mode:
-
-By modifying the #define OLYMPIC_NETWORK_MONITOR from 0 to 1 in the 
-source code the driver will implement a quasi network monitoring 
-mode.  All unexpected MAC frames (beaconing etc.) will be received
-by the driver and the source and destination addresses printed. 
-Also an entry will be added in  /proc/net called olympic_tr. This 
-displays low level information about the configuration of the ring and
-the adapter. This feature has been designed for network administrators
-to assist in the diagnosis of network / ring problems.
 
 6/8/99 Peter De Schrijver and Mike Phillips
 
diff -urN linux-2.4.4-pre4/MAINTAINERS linux/MAINTAINERS
--- linux-2.4.4-pre4/MAINTAINERS	Mon Dec  3 22:35:44 2001
+++ linux/MAINTAINERS	Mon Dec  3 22:35:54 2001
@@ -961,9 +961,9 @@
 P:	Peter De Shrijver
 M:	p2@ace.ulyssis.sutdent.kuleuven.ac.be	
 P:	Mike Phillips
-M:	phillim@amtrak.com
+M:	mikep@linuxtr.net 
 L:	linux-net@vger.kernel.org
-L:	linux-tr@emissary.aus-etc.com
+L:	linux-tr@linuxtr.net
 W:	http://www.linuxtr.net
 S:	Maintained
 
diff -urN linux-2.4.4-pre4/Makefile linux/Makefile
--- linux-2.4.4-pre4/Makefile	Mon Dec  3 22:35:44 2001
+++ linux/Makefile	Mon Dec  3 22:35:54 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 4
-EXTRAVERSION =-pre4
+EXTRAVERSION =-pre5
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.4-pre4/arch/i386/defconfig linux/arch/i386/defconfig
--- linux-2.4.4-pre4/arch/i386/defconfig	Mon Dec  3 22:35:44 2001
+++ linux/arch/i386/defconfig	Mon Dec  3 22:35:54 2001
@@ -5,6 +5,8 @@
 CONFIG_ISA=y
 # CONFIG_SBUS is not set
 CONFIG_UID16=y
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
diff -urN linux-2.4.4-pre4/arch/sparc/config.in linux/arch/sparc/config.in
--- linux-2.4.4-pre4/arch/sparc/config.in	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc/config.in	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.108 2001/02/18 09:02:59 davem Exp $
+# $Id: config.in,v 1.109 2001/04/18 21:06:05 davem Exp $
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
diff -urN linux-2.4.4-pre4/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c
--- linux-2.4.4-pre4/arch/sparc/kernel/irq.c	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc/kernel/irq.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/*  $Id: irq.c,v 1.110 2001/02/13 01:16:43 davem Exp $
+/*  $Id: irq.c,v 1.111 2001/04/14 21:13:46 davem Exp $
  *  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
  *                            Sparc the IRQ's are basically 'cast in stone'
  *                            and you are supposed to probe the prom's device
diff -urN linux-2.4.4-pre4/arch/sparc/kernel/semaphore.c linux/arch/sparc/kernel/semaphore.c
--- linux-2.4.4-pre4/arch/sparc/kernel/semaphore.c	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc/kernel/semaphore.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: semaphore.c,v 1.6 2001/01/05 04:40:07 davem Exp $ */
+/* $Id: semaphore.c,v 1.7 2001/04/18 21:06:05 davem Exp $ */
 
 /* sparc32 semaphore implementation, based on i386 version */
 
diff -urN linux-2.4.4-pre4/arch/sparc/kernel/setup.c linux/arch/sparc/kernel/setup.c
--- linux-2.4.4-pre4/arch/sparc/kernel/setup.c	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc/kernel/setup.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.123 2001/02/13 01:16:43 davem Exp $
+/*  $Id: setup.c,v 1.124 2001/04/14 21:13:46 davem Exp $
  *  linux/arch/sparc/kernel/setup.c
  *
  *  Copyright (C) 1995  David S. Miller (davem@caip.rutgers.edu)
diff -urN linux-2.4.4-pre4/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c
--- linux-2.4.4-pre4/arch/sparc/mm/init.c	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc/mm/init.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.96 2000/11/30 08:51:50 anton Exp $
+/*  $Id: init.c,v 1.98 2001/04/14 21:13:45 davem Exp $
  *  linux/arch/sparc/mm/init.c
  *
  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
diff -urN linux-2.4.4-pre4/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c
--- linux-2.4.4-pre4/arch/sparc/mm/srmmu.c	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc/mm/srmmu.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.228 2001/03/16 06:56:20 davem Exp $
+/* $Id: srmmu.c,v 1.229 2001/04/14 21:13:45 davem Exp $
  * srmmu.c:  SRMMU specific routines for memory management.
  *
  * Copyright (C) 1995 David S. Miller  (davem@caip.rutgers.edu)
diff -urN linux-2.4.4-pre4/arch/sparc/mm/sun4c.c linux/arch/sparc/mm/sun4c.c
--- linux-2.4.4-pre4/arch/sparc/mm/sun4c.c	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc/mm/sun4c.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: sun4c.c,v 1.205 2001/03/16 06:57:41 davem Exp $
+/* $Id: sun4c.c,v 1.206 2001/04/14 21:13:45 davem Exp $
  * sun4c.c: Doing in software what should be done in hardware.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
diff -urN linux-2.4.4-pre4/arch/sparc64/config.in linux/arch/sparc64/config.in
--- linux-2.4.4-pre4/arch/sparc64/config.in	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc64/config.in	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.139 2001/04/03 12:29:38 davem Exp $
+# $Id: config.in,v 1.141 2001/04/19 01:52:04 davem Exp $
 # For a description of the syntax of this configuration file,
 # see the Configure script.
 #
@@ -33,8 +33,8 @@
 
 # Global things across all Sun machines.
 define_bool CONFIG_HAVE_DEC_LOCK y
-define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
-define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
 define_bool CONFIG_ISA n
 define_bool CONFIG_EISA n
 define_bool CONFIG_MCA n
diff -urN linux-2.4.4-pre4/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- linux-2.4.4-pre4/arch/sparc64/defconfig	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc64/defconfig	Mon Dec  3 22:35:55 2001
@@ -20,9 +20,11 @@
 CONFIG_BBC_I2C=m
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
-# CONFIG_SMP is not set
+CONFIG_SMP=y
 CONFIG_SPARC64=y
 CONFIG_HAVE_DEC_LOCK=y
+# CONFIG_RWSEM_GENERIC_SPINLOCK=n
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
@@ -40,7 +42,7 @@
 CONFIG_SUN_IO=y
 CONFIG_PCI=y
 CONFIG_RTC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_NAMES is not set
 CONFIG_SUN_OPENPROMFS=m
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
@@ -91,6 +93,7 @@
 # CONFIG_FB_PM2_FIFO_DISCONNECT is not set
 CONFIG_FB_PM2_PCI=y
 # CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E1355 is not set
 # CONFIG_FB_MATROX is not set
 CONFIG_FB_ATY=y
 # CONFIG_FB_ATY128 is not set
diff -urN linux-2.4.4-pre4/arch/sparc64/kernel/init_task.c linux/arch/sparc64/kernel/init_task.c
--- linux-2.4.4-pre4/arch/sparc64/kernel/init_task.c	Mon Jul 26 22:41:09 1999
+++ linux/arch/sparc64/kernel/init_task.c	Mon Dec  3 22:35:55 2001
@@ -15,6 +15,5 @@
  * We really don't need this special alignment like the Intel does, but
  * I do it anyways for completeness.
  */
-union task_union init_task_union
-	__attribute__((__section__(".text"))) =
-		{ INIT_TASK(init_task_union.task) };
+__asm__ (".text");
+union task_union init_task_union = { INIT_TASK(init_task_union.task) };
diff -urN linux-2.4.4-pre4/arch/sparc64/kernel/pci_psycho.c linux/arch/sparc64/kernel/pci_psycho.c
--- linux-2.4.4-pre4/arch/sparc64/kernel/pci_psycho.c	Tue Mar  6 22:44:16 2001
+++ linux/arch/sparc64/kernel/pci_psycho.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.21 2001/02/28 03:28:55 davem Exp $
+/* $Id: pci_psycho.c,v 1.22 2001/04/17 01:19:23 davem Exp $
  * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -757,6 +757,8 @@
 	error_bits = afsr &
 		(PSYCHO_UEAFSR_PPIO | PSYCHO_UEAFSR_PDRD | PSYCHO_UEAFSR_PDWR |
 		 PSYCHO_UEAFSR_SPIO | PSYCHO_UEAFSR_SDRD | PSYCHO_UEAFSR_SDWR);
+	if (!error_bits)
+		return;
 	psycho_write(afsr_reg, error_bits);
 
 	/* Log the error. */
@@ -830,6 +832,8 @@
 	error_bits = afsr &
 		(PSYCHO_CEAFSR_PPIO | PSYCHO_CEAFSR_PDRD | PSYCHO_CEAFSR_PDWR |
 		 PSYCHO_CEAFSR_SPIO | PSYCHO_CEAFSR_SDRD | PSYCHO_CEAFSR_SDWR);
+	if (!error_bits)
+		return;
 	psycho_write(afsr_reg, error_bits);
 
 	/* Log the error. */
@@ -922,6 +926,8 @@
 		 PSYCHO_PCIAFSR_PRTRY | PSYCHO_PCIAFSR_PPERR |
 		 PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA |
 		 PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR);
+	if (!error_bits)
+		return;
 	psycho_write(afsr_reg, error_bits);
 
 	/* Log the error. */
diff -urN linux-2.4.4-pre4/arch/sparc64/kernel/pci_sabre.c linux/arch/sparc64/kernel/pci_sabre.c
--- linux-2.4.4-pre4/arch/sparc64/kernel/pci_sabre.c	Tue Mar  6 22:44:16 2001
+++ linux/arch/sparc64/kernel/pci_sabre.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.25 2001/02/28 03:28:55 davem Exp $
+/* $Id: pci_sabre.c,v 1.26 2001/04/17 01:19:23 davem Exp $
  * pci_sabre.c: Sabre specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -774,6 +774,8 @@
 		(SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR |
 		 SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR |
 		 SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE);
+	if (!error_bits)
+		return;
 	sabre_write(afsr_reg, error_bits);
 
 	/* Log the error. */
@@ -829,6 +831,8 @@
 	error_bits = afsr &
 		(SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR |
 		 SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR);
+	if (!error_bits)
+		return;
 	sabre_write(afsr_reg, error_bits);
 
 	/* Log the error. */
@@ -885,6 +889,8 @@
 		 SABRE_PIOAFSR_PRTRY | SABRE_PIOAFSR_PPERR |
 		 SABRE_PIOAFSR_SMA | SABRE_PIOAFSR_STA |
 		 SABRE_PIOAFSR_SRTRY | SABRE_PIOAFSR_SPERR);
+	if (!error_bits)
+		return;
 	sabre_write(afsr_reg, error_bits);
 
 	/* Log the error. */
diff -urN linux-2.4.4-pre4/arch/sparc64/kernel/pci_schizo.c linux/arch/sparc64/kernel/pci_schizo.c
--- linux-2.4.4-pre4/arch/sparc64/kernel/pci_schizo.c	Sun Mar 25 18:14:21 2001
+++ linux/arch/sparc64/kernel/pci_schizo.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_schizo.c,v 1.13 2001/03/21 00:29:58 davem Exp $
+/* $Id: pci_schizo.c,v 1.14 2001/04/17 01:19:23 davem Exp $
  * pci_schizo.c: SCHIZO specific PCI controller support.
  *
  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
@@ -716,6 +716,8 @@
 	error_bits = afsr &
 		(SCHIZO_UEAFSR_PPIO | SCHIZO_UEAFSR_PDRD | SCHIZO_UEAFSR_PDWR |
 		 SCHIZO_UEAFSR_SPIO | SCHIZO_UEAFSR_SDMA);
+	if (!error_bits)
+		return;
 	schizo_write(afsr_reg, error_bits);
 
 	/* Log the error. */
@@ -802,6 +804,8 @@
 	error_bits = afsr &
 		(SCHIZO_CEAFSR_PPIO | SCHIZO_CEAFSR_PDRD | SCHIZO_CEAFSR_PDWR |
 		 SCHIZO_CEAFSR_SPIO | SCHIZO_CEAFSR_SDMA);
+	if (!error_bits)
+		return;
 	schizo_write(afsr_reg, error_bits);
 
 	/* Log the error. */
@@ -901,6 +905,8 @@
 		 SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |
 		 SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |
 		 SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS);
+	if (!error_bits)
+		return;
 	schizo_write(afsr_reg, error_bits);
 
 	/* Log the error. */
diff -urN linux-2.4.4-pre4/arch/sparc64/kernel/starfire.c linux/arch/sparc64/kernel/starfire.c
--- linux-2.4.4-pre4/arch/sparc64/kernel/starfire.c	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc64/kernel/starfire.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: starfire.c,v 1.9 2001/02/13 01:16:44 davem Exp $
+/* $Id: starfire.c,v 1.10 2001/04/14 21:13:45 davem Exp $
  * starfire.c: Starfire/E10000 support.
  *
  * Copyright (C) 1998 David S. Miller (davem@redhat.com)
diff -urN linux-2.4.4-pre4/arch/sparc64/solaris/timod.c linux/arch/sparc64/solaris/timod.c
--- linux-2.4.4-pre4/arch/sparc64/solaris/timod.c	Mon Dec  3 22:35:45 2001
+++ linux/arch/sparc64/solaris/timod.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: timod.c,v 1.10 2000/07/28 12:15:02 davem Exp $
+/* $Id: timod.c,v 1.11 2001/04/14 21:12:01 davem Exp $
  * timod.c: timod emulation.
  *
  * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
@@ -611,7 +611,7 @@
 		return 0;
 	}
 	default:
-		printk("timod_putmsg: unsupported command %u.\n", ret);
+		printk(KERN_INFO "timod_putmsg: unsupported command %u.\n", ret);
 		break;
 	}
 	return -EINVAL;
diff -urN linux-2.4.4-pre4/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- linux-2.4.4-pre4/drivers/block/ps2esdi.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/block/ps2esdi.c	Mon Dec  3 22:35:55 2001
@@ -52,6 +52,7 @@
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <asm/dma.h>
+#include <asm/mca_dma.h>
 #include <asm/uaccess.h>
 
 #define PS2ESDI_IRQ 14
@@ -657,33 +658,23 @@
 /* prepare for dma - do all the necessary setup */
 static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode)
 {
-	u_int tc;
-	
-	buffer=(char *)virt_to_bus(buffer);
-
+	unsigned long flags;
 #if 0
 	printk("ps2esdi: b_wait: %p\n", &CURRENT->bh->b_wait);
 #endif
-	cli();
+	flags = claim_dma_lock();
 
-	outb(dma_arb_level | DMA_MASK_CHAN, PORT_DMA_FN);
+	mca_disable_dma(dma_arb_level);
 
-	outb(dma_arb_level | DMA_WRITE_ADDR, PORT_DMA_FN);
-	outb((u_int) buffer & (u_int) 0xff, PORT_DMA_EX);
-	outb(((u_int) buffer >> 8) & (u_int) 0xff, PORT_DMA_EX);
-	outb(((u_int) buffer >> 16) & (u_int) 0xff, PORT_DMA_EX);
+	mca_set_dma_addr(dma_arb_level, virt_to_bus(buffer));
 
-	outb(dma_arb_level | DMA_WRITE_TC, PORT_DMA_FN);
-	tc = (length * SECT_SIZE / 2) - 1;
-	outb(tc & 0xff, PORT_DMA_EX);
-	outb((tc >> 8) & 0xff, PORT_DMA_EX);
+	mca_set_dma_count(dma_arb_level, length * 512 / 2);
 
-	outb(dma_arb_level | DMA_WRITE_MODE, PORT_DMA_FN);
-	outb(dma_xmode, PORT_DMA_EX);
+	mca_set_dma_mode(dma_arb_level, dma_xmode);
 
-	outb(dma_arb_level | DMA_UNMASK_CHAN, PORT_DMA_FN);
+	mca_enable_dma(dma_arb_level);
 
-	sti();
+	release_dma_lock(flags);
 
 }				/* prepare for dma */
 
@@ -861,7 +852,9 @@
 	switch (int_ret_code & 0x0f) {
 	case INT_TRANSFER_REQ:
 		ps2esdi_prep_dma(CURRENT->buffer, CURRENT->current_nr_sectors,
-		    (CURRENT->cmd == READ) ? DMA_READ_16 : DMA_WRITE_16);
+		    (CURRENT->cmd == READ)
+		    ? MCA_DMA_MODE_16 | MCA_DMA_MODE_WRITE | MCA_DMA_MODE_XFER
+		    : MCA_DMA_MODE_16 | MCA_DMA_MODE_READ);
 		outb(CTRL_ENABLE_DMA | CTRL_ENABLE_INTR, ESDI_CONTROL);
 		ending = -1;
 		break;
diff -urN linux-2.4.4-pre4/drivers/char/synclink.c linux/drivers/char/synclink.c
--- linux-2.4.4-pre4/drivers/char/synclink.c	Tue Mar  6 19:44:34 2001
+++ linux/drivers/char/synclink.c	Mon Dec  3 22:35:55 2001
@@ -7344,8 +7344,6 @@
 	d->tx_timeout = mgsl_sppp_tx_timeout;
 	d->watchdog_timeo = 10*HZ;
 
-	dev_init_buffers(d);
-
 	if (register_netdev(d) == -1) {
 		printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
 		sppp_detach(info->netdev);
diff -urN linux-2.4.4-pre4/drivers/isdn/Config.in linux/drivers/isdn/Config.in
--- linux-2.4.4-pre4/drivers/isdn/Config.in	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/Config.in	Mon Dec  3 22:35:55 2001
@@ -130,8 +130,8 @@
    dep_tristate '  AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI $CONFIG_ISDN_CAPI $CONFIG_PCI
    dep_mbool    '    AVM B1 PCI V4 support' CONFIG_ISDN_DRV_AVMB1_B1PCIV4 $CONFIG_ISDN_DRV_AVMB1_B1PCI
    dep_tristate '  AVM T1/T1-B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA $CONFIG_ISDN_CAPI
-   dep_tristate '  AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA $CONFIG_ISDN_CAPI $CONFIG_PCMCIA
-   dep_tristate '  AVM B1/M1/M2 PCMCIA cs module' CONFIG_ISDN_DRV_AVMB1_AVM_CS $CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
+   dep_tristate '  AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA $CONFIG_ISDN_CAPI
+   dep_tristate '  AVM B1/M1/M2 PCMCIA cs module' CONFIG_ISDN_DRV_AVMB1_AVM_CS $CONFIG_ISDN_DRV_AVMB1_B1PCMCIA $CONFIG_PCMCIA
    dep_tristate '  AVM T1/T1-B PCI support' CONFIG_ISDN_DRV_AVMB1_T1PCI $CONFIG_ISDN_CAPI $CONFIG_PCI
    dep_tristate '  AVM C4 support' CONFIG_ISDN_DRV_AVMB1_C4 $CONFIG_ISDN_CAPI $CONFIG_PCI
 fi
diff -urN linux-2.4.4-pre4/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c
--- linux-2.4.4-pre4/drivers/isdn/avmb1/b1pci.c	Sun Mar 25 18:20:44 2001
+++ linux/drivers/isdn/avmb1/b1pci.c	Mon Dec  3 22:35:55 2001
@@ -327,7 +327,7 @@
 
 	div4->detach_ctr(ctrl);
 	free_irq(card->irq, card);
-	iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+	iounmap(card->mbase);
 	release_region(card->port, AVMB1_PORTLEN);
 	ctrl->driverdata = 0;
 	kfree(card->ctrlinfo);
@@ -358,7 +358,6 @@
 
 static int b1pciv4_add_card(struct capi_driver *driver, struct capicardparams *p)
 {
-	unsigned long base, page_offset;
 	avmcard *card;
 	avmctrl_info *cinfo;
 	int retval;
@@ -409,12 +408,8 @@
 		return -EBUSY;
 	}
 
-	base = card->membase & PAGE_MASK;
-	page_offset = card->membase - base;
-	card->mbase = ioremap_nocache(base, page_offset + 64);
-	if (card->mbase) {
-		card->mbase += page_offset;
-	} else {
+	card->mbase = ioremap_nocache(card->membase, 64);
+	if (!card->mbase) {
 		printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
 					driver->name, card->membase);
 	        kfree(card->ctrlinfo);
@@ -429,7 +424,7 @@
 	if ((retval = b1pciv4_detect(card)) != 0) {
 		printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
 					driver->name, card->port, retval);
-                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+                iounmap(card->mbase);
 	        kfree(card->ctrlinfo);
 		kfree(card->dma);
 		kfree(card);
@@ -445,7 +440,7 @@
 	if (retval) {
 		printk(KERN_ERR "%s: unable to get IRQ %d.\n",
 				driver->name, card->irq);
-                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+                iounmap(card->mbase);
 		release_region(card->port, AVMB1_PORTLEN);
 	        kfree(card->ctrlinfo);
 		kfree(card->dma);
@@ -457,7 +452,7 @@
 	cinfo->capi_ctrl = div4->attach_ctr(driver, card->name, cinfo);
 	if (!cinfo->capi_ctrl) {
 		printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
-                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+                iounmap(card->mbase);
 		free_irq(card->irq, card);
 		release_region(card->port, AVMB1_PORTLEN);
 	        kfree(card->ctrlinfo);
@@ -508,21 +503,21 @@
 	struct capicardparams param;
 	int retval;
 
+	if (pci_enable_device(dev) < 0) {
+		printk(KERN_ERR "%s: failed to enable AVM-B1\n",
+		       driver->name);
+		return -ENODEV;
+	}
+	param.irq = dev->irq;
+
 	if (pci_resource_start(dev, 2)) { /* B1 PCI V4 */
 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
 		driver = &b1pciv4_driver;
+
+		pci_set_master(dev);
 #endif
 		param.membase = pci_resource_start(dev, 0);
 		param.port = pci_resource_start(dev, 2);
-		param.irq = dev->irq;
-
-		retval = pci_enable_device (dev);
-		if (retval != 0) {
-		        printk(KERN_ERR
-			"%s: failed to enable AVM-B1 V4 at i/o %#x, irq %d, mem %#x err=%d\n",
-			driver->name, param.port, param.irq, param.membase, retval);
-			return -EIO;
-		}
 
 		printk(KERN_INFO
 		"%s: PCI BIOS reports AVM-B1 V4 at i/o %#x, irq %d, mem %#x\n",
@@ -540,15 +535,7 @@
 	} else {
 		param.membase = 0;
 		param.port = pci_resource_start(dev, 1);
-		param.irq = dev->irq;
 
-		retval = pci_enable_device (dev);
-		if (retval != 0) {
-		        printk(KERN_ERR
-			"%s: failed to enable AVM-B1 at i/o %#x, irq %d, err=%d\n",
-			driver->name, param.port, param.irq, retval);
-			return -EIO;
-		}
 		printk(KERN_INFO
 		"%s: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
 		driver->name, param.port, param.irq);
@@ -570,7 +557,6 @@
 #endif
 	struct pci_dev *dev = NULL;
 	char *p;
-	int retval;
 
 	MOD_INC_USE_COUNT;
 
@@ -592,50 +578,29 @@
 	printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
 
         di = attach_capi_driver(driver);
-
 	if (!di) {
 		printk(KERN_ERR "%s: failed to attach capi_driver\n",
 				driver->name);
 		MOD_DEC_USE_COUNT;
-		return -EIO;
+		return -ENODEV;
 	}
 
 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
 	printk(KERN_INFO "%s: revision %s\n", driverv4->name, driverv4->revision);
 
         div4 = attach_capi_driver(driverv4);
-
 	if (!div4) {
     		detach_capi_driver(driver);
 		printk(KERN_ERR "%s: failed to attach capi_driver\n",
 				driverv4->name);
 		MOD_DEC_USE_COUNT;
-		return -EIO;
+		return -ENODEV;
 	}
 #endif
 
-#ifdef CONFIG_PCI
-	if (!pci_present()) {
-		printk(KERN_ERR "%s: no PCI bus present\n", driver->name);
-    		detach_capi_driver(driver);
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
-    		detach_capi_driver(driverv4);
-#endif
-		MOD_DEC_USE_COUNT;
-		return -EIO;
-	}
-
 	while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, dev))) {
-		retval = add_card(dev);
-		if (retval != 0) {
-    			detach_capi_driver(driver);
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
-    			detach_capi_driver(driverv4);
-#endif
-			MOD_DEC_USE_COUNT;
-			return retval;
-		}
-		ncards++;
+		if (add_card(dev) == 0)
+			ncards++;
 	}
 	if (ncards) {
 		printk(KERN_INFO "%s: %d B1-PCI card(s) detected\n",
@@ -649,12 +614,7 @@
 	detach_capi_driver(driverv4);
 #endif
 	MOD_DEC_USE_COUNT;
-	return -ESRCH;
-#else
-	printk(KERN_ERR "%s: kernel not compiled with PCI.\n", driver->name);
-	MOD_DEC_USE_COUNT;
-	return -EIO;
-#endif
+	return -ENODEV;
 }
 
 static void __exit b1pci_exit(void)
diff -urN linux-2.4.4-pre4/drivers/isdn/avmb1/c4.c linux/drivers/isdn/avmb1/c4.c
--- linux-2.4.4-pre4/drivers/isdn/avmb1/c4.c	Sun Mar 25 18:20:44 2001
+++ linux/drivers/isdn/avmb1/c4.c	Mon Dec  3 22:35:55 2001
@@ -1012,7 +1012,7 @@
 	}
 
 	free_irq(card->irq, card);
-	iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+	iounmap(card->mbase);
 	release_region(card->port, AVMB1_PORTLEN);
 	ctrl->driverdata = 0;
 	kfree(card->ctrlinfo);
@@ -1194,7 +1194,6 @@
 
 static int c4_add_card(struct capi_driver *driver, struct capicardparams *p)
 {
-	unsigned long base, page_offset;
 	avmctrl_info *cinfo;
 	avmcard *card;
 	int retval;
@@ -1249,12 +1248,8 @@
 		return -EBUSY;
 	}
 
-	base = card->membase & PAGE_MASK;
-	page_offset = card->membase - base;
-	card->mbase = ioremap_nocache(base, page_offset + 128);
-	if (card->mbase) {
-		card->mbase += page_offset;
-	} else {
+	card->mbase = ioremap_nocache(card->membase, 128);
+	if (card->mbase == 0) {
 		printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
 					driver->name, card->membase);
 	        kfree(card->ctrlinfo);
@@ -1267,7 +1262,7 @@
 	if ((retval = c4_detect(card)) != 0) {
 		printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
 					driver->name, card->port, retval);
-                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+                iounmap(card->mbase);
 	        kfree(card->ctrlinfo);
 		kfree(card->dma);
 		kfree(card);
@@ -1282,7 +1277,7 @@
 	if (retval) {
 		printk(KERN_ERR "%s: unable to get IRQ %d.\n",
 				driver->name, card->irq);
-                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+                iounmap(card->mbase);
 		release_region(card->port, AVMB1_PORTLEN);
 	        kfree(card->ctrlinfo);
 		kfree(card->dma);
@@ -1302,7 +1297,7 @@
 				cinfo = &card->ctrlinfo[i];
 				di->detach_ctr(cinfo->capi_ctrl);
 			}
-                	iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+                	iounmap(card->mbase);
 			free_irq(card->irq, card);
 			release_region(card->port, AVMB1_PORTLEN);
 	        	kfree(card->dma);
@@ -1364,20 +1359,11 @@
 	printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
 
         di = attach_capi_driver(driver);
-
 	if (!di) {
 		printk(KERN_ERR "%s: failed to attach capi_driver\n",
 				driver->name);
 		MOD_DEC_USE_COUNT;
-		return -EIO;
-	}
-
-#ifdef CONFIG_PCI
-	if (!pci_present()) {
-		printk(KERN_ERR "%s: no PCI bus present\n", driver->name);
-    		detach_capi_driver(driver);
-		MOD_DEC_USE_COUNT;
-		return -EIO;
+		return -ENODEV;
 	}
 
 	while ((dev = pci_find_subsys(
@@ -1385,20 +1371,17 @@
 			PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, dev))) {
 		struct capicardparams param;
 
+		if (pci_enable_device(dev) < 0) {
+		        printk(KERN_ERR "%s: failed to enable AVM-C4\n",
+			       driver->name);
+			continue;
+		}
+		pci_set_master(dev);
+
 		param.port = pci_resource_start(dev, 1);
 		param.irq = dev->irq;
 		param.membase = pci_resource_start(dev, 0);
-
-		retval = pci_enable_device (dev);
-		if (retval != 0) {
-		        printk(KERN_ERR
-			"%s: failed to enable AVM-C4 at i/o %#x, irq %d, mem %#x err=%d\n",
-			driver->name, param.port, param.irq, param.membase, retval);
-    			detach_capi_driver(driver);
-			MOD_DEC_USE_COUNT;
-			return -EIO;
-		}
-
+  
 		printk(KERN_INFO
 			"%s: PCI BIOS reports AVM-C4 at i/o %#x, irq %d, mem %#x\n",
 			driver->name, param.port, param.irq, param.membase);
@@ -1407,9 +1390,7 @@
 		        printk(KERN_ERR
 			"%s: no AVM-C4 at i/o %#x, irq %d detected, mem %#x\n",
 			driver->name, param.port, param.irq, param.membase);
-    			detach_capi_driver(driver);
-			MOD_DEC_USE_COUNT;
-			return retval;
+			continue;
 		}
 		ncards++;
 	}
@@ -1422,12 +1403,7 @@
 	printk(KERN_ERR "%s: NO C4 card detected\n", driver->name);
 	detach_capi_driver(driver);
 	MOD_DEC_USE_COUNT;
-	return -ESRCH;
-#else
-	printk(KERN_ERR "%s: kernel not compiled with PCI.\n", driver->name);
-	MOD_DEC_USE_COUNT;
-	return -EIO;
-#endif
+	return -ENODEV;
 }
 
 static void __exit c4_exit(void)
diff -urN linux-2.4.4-pre4/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- linux-2.4.4-pre4/drivers/isdn/avmb1/capi.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/avmb1/capi.c	Mon Dec  3 22:35:55 2001
@@ -1,11 +1,14 @@
 /*
- * $Id: capi.c,v 1.44.6.8 2001/03/21 08:52:21 kai Exp $
+ * $Id: capi.c,v 1.44.6.9 2001/04/08 17:51:42 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
  * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
  *
  * $Log: capi.c,v $
+ * Revision 1.44.6.9  2001/04/08 17:51:42  kai
+ * merge various fixes from HEAD (found by the CHECKER project)
+ *
  * Revision 1.44.6.8  2001/03/21 08:52:21  kai
  * merge from main branch: fix buffer for revision string (calle)
  *
@@ -268,7 +271,7 @@
 #include "capifs.h"
 #endif
 
-static char *revision = "$Revision: 1.44.6.8 $";
+static char *revision = "$Revision: 1.44.6.9 $";
 
 MODULE_AUTHOR("Carsten Paeth (calle@calle.in-berlin.de)");
 
@@ -533,9 +536,6 @@
 	memset(np, 0, sizeof(struct capincci));
 	np->ncci = ncci;
 	np->cdev = cdev;
-	for (pp=&cdev->nccis; *pp; pp = &(*pp)->next)
-		;
-	*pp = np;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 	mp = 0;
 	if (cdev->userflags & CAPIFLAG_HIGHJACKING)
@@ -553,6 +553,9 @@
 #endif
 	}
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+	for (pp=&cdev->nccis; *pp; pp = &(*pp)->next)
+		;
+	*pp = np;
         return np;
 }
 
@@ -1334,6 +1337,7 @@
 #ifdef _DEBUG_REFCOUNT
 	printk(KERN_DEBUG "capi_raw_open %d\n", GET_USE_COUNT(THIS_MODULE));
 #endif
+
 	mp->datahandle = 0;
 	mp->file = file;
 	file->private_data = (void *)mp;
@@ -2120,6 +2124,7 @@
 static int __init capi_init(void)
 {
 	char *p;
+	char *compileinfo;
 
 	MOD_INC_USE_COUNT;
 
@@ -2200,8 +2205,17 @@
 
 	(void)proc_init();
 
-	printk(KERN_NOTICE "capi20: Rev%s: started up with major %d\n",
-				rev, capi_major);
+#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
+#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
+        compileinfo = " (middleware+capifs)";
+#else
+        compileinfo = " (no capifs)";
+#endif
+#else
+        compileinfo = " (no middleware)";
+#endif
+	printk(KERN_NOTICE "capi20: Rev %s: started up with major %d%s\n",
+				rev, capi_major, compileinfo);
 
 	MOD_DEC_USE_COUNT;
 	return 0;
diff -urN linux-2.4.4-pre4/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c
--- linux-2.4.4-pre4/drivers/isdn/avmb1/capidrv.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/avmb1/capidrv.c	Mon Dec  3 22:35:55 2001
@@ -1,11 +1,14 @@
 /*
- * $Id: capidrv.c,v 1.39.6.4 2001/03/21 08:52:21 kai Exp $
+ * $Id: capidrv.c,v 1.39.6.5 2001/04/08 17:51:42 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
  * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
  *
  * $Log: capidrv.c,v $
+ * Revision 1.39.6.5  2001/04/08 17:51:42  kai
+ * merge various fixes from HEAD (found by the CHECKER project)
+ *
  * Revision 1.39.6.4  2001/03/21 08:52:21  kai
  * merge from main branch: fix buffer for revision string (calle)
  *
@@ -231,7 +234,7 @@
 #include "capicmd.h"
 #include "capidrv.h"
 
-static char *revision = "$Revision: 1.39.6.4 $";
+static char *revision = "$Revision: 1.39.6.5 $";
 static int debugmode = 0;
 
 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
diff -urN linux-2.4.4-pre4/drivers/isdn/avmb1/t1pci.c linux/drivers/isdn/avmb1/t1pci.c
--- linux-2.4.4-pre4/drivers/isdn/avmb1/t1pci.c	Sun Mar 25 18:20:44 2001
+++ linux/drivers/isdn/avmb1/t1pci.c	Mon Dec  3 22:35:55 2001
@@ -124,7 +124,7 @@
 
 	di->detach_ctr(ctrl);
 	free_irq(card->irq, card);
-	iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+	iounmap(card->mbase);
 	release_region(card->port, AVMB1_PORTLEN);
 	ctrl->driverdata = 0;
 	kfree(card->ctrlinfo);
@@ -138,7 +138,6 @@
 
 static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
 {
-	unsigned long base, page_offset;
 	avmcard *card;
 	avmctrl_info *cinfo;
 	int retval;
@@ -189,12 +188,8 @@
 		return -EBUSY;
 	}
 
-	base = card->membase & PAGE_MASK;
-	page_offset = card->membase - base;
-	card->mbase = ioremap_nocache(base, page_offset + 64);
-	if (card->mbase) {
-		card->mbase += page_offset;
-	} else {
+	card->mbase = ioremap_nocache(card->membase, 64);
+	if (!card->mbase) {
 		printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
 					driver->name, card->membase);
 	        kfree(card->ctrlinfo);
@@ -213,7 +208,7 @@
 		else
 			printk(KERN_NOTICE "%s: card at 0x%x, but cabel not connected or T1 has no power (%d)\n",
 					driver->name, card->port, retval);
-                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+                iounmap(card->mbase);
 	        kfree(card->ctrlinfo);
 		kfree(card->dma);
 		kfree(card);
@@ -228,7 +223,7 @@
 	if (retval) {
 		printk(KERN_ERR "%s: unable to get IRQ %d.\n",
 				driver->name, card->irq);
-                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+                iounmap(card->mbase);
 		release_region(card->port, AVMB1_PORTLEN);
 	        kfree(card->ctrlinfo);
 		kfree(card->dma);
@@ -240,7 +235,7 @@
 	cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo);
 	if (!cinfo->capi_ctrl) {
 		printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
-                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+                iounmap(card->mbase);
 		free_irq(card->irq, card);
 		release_region(card->port, AVMB1_PORTLEN);
 	        kfree(card->ctrlinfo);
@@ -318,7 +313,6 @@
 	printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
 
         di = attach_capi_driver(driver);
-
 	if (!di) {
 		printk(KERN_ERR "%s: failed to attach capi_driver\n",
 				driver->name);
@@ -326,31 +320,20 @@
 		return -EIO;
 	}
 
-#ifdef CONFIG_PCI
-	if (!pci_present()) {
-		printk(KERN_ERR "%s: no PCI bus present\n", driver->name);
-    		detach_capi_driver(driver);
-		MOD_DEC_USE_COUNT;
-		return -EIO;
-	}
-
 	while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, dev))) {
 		struct capicardparams param;
 
+		if (pci_enable_device(dev) < 0) {
+		        printk(KERN_ERR	"%s: failed to enable AVM-T1-PCI\n",
+			       driver->name);
+			continue;
+		}
+		pci_set_master(dev);
+
 		param.port = pci_resource_start(dev, 1);
  		param.irq = dev->irq;
 		param.membase = pci_resource_start(dev, 0);
 
-		retval = pci_enable_device (dev);
-		if (retval != 0) {
-		        printk(KERN_ERR
-			"%s: failed to enable AVM-T1-PCI at i/o %#x, irq %d, mem %#x err=%d\n",
-			driver->name, param.port, param.irq, param.membase, retval);
-    			detach_capi_driver(&t1pci_driver);
-			MOD_DEC_USE_COUNT;
-			return -EIO;
-		}
-
 		printk(KERN_INFO
 			"%s: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n",
 			driver->name, param.port, param.irq, param.membase);
@@ -359,9 +342,7 @@
 		        printk(KERN_ERR
 			"%s: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n",
 			driver->name, param.port, param.irq, param.membase);
-    			detach_capi_driver(&t1pci_driver);
-			MOD_DEC_USE_COUNT;
-			return retval;
+			continue;
 		}
 		ncards++;
 	}
@@ -374,12 +355,7 @@
 	printk(KERN_ERR "%s: NO T1-PCI card detected\n", driver->name);
 	detach_capi_driver(&t1pci_driver);
 	MOD_DEC_USE_COUNT;
-	return -ESRCH;
-#else
-	printk(KERN_ERR "%s: kernel not compiled with PCI.\n", driver->name);
-	MOD_DEC_USE_COUNT;
-	return -EIO;
-#endif
+	return -ENODEV;
 }
 
 static void __exit t1pci_exit(void)
diff -urN linux-2.4.4-pre4/drivers/isdn/eicon/eicon_idi.c linux/drivers/isdn/eicon/eicon_idi.c
--- linux-2.4.4-pre4/drivers/isdn/eicon/eicon_idi.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/eicon/eicon_idi.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: eicon_idi.c,v 1.41.6.1 2001/02/10 14:44:09 kai Exp $
+/* $Id: eicon_idi.c,v 1.41.6.2 2001/04/07 21:41:44 armin Exp $
  *
  * ISDN lowlevel-module for Eicon active cards.
  *        IDI interface 
@@ -36,7 +36,7 @@
 
 #undef EICON_FULL_SERVICE_OKTETT
 
-char *eicon_idi_revision = "$Revision: 1.41.6.1 $";
+char *eicon_idi_revision = "$Revision: 1.41.6.2 $";
 
 eicon_manifbuf *manbuf;
 
diff -urN linux-2.4.4-pre4/drivers/isdn/hisax/bkm_a8.c linux/drivers/isdn/hisax/bkm_a8.c
--- linux-2.4.4-pre4/drivers/isdn/hisax/bkm_a8.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/bkm_a8.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: bkm_a8.c,v 1.14.6.4 2001/02/16 16:43:25 kai Exp $
+/* $Id: bkm_a8.c,v 1.14.6.5 2001/04/15 14:51:09 keil Exp $
  * bkm_a8.c     low level stuff for Scitel Quadro (4*S0, passive)
  *              derived from the original file sedlbauer.c
  *              derived from the original file niccy.c
@@ -27,7 +27,7 @@
 
 extern const char *CardType[];
 
-const char sct_quadro_revision[] = "$Revision: 1.14.6.4 $";
+const char sct_quadro_revision[] = "$Revision: 1.14.6.5 $";
 
 static const char *sct_quadro_subtypes[] =
 {
@@ -205,9 +205,9 @@
 void
 release_io_sct_quadro(struct IsdnCardState *cs)
 {
-	release_region(cs->hw.ax.base & 0xffffffc0, 256);
+	release_region(cs->hw.ax.base & 0xffffffc0, 128);
 	if (cs->subtyp == SCT_1)
-		release_region(cs->hw.ax.plx_adr, 256);
+		release_region(cs->hw.ax.plx_adr, 64);
 }
 
 static void
@@ -403,9 +403,9 @@
 	switch(cs->subtyp) {
 		case 1:
 			cs->hw.ax.base = pci_ioaddr5 + 0x00;
-			if (sct_alloc_io(pci_ioaddr1, 256))
+			if (sct_alloc_io(pci_ioaddr1, 128))
 				return(0);
-			if (sct_alloc_io(pci_ioaddr5, 256))
+			if (sct_alloc_io(pci_ioaddr5, 64))
 				return(0);
 			/* disable all IPAC */
 			writereg(pci_ioaddr5, pci_ioaddr5 + 4,
@@ -419,17 +419,17 @@
 			break;
 		case 2:
 			cs->hw.ax.base = pci_ioaddr4 + 0x08;
-			if (sct_alloc_io(pci_ioaddr4, 256))
+			if (sct_alloc_io(pci_ioaddr4, 64))
 				return(0);
 			break;
 		case 3:
 			cs->hw.ax.base = pci_ioaddr3 + 0x10;
-			if (sct_alloc_io(pci_ioaddr3, 256))
+			if (sct_alloc_io(pci_ioaddr3, 64))
 				return(0);
 			break;
 		case 4:
 			cs->hw.ax.base = pci_ioaddr2 + 0x20;
-			if (sct_alloc_io(pci_ioaddr2, 256))
+			if (sct_alloc_io(pci_ioaddr2, 64))
 				return(0);
 			break;
 	}	
diff -urN linux-2.4.4-pre4/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- linux-2.4.4-pre4/drivers/isdn/hisax/config.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/hisax/config.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: config.c,v 2.57.6.11 2001/03/13 16:17:08 kai Exp $
+/* $Id: config.c,v 2.57.6.13 2001/04/08 19:41:28 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
diff -urN linux-2.4.4-pre4/drivers/isdn/hisax/elsa_cs.c linux/drivers/isdn/hisax/elsa_cs.c
--- linux-2.4.4-pre4/drivers/isdn/hisax/elsa_cs.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/hisax/elsa_cs.c	Mon Dec  3 22:35:55 2001
@@ -56,7 +56,7 @@
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
 static char *version =
-"elsa_cs.c $Revision: 3.0 $ $Date: 2001/03/10 10:00:23 $ (K.Lichtenwalder)";
+"elsa_cs.c $Revision: 1.1.2.1 $ $Date: 2001/04/15 08:01:34 $ (K.Lichtenwalder)";
 #else
 #define DEBUG(n, args...)
 #endif
diff -urN linux-2.4.4-pre4/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c
--- linux-2.4.4-pre4/drivers/isdn/hisax/hfc_pci.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hfc_pci.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_pci.c,v 1.34.6.4 2001/02/13 10:33:58 kai Exp $
+/* $Id: hfc_pci.c,v 1.34.6.5 2001/04/08 19:32:26 kai Exp $
 
  * hfc_pci.c     low level driver for CCD´s hfc-pci based cards
  *
@@ -35,7 +35,7 @@
 
 extern const char *CardType[];
 
-static const char *hfcpci_revision = "$Revision: 1.34.6.4 $";
+static const char *hfcpci_revision = "$Revision: 1.34.6.5 $";
 
 /* table entry in the PCI devices list */
 typedef struct {
@@ -235,6 +235,59 @@
 		return (NULL);
 }
 
+/***************************************/
+/* clear the desired B-channel rx fifo */
+/***************************************/
+static void hfcpci_clear_fifo_rx(struct IsdnCardState *cs, int fifo)
+{       u_char fifo_state;
+        bzfifo_type *bzr;
+
+	if (fifo) {
+	        bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2;
+		fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B2RX;
+	} else {
+	        bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1;
+		fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B1RX;
+	}
+	if (fifo_state)
+	        cs->hw.hfcpci.fifo_en ^= fifo_state;
+	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);
+	cs->hw.hfcpci.last_bfifo_cnt[fifo] = 0;
+	bzr->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1;
+	bzr->za[MAX_B_FRAMES].z2 = bzr->za[MAX_B_FRAMES].z1;
+	bzr->f1 = MAX_B_FRAMES;
+	bzr->f2 = bzr->f1;	/* init F pointers to remain constant */
+	if (fifo_state)
+	        cs->hw.hfcpci.fifo_en |= fifo_state;
+	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);
+}   
+
+/***************************************/
+/* clear the desired B-channel tx fifo */
+/***************************************/
+static void hfcpci_clear_fifo_tx(struct IsdnCardState *cs, int fifo)
+{       u_char fifo_state;
+        bzfifo_type *bzt;
+
+	if (fifo) {
+	        bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2;
+		fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B2TX;
+	} else {
+	        bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1;
+		fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B1TX;
+	}
+	if (fifo_state)
+	        cs->hw.hfcpci.fifo_en ^= fifo_state;
+	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);
+	bzt->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1;
+	bzt->za[MAX_B_FRAMES].z2 = bzt->za[MAX_B_FRAMES].z1;
+	bzt->f1 = MAX_B_FRAMES;
+	bzt->f2 = bzt->f1;	/* init F pointers to remain constant */
+	if (fifo_state)
+	        cs->hw.hfcpci.fifo_en |= fifo_state;
+	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);
+}   
+
 /*********************************************/
 /* read a complete B-frame out of the buffer */
 /*********************************************/
@@ -428,7 +481,7 @@
 {
 	long flags;
 	struct IsdnCardState *cs = bcs->cs;
-	int rcnt;
+	int rcnt, real_fifo;
 	int receive, count = 5;
 	struct sk_buff *skb;
 	bzfifo_type *bz;
@@ -440,9 +493,11 @@
 	if ((bcs->channel) && (!cs->hw.hfcpci.bswapped)) {
 		bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2;
 		bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2;
+		real_fifo = 1;
 	} else {
 		bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1;
 		bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b1;
+		real_fifo = 0;
 	}
       Begin:
 	count--;
@@ -475,6 +530,11 @@
 		rcnt = bz->f1 - bz->f2;
 		if (rcnt < 0)
 			rcnt += MAX_B_FRAMES + 1;
+		if (cs->hw.hfcpci.last_bfifo_cnt[real_fifo] > rcnt + 1) {
+		        rcnt = 0;
+			hfcpci_clear_fifo_rx(cs, real_fifo);
+		}
+		cs->hw.hfcpci.last_bfifo_cnt[real_fifo] = rcnt;
 		if (rcnt > 1)
 			receive = 1;
 		else
@@ -1253,7 +1313,6 @@
 mode_hfcpci(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
-	bzfifo_type *bzr, *bzt;
 	int flags, fifo2;
 
 	if (cs->debug & L1_DEB_HSCX)
@@ -1300,6 +1359,8 @@
 			}
 			break;
 		case (L1_MODE_TRANS):
+		        hfcpci_clear_fifo_rx(cs, fifo2);
+		        hfcpci_clear_fifo_tx(cs, fifo2);
 			if (bc) {
 				cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;
 				cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;
@@ -1312,26 +1373,16 @@
 				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
 				cs->hw.hfcpci.ctmt |= 2;
 				cs->hw.hfcpci.conn &= ~0x18;
-				bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2;
-				bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2;
 			} else {
 				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1;
 				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
 				cs->hw.hfcpci.ctmt |= 1;
 				cs->hw.hfcpci.conn &= ~0x03;
-				bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1;
-				bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1;
 			}
-			bzr->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1;
-			bzr->za[MAX_B_FRAMES].z2 = bzr->za[MAX_B_FRAMES].z1;
-			bzr->f1 = MAX_B_FRAMES;
-			bzr->f2 = bzr->f1;	/* init F pointers to remain constant */
-			bzt->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1;
-			bzt->za[MAX_B_FRAMES].z2 = bzt->za[MAX_B_FRAMES].z1;
-			bzt->f1 = MAX_B_FRAMES;
-			bzt->f2 = bzt->f1;	/* init F pointers to remain constant */
 			break;
 		case (L1_MODE_HDLC):
+		        hfcpci_clear_fifo_rx(cs, fifo2);
+		        hfcpci_clear_fifo_tx(cs, fifo2);
 			if (bc) {
 				cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;
 				cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;
@@ -1340,11 +1391,13 @@
 				cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;
 			}
 			if (fifo2) {
+			        cs->hw.hfcpci.last_bfifo_cnt[1] = 0;  
 				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2;
 				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
 				cs->hw.hfcpci.ctmt &= ~2;
 				cs->hw.hfcpci.conn &= ~0x18;
 			} else {
+			        cs->hw.hfcpci.last_bfifo_cnt[0] = 0;  
 				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1;
 				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
 				cs->hw.hfcpci.ctmt &= ~1;
@@ -1633,7 +1686,8 @@
 
 #endif				/* CONFIG_PCI */
 
-int __init setup_hfcpci(struct IsdnCard *card)
+int __init
+setup_hfcpci(struct IsdnCard *card)
 {
 	struct IsdnCardState *cs = card->cs;
 	char tmp[64];
@@ -1645,7 +1699,7 @@
 #endif
 	strcpy(tmp, hfcpci_revision);
 	printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp));
-#ifdef CONFIG_PCI
+#if CONFIG_PCI
 	cs->hw.hfcpci.int_s1 = 0;
 	cs->dc.hfcpci.ph_state = 0;
 	cs->hw.hfcpci.fifo = 255;
@@ -1659,6 +1713,7 @@
 			if (tmp_hfcpci) {
 				if (pci_enable_device(tmp_hfcpci))
 					continue;
+				pci_set_master(tmp_hfcpci);
 				if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))
 					continue;
 				else
diff -urN linux-2.4.4-pre4/drivers/isdn/hisax/hfc_pci.h linux/drivers/isdn/hisax/hfc_pci.h
--- linux-2.4.4-pre4/drivers/isdn/hisax/hfc_pci.h	Sun Aug  6 12:43:41 2000
+++ linux/drivers/isdn/hisax/hfc_pci.h	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_pci.h,v 1.8 2000/06/26 08:59:13 keil Exp $
+/* $Id: hfc_pci.h,v 1.8.6.1 2001/04/08 19:32:26 kai Exp $
  *
  *  specific defines for CCD's HFC 2BDS0 PCI chips
  *
@@ -178,6 +178,9 @@
 #define HFCPCI_FIFOEN_B1     0x03
 #define HFCPCI_FIFOEN_B2     0x0C
 #define HFCPCI_FIFOEN_DTX    0x10
+#define HFCPCI_FIFOEN_B1TX   0x01
+#define HFCPCI_FIFOEN_B1RX   0x02
+#define HFCPCI_FIFOEN_B2TX   0x04
 #define HFCPCI_FIFOEN_B2RX   0x08
 
 
diff -urN linux-2.4.4-pre4/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h
--- linux-2.4.4-pre4/drivers/isdn/hisax/hisax.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hisax.h	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: hisax.h,v 2.52.6.3 2001/02/16 16:43:27 kai Exp $
+/* $Id: hisax.h,v 2.52.6.4 2001/04/08 19:32:26 kai Exp $
  *
  *   Basic declarations, defines and prototypes
  *
@@ -687,6 +687,7 @@
         unsigned char *pci_io; /* start of PCI IO memory */
         void *share_start; /* shared memory for Fifos start */
         void *fifos; /* FIFO memory */ 
+        int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
 	struct timer_list timer;
 };
 
diff -urN linux-2.4.4-pre4/drivers/isdn/hisax/isar.c linux/drivers/isdn/hisax/isar.c
--- linux-2.4.4-pre4/drivers/isdn/hisax/isar.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/hisax/isar.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: isar.c,v 1.17.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: isar.c,v 1.17.6.2 2001/04/08 17:51:42 kai Exp $
  *
  * isar.c   ISAR (Siemens PSB 7110) specific routines
  *
diff -urN linux-2.4.4-pre4/drivers/isdn/hysdn/boardergo.c linux/drivers/isdn/hysdn/boardergo.c
--- linux-2.4.4-pre4/drivers/isdn/hysdn/boardergo.c	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hysdn/boardergo.c	Mon Dec  3 22:35:55 2001
@@ -386,7 +386,9 @@
 			dpr->ToPcInt = 1;	/* interrupt to E1 for all cards */
 
 			restore_flags(flags);
-			if ((i = hysdn_net_create(card))) {
+			if ((hynet_enable & (1 << card->myid)) 
+			    && (i = hysdn_net_create(card))) 
+			{
 				ergo_stopcard(card);
 				card->state = CARD_STATE_BOOTERR;
 				return (i);
diff -urN linux-2.4.4-pre4/drivers/isdn/hysdn/hycapi.c linux/drivers/isdn/hysdn/hycapi.c
--- linux-2.4.4-pre4/drivers/isdn/hysdn/hycapi.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/hysdn/hycapi.c	Mon Dec  3 22:35:55 2001
@@ -41,7 +41,10 @@
 #include "hysdn_defs.h"
 #include <linux/kernelcapi.h>
 
-static char hycapi_revision[]="$Revision: 1.8.6.1 $";
+static char hycapi_revision[]="$Revision: 1.11 $";
+
+unsigned int hycapi_enable = 0xffffffff; 
+MODULE_PARM(hycapi_enable, "i");
 
 typedef struct _hycapi_appl {
 	unsigned int ctrl_mask;
@@ -542,15 +545,11 @@
 	printk(KERN_NOTICE "hycapi_rx_capipkt\n");    
 #endif
 	if(!cinfo) {
-		printk(KERN_ERR "HYSDN Card%d: no HYCAPI-controller!\n",
-		       card->myid);
 		return;
 	}
 	ctrl = cinfo->capi_ctrl;
 	if(!ctrl)
 	{
-		printk(KERN_ERR "HYSDN Card%d: no CAPI-controller (1)!\n",
-		       card->myid);
 		return;
 	}
 	if(len < CAPI_MSG_BASELEN) {
@@ -644,8 +643,6 @@
 	printk(KERN_NOTICE "hycapi_tx_capiack\n");    
 #endif
 	if(!cinfo) {
-		printk(KERN_ERR "HYSDN Card%d: no CAPI-controller (2)!\n",
-		       card->myid);
 		return;
 	}
 	spin_lock_irq(&cinfo->lock);
@@ -671,8 +668,6 @@
 {
 	hycapictrl_info *cinfo = card->hyctrlinfo;
 	if(!cinfo) {
-		printk(KERN_ERR "HYSDN Card%d: no CAPI-controller! (3)\n",
-		       card->myid);
 		return (struct sk_buff *)NULL;
 	}
 	if (!cinfo->sk_count)
@@ -792,6 +787,9 @@
 #ifdef HYCAPI_PRINTFNAMES
 	printk(KERN_NOTICE "hycapi_capi_create\n");        
 #endif
+	if((hycapi_enable & (1 << card->myid)) == 0) {
+		return 1;
+	}
 	if (!card->hyctrlinfo) {
 		cinfo = (hycapictrl_info *) kmalloc(sizeof(hycapictrl_info), GFP_ATOMIC);
 		if (!cinfo) {
diff -urN linux-2.4.4-pre4/drivers/isdn/hysdn/hysdn_defs.h linux/drivers/isdn/hysdn/hysdn_defs.h
--- linux-2.4.4-pre4/drivers/isdn/hysdn/hysdn_defs.h	Tue Nov 28 21:44:41 2000
+++ linux/drivers/isdn/hysdn/hysdn_defs.h	Mon Dec  3 22:35:55 2001
@@ -273,6 +273,7 @@
 extern int hysdn_tx_cfgline(hysdn_card *, uchar *, word);	/* send one cfg line */
 
 /* hysdn_net.c */
+extern unsigned int hynet_enable; 
 extern char *hysdn_net_revision;
 extern int hysdn_net_create(hysdn_card *);	/* create a new net device */
 extern int hysdn_net_release(hysdn_card *);	/* delete the device */
@@ -282,6 +283,7 @@
 extern void hysdn_rx_netpkt(hysdn_card *, uchar *, word);	/* rxed packet from network */
 
 #ifdef CONFIG_HYSDN_CAPI
+extern unsigned int hycapi_enable; 
 extern struct capi_driver_interface *hy_di;
 extern int hycapi_capi_create(hysdn_card *);	/* create a new capi device */
 extern int hycapi_capi_release(hysdn_card *);	/* delete the device */
diff -urN linux-2.4.4-pre4/drivers/isdn/hysdn/hysdn_net.c linux/drivers/isdn/hysdn/hysdn_net.c
--- linux-2.4.4-pre4/drivers/isdn/hysdn/hysdn_net.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/hysdn/hysdn_net.c	Mon Dec  3 22:35:55 2001
@@ -37,8 +37,11 @@
 
 #include "hysdn_defs.h"
 
+unsigned int hynet_enable = 0xffffffff; 
+MODULE_PARM(hynet_enable, "i");
+
 /* store the actual version for log reporting */
-char *hysdn_net_revision = "$Revision: 1.8.6.1 $";
+char *hysdn_net_revision = "$Revision: 1.10 $";
 
 #define MAX_SKB_BUFFERS 20	/* number of buffers for keeping TX-data */
 
diff -urN linux-2.4.4-pre4/drivers/isdn/hysdn/hysdn_procconf.c linux/drivers/isdn/hysdn/hysdn_procconf.c
--- linux-2.4.4-pre4/drivers/isdn/hysdn/hysdn_procconf.c	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hysdn/hysdn_procconf.c	Mon Dec  3 22:35:55 2001
@@ -41,7 +41,7 @@
 #define CONF_STATE_DETECT 0	/* waiting for detect */
 #define CONF_STATE_CONF   1	/* writing config data */
 #define CONF_STATE_POF    2	/* writing pof data */
-#define CONF_LINE_LEN    80	/* 80 chars max */
+#define CONF_LINE_LEN   255	/* 255 chars max */
 
 struct conf_writedata {
 	hysdn_card *card;	/* card the device is connected to */
diff -urN linux-2.4.4-pre4/drivers/isdn/hysdn/hysdn_sched.c linux/drivers/isdn/hysdn/hysdn_sched.c
--- linux-2.4.4-pre4/drivers/isdn/hysdn/hysdn_sched.c	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hysdn/hysdn_sched.c	Mon Dec  3 22:35:55 2001
@@ -47,7 +47,10 @@
 
 	switch (chan) {
 		case CHAN_NDIS_DATA:
-			hysdn_rx_netpkt(card, buf, len);	/* give packet to network handler */
+			if (hynet_enable & (1 << card->myid)) {
+                          /* give packet to network handler */
+				hysdn_rx_netpkt(card, buf, len);
+			}
 			break;
 
 		case CHAN_ERRLOG:
@@ -58,7 +61,9 @@
 #ifdef CONFIG_HYSDN_CAPI
          	case CHAN_CAPI:
 /* give packet to CAPI handler */
-			hycapi_rx_capipkt(card, buf, len);
+			if (hycapi_enable & (1 << card->myid)) {
+				hycapi_rx_capipkt(card, buf, len);
+			}
 			break;
 #endif /* CONFIG_HYSDN_CAPI */
 		default:
@@ -115,7 +120,9 @@
 		return (1);	/* tell that data should be send */
 	}			/* error log start and able to send */
 	/* now handle network interface packets */
-	if ((skb = hysdn_tx_netget(card)) != NULL) {
+	if ((hynet_enable & (1 << card->myid)) && 
+	    (skb = hysdn_tx_netget(card)) != NULL) 
+	{
 		if (skb->len <= maxlen) {
 			memcpy(buf, skb->data, skb->len);	/* copy the packet to the buffer */
 			*len = skb->len;
@@ -126,7 +133,9 @@
 			hysdn_tx_netack(card);	/* aknowledge packet -> throw away */
 	}			/* send a network packet if available */
 #ifdef CONFIG_HYSDN_CAPI
-	if((skb = hycapi_tx_capiget(card)) != NULL) {
+	if( ((hycapi_enable & (1 << card->myid))) && 
+	    ((skb = hycapi_tx_capiget(card)) != NULL) )
+	{
 		if (skb->len <= maxlen) {
 			memcpy(buf, skb->data, skb->len);
 			*len = skb->len;
diff -urN linux-2.4.4-pre4/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- linux-2.4.4-pre4/drivers/isdn/isdn_common.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/isdn_common.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.114.6.8 2001/02/16 16:43:22 kai Exp $
+/* $Id: isdn_common.c,v 1.114.6.10 2001/04/08 19:14:00 kai Exp $
 
  * Linux ISDN subsystem, common used functions (linklevel).
  *
@@ -51,7 +51,7 @@
 
 isdn_dev *dev;
 
-static char *isdn_revision = "$Revision: 1.114.6.8 $";
+static char *isdn_revision = "$Revision: 1.114.6.10 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
@@ -260,7 +260,6 @@
 static int isdn_timer_cnt1 = 0;
 static int isdn_timer_cnt2 = 0;
 static int isdn_timer_cnt3 = 0;
-static int isdn_timer_cnt4 = 0;
 
 static void
 isdn_timer_funct(ulong dummy)
@@ -284,16 +283,11 @@
 			isdn_timer_cnt2 = 0;
 			if (tf & ISDN_TIMER_NETHANGUP)
 				isdn_net_autohup();
-			if (++isdn_timer_cnt3 > ISDN_TIMER_RINGING) {
+			if (++isdn_timer_cnt3 >= ISDN_TIMER_RINGING) {
 				isdn_timer_cnt3 = 0;
 				if (tf & ISDN_TIMER_MODEMRING)
 					isdn_tty_modem_ring();
 			}
-			if (++isdn_timer_cnt4 > ISDN_TIMER_KEEPINT) {
-				isdn_timer_cnt4 = 0;
-				if (tf & ISDN_TIMER_KEEPALIVE)
-					isdn_net_slarp_out();
-			}
 			if (tf & ISDN_TIMER_CARRIER)
 				isdn_tty_carrier_timeout();
 		}
@@ -1120,7 +1114,7 @@
 		return -ENODEV;
 
 	lock_kernel();
- 	if (minor <= ISDN_MINOR_BMAX) {
+	if (minor <= ISDN_MINOR_BMAX) {
 		printk(KERN_WARNING "isdn_write minor %d obsolete!\n", minor);
 		drvidx = isdn_minor2drv(minor);
 		if (drvidx < 0) {
diff -urN linux-2.4.4-pre4/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- linux-2.4.4-pre4/drivers/isdn/isdn_net.c	Thu Feb  8 10:40:25 2001
+++ linux/drivers/isdn/isdn_net.c	Mon Dec  3 22:35:55 2001
@@ -22,6 +22,11 @@
  *
  */
 
+/* Jan 2001: fix CISCO HDLC      Bjoern A. Zeeb <i4l@zabbadoz.net>
+ *           for info on the protocol, see 
+ *           http://i4l.zabbadoz.net/i4l/cisco-hdlc.txt
+ */
+
 #include <linux/config.h>
 #define __NO_VERSION__
 #include <linux/module.h>
@@ -182,7 +187,10 @@
 int isdn_net_force_dial_lp(isdn_net_local *);
 static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
 
-char *isdn_net_revision = "$Revision: 1.140.6.3 $";
+static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
+static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
+
+char *isdn_net_revision = "$Revision: 1.144 $";
 
  /*
   * Code for raw-networking over ISDN
@@ -454,6 +462,8 @@
 					pops -> disconn_ind(cprot);
 #endif /* CONFIG_ISDN_X25 */
 				if ((!lp->dialstate) && (lp->flags & ISDN_NET_CONNECTED)) {
+					if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
+						isdn_net_ciscohdlck_disconnected(lp);
 #ifdef CONFIG_ISDN_PPP
 					if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
 						isdn_ppp_free(lp);
@@ -498,7 +508,7 @@
 						lp->dialstate = 0;
 						isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
 						if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
-							isdn_timer_ctrl(ISDN_TIMER_KEEPALIVE, 1);
+							isdn_net_ciscohdlck_connected(lp);
 						if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
 							if (lp->master) { /* is lp a slave? */
 								isdn_net_dev *nd = ((isdn_net_local *)lp->master->priv)->netdev;
@@ -660,7 +670,7 @@
 					isdn_net_hangup(&p->dev);
 					break;
 				}
-				if (!strcmp(lp->dial->num, "LEASED")) {
+				if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
 					restore_flags(flags);
 					lp->dialstate = 4;
 					printk(KERN_INFO "%s: Open leased line ...\n", lp->name);
@@ -1415,92 +1425,347 @@
 	return htons(ETH_P_802_2);
 }
 
-static void
-isdn_net_slarp_send(isdn_net_local *lp, int is_reply)
+
+/* 
+ * CISCO HDLC keepalive specific stuff
+ */
+static struct sk_buff*
+isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len)
 {
 	unsigned short hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
-	struct sk_buff *skb = alloc_skb(hl + sizeof(cisco_hdr) + sizeof(cisco_slarp), GFP_ATOMIC);
-	unsigned long t = (jiffies / HZ * 1000000);
-	cisco_hdr *ch;
-	cisco_slarp *s;
+	struct sk_buff *skb;
 
+	skb = alloc_skb(hl + len, GFP_ATOMIC);
 	if (!skb) {
-		printk(KERN_WARNING
-		       "%s: Could not allocate SLARP reply\n", lp->name);
-		return;
+		printk("isdn out of mem at %s:%d!\n", __FILE__, __LINE__);
+		return 0;
 	}
 	skb_reserve(skb, hl);
-	ch = (cisco_hdr *)skb_put(skb, sizeof(cisco_hdr));
-	ch->addr = CISCO_ADDR_UNICAST;
-	ch->ctrl = 0;
-	ch->type = htons(CISCO_TYPE_SLARP);
-	s = (cisco_slarp *)skb_put(skb, sizeof(cisco_slarp));
-	if (is_reply) {
-		s->code = htonl(CISCO_SLARP_REPLY);
-		memset(&s->slarp.reply.ifaddr, 0, sizeof(__u32));
-		memset(&s->slarp.reply.netmask, 0, sizeof(__u32));
-	} else {
-		lp->cisco_myseq++;
-		s->code = htonl(CISCO_SLARP_KEEPALIVE);
-		s->slarp.keepalive.my_seq = htonl(lp->cisco_myseq);
-		s->slarp.keepalive.your_seq = htonl(lp->cisco_yourseq);
-	}
-	s->rel = 0xffff;
-	s->t1 = t >> 16;
-	s->t0 = t & 0xffff;
-	isdn_net_write_super(lp, skb);
+	return skb;
 }
 
-static void
-isdn_net_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
+/* cisco hdlck device private ioctls */
+int
+isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-	cisco_slarp *s = (cisco_slarp *)skb->data;
+	isdn_net_local *lp = (isdn_net_local *) dev->priv;
+	unsigned long len = 0;
+	unsigned long expires = 0;
+	int tmp = 0;
+	int period = lp->cisco_keepalive_period;
+	char debserint = lp->cisco_debserint;
+	int rc = 0;
+
+	if (lp->p_encap != ISDN_NET_ENCAP_CISCOHDLCK)
+		return -EINVAL;
+
+	switch (cmd) {
+		/* get/set keepalive period */
+		case SIOCGKEEPPERIOD:
+			len = (unsigned long)sizeof(lp->cisco_keepalive_period);
+			if (copy_to_user((char *)ifr->ifr_ifru.ifru_data,
+				(int *)&lp->cisco_keepalive_period, len))
+				rc = -EFAULT;
+			break;
+		case SIOCSKEEPPERIOD:
+			tmp = lp->cisco_keepalive_period;
+			len = (unsigned long)sizeof(lp->cisco_keepalive_period);
+			if (copy_from_user((int *)&period,
+				(char *)ifr->ifr_ifru.ifru_data, len))
+				rc = -EFAULT;
+			if ((period > 0) && (period <= 32767))
+				lp->cisco_keepalive_period = period;
+			else
+				rc = -EINVAL;
+			if (!rc && (tmp != lp->cisco_keepalive_period)) {
+				expires = (unsigned long)(jiffies +
+					lp->cisco_keepalive_period * HZ);
+				mod_timer(&lp->cisco_timer, expires);
+				printk(KERN_INFO "%s: Keepalive period set "
+					"to %d seconds.\n",
+					lp->name, lp->cisco_keepalive_period);
+			}
+			break;
 
-	switch (ntohl(s->code)) {
-		case CISCO_SLARP_REQUEST:
-			isdn_net_slarp_send(lp, 1);
+		/* get/set debugging */
+		case SIOCGDEBSERINT:
+			len = (unsigned long)sizeof(lp->cisco_debserint);
+			if (copy_to_user((char *)ifr->ifr_ifru.ifru_data,
+				(char *)&lp->cisco_debserint, len))
+				rc = -EFAULT;
 			break;
-		case CISCO_SLARP_REPLY:
-			/* Ignore replies */
+		case SIOCSDEBSERINT:
+			len = (unsigned long)sizeof(lp->cisco_debserint);
+			if (copy_from_user((char *)&debserint,
+				(char *)ifr->ifr_ifru.ifru_data, len))
+				rc = -EFAULT;
+			if ((debserint >= 0) && (debserint <= 64))
+				lp->cisco_debserint = debserint;
+			else
+				rc = -EINVAL;
 			break;
-		case CISCO_SLARP_KEEPALIVE:
-			lp->cisco_yourseq = s->slarp.keepalive.my_seq;
-			if (ntohl(s->slarp.keepalive.my_seq == lp->cisco_myseq)) {
-				if (lp->cisco_loop++ == 2) {
-					printk(KERN_WARNING "%s: Keepalive Loop\n",
-					       lp->name);
-					lp->cisco_myseq ^= jiffies;
-				}
-			} else
-				lp->cisco_loop = 0;
+
+		default:
+			rc = -EINVAL;
 			break;
 	}
-	kfree_skb(skb);
+	return (rc);
 }
 
-/*
- * Called every 10 sec. via timer-interrupt if
- * any network-interface has Cisco-Keepalive-Encapsulation
- * and is online.
- * Send Keepalive-Packet and re-schedule.
- */
-void
-isdn_net_slarp_out(void)
+/* called via cisco_timer.function */
+static void
+isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
 {
-	isdn_net_dev *p = dev->netdev;
-	int anymore = 0;
+	isdn_net_local *lp = (isdn_net_local *) data;
+	struct sk_buff *skb;
+	unsigned char *p;
+	unsigned long last_cisco_myseq = lp->cisco_myseq;
+	int myseq_diff = 0;
 
-	while (p) {
-		isdn_net_local *l = p->local;
-		if ((l->p_encap == ISDN_NET_ENCAP_CISCOHDLCK) &&
-		    (l->flags & ISDN_NET_CONNECTED) &&
-		    (!l->dialstate)                           ) {
-			anymore = 1;
-			isdn_net_slarp_send(l, 0);
+	if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate) {
+		printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
+		return;
+	}
+	lp->cisco_myseq++;
+
+	myseq_diff = (lp->cisco_myseq - lp->cisco_mineseen);
+	if ((lp->cisco_line_state) && ((myseq_diff >= 3)||(myseq_diff <= -3))) {
+		/* line up -> down */
+		lp->cisco_line_state = 0;
+		printk (KERN_WARNING
+				"UPDOWN: Line protocol on Interface %s,"
+				" changed state to down\n", lp->name);
+		/* should stop routing higher-level data accross */
+	} else if ((!lp->cisco_line_state) &&
+		(myseq_diff >= 0) && (myseq_diff <= 2)) {
+		/* line down -> up */
+		lp->cisco_line_state = 1;
+		printk (KERN_WARNING
+				"UPDOWN: Line protocol on Interface %s,"
+				" changed state to up\n", lp->name);
+		/* restart routing higher-level data accross */
+	}
+
+	if (lp->cisco_debserint)
+		printk (KERN_DEBUG "%s: HDLC "
+			"myseq %lu, mineseen %lu%c, yourseen %lu, %s\n",
+			lp->name, last_cisco_myseq, lp->cisco_mineseen,
+			((last_cisco_myseq == lp->cisco_mineseen) ? '*' : 040),
+			lp->cisco_yourseq,
+			((lp->cisco_line_state) ? "line up" : "line down"));
+
+	skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
+	if (!skb)
+		return;
+
+	p = skb_put(skb, 4 + 14);
+
+	/* cisco header */
+	p += put_u8 (p, CISCO_ADDR_UNICAST);
+	p += put_u8 (p, CISCO_CTRL);
+	p += put_u16(p, CISCO_TYPE_SLARP);
+
+	/* slarp keepalive */
+	p += put_u32(p, CISCO_SLARP_KEEPALIVE);
+	p += put_u32(p, lp->cisco_myseq);
+	p += put_u32(p, lp->cisco_yourseq);
+	p += put_u16(p, 0xffff); // reliablity, always 0xffff
+
+	isdn_net_write_super(lp, skb);
+
+	lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ;
+	
+	add_timer(&lp->cisco_timer);
+}
+
+static void
+isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp)
+{
+	struct sk_buff *skb;
+	unsigned char *p;
+
+	skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
+	if (!skb)
+		return;
+
+	p = skb_put(skb, 4 + 14);
+
+	/* cisco header */
+	p += put_u8 (p, CISCO_ADDR_UNICAST);
+	p += put_u8 (p, CISCO_CTRL);
+	p += put_u16(p, CISCO_TYPE_SLARP);
+
+	/* slarp request */
+	p += put_u32(p, CISCO_SLARP_REQUEST);
+	p += put_u32(p, 0); // address
+	p += put_u32(p, 0); // netmask
+	p += put_u16(p, 0); // unused
+
+	isdn_net_write_super(lp, skb);
+}
+
+static void 
+isdn_net_ciscohdlck_connected(isdn_net_local *lp)
+{
+	lp->cisco_myseq = 0;
+	lp->cisco_mineseen = 0;
+	lp->cisco_yourseq = 0;
+	lp->cisco_keepalive_period = ISDN_TIMER_KEEPINT;
+	lp->cisco_last_slarp_in = 0;
+	lp->cisco_line_state = 0;
+	lp->cisco_debserint = 0;
+
+	/* send slarp request because interface/seq.no.s reset */
+	isdn_net_ciscohdlck_slarp_send_request(lp);
+
+	init_timer(&lp->cisco_timer);
+	lp->cisco_timer.data = (unsigned long) lp;
+	lp->cisco_timer.function = isdn_net_ciscohdlck_slarp_send_keepalive;
+	lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ;
+	add_timer(&lp->cisco_timer);
+}
+
+static void 
+isdn_net_ciscohdlck_disconnected(isdn_net_local *lp)
+{
+	del_timer(&lp->cisco_timer);
+}
+
+static void
+isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
+{
+	struct sk_buff *skb;
+	unsigned char *p;
+	struct in_device *in_dev = NULL;
+	u32 addr = 0;		/* local ipv4 address */
+	u32 mask = 0;		/* local netmask */
+
+	if ((in_dev = lp->netdev->dev.ip_ptr) != NULL) {
+		/* take primary(first) address of interface */
+		struct in_ifaddr *ifa = in_dev->ifa_list;
+		if (ifa != NULL) {
+			addr = ifa->ifa_local;
+			mask = ifa->ifa_mask;
 		}
-		p = (isdn_net_dev *) p->next;
 	}
-	isdn_timer_ctrl(ISDN_TIMER_KEEPALIVE, anymore);
+
+	skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
+	if (!skb)
+		return;
+
+	p = skb_put(skb, 4 + 14);
+
+	/* cisco header */
+	p += put_u8 (p, CISCO_ADDR_UNICAST);
+	p += put_u8 (p, CISCO_CTRL);
+	p += put_u16(p, CISCO_TYPE_SLARP);
+
+	/* slarp reply, send own ip/netmask; if values are nonsense remote
+	 * should think we are unable to provide it with an address via SLARP */
+	p += put_u32(p, CISCO_SLARP_REPLY);
+	p += put_u32(p, addr);	// address
+	p += put_u32(p, mask);	// netmask
+	p += put_u16(p, 0);	// unused
+
+	isdn_net_write_super(lp, skb);
+}
+
+static void
+isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
+{
+	unsigned char *p;
+	int period;
+	__u32 code;
+	__u32 my_seq, addr;
+	__u32 your_seq, mask;
+	__u16 unused;
+
+	if (skb->len < 14)
+		return;
+
+	p = skb->data;
+	p += get_u32(p, &code);
+	
+	switch (code) {
+	case CISCO_SLARP_REQUEST:
+		lp->cisco_yourseq = 0;
+		isdn_net_ciscohdlck_slarp_send_reply(lp);
+		break;
+	case CISCO_SLARP_REPLY:
+		/* Ignore replies - at least for now */
+		if (lp->cisco_debserint) {
+			p += get_u32(p, &addr);
+			p += get_u32(p, &mask);
+			p += get_u16(p, &unused);
+			printk(KERN_DEBUG "%s: got slarp reply (%ul/%ul) - "
+				"ignored\n", lp->name, addr, mask);
+		}
+		break;
+	case CISCO_SLARP_KEEPALIVE:
+		period = (int)((jiffies - lp->cisco_last_slarp_in
+				+ HZ/2 - 1) / HZ);
+		if (lp->cisco_debserint &&
+				(period != lp->cisco_keepalive_period) &&
+				lp->cisco_last_slarp_in) {
+			printk(KERN_DEBUG "%s: Keepalive period mismatch - "
+				"is %d but should be %d.\n",
+				lp->name, period, lp->cisco_keepalive_period);
+		}
+		lp->cisco_last_slarp_in = jiffies;
+		p += get_u32(p, &my_seq);
+		p += get_u32(p, &your_seq);
+		p += get_u16(p, &unused);
+		lp->cisco_yourseq = my_seq;
+		lp->cisco_mineseen = your_seq;
+		break;
+	}
+}
+
+static void
+isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
+{
+	unsigned char *p;
+	__u8 addr;
+	__u8 ctrl;
+	__u16 type;
+	
+	if (skb->len < 4)
+		goto out_free;
+
+	p = skb->data;
+	p += get_u8 (p, &addr);
+	p += get_u8 (p, &ctrl);
+	p += get_u16(p, &type);
+	skb_pull(skb, 4);
+	
+	if (addr != CISCO_ADDR_UNICAST && addr != CISCO_ADDR_BROADCAST) {
+		printk(KERN_WARNING "%s: Unknown Cisco addr 0x%02x\n",
+		       lp->name, addr);
+		goto out_free;
+	}
+	if (ctrl != CISCO_CTRL) {
+		printk(KERN_WARNING "%s: Unknown Cisco ctrl 0x%02x\n",
+		       lp->name, ctrl);
+		goto out_free;
+	}
+
+	switch (type) {
+	case CISCO_TYPE_INET:
+		skb->protocol = htons(ETH_P_IP);
+		netif_rx(skb);
+		break;
+	case CISCO_TYPE_SLARP:
+		isdn_net_ciscohdlck_slarp_in(lp, skb);
+		goto out_free;
+	default:
+		printk(KERN_WARNING "%s: Unknown Cisco type 0x%04x\n",
+		       lp->name, type);
+		goto out_free;
+	}
+	return;
+
+ out_free:
+	kfree_skb(skb);
 }
 
 /*
@@ -1517,8 +1782,6 @@
 #ifdef CONFIG_ISDN_X25
 	struct concap_proto *cprot = lp -> netdev -> cprot;
 #endif
-	cisco_hdr *ch;
-
 	lp->transcount += skb->len;
 
 	lp->stats.rx_packets++;
@@ -1558,36 +1821,8 @@
 			skb->protocol = htons(ETH_P_IP);
 			break;
 		case ISDN_NET_ENCAP_CISCOHDLCK:
-			ch = (cisco_hdr *)skb->data;
-			if ((ch->addr != CISCO_ADDR_UNICAST) &&
-			    (ch->addr != CISCO_ADDR_BROADCAST)  ) {
-				printk(KERN_WARNING "%s: Unknown Cisco addr 0x%02x\n",
-				       lp->name, ch->addr);
-				kfree_skb(skb);
-				return;
-			}
-			if (ch->ctrl != 0) {
-				printk(KERN_WARNING "%s: Unknown Cisco ctrl 0x%02x\n",
-				       lp->name, ch->ctrl);
-				kfree_skb(skb);
-				return;
-			}
-			switch (ntohs(ch->type)) {
-				case CISCO_TYPE_INET:
-					skb_pull(skb, 4);
-					skb->protocol = htons(ETH_P_IP);
-					break;
-				case CISCO_TYPE_SLARP:
-					skb_pull(skb, 4);
-					isdn_net_slarp_in(olp, skb);
-					return;
-				default:
-					printk(KERN_WARNING "%s: Unknown Cisco type 0x%04x\n",
-					       lp->name, ch->type);
-					kfree_skb(skb);
-					return;
-			}
-			break;
+			isdn_net_ciscohdlck_receive(lp, skb);
+			return;
 		case ISDN_NET_ENCAP_CISCOHDLC:
 			/* CISCO-HDLC IP with type field and  fake I-frame-header */
 			skb_pull(skb, 2);
@@ -1705,6 +1940,7 @@
 		void *daddr, void *saddr, unsigned plen)
 {
 	isdn_net_local *lp = dev->priv;
+	unsigned char *p;
 	ushort len = 0;
 
 	switch (lp->p_encap) {
@@ -1733,10 +1969,11 @@
 			len = 2;
 			break;
 		case ISDN_NET_ENCAP_CISCOHDLC:
-			skb_push(skb, 4);
-			skb->data[0] = 0x0f;
-			skb->data[1] = 0x00;
-			*((ushort *) & skb->data[2]) = htons(type);
+		case ISDN_NET_ENCAP_CISCOHDLCK:
+			p = skb_push(skb, 4);
+			p += put_u8 (p, CISCO_ADDR_UNICAST);
+			p += put_u8 (p, CISCO_CTRL);
+			p += put_u16(p, type);
 			len = 4;
 			break;
 #ifdef CONFIG_ISDN_X25
@@ -1842,9 +2079,7 @@
 	ndev->stop = &isdn_net_close;
 	ndev->get_stats = &isdn_net_get_stats;
 	ndev->rebuild_header = &isdn_net_rebuild_header;
-#ifdef CONFIG_ISDN_PPP
-	ndev->do_ioctl = isdn_ppp_dev_ioctl;
-#endif
+	ndev->do_ioctl = NULL;
 	return 0;
 }
 
@@ -2508,6 +2743,7 @@
 #else
 			p->dev.type = ARPHRD_PPP;	/* change ARP type */
 			p->dev.addr_len = 0;
+			p->dev.do_ioctl = isdn_ppp_dev_ioctl;
 #endif
 			break;
 		case ISDN_NET_ENCAP_X25IFACE:
@@ -2519,6 +2755,9 @@
 			p->dev.type = ARPHRD_X25;	/* change ARP type */
 			p->dev.addr_len = 0;
 #endif
+			break;
+		case ISDN_NET_ENCAP_CISCOHDLCK:
+			p->dev.do_ioctl = isdn_ciscohdlck_dev_ioctl;
 			break;
 		default:
 			if( cfg->p_encap >= 0 &&
diff -urN linux-2.4.4-pre4/drivers/isdn/isdn_net.h linux/drivers/isdn/isdn_net.h
--- linux-2.4.4-pre4/drivers/isdn/isdn_net.h	Tue Aug  8 15:03:57 2000
+++ linux/drivers/isdn/isdn_net.h	Mon Dec  3 22:35:55 2001
@@ -33,31 +33,9 @@
  * Definitions for Cisco-HDLC header.
  */
 
-typedef struct cisco_hdr {
-	__u8  addr; /* unicast/broadcast */
-	__u8  ctrl; /* Always 0          */
-	__u16 type; /* IP-typefield      */
-} cisco_hdr;
-
-typedef struct cisco_slarp {
-	__u32 code;                     /* SLREQ/SLREPLY/KEEPALIVE */
-	union {
-		struct {
-			__u32 ifaddr;   /* My interface address     */
-			__u32 netmask;  /* My interface netmask     */
-		} reply;
-		struct {
-			__u32 my_seq;   /* Packet sequence number   */
-			__u32 your_seq;
-		} keepalive;
-	} slarp;
-	__u16 rel;                      /* Always 0xffff            */
-	__u16 t1;                       /* Uptime in usec >> 16     */
-	__u16 t0;                       /* Uptime in usec & 0xffff  */
-} cisco_slarp;
-
 #define CISCO_ADDR_UNICAST    0x0f
 #define CISCO_ADDR_BROADCAST  0x8f
+#define CISCO_CTRL            0x00
 #define CISCO_TYPE_INET       0x0800
 #define CISCO_TYPE_SLARP      0x8035
 #define CISCO_SLARP_REPLY     0
@@ -83,7 +61,6 @@
 extern int isdn_net_force_dial(char *);
 extern isdn_net_dev *isdn_net_findif(char *);
 extern int isdn_net_rcv_skb(int, struct sk_buff *);
-extern void isdn_net_slarp_out(void);
 extern int isdn_net_dial_req(isdn_net_local *);
 extern void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb);
 extern void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb);
@@ -166,6 +143,52 @@
 		master_lp->netdev->queue = lp->next;
 	lp->next = lp->last = lp;	/* (re)set own pointers */
 	spin_unlock_irqrestore(&master_lp->netdev->queue_lock, flags);
+}
+
+static inline int
+put_u8(unsigned char *p, __u8 x)
+{
+	p[0] = x;
+	return 1;
+}
+
+static inline int
+put_u16(unsigned char *p, __u16 x)
+{
+	p[0] = x >> 8;
+	p[1] = x;
+	return 2;
+}
+
+static inline int
+put_u32(unsigned char *p, __u32 x)
+{
+	p[0] = x >> 24;
+	p[1] = x >> 16;
+	p[2] = x >> 8;
+	p[3] = x;
+	return 4;
+}
+
+static inline int
+get_u8(unsigned char *p, __u8 *x)
+{
+	*x = p[0];
+	return 1;
+}
+
+static inline int
+get_u16(unsigned char *p, __u16 *x)
+{
+	*x = (p[0] << 8) + p[1];
+	return 2;
+}
+
+static inline int
+get_u32(unsigned char *p, __u32 *x)
+{
+	*x = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
+	return 4;
 }
 
 
diff -urN linux-2.4.4-pre4/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- linux-2.4.4-pre4/drivers/isdn/isdn_ppp.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/isdn_ppp.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.c,v 1.85.6.2 2001/01/23 17:45:02 kai Exp $
+/* $Id: isdn_ppp.c,v 1.85.6.4 2001/04/08 18:53:07 kai Exp $
  *
  * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
@@ -83,7 +83,7 @@
 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
 #endif	/* CONFIG_ISDN_MPP */
   
-char *isdn_ppp_revision = "$Revision: 1.85.6.2 $";
+char *isdn_ppp_revision = "$Revision: 1.85.6.4 $";
 
 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
 
diff -urN linux-2.4.4-pre4/drivers/isdn/sc/interrupt.c linux/drivers/isdn/sc/interrupt.c
--- linux-2.4.4-pre4/drivers/isdn/sc/interrupt.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/sc/interrupt.c	Mon Dec  3 22:35:55 2001
@@ -1,5 +1,5 @@
 /*
- *  $Id: interrupt.c,v 1.4.8.1 2001/03/13 16:17:09 kai Exp $
+ *  $Id: interrupt.c,v 1.4.8.2 2001/04/08 17:51:43 kai Exp $
  *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
diff -urN linux-2.4.4-pre4/drivers/isdn/sc/message.c linux/drivers/isdn/sc/message.c
--- linux-2.4.4-pre4/drivers/isdn/sc/message.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/isdn/sc/message.c	Mon Dec  3 22:35:55 2001
@@ -1,5 +1,5 @@
 /*
- *  $Id: message.c,v 1.5 1999/09/04 06:20:07 keil Exp $
+ *  $Id: message.c,v 1.5.8.1 2001/04/08 17:51:43 kai Exp $
  *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
  *  message.c - functions for sending and receiving control messages
diff -urN linux-2.4.4-pre4/drivers/media/video/stradis.c linux/drivers/media/video/stradis.c
--- linux-2.4.4-pre4/drivers/media/video/stradis.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/media/video/stradis.c	Mon Dec  3 22:35:55 2001
@@ -2196,9 +2196,9 @@
 
 		/* disable PCI bus-mastering */
 		pci_read_config_byte(saa->dev, PCI_COMMAND, &command);
-		/* Should this be &=~ ?? */
 		command &= ~PCI_COMMAND_MASTER;
 		pci_write_config_byte(saa->dev, PCI_COMMAND, command);
+
 		/* unmap and free memory */
 		saa->audhead = saa->audtail = saa->osdhead = 0;
 		saa->vidhead = saa->vidtail = saa->osdtail = 0;
diff -urN linux-2.4.4-pre4/drivers/net/3c501.c linux/drivers/net/3c501.c
--- linux-2.4.4-pre4/drivers/net/3c501.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/3c501.c	Mon Dec  3 22:35:55 2001
@@ -85,7 +85,7 @@
  *
  */
 
-static const char *version =
+static const char version[] =
     "3c501.c: 2000/02/08 Alan Cox (alan@redhat.com).\n";
 
 /*
diff -urN linux-2.4.4-pre4/drivers/net/3c503.c linux/drivers/net/3c503.c
--- linux-2.4.4-pre4/drivers/net/3c503.c	Tue Mar  6 19:28:33 2001
+++ linux/drivers/net/3c503.c	Mon Dec  3 22:35:55 2001
@@ -30,7 +30,7 @@
 
 */
 
-static const char *version =
+static const char version[] =
     "3c503.c:v1.10 9/23/93  Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/3c505.c linux/drivers/net/3c505.c
--- linux-2.4.4-pre4/drivers/net/3c505.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/3c505.c	Mon Dec  3 22:35:55 2001
@@ -119,13 +119,13 @@
  *
  *********************************************************/
 
-static const char *filename = __FILE__;
+static const char filename[] = __FILE__;
 
-static const char *timeout_msg = "*** timeout at %s:%s (line %d) ***\n";
+static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n";
 #define TIMEOUT_MSG(lineno) \
 	printk(timeout_msg, filename,__FUNCTION__,(lineno))
 
-static const char *invalid_pcb_msg =
+static const char invalid_pcb_msg[] =
 "*** invalid pcb length %d at %s:%s (line %d) ***\n";
 #define INVALID_PCB_MSG(len) \
 	printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__)
diff -urN linux-2.4.4-pre4/drivers/net/3c507.c linux/drivers/net/3c507.c
--- linux-2.4.4-pre4/drivers/net/3c507.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/3c507.c	Mon Dec  3 22:35:55 2001
@@ -23,7 +23,7 @@
 	The statistics need to be updated correctly.
 */
 
-static const char *version =
+static const char version[] =
 	"3c507.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 
diff -urN linux-2.4.4-pre4/drivers/net/8139too.c linux/drivers/net/8139too.c
--- linux-2.4.4-pre4/drivers/net/8139too.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/8139too.c	Mon Dec  3 22:35:55 2001
@@ -149,7 +149,7 @@
 #include <asm/io.h>
 
 
-#define RTL8139_VERSION "0.9.15d"
+#define RTL8139_VERSION "0.9.16"
 #define MODNAME "8139too"
 #define RTL8139_DRIVER_NAME   MODNAME " Fast Ethernet driver " RTL8139_VERSION
 #define PFX MODNAME ": "
@@ -221,8 +221,8 @@
 #define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */
 
 /* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024, 7==end of packet. */
-#define RX_FIFO_THRESH	6	/* Rx buffer level before first PCI xfer.  */
-#define RX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
+#define RX_FIFO_THRESH	7	/* Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST	7	/* Maximum PCI burst, '6' is 1024 */
 #define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
 
 
@@ -492,7 +492,7 @@
 } chip_t;
 
 enum chip_flags {
-	HasPwrDn = (1 << 0),
+	HasHltClk = (1 << 0),
 	HasLWake = (1 << 1),
 };
 
@@ -507,19 +507,19 @@
 	{ "RTL-8139",
 	  0x40,
 	  0xf0fe0040, /* XXX copied from RTL8139A, verify */
-	  HasPwrDn,
+	  HasHltClk,
 	},
 
 	{ "RTL-8139 rev K",
 	  0x60,
 	  0xf0fe0040,
-	  HasPwrDn,
+	  HasHltClk,
 	},
 
 	{ "RTL-8139A",
 	  0x70,
 	  0xf0fe0040,
-	  0,
+	  HasHltClk, /* XXX undocumented? */
 	},
 
 	{ "RTL-8139B",
@@ -573,6 +573,7 @@
 	pid_t thr_pid;
 	wait_queue_head_t thr_wait;
 	struct semaphore thr_exited;
+	u32 rx_config;
 };
 
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
@@ -634,6 +635,7 @@
 #define RTL_W32_F(reg, val32)	do { writel ((val32), ioaddr + (reg)); readl (ioaddr + (reg)); } while (0)
 
 
+#define MMIO_FLUSH_AUDIT_COMPLETE 1
 #if MMIO_FLUSH_AUDIT_COMPLETE
 
 /* write MMIO register */
@@ -701,6 +703,23 @@
 }
 
 
+static void rtl8139_chip_reset (void *ioaddr)
+{
+	int i;
+
+	/* Soft reset the chip. */
+	RTL_W8 (ChipCmd, CmdReset);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--) {
+		barrier();
+		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
+			break;
+		udelay (10);
+	}
+}
+
+
 static int __devinit rtl8139_init_board (struct pci_dev *pdev,
 					 struct net_device **dev_out)
 {
@@ -708,7 +727,8 @@
 	struct net_device *dev;
 	struct rtl8139_private *tp;
 	u8 tmp8;
-	int rc, i;
+	int rc;
+	unsigned int i, have_pci_pm = 1;
 	u32 pio_start, pio_end, pio_flags, pio_len;
 	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
 	u32 tmp;
@@ -749,30 +769,37 @@
 	 * we talk to the chip directly */
 	DPRINTK("PIO region size == 0x%02X\n", pio_len);
 	DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
-	if (pio_len == RTL8139B_IO_SIZE)
-		tp->chipset = CH_8139B;
 
+	/* ugly hueristic, but it's a chicken-and-egg problem */
+	if (pio_len < RTL8139B_IO_SIZE)
+		have_pci_pm = 0;
+	
+#ifdef USE_IO_OPS
 	/* make sure PCI base addr 0 is PIO */
 	if (!(pio_flags & IORESOURCE_IO)) {
 		printk (KERN_ERR PFX "%s: region #0 not a PIO resource, aborting\n", pdev->slot_name);
 		rc = -ENODEV;
 		goto err_out;
 	}
-
+	/* check for weird/broken PCI region reporting */
+	if (pio_len < RTL_MIN_IO_SIZE) {
+		printk (KERN_ERR PFX "%s: Invalid PCI I/O region size(s), aborting\n", pdev->slot_name);
+		rc = -ENODEV;
+		goto err_out;
+	}
+#else
 	/* make sure PCI base addr 1 is MMIO */
 	if (!(mmio_flags & IORESOURCE_MEM)) {
 		printk (KERN_ERR PFX "%s: region #1 not an MMIO resource, aborting\n", pdev->slot_name);
 		rc = -ENODEV;
 		goto err_out;
 	}
-
-	/* check for weird/broken PCI region reporting */
-	if ((pio_len < RTL_MIN_IO_SIZE) ||
-	    (mmio_len < RTL_MIN_IO_SIZE)) {
-		printk (KERN_ERR PFX "%s: Invalid PCI region size(s), aborting\n", pdev->slot_name);
+	if (mmio_len < RTL_MIN_IO_SIZE) {
+		printk (KERN_ERR PFX "%s: Invalid PCI mem region size(s), aborting\n", pdev->slot_name);
 		rc = -ENODEV;
 		goto err_out;
 	}
+#endif
 
 	rc = pci_request_regions (pdev, "8139too");
 	if (rc)
@@ -796,61 +823,43 @@
 	tp->mmio_addr = ioaddr;
 #endif /* USE_IO_OPS */
 
-	/* Bring the chip out of low-power mode. */
-	if (rtl_chip_info[tp->chipset].flags & HasPwrDn) {
-		tmp8 = RTL_R8 (Config1);
-		if (tmp8 & (SLEEP|PWRDN)) {
-			RTL_W8_F (Cfg9346, Cfg9346_Unlock);
-			RTL_W8 (Config1, tmp8 & ~(SLEEP|PWRDN));
-			RTL_W8_F (Cfg9346, Cfg9346_Lock);
-		}
-	} else {
+	/* Bring old chips out of low-power mode. */
+	if (have_pci_pm) {
 		u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
 		if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
 		    (tmp8 & LWAKE))
 			new_tmp8 &= ~LWAKE;
 		new_tmp8 |= Cfg1_PM_Enable;
 		if (new_tmp8 != tmp8) {
-			RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+			RTL_W8 (Cfg9346, Cfg9346_Unlock);
 			RTL_W8 (Config1, tmp8);
-			RTL_W8_F (Cfg9346, Cfg9346_Lock);
+			RTL_W8 (Cfg9346, Cfg9346_Lock);
 		}
 		if (rtl_chip_info[tp->chipset].flags & HasLWake) {
 			tmp8 = RTL_R8 (Config4);
 			if (tmp8 & LWPTN)
 				RTL_W8 (Config4, tmp8 & ~LWPTN);
 		}
+	} else {
+		RTL_W8 (HltClk, 'R');
+		tmp8 = RTL_R8 (Config1);
+		tmp8 &= ~(SLEEP | PWRDN);
+		RTL_W8 (Config1, tmp8);
 	}
 
-	/* Soft reset the chip. */
-	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
-
-	/* Check that the chip has finished the reset. */
-	for (i = 1000; i > 0; i--) {
-		barrier();
-		udelay (10);
-		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
-			break;
-	}
+	rtl8139_chip_reset (ioaddr);
 
-	/* make sure chip thinks PIO and MMIO are enabled */
-	tmp8 = RTL_R8 (Config1);
-	if ((tmp8 & Cfg1_PIO) == 0) {
-		printk (KERN_ERR PFX "%s: PIO not enabled, Cfg1=%02X, aborting\n",
-			pdev->slot_name, tmp8);
-		rc = -EIO;
-		goto err_out;
-	}
-	if ((tmp8 & Cfg1_MMIO) == 0) {
-		printk (KERN_ERR PFX "%s: MMIO not enabled, Cfg1=%02X, aborting\n",
-			pdev->slot_name, tmp8);
+	/* check for missing/broken hardware */
+	if (RTL_R32 (TxConfig) == 0xFFFFFFFF) {
+		printk (KERN_ERR PFX "%s: Chip not responding, ignoring board\n",
+			pdev->slot_name);
 		rc = -EIO;
 		goto err_out;
 	}
 
 	/* identify chip attached to board */
 	tmp = RTL_R8 (ChipVersion);
-	for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--)
+	for (i = 0; i < ARRAY_SIZE (rtl_chip_info); i++)
 		if (tmp == rtl_chip_info[i].version) {
 			tp->chipset = i;
 			goto match;
@@ -887,7 +896,6 @@
 	int i, addr_len, option;
 	void *ioaddr;
 	static int board_idx = -1;
-	static int printed_version;
 
 	DPRINTK ("ENTER\n");
 
@@ -896,10 +904,16 @@
 
 	board_idx++;
 
-	if (!printed_version) {
-		printk (KERN_INFO RTL8139_DRIVER_NAME " loaded\n");
-		printed_version = 1;
+	/* when we're built into the kernel, the driver version message
+	 * is only printed if at least one 8139 board has been found
+	 */
+#ifndef MODULE
+	{
+		static int printed_version;
+		if (!printed_version++)
+			printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
 	}
+#endif
 
 	i = rtl8139_init_board (pdev, &dev);
 	if (i < 0) {
@@ -988,14 +1002,6 @@
 #endif
 		tp->phys[0] = 32;
 
-	/* Put the chip into low-power mode. */
-	if (rtl_chip_info[tp->chipset].flags & HasPwrDn) {
-		RTL_W8_F (Cfg9346, Cfg9346_Unlock);
-		RTL_W8_F (Config1, RTL_R8 (Config1) | PWRDN);
-		RTL_W8_F (HltClk, 'H');	/* 'R' would leave the clock running. */
-		RTL_W8_F (Cfg9346, Cfg9346_Lock);
-	}
-
 	/* The lower four bits are the media type. */
 	option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
 	if (option > 0) {
@@ -1021,6 +1027,10 @@
 				   ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
 	}
 
+	/* Put the chip into low-power mode. */
+	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
+		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
+
 	DPRINTK ("EXIT - returning 0\n");
 	return 0;
 
@@ -1216,11 +1226,11 @@
 	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
 		void *ioaddr = tp->mmio_addr;
 		if (location == 0) {
-			RTL_W8_F (Cfg9346, Cfg9346_Unlock);
-			RTL_W16_F (BasicModeCtrl, value);
-			RTL_W8_F (Cfg9346, Cfg9346_Lock);
+			RTL_W8 (Cfg9346, Cfg9346_Unlock);
+			RTL_W16 (BasicModeCtrl, value);
+			RTL_W8 (Cfg9346, Cfg9346_Lock);
 		} else if (location < 8 && mii_2_8139_map[location])
-			RTL_W16_F (mii_2_8139_map[location], value);
+			RTL_W16 (mii_2_8139_map[location], value);
 		return;
 	}
 
@@ -1315,33 +1325,30 @@
 
 	DPRINTK ("ENTER\n");
 
-	/* Soft reset the chip. */
-	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
-	udelay (100);
+	/* Bring old chips out of low-power mode. */
+	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
+		RTL_W8 (HltClk, 'R');
 
-	/* Check that the chip has finished the reset. */
-	for (i = 1000; i > 0; i--)
-		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
-			break;
+	rtl8139_chip_reset (ioaddr);
 
 	/* unlock Config[01234] and BMCR register writes */
-	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+	RTL_W8 (Cfg9346, Cfg9346_Unlock);
 	/* Restore our idea of the MAC address. */
 	RTL_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
-	RTL_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+	RTL_W32 (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
 
 	/* Must enable Tx/Rx before setting transfer thresholds! */
-	RTL_W8_F (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) |
-			   CmdRxEnb | CmdTxEnb);
+	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
-	i = rtl8139_rx_config |
-	    (RTL_R32 (RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
-	RTL_W32_F (RxConfig, i);
+	tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
+	RTL_W32 (RxConfig, rtl8139_rx_config);
 
 	/* Check this value: the documentation for IFG contradicts ifself. */
 	RTL_W32 (TxConfig, (TX_DMA_BURST << TxDMAShift));
 
 	tp->cur_rx = 0;
+	
+	DPRINTK("check_duplex");
 
 	/* This is check_duplex() */
 	if (tp->phys[0] >= 0  ||  (tp->drv_flags & HAS_MII_XCVR)) {
@@ -1358,8 +1365,6 @@
 			   tp->full_duplex ? "full" : "half", mii_reg5);
 	}
 
-	RTL_W8 (Config1, RTL_R8 (Config1) | Cfg1_Driver_Load);
-
 	if (tp->chipset >= CH_8139B) {
 		tmp = RTL_R8 (Config4) & ~(1<<2);
 		/* chip will clear Rx FIFO overflow automatically */
@@ -1371,9 +1376,10 @@
 		RTL_W8 (Config3, RTL_R8 (Config3) & ~(1<<5));
 	}
 
+	DPRINTK("init buffer addresses\n");
+
 	/* Lock Config[01234] and BMCR register writes */
-	RTL_W8_F (Cfg9346, Cfg9346_Lock);
-	udelay (10);
+	RTL_W8 (Cfg9346, Cfg9346_Lock);
 
 	/* init Rx ring buffer DMA address */
 	RTL_W32_F (RxBuf, tp->rx_ring_dma);
@@ -1382,7 +1388,7 @@
 	for (i = 0; i < NUM_TX_DESC; i++)
 		RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
 
-	RTL_W32_F (RxMissed, 0);
+	RTL_W32 (RxMissed, 0);
 
 	rtl8139_set_rx_mode (dev);
 
@@ -1390,11 +1396,12 @@
 	RTL_W16 (MultiIntr, RTL_R16 (MultiIntr) & MultiIntrClear);
 
 	/* make sure RxTx has started */
-	RTL_W8_F (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) |
-			   CmdRxEnb | CmdTxEnb);
+	tmp = RTL_R8 (ChipCmd);
+	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
+		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
 	/* Enable all known interrupts by setting the interrupt mask. */
-	RTL_W16_F (IntrMask, rtl8139_intr_mask);
+	RTL_W16 (IntrMask, rtl8139_intr_mask);
 
 	netif_start_queue (dev);
 
@@ -1628,6 +1635,7 @@
 	void *ioaddr = tp->mmio_addr;
 	int i;
 	u8 tmp8;
+	unsigned long flags;
 
 	DPRINTK ("%s: Transmit timeout, status %2.2x %4.4x "
 		 "media %2.2x.\n", dev->name,
@@ -1638,7 +1646,7 @@
 	/* disable Tx ASAP, if not already */
 	tmp8 = RTL_R8 (ChipCmd);
 	if (tmp8 & CmdTxEnb)
-		RTL_W8 (ChipCmd, tmp8 & ~CmdTxEnb);
+		RTL_W8 (ChipCmd, CmdRxEnb);
 
 	/* Disable interrupts by clearing the interrupt mask. */
 	RTL_W16 (IntrMask, 0x0000);
@@ -1653,9 +1661,9 @@
 				" (queue head)" : "");
 
 	/* Stop a shared interrupt from scavenging while we are. */
-	spin_lock_irq (&tp->lock);
+	spin_lock_irqsave (&tp->lock, flags);
 	rtl8139_tx_clear (tp);
-	spin_unlock_irq (&tp->lock);
+	spin_unlock_irqrestore (&tp->lock, flags);
 
 	/* ...and finally, reset everything */
 	rtl8139_hw_start (dev);
@@ -1669,7 +1677,8 @@
 {
 	struct rtl8139_private *tp = dev->priv;
 	void *ioaddr = tp->mmio_addr;
-	int entry;
+	unsigned int entry;
+	unsigned long flags;
 
 	/* Calculate the next Tx descriptor entry. */
 	entry = tp->cur_tx % NUM_TX_DESC;
@@ -1696,13 +1705,13 @@
 
 	dev->trans_start = jiffies;
 
-	spin_lock_irq (&tp->lock);
+	spin_lock_irqsave (&tp->lock, flags);
 
 	tp->cur_tx++;
 	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
 		netif_stop_queue (dev);
 
-	spin_unlock_irq (&tp->lock);
+	spin_unlock_irqrestore (&tp->lock, flags);
 
 	DPRINTK ("%s: Queued Tx packet at %p size %u to slot %d.\n",
 		 dev->name, skb->data, skb->len, entry);
@@ -1775,6 +1784,7 @@
 
 		dirty_tx++;
 		tx_left--;
+		barrier();
 	}
 
 #ifndef RTL8139_NDEBUG
@@ -1819,8 +1829,7 @@
 	tp->cur_rx = 0;
 
 	/* disable receive */
-	tmp8 = RTL_R8 (ChipCmd) & ChipCmdClear;
-	RTL_W8_F (ChipCmd, tmp8 | CmdTxEnb);
+	RTL_W8 (ChipCmd, CmdTxEnb);
 
 	/* A.C.: Reset the multicast list. */
 	rtl8139_set_rx_mode (dev);
@@ -1828,11 +1837,11 @@
 	/* XXX potentially temporary hack to
 	 * restart hung receiver */
 	while (--tmp_work > 0) {
+		barrier();
 		tmp8 = RTL_R8 (ChipCmd);
 		if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
 			break;
-		RTL_W8_F (ChipCmd,
-			  (tmp8 & ChipCmdClear) | CmdRxEnb | CmdTxEnb);
+		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 	}
 
 	/* G.S.: Re-enable receiver */
@@ -1849,7 +1858,7 @@
 				  u16 status)
 {
 	unsigned char *rx_ring;
-	u16 cur_rx;
+	u16 cur_rx, ackstat;
 
 	assert (dev != NULL);
 	assert (tp != NULL);
@@ -1875,6 +1884,8 @@
 		unsigned int pkt_size;
 		struct sk_buff *skb;
 
+		mb();
+
 		/* read size+status of next frame from DMA ring buffer */
 		rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
 		rx_size = rx_status >> 16;
@@ -1894,10 +1905,8 @@
 		}
 #endif
 
-		if (rx_size == 0xfff0) { /* Early Rx in progress */
-			RTL_W16_F (IntrStatus, status);
+		if (rx_size == 0xfff0) /* Early Rx in progress */
 			break;
-		}
 
 		/* If Rx err or invalid rx_size/rx_status received
 		 * (which happens if we get lost in the ring),
@@ -1905,6 +1914,7 @@
 		 * Rx processing.
 		 */
 		if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+		    (rx_size < 8) ||
 		    (!(rx_status & RxStatusOK))) {
 			rtl8139_rx_err (rx_status, dev, tp, ioaddr);
 			return;
@@ -1941,8 +1951,10 @@
 
 		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
 		RTL_W16 (RxBufPtr, cur_rx - 16);
-		RTL_W16_F (IntrStatus, status);
-		barrier();
+
+		ackstat = RTL_R16 (IntrStatus) & status;
+		if (ackstat)
+			RTL_W16 (IntrStatus, ackstat);
 	}
 
 	DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
@@ -1951,6 +1963,12 @@
 		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
 	tp->cur_rx = cur_rx;
+
+	if (RTL_R8 (ChipCmd) & RxBufEmpty) {
+		ackstat = RTL_R16 (IntrStatus) & status;
+		if (ackstat)
+			RTL_W16_F (IntrStatus, ackstat);
+	}
 }
 
 
@@ -2100,6 +2118,7 @@
 	struct rtl8139_private *tp = dev->priv;
 	void *ioaddr = tp->mmio_addr;
 	int ret = 0;
+	unsigned long flags;
 
 	DPRINTK ("ENTER\n");
 
@@ -2117,19 +2136,19 @@
 	DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n",
 			dev->name, RTL_R16 (IntrStatus));
 
-	spin_lock_irq (&tp->lock);
+	spin_lock_irqsave (&tp->lock, flags);
 
 	/* Stop the chip's Tx and Rx DMA processes. */
-	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear));
+	RTL_W8 (ChipCmd, 0);
 
 	/* Disable interrupts by clearing the interrupt mask. */
-	RTL_W16 (IntrMask, 0x0000);
+	RTL_W16 (IntrMask, 0);
 
 	/* Update the error counts. */
 	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 	RTL_W32 (RxMissed, 0);
 
-	spin_unlock_irq (&tp->lock);
+	spin_unlock_irqrestore (&tp->lock, flags);
 
 	synchronize_irq ();
 	free_irq (dev->irq, dev);
@@ -2146,10 +2165,8 @@
 	/* Green! Put the chip in low-power mode. */
 	RTL_W8 (Cfg9346, Cfg9346_Unlock);
 
-	if (rtl_chip_info[tp->chipset].flags & HasPwrDn) {
-		RTL_W8 (Config1, 0x03);
+	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
 		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
-	}
 
 	DPRINTK ("EXIT\n");
 	return 0;
@@ -2208,14 +2225,15 @@
 {
 	struct rtl8139_private *tp = dev->priv;
 	void *ioaddr = tp->mmio_addr;
+	unsigned long flags;
 
 	DPRINTK ("ENTER\n");
 
 	if (netif_running(dev)) {
-		spin_lock_irq (&tp->lock);
+		spin_lock_irqsave (&tp->lock, flags);
 		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 		RTL_W32 (RxMissed, 0);
-		spin_unlock_irq (&tp->lock);
+		spin_unlock_irqrestore (&tp->lock, flags);
 	}
 
 	DPRINTK ("EXIT\n");
@@ -2275,22 +2293,26 @@
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
 	} else {
 		struct dev_mc_list *mclist;
-		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+		rx_mode = AcceptBroadcast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0;
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-		     i++, mclist = mclist->next)
+		     i++, mclist = mclist->next) {
 			set_bit (ether_crc (ETH_ALEN, mclist->dmi_addr) >> 26,
 				 mc_filter);
+			rx_mode |= AcceptMulticast;
+		}
 	}
 
 	spin_lock_irqsave (&tp->lock, flags);
 
 	/* We can safely update without stopping the chip. */
-	tmp = rtl8139_rx_config | rx_mode |
-		(RTL_R32 (RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
-	RTL_W32_F (RxConfig, tmp);
+	tmp = rtl8139_rx_config | rx_mode;
+	if (tp->rx_config != tmp) {
+		RTL_W32 (RxConfig, tmp);
+		tp->rx_config = tmp;
+	}
 	RTL_W32_F (MAR0 + 0, mc_filter[0]);
-	RTL_W32_F (MAR0 + 4, mc_filter[1]);
+	RTL_W32 (MAR0 + 4, mc_filter[1]);
 
 	spin_unlock_irqrestore (&tp->lock, flags);
 
@@ -2313,8 +2335,8 @@
 	spin_lock_irqsave (&tp->lock, flags);
 
 	/* Disable interrupts, stop Tx and Rx. */
-	RTL_W16 (IntrMask, 0x0000);
-	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear));
+	RTL_W16 (IntrMask, 0);
+	RTL_W8 (ChipCmd, 0);
 
 	/* Update the error counts. */
 	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
@@ -2347,6 +2369,13 @@
 
 static int __init rtl8139_init_module (void)
 {
+	/* when we're a module, we always print a version message,
+	 * even if no 8139 board is found.
+	 */
+#ifdef MODULE
+	printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+#endif
+
 	return pci_module_init (&rtl8139_pci_driver);
 }
 
diff -urN linux-2.4.4-pre4/drivers/net/8390.c linux/drivers/net/8390.c
--- linux-2.4.4-pre4/drivers/net/8390.c	Sun Feb  4 10:05:30 2001
+++ linux/drivers/net/8390.c	Mon Dec  3 22:35:55 2001
@@ -45,7 +45,7 @@
 
   */
 
-static const char *version =
+static const char version[] =
     "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/8390.h linux/drivers/net/8390.h
--- linux-2.4.4-pre4/drivers/net/8390.h	Mon Mar 26 15:49:39 2001
+++ linux/drivers/net/8390.h	Mon Dec  3 22:35:55 2001
@@ -116,7 +116,8 @@
  
 #if defined(CONFIG_MAC) || defined(CONFIG_AMIGA_PCMCIA) || \
     defined(CONFIG_ARIADNE2) || defined(CONFIG_ARIADNE2_MODULE) || \
-    defined(CONFIG_HYDRA) || defined(CONFIG_HYDRA_MODULE)
+    defined(CONFIG_HYDRA) || defined(CONFIG_HYDRA_MODULE) || \
+    defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE)
 #define EI_SHIFT(x)	(ei_local->reg_offset[x])
 #else
 #define EI_SHIFT(x)	(x)
diff -urN linux-2.4.4-pre4/drivers/net/Config.in linux/drivers/net/Config.in
--- linux-2.4.4-pre4/drivers/net/Config.in	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/Config.in	Mon Dec  3 22:35:55 2001
@@ -49,6 +49,9 @@
    if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then
       tristate '  MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC
    fi
+   if [ "$CONFIG_MIPS_GT96100" = "y" ]; then
+      bool '  MIPS GT96100 Ethernet support' CONFIG_MIPS_GT96100ETH
+   fi
    if [ "$CONFIG_SGI_IP27" = "y" ]; then
       bool '  SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH
    fi
@@ -163,6 +166,9 @@
       dep_tristate '    Sun Happy Meal 10/100baseT PCI support' CONFIG_HAPPYMEAL $CONFIG_PCI
       if [ "$CONFIG_OBSOLETE" = "y" ]; then
 	 bool '    Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET
+      fi
+      if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ORION" = "y" ]; then
+	 bool '    Philips SAA9730 Ethernet support (EXPERIMENTAL)' CONFIG_LAN_SAA9730
       fi
    fi
    bool '  Pocket and portable adapters' CONFIG_NET_POCKET
diff -urN linux-2.4.4-pre4/drivers/net/Makefile linux/drivers/net/Makefile
--- linux-2.4.4-pre4/drivers/net/Makefile	Mon Mar 26 15:39:56 2001
+++ linux/drivers/net/Makefile	Mon Dec  3 22:35:55 2001
@@ -18,6 +18,8 @@
 export-objs     :=	8390.o arlan.o aironet4500_core.o aironet4500_card.o \
 			ppp_async.o ppp_generic.o slhc.o pppox.o auto_irq.o \
 			net_init.o
+list-multi	:=	rcpci.o
+rcpci-objs	:=	rcpci45.o rclanmtl.o
 
 ifeq ($(CONFIG_TULIP),y)
   obj-y += tulip/tulip.o
@@ -169,6 +171,7 @@
 obj-$(CONFIG_WAVELAN) += wavelan.o
 obj-$(CONFIG_ARLAN) += arlan.o arlan-proc.o
 obj-$(CONFIG_ZNET) += znet.o
+obj-$(CONFIG_LAN_SAA9730) += saa9730.o
 obj-$(CONFIG_DEPCA) += depca.o
 obj-$(CONFIG_EWRK3) += ewrk3.o
 obj-$(CONFIG_ATP) += atp.o
@@ -187,6 +190,7 @@
 obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
 obj-$(CONFIG_EQUALIZER) += eql.o
 obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
+obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o
 obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
 obj-$(CONFIG_BAGETLANCE) += bagetlance.o
 obj-$(CONFIG_DECLANCE) += declance.o
@@ -201,19 +205,28 @@
 obj-$(CONFIG_MACMACE) += macmace.o
 obj-$(CONFIG_MAC89x0) += mac89x0.o
 obj-$(CONFIG_TUN) += tun.o
+
+ifeq ($(CONFIG_ARCH_ACORN),y)
+mod-subdirs	+= ../acorn/net
+subdir-y	+= ../acorn/net
+obj-y		+= ../acorn/net/acorn-net.o
+endif
+
 #
 # HIPPI adapters
 #
 
 ifneq ($(ARCH),s390)
+ifneq ($(ARCH),s390x)
 obj-y += auto_irq.o
 endif
+endif
 
 include $(TOPDIR)/Rules.make
 
 clean:
 	rm -f core *.o *.a *.s
 
-rcpci.o: rcpci45.o rclanmtl.o
-	$(LD) -r -o rcpci.o rcpci45.o rclanmtl.o
+rcpci.o: $(rcpci-objs)
+	$(LD) -r -o $@ $(rcpci-objs)
 
diff -urN linux-2.4.4-pre4/drivers/net/Space.c linux/drivers/net/Space.c
--- linux-2.4.4-pre4/drivers/net/Space.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/Space.c	Mon Dec  3 22:35:55 2001
@@ -544,7 +544,6 @@
 #ifdef CONFIG_TR
 /* Token-ring device probe */
 extern int ibmtr_probe(struct net_device *);
-extern int olympic_probe(struct net_device *);
 extern int smctr_probe(struct net_device *);
 
 static int
@@ -553,9 +552,6 @@
     if (1
 #ifdef CONFIG_IBMTR
 	&& ibmtr_probe(dev)
-#endif
-#ifdef CONFIG_IBMOL
-	&& olympic_probe(dev)
 #endif
 #ifdef CONFIG_SMCTR
 	&& smctr_probe(dev)
diff -urN linux-2.4.4-pre4/drivers/net/ac3200.c linux/drivers/net/ac3200.c
--- linux-2.4.4-pre4/drivers/net/ac3200.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/ac3200.c	Mon Dec  3 22:35:55 2001
@@ -19,7 +19,7 @@
 
   */
 
-static const char *version =
+static const char version[] =
 	"ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/aironet4500_card.c linux/drivers/net/aironet4500_card.c
--- linux-2.4.4-pre4/drivers/net/aironet4500_card.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/aironet4500_card.c	Mon Dec  3 22:35:55 2001
@@ -128,17 +128,12 @@
 //		request_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
 //		request_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");
 
-//		pci_write_config_word(pdev, PCI_COMMAND, 0);
-		udelay(10000);
+		mdelay(10);
 
 		pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-		new_command = pci_command |0x100 | PCI_COMMAND_MEMORY|PCI_COMMAND_IO;
-		if (pci_command != new_command) {
-			printk(KERN_INFO "  The PCI BIOS has not enabled this"
-				   " device!  Updating PCI command %4.4x->%4.4x.\n",
-				   pci_command, new_command);
+		new_command = pci_command | PCI_COMMAND_SERR;
+		if (pci_command != new_command)
 			pci_write_config_word(pdev, PCI_COMMAND, new_command);
-		}
 
 
 /*		if (device == PCI_DEVICE_AIRONET_4800)
diff -urN linux-2.4.4-pre4/drivers/net/apne.c linux/drivers/net/apne.c
--- linux-2.4.4-pre4/drivers/net/apne.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/apne.c	Mon Dec  3 22:35:55 2001
@@ -116,7 +116,7 @@
 #define WORDSWAP(a) ( (((a)>>8)&0xff) | ((a)<<8) )
 
 
-static const char *version =
+static const char version[] =
     "apne.c:v1.1 7/10/98 Alain Malek (Alain.Malek@cryogen.ch)\n";
 
 static int apne_owned;	/* signal if card already owned */
diff -urN linux-2.4.4-pre4/drivers/net/appletalk/cops.c linux/drivers/net/appletalk/cops.c
--- linux-2.4.4-pre4/drivers/net/appletalk/cops.c	Tue Mar 20 12:05:00 2001
+++ linux/drivers/net/appletalk/cops.c	Mon Dec  3 22:35:55 2001
@@ -98,7 +98,7 @@
 static int io = 0x240;		/* Default IO for Dayna */
 static int irq = 5;		/* Default IRQ */
 #else
-static int io = 0;		/* Default IO for Dayna */
+static int io;			/* Default IO for Dayna */
 #endif
 
 /*
diff -urN linux-2.4.4-pre4/drivers/net/appletalk/ltpc.c linux/drivers/net/appletalk/ltpc.c
--- linux-2.4.4-pre4/drivers/net/appletalk/ltpc.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/appletalk/ltpc.c	Mon Dec  3 22:35:55 2001
@@ -197,14 +197,14 @@
 */
 
 /* insmod-tweakable variables */
-static int debug=0;
+static int debug;
 #define DEBUG_VERBOSE 1
 #define DEBUG_UPPER 2
 #define DEBUG_LOWER 4
 
-static int io=0;
-static int irq=0;
-static int dma=0;
+static int io;
+static int irq;
+static int dma;
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -281,7 +281,7 @@
 
 /* the transmit queue itself */
 
-static struct xmitQel *xmQhd=NULL,*xmQtl=NULL;
+static struct xmitQel *xmQhd, *xmQtl;
 
 static void enQ(struct xmitQel *qel)
 {
@@ -489,7 +489,7 @@
 static unsigned char rescbuf[2] = {LT_GETRESULT,0};
 static unsigned char resdbuf[2];
 
-static int QInIdle=0;
+static int QInIdle;
 
 /* idle expects to be called with the IRQ line high -- either because of
  * an interrupt, or because the line is tri-stated
@@ -910,7 +910,7 @@
 	return 0;
 }
 
-static int ltpc_poll_counter = 0;
+static int ltpc_poll_counter;
 
 static void ltpc_poll(unsigned long l)
 {
diff -urN linux-2.4.4-pre4/drivers/net/arcnet/arcnet.c linux/drivers/net/arcnet/arcnet.c
--- linux-2.4.4-pre4/drivers/net/arcnet/arcnet.c	Sat Mar  3 10:55:48 2001
+++ linux/drivers/net/arcnet/arcnet.c	Mon Dec  3 22:35:55 2001
@@ -107,7 +107,7 @@
 
 void __init arcnet_init(void)
 {
-	static int arcnet_inited = 0;
+	static int arcnet_inited;
 	int count;
 
 	if (arcnet_inited++)
@@ -361,8 +361,6 @@
 	dev->get_stats = arcnet_get_stats;
 	dev->hard_header = arcnet_header;
 	dev->rebuild_header = arcnet_rebuild_header;
-
-	dev_init_buffers(dev);
 }
 
 
@@ -528,7 +526,7 @@
 	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
 	int status = 0;		/* default is failure */
 	unsigned short type;
-	uint8_t daddr;
+	uint8_t daddr=0;
 
 	if (skb->nh.raw - skb->mac.raw != 2) {
 		BUGMSG(D_NORMAL,
diff -urN linux-2.4.4-pre4/drivers/net/arcnet/com20020-pci.c linux/drivers/net/arcnet/com20020-pci.c
--- linux-2.4.4-pre4/drivers/net/arcnet/com20020-pci.c	Tue Mar  6 19:28:35 2001
+++ linux/drivers/net/arcnet/com20020-pci.c	Mon Dec  3 22:35:55 2001
@@ -44,12 +44,12 @@
 
 /* Module parameters */
 
-static int node = 0;
+static int node;
 static char *device;		/* use eg. device="arc1" to change name */
 static int timeout = 3;
-static int backplane = 0;
-static int clockp = 0;
-static int clockm = 0;
+static int backplane;
+static int clockp;
+static int clockm;
 
 MODULE_PARM(node, "i");
 MODULE_PARM(device, "s");
diff -urN linux-2.4.4-pre4/drivers/net/arcnet/com90io.c linux/drivers/net/arcnet/com90io.c
--- linux-2.4.4-pre4/drivers/net/arcnet/com90io.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/arcnet/com90io.c	Mon Dec  3 22:35:55 2001
@@ -373,8 +373,8 @@
 
 /* Module parameters */
 
-static int io = 0x0;		/* use the insmod io= irq= shmem= options */
-static int irq = 0;
+static int io;			/* use the insmod io= irq= shmem= options */
+static int irq;
 static char *device;		/* use eg. device=arc1 to change name */
 
 MODULE_PARM(io, "i");
diff -urN linux-2.4.4-pre4/drivers/net/arcnet/com90xx.c linux/drivers/net/arcnet/com90xx.c
--- linux-2.4.4-pre4/drivers/net/arcnet/com90xx.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/arcnet/com90xx.c	Mon Dec  3 22:35:55 2001
@@ -610,9 +610,9 @@
 
 /* Module parameters */
 
-static int io = 0x0;		/* use the insmod io= irq= shmem= options */
-static int irq = 0;
-static int shmem = 0;
+static int io;			/* use the insmod io= irq= shmem= options */
+static int irq;
+static int shmem;
 static char *device;		/* use eg. device=arc1 to change name */
 
 MODULE_PARM(io, "i");
diff -urN linux-2.4.4-pre4/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c
--- linux-2.4.4-pre4/drivers/net/atari_bionet.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/atari_bionet.c	Mon Dec  3 22:35:55 2001
@@ -79,7 +79,7 @@
 
 #define MAX_POLL_TIME	10
 
-static char *version =
+static char version[] =
 	"bionet.c:v1.0 06-feb-96 (c) Hartmut Laue.\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/atarilance.c linux/drivers/net/atarilance.c
--- linux-2.4.4-pre4/drivers/net/atarilance.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/atarilance.c	Mon Dec  3 22:35:55 2001
@@ -42,7 +42,7 @@
 
 */
 
-static char *version = "atarilance.c: v1.3 04/04/96 "
+static char version[] = "atarilance.c: v1.3 04/04/96 "
 					   "Roman.Hodek@informatik.uni-erlangen.de\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/de600.c linux/drivers/net/de600.c
--- linux-2.4.4-pre4/drivers/net/de600.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/de600.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-static const char *version =
+static const char version[] =
 	"de600.c: $Revision: 1.40 $,  Bjorn Ekwall (bj0rn@blox.se)\n";
 /*
  *	de600.c
diff -urN linux-2.4.4-pre4/drivers/net/de620.c linux/drivers/net/de620.c
--- linux-2.4.4-pre4/drivers/net/de620.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/de620.c	Mon Dec  3 22:35:55 2001
@@ -38,7 +38,7 @@
  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *****************************************************************************/
-static const char *version =
+static const char version[] =
 	"de620.c: $Revision: 1.40 $,  Bjorn Ekwall <bj0rn@blox.se>\n";
 
 /***********************************************************************
diff -urN linux-2.4.4-pre4/drivers/net/e2100.c linux/drivers/net/e2100.c
--- linux-2.4.4-pre4/drivers/net/e2100.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/e2100.c	Mon Dec  3 22:35:55 2001
@@ -31,7 +31,7 @@
 	If this happens, you must power down the machine for about 30 seconds.
 */
 
-static const char *version =
+static const char version[] =
 	"e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/eepro.c linux/drivers/net/eepro.c
--- linux-2.4.4-pre4/drivers/net/eepro.c	Tue Mar  6 19:28:35 2001
+++ linux/drivers/net/eepro.c	Mon Dec  3 22:35:55 2001
@@ -96,7 +96,7 @@
 
 */
 
-static const char *version =
+static const char version[] =
 	"eepro.c: v0.12c 01/08/2000 aris@conectiva.com.br\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/eql.c linux/drivers/net/eql.c
--- linux-2.4.4-pre4/drivers/net/eql.c	Tue Mar 20 12:05:01 2001
+++ linux/drivers/net/eql.c	Mon Dec  3 22:35:55 2001
@@ -240,8 +240,6 @@
 	 *	eql-generic values. 
 	 */
 
-	dev_init_buffers(dev);
-	
 	/*
 	 *	Now we undo some of the things that eth_setup does
 	 * 	that we don't like 
diff -urN linux-2.4.4-pre4/drivers/net/es3210.c linux/drivers/net/es3210.c
--- linux-2.4.4-pre4/drivers/net/es3210.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/es3210.c	Mon Dec  3 22:35:55 2001
@@ -45,7 +45,7 @@
 
 */
 
-static const char *version =
+static const char version[] =
 	"es3210.c: Driver revision v0.03, 14/09/96\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/eth16i.c linux/drivers/net/eth16i.c
--- linux-2.4.4-pre4/drivers/net/eth16i.c	Sat Mar  3 10:55:48 2001
+++ linux/drivers/net/eth16i.c	Mon Dec  3 22:35:55 2001
@@ -434,7 +434,7 @@
 
 static struct net_device_stats *eth16i_get_stats(struct net_device *dev);
 
-static char *cardname = "ICL EtherTeam 16i/32";
+static char cardname[] = "ICL EtherTeam 16i/32";
 
 int __init eth16i_probe(struct net_device *dev)
 {
diff -urN linux-2.4.4-pre4/drivers/net/fc/iph5526.c linux/drivers/net/fc/iph5526.c
--- linux-2.4.4-pre4/drivers/net/fc/iph5526.c	Tue Mar 20 12:05:00 2001
+++ linux/drivers/net/fc/iph5526.c	Mon Dec  3 22:35:55 2001
@@ -241,7 +241,7 @@
 	struct fc_info *fi = (struct fc_info *)dev->priv;
 #else
 	struct fc_info *fi;
-	static int count = 0;
+	static int count;
  
 	if(fc[count] != NULL) {
 		if (dev == NULL) {
@@ -4523,9 +4523,9 @@
 
 static struct net_device *dev_fc[MAX_FC_CARDS];
 
-static int io =  0;
-static int irq  = 0;
-static int bad  = 0;	/* 0xbad = bad sig or no reset ack */
+static int io;
+static int irq;
+static int bad;	/* 0xbad = bad sig or no reset ack */
 static int scsi_registered;
 
 
diff -urN linux-2.4.4-pre4/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c
--- linux-2.4.4-pre4/drivers/net/fmv18x.c	Sat Mar  3 10:55:48 2001
+++ linux/drivers/net/fmv18x.c	Mon Dec  3 22:35:55 2001
@@ -31,7 +31,7 @@
     The Fujitsu FMV-181/182 user's guide
 */
 
-static const char *version =
+static const char version[] =
 	"fmv18x.c:v2.2.0 09/24/98  Yutaka TAMIYA (tamy@flab.fujitsu.co.jp)\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/6pack.c linux/drivers/net/hamradio/6pack.c
--- linux-2.4.4-pre4/drivers/net/hamradio/6pack.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/hamradio/6pack.c	Mon Dec  3 22:35:55 2001
@@ -794,8 +794,6 @@
 	memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);	/* Only activated in AX.25 mode */
 	memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);	/*    ""      ""       ""    "" */
 
-	dev_init_buffers(dev);
-
 	/* New-style flags. */
 	dev->flags		= 0;
 
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/baycom_epp.c linux/drivers/net/hamradio/baycom_epp.c
--- linux-2.4.4-pre4/drivers/net/hamradio/baycom_epp.c	Mon Dec 11 13:23:31 2000
+++ linux/drivers/net/hamradio/baycom_epp.c	Mon Dec  3 22:35:55 2001
@@ -1379,8 +1379,6 @@
 	dev->get_stats = baycom_get_stats;
 
 	/* Fill in the fields of the device structure */
-	dev_init_buffers(dev);
-
 	bc->skb = NULL;
 	
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/baycom_par.c linux/drivers/net/hamradio/baycom_par.c
--- linux-2.4.4-pre4/drivers/net/hamradio/baycom_par.c	Wed Jul  5 12:59:11 2000
+++ linux/drivers/net/hamradio/baycom_par.c	Mon Dec  3 22:35:55 2001
@@ -569,7 +569,7 @@
 
 static int __init baycom_par_setup(char *str)
 {
-        static unsigned nr_dev = 0;
+        static unsigned nr_dev;
 	int ints[2];
 
         if (nr_dev >= NR_PORTS)
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/baycom_ser_fdx.c linux/drivers/net/hamradio/baycom_ser_fdx.c
--- linux-2.4.4-pre4/drivers/net/hamradio/baycom_ser_fdx.c	Wed Jul  5 12:59:11 2000
+++ linux/drivers/net/hamradio/baycom_ser_fdx.c	Mon Dec  3 22:35:55 2001
@@ -689,7 +689,7 @@
 
 static int __init baycom_ser_fdx_setup(char *str)
 {
-        static unsigned nr_dev = 0;
+        static unsigned nr_dev;
         int ints[4];
 
         if (nr_dev >= NR_PORTS)
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/baycom_ser_hdx.c linux/drivers/net/hamradio/baycom_ser_hdx.c
--- linux-2.4.4-pre4/drivers/net/hamradio/baycom_ser_hdx.c	Wed Jul  5 12:59:11 2000
+++ linux/drivers/net/hamradio/baycom_ser_hdx.c	Mon Dec  3 22:35:55 2001
@@ -729,7 +729,7 @@
 
 static int __init baycom_ser_hdx_setup(char *str)
 {
-        static unsigned nr_dev = 0;
+        static unsigned nr_dev;
 	int ints[3];
 
         if (nr_dev >= NR_PORTS)
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/bpqether.c linux/drivers/net/hamradio/bpqether.c
--- linux-2.4.4-pre4/drivers/net/hamradio/bpqether.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/net/hamradio/bpqether.c	Mon Dec  3 22:35:55 2001
@@ -530,8 +530,6 @@
                 return -EIO;
         }
 
-	dev_init_buffers(dev);
-
 	dev->hard_start_xmit = bpq_xmit;
 	dev->open	     = bpq_open;
 	dev->stop	     = bpq_close;
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/dmascc.c linux/drivers/net/hamradio/dmascc.c
--- linux-2.4.4-pre4/drivers/net/hamradio/dmascc.c	Tue Jul 18 16:52:35 2000
+++ linux/drivers/net/hamradio/dmascc.c	Mon Dec  3 22:35:55 2001
@@ -294,7 +294,7 @@
 
 /* Global variables */
 
-static struct scc_info *first = NULL;
+static struct scc_info *first;
 static unsigned long rand;
 
 
@@ -593,7 +593,6 @@
     dev->tx_queue_len = 64;
     memcpy(dev->broadcast, ax25_broadcast, 7);
     memcpy(dev->dev_addr, ax25_test, 7);
-    dev_init_buffers(dev);
     rtnl_lock();
     if (register_netdevice(dev)) {
       printk("dmascc: could not register %s\n", dev->name);
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/hdlcdrv.c linux/drivers/net/hamradio/hdlcdrv.c
--- linux-2.4.4-pre4/drivers/net/hamradio/hdlcdrv.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/hamradio/hdlcdrv.c	Mon Dec  3 22:35:55 2001
@@ -791,7 +791,6 @@
 	dev->get_stats = hdlcdrv_get_stats;
 
 	/* Fill in the fields of the device structure */
-	dev_init_buffers(dev);
 
 	s->skb = NULL;
 	
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/mkiss.c linux/drivers/net/hamradio/mkiss.c
--- linux-2.4.4-pre4/drivers/net/hamradio/mkiss.c	Mon Jan 22 13:32:10 2001
+++ linux/drivers/net/hamradio/mkiss.c	Mon Dec  3 22:35:55 2001
@@ -935,8 +935,6 @@
 	memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
 	memcpy(dev->dev_addr,  ax25_test,  AX25_ADDR_LEN);
 
-	dev_init_buffers(dev);
-
 	/* New-style flags. */
 	dev->flags      = 0;
 
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/scc.c linux/drivers/net/hamradio/scc.c
--- linux-2.4.4-pre4/drivers/net/hamradio/scc.c	Tue Mar 20 12:05:00 2001
+++ linux/drivers/net/hamradio/scc.c	Mon Dec  3 22:35:55 2001
@@ -214,7 +214,7 @@
 static int scc_net_set_mac_address(struct net_device *dev, void *addr);
 static struct net_device_stats * scc_net_get_stats(struct net_device *dev);
 
-static unsigned char *SCC_DriverName = "scc";
+static unsigned char SCC_DriverName[] = "scc";
 
 static struct irqflags { unsigned char used : 1; } Ivec[16];
 	
@@ -1574,8 +1574,6 @@
 
 static int scc_net_init(struct net_device *dev)
 {
-	dev_init_buffers(dev);
-	
 	dev->tx_queue_len    = 16;	/* should be enough... */
 
 	dev->open            = scc_net_open;
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/soundmodem/sm.c linux/drivers/net/hamradio/soundmodem/sm.c
--- linux-2.4.4-pre4/drivers/net/hamradio/soundmodem/sm.c	Wed Jul  5 12:59:11 2000
+++ linux/drivers/net/hamradio/soundmodem/sm.c	Mon Dec  3 22:35:55 2001
@@ -728,7 +728,7 @@
 
 static int __init sm_setup(char *str)
 {
-	static unsigned nr_dev = 0;
+	static unsigned nr_dev;
 	int ints[8];
 
 	if (nr_dev >= NR_PORTS)
diff -urN linux-2.4.4-pre4/drivers/net/hamradio/yam.c linux/drivers/net/hamradio/yam.c
--- linux-2.4.4-pre4/drivers/net/hamradio/yam.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/hamradio/yam.c	Mon Dec  3 22:35:55 2001
@@ -1071,7 +1071,6 @@
 	dev->hard_start_xmit = yam_send_packet;
 	dev->get_stats = yam_get_stats;
 
-	dev_init_buffers(dev);
 	skb_queue_head_init(&yp->send_queue);
 
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
diff -urN linux-2.4.4-pre4/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
--- linux-2.4.4-pre4/drivers/net/hp-plus.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/hp-plus.c	Mon Dec  3 22:35:55 2001
@@ -18,7 +18,7 @@
 	programming information.
 */
 
-static const char *version =
+static const char version[] =
 "hp-plus.c:v1.10 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/module.h>
@@ -141,7 +141,7 @@
 {
 	int i, retval;
 	unsigned char checksum = 0;
-	const char *name = "HP-PC-LAN+";
+	const char name[] = "HP-PC-LAN+";
 	int mem_start;
 	static unsigned version_printed;
 
diff -urN linux-2.4.4-pre4/drivers/net/hp.c linux/drivers/net/hp.c
--- linux-2.4.4-pre4/drivers/net/hp.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/hp.c	Mon Dec  3 22:35:55 2001
@@ -18,7 +18,7 @@
 	  The Crynwr packet driver.
 */
 
-static const char *version =
+static const char version[] =
 	"hp.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 
diff -urN linux-2.4.4-pre4/drivers/net/lance.c linux/drivers/net/lance.c
--- linux-2.4.4-pre4/drivers/net/lance.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/lance.c	Mon Dec  3 22:35:55 2001
@@ -38,7 +38,7 @@
     Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 11/01/2001
 */
 
-static const char *version = "lance.c:v1.15ac 1999/11/13 dplatt@3do.com, becker@cesdis.gsfc.nasa.gov\n";
+static const char version[] = "lance.c:v1.15ac 1999/11/13 dplatt@3do.com, becker@cesdis.gsfc.nasa.gov\n";
 
 #include <linux/module.h>
 #include <linux/kernel.h>
diff -urN linux-2.4.4-pre4/drivers/net/loopback.c linux/drivers/net/loopback.c
--- linux-2.4.4-pre4/drivers/net/loopback.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/loopback.c	Mon Dec  3 22:35:55 2001
@@ -127,7 +127,5 @@
 	 *	Fill in the generic fields of the device structure. 
 	 */
    
-	dev_init_buffers(dev);
-  
 	return(0);
 };
diff -urN linux-2.4.4-pre4/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c
--- linux-2.4.4-pre4/drivers/net/myri_sbus.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/myri_sbus.c	Mon Dec  3 22:35:55 2001
@@ -3,7 +3,7 @@
  * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com)
  */
 
-static char *version =
+static char version[] =
         "myri_sbus.c:v1.9 12/Sep/99 David S. Miller (davem@redhat.com)\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/net_init.c linux/drivers/net/net_init.c
--- linux-2.4.4-pre4/drivers/net/net_init.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/net_init.c	Mon Dec  3 22:35:55 2001
@@ -174,8 +174,6 @@
 #if defined(CONFIG_HIPPI) || defined(CONFIG_TR) || defined(CONFIG_NET_FC)
 static int __register_netdev(struct net_device *dev)
 {
-	dev_init_buffers(dev);
-	
 	if (dev->init && dev->init(dev) != 0) {
 		unregister_netdev(dev);
 		return -EIO;
@@ -418,8 +416,6 @@
 
 	/* New-style flags. */
 	dev->flags		= IFF_BROADCAST|IFF_MULTICAST;
-
-	dev_init_buffers(dev);
 }
 EXPORT_SYMBOL(ether_setup);
 
@@ -446,10 +442,6 @@
 
 	/* New-style flags */
 	dev->flags		= IFF_BROADCAST | IFF_MULTICAST;
-
-	dev_init_buffers(dev);
-	
-	return;
 }
 EXPORT_SYMBOL(fddi_setup);
 
@@ -486,8 +478,6 @@
 	 * static ARP tables. ARP is disabled by hippi_neigh_setup_dev. 
 	 */
 	dev->flags = 0; 
-
-	dev_init_buffers(dev);
 }
 EXPORT_SYMBOL(hippi_setup);
 #endif /* CONFIG_HIPPI */
@@ -525,8 +515,6 @@
 	dev->broadcast[0]	= 0xFF;
 
 	dev->flags		= IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
-
-	dev_init_buffers(dev);
 }
 EXPORT_SYMBOL(ltalk_setup);
 
@@ -676,7 +664,6 @@
 
         /* New-style flags. */
         dev->flags              =        IFF_BROADCAST;
-	dev_init_buffers(dev);
 }
 
 /**
diff -urN linux-2.4.4-pre4/drivers/net/ni65.c linux/drivers/net/ni65.c
--- linux-2.4.4-pre4/drivers/net/ni65.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/ni65.c	Mon Dec  3 22:35:55 2001
@@ -1174,16 +1174,12 @@
 }
 
 #ifdef MODULE
-static struct net_device dev_ni65 = {
-	"",	/* "ni6510": device name inserted by net_init.c */
-	0, 0, 0, 0,
-	0x360, 9,	 /* I/O address, IRQ */
-	0, 0, 0, NULL, ni65_probe };
+static struct net_device dev_ni65 = { base_addr: 0x360, irq: 9, init: ni65_probe };
 
 /* set: io,irq,dma or set it when calling insmod */
-static int irq=0;
-static int io=0;
-static int dma=0;
+static int irq;
+static int io;
+static int dma;
 
 MODULE_PARM(irq, "i");
 MODULE_PARM(io, "i");
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/3c574_cs.c linux/drivers/net/pcmcia/3c574_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/3c574_cs.c	Fri Mar  2 11:02:15 2001
+++ linux/drivers/net/pcmcia/3c574_cs.c	Mon Dec  3 22:35:55 2001
@@ -210,7 +210,7 @@
 /* Set iff a MII transceiver on any interface requires mdio preamble.
    This only set with the original DP83840 on older 3c905 boards, so the extra
    code size of a per-interface flag is not worthwhile. */
-static char mii_preamble_required = 0;
+static char mii_preamble_required;
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
@@ -253,7 +253,7 @@
 static dev_link_t *tc574_attach(void);
 static void tc574_detach(dev_link_t *);
 
-static dev_link_t *dev_list = NULL;
+static dev_link_t *dev_list;
 
 static void flush_stale_links(void)
 {
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/3c589_cs.c linux/drivers/net/pcmcia/3c589_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/3c589_cs.c	Fri Mar  2 11:02:15 2001
+++ linux/drivers/net/pcmcia/3c589_cs.c	Mon Dec  3 22:35:55 2001
@@ -127,7 +127,7 @@
 /* Parameters that can be set with 'insmod' */
 
 /* Special hook for setting if_port when module is loaded */
-static int if_port = 0;
+static int if_port;
 
 /* Bit map of interrupts to choose from */
 static u_int irq_mask = 0xdeb8;
@@ -163,7 +163,7 @@
 static dev_link_t *tc589_attach(void);
 static void tc589_detach(dev_link_t *);
 
-static dev_link_t *dev_list = NULL;
+static dev_link_t *dev_list;
 
 /*======================================================================
 
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/aironet4500_cs.c linux/drivers/net/pcmcia/aironet4500_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/aironet4500_cs.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/pcmcia/aironet4500_cs.c	Mon Dec  3 22:35:55 2001
@@ -81,7 +81,7 @@
 static int awc_event(event_t event, int priority,
 					   event_callback_args_t *args);
 
-static dev_link_t *dev_list = NULL;
+static dev_link_t *dev_list;
 
 static void cs_error(client_handle_t handle, int func, int ret)
 {
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/com20020_cs.c linux/drivers/net/pcmcia/com20020_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/com20020_cs.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/pcmcia/com20020_cs.c	Mon Dec  3 22:35:55 2001
@@ -104,11 +104,11 @@
 
 /* Parameters that can be set with 'insmod' */
 
-static int node = 0;
+static int node;
 static int timeout = 3;
-static int backplane = 0;
-static int clockp = 0;
-static int clockm = 0;
+static int backplane;
+static int clockp;
+static int clockm;
 
 MODULE_PARM(node, "i");
 MODULE_PARM(timeout, "i");
@@ -135,7 +135,7 @@
 static dev_link_t *com20020_attach(void);
 static void com20020_detach(dev_link_t *);
 
-static dev_link_t *dev_list = NULL;
+static dev_link_t *dev_list;
 
 /*====================================================================*/
 
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/fmvj18x_cs.c linux/drivers/net/pcmcia/fmvj18x_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/fmvj18x_cs.c	Fri Mar  2 11:02:15 2001
+++ linux/drivers/net/pcmcia/fmvj18x_cs.c	Mon Dec  3 22:35:55 2001
@@ -76,7 +76,7 @@
 
 /* SRAM configuration */
 /* 0:4KB*2 TX buffer   else:8KB*2 TX buffer */
-static int sram_config = 0;
+static int sram_config;
 
 MODULE_PARM(irq_mask, "i");
 MODULE_PARM(irq_list, "1-4i");
@@ -117,7 +117,7 @@
 static void fjn_tx_timeout(struct net_device *dev);
 
 static dev_info_t dev_info = "fmvj18x_cs";
-static dev_link_t *dev_list = NULL;
+static dev_link_t *dev_list;
 
 /*
     card type
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/ibmtr_cs.c linux/drivers/net/pcmcia/ibmtr_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/ibmtr_cs.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/pcmcia/ibmtr_cs.c	Mon Dec  3 22:35:55 2001
@@ -93,10 +93,10 @@
 static int irq_list[4] = { -1 };
 
 /* MMIO base address */
-static u_long mmiobase = 0;
+static u_long mmiobase;
 
 /* SRAM base address */
-static u_long srambase = 0;
+static u_long srambase;
 
 /* SRAM size 8,16,32,64 */
 static u_long sramsize = 16;
@@ -124,7 +124,7 @@
 static dev_link_t *ibmtr_attach(void);
 static void ibmtr_detach(dev_link_t *);
 
-static dev_link_t *dev_list = NULL;
+static dev_link_t *dev_list;
 
 extern int ibmtr_probe(struct net_device *dev);
 unsigned char pcmcia_reality_check(unsigned char gss);
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/netwave_cs.c linux/drivers/net/pcmcia/netwave_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/netwave_cs.c	Fri Mar  2 11:02:15 2001
+++ linux/drivers/net/pcmcia/netwave_cs.c	Mon Dec  3 22:35:55 2001
@@ -187,7 +187,7 @@
  * This timing should be provided by the HBA. If it becomes a 
  * problem, try setting mem_speed to 400. 
  */
-static int mem_speed = 0;
+static int mem_speed;
 
 /* Bit map of interrupts to choose from */
 /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
@@ -250,7 +250,7 @@
    memory card driver uses an array of dev_link_t pointers, where minor
    device numbers are used to derive the corresponding array index.
 */
-static dev_link_t *dev_list = NULL;
+static dev_link_t *dev_list;
 
 /*
    A dev_link_t structure has fields for most things that are needed
@@ -1554,7 +1554,7 @@
    
 #ifdef PCMCIA_DEBUG
     if (pc_debug > 2) {
-	static int old = 0;
+	static int old;
 	if (old != dev->mc_count) {
 	    old = dev->mc_count;
 	    DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/nmclan_cs.c linux/drivers/net/pcmcia/nmclan_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/nmclan_cs.c	Fri Mar  2 11:02:15 2001
+++ linux/drivers/net/pcmcia/nmclan_cs.c	Mon Dec  3 22:35:55 2001
@@ -379,7 +379,7 @@
 #endif
 
 static dev_info_t dev_info="nmclan_cs";
-static dev_link_t *dev_list=NULL;
+static dev_link_t *dev_list;
 
 static char *if_names[]={
     "Auto", "10baseT", "BNC",
@@ -400,7 +400,7 @@
 ---------------------------------------------------------------------------- */
 
 /* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
-static int if_port=0;
+static int if_port;
 
 /* Bit map of interrupts to choose from */
 static u_int irq_mask = 0xdeb8;
@@ -1605,7 +1605,7 @@
 
 #ifdef PCMCIA_DEBUG
   if (pc_debug > 1) {
-    static int old = 0;
+    static int old;
     if (dev->mc_count != old) {
       old = dev->mc_count;
       DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
@@ -1660,7 +1660,7 @@
 
 #ifdef PCMCIA_DEBUG
   if (pc_debug > 1) {
-    static int old = 0;
+    static int old;
     if (dev->mc_count != old) {
       old = dev->mc_count;
       DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/ray_cs.c linux/drivers/net/pcmcia/ray_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/ray_cs.c	Fri Mar  2 11:02:15 2001
+++ linux/drivers/net/pcmcia/ray_cs.c	Mon Dec  3 22:35:55 2001
@@ -82,7 +82,7 @@
 #define PCMCIA_DEBUG RAYLINK_DEBUG
 #endif
 #ifdef PCMCIA_DEBUG
-static int ray_debug = 0;
+static int ray_debug;
 static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 /* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */
@@ -172,19 +172,19 @@
 static int beacon_period = 256;
 
 /* power save mode (0 = off, 1 = save power) */
-static int psm = 0;
+static int psm;
 
 /* String for network's Extended Service Set ID. 32 Characters max */
-static char *essid = NULL;
+static char *essid;
 
 /* Default to encapsulation unless translation requested */
 static int translate = 1;
 
 static int country = USA;
 
-static int sniffer = 0;
+static int sniffer;
 
-static int bc = 0;
+static int bc;
 
 /* 48 bit physical card address if overriding card's real physical
  * address is required.  Since IEEE 802.11 addresses are 48 bits
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/smc91c92_cs.c linux/drivers/net/pcmcia/smc91c92_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/smc91c92_cs.c	Fri Mar  2 11:02:15 2001
+++ linux/drivers/net/pcmcia/smc91c92_cs.c	Mon Dec  3 22:35:55 2001
@@ -76,7 +76,7 @@
    1 = 10baseT (and autoselect if #define AUTOSELECT),
    2 = AUI/10base2,
 */
-static int if_port = 0;
+static int if_port;
 
 /* Bit map of interrupts to choose from. */
 static u_int irq_mask = 0xdeb8;
@@ -100,7 +100,7 @@
 
 static dev_info_t dev_info = "smc91c92_cs";
 
-static dev_link_t *dev_list = NULL;
+static dev_link_t *dev_list;
 
 struct smc_private {
     dev_link_t			link;
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/wavelan_cs.h linux/drivers/net/pcmcia/wavelan_cs.h
--- linux-2.4.4-pre4/drivers/net/pcmcia/wavelan_cs.h	Fri Mar  2 11:02:15 2001
+++ linux/drivers/net/pcmcia/wavelan_cs.h	Mon Dec  3 22:35:55 2001
@@ -737,11 +737,11 @@
 /**************************** VARIABLES ****************************/
 
 static dev_info_t dev_info = "wavelan_cs";
-static dev_link_t *dev_list = NULL;	/* Linked list of devices */
+static dev_link_t *dev_list;		/* Linked list of devices */
 
 /* WARNING : the following variable MUST be volatile
  * It is used by wv_82593_cmd to syncronise with wavelan_interrupt */ 
-static volatile int	wv_wait_completed = 0;
+static volatile int	wv_wait_completed;
 
 /*
  * Parameters that can be set with 'insmod'
@@ -754,7 +754,7 @@
 static int 	irq_list[4] = { -1 };
 
 /* Shared memory speed, in ns */
-static int	mem_speed = 0;
+static int	mem_speed;
 
 /* New module interface */
 MODULE_PARM(irq_mask, "i");
@@ -763,7 +763,7 @@
 
 #ifdef WAVELAN_ROAMING		/* Conditional compile, see above in options */
 /* Enable roaming mode ? No ! Please keep this to 0 */
-static int	do_roaming = 0;
+static int	do_roaming;
 MODULE_PARM(do_roaming, "i");
 #endif	/* WAVELAN_ROAMING */
 
diff -urN linux-2.4.4-pre4/drivers/net/pcmcia/xirc2ps_cs.c linux/drivers/net/pcmcia/xirc2ps_cs.c
--- linux-2.4.4-pre4/drivers/net/pcmcia/xirc2ps_cs.c	Fri Mar  2 11:02:15 2001
+++ linux/drivers/net/pcmcia/xirc2ps_cs.c	Mon Dec  3 22:35:55 2001
@@ -328,7 +328,7 @@
  * device numbers are used to derive the corresponding array index.
  */
 
-static dev_link_t *dev_list = NULL;
+static dev_link_t *dev_list;
 
 /****************
  * A dev_link_t structure has fields for most things that are needed
diff -urN linux-2.4.4-pre4/drivers/net/plip.c linux/drivers/net/plip.c
--- linux-2.4.4-pre4/drivers/net/plip.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/plip.c	Mon Dec  3 22:35:55 2001
@@ -54,7 +54,7 @@
  *     To use with DOS box, please do (Turn on ARP switch):
  *	# ifconfig plip[0-2] arp
  */
-static const char *version = "NET3 PLIP version 2.4-parport gniibe@mri.co.jp\n";
+static const char version[] = "NET3 PLIP version 2.4-parport gniibe@mri.co.jp\n";
 
 /*
   Sources:
diff -urN linux-2.4.4-pre4/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c
--- linux-2.4.4-pre4/drivers/net/ppp_generic.c	Sun Feb  4 10:05:30 2001
+++ linux/drivers/net/ppp_generic.c	Mon Dec  3 22:35:55 2001
@@ -848,8 +848,6 @@
 	dev->tx_queue_len = 3;
 	dev->type = ARPHRD_PPP;
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-
-	dev_init_buffers(dev);
 	return 0;
 }
 
diff -urN linux-2.4.4-pre4/drivers/net/ptifddi.c linux/drivers/net/ptifddi.c
--- linux-2.4.4-pre4/drivers/net/ptifddi.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/ptifddi.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: ptifddi.c,v 1.13 2000/07/11 22:35:22 davem Exp $
+/* $Id: ptifddi.c,v 1.14 2001/04/14 01:12:04 davem Exp $
  * ptifddi.c: Network driver for Performance Technologies single-attach
  *            and dual-attach FDDI sbus cards.
  *
diff -urN linux-2.4.4-pre4/drivers/net/rrunner.c linux/drivers/net/rrunner.c
--- linux-2.4.4-pre4/drivers/net/rrunner.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/rrunner.c	Mon Dec  3 22:35:55 2001
@@ -104,7 +104,7 @@
 
 static char version[] __initdata = "rrunner.c: v0.22 03/01/2000  Jes Sorensen (Jes.Sorensen@cern.ch)\n";
 
-static struct net_device *root_dev = NULL;
+static struct net_device *root_dev;
 
 
 /*
diff -urN linux-2.4.4-pre4/drivers/net/sb1000.c linux/drivers/net/sb1000.c
--- linux-2.4.4-pre4/drivers/net/sb1000.c	Tue Mar  6 19:44:36 2001
+++ linux/drivers/net/sb1000.c	Mon Dec  3 22:35:55 2001
@@ -191,7 +191,7 @@
 		ioaddr[0]=idev->resource[0].start;
 		ioaddr[1]=idev->resource[1].start;
 		
-		irq = idev->irq;
+		irq = idev->irq_resource[0].start;
 
 		/* check I/O base and IRQ */
 		if (dev->base_addr != 0 && dev->base_addr != ioaddr[0])
diff -urN linux-2.4.4-pre4/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c
--- linux-2.4.4-pre4/drivers/net/seeq8005.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/seeq8005.c	Mon Dec  3 22:35:55 2001
@@ -14,7 +14,7 @@
 
 */
 
-static const char *version =
+static const char version[] =
 	"seeq8005.c:v1.00 8/07/95 Hamish Coleman (hamish@zot.apana.org.au)\n";
 
 /*
diff -urN linux-2.4.4-pre4/drivers/net/shaper.c linux/drivers/net/shaper.c
--- linux-2.4.4-pre4/drivers/net/shaper.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/shaper.c	Mon Dec  3 22:35:55 2001
@@ -651,8 +651,6 @@
 	 *	Intialise the packet queues
 	 */
 	 
-	dev_init_buffers(dev);
-	
 	/*
 	 *	Handlers for when we attach to a device.
 	 */
diff -urN linux-2.4.4-pre4/drivers/net/sis900.c linux/drivers/net/sis900.c
--- linux-2.4.4-pre4/drivers/net/sis900.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/sis900.c	Mon Dec  3 22:35:55 2001
@@ -5,7 +5,7 @@
    Modified from the driver which is originally written by Donald Becker.
    
    This software may be used and distributed according to the terms
-   of the GNU Public License (GPL), incorporated herein by reference.
+   of the GNU General Public License (GPL), incorporated herein by reference.
    Drivers based on this skeleton fall under the GPL and must retain
    the authorship (implicit copyright) notice.
    
diff -urN linux-2.4.4-pre4/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
--- linux-2.4.4-pre4/drivers/net/sk98lin/skge.c	Tue Mar  6 19:28:34 2001
+++ linux/drivers/net/sk98lin/skge.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/******************************************************************************
+;/******************************************************************************
  *
  * Name:      	skge.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
@@ -343,7 +343,7 @@
 
 /* global variables *********************************************************/
 static const char *BootString = BOOT_STRING;
-static struct net_device *root_dev = NULL;
+static struct net_device *root_dev;
 static int probed __initdata = 0;
 
 /* local variables **********************************************************/
@@ -602,8 +602,8 @@
 #endif
 
 
-static int debug = 0; /* not used */
-static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */
+static int debug; /* not used */
+static int options[SK_MAX_CARD_PARAM]; /* not used */
 
 
 /*****************************************************************************
diff -urN linux-2.4.4-pre4/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- linux-2.4.4-pre4/drivers/net/sk_g16.c	Tue Mar 20 12:05:00 2001
+++ linux/drivers/net/sk_g16.c	Mon Dec  3 22:35:55 2001
@@ -23,7 +23,7 @@
  *
 -*/
 
-static const char *rcsid = "$Id: sk_g16.c,v 1.1 1994/06/30 16:25:15 root Exp $";
+static const char rcsid[] = "$Id: sk_g16.c,v 1.1 1994/06/30 16:25:15 root Exp $";
 
 /*
  * The Schneider & Koch (SK) G16 Network device driver is based
@@ -622,7 +622,7 @@
 
 
 #ifdef MODULE
-static int io = 0; /* 0 == probe */
+static int io;	/* 0 == probe */
 
 static int __init SK_init_module (void)
 {
diff -urN linux-2.4.4-pre4/drivers/net/skfp/skfddi.c linux/drivers/net/skfp/skfddi.c
--- linux-2.4.4-pre4/drivers/net/skfp/skfddi.c	Tue Mar  6 19:28:34 2001
+++ linux/drivers/net/skfp/skfddi.c	Mon Dec  3 22:35:55 2001
@@ -2557,7 +2557,7 @@
  *
  ************************/
 #define LP(a) ((struct s_smc*)(a))
-static struct net_device *mdev = NULL;
+static struct net_device *mdev;
 
 /************************
  *
diff -urN linux-2.4.4-pre4/drivers/net/slip.c linux/drivers/net/slip.c
--- linux-2.4.4-pre4/drivers/net/slip.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/slip.c	Mon Dec  3 22:35:55 2001
@@ -92,7 +92,7 @@
 	struct slip	ctrl;		/* SLIP things			*/
 	struct net_device	dev;		/* the device			*/
 } slip_ctrl_t;
-static slip_ctrl_t	**slip_ctrls = NULL;
+static slip_ctrl_t	**slip_ctrls;
 
 int slip_maxdev = SL_NRUNIT;		/* Can be overridden with insmod! */
 MODULE_PARM(slip_maxdev, "i");
@@ -647,8 +647,6 @@
 	dev->tx_queue_len	= 10;
 
 	SET_MODULE_OWNER(dev);
-
-	dev_init_buffers(dev);
 
 	/* New-style flags. */
 	dev->flags		= IFF_NOARP|IFF_POINTOPOINT|IFF_MULTICAST;
diff -urN linux-2.4.4-pre4/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- linux-2.4.4-pre4/drivers/net/smc-ultra.c	Tue Mar 20 12:05:00 2001
+++ linux/drivers/net/smc-ultra.c	Mon Dec  3 22:35:55 2001
@@ -53,7 +53,7 @@
 	interface and then load the module with an explicit io=0x___ option.
 */
 
-static const char *version =
+static const char version[] =
 	"smc-ultra.c:v2.02 2/3/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/config.h>
diff -urN linux-2.4.4-pre4/drivers/net/smc9194.c linux/drivers/net/smc9194.c
--- linux-2.4.4-pre4/drivers/net/smc9194.c	Tue Mar 20 12:05:01 2001
+++ linux/drivers/net/smc9194.c	Mon Dec  3 22:35:55 2001
@@ -53,7 +53,7 @@
  .      12/15/00  Christian Jullien fix "Warning: kfree_skb on hard IRQ"
  ----------------------------------------------------------------------------*/
 
-static const char *version =
+static const char version[] =
 	"smc9194.c:v0.14 12/15/00 by Erik Stahlman (erik@vt.edu)\n";
 
 #include <linux/module.h>
diff -urN linux-2.4.4-pre4/drivers/net/starfire.c linux/drivers/net/starfire.c
--- linux-2.4.4-pre4/drivers/net/starfire.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/starfire.c	Mon Dec  3 22:35:55 2001
@@ -53,7 +53,7 @@
 
 static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
 static int max_interrupt_work = 20;
-static int mtu = 0;
+static int mtu;
 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
    The Starfire has a 512 element hash table based on the Ethernet CRC.  */
 static int multicast_filter_limit = 32;
@@ -88,22 +88,31 @@
 
 #define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
 
+/*
+ * The ia64 doesn't allow for unaligned loads even of integers being
+ * misaligned on a 2 byte boundary. Thus always force copying of
+ * packets as the starfire doesn't allow for misaligned DMAs ;-(
+ * 23/10/2000 - Jes
+ */
+#ifdef __ia64__
+#define PKT_SHOULD_COPY(pkt_len)	1
+#else
+#define PKT_SHOULD_COPY(pkt_len)	(pkt_len < rx_copybreak)
+#endif
+
 #if !defined(__OPTIMIZE__)
 #warning  You must compile this file with the correct options!
 #warning  See the last lines of the source file.
 #error You must compile this driver with "-O".
 #endif
 
-/* Include files, designed to support most kernel versions 2.0.0 and later. */
-#include <linux/version.h>
 #include <linux/module.h>
-
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -320,6 +329,7 @@
 	dma_addr_t mapping;
 };
 
+#define MII_CNT		4
 struct netdev_private {
 	/* Descriptor rings first for alignment. */
 	struct starfire_rx_desc *rx_ring;
@@ -356,7 +366,7 @@
 	/* MII transceiver section. */
 	int mii_cnt;						/* MII device addresses. */
 	u16 advertising;					/* NWay media advertisement */
-	unsigned char phys[2];				/* MII device addresses. */
+	unsigned char phys[MII_CNT];		/* MII device addresses, only first one used. */
 };
 
 static int  mdio_read(struct net_device *dev, int phy_id, int location);
@@ -385,40 +395,38 @@
 	int i, irq, option, chip_idx = ent->driver_data;
 	struct net_device *dev;
 	static int card_idx = -1;
-	static int printed_version = 0;
+	static int printed_version;
 	long ioaddr;
 	int drv_flags, io_size = netdrv_tbl[chip_idx].io_size;
 
 	card_idx++;
 	option = card_idx < MAX_UNITS ? options[card_idx] : 0;
-	
+
 	if (!printed_version++)
 		printk(KERN_INFO "%s" KERN_INFO "%s" KERN_INFO "%s",
 		       version1, version2, version3);
 
+	if (pci_enable_device (pdev))
+		return -EIO;
+
 	ioaddr = pci_resource_start (pdev, 0);
 	if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_MEM) == 0)) {
 		printk (KERN_ERR "starfire %d: no PCI MEM resources, aborting\n", card_idx);
 		return -ENODEV;
 	}
 	
-	dev = init_etherdev(NULL, sizeof(*np));
+	dev = alloc_etherdev(sizeof(*np));
 	if (!dev) {
 		printk (KERN_ERR "starfire %d: cannot alloc etherdev, aborting\n", card_idx);
 		return -ENOMEM;
 	}
+	SET_MODULE_OWNER(dev);
 	
 	irq = pdev->irq; 
 
-	if (request_mem_region (ioaddr, io_size, dev->name) == NULL) {
-		printk (KERN_ERR "starfire %d: resource 0x%x @ 0x%lx busy, aborting\n",
-			card_idx, io_size, ioaddr);
+	if (pci_request_regions (pdev, "starfire"))
 		goto err_out_free_netdev;
-	}
-	
-	if (pci_enable_device (pdev))
-		goto err_out_free_res;
-	
+
 	ioaddr = (long) ioremap (ioaddr, io_size);
 	if (!ioaddr) {
 		printk (KERN_ERR "starfire %d: cannot remap 0x%x @ 0x%lx, aborting\n",
@@ -428,15 +436,9 @@
 
 	pci_set_master (pdev);
 	
-	printk(KERN_INFO "%s: %s at 0x%lx, ",
-		   dev->name, netdrv_tbl[chip_idx].name, ioaddr);
-
 	/* Serial EEPROM reads are hidden by the hardware. */
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20-i);
-	for (i = 0; i < 5; i++)
-			printk("%2.2x:", dev->dev_addr[i]);
-	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
 
 #if ! defined(final_version) /* Dump the EEPROM contents during development. */
 	if (debug > 4)
@@ -452,7 +454,7 @@
 	dev->irq = irq;
 
 	np = dev->priv;
-	pdev->driver_data = dev;
+	pci_set_drvdata(pdev, dev);
 
 	np->pci_dev = pdev;
 	drv_flags = netdrv_tbl[chip_idx].drv_flags;
@@ -487,9 +489,19 @@
 	if (mtu)
 		dev->mtu = mtu;
 
+	i = register_netdev(dev);
+	if (i)
+		goto err_out_cleardev;
+
+	printk(KERN_INFO "%s: %s at 0x%lx, ",
+		   dev->name, netdrv_tbl[chip_idx].name, ioaddr);
+	for (i = 0; i < 5; i++)
+			printk("%2.2x:", dev->dev_addr[i]);
+	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
+
 	if (drv_flags & CanHaveMII) {
 		int phy, phy_idx = 0;
-		for (phy = 0; phy < 32 && phy_idx < 4; phy++) {
+		for (phy = 0; phy < 32 && phy_idx < MII_CNT; phy++) {
 			int mii_status = mdio_read(dev, phy, 1);
 			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
 				np->phys[phy_idx++] = phy;
@@ -504,8 +516,11 @@
 
 	return 0;
 
+err_out_cleardev:
+	pci_set_drvdata(pdev, NULL);
+	iounmap((void *)ioaddr);
 err_out_free_res:
-	release_mem_region (ioaddr, io_size);
+	pci_release_regions (pdev);
 err_out_free_netdev:
 	unregister_netdev (dev);
 	kfree (dev);
@@ -537,19 +552,15 @@
 
 static int netdev_open(struct net_device *dev)
 {
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 	int i, retval;
 
 	/* Do we ever need to reset the chip??? */
 
-	MOD_INC_USE_COUNT;
-
 	retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);
-	if (retval) {
-		MOD_DEC_USE_COUNT;
+	if (retval)
 		return retval;
-	}
 
 	/* Disable the Rx and Tx, and reset the chip. */
 	writel(0, ioaddr + GenCtrl);
@@ -580,7 +591,6 @@
 		if (np->rx_ring)
 			pci_free_consistent(np->pci_dev, PAGE_SIZE,
 								np->rx_ring, np->rx_ring_dma);
-		MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
 
@@ -666,7 +676,7 @@
 
 static void check_duplex(struct net_device *dev, int startup)
 {
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 	int new_tx_mode ;
 
@@ -699,7 +709,7 @@
 static void netdev_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 	int next_tick = 60*HZ;		/* Check before driver release. */
 
@@ -727,7 +737,7 @@
 
 static void tx_timeout(struct net_device *dev)
 {
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 
 	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
@@ -809,8 +819,8 @@
 
 static int start_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
-	unsigned entry;
+	struct netdev_private *np = dev->priv;
+	unsigned int entry;
 
 	/* Caution: the write order is important here, set the field
 	   with the "ownership" bits last. */
@@ -840,6 +850,9 @@
 #endif
 
 	/* Non-x86: explicitly flush descriptor cache lines here. */
+	/* Ensure everything is written back above before the transmit is
+	   initiated. - Jes */
+	wmb();
 
 	/* Update the producer index. */
 	writel(++entry, dev->base_addr + TxProducerIdx);
@@ -974,7 +987,7 @@
    for clarity and better register allocation. */
 static int netdev_rx(struct net_device *dev)
 {
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 	int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx;
 	u32 desc_status;
 
@@ -1012,7 +1025,7 @@
 #endif
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
-			if (pkt_len < rx_copybreak
+			if (PKT_SHOULD_COPY(pkt_len)
 				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 				skb->dev = dev;
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
@@ -1034,14 +1047,6 @@
 				temp = skb_put(skb, pkt_len);
 				np->rx_info[entry].skb = NULL;
 				np->rx_info[entry].mapping = 0;
-#ifndef final_version				/* Remove after testing. */
-				if (le32_to_cpu(np->rx_ring[entry].rxaddr & ~3) != ((unsigned long) temp))
-					printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
-						   "do not match in netdev_rx: %d vs. %p / %p.\n",
-						   dev->name,
-						   le32_to_cpu(np->rx_ring[entry].rxaddr),
-						   skb->head, temp);
-#endif
 			}
 #ifndef final_version				/* Remove after testing. */
 			/* You will want this info for the initial debug. */
@@ -1104,7 +1109,7 @@
 
 static void netdev_error(struct net_device *dev, int intr_status)
 {
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 
 	if (intr_status & LinkChange) {
 		printk(KERN_NOTICE "%s: Link changed: Autonegotiation advertising"
@@ -1133,7 +1138,7 @@
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 
 	/* This adapter architecture needs no SMP locks. */
 	np->stats.tx_bytes = readl(ioaddr + 0x57010);
@@ -1238,7 +1243,7 @@
 
 static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 	u16 *data = (u16 *)&rq->ifr_data;
 
 	switch(cmd) {
@@ -1276,7 +1281,7 @@
 static int netdev_close(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
-	struct netdev_private *np = (struct netdev_private *)dev->priv;
+	struct netdev_private *np = dev->priv;
 	int i;
 
 	netif_stop_queue(dev);
@@ -1338,15 +1343,13 @@
 		np->tx_info[i].mapping = 0;
 	}
 
-	MOD_DEC_USE_COUNT;
-
 	return 0;
 }
 
 
 static void __devexit starfire_remove_one (struct pci_dev *pdev)
 {
-	struct net_device *dev = pdev->driver_data;
+	struct net_device *dev = pci_get_drvdata(pdev);
 	struct netdev_private *np;
 	
 	if (!dev)
@@ -1356,6 +1359,7 @@
 
 	unregister_netdev(dev);
 	iounmap((char *)dev->base_addr);
+	pci_release_regions (pdev);
 
 	if (np->tx_done_q)
 		pci_free_consistent(np->pci_dev, PAGE_SIZE,
@@ -1371,6 +1375,8 @@
 				    np->rx_ring, np->rx_ring_dma);
 
 	kfree(dev);
+
+	pci_set_drvdata(pdev, NULL);
 }
 
 
diff -urN linux-2.4.4-pre4/drivers/net/sun3lance.c linux/drivers/net/sun3lance.c
--- linux-2.4.4-pre4/drivers/net/sun3lance.c	Tue Mar  6 19:28:35 2001
+++ linux/drivers/net/sun3lance.c	Mon Dec  3 22:35:55 2001
@@ -243,7 +243,7 @@
 
 int __init sun3lance_probe( struct net_device *dev )
 {	
-	static int found = 0;
+	static int found;
 
 	if(found)
 		return(ENODEV);
@@ -262,7 +262,7 @@
 	
 	struct lance_private	*lp;
 	int 			i;
-	static int 		did_version = 0;
+	static int 		did_version;
 	int found = 0;
 	volatile unsigned short *ioaddr_probe;
 	unsigned short tmp1, tmp2;
@@ -585,7 +585,7 @@
 	struct net_device *dev = dev_id;
 	struct lance_private *lp = dev->priv;
 	int csr0;
-	static int in_interrupt = 0;
+	static int in_interrupt;
 
 	if (dev == NULL) {
 		DPRINTK( 1, ( "lance_interrupt(): invalid dev_id\n" ));
diff -urN linux-2.4.4-pre4/drivers/net/sunbmac.c linux/drivers/net/sunbmac.c
--- linux-2.4.4-pre4/drivers/net/sunbmac.c	Tue Mar  6 22:44:16 2001
+++ linux/drivers/net/sunbmac.c	Mon Dec  3 22:35:55 2001
@@ -63,7 +63,7 @@
 #define DIRQ(x)
 #endif
 
-static struct bigmac *root_bigmac_dev = NULL;
+static struct bigmac *root_bigmac_dev;
 
 #define DEFAULT_JAMSIZE    4 /* Toe jam */
 
diff -urN linux-2.4.4-pre4/drivers/net/sundance.c linux/drivers/net/sundance.c
--- linux-2.4.4-pre4/drivers/net/sundance.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/sundance.c	Mon Dec  3 22:35:55 2001
@@ -30,7 +30,7 @@
 static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 20;
-static int mtu = 0;
+static int mtu;
 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
    Typical is a 64 element hash table based on the Ethernet CRC.  */
 static int multicast_filter_limit = 32;
@@ -39,7 +39,7 @@
    Setting to > 1518 effectively disables this feature.
    This chip can receive into offset buffers, so the Alpha does not
    need a copy-align. */
-static int rx_copybreak = 0;
+static int rx_copybreak;
 
 /* Used to pass the media type, etc.
    Both 'options[]' and 'full_duplex[]' should exist for driver
@@ -527,7 +527,7 @@
 /* Set iff a MII transceiver on any interface requires mdio preamble.
    This only set with older tranceivers, so the extra
    code size of a per-interface flag is not worthwhile. */
-static char mii_preamble_required = 0;
+static char mii_preamble_required;
 
 enum mii_reg_bits {
 	MDIO_ShiftClk=0x0001, MDIO_Data=0x0002, MDIO_EnbOutput=0x0004,
diff -urN linux-2.4.4-pre4/drivers/net/sungem.c linux/drivers/net/sungem.c
--- linux-2.4.4-pre4/drivers/net/sungem.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/sungem.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: sungem.c,v 1.11 2001/04/04 14:49:40 davem Exp $
+/* $Id: sungem.c,v 1.12 2001/04/17 07:20:20 davem Exp $
  * sungem.c: Sun GEM ethernet driver.
  *
  * Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com)
@@ -412,21 +412,41 @@
 	while (entry != limit) {
 		struct sk_buff *skb;
 		struct gem_txd *txd;
-		u32 dma_addr;
+		u32 dma_addr, dma_len;
+		int frag;
 
-		txd = &gp->init_block->txd[entry];
 		skb = gp->tx_skbs[entry];
-		dma_addr = (u32) le64_to_cpu(txd->buffer);
-		pci_unmap_single(gp->pdev, dma_addr,
-				 skb->len, PCI_DMA_TODEVICE);
-		gp->tx_skbs[entry] = NULL;
+		if (skb_shinfo(skb)->nr_frags) {
+			int last = entry + skb_shinfo(skb)->nr_frags;
+			int walk = entry;
+			int incomplete = 0;
 
+			last &= (TX_RING_SIZE - 1);
+			for (;;) {
+				walk = NEXT_TX(walk);
+				if (walk == limit)
+					incomplete = 1;
+				if (walk == last)
+					break;
+			}
+			if (incomplete)
+				break;
+		}
+		gp->tx_skbs[entry] = NULL;
 		gp->net_stats.tx_bytes += skb->len;
-		gp->net_stats.tx_packets++;
 
-		dev_kfree_skb_irq(skb);
+		for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
+			txd = &gp->init_block->txd[entry];
 
-		entry = NEXT_TX(entry);
+			dma_addr = (u32) le64_to_cpu(txd->buffer);
+			dma_len = le64_to_cpu(txd->control_word) & TXDCTRL_BUFSZ;
+
+			pci_unmap_single(gp->pdev, dma_addr, dma_len, PCI_DMA_TODEVICE);
+			entry = NEXT_TX(entry);
+		}
+
+		gp->net_stats.tx_packets++;
+		dev_kfree_skb_irq(skb);
 	}
 	gp->tx_old = entry;
 
@@ -606,30 +626,84 @@
 static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct gem *gp = dev->priv;
-	long len;
-	int entry, avail;
-	u32 mapping;
+	int entry;
+	u64 ctrl;
 
-	len = skb->len;
-	mapping = pci_map_single(gp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	ctrl = 0;
+	if (skb->ip_summed == CHECKSUM_HW) {
+		u64 csum_start_off, csum_stuff_off;
+
+		csum_start_off = (u64) (skb->h.raw - skb->data);
+		csum_stuff_off = (u64) ((skb->h.raw + skb->csum) - skb->data);
+
+		ctrl = (TXDCTRL_CENAB |
+			(csum_start_off << 15) |
+			(csum_stuff_off << 21));
+	}
 
 	spin_lock_irq(&gp->lock);
-	entry = gp->tx_new;
-	gp->tx_skbs[entry] = skb;
 
-	gp->tx_new = NEXT_TX(entry);
-	avail = TX_BUFFS_AVAIL(gp);
-	if (avail <= 0)
+	if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) {
 		netif_stop_queue(dev);
+		spin_unlock_irq(&gp->lock);
+		return 1;
+	}
 
-	{
+	entry = gp->tx_new;
+	gp->tx_skbs[entry] = skb;
+
+	if (skb_shinfo(skb)->nr_frags == 0) {
 		struct gem_txd *txd = &gp->init_block->txd[entry];
-		u64 ctrl = (len & TXDCTRL_BUFSZ) | TXDCTRL_EOF | TXDCTRL_SOF;
+		u32 mapping, len;
 
-		txd->control_word = cpu_to_le64(ctrl);
+		len = skb->len;
+		mapping = pci_map_single(gp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+		ctrl |= TXDCTRL_SOF | TXDCTRL_EOF | len;
 		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, first_mapping;
+		int frag, first_entry = entry;
+
+		/* We must give this initial chunk to the device last.
+		 * Otherwise we could race with the device.
+		 */
+		first_len = skb->len - skb->data_len;
+		first_mapping = pci_map_single(gp->pdev, skb->data,
+					       first_len, PCI_DMA_TODEVICE);
+		entry = NEXT_TX(entry);
+
+		for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
+			skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
+			u32 len, mapping;
+			u64 this_ctrl;
+
+			len = this_frag->size;
+			mapping = pci_map_single(gp->pdev,
+						 ((void *) page_address(this_frag->page) +
+						  this_frag->page_offset),
+						 len, PCI_DMA_TODEVICE);
+			this_ctrl = ctrl;
+			if (frag == skb_shinfo(skb)->nr_frags - 1)
+				this_ctrl |= TXDCTRL_EOF;
+			
+			txd = &gp->init_block->txd[entry];
+			txd->buffer = cpu_to_le64(mapping);
+			txd->control_word = cpu_to_le64(this_ctrl | len);
+
+			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);
 	}
 
+	gp->tx_new = entry;
+	if (TX_BUFFS_AVAIL(gp) <= 0)
+		netif_stop_queue(dev);
+
 	writel(gp->tx_new, gp->regs + TXDMA_KICK);
 	spin_unlock_irq(&gp->lock);
 
@@ -890,14 +964,22 @@
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		if (gp->tx_skbs[i] != NULL) {
 			struct gem_txd *txd;
+			int frag;
 
 			skb = gp->tx_skbs[i];
-			txd = &gb->txd[i];
-			dma_addr = (u32) le64_to_cpu(txd->buffer);
-			pci_unmap_single(gp->pdev, dma_addr,
-					 skb->len, PCI_DMA_TODEVICE);
-			dev_kfree_skb_any(skb);
 			gp->tx_skbs[i] = NULL;
+
+			for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
+				txd = &gb->txd[i];
+				dma_addr = (u32) le64_to_cpu(txd->buffer);
+				pci_unmap_single(gp->pdev, dma_addr,
+						 le64_to_cpu(txd->control_word) &
+						 TXDCTRL_BUFSZ, PCI_DMA_TODEVICE);
+
+				if (frag != skb_shinfo(skb)->nr_frags)
+					i++;
+			}
+			dev_kfree_skb_any(skb);
 		}
 	}
 }
@@ -1609,6 +1691,9 @@
 	dev->change_mtu = gem_change_mtu;
 	dev->irq = pdev->irq;
 	dev->dma = 0;
+
+	/* GEM can do it all... */
+	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
 	return 0;
 
diff -urN linux-2.4.4-pre4/drivers/net/sunhme.c linux/drivers/net/sunhme.c
--- linux-2.4.4-pre4/drivers/net/sunhme.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/sunhme.c	Mon Dec  3 22:35:55 2001
@@ -1,4 +1,4 @@
-/* $Id: sunhme.c,v 1.115 2001/03/29 06:37:09 davem Exp $
+/* $Id: sunhme.c,v 1.116 2001/04/17 07:20:52 davem Exp $
  * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching,
  *           auto carrier detecting ethernet driver.  Also known as the
  *           "Happy Meal Ethernet" found on SunSwift SBUS cards.
@@ -13,7 +13,7 @@
  *     argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50
  */
 
-static char *version =
+static char version[] =
         "sunhme.c:v1.99 12/Sep/99 David S. Miller (davem@redhat.com)\n";
 
 #include <linux/module.h>
@@ -73,14 +73,14 @@
 /* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
 MODULE_PARM(macaddr, "6i");
 
-static struct happy_meal *root_happy_dev = NULL;
+static struct happy_meal *root_happy_dev;
 
 #ifdef CONFIG_SBUS
-static struct quattro *qfe_sbus_list = NULL;
+static struct quattro *qfe_sbus_list;
 #endif
 
 #ifdef CONFIG_PCI
-static struct quattro *qfe_pci_list = NULL;
+static struct quattro *qfe_pci_list;
 #endif
 
 #undef HMEDEBUG
@@ -102,7 +102,7 @@
 };
 #define TX_LOG_LEN	128
 static struct hme_tx_logent tx_log[TX_LOG_LEN];
-static int txlog_cur_entry = 0;
+static int txlog_cur_entry;
 static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigned int s)
 {
 	struct hme_tx_logent *tlp;
@@ -1997,16 +1997,12 @@
 			dma_len &= TXFLAG_SIZE;
 			hme_dma_unmap(hp, dma_addr, dma_len, DMA_TODEVICE);
 
-			if (frag != skb_shinfo(skb)->nr_frags) {
-				elem = NEXT_TX(elem);
-				this = &txbase[elem];
-			}
+			elem = NEXT_TX(elem);
+			this = &txbase[elem];
 		}
 
 		dev_kfree_skb_irq(skb);
-
 		hp->net_stats.tx_packets++;
-		elem = NEXT_TX(elem);
 	}
 	hp->tx_old = elem;
 	TXD((">"));
@@ -2510,7 +2506,7 @@
 		return -EOPNOTSUPP;
 }
 
-static int hme_version_printed = 0;
+static int hme_version_printed;
 
 #ifdef CONFIG_SBUS
 void __init quattro_get_ranges(struct quattro *qp)
diff -urN linux-2.4.4-pre4/drivers/net/sunlance.c linux/drivers/net/sunlance.c
--- linux-2.4.4-pre4/drivers/net/sunlance.c	Tue Mar  6 22:44:16 2001
+++ linux/drivers/net/sunlance.c	Mon Dec  3 22:35:55 2001
@@ -66,10 +66,10 @@
 
 #undef DEBUG_DRIVER
 
-static char *version =
+static char version[] =
 	"sunlance.c:v2.00 11/Sep/99 Miguel de Icaza (miguel@nuclecu.unam.mx)\n";
 
-static char *lancestr = "LANCE";
+static char lancestr[] = "LANCE";
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -291,7 +291,7 @@
 
 #define LANCE_ADDR(x) ((long)(x) & ~0xff000000)
 
-static struct lance_private *root_lance_dev = NULL;
+static struct lance_private *root_lance_dev;
 
 /* Load the CSR registers */
 static void load_csrs(struct lance_private *lp)
@@ -1307,7 +1307,7 @@
 				   struct sbus_dma *ledma,
 				   struct sbus_dev *lebuffer)
 {
-	static unsigned version_printed = 0;
+	static unsigned version_printed;
 	struct lance_private *lp = NULL;
 	int    i;
 
@@ -1518,7 +1518,7 @@
 static int __init sparc_lance_probe(void)
 {
 	static struct sbus_dev sdev;
-	static int called = 0;
+	static int called;
 
 	root_lance_dev = NULL;
 
@@ -1545,7 +1545,7 @@
 	struct sbus_dev *sdev = 0;
 	struct net_device *dev = NULL;
 	struct sbus_dma *ledma = 0;
-	static int called = 0;
+	static int called;
 	int cards = 0, v;
 
 	root_lance_dev = NULL;
diff -urN linux-2.4.4-pre4/drivers/net/sunqe.c linux/drivers/net/sunqe.c
--- linux-2.4.4-pre4/drivers/net/sunqe.c	Tue Mar  6 22:44:16 2001
+++ linux/drivers/net/sunqe.c	Mon Dec  3 22:35:55 2001
@@ -7,7 +7,7 @@
  * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com)
  */
 
-static char *version =
+static char version[] =
         "sunqe.c:v2.9 9/11/99 David S. Miller (davem@redhat.com)\n";
 
 #include <linux/module.h>
@@ -46,7 +46,7 @@
 
 #include "sunqe.h"
 
-static struct sunqec *root_qec_dev = NULL;
+static struct sunqec *root_qec_dev;
 
 static void qe_set_multicast(struct net_device *dev);
 
@@ -733,7 +733,7 @@
 /* Four QE's per QEC card. */
 static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
 {
-	static unsigned version_printed = 0;
+	static unsigned version_printed;
 	struct net_device *qe_devs[4];
 	struct sunqe *qeps[4];
 	struct sbus_dev *qesdevs[4];
@@ -983,7 +983,7 @@
 	struct net_device *dev = NULL;
 	struct sbus_bus *bus;
 	struct sbus_dev *sdev = 0;
-	static int called = 0;
+	static int called;
 	int cards = 0, v;
 
 	root_qec_dev = NULL;
diff -urN linux-2.4.4-pre4/drivers/net/tlan.c linux/drivers/net/tlan.c
--- linux-2.4.4-pre4/drivers/net/tlan.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/tlan.c	Mon Dec  3 22:35:55 2001
@@ -205,7 +205,7 @@
 static	int		bbuf;
 static	u8		*TLanPadBuffer;
 static	char		TLanSignature[] = "TLAN";
-static const char *tlan_banner = "ThunderLAN driver v1.14a\n";
+static const char tlan_banner[] = "ThunderLAN driver v1.14a\n";
 static int tlan_have_pci;
 static int tlan_have_eisa;
 
@@ -427,7 +427,7 @@
 
 static int __init tlan_probe(void)
 {
-	static int	pad_allocated = 0;
+	static int	pad_allocated;
 	
 	printk(KERN_INFO "%s", tlan_banner);
 	
diff -urN linux-2.4.4-pre4/drivers/net/tokenring/lanstreamer.c linux/drivers/net/tokenring/lanstreamer.c
--- linux-2.4.4-pre4/drivers/net/tokenring/lanstreamer.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/net/tokenring/lanstreamer.c	Mon Dec  3 22:35:55 2001
@@ -121,7 +121,7 @@
  * Official releases will only have an a.b.c version number format.
  */
 
-static char *version = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan";
+static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan";
 
 static struct pci_device_id streamer_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,},
diff -urN linux-2.4.4-pre4/drivers/net/tokenring/madgemc.c linux/drivers/net/tokenring/madgemc.c
--- linux-2.4.4-pre4/drivers/net/tokenring/madgemc.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/net/tokenring/madgemc.c	Mon Dec  3 22:35:55 2001
@@ -61,7 +61,7 @@
 
 	struct madgemc_card *next;
 };
-static struct madgemc_card *madgemc_card_list = NULL;
+static struct madgemc_card *madgemc_card_list;
 
 
 int madgemc_probe(void);
@@ -155,7 +155,7 @@
 
 int __init madgemc_probe(void)
 {	
-	static int versionprinted = 0;
+	static int versionprinted;
 	struct net_device *dev;
 	struct net_local *tp;
 	struct madgemc_card *card;
@@ -525,7 +525,7 @@
  */
 static void madgemc_setregpage(struct net_device *dev, int page)
 {	
-	static int reg1 = 0;
+	static int reg1;
 
 	reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
 	if ((page == 0) && (reg1 & MC_CONTROL_REG1_SRSX)) {
diff -urN linux-2.4.4-pre4/drivers/net/tokenring/olympic.c linux/drivers/net/tokenring/olympic.c
--- linux-2.4.4-pre4/drivers/net/tokenring/olympic.c	Tue Mar 20 12:05:00 2001
+++ linux/drivers/net/tokenring/olympic.c	Mon Dec  3 22:35:55 2001
@@ -1,6 +1,6 @@
 /*
  *   olympic.c (c) 1999 Peter De Schrijver All Rights Reserved
- *		   1999 Mike Phillips (mikep@linuxtr.net)
+ *		   1999/2000 Mike Phillips (mikep@linuxtr.net)
  *
  *  Linux driver for IBM PCI tokenring cards based on the Pit/Pit-Phy/Olympic
  *  chipset. 
@@ -38,10 +38,21 @@
  *            Fixing the hardware descriptors was another matter,
  *            because they weren't going through read[wl](), there all
  *            the results had to be in memory in le32 values. kdaaker
+ *
  * 12/23/00 - Added minimal Cardbus support (Thanks Donald).
  *
+ * 03/09/01 - Add new pci api, dev_base_lock, general clean up. 
+ *
+ * 03/27/01 - Add new dma pci (Thanks to Kyle Lucke) and alloc_trdev
+ *	      Change proc_fs behaviour, now one entry per adapter.
+ *
+ * 04/09/01 - Couple of bug fixes to the dma unmaps and ejecting the
+ *	      adapter when live does not take the system down with it.
+ * 
  *  To Do:
- *           Complete full Cardbus / hot-swap support.
+ *
+ *	     Complete full Cardbus / hot-swap support.
+ *	     Wake on lan	
  * 
  *  If Problems do Occur
  *  Most problems can be rectified by either closing and opening the interface
@@ -53,14 +64,6 @@
 
 #define OLYMPIC_DEBUG 0
 
-/* Change OLYMPIC_NETWORK_MONITOR to receive mac frames through the arb channel.
- * Will also create a /proc/net/olympic_tr entry if proc_fs is compiled into the
- * kernel.
- * Intended to be used to create a ring-error reporting network module 
- * i.e. it will give you the source address of beaconers on the ring 
- */
-
-#define OLYMPIC_NETWORK_MONITOR 0
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -100,14 +103,7 @@
  */
 
 static char *version = 
-"Olympic.c v0.5.C 12/23/00 - Peter De Schrijver & Mike Phillips" ; 
-
-static struct pci_device_id olympic_pci_tbl[] __initdata = {
-	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR_WAKE, PCI_ANY_ID, PCI_ANY_ID, },
-	{ }			/* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, olympic_pci_tbl);
-
+"Olympic.c v0.9.C 4/18/01 - Peter De Schrijver & Mike Phillips" ; 
 
 static char *open_maj_error[]  = {"No error", "Lobe Media Test", "Physical Insertion",
 				   "Address Verification", "Neighbor Notification (Ring Poll)",
@@ -137,22 +133,34 @@
  */
 
 static int ringspeed[OLYMPIC_MAX_ADAPTERS] = {0,} ;
-
 MODULE_PARM(ringspeed, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i");
 
 /* Packet buffer size */
 
 static int pkt_buf_sz[OLYMPIC_MAX_ADAPTERS] = {0,} ;
- 
 MODULE_PARM(pkt_buf_sz, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i") ; 
 
 /* Message Level */
 
 static int message_level[OLYMPIC_MAX_ADAPTERS] = {0,} ; 
-
 MODULE_PARM(message_level, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i") ; 
 
-static int olympic_scan(struct net_device *dev);
+/* Change network_monitor to receive mac frames through the arb channel.
+ * Will also create a /proc/net/olympic_tr%d entry, where %d is the tr
+ * device, i.e. tr0, tr1 etc. 
+ * Intended to be used to create a ring-error reporting network module 
+ * i.e. it will give you the source address of beaconers on the ring 
+ */
+static int network_monitor[OLYMPIC_MAX_ADAPTERS] = {0,};
+MODULE_PARM(network_monitor, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i");
+
+static struct pci_device_id olympic_pci_tbl[] __devinitdata = {
+	{PCI_VENDOR_ID_IBM,PCI_DEVICE_ID_IBM_TR_WAKE,PCI_ANY_ID,PCI_ANY_ID,},
+	{ } 	/* Terminating Entry */
+};
+MODULE_DEVICE_TABLE(pci,olympic_pci_tbl) ; 
+
+static int __init olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 
 static int olympic_init(struct net_device *dev);
 static int olympic_open(struct net_device *dev);
 static int olympic_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -165,109 +173,89 @@
 static int olympic_change_mtu(struct net_device *dev, int mtu);
 static void olympic_srb_bh(struct net_device *dev) ; 
 static void olympic_asb_bh(struct net_device *dev) ; 
-#if OLYMPIC_NETWORK_MONITOR
-#ifdef CONFIG_PROC_FS
-static int sprintf_info(char *buffer, struct net_device *dev) ; 
-#endif
-#endif
+static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) ; 
 
-int __init olympic_probe(struct net_device *dev)
+static int __init olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	int cards_found;
+	struct net_device *dev ; 
+	struct olympic_private *olympic_priv;
+	static int card_no = -1 ;
+	int i ; 
 
-	cards_found=olympic_scan(dev);
-	return cards_found ? 0 : -ENODEV;
-}
+	card_no++ ; 
 
-static int __init olympic_scan(struct net_device *dev)
-{
-	struct pci_dev *pci_device = NULL ;
-	struct olympic_private *olympic_priv;
-	int card_no = 0 ;
-	if (pci_present()) {
+	if ((i = pci_enable_device(pdev))) {
+		return i ; 
+	}
 
-		while((pci_device=pci_find_device(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR_WAKE, pci_device))) {
-			__u16 pci_command ; 
+	pci_set_master(pdev);
 
-			if (pci_enable_device(pci_device))
-				continue;
+	if ((i = pci_request_regions(pdev,"olympic"))) { 
+		return i ; 
+	} ; 
+ 
+	dev = alloc_trdev(sizeof(struct olympic_private)) ; 
 
-			/* These lines are needed by the PowerPC, it appears that these flags
-			 * are not being set properly for the PPC, this may well be fixed with
-			 * the new PCI code */ 
-			pci_read_config_word(pci_device, PCI_COMMAND, &pci_command);
-			pci_command |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-			pci_write_config_word(pci_device, PCI_COMMAND,pci_command);
-			pci_set_master(pci_device);
-
-			/* Check to see if io has been allocated, if so, we've already done this card,
-			   so continue on the card discovery loop  */
-
-			if (check_region(pci_resource_start(pci_device, 0), OLYMPIC_IO_SPACE)) {
-				card_no++ ; 
-				continue ; 
-			}
+	if (!dev) {
+		pci_release_regions(pdev) ; 
+		return -ENOMEM ; 
+	}
 
-			olympic_priv=kmalloc(sizeof (struct olympic_private), GFP_KERNEL);
-			if (!olympic_priv)
-				return 0;
-			memset(olympic_priv, 0, sizeof(struct olympic_private));
-			init_waitqueue_head(&olympic_priv->srb_wait);
-			init_waitqueue_head(&olympic_priv->trb_wait);
-#ifndef MODULE
-			dev = init_trdev(NULL, 0);
-			if (!dev) {
-				kfree(olympic_priv);
-				return 0;
-			}
-#endif
-			dev->priv=(void *)olympic_priv;
+	olympic_priv = dev->priv ;
+	
+	init_waitqueue_head(&olympic_priv->srb_wait);
+	init_waitqueue_head(&olympic_priv->trb_wait);
 #if OLYMPIC_DEBUG  
-			printk("pci_device: %p, dev:%p, dev->priv: %p\n", pci_device, dev, dev->priv);
+	printk(KERN_INFO "pci_device: %p, dev:%p, dev->priv: %p\n", pdev, dev, dev->priv);
 #endif
-			dev->irq=pci_device->irq;
-			dev->base_addr=pci_resource_start(pci_device, 0);
-			dev->init=&olympic_init;	/* AKPM: Not needed */
-			olympic_priv->olympic_card_name = (char *)pci_device->resource[0].name ; 
-			/* FIXME: check ioremap return val, handle cleanup */
-			olympic_priv->olympic_mmio = 
-				ioremap(pci_resource_start(pci_device,1),256);
-			olympic_priv->olympic_lap = 
-				ioremap(pci_resource_start(pci_device,2),2048);
-			
-			if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
-				olympic_priv->pkt_buf_sz = PKT_BUF_SZ ; 
-			else
-				olympic_priv->pkt_buf_sz = pkt_buf_sz[card_no] ; 
-
-			olympic_priv->olympic_ring_speed = ringspeed[card_no] ; 
-			olympic_priv->olympic_message_level = message_level[card_no] ; 
-	
-			if(olympic_init(dev)==-1) {
-				kfree(dev->priv);
-#ifndef MODULE
-				unregister_netdev(dev);
-				kfree(dev);
-#endif
-				return 0;
-			}				
+	dev->irq=pdev->irq;
+	dev->base_addr=pci_resource_start(pdev, 0);
+	dev->init=NULL; /* Must be NULL otherwise we get called twice */
+	olympic_priv->olympic_card_name = (char *)pdev->name ; 
+	olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256);
+	olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048);
+	olympic_priv->pdev = pdev ; 
+				
+	if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
+		olympic_priv->pkt_buf_sz = PKT_BUF_SZ ; 
+	else
+		olympic_priv->pkt_buf_sz = pkt_buf_sz[card_no] ; 
 
-			dev->open=&olympic_open;
-			dev->hard_start_xmit=&olympic_xmit;
-			dev->change_mtu=&olympic_change_mtu;
-
-			dev->stop=&olympic_close;
-			dev->do_ioctl=NULL;
-			dev->set_multicast_list=&olympic_set_rx_mode;
-			dev->get_stats=&olympic_get_stats ;
-			dev->set_mac_address=&olympic_set_mac_address ;  
-			return 1; 
-		}
+	dev->mtu = olympic_priv->pkt_buf_sz - TR_HLEN ; 
+	olympic_priv->olympic_ring_speed = ringspeed[card_no] ; 
+	olympic_priv->olympic_message_level = message_level[card_no] ; 
+	olympic_priv->olympic_network_monitor = network_monitor[card_no];
+	
+	if((i = olympic_init(dev))) {
+		iounmap(olympic_priv->olympic_mmio) ; 
+		iounmap(olympic_priv->olympic_lap) ; 
+		kfree(dev) ; 
+		pci_release_regions(pdev) ; 
+		return i ; 
+	}				
+
+	dev->open=&olympic_open;
+	dev->hard_start_xmit=&olympic_xmit;
+	dev->change_mtu=&olympic_change_mtu;
+	dev->stop=&olympic_close;
+	dev->do_ioctl=NULL;
+	dev->set_multicast_list=&olympic_set_rx_mode;
+	dev->get_stats=&olympic_get_stats ;
+	dev->set_mac_address=&olympic_set_mac_address ;  
+
+	pci_set_drvdata(pdev,dev) ; 
+	register_netdev(dev) ; 
+	printk("Olympic: %s registered as: %s\n",olympic_priv->olympic_card_name,dev->name);
+	if (olympic_priv->olympic_network_monitor) { /* Must go after register_netdev as we need the device name */ 
+		char proc_name[20] ; 
+		strcpy(proc_name,"net/olympic_") ; 
+		strcat(proc_name,dev->name) ; 
+		create_proc_read_entry(proc_name,0,0,olympic_proc_info,(void *)dev) ; 
+		printk("Olympic: Network Monitor information: /proc/%s\n",proc_name); 
 	}
 	return  0 ;
 }
 
-
 static int __init olympic_init(struct net_device *dev)
 {
     	struct olympic_private *olympic_priv;
@@ -279,17 +267,15 @@
 	olympic_mmio=olympic_priv->olympic_mmio;
 
 	printk("%s \n", version);
-	printk("%s: %s. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n",dev->name, olympic_priv->olympic_card_name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq);
+	printk("%s. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n", olympic_priv->olympic_card_name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq);
 
-	request_region(dev->base_addr, OLYMPIC_IO_SPACE, "olympic");
 	writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL);
 	t=jiffies;
 	while((readl(olympic_priv->olympic_mmio+BCTL)) & BCTL_SOFTRESET) {
 		schedule();		
 		if(jiffies-t > 40*HZ) {
 			printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
-			release_region(dev->base_addr, OLYMPIC_IO_SPACE) ; 
-			return -1;
+			return -ENODEV;
 		}
 	}
 
@@ -313,14 +299,14 @@
 	if (olympic_priv->olympic_ring_speed  == 0) { /* Autosense */
 		writel(readl(olympic_mmio+GPR)|GPR_AUTOSENSE,olympic_mmio+GPR);
 		if (olympic_priv->olympic_message_level) 
-			printk(KERN_INFO "%s: Ringspeed autosense mode on\n",dev->name);
+			printk(KERN_INFO "%s: Ringspeed autosense mode on\n",olympic_priv->olympic_card_name);
 	} else if (olympic_priv->olympic_ring_speed == 16) {
 		if (olympic_priv->olympic_message_level) 
-			printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", dev->name);
+			printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", olympic_priv->olympic_card_name);
 		writel(GPR_16MBPS, olympic_mmio+GPR);
 	} else if (olympic_priv->olympic_ring_speed == 4) {
 		if (olympic_priv->olympic_message_level) 
-			printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", dev->name) ; 
+			printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", olympic_priv->olympic_card_name) ; 
 		writel(0, olympic_mmio+GPR);
 	} 
 	
@@ -335,10 +321,9 @@
 	t=jiffies;
 	while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) {
 		schedule();		
-		if(jiffies-t > 40*HZ) {
+		if(jiffies-t > 15*HZ) {
 			printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
-			release_region(dev->base_addr, OLYMPIC_IO_SPACE); 
-			return -1;
+			return -ENODEV;
 		}
 	}
 	
@@ -361,8 +346,7 @@
 #endif	
 	if(readw(init_srb+6)) {
 		printk(KERN_INFO "tokenring card intialization failed. errorcode : %x\n",readw(init_srb+6));
-		release_region(dev->base_addr, OLYMPIC_IO_SPACE);
-		return -1;
+		return -ENODEV;
 	}
 
 	if (olympic_priv->olympic_message_level) {
@@ -401,15 +385,10 @@
 {
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
 	__u8 *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;
-	unsigned long flags;
+	unsigned long flags, t;
 	char open_error[255] ; 
 	int i, open_finished = 1 ;
 
-#if OLYMPIC_NETWORK_MONITOR
-	__u8 *oat ; 
-	__u8 *opt ; 
-#endif
-
 	if(request_irq(dev->irq, &olympic_interrupt, SA_SHIRQ , "olympic", dev)) {
 		return -EAGAIN;
 	}
@@ -451,12 +430,10 @@
 		writeb(OLYMPIC_CLEAR_RET_CODE,init_srb+2);
 
 		/* If Network Monitor, instruct card to copy MAC frames through the ARB */
-
-#if OLYMPIC_NETWORK_MONITOR
-		writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8);
-#else
-		writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8);
-#endif		
+		if (olympic_priv->olympic_network_monitor) 
+			writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8);
+		else
+			writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8);
 
 		if (olympic_priv->olympic_laa[0]) {
 			writeb(olympic_priv->olympic_laa[0],init_srb+12);
@@ -473,17 +450,23 @@
 
 		writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
 
+		t = jiffies ; 
  		while(olympic_priv->srb_queued) {        
         		interruptible_sleep_on_timeout(&olympic_priv->srb_wait, 60*HZ);
         		if(signal_pending(current))	{            
-				printk(KERN_WARNING "%s: SRB timed out.\n",
+				printk(KERN_WARNING "%s: Signal received in open.\n",
                 			dev->name);
-            			printk(KERN_WARNING "SISR=%x MISR=%x\n",
+            			printk(KERN_WARNING "SISR=%x LISR=%x\n",
                 			readl(olympic_mmio+SISR),
                 			readl(olympic_mmio+LISR));
             			olympic_priv->srb_queued=0;
             			break;
         		}
+			if ((jiffies-t) > 60*HZ) { 
+				printk(KERN_WARNING "%s: SRB timed out. \n",dev->name) ; 
+				olympic_priv->srb_queued=0;
+				break ; 
+			} 
     		}
 		restore_flags(flags);
 #if OLYMPIC_DEBUG
@@ -572,7 +555,8 @@
 
 		skb->dev = dev;
 
-		olympic_priv->olympic_rx_ring[i].buffer = cpu_to_le32(virt_to_bus(skb->data));
+		olympic_priv->olympic_rx_ring[i].buffer = cpu_to_le32(pci_map_single(olympic_priv->pdev, 
+							  skb->data,olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)) ; 
 		olympic_priv->olympic_rx_ring[i].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz); 
 		olympic_priv->rx_ring_skb[i]=skb;
 	}
@@ -583,12 +567,16 @@
 		return -EIO;
 	}
 
-	writel(virt_to_bus(&olympic_priv->olympic_rx_ring[0]), olympic_mmio+RXDESCQ);
-	writel(virt_to_bus(&olympic_priv->olympic_rx_ring[0]), olympic_mmio+RXCDA);
+	olympic_priv->rx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_rx_ring, 
+					 sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
+	writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXDESCQ);
+	writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXCDA);
 	writew(i, olympic_mmio+RXDESCQCNT);
 		
-	writel(virt_to_bus(&olympic_priv->olympic_rx_status_ring[0]), olympic_mmio+RXSTATQ);
-	writel(virt_to_bus(&olympic_priv->olympic_rx_status_ring[0]), olympic_mmio+RXCSA);
+	olympic_priv->rx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_rx_status_ring, 
+						sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
+	writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXSTATQ);
+	writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXCSA);
 	
  	olympic_priv->rx_ring_last_received = OLYMPIC_RX_RING_SIZE - 1;	/* last processed rx status */
 	olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE - 1;  
@@ -597,20 +585,22 @@
 
 #if OLYMPIC_DEBUG 
 	printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
-	printk("RXCSA: %x, rx_status_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio+RXCSA)),&olympic_priv->olympic_rx_status_ring[0]);
+	printk("RXCSA: %x, rx_status_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);
 	printk(" stat_ring[1]: %p, stat_ring[2]: %p, stat_ring[3]: %p\n", &(olympic_priv->olympic_rx_status_ring[1]), &(olympic_priv->olympic_rx_status_ring[2]), &(olympic_priv->olympic_rx_status_ring[3]) );
 	printk(" stat_ring[4]: %p, stat_ring[5]: %p, stat_ring[6]: %p\n", &(olympic_priv->olympic_rx_status_ring[4]), &(olympic_priv->olympic_rx_status_ring[5]), &(olympic_priv->olympic_rx_status_ring[6]) );
 	printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7])  );
 
-	printk("RXCDA: %x, rx_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio+RXCDA)),&olympic_priv->olympic_rx_ring[0]);
+	printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
+	printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr =
+%08x\n",olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; 
 #endif
 
 	writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
 
 #if OLYMPIC_DEBUG 
 	printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
-	printk("RXCSA: %x, rx_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio+RXCSA)),&olympic_priv->olympic_rx_status_ring[0]);
-	printk("RXCDA: %x, rx_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio+RXCDA)),&olympic_priv->olympic_rx_ring[0]);
+	printk("RXCSA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);
+	printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
 #endif 
 
 	writel(SISR_RX_STATUS | SISR_RX_NOBUF,olympic_mmio+SISR_MASK_SUM);
@@ -622,12 +612,16 @@
 		olympic_priv->olympic_tx_ring[i].buffer=0xdeadbeef;
 
 	olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE;
-	writel(virt_to_bus(&olympic_priv->olympic_tx_ring[0]), olympic_mmio+TXDESCQ_1);
-	writel(virt_to_bus(&olympic_priv->olympic_tx_ring[0]), olympic_mmio+TXCDA_1);
+	olympic_priv->tx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_tx_ring,
+					 sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE,PCI_DMA_TODEVICE) ; 
+	writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXDESCQ_1);
+	writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXCDA_1);
 	writew(OLYMPIC_TX_RING_SIZE, olympic_mmio+TXDESCQCNT_1);
 	
-	writel(virt_to_bus(&olympic_priv->olympic_tx_status_ring[0]),olympic_mmio+TXSTATQ_1);
-	writel(virt_to_bus(&olympic_priv->olympic_tx_status_ring[0]),olympic_mmio+TXCSA_1);
+	olympic_priv->tx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_tx_status_ring,
+						sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
+	writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXSTATQ_1);
+	writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXCSA_1);
 	writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXSTATQCNT_1);
 		
 	olympic_priv->tx_ring_free=0; /* next entry in tx ring to use */
@@ -640,33 +634,32 @@
 	printk("SISR MASK: %x\n",readl(olympic_mmio+SISR_MASK));
 #endif
 
-#if OLYMPIC_NETWORK_MONITOR
-	oat = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
-	opt = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
-
-	printk("%s: Node Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, 
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)), 
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+1),
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+2),
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+3),
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+4),
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+5));
-	printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name, 
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), 
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
-		    readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
-
-	printk("%s: NAUN Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, 
+	if (olympic_priv->olympic_network_monitor) { 
+		__u8 *oat ; 
+		__u8 *opt ; 
+		oat = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
+		opt = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
+
+		printk("%s: Node Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, 
+			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)), 
+			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+1),
+			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+2),
+			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+3),
+			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+4),
+			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+5));
+		printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name, 
+			readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), 
+			readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
+			readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
+			readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
+		printk("%s: NAUN Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, 
 			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)),
 			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+1),
 			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+2),
 			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+3),
 			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+4),
 			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+5));
-
-
-#endif 	
+	}
 	
 	netif_start_queue(dev);
 	MOD_INC_USE_COUNT ;
@@ -703,7 +696,6 @@
 		olympic_priv->rx_status_last_received++ ;
 		olympic_priv->rx_status_last_received &= (OLYMPIC_RX_RING_SIZE -1);
 #if OLYMPIC_DEBUG
-		printk(" stat_ring addr: %x \n", &(olympic_priv->olympic_rx_status_ring[olympic_priv->rx_status_last_received]) ); 
 		printk("rx status: %x rx len: %x \n", le32_to_cpu(rx_status->status_buffercnt), le32_to_cpu(rx_status->fragmentcnt_framelen));
 #endif
 		length = le32_to_cpu(rx_status->fragmentcnt_framelen) & 0xffff;
@@ -760,10 +752,17 @@
 						olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
 						rx_ring_last_received = olympic_priv->rx_ring_last_received ;
 						skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ; 
+						/* unmap buffer */
+						pci_unmap_single(olympic_priv->pdev,
+							le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), 
+							olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; 
 						skb_put(skb2,length);
 						skb2->protocol = tr_type_trans(skb2,dev);
-						olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer = cpu_to_le32(virt_to_bus(skb->data));
-						olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz); 
+						olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer = 
+							cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, 
+							olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
+						olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length = 
+							cpu_to_le32(olympic_priv->pkt_buf_sz); 
 						olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ; 
 						netif_rx(skb2) ; 
 					} else {
@@ -773,13 +772,13 @@
 							rx_ring_last_received = olympic_priv->rx_ring_last_received ; 
 							rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]);
 							cpy_length = (i == 1 ? frag_len : le32_to_cpu(rx_desc->res_length)); 
-							memcpy(skb_put(skb, cpy_length), bus_to_virt(le32_to_cpu(rx_desc->buffer)), cpy_length) ; 
+							memcpy(skb_put(skb, cpy_length), olympic_priv->rx_ring_skb[rx_ring_last_received]->data, cpy_length) ;
 						} while (--i) ; 
 		
 						skb->protocol = tr_type_trans(skb,dev);
 						netif_rx(skb) ; 
 					} 
-					dev->last_rx = jiffies ;
+					dev->last_rx = jiffies ; 
 					olympic_priv->olympic_stats.rx_packets++ ; 
 					olympic_priv->olympic_stats.rx_bytes += length ; 
 				} /* if skb == null */
@@ -807,10 +806,15 @@
 	__u32 sisr;
 	__u8 *adapter_check_area ; 
 	
-	sisr=readl(olympic_mmio+SISR_RR) ; /* Reset sisr */ 
-	
+	/* 
+	 *  Read sisr but don't reset it yet. 
+	 *  The indication bit may have been set but the interrupt latch
+	 *  bit may not be set, so we'd lose the interrupt later. 
+	 */ 
+	sisr=readl(olympic_mmio+SISR) ; 
 	if (!(sisr & SISR_MI)) /* Interrupt isn't for us */ 
 		return ;
+	sisr=readl(olympic_mmio+SISR_RR) ;  /* Read & Reset sisr */ 
 
 	spin_lock(&olympic_priv->olympic_lock);
 
@@ -826,15 +830,22 @@
 			olympic_priv->srb_queued=0;
 		} /* SISR_SRB_REPLY */
 
+		/* We shouldn't ever miss the Tx interrupt, but the you never know, hence the loop to ensure
+		   we get all tx completions. */
 		if (sisr & SISR_TX1_EOF) {
-			olympic_priv->tx_ring_last_status++;
-			olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1);
-			olympic_priv->free_tx_ring_entries++;
-			olympic_priv->olympic_stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
-			olympic_priv->olympic_stats.tx_packets++ ; 
-			dev_kfree_skb_irq(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
-			olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=0xdeadbeef;
-			olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0;
+			while(olympic_priv->olympic_tx_status_ring[(olympic_priv->tx_ring_last_status + 1) & (OLYMPIC_TX_RING_SIZE-1)].status) { 
+				olympic_priv->tx_ring_last_status++;
+				olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1);
+				olympic_priv->free_tx_ring_entries++;
+				olympic_priv->olympic_stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
+				olympic_priv->olympic_stats.tx_packets++ ; 
+				pci_unmap_single(olympic_priv->pdev, 
+					le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer), 
+					olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE);
+				dev_kfree_skb_irq(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
+				olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=0xdeadbeef;
+				olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0;
+			}
 			netif_wake_queue(dev);
 		} /* SISR_TX1_EOF */
 	
@@ -843,12 +854,39 @@
 		} /* SISR_RX_STATUS */
 	
 		if (sisr & SISR_ADAPTER_CHECK) {
+			int i ; 
+			netif_stop_queue(dev);
 			printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
 			writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
 			adapter_check_area = (__u8 *)(olympic_mmio+LAPWWO) ; 
 			printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ; 
-			free_irq(dev->irq, dev) ; 
-	
+			/* The adapter is effectively dead, clean up and exit */
+			for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
+				dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
+				if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
+					pci_unmap_single(olympic_priv->pdev, 
+						le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
+						olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
+				}
+				olympic_priv->rx_status_last_received++;
+				olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
+			}
+			/* unmap rings */
+			pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr, 
+				sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
+			pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
+				sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
+
+			pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr, 
+				sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
+			pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, 
+				sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
+
+			free_irq(dev->irq, dev) ;
+			MOD_DEC_USE_COUNT ;
+			dev->stop = NULL ;  
+			spin_unlock(&olympic_priv->olympic_lock) ; 
+			return ; 
 		} /* SISR_ADAPTER_CHECK */
 	
 		if (sisr & SISR_ASB_FREE) {
@@ -878,7 +916,6 @@
 		printk(KERN_WARNING "%s: Unexpected interrupt: %x\n",dev->name, sisr);
 		printk(KERN_WARNING "%s: SISR_MASK: %x\n",dev->name, readl(olympic_mmio+SISR_MASK)) ;
 	} /* One if the interrupts we want */
-
 	writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
 	
 	spin_unlock(&olympic_priv->olympic_lock) ; 
@@ -895,17 +932,15 @@
 	netif_stop_queue(dev);
 	
 	if(olympic_priv->free_tx_ring_entries) {
-		olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer = cpu_to_le32(virt_to_bus(skb->data));
+		olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer = 
+			cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, skb->len,PCI_DMA_TODEVICE));
 		olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length = cpu_to_le32(skb->len | (0x80000000));
 		olympic_priv->tx_ring_skb[olympic_priv->tx_ring_free]=skb;
 		olympic_priv->free_tx_ring_entries--;
 
         	olympic_priv->tx_ring_free++;
         	olympic_priv->tx_ring_free &= (OLYMPIC_TX_RING_SIZE-1);
-
-
 		writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1);
-
 		netif_wake_queue(dev);
 		spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
 		return 0;
@@ -921,7 +956,7 @@
 {
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
     	__u8 *olympic_mmio=olympic_priv->olympic_mmio,*srb;
-	unsigned long flags;
+	unsigned long t,flags;
 	int i;
 
 	netif_stop_queue(dev);
@@ -939,18 +974,21 @@
 	olympic_priv->srb_queued=1;
 
 	writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
-
+	
+	t = jiffies ; 
 	while(olympic_priv->srb_queued) {
 	        interruptible_sleep_on_timeout(&olympic_priv->srb_wait, jiffies+60*HZ);
         	if(signal_pending(current))	{            
-			printk(KERN_WARNING "%s: SRB timed out.\n",
-                		dev->name);
-            		printk(KERN_WARNING "SISR=%x MISR=%x\n",
-                	readl(olympic_mmio+SISR),
-                	readl(olympic_mmio+LISR));
+			printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
+            		printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR));
             		olympic_priv->srb_queued=0;
             		break;
         	}
+		if ((jiffies-t) > 60*HZ) { 
+			printk(KERN_WARNING "%s: SRB timed out. May not be fatal. \n",dev->name) ; 
+			olympic_priv->srb_queued=0;
+			break ; 
+		} 
     	}
 
 	restore_flags(flags) ; 
@@ -959,9 +997,24 @@
 	
 	for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
 		dev_kfree_skb(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
+		if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
+			pci_unmap_single(olympic_priv->pdev, 
+				le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
+				olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
+		}
 		olympic_priv->rx_status_last_received++;
 		olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
 	}
+	/* unmap rings */
+	pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr, 
+		sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
+	pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
+		sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
+
+	pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr, 
+		sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
+	pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, 
+		sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
 
 	/* reset tx/rx fifo's and busmaster logic */
 
@@ -1239,9 +1292,6 @@
 	__u8 fdx_prot_error ; 
 	__u16 next_ptr;
 	int i ; 
-#if OLYMPIC_NETWORK_MONITOR
-	struct trh_hdr *mac_hdr ; 
-#endif
 
 	arb_block = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->arb) ; 
 	asb_block = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->asb) ; 
@@ -1271,8 +1321,7 @@
 #endif 
 		mac_frame = dev_alloc_skb(frame_len) ; 
 		if (!mac_frame) {
-			printk(KERN_WARNING "%s: Memory squeeze, dropping "
-			       "frame.\n", dev->name);
+			printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", dev->name);
 			goto drop_frame;
 		}
 
@@ -1283,19 +1332,19 @@
 			buffer_len = swab16(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); 
 			memcpy_fromio(skb_put(mac_frame, buffer_len), frame_data , buffer_len ) ;
 			next_ptr=readw(buf_ptr+offsetof(struct mac_receive_buffer,next)); 
-
 		} while (next_ptr && (buf_ptr=olympic_priv->olympic_lap + ntohs(next_ptr)));
 
-#if OLYMPIC_NETWORK_MONITOR
-		printk(KERN_WARNING "%s: Received MAC Frame, details: \n",dev->name) ;
-		mac_hdr = (struct trh_hdr *)mac_frame->data ; 
-		printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name , mac_hdr->daddr[0], mac_hdr->daddr[1], mac_hdr->daddr[2], mac_hdr->daddr[3], mac_hdr->daddr[4], mac_hdr->daddr[5]) ; 
-		printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name , mac_hdr->saddr[0], mac_hdr->saddr[1], mac_hdr->saddr[2], mac_hdr->saddr[3], mac_hdr->saddr[4], mac_hdr->saddr[5]) ; 
-#endif
+		if (olympic_priv->olympic_network_monitor) { 
+			struct trh_hdr *mac_hdr ; 
+			printk(KERN_WARNING "%s: Received MAC Frame, details: \n",dev->name) ;
+			mac_hdr = (struct trh_hdr *)mac_frame->data ; 
+			printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name , mac_hdr->daddr[0], mac_hdr->daddr[1], mac_hdr->daddr[2], mac_hdr->daddr[3], mac_hdr->daddr[4], mac_hdr->daddr[5]) ; 
+			printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name , mac_hdr->saddr[0], mac_hdr->saddr[1], mac_hdr->saddr[2], mac_hdr->saddr[3], mac_hdr->saddr[4], mac_hdr->saddr[5]) ; 
+		}
 		mac_frame->dev = dev ; 
 		mac_frame->protocol = tr_type_trans(mac_frame,dev);
 		netif_rx(mac_frame) ; 	
-		dev->last_rx = jiffies ;
+		dev->last_rx = jiffies;
 
 drop_frame:
 		/* Now tell the card we have dealt with the received frame */
@@ -1351,17 +1400,29 @@
 			writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
 			netif_stop_queue(dev);
 			olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ; 
-			
-			olympic_priv->rx_status_last_received++;
-			olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
 			for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
-				dev_kfree_skb(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
+				dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
+				if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
+					pci_unmap_single(olympic_priv->pdev, 
+						le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
+						olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
+				}
 				olympic_priv->rx_status_last_received++;
 				olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
 			}
+			/* unmap rings */
+			pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr, 
+				sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
+			pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
+				sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
+
+			pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr, 
+				sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
+			pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, 
+				sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
 
 			free_irq(dev->irq,dev);
-			
+			dev->stop=NULL;
 			printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ; 
 			MOD_DEC_USE_COUNT ; 
 		} /* If serious error */
@@ -1489,61 +1550,20 @@
 	return 0 ; 
 }
 
-#if OLYMPIC_NETWORK_MONITOR
-#ifdef CONFIG_PROC_FS
 static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
 {
-	struct pci_dev *pci_device = NULL ;
+	struct net_device *dev = (struct net_device *)data ; 
+	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
+	__u8 *oat = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
+	__u8 *opt = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
+	int size = 0 ; 
 	int len=0;
 	off_t begin=0;
 	off_t pos=0;
-	int size;
 	
-	struct net_device *dev;
-
-
 	size = sprintf(buffer, 
-		"IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapters\n");
-	
-	pos+=size;
-	len+=size;
-	
-
-	while((pci_device=pci_find_device(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR_WAKE, pci_device))) {
-	
-		for (dev = dev_base; dev != NULL; dev = dev->next) 
-		{
-			if (dev->base_addr == pci_device->resource[0].start ) { /* Yep, an Olympic device */	
-				size = sprintf_info(buffer+len, dev);
-				len+=size;
-				pos=begin+len;
-				
-				if(pos<offset)
-				{
-					len=0;
-					begin=pos;
-				}
-				if(pos>offset+length)
-					break;
-			} /* if */
-		} /* for */
-	} /* While */
-
-	*start=buffer+(offset-begin);	/* Start of wanted data */
-	len-=(offset-begin);		/* Start slop */
-	if(len>length)
-		len=length;		/* Ending slop */
-	return len;
-}
-
-static int sprintf_info(char *buffer, struct net_device *dev)
-{
-	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
-	__u8 *oat = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
-	__u8 *opt = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
-	int size = 0 ; 
-		
-	size = sprintf(buffer, "\n%6s: Adapter Address   : Node Address      : Functional Addr\n",
+		"IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name);
+	size += sprintf(buffer+size, "\n%6s: Adapter Address   : Node Address      : Functional Addr\n",
  	   dev->name); 
 
 	size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x\n",
@@ -1628,70 +1648,56 @@
 	  readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2),
 	  readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+3));
 
- 
-	return size;
+	len=size;
+	pos=begin+size;
+	if (pos<offset) {
+		len=0;
+		begin=pos;
+	}
+	*start=buffer+(offset-begin);	/* Start of wanted data */
+	len-=(offset-begin);		/* Start slop */
+	if(len>length)
+		len=length;		/* Ending slop */
+	return len;
 }
-#endif
-#endif 
-
-#ifdef MODULE
 
-static struct net_device* dev_olympic[OLYMPIC_MAX_ADAPTERS];
-
-int init_module(void)
+static void __devexit olympic_remove_one(struct pci_dev *pdev) 
 {
-        int i;
-
-#if OLYMPIC_NETWORK_MONITOR
-#ifdef CONFIG_PROC_FS
-	create_proc_read_entry("net/olympic_tr",0,0,olympic_proc_info,NULL); 
-#endif
-#endif
-        for (i = 0; (i<OLYMPIC_MAX_ADAPTERS); i++) {
-		dev_olympic[i] = NULL;
-                dev_olympic[i] = init_trdev(dev_olympic[i], 0);
-                if (dev_olympic[i] == NULL) {
-			if (i == 0)
-                        	return -ENOMEM;
-			break;
-		}
-
-		dev_olympic[i]->init      = &olympic_probe;
+	struct net_device *dev = pdev->driver_data ; 
+	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
 
-	        if (register_trdev(dev_olympic[i]) != 0) {
-			kfree(dev_olympic[i]);
-			dev_olympic[i] = NULL;
-		        if (i == 0) {
-			        printk("Olympic: No IBM PCI Token Ring cards found in system.\n");
-		                return -EIO;
-			} else {
-			       	printk("Olympic: %d IBM PCI Token Ring card(s) found in system.\n",i) ; 
-				return 0;
-			}
-	        }
+	if (olympic_priv->olympic_network_monitor) { 
+		char proc_name[20] ; 
+		strcpy(proc_name,"net/olympic_") ; 
+		strcat(proc_name,dev->name) ;
+		remove_proc_entry(proc_name,NULL); 
 	}
+	unregister_trdev(dev) ; 
+	iounmap(olympic_priv->olympic_mmio) ; 
+	iounmap(olympic_priv->olympic_lap) ; 
+	pci_release_regions(pdev) ; 	
+	kfree(dev) ; 
+}
 
-	return 0;
+static struct pci_driver olympic_driver = { 
+	name:		"olympic",
+	id_table:	olympic_pci_tbl,
+	probe:		olympic_probe,
+	remove:		olympic_remove_one
+};
+
+static int __init olympic_pci_init(void) 
+{
+	return pci_module_init (&olympic_driver) ; 
 }
 
-void cleanup_module(void)
+static void __exit olympic_pci_cleanup(void)
 {
-        int i;
+	return pci_unregister_driver(&olympic_driver) ; 
+}	
+
+
+module_init(olympic_pci_init) ; 
+module_exit(olympic_pci_cleanup) ; 
 
-        for (i = 0; i < OLYMPIC_MAX_ADAPTERS; i++)
-	        if (dev_olympic[i]) {
-			 unregister_trdev(dev_olympic[i]);
-			 release_region(dev_olympic[i]->base_addr, OLYMPIC_IO_SPACE);
-			 kfree(dev_olympic[i]->priv);
-			 kfree(dev_olympic[i]);
-			 dev_olympic[i] = NULL;
-                }
-
-#if OLYMPIC_NETWORK_MONITOR
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry("net/olympic_tr", NULL) ; 
-#endif 
-#endif
-}
-#endif /* MODULE */
 
diff -urN linux-2.4.4-pre4/drivers/net/tokenring/olympic.h linux/drivers/net/tokenring/olympic.h
--- linux-2.4.4-pre4/drivers/net/tokenring/olympic.h	Tue Mar  6 19:28:35 2001
+++ linux/drivers/net/tokenring/olympic.h	Mon Dec  3 22:35:55 2001
@@ -1,6 +1,6 @@
 /*
  *  olympic.h (c) 1999 Peter De Schrijver All Rights Reserved
- *                1999 Mike Phillips (mikep@linuxtr.net)
+ *                1999,2000 Mike Phillips (mikep@linuxtr.net)
  *
  *  Linux driver for IBM PCI tokenring cards based on the olympic and the PIT/PHY chipset.
  *
@@ -251,6 +251,7 @@
 
 	__u8 *olympic_mmio;
 	__u8 *olympic_lap;
+	struct pci_dev *pdev ; 
 	char *olympic_card_name ; 
 
 	spinlock_t olympic_lock ; 
@@ -263,10 +264,12 @@
 	volatile int trb_queued;   /* True if a TRB is posted */
 	wait_queue_head_t trb_wait ; 
 
+	/* These must be on a 4 byte boundary. */
 	struct olympic_rx_desc olympic_rx_ring[OLYMPIC_RX_RING_SIZE];
 	struct olympic_tx_desc olympic_tx_ring[OLYMPIC_TX_RING_SIZE];
 	struct olympic_rx_status olympic_rx_status_ring[OLYMPIC_RX_RING_SIZE];	
 	struct olympic_tx_status olympic_tx_status_ring[OLYMPIC_TX_RING_SIZE];	
+
 	struct sk_buff *tx_ring_skb[OLYMPIC_TX_RING_SIZE], *rx_ring_skb[OLYMPIC_RX_RING_SIZE];	
 	int tx_ring_free, tx_ring_last_status, rx_ring_last_received,rx_status_last_received, free_tx_ring_entries;
 
@@ -274,9 +277,13 @@
 	__u16 olympic_lan_status ;
 	__u8 olympic_ring_speed ;
 	__u16 pkt_buf_sz ; 
-	__u8 olympic_receive_options, olympic_copy_all_options, olympic_message_level;  
+	__u8 olympic_receive_options, olympic_copy_all_options,olympic_message_level, olympic_network_monitor;  
 	__u16 olympic_addr_table_addr, olympic_parms_addr ; 
 	__u8 olympic_laa[6] ; 
+	__u32 rx_ring_dma_addr;
+	__u32 rx_status_ring_dma_addr;
+	__u32 tx_ring_dma_addr;
+	__u32 tx_status_ring_dma_addr;
 };
 
 struct olympic_adapter_addr_table {
diff -urN linux-2.4.4-pre4/drivers/net/tokenring/smctr.c linux/drivers/net/tokenring/smctr.c
--- linux-2.4.4-pre4/drivers/net/tokenring/smctr.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/tokenring/smctr.c	Mon Dec  3 22:35:55 2001
@@ -63,7 +63,7 @@
 #include "smctr_firmware.h"      /* SMC adapter firmware */
 
 static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@turbolinux.com\n";
-static const char *cardname = "smctr";
+static const char cardname[] = "smctr";
 
 
 #define SMCTR_IO_EXTENT   20
@@ -82,7 +82,7 @@
 static int ringspeed;
 
 /* SMC Name of the Adapter. */
-static char *smctr_name = "SMC TokenCard";
+static char smctr_name[] = "SMC TokenCard";
 char *smctr_model = "Unknown";
 
 /* Use 0 for production, 1 for verification, 2 for debug, and
diff -urN linux-2.4.4-pre4/drivers/net/tokenring/tms380tr.c linux/drivers/net/tokenring/tms380tr.c
--- linux-2.4.4-pre4/drivers/net/tokenring/tms380tr.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/tokenring/tms380tr.c	Mon Dec  3 22:35:55 2001
@@ -68,7 +68,7 @@
  */
 
 #ifdef MODULE
-static const char *version = "tms380tr.c: v1.08 14/01/2001 by Christoph Goos, Adam Fritzler\n";
+static const char version[] = "tms380tr.c: v1.08 14/01/2001 by Christoph Goos, Adam Fritzler\n";
 #endif
 
 #ifdef MODULE
diff -urN linux-2.4.4-pre4/drivers/net/tokenring/tmsisa.c linux/drivers/net/tokenring/tmsisa.c
--- linux-2.4.4-pre4/drivers/net/tokenring/tmsisa.c	Tue Mar 20 12:05:00 2001
+++ linux/drivers/net/tokenring/tmsisa.c	Mon Dec  3 22:35:55 2001
@@ -93,7 +93,7 @@
 	struct tms_isa_card *next;
 };
 
-static struct tms_isa_card *tms_isa_card_list = NULL;
+static struct tms_isa_card *tms_isa_card_list;
 
 static int __init tms_isa_probe1(int ioaddr)
 {
@@ -129,7 +129,7 @@
 
 int __init tms_isa_probe(struct net_device *dev)
 {
-        static int versionprinted = 0;
+        static int versionprinted;
 	struct net_local *tp;
 	int j;
 	struct tms_isa_card *card;
diff -urN linux-2.4.4-pre4/drivers/net/tun.c linux/drivers/net/tun.c
--- linux-2.4.4-pre4/drivers/net/tun.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/tun.c	Mon Dec  3 22:35:55 2001
@@ -48,7 +48,7 @@
 #include <asm/uaccess.h>
 
 #ifdef TUN_DEBUG
-static int debug=0;
+static int debug;
 #endif
 
 /* Network device part of the driver */
@@ -147,8 +147,6 @@
 		dev->type = ARPHRD_PPP; 
 		dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
 		dev->tx_queue_len = 10;
-
-		dev_init_buffers(dev);
 		break;
 
 	case TUN_TAP_DEV:
diff -urN linux-2.4.4-pre4/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- linux-2.4.4-pre4/drivers/net/via-rhine.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/via-rhine.c	Mon Dec  3 22:35:55 2001
@@ -69,7 +69,7 @@
 
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1518 effectively disables this feature. */
-static int rx_copybreak = 0;
+static int rx_copybreak;
 
 /* Used to pass the media type, etc.
    Both 'options[]' and 'full_duplex[]' should exist for driver
@@ -477,7 +477,7 @@
 	int i, option;
 	int chip_id = (int) ent->driver_data;
 	static int card_idx = -1;
-	static int did_version = 0;
+	static int did_version;
 	long ioaddr;
 	int io_size;
 	int pci_flags;
diff -urN linux-2.4.4-pre4/drivers/net/wan/cycx_x25.c linux/drivers/net/wan/cycx_x25.c
--- linux-2.4.4-pre4/drivers/net/wan/cycx_x25.c	Tue Mar 20 12:05:01 2001
+++ linux/drivers/net/wan/cycx_x25.c	Mon Dec  3 22:35:55 2001
@@ -492,7 +492,6 @@
         dev->tx_queue_len = 10;
 
 	/* Initialize socket buffers */
-	dev_init_buffers(dev);
 	set_chan_state(dev, WAN_DISCONNECTED);
 
 	return 0;
diff -urN linux-2.4.4-pre4/drivers/net/wan/dlci.c linux/drivers/net/wan/dlci.c
--- linux-2.4.4-pre4/drivers/net/wan/dlci.c	Sat Mar  3 10:55:48 2001
+++ linux/drivers/net/wan/dlci.c	Mon Dec  3 22:35:55 2001
@@ -575,8 +575,6 @@
 	dev->addr_len		= sizeof(short);
 	memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
 
-	dev_init_buffers(dev);
-	
 	return(0);
 }
 
diff -urN linux-2.4.4-pre4/drivers/net/wan/hdlc.c linux/drivers/net/wan/hdlc.c
--- linux-2.4.4-pre4/drivers/net/wan/hdlc.c	Tue Mar  6 19:44:36 2001
+++ linux/drivers/net/wan/hdlc.c	Mon Dec  3 22:35:55 2001
@@ -1292,8 +1292,6 @@
 		pvc->netdev.tx_queue_len = 0;
 		pvc->netdev.flags = IFF_POINTOPOINT;
 
-		dev_init_buffers(&pvc->netdev);
-
 		pvc->master = hdlc;
 		*(u16*)pvc->netdev.dev_addr = htons(dlci);
 		dlci_to_q922(pvc->netdev.broadcast, dlci);
@@ -1393,7 +1391,6 @@
 
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
 
-	dev_init_buffers(dev);
 	return 0;
 }
 
@@ -1423,7 +1420,6 @@
 	if (result != 0)
 		return -EIO;
 
-	dev_init_buffers(dev);
 	MOD_INC_USE_COUNT;
 	return 0;
 }
diff -urN linux-2.4.4-pre4/drivers/net/wan/hostess_sv11.c linux/drivers/net/wan/hostess_sv11.c
--- linux-2.4.4-pre4/drivers/net/wan/hostess_sv11.c	Tue Mar  6 19:44:36 2001
+++ linux/drivers/net/wan/hostess_sv11.c	Mon Dec  3 22:35:55 2001
@@ -347,7 +347,6 @@
 		d->do_ioctl = hostess_ioctl;
 #ifdef LINUX_21			
 		d->neigh_setup = hostess_neigh_setup_dev;
-		dev_init_buffers(d);
 #else
 		d->init = return_0;
 #endif
diff -urN linux-2.4.4-pre4/drivers/net/wan/lapbether.c linux/drivers/net/wan/lapbether.c
--- linux-2.4.4-pre4/drivers/net/wan/lapbether.c	Mon Jan 22 13:32:10 2001
+++ linux/drivers/net/wan/lapbether.c	Mon Dec  3 22:35:55 2001
@@ -400,8 +400,6 @@
                 return -EIO;
         }
 
-	dev_init_buffers(dev);
-
 	dev->hard_start_xmit = lapbeth_xmit;
 	dev->open	     = lapbeth_open;
 	dev->stop	     = lapbeth_close;
diff -urN linux-2.4.4-pre4/drivers/net/wan/sdla.c linux/drivers/net/wan/sdla.c
--- linux-2.4.4-pre4/drivers/net/wan/sdla.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/wan/sdla.c	Mon Dec  3 22:35:55 2001
@@ -1641,8 +1641,6 @@
 	dev->addr_len		= 0;
 	dev->mtu		= SDLA_MAX_MTU;
 
-	dev_init_buffers(dev);
-   
 	flp->activate		= sdla_activate;
 	flp->deactivate		= sdla_deactivate;
 	flp->assoc		= sdla_assoc;
diff -urN linux-2.4.4-pre4/drivers/net/wan/sdla_chdlc.c linux/drivers/net/wan/sdla_chdlc.c
--- linux-2.4.4-pre4/drivers/net/wan/sdla_chdlc.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/wan/sdla_chdlc.c	Mon Dec  3 22:35:55 2001
@@ -152,13 +152,13 @@
 	unsigned short timer_int_enabled;
 	char update_comms_stats;		/* updating comms stats */
 
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	bh_data_t *bh_head;	  	  /* Circular buffer for chdlc_bh */
 	unsigned long  tq_working;
 	volatile int  bh_write;
 	volatile int  bh_read;
 	atomic_t  bh_buff_used;
-      #endif
+#endif
 	
 	unsigned char interface_down;
 
@@ -568,7 +568,7 @@
 	}
 
 	if ((card->tty_opt=conf->tty) == WANOPT_YES){
-              #if defined(LINUX_2_4) || defined(LINUX_2_1)	
+#if defined(LINUX_2_4) || defined(LINUX_2_1)	
 		int err;
 		card->tty_minor = conf->tty_minor;
 
@@ -581,11 +581,11 @@
 		if (err){
 			return err;
 		}
-              #else
+#else
 		printk(KERN_INFO "%s: Error: TTY driver is not supported on 2.0.X kernels!\n",
 				card->devname);	
 		return -EINVAL;  
-              #endif
+#endif
 	}else{
 	
 
@@ -850,7 +850,7 @@
 			min (conf->slarp_timer, MAX_SLARP_REQ_TIMER) :
 			DEFAULT_SLARP_REQ_TIMER;
 
-	      #ifdef LINUX_2_0
+#ifdef LINUX_2_0
 		if (card->u.c.slarp_timer){
 			printk(KERN_INFO 
 				"%s: Error: Dynamic IP support not available for 2.0.X kernels\n",
@@ -859,7 +859,7 @@
 						card->devname);
 		}
 		card->u.c.slarp_timer=0;
-	      #endif	
+#endif	
 
 
 		if (conf->hdlc_streaming == WANOPT_YES) {
@@ -891,48 +891,48 @@
 			} 
 
 		} else if( strcmp(conf->usedby, "API") == 0) {
-                      #if defined(LINUX_2_1) || defined(LINUX_2_4) 
+#if defined(LINUX_2_1) || defined(LINUX_2_4) 
 			card->u.c.usedby = API;
 			printk(KERN_INFO "%s: Running in API mode !\n",
 				wandev->name);
-                      #else
+#else
 			printk(KERN_INFO "%s: API Mode is not supported for kernels lower than 2.2.X!\n",
 				wandev->name);
 			printk(KERN_INFO "%s: Please upgrade to a 2.2.X kernel fro the API support\n",
 				wandev->name);
 	                kfree(chdlc_priv_area);
 			return -EINVAL;
-                      #endif
+#endif
 		}
 	}
 
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	/* Tells us that if this interface is a
          * gateway or not */
 	if ((chdlc_priv_area->gateway = conf->gateway) == WANOPT_YES){
 		printk(KERN_INFO "%s: Interface %s is set as a gateway.\n",
 			card->devname,card->u.c.if_name);
 	}
-      #endif
+#endif
 
 	/* Get Multicast Information */
 	chdlc_priv_area->mc = conf->mc;
 
 	/* prepare network device data space for registration */
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	strcpy(dev->name,card->u.c.if_name);
-      #else
+#else
 	dev->name = (char *)kmalloc(strlen(card->u.c.if_name) + 2, GFP_KERNEL); 
 	sprintf(dev->name, "%s", card->u.c.if_name);
-      #endif
+#endif
 
 	dev->init = &if_init;
 	dev->priv = chdlc_priv_area;
 
 	/* Initialize the polling task routine */
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	chdlc_priv_area->poll_task.next = NULL;
-      #endif
+#endif
 	chdlc_priv_area->poll_task.sync=0;
 	chdlc_priv_area->poll_task.routine = (void*)(void*)chdlc_poll;
 	chdlc_priv_area->poll_task.data = dev;
@@ -962,9 +962,9 @@
 	chdlc_private_area_t* chdlc_priv_area = dev->priv;
 	sdla_t* card = chdlc_priv_area->card;
 	wan_device_t* wandev = &card->wandev;
-      #ifdef LINUX_2_0
+#ifdef LINUX_2_0
 	int i;
-      #endif
+#endif
 
 	/* Initialize device driver entry points */
 	dev->open		= &if_open;
@@ -973,10 +973,10 @@
 	dev->rebuild_header	= &if_rebuild_hdr;
 	dev->hard_start_xmit	= &if_send;
 	dev->get_stats		= &if_stats;
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	dev->tx_timeout		= &if_tx_timeout;
 	dev->watchdog_timeo	= TX_TIMEOUT;
-      #endif
+#endif
 
 	
 	/* Initialize media-specific parameters */
@@ -988,16 +988,16 @@
 		dev->flags 	|= IFF_MULTICAST;
 	}
 	
-      #ifdef LINUX_2_0
+#ifdef LINUX_2_0
 	dev->family		= AF_INET;
-      #endif	
+#endif	
 
 	if (chdlc_priv_area->true_if_encoding){
-	      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 		dev->type	= ARPHRD_HDLC; /* This breaks the tcpdump */
-	      #else
+#else
 		dev->type	= ARPHRD_PPP;
-	      #endif
+#endif
 	}else{
 		dev->type	= ARPHRD_PPP;
 	}
@@ -1024,13 +1024,12 @@
         dev->tx_queue_len = 100;
    
 	/* Initialize socket buffers */
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	dev_init_buffers(dev);
-      #else
+#else
         for (i = 0; i < DEV_NUMBUFFS; ++i)
                 skb_queue_head_init(&dev->buffs[i]);
-      #endif
-
+#endif
 	return 0;
 }
 
@@ -1053,13 +1052,13 @@
 	if (is_dev_running(dev))
 		return -EBUSY;
 
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	/* Initialize the task queue */
 	chdlc_priv_area->tq_working=0;
 
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	chdlc_priv_area->common.wanpipe_task.next = NULL;
-      #endif
+#endif
 	chdlc_priv_area->common.wanpipe_task.sync = 0;
 	chdlc_priv_area->common.wanpipe_task.routine = (void *)(void *)chdlc_bh;
 	chdlc_priv_area->common.wanpipe_task.data = dev;
@@ -1069,18 +1068,18 @@
 	chdlc_priv_area->bh_head = kmalloc((sizeof(bh_data_t)*(MAX_BH_BUFF+1)),GFP_ATOMIC);
 	memset(chdlc_priv_area->bh_head,0,(sizeof(bh_data_t)*(MAX_BH_BUFF+1)));
 	atomic_set(&chdlc_priv_area->bh_buff_used, 0);
-      #endif
+#endif
  
 	do_gettimeofday(&tv);
 	chdlc_priv_area->router_start_time = tv.tv_sec;
 
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	netif_start_queue(dev);
-      #else
+#else
 	dev->interrupt = 0;
 	dev->tbusy = 0;
 	dev->start = 1;
-      #endif
+#endif
 
 	wanpipe_open(card);
 
@@ -1111,7 +1110,7 @@
 	chdlc_private_area_t* chdlc_priv_area = dev->priv;
 	sdla_t* card = chdlc_priv_area->card;
 
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 
 	if (chdlc_priv_area->bh_head){
 		int i;
@@ -1126,12 +1125,12 @@
 		kfree(chdlc_priv_area->bh_head);
 		chdlc_priv_area->bh_head=NULL;
 	}
-      #endif
+#endif
 
 	stop_net_queue(dev);
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	dev->start=0;
-      #endif
+#endif
 	wanpipe_close(card);
 	del_timer(&chdlc_priv_area->poll_delay_timer);
 	return 0;
@@ -1147,7 +1146,7 @@
 		flags->interrupt_info_struct.interrupt_permission = 0;	
 	}
 
-      #if defined(LINUX_2_4) || defined(LINUX_2_1)	
+#if defined(LINUX_2_4) || defined(LINUX_2_1)	
 	if (!tty_init_cnt)
 		return;
 
@@ -1171,7 +1170,7 @@
 		state = &rs_table[card->tty_minor];
 		memset(state,0,sizeof(state));
 	}
-      #endif
+#endif
 	return;
 }
 
@@ -1264,9 +1263,9 @@
 	unsigned long smp_flags;
 	int err=0;
 
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	netif_stop_queue(dev);
-      #endif
+#endif
 	
 	if (skb == NULL){
 		/* If we get here, some higher layer thinks we've missed an
@@ -1279,7 +1278,7 @@
 		return 0;
 	}
 
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	if (dev->tbusy){
 
 		/* If our device stays busy for at least 5 seconds then we will
@@ -1298,7 +1297,7 @@
 		/* unbusy the interface */
 		clear_bit(0,&dev->tbusy);
 	}
-      #endif
+#endif
 
    	if (ntohs(skb->protocol) != htons(PVC_PROT)){
 
@@ -1380,15 +1379,15 @@
 			stop_net_queue(dev);
 		}else{
 			++card->wandev.stats.tx_packets;
-		      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
                         card->wandev.stats.tx_bytes += len;
-		      #endif
+#endif
 			
 			start_net_queue(dev);
 			
-		      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 		 	dev->trans_start = jiffies;
-		      #endif
+#endif
 		}	
 	}
 
@@ -1420,14 +1419,14 @@
 {
 	u32 src_ip_addr;
         u32 broadcast_ip_addr = 0;
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
         struct in_device *in_dev;
-      #endif
+#endif
         /* read the IP source address from the outgoing packet */
         src_ip_addr = *(u32 *)(skb->data + 12);
 
 	/* read the IP broadcast address for the device */
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
         in_dev = dev->ip_ptr;
         if(in_dev != NULL) {
                 struct in_ifaddr *ifa= in_dev->ifa_list;
@@ -1436,9 +1435,9 @@
                 else
                         return 0;
         }
-      #else
+#else
         broadcast_ip_addr = dev->pa_brdaddr;
-      #endif
+#endif
  
         /* check if the IP Source Address is a Broadcast address */
         if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) {
@@ -2028,7 +2027,7 @@
 		flags->interrupt_info_struct.interrupt_permission &=
 			 ~APP_INT_ON_TX_FRAME;
 
-	      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 
 		if (card->tty_opt){
 			wanpipe_tty_trigger_poll(card);
@@ -2043,9 +2042,9 @@
 				wake_net_dev(dev);
 			}
 		}
-	      #else
+#else
 		wake_net_dev(dev);
-	      #endif
+#endif
 		break;
 
 	case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
@@ -2131,7 +2130,7 @@
 
 	len  = rxbuf->frame_length;
 
-      #if defined(LINUX_2_4) || defined(LINUX_2_1)	
+#if defined(LINUX_2_4) || defined(LINUX_2_1)	
 	if (card->tty_opt){
 
 		if (rxbuf->error_flag){	
@@ -2149,7 +2148,7 @@
 		wanpipe_tty_receive(card,addr,len);
 		goto rx_exit;
 	}
-      #endif
+#endif
 
 	dev = card->wandev.dev;
 
@@ -3266,9 +3265,9 @@
 		
 			if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
 				++ card->wandev.stats.tx_packets;
-				#if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 				card->wandev.stats.tx_bytes += len;
-				#endif
+#endif
 			}
 		}
 	} else {	
@@ -3804,11 +3803,11 @@
 	if (test_bit(PERI_CRIT,&card->wandev.critical)){
 		return; 
 	}
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	schedule_task(&chdlc_priv_area->poll_task);
-      #else
+#else
 	queue_task(&chdlc_priv_area->poll_task, &tq_scheduler);
-      #endif
+#endif
 	return;
 }
 
@@ -3856,11 +3855,11 @@
 
 static void wanpipe_tty_trigger_poll(sdla_t *card)
 {
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	schedule_task(&card->tty_task_queue);
-      #else
+#else
 	queue_task(&card->tty_task_queue, &tq_scheduler);
-      #endif
+#endif
 }
 
 static void tty_poll_task (void* data)
@@ -3876,10 +3875,10 @@
 		(tty->ldisc.write_wakeup)(tty);
 	}
 	wake_up_interruptible(&tty->write_wait);
-      #if defined(SERIAL_HAVE_POLL_WAIT) || \
+#if defined(SERIAL_HAVE_POLL_WAIT) || \
          (defined LINUX_2_1 && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15))
 	wake_up_interruptible(&tty->poll_wait);
-      #endif	
+#endif	
 	return;
 }
 
diff -urN linux-2.4.4-pre4/drivers/net/wan/sdla_fr.c linux/drivers/net/wan/sdla_fr.c
--- linux-2.4.4-pre4/drivers/net/wan/sdla_fr.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/wan/sdla_fr.c	Mon Dec  3 22:35:55 2001
@@ -891,27 +891,26 @@
 			
 			chan->common.usedby = BRIDGE;
 			
-                      #if defined(LINUX_2_1) || defined(LINUX_2_4) 
+#if defined(LINUX_2_1) || defined(LINUX_2_4) 
 			printk(KERN_INFO "%s: Running in WANPIPE (BRIDGE) mode.\n", 
 					card->devname);
-                      #else
+#else
 			printk(KERN_INFO "%s: WANPIPE Bridging mode not supported in 2.0.X kernels.\n",
 					card->devname);
 			err = -EPROTONOSUPPORT;
-                      #endif
-			
+#endif
 		}else if( strcmp(conf->usedby, "BRIDGE_N") == 0 ){
 			
 			chan->common.usedby = BRIDGE_NODE;
-			
-                      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+		
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 			printk(KERN_INFO "%s: Running in WANPIPE (BRIDGE_NODE) mode.\n", 
 					card->devname);
-                      #else
+#else
 			printk(KERN_INFO "%s: WANPIPE Bridging mode not supported in 2.0.X kernels.\n",
 					card->devname);
 			err = -EPROTONOSUPPORT;
-                      #endif
+#endif
 		}
 
 		if (!err){
@@ -928,18 +927,18 @@
 
         } else if(strcmp(conf->usedby, "API") == 0){
 
-              #if defined(LINUX_2_1) || defined(LINUX_2_4) 
+#if defined(LINUX_2_1) || defined(LINUX_2_4) 
                 chan->common.usedby = API;
                 printk(KERN_INFO "%s: Running in API mode.\n",
 			wandev->name);
-              #else
+#else
                 printk(KERN_INFO "%s: The API Mode is not supported for"
 				 "kernels lower than 2.2.X !\n",
 					wandev->name);
 		printk(KERN_INFO "%s: Please upgrade to a 2.2.X kernel for the API support\n",
 					wandev->name);
                 err = -EINVAL;
-              #endif
+#endif
         }
 
 	if (err) {
@@ -984,16 +983,16 @@
 	chan->mc = conf->mc;
 
 	if (conf->inarp == WANOPT_YES){
-	      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 		printk(KERN_INFO "%s: Inverse ARP Support Enabled\n",card->devname);
 		chan->inarp = conf->inarp ? INARP_REQUEST : INARP_NONE;
 		chan->inarp_interval = conf->inarp_interval ? conf->inarp_interval : 10;
-	      #else
+#else
 		printk(KERN_INFO "%s: Warning, Inverse ARP Support not available for 2.0.X kernels!\n",
 				card->devname);
 		chan->inarp = INARP_NONE;
 		chan->inarp_interval = 10;
-              #endif
+#endif
 	}else{
 		printk(KERN_INFO "%s: Inverse ARP Support Disabled\n",card->devname);
 		chan->inarp = INARP_NONE;
@@ -1027,12 +1026,17 @@
 	chan->transmit_length = 0;
 
 	/* prepare network device data space for registration */
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	strcpy(dev->name,chan->name);
-      #else
+#else
 	dev->name = (char *)kmalloc(strlen(chan->name) + 2, GFP_KERNEL); 
+	if(dev->name == NULL)
+	{
+		kfree(chan);
+		return -ENOMEM;
+	}
 	sprintf(dev->name, "%s", chan->name);
-      #endif
+#endif
 	
 	dev->init = &if_init;
 	dev->priv = chan;
@@ -1041,9 +1045,9 @@
          * We need a poll routine for each network
          * interface. 
          */
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	chan->fr_poll_task.next = NULL;
-      #endif
+#endif
 	chan->fr_poll_task.sync = 0;
 	chan->fr_poll_task.routine = (void *)(void *)fr_poll;
 	chan->fr_poll_task.data = dev;
@@ -1222,9 +1226,9 @@
 	fr_channel_t* chan = dev->priv;
 	sdla_t* card = chan->card;
 	wan_device_t* wandev = &card->wandev;
-      #ifdef LINUX_2_0
+#ifdef LINUX_2_0
 	int i;
-      #endif
+#endif
 
 	/* Initialize device driver entry points */
 	dev->open		= &if_open;
@@ -1233,16 +1237,15 @@
 	dev->rebuild_header	= &if_rebuild_hdr;
 	dev->hard_start_xmit	= &if_send;
 	dev->get_stats		= &if_stats;
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	dev->tx_timeout		= &if_tx_timeout;
 	dev->watchdog_timeo	= TX_TIMEOUT;
-      #endif
+#endif
 	
 	if (chan->common.usedby == WANPIPE || chan->common.usedby == API){
-		
-              #ifdef LINUX_2_0
+#ifdef LINUX_2_0
 		dev->family = AF_INET;
-              #endif
+#endif
 		/* Initialize media-specific parameters */
 		if (chan->true_if_encoding){
 			dev->type 		= ARPHRD_DLCI;  /* This breaks tcpdump */
@@ -1275,13 +1278,12 @@
         	dev->tx_queue_len = 100;
 
 			/* Initialize socket buffers */
-	      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 		dev_init_buffers(dev);
-	      #else
+#else
 	        for (i = 0; i < DEV_NUMBUFFS; ++i)
 			skb_queue_head_init(&dev->buffs[i]);
-	      #endif
- 
+#endif
 	}else{
 
 		/* Setup the interface for Bridging */
@@ -1321,13 +1323,13 @@
 	if (is_dev_running(dev))
 		return -EBUSY;
 	
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	/* Initialize the task queue */
 	chan->tq_working=0;
 
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	chan->common.wanpipe_task.next = NULL;
-      #endif
+#endif
 	chan->common.wanpipe_task.sync = 0;
 	chan->common.wanpipe_task.routine = (void *)(void *)fr_bh;
 	chan->common.wanpipe_task.data = dev;
@@ -1336,15 +1338,15 @@
 	chan->bh_head = kmalloc((sizeof(bh_data_t)*MAX_BH_BUFF),GFP_ATOMIC);
 	memset(chan->bh_head,0,(sizeof(bh_data_t)*MAX_BH_BUFF));
 	atomic_set(&chan->bh_buff_used, 0);
-      #endif
+#endif
 
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	netif_start_queue(dev);
-      #else	
+#else	
 	dev->interrupt = 0;
 	dev->tbusy = 0;
 	dev->start = 1;
-      #endif
+#endif
 
 	wanpipe_open(card);
 	do_gettimeofday( &tv );
@@ -1374,9 +1376,9 @@
 	}
 
 	stop_net_queue(dev);
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	dev->start=0;
-      #endif
+#endif
 	wanpipe_close(card);
 
 	return 0;
@@ -1397,9 +1399,9 @@
 {
 #endif
 
-      #if defined(LINUX_2_1) || defined(LINUX_2_4) 
+#if defined(LINUX_2_1) || defined(LINUX_2_4) 
 	netdevice_t *dev = skb->dev;
-      #endif
+#endif
 	fr_channel_t* chan = dev->priv;
 	sdla_t* card = chan->card;
 
@@ -1468,9 +1470,9 @@
 
 	chan->drvstats_if_send.if_send_entry++;
 
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	netif_stop_queue(dev);
-      #endif
+#endif
 	
         if (skb == NULL) {             
 		/* if we get here, some higher layer thinks we've missed an
@@ -1509,7 +1511,7 @@
 	}
        	clear_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical);
  
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
     	if (dev->tbusy) {
 
 		/* If our device stays busy for at least 5 seconds then we will
@@ -1530,7 +1532,7 @@
 		chan->drvstats_if_send.if_send_tbusy_timeout ++;
 		dev->tbusy = 0;
     	}
-      #endif
+#endif
 
 	
 	/* Move the if_header() code to here. By inserting frame
@@ -1693,14 +1695,13 @@
 				++chan->ifstats.tx_packets;
 				++card->wandev.stats.tx_packets;
 				
-			      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
                                 chan->ifstats.tx_bytes += skb->len;
                                 card->wandev.stats.tx_bytes += skb->len;
-			      #endif
-				
-			      #ifdef LINUX_2_4
+#endif
+#ifdef LINUX_2_4
 				dev->trans_start = jiffies;
-			      #endif
+#endif
 			}
 		}
 	}
@@ -1789,16 +1790,16 @@
 {
         u32 src_ip_addr;
         u32 broadcast_ip_addr = 0;
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
         struct in_device *in_dev;
-      #endif
+#endif
         fr_channel_t* chan = dev->priv;
  
         /* read the IP source address from the outgoing packet */
         src_ip_addr = *(u32 *)(skb->data + 14);
 
         /* read the IP broadcast address for the device */
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
         in_dev = dev->ip_ptr;
         if(in_dev != NULL) {
                 struct in_ifaddr *ifa= in_dev->ifa_list;
@@ -1807,9 +1808,9 @@
                 else
                         return 0;
         }
-      #else
+#else
         broadcast_ip_addr = dev->pa_brdaddr;
-      #endif
+#endif
 
         /* check if the IP Source Address is a Broadcast address */
         if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) {
@@ -2255,7 +2256,7 @@
 			}
 		}
 
-	#if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	}else if (chan->common.usedby == API) {
 
 		/* We are in API mode. 
@@ -2361,10 +2362,10 @@
 		++chan->ifstats.rx_packets;
 		++card->wandev.stats.rx_packets;
 
-		#if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 		chan->ifstats.rx_bytes += len_incl_hdr;
 		card->wandev.stats.rx_bytes += len_incl_hdr;
-		#endif
+#endif
 	}
 
 rx_done:
@@ -2456,10 +2457,10 @@
 
 		++chan->ifstats.tx_packets;
 		++card->wandev.stats.tx_packets;
-              #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 		chan->ifstats.tx_bytes += chan->transmit_length;
 		card->wandev.stats.tx_bytes += chan->transmit_length;
-              #endif
+#endif
 
 		/* We must free an sk buffer, which we used
 		 * for delayed transmission; Otherwise, the sock
@@ -2469,13 +2470,13 @@
 		chan->delay_skb = NULL;				
         	chan->transmit_length = 0;
 
-	      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 		dev->trans_start = jiffies;
-	      #endif
+#endif
 
-	      #ifdef LINUX_2_0
+#ifdef LINUX_2_0
 		wake_net_dev(dev);
-	      #else
+#else
 		if (is_queue_stopped(dev)){
 			/* If using API, than wakeup socket BH handler */
 			if (chan->common.usedby == API){
@@ -2485,7 +2486,7 @@
 				wake_net_dev(dev);
 			}
 		}
-	      #endif
+#endif
 	}
 
 end_of_tx_intr:
@@ -4712,15 +4713,15 @@
 {
 	if (card->hw.type != SDLA_S514){
 
-	      #if defined(__SMP__) || defined(LINUX_2_4)
+#if defined(__SMP__) || defined(LINUX_2_4)
 		spin_lock_irqsave(&card->wandev.lock, *smp_flags);
-	      #else
+#else
           	disable_irq(card->hw.irq);
-	      #endif
+#endif
 	}else{
-	      #if defined(__SMP__) || defined(LINUX_2_4)
+#if defined(__SMP__) || defined(LINUX_2_4)
 		spin_lock(&card->u.f.if_send_lock);
-	      #endif
+#endif
 	}
 	return;
 }
@@ -4730,15 +4731,15 @@
 {
 	if (card->hw.type != SDLA_S514){
 
-	      #if defined(__SMP__) || defined(LINUX_2_4)
+#if defined(__SMP__) || defined(LINUX_2_4)
 		spin_unlock_irqrestore (&card->wandev.lock, *smp_flags);
-	      #else
+#else
           	enable_irq(card->hw.irq);
-	      #endif
+#endif
 	}else{
-	      #if defined(__SMP__) || defined(LINUX_2_4)
+#if defined(__SMP__) || defined(LINUX_2_4)
 		spin_unlock(&card->u.f.if_send_lock);
-	      #endif
+#endif
 	}
 	return;
 }
@@ -4925,11 +4926,11 @@
 static void trigger_fr_poll (netdevice_t *dev)
 {
 	fr_channel_t* chan = dev->priv;
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	schedule_task(&chan->fr_poll_task);
-      #else
+#else
 	queue_task(&chan->fr_poll_task, &tq_scheduler);
-      #endif
+#endif
 	return;
 }
 
@@ -5301,13 +5302,13 @@
 	 * an Ethernet header */
 	if (op_mode == BRIDGE || op_mode == BRIDGE_NODE){
 
-	      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 
 		/* Encapsulate the packet as a bridged Ethernet frame. */
-              #ifdef DEBUG
+#ifdef DEBUG
 		printk(KERN_INFO "%s: encapsulating skb for frame relay\n", 
 			dev->name);
-              #endif
+#endif
 		
 		chan->fr_header[0] = 0x03;
 		chan->fr_header[1] = 0x00;
@@ -5322,12 +5323,12 @@
 		skb->protocol = ETH_P_802_3;
 		return 8;
 
-	      #else
+#else
 
 		/* BRIDGING is not supported in 2.0.X */
 		return -EINVAL;
 
-	      #endif
+#endif
 	}
 		
 	return 0;
diff -urN linux-2.4.4-pre4/drivers/net/wan/sdla_ppp.c linux/drivers/net/wan/sdla_ppp.c
--- linux-2.4.4-pre4/drivers/net/wan/sdla_ppp.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/wan/sdla_ppp.c	Mon Dec  3 22:35:55 2001
@@ -616,21 +616,26 @@
 	}
 
 	/* prepare network device data space for registration */
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
  	strcpy(dev->name,card->u.p.if_name);
-      #else
+#else
 	dev->name = (char *)kmalloc(strlen(card->u.p.if_name) + 2, GFP_KERNEL); 
+	if(dev->name == NULL)
+	{
+		kfree(ppp_priv_area);
+		return -ENOMEM;
+	}
 	sprintf(dev->name, "%s", card->u.p.if_name);
-      #endif
+#endif
 	
 	dev->init = &if_init;
 	dev->priv = ppp_priv_area;
 	dev->mtu = min(dev->mtu, card->wandev.mtu);
 
 	/* Initialize the polling task routine */
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	ppp_priv_area->poll_task.next = NULL;
-      #endif
+#endif
 	ppp_priv_area->poll_task.sync=0;
 	ppp_priv_area->poll_task.routine = (void*)(void*)ppp_poll;
 	ppp_priv_area->poll_task.data = dev;
@@ -745,9 +750,9 @@
 	ppp_private_area_t *ppp_priv_area = dev->priv;
 	sdla_t *card = ppp_priv_area->card;
 	wan_device_t *wandev = &card->wandev;
-      #ifdef LINUX_2_0
+#ifdef LINUX_2_0
 	int i;
-      #endif
+#endif
 
 	/* Initialize device driver entry points */
 	dev->open		= &if_open;
@@ -756,10 +761,10 @@
 	dev->rebuild_header	= &if_rebuild_hdr;
 	dev->hard_start_xmit	= &if_send;
 	dev->get_stats		= &if_stats;
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	dev->tx_timeout		= &if_tx_timeout;
 	dev->watchdog_timeo	= TX_TIMEOUT;
-      #endif
+#endif
 
 	/* Initialize media-specific parameters */
 	dev->type		= ARPHRD_PPP;	/* ARP h/w type */
@@ -771,9 +776,9 @@
 		dev->flags	|= IFF_MULTICAST;
 	}
 
-      #ifdef LINUX_2_0
+#ifdef LINUX_2_0
 	dev->family		= AF_INET;
-      #endif	
+#endif	
 	dev->mtu		= wandev->mtu;
 	dev->hard_header_len	= PPP_HDR_LEN;	/* media header length */
 
@@ -788,9 +793,9 @@
         dev->tx_queue_len = 100;
    
 	/* Initialize socket buffers */
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	dev_init_buffers(dev);
-      #else
+#else
         for (i = 0; i < DEV_NUMBUFFS; ++i)
                 skb_queue_head_init(&dev->buffs[i]);
       #endif
@@ -817,13 +822,13 @@
 
 	wanpipe_open(card);
 
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	netif_start_queue(dev);
-      #else
+#else
 	dev->interrupt = 0;
 	dev->tbusy = 0;
 	dev->start = 1;
-      #endif
+#endif
 	
 	do_gettimeofday( &tv );
 	ppp_priv_area->router_start_time = tv.tv_sec;
@@ -856,9 +861,9 @@
 	sdla_t *card = ppp_priv_area->card;
 
 	stop_net_queue(dev);
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	dev->start=0;
-      #endif
+#endif
 	wanpipe_close(card);
 
 	del_timer (&ppp_priv_area->poll_delay_timer);
@@ -973,9 +978,9 @@
 	
 	++ppp_priv_area->if_send_stat.if_send_entry;
 
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	netif_stop_queue(dev);
-      #endif
+#endif
 	
 	if (skb == NULL) {
 
@@ -991,7 +996,7 @@
 		return 0;
 	}
 
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	if (dev->tbusy) {
 
 		/* If our device stays busy for at least 5 seconds then we will
@@ -1015,7 +1020,7 @@
 		/* unbusy the card (because only one interface per card)*/
 		dev->tbusy = 0;
 	}	
-      #endif
+#endif
 	
 	sendpacket = skb->data;
 
@@ -1090,15 +1095,13 @@
 		} else {
 			++ppp_priv_area->if_send_stat.if_send_bfr_passed_to_adptr;
 			++card->wandev.stats.tx_packets;
-                      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 			card->wandev.stats.tx_bytes += skb->len;
-                      #endif
+#endif
 			start_net_queue(dev);
-		      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 			dev->trans_start = jiffies;
-		      #endif
-
-
+#endif
 		}
     	}
 	
@@ -1897,9 +1900,9 @@
 				skb->mac.raw  = skb->data;
 
 			    	++card->wandev.stats.rx_packets;
- 			      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 				card->wandev.stats.rx_bytes += skb->len;
-			      #endif
+#endif
 		    		++ppp_priv_area->rx_intr_stat.rx_intr_bfr_passed_to_stack;	
 				netif_rx(skb);
 			}
@@ -2425,13 +2428,13 @@
 			cfg.ip_options		= L_IP_LOCAL_ASSIG |
 						  R_IP_LOCAL_ASSIG | 
 						  ENABLE_IP;
-                      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 			cfg.ip_local		= in_dev->ifa_list->ifa_local;
 			cfg.ip_remote		= in_dev->ifa_list->ifa_address;
-		      #else
+#else
 			cfg.ip_local		= dev->pa_addr;
 			cfg.ip_remote		= dev->pa_dstaddr;
-                      #endif
+#endif
 
 			/* Debugging code used to check that IP addresses
                          * obtained from the kernel are correct */
@@ -2451,7 +2454,7 @@
 	
 		case WANOPT_PPP_PEER:
 
-			#if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 
 			printk(KERN_INFO "%s: PPP IP Mode: PEER\n",card->devname);
 			cfg.ip_options		= L_IP_REMOTE_ASSIG | 
@@ -2461,7 +2464,7 @@
 			cfg.ip_remote		= 0x00;
 			break;
 
-			#else
+#else
 
 			/* No PEER support for 2.0.X kernels, drop down to default
    			 * condition */
@@ -2469,7 +2472,7 @@
 			printk(KERN_INFO "%s: ERROR, PEER mode is not supported in 2.0.X kernels\n",
 						card->devname);
 			
-			#endif
+#endif
 
 		default:
 			printk(KERN_INFO "%s: ERROR: Unsuported PPP Mode Selected\n",
@@ -3057,15 +3060,15 @@
 	ppp_private_area_t *ppp_priv_area = dev->priv;
 	int err;
 
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	struct ifreq if_info;
 	struct sockaddr_in *if_data1, *if_data2;
 	mm_segment_t fs;
-      #else
-	#ifdef _DYNAMIC_ROUTE_20X_SUPPORT_
+#else
+#ifdef _DYNAMIC_ROUTE_20X_SUPPORT_
         struct rtentry route;
-	#endif
-      #endif
+#endif
+#endif
 
 
 	
@@ -3105,7 +3108,7 @@
 
 	err = 0;
 
-      #ifdef _DYNAMIC_ROUTE_20X_SUPPORT_
+#ifdef _DYNAMIC_ROUTE_20X_SUPPORT_
 	dev->pa_dstaddr = ppp_priv_area->ip_remote;
 	dev->pa_addr = ppp_priv_area->ip_local;
 
@@ -3122,7 +3125,7 @@
 	
 	err = ip_rt_new(&route);
 
-      #endif
+#endif
 
 #endif
 
@@ -3307,14 +3310,14 @@
 {
 	u32 src_ip_addr;
         u32 broadcast_ip_addr = 0;
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
         struct in_device *in_dev;
-      #endif
+#endif
         /* read the IP source address from the outgoing packet */
         src_ip_addr = *(u32 *)(skb->data + 12);
 
 	/* read the IP broadcast address for the device */
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
         in_dev = dev->ip_ptr;
         if(in_dev != NULL) {
                 struct in_ifaddr *ifa= in_dev->ifa_list;
@@ -3323,9 +3326,9 @@
                 else
                         return 0;
         }
-      #else
+#else
         broadcast_ip_addr = dev->pa_brdaddr;
-      #endif
+#endif
  
         /* check if the IP Source Address is a Broadcast address */
         if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) {
@@ -3347,20 +3350,20 @@
 
 void s508_lock (sdla_t *card, unsigned long *smp_flags)
 {
-      #if defined(__SMP__) || defined(LINUX_2_4)
+#if defined(__SMP__) || defined(LINUX_2_4)
 	spin_lock_irqsave(&card->wandev.lock, *smp_flags);
-      #else
+#else
 	disable_irq(card->hw.irq);
-      #endif                                                                     
+#endif                                                                     
 }
 
 void s508_unlock (sdla_t *card, unsigned long *smp_flags)
 {
-      #if defined(__SMP__) || defined(LINUX_2_4)
+#if defined(__SMP__) || defined(LINUX_2_4)
         spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
-      #else
+#else
 	enable_irq(card->hw.irq);
-      #endif           
+#endif           
 }
 
 static int read_connection_info (sdla_t *card)
@@ -3683,11 +3686,11 @@
 			return;
 		}
 
-	      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 		schedule_task(&ppp_priv_area->poll_task);
-	      #else
+#else
 		queue_task(&ppp_priv_area->poll_task, &tq_scheduler);
-	      #endif
+#endif
 	}
 	return;
 }
diff -urN linux-2.4.4-pre4/drivers/net/wan/sdla_x25.c linux/drivers/net/wan/sdla_x25.c
--- linux-2.4.4-pre4/drivers/net/wan/sdla_x25.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/wan/sdla_x25.c	Mon Dec  3 22:35:55 2001
@@ -791,9 +791,9 @@
 	
 	init_global_statistics(card);	
 
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	card->u.x.x25_poll_task.next = NULL;
-      #endif
+#endif
 	card->u.x.x25_poll_task.sync=0;
 	card->u.x.x25_poll_task.routine = (void*)(void*)wpx_poll;
 	card->u.x.x25_poll_task.data = card;
@@ -1010,12 +1010,18 @@
 		chan->network_number = 0xDEADBEEF;
 
 	/* prepare network device data space for registration */
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	strcpy(dev->name,chan->name);
-      #else
+#else
 	dev->name = (char *)kmalloc(strlen(chan->name) + 2, GFP_KERNEL); 
+	if(dev->name == NULL)
+	{
+		kfree(chan);
+		dev->priv = NULL;
+		return -ENOMEM;
+	}
 	sprintf(dev->name, "%s", chan->name);
-      #endif
+#endif
 	dev->init = &if_init;
 
 	init_x25_channel_struct(chan);
@@ -1117,9 +1123,9 @@
 	x25_channel_t* chan = dev->priv;
 	sdla_t* card = chan->card;
 	wan_device_t* wandev = &card->wandev;
-      #ifdef LINUX_2_0
+#ifdef LINUX_2_0
 	int i;
-      #endif
+#endif
 
 	/* Initialize device driver entry points */
 	dev->open		= &if_open;
@@ -1129,18 +1135,18 @@
 	dev->hard_start_xmit	= &if_send;
 	dev->get_stats		= &if_stats;
 
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	dev->tx_timeout		= &if_tx_timeout;
 	dev->watchdog_timeo	= TX_TIMEOUT;
-      #endif
+#endif
 
 	/* Initialize media-specific parameters */
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	dev->type		= ARPHRD_PPP;		/* ARP h/w type */
-      #else
+#else
         dev->family             = AF_INET;      /* address family */
         dev->type               = ARPHRD_PPP;   /* no x25 type */
-      #endif
+#endif
 	dev->flags		|= IFF_POINTOPOINT;
 	dev->flags		|= IFF_NOARP;
 
@@ -1168,13 +1174,12 @@
         dev->tx_queue_len = 100;
 
 	/* Initialize socket buffers */
-      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 	dev_init_buffers(dev);	
-      #else
+#else
         for (i = 0; i < DEV_NUMBUFFS; ++i)
                 skb_queue_head_init(&dev->buffs[i]);
-      #endif
-
+#endif
 	/* FIXME Why are we doing this */
 	set_chan_state(dev, WAN_DISCONNECTED);
 	return 0;
@@ -1216,9 +1221,9 @@
 	chan->tq_working = 0;
 
 	/* Initialize the task queue */
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	chan->common.wanpipe_task.next = NULL;
-      #endif
+#endif
 	chan->common.wanpipe_task.sync = 0;
 	chan->common.wanpipe_task.routine = (void *)(void *)x25api_bh;
 	chan->common.wanpipe_task.data = dev;
@@ -1272,14 +1277,13 @@
 	do_gettimeofday( &tv );
 	chan->router_start_time = tv.tv_sec;
 
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	netif_start_queue(dev);
-      #else	
+#else	
 	dev->interrupt = 0;
 	dev->tbusy = 0;
 	dev->start = 1;
-      #endif
-
+#endif
 	return 0;
 }
 
@@ -1312,10 +1316,10 @@
 	unsigned long smp_flags;
 	
 	stop_net_queue(dev);
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	dev->start=0;
-      #endif
-	
+#endif
+
 	if ((chan->common.state == WAN_CONNECTED) || 
 	    (chan->common.state == WAN_CONNECTING)){
 		S508_S514_lock(card, &smp_flags);
@@ -1454,14 +1458,14 @@
 
 	++chan->if_send_stat.if_send_entry;
 
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	netif_stop_queue(dev);
-      #endif
+#endif
 
 	/* No need to check frame length, since socket code
          * will perform the check for us */
 
-      #ifndef LINUX_2_4
+#ifndef LINUX_2_4
 	if (dev->tbusy){
 		netdevice_t *dev2;
 		
@@ -1479,7 +1483,7 @@
 		}
 		++chan->if_send_stat.if_send_tbusy_timeout;
 	}
-      #endif
+#endif
 
 	chan->tick_counter = jiffies;
 	
@@ -1789,9 +1793,9 @@
 		}		
 
 		++chan->ifstats.rx_packets;
-	      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 		chan->ifstats.rx_bytes += skb->len;
-	      #endif
+#endif
 		
 
 		chan->rx_skb = NULL;
@@ -1836,9 +1840,9 @@
 			}
 		}else{
 			skb->mac.raw = skb->data;
-		      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 			chan->ifstats.rx_bytes += skb->len;
-		      #endif
+#endif
 			++chan->ifstats.rx_packets;
 			++chan->rx_intr_stat.rx_intr_bfr_passed_to_stack;
 			netif_rx(skb);
@@ -2339,11 +2343,11 @@
 
 static void trigger_x25_poll(sdla_t *card)
 {
-      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 	schedule_task(&card->u.x.x25_poll_task);
-      #else
+#else
 	queue_task(&card->u.x.x25_poll_task, &tq_scheduler);
-      #endif
+#endif
 }
 
 /*====================================================================
@@ -3104,9 +3108,9 @@
 		break;
 
 	case 0x08:	/* modem failure */
-	#ifndef MODEM_NOT_LOG
+#ifndef MODEM_NOT_LOG
 		printk(KERN_INFO "%s: modem failure!\n", card->devname);
-	#endif MODEM_NOT_LOG
+#endif MODEM_NOT_LOG
 		api_oob_event(card,mb);
 		break;
 
@@ -3763,9 +3767,9 @@
 		case 0x00:	/* success */
 			chan->i_timeout_sofar = jiffies;
 
-		      #ifdef LINUX_2_4
+#ifdef LINUX_2_4
 			dev->trans_start=jiffies;
-		      #endif
+#endif
 			
 			if ((qdm & M_BIT) && !card->u.x.LAPB_hdlc){
 				if (!tx_intr){
@@ -3777,9 +3781,9 @@
 					chan->tx_offset += len;
 
 					++chan->ifstats.tx_packets;
-				      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 					chan->ifstats.tx_bytes += len;
-				      #endif
+#endif
 					
 					if (chan->tx_offset < orig_len){
 						setup_for_delayed_transmit (dev, buff, data_len);
@@ -3792,9 +3796,9 @@
                                          * be X number of times larger than max data size.
 					 */
 					++chan->ifstats.tx_packets;
-				      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 					chan->ifstats.tx_bytes += len;
-				      #endif
+#endif
 					
 					++chan->if_send_stat.if_send_bfr_passed_to_adptr;
 					chan->tx_offset += len;
@@ -3814,9 +3818,9 @@
 				}
 			}else{
 				++chan->ifstats.tx_packets;
-			      #if defined(LINUX_2_1) || defined(LINUX_2_4)
+#if defined(LINUX_2_1) || defined(LINUX_2_4)
 				chan->ifstats.tx_bytes += len;
-			      #endif
+#endif
 				++chan->if_send_stat.if_send_bfr_passed_to_adptr;
 				res=0;
 			}
diff -urN linux-2.4.4-pre4/drivers/net/wan/sdlamain.c linux/drivers/net/wan/sdlamain.c
--- linux-2.4.4-pre4/drivers/net/wan/sdlamain.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/wan/sdlamain.c	Mon Dec  3 22:35:55 2001
@@ -511,11 +511,11 @@
 	if (!card->configured){
 
 		/* Initialize the Spin lock */
-	      #if defined(__SMP__) || defined(LINUX_2_4) 
+#if defined(__SMP__) || defined(LINUX_2_4) 
 		printk(KERN_INFO "%s: Initializing for SMP\n",wandev->name);
-	      #endif
+#endif
 
-		/* Piggiback spin lock has already been initialized,
+		/* Piggyback spin lock has already been initialized,
 		 * in check_s514/s508_conflicts() */
 		if (!card->wandev.piggyback){
 			spin_lock_init(&card->wandev.lock);
@@ -543,7 +543,7 @@
 
 	case SFID_X25_502:
 	case SFID_X25_508:
-		printk(KERN_INFO "%s: Starting x25 Protocol Init.\n",
+		printk(KERN_INFO "%s: Starting X.25 Protocol Init.\n",
 				card->devname);
 		err = wpx_init(card, conf);
 		break;
diff -urN linux-2.4.4-pre4/drivers/net/wan/sealevel.c linux/drivers/net/wan/sealevel.c
--- linux-2.4.4-pre4/drivers/net/wan/sealevel.c	Tue Mar  6 19:44:37 2001
+++ linux/drivers/net/wan/sealevel.c	Mon Dec  3 22:35:55 2001
@@ -375,7 +375,6 @@
 			d->do_ioctl = sealevel_ioctl;
 #ifdef LINUX_21			
 			d->neigh_setup = sealevel_neigh_setup_dev;
-			dev_init_buffers(d);
 #else
 			d->init = return_0;
 #endif
diff -urN linux-2.4.4-pre4/drivers/net/wan/syncppp.c linux/drivers/net/wan/syncppp.c
--- linux-2.4.4-pre4/drivers/net/wan/syncppp.c	Tue Mar  6 19:44:37 2001
+++ linux/drivers/net/wan/syncppp.c	Mon Dec  3 22:35:55 2001
@@ -1048,7 +1048,6 @@
 	dev->hard_header_cache = NULL;
 	dev->header_cache_update = NULL;
 	dev->flags = IFF_MULTICAST|IFF_POINTOPOINT|IFF_NOARP;
-	dev_init_buffers(dev);
 }
 
 EXPORT_SYMBOL(sppp_attach);
diff -urN linux-2.4.4-pre4/drivers/net/wan/wanpipe_multppp.c linux/drivers/net/wan/wanpipe_multppp.c
--- linux-2.4.4-pre4/drivers/net/wan/wanpipe_multppp.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/net/wan/wanpipe_multppp.c	Mon Dec  3 22:35:55 2001
@@ -720,7 +720,6 @@
    
 	/* Initialize socket buffers */
       #if defined(LINUX_2_1) || defined(LINUX_2_4)
-	dev_init_buffers(dev);
       #else
         for (i = 0; i < DEV_NUMBUFFS; ++i)
                 skb_queue_head_init(&dev->buffs[i]);
diff -urN linux-2.4.4-pre4/drivers/net/wan/x25_asy.c linux/drivers/net/wan/x25_asy.c
--- linux-2.4.4-pre4/drivers/net/wan/x25_asy.c	Sat Nov 11 19:02:39 2000
+++ linux/drivers/net/wan/x25_asy.c	Mon Dec  3 22:35:55 2001
@@ -874,8 +874,6 @@
 	dev->type		= ARPHRD_X25;
 	dev->tx_queue_len	= 10;
 
-	dev_init_buffers(dev);
-	
 	/* New-style flags. */
 	dev->flags		= IFF_NOARP;
 
diff -urN linux-2.4.4-pre4/drivers/net/wd.c linux/drivers/net/wd.c
--- linux-2.4.4-pre4/drivers/net/wd.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/wd.c	Mon Dec  3 22:35:55 2001
@@ -24,7 +24,7 @@
 
 */
 
-static const char *version =
+static const char version[] =
 	"wd.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #include <linux/module.h>
@@ -126,7 +126,7 @@
 	int ancient = 0;			/* An old card without config registers. */
 	int word16 = 0;				/* 0 = 8 bit, 1 = 16 bit */
 	const char *model_name;
-	static unsigned version_printed = 0;
+	static unsigned version_printed;
 
 	for (i = 0; i < 8; i++)
 		checksum += inb(ioaddr + 8 + i);
diff -urN linux-2.4.4-pre4/drivers/net/winbond-840.c linux/drivers/net/winbond-840.c
--- linux-2.4.4-pre4/drivers/net/winbond-840.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/winbond-840.c	Mon Dec  3 22:35:55 2001
@@ -67,7 +67,7 @@
 
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1518 effectively disables this feature. */
-static int rx_copybreak = 0;
+static int rx_copybreak;
 
 /* Used to pass the media type, etc.
    Both 'options[]' and 'full_duplex[]' should exist for driver
diff -urN linux-2.4.4-pre4/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c
--- linux-2.4.4-pre4/drivers/net/yellowfin.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/yellowfin.c	Mon Dec  3 22:35:55 2001
@@ -386,7 +386,7 @@
 	struct yellowfin_private *np;
 	int irq;
 	int chip_idx = ent->driver_data;
-	static int find_cnt = 0;
+	static int find_cnt;
 	long ioaddr, real_ioaddr;
 	int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
 	int drv_flags = pci_id_tbl[chip_idx].drv_flags;
diff -urN linux-2.4.4-pre4/drivers/net/zlib.c linux/drivers/net/zlib.c
--- linux-2.4.4-pre4/drivers/net/zlib.c	Sat Mar  3 10:55:47 2001
+++ linux/drivers/net/zlib.c	Mon Dec  3 22:35:55 2001
@@ -2065,7 +2065,7 @@
  */
 local void tr_static_init()
 {
-    static int static_init_done = 0;
+    static int static_init_done;
     int n;        /* iterates over tree elements */
     int bits;     /* bit counter */
     int length;   /* length value */
diff -urN linux-2.4.4-pre4/drivers/net/znet.c linux/drivers/net/znet.c
--- linux-2.4.4-pre4/drivers/net/znet.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/znet.c	Mon Dec  3 22:35:55 2001
@@ -1,6 +1,6 @@
 /* znet.c: An Zenith Z-Note ethernet driver for linux. */
 
-static const char *version = "znet.c:v1.02 9/23/94 becker@cesdis.gsfc.nasa.gov\n";
+static const char version[] = "znet.c:v1.02 9/23/94 becker@cesdis.gsfc.nasa.gov\n";
 
 /*
 	Written by Donald Becker.
diff -urN linux-2.4.4-pre4/drivers/parport/ChangeLog linux/drivers/parport/ChangeLog
--- linux-2.4.4-pre4/drivers/parport/ChangeLog	Mon Dec  3 22:35:45 2001
+++ linux/drivers/parport/ChangeLog	Mon Dec  3 22:35:55 2001
@@ -1,3 +1,10 @@
+2001-04-14  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	Merged:  2001-03-30  Tim Waugh  <twaugh@redhat.com>
+
+        * drivers/parport/parport_pc.c: Make Via SuperIO chipsets behave
+        like everything else with respect to irq= and dma= parameters.
+
 2001-04-08  Tim Waugh  <twaugh@redhat.com>
 
       * parport_pc.c (parport_pc_save_state): Read from the soft copy of
diff -urN linux-2.4.4-pre4/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- linux-2.4.4-pre4/drivers/parport/parport_pc.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/parport/parport_pc.c	Mon Dec  3 22:35:55 2001
@@ -2180,7 +2180,8 @@
 
 
 /* Via support maintained by Jeff Garzik <jgarzik@mandrakesoft.com> */
-static int __devinit sio_via_686a_probe (struct pci_dev *pdev)
+static int __devinit sio_via_686a_probe (struct pci_dev *pdev, int autoirq,
+					 int autodma)
 {
 	u8 tmp;
 	int dma, irq;
@@ -2215,7 +2216,7 @@
 	case 0x378: port2 = 0x778; break;
 	case 0x278: port2 = 0x678; break;
 	default:
-		printk (KERN_INFO "parport_pc: Via 686A weird parport base 0x%X, ignoring\n",
+		printk (KERN_INFO "parport_pc: Weird Via 686A parport base 0x%X, ignoring\n",
 			port1);
 		return 0;
 	}
@@ -2260,6 +2261,14 @@
 	if (!have_eppecp)
 		dma = PARPORT_DMA_NONE;
 
+	/* Let the user (or defaults) steer us away from interrupts and DMA */
+	if (autoirq != PARPORT_IRQ_AUTO) {
+		irq = PARPORT_IRQ_NONE;
+		dma = PARPORT_DMA_NONE;
+	}
+	if (autodma != PARPORT_DMA_AUTO)
+		dma = PARPORT_DMA_NONE;
+
 	/* finally, do the probe with values obtained */
 	if (parport_pc_probe_port (port1, port2, irq, dma, NULL)) {
 		printk (KERN_INFO
@@ -2285,7 +2294,7 @@
 
 /* each element directly indexed from enum list, above */
 static struct parport_pc_superio {
-	int (*probe) (struct pci_dev *pdev);
+	int (*probe) (struct pci_dev *pdev, int autoirq, int autodma);
 } parport_pc_superio_info[] __devinitdata = {
 	{ sio_via_686a_probe, },
 };
@@ -2542,7 +2551,7 @@
 	probe:		parport_pc_pci_probe,
 };
 
-static int __init parport_pc_init_superio (void)
+static int __init parport_pc_init_superio (int autoirq, int autodma)
 {
 #ifdef CONFIG_PCI
 	const struct pci_device_id *id;
@@ -2553,7 +2562,8 @@
 		if (id == NULL || id->driver_data >= last_sio)
 			continue;
 
-		return parport_pc_superio_info[id->driver_data].probe (pdev);
+		return parport_pc_superio_info[id->driver_data].probe
+			(pdev, autoirq, autodma);
 	}
 #endif /* CONFIG_PCI */
 
@@ -2596,7 +2606,7 @@
 #endif
 
 	/* Onboard SuperIO chipsets that show themselves on the PCI bus. */
-	count += parport_pc_init_superio ();
+	count += parport_pc_init_superio (autoirq, autodma);
 
 	/* ISA ports and whatever (see asm/parport.h). */
 	count += parport_pc_find_nonpci_ports (autoirq, autodma);
diff -urN linux-2.4.4-pre4/drivers/pci/pci.c linux/drivers/pci/pci.c
--- linux-2.4.4-pre4/drivers/pci/pci.c	Tue Mar  6 22:44:15 2001
+++ linux/drivers/pci/pci.c	Mon Dec  3 22:35:55 2001
@@ -21,6 +21,7 @@
 #include <linux/spinlock.h>
 #include <linux/pm.h>
 #include <linux/kmod.h>		/* for hotplug_path */
+#include <linux/bitops.h>
 
 #include <asm/page.h>
 #include <asm/dma.h>	/* isa_dma_bridge_buggy */
@@ -286,12 +287,33 @@
 {
 	int err;
 
+	pci_set_power_state(dev, 0);
 	if ((err = pcibios_enable_device(dev)) < 0)
 		return err;
-	pci_set_power_state(dev, 0);
 	return 0;
 }
 
+/**
+ * pci_disable_device - Disable PCI device after use
+ * @dev: PCI device to be disabled
+ *
+ * Signal to the system that the PCI device is not in use by the system
+ * anymore.  Currently this only involves disabling PCI busmastering,
+ * if active.
+ */
+
+void
+pci_disable_device(struct pci_dev *dev)
+{
+	u16 pci_command;
+
+	pci_read_config_word(dev, PCI_COMMAND, &pci_command);
+	if (pci_command & PCI_COMMAND_MASTER) {
+		pci_command &= ~PCI_COMMAND_MASTER;
+		pci_write_config_word(dev, PCI_COMMAND, pci_command);
+	}
+}
+
 int
 pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
 {
@@ -1339,6 +1361,352 @@
 }
 #endif
 
+/*
+ * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
+ * small blocks are easily used by drivers for bus mastering controllers.
+ * This should probably be sharing the guts of the slab allocator.
+ */
+
+struct pci_pool {	/* the pool */
+	struct list_head	page_list;
+	spinlock_t		lock;
+	size_t			blocks_per_page;
+	size_t			size;
+	int			flags;
+	struct pci_dev		*dev;
+	size_t			allocation;
+	char			name [32];
+	wait_queue_head_t	waitq;
+};
+
+struct pci_page {	/* cacheable header for 'allocation' bytes */
+	struct list_head	page_list;
+	void			*vaddr;
+	dma_addr_t		dma;
+	unsigned long		bitmap [0];
+};
+
+#define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
+#define	POOL_POISON_BYTE	0xa7
+
+// #define CONFIG_PCIPOOL_DEBUG
+
+
+/**
+ * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
+ * @name: name of pool, for diagnostics
+ * @pdev: pci device that will be doing the DMA
+ * @size: size of the blocks in this pool.
+ * @align: alignment requirement for blocks; must be a power of two
+ * @allocation: returned blocks won't cross this boundary (or zero)
+ * @flags: SLAB_* flags (not all are supported).
+ *
+ * Returns a pci allocation pool with the requested characteristics, or
+ * null if one can't be created.  Given one of these pools, pci_pool_alloc()
+ * may be used to allocate memory.  Such memory will all have "consistent"
+ * DMA mappings, accessible by the device and its driver without using
+ * cache flushing primitives.  The actual size of blocks allocated may be
+ * larger than requested because of alignment.
+ *
+ * If allocation is nonzero, objects returned from pci_pool_alloc() won't
+ * cross that size boundary.  This is useful for devices which have
+ * addressing restrictions on individual DMA transfers, such as not crossing
+ * boundaries of 4KBytes.
+ */
+struct pci_pool *
+pci_pool_create (const char *name, struct pci_dev *pdev,
+	size_t size, size_t align, size_t allocation, int flags)
+{
+	struct pci_pool		*retval;
+
+	if (align == 0)
+		align = 1;
+	if (size == 0)
+		return 0;
+	else if (size < align)
+		size = align;
+	else if ((size % align) != 0) {
+		size += align + 1;
+		size &= ~(align - 1);
+	}
+
+	if (allocation == 0) {
+		if (PAGE_SIZE < size)
+			allocation = size;
+		else
+			allocation = PAGE_SIZE;
+		// FIXME: round up for less fragmentation
+	} else if (allocation < size)
+		return 0;
+
+	if (!(retval = kmalloc (sizeof *retval, flags)))
+		return retval;
+
+#ifdef	CONFIG_PCIPOOL_DEBUG
+	flags |= SLAB_POISON;
+#endif
+
+	strncpy (retval->name, name, sizeof retval->name);
+	retval->name [sizeof retval->name - 1] = 0;
+
+	retval->dev = pdev;
+	INIT_LIST_HEAD (&retval->page_list);
+	spin_lock_init (&retval->lock);
+	retval->size = size;
+	retval->flags = flags;
+	retval->allocation = allocation;
+	retval->blocks_per_page = allocation / size;
+	init_waitqueue_head (&retval->waitq);
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+	printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n",
+		pdev ? pdev->slot_name : NULL, retval->name, size,
+		retval->blocks_per_page, allocation);
+#endif
+
+	return retval;
+}
+
+
+static struct pci_page *
+pool_alloc_page (struct pci_pool *pool, int mem_flags)
+{
+	struct pci_page	*page;
+	int		mapsize;
+
+	mapsize = pool->blocks_per_page;
+	mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
+	mapsize *= sizeof (long);
+
+	page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
+	if (!page)
+		return 0;
+	page->vaddr = pci_alloc_consistent (pool->dev,
+				pool->allocation, &page->dma);
+	if (page->vaddr) {
+		memset (page->bitmap, ~0, mapsize);	// bit set == free
+		if (pool->flags & SLAB_POISON)
+			memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+		list_add (&page->page_list, &pool->page_list);
+	} else {
+		kfree (page);
+		page = 0;
+	}
+	return page;
+}
+
+
+static inline int
+is_page_busy (int blocks, unsigned long *bitmap)
+{
+	while (blocks > 0) {
+		if (*bitmap++ != ~0)
+			return 1;
+		blocks -= BITS_PER_LONG;
+	}
+	return 0;
+}
+
+static void
+pool_free_page (struct pci_pool *pool, struct pci_page *page)
+{
+	dma_addr_t	dma = page->dma;
+
+	if (pool->flags & SLAB_POISON)
+		memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+	pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
+	list_del (&page->page_list);
+	kfree (page);
+}
+
+
+/**
+ * pci_pool_destroy - destroys a pool of pci memory blocks.
+ * @pool: pci pool that will be destroyed
+ *
+ * Caller guarantees that no more memory from the pool is in use,
+ * and that nothing will try to use the pool after this call.
+ */
+void
+pci_pool_destroy (struct pci_pool *pool)
+{
+	unsigned long		flags;
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+	printk (KERN_DEBUG "pcipool destroy %s/%s\n",
+		pool->dev ? pool->dev->slot_name : NULL,
+		pool->name);
+#endif
+
+	spin_lock_irqsave (&pool->lock, flags);
+	while (!list_empty (&pool->page_list)) {
+		struct pci_page		*page;
+		page = list_entry (pool->page_list.next,
+				struct pci_page, page_list);
+		if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
+			printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
+				pool->dev ? pool->dev->slot_name : NULL,
+				pool->name, page->vaddr);
+			/* leak the still-in-use consistent memory */
+			list_del (&page->page_list);
+			kfree (page);
+		} else
+			pool_free_page (pool, page);
+	}
+	spin_unlock_irqrestore (&pool->lock, flags);
+	kfree (pool);
+}
+
+
+/**
+ * pci_pool_alloc - get a block of consistent memory
+ * @pool: pci pool that will produce the block
+ * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
+ * @handle: pointer to dma address of block
+ *
+ * This returns the kernel virtual address of a currently unused block,
+ * and reports its dma address through the handle.
+ * If such a memory block can't be allocated, null is returned.
+ */
+void *
+pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
+{
+	unsigned long		flags;
+	struct list_head	*entry;
+	struct pci_page		*page;
+	int			map, block;
+	size_t			offset;
+	void			*retval;
+
+restart:
+	spin_lock_irqsave (&pool->lock, flags);
+	list_for_each (entry, &pool->page_list) {
+		int		i;
+		page = list_entry (entry, struct pci_page, page_list);
+		/* only cachable accesses here ... */
+		for (map = 0, i = 0;
+				i < pool->blocks_per_page;
+				i += BITS_PER_LONG, map++) {
+			if (page->bitmap [map] == 0)
+				continue;
+			block = ffs (page->bitmap [map]);
+			if ((i + block) <= pool->blocks_per_page) {
+				block--;
+				clear_bit (block, &page->bitmap [map]);
+				offset = (BITS_PER_LONG * map) + block;
+				offset *= pool->size;
+				goto ready;
+			}
+		}
+	}
+	if (!(page = pool_alloc_page (pool, mem_flags))) {
+		if (mem_flags == SLAB_KERNEL) {
+			DECLARE_WAITQUEUE (wait, current);
+
+			current->state = TASK_INTERRUPTIBLE;
+			add_wait_queue (&pool->waitq, &wait);
+			spin_unlock_irqrestore (&pool->lock, flags);
+
+			schedule_timeout (POOL_TIMEOUT_JIFFIES);
+
+			current->state = TASK_RUNNING;
+			remove_wait_queue (&pool->waitq, &wait);
+			goto restart;
+		}
+		retval = 0;
+		goto done;
+	}
+
+	clear_bit (0, &page->bitmap [0]);
+	offset = 0;
+ready:
+	retval = offset + page->vaddr;
+	*handle = offset + page->dma;
+done:
+	spin_unlock_irqrestore (&pool->lock, flags);
+	return retval;
+}
+
+
+static struct pci_page *
+pool_find_page (struct pci_pool *pool, dma_addr_t dma)
+{
+	unsigned long		flags;
+	struct list_head	*entry;
+	struct pci_page		*page;
+
+	spin_lock_irqsave (&pool->lock, flags);
+	list_for_each (entry, &pool->page_list) {
+		page = list_entry (entry, struct pci_page, page_list);
+		if (dma < page->dma)
+			continue;
+		if (dma < (page->dma + pool->allocation))
+			goto done;
+	}
+	page = 0;
+done:
+	spin_unlock_irqrestore (&pool->lock, flags);
+	return page;
+}
+
+
+/**
+ * pci_pool_free - put block back into pci pool
+ * @pool: the pci pool holding the block
+ * @vaddr: virtual address of block
+ * @dma: dma address of block
+ *
+ * Caller promises neither device nor driver will again touch this block
+ * unless it is first re-allocated.
+ */
+void
+pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
+{
+	struct pci_page		*page;
+	unsigned long		flags;
+	int			map, block;
+
+	if ((page = pool_find_page (pool, dma)) == 0) {
+		printk (KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, vaddr, dma);
+		return;
+	}
+#ifdef	CONFIG_PCIPOOL_DEBUG
+	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
+		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, vaddr, dma);
+		return;
+	}
+#endif
+
+	block = dma - page->dma;
+	block /= pool->size;
+	map = block / BITS_PER_LONG;
+	block %= BITS_PER_LONG;
+
+#ifdef	CONFIG_PCIPOOL_DEBUG
+	if (page->bitmap [map] & (1 << block)) {
+		printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, dma);
+		return;
+	}
+#endif
+	if (pool->flags & SLAB_POISON)
+		memset (vaddr, POOL_POISON_BYTE, pool->size);
+
+	spin_lock_irqsave (&pool->lock, flags);
+	set_bit (block, &page->bitmap [map]);
+	if (waitqueue_active (&pool->waitq))
+		wake_up (&pool->waitq);
+	else if (!is_page_busy (pool->blocks_per_page, page->bitmap))
+		pool_free_page (pool, page);
+	spin_unlock_irqrestore (&pool->lock, flags);
+}
+
+
 void __init pci_init(void)
 {
 	struct pci_dev *dev;
@@ -1381,6 +1749,7 @@
 EXPORT_SYMBOL(pci_devices);
 EXPORT_SYMBOL(pci_root_buses);
 EXPORT_SYMBOL(pci_enable_device);
+EXPORT_SYMBOL(pci_disable_device);
 EXPORT_SYMBOL(pci_find_capability);
 EXPORT_SYMBOL(pci_release_regions);
 EXPORT_SYMBOL(pci_request_regions);
@@ -1420,4 +1789,11 @@
 
 EXPORT_SYMBOL(isa_dma_bridge_buggy);
 EXPORT_SYMBOL(pci_pci_problems);
+
+/* Pool allocator */
+
+EXPORT_SYMBOL (pci_pool_create);
+EXPORT_SYMBOL (pci_pool_destroy);
+EXPORT_SYMBOL (pci_pool_alloc);
+EXPORT_SYMBOL (pci_pool_free);
 
diff -urN linux-2.4.4-pre4/drivers/pci/quirks.c linux/drivers/pci/quirks.c
--- linux-2.4.4-pre4/drivers/pci/quirks.c	Sat Dec 30 11:23:13 2000
+++ linux/drivers/pci/quirks.c	Mon Dec  3 22:35:55 2001
@@ -248,6 +248,20 @@
 }
 
 /*
+ * CardBus controllers have a legacy base address that enables them
+ * to respond as i82365 pcmcia controllers.  We don't want them to
+ * do this even if the Linux CardBus driver is not loaded, because
+ * the Linux i82365 driver does not (and should not) handle CardBus.
+ */
+static void __init quirk_cardbus_legacy(struct pci_dev *dev)
+{
+	if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class)
+		return;
+	pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
+}
+
+
+/*
  *  The main table of quirks.
  */
 
@@ -283,6 +297,7 @@
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_AL,	PCI_DEVICE_ID_AL_M7101,		quirk_ali7101_acpi },
  	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371SB_2,	quirk_piix3_usb },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371AB_2,	quirk_piix3_usb },
+	{ PCI_FIXUP_FINAL,	PCI_ANY_ID,		PCI_ANY_ID,			quirk_cardbus_legacy },
 	{ 0 }
 };
 
diff -urN linux-2.4.4-pre4/drivers/pnp/isapnp.c linux/drivers/pnp/isapnp.c
--- linux-2.4.4-pre4/drivers/pnp/isapnp.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/pnp/isapnp.c	Mon Dec  3 22:35:55 2001
@@ -55,7 +55,7 @@
 struct resource *isapnp_rdp_res;
 
 int isapnp_disable;			/* Disable ISA PnP */
-int isapnp_rdp;			/* Read Data Port */
+int isapnp_rdp;				/* Read Data Port */
 int isapnp_reset = 1;			/* reset all PnP cards (deactivate) */
 int isapnp_skip_pci_scan;		/* skip PCI resource scanning */
 int isapnp_verbose = 1;			/* verbose mode */
@@ -993,10 +993,15 @@
 			header[4], header[5], header[6], header[7], header[8]);
 		printk("checksum = 0x%x\n", checksum);
 #endif
-		if (checksum == 0x00 || checksum != header[8])	/* not valid CSN */
+		/* Don't be strict on the checksum, here !
+                   e.g. 'SCM SwapBox Plug and Play' has header[8]==0 (should be: b7)*/
+		if (header[8] == 0)
+			;
+		else if (checksum == 0x00 || checksum != header[8])	/* not valid CSN */
 			continue;
 		if ((card = isapnp_alloc(sizeof(struct pci_bus))) == NULL)
 			continue;
+
 		card->number = csn;
 		card->vendor = (header[1] << 8) | header[0];
 		card->device = (header[3] << 8) | header[2];
@@ -2197,7 +2202,7 @@
 	 *	so let the user know where.
 	 */
 	 
-	printk("isapnp: Scanning for Pnp cards...\n");
+	printk("isapnp: Scanning for PnP cards...\n");
 	if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
 		isapnp_rdp |= 3;
 		isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");
@@ -2258,5 +2263,86 @@
 	if (isapnp_detected)
 		isapnp_free_all_resources();
 }
+
+#else
+
+/* format is: noisapnp */
+
+static int __init isapnp_setup_disable(char *str)
+{
+	isapnp_disable = 1;
+	return 1;
+}
+
+__setup("noisapnp", isapnp_setup_disable);
+
+/* format is: isapnp=rdp,reset,skip_pci_scan,verbose */
+
+static int __init isapnp_setup_isapnp(char *str)
+{
+	(void)((get_option(&str,&isapnp_rdp) == 2) &&
+	       (get_option(&str,&isapnp_reset) == 2) &&
+	       (get_option(&str,&isapnp_skip_pci_scan) == 2) &&
+	       (get_option(&str,&isapnp_verbose) == 2));
+	return 1;
+}
+
+__setup("isapnp=", isapnp_setup_isapnp);
+
+/* format is: isapnp_reserve_irq=irq1[,irq2] .... */
+
+static int __init isapnp_setup_reserve_irq(char *str)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		if (get_option(&str,&isapnp_reserve_irq[i]) != 2)
+			break;
+	return 1;
+}
+
+__setup("isapnp_reserve_irq=", isapnp_setup_reserve_irq);
+
+/* format is: isapnp_reserve_dma=dma1[,dma2] .... */
+
+static int __init isapnp_setup_reserve_dma(char *str)
+{
+	int i;
+
+	for (i = 0; i < 8; i++)
+		if (get_option(&str,&isapnp_reserve_dma[i]) != 2)
+			break;
+	return 1;
+}
+
+__setup("isapnp_reserve_dma=", isapnp_setup_reserve_dma);
+
+/* format is: isapnp_reserve_io=io1,size1[,io2,size2] .... */
+
+static int __init isapnp_setup_reserve_io(char *str)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		if (get_option(&str,&isapnp_reserve_io[i]) != 2)
+			break;
+	return 1;
+}
+
+__setup("isapnp_reserve_io=", isapnp_setup_reserve_io);
+
+/* format is: isapnp_reserve_mem=mem1,size1[,mem2,size2] .... */
+
+static int __init isapnp_setup_reserve_mem(char *str)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		if (get_option(&str,&isapnp_reserve_mem[i]) != 2)
+			break;
+	return 1;
+}
+
+__setup("isapnp_reserve_mem=", isapnp_setup_reserve_mem);
 
 #endif
diff -urN linux-2.4.4-pre4/drivers/s390/char/tuball.c linux/drivers/s390/char/tuball.c
--- linux-2.4.4-pre4/drivers/s390/char/tuball.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/s390/char/tuball.c	Mon Dec  3 22:35:56 2001
@@ -14,7 +14,7 @@
 #ifndef MODULE
 #include <linux/init.h>
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
-#include "../../../arch/s390/kernel/cpcmd.h"
+#include <asm/cpcmd.h>
 #include <linux/bootmem.h>
 #else
 #include "../../../../arch/s390/kernel/cpcmd.h"
diff -urN linux-2.4.4-pre4/drivers/s390/net/ctcmain.c linux/drivers/s390/net/ctcmain.c
--- linux-2.4.4-pre4/drivers/s390/net/ctcmain.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/s390/net/ctcmain.c	Mon Dec  3 22:35:56 2001
@@ -3252,7 +3252,6 @@
 	dev->type                = ARPHRD_SLIP;
 	dev->tx_queue_len        = 100;
 	SET_DEVICE_START(dev, 1);
-	dev_init_buffers(dev);
 	dev->flags	         = IFF_POINTOPOINT | IFF_NOARP;
 	for (direction = READ; direction <= WRITE; direction++) {
 		if ((ctc_no_auto == 0) || (devno[direction] == -1))
diff -urN linux-2.4.4-pre4/drivers/s390/net/netiucv.c linux/drivers/s390/net/netiucv.c
--- linux-2.4.4-pre4/drivers/s390/net/netiucv.c	Mon Dec  3 22:35:45 2001
+++ linux/drivers/s390/net/netiucv.c	Mon Dec  3 22:35:56 2001
@@ -707,7 +707,6 @@
 	dev->flags = IFF_NOARP | IFF_POINTOPOINT;
 	dev->mtu = 9216;
 
-	dev_init_buffers (dev);
 	pr_debug ("%s: iucv_init  dev@=%p\n", dev->name, dev);
 	return 0;
 }
diff -urN linux-2.4.4-pre4/drivers/sbus/char/sab82532.c linux/drivers/sbus/char/sab82532.c
--- linux-2.4.4-pre4/drivers/sbus/char/sab82532.c	Sun Mar 25 18:14:21 2001
+++ linux/drivers/sbus/char/sab82532.c	Mon Dec  3 22:35:56 2001
@@ -1,4 +1,4 @@
-/* $Id: sab82532.c,v 1.56 2001/03/15 02:11:10 davem Exp $
+/* $Id: sab82532.c,v 1.58 2001/04/17 06:30:36 davem Exp $
  * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -49,7 +49,7 @@
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 256
 
-#define SERIAL_PARANOIA_CHECK
+#undef SERIAL_PARANOIA_CHECK
 #define SERIAL_DO_RESTART
 
 /* Set of debugging defines */
@@ -299,15 +299,15 @@
  * This routine is used by the interrupt handler to schedule
  * processing in the software interrupt portion of the driver.
  */
-static inline void sab82532_sched_event(struct sab82532 *info, int event)
+static void sab82532_sched_event(struct sab82532 *info, int event)
 {
 	info->event |= 1 << event;
 	queue_task(&info->tqueue, &tq_serial);
 	mark_bh(SERIAL_BH);
 }
 
-static inline void receive_chars(struct sab82532 *info,
-				 union sab82532_irq_status *stat)
+static void receive_chars(struct sab82532 *info,
+			  union sab82532_irq_status *stat)
 {
 	struct tty_struct *tty = info->tty;
 	unsigned char buf[32];
@@ -389,8 +389,8 @@
 	queue_task(&tty->flip.tqueue, &tq_timer);
 }
 
-static inline void transmit_chars(struct sab82532 *info,
-				  union sab82532_irq_status *stat)
+static void transmit_chars(struct sab82532 *info,
+			   union sab82532_irq_status *stat)
 {
 	int i;
 
@@ -446,8 +446,8 @@
 	}
 }
 
-static inline void check_status(struct sab82532 *info,
-				union sab82532_irq_status *stat)
+static void check_status(struct sab82532 *info,
+			 union sab82532_irq_status *stat)
 {
 	struct tty_struct *tty = info->tty;
 	int modem_change = 0;
@@ -1887,10 +1887,6 @@
 	       info->count);
 #endif
 
-	info->count++;
-	tty->driver_data = info;
-	info->tty = tty;
-
 	if (!tmp_buf) {
 		page = get_free_page(GFP_KERNEL);
 		if (!page)
@@ -1901,6 +1897,10 @@
 			tmp_buf = (unsigned char *) page;
 	}
 
+	info->count++;
+	tty->driver_data = info;
+	info->tty = tty;
+
 	/*
 	 * If the port is in the middle of closing, bail out now.
 	 */
@@ -2151,7 +2151,7 @@
 
 static inline void __init show_serial_version(void)
 {
-	char *revision = "$Revision: 1.56 $";
+	char *revision = "$Revision: 1.58 $";
 	char *version, *p;
 
 	version = strchr(revision, ' ');
diff -urN linux-2.4.4-pre4/drivers/sbus/char/su.c linux/drivers/sbus/char/su.c
--- linux-2.4.4-pre4/drivers/sbus/char/su.c	Sun Mar 25 18:14:21 2001
+++ linux/drivers/sbus/char/su.c	Mon Dec  3 22:35:56 2001
@@ -1,4 +1,4 @@
-/* $Id: su.c,v 1.45 2001/03/15 02:11:10 davem Exp $
+/* $Id: su.c,v 1.47 2001/04/18 21:06:15 davem Exp $
  * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -11,7 +11,7 @@
 /*
  * Configuration section.
  */
-#define SERIAL_PARANOIA_CHECK
+#undef SERIAL_PARANOIA_CHECK
 #define CONFIG_SERIAL_NOPAUSE_IO	/* Unused on sparc */
 #define SERIAL_DO_RESTART
 
@@ -335,7 +335,7 @@
  * This routine is used by the interrupt handler to schedule
  * processing in the software interrupt portion of the driver.
  */
-static __inline__ void
+static void
 su_sched_event(struct su_struct *info, int event)
 {
 	info->event |= 1 << event;
@@ -343,7 +343,7 @@
 	mark_bh(SERIAL_BH);
 }
 
-static __inline__ void
+static void
 receive_kbd_ms_chars(struct su_struct *info, struct pt_regs *regs, int is_brk)
 {
 	unsigned char status = 0;
@@ -378,7 +378,7 @@
 	} while (status & UART_LSR_DR);
 }
 
-static __inline__ void
+static void
 receive_serial_chars(struct su_struct *info, int *status, struct pt_regs *regs)
 {
 	struct tty_struct *tty = info->tty;
@@ -471,7 +471,7 @@
 		batten_down_hatches();
 }
 
-static __inline__ void
+static void
 transmit_chars(struct su_struct *info, int *intr_done)
 {
 	int count;
@@ -515,7 +515,7 @@
 	}
 }
 
-static __inline__ void
+static void
 check_modem_status(struct su_struct *info)
 {
 	int	status;
@@ -929,7 +929,7 @@
 	restore_flags(flags);
 }
 
-static __inline__ int
+static int
 su_get_baud_rate(struct su_struct *info)
 {
 	static int baud_table[] = {
@@ -2117,7 +2117,7 @@
 /*
  * /proc fs routines....
  */
-static __inline__ int
+static int
 line_info(char *buf, struct su_struct *info)
 {
 	char		stat_buf[30], control, status;
@@ -2220,7 +2220,7 @@
  */
 static __inline__ void __init show_su_version(void)
 {
-	char *revision = "$Revision: 1.45 $";
+	char *revision = "$Revision: 1.47 $";
 	char *version, *p;
 
 	version = strchr(revision, ' ');
@@ -2900,6 +2900,7 @@
 		case 9600:
 		default:
 			cflag |= B9600;
+			baud = 9600;
 			break;
 	}
 	switch (bits) {
diff -urN linux-2.4.4-pre4/drivers/sbus/char/sunserial.c linux/drivers/sbus/char/sunserial.c
--- linux-2.4.4-pre4/drivers/sbus/char/sunserial.c	Sun Mar 25 18:14:21 2001
+++ linux/drivers/sbus/char/sunserial.c	Mon Dec  3 22:35:56 2001
@@ -1,4 +1,4 @@
-/* $Id: sunserial.c,v 1.78 2001/03/21 22:43:11 davem Exp $
+/* $Id: sunserial.c,v 1.79 2001/04/18 21:06:17 davem Exp $
  * serial.c: Serial port driver infrastructure for the Sparc.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -308,7 +308,7 @@
 		case 9600: cflag |= B9600; break;
 		case 19200: cflag |= B19200; break;
 		case 38400: cflag |= B38400; break;
-		default: cflag |= B9600; break;
+		default: baud = 9600; cflag |= B9600; break;
 	}
 
 	switch (bits) {
diff -urN linux-2.4.4-pre4/drivers/sbus/char/zs.c linux/drivers/sbus/char/zs.c
--- linux-2.4.4-pre4/drivers/sbus/char/zs.c	Thu Jan  4 12:50:17 2001
+++ linux/drivers/sbus/char/zs.c	Mon Dec  3 22:35:56 2001
@@ -1,4 +1,4 @@
-/* $Id: zs.c,v 1.61 2001/01/03 08:08:49 ecd Exp $
+/* $Id: zs.c,v 1.63 2001/04/17 06:30:36 davem Exp $
  * zs.c: Zilog serial port driver for the Sparc.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -217,7 +217,7 @@
  * buffer across all the serial ports, since it significantly saves
  * memory if large numbers of serial ports are open.
  */
-static unsigned char tmp_buf[4096]; /* This is cheating */
+static unsigned char *tmp_buf = 0;
 static DECLARE_MUTEX(tmp_buf_sem);
 
 static inline int serial_paranoia_check(struct sun_serial *info,
@@ -252,8 +252,8 @@
  * register access, other machines handle this in hardware via auxiliary
  * flip-flops which implement the settle time we do in software.
  */
-static inline unsigned char read_zsreg(struct sun_zschannel *channel,
-				       unsigned char reg)
+static unsigned char read_zsreg(struct sun_zschannel *channel,
+				unsigned char reg)
 {
 	unsigned char retval;
 
@@ -265,8 +265,8 @@
 	return retval;
 }
 
-static inline void write_zsreg(struct sun_zschannel *channel,
-			       unsigned char reg, unsigned char value)
+static void write_zsreg(struct sun_zschannel *channel,
+			unsigned char reg, unsigned char value)
 {
 	ZSLOG(reg, value, 1);
 	sbus_writeb(reg, &channel->control);
@@ -275,7 +275,7 @@
 	ZSDELAY();
 }
 
-static inline void load_zsregs(struct sun_serial *info, unsigned char *regs)
+static void load_zsregs(struct sun_serial *info, unsigned char *regs)
 {
 	struct sun_zschannel *channel = info->zs_channel;
 	unsigned long flags;
@@ -323,7 +323,7 @@
 
 #define ZS_PUT_CHAR_MAX_DELAY	2000	/* 10 ms */
 
-static inline void zs_put_char(struct sun_zschannel *channel, char ch)
+static void zs_put_char(struct sun_zschannel *channel, char ch)
 {
 	int loops = ZS_PUT_CHAR_MAX_DELAY;
 
@@ -346,7 +346,7 @@
 }
 
 /* Sets or clears DTR/RTS on the requested line */
-static inline void zs_rtsdtr(struct sun_serial *ss, int set)
+static void zs_rtsdtr(struct sun_serial *ss, int set)
 {
 	unsigned long flags;
 
@@ -362,7 +362,7 @@
 	return;
 }
 
-static inline void kgdb_chaninit(struct sun_serial *ss, int intson, int bps)
+static void kgdb_chaninit(struct sun_serial *ss, int intson, int bps)
 {
 	int brg;
 
@@ -475,8 +475,7 @@
  * This routine is used by the interrupt handler to schedule
  * processing in the software interrupt portion of the driver.
  */
-static _INLINE_ void zs_sched_event(struct sun_serial *info,
-				    int event)
+static void zs_sched_event(struct sun_serial *info, int event)
 {
 	info->event |= 1 << event;
 	queue_task(&info->tqueue, &tq_serial);
@@ -487,7 +486,7 @@
 extern void breakpoint(void);  /* For the KGDB frame character */
 #endif
 
-static _INLINE_ void receive_chars(struct sun_serial *info, struct pt_regs *regs)
+static void receive_chars(struct sun_serial *info, struct pt_regs *regs)
 {
 	struct tty_struct *tty = info->tty;
 	unsigned char ch, stat;
@@ -575,7 +574,7 @@
 		queue_task(&tty->flip.tqueue, &tq_timer);
 }
 
-static _INLINE_ void transmit_chars(struct sun_serial *info)
+static void transmit_chars(struct sun_serial *info)
 {
 	struct tty_struct *tty = info->tty;
 
@@ -611,7 +610,7 @@
 	}
 }
 
-static _INLINE_ void status_handle(struct sun_serial *info)
+static void status_handle(struct sun_serial *info)
 {
 	unsigned char status;
 
@@ -655,7 +654,7 @@
 	return;
 }
 
-static _INLINE_ void special_receive(struct sun_serial *info)
+static void special_receive(struct sun_serial *info)
 {
 	struct tty_struct *tty = info->tty;
 	unsigned char ch, stat;
@@ -1153,7 +1152,7 @@
 	if (serial_paranoia_check(info, tty->device, "zs_write"))
 		return 0;
 
-	if (!info || !info->xmit_buf)
+	if (!info || !info->xmit_buf || !tmp_buf)
 		return 0;
 
 	save_flags(flags);
@@ -1863,6 +1862,17 @@
 		printk("zs_open %s%d, tty overwrite.\n", tty->driver.name, info->line);
 		return -EBUSY;
 	}
+
+	if (!tmp_buf) {
+		unsigned long page = get_free_page(GFP_KERNEL);
+		if (!page)
+			return -ENOMEM;
+		if (tmp_buf)
+			free_page(page);
+		else
+			tmp_buf = (unsigned char *) page;
+	}
+
 	info->count++;
 	tty->driver_data = info;
 	info->tty = tty;
@@ -1912,7 +1922,7 @@
 
 static void show_serial_version(void)
 {
-	char *revision = "$Revision: 1.61 $";
+	char *revision = "$Revision: 1.63 $";
 	char *version, *p;
 
 	version = strchr(revision, ' ');
diff -urN linux-2.4.4-pre4/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
--- linux-2.4.4-pre4/drivers/scsi/qlogicfc.c	Mon Dec  3 22:35:46 2001
+++ linux/drivers/scsi/qlogicfc.c	Mon Dec  3 22:35:56 2001
@@ -758,7 +758,7 @@
 
 		        host = scsi_register(tmpt, sizeof(struct isp2x00_hostdata));
 			if (!host) {
-			        printk("qlogicfc%d : could not register host.\n", hostdata->host_id);
+			        printk("qlogicfc%d : could not register host.\n", hosts);
 				continue;
 			}
 			host->max_id = QLOGICFC_MAX_ID + 1;
@@ -771,7 +771,7 @@
 			hostdata->res = pci64_alloc_consistent(pdev, RES_SIZE + REQ_SIZE, &busaddr);
 
 			if (!hostdata->res){
-			        printk("qlogicfc%d : could not allocate memory for request and response queue.\n", hostdata->host_id);
+			        printk("qlogicfc%d : could not allocate memory for request and response queue.\n", hosts);
 				pci64_free_consistent(pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
 			        scsi_unregister(host);
 				continue;
diff -urN linux-2.4.4-pre4/drivers/sound/Config.in linux/drivers/sound/Config.in
--- linux-2.4.4-pre4/drivers/sound/Config.in	Mon Dec  3 22:35:46 2001
+++ linux/drivers/sound/Config.in	Mon Dec  3 22:35:56 2001
@@ -14,11 +14,11 @@
         bool '    Separate rear out jack' CONFIG_SOUND_CMPCI_REAR
     fi
 fi
-dep_tristate '  Creative SBLive! (EMU10K1)' CONFIG_SOUND_EMU10K1 $CONFIG_SOUND
+dep_tristate '  Creative SBLive! (EMU10K1)' CONFIG_SOUND_EMU10K1 $CONFIG_SOUND $CONFIG_PCI
 dep_tristate '  Crystal SoundFusion (CS4280/461x)' CONFIG_SOUND_FUSION $CONFIG_SOUND
 dep_tristate '  Crystal Sound CS4281' CONFIG_SOUND_CS4281 $CONFIG_SOUND
-dep_tristate '  Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND
-dep_tristate '  Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND
+dep_tristate '  Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND $CONFIG_PCI
+dep_tristate '  Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND $CONFIG_PCI
 dep_tristate '  ESS Technology Solo1' CONFIG_SOUND_ESSSOLO1 $CONFIG_SOUND
 dep_tristate '  ESS Maestro, Maestro2, Maestro2E driver' CONFIG_SOUND_MAESTRO $CONFIG_SOUND
 dep_tristate '  ESS Maestro3/Allegro driver (EXPERIMENTAL)' CONFIG_SOUND_MAESTRO3 $CONFIG_SOUND $CONFIG_PCI $CONFIG_EXPERIMENTAL
diff -urN linux-2.4.4-pre4/drivers/sound/cs4281/cs4281_wrapper-24.c linux/drivers/sound/cs4281/cs4281_wrapper-24.c
--- linux-2.4.4-pre4/drivers/sound/cs4281/cs4281_wrapper-24.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/cs4281/cs4281_wrapper-24.c	Mon Dec  3 22:35:56 2001
@@ -40,12 +40,3 @@
 				    (state)->tmpbuff, (state)->dmaaddr_tmpbuff);
 #define cs4x_pgoff(vma) ((vma)->vm_pgoff)
 
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
-	 ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCISMEMORYREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
-	 ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
-#define PCI_GET_DRIVER_DATA pci_get_drvdata
-#define PCI_SET_DRIVER_DATA pci_set_drvdata
-#define PCI_SET_DMA_MASK(pcidev,mask) pcidev->dma_mask = mask
-
diff -urN linux-2.4.4-pre4/drivers/sound/cs4281/cs4281m.c linux/drivers/sound/cs4281/cs4281m.c
--- linux-2.4.4-pre4/drivers/sound/cs4281/cs4281m.c	Mon Dec  3 22:35:46 2001
+++ linux/drivers/sound/cs4281/cs4281m.c	Mon Dec  3 22:35:56 2001
@@ -4294,23 +4294,24 @@
 			 "cs4281: pci_enable_device() failed\n"));
 		return -1;
 	}
-	if (!RSRCISMEMORYREGION(pcidev, 0) ||
-	    !RSRCISMEMORYREGION(pcidev, 1)) {
+	if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM) ||
+	    !(pci_resource_flags(pcidev, 1) & IORESOURCE_MEM)) {
 		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
 			 "cs4281: probe()- Memory region not assigned\n"));
-		return -1;
+		return -ENODEV;
 	}
 	if (pcidev->irq == 0) {
 		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
 			 "cs4281: probe() IRQ not assigned\n"));
-		return -1;
+		return -ENODEV;
 	}
-	if (!pci_dma_supported(pcidev, 0xffffffff)) {
+	dma_mask = 0xffffffff;	/* this enables playback and recording */
+	i = pci_set_dma_mask(pcidev, dma_mask);
+	if (i) {
 		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
 		      "cs4281: probe() architecture does not support 32bit PCI busmaster DMA\n"));
-		return -1;
+		return i;
 	}
-	dma_mask = 0xffffffff;	/* this enables playback and recording */
 	if (!(s = kmalloc(sizeof(struct cs4281_state), GFP_KERNEL))) {
 		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
 		      "cs4281: probe() no memory for state struct.\n"));
@@ -4328,8 +4329,8 @@
 	init_MUTEX(&s->open_sem_adc);
 	init_MUTEX(&s->open_sem_dac);
 	spin_lock_init(&s->lock);
-	s->pBA0phys = RSRCADDRESS(pcidev, 0);
-	s->pBA1phys = RSRCADDRESS(pcidev, 1);
+	s->pBA0phys = pci_resource_start(pcidev, 0);
+	s->pBA1phys = pci_resource_start(pcidev, 1);
 
 	/* Convert phys to linear. */
 	s->pBA0 = ioremap_nocache(s->pBA0phys, 4096);
@@ -4427,8 +4428,7 @@
 	mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long) &val);
 	set_fs(fs);
 
-	PCI_SET_DRIVER_DATA(pcidev, s);
-	PCI_SET_DMA_MASK(pcidev, dma_mask);
+	pci_set_drvdata(pcidev, s);
 	list_add(&s->list, &cs4281_devs);
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
 		"cs4281: probe()- device allocated successfully\n"));
@@ -4457,7 +4457,7 @@
 
 static void __devinit cs4281_remove(struct pci_dev *pci_dev)
 {
-	struct cs4281_state *s = PCI_GET_DRIVER_DATA(pci_dev);
+	struct cs4281_state *s = pci_get_drvdata(pci_dev);
 	// stop DMA controller 
 	synchronize_irq();
 	free_irq(s->irq, s);
@@ -4467,7 +4467,7 @@
 	iounmap(s->pBA1);
 	iounmap(s->pBA0);
 	kfree(s);
-	PCI_SET_DRIVER_DATA(pci_dev,NULL);
+	pci_set_drvdata(pci_dev,NULL);
 	list_del(&s->list);
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
 		 "cs4281: cs4281_remove()-: remove successful\n"));
diff -urN linux-2.4.4-pre4/drivers/sound/emu10k1/audio.c linux/drivers/sound/emu10k1/audio.c
--- linux-2.4.4-pre4/drivers/sound/emu10k1/audio.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/sound/emu10k1/audio.c	Mon Dec  3 22:35:56 2001
@@ -272,7 +272,7 @@
 
 					/* Undo marking the pages as reserved */
 					for (i = 0; i < woinst->buffer.pages; i++)
-						mem_map_reserve(virt_to_page(woinst->buffer.addr[i]));
+						mem_map_unreserve(virt_to_page(woinst->buffer.addr[i]));
 				}
 
 				emu10k1_waveout_close(wave_dev);
@@ -322,7 +322,7 @@
 
 					/* Undo marking the pages as reserved */
 					for (i = 0; i < woinst->buffer.pages; i++)
-						mem_map_reserve(virt_to_page(woinst->buffer.addr[i]));
+						mem_map_unreserve(virt_to_page(woinst->buffer.addr[i]));
 				}
 
 				emu10k1_waveout_close(wave_dev);
@@ -1011,7 +1011,7 @@
 static int emu10k1_audio_open(struct inode *inode, struct file *file)
 {
 	int minor = MINOR(inode->i_rdev);
-	struct emu10k1_card *card;
+	struct emu10k1_card *card=NULL;
 	struct list_head *entry;
 	struct emu10k1_wavedevice *wave_dev;
 
@@ -1204,7 +1204,7 @@
 
 				/* Undo marking the pages as reserved */
 				for (i = 0; i < woinst->buffer.pages; i++)
-					mem_map_reserve(virt_to_page(woinst->buffer.addr[i]));
+					mem_map_unreserve(virt_to_page(woinst->buffer.addr[i]));
 			}
 
 			emu10k1_waveout_close(wave_dev);
diff -urN linux-2.4.4-pre4/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
--- linux-2.4.4-pre4/drivers/sound/i810_audio.c	Mon Dec  3 22:35:46 2001
+++ linux/drivers/sound/i810_audio.c	Mon Dec  3 22:35:56 2001
@@ -1814,11 +1814,7 @@
 	/* stop DMA state machine and free DMA buffers/channels */
 	if(dmabuf->enable == DAC_RUNNING ||
 	   (dmabuf->count && (dmabuf->trigger & PCM_ENABLE_OUTPUT))) {
-		if(drain_dac(state,file->f_mode & O_NDELAY)) {
-			up(&state->open_sem);
-			unlock_kernel();
-			return -EBUSY;
-		}
+		drain_dac(state,0);
 		stop_dac(state);
 	}
 	if(dmabuf->enable & ADC_RUNNING) {
diff -urN linux-2.4.4-pre4/drivers/sound/maestro3.c linux/drivers/sound/maestro3.c
--- linux-2.4.4-pre4/drivers/sound/maestro3.c	Mon Dec  3 22:35:46 2001
+++ linux/drivers/sound/maestro3.c	Mon Dec  3 22:35:56 2001
@@ -2595,17 +2595,15 @@
 
     DPRINTK(DPMOD, "in maestro_install\n");
 
-    if (!pci_dma_supported(pci_dev, M3_PCI_DMA_MASK)) {
+    if (pci_enable_device(pci_dev))
+        return -EIO;
+
+    if (pci_set_dma_mask(pci_dev, M3_PCI_DMA_MASK)) {
         printk(KERN_ERR PFX "architecture does not support limiting to 28bit PCI bus addresses\n");
         return -ENODEV;
     }
         
-    if (pci_enable_device(pci_dev))
-        return -EIO;
-
     pci_set_master(pci_dev);
-
-    pci_dev->dma_mask = M3_PCI_DMA_MASK;
 
     if( (card = kmalloc(sizeof(struct m3_card), GFP_KERNEL)) == NULL) {
         printk(KERN_WARNING PFX "out of memory\n");
diff -urN linux-2.4.4-pre4/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c
--- linux-2.4.4-pre4/drivers/sound/sb_common.c	Fri Feb 16 16:02:37 2001
+++ linux/drivers/sound/sb_common.c	Mon Dec  3 22:35:56 2001
@@ -1227,7 +1227,7 @@
 		if (!ess_midi_init(devc, hw_config))
 			return 0;
 		hw_config->name = "ESS1xxx MPU";
-		devc->midi_irq_cookie = -1;
+		devc->midi_irq_cookie = NULL;
 		if (!probe_mpu401(hw_config))
 			return 0;
 		attach_mpu401(hw_config, owner);
diff -urN linux-2.4.4-pre4/drivers/usb/dc2xx.c linux/drivers/usb/dc2xx.c
--- linux-2.4.4-pre4/drivers/usb/dc2xx.c	Sun Mar 25 18:14:21 2001
+++ linux/drivers/usb/dc2xx.c	Mon Dec  3 22:35:56 2001
@@ -48,7 +48,7 @@
  * 01 Nov, 2000 .. usb_device_id support added by Adam J. Richter
  *
  * Thanks to:  the folk who've provided USB product IDs, sent in
- * patches, and shared their sucesses!
+ * patches, and shared their successes!
  */
 
 #include <linux/config.h>
diff -urN linux-2.4.4-pre4/drivers/usb/hid.h linux/drivers/usb/hid.h
--- linux-2.4.4-pre4/drivers/usb/hid.h	Fri Feb  9 11:30:23 2001
+++ linux/drivers/usb/hid.h	Mon Dec  3 22:35:56 2001
@@ -205,7 +205,7 @@
 };
 
 /*
- * This is the local enviroment. It is resistent up the the next main-item.
+ * This is the local enviroment. It is resistent up the next main-item.
  */
 
 #define HID_MAX_DESCRIPTOR_SIZE		4096
diff -urN linux-2.4.4-pre4/drivers/usb/plusb.c linux/drivers/usb/plusb.c
--- linux-2.4.4-pre4/drivers/usb/plusb.c	Sun Mar 25 18:14:21 2001
+++ linux/drivers/usb/plusb.c	Mon Dec  3 22:35:56 2001
@@ -255,7 +255,7 @@
 /*
  * dequeue_next_skb - submit the first thing on the tx_skb_list to the
  * USB stack.  This function should be called each time we get a new
- * message to send to the other host, or each time a message is sucessfully
+ * message to send to the other host, or each time a message is successfully
  * sent.
  */
 static void dequeue_next_skb(char * func, plusb_t * s)
@@ -393,7 +393,7 @@
 
 /*
  * plusb_write_bulk_complete () - callback after the data has been
- *   sent to the USB device, or a timeout occured.
+ *   sent to the USB device, or a timeout occurred.
  */
 static void plusb_write_bulk_complete(urb_t *purb)
 {
diff -urN linux-2.4.4-pre4/drivers/usb/scanner.c linux/drivers/usb/scanner.c
--- linux-2.4.4-pre4/drivers/usb/scanner.c	Sun Mar 25 18:14:21 2001
+++ linux/drivers/usb/scanner.c	Mon Dec  3 22:35:56 2001
@@ -174,7 +174,7 @@
  *      <flynn@isr.uni-stuttgart.de>.
  *    - Added iVina 1200U ID. Thanks to Dyson Lin <dyson@avision.com.tw>.
  *    - Added access time update for the device file courtesy of Paul
- *      Mackerras <paulus@linuxcare.com>.  This allows a user space daemon
+ *      Mackerras <paulus@samba.org>.  This allows a user space daemon
  *      to turn the lamp off for a Umax 1220U scanner after a prescribed
  *      time.
  *    - Fixed HP S20 ID's.  Thanks to Ruud Linders <rlinders@xs4all.nl>.
@@ -420,7 +420,7 @@
 		dbg("write stats(%d): result:%d this_write:%d partial:%d", scn_minor, result, this_write, partial);
 
 		if (result == -ETIMEDOUT) {	/* NAK -- shouldn't happen */
-			warn("write_scanner: NAK recieved.");
+			warn("write_scanner: NAK received.");
 			ret = result;
 			break;
 		} else if (result < 0) { /* We should not get any I/O errors */
diff -urN linux-2.4.4-pre4/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- linux-2.4.4-pre4/drivers/usb/serial/ftdi_sio.c	Mon Dec  3 22:35:46 2001
+++ linux/drivers/usb/serial/ftdi_sio.c	Mon Dec  3 22:35:56 2001
@@ -422,7 +422,7 @@
 		unsigned char *first_byte = port->write_urb->transfer_buffer;
 
 		/* Was seeing a race here, got a read callback, then write callback before
-		   hitting interuptible_sleep_on  - so wrapping in a wait_queue */
+		   hitting interruptible_sleep_on  - so wrapping in a wait_queue */
 
 		add_wait_queue(&port->write_wait, &wait);
 		set_current_state (TASK_INTERRUPTIBLE);
diff -urN linux-2.4.4-pre4/drivers/usb/serial/visor.h linux/drivers/usb/serial/visor.h
--- linux-2.4.4-pre4/drivers/usb/serial/visor.h	Fri May  5 13:41:30 2000
+++ linux/drivers/usb/serial/visor.h	Mon Dec  3 22:35:56 2001
@@ -29,7 +29,7 @@
 
 /****************************************************************************
  * VISOR_REQUEST_BYTES_AVAILABLE asks the visor for the number of bytes that
- * are available to be transfered to the host for the specified endpoint.
+ * are available to be transferred to the host for the specified endpoint.
  * Currently this is not used, and always returns 0x0001
  ****************************************************************************/
 #define VISOR_REQUEST_BYTES_AVAILABLE		0x01
diff -urN linux-2.4.4-pre4/drivers/usb/storage/sddr09.c linux/drivers/usb/storage/sddr09.c
--- linux-2.4.4-pre4/drivers/usb/storage/sddr09.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/usb/storage/sddr09.c	Mon Dec  3 22:35:56 2001
@@ -182,7 +182,7 @@
 		return US_BULK_TRANSFER_SHORT;
 	}
 
-	US_DEBUGP("Transfered %d of %d bytes\n", act_len, len);
+	US_DEBUGP("Transferred %d of %d bytes\n", act_len, len);
 
 	return US_BULK_TRANSFER_GOOD;
 }
diff -urN linux-2.4.4-pre4/drivers/usb/storage/transport.c linux/drivers/usb/storage/transport.c
--- linux-2.4.4-pre4/drivers/usb/storage/transport.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/usb/storage/transport.c	Mon Dec  3 22:35:56 2001
@@ -635,7 +635,7 @@
 /* Invoke the transport and basic error-handling/recovery methods
  *
  * This is used by the protocol layers to actually send the message to
- * the device and recieve the response.
+ * the device and receive the response.
  */
 void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
 {
@@ -821,7 +821,7 @@
 {
 	struct us_data *us = (struct us_data *)urb->context;
 
-	US_DEBUGP("USB IRQ recieved for device on host %d\n", us->host_no);
+	US_DEBUGP("USB IRQ received for device on host %d\n", us->host_no);
 	US_DEBUGP("-- IRQ data length is %d\n", urb->actual_length);
 	US_DEBUGP("-- IRQ state is %d\n", urb->status);
 	US_DEBUGP("-- Interrupt Status (0x%x, 0x%x)\n",
@@ -1117,7 +1117,7 @@
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
-	/* if the command transfered well, then we go to the data stage */
+	/* if the command transferred well, then we go to the data stage */
 	if (result == 0) {
 		/* send/receive data payload, if there is any */
 		if (bcb.DataTransferLength) {
diff -urN linux-2.4.4-pre4/drivers/usb/storage/transport.h linux/drivers/usb/storage/transport.h
--- linux-2.4.4-pre4/drivers/usb/storage/transport.h	Mon Mar 26 15:49:54 2001
+++ linux/drivers/usb/storage/transport.h	Mon Dec  3 22:35:56 2001
@@ -107,7 +107,7 @@
  * us_bulk_transfer() return codes
  */
 #define US_BULK_TRANSFER_GOOD		0  /* good transfer                 */
-#define US_BULK_TRANSFER_SHORT		1  /* transfered less than expected */
+#define US_BULK_TRANSFER_SHORT		1  /* transferred less than expected */
 #define US_BULK_TRANSFER_FAILED		2  /* transfer died in the middle   */
 #define US_BULK_TRANSFER_ABORTED	3  /* transfer canceled             */
 
diff -urN linux-2.4.4-pre4/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
--- linux-2.4.4-pre4/drivers/usb/usb-ohci.c	Fri Mar 23 11:50:01 2001
+++ linux/drivers/usb/usb-ohci.c	Mon Dec  3 22:35:56 2001
@@ -12,11 +12,15 @@
  * 
  * History:
  * 
+ * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam);
+ 	pci_map_single (db)
+ * 2001/03/21 td and dev/ed allocation uses new pci_pool API (db)
  * 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam)
+ *
  * 2000/09/26 fixed races in removing the private portion of the urb
  * 2000/09/07 disable bulk and control lists when unlinking the last
  *	endpoint descriptor in order to avoid unrecoverable errors on
- *	the Lucent chips.
+ *	the Lucent chips. (rwc@sgi)
  * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some
  *	urb unlink probs, indentation fixes
  * 2000/08/11 various oops fixes mostly affecting iso and cleanup from
@@ -65,8 +69,6 @@
 
 #define OHCI_USE_NPS		// force NoPowerSwitching mode
 // #define OHCI_VERBOSE_DEBUG	/* not always helpful */
-// #define OHCI_MEM_SLAB
-// #define OHCI_MEM_FLAGS	SLAB_POISON	/* no redzones; see mm/slab.c */
 
 #include "usb-ohci.h"
 
@@ -100,10 +102,29 @@
 
 static void urb_free_priv (struct ohci *hc, urb_priv_t * urb_priv)
 {
-	int i;
-
-	for (i = 0; i < urb_priv->length; i++) {
-		if (urb_priv->td [i]) {
+	int		i;
+	int		last = urb_priv->length - 1;
+	struct td	*td;
+
+	for (i = 0; i <= last; i++) {
+		td = urb_priv->td [i];
+		if (td) {
+			int		len;
+			int		dir;
+
+			if ((td->hwINFO & cpu_to_le32 (TD_DP)) == TD_DP_SETUP) {
+				len = 8;
+				dir = PCI_DMA_TODEVICE;
+			} else if (i == last) {
+				len = td->urb->transfer_buffer_length,
+				dir = usb_pipeout (td->urb->pipe)
+					? PCI_DMA_TODEVICE
+					: PCI_DMA_FROMDEVICE;
+			} else
+				len = dir = 0;
+			if (len && td->data_dma)
+				pci_unmap_single (hc->ohci_dev,
+					td->data_dma, len, dir);
 			td_free (hc, urb_priv->td [i]);
 		}
 	}
@@ -118,6 +139,11 @@
 	if (urb_priv) {
 		urb->hcpriv = NULL;
 
+		if (urb->timeout) {
+			list_del (&urb->urb_list);
+			urb->timeout -= jiffies;
+		}
+
 		/* Release int/iso bandwidth */
 		if (urb->bandwidth) {
 			switch (usb_pipetype(urb->pipe)) {
@@ -132,7 +158,7 @@
 			}
 		}
 
-		urb_free_priv ((struct ohci *)urb->dev->bus, urb_priv);
+		urb_free_priv ((struct ohci *)urb->dev->bus->hcpriv, urb_priv);
 		usb_dec_dev_use (urb->dev);
 		urb->dev = NULL;
 	}
@@ -214,7 +240,7 @@
 		    continue;
 		printk (KERN_DEBUG __FILE__ ": %s branch int %2d(%2x):", str, i, i);
 		while (*ed_p != 0 && j--) {
-			ed_t *ed = (ed_t *) bus_to_virt(le32_to_cpup(ed_p));
+			ed_t *ed = dma_to_ed (ohci, le32_to_cpup(ed_p));
 			printk (" ed: %4x;", ed->hwINFO);
 			ed_p = &ed->hwNextED;
 		}
@@ -385,7 +411,7 @@
 
 /* return a request to the completion handler */
  
-static int sohci_return_urb (urb_t * urb)
+static int sohci_return_urb (struct ohci *hc, urb_t * urb)
 {
 	urb_priv_t * urb_priv = urb->hcpriv;
 	urb_t * urbt;
@@ -407,7 +433,15 @@
 
 	switch (usb_pipetype (urb->pipe)) {
   		case PIPE_INTERRUPT:
-			urb->complete (urb); /* call complete and requeue URB */	
+			pci_unmap_single (hc->ohci_dev,
+				urb_priv->td [0]->data_dma,
+				urb->transfer_buffer_length,
+				usb_pipeout (urb->pipe)
+					? PCI_DMA_TODEVICE
+					: PCI_DMA_FROMDEVICE);
+			urb->complete (urb);
+
+			/* implicitly requeued */
   			urb->actual_length = 0;
   			urb->status = USB_ST_URB_PENDING;
   			if (urb_priv->state != URB_DEL)
@@ -417,8 +451,13 @@
 		case PIPE_ISOCHRONOUS:
 			for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next);
 			if (urbt) { /* send the reply and requeue URB */	
+				pci_unmap_single (hc->ohci_dev,
+					urb_priv->td [0]->data_dma,
+					urb->transfer_buffer_length,
+					usb_pipeout (urb->pipe)
+						? PCI_DMA_TODEVICE
+						: PCI_DMA_FROMDEVICE);
 				urb->complete (urb);
-				
 				spin_lock_irqsave (&usb_ed_lock, flags);
 				urb->actual_length = 0;
   				urb->status = USB_ST_URB_PENDING;
@@ -460,6 +499,7 @@
 	int i, size = 0;
 	unsigned long flags;
 	int bustime = 0;
+	int mem_flags = ALLOC_FLAGS;
 	
 	if (!urb->dev || !urb->dev->bus)
 		return -ENODEV;
@@ -489,7 +529,7 @@
 	}
 
 	/* every endpoint has a ed, locate and fill it */
-	if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1))) {
+	if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1, mem_flags))) {
 		usb_dec_dev_use (urb->dev);	
 		return -ENOMEM;
 	}
@@ -534,8 +574,9 @@
 
 	/* allocate the TDs */
 	for (i = 0; i < size; i++) { 
-		urb_priv->td[i] = td_alloc (ohci);
+		urb_priv->td[i] = td_alloc (ohci, mem_flags);
 		if (!urb_priv->td[i]) {
+			urb_priv->length = i;
 			urb_free_priv (ohci, urb_priv);
 			usb_dec_dev_use (urb->dev);	
 			return -ENOMEM;
@@ -569,6 +610,7 @@
 				return bustime;
 			}
 			usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc (urb->pipe));
+			urb->timeout = 0;
 	}
 
 	spin_lock_irqsave (&usb_ed_lock, flags);
@@ -582,6 +624,29 @@
 
 	/* fill the TDs and link it to the ed */
 	td_submit_urb (urb);
+
+	/* maybe add to ordered list of timeouts */
+	if (urb->timeout) {
+		struct list_head	*entry;
+
+		// FIXME:  usb-uhci uses relative timeouts (like this),
+		// while uhci uses absolute ones (probably better).
+		// Pick one solution and change the affected drivers.
+		urb->timeout += jiffies;
+
+		list_for_each (entry, &ohci->timeout_list) {
+			struct urb	*next_urb;
+
+			next_urb = list_entry (entry, struct urb, urb_list);
+			if (time_after_eq (urb->timeout, next_urb->timeout))
+				break;
+		}
+		list_add (&urb->urb_list, entry);
+
+		/* drive timeouts by SF (messy, but works) */
+		writel (OHCI_INTR_SF, &ohci->regs->intrenable);	
+	}
+
 	spin_unlock_irqrestore (&usb_ed_lock, flags);
 
 	return 0;	
@@ -687,18 +752,11 @@
 {
 	struct ohci_device * dev;
 
-	/* FIXME:  ED allocation with pci_consistent memory
-	 * must know the controller ... either pass it in here,
-	 * or decouple ED allocation from dev allocation.
-	 */
-	dev = dev_alloc (NULL);
+	dev = dev_alloc ((struct ohci *) usb_dev->bus->hcpriv, ALLOC_FLAGS);
 	if (!dev)
 		return -ENOMEM;
-		
-	memset (dev, 0, sizeof (*dev));
 
 	usb_dev->hcpriv = dev;
-
 	return 0;
 }
 
@@ -783,7 +841,7 @@
 	}
 
 	/* free device, and associated EDs */
-	dev_free (dev);
+	dev_free (ohci, dev);
 
 	return 0;
 }
@@ -877,9 +935,9 @@
 	case PIPE_CONTROL:
 		ed->hwNextED = 0;
 		if (ohci->ed_controltail == NULL) {
-			writel (virt_to_bus (ed), &ohci->regs->ed_controlhead);
+			writel (ed->dma, &ohci->regs->ed_controlhead);
 		} else {
-			ohci->ed_controltail->hwNextED = cpu_to_le32 (virt_to_bus (ed));
+			ohci->ed_controltail->hwNextED = cpu_to_le32 (ed->dma);
 		}
 		ed->ed_prev = ohci->ed_controltail;
 		if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
@@ -893,9 +951,9 @@
 	case PIPE_BULK:
 		ed->hwNextED = 0;
 		if (ohci->ed_bulktail == NULL) {
-			writel (virt_to_bus (ed), &ohci->regs->ed_bulkhead);
+			writel (ed->dma, &ohci->regs->ed_bulkhead);
 		} else {
-			ohci->ed_bulktail->hwNextED = cpu_to_le32 (virt_to_bus (ed));
+			ohci->ed_bulktail->hwNextED = cpu_to_le32 (ed->dma);
 		}
 		ed->ed_prev = ohci->ed_bulktail;
 		if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
@@ -916,11 +974,11 @@
 		for (i = 0; i < ep_rev (6, interval); i += inter) {
 			inter = 1;
 			for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]); 
-				(*ed_p != 0) && (((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval >= interval); 
-				ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) 
-					inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval);
+				(*ed_p != 0) && ((dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval >= interval); 
+				ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED)) 
+					inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval);
 			ed->hwNextED = *ed_p; 
-			*ed_p = cpu_to_le32 (virt_to_bus (ed));
+			*ed_p = cpu_to_le32 (ed->dma);
 		}
 #ifdef DEBUG
 		ep_print_int_eds (ohci, "LINK_INT");
@@ -931,16 +989,16 @@
 		ed->hwNextED = 0;
 		ed->int_interval = 1;
 		if (ohci->ed_isotail != NULL) {
-			ohci->ed_isotail->hwNextED = cpu_to_le32 (virt_to_bus (ed));
+			ohci->ed_isotail->hwNextED = cpu_to_le32 (ed->dma);
 			ed->ed_prev = ohci->ed_isotail;
 		} else {
 			for ( i = 0; i < 32; i += inter) {
 				inter = 1;
 				for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i)]); 
 					*ed_p != 0; 
-					ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) 
-						inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval);
-				*ed_p = cpu_to_le32 (virt_to_bus (ed));	
+					ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED)) 
+						inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval);
+				*ed_p = cpu_to_le32 (ed->dma);	
 			}	
 			ed->ed_prev = NULL;
 		}	
@@ -984,7 +1042,7 @@
 		if (ohci->ed_controltail == ed) {
 			ohci->ed_controltail = ed->ed_prev;
 		} else {
-			((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
+			(dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
 		}
 		break;
       
@@ -1001,7 +1059,7 @@
 		if (ohci->ed_bulktail == ed) {
 			ohci->ed_bulktail = ed->ed_prev;
 		} else {
-			((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
+			(dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
 		}
 		break;
       
@@ -1012,9 +1070,9 @@
 		for (i = 0; i < ep_rev (6, interval); i += inter) {
 			for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]), inter = 1; 
 				(*ed_p != 0) && (*ed_p != ed->hwNextED); 
-				ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED), 
-				inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval)) {				
-					if(((ed_t *) bus_to_virt (le32_to_cpup (ed_p))) == ed) {
+				ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED), 
+				inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval)) {				
+					if((dma_to_ed (ohci, le32_to_cpup (ed_p))) == ed) {
 			  			*ed_p = ed->hwNextED;		
 			  			break;
 			  		}
@@ -1031,7 +1089,7 @@
 		if (ohci->ed_isotail == ed)
 			ohci->ed_isotail = ed->ed_prev;
 		if (ed->hwNextED != 0) 
-		    ((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
+		    (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
 				    
 		if (ed->ed_prev != NULL) {
 			ed->ed_prev->hwNextED = ed->hwNextED;
@@ -1039,9 +1097,9 @@
 			for (i = 0; i < 32; i++) {
 				for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i)]); 
 						*ed_p != 0; 
-						ed_p = &(((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->hwNextED)) {
-					// inter = ep_rev (6, ((ed_t *) bus_to_virt (le32_to_cpup (ed_p)))->int_interval);
-					if(((ed_t *) bus_to_virt (le32_to_cpup (ed_p))) == ed) {
+						ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED)) {
+					// inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval);
+					if((dma_to_ed (ohci, le32_to_cpup (ed_p))) == ed) {
 						*ed_p = ed->hwNextED;		
 						break;
 					}
@@ -1066,7 +1124,13 @@
  * in all other cases the state is left unchanged
  * the ed info fields are setted anyway even though most of them should not change */
  
-static ed_t * ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int interval, int load)
+static ed_t * ep_add_ed (
+	struct usb_device * usb_dev,
+	unsigned int pipe,
+	int interval,
+	int load,
+	int mem_flags
+)
 {
    	ohci_t * ohci = usb_dev->bus->hcpriv;
 	td_t * td;
@@ -1089,13 +1153,16 @@
 	if (ed->state == ED_NEW) {
 		ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */
   		/* dummy td; end of td list for ed */
-		td = td_alloc (ohci);
-  		if (!td) {
+		td = td_alloc (ohci, mem_flags);
+		/* hash the ed for later reverse mapping */
+ 		if (!td || !hash_add_ed (ohci, (ed_t *)ed)) {
 			/* out of memory */
+		        if (td)
+		            td_free(ohci, td);
 			spin_unlock_irqrestore (&usb_ed_lock, flags);
 			return NULL;
 		}
-		ed->hwTailP = cpu_to_le32 (virt_to_bus (td));
+		ed->hwTailP = cpu_to_le32 (td->td_dma);
 		ed->hwHeadP = ed->hwTailP;	
 		ed->state = ED_UNLINK;
 		ed->type = usb_pipetype (pipe);
@@ -1164,43 +1231,52 @@
  * TD handling functions
  *-------------------------------------------------------------------------*/
 
-/* prepare a TD */
+/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
 
-static void td_fill (unsigned int info, void * data, int len, urb_t * urb, int index)
+static void
+td_fill (ohci_t * ohci, unsigned int info,
+	dma_addr_t data, int len,
+	urb_t * urb, int index)
 {
 	volatile td_t  * td, * td_pt;
 	urb_priv_t * urb_priv = urb->hcpriv;
-
+	
 	if (index >= urb_priv->length) {
 		err("internal OHCI error: TD index > length");
 		return;
 	}
 	
+	/* use this td as the next dummy */
 	td_pt = urb_priv->td [index];
+	td_pt->hwNextTD = 0;
+
 	/* fill the old dummy TD */
-	td = urb_priv->td [index] = (td_t *)
-		bus_to_virt (le32_to_cpup (&urb_priv->ed->hwTailP) & 0xfffffff0);
+	td = urb_priv->td [index] = dma_to_td (ohci,
+			le32_to_cpup (&urb_priv->ed->hwTailP) & ~0xf);
+
 	td->ed = urb_priv->ed;
 	td->next_dl_td = NULL;
 	td->index = index;
 	td->urb = urb; 
+	td->data_dma = data;
+	if (!len)
+		data = 0;
+
 	td->hwINFO = cpu_to_le32 (info);
 	if ((td->ed->type) == PIPE_ISOCHRONOUS) {
-		td->hwCBP = cpu_to_le32 (((!data || !len)
-			? 0
-			: virt_to_bus (data)) & 0xFFFFF000);
+		td->hwCBP = cpu_to_le32 (data & 0xFFFFF000);
 		td->ed->last_iso = info & 0xffff;
 	} else {
-		td->hwCBP = cpu_to_le32 (((!data || !len)
-			? 0
-			: virt_to_bus (data))); 
+		td->hwCBP = cpu_to_le32 (data); 
 	}			
-	td->hwBE = cpu_to_le32 ((!data || !len )
-		? 0
-		: virt_to_bus (data + len - 1));
-	td->hwNextTD = cpu_to_le32 (virt_to_bus (td_pt));
-	td->hwPSW [0] = cpu_to_le16 ((virt_to_bus (data) & 0x0FFF) | 0xE000);
-	td_pt->hwNextTD = 0;
+	if (data)
+		td->hwBE = cpu_to_le32 (data + len - 1);
+	else
+		td->hwBE = 0;
+	td->hwNextTD = cpu_to_le32 (td_pt->td_dma);
+	td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000);
+
+	/* append to queue */
 	td->ed->hwTailP = td->hwNextTD;
 }
 
@@ -1212,8 +1288,7 @@
 { 
 	urb_priv_t * urb_priv = urb->hcpriv;
 	ohci_t * ohci = (ohci_t *) urb->dev->bus->hcpriv;
-	void * ctrl = urb->setup_packet;
-	void * data = urb->transfer_buffer;
+	dma_addr_t data;
 	int data_len = urb->transfer_buffer_length;
 	int cnt = 0; 
 	__u32 info = 0;
@@ -1228,18 +1303,28 @@
 	}
 	
 	urb_priv->td_cnt = 0;
+
+	if (data_len) {
+		data = pci_map_single (ohci->ohci_dev,
+			urb->transfer_buffer, data_len,
+			usb_pipeout (urb->pipe)
+				? PCI_DMA_TODEVICE
+				: PCI_DMA_FROMDEVICE
+			);
+	} else
+		data = 0;
 	
 	switch (usb_pipetype (urb->pipe)) {
 		case PIPE_BULK:
 			info = usb_pipeout (urb->pipe)? 
 				TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
 			while(data_len > 4096) {		
-				td_fill (info | (cnt? TD_T_TOGGLE:toggle), data, 4096, urb, cnt);
+				td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, urb, cnt);
 				data += 4096; data_len -= 4096; cnt++;
 			}
 			info = usb_pipeout (urb->pipe)?
 				TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
-			td_fill (info | (cnt? TD_T_TOGGLE:toggle), data, data_len, urb, cnt);
+			td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, urb, cnt);
 			cnt++;
 			writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
 			break;
@@ -1247,27 +1332,32 @@
 		case PIPE_INTERRUPT:
 			info = usb_pipeout (urb->pipe)? 
 				TD_CC | TD_DP_OUT | toggle: TD_CC | TD_R | TD_DP_IN | toggle;
-			td_fill (info, data, data_len, urb, cnt++);
+			td_fill (ohci, info, data, data_len, urb, cnt++);
 			break;
 
 		case PIPE_CONTROL:
 			info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
-			td_fill (info, ctrl, 8, urb, cnt++); 
+			td_fill (ohci, info,
+				pci_map_single (ohci->ohci_dev,
+					urb->setup_packet, 8,
+					PCI_DMA_TODEVICE),
+				8, urb, cnt++); 
 			if (data_len > 0) {  
 				info = usb_pipeout (urb->pipe)? 
 					TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
-				td_fill (info, data, data_len, urb, cnt++);  
+				/* NOTE:  mishandles transfers >8K, some >4K */
+				td_fill (ohci, info, data, data_len, urb, cnt++);  
 			} 
 			info = usb_pipeout (urb->pipe)? 
  				TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
-			td_fill (info, NULL, 0, urb, cnt++);
+			td_fill (ohci, info, data, 0, urb, cnt++);
 			writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
 			break;
 
 		case PIPE_ISOCHRONOUS:
 			for (cnt = 0; cnt < urb->number_of_packets; cnt++) {
-				td_fill (TD_CC|TD_ISO | ((urb->start_frame + cnt) & 0xffff), 
- 					(__u8 *) data + urb->iso_frame_desc[cnt].offset, 
+				td_fill (ohci, TD_CC|TD_ISO | ((urb->start_frame + cnt) & 0xffff), 
+					data + urb->iso_frame_desc[cnt].offset, 
 					urb->iso_frame_desc[cnt].length, urb, cnt); 
 			}
 			break;
@@ -1318,9 +1408,9 @@
 				((td->index == 0) || (td->index == urb_priv->length - 1)))) {
  			if (tdBE != 0) {
  				if (td->hwCBP == 0)
-					urb->actual_length = bus_to_virt (tdBE) - urb->transfer_buffer + 1;
+					urb->actual_length += tdBE - td->data_dma + 1;
   				else
-					urb->actual_length = bus_to_virt (tdCBP) - urb->transfer_buffer;
+					urb->actual_length += tdCBP - td->data_dma;
 			}
   		}
   	}
@@ -1366,7 +1456,7 @@
 	ohci->hcca->done_head = 0;
 	
 	while (td_list_hc) {		
-		td_list = (td_t *) bus_to_virt (td_list_hc);
+		td_list = dma_to_td (ohci, td_list_hc);
 
 		if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) {
 			urb_priv = (urb_priv_t *) td_list->urb->hcpriv;
@@ -1411,8 +1501,8 @@
 
 	for (ed = ohci->ed_rm_list[frame]; ed != NULL; ed = ed->ed_rm_list) {
 
-   	 	tdTailP = bus_to_virt (le32_to_cpup (&ed->hwTailP) & 0xfffffff0);
-		tdHeadP = bus_to_virt (le32_to_cpup (&ed->hwHeadP) & 0xfffffff0);
+		tdTailP = dma_to_td (ohci, le32_to_cpup (&ed->hwTailP) & 0xfffffff0);
+		tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP) & 0xfffffff0);
 		edINFO = le32_to_cpup (&ed->hwINFO);
 		td_p = &ed->hwHeadP;
 
@@ -1420,7 +1510,7 @@
 			urb_t * urb = td->urb;
 			urb_priv_t * urb_priv = td->urb->hcpriv;
 			
-			td_next = bus_to_virt (le32_to_cpup (&td->hwNextTD) & 0xfffffff0);
+			td_next = dma_to_td (ohci, le32_to_cpup (&td->hwNextTD) & 0xfffffff0);
 			if ((urb_priv->state == URB_DEL) || (ed->state & ED_DEL)) {
 				tdINFO = le32_to_cpup (&td->hwINFO);
 				if (TD_CC_GET (tdINFO) < 0xE)
@@ -1439,7 +1529,8 @@
 			struct ohci_device * dev = usb_to_ohci (ohci->dev[edINFO & 0x7F]);
 			td_free (ohci, tdTailP); /* free dummy td */
    	 		ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); 
-   	 		ed->state = ED_NEW; 
+			ed->state = ED_NEW;
+			hash_free_ed(ohci, ed);
    	 		/* if all eds are removed wake up sohci_free_dev */
    	 		if (!--dev->ed_cnt) {
 				wait_queue_head_t *wait_head = dev->wait;
@@ -1450,7 +1541,7 @@
 			}
    	 	} else {
    	 		ed->state &= ~ED_URB_DEL;
-			tdHeadP = bus_to_virt (le32_to_cpup (&ed->hwHeadP) & 0xfffffff0);
+			tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP) & 0xfffffff0);
 
 			if (tdHeadP == tdTailP) {
 				if (ed->state == ED_OPER)
@@ -1458,6 +1549,7 @@
 				td_free (ohci, tdTailP);
 				ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP);
 				ed->state = ED_NEW;
+				hash_free_ed(ohci, ed);
 				--(usb_to_ohci (ohci->dev[edINFO & 0x7F]))->ed_cnt;
 			} else
    	 			ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP);
@@ -1535,7 +1627,7 @@
 			if ((ed->state & (ED_OPER | ED_UNLINK))
 					&& (urb_priv->state != URB_DEL)) {
   				urb->status = cc_to_error[cc];
-  				sohci_return_urb (urb);
+  				sohci_return_urb (ohci, urb);
   			} else {
 				spin_lock_irqsave (&usb_ed_lock, flags);
   				dl_del_urb (urb);
@@ -1765,9 +1857,6 @@
 	wIndex        = le16_to_cpu (cmd->index);
 	wLength       = le16_to_cpu (cmd->length);
 
-	dbg ("rh_submit_urb, req = %d(%x) len=%d", bmRType_bReq,
-		bmRType_bReq, wLength);
-
 	switch (bmRType_bReq) {
 	/* Request Destination:
 	   without flags: Device, 
@@ -2068,6 +2157,37 @@
 
 /*-------------------------------------------------------------------------*/
 
+/* called only from interrupt handler */
+
+static void check_timeouts (struct ohci *ohci)
+{
+	spin_lock (&usb_ed_lock);
+	while (!list_empty (&ohci->timeout_list)) {
+		struct urb	*urb;
+
+		urb = list_entry (ohci->timeout_list.next, struct urb, urb_list);
+		if (time_after (jiffies, urb->timeout))
+			break;
+
+		list_del_init (&urb->urb_list);
+		if (urb->status != -EINPROGRESS)
+			continue;
+
+		urb->transfer_flags |= USB_TIMEOUT_KILLED | USB_ASYNC_UNLINK;
+		spin_unlock (&usb_ed_lock);
+
+		// outside the interrupt handler (in a timer...)
+		// this reference would race interrupts
+		sohci_unlink_urb (urb);
+
+		spin_lock (&usb_ed_lock);
+	}
+	spin_unlock (&usb_ed_lock);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
 /* an interrupt happens */
 
 static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
@@ -2120,10 +2240,18 @@
 		if (ohci->ed_rm_list[frame] != NULL)
 			writel (OHCI_INTR_SF, &regs->intrenable);	
 	}
+
+	if (!list_empty (&ohci->timeout_list)) {
+		check_timeouts (ohci);
+// FIXME:  enable SF as needed in a timer;
+// don't make lots of 1ms interrupts
+// On unloaded USB, think 4k ~= 4-5msec
+		if (!list_empty (&ohci->timeout_list))
+			writel (OHCI_INTR_SF, &regs->intrenable);	
+	}
+
 	writel (ints, &regs->intrstatus);
 	writel (OHCI_INTR_MIE, &regs->intrenable);	
-
-	/* FIXME:  check URB timeouts */
 }
 
 /*-------------------------------------------------------------------------*/
@@ -2159,6 +2287,8 @@
 	INIT_LIST_HEAD (&ohci->ohci_hcd_list);
 	list_add (&ohci->ohci_hcd_list, &ohci_hcd_list);
 
+	INIT_LIST_HEAD (&ohci->timeout_list);
+
 	bus = usb_alloc_bus (&sohci_device_operations);
 	if (!bus) {
 		kfree (ohci);
@@ -2198,6 +2328,8 @@
 
 	list_del (&ohci->ohci_hcd_list);
 	INIT_LIST_HEAD (&ohci->ohci_hcd_list);
+
+	ohci_mem_cleanup (ohci);
     
 	/* unmap the IO address space */
 	iounmap (ohci->regs);
@@ -2220,6 +2352,7 @@
 	ohci_t * ohci;
 	u8 latency, limit;
 	char buf[8], *bufp = buf;
+	int ret;
 
 #ifndef __sparc__
 	sprintf(buf, "%d", irq);
@@ -2234,6 +2367,10 @@
 	if (!ohci) {
 		return -ENOMEM;
 	}
+	if ((ret = ohci_mem_init (ohci)) < 0) {
+		hc_release_ohci (ohci);
+		return ret;
+	}
 
 	/* bad pci latencies can contribute to overruns */ 
 	pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
@@ -2586,11 +2723,7 @@
 {
 	int ret;
 
-	if ((ret = ohci_mem_init ()) < 0)
-		return ret;
-
 	if ((ret = pci_module_init (&ohci_pci_driver)) < 0) {
-		ohci_mem_cleanup ();
 		return ret;
 	}
 
@@ -2608,7 +2741,6 @@
 	pmu_unregister_sleep_notifier (&ohci_sleep_notifier);
 #endif  
 	pci_unregister_driver (&ohci_pci_driver);
-	ohci_mem_cleanup ();
 }
 
 module_init (ohci_hcd_init);
diff -urN linux-2.4.4-pre4/drivers/usb/usb-ohci.h linux/drivers/usb/usb-ohci.h
--- linux-2.4.4-pre4/drivers/usb/usb-ohci.h	Mon Mar 19 17:21:54 2001
+++ linux/drivers/usb/usb-ohci.h	Mon Dec  3 22:35:56 2001
@@ -39,7 +39,7 @@
 #define ED_URB_DEL  	0x08
 
 /* usb_ohci_ed */
-typedef struct ed {
+struct ed {
 	__u32 hwINFO;       
 	__u32 hwTailP;
 	__u32 hwHeadP;
@@ -53,9 +53,12 @@
 	__u8 state;
 	__u8 type; 
 	__u16 last_iso;
-    struct ed * ed_rm_list;
-   
-} ed_t;
+	struct ed * ed_rm_list;
+
+	dma_addr_t dma;
+	__u32 unused[3];
+} __attribute((aligned(16)));
+typedef struct ed ed_t;
 
  
 /* TD info field */
@@ -75,7 +78,7 @@
 #define TD_DP_IN    0x00100000
 #define TD_DP_OUT   0x00080000
 
-#define TD_ISO		0x00010000
+#define TD_ISO	    0x00010000
 #define TD_DEL      0x00020000
 
 /* CC Codes */
@@ -96,20 +99,24 @@
 
 #define MAXPSW 1
 
-typedef struct td { 
+struct td {
 	__u32 hwINFO;
   	__u32 hwCBP;		/* Current Buffer Pointer */
   	__u32 hwNextTD;		/* Next TD Pointer */
   	__u32 hwBE;		/* Memory Buffer End Pointer */
-  	__u16 hwPSW[MAXPSW];
 
+  	__u16 hwPSW[MAXPSW];
   	__u8 unused;
   	__u8 index;
   	struct ed * ed;
   	struct td * next_dl_td;
   	urb_t * urb;
-} td_t;
 
+	dma_addr_t td_dma;
+	dma_addr_t data_dma;
+	__u32 unused2[2];
+} __attribute((aligned(16)));
+typedef struct td td_t;
 
 #define OHCI_ED_SKIP	(1 << 14)
 
@@ -121,7 +128,7 @@
  
 #define NUM_INTS 32	/* part of the OHCI standard */
 struct ohci_hcca {
-    __u32	int_table[NUM_INTS];	/* Interrupt ED table */
+	__u32	int_table[NUM_INTS];	/* Interrupt ED table */
 	__u16	frame_no;		/* current frame number */
 	__u16	pad1;			/* set to 0 on each frame_no change */
 	__u32	done_head;		/* info returned for an interrupt */
@@ -337,6 +344,27 @@
 } urb_priv_t;
 #define URB_DEL 1
 
+
+/* Hash struct used for TD/ED hashing */
+struct hash_t {
+	void		*virt;
+	dma_addr_t	dma;
+	struct hash_t	*next; // chaining for collision cases
+};
+
+/* List of TD/ED hash entries */
+struct hash_list_t {
+	struct hash_t	*head;
+	struct hash_t	*tail;
+};
+
+#define TD_HASH_SIZE    64    /* power'o'two */
+#define ED_HASH_SIZE    64    /* power'o'two */
+
+#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 5)) % TD_HASH_SIZE)
+#define ED_HASH_FUNC(ed_dma) ((ed_dma ^ (ed_dma >> 5)) % ED_HASH_SIZE)
+
+
 /*
  * This is the full ohci controller description
  *
@@ -356,7 +384,8 @@
 	struct ohci_regs * regs;	/* OHCI controller's memory */
 	struct list_head ohci_hcd_list;	/* list of all ohci_hcd */
 
-	struct ohci * next; 		// chain of uhci device contexts
+	struct ohci * next; 		// chain of ohci device contexts
+	struct list_head timeout_list;
 	// struct list_head urb_list; 	// list of all pending urbs
 	// spinlock_t urb_list_lock; 	// lock to keep consistency 
   
@@ -371,17 +400,21 @@
 	struct usb_device * dev[128];
 	struct virt_root_hub rh;
 
-	/* PCI device handle and settings */
+	/* PCI device handle, settings, ... */
 	struct pci_dev	*ohci_dev;
 	u8		pci_latency;
-} ohci_t;
+	struct pci_pool	*td_cache;
+	struct pci_pool	*dev_cache;
+	struct hash_list_t	td_hash[TD_HASH_SIZE];
+	struct hash_list_t	ed_hash[ED_HASH_SIZE];
 
+} ohci_t;
 
-#define NUM_TDS	0		/* num of preallocated transfer descriptors */
 #define NUM_EDS 32		/* num of preallocated endpoint descriptors */
 
 struct ohci_device {
 	ed_t 	ed[NUM_EDS];
+	dma_addr_t dma;
 	int ed_cnt;
 	wait_queue_head_t * wait;
 };
@@ -393,10 +426,10 @@
 /* endpoint */
 static int ep_link(ohci_t * ohci, ed_t * ed);
 static int ep_unlink(ohci_t * ohci, ed_t * ed);
-static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned int pipe, int interval, int load);
+static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned int pipe, int interval, int load, int mem_flags);
 static void ep_rm_ed(struct usb_device * usb_dev, ed_t * ed);
 /* td */
-static void td_fill(unsigned int info, void * data, int len, urb_t * urb, int index);
+static void td_fill(ohci_t * ohci, unsigned int info, dma_addr_t data, int len, urb_t * urb, int index);
 static void td_submit_urb(urb_t * urb);
 /* root hub */
 static int rh_submit_urb(urb_t * urb);
@@ -406,97 +439,204 @@
 /*-------------------------------------------------------------------------*/
 
 #define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL)
- 
-#ifdef OHCI_MEM_SLAB
-#define	__alloc(t,c) kmem_cache_alloc(c,ALLOC_FLAGS)
-#define	__free(c,x) kmem_cache_free(c,x)
-static kmem_cache_t *td_cache, *ed_cache;
 
-/*
- * WARNING:  do NOT use this with "forced slab debug"; it won't respect
- * our hardware alignment requirement.
- */
-#ifndef OHCI_MEM_FLAGS
-#define	OHCI_MEM_FLAGS 0
+#ifdef DEBUG
+#	define OHCI_MEM_FLAGS	SLAB_POISON
+#else
+#	define OHCI_MEM_FLAGS	0
+#endif
+ 
+#ifndef CONFIG_PCI
+#	error "usb-ohci currently requires PCI-based controllers"
+	/* to support non-PCI OHCIs, you need custom bus/mem/... glue */
 #endif
 
-static int ohci_mem_init (void)
+
+/* Recover a TD/ED using its collision chain */
+static inline void *
+dma_to_ed_td (struct hash_list_t * entry, dma_addr_t dma)
 {
-	/* redzoning (or forced debug!) breaks alignment */
-	int	flags = (OHCI_MEM_FLAGS) & ~SLAB_RED_ZONE;
+	struct hash_t * scan = entry->head;
+	while (scan && scan->dma != dma)
+		scan = scan->next;
+	if (!scan)
+		BUG();
+	return scan->virt;
+}
 
-	/* TDs accessed by controllers and host */
-	td_cache = kmem_cache_create ("ohci_td", sizeof (struct td), 0,
-		flags | SLAB_HWCACHE_ALIGN, NULL, NULL);
-	if (!td_cache) {
-		dbg ("no TD cache?");
-		return -ENOMEM;
-	}
+static inline struct ed *
+dma_to_ed (struct ohci * hc, dma_addr_t ed_dma)
+{
+	return (struct ed *) dma_to_ed_td(&(hc->ed_hash[ED_HASH_FUNC(ed_dma)]),
+				      ed_dma);
+}
 
-	/* EDs are accessed by controllers and host;  dev part is host-only */
-	ed_cache = kmem_cache_create ("ohci_ed", sizeof (struct ohci_device), 0,
-		flags | SLAB_HWCACHE_ALIGN, NULL, NULL);
-	if (!ed_cache) {
-		dbg ("no ED cache?");
-		kmem_cache_destroy (td_cache);
-		td_cache = 0;
-		return -ENOMEM;
+static inline struct td *
+dma_to_td (struct ohci * hc, dma_addr_t td_dma)
+{
+	return (struct td *) dma_to_ed_td(&(hc->td_hash[TD_HASH_FUNC(td_dma)]),
+				      td_dma);
+}
+
+/* Add a hash entry for a TD/ED; return true on success */
+static inline int
+hash_add_ed_td(struct hash_list_t * entry, void * virt, dma_addr_t dma)
+{
+	struct hash_t * scan;
+	
+	scan = (struct hash_t *)kmalloc(sizeof(struct hash_t), ALLOC_FLAGS);
+	if (!scan)
+		return 0;
+	
+	if (!entry->tail) {
+		entry->head = entry->tail = scan;
+	} else {
+		entry->tail->next = scan;
+		entry->tail = scan;
 	}
-	dbg ("slab flags 0x%x", flags);
-	return 0;
+	
+	scan->virt = virt;
+	scan->dma = dma;
+	scan->next = NULL;
+	return 1;
 }
 
-static void ohci_mem_cleanup (void)
+static inline int
+hash_add_ed (struct ohci * hc, struct ed * ed)
 {
-	if (ed_cache && kmem_cache_destroy (ed_cache))
-		err ("ed_cache remained");
-	ed_cache = 0;
-
-	if (td_cache && kmem_cache_destroy (td_cache))
-		err ("td_cache remained");
-	td_cache = 0;
+	return hash_add_ed_td (&(hc->ed_hash[ED_HASH_FUNC(ed->dma)]),
+			ed, ed->dma);
 }
 
-#else
-#define	__alloc(t,c) kmalloc(sizeof(t),ALLOC_FLAGS)
-#define	__free(dev,x) kfree(x)
-#define td_cache 0
-#define ed_cache 0
+static inline int
+hash_add_td (struct ohci * hc, struct td * td)
+{
+	return hash_add_ed_td (&(hc->td_hash[TD_HASH_FUNC(td->td_dma)]),
+			td, td->td_dma);
+}
 
-static inline int ohci_mem_init (void) { return 0; }
-static inline void ohci_mem_cleanup (void) { return; }
 
-/* FIXME: pci_consistent version */
+static inline void
+hash_free_ed_td (struct hash_list_t * entry, void * virt)
+{
+	struct hash_t *scan, *prev;
+	scan = prev = entry->head;
 
-#endif
+	// Find and unlink hash entry
+	while (scan && scan->virt != virt) {
+		prev = scan;
+		scan = scan->next;
+	}
+	if (scan) {
+		if (scan == entry->head) {
+			if (entry->head == entry->tail)
+				entry->head = entry->tail = NULL;
+			else
+				entry->head = scan->next;
+		} else if (scan == entry->tail) {
+			entry->tail = prev;
+			prev->next = NULL;
+		} else
+			prev->next = scan->next;
+		kfree(scan);
+	}
+}
+
+static inline void
+hash_free_ed (struct ohci * hc, struct ed * ed)
+{
+	hash_free_ed_td (&(hc->ed_hash[ED_HASH_FUNC(ed->dma)]), ed);
+}
+
+static inline void
+hash_free_td (struct ohci * hc, struct td * td)
+{
+	hash_free_ed_td (&(hc->td_hash[TD_HASH_FUNC(td->td_dma)]), td);
+}
+
+
+static int ohci_mem_init (struct ohci *ohci)
+{
+	ohci->td_cache = pci_pool_create ("ohci_td", ohci->ohci_dev,
+		sizeof (struct td),
+		16 /* byte alignment */,
+		0 /* no page-crossing issues */,
+		GFP_KERNEL | OHCI_MEM_FLAGS);
+	if (!ohci->td_cache)
+		return -ENOMEM;
+	ohci->dev_cache = pci_pool_create ("ohci_dev", ohci->ohci_dev,
+		sizeof (struct ohci_device),
+		16 /* byte alignment */,
+		0 /* no page-crossing issues */,
+		GFP_KERNEL | OHCI_MEM_FLAGS);
+	if (!ohci->dev_cache)
+		return -ENOMEM;
+	return 0;
+}
 
+static void ohci_mem_cleanup (struct ohci *ohci)
+{
+	if (ohci->td_cache) {
+		pci_pool_destroy (ohci->td_cache);
+		ohci->td_cache = 0;
+	}
+	if (ohci->dev_cache) {
+		pci_pool_destroy (ohci->dev_cache);
+		ohci->dev_cache = 0;
+	}
+}
 
 /* TDs ... */
 static inline struct td *
-td_alloc (struct ohci *hc)
+td_alloc (struct ohci *hc, int mem_flags)
 {
-	struct td *td = (struct td *) __alloc (struct td, td_cache);
+	dma_addr_t	dma;
+	struct td	*td;
+
+	td = pci_pool_alloc (hc->td_cache, mem_flags, &dma);
+	if (td) {
+		td->td_dma = dma;
+
+		/* hash it for later reverse mapping */
+		if (!hash_add_td (hc, td)) {
+			pci_pool_free (hc->td_cache, td, dma);
+			return NULL;
+		}
+	}
 	return td;
 }
 
 static inline void
 td_free (struct ohci *hc, struct td *td)
 {
-	__free (td_cache, td);
+	hash_free_td (hc, td);
+	pci_pool_free (hc->td_cache, td, td->td_dma);
 }
 
 
 /* DEV + EDs ... only the EDs need to be consistent */
 static inline struct ohci_device *
-dev_alloc (struct ohci *hc)
+dev_alloc (struct ohci *hc, int mem_flags)
 {
-	struct ohci_device *dev = (struct ohci_device *)
-		__alloc (struct ohci_device, ed_cache);
+	dma_addr_t		dma;
+	struct ohci_device	*dev;
+	int			i, offset;
+
+	dev = pci_pool_alloc (hc->dev_cache, mem_flags, &dma);
+	if (dev) {
+		memset (dev, 0, sizeof (*dev));
+		dev->dma = dma;
+		offset = ((char *)&dev->ed) - ((char *)dev);
+		for (i = 0; i < NUM_EDS; i++, offset += sizeof dev->ed [0])
+			dev->ed [i].dma = dma + offset;
+		/* add to hashtable if used */
+	}
 	return dev;
 }
 
 static inline void
-dev_free (struct ohci_device *dev)
+dev_free (struct ohci *hc, struct ohci_device *dev)
 {
-	__free (ed_cache, dev);
+	pci_pool_free (hc->dev_cache, dev, dev->dma);
 }
+
diff -urN linux-2.4.4-pre4/drivers/usb/usb-uhci.c linux/drivers/usb/usb-uhci.c
--- linux-2.4.4-pre4/drivers/usb/usb-uhci.c	Sat Mar  3 10:55:48 2001
+++ linux/drivers/usb/usb-uhci.c	Mon Dec  3 22:35:56 2001
@@ -1411,7 +1411,7 @@
 /*-------------------------------------------------------------------*/
 // submits USB interrupt (ie. polling ;-) 
 // ASAP-flag set implicitely
-// if period==0, the the transfer is only done once
+// if period==0, the transfer is only done once
 
 _static int uhci_submit_int_urb (urb_t *urb)
 {
@@ -2390,7 +2390,7 @@
 			usb_endpoint_halt (urb->dev, usb_pipeendpoint (urb->pipe), usb_pipeout (urb->pipe));
 		}
 
-		// if any error occured: ignore this td, and continue
+		// if any error occurred: ignore this td, and continue
 		if (status != 0) {
 			//uhci_show_td (desc);
 			urb->error_count++;
diff -urN linux-2.4.4-pre4/drivers/video/acornfb.c linux/drivers/video/acornfb.c
--- linux-2.4.4-pre4/drivers/video/acornfb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/acornfb.c	Mon Dec  3 22:35:56 2001
@@ -263,28 +263,28 @@
 	vidc.v_border_end	= vidc.v_display_end;
 
 #ifdef CONFIG_ARCH_A5K
-	outb(vid_ctl, IOEB_VID_CTL);
+	__raw_writeb(vid_ctl, IOEB_VID_CTL);
 #endif
 	if (memcmp(&current_vidc, &vidc, sizeof(vidc))) {
 		current_vidc = vidc;
 
-		outl(0xe0000000 | vidc_ctl,			IO_VIDC_BASE);
-		outl(0x80000000 | (vidc.h_cycle << 14),		IO_VIDC_BASE);
-		outl(0x84000000 | (vidc.h_sync_width << 14),	IO_VIDC_BASE);
-		outl(0x88000000 | (vidc.h_border_start << 14),	IO_VIDC_BASE);
-		outl(0x8c000000 | (vidc.h_display_start << 14),	IO_VIDC_BASE);
-		outl(0x90000000 | (vidc.h_display_end << 14),	IO_VIDC_BASE);
-		outl(0x94000000 | (vidc.h_border_end << 14),	IO_VIDC_BASE);
-		outl(0x98000000,				IO_VIDC_BASE);
-		outl(0x9c000000 | (vidc.h_interlace << 14),	IO_VIDC_BASE);
-		outl(0xa0000000 | (vidc.v_cycle << 14),		IO_VIDC_BASE);
-		outl(0xa4000000 | (vidc.v_sync_width << 14),	IO_VIDC_BASE);
-		outl(0xa8000000 | (vidc.v_border_start << 14),	IO_VIDC_BASE);
-		outl(0xac000000 | (vidc.v_display_start << 14),	IO_VIDC_BASE);
-		outl(0xb0000000 | (vidc.v_display_end << 14),	IO_VIDC_BASE);
-		outl(0xb4000000 | (vidc.v_border_end << 14),	IO_VIDC_BASE);
-		outl(0xb8000000,				IO_VIDC_BASE);
-		outl(0xbc000000,				IO_VIDC_BASE);
+		vidc_writel(0xe0000000 | vidc_ctl);
+		vidc_writel(0x80000000 | (vidc.h_cycle << 14));
+		vidc_writel(0x84000000 | (vidc.h_sync_width << 14));
+		vidc_writel(0x88000000 | (vidc.h_border_start << 14));
+		vidc_writel(0x8c000000 | (vidc.h_display_start << 14));
+		vidc_writel(0x90000000 | (vidc.h_display_end << 14));
+		vidc_writel(0x94000000 | (vidc.h_border_end << 14));
+		vidc_writel(0x98000000);
+		vidc_writel(0x9c000000 | (vidc.h_interlace << 14));
+		vidc_writel(0xa0000000 | (vidc.v_cycle << 14));
+		vidc_writel(0xa4000000 | (vidc.v_sync_width << 14));
+		vidc_writel(0xa8000000 | (vidc.v_border_start << 14));
+		vidc_writel(0xac000000 | (vidc.v_display_start << 14));
+		vidc_writel(0xb0000000 | (vidc.v_display_end << 14));
+		vidc_writel(0xb4000000 | (vidc.v_border_end << 14));
+		vidc_writel(0xb8000000);
+		vidc_writel(0xbc000000);
 	}
 #ifdef DEBUG_MODE_SELECTION
 	printk(KERN_DEBUG "VIDC registers for %dx%dx%d:\n", var->xres,
@@ -310,7 +310,7 @@
 static inline void
 acornfb_palette_write(u_int regno, union palette pal)
 {
-	outl(pal.p, IO_VIDC_BASE);
+	vidc_writel(pal.p);
 }
 
 static inline union palette
@@ -402,27 +402,27 @@
 	if (memcmp(&current_vidc, &vidc, sizeof(vidc))) {
 		current_vidc = vidc;
 
-		outl(VIDC20_CTRL| vidc.control,		IO_VIDC_BASE);
-		outl(0xd0000000 | vidc.pll_ctl,		IO_VIDC_BASE);
-		outl(0x80000000 | vidc.h_cycle,		IO_VIDC_BASE);
-		outl(0x81000000 | vidc.h_sync_width,	IO_VIDC_BASE);
-		outl(0x82000000 | vidc.h_border_start,	IO_VIDC_BASE);
-		outl(0x83000000 | vidc.h_display_start,	IO_VIDC_BASE);
-		outl(0x84000000 | vidc.h_display_end,	IO_VIDC_BASE);
-		outl(0x85000000 | vidc.h_border_end,	IO_VIDC_BASE);
-		outl(0x86000000,			IO_VIDC_BASE);
-		outl(0x87000000 | vidc.h_interlace,	IO_VIDC_BASE);
-		outl(0x90000000 | vidc.v_cycle,		IO_VIDC_BASE);
-		outl(0x91000000 | vidc.v_sync_width,	IO_VIDC_BASE);
-		outl(0x92000000 | vidc.v_border_start,	IO_VIDC_BASE);
-		outl(0x93000000 | vidc.v_display_start,	IO_VIDC_BASE);
-		outl(0x94000000 | vidc.v_display_end,	IO_VIDC_BASE);
-		outl(0x95000000 | vidc.v_border_end,	IO_VIDC_BASE);
-		outl(0x96000000,			IO_VIDC_BASE);
-		outl(0x97000000,			IO_VIDC_BASE);
+		vidc_writel(VIDC20_CTRL| vidc.control);
+		vidc_writel(0xd0000000 | vidc.pll_ctl);
+		vidc_writel(0x80000000 | vidc.h_cycle);
+		vidc_writel(0x81000000 | vidc.h_sync_width);
+		vidc_writel(0x82000000 | vidc.h_border_start);
+		vidc_writel(0x83000000 | vidc.h_display_start);
+		vidc_writel(0x84000000 | vidc.h_display_end);
+		vidc_writel(0x85000000 | vidc.h_border_end);
+		vidc_writel(0x86000000);
+		vidc_writel(0x87000000 | vidc.h_interlace);
+		vidc_writel(0x90000000 | vidc.v_cycle);
+		vidc_writel(0x91000000 | vidc.v_sync_width);
+		vidc_writel(0x92000000 | vidc.v_border_start);
+		vidc_writel(0x93000000 | vidc.v_display_start);
+		vidc_writel(0x94000000 | vidc.v_display_end);
+		vidc_writel(0x95000000 | vidc.v_border_end);
+		vidc_writel(0x96000000);
+		vidc_writel(0x97000000);
 	}
 
-	outl(fsize, IOMD_FSIZE);
+	iomd_writel(fsize, IOMD_FSIZE);
 
 	ext_ctl = acornfb_default_econtrol();
 
@@ -440,7 +440,7 @@
 			ext_ctl |= VIDC20_ECTL_VS_NVSYNC;
 	}
 
-	outl(VIDC20_ECTL | ext_ctl, IO_VIDC_BASE);
+	vidc_writel(VIDC20_ECTL | ext_ctl);
 
 	words_per_line = var->xres * var->bits_per_pixel / 32;
 
@@ -461,7 +461,7 @@
 	} else 
 		dat_ctl |= VIDC20_DCTL_BUS_D31_0;
 
-	outl(VIDC20_DCTL | dat_ctl, IO_VIDC_BASE);
+	vidc_writel(VIDC20_DCTL | dat_ctl);
 
 #ifdef DEBUG_MODE_SELECTION
 	printk(KERN_DEBUG "VIDC registers for %dx%dx%d:\n", var->xres,
@@ -490,8 +490,8 @@
 static inline void
 acornfb_palette_write(u_int regno, union palette pal)
 {
-	outl(0x10000000 | regno, IO_VIDC_BASE);
-	outl(pal.p, IO_VIDC_BASE);
+	vidc_writel(0x10000000 | regno);
+	vidc_writel(pal.p);
 }
 
 static inline union palette
@@ -672,7 +672,7 @@
 #if defined(HAS_MEMC)
 	memc_write(VDMA_INIT, off >> 2);
 #elif defined(HAS_IOMD)
-	outl(current_par.screen_base_p + off, IOMD_VIDINIT);
+	iomd_writel(current_par.screen_base_p + off, IOMD_VIDINIT);
 #endif
 }
 
@@ -744,12 +744,12 @@
 		int i;
 
 		pal.p = 0;
-		outl(0x10000000, IO_VIDC_BASE);
+		vidc_writel(0x10000000);
 		for (i = 0; i < 256; i += 1) {
 			pal.vidc20.red   = current_par.palette[ i       & 31].vidc20.red;
 			pal.vidc20.green = current_par.palette[(i >> 1) & 31].vidc20.green;
 			pal.vidc20.blue  = current_par.palette[(i >> 2) & 31].vidc20.blue;
-			outl(pal.p, IO_VIDC_BASE);
+			vidc_writel(pal.p);
 			/* Palette register pointer auto-increments */
 		}
 	} else
@@ -1074,9 +1074,9 @@
 			control = DMA_CR_E | DMA_CR_D | 16;
 		}
 
-		outl(start,   IOMD_VIDSTART);
-		outl(size,    IOMD_VIDEND);
-		outl(control, IOMD_VIDCR);
+		iomd_writel(start,   IOMD_VIDSTART);
+		iomd_writel(size,    IOMD_VIDEND);
+		iomd_writel(control, IOMD_VIDCR);
 #endif
 		acornfb_update_dma(var);
 		acornfb_set_timing(var);
@@ -1119,6 +1119,45 @@
 	return 0;
 }
 
+/*
+ * Note that we are entered with the kernel locked.
+ */
+static int
+acornfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+{
+	unsigned long off, start;
+	u32 len;
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	start = current_par.screen_base_p;
+	len = PAGE_ALIGN(start & ~PAGE_MASK) + current_par.screen_size;
+	start &= PAGE_MASK;
+	if ((vma->vm_end - vma->vm_start + off) > len)
+		return -EINVAL;
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO;
+
+#ifdef CONFIG_CPU_32
+	pgprot_val(vma->vm_page_prot) &= ~L_PTE_CACHEABLE;
+#endif
+
+	/*
+	 * Don't alter the page protection flags; we want to keep the area
+	 * cached for better performance.  This does mean that we may miss
+	 * some updates to the screen occasionally, but process switches
+	 * should cause the caches and buffers to be flushed often enough.
+	 */
+	if (io_remap_page_range(vma->vm_start, off,
+				vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
+		return -EAGAIN;
+	return 0;
+}
+
 static struct fb_ops acornfb_ops = {
 	owner:		THIS_MODULE,
 	fb_get_fix:	acornfb_get_fix,
@@ -1127,6 +1166,7 @@
 	fb_get_cmap:	acornfb_get_cmap,
 	fb_set_cmap:	acornfb_set_cmap,
 	fb_pan_display:	acornfb_pan_display,
+	fb_mmap:	acornfb_mmap,
 };
 
 static int
diff -urN linux-2.4.4-pre4/drivers/video/amifb.c linux/drivers/video/amifb.c
--- linux-2.4.4-pre4/drivers/video/amifb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/amifb.c	Mon Dec  3 22:35:56 2001
@@ -256,7 +256,7 @@
       - for horizontal panning decrease diwstrt_h
       - the length of a fetchline must be aligned to fetchsize (table 3)
       - if fetchstart is smaller than fetchsize, then ddfstrt can a little bit
-        moved to optimize use of dma (usefull for OCS/ECS overscan displays)
+        moved to optimize use of dma (useful for OCS/ECS overscan displays)
       - ddfstop is ddfstrt+ddfsize-fetchsize
       - If C= didn't change anything for AGA, then at following positions the
         dma bus is allready used:
@@ -2106,7 +2106,7 @@
 			return -EINVAL;
 		}
 		if (par->diwstop_v > par->vtotal) {
-			DPRINTK("invaild diwstop_v\n");
+			DPRINTK("invalid diwstop_v\n");
 			return -EINVAL;
 		}
 
diff -urN linux-2.4.4-pre4/drivers/video/atafb.c linux/drivers/video/atafb.c
--- linux-2.4.4-pre4/drivers/video/atafb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/atafb.c	Mon Dec  3 22:35:56 2001
@@ -208,7 +208,7 @@
 
 /*
 The MV300 mixes the color registers. So we need an array of munged
-indices in order to acces the correct reg.
+indices in order to access the correct reg.
 */
 static int MV300_reg_1bit[2]={0,1};
 static int MV300_reg_4bit[16]={
diff -urN linux-2.4.4-pre4/drivers/video/imsttfb.c linux/drivers/video/imsttfb.c
--- linux-2.4.4-pre4/drivers/video/imsttfb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/imsttfb.c	Mon Dec  3 22:35:56 2001
@@ -178,10 +178,10 @@
 
 /* TI TVP 3030 RAMDAC Direct Registers */
 enum {
-	TVPADDRW = 0x00,	/* 0  Palette/Cursor RAM Write Adress/Index */
+	TVPADDRW = 0x00,	/* 0  Palette/Cursor RAM Write Address/Index */
 	TVPPDATA = 0x04,	/* 1  Palette Data RAM Data */
 	TVPPMASK = 0x08,	/* 2  Pixel Read-Mask */
-	TVPPADRR = 0x0c,	/* 3  Palette/Cursor RAM Read Adress */
+	TVPPADRR = 0x0c,	/* 3  Palette/Cursor RAM Read Address */
 	TVPCADRW = 0x10,	/* 4  Cursor/Overscan Color Write Address */
 	TVPCDATA = 0x14,	/* 5  Cursor/Overscan Color Data */
 				/* 6  reserved */
diff -urN linux-2.4.4-pre4/drivers/video/maxinefb.c linux/drivers/video/maxinefb.c
--- linux-2.4.4-pre4/drivers/video/maxinefb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/maxinefb.c	Mon Dec  3 22:35:56 2001
@@ -0,0 +1,425 @@
+/*
+ *      linux/drivers/video/maxinefb.c
+ *
+ *	DECstation 5000/xx onboard framebuffer support ... derived from:
+ *	"HP300 Topcat framebuffer support (derived from macfb of all things)
+ *	Phil Blundell <philb@gnu.org> 1998", the original code can be
+ *      found in the file hpfb.c in the same directory.
+ *
+ *      DECstation related code Copyright (C) 1999,2000,2001 by
+ *      Michael Engel <engel@unix-ag.org> and
+ *      Karsten Merker <merker@linuxtag.org>.
+ *      This file is subject to the terms and conditions of the GNU General
+ *      Public License.  See the file COPYING in the main directory of this
+ *      archive for more details.
+ *
+ */
+
+/*
+ * Changes:
+ * 2001/01/27 removed debugging and testing code, fixed fb_ops
+ *            initialization which had caused a crash before,
+ *            general cleanup, first official release (KM)
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <video/fbcon.h>
+#include "maxinefb.h"
+
+/* bootinfo.h defines the machine type values, needed when checking */
+/* whether are really running on a maxine, KM                       */
+#include <asm/bootinfo.h>
+
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+
+#define arraysize(x)    (sizeof(x)/sizeof(*(x)))
+
+static struct display disp;
+static struct fb_info fb_info;
+
+unsigned long fb_start, fb_size = 1024 * 768, fb_line_length = 1024;
+unsigned long fb_regs;
+unsigned char fb_bitmask;
+
+static struct fb_var_screeninfo maxinefb_defined = {
+	0, 0, 0, 0,		/* W,H, W, H (virtual) load xres,xres_virtual */
+	0, 0,			/* virtual -> visible no offset */
+	0,			/* depth -> load bits_per_pixel */
+	0,			/* greyscale ? */
+	{0, 0, 0},		/* R */
+	{0, 0, 0},		/* G */
+	{0, 0, 0},		/* B */
+	{0, 0, 0},		/* transparency */
+	0,			/* standard pixel format */
+	FB_ACTIVATE_NOW,
+	274, 195,		/* 14" monitor */
+	FB_ACCEL_NONE,
+	0L, 0L, 0L, 0L, 0L,
+	0L, 0L, 0,		/* No sync info */
+	FB_VMODE_NONINTERLACED,
+	{0, 0, 0, 0, 0, 0}
+};
+
+struct maxinefb_par {
+};
+
+static int currcon = 0;
+struct maxinefb_par current_par;
+
+/* Reference to machine type set in arch/mips/dec/prom/identify.c, KM */
+extern unsigned long mips_machtype;
+
+
+/* Handle the funny Inmos RamDAC/video controller ... */
+
+void maxinefb_ims332_write_register(int regno, register unsigned int val)
+{
+	register unsigned char *regs = (char *) MAXINEFB_IMS332_ADDRESS;
+	unsigned char *wptr;
+
+	wptr = regs + 0xa0000 + (regno << 4);
+	*((volatile unsigned int *) (regs)) = (val >> 8) & 0xff00;
+	*((volatile unsigned short *) (wptr)) = val;
+}
+
+unsigned int maxinefb_ims332_read_register(int regno)
+{
+	register unsigned char *regs = (char *) MAXINEFB_IMS332_ADDRESS;
+	unsigned char *rptr;
+	register unsigned int j, k;
+
+	rptr = regs + 0x80000 + (regno << 4);
+	j = *((volatile unsigned short *) rptr);
+	k = *((volatile unsigned short *) regs);
+
+	return (j & 0xffff) | ((k & 0xff00) << 8);
+}
+
+
+static void maxinefb_encode_var(struct fb_var_screeninfo *var,
+				struct maxinefb_par *par)
+{
+	int i = 0;
+	var->xres = 1024;
+	var->yres = 768;
+	var->xres_virtual = 1024;
+	var->yres_virtual = 768;
+	var->xoffset = 0;
+	var->yoffset = 0;
+	var->bits_per_pixel = 8;
+	var->grayscale = 0;
+	var->transp.offset = 0;
+	var->transp.length = 0;
+	var->transp.msb_right = 0;
+	var->nonstd = 0;
+	var->activate = 1;
+	var->height = -1;
+	var->width = -1;
+	var->vmode = FB_VMODE_NONINTERLACED;
+	var->pixclock = 0;
+	var->sync = 0;
+	var->left_margin = 0;
+	var->right_margin = 0;
+	var->upper_margin = 0;
+	var->lower_margin = 0;
+	var->hsync_len = 0;
+	var->vsync_len = 0;
+	for (i = 0; i < arraysize(var->reserved); i++)
+		var->reserved[i] = 0;
+}
+
+static void maxinefb_get_par(struct maxinefb_par *par)
+{
+	*par = current_par;
+}
+
+static int maxinefb_fb_update_var(int con, struct fb_info *info)
+{
+	return 0;
+}
+
+static int maxinefb_do_fb_set_var(struct fb_var_screeninfo *var,
+				  int isactive)
+{
+	struct maxinefb_par par;
+
+	maxinefb_get_par(&par);
+	maxinefb_encode_var(var, &par);
+	return 0;
+}
+
+
+/* Get the palette */
+
+static int maxinefb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     struct fb_info *info)
+{
+	unsigned int i;
+	unsigned long hw_colorvalue = 0;	/* raw color value from the register */
+	unsigned int length;
+
+	if (((cmap->start) + (cmap->len)) >= 256) {
+		length = 256 - (cmap->start);
+	} else {
+		length = cmap->len;
+	}
+	for (i = 0; i < length; i++) {
+		hw_colorvalue =
+		    maxinefb_ims332_read_register(IMS332_REG_COLOR_PALETTE
+						  + cmap->start + i);
+		(cmap->red[i]) = ((hw_colorvalue & 0x0000ff));
+		(cmap->green[i]) = ((hw_colorvalue & 0x00ff00) >> 8);
+		(cmap->blue[i]) = ((hw_colorvalue & 0xff0000) >> 16);
+
+	}
+	return 0;
+}
+
+
+/* Set the palette */
+
+static int maxinefb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     struct fb_info *info)
+{
+	unsigned int i;
+	unsigned long hw_colorvalue;	/* value to be written into the palette reg. */
+	unsigned short cmap_red;
+	unsigned short cmap_green;
+	unsigned short cmap_blue;
+	unsigned int length;
+
+	hw_colorvalue = 0;
+	if (((cmap->start) + (cmap->len)) >= 256) {
+		length = 256 - (cmap->start);
+	} else {
+		length = cmap->len;
+	}
+
+	for (i = 0; i < length; i++) {
+		cmap_red = ((cmap->red[i]) >> 8);	/* The cmap fields are 16 bits    */
+		cmap_green = ((cmap->green[i]) >> 8);	/* wide, but the harware colormap */
+		cmap_blue = ((cmap->blue[i]) >> 8);	/* registers are only 8 bits wide */
+
+		hw_colorvalue =
+		    (cmap_blue << 16) + (cmap_green << 8) + (cmap_red);
+		maxinefb_ims332_write_register(IMS332_REG_COLOR_PALETTE +
+					       cmap->start + i,
+					       hw_colorvalue);
+	}
+	return 0;
+}
+
+static int maxinefb_get_var(struct fb_var_screeninfo *var, int con,
+			    struct fb_info *info)
+{
+	struct maxinefb_par par;
+	if (con == -1) {
+		maxinefb_get_par(&par);
+		maxinefb_encode_var(var, &par);
+	} else
+		*var = fb_display[con].var;
+	return 0;
+}
+
+
+static int maxinefb_set_var(struct fb_var_screeninfo *var, int con,
+			    struct fb_info *info)
+{
+	int err;
+
+	if ((err = maxinefb_do_fb_set_var(var, 1)))
+		return err;
+	return 0;
+}
+static void maxinefb_encode_fix(struct fb_fix_screeninfo *fix,
+				struct maxinefb_par *par)
+{
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, "maxinefb");
+	/* fix->id is a char[16], so a maximum of 15 characters, KM */
+
+	fix->smem_start = (char *) fb_start;	/* display memory base address, KM */
+	fix->smem_len = fb_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	fix->xpanstep = 0;
+	fix->ypanstep = 0;
+	fix->ywrapstep = 0;
+	fix->line_length = fb_line_length;
+}
+
+static int maxinefb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			    struct fb_info *info)
+{
+	struct maxinefb_par par;
+	maxinefb_get_par(&par);
+	maxinefb_encode_fix(fix, &par);
+	return 0;
+}
+
+
+static int maxinefb_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg, int con,
+			  struct fb_info *info)
+{
+	return -EINVAL;
+}
+
+static int maxinefb_switch(int con, struct fb_info *info)
+{
+	maxinefb_do_fb_set_var(&fb_display[con].var, 1);
+	currcon = con;
+	return 0;
+}
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+
+static void maxinefb_blank(int blank, struct fb_info *info)
+{
+	/* Not supported */
+}
+
+static int maxinefb_open(struct fb_info *info, int user)
+{
+	/*
+	 * Nothing, only a usage count for the moment
+	 */
+	MOD_INC_USE_COUNT;
+	return (0);
+}
+
+static void maxinefb_set_disp(int con)
+{
+	struct fb_fix_screeninfo fix;
+	struct display *display;
+
+	if (con >= 0)
+		display = &fb_display[con];
+	else
+		display = &disp;	/* used during initialization */
+
+	maxinefb_get_fix(&fix, con, 0);
+
+	display->screen_base = fix.smem_start;
+	display->visual = fix.visual;
+	display->type = fix.type;
+	display->type_aux = fix.type_aux;
+	display->ypanstep = fix.ypanstep;
+	display->ywrapstep = fix.ywrapstep;
+	display->line_length = fix.line_length;
+	display->next_line = fix.line_length;
+	display->can_soft_blank = 0;
+	display->inverse = 0;
+
+	display->dispsw = &fbcon_cfb8;
+}
+
+static int maxinefb_release(struct fb_info *info, int user)
+{
+	MOD_DEC_USE_COUNT;
+	return (0);
+}
+
+static struct fb_ops maxinefb_ops = {
+	owner:THIS_MODULE,
+	fb_open:maxinefb_open,
+	fb_release:maxinefb_release,
+	fb_get_fix:maxinefb_get_fix,
+	fb_get_var:maxinefb_get_var,
+	fb_set_var:maxinefb_set_var,
+	fb_get_cmap:maxinefb_get_cmap,
+	fb_set_cmap:maxinefb_set_cmap,
+	fb_ioctl:maxinefb_ioctl,
+	fb_mmap:0,
+	fb_rasterimg:0
+};
+
+int __init maxinefb_init_one()
+{
+	volatile unsigned char *fboff;
+	int i;
+
+	/* Framebuffer display memory base address */
+	fb_start = DS5000_xx_ONBOARD_FBMEM_START;
+
+	/* Clear screen */
+	for (fboff = fb_start; fboff < fb_start + 0x1ffff; fboff++)
+		*fboff = 0x0;
+
+	/* erase hardware cursor */
+	for (i = 0; i < 512; i++) {
+		maxinefb_ims332_write_register(IMS332_REG_CURSOR_RAM + i,
+					       0);
+		/*
+		   if (i&0x8 == 0)
+		   maxinefb_ims332_write_register (IMS332_REG_CURSOR_RAM + i, 0x0f);
+		   else
+		   maxinefb_ims332_write_register (IMS332_REG_CURSOR_RAM + i, 0xf0);
+		 */
+	}
+
+	/* Fill in the available video resolution */
+	maxinefb_defined.xres = 1024;
+	maxinefb_defined.yres = 768;
+	maxinefb_defined.xres_virtual = 1024;
+	maxinefb_defined.yres_virtual = 768;
+	maxinefb_defined.bits_per_pixel = 8;
+
+	/* Let there be consoles... */
+
+	strcpy(fb_info.modename, "Maxine onboard graphics 1024x768x8");
+	/* fb_info.modename: maximum of 39 characters + trailing nullbyte, KM */
+	fb_info.changevar = NULL;
+	fb_info.node = -1;
+	fb_info.fbops = &maxinefb_ops;
+	fb_info.disp = &disp;
+	fb_info.switch_con = &maxinefb_switch;
+	fb_info.updatevar = &maxinefb_fb_update_var;
+	fb_info.blank = &maxinefb_blank;
+	fb_info.flags = FBINFO_FLAG_DEFAULT;
+	maxinefb_do_fb_set_var(&maxinefb_defined, 1);
+
+	maxinefb_get_var(&disp.var, -1, &fb_info);
+	maxinefb_set_disp(-1);
+
+	if (register_framebuffer(&fb_info) < 0)
+		return 1;
+
+	return 0;
+}
+
+
+/* Initialise the framebuffer */
+
+void __init maxinefb_init()
+{
+	unsigned int sid;
+
+	if (mips_machtype == MACH_DS5000_XX) {
+		printk("Maxinefb: Personal DECstation detected\n");
+		printk("Maxinefb: initializing onboard framebuffer\n");
+
+		maxinefb_init_one();
+
+	}
+
+}
+
+void __init maxinefb_setup(char *options, int *ints)
+{
+}
diff -urN linux-2.4.4-pre4/drivers/video/maxinefb.h linux/drivers/video/maxinefb.h
--- linux-2.4.4-pre4/drivers/video/maxinefb.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/maxinefb.h	Mon Dec  3 22:35:56 2001
@@ -0,0 +1,37 @@
+/*
+ *      linux/drivers/video/maxinefb.h
+ *
+ *      DECstation 5000/xx onboard framebuffer support, Copyright (C) 1999 by
+ *      Michael Engel <engel@unix-ag.org> and Karsten Merker <merker@guug.de>
+ *      This file is subject to the terms and conditions of the GNU General
+ *      Public License.  See the file COPYING in the main directory of this
+ *      archive for more details.
+ */
+
+
+/*
+ * IMS332 video controller register base address
+ */
+#define MAXINEFB_IMS332_ADDRESS                  0xbc140000
+
+/*
+ * Begin of DECstation 5000/xx onboard framebuffer memory, default resolution
+ * is 1024x768x8
+ */
+#define DS5000_xx_ONBOARD_FBMEM_START	0xaa000000
+
+/*
+ *      The IMS 332 video controller used in the DECstation 5000/xx series
+ *      uses 32 bits wide registers; the following defines declare the
+ *      register numbers, to get the real offset, these have to be multiplied
+ *      by four.
+ */
+
+#define IMS332_REG_CURSOR_RAM           0x200	/* hardware cursor bitmap */
+
+/*
+ * The color palette entries have the form 0x00BBGGRR
+ */
+#define IMS332_REG_COLOR_PALETTE        0x100	/* color palette, 256 entries */
+#define IMS332_REG_CURSOR_COLOR_PALETTE	0x0a1	/* cursor color palette, */
+						/* 3 entries             */
diff -urN linux-2.4.4-pre4/drivers/video/pmag-ba-fb.c linux/drivers/video/pmag-ba-fb.c
--- linux-2.4.4-pre4/drivers/video/pmag-ba-fb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/pmag-ba-fb.c	Mon Dec  3 22:35:56 2001
@@ -0,0 +1,431 @@
+/*
+ *      linux/drivers/video/pmag-ba-fb.c
+ *
+ *	PMAG-BA TurboChannel framebuffer card support ... derived from:
+ *	"HP300 Topcat framebuffer support (derived from macfb of all things)
+ *	Phil Blundell <philb@gnu.org> 1998", the original code can be
+ *      found in the file hpfb.c in the same directory.
+ *
+ *	Based on digital document:
+ * 	"PMAG-BA TURBOchannel Color Frame Buffer
+ *	 Functional Specification", Revision 1.2, August 27, 1990
+ *
+ *      DECstation related code Copyright (C) 1999, 2000, 2001 by
+ *      Michael Engel <engel@unix-ag.org>, 
+ *      Karsten Merker <merker@linuxtag.org> and
+ *	Harald Koerfgen <harald@unix-ag.org>.
+ *      This file is subject to the terms and conditions of the GNU General
+ *      Public License.  See the file COPYING in the main directory of this
+ *      archive for more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <asm/bootinfo.h>
+#include <asm/dec/machtype.h>
+#include <asm/dec/tc.h>
+#include "pmag-ba-fb.h"
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+
+#define arraysize(x)    (sizeof(x)/sizeof(*(x)))
+
+struct pmag_ba_ramdac_regs {
+	unsigned char addr_low;
+	unsigned char pad0[3];
+	unsigned char addr_hi;
+	unsigned char pad1[3];
+	unsigned char data;
+	unsigned char pad2[3];
+	unsigned char cmap;
+};
+
+struct pmag_ba_my_fb_info {
+	struct fb_info info;
+	struct pmag_ba_ramdac_regs *bt459_regs;
+	unsigned long pmagba_fb_start;
+	unsigned long pmagba_fb_size;
+	unsigned long pmagba_fb_line_length;
+};
+
+static struct display disp;
+/*
+ * Max 3 TURBOchannel slots -> max 3 PMAG-BA :)
+ */
+static struct pmag_ba_my_fb_info pmagba_fb_info[3];
+
+static struct fb_var_screeninfo pmagbafb_defined = {
+	0, 0, 0, 0,		/* W,H, W, H (virtual) load xres,xres_virtual */
+	0, 0,			/* virtual -> visible no offset */
+	0,			/* depth -> load bits_per_pixel */
+	0,			/* greyscale ? */
+	{0, 0, 0},		/* R */
+	{0, 0, 0},		/* G */
+	{0, 0, 0},		/* B */
+	{0, 0, 0},		/* transparency */
+	0,			/* standard pixel format */
+	FB_ACTIVATE_NOW,
+	274, 195,		/* 14" monitor */
+	FB_ACCEL_NONE,
+	0L, 0L, 0L, 0L, 0L,
+	0L, 0L, 0,		/* No sync info */
+	FB_VMODE_NONINTERLACED,
+	{0, 0, 0, 0, 0, 0}
+};
+
+struct pmagbafb_par {
+};
+
+static int currcon = 0;
+struct pmagbafb_par current_par;
+
+static void pmagbafb_encode_var(struct fb_var_screeninfo *var,
+				struct pmagbafb_par *par)
+{
+	int i = 0;
+	var->xres = 1024;
+	var->yres = 864;
+	var->xres_virtual = 1024;
+	var->yres_virtual = 864;
+	var->xoffset = 0;
+	var->yoffset = 0;
+	var->bits_per_pixel = 8;
+	var->grayscale = 0;
+	var->transp.offset = 0;
+	var->transp.length = 0;
+	var->transp.msb_right = 0;
+	var->nonstd = 0;
+	var->activate = 1;
+	var->height = -1;
+	var->width = -1;
+	var->vmode = FB_VMODE_NONINTERLACED;
+	var->pixclock = 0;
+	var->sync = 0;
+	var->left_margin = 0;
+	var->right_margin = 0;
+	var->upper_margin = 0;
+	var->lower_margin = 0;
+	var->hsync_len = 0;
+	var->vsync_len = 0;
+	for (i = 0; i < arraysize(var->reserved); i++)
+		var->reserved[i] = 0;
+}
+
+static void pmagbafb_get_par(struct pmagbafb_par *par)
+{
+	*par = current_par;
+}
+
+static int pmagba_fb_update_var(int con, struct fb_info *info)
+{
+	return 0;
+}
+
+static int pmagba_do_fb_set_var(struct fb_var_screeninfo *var,
+				int isactive)
+{
+	struct pmagbafb_par par;
+
+	pmagbafb_get_par(&par);
+	pmagbafb_encode_var(var, &par);
+	return 0;
+}
+
+/*
+ * Turn hardware cursor off
+ */
+void pmagbafb_erase_cursor(struct pmag_ba_my_fb_info *info)
+{
+	info->bt459_regs->addr_low = 0;
+	info->bt459_regs->addr_hi = 3;
+	info->bt459_regs->data = 0;
+}
+
+/*
+ * Write to a Bt459 color map register
+ */
+void pmag_ba_bt459_write_colormap(struct pmag_ba_my_fb_info *info,
+				  int reg, __u8 red, __u8 green, __u8 blue)
+{
+	info->bt459_regs->addr_low = (__u8) reg;
+	info->bt459_regs->addr_hi = 0;
+	info->bt459_regs->cmap = red;
+	info->bt459_regs->cmap = green;
+	info->bt459_regs->cmap = blue;
+}
+
+/*
+ * Get the palette
+ */
+
+static int pmagbafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     struct fb_info *info)
+{
+	unsigned int i;
+	unsigned int length;
+
+	if (((cmap->start) + (cmap->len)) >= 256) {
+		length = 256 - (cmap->start);
+	} else {
+		length = cmap->len;
+	}
+	for (i = 0; i < length; i++) {
+		/*
+		 * TODO
+		 */
+	}
+	return 0;
+}
+
+/*
+ * Set the palette. 
+ */
+static int pmagbafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     struct fb_info *info)
+{
+	unsigned int i;
+	__u8 cmap_red, cmap_green, cmap_blue;
+	unsigned int length;
+
+	if (((cmap->start) + (cmap->len)) >= 256)
+		length = 256 - (cmap->start);
+	else
+		length = cmap->len;
+
+	for (i = 0; i < length; i++) {
+		cmap_red = ((cmap->red[i]) >> 8);	/* The cmap fields are 16 bits    */
+		cmap_green = ((cmap->green[i]) >> 8);	/* wide, but the harware colormap */
+		cmap_blue = ((cmap->blue[i]) >> 8);	/* registers are only 8 bits wide */
+
+		pmag_ba_bt459_write_colormap((struct pmag_ba_my_fb_info *)
+					     info, cmap->start + i,
+					     cmap_red, cmap_green,
+					     cmap_blue);
+	}
+	return 0;
+}
+
+static int pmagbafb_get_var(struct fb_var_screeninfo *var, int con,
+			    struct fb_info *info)
+{
+	struct pmagbafb_par par;
+	if (con == -1) {
+		pmagbafb_get_par(&par);
+		pmagbafb_encode_var(var, &par);
+	} else
+		*var = fb_display[con].var;
+	return 0;
+}
+
+
+static int pmagbafb_set_var(struct fb_var_screeninfo *var, int con,
+			    struct fb_info *info)
+{
+	int err;
+
+	if ((err = pmagba_do_fb_set_var(var, 1)))
+		return err;
+	return 0;
+}
+
+static void pmagbafb_encode_fix(struct fb_fix_screeninfo *fix,
+				struct pmagbafb_par *par,
+				struct pmag_ba_my_fb_info *info)
+{
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, "PMAG-BA");
+
+	fix->smem_start = info->pmagba_fb_start;
+	fix->smem_len = info->pmagba_fb_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	fix->xpanstep = 0;
+	fix->ypanstep = 0;
+	fix->ywrapstep = 0;
+	fix->line_length = info->pmagba_fb_line_length;
+}
+
+static int pmagbafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			    struct fb_info *info)
+{
+	struct pmagbafb_par par;
+
+	pmagbafb_get_par(&par);
+	pmagbafb_encode_fix(fix, &par, (struct pmag_ba_my_fb_info *) info);
+
+	return 0;
+}
+
+
+static int pmagbafb_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg, int con,
+			  struct fb_info *info)
+{
+	return -EINVAL;
+}
+
+static int pmagbafb_switch(int con, struct fb_info *info)
+{
+	pmagba_do_fb_set_var(&fb_display[con].var, 1);
+	currcon = con;
+
+	return 0;
+}
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+
+static void pmagbafb_blank(int blank, struct fb_info *info)
+{
+	/* Not supported */
+}
+
+static int pmagbafb_open(struct fb_info *info, int user)
+{
+	/*
+	 * Nothing, only a usage count for the moment
+	 */
+	MOD_INC_USE_COUNT;
+	return (0);
+}
+
+static void pmagbafb_set_disp(int con, struct pmag_ba_my_fb_info *info)
+{
+	struct fb_fix_screeninfo fix;
+	struct display *display;
+
+	if (con >= 0)
+		display = &fb_display[con];
+	else
+		display = &disp;	/* used during initialization */
+
+	pmagbafb_get_fix(&fix, con, (struct fb_info *) info);
+
+	display->screen_base = (char *) fix.smem_start;
+	display->visual = fix.visual;
+	display->type = fix.type;
+	display->type_aux = fix.type_aux;
+	display->ypanstep = fix.ypanstep;
+	display->ywrapstep = fix.ywrapstep;
+	display->line_length = fix.line_length;
+	display->next_line = fix.line_length;
+	display->can_soft_blank = 0;
+	display->inverse = 0;
+
+	display->dispsw = &fbcon_cfb8;
+}
+
+static int pmagbafb_release(struct fb_info *info, int user)
+{
+	MOD_DEC_USE_COUNT;
+	return (0);
+}
+
+static struct fb_ops pmagbafb_ops = {
+	owner:THIS_MODULE,
+	fb_open:pmagbafb_open,
+	fb_release:pmagbafb_release,
+	fb_get_fix:pmagbafb_get_fix,
+	fb_get_var:pmagbafb_get_var,
+	fb_set_var:pmagbafb_set_var,
+	fb_get_cmap:pmagbafb_get_cmap,
+	fb_set_cmap:pmagbafb_set_cmap,
+	fb_ioctl:pmagbafb_ioctl,
+	fb_mmap:0,
+	fb_rasterimg:0
+};
+
+int __init pmagbafb_init_one(int slot)
+{
+	unsigned long base_addr = get_tc_base_addr(slot);
+	struct pmag_ba_my_fb_info *ip =
+	    (struct pmag_ba_my_fb_info *) &pmagba_fb_info[slot];
+
+	printk("PMAG-BA framebuffer in slot %d\n", slot);
+
+	/*
+	 * Framebuffer display memory base address and friends
+	 */
+	ip->bt459_regs =
+	    (struct pmag_ba_ramdac_regs *) (base_addr +
+					    PMAG_BA_BT459_OFFSET);
+	ip->pmagba_fb_start = base_addr + PMAG_BA_ONBOARD_FBMEM_OFFSET;
+	ip->pmagba_fb_size = 1024 * 864;
+	ip->pmagba_fb_line_length = 1024;
+
+	/*
+	 * Configure the Bt459 RAM DAC
+	 */
+	pmagbafb_erase_cursor(ip);
+
+	/*
+	 *      Fill in the available video resolution
+	 */
+
+	pmagbafb_defined.xres = 1024;
+	pmagbafb_defined.yres = 864;
+	pmagbafb_defined.xres_virtual = 1024;
+	pmagbafb_defined.yres_virtual = 864;
+	pmagbafb_defined.bits_per_pixel = 8;
+
+	/*
+	 *      Let there be consoles..
+	 */
+	strcpy(ip->info.modename, "PMAG-BA");
+	ip->info.changevar = NULL;
+	ip->info.node = -1;
+	ip->info.fbops = &pmagbafb_ops;
+	ip->info.disp = &disp;
+	ip->info.switch_con = &pmagbafb_switch;
+	ip->info.updatevar = &pmagba_fb_update_var;
+	ip->info.blank = &pmagbafb_blank;
+	ip->info.flags = FBINFO_FLAG_DEFAULT;
+
+	pmagba_do_fb_set_var(&pmagbafb_defined, 1);
+	pmagbafb_get_var(&disp.var, -1, (struct fb_info *) ip);
+	pmagbafb_set_disp(-1, ip);
+
+	if (register_framebuffer((struct fb_info *) ip) < 0)
+		return 1;
+
+	return 0;
+}
+
+/* 
+ * Initialise the framebuffer
+ */
+
+int __init pmagbafb_init(void)
+{
+	int sid;
+	int found = 0;
+
+	if (TURBOCHANNEL) {
+		while ((sid = search_tc_card("PMAG-BA")) >= 0) {
+			found = 1;
+			claim_tc_card(sid);
+			pmagbafb_init_one(sid);
+		}
+		return found ? 0 : -ENODEV;
+	} else {
+		return -ENODEV;
+	}
+}
+
+int __init pmagbafb_setup(char *options)
+{
+	return 0;
+}
diff -urN linux-2.4.4-pre4/drivers/video/pmag-ba-fb.h linux/drivers/video/pmag-ba-fb.h
--- linux-2.4.4-pre4/drivers/video/pmag-ba-fb.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/pmag-ba-fb.h	Mon Dec  3 22:35:56 2001
@@ -0,0 +1,24 @@
+/*
+ *      linux/drivers/video/pmag-ba-fb.h
+ *
+ *      TurboChannel PMAG-BA framebuffer card support,
+ *      Copyright (C) 1999,2000,2001 by
+ *      Michael Engel <engel@unix-ag.org>,
+ *      Karsten Merker <merker@linuxtag.org>
+ *      This file is subject to the terms and conditions of the GNU General
+ *      Public License.  See the file COPYING in the main directory of this
+ *      archive for more details.
+ */
+
+/*
+ * Bt459 RAM DAC register base offset (rel. to TC slot base address)
+ */
+
+#define PMAG_BA_BT459_OFFSET                    0x00200000
+
+/*
+ * Begin of PMAG-BA framebuffer memory relative to TC slot address,
+ * resolution is 1024x864x8
+ */
+
+#define PMAG_BA_ONBOARD_FBMEM_OFFSET    0x00000000
diff -urN linux-2.4.4-pre4/drivers/video/pmagb-b-fb.c linux/drivers/video/pmagb-b-fb.c
--- linux-2.4.4-pre4/drivers/video/pmagb-b-fb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/pmagb-b-fb.c	Mon Dec  3 22:35:56 2001
@@ -0,0 +1,434 @@
+/*
+ *      linux/drivers/video/pmagb-b-fb.c
+ *
+ *	PMAGB-B TurboChannel framebuffer card support ... derived from:
+ *	"HP300 Topcat framebuffer support (derived from macfb of all things)
+ *	Phil Blundell <philb@gnu.org> 1998", the original code can be
+ *      found in the file hpfb.c in the same directory.
+ *
+ *      DECstation related code Copyright (C) 1999, 2000, 2001 by
+ *      Michael Engel <engel@unix-ag.org>,
+ *      Karsten Merker <merker@linuxtag.org> and 
+ *	Harald Koerfgen <harald@unix-ag.org>.
+ *      This file is subject to the terms and conditions of the GNU General
+ *      Public License.  See the file COPYING in the main directory of this
+ *      archive for more details.
+ *
+ */
+
+/*
+ *      We currently only support the PMAGB-B in high resolution mode
+ *      as I know of no way to detect low resolution mode set via jumper.
+ *      KM, 2001/01/07
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <asm/bootinfo.h>
+#include <asm/dec/machtype.h>
+#include <asm/dec/tc.h>
+#include "pmagb-b-fb.h"
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+
+#define arraysize(x)    (sizeof(x)/sizeof(*(x)))
+
+struct pmagb_b_ramdac_regs {
+	unsigned char addr_low;
+	unsigned char pad0[3];
+	unsigned char addr_hi;
+	unsigned char pad1[3];
+	unsigned char data;
+	unsigned char pad2[3];
+	unsigned char cmap;
+};
+
+struct pmagb_b_my_fb_info {
+	struct fb_info info;
+	struct pmagb_b_ramdac_regs *bt459_regs;
+	unsigned long pmagbb_fb_start;
+	unsigned long pmagbb_fb_size;
+	unsigned long pmagbb_fb_line_length;
+};
+
+static struct display disp;
+/*
+ * Max 3 TURBOchannel slots -> max 3 PMAGB-B :)
+ */
+static struct pmagb_b_my_fb_info pmagbb_fb_info[3];
+
+static struct fb_var_screeninfo pmagbbfb_defined = {
+	0, 0, 0, 0,		/* W,H, W, H (virtual) load xres,xres_virtual */
+	0, 0,			/* virtual -> visible no offset */
+	0,			/* depth -> load bits_per_pixel */
+	0,			/* greyscale ? */
+	{0, 0, 0},		/* R */
+	{0, 0, 0},		/* G */
+	{0, 0, 0},		/* B */
+	{0, 0, 0},		/* transparency */
+	0,			/* standard pixel format */
+	FB_ACTIVATE_NOW,
+	274, 195,		/* 14" monitor */
+	FB_ACCEL_NONE,
+	0L, 0L, 0L, 0L, 0L,
+	0L, 0L, 0,		/* No sync info */
+	FB_VMODE_NONINTERLACED,
+	{0, 0, 0, 0, 0, 0}
+};
+
+struct pmagbbfb_par {
+};
+
+static int currcon = 0;
+struct pmagbbfb_par current_par;
+
+static void pmagbbfb_encode_var(struct fb_var_screeninfo *var,
+				struct pmagbbfb_par *par)
+{
+	int i = 0;
+	var->xres = 1280;
+	var->yres = 1024;
+	var->xres_virtual = 1280;
+	var->yres_virtual = 1024;
+	var->xoffset = 0;
+	var->yoffset = 0;
+	var->bits_per_pixel = 8;
+	var->grayscale = 0;
+	var->transp.offset = 0;
+	var->transp.length = 0;
+	var->transp.msb_right = 0;
+	var->nonstd = 0;
+	var->activate = 1;
+	var->height = -1;
+	var->width = -1;
+	var->vmode = FB_VMODE_NONINTERLACED;
+	var->pixclock = 0;
+	var->sync = 0;
+	var->left_margin = 0;
+	var->right_margin = 0;
+	var->upper_margin = 0;
+	var->lower_margin = 0;
+	var->hsync_len = 0;
+	var->vsync_len = 0;
+	for (i = 0; i < arraysize(var->reserved); i++)
+		var->reserved[i] = 0;
+}
+
+static void pmagbbfb_get_par(struct pmagbbfb_par *par)
+{
+	*par = current_par;
+}
+
+static int pmagbb_fb_update_var(int con, struct fb_info *info)
+{
+	return 0;
+}
+
+static int pmagbb_do_fb_set_var(struct fb_var_screeninfo *var,
+				int isactive)
+{
+	struct pmagbbfb_par par;
+
+	pmagbbfb_get_par(&par);
+	pmagbbfb_encode_var(var, &par);
+	return 0;
+}
+
+/*
+ * Turn hardware cursor off
+ */
+void pmagbbfb_erase_cursor(struct pmagb_b_my_fb_info *info)
+{
+	info->bt459_regs->addr_low = 0;
+	info->bt459_regs->addr_hi = 3;
+	info->bt459_regs->data = 0;
+}
+
+/*
+ * Write to a Bt459 color map register
+ */
+void pmagb_b_bt459_write_colormap(struct pmagb_b_my_fb_info *info,
+				  int reg, __u8 red, __u8 green, __u8 blue)
+{
+	info->bt459_regs->addr_low = (__u8) reg;
+	info->bt459_regs->addr_hi = 0;
+	info->bt459_regs->cmap = red;
+	info->bt459_regs->cmap = green;
+	info->bt459_regs->cmap = blue;
+}
+
+/*
+ * Get the palette
+ */
+
+static int pmagbbfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     struct fb_info *info)
+{
+	unsigned int i;
+	unsigned int length;
+
+	if (((cmap->start) + (cmap->len)) >= 256) {
+		length = 256 - (cmap->start);
+	} else {
+		length = cmap->len;
+	}
+	for (i = 0; i < length; i++) {
+		/*
+		 * TODO
+		 */
+	}
+	return 0;
+}
+
+/*
+ * Set the palette. 
+ */
+static int pmagbbfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     struct fb_info *info)
+{
+	unsigned int i;
+	__u8 cmap_red, cmap_green, cmap_blue;
+	unsigned int length;
+
+	if (((cmap->start) + (cmap->len)) >= 256)
+		length = 256 - (cmap->start);
+	else
+		length = cmap->len;
+
+	for (i = 0; i < length; i++) {
+		cmap_red = ((cmap->red[i]) >> 8);	/* The cmap fields are 16 bits    */
+		cmap_green = ((cmap->green[i]) >> 8);	/* wide, but the harware colormap */
+		cmap_blue = ((cmap->blue[i]) >> 8);	/* registers are only 8 bits wide */
+
+		pmagb_b_bt459_write_colormap((struct pmagb_b_my_fb_info *)
+					     info, cmap->start + i,
+					     cmap_red, cmap_green,
+					     cmap_blue);
+	}
+	return 0;
+}
+
+static int pmagbbfb_get_var(struct fb_var_screeninfo *var, int con,
+			    struct fb_info *info)
+{
+	struct pmagbbfb_par par;
+	if (con == -1) {
+		pmagbbfb_get_par(&par);
+		pmagbbfb_encode_var(var, &par);
+	} else
+		*var = fb_display[con].var;
+	return 0;
+}
+
+
+static int pmagbbfb_set_var(struct fb_var_screeninfo *var, int con,
+			    struct fb_info *info)
+{
+	int err;
+
+	if ((err = pmagbb_do_fb_set_var(var, 1)))
+		return err;
+	return 0;
+}
+
+static void pmagbbfb_encode_fix(struct fb_fix_screeninfo *fix,
+				struct pmagbbfb_par *par,
+				struct pmagb_b_my_fb_info *info)
+{
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, "PMAGB-BA");
+
+	fix->smem_start = info->pmagbb_fb_start;
+	fix->smem_len = info->pmagbb_fb_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	fix->xpanstep = 0;
+	fix->ypanstep = 0;
+	fix->ywrapstep = 0;
+	fix->line_length = info->pmagbb_fb_line_length;
+}
+
+static int pmagbbfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			    struct fb_info *info)
+{
+	struct pmagbbfb_par par;
+
+	pmagbbfb_get_par(&par);
+	pmagbbfb_encode_fix(fix, &par, (struct pmagb_b_my_fb_info *) info);
+
+	return 0;
+}
+
+
+static int pmagbbfb_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg, int con,
+			  struct fb_info *info)
+{
+	return -EINVAL;
+}
+
+static int pmagbbfb_switch(int con, struct fb_info *info)
+{
+	pmagbb_do_fb_set_var(&fb_display[con].var, 1);
+	currcon = con;
+
+	return 0;
+}
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+
+static void pmagbbfb_blank(int blank, struct fb_info *info)
+{
+	/* Not supported */
+}
+
+static int pmagbbfb_open(struct fb_info *info, int user)
+{
+	/*
+	 * Nothing, only a usage count for the moment
+	 */
+	MOD_INC_USE_COUNT;
+	return (0);
+}
+
+static void pmagbbfb_set_disp(int con, struct pmagb_b_my_fb_info *info)
+{
+	struct fb_fix_screeninfo fix;
+	struct display *display;
+
+	if (con >= 0)
+		display = &fb_display[con];
+	else
+		display = &disp;	/* used during initialization */
+
+	pmagbbfb_get_fix(&fix, con, (struct fb_info *) info);
+
+	display->screen_base = (char *) fix.smem_start;
+	display->visual = fix.visual;
+	display->type = fix.type;
+	display->type_aux = fix.type_aux;
+	display->ypanstep = fix.ypanstep;
+	display->ywrapstep = fix.ywrapstep;
+	display->line_length = fix.line_length;
+	display->next_line = fix.line_length;
+	display->can_soft_blank = 0;
+	display->inverse = 0;
+
+	display->dispsw = &fbcon_cfb8;
+}
+
+static int pmagbbfb_release(struct fb_info *info, int user)
+{
+	MOD_DEC_USE_COUNT;
+	return (0);
+}
+
+static struct fb_ops pmagbbfb_ops = {
+	owner:THIS_MODULE,
+	fb_open:pmagbbfb_open,
+	fb_release:pmagbbfb_release,
+	fb_get_fix:pmagbbfb_get_fix,
+	fb_get_var:pmagbbfb_get_var,
+	fb_set_var:pmagbbfb_set_var,
+	fb_get_cmap:pmagbbfb_get_cmap,
+	fb_set_cmap:pmagbbfb_set_cmap,
+	fb_ioctl:pmagbbfb_ioctl,
+	fb_mmap:0,
+	fb_rasterimg:0
+};
+
+int __init pmagbbfb_init_one(int slot)
+{
+	unsigned long base_addr = get_tc_base_addr(slot);
+	struct pmagb_b_my_fb_info *ip =
+	    (struct pmagb_b_my_fb_info *) &pmagbb_fb_info[slot];
+
+	printk("PMAGB-BA framebuffer in slot %d\n", slot);
+
+	/*
+	 * Framebuffer display memory base address and friends
+	 */
+	ip->bt459_regs =
+	    (struct pmagb_b_ramdac_regs *) (base_addr +
+					    PMAGB_B_BT459_OFFSET);
+	ip->pmagbb_fb_start = base_addr + PMAGB_B_ONBOARD_FBMEM_OFFSET;
+	ip->pmagbb_fb_size = 1280 * 1024;
+	ip->pmagbb_fb_line_length = 1280;
+
+	/*
+	 * Configure the Bt459 RAM DAC
+	 */
+	pmagbbfb_erase_cursor(ip);
+
+	/*
+	 *      Fill in the available video resolution
+	 */
+
+	pmagbbfb_defined.xres = 1280;
+	pmagbbfb_defined.yres = 1024;
+	pmagbbfb_defined.xres_virtual = 1280;
+	pmagbbfb_defined.yres_virtual = 1024;
+	pmagbbfb_defined.bits_per_pixel = 8;
+
+	/*
+	 *      Let there be consoles..
+	 */
+	strcpy(ip->info.modename, "PMAGB-BA");
+	ip->info.changevar = NULL;
+	ip->info.node = -1;
+	ip->info.fbops = &pmagbbfb_ops;
+	ip->info.disp = &disp;
+	ip->info.switch_con = &pmagbbfb_switch;
+	ip->info.updatevar = &pmagbb_fb_update_var;
+	ip->info.blank = &pmagbbfb_blank;
+	ip->info.flags = FBINFO_FLAG_DEFAULT;
+
+	pmagbb_do_fb_set_var(&pmagbbfb_defined, 1);
+	pmagbbfb_get_var(&disp.var, -1, (struct fb_info *) ip);
+	pmagbbfb_set_disp(-1, ip);
+
+	if (register_framebuffer((struct fb_info *) ip) < 0)
+		return 1;
+
+	return 0;
+}
+
+/* 
+ * Initialise the framebuffer
+ */
+
+int __init pmagbbfb_init(void)
+{
+	int sid;
+	int found = 0;
+
+	if (TURBOCHANNEL) {
+		while ((sid = search_tc_card("PMAGB-BA")) >= 0) {
+			found = 1;
+			claim_tc_card(sid);
+			pmagbbfb_init_one(sid);
+		}
+		return found ? 0 : -ENODEV;
+	} else {
+		return -ENODEV;
+	}
+}
+
+int __init pmagbbfb_setup(char *options)
+{
+	return 0;
+}
diff -urN linux-2.4.4-pre4/drivers/video/pmagb-b-fb.h linux/drivers/video/pmagb-b-fb.h
--- linux-2.4.4-pre4/drivers/video/pmagb-b-fb.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/pmagb-b-fb.h	Mon Dec  3 22:35:56 2001
@@ -0,0 +1,32 @@
+/*
+ *      linux/drivers/video/pmagb-b-fb.h
+ *
+ *      TurboChannel PMAGB-B framebuffer card support,
+ *      Copyright (C) 1999, 2000, 2001 by
+ *      Michael Engel <engel@unix-ag.org> and 
+ *      Karsten Merker <merker@linxutag.org>
+ *      This file is subject to the terms and conditions of the GNU General
+ *      Public License.  See the file COPYING in the main directory of this
+ *      archive for more details.
+ */
+
+
+/*
+ * Bt459 RAM DAC register base offset (rel. to TC slot base address)
+ */
+#define PMAGB_B_BT459_OFFSET			0x001C0000
+
+/*
+ * Begin of PMAGB-B framebuffer memory, resolution is configurable:
+ * 1024x864x8 or 1280x1024x8, settable by jumper on the card
+ */
+#define PMAGB_B_ONBOARD_FBMEM_OFFSET	0x00201000
+
+/*
+ * Bt459 register offsets, byte-wide registers
+ */
+
+#define BT459_ADR_LOW			BT459_OFFSET + 0x00	/* addr. low */
+#define BT459_ADR_HIGH			BT459_OFFSET + 0x04	/* addr. high */
+#define BT459_DATA			BT459_OFFSET + 0x08	/* r/w data */
+#define BT459_CMAP			BT459_OFFSET + 0x0C	/* color map */
diff -urN linux-2.4.4-pre4/drivers/video/riva/rivafb.h linux/drivers/video/riva/rivafb.h
--- linux-2.4.4-pre4/drivers/video/riva/rivafb.h	Sat Feb  3 12:48:00 2001
+++ linux/drivers/video/riva/rivafb.h	Mon Dec  3 22:35:56 2001
@@ -82,4 +82,4 @@
 #endif
 };
 
-#endif /* __RIVAFB_H */
\ No newline at end of file
+#endif /* __RIVAFB_H */
diff -urN linux-2.4.4-pre4/drivers/video/sa1100fb.c linux/drivers/video/sa1100fb.c
--- linux-2.4.4-pre4/drivers/video/sa1100fb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/sa1100fb.c	Mon Dec  3 22:35:56 2001
@@ -688,6 +688,16 @@
 		init_var.grayscale	= 0;
 		init_var.sync		= 0;
 		init_var.pixclock	= 171521;
+	} else if (machine_is_pangolin()) {
+		current_par.max_xres	= 1024;
+		current_par.max_yres	= 768;
+		current_par.max_bpp	= 16;
+		init_var.red.length	= 5;
+		init_var.green.length	= 6;
+		init_var.blue.length	= 5;
+		init_var.grayscale	= 0;
+		init_var.sync		= 0;	
+		init_var.pixclock	= 15400;
 	} else if (machine_is_bitsy()) {
 		current_par.max_xres	= 320;
 		current_par.max_yres	= 240;
@@ -717,15 +727,7 @@
 		init_var.grayscale	= 1;
 		init_var.pixclock	= 150000;	
 		init_var.sync		= 0;
-	} else if (machine_is_penny()) {
-		current_par.max_xres	= 640;
-		current_par.max_yres	= 480;
-		current_par.max_bpp	= 8;
-		init_var.red.length	= 4;				
-		init_var.green		= init_var.red;
-		init_var.blue		= init_var.red;
-		init_var.sync		= 0;
-	} else if (machine_is_thinclient() || machine_is_graphicsclient()) {
+	} else if (machine_is_graphicsclient()) {
 		current_par.max_xres	= 640;
 		current_par.max_yres	= 480;
 		current_par.max_bpp	= 8;
@@ -733,24 +735,6 @@
 		init_var.green		= init_var.red;
 		init_var.blue		= init_var.red;
 		init_var.sync		= 0;
-	} else if (machine_is_tifon()) {
-		current_par.max_xres	= 640;
-		current_par.max_yres	= 200;
-		current_par.max_bpp	= 4;
-		current_par.inv_4bpp	= 1;
-		init_var.red.length	= 4;				
-		init_var.green		= init_var.red;
-		init_var.blue		= init_var.red;
-		init_var.grayscale	= 1;
-	        init_var.pixclock	= 150000;	
-	        init_var.left_margin	= 20;
-	        init_var.right_margin	= 255;
-	        init_var.upper_margin	= 20;
-	        init_var.lower_margin	= 0;
-	        init_var.hsync_len	= 2;
-	        init_var.vsync_len	= 1;
-		init_var.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT;
-		init_var.vmode		= 0;
 	} else if (machine_is_xp860()) {
 		current_par.max_xres	= 1024;
 		current_par.max_yres	= 768;
@@ -870,14 +854,7 @@
 {
 	unsigned int pcd = 0;
 
-	if (machine_is_tifon()) {
-		pcd = frequency[PPCR &0xf] / 1000;
-		pcd *= pixclock/1000;
-		pcd = pcd / 10000000 * 12;
-		/* the last multiplication by 1.2 is to handle */
-		/* sync problems */
-	}
-	if (machine_is_assabet()) {
+	if (machine_is_assabet() | machine_is_pangolin()) {
 		pcd = frequency[PPCR & 0xf] / 1000;
 		pcd *= pixclock / 1000;
 		pcd = pcd / 1000000;
@@ -933,6 +910,26 @@
 
 		/* Set board control register to handle new color depth */
 		sa1100fb_assabet_set_truecolor(var->bits_per_pixel >= 16);
+	} else if (machine_is_pangolin()) {
+		DPRINTK("Configuring Pangolin LCD\n");
+		lcd_shadow.lccr0 = 
+			LCCR0_LEN + LCCR0_Color + LCCR0_LDM +
+			LCCR0_BAM + LCCR0_ERM + LCCR0_Act +
+			LCCR0_LtlEnd + LCCR0_DMADel(0);
+		lcd_shadow.lccr1 = 
+			LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(63) + 
+			LCCR1_BegLnDel(127) + LCCR1_EndLnDel(127);
+		lcd_shadow.lccr2 = 
+			LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(2) + 
+			LCCR2_BegFrmDel(18) + LCCR2_EndFrmDel(18);
+		lcd_shadow.lccr3 = 
+			LCCR3_PixClkDiv(pcd) + LCCR3_HorSnchH +
+			LCCR3_VrtSnchH + LCCR3_OutEnH;
+		DPRINTK("pcd = %d\n", pcd);
+		DPRINTK("LCCR1_DisWdth(var->xres) = 0x%x\n",
+			LCCR1_DisWdth(var->xres));
+		DPRINTK("LCCR2_DisHght(var->yres) = 0x%x\n",
+			LCCR2_DisHght(var->yres));
 	} else if (machine_is_bitsy()) {
 		DPRINTK("Configuring  Bitsy LCD\n");
 		lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act +
@@ -998,24 +995,8 @@
 		lcd_shadow.lccr3 = 
 			LCCR3_PixClkDiv(34) + LCCR3_ACBsDiv(512) +
 			LCCR3_ACBsCntOff + LCCR3_HorSnchH + LCCR3_VrtSnchH;
-	} else if (machine_is_penny()) {
-		DPRINTK("Configuring  Penny LCD\n");
-		lcd_shadow.lccr0 = 
-			LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act + 
-			LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + 
-			LCCR0_DMADel(0); 
-		lcd_shadow.lccr1 = 
-			LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(65) +
-			LCCR1_EndLnDel(43) + LCCR1_BegLnDel(43);
-		lcd_shadow.lccr2 = 
-			LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(35) + 
-			LCCR2_EndFrmDel(0) + LCCR2_BegFrmDel(0);
-		lcd_shadow.lccr3 = 
-			LCCR3_PixClkDiv(16) + LCCR3_ACBsDiv (2) + LCCR3_ACBsCntOff +
-			((var->sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HorSnchH : LCCR3_HorSnchL) +
-			((var->sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VrtSnchH : LCCR3_VrtSnchL);
-	} else if (machine_is_thinclient() || machine_is_graphicsclient()) {
-		DPRINTK("Configuring ThinClient LCD\n");
+	} else if (machine_is_graphicsclient()) {
+		DPRINTK("Configuring GraphicsClient LCD\n");
 		lcd_shadow.lccr0 = 
 			LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act;
 		lcd_shadow.lccr1 = 
@@ -1027,29 +1008,6 @@
 		lcd_shadow.lccr3 = 
 			LCCR3_PixClkDiv(6) + LCCR3_ACBsDiv(2) + 
 			LCCR3_ACBsCntOff + LCCR3_HorSnchL + LCCR3_VrtSnchL;
-	} else if (machine_is_tifon()) {
-		DPRINTK("Configuring TIFON LCD\n");
-		lcd_shadow.lccr0 = 
-			LCCR0_LEN + LCCR0_Mono + LCCR0_Sngl + LCCR0_Pas +
-			LCCR0_BigEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + 
-			LCCR0_8PixMono + LCCR0_DMADel(0);
-		lcd_shadow.lccr1 = 
-			LCCR1_DisWdth(var->xres) + 
-			LCCR1_HorSnchWdth(var->hsync_len) +
-			LCCR1_BegLnDel(var->left_margin) +
-			LCCR1_EndLnDel(var->right_margin);
-		lcd_shadow.lccr2 = 
-			LCCR2_DisHght(var->yres) + 
-			LCCR2_VrtSnchWdth(var->vsync_len) +
-			LCCR2_BegFrmDel(var->upper_margin) +
-			LCCR2_EndFrmDel(var->lower_margin);
-		lcd_shadow.lccr3 = 
-			LCCR3_PixClkDiv(pcd) + LCCR3_ACBsDiv(512) +
-			LCCR3_ACBsCnt(0) + LCCR3_HorSnchH + LCCR3_VrtSnchH;
-		/*
-			((current_var.sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HorSnchH : LCCR3_HorSnchL) +
-			((current_var.sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VrtSnchH : LCCR3_VrtSnchL);
-		*/
 	} else if (machine_is_xp860()) {
 		DPRINTK("Configuring XP860 LCD\n");
 		lcd_shadow.lccr0 = 
@@ -1116,13 +1074,6 @@
 		                if (current_par.controller_state != LCD_MODE_DISABLE_BEFORE_ENABLE)
 		                        clr_bitsy_egpio(EGPIO_BITSY_LCD_ON | EGPIO_BITSY_LCD_PCI | EGPIO_BITSY_LCD_5V_ON | EGPIO_BITSY_LVDD_ON);
 #endif
-			} else if (machine_is_penny()) {
-#ifdef CONFIG_SA1100_PENNY
-				FpgaLcdCS1 = 0x000;	/* LCD Backlight to 0%    */
-				FpgaPortI &= ~LCD_ON;	/* Turn off LCD Backlight */
-#endif
-			} else if (machine_is_tifon()) {
-				GPCR = GPIO_GPIO(24);	/* turn off display */
 			}
 		}
 	}
@@ -1174,7 +1125,7 @@
 
 		/* Make sure the mode bits are present in the first palette entry */
 		current_par.v_palette_base[0] &= 0x0FFF; 	           
-		current_par.v_palette_base[0] |= SA1100_PALETTE_MODE_VAL(current_par.bits_per_pixel); 	 
+		current_par.v_palette_base[0] |= SA1100_PALETTE_MODE_VAL(current_par.bits_per_pixel);
 
 		/* Enable GPIO<9:2> for LCD usage if dual-scan */
 		if (lcd_shadow.lccr0 & LCCR0_SDS) {
@@ -1204,15 +1155,6 @@
 			DPRINTK("LCCR2=%x\n", LCCR2);
 			DPRINTK("LCCR3=%x\n", LCCR3);
 #endif
-		} else if (machine_is_penny()) {
-#ifdef CONFIG_SA1100_PENNY
-			FpgaLcdCS1 = 0x0FF;	/* LCD Backlight to 100% */
-			FpgaPortI  |= LCD_ON;	/* Turn on LCD Backlight */
-#endif
-		} else if (machine_is_tifon()) {
-			GPCR = GPIO_GPIO(24);	/* cycle on/off-switch */
-			udelay(150);
-			GPSR = GPIO_GPIO(24);	/* turn on display */
 		}
 
 		current_par.controller_state = LCD_MODE_ENABLED;
@@ -1307,19 +1249,15 @@
 		GAFR |= 0x3fc;
 		sa1100fb_assabet_set_truecolor(current_par.visual ==
 					       FB_VISUAL_TRUECOLOR);
+	} else if (machine_is_pangolin()) {
+		GPDR |= 0x3fc;
+		GAFR |= 0x3fc;
 	} else if (machine_is_bitsy()) {
 		GPDR = (GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8);
 		GAFR |= (GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8);
 	} else if (machine_is_cerf()) {
 		GPDR |= 0x3fc;
 		GAFR |= 0x3fc;
-	} else if (machine_is_penny()) {
-#ifdef CONFIG_SA1100_PENNY
-		GPDR |= GPIO_GPDR_GFX;	/* GPIO Data Direction register for LCD data bits 8-11 */
-		GAFR |= GPIO_GAFR_GFX;	/* GPIO Alternate Function register for LCD data bits 8-11 */
-#endif
-	} else if (machine_is_tifon()) {
-		GPDR |= GPIO_GPIO(24);	/* set GPIO24 to output */
 	} else if (machine_is_xp860()) {
 		GPDR |= 0x3fc;
 		GAFR |= 0x3fc;
diff -urN linux-2.4.4-pre4/drivers/video/tdfxfb.c linux/drivers/video/tdfxfb.c
--- linux-2.4.4-pre4/drivers/video/tdfxfb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/tdfxfb.c	Mon Dec  3 22:35:56 2001
@@ -88,6 +88,10 @@
 
 #include <linux/spinlock.h>
 
+#ifndef PCI_DEVICE_ID_3DFX_VOODOO5
+#define PCI_DEVICE_ID_3DFX_VOODOO5	0x0009
+#endif
+
 /* membase0 register offsets */
 #define STATUS		0x00
 #define PCIINIT0	0x04
@@ -248,6 +252,7 @@
 
 #define BANSHEE_MAX_PIXCLOCK 270000.0
 #define VOODOO3_MAX_PIXCLOCK 300000.0
+#define VOODOO5_MAX_PIXCLOCK 350000.0
 
 struct banshee_reg {
   /* VGA rubbish */
@@ -279,6 +284,7 @@
   unsigned long clip1max;
   unsigned long srcbase;
   unsigned long dstbase;
+  unsigned long miscinit0;
 };
 
 struct tdfxfb_par {
@@ -646,12 +652,14 @@
 static void do_flashcursor(unsigned long ptr)
 {
    struct fb_info_tdfx* i=(struct fb_info_tdfx *)ptr;
-   spin_lock(&i->DAClock);
+   unsigned long flags;
+
+   spin_lock_irqsave(&i->DAClock, flags);
    banshee_make_room(1);
    tdfx_outl( VIDPROCCFG, tdfx_inl(VIDPROCCFG) ^ VIDCFG_HWCURSOR_ENABLE );
    i->cursor.timer.expires=jiffies+HZ/2;
    add_timer(&i->cursor.timer);
-   spin_unlock(&i->DAClock);
+   spin_unlock_irqrestore(&i->DAClock, flags);
 }
 
 /*
@@ -921,6 +929,7 @@
   tdfx_outl(VIDDESKSTART,  reg->startaddr);
   tdfx_outl(VIDPROCCFG,    reg->vidcfg);
   tdfx_outl(VGAINIT1,      reg->vgainit1);  
+  tdfx_outl(MISCINIT0,	   reg->miscinit0);
 
   banshee_make_room(8);
   tdfx_outl(SRCBASE,         reg->srcbase);
@@ -942,19 +951,27 @@
   u32 lfbsize   = 0;
   int sgram_p     = 0;
 
-  if(!((fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE) ||
-       (fb_info.dev == PCI_DEVICE_ID_3DFX_VOODOO3)))
-    return 0;
-
   draminit0 = tdfx_inl(DRAMINIT0);  
   draminit1 = tdfx_inl(DRAMINIT1);
-   
-  sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1;
+
+  if ((fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE) ||
+      (fb_info.dev == PCI_DEVICE_ID_3DFX_VOODOO3)) {
+    sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1;
   
-  lfbsize = sgram_p ?
-    (((draminit0 & DRAMINIT0_SGRAM_NUM)  ? 2 : 1) * 
-     ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) :
-    16 * 1024 * 1024;
+    lfbsize = sgram_p ?
+      (((draminit0 & DRAMINIT0_SGRAM_NUM)  ? 2 : 1) * 
+       ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) :
+      16 * 1024 * 1024;
+  } else {
+    /* Voodoo4/5 */
+    u32 chips, psize, banks;
+
+    chips = ((draminit0 & (1 << 26)) == 0) ? 4 : 8;
+    psize = 1 << ((draminit0 & 0x38000000) >> 28);
+    banks = ((draminit0 & (1 << 30)) == 0) ? 2 : 4;
+    lfbsize = chips * psize * banks;
+    lfbsize <<= 20;
+  }
 
   /* disable block writes for SDRAM (why?) */
   miscinit1 = tdfx_inl(MISCINIT1);
@@ -1412,6 +1429,26 @@
   reg.screensize = par->width | (par->height << 12);
   reg.vidcfg &= ~VIDCFG_HALF_MODE;
 
+  reg.miscinit0 = tdfx_inl(MISCINIT0);
+
+#if defined(__BIG_ENDIAN)
+  switch (par->bpp) {
+    case 8:
+      reg.miscinit0 &= ~(1 << 30);
+      reg.miscinit0 &= ~(1 << 31);
+      break;
+    case 16:
+      reg.miscinit0 |= (1 << 30);
+      reg.miscinit0 |= (1 << 31);
+      break;
+    case 24:
+    case 32:
+      reg.miscinit0 |= (1 << 30);
+      reg.miscinit0 &= ~(1 << 31);
+      break;
+  }
+#endif
+
   do_write_regs(&reg);
 
   i->current_par = *par;
@@ -1462,6 +1499,7 @@
   switch(i->dev) {
   case PCI_DEVICE_ID_3DFX_BANSHEE:
   case PCI_DEVICE_ID_3DFX_VOODOO3:
+  case PCI_DEVICE_ID_3DFX_VOODOO5:
     par->width       = (var->xres + 15) & ~15; /* could sometimes be 8 */
     par->width_virt  = par->width;
     par->height      = var->yres;
@@ -1584,32 +1622,34 @@
 
   switch(info->dev) {
   case PCI_DEVICE_ID_3DFX_BANSHEE:
+    strcpy(fix->id, "3Dfx Banshee");
+    break;
   case PCI_DEVICE_ID_3DFX_VOODOO3:
-    strcpy(fix->id, 
-	   info->dev == PCI_DEVICE_ID_3DFX_BANSHEE 
-	   ? "3Dfx Banshee"
-	   : "3Dfx Voodoo3");
-    fix->smem_start  = info->bufbase_phys;
-    fix->smem_len    = info->bufbase_size;
-    fix->mmio_start  = info->regbase_phys;
-    fix->mmio_len    = info->regbase_size;
-    fix->accel       = FB_ACCEL_3DFX_BANSHEE;
-    fix->type        = FB_TYPE_PACKED_PIXELS;
-    fix->type_aux    = 0;
-    fix->line_length = par->lpitch;
-    fix->visual      = (par->bpp == 8) 
-                       ? FB_VISUAL_PSEUDOCOLOR
-                       : FB_VISUAL_DIRECTCOLOR;
-
-    fix->xpanstep    = 0; 
-    fix->ypanstep    = nopan ? 0 : 1;
-    fix->ywrapstep   = nowrap ? 0 : 1;
-
+    strcpy(fix->id, "3Dfx Voodoo3");
+    break;
+  case PCI_DEVICE_ID_3DFX_VOODOO5:
+    strcpy(fix->id, "3Dfx Voodoo5");
     break;
   default:
     return -EINVAL;
   }
 
+  fix->smem_start  = info->bufbase_phys;
+  fix->smem_len    = info->bufbase_size;
+  fix->mmio_start  = info->regbase_phys;
+  fix->mmio_len    = info->regbase_size;
+  fix->accel       = FB_ACCEL_3DFX_BANSHEE;
+  fix->type        = FB_TYPE_PACKED_PIXELS;
+  fix->type_aux    = 0;
+  fix->line_length = par->lpitch;
+  fix->visual      = (par->bpp == 8) 
+                     ? FB_VISUAL_PSEUDOCOLOR
+                     : FB_VISUAL_DIRECTCOLOR;
+
+  fix->xpanstep    = 0; 
+  fix->ypanstep    = nopan ? 0 : 1;
+  fix->ywrapstep   = nowrap ? 0 : 1;
+
   return 0;
 }
 
@@ -1850,17 +1890,25 @@
   while ((pdev = pci_find_device(PCI_VENDOR_ID_3DFX, PCI_ANY_ID, pdev))) {
     if(((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
        ((pdev->device == PCI_DEVICE_ID_3DFX_BANSHEE) ||
-	(pdev->device == PCI_DEVICE_ID_3DFX_VOODOO3))) {
-      char* name = pdev->device == PCI_DEVICE_ID_3DFX_BANSHEE
-	? "Banshee"
-	: "Voodoo3";
+	(pdev->device == PCI_DEVICE_ID_3DFX_VOODOO3) ||
+	(pdev->device == PCI_DEVICE_ID_3DFX_VOODOO5))) {
+      char *name;
 
       fb_info.dev   = pdev->device;
-      fb_info.max_pixclock = 
-	pdev->device == PCI_DEVICE_ID_3DFX_BANSHEE 
-	? BANSHEE_MAX_PIXCLOCK
-	: VOODOO3_MAX_PIXCLOCK;
-
+      switch (pdev->device) {
+      case PCI_DEVICE_ID_3DFX_BANSHEE:
+	fb_info.max_pixclock = BANSHEE_MAX_PIXCLOCK;
+	name = "Banshee";
+	break;
+      case PCI_DEVICE_ID_3DFX_VOODOO3:
+	fb_info.max_pixclock = VOODOO3_MAX_PIXCLOCK;
+	name = "Voodoo3";
+	break;
+      case PCI_DEVICE_ID_3DFX_VOODOO5:
+	fb_info.max_pixclock = VOODOO5_MAX_PIXCLOCK;
+	name = "Voodoo5";
+	break;
+      }
       fb_info.regbase_phys = pci_resource_start(pdev, 0);
       fb_info.regbase_size = 1 << 24;
       fb_info.regbase_virt = ioremap_nocache(fb_info.regbase_phys, 1 << 24);
diff -urN linux-2.4.4-pre4/drivers/video/vesafb.c linux/drivers/video/vesafb.c
--- linux-2.4.4-pre4/drivers/video/vesafb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/vesafb.c	Mon Dec  3 22:35:56 2001
@@ -2,7 +2,7 @@
  * framebuffer driver for VBE 2.0 compliant graphic boards
  *
  * switching to graphics mode happens at boot time (while
- * running in real mode, see arch/i386/video.S).
+ * running in real mode, see arch/i386/boot/video.S).
  *
  * (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
  *
diff -urN linux-2.4.4-pre4/drivers/video/vga16fb.c linux/drivers/video/vga16fb.c
--- linux-2.4.4-pre4/drivers/video/vga16fb.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/video/vga16fb.c	Mon Dec  3 22:35:56 2001
@@ -897,6 +897,10 @@
 	/* XXX share VGA_FB_PHYS region with vgacon */
 
         vga16fb.video_vbase = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
+	if (!vga16fb.video_vbase) {
+		printk(KERN_ERR "vga16fb: unable to map device\n");
+		return -ENOMEM;
+	}
 	printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.video_vbase);
 
 	vga16fb.isVGA = ORIG_VIDEO_ISVGA;
@@ -931,8 +935,10 @@
 	vga16fb.fb_info.flags=FBINFO_FLAG_DEFAULT;
 	vga16fb_set_disp(-1, &vga16fb);
 
-	if (register_framebuffer(&vga16fb.fb_info)<0)
+	if (register_framebuffer(&vga16fb.fb_info)<0) {
+		iounmap(vga16fb.video_vbase);
 		return -EINVAL;
+	}
 
 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
 	       GET_FB_IDX(vga16fb.fb_info.node), vga16fb.fb_info.modename);
diff -urN linux-2.4.4-pre4/fs/adfs/super.c linux/fs/adfs/super.c
--- linux-2.4.4-pre4/fs/adfs/super.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/adfs/super.c	Mon Dec  3 22:35:56 2001
@@ -386,12 +386,6 @@
 	sb->u.adfs_sb.s_version  = dr->format_version;
 	sb->u.adfs_sb.s_log2sharesize = dr->log2sharesize;
 	
-	/*
-	 * Max file size is 2Gb
-	 */
-	 
-	sb->s_maxbytes = MAX_NON_LFS;
-
 	sb->u.adfs_sb.s_map = adfs_read_map(sb, dr);
 	if (!sb->u.adfs_sb.s_map)
 		goto error_free_bh;
diff -urN linux-2.4.4-pre4/fs/affs/super.c linux/fs/affs/super.c
--- linux-2.4.4-pre4/fs/affs/super.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/affs/super.c	Mon Dec  3 22:35:56 2001
@@ -415,12 +415,6 @@
 
 	s->s_flags |= MS_NODEV | MS_NOSUID;
 
-	/*
-	 * Max file size is 2Gb
-	 */
-	 
-	s->s_maxbytes = MAX_NON_LFS;
-
 	/* Keep super block in cache */
 	bb = affs_bread(dev,root_block,s->s_blocksize);
 	if (!bb)
diff -urN linux-2.4.4-pre4/fs/bfs/inode.c linux/fs/bfs/inode.c
--- linux-2.4.4-pre4/fs/bfs/inode.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/bfs/inode.c	Mon Dec  3 22:35:56 2001
@@ -250,7 +250,6 @@
 	set_blocksize(dev, BFS_BSIZE);
 	s->s_blocksize = BFS_BSIZE;
 	s->s_blocksize_bits = BFS_BSIZE_BITS;
-	s->s_maxbytes = MAX_NON_LFS;
 
 	bh = bread(dev, 0, BFS_BSIZE);
 	if(!bh)
diff -urN linux-2.4.4-pre4/fs/buffer.c linux/fs/buffer.c
--- linux-2.4.4-pre4/fs/buffer.c	Mon Dec  3 22:35:46 2001
+++ linux/fs/buffer.c	Mon Dec  3 22:35:56 2001
@@ -555,25 +555,6 @@
 	return bh;
 }
 
-unsigned int get_hardblocksize(kdev_t dev)
-{
-	/*
-	 * Get the hard sector size for the given device.  If we don't know
-	 * what it is, return 0.
-	 */
-	if (hardsect_size[MAJOR(dev)] != NULL) {
-		int blksize = hardsect_size[MAJOR(dev)][MINOR(dev)];
-		if (blksize != 0)
-			return blksize;
-	}
-
-	/*
-	 * We don't know what the hardware sector size for this device is.
-	 * Return 0 indicating that we don't know.
-	 */
-	return 0;
-}
-
 void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode)
 {
 	spin_lock(&lru_list_lock);
diff -urN linux-2.4.4-pre4/fs/coda/inode.c linux/fs/coda/inode.c
--- linux-2.4.4-pre4/fs/coda/inode.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/coda/inode.c	Mon Dec  3 22:35:56 2001
@@ -141,7 +141,6 @@
         sb->s_magic = CODA_SUPER_MAGIC;
         sb->s_dev = dev;
         sb->s_op = &coda_super_operations;
-	sb->s_maxbytes = MAX_NON_LFS;
 
 	/* get root fid from Venus: this needs the root inode */
 	error = venus_rootfid(sb, &fid);
diff -urN linux-2.4.4-pre4/fs/cramfs/inode.c linux/fs/cramfs/inode.c
--- linux-2.4.4-pre4/fs/cramfs/inode.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/cramfs/inode.c	Mon Dec  3 22:35:56 2001
@@ -195,7 +195,6 @@
 	/* Set it all up.. */
 	sb->s_op	= &cramfs_ops;
 	sb->s_root 	= d_alloc_root(get_cramfs_inode(sb, &super.root));
-	sb->s_maxbytes = MAX_NON_LFS;
 	retval = sb;
 out:
 	return retval;
diff -urN linux-2.4.4-pre4/fs/efs/super.c linux/fs/efs/super.c
--- linux-2.4.4-pre4/fs/efs/super.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/efs/super.c	Mon Dec  3 22:35:56 2001
@@ -178,7 +178,6 @@
 	s->s_magic		= EFS_SUPER_MAGIC;
 	s->s_blocksize		= EFS_BLOCKSIZE;
 	s->s_blocksize_bits	= EFS_BLOCKSIZE_BITS;
-	s->s_maxbytes		= MAX_NON_LFS;
 
 	if (!(s->s_flags & MS_RDONLY)) {
 #ifdef DEBUG
diff -urN linux-2.4.4-pre4/fs/ext2/super.c linux/fs/ext2/super.c
--- linux-2.4.4-pre4/fs/ext2/super.c	Fri Dec 29 14:36:44 2000
+++ linux/fs/ext2/super.c	Mon Dec  3 22:35:56 2001
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/locks.h>
+#include <linux/blkdev.h>
 #include <asm/uaccess.h>
 
 
@@ -380,6 +381,23 @@
 }
 
 #define log2(n) ffz(~(n))
+ 
+/*
+ * Maximal file size.  There is a direct, and {,double-,triple-}indirect
+ * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks.
+ * We need to be 1 filesystem block less than the 2^32 sector limit.
+ */
+static loff_t ext2_max_size(int bits)
+{
+	loff_t res = EXT2_NDIR_BLOCKS;
+	res += 1LL << (bits-2);
+	res += 1LL << (2*(bits-2));
+	res += 1LL << (3*(bits-2));
+	res <<= bits;
+	if (res > (512LL << 32) - (1 << bits))
+		res = (512LL << 32) - (1 << bits);
+	return res;
+}
 
 struct super_block * ext2_read_super (struct super_block * sb, void * data,
 				      int silent)
@@ -404,11 +422,9 @@
 	 * This is important for devices that have a hardware
 	 * sectorsize that is larger than the default.
 	 */
-	blocksize = get_hardblocksize(dev);
-	if( blocksize == 0 || blocksize < BLOCK_SIZE )
-	  {
+	blocksize = get_hardsect_size(dev);
+	if(blocksize < BLOCK_SIZE )
 	    blocksize = BLOCK_SIZE;
-	  }
 
 	sb->u.ext2_sb.s_mount_opt = 0;
 	if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
@@ -475,6 +491,9 @@
 	sb->s_blocksize_bits =
 		le32_to_cpu(EXT2_SB(sb)->s_es->s_log_block_size) + 10;
 	sb->s_blocksize = 1 << sb->s_blocksize_bits;
+
+	sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits);
+
 	if (sb->s_blocksize != BLOCK_SIZE &&
 	    (sb->s_blocksize == 1024 || sb->s_blocksize == 2048 ||
 	     sb->s_blocksize == 4096)) {
@@ -482,11 +501,9 @@
 		 * Make sure the blocksize for the filesystem is larger
 		 * than the hardware sectorsize for the machine.
 		 */
-		hblock = get_hardblocksize(dev);
-		if(    (hblock != 0)
-		    && (sb->s_blocksize < hblock) )
-		{
-			printk("EXT2-fs: blocksize too small for device.\n");
+		hblock = get_hardsect_size(dev);
+		if (sb->s_blocksize < hblock) {
+			printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n");
 			goto failed_mount;
 		}
 
diff -urN linux-2.4.4-pre4/fs/fat/Makefile linux/fs/fat/Makefile
--- linux-2.4.4-pre4/fs/fat/Makefile	Fri Dec 29 14:07:23 2000
+++ linux/fs/fat/Makefile	Mon Dec  3 22:35:56 2001
@@ -11,7 +11,7 @@
 
 export-objs := fatfs_syms.o
 
-obj-y    := buffer.o cache.o dir.o file.o inode.o misc.o tables.o cvf.o fatfs_syms.o
+obj-y    := buffer.o cache.o dir.o file.o inode.o misc.o cvf.o fatfs_syms.o
 obj-m    := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.4-pre4/fs/fat/dir.c linux/fs/fat/dir.c
--- linux-2.4.4-pre4/fs/fat/dir.c	Tue Sep  5 14:07:29 2000
+++ linux/fs/fat/dir.c	Mon Dec  3 22:35:56 2001
@@ -65,7 +65,7 @@
 
 	while (*ip) {
 		ec = *ip++;
-		if ( (charlen = nls->uni2char(ec, op, 3)) > 0) {
+		if ( (charlen = nls->uni2char(ec, op, NLS_MAX_CHARSET_SIZE)) > 0) {
 			op += charlen;
 		} else {
 			if (uni_xlate == 1) {
@@ -114,20 +114,44 @@
 }
 
 static inline int
-fat_short2lower_uni(struct nls_table *t, unsigned char c, wchar_t *uni)
+fat_short2uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni)
 {
 	int charlen;
-	unsigned char nc = t->charset2lower[c];
-	
-	if (!nc)
-		nc = c;
 
-	if ( (charlen = t->char2uni(&nc, 1, uni)) < 0) {
+	charlen = t->char2uni(c, clen, uni);
+	if (charlen < 0) {
 		*uni = 0x003f;	/* a question mark */
+		charlen = 1;
 	}
 	return charlen;
 }
 
+static inline int
+fat_short2lower_uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni)
+{
+	int charlen;
+	wchar_t wc;
+
+	charlen = t->char2uni(c, clen, &wc);
+	if (charlen < 0) {
+		*uni = 0x003f;	/* a question mark */
+		charlen = 1;
+	} else if (charlen <= 1) {
+		unsigned char nc = t->charset2lower[*c];
+		
+		if (!nc)
+			nc = *c;
+		
+		if ( (charlen = t->char2uni(&nc, 1, uni)) < 0) {
+			*uni = 0x003f;	/* a question mark */
+			charlen = 1;
+		}
+	} else
+		*uni = wc;
+	
+	return charlen;
+}
+
 static int
 fat_strnicmp(struct nls_table *t, const unsigned char *s1,
 					const unsigned char *s2, int len)
@@ -153,10 +177,11 @@
 	struct nls_table *nls_disk = MSDOS_SB(sb)->nls_disk;
 	wchar_t bufuname[14];
 	unsigned char xlate_len, long_slots, *unicode = NULL;
-	char c, bufname[260];	/* 256 + 4 */
+	char work[8], bufname[260];	/* 256 + 4 */
 	int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate;
 	int utf8 = MSDOS_SB(sb)->options.utf8;
-	int ino, i, i2, last, res = 0;
+	int nocase = MSDOS_SB(sb)->options.nocase;
+	int ino, chl, i, j, last_u, res = 0;
 	loff_t cpos = 0;
 
 	while(1) {
@@ -237,27 +262,49 @@
 				long_slots = 0;
 		}
 
-		for (i = 0, last = 0; i < 8;) {
-			if (!(c = de->name[i])) break;
-			if (c == 0x05) c = 0xE5;
-			fat_short2lower_uni(nls_disk, c, &bufuname[i++]);
-			if (c != ' ')
-				last = i;
+		for (i = 0; i < 8; i++) {
+			/* see namei.c, msdos_format_name */
+			if (de->name[i] == 0x05)
+				work[i] = 0xE5;
+			else
+				work[i] = de->name[i];
 		}
-		i = last;
-		fat_short2lower_uni(nls_disk, '.', &bufuname[i++]);
-		for (i2 = 0; i2 < 3; i2++) {
-			if (!(c = de->ext[i2])) break;
-			fat_short2lower_uni(nls_disk, c, &bufuname[i++]);
-			if (c != ' ')
-				last = i;
+		for (i = 0, j = 0, last_u = 0; i < 8;) {
+			if (!work[i]) break;
+			if (nocase)
+				chl = fat_short2uni(nls_disk, &work[i], 8 - i, &bufuname[j++]);
+			else
+				chl = fat_short2lower_uni(nls_disk, &work[i], 8 - i, &bufuname[j++]);
+			if (chl <= 1) {
+				if (work[i] != ' ')
+					last_u = j;
+			} else {
+				last_u = j;
+			}
+			i += chl;
 		}
-		if (!last)
+		j = last_u;
+		fat_short2uni(nls_disk, ".", 1, &bufuname[j++]);
+		for (i = 0; i < 3;) {
+			if (!de->ext[i]) break;
+			if (nocase)
+				chl = fat_short2uni(nls_disk, &de->ext[i], 3 - i, &bufuname[j++]);
+			else
+				chl = fat_short2lower_uni(nls_disk, &de->ext[i], 3 - i, &bufuname[j++]);
+			if (chl <= 1) {
+				if (de->ext[i] != ' ')
+					last_u = j;
+			} else {
+				last_u = j;
+			}
+			i += chl;
+		}
+		if (!last_u)
 			continue;
 
-		memset(&bufuname[last], 0, sizeof(wchar_t));
+		bufuname[last_u] = 0x0000;
 		xlate_len = utf8
-			?utf8_wcstombs(bufname, bufuname, 260)
+			?utf8_wcstombs(bufname, bufuname, sizeof(bufname))
 			:uni16_to_x8(bufname, bufuname, uni_xlate, nls_io);
 		if (xlate_len == name_len)
 			if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
@@ -267,7 +314,7 @@
 
 		if (long_slots) {
 			xlate_len = utf8
-				?utf8_wcstombs(bufname, (wchar_t *) unicode, 260)
+				?utf8_wcstombs(bufname, (wchar_t *) unicode, sizeof(bufname))
 				:uni16_to_x8(bufname, (wchar_t *) unicode, uni_xlate, nls_io);
 			if (xlate_len != name_len)
 				continue;
@@ -298,15 +345,15 @@
 	struct msdos_dir_entry *de;
 	struct nls_table *nls_io = MSDOS_SB(sb)->nls_io;
 	struct nls_table *nls_disk = MSDOS_SB(sb)->nls_disk;
-	wchar_t bufuname[14], *ptuname = &bufuname[0];
+	wchar_t bufuname[14];
 	unsigned char long_slots, *unicode = NULL;
-	char c, bufname[56], *ptname = bufname;
+	char c, work[8], bufname[56], *ptname = bufname;
 	unsigned long lpos, dummy, *furrfu = &lpos;
 	int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate;
 	int isvfat = MSDOS_SB(sb)->options.isvfat;
 	int utf8 = MSDOS_SB(sb)->options.utf8;
 	int nocase = MSDOS_SB(sb)->options.nocase;
-	int ino,inum,i,i2,last, dotoffset = 0;
+	int ino, inum, chi, chl, i, i2, j, last, last_u, dotoffset = 0;
 	loff_t cpos;
 
 	cpos = filp->f_pos;
@@ -414,33 +461,67 @@
 	}
 
 	if ((de->attr & ATTR_HIDDEN) && MSDOS_SB(sb)->options.dotsOK) {
-		fat_short2lower_uni(nls_disk, '.', ptuname);
 		*ptname++ = '.';
 		dotoffset = 1;
 	}
-	for (i = 0, last = 0; i < 8;) {
-		if (!(c = de->name[i])) break;
+
+	for (i = 0; i < 8; i++) {
 		/* see namei.c, msdos_format_name */
-		if (c == 0x05) c = 0xE5;
-		fat_short2lower_uni(nls_disk, c, &ptuname[i]);
-		ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
-		if (c != ' ')
-			last = i;
+		if (de->name[i] == 0x05)
+			work[i] = 0xE5;
+		else
+			work[i] = de->name[i];
+	}
+	for (i = 0, j = 0, last = 0, last_u = 0; i < 8;) {
+		if (!(c = work[i])) break;
+		if (nocase)
+			chl = fat_short2uni(nls_disk, &work[i], 8 - i, &bufuname[j++]);
+		else
+			chl = fat_short2lower_uni(nls_disk, &work[i], 8 - i, &bufuname[j++]);
+		if (chl <= 1) {
+			ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
+			if (c != ' ') {
+				last = i;
+				last_u = j;
+			}
+		} else {
+			last_u = j;
+			for (chi = 0; chi < chl && i < 8; chi++) {
+				ptname[i] = work[i];
+				i++; last = i;
+			}
+		}
 	}
 	i = last;
-	fat_short2lower_uni(nls_disk, '.', &ptuname[i]);
+	j = last_u;
+	fat_short2uni(nls_disk, ".", 1, &bufuname[j++]);
 	ptname[i++] = '.';
-	for (i2 = 0; i2 < 3; i2++) {
+	for (i2 = 0; i2 < 3;) {
 		if (!(c = de->ext[i2])) break;
-		fat_short2lower_uni(nls_disk, c, &ptuname[i]);
-		ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
-		if (c != ' ')
-			last = i;
+		if (nocase)
+			chl = fat_short2uni(nls_disk, &de->ext[i2], 3 - i2, &bufuname[j++]);
+		else
+			chl = fat_short2lower_uni(nls_disk, &de->ext[i2], 3 - i2, &bufuname[j++]);
+		if (chl <= 1) {
+			i2++;
+			ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
+			if (c != ' ') {
+				last = i;
+				last_u = j;
+			}
+		} else {
+			last_u = j;
+			for (chi = 0; chi < chl && i2 < 3; chi++) {
+				ptname[i++] = de->ext[i2++];
+				last = i;
+			}
+		}
 	}
 	if (!last)
 		goto RecEnd;
 
 	i = last + dotoffset;
+	j = last_u;
 
 	lpos = cpos - (long_slots+1)*sizeof(struct msdos_dir_entry);
 	if (!memcmp(de->name,MSDOS_DOT,11))
@@ -458,8 +539,8 @@
 	}
 
 	if (isvfat) {
-		memset(&bufuname[i], 0, sizeof(wchar_t));
-		i = utf8 ? utf8_wcstombs(bufname, bufuname, 56)
+		bufuname[j] = 0x0000;
+		i = utf8 ? utf8_wcstombs(bufname, bufuname, sizeof(bufname))
 			 : uni16_to_x8(bufname, bufuname, uni_xlate, nls_io);
 	}
 
@@ -471,8 +552,8 @@
 			goto FillFailed;
 	} else {
 		char longname[275];
-		unsigned char long_len = utf8
-			? utf8_wcstombs(longname, (wchar_t *) unicode, 275)
+		int long_len = utf8
+			? utf8_wcstombs(longname, (wchar_t *) unicode, sizeof(longname))
 			: uni16_to_x8(longname, (wchar_t *) unicode, uni_xlate,
 				      nls_io);
 		if (both) {
diff -urN linux-2.4.4-pre4/fs/fat/fatfs_syms.c linux/fs/fat/fatfs_syms.c
--- linux-2.4.4-pre4/fs/fat/fatfs_syms.c	Sat Jul  8 19:38:30 2000
+++ linux/fs/fat/fatfs_syms.c	Mon Dec  3 22:35:56 2001
@@ -14,7 +14,6 @@
 #include <linux/fat_cvf.h>
 
 #include "msbuffer.h"
-#include "tables.h"
 
 EXPORT_SYMBOL(fat_new_dir);
 EXPORT_SYMBOL(fat_get_block);
diff -urN linux-2.4.4-pre4/fs/fat/inode.c linux/fs/fat/inode.c
--- linux-2.4.4-pre4/fs/fat/inode.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/fat/inode.c	Mon Dec  3 22:35:56 2001
@@ -434,7 +434,7 @@
 	char *p;
 	int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;
 	int debug,error,fat,cp;
-	int blksize = 512;
+	int blksize;
 	int fat32;
 	struct fat_mount_options opts;
 	char buf[50];
@@ -448,14 +448,14 @@
 	sbi->private_data = NULL;
 
 	sbi->dir_ops = fs_dir_inode_ops;
-	sb->s_op = &fat_sops;
-	if (hardsect_size[MAJOR(sb->s_dev)] != NULL){
-		blksize = hardsect_size[MAJOR(sb->s_dev)][MINOR(sb->s_dev)];
-		if (blksize != 512){
-			printk ("MSDOS: Hardware sector size is %d\n",blksize);
-		}
 
-	}
+	sb->s_maxbytes = MAX_NON_LFS;
+	sb->s_op = &fat_sops;
+	blksize = get_hardsect_size(sb->s_dev);
+	if (!blksize)
+		blksize = 512;
+	if (blksize != 512)
+		printk ("MSDOS: Hardware sector size is %d\n",blksize);
 
 	opts.isvfat = sbi->options.isvfat;
 	if (!parse_options((char *) data, &fat, &blksize, &debug, &opts, 
diff -urN linux-2.4.4-pre4/fs/file_table.c linux/fs/file_table.c
--- linux-2.4.4-pre4/fs/file_table.c	Tue Dec  5 10:27:31 2000
+++ linux/fs/file_table.c	Mon Dec  3 22:35:56 2001
@@ -66,10 +66,10 @@
 			goto new_one;
 		}
 		/* Big problems... */
-		printk("VFS: filp allocation failed\n");
+		printk(KERN_WARNING "VFS: filp allocation failed\n");
 
 	} else if (files_stat.max_files > old_max) {
-		printk("VFS: file-max limit %d reached\n", files_stat.max_files);
+		printk(KERN_INFO "VFS: file-max limit %d reached\n", files_stat.max_files);
 		old_max = files_stat.max_files;
 	}
 	file_list_unlock();
diff -urN linux-2.4.4-pre4/fs/filesystems.c linux/fs/filesystems.c
--- linux-2.4.4-pre4/fs/filesystems.c	Mon Dec  3 22:35:46 2001
+++ linux/fs/filesystems.c	Mon Dec  3 22:35:56 2001
@@ -7,6 +7,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <linux/kmod.h>
diff -urN linux-2.4.4-pre4/fs/hfs/super.c linux/fs/hfs/super.c
--- linux-2.4.4-pre4/fs/hfs/super.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/hfs/super.c	Mon Dec  3 22:35:56 2001
@@ -436,7 +436,6 @@
 		goto bail1;
 	}
 
-	s->s_maxbytes = MAX_NON_LFS;
 	s->s_magic = HFS_SUPER_MAGIC;
 	s->s_blocksize_bits = HFS_SECTOR_SIZE_BITS;
 	s->s_blocksize = HFS_SECTOR_SIZE;
diff -urN linux-2.4.4-pre4/fs/hpfs/super.c linux/fs/hpfs/super.c
--- linux-2.4.4-pre4/fs/hpfs/super.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/hpfs/super.c	Mon Dec  3 22:35:56 2001
@@ -427,7 +427,6 @@
 	s->s_blocksize = 512;
 	s->s_blocksize_bits = 9;
 	s->s_op = &hpfs_sops;
-	s->s_maxbytes = MAX_NON_LFS;
 
 	s->s_hpfs_root = superblock->root;
 	s->s_hpfs_fs_size = superblock->n_sectors;
diff -urN linux-2.4.4-pre4/fs/inode.c linux/fs/inode.c
--- linux-2.4.4-pre4/fs/inode.c	Thu Mar 22 11:04:13 2001
+++ linux/fs/inode.c	Mon Dec  3 22:35:56 2001
@@ -13,6 +13,8 @@
 #include <linux/quotaops.h>
 #include <linux/slab.h>
 #include <linux/cache.h>
+#include <linux/swap.h>
+#include <linux/swapctl.h>
 
 /*
  * New inode.c implementation.
@@ -197,6 +199,34 @@
 	inodes_stat.nr_unused--;
 }
 
+static inline void __sync_one(struct inode *inode, int sync)
+{
+	unsigned dirty;
+
+	list_del(&inode->i_list);
+	list_add(&inode->i_list, atomic_read(&inode->i_count)
+						? &inode_in_use
+						: &inode_unused);
+
+	/* Set I_LOCK, reset I_DIRTY */
+	dirty = inode->i_state & I_DIRTY;
+	inode->i_state |= I_LOCK;
+	inode->i_state &= ~I_DIRTY;
+	spin_unlock(&inode_lock);
+
+	filemap_fdatasync(inode->i_mapping);
+
+	/* Don't write the inode if only I_DIRTY_PAGES was set */
+	if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC))
+		write_inode(inode, sync);
+
+	filemap_fdatawait(inode->i_mapping);
+
+	spin_lock(&inode_lock);
+	inode->i_state &= ~I_LOCK;
+	wake_up(&inode->i_wait);
+}
+
 static inline void sync_one(struct inode *inode, int sync)
 {
 	if (inode->i_state & I_LOCK) {
@@ -206,29 +236,7 @@
 		iput(inode);
 		spin_lock(&inode_lock);
 	} else {
-		unsigned dirty;
-
-		list_del(&inode->i_list);
-		list_add(&inode->i_list, atomic_read(&inode->i_count)
-							? &inode_in_use
-							: &inode_unused);
-		/* Set I_LOCK, reset I_DIRTY */
-		dirty = inode->i_state & I_DIRTY;
-		inode->i_state |= I_LOCK;
-		inode->i_state &= ~I_DIRTY;
-		spin_unlock(&inode_lock);
-
-		filemap_fdatasync(inode->i_mapping);
-
-		/* Don't write the inode if only I_DIRTY_PAGES was set */
-		if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC))
-			write_inode(inode, sync);
-
-		filemap_fdatawait(inode->i_mapping);
-
-		spin_lock(&inode_lock);
-		inode->i_state &= ~I_LOCK;
-		wake_up(&inode->i_wait);
+		__sync_one(inode, sync);
 	}
 }
 
@@ -236,10 +244,42 @@
 {
 	struct list_head * tmp;
 
-	while ((tmp = head->prev) != head)
+	while ((tmp = head->prev) != head) 
 		sync_one(list_entry(tmp, struct inode, i_list), 0);
 }
 
+static inline int try_to_sync_unused_list(struct list_head *head)
+{
+	struct list_head *tmp = head;
+	struct inode *inode;
+
+	while ((tmp = tmp->prev) != head) {
+		inode = list_entry(tmp, struct inode, i_list);
+
+		if (!(inode->i_state & I_LOCK) 
+				&& !atomic_read(&inode->i_count)) {
+			/* 
+			 * We're under PF_MEMALLOC here, and syncing the 
+			 * inode may have to allocate memory. To avoid
+			 * running into a OOM deadlock, we write one 
+			 * inode synchronously and stop syncing in case 
+			 * we're under freepages.low
+			 */
+
+			int sync = nr_free_pages() < freepages.low;
+			__sync_one(inode, sync);
+			if (sync) 
+				return 0;
+			/* 
+			 * __sync_one moved the inode to another list,
+			 * so we have to start looking from the list head.
+			 */
+			tmp = head;
+		}
+	}
+	return 1;
+}
+
 /**
  *	sync_inodes
  *	@dev: device to sync the inodes from.
@@ -273,13 +313,14 @@
 /*
  * Called with the spinlock already held..
  */
-static void sync_all_inodes(void)
+static void try_to_sync_unused_inodes(void)
 {
 	struct super_block * sb = sb_entry(super_blocks.next);
 	for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.next)) {
 		if (!sb->s_dev)
 			continue;
-		sync_list(&sb->s_dirty);
+		if (!try_to_sync_unused_list(&sb->s_dirty))
+			break;
 	}
 }
 
@@ -503,13 +544,12 @@
 {
 	LIST_HEAD(list);
 	struct list_head *entry, *freeable = &list;
-	int count = 0;
+	int count = 0, synced = 0;
 	struct inode * inode;
 
 	spin_lock(&inode_lock);
-	/* go simple and safe syncing everything before starting */
-	sync_all_inodes();
 
+free_unused:
 	entry = inode_unused.prev;
 	while (entry != &inode_unused)
 	{
@@ -536,6 +576,20 @@
 	spin_unlock(&inode_lock);
 
 	dispose_list(freeable);
+
+	/* 
+	 * If we freed enough clean inodes, avoid writing 
+	 * dirty ones. Also giveup if we already tried to
+	 * sync dirty inodes.
+	 */
+	if (!goal || synced)
+		return;
+	
+	synced = 1;
+
+	spin_lock(&inode_lock);
+	try_to_sync_unused_inodes();
+	goto free_unused;
 }
 
 void shrink_icache_memory(int priority, int gfp_mask)
diff -urN linux-2.4.4-pre4/fs/isofs/inode.c linux/fs/isofs/inode.c
--- linux-2.4.4-pre4/fs/isofs/inode.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/isofs/inode.c	Mon Dec  3 22:35:56 2001
@@ -27,6 +27,7 @@
 #include <linux/nls.h>
 #include <linux/ctype.h>
 #include <linux/smp_lock.h>
+#include <linux/blkdev.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -493,21 +494,21 @@
 	printk("iocharset = %s\n", opt.iocharset);
 #endif
 
- 	/*
- 	 * First of all, get the hardware blocksize for this device.
- 	 * If we don't know what it is, or the hardware blocksize is
- 	 * larger than the blocksize the user specified, then use
- 	 * that value.
- 	 */
- 	blocksize = get_hardblocksize(dev);
- 	if(blocksize > opt.blocksize) {
- 	    /*
- 	     * Force the blocksize we are going to use to be the
- 	     * hardware blocksize.
- 	     */
- 	    opt.blocksize = blocksize;
+	/*
+	 * First of all, get the hardware blocksize for this device.
+	 * If we don't know what it is, or the hardware blocksize is
+	 * larger than the blocksize the user specified, then use
+	 * that value.
+	 */
+	blocksize = get_hardsect_size(dev);
+	if(blocksize > opt.blocksize) {
+	    /*
+	     * Force the blocksize we are going to use to be the
+	     * hardware blocksize.
+	     */
+	    opt.blocksize = blocksize;
 	}
- 
+
 	blocksize_bits = 0;
 	{
 	  int i = opt.blocksize;
@@ -666,8 +667,6 @@
 	/* Set this for reference. Its not currently used except on write
 	   which we don't have .. */
 	   
-	s->s_maxbytes = MAX_NON_LFS;
-
 	/* RDE: data zone now byte offset! */
 
 	first_data_zone = ((isonum_733 (rootp->extent) +
diff -urN linux-2.4.4-pre4/fs/minix/inode.c linux/fs/minix/inode.c
--- linux-2.4.4-pre4/fs/minix/inode.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/minix/inode.c	Mon Dec  3 22:35:56 2001
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/highuid.h>
+#include <linux/blkdev.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -179,7 +180,7 @@
 	const char * errmsg;
 	struct inode *root_inode;
 	unsigned int hblock;
-	
+
 	/* N.B. These should be compile-time tests.
 	   Unfortunately that is impossible. */
 	if (32 != sizeof (struct minix_inode))
@@ -187,8 +188,8 @@
 	if (64 != sizeof(struct minix2_inode))
 		panic("bad V2 i-node size");
 
-	hblock = get_hardblocksize(dev);
-	if (hblock && hblock > BLOCK_SIZE)
+	hblock = get_hardsect_size(dev);
+	if (hblock > BLOCK_SIZE)
 		goto out_bad_hblock;
 
 	set_blocksize(dev, BLOCK_SIZE);
@@ -259,8 +260,6 @@
 
 	minix_set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
 	minix_set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
-
-	s->s_maxbytes = MAX_NON_LFS;
 
 	/* set up enough so that it can read an inode */
 	s->s_op = &minix_sops;
diff -urN linux-2.4.4-pre4/fs/msdos/namei.c linux/fs/msdos/namei.c
--- linux-2.4.4-pre4/fs/msdos/namei.c	Tue Sep  5 14:07:29 2000
+++ linux/fs/msdos/namei.c	Mon Dec  3 22:35:56 2001
@@ -389,7 +389,7 @@
 	return res;
 
 mkdir_error:
-	printk("msdos_mkdir: error=%d, attempting cleanup\n", res);
+	printk(KERN_WARNING "msdos_mkdir: error=%d, attempting cleanup\n", res);
 	inode->i_nlink = 0;
 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	dir->i_nlink--;
diff -urN linux-2.4.4-pre4/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- linux-2.4.4-pre4/fs/ncpfs/inode.c	Fri Mar  2 11:12:11 2001
+++ linux/fs/ncpfs/inode.c	Mon Dec  3 22:35:56 2001
@@ -327,7 +327,6 @@
 	else
 		default_bufsize = 1024;
 
-	sb->s_maxbytes = MAX_NON_LFS;
 	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
 	sb->s_blocksize_bits = 10;
 	sb->s_magic = NCP_SUPER_MAGIC;
diff -urN linux-2.4.4-pre4/fs/nfs/inode.c linux/fs/nfs/inode.c
--- linux-2.4.4-pre4/fs/nfs/inode.c	Mon Dec  3 22:35:46 2001
+++ linux/fs/nfs/inode.c	Mon Dec  3 22:35:56 2001
@@ -435,9 +435,7 @@
         if (server->namelen == 0 || server->namelen > maxlen)
                 server->namelen = maxlen;
 
-	if(version == 2)
-		sb->s_maxbytes = MAX_NON_LFS;
-	else
+	if(version > 2)
 		sb->s_maxbytes = ~0ULL;	/* Unlimited on NFSv3 */
 
 	/* Fire up the writeback cache */
diff -urN linux-2.4.4-pre4/fs/ntfs/Makefile linux/fs/ntfs/Makefile
--- linux-2.4.4-pre4/fs/ntfs/Makefile	Fri Dec 29 14:07:23 2000
+++ linux/fs/ntfs/Makefile	Mon Dec  3 22:35:56 2001
@@ -4,7 +4,8 @@
 
 obj-y   := fs.o sysctl.o support.o util.o inode.o dir.o super.o attr.o
 obj-m   := $(O_TARGET)
-EXTRA_CFLAGS = -DNTFS_IN_LINUX_KERNEL -DNTFS_VERSION=\"000607\"
+# Version format: YYMMDD
+EXTRA_CFLAGS = -DNTFS_IN_LINUX_KERNEL -DNTFS_VERSION=\"010116\"
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.4.4-pre4/fs/ntfs/attr.c linux/fs/ntfs/attr.c
--- linux-2.4.4-pre4/fs/ntfs/attr.c	Mon Apr 12 10:05:58 1999
+++ linux/fs/ntfs/attr.c	Mon Dec  3 22:35:56 2001
@@ -1,10 +1,10 @@
-/*
- *  attr.c
+/*  attr.c
  *
  *  Copyright (C) 1996-1999 Martin von Löwis
  *  Copyright (C) 1996-1997 Régis Duchesne
  *  Copyright (C) 1998 Joseph Malicki
  *  Copyright (C) 1999 Steve Dodd
+ *  Copyright (C) 2001 Anton Altaparmakov (AIA)
  */
 
 #include "ntfstypes.h"
@@ -12,401 +12,389 @@
 #include "attr.h"
 
 #include <linux/errno.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
 #include "macros.h"
 #include "support.h"
 #include "util.h"
 #include "super.h"
 #include "inode.h"
 
-/* Look if an attribute already exists in the inode, and if not, create it */
-int 
-ntfs_new_attr(ntfs_inode *ino,int type,void *name,int namelen,int *pos,
-			int *found, int do_search )
+/* Look if an attribute already exists in the inode, and if not, create it. */
+int ntfs_new_attr(ntfs_inode *ino, int type, void *name, int namelen, int *pos,
+		  int *found, int do_search)
 {
-	int do_insert=0;
+	int do_insert = 0;
 	int i;
 
-	for(i=0;i<ino->attr_count;i++)
+	for (i = 0; i < ino->attr_count; i++)
 	{
-		int n=min(namelen,ino->attrs[i].namelen);
-		int s=ntfs_uni_strncmp(ino->attrs[i].name,name,n);
-		if( do_search ) {
-			/*
-			 * We assume that each attribute can be uniquely 
-			 * identified by inode
-			 * number, attribute type and attribute name.
-			 */
-			if(ino->attrs[i].type==type && ino->attrs[i].namelen==namelen && !s){
-				*found=1;
-				*pos=i;
+		int n = min(namelen, ino->attrs[i].namelen);
+		int s = ntfs_uni_strncmp(ino->attrs[i].name, name, n);
+		if (do_search) {
+			/* We assume that each attribute can be uniquely 
+			 * identified by inode number, attribute type and
+			 * attribute name. */
+			if (ino->attrs[i].type == type && 
+			    ino->attrs[i].namelen == namelen && !s) {
+				*found = 1;
+				*pos = i;
 				return 0;
 			}
 		}
-		/* attributes are ordered by type, then by name */
-		if(ino->attrs[i].type>type || (ino->attrs[i].type==type && s==1)){
-			do_insert=1;
+		/* Attributes are ordered by type, then by name. */
+		if (ino->attrs[i].type > type || 
+		    (ino->attrs[i].type == type && s == 1)) {
+			do_insert = 1;
 			break;
 		}
 	}
 
-	/* re-allocate space */
-	if(ino->attr_count % 8 ==0)
+	/* Re-allocate space. */
+	if (ino->attr_count % 8 == 0)
 	{
 		ntfs_attribute* new;
-		new = (ntfs_attribute*)ntfs_malloc((ino->attr_count+8)*
-			     sizeof(ntfs_attribute));
-		if( !new )
-			return ENOMEM;
-		if( ino->attrs ) {
-			ntfs_memcpy( new, ino->attrs, ino->attr_count*sizeof(ntfs_attribute) );
-			ntfs_free( ino->attrs );
+		new = (ntfs_attribute*)ntfs_malloc((ino->attr_count + 8) *
+							sizeof(ntfs_attribute));
+		if (!new)
+			return -ENOMEM;
+		if (ino->attrs) {
+			ntfs_memcpy(new, ino->attrs, ino->attr_count *
+							sizeof(ntfs_attribute));
+			ntfs_free(ino->attrs);
 		}
 		ino->attrs = new;
 	}
-	if(do_insert)
-		ntfs_memmove(ino->attrs+i+1,ino->attrs+i,(ino->attr_count-i)*
-			    sizeof(ntfs_attribute));
-
+	if (do_insert)
+		ntfs_memmove(ino->attrs + i + 1, ino->attrs + i,
+			     (ino->attr_count - i) * sizeof(ntfs_attribute));
 	ino->attr_count++;
-	ino->attrs[i].type=type;
-	ino->attrs[i].namelen=namelen;
-	ino->attrs[i].name=name;
-	*pos=i;
-	*found=0;
+	ino->attrs[i].type = type;
+	ino->attrs[i].namelen = namelen;
+	ino->attrs[i].name = name;
+	*pos = i;
+	*found = 0;
 	return 0;
 }
 
-int 
-ntfs_make_attr_resident(ntfs_inode *ino,ntfs_attribute *attr)
+int ntfs_make_attr_resident(ntfs_inode *ino, ntfs_attribute *attr)
 {
-	int size=attr->size;
-	if(size>0){
+	int size = attr->size;
+	if (size > 0) {
 		/* FIXME: read data, free clusters */
-		return EOPNOTSUPP;
+		return -EOPNOTSUPP;
 	}
-	attr->resident=1;
+	attr->resident = 1;
 	return 0;
 }
 
-/* Store in the inode readable information about a run */
-void
-ntfs_insert_run(ntfs_attribute *attr,int cnum,ntfs_cluster_t cluster,int len)
+/* Store in the inode readable information about a run. */
+void ntfs_insert_run(ntfs_attribute *attr, int cnum, ntfs_cluster_t cluster,
+		     int len)
 {
-	/* (re-)allocate space if necessary */
-	if(attr->d.r.len % 8 == 0) {
+	/* (re-)allocate space if necessary. */
+	if (attr->d.r.len % 8 == 0) {
 		ntfs_runlist* new;
-		new = ntfs_malloc((attr->d.r.len+8)*sizeof(ntfs_runlist));
-		if( !new )
+		new = ntfs_malloc((attr->d.r.len + 8) * sizeof(ntfs_runlist));
+		if (!new)
 			return;
-		if( attr->d.r.runlist ) {
+		if (attr->d.r.runlist) {
 			ntfs_memcpy(new, attr->d.r.runlist, attr->d.r.len
-				    *sizeof(ntfs_runlist));
-			ntfs_free( attr->d.r.runlist );
+							* sizeof(ntfs_runlist));
+			ntfs_free(attr->d.r.runlist);
 		}
 		attr->d.r.runlist = new;
 	}
-	if(attr->d.r.len>cnum)
-		ntfs_memmove(attr->d.r.runlist+cnum+1,attr->d.r.runlist+cnum,
-			    (attr->d.r.len-cnum)*sizeof(ntfs_runlist));
-	attr->d.r.runlist[cnum].cluster=cluster;
-	attr->d.r.runlist[cnum].len=len;
+	if (attr->d.r.len > cnum)
+		ntfs_memmove(attr->d.r.runlist + cnum + 1,
+			     attr->d.r.runlist + cnum,
+			     (attr->d.r.len - cnum) * sizeof(ntfs_runlist));
+	attr->d.r.runlist[cnum].cluster = cluster;
+	attr->d.r.runlist[cnum].len = len;
 	attr->d.r.len++;
 }
 
-/* Extends an attribute. Another run will be added if necessary,
- * but we try to extend the last run in the runlist first.
+/* Extends an attribute. Another run will be added if necessary, but we try to
+ * extend the last run in the runlist first.
  * FIXME: what if there isn't enough contiguous space, we don't create
  * multiple runs?
  *
  * *len: the desired new length of the attr (_not_ the amount to extend by)
  */
-int ntfs_extend_attr(ntfs_inode *ino, ntfs_attribute *attr, int *len,
-		int flags)
+int ntfs_extend_attr(ntfs_inode *ino, ntfs_attribute *attr, int *len, int flags)
 {
-	int error=0;
+	int error = 0;
 	ntfs_runlist *rl;
 	int rlen;
 	ntfs_cluster_t cluster;
 	int clen;
 
-	if(attr->compressed)return EOPNOTSUPP;
-	if(ino->record_count>1)return EOPNOTSUPP;
-
-	if(attr->resident) {
-		error = ntfs_make_attr_nonresident(ino,attr);
-		if(error)
+	if (attr->compressed || ino->record_count > 1)
+		return -EOPNOTSUPP;
+	if (attr->resident) {
+		error = ntfs_make_attr_nonresident(ino, attr);
+		if (error)
 			return error;
 	}
-
-	if( *len <= attr->allocated )
-		return 0;	/* truely stupid things do sometimes happen */
-
-	rl=attr->d.r.runlist;
-	rlen=attr->d.r.len-1;
-
-	if(rlen>=0)
-		cluster=rl[rlen].cluster+rl[rlen].len;
+	if (*len <= attr->allocated)
+		return 0;	/* Truely stupid things do sometimes happen. */
+	rl = attr->d.r.runlist;
+	rlen = attr->d.r.len - 1;
+	if (rlen >= 0)
+		cluster = rl[rlen].cluster + rl[rlen].len;
 	else
-		/* no preference for allocation space */
-		cluster=0;
-
-	/* calculate the extra space we need, and round up to multiple of cluster
-	 * size to get number of new clusters needed */
-
-	clen=( (*len - attr->allocated ) + ino->vol->clustersize - 1 ) /
+		/* No preference for allocation space. */
+		cluster = 0;
+	/* Calculate the extra space we need, and round up to multiple of
+	 * cluster size to get number of new clusters needed */
+	clen = ((*len - attr->allocated) + ino->vol->clustersize - 1) /
 		ino->vol->clustersize;
-	if(clen==0)
+	if (clen == 0)
 		return 0;
-
 	/* FIXME: try to allocate smaller pieces */
-	error=ntfs_allocate_clusters(ino->vol,&cluster,&clen,
-				     flags|ALLOC_REQUIRE_SIZE);
-	if(error)return error;
-	attr->allocated += clen*ino->vol->clustersize;
+	error = ntfs_allocate_clusters(ino->vol, &cluster, &clen,
+				       flags | ALLOC_REQUIRE_SIZE);
+	if (error)
+		return error;
+	attr->allocated += clen * ino->vol->clustersize;
 	*len = attr->allocated;
-
-	/* contiguous chunk */
-	if(rlen>=0 && cluster==rl[rlen].cluster+rl[rlen].len){
+	/* Contiguous chunk. */
+	if (rlen >= 0 && cluster == rl[rlen].cluster + rl[rlen].len) {
 		rl[rlen].len += clen;
 		return 0;
 	}
-	ntfs_insert_run(attr,rlen+1,cluster,clen);
+	ntfs_insert_run(attr, rlen + 1, cluster, clen);
 	return 0;
 }
 
-int
-ntfs_make_attr_nonresident(ntfs_inode *ino, ntfs_attribute *attr)
+int ntfs_make_attr_nonresident(ntfs_inode *ino, ntfs_attribute *attr)
 {
-	void *data=attr->d.data;
-	int len=attr->size;
-	int error,alen;
+	void *data = attr->d.data;
+	int len = attr->size;
+	int error, alen;
 	ntfs_io io;
-	attr->d.r.len=0;
-	attr->d.r.runlist=0;
-	attr->resident=0;
-	attr->allocated=attr->initialized=0;
-	alen=len;
-	error=ntfs_extend_attr(ino,attr,&alen,ALLOC_REQUIRE_SIZE);
-	if(error)return error;/* FIXME: On error, restore old values */
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	io.param=data;
-	io.size=len;
-	io.do_read=0;
-	return ntfs_readwrite_attr(ino,attr,0,&io);
+	attr->d.r.len = 0;
+	attr->d.r.runlist = 0;
+	attr->resident = 0;
+	attr->allocated=attr->initialized = 0;
+	alen = len;
+	error = ntfs_extend_attr(ino, attr, &alen, ALLOC_REQUIRE_SIZE);
+	if (error)
+		return error; /* FIXME: On error, restore old values. */
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	io.param = data;
+	io.size = len;
+	io.do_read = 0;
+	return ntfs_readwrite_attr(ino, attr, 0, &io);
 }
 
-int
-ntfs_attr_allnonresident(ntfs_inode *ino)
+int ntfs_attr_allnonresident(ntfs_inode *ino)
 {
-	int i, error=0;
+	int i, error = 0;
         ntfs_volume *vol = ino->vol;
 
-	for (i=0; !error && i<ino->attr_count; i++)
+	for (i = 0; !error && i < ino->attr_count; i++)
 	{
-		if (ino->attrs[i].type != vol->at_security_descriptor
-		    && ino->attrs[i].type != vol->at_data)
+		if (ino->attrs[i].type != vol->at_security_descriptor &&
+		    ino->attrs[i].type != vol->at_data)
 			continue;
-		error = ntfs_make_attr_nonresident (ino, ino->attrs+i);
+		error = ntfs_make_attr_nonresident(ino, ino->attrs + i);
 	}
 	return error;
 }
 
-/* Resize the attribute to a newsize */
+/* Resize the attribute to a newsize. */
 int ntfs_resize_attr(ntfs_inode *ino, ntfs_attribute *attr, int newsize)
 {
-	int error=0;
-	int oldsize=attr->size;
-	int clustersize=ino->vol->clustersize;
-	int i,count,newlen,newcount;
+	int error = 0;
+	int oldsize = attr->size;
+	int clustersize = ino->vol->clustersize;
+	int i, count, newlen, newcount;
 	ntfs_runlist *rl;
 
-	if(newsize==oldsize)
+	if (newsize == oldsize)
 		return 0;
-	/* modifying compressed attributes not supported yet */
-	if(attr->compressed)
-		/* extending is easy: just insert sparse runs */
-		return EOPNOTSUPP;
-	if(attr->resident){
+	/* FIXME: Modifying compressed attributes not supported yet. */
+	if (attr->compressed)
+		/* FIXME: Extending is easy: just insert sparse runs. */
+		return -EOPNOTSUPP;
+	if (attr->resident) {
 		void *v;
-		if(newsize>ino->vol->mft_recordsize){
-			error=ntfs_make_attr_nonresident(ino,attr);
-			if(error)return error;
-			return ntfs_resize_attr(ino,attr,newsize);
+		if (newsize > ino->vol->mft_recordsize) {
+			error = ntfs_make_attr_nonresident(ino, attr);
+			if (error)
+				return error;
+			return ntfs_resize_attr(ino, attr, newsize);
 		}
-		v=attr->d.data;
-		if(newsize){
-			attr->d.data=ntfs_malloc(newsize);
-			if(!attr->d.data) {
+		v = attr->d.data;
+		if (newsize) {
+			attr->d.data = ntfs_malloc(newsize);
+			if (!attr->d.data) {
 				ntfs_free(v);
-				return ENOMEM;
+				return -ENOMEM;
 			}
-			if(newsize>oldsize)
-				ntfs_bzero((char*)attr->d.data+oldsize,
-					   newsize-oldsize);
-			ntfs_memcpy((char*)attr->d.data,v,min(newsize,oldsize));
-		}else
-			attr->d.data=0;
+			if (newsize > oldsize)
+				ntfs_bzero((char*)attr->d.data + oldsize,
+					   newsize - oldsize);
+			ntfs_memcpy((char*)attr->d.data, v,
+				    min(newsize, oldsize));
+		} else
+			attr->d.data = 0;
 		ntfs_free(v);
-		attr->size=newsize;
+		attr->size = newsize;
 		return 0;
 	}
-	/* non-resident attribute */
-	rl=attr->d.r.runlist;
-	if(newsize<oldsize){
-		for(i=0,count=0;i<attr->d.r.len;i++){
-			if((count+rl[i].len)*clustersize>newsize)
+	/* Non-resident attribute. */
+	rl = attr->d.r.runlist;
+	if (newsize < oldsize) {
+		for (i = 0, count = 0; i < attr->d.r.len; i++) {
+			if ((count + rl[i].len) * clustersize > newsize)
 				break;
-			count+=(int)rl[i].len;
+			count += (int)rl[i].len;
 		}
-		newlen=i+1;
-		/* free unused clusters in current run, unless sparse */
-		newcount=count;
-		if(rl[i].cluster!=MAX_CLUSTER_T){
-			int rounded=newsize-count*clustersize;
-			rounded=(rounded+clustersize-1)/clustersize;
-			error=ntfs_deallocate_clusters(ino->vol,rl[i].cluster+rounded,
-						       (int)rl[i].len-rounded);
-			if(error)
-				return error; /* FIXME: incomplete operation */
-			rl[i].len=rounded;
-			newcount=count+rounded;
+		newlen = i + 1;
+		/* Free unused clusters in current run, unless sparse. */
+		newcount = count;
+		if (rl[i].cluster != MAX_CLUSTER_T) {
+			int rounded = newsize - count * clustersize;
+			rounded = (rounded + clustersize - 1) / clustersize;
+			error = ntfs_deallocate_clusters(ino->vol, 
+						rl[i].cluster + rounded,
+						(int)rl[i].len - rounded);
+			if (error)
+				return error; /* FIXME: Incomplete operation. */
+			rl[i].len = rounded;
+			newcount = count + rounded;
 		}
-		/* free all other runs */
-		for(i++;i<attr->d.r.len;i++)
-			if(rl[i].cluster!=MAX_CLUSTER_T){
-				error=ntfs_deallocate_clusters(ino->vol,rl[i].cluster,(int)rl[i].len);
-				if(error)
-					return error; /* FIXME: incomplete operation */
+		/* Free all other runs. */
+		for (i++; i < attr->d.r.len; i++)
+			if (rl[i].cluster != MAX_CLUSTER_T) {
+				error = ntfs_deallocate_clusters(ino->vol,
+								rl[i].cluster,
+								(int)rl[i].len);
+				if (error)
+					return error; /* FIXME: Incomplete 
+						       * operation */
 			}
-		/* FIXME? free space for extra runs in memory */
-		attr->d.r.len=newlen;
-	}else{
-		newlen=newsize;
-		error=ntfs_extend_attr(ino,attr,&newlen,ALLOC_REQUIRE_SIZE);
-		if(error)return error; /* FIXME: incomplete */
-		newcount=newlen/clustersize;
+		/* FIXME: Free space for extra runs in memory? */
+		attr->d.r.len = newlen;
+	} else {
+		newlen = newsize;
+		error = ntfs_extend_attr(ino, attr, &newlen,
+					 ALLOC_REQUIRE_SIZE);
+		if (error)
+			return error; /* FIXME: Incomplete operation. */
+		newcount = newlen / clustersize;
 	}
-	/* fill in new sizes */
-	attr->allocated = newcount*clustersize;
+	/* Fill in new sizes. */
+	attr->allocated = newcount * clustersize;
 	attr->size = newsize;
 	/* attr->initialized does not change. */
-	if(!newsize)
-		error=ntfs_make_attr_resident(ino,attr);
+	if (!newsize)
+		error = ntfs_make_attr_resident(ino, attr);
 	return error;
 }
 
 int ntfs_create_attr(ntfs_inode *ino, int anum, char *aname, void *data,
-	int dsize, ntfs_attribute **rattr)
+		     int dsize, ntfs_attribute **rattr)
 {
 	void *name;
 	int namelen;
-	int found,i;
+	int found, i;
 	int error;
 	ntfs_attribute *attr;
-	if(dsize>ino->vol->mft_recordsize)
-		/* FIXME: non-resident attributes */
-		return EOPNOTSUPP;
-	if(aname){
-		namelen=strlen(aname);
-		name=ntfs_malloc(2*namelen);
-		if( !name )
-			return ENOMEM;
-		ntfs_ascii2uni(name,aname,namelen);
-	}else{
-		name=0;
-		namelen=0;
-	}
-
-	error = ntfs_new_attr(ino,anum,name,namelen,&i,&found,1);
-	if( error ) {
-		ntfs_free( name );
+	
+	if (dsize > ino->vol->mft_recordsize)
+		/* FIXME: Non-resident attributes. */
+		return -EOPNOTSUPP;
+	if (aname) {
+		namelen = strlen(aname);
+		name = ntfs_malloc(2 * namelen);
+		if (!name)
+			return -ENOMEM;
+		ntfs_ascii2uni(name, aname, namelen);
+	} else {
+		name = 0;
+		namelen = 0;
+	}
+	error = ntfs_new_attr(ino, anum, name, namelen, &i, &found, 1);
+	if (error) {
+		ntfs_free(name);
 		return error;
 	}
-
-	if(found){
+	if (found) {
 		ntfs_free(name);
-		return EEXIST;
+		return -EEXIST;
 	}
-	*rattr=attr=ino->attrs+i;
-	/* allocate a new number.
-	   FIXME: Should this happen on inode writeback?
-	   FIXME: extensions records not supported */
-	error=ntfs_allocate_attr_number(ino,&i);
-	if(error)
+	*rattr = attr = ino->attrs + i;
+	/* Allocate a new number.
+	 * FIXME: Should this happen on inode writeback?
+	 * FIXME: Extension records not supported. */
+	error = ntfs_allocate_attr_number(ino, &i);
+	if (error)
 		return error;
-	attr->attrno=i;
-
-	attr->resident=1;
-	attr->compressed=attr->cengine=0;
-	attr->size=attr->allocated=attr->initialized=dsize;
+	attr->attrno = i;
+	attr->resident = 1;
+	attr->compressed = attr->cengine = 0;
+	attr->size = attr->allocated = attr->initialized = dsize;
 
 	/* FIXME: INDEXED information should come from $AttrDef
-	   Currently, only file names are indexed */
-	if(anum==ino->vol->at_file_name){
-		attr->indexed=1;
-	}else
-		attr->indexed=0;
-	attr->d.data=ntfs_malloc(dsize);
-
-	if( !attr->d.data )
-		return ENOMEM;
-
-	ntfs_memcpy(attr->d.data,data,dsize);
+	 * Currently, only file names are indexed. As of NTFS v3.0 (Win2k),
+	 * this is no longer true. Different attributes can be indexed now. */
+	if (anum == ino->vol->at_file_name) {
+		attr->indexed = 1;
+	} else
+		attr->indexed = 0;
+	attr->d.data = ntfs_malloc(dsize);
+	if (!attr->d.data)
+		return -ENOMEM;
+	ntfs_memcpy(attr->d.data, data, dsize);
 	return 0;
 }
 
 /* Non-resident attributes are stored in runs (intervals of clusters).
  *
  * This function stores in the inode readable information about a non-resident
- * attribute.
- */
-static int 
-ntfs_process_runs(ntfs_inode *ino,ntfs_attribute* attr,unsigned char *data)
+ * attribute. */
+static int ntfs_process_runs(ntfs_inode *ino, ntfs_attribute* attr,
+			     unsigned char *data)
 {
-	int startvcn,endvcn;
-	int vcn,cnum;
+	int startvcn, endvcn;
+	int vcn, cnum;
 	ntfs_cluster_t cluster;
-	int len,ctype;
-	startvcn = NTFS_GETU64(data+0x10);
-	endvcn = NTFS_GETU64(data+0x18);
-
-	/* check whether this chunk really belongs to the end */
-	for(cnum=0,vcn=0;cnum<attr->d.r.len;cnum++)
-		vcn+=attr->d.r.runlist[cnum].len;
-	if(vcn!=startvcn)
-	{
+	int len, ctype;
+	startvcn = NTFS_GETU64(data + 0x10);
+	endvcn = NTFS_GETU64(data + 0x18);
+
+	/* Check whether this chunk really belongs to the end. */
+	for (cnum = 0, vcn = 0; cnum < attr->d.r.len; cnum++)
+		vcn += attr->d.r.runlist[cnum].len;
+	if (vcn != startvcn) {
 		ntfs_error("Problem with runlist in extended record\n");
 		return -1;
 	}
-	if(!endvcn)
-	{
-		endvcn = NTFS_GETU64(data+0x28)-1; /* allocated length */
+	if (!endvcn) {
+		endvcn = NTFS_GETU64(data + 0x28) - 1; /* Allocated length. */
 		endvcn /= ino->vol->clustersize;
 	}
-	data=data+NTFS_GETU16(data+0x20);
-	cnum=attr->d.r.len;
-	cluster=0;
-	for(vcn=startvcn; vcn<=endvcn; vcn+=len)
-	{
-		if(ntfs_decompress_run(&data,&len,&cluster,&ctype))
+	data = data + NTFS_GETU16(data + 0x20);
+	cnum = attr->d.r.len;
+	cluster = 0;
+	for (vcn = startvcn; vcn <= endvcn; vcn += len)	{
+		if (ntfs_decompress_run(&data, &len, &cluster, &ctype))
 			return -1;
-		if(ctype)
-			ntfs_insert_run(attr,cnum,-1,len);
+		if (ctype)
+			ntfs_insert_run(attr, cnum, -1, len);
 		else
-			ntfs_insert_run(attr,cnum,cluster,len);
+			ntfs_insert_run(attr, cnum, cluster, len);
 		cnum++;
 	}
 	return 0;
 }
   
-/* Insert the attribute starting at attr in the inode ino */
+/* Insert the attribute starting at attr in the inode ino. */
 int ntfs_insert_attribute(ntfs_inode *ino, unsigned char* attrdata)
 {
-	int i,found;
+	int i, found;
 	int type;
 	short int *name;
 	int namelen;
@@ -415,208 +403,207 @@
 	int error;
 
 	type = NTFS_GETU32(attrdata);
-	namelen = NTFS_GETU8(attrdata+9);
-	/* read the attribute's name if it has one */
-	if(!namelen)
-		name=0;
-	else
-	{
-		/* 1 Unicode character fits in 2 bytes */
-		name=ntfs_malloc(2*namelen);
-		if( !name )
-			return ENOMEM;
-
-		ntfs_memcpy(name,attrdata+NTFS_GETU16(attrdata+10),2*namelen);
-	}
-
-	error = ntfs_new_attr(ino,type,name,namelen,&i,&found,1);
-	if( error ) {
-		if( name ) ntfs_free( name );
+	namelen = NTFS_GETU8(attrdata + 9);
+	/* Read the attribute's name if it has one. */
+	if (!namelen)
+		name = 0;
+	else {
+		/* 1 Unicode character fits in 2 bytes. */
+		name = ntfs_malloc(2 * namelen);
+		if (!name)
+			return -ENOMEM;
+		ntfs_memcpy(name, attrdata + NTFS_GETU16(attrdata + 10),
+			    2 * namelen);
+	}
+	error = ntfs_new_attr(ino, type, name, namelen, &i, &found, 1);
+	if (error) {
+		if (name)
+			ntfs_free(name);
 		return error;
 	}
-
-	/* We can have in one inode two attributes with type 0x00000030 (File Name) 
-	   and without name */
-	if(found && /*FIXME*/type!=ino->vol->at_file_name)
+	/* We can have in one inode two attributes with type 0x00000030 (File
+	 * Name) and without name. FIXME: We can have a lot more than two!
+	 * That is how hard links are implemented. (AIA) */
+	if (found && /*FIXME*/ type != ino->vol->at_file_name)
 	{
-		ntfs_process_runs(ino,ino->attrs+i,attrdata);
+		ntfs_process_runs(ino, ino->attrs + i, attrdata);
 		return 0;
- 	} else if( found ) {
- 		/*	Don't understand the above, but I know it leaks memory below
- 			as it overwrites a found entry without freeing it. So here we
- 			call ntfs_new_attr again but this time ask it to always allocate a
- 			new	entry */
- 		ntfs_new_attr(ino,type,name,namelen,&i,&found,0);
-	}
-	attr=ino->attrs+i;
-	attr->resident=NTFS_GETU8(attrdata+8)==0;
-	attr->compressed=NTFS_GETU16(attrdata+0xC);
-	attr->attrno=NTFS_GETU16(attrdata+0xE);
+ 	} else if (found) {
+ 		/* Don't understand the above, but I know it leaks memory below
+		 * as it overwrites a found entry without freeing it. So here
+		 * we call ntfs_new_attr again but this time ask it to always
+		 * allocate a new entry. */
+ 		ntfs_new_attr(ino, type, name, namelen, &i, &found, 0);
+	}
+	attr = ino->attrs + i;
+	attr->resident = NTFS_GETU8(attrdata + 8) == 0;
+	attr->compressed = NTFS_GETU16(attrdata + 0xC);
+	attr->attrno = NTFS_GETU16(attrdata + 0xE);
   
-	if(attr->resident) {
-		attr->size=NTFS_GETU16(attrdata+0x10);
-		data=attrdata+NTFS_GETU16(attrdata+0x14);
+	if (attr->resident) {
+		attr->size = NTFS_GETU16(attrdata + 0x10);
+		data = attrdata + NTFS_GETU16(attrdata + 0x14);
 		attr->d.data = (void*)ntfs_malloc(attr->size);
-		if( !attr->d.data )
-			return ENOMEM;
-		ntfs_memcpy(attr->d.data,data,attr->size);
-		attr->indexed=NTFS_GETU16(attrdata+0x16);
-	}else{
-		attr->allocated=NTFS_GETU32(attrdata+0x28);
-		attr->size=NTFS_GETU32(attrdata+0x30);
-		attr->initialized=NTFS_GETU32(attrdata+0x38);
-		attr->cengine=NTFS_GETU16(attrdata+0x22);
-		if(attr->compressed)
-			attr->compsize=NTFS_GETU32(attrdata+0x40);
-		ino->attrs[i].d.r.runlist=0;
-		ino->attrs[i].d.r.len=0;
-		ntfs_process_runs(ino,attr,attrdata);
+		if (!attr->d.data)
+			return -ENOMEM;
+		ntfs_memcpy(attr->d.data, data, attr->size);
+		attr->indexed = NTFS_GETU16(attrdata + 0x16);
+	} else {
+		attr->allocated = NTFS_GETU32(attrdata + 0x28);
+		attr->size = NTFS_GETU32(attrdata + 0x30);
+		attr->initialized = NTFS_GETU32(attrdata + 0x38);
+		attr->cengine = NTFS_GETU16(attrdata + 0x22);
+		if (attr->compressed)
+			attr->compsize = NTFS_GETU32(attrdata + 0x40);
+		ino->attrs[i].d.r.runlist = 0;
+		ino->attrs[i].d.r.len = 0;
+		ntfs_process_runs(ino, attr, attrdata);
 	}
 	return 0;
 }
 
-int
-ntfs_read_zero(ntfs_io *dest,int size)
+int ntfs_read_zero(ntfs_io *dest, int size)
 {
-	char *sparse=ntfs_calloc(512);
-	if(!sparse)
-		return ENOMEM;
-	while(size){
-		int i=min(size,512);
-		dest->fn_put(dest,sparse,i);
-		size-=i;
+	char *sparse = ntfs_calloc(512);
+	if (!sparse)
+		return -ENOMEM;
+	while (size) {
+		int i = min(size, 512);
+		dest->fn_put(dest, sparse, i);
+		size -= i;
 	}
 	ntfs_free(sparse);
 	return 0;
 }
 
-/* process compressed attributes */
+/* Process compressed attributes. */
 int ntfs_read_compressed(ntfs_inode *ino, ntfs_attribute *attr, int offset,
-	ntfs_io *dest)
+			 ntfs_io *dest)
 {
-	int error=0;
-	int clustersize,l;
-	int s_vcn,rnum,vcn,len,chunk,got,l1,offs1,copied;
-	ntfs_cluster_t cluster,cl1;
-	char *comp=0,*comp1;
-	char *decomp=0;
+	int error = 0;
+	int clustersize, l;
+	int s_vcn, rnum, vcn, len, chunk, got, l1, offs1, copied;
+	ntfs_cluster_t cluster, cl1;
+	char *comp = 0, *comp1;
+	char *decomp = 0;
 	ntfs_io io;
 	ntfs_runlist *rl;
 
-	l=dest->size;
-	clustersize=ino->vol->clustersize;
-	/* starting cluster of potential chunk
-	   there are three situations:
-	   a) in a large uncompressible or sparse chunk, 
-	   s_vcn is in the middle of a run
-	   b) s_vcn is right on a run border
-	   c) when several runs make a chunk, s_vcn is before the chunks
-	*/
-	s_vcn=offset/clustersize;
-	/* round down to multiple of 16 */
+	l = dest->size;
+	clustersize = ino->vol->clustersize;
+	/* Starting cluster of potential chunk. There are three situations:
+	   a) In a large uncompressible or sparse chunk, s_vcn is in the middle
+	      of a run.
+	   b) s_vcn is right on a run border.
+	   c) When several runs make a chunk, s_vcn is before the chunks. */
+	s_vcn = offset / clustersize;
+	/* Round down to multiple of 16. */
 	s_vcn &= ~15;
-	rl=attr->d.r.runlist;
-	for(rnum=vcn=0;rnum<attr->d.r.len && vcn+rl->len<=s_vcn;rnum++,rl++)
-		vcn+=rl->len;
-	if(rnum==attr->d.r.len){
-		/* beyond end of file */
-		/* FIXME: check allocated/initialized */
-		dest->size=0;
+	rl = attr->d.r.runlist;
+	for (rnum = vcn = 0; rnum < attr->d.r.len && vcn + rl->len <= s_vcn;
+								rnum++, rl++)
+		vcn += rl->len;
+	if (rnum == attr->d.r.len) {
+		/* Beyond end of file. */
+		/* FIXME: Check allocated / initialized. */
+		dest->size = 0;
 		return 0;
 	}
-	io.do_read=1;
-	io.fn_put=ntfs_put;
-	io.fn_get=0;
-	cluster=rl->cluster;
-	len=rl->len;
-	copied=0;
-	while(l){
-		chunk=0;
-		if(cluster==MAX_CLUSTER_T){
-			/* sparse cluster */
+	io.do_read = 1;
+	io.fn_put = ntfs_put;
+	io.fn_get = 0;
+	cluster = rl->cluster;
+	len = rl->len;
+	copied = 0;
+	while (l) {
+		chunk = 0;
+		if (cluster == MAX_CLUSTER_T) {
+			/* Sparse cluster. */
 			int l1;
-			if((len-(s_vcn-vcn)) & 15)
-				ntfs_error("unexpected sparse chunk size");
-			l1=chunk = min((vcn+len)*clustersize-offset,l);
-			error = ntfs_read_zero(dest,l1);
-			if(error)
+			if ((len - (s_vcn - vcn)) & 15)
+				ntfs_error("Unexpected sparse chunk size.");
+			l1 = chunk = min((vcn + len) * clustersize - offset, l);
+			error = ntfs_read_zero(dest, l1);
+			if (error)
 				goto out;
-		}else if(dest->do_read){
-			if(!comp){
-				comp=ntfs_malloc(16*clustersize);
-				if(!comp){
-					error=ENOMEM;
+		} else if (dest->do_read) {
+			if (!comp) {
+				comp = ntfs_malloc(16 * clustersize);
+				if (!comp) {
+					error = -ENOMEM;
 					goto out;
 				}
 			}
-			got=0;
-			/* we might need to start in the middle of a run */
-			cl1=cluster+s_vcn-vcn;
-			comp1=comp;
-			do{
-				io.param=comp1;
-				l1=min(len-max(s_vcn-vcn,0),16-got);
-				io.size=l1*clustersize;
-				error=ntfs_getput_clusters(ino->vol,cl1,0,&io);
-				if(error)goto out;
-				if(l1+max(s_vcn-vcn,0)==len){
-					rnum++;rl++;
-					vcn+=len;
-					cluster=cl1=rl->cluster;
-					len=rl->len;
+			got = 0;
+			/* We might need to start in the middle of a run. */
+			cl1 = cluster + s_vcn - vcn;
+			comp1 = comp;
+			do {
+				io.param = comp1;
+				l1 = min(len - max(s_vcn - vcn, 0), 16 - got);
+				io.size = l1 * clustersize;
+				error = ntfs_getput_clusters(ino->vol, cl1, 0,
+					       		     &io);
+				if (error)
+					goto out;
+				if (l1 + max(s_vcn - vcn, 0) == len) {
+					rnum++;
+					rl++;
+					vcn += len;
+					cluster = cl1 = rl->cluster;
+					len = rl->len;
 				}
-				got+=l1;
-				comp1+=l1*clustersize;
-			}while(cluster!=MAX_CLUSTER_T && got<16); /* until empty run */
-			chunk=16*clustersize;
-			if(cluster!=MAX_CLUSTER_T || got==16)
-				/* uncompressible */
-				comp1=comp;
-			else{
-				if(!decomp){
-					decomp=ntfs_malloc(16*clustersize);
-					if(!decomp){
-						error=ENOMEM;
+				got += l1;
+				comp1 += l1 * clustersize;
+			} while (cluster != MAX_CLUSTER_T && got < 16);
+							/* Until empty run. */
+			chunk = 16 * clustersize;
+			if (cluster != MAX_CLUSTER_T || got == 16)
+				/* Uncompressible */
+				comp1 = comp;
+			else {
+				if (!decomp) {
+					decomp = ntfs_malloc(16 * clustersize);
+					if (!decomp) {
+						error = -ENOMEM;
 						goto out;
 					}
 				}
-				/* make sure there are null bytes
-				   after the last block */
-				*(ntfs_u32*)comp1=0;
-				ntfs_decompress(decomp,comp,chunk);
-				comp1=decomp;
+				/* Make sure there are null bytes after the
+				 * last block. */
+				*(ntfs_u32*)comp1 = 0;
+				ntfs_decompress(decomp, comp, chunk);
+				comp1 = decomp;
 			}
-			offs1=offset-s_vcn*clustersize;
-			chunk=min(16*clustersize-offs1,chunk);
-			chunk=min(l,chunk);
-			dest->fn_put(dest,comp1+offs1,chunk);
+			offs1 = offset - s_vcn * clustersize;
+			chunk = min(16 * clustersize - offs1, chunk);
+			chunk = min(l, chunk);
+			dest->fn_put(dest, comp1 + offs1, chunk);
 		}
-		l-=chunk;
-		copied+=chunk;
-		offset+=chunk;
-		s_vcn=offset/clustersize & ~15;
-		if(l && offset>=((vcn+len)*clustersize)){
-			rnum++;rl++;
-			vcn+=len;
-			cluster=rl->cluster;
-			len=rl->len;
+		l -= chunk;
+		copied += chunk;
+		offset += chunk;
+		s_vcn = offset / clustersize & ~15;
+		if (l && offset >= ((vcn + len) * clustersize)) {
+			rnum++;
+			rl++;
+			vcn += len;
+			cluster = rl->cluster;
+			len = rl->len;
 		}
 	}
  out:
-	if(comp)ntfs_free(comp);
-	if(decomp)ntfs_free(decomp);
-	dest->size=copied;
+	if (comp)
+		ntfs_free(comp);
+	if (decomp)
+		ntfs_free(decomp);
+	dest->size = copied;
 	return error;
 }
 
 int ntfs_write_compressed(ntfs_inode *ino, ntfs_attribute *attr, int offset,
-	ntfs_io *dest)
+			  ntfs_io *dest)
 {
-	return EOPNOTSUPP;
+	return -EOPNOTSUPP;
 }
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/ntfs/attr.h linux/fs/ntfs/attr.h
--- linux-2.4.4-pre4/fs/ntfs/attr.h	Mon Apr 12 10:05:58 1999
+++ linux/fs/ntfs/attr.h	Mon Dec  3 22:35:56 2001
@@ -1,24 +1,33 @@
-/*
- *  attr.h
- *  Header file for attr.c
+/*  attr.h -  Header file for attr.c
  *
  *  Copyright (C) 1997 Régis Duchesne
  */
 
 int ntfs_extend_attr(ntfs_inode *ino, ntfs_attribute *attr, int *len,
-  int flags);
+		     int flags);
+
 int ntfs_resize_attr(ntfs_inode *ino, ntfs_attribute *attr, int newsize);
+
 int ntfs_insert_attribute(ntfs_inode *ino, unsigned char* attrdata);
+
 int ntfs_read_compressed(ntfs_inode *ino, ntfs_attribute *attr, int offset,
-  ntfs_io *dest);
+			 ntfs_io *dest);
+
 int ntfs_write_compressed(ntfs_inode *ino, ntfs_attribute *attr, int offset,
-  ntfs_io *dest);
+			  ntfs_io *dest);
+
 int ntfs_create_attr(ntfs_inode *ino, int anum, char *aname, void *data,
-  int dsize, ntfs_attribute **rattr);
-int ntfs_read_zero(ntfs_io *dest,int size);
+		     int dsize, ntfs_attribute **rattr);
+
+int ntfs_read_zero(ntfs_io *dest, int size);
+
 int ntfs_make_attr_nonresident(ntfs_inode *ino, ntfs_attribute *attr);
+
 int ntfs_attr_allnonresident(ntfs_inode *ino);
-int ntfs_new_attr( ntfs_inode *ino, int type, void *name, int namelen,
- int *pos, int *found, int do_search );
-void ntfs_insert_run( ntfs_attribute *attr, int cnum, ntfs_cluster_t cluster,
- int len );
+
+int ntfs_new_attr(ntfs_inode *ino, int type, void *name, int namelen,
+		  int *pos, int *found, int do_search );
+
+void ntfs_insert_run(ntfs_attribute *attr, int cnum, ntfs_cluster_t cluster,
+		     int len );
+
diff -urN linux-2.4.4-pre4/fs/ntfs/dir.c linux/fs/ntfs/dir.c
--- linux-2.4.4-pre4/fs/ntfs/dir.c	Mon Apr 12 10:05:58 1999
+++ linux/fs/ntfs/dir.c	Mon Dec  3 22:35:56 2001
@@ -1,9 +1,9 @@
-/*
- *  dir.c
+/*  dir.c
  *
  *  Copyright (C) 1995-1997, 1999 Martin von Löwis
  *  Copyright (C) 1999 Steve Dodd
  *  Copyright (C) 1999 Joseph Malicki
+ *  Copyright (C) 2001 Anton Altaparmakov (AIA)
  */
 
 #include "ntfstypes.h"
@@ -20,39 +20,44 @@
 
 static char I30[]="$I30";
 
-/* An index record should start with INDX, and the last word in each
-   block should contain the check value. If it passes, the original
-   values need to be restored */
+/* An index record should start with INDX, and the last word in each block
+ * should contain the check value. If it passes, the original values need to
+ * be restored. */
 int ntfs_check_index_record(ntfs_inode *ino, char *record)
 {
-	return ntfs_fixup_record(ino->vol, record, "INDX", 
+	return ntfs_fixup_record(ino->vol, record, "INDX",
 				 ino->u.index.recordsize);
 }
 
 static inline int ntfs_is_top(ntfs_u64 stack)
 {
-	return stack==14;
+	return stack == 14;
 }
 
 static int ntfs_pop(ntfs_u64 *stack)
 {
-	static int width[16]={1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,-1};
-	int res=-1;
-	switch(width[*stack & 15])
-	{
-	case 1:res=(int)((*stack&15)>>1);
-		*stack>>=4;
+	static int width[16] = {1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,-1};
+	int res = -1;
+	
+	switch (width[*stack & 15]) {
+	case 1:
+		res = (int)((*stack & 15) >> 1);
+		*stack >>= 4;
 		break;
-	case 2:res=(int)(((*stack&63)>>2)+7);
-		*stack>>=6;
+	case 2:
+		res = (int)(((*stack & 63) >> 2) + 7);
+		*stack >>= 6;
 		break;
-	case 3:res=(int)(((*stack & 255)>>3)+23);
-		*stack>>=8;
+	case 3:
+		res = (int)(((*stack & 255) >> 3) + 23);
+		*stack >>= 8;
 		break;
-	case 4:res=(int)(((*stack & 1023)>>4)+55);
-		*stack>>=10;
+	case 4:
+		res = (int)(((*stack & 1023) >> 4) + 55);
+		*stack >>= 10;
 		break;
-	default:ntfs_error("Unknown encoding\n");
+	default:
+		ntfs_error("Unknown encoding\n");
 	}
 	return res;
 }
@@ -62,12 +67,16 @@
 	return 14;
 }
 
-static ntfs_u64 ntfs_push(ntfs_u64 stack,int i)
+static ntfs_u64 ntfs_push(ntfs_u64 stack, int i)
 {
-	if(i<7)return (stack<<4)|(i<<1);
-	if(i<23)return (stack<<6)|((i-7)<<2)|1;
-	if(i<55)return (stack<<8)|((i-23)<<3)|3;
-	if(i<120)return (stack<<10)|((i-55)<<4)|7;
+	if (i < 7)
+		return (stack << 4) | (i << 1);
+	if (i < 23)
+		return (stack << 6) | ((i - 7) << 2) | 1;
+	if (i < 55)
+		return (stack << 8) | ((i - 23) << 3) | 3;
+	if (i < 120)
+		return (stack << 10) | ((i - 55) << 4) | 7;
 	ntfs_error("Too many entries\n");
 	return ~((ntfs_u64)0);
 }
@@ -77,133 +86,136 @@
 {
 	while(!ntfs_is_top(stack))
 	{
-		printf("%d ",ntfs_pop(&stack));
+		printf("%d ", ntfs_pop(&stack));
 	}
 	printf("\n");
 }
 #endif
 
-/* True if the entry points to another block of entries */
+/* True if the entry points to another block of entries. */
 static inline int ntfs_entry_has_subnodes(char* entry)
 {
-	return (int)NTFS_GETU8(entry+12)&1;
+	return (int)NTFS_GETU8(entry + 12) & 1;
 }
 
-/* True if it is not the 'end of dir' entry */
+/* True if it is not the 'end of dir' entry. */
 static inline int ntfs_entry_is_used(char* entry)
 {
-	return (int)(NTFS_GETU8(entry+12)&2)==0;
+	return (int)(NTFS_GETU8(entry + 12) & 2) == 0;
 }
 
 static int ntfs_allocate_index_block(ntfs_iterate_s *walk)
 {
-	ntfs_attribute *allocation=0,*bitmap=0;
-	int error,size,i,bit;
+	ntfs_attribute *allocation = 0, *bitmap = 0;
+	int error, size, i, bit;
 	ntfs_u8 *bmap;
 	ntfs_io io;
-	ntfs_volume *vol=walk->dir->vol;
+	ntfs_volume *vol = walk->dir->vol;
 
-	/* check for allocation attribute */
-	allocation=ntfs_find_attr(walk->dir,vol->at_index_allocation,I30);
-	if(!allocation){
+	/* Check for allocation attribute. */
+	allocation = ntfs_find_attr(walk->dir, vol->at_index_allocation, I30);
+	if (!allocation) {
 		ntfs_u8 bmp[8];
-		/* create index allocation attribute */
-		error=ntfs_create_attr(walk->dir,vol->at_index_allocation,I30,
-				       0,0,&allocation);
-		if(error)return error;
-		ntfs_bzero(bmp,sizeof(bmp));
-		error=ntfs_create_attr(walk->dir,vol->at_bitmap,I30,
-				       bmp,sizeof(bmp),&bitmap);
-		if(error)return error;
-	}else
-		bitmap=ntfs_find_attr(walk->dir,vol->at_bitmap,I30);
-	if(!bitmap){
+		/* Create index allocation attribute. */
+		error = ntfs_create_attr(walk->dir, vol->at_index_allocation,
+					 I30, 0, 0, &allocation);
+		if (error)
+			return error;
+		ntfs_bzero(bmp, sizeof(bmp));
+		error = ntfs_create_attr(walk->dir, vol->at_bitmap, I30, bmp,
+					 sizeof(bmp), &bitmap);
+		if (error)
+			return error;
+	} else
+		bitmap = ntfs_find_attr(walk->dir, vol->at_bitmap, I30);
+	if (!bitmap) {
 		ntfs_error("Directory w/o bitmap\n");
-		return EINVAL;
+		return -EINVAL;
 	}
-	size=bitmap->size;
-	bmap=ntfs_malloc(size);
-	if(!bmap)return ENOMEM;
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	io.param=bmap;
-	io.size=size;
-	error=ntfs_read_attr(walk->dir,vol->at_bitmap,I30,0,&io);
-	if(error){
+	size = bitmap->size;
+	bmap = ntfs_malloc(size);
+	if (!bmap)
+		return -ENOMEM;
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	io.param = bmap;
+	io.size = size;
+	error = ntfs_read_attr(walk->dir, vol->at_bitmap, I30, 0, &io);
+	if (error) {
 		ntfs_free(bmap);
 		return error;
 	}
-	if(io.size!=size){
+	if (io.size != size) {
 		ntfs_free(bmap);
-		return EIO;
+		return -EIO;
 	}
-	
-	/* allocate a bit */
-	for(i=bit=0;i<size;i++){
-		if(bmap[i]==0xFF)continue;
-		for(bit=0;bit<8;bit++)
-			if(((bmap[i]>>bit) & 1) == 0)
+	/* Allocate a bit. */
+	for (i = bit = 0; i < size; i++) {
+		if (bmap[i] == 0xFF)
+			continue;
+		for (bit = 0; bit < 8; bit++)
+			if (((bmap[i] >> bit) & 1) == 0)
 				break;
-		if(bit!=8)break;
+		if (bit != 8)
+			break;
 	}
-	if(i==size)
-		/* FIXME: extend bitmap */
-		return EOPNOTSUPP;
-	walk->newblock=(i*8+bit)*walk->dir->u.index.clusters_per_record;
-	bmap[i]|= 1<<bit;
-	io.param=bmap;
-	io.size=size;
-	error=ntfs_write_attr(walk->dir,vol->at_bitmap,I30,0,&io);
-	if(error || io.size!=size){
+	if (i == size)
+		/* FIXME: Extend bitmap. */
+		return -EOPNOTSUPP;
+	walk->newblock = (i * 8 + bit) * walk->dir->u.index.clusters_per_record;
+	bmap[i] |= 1 << bit;
+	io.param = bmap;
+	io.size = size;
+	error = ntfs_write_attr(walk->dir, vol->at_bitmap, I30, 0, &io);
+	if (error || io.size != size) {
 		ntfs_free(bmap);
-		return error?error:EIO;
+		return error ? error : -EIO;
 	}
 	ntfs_free(bmap);
-
-	/* check whether record is out of allocated range */
-	size=allocation->size;
-	if(walk->newblock * vol->clustersize >= size){
-		/* build index record */
-		int s1=walk->dir->u.index.recordsize;
-		int nr_fix = s1/vol->blocksize+1;
+	/* Check whether record is out of allocated range. */
+	size = allocation->size;
+	if (walk->newblock * vol->clustersize >= size) {
+		/* Build index record. */
+		int s1 = walk->dir->u.index.recordsize;
+		int nr_fix = s1/vol->blocksize + 1;
 		int hsize;
-		char *record=ntfs_malloc(s1);
-		if( !record )
-			return ENOMEM;
-		ntfs_bzero(record,s1);
-		/* magic */
-		ntfs_memcpy(record,"INDX",4);
-		/* offset to fixups */
-		NTFS_PUTU16(record+4,0x28);
-		/* number of fixups */
-		NTFS_PUTU16(record+6,nr_fix);
-		/* FIXME: log file number */
+		char *record = ntfs_malloc(s1);
+		if (!record)
+			return -ENOMEM;
+		ntfs_bzero(record, s1);
+		/* Magic */
+		ntfs_memcpy(record, "INDX", 4);
+		/* Offset to fixups */
+		NTFS_PUTU16(record + 4, 0x28);
+		/* Number of fixups. */
+		NTFS_PUTU16(record + 6, nr_fix);
+		/* Log file sequence number - We don't do journalling so we
+		 * just set it to zero which should be the Right Thing. (AIA) */
+		NTFS_PUTU64(record + 8, 0);
 		/* VCN of buffer */
-		NTFS_PUTU64(record+0x10,walk->newblock);
-		/* header size. */
-		hsize = 0x10+2*nr_fix;
-		hsize = (hsize+7) & ~7; /* Align. */
-		NTFS_PUTU16(record+0x18, hsize);
-		/* total size of record */
-		NTFS_PUTU32(record+0x20,s1-0x18);
+		NTFS_PUTU64(record + 0x10, walk->newblock);
+		/* Header size. */
+		hsize = 0x10 + 2 * nr_fix;
+		hsize = (hsize + 7) & ~7; /* Align. */
+		NTFS_PUTU16(record + 0x18, hsize);
+		/* Total size of record. */
+		NTFS_PUTU32(record + 0x20, s1 - 0x18);
 		/* Writing the data will extend the attribute. */
-		io.param=record;
-		io.size=s1;
-		io.do_read=0;
-		error=ntfs_readwrite_attr(walk->dir, allocation, size, &io);
-		if(error || io.size!=s1){
+		io.param = record;
+		io.size = s1;
+		io.do_read = 0;
+		error = ntfs_readwrite_attr(walk->dir, allocation, size, &io);
+		if (error || io.size != s1) {
 			ntfs_free(record);
-			return error?error:EIO;
+			return error ? error : -EIO;
 		}
 		ntfs_free(record);
 	}
-
 	return 0;
 }
 
 /* Write an index block (root or allocation) back to storage.
-   used is the total number of bytes in buf, including all headers. */
-
+ * Used is the total number of bytes in buf, including all headers. */
 static int ntfs_index_writeback(ntfs_iterate_s *walk, ntfs_u8 *buf, int block,
 				int used)
 {
@@ -212,231 +224,235 @@
 	ntfs_attribute *a;
 	ntfs_volume *vol = walk->dir->vol;
 	
-	io.fn_put=0;
-	io.fn_get=ntfs_get;
-	io.param=buf;
-	if(block==-1){
-		NTFS_PUTU16(buf+0x14,used-0x10);
-		/* 0x18 is a copy thereof */
-		NTFS_PUTU16(buf+0x18,used-0x10);
-		io.size=used;
-		error=ntfs_write_attr(walk->dir,vol->at_index_root,
-				      I30,0,&io);
-		if(error)return error;
-		if(io.size!=used)return EIO;
-		/* shrink if necessary */
+	io.fn_put = 0;
+	io.fn_get = ntfs_get;
+	io.param = buf;
+	if (block == -1) {
+		NTFS_PUTU16(buf + 0x14, used - 0x10);
+		/* 0x18 is a copy thereof. */
+		NTFS_PUTU16(buf + 0x18, used - 0x10);
+		io.size = used;
+		error = ntfs_write_attr(walk->dir, vol->at_index_root, I30, 0,
+					&io);
+		if (error)
+			return error;
+		if (io.size != used)
+			return -EIO;
+		/* Shrink if necessary. */
 		a = ntfs_find_attr(walk->dir, vol->at_index_root, I30);
 		ntfs_resize_attr(walk->dir, a, used);
-	}else{
-		NTFS_PUTU16(buf+0x1C,used-0x18);
-		ntfs_insert_fixups(buf,vol->blocksize);
-		io.size=walk->dir->u.index.recordsize;
-		error=ntfs_write_attr(walk->dir,vol->at_index_allocation,I30,
-				      block*vol->clustersize,
-				      &io);
-		if(error)return error;
-		if(io.size!=walk->dir->u.index.recordsize)
-			return EIO;
+	} else {
+		NTFS_PUTU16(buf + 0x1C, used - 0x18);
+		ntfs_insert_fixups(buf, vol->blocksize);
+		io.size = walk->dir->u.index.recordsize;
+		error = ntfs_write_attr(walk->dir, vol->at_index_allocation,
+					I30, block*vol->clustersize, &io);
+		if (error)
+			return error;
+		if (io.size != walk->dir->u.index.recordsize)
+			return -EIO;
 	}
 	return 0;
 }
 
 static int ntfs_split_record(ntfs_iterate_s *walk, char *start, int bsize,
-	int usize)
+			     int usize)
 {
-	char *entry,*prev;
-	ntfs_u8 *newbuf=0,*middle=0;
-	int error,othersize,mlen;
+	char *entry, *prev;
+	ntfs_u8 *newbuf = 0, *middle = 0;
+	int error, othersize, mlen;
 	ntfs_io io;
-	ntfs_volume *vol=walk->dir->vol;
+	ntfs_volume *vol = walk->dir->vol;
 	int oldblock;
 
-	error=ntfs_allocate_index_block(walk);
-	if(error)
+	error = ntfs_allocate_index_block(walk);
+	if (error)
 		return error;
-	/* This should not happen */
-	if(walk->block == -1){
+	/* This should not happen. */
+	if (walk->block == -1) {
 		ntfs_error("Trying to split root");
-		return EOPNOTSUPP;
+		return -EOPNOTSUPP;
 	}
-	entry = start+NTFS_GETU16(start+0x18)+0x18; 
-	for(prev=entry; entry-start<usize/2; entry += NTFS_GETU16(entry+8))
-		prev=entry;
-
-	newbuf=ntfs_malloc(vol->index_recordsize);
-	if(!newbuf)
-		return ENOMEM;
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	io.param=newbuf;
-	io.size=vol->index_recordsize;
-	/* read in old header. FIXME: reading everything is overkill */
-	error=ntfs_read_attr(walk->dir,vol->at_index_allocation,I30,
-			     walk->newblock*vol->clustersize,&io);
-	if(error)goto out;
-	if(io.size!=vol->index_recordsize){
-		error=EIO;
-		goto out;
-	}
-	/* FIXME: adjust header */
-	/* copy everything from entry to new block */
-	othersize=usize-(entry-start);
-	ntfs_memcpy(newbuf+NTFS_GETU16(newbuf+0x18)+0x18,entry,othersize);
+	entry = start + NTFS_GETU16(start + 0x18) + 0x18; 
+	for (prev = entry; entry - start < usize / 2; 
+					       entry += NTFS_GETU16(entry + 8))
+		prev = entry;
+	newbuf = ntfs_malloc(vol->index_recordsize);
+	if (!newbuf)
+		return -ENOMEM;
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	io.param = newbuf;
+	io.size = vol->index_recordsize;
+	/* Read in old header. FIXME: Reading everything is overkill. */
+	error = ntfs_read_attr(walk->dir, vol->at_index_allocation, I30,
+			       walk->newblock * vol->clustersize, &io);
+	if (error)
+		goto out;
+	if (io.size != vol->index_recordsize) {
+		error = -EIO;
+		goto out;
+	}
+	/* FIXME: Adjust header. */
+	/* Copy everything from entry to new block. */
+	othersize = usize - (entry - start);
+	ntfs_memcpy(newbuf + NTFS_GETU16(newbuf + 0x18) + 0x18, entry,
+								    othersize);
 	/* Copy flags. */
-	NTFS_PUTU32(newbuf+0x24, NTFS_GETU32(start+0x24));
-	error=ntfs_index_writeback(walk,newbuf,walk->newblock,
-				   othersize+NTFS_GETU16(newbuf+0x18)+0x18);
-	if(error)goto out;
-
-	/* move prev to walk */
-	mlen=NTFS_GETU16(prev+0x8);
+	NTFS_PUTU32(newbuf + 0x24, NTFS_GETU32(start + 0x24));
+	error = ntfs_index_writeback(walk, newbuf, walk->newblock,
+				othersize + NTFS_GETU16(newbuf + 0x18) + 0x18);
+	if (error)
+		goto out;
+	/* Move prev to walk. */
+	mlen = NTFS_GETU16(prev + 0x8);
 	/* Remember old child node. */
-	if(ntfs_entry_has_subnodes(prev))
-		oldblock = NTFS_GETU32(prev+mlen-8);
+	if (ntfs_entry_has_subnodes(prev))
+		oldblock = NTFS_GETU32(prev + mlen - 8);
 	else
 		oldblock = -1;
-	/* allow for pointer to subnode */
-	middle=ntfs_malloc(ntfs_entry_has_subnodes(prev)?mlen:mlen+8);
-	if(!middle){
-		error=ENOMEM;
+	/* Allow for pointer to subnode. */
+	middle = ntfs_malloc(ntfs_entry_has_subnodes(prev) ? mlen : mlen + 8);
+	if (!middle){
+		error = -ENOMEM;
 		goto out;
 	}
-	ntfs_memcpy(middle,prev,mlen);
-	/* set has_subnodes flag */
-	NTFS_PUTU8(middle+0xC, NTFS_GETU8(middle+0xC) | 1);
-	/* middle entry points to block, parent entry will point to newblock */
-	NTFS_PUTU64(middle+mlen-8,walk->block);
-	if(walk->new_entry)
-		ntfs_error("entry not reset");
-	walk->new_entry=middle;
-	walk->u.flags|=ITERATE_SPLIT_DONE;
+	ntfs_memcpy(middle, prev, mlen);
+	/* Set has_subnodes flag. */
+	NTFS_PUTU8(middle + 0xC, NTFS_GETU8(middle + 0xC) | 1);
+	/* Middle entry points to block, parent entry will point to newblock. */
+	NTFS_PUTU64(middle + mlen - 8, walk->block);
+	if (walk->new_entry)
+		ntfs_error("Entry not reset");
+	walk->new_entry = middle;
+	walk->u.flags |= ITERATE_SPLIT_DONE;
 	/* Terminate old block. */
-	othersize = usize-(prev-start);
+	othersize = usize - (prev-start);
 	NTFS_PUTU64(prev, 0);
-	if(oldblock==-1){
-		NTFS_PUTU32(prev+8, 0x10);
-		NTFS_PUTU32(prev+0xC, 2);
+	if (oldblock == -1) {
+		NTFS_PUTU32(prev + 8, 0x10);
+		NTFS_PUTU32(prev + 0xC, 2);
 		othersize += 0x10;
-	}else{
-		NTFS_PUTU32(prev+8, 0x18);
-		NTFS_PUTU32(prev+0xC, 3);
-		NTFS_PUTU64(prev+0x10, oldblock);
+	} else {
+		NTFS_PUTU32(prev + 8, 0x18);
+		NTFS_PUTU32(prev + 0xC, 3);
+		NTFS_PUTU64(prev + 0x10, oldblock);
 		othersize += 0x18;
 	}
-	/* write back original block */
-	error=ntfs_index_writeback(walk,start,walk->block,othersize);
+	/* Write back original block. */
+	error = ntfs_index_writeback(walk, start, walk->block, othersize);
  out:
-	if(newbuf)ntfs_free(newbuf);
-	if(middle)ntfs_free(middle);
+	if (newbuf)
+		ntfs_free(newbuf);
+	if (middle)
+		ntfs_free(middle);
 	return error;
 }
 
 static int ntfs_dir_insert(ntfs_iterate_s *walk, char *start, char* entry)
 {
-	int blocksize,usedsize,error,offset;
-	int do_split=0;
-	offset=entry-start;
-	if(walk->block==-1){ /*index root */
-		blocksize=walk->dir->vol->mft_recordsize;
-		usedsize=NTFS_GETU16(start+0x14)+0x10;
-	}else{
-		blocksize=walk->dir->u.index.recordsize;
-		usedsize=NTFS_GETU16(start+0x1C)+0x18;
-	}
-	if(usedsize+walk->new_entry_size > blocksize){
-		char* s1=ntfs_malloc(blocksize+walk->new_entry_size);
-		if(!s1)return ENOMEM;
-		ntfs_memcpy(s1,start,usedsize);
-		do_split=1;
-		/* adjust entry to s1 */
-		entry=s1+(entry-start);
-		start=s1;
-	}
-	ntfs_memmove(entry+walk->new_entry_size,entry,usedsize-offset);
-	ntfs_memcpy(entry,walk->new_entry,walk->new_entry_size);
-	usedsize+=walk->new_entry_size;
+	int blocksize, usedsize, error, offset;
+	int do_split = 0;
+	offset = entry - start;
+	if (walk->block == -1) { /* index root */
+		blocksize = walk->dir->vol->mft_recordsize;
+		usedsize = NTFS_GETU16(start + 0x14) + 0x10;
+	} else {
+		blocksize = walk->dir->u.index.recordsize;
+		usedsize = NTFS_GETU16(start + 0x1C) + 0x18;
+	}
+	if (usedsize + walk->new_entry_size > blocksize) {
+		char* s1 = ntfs_malloc(blocksize + walk->new_entry_size);
+		if (!s1)
+			return -ENOMEM;
+		ntfs_memcpy(s1, start, usedsize);
+		do_split = 1;
+		/* Adjust entry to s1. */
+		entry = s1 + (entry - start);
+		start = s1;
+	}
+	ntfs_memmove(entry + walk->new_entry_size, entry, usedsize - offset);
+	ntfs_memcpy(entry, walk->new_entry, walk->new_entry_size);
+	usedsize += walk->new_entry_size;
 	ntfs_free(walk->new_entry);
-	walk->new_entry=0;
-	if(do_split){
-		error=ntfs_split_record(walk,start,blocksize,usedsize);
+	walk->new_entry = 0;
+	if (do_split) {
+		error = ntfs_split_record(walk, start, blocksize, usedsize);
 		ntfs_free(start);
-	}else{
-		error=ntfs_index_writeback(walk,start,walk->block,usedsize);
-		if(error)return error;
+	} else {
+		error = ntfs_index_writeback(walk, start, walk->block,usedsize);
+		if (error)
+			return error;
 	}
 	return 0;
 }
 
-/* Try to split INDEX_ROOT attributes. Return E2BIG if nothing changed. */
-
-int
-ntfs_split_indexroot(ntfs_inode *ino)
+/* Try to split INDEX_ROOT attributes. Return -E2BIG if nothing changed. */
+int ntfs_split_indexroot(ntfs_inode *ino)
 {
 	ntfs_attribute *ra;
-	ntfs_u8 *root=0, *index=0;
+	ntfs_u8 *root = 0, *index = 0;
 	ntfs_io io;
 	int error, off, i, bsize, isize;
 	ntfs_iterate_s walk;
 
 	ra = ntfs_find_attr(ino, ino->vol->at_index_root, I30);
-	if(!ra)
-		return E2BIG;
+	if (!ra)
+		return -E2BIG;
 	bsize = ino->vol->mft_recordsize;
 	root = ntfs_malloc(bsize);
-	if(!root)
-		return E2BIG;
+	if (!root)
+		return -E2BIG;
 	io.fn_put = ntfs_put;
 	io.param = root;
 	io.size = bsize;
 	error = ntfs_read_attr(ino, ino->vol->at_index_root, I30, 0, &io);
-	if(error)
+	if (error)
 		goto out;
 	off = 0x20;
 	/* Count number of entries. */
-	for(i = 0; ntfs_entry_is_used(root+off); i++)
-		off += NTFS_GETU16(root+off+8);
-	if(i<=2){
+	for (i = 0; ntfs_entry_is_used(root + off); i++)
+		off += NTFS_GETU16(root + off + 8);
+	if (i <= 2) {
 		/* We don't split small index roots. */
-		error = E2BIG;
+		error = -E2BIG;
 		goto out;
 	}
 	index = ntfs_malloc(ino->vol->index_recordsize);
-	if(!index) {
-		error = ENOMEM; goto out;
+	if (!index) {
+		error = -ENOMEM;
+		goto out;
 	}
 	walk.dir = ino;
 	walk.block = -1;
 	walk.result = walk.new_entry = 0;
 	walk.name = 0;
 	error = ntfs_allocate_index_block(&walk);
-	if(error)
+	if (error)
 		goto out;
-
 	/* Write old root to new index block. */
 	io.param = index;
 	io.size = ino->vol->index_recordsize;
 	error = ntfs_read_attr(ino, ino->vol->at_index_allocation, I30,
-			       walk.newblock*ino->vol->clustersize, &io);
-	if(error)
+			       walk.newblock * ino->vol->clustersize, &io);
+	if (error)
 		goto out;
-	isize = NTFS_GETU16(root+0x18) - 0x10;
-	ntfs_memcpy(index+NTFS_GETU16(index+0x18)+0x18, root+0x20, isize);
+	isize = NTFS_GETU16(root + 0x18) - 0x10;
+	ntfs_memcpy(index + NTFS_GETU16(index + 0x18) + 0x18, root+0x20, isize);
 	/* Copy flags. */
-	NTFS_PUTU32(index+0x24, NTFS_GETU32(root+0x1C));
-
+	NTFS_PUTU32(index + 0x24, NTFS_GETU32(root + 0x1C));
 	error = ntfs_index_writeback(&walk, index, walk.newblock, 
-				     isize+NTFS_GETU16(index+0x18)+0x18);
+				     isize + NTFS_GETU16(index + 0x18) + 0x18);
 	if(error)
 		goto out;
-
 	/* Mark root as split. */
-	NTFS_PUTU32(root+0x1C, 1);
+	NTFS_PUTU32(root + 0x1C, 1);
 	/* Truncate index root. */
-	NTFS_PUTU64(root+0x20, 0);
-	NTFS_PUTU32(root+0x28, 0x18);
-	NTFS_PUTU32(root+0x2C, 3);
-	NTFS_PUTU64(root+0x30, walk.newblock);
-	error = ntfs_index_writeback(&walk,root,-1,0x38);
+	NTFS_PUTU64(root + 0x20, 0);
+	NTFS_PUTU32(root + 0x28, 0x18);
+	NTFS_PUTU32(root + 0x2C, 3);
+	NTFS_PUTU64(root + 0x30, walk.newblock);
+	error = ntfs_index_writeback(&walk, root, -1, 0x38);
  out:
 	ntfs_free(root);
 	ntfs_free(index);
@@ -451,422 +467,428 @@
 	return 1;
 }
 
-/* use $UpCase some day */
+/* Use $UpCase some day. */
 static inline unsigned short ntfs_my_toupper(ntfs_volume *vol, ntfs_u16 x)
 {
-	/* we should read any pending rest of $UpCase here */
-	if(x >= vol->upcase_length)
+	/* We should read any pending rest of $UpCase here. */
+	if (x >= vol->upcase_length)
 		return x;
 	return vol->upcase[x];
 }
 
-/* everything passed in walk and entry */
+/* Everything passed in walk and entry. */
 static int ntfs_my_strcmp(ntfs_iterate_s *walk, const unsigned char *entry)
 {
-	int lu=*(entry+0x50);
+	int lu = *(entry + 0x50);
 	int i;
 
-	ntfs_u16* name=(ntfs_u16*)(entry+0x52);
-	ntfs_volume *vol=walk->dir->vol;
-	for(i=0;i<lu && i<walk->namelen;i++)
-		if(ntfs_my_toupper(vol,NTFS_GETU16(name+i))!=ntfs_my_toupper(vol,NTFS_GETU16(walk->name+i)))
+	ntfs_u16* name = (ntfs_u16*)(entry + 0x52);
+	ntfs_volume *vol = walk->dir->vol;
+	for (i = 0; i < lu && i < walk->namelen; i++)
+		if (ntfs_my_toupper(vol, NTFS_GETU16(name + i)) != 
+			     ntfs_my_toupper(vol, NTFS_GETU16(walk->name + i)))
 			break;
-	if(i==lu && i==walk->namelen)return 0;
-	if(i==lu)return 1;
-	if(i==walk->namelen)return -1;
-	if(ntfs_my_toupper(vol,NTFS_GETU16(name+i))<ntfs_my_toupper(vol,NTFS_GETU16(walk->name+i)))return 1;
+	if (i == lu && i == walk->namelen)
+		return 0;
+	if (i == lu)
+		return 1;
+	if (i == walk->namelen)
+		return -1;
+	if (ntfs_my_toupper(vol, NTFS_GETU16(name + i)) < 
+			    ntfs_my_toupper(vol, NTFS_GETU16(walk->name + i)))
+		return 1;
 	return -1;
 }
 
-/* Necessary forward declaration */
+/* Necessary forward declaration. */
 static int ntfs_getdir_iterate(ntfs_iterate_s *walk, char *start, char *entry);
 
-/* Parse a block of entries. Load the block, fix it up, and iterate
-   over the entries. The block is given as virtual cluster number */
+/* Parse a block of entries. Load the block, fix it up, and iterate over the
+ * entries. The block is given as virtual cluster number. */
 static int ntfs_getdir_record(ntfs_iterate_s *walk, int block)
 {
-	int length=walk->dir->u.index.recordsize;
-	char *record=(char*)ntfs_malloc(length);
+	int length = walk->dir->u.index.recordsize;
+	char *record = (char*)ntfs_malloc(length);
 	char *offset;
 	int retval,error;
 	int oldblock;
 	ntfs_io io;
 
-	if( !record )
-		return ENOMEM;
-
-	io.fn_put=ntfs_put;
-	io.param=record;
-	io.size=length;
-	/* Read the block from the index allocation attribute */
-	error=ntfs_read_attr(walk->dir,walk->dir->vol->at_index_allocation,I30,
-			     block*walk->dir->vol->clustersize,&io);
-	if(error || io.size!=length){
+	if (!record)
+		return -ENOMEM;
+	io.fn_put = ntfs_put;
+	io.param = record;
+	io.size = length;
+	/* Read the block from the index allocation attribute. */
+	error = ntfs_read_attr(walk->dir, walk->dir->vol->at_index_allocation,
+			       I30, block * walk->dir->vol->clustersize, &io);
+	if (error || io.size != length) {
 		ntfs_error("read failed\n");
 		ntfs_free(record);
 		return 0;
 	}
-	if(!ntfs_check_index_record(walk->dir,record)){
-		ntfs_error("%x is not an index record\n",block);
+	if (!ntfs_check_index_record(walk->dir, record)) {
+		ntfs_error("%x is not an index record\n", block);
 		ntfs_free(record);
 		return 0;
 	}
-	offset=record+NTFS_GETU16(record+0x18)+0x18;
-	oldblock=walk->block;
-	walk->block=block;
-	retval=ntfs_getdir_iterate(walk,record,offset);
-	walk->block=oldblock;
+	offset = record + NTFS_GETU16(record + 0x18) + 0x18;
+	oldblock = walk->block;
+	walk->block = block;
+	retval = ntfs_getdir_iterate(walk, record, offset);
+	walk->block = oldblock;
 	ntfs_free(record);
 	return retval;
 }
 
-/* go down to the next block of entries. These collate before
-   the current entry */
+/* Go down to the next block of entries. These collate before the current
+ * entry. */
 static int ntfs_descend(ntfs_iterate_s *walk, ntfs_u8 *start, ntfs_u8 *entry)
 {
-	int length=NTFS_GETU16(entry+8);
+	int length = NTFS_GETU16(entry + 8);
 	int nextblock=NTFS_GETU32(entry+length-8);
 	int error;
 
-	if(!ntfs_entry_has_subnodes(entry)) {
+	if (!ntfs_entry_has_subnodes(entry)) {
 		ntfs_error("illegal ntfs_descend call\n");
 		return 0;
 	}
-	error=ntfs_getdir_record(walk,nextblock);
-	if(!error && walk->type==DIR_INSERT && 
-	   (walk->u.flags & ITERATE_SPLIT_DONE)){
+	error = ntfs_getdir_record(walk, nextblock);
+	if (!error && walk->type == DIR_INSERT && 
+	    (walk->u.flags & ITERATE_SPLIT_DONE)) {
 		/* Split has occurred. Adjust entry, insert new_entry. */
-		NTFS_PUTU32(entry+length-8,walk->newblock);
+		NTFS_PUTU32(entry + length - 8, walk->newblock);
 		/* Reset flags, as the current block might be split again. */
 		walk->u.flags &= ~ITERATE_SPLIT_DONE;
-		error=ntfs_dir_insert(walk,start,entry);
+		error = ntfs_dir_insert(walk, start, entry);
 	}
 	return error;
 }
 
-static int 
-ntfs_getdir_iterate_byposition(ntfs_iterate_s *walk,char* start,char *entry)
+static int ntfs_getdir_iterate_byposition(ntfs_iterate_s *walk, char* start,
+					  char *entry)
 {
-	int retval=0;
-	int curpos=0,destpos=0;
+	int retval = 0;
+	int curpos = 0, destpos = 0;
 	int length;
-	if(walk->u.pos!=0){
-		if(ntfs_is_top(walk->u.pos))return 0;
-		destpos=ntfs_pop(&walk->u.pos);
-	}
-	while(1){
-		if(walk->u.pos==0)
-		{
-			if(ntfs_entry_has_subnodes(entry))
-				ntfs_descend(walk,start,entry);
+	if (walk->u.pos != 0) {
+		if (ntfs_is_top(walk->u.pos))
+			return 0;
+		destpos = ntfs_pop(&walk->u.pos);
+	}
+	while (1) {
+		if (walk->u.pos == 0) {
+			if (ntfs_entry_has_subnodes(entry))
+				ntfs_descend(walk, start, entry);
 			else
-				walk->u.pos=ntfs_top();
-			if(ntfs_is_top(walk->u.pos) && !ntfs_entry_is_used(entry))
-			{
+				walk->u.pos = ntfs_top();
+			if (ntfs_is_top(walk->u.pos) && 
+			    !ntfs_entry_is_used(entry))
 				return 1;
-			}
-			walk->u.pos=ntfs_push(walk->u.pos,curpos);
+			walk->u.pos = ntfs_push(walk->u.pos, curpos);
 			return 1;
 		}
-		if(curpos==destpos)
-		{
-			if(!ntfs_is_top(walk->u.pos) && ntfs_entry_has_subnodes(entry))
-			{
-				retval=ntfs_descend(walk,start,entry);
-				if(retval){
-					walk->u.pos=ntfs_push(walk->u.pos,curpos);
+		if (curpos == destpos) {
+			if (!ntfs_is_top(walk->u.pos) && 
+			    ntfs_entry_has_subnodes(entry)) {
+				retval = ntfs_descend(walk, start, entry);
+				if (retval) {
+					walk->u.pos = ntfs_push(walk->u.pos,
+								curpos);
 					return retval;
-				}else{
-					if(!ntfs_entry_is_used(entry))
-						return 0;
-					walk->u.pos=0;
 				}
+				if (!ntfs_entry_is_used(entry))
+					return 0;
+				walk->u.pos = 0;
 			}
-			if(ntfs_entry_is_used(entry))
-			{
-				retval=ntfs_copyresult(walk->result,entry);
-				walk->u.pos=0;
-			}else{
-				walk->u.pos=ntfs_top();
+			if (ntfs_entry_is_used(entry)) {
+				retval = ntfs_copyresult(walk->result, entry);
+				walk->u.pos = 0;
+			} else {
+				walk->u.pos = ntfs_top();
 				return 0;
 			}
 		}
 		curpos++;
-		if(!ntfs_entry_is_used(entry))break;
-		length=NTFS_GETU16(entry+8);
-		if(!length){
+		if (!ntfs_entry_is_used(entry))
+			break;
+		length = NTFS_GETU16(entry + 8);
+		if (!length) {
 			ntfs_error("infinite loop\n");
 			break;
 		}
-		entry+=length;
+		entry += length;
 	}
 	return -1;
 }
 	
-/* Iterate over a list of entries, either from an index block, or from
-   the index root. 
-   If searching BY_POSITION, pop the top index from the position. If the
-   position stack is empty then, return the item at the index and set the
-   position to the next entry. If the position stack is not empty, 
-   recursively proceed for subnodes. If the entry at the position is the
-   'end of dir' entry, return 'not found' and the empty stack.
-   If searching BY_NAME, walk through the items until found or until
-   one item is collated after the requested item. In the former case, return
-   the result. In the latter case, recursively proceed to the subnodes.
-   If 'end of dir' is reached, the name is not in the directory */
+/* Iterate over a list of entries, either from an index block, or from the
+ * index root.
+ * If searching BY_POSITION, pop the top index from the position. If the
+ * position stack is empty then, return the item at the index and set the
+ * position to the next entry. If the position stack is not empty, 
+ * recursively proceed for subnodes. If the entry at the position is the
+ * 'end of dir' entry, return 'not found' and the empty stack.
+ * If searching BY_NAME, walk through the items until found or until
+ * one item is collated after the requested item. In the former case, return
+ * the result. In the latter case, recursively proceed to the subnodes.
+ * If 'end of dir' is reached, the name is not in the directory */
 static int ntfs_getdir_iterate(ntfs_iterate_s *walk, char *start, char *entry)
 {
 	int length;
 	int cmp;
 
-	if(walk->type==BY_POSITION)
-		return ntfs_getdir_iterate_byposition(walk,start,entry);
-	do{
-		/* if the current entry is a real one, compare with the
-		   requested item. If the current entry is the last item,
-		   it is always larger than the requested item */
-		cmp = ntfs_entry_is_used(entry) ? ntfs_my_strcmp(walk,entry) : -1;
-		switch(walk->type){
+	if (walk->type == BY_POSITION)
+		return ntfs_getdir_iterate_byposition(walk, start, entry);
+	do {
+		/* If the current entry is a real one, compare with the
+		 * requested item. If the current entry is the last item, it
+		 * is always larger than the requested item. */
+		cmp = ntfs_entry_is_used(entry) ? 
+						ntfs_my_strcmp(walk,entry) : -1;
+		switch (walk->type) {
 		case BY_NAME:
-			switch(cmp)
-			{
-			case -1:return ntfs_entry_has_subnodes(entry)?
-				       ntfs_descend(walk,start,entry):0;
-			case  0:return ntfs_copyresult(walk->result,entry);
-			case  1:break;
+			switch (cmp) {
+				case -1:
+					return ntfs_entry_has_subnodes(entry) ?
+					       ntfs_descend(walk,start,entry) :
+					       0;
+				case  0:
+					return ntfs_copyresult(walk->result,
+							       entry);
+				case  1:
+					break;
 			}
 			break;
 		case DIR_INSERT:
-			switch(cmp){
-			case -1:return ntfs_entry_has_subnodes(entry)?
-				       ntfs_descend(walk,start,entry):
-					       ntfs_dir_insert(walk,start,entry);
-			case  0:return EEXIST;
-			case  1:break;
+			switch (cmp) {
+			case -1:
+				return ntfs_entry_has_subnodes(entry) ?
+					   ntfs_descend(walk, start, entry) :
+					   ntfs_dir_insert(walk, start, entry);
+			case  0:
+				return -EEXIST;
+			case  1:
+				break;
 			}
 			break;
 		default:
-			ntfs_error("TODO\n");
+			ntfs_error("TODO\n"); /* FIXME: ? */
 		}
-		if(!ntfs_entry_is_used(entry))break;
-		length=NTFS_GETU16(entry+8);
-		if(!length){
+		if (!ntfs_entry_is_used(entry))
+			break;
+		length = NTFS_GETU16(entry + 8);
+		if (!length) {
 			ntfs_error("infinite loop\n");
 			break;
 		}
-		entry+=length;
-	}while(1);
+		entry += length;
+	} while (1);
 	return 0;
 }
 
-/*	Tree walking is done using position numbers. The following numbers have
-    a special meaning:
-        0    start (.)
-        -1   no more entries
-        -2   ..
-    All other numbers encode sequences of indices. The sequence a,b,c is 
-    encoded as <stop><c><b><a>, where <foo> is the encoding of foo. The
-    first few integers are encoded as follows:
-        0:    0000    1:    0010    2:    0100    3:    0110
-        4:    1000    5:    1010    6:    1100 stop:    1110
-        7:  000001    8:  000101	9:  001001   10:  001101
-    The least significant bits give the width of this encoding, the
-    other bits encode the value, starting from the first value of the 
-    interval.
-     tag     width  first value  last value
-     0       3      0            6
-     01      4      7            22
-     011     5      23           54
-     0111    6      55           119
-     More values are hopefully not needed, as the file position has currently
-     64 bits in total.
-*/
+/*  Tree walking is done using position numbers. The following numbers have a
+ *  special meaning:
+ *       0   start (.)
+ *      -1   no more entries
+ *      -2   ..
+ *  All other numbers encode sequences of indices. The sequence a, b, c is 
+ *  encoded as <stop><c><b><a>, where <foo> is the encoding of foo. The
+ *  first few integers are encoded as follows:
+ *      0:    0000    1:    0010    2:    0100    3:    0110
+ *      4:    1000    5:    1010    6:    1100 stop:    1110
+ *      7:  000001    8:  000101    9:  001001   10:  001101
+ *  The least significant bits give the width of this encoding, the other bits
+ *  encode the value, starting from the first value of the interval.
+ *   tag     width  first value  last value
+ *   0       3      0            6
+ *   01      4      7            22
+ *   011     5      23           54
+ *   0111    6      55           119
+ *   More values are hopefully not needed, as the file position has currently
+ *   64 bits in total. */
 
-/* Find an entry in the directory. Return 0 if not found, otherwise copy
-   the entry to the result buffer. */
+/* Find an entry in the directory. Return 0 if not found, otherwise copy the
+ * entry to the result buffer. */
 int ntfs_getdir(ntfs_iterate_s* walk)
 {
-	int length=walk->dir->vol->mft_recordsize;
-	int retval,error;
-	/* start at the index root.*/
-	char *root=ntfs_malloc(length);
+	int length = walk->dir->vol->mft_recordsize;
+	int retval, error;
+	/* Start at the index root. */
+	char *root = ntfs_malloc(length);
 	ntfs_io io;
 
-	if( !root )
-		return ENOMEM;
-
-	io.fn_put=ntfs_put;
-	io.param=root;
-	io.size=length;
-	error=ntfs_read_attr(walk->dir,walk->dir->vol->at_index_root,
-			     I30,0,&io);
-	if(error)
-	{
+	if (!root)
+		return -ENOMEM;
+	io.fn_put = ntfs_put;
+	io.param = root;
+	io.size = length;
+	error = ntfs_read_attr(walk->dir, walk->dir->vol->at_index_root, I30,
+			       0, &io);
+	if (error) {
 		ntfs_error("Not a directory\n");
 		return 0;
 	}
-	walk->block=-1;
-	/* FIXME: move these to walk */
-	walk->dir->u.index.recordsize = NTFS_GETU32(root+0x8);
-	walk->dir->u.index.clusters_per_record = NTFS_GETU32(root+0xC);
-	/* FIXME: consistency check */
-	/* skip header */
-	retval = ntfs_getdir_iterate(walk,root,root+0x20);
+	walk->block = -1;
+	/* FIXME: Move these to walk. */
+	walk->dir->u.index.recordsize = NTFS_GETU32(root + 0x8);
+	walk->dir->u.index.clusters_per_record = NTFS_GETU32(root + 0xC);
+	/* FIXME: Consistency check. */
+	/* Skip header. */
+	retval = ntfs_getdir_iterate(walk, root, root + 0x20);
 	ntfs_free(root);
 	return retval;
 }
 
 /* Find an entry in the directory by its position stack. Iteration starts
-   if the stack is 0, in which case the position is set to the first item
-   in the directory. If the position is nonzero, return the item at the
-   position and change the position to the next item. The position is -1
-   if there are no more items */
+ * if the stack is 0, in which case the position is set to the first item
+ * in the directory. If the position is nonzero, return the item at the
+ * position and change the position to the next item. The position is -1
+ * if there are no more items. */
 int ntfs_getdir_byposition(ntfs_iterate_s *walk)
 {
-	walk->type=BY_POSITION;
+	walk->type = BY_POSITION;
 	return ntfs_getdir(walk);
 }
 
-/* Find an entry in the directory by its name. Return 0 if not found */
+/* Find an entry in the directory by its name. Return 0 if not found. */
 int ntfs_getdir_byname(ntfs_iterate_s *walk)
 {
-	walk->type=BY_NAME;
+	walk->type = BY_NAME;
 	return ntfs_getdir(walk);
 }
 
-int ntfs_getdir_unsorted(ntfs_inode *ino,ntfs_u32 *p_high,ntfs_u32* p_low,
-			 int(*cb)(ntfs_u8*,void*),void *param)
+int ntfs_getdir_unsorted(ntfs_inode *ino, ntfs_u32 *p_high, ntfs_u32* p_low,
+			 int (*cb)(ntfs_u8*, void*), void *param)
 {
-	char *buf=0,*entry=0;
+	char *buf = 0, *entry = 0;
 	ntfs_io io;
 	int length;
 	int block;
 	int start;
 	ntfs_attribute *attr;
-	ntfs_volume *vol=ino->vol;
-	int byte,bit;
-	int error=0;
+	ntfs_volume *vol = ino->vol;
+	int byte, bit;
+	int error = 0;
 
-	if(!ino){
+	if (!ino) {
 		ntfs_error("No inode passed to getdir_unsorted\n");
-		return EINVAL;
+		return -EINVAL;
 	}
-	if(!vol){
-		ntfs_error("Inode %d has no volume\n",ino->i_number);
-		return EINVAL;
-	}
-	ntfs_debug(DEBUG_DIR3,"unsorted 1\n");
-	/* are we still in the index root */
-	if(*p_high==0){
-		buf=ntfs_malloc(length=vol->mft_recordsize);
-		if( !buf )
-			return ENOMEM;
-		io.fn_put=ntfs_put;
-		io.param=buf;
-		io.size=length;
-		error=ntfs_read_attr(ino,vol->at_index_root,I30,0,&io);
-		if(error){
+	if (!vol) {
+		ntfs_error("Inode %d has no volume\n", ino->i_number);
+		return -EINVAL;
+	}
+	ntfs_debug(DEBUG_DIR3, "unsorted 1\n");
+	/* Are we still in the index root? */
+	if (*p_high == 0) {
+		buf = ntfs_malloc(length = vol->mft_recordsize);
+		if (!buf)
+			return -ENOMEM;
+		io.fn_put = ntfs_put;
+		io.param = buf;
+		io.size = length;
+		error = ntfs_read_attr(ino, vol->at_index_root, I30, 0, &io);
+		if (error) {
 			ntfs_free(buf);
 			return error;
 		}
-		ino->u.index.recordsize = NTFS_GETU32(buf+0x8);
-		ino->u.index.clusters_per_record = NTFS_GETU32(buf+0xC);
-		entry=buf+0x20;
-		ntfs_debug(DEBUG_DIR3,"unsorted 2\n");
-	}else{ /* we are in an index record */
-		length=ino->u.index.recordsize;
-		buf=ntfs_malloc(length);
-		if( !buf )
-			return ENOMEM;
-		io.fn_put=ntfs_put;
-		io.param=buf;
-		io.size=length;
-		/* 0 is index root, index allocation starts with 4 */
+		ino->u.index.recordsize = NTFS_GETU32(buf + 0x8);
+		ino->u.index.clusters_per_record = NTFS_GETU32(buf + 0xC);
+		entry = buf + 0x20;
+		ntfs_debug(DEBUG_DIR3, "unsorted 2\n");
+	} else { /* we are in an index record */
+		length = ino->u.index.recordsize;
+		buf = ntfs_malloc(length);
+		if (!buf)
+			return -ENOMEM;
+		io.fn_put = ntfs_put;
+		io.param = buf;
+		io.size = length;
+		/* 0 is index root, index allocation starts with 4. */
 		block = *p_high - ino->u.index.clusters_per_record;
-		error=ntfs_read_attr(ino,vol->at_index_allocation,I30,
-				     block*vol->clustersize,&io);
-		if(!error && io.size!=length)error=EIO;
-		if(error){
+		error = ntfs_read_attr(ino, vol->at_index_allocation, I30,
+				       block*vol->clustersize, &io);
+		if (!error && io.size != length)
+			error = -EIO;
+		if (error) {
 			ntfs_error("read failed\n");
 			ntfs_free(buf);
 			return error;
 		}
-		if(!ntfs_check_index_record(ino,buf)){
-			ntfs_error("%x is not an index record\n",block);
+		if (!ntfs_check_index_record(ino, buf)) {
+			ntfs_error("%x is not an index record\n", block);
 			ntfs_free(buf);
-			return ENOTDIR;
+			return -ENOTDIR;
 		}
-		entry=buf+NTFS_GETU16(buf+0x18)+0x18;
-		ntfs_debug(DEBUG_DIR3,"unsorted 3\n");
+		entry = buf + NTFS_GETU16(buf + 0x18) + 0x18;
+		ntfs_debug(DEBUG_DIR3, "unsorted 3\n");
 	}
-
-	/* process the entries */
-	start=*p_low;
-	while(ntfs_entry_is_used(entry)){
-		ntfs_debug(DEBUG_DIR3,"unsorted 4\n");
-		if(start)
-			start--; /* skip entries that were already processed */
-		else{
-			ntfs_debug(DEBUG_DIR3,"unsorted 5\n");
-			if((error=cb(entry,param)))
-				/* the entry could not be processed */
+	/* Process the entries. */
+	start = *p_low;
+	while (ntfs_entry_is_used(entry)) {
+		ntfs_debug(DEBUG_DIR3, "unsorted 4\n");
+		if (start)
+			start--; /* Skip entries that were already processed. */
+		else {
+			ntfs_debug(DEBUG_DIR3, "unsorted 5\n");
+			if ((error = cb(entry, param)))
+				/* The entry could not be processed. */
 				break;
 			(*p_low)++;
 		}
-		entry+=NTFS_GETU16(entry+8);
+		entry += NTFS_GETU16(entry + 8);
 	}
-
-	ntfs_debug(DEBUG_DIR3,"unsorted 6\n");
-	/* caller did not process all entries */
-	if(error){
+	ntfs_debug(DEBUG_DIR3, "unsorted 6\n");
+	/* Caller did not process all entries. */
+	if (error) {
 		ntfs_free(buf);
-		ntfs_debug(DEBUG_DIR3,"unsorted 7\n");
+		ntfs_debug(DEBUG_DIR3, "unsorted 7\n");
 		return error;
 	}
-
-	/* we have to locate the next record */
+	/* We have to locate the next record. */
 	ntfs_free(buf);
-	buf=0;
-	*p_low=0;
-	attr=ntfs_find_attr(ino,vol->at_bitmap,I30);
-	if(!attr){
-		/* directory does not have index allocation */
-		*p_high=0xFFFFFFFF;
-		*p_low=0;
-		ntfs_debug(DEBUG_DIR3,"unsorted 8\n");
+	buf = 0;
+	*p_low = 0;
+	attr = ntfs_find_attr(ino, vol->at_bitmap, I30);
+	if (!attr) {
+		/* Directory does not have index allocation. */
+		*p_high = 0xFFFFFFFF;
+		*p_low = 0;
+		ntfs_debug(DEBUG_DIR3, "unsorted 8\n");
 		return 0;
 	}
-	buf=ntfs_malloc(length=attr->size);
-	if( !buf )
-		return ENOMEM;
-
-	io.param=buf;
-	io.size=length;
-	error=ntfs_read_attr(ino,vol->at_bitmap,I30,0,&io);
-	if(!error && io.size!=length)error=EIO;
-	if(error){
+	buf = ntfs_malloc(length = attr->size);
+	if (!buf)
+		return -ENOMEM;
+	io.param = buf;
+	io.size = length;
+	error = ntfs_read_attr(ino, vol->at_bitmap, I30, 0, &io);
+	if (!error && io.size != length)
+		error = -EIO;
+	if (error) {
 		ntfs_free(buf);
-		ntfs_debug(DEBUG_DIR3,"unsorted 9\n");
-		return EIO;
+		ntfs_debug(DEBUG_DIR3, "unsorted 9\n");
+		return -EIO;
 	}
-	attr=ntfs_find_attr(ino,vol->at_index_allocation,I30);
-	while(1){
-		if(*p_high*vol->clustersize > attr->size){
-			/* no more index records */
-			*p_high=0xFFFFFFFF;
+	attr = ntfs_find_attr(ino, vol->at_index_allocation, I30);
+	while (1) {
+		if (*p_high * vol->clustersize > attr->size) {
+			/* No more index records. */
+			*p_high = 0xFFFFFFFF;
 			ntfs_free(buf);
-			ntfs_debug(DEBUG_DIR3,"unsorted 10\n");
+			ntfs_debug(DEBUG_DIR3, "unsorted 10\n");
 			return 0;
 		}
-		*p_high+=ino->u.index.clusters_per_record;
-		byte=*p_high/ino->u.index.clusters_per_record-1;
+		*p_high += ino->u.index.clusters_per_record;
+		byte = *p_high / ino->u.index.clusters_per_record - 1;
 		bit  = 1 << (byte & 7);
 		byte = byte >> 3;
-		/* this record is allocated */
-		if(buf[byte] & bit)
+		/* This record is allocated. */
+		if (buf[byte] & bit)
 			break;
 	}
-	ntfs_debug(DEBUG_DIR3,"unsorted 11\n");
+	ntfs_debug(DEBUG_DIR3, "unsorted 11\n");
 	ntfs_free(buf);
 	return 0;
 }
@@ -874,116 +896,120 @@
 int ntfs_dir_add(ntfs_inode *dir, ntfs_inode *new, ntfs_attribute *name)
 {
 	ntfs_iterate_s walk;
-	int nsize,esize;
-	ntfs_u8* entry,*ndata;
+	int nsize, esize;
+	ntfs_u8* entry, *ndata;
 	int error;
 
-	walk.type=DIR_INSERT;
-	walk.dir=dir;
-	walk.u.flags=0;
+	walk.type = DIR_INSERT;
+	walk.dir = dir;
+	walk.u.flags = 0;
 	nsize = name->size;
 	ndata = name->d.data;
-	walk.name=(ntfs_u16*)(ndata+0x42);
-	walk.namelen=NTFS_GETU8(ndata+0x40);
-	walk.new_entry_size = esize = ((nsize+0x18)/8)*8;
-	walk.new_entry=entry=ntfs_malloc(esize);
-	if(!entry)return ENOMEM;
-	ntfs_bzero(entry,esize);
-	NTFS_PUTINUM(entry,new);
-	NTFS_PUTU16(entry+0x8,esize); /* size of entry */
-	NTFS_PUTU16(entry+0xA,nsize); /* size of original name attribute */
-	NTFS_PUTU32(entry+0xC,0);     /* FIXME: D-F? */
-	ntfs_memcpy(entry+0x10,ndata,nsize);
-	error=ntfs_getdir(&walk);
-	if(walk.new_entry)
+	walk.name = (ntfs_u16*)(ndata + 0x42);
+	walk.namelen = NTFS_GETU8(ndata + 0x40);
+	walk.new_entry_size = esize = ((nsize + 0x18) / 8) * 8;
+	walk.new_entry = entry = ntfs_malloc(esize);
+	if (!entry)
+		return -ENOMEM;
+	ntfs_bzero(entry, esize);
+	NTFS_PUTINUM(entry, new);
+	NTFS_PUTU16(entry + 0x8, esize); /* Size of entry. */
+	NTFS_PUTU16(entry + 0xA, nsize); /* Size of original name attribute. */
+	NTFS_PUTU32(entry + 0xC, 0);     /* FIXME: D-F? */
+	ntfs_memcpy(entry + 0x10, ndata, nsize);
+	error = ntfs_getdir(&walk);
+	if (walk.new_entry)
 		ntfs_free(walk.new_entry);
 	return error;
 }
 
 #if 0
-int ntfs_dir_add1(ntfs_inode *dir,const char* name,int namelen,ntfs_inode *ino)
+int ntfs_dir_add1(ntfs_inode *dir, const char* name, int namelen,
+		  ntfs_inode *ino)
 {
 	ntfs_iterate_s walk;
 	int error;
 	int nsize;
 	char *entry;
 	ntfs_attribute *name_attr;
-	error=ntfs_decodeuni(dir->vol,name,namelen,&walk.name,&walk.namelen);
-	if(error)
+	error = ntfs_decodeuni(dir->vol, name, namelen, &walk.name,
+			       &walk.namelen);
+	if (error)
 		return error;
-	/* FIXME: set flags */
-	walk.type=DIR_INSERT;
-	walk.dir=dir;
-	/*walk.new=ino;*/
-	/* prepare new entry */
-	/* round up to a multiple of 8 */
-	walk.new_entry_size = nsize = ((0x52+2*walk.namelen+7)/8)*8;
-	walk.new_entry=entry=ntfs_malloc(nsize);
-	if(!entry)
-		return ENOMEM;
-	ntfs_bzero(entry,nsize);
-	NTFS_PUTINUM(entry,ino);
-	NTFS_PUTU16(entry+8,nsize);
-	NTFS_PUTU16(entry+0xA,0x42+2*namelen); /*FIXME: size of name attr*/
-	NTFS_PUTU32(entry+0xC,0); /*FIXME: D-F? */
-	name_attr=ntfs_find_attr(ino,vol->at_file_name,0); /* FIXME:multiple names */
-	if(!name_attr || !name_attr->resident)
-		return EIDRM;
-	/* directory, file stamps, sizes, filename */
-	ntfs_memcpy(entry+0x10,name_attr->d.data,0x42+2*namelen);
-	error=ntfs_getdir(&walk);
+	/* FIXME: Set flags. */
+	walk.type = DIR_INSERT;
+	walk.dir = dir;
+	/* walk.new = ino; */
+	/* Prepare new entry. */
+	/* Round up to a multiple of 8. */
+	walk.new_entry_size = nsize = ((0x52 + 2 * walk.namelen + 7) / 8) * 8;
+	walk.new_entry = entry = ntfs_malloc(nsize);
+	if (!entry)
+		return -ENOMEM;
+	ntfs_bzero(entry, nsize);
+	NTFS_PUTINUM(entry, ino);
+	NTFS_PUTU16(entry + 8, nsize);
+	NTFS_PUTU16(entry + 0xA, 0x42 + 2 * namelen); /* FIXME: Size of name 
+						       * attribute. */
+	NTFS_PUTU32(entry + 0xC, 0); /* FIXME: D-F? */
+	name_attr = ntfs_find_attr(ino, vol->at_file_name, 0);
+						    /* FIXME: multiple names */
+	if (!name_attr || !name_attr->resident)
+		return -EIDRM;
+	/* Directory, file stamps, sizes, filename. */
+	ntfs_memcpy(entry + 0x10, name_attr->d.data, 0x42 + 2 * namelen);
+	error = ntfs_getdir(&walk);
 	ntfs_free(walk.name);
 	return error;
 }
 #endif
 
 /* Fills out and creates an INDEX_ROOT attribute. */
-
-int
-ntfs_add_index_root (ntfs_inode *ino, int type)
+int ntfs_add_index_root(ntfs_inode *ino, int type)
 {
 	ntfs_attribute *da;
-	ntfs_u8 data[0x30]; /* 0x20 header, 0x10 last entry */
+	ntfs_u8 data[0x30]; /* 0x20 header, 0x10 last entry. */
 	char name[10];
 
 	NTFS_PUTU32(data, type);
-	/* ??? */
-	NTFS_PUTU32(data+4, 1);
-	NTFS_PUTU32(data+8, ino->vol->index_recordsize);
-	NTFS_PUTU32(data+0xC, ino->vol->index_clusters_per_record);
-	/* ??? */
-	NTFS_PUTU32(data+0x10, 0x10);
+	/* FIXME: ??? */
+	NTFS_PUTU32(data + 4, 1);
+	NTFS_PUTU32(data + 8, ino->vol->index_recordsize);
+	NTFS_PUTU32(data + 0xC, ino->vol->index_clusters_per_record);
+	/* FXIME: ??? */
+	NTFS_PUTU32(data + 0x10, 0x10);
 	/* Size of entries, including header. */
-	NTFS_PUTU32(data+0x14, 0x20);
-	NTFS_PUTU32(data+0x18, 0x20);
+	NTFS_PUTU32(data + 0x14, 0x20);
+	NTFS_PUTU32(data + 0x18, 0x20);
 	/* No index allocation, yet. */
-	NTFS_PUTU32(data+0x1C, 0);
-	/* add last entry. */
-	/* indexed MFT record. */
-	NTFS_PUTU64(data+0x20, 0);
-	/* size of entry */
-	NTFS_PUTU32(data+0x28, 0x10);
-	/* flags: last entry, no child nodes. */
-	NTFS_PUTU32(data+0x2C, 2);
-	/* compute name */
+	NTFS_PUTU32(data + 0x1C, 0);
+	/* Add last entry. */
+	/* Indexed MFT record. */
+	NTFS_PUTU64(data + 0x20, 0);
+	/* Size of entry. */
+	NTFS_PUTU32(data + 0x28, 0x10);
+	/* Flags: Last entry, no child nodes. */
+	NTFS_PUTU32(data + 0x2C, 2);
+	/* Compute name. */
 	ntfs_indexname(name, type);
 	return ntfs_create_attr(ino, ino->vol->at_index_root, name,
 				data, sizeof(data), &da);
 }
 
-int
-ntfs_mkdir(ntfs_inode* dir,const char* name,int namelen, ntfs_inode *result)
+int ntfs_mkdir(ntfs_inode* dir, const char* name, int namelen,
+	       ntfs_inode *result)
 {
 	int error;
+	
 	error = ntfs_alloc_inode(dir, result, name, namelen, NTFS_AFLAG_DIR);
-	if(error)
+	if (error)
 		goto out;
 	error = ntfs_add_index_root(result, 0x30);
 	if (error)
 		goto out;
-	/* Set directory bit */
+	/* Set directory bit. */
 	result->attr[0x16] |= 2;
-	error = ntfs_update_inode (dir);
+	error = ntfs_update_inode(dir);
 	if (error)
 		goto out;
 	error = ntfs_update_inode (result);
@@ -993,8 +1019,3 @@
 	return error;
 }
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/ntfs/dir.h linux/fs/ntfs/dir.h
--- linux-2.4.4-pre4/fs/ntfs/dir.h	Mon Apr 12 10:05:58 1999
+++ linux/fs/ntfs/dir.h	Mon Dec  3 22:35:56 2001
@@ -1,6 +1,4 @@
-/*
- *  dir.h
- *  Header file for dir.c
+/*  dir.h - Header file for dir.c
  *
  *  Copyright (C) 1997 Régis Duchesne
  */
@@ -32,11 +30,19 @@
 } ntfs_iterate_s;
 
 int ntfs_getdir_unsorted(ntfs_inode *ino, ntfs_u32 *p_high, ntfs_u32* p_low,
-  int(*cb)(ntfs_u8*,void*), void *param);
+			 int (*cb)(ntfs_u8*, void*), void *param);
+
 int ntfs_getdir_byname(ntfs_iterate_s *walk);
+
 int ntfs_dir_add(ntfs_inode *dir, ntfs_inode *new, ntfs_attribute *name);
+
 int ntfs_check_index_record(ntfs_inode *ino, char *record);
+
 int ntfs_getdir_byposition(ntfs_iterate_s *walk);
+
 int ntfs_mkdir(ntfs_inode* dir,const char* name,int namelen, ntfs_inode *ino);
+
 int ntfs_split_indexroot(ntfs_inode *ino);
-int ntfs_add_index_root( ntfs_inode *ino, int type );
+
+int ntfs_add_index_root(ntfs_inode *ino, int type);
+
diff -urN linux-2.4.4-pre4/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- linux-2.4.4-pre4/fs/ntfs/fs.c	Fri Dec 29 14:07:57 2000
+++ linux/fs/ntfs/fs.c	Mon Dec  3 22:35:56 2001
@@ -1,19 +1,12 @@
-/*
- *  fs.c
- *  NTFS driver for Linux 2.3.x
+/*  fs.c - NTFS driver for Linux 2.4.x
  *
  *  Copyright (C) 1995-1997, 1999 Martin von Löwis
  *  Copyright (C) 1996 Richard Russon
  *  Copyright (C) 1996-1997 Régis Duchesne
- *  Copyright (C) 2000, Anton Altaparmakov
+ *  Copyright (C) 2000-2001, Anton Altaparmakov (AIA)
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef NTFS_IN_LINUX_KERNEL
 #include <linux/config.h>
-#endif
 
 #include "ntfstypes.h"
 #include "struct.h"
@@ -30,66 +23,67 @@
 #include <linux/locks.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
+#include <asm/page.h>
 
-/* Forward declarations */
+/* Forward declarations. */
 static struct inode_operations ntfs_dir_inode_operations;
 static struct file_operations ntfs_dir_operations;
 
 #define ITEM_SIZE 2040
 
-/* io functions to user space */
-static void ntfs_putuser(ntfs_io* dest,void *src,ntfs_size_t len)
+/* Io functions to user space. */
+static void ntfs_putuser(ntfs_io* dest, void *src, ntfs_size_t len)
 {
-	copy_to_user(dest->param,src,len);
-	dest->param+=len;
+	copy_to_user(dest->param, src, len);
+	dest->param += len;
 }
 
 #ifdef CONFIG_NTFS_RW
-struct ntfs_getuser_update_vm_s{
+struct ntfs_getuser_update_vm_s {
 	const char *user;
 	struct inode *ino;
 	loff_t off;
 };
 
-static void ntfs_getuser_update_vm (void *dest, ntfs_io *src, ntfs_size_t len)
+static void ntfs_getuser_update_vm(void *dest, ntfs_io *src, ntfs_size_t len)
 {
 	struct ntfs_getuser_update_vm_s *p = src->param;
-	copy_from_user (dest, p->user, len);
+	
+	copy_from_user(dest, p->user, len);
 	p->user += len;
 	p->off += len;
 }
 #endif
 
-static ssize_t
-ntfs_read(struct file * filp, char *buf, size_t count, loff_t *off)
+static ssize_t ntfs_read(struct file *filp, char *buf, size_t count,loff_t *off)
 {
 	int error;
 	ntfs_io io;
-	ntfs_inode *ino=NTFS_LINO2NINO(filp->f_dentry->d_inode);
+	ntfs_inode *ino = NTFS_LINO2NINO(filp->f_dentry->d_inode);
 
-	/* inode is not properly initialized */
-	if(!ino)return -EINVAL;
+	/* Inode is not properly initialized. */
+	if (!ino)
+		return -EINVAL;
 	ntfs_debug(DEBUG_OTHER, "ntfs_read %x,%x,%x ->",
-		   (unsigned)ino->i_number,(unsigned)*off,(unsigned)count);
-	/* inode has no unnamed data attribute */
-	if(!ntfs_find_attr(ino,ino->vol->at_data,NULL))
+		   (unsigned)ino->i_number, (unsigned)*off, (unsigned)count);
+	/* Inode has no unnamed data attribute. */
+	if(!ntfs_find_attr(ino, ino->vol->at_data, NULL))
 		return -EINVAL;
-	
-	/* read the data */
-	io.fn_put=ntfs_putuser;
-	io.fn_get=0;
-	io.param=buf;
-	io.size=count;
-	error=ntfs_read_attr(ino,ino->vol->at_data,NULL,*off,&io);
-	if(error && !io.size)return -error;
-	
-	*off+=io.size;
+	/* Read the data. */
+	io.fn_put = ntfs_putuser;
+	io.fn_get = 0;
+	io.param = buf;
+	io.size = count;
+	error = ntfs_read_attr(ino, ino->vol->at_data, NULL, *off, &io);
+	if (error && !io.size)
+		return error;
+	*off += io.size;
 	return io.size;
 }
 
 #ifdef CONFIG_NTFS_RW
-static ssize_t
-ntfs_write(struct file *filp,const char* buf,size_t count,loff_t *pos)
+static ssize_t ntfs_write(struct file *filp, const char* buf, size_t count,
+			  loff_t *pos)
 {
 	int ret;
 	ntfs_io io;
@@ -99,14 +93,13 @@
 
 	if (!ino)
 		return -EINVAL;
-	ntfs_debug (DEBUG_LINUX, "ntfs_write %x,%x,%x ->\n",
-	       (unsigned)ino->i_number, (unsigned)*pos, (unsigned)count);
-	/* Allows to lock fs ro at any time */
+	ntfs_debug(DEBUG_LINUX, "ntfs_write %x, %x, %x ->\n",
+		   (unsigned)ino->i_number, (unsigned)*pos, (unsigned)count);
+	/* Allows to lock fs ro at any time. */
 	if (inode->i_sb->s_flags & MS_RDONLY)
 		return -ENOSPC;
-	if (!ntfs_find_attr(ino,ino->vol->at_data,NULL))
+	if (!ntfs_find_attr(ino, ino->vol->at_data, NULL))
 		return -EINVAL;
-
 	/* Evaluating O_APPEND is the file system's job... */
 	if (filp->f_flags & O_APPEND)
 		*pos = inode->i_size;
@@ -117,15 +110,14 @@
 	io.fn_get = ntfs_getuser_update_vm;
 	io.param = &param;
 	io.size = count;
-	ret = ntfs_write_attr (ino, ino->vol->at_data, NULL, *pos, &io);
-	ntfs_debug (DEBUG_LINUX, "write -> %x\n", ret);
-	if(ret<0)
+	ret = ntfs_write_attr(ino, ino->vol->at_data, NULL, *pos, &io);
+	ntfs_debug(DEBUG_LINUX, "write -> %x\n", ret);
+	if (ret < 0)
 		return -EINVAL;
-
 	*pos += io.size;
 	if (*pos > inode->i_size)
 		inode->i_size = *pos;
-	mark_inode_dirty (filp->f_dentry->d_inode);
+	mark_inode_dirty(filp->f_dentry->d_inode);
 	return io.size;
 }
 #endif
@@ -140,269 +132,273 @@
 	int namelen;
 };
 	
-static int ntfs_printcb(ntfs_u8 *entry,void *param)
+static int ntfs_printcb(ntfs_u8 *entry, void *param)
 {
-	struct ntfs_filldir* nf=param;
-	int flags=NTFS_GETU8(entry+0x51);
-	int show_hidden=0;
-	int length=NTFS_GETU8(entry+0x50);
-	int inum=NTFS_GETU32(entry);
+	struct ntfs_filldir *nf = param;
+	int flags = NTFS_GETU8(entry + 0x51);
+	int show_hidden = 0;
+	int length = NTFS_GETU8(entry + 0x50);
+	int inum = NTFS_GETU32(entry);
 	int error;
 #ifdef NTFS_NGT_NT_DOES_LOWER
-	int i,to_lower=0;
+	int i, to_lower = 0;
 #endif
-	switch(nf->type){
+	switch (nf->type) {
 	case ngt_dos:
-		/* Don't display long names */
-		if((flags & 2)==0)
+		/* Don't display long names. */
+		if ((flags & 2) == 0)
 			return 0;
 		break;
 	case ngt_nt:
-		/* Don't display short-only names */
-		switch(flags&3){
-		case 2: return 0;
+		/* Don't display short-only names. */
+		switch (flags & 3) {
+		case 2: 
+			return 0;
 #ifdef NTFS_NGT_NT_DOES_LOWER
-		case 3: to_lower=1;
+		case 3: 
+			to_lower = 1;
 #endif
 		}
 		break;
 	case ngt_posix:
 		break;
 	case ngt_full:
-		show_hidden=1;
+		show_hidden = 1;
 		break;
 	}
-	if(!show_hidden && ((NTFS_GETU8(entry+0x48) & 2)==2)){
-		ntfs_debug(DEBUG_OTHER,"Skipping hidden file\n");
+	if (!show_hidden && ((NTFS_GETU8(entry + 0x48) & 2) == 2)) {
+		ntfs_debug(DEBUG_OTHER, "Skipping hidden file\n");
 		return 0;
 	}
-	nf->name=0;
-	if(ntfs_encodeuni(NTFS_INO2VOL(nf->dir),(ntfs_u16*)(entry+0x52),
-			  length,&nf->name,&nf->namelen)){
-		ntfs_debug(DEBUG_OTHER,"Skipping unrepresentable file\n");
-		if(nf->name)ntfs_free(nf->name);
+	nf->name = 0;
+	if (ntfs_encodeuni(NTFS_INO2VOL(nf->dir), (ntfs_u16*)(entry + 0x52),
+			   length, &nf->name, &nf->namelen)){
+		ntfs_debug(DEBUG_OTHER, "Skipping unrepresentable file\n");
+		if (nf->name)
+			ntfs_free(nf->name);
 		return 0;
 	}
-	/* Do not return ".", as this is faked */
-	if(length==1 && *nf->name=='.')
+	/* Do not return ".", as this is faked. */
+	if (length == 1 && *nf->name == '.')
 		return 0;
 #ifdef NTFS_NGT_NT_DOES_LOWER
-	if(to_lower)
-		for(i=0;i<nf->namelen;i++)
-			/* This supports ASCII only. Since only DOS-only
-			   names get converted, and since those are restricted
-			   to ASCII, this should be correct */
-			if(nf->name[i]>='A' && nf->name[i]<='Z')
-				nf->name[i]+='a'-'A';
-#endif
-	nf->name[nf->namelen]=0;
-	ntfs_debug(DEBUG_OTHER, "readdir got %s,len %d\n",nf->name,nf->namelen);
-	/* filldir expects an off_t rather than an loff_t.
-	   Hope we don't have more than 65535 index records */
-	error=nf->filldir(nf->dirent,nf->name,nf->namelen,
-			(nf->ph<<16)|nf->pl,inum,DT_UNKNOWN);
+	if (to_lower)
+		for(i = 0; i < nf->namelen; i++)
+			/* This supports ASCII only. Since only DOS-only names
+			 * get converted, and since those are restricted to
+			 * ASCII, this should be correct. */
+			if (nf->name[i] >= 'A' && nf->name[i] <= 'Z')
+				nf->name[i] += 'a' - 'A';
+#endif
+	nf->name[nf->namelen] = 0;
+	ntfs_debug(DEBUG_OTHER, "readdir got %s, len %d\n", nf->name,
+		       						nf->namelen);
+	/* filldir expects an off_t rather than an loff_t. Hope we don't have
+	 * more than 65535 index records. */
+	error = nf->filldir(nf->dirent, nf->name, nf->namelen,
+			    (nf->ph << 16) | nf->pl, inum, DT_UNKNOWN);
 	ntfs_free(nf->name);
-	/* Linux filldir errors are negative, other errors positive */
 	return error;
 }
 
-/* readdir returns '..', then '.', then the directory entries in sequence
-   As the root directory contains a entry for itself, '.' is not emulated
-   for the root directory */
+/* readdir returns '..', then '.', then the directory entries in sequence.
+ * As the root directory contains a entry for itself, '.' is not emulated for
+ * the root directory. */
 static int ntfs_readdir(struct file* filp, void *dirent, filldir_t filldir)
 {
 	struct ntfs_filldir cb;
 	int error;
-	struct inode *dir=filp->f_dentry->d_inode;
+	struct inode *dir = filp->f_dentry->d_inode;
 
 	ntfs_debug(DEBUG_OTHER, "ntfs_readdir ino %x mode %x\n",
-	       (unsigned)dir->i_ino,(unsigned int)dir->i_mode);
+		   (unsigned)dir->i_ino, (unsigned int)dir->i_mode);
 
 	ntfs_debug(DEBUG_OTHER, "readdir: Looking for file %x dircount %d\n",
-	       (unsigned)filp->f_pos,atomic_read(&dir->i_count));
-	cb.pl=filp->f_pos & 0xFFFF;
-	cb.ph=filp->f_pos >> 16;
-	/* end of directory */
-	if(cb.ph==0xFFFF){
-		/* FIXME: Maybe we can return those with the previous call */
-		switch(cb.pl){
-		case 0: filldir(dirent,".",1,filp->f_pos,dir->i_ino,DT_DIR);
-			filp->f_pos=0xFFFF0001;
+		   (unsigned)filp->f_pos, atomic_read(&dir->i_count));
+	cb.pl = filp->f_pos & 0xFFFF;
+	cb.ph = filp->f_pos >> 16;
+	/* End of directory. */
+	if (cb.ph == 0xFFFF) {
+		/* FIXME: Maybe we can return those with the previous call. */
+		switch (cb.pl) {
+		case 0: 
+			filldir(dirent, ".", 1, filp->f_pos, dir->i_ino,DT_DIR);
+			filp->f_pos = 0xFFFF0001;
 			return 0;
-			/* FIXME: parent directory */
-		case 1: filldir(dirent,"..",2,filp->f_pos,0,DT_DIR);
-			filp->f_pos=0xFFFF0002;
+			/* FIXME: Parent directory. */
+		case 1:
+			filldir(dirent, "..", 2, filp->f_pos, 0, DT_DIR);
+			filp->f_pos = 0xFFFF0002;
 			return 0;
 		}
 		ntfs_debug(DEBUG_OTHER, "readdir: EOD\n");
 		return 0;
 	}
-	cb.dir=dir;
-	cb.filldir=filldir;
-	cb.dirent=dirent;
-	cb.type=NTFS_INO2VOL(dir)->ngt;
-	do{
+	cb.dir = dir;
+	cb.filldir = filldir;
+	cb.dirent = dirent;
+	cb.type = NTFS_INO2VOL(dir)->ngt;
+	do {
 		ntfs_debug(DEBUG_OTHER,"looking for next file\n");
-		error=ntfs_getdir_unsorted(NTFS_LINO2NINO(dir),&cb.ph,&cb.pl,
-				   ntfs_printcb,&cb);
-	}while(!error && cb.ph!=0xFFFFFFFF);
-	filp->f_pos=(cb.ph<<16)|cb.pl;
-	ntfs_debug(DEBUG_OTHER, "new position %x\n",(unsigned)filp->f_pos);
-        /* -EINVAL is on user buffer full. This is not considered 
-	   as an error by sys_getdents */
-	if(error<0) 
-		error=0;
-	/* Otherwise (device error, inconsistent data), switch the sign */
-	return -error;
+		error = ntfs_getdir_unsorted(NTFS_LINO2NINO(dir), &cb.ph,
+					     &cb.pl, ntfs_printcb, &cb);
+	} while (!error && cb.ph != 0xFFFFFFFF);
+	filp->f_pos = (cb.ph << 16) | cb.pl;
+	ntfs_debug(DEBUG_OTHER, "new position %x\n", (unsigned)filp->f_pos);
+        /* -EINVAL is on user buffer full. This is not considered as an error
+	 * by sys_getdents. */
+	if (error == -EINVAL) 
+		error = 0;
+	/* Otherwise (device error, inconsistent data) return the error code. */
+	return error;
 }
 
-/* Copied from vfat driver */
+/* Copied from vfat driver. */
 static int simple_getbool(char *s, int *setval)
 {
 	if (s) {
-		if (!strcmp(s,"1") || !strcmp(s,"yes") || !strcmp(s,"true")) {
+		if (!strcmp(s, "1") || !strcmp(s, "yes") || !strcmp(s, "true"))
 			*setval = 1;
-		} else if (!strcmp(s,"0") || !strcmp(s,"no") || !strcmp(s,"false")) {
+		else if (!strcmp(s, "0") || !strcmp(s, "no") ||
+							!strcmp(s, "false"))
 			*setval = 0;
-		} else {
+		else
 			return 0;
-		}
-	} else {
+	} else
 		*setval = 1;
-	}
 	return 1;
 }
 
-/* Parse the (re)mount options */
-static int parse_options(ntfs_volume* vol,char *opt)
+/* Parse the (re)mount options. */
+static int parse_options(ntfs_volume* vol, char *opt)
 {
 	char *value;
 
-	vol->uid=vol->gid=0;
-	vol->umask=0077;
-	vol->ngt=ngt_nt;
-	vol->nls_map=0;
-	vol->nct=0;
-	if(!opt)goto done;
-
-	for(opt = strtok(opt,",");opt;opt=strtok(NULL,","))
+	vol->uid = vol->gid = 0;
+	vol->umask = 0077;
+	vol->ngt = ngt_nt;
+	vol->nls_map = 0;
+	vol->nct = 0;
+	if (!opt)
+		goto done;
+	for (opt = strtok(opt, ","); opt; opt = strtok(NULL, ","))
 	{
 		if ((value = strchr(opt, '=')) != NULL)
-			*value++='\0';
-		if(strcmp(opt,"uid")==0)
-		{
-			if(!value || !*value)goto needs_arg;
-			vol->uid=simple_strtoul(value,&value,0);
-			if(*value){
+			*value ++= '\0';
+		if (strcmp(opt, "uid") == 0) {
+			if (!value || !*value)
+				goto needs_arg;
+			vol->uid = simple_strtoul(value, &value, 0);
+			if (*value) {
 				printk(KERN_ERR "NTFS: uid invalid argument\n");
 				return 0;
 			}
-		}else if(strcmp(opt, "gid") == 0)
-		{
-			if(!value || !*value)goto needs_arg;
-			vol->gid=simple_strtoul(value,&value,0);
-			if(*value){
-				printk(KERN_ERR "gid invalid argument\n");
+		} else if (strcmp(opt, "gid") == 0) {
+			if (!value || !*value)
+				goto needs_arg;
+			vol->gid = simple_strtoul(value, &value, 0);
+			if (*value) {
+				printk(KERN_ERR "NTFS: gid invalid argument\n");
 				return 0;
 			}
-		}else if(strcmp(opt, "umask") == 0)
-		{
-			if(!value || !*value)goto needs_arg;
-			vol->umask=simple_strtoul(value,&value,0);
-			if(*value){
-				printk(KERN_ERR "umask invalid argument\n");
+		} else if (strcmp(opt, "umask") == 0) {
+			if (!value || !*value)
+				goto needs_arg;
+			vol->umask = simple_strtoul(value, &value, 0);
+			if (*value) {
+				printk(KERN_ERR "NTFS: umask invalid "
+						"argument\n");
 				return 0;
 			}
-		}else if(strcmp(opt, "iocharset") == 0){
-			if(!value || !*value)goto needs_arg;
-			vol->nls_map=load_nls(value);
+		} else if (strcmp(opt, "iocharset") == 0) {
+			if (!value || !*value)
+				goto needs_arg;
+			vol->nls_map = load_nls(value);
 			vol->nct |= nct_map;
-			if(!vol->nls_map){
+			if (!vol->nls_map) {
 				printk(KERN_ERR "NTFS: charset not found");
 				return 0;
 			}
-		}else if(strcmp(opt, "posix") == 0){
+		} else if (strcmp(opt, "posix") == 0) {
 			int val;
-			if(!value || !*value)goto needs_arg;
-			if(!simple_getbool(value,&val))
+			if (!value || !*value)
+				goto needs_arg;
+			if (!simple_getbool(value, &val))
 				goto needs_bool;
-			vol->ngt=val?ngt_posix:ngt_nt;
-		}else if(strcmp(opt,"utf8") == 0){
-			int val=0;
-			if(!value || !*value)
-				val=1;
-			else if(!simple_getbool(value,&val))
+			vol->ngt = val ? ngt_posix : ngt_nt;
+		} else if (strcmp(opt, "utf8") == 0) {
+			int val = 0;
+			if (!value || !*value)
+				val = 1;
+			else if (!simple_getbool(value, &val))
 				goto needs_bool;
-			if(val)
-				vol->nct|=nct_utf8;
-		}else if(strcmp(opt,"uni_xlate") == 0){
-			int val=0;
-			/* no argument: uni_vfat.
-			   boolean argument: uni_vfat.
-			   "2": uni.
-			*/
-			if(!value || !*value)
-				val=1;
-			else if(strcmp(value,"2")==0)
+			if (val)
+				vol->nct |= nct_utf8;
+		} else if (strcmp(opt, "uni_xlate") == 0) {
+			int val = 0;
+			/* No argument: uni_vfat. boolean argument: uni_vfat.
+			 * "2": uni. */
+			if (!value || !*value)
+				val = 1;
+			else if (strcmp(value, "2") == 0)
 				vol->nct |= nct_uni_xlate;
-			else if(!simple_getbool(value,&val))
+			else if (!simple_getbool(value, &val))
 				goto needs_bool;
-			if(val)
+			if (val)
 				vol->nct |= nct_uni_xlate_vfat | nct_uni_xlate;
-		}else{
+		} else {
 			printk(KERN_ERR "NTFS: unkown option '%s'\n", opt);
 			return 0;
 		}
 	}
-	if(vol->nct & nct_utf8 & (nct_map | nct_uni_xlate)){
-		printk(KERN_ERR "utf8 cannot be combined with iocharset or uni_xlate\n");
+	if (vol->nct & nct_utf8 & (nct_map | nct_uni_xlate)) {
+		printk(KERN_ERR "utf8 cannot be combined with iocharset or "
+				"uni_xlate\n");
 		return 0;
 	}
  done:
-	if((vol->nct & (nct_uni_xlate | nct_map | nct_utf8))==0)
+	if ((vol->nct & (nct_uni_xlate | nct_map | nct_utf8)) == 0)
 		/* default to UTF-8 */
-		vol->nct=nct_utf8;
-	if(!vol->nls_map){
-		vol->nls_map=load_nls_default();
+		vol->nct = nct_utf8;
+	if (!vol->nls_map) {
+		vol->nls_map = load_nls_default();
 		if (vol->nls_map)
-			vol->nct=nct_map | (vol->nct&nct_uni_xlate);
+			vol->nct = nct_map | (vol->nct&nct_uni_xlate);
 	}
 	return 1;
-
  needs_arg:
-	printk(KERN_ERR "NTFS: %s needs an argument",opt);
+	printk(KERN_ERR "NTFS: %s needs an argument", opt);
 	return 0;
  needs_bool:
-	printk(KERN_ERR "NTFS: %s needs boolean argument",opt);
+	printk(KERN_ERR "NTFS: %s needs boolean argument", opt);
 	return 0;
 }
 			
 static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d)
 {
-	struct inode *res=0;
-	char *item=0;
+	struct inode *res = 0;
+	char *item = 0;
 	ntfs_iterate_s walk;
 	int error;
-	ntfs_debug(DEBUG_NAME1, "Looking up %s in %x\n",d->d_name.name,
+	
+	ntfs_debug(DEBUG_NAME1, "Looking up %s in %x\n", d->d_name.name,
 		   (unsigned)dir->i_ino);
-	/* convert to wide string */
-	error=ntfs_decodeuni(NTFS_INO2VOL(dir),(char*)d->d_name.name,
-			     d->d_name.len,&walk.name,&walk.namelen);
-	if(error)
-		return ERR_PTR(-error);
-	item=ntfs_malloc(ITEM_SIZE);
-	if( !item )
+	/* Convert to wide string. */
+	error = ntfs_decodeuni(NTFS_INO2VOL(dir), (char*)d->d_name.name,
+			       d->d_name.len, &walk.name, &walk.namelen);
+	if (error)
+		return ERR_PTR(error);
+	item = ntfs_malloc(ITEM_SIZE);
+	if (!item)
 		return ERR_PTR(-ENOMEM);
-	/* ntfs_getdir will place the directory entry into item,
-	   and the first long long is the MFT record number */
-	walk.type=BY_NAME;
-	walk.dir=NTFS_LINO2NINO(dir);
-	walk.result=item;
-	if(ntfs_getdir_byname(&walk))
-	{
-		res=iget(dir->i_sb,NTFS_GETU32(item));
-	}
-	d_add(d,res);
+	/* ntfs_getdir will place the directory entry into item, and the first
+	 * long long is the MFT record number. */
+	walk.type = BY_NAME;
+	walk.dir = NTFS_LINO2NINO(dir);
+	walk.result = item;
+	if (ntfs_getdir_byname(&walk))
+		res = iget(dir->i_sb, NTFS_GETU32(item));
+	d_add(d, res);
 	ntfs_free(item);
 	ntfs_free(walk.name);
 	/* Always return success, the dcache will handle negative entries. */
@@ -419,74 +415,61 @@
 static struct inode_operations ntfs_inode_operations_nobmap;
 
 #ifdef CONFIG_NTFS_RW
-static int
-ntfs_create(struct inode* dir,struct dentry *d,int mode)
+static int ntfs_create(struct inode* dir, struct dentry *d, int mode)
 {
-	struct inode *r=0;
-	ntfs_inode *ino=0;
+	struct inode *r = 0;
+	ntfs_inode *ino = 0;
 	ntfs_volume *vol;
-	int error=0;
+	int error = 0;
 	ntfs_attribute *si;
 
-	r=new_inode(dir->i_sb);
-	if(!r){
-		error=ENOMEM;
+	r = new_inode(dir->i_sb);
+	if (!r) {
+		error = -ENOMEM;
 		goto fail;
 	}
-
-	ntfs_debug(DEBUG_OTHER, "ntfs_create %s\n",d->d_name.name);
-	vol=NTFS_INO2VOL(dir);
-#ifdef NTFS_IN_LINUX_KERNEL
-	ino=NTFS_LINO2NINO(r);
-#else
-	ino=ntfs_malloc(sizeof(ntfs_inode));
-	if(!ino){
-		error=ENOMEM;
+	ntfs_debug(DEBUG_OTHER, "ntfs_create %s\n", d->d_name.name);
+	vol = NTFS_INO2VOL(dir);
+	ino = NTFS_LINO2NINO(r);
+	error = ntfs_alloc_file(NTFS_LINO2NINO(dir), ino, (char*)d->d_name.name,
+				d->d_name.len);
+	if (error)
 		goto fail;
-	}
-	r->u.generic_ip=ino;
-#endif
-	error=ntfs_alloc_file(NTFS_LINO2NINO(dir),ino,(char*)d->d_name.name,
-			       d->d_name.len);
-	if(error)goto fail;
-	error=ntfs_update_inode(ino);
-	if(error)goto fail;
-	error=ntfs_update_inode(NTFS_LINO2NINO(dir));
-	if(error)goto fail;
-
-	r->i_uid=vol->uid;
-	r->i_gid=vol->gid;
+	error = ntfs_update_inode(ino);
+	if (error)
+		goto fail;
+	error = ntfs_update_inode(NTFS_LINO2NINO(dir));
+	if (error)
+		goto fail;
+	r->i_uid = vol->uid;
+	r->i_gid = vol->gid;
 	/* FIXME: dirty? dev? */
-	/* get the file modification times from the standard information */
-	si=ntfs_find_attr(ino,vol->at_standard_information,NULL);
-	if(si){
-		char *attr=si->d.data;
-		r->i_atime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));
-		r->i_ctime=ntfs_ntutc2unixutc(NTFS_GETU64(attr));
-		r->i_mtime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));
+	/* Get the file modification times from the standard information. */
+	si = ntfs_find_attr(ino, vol->at_standard_information, NULL);
+	if (si) {
+		char *attr = si->d.data;
+		r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 0x18));
+		r->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr));
+		r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8));
 	}
 	/* It's not a directory */
-	r->i_op=&ntfs_inode_operations_nobmap;
-	r->i_fop=&ntfs_file_operations_nommap,
-	r->i_mode=S_IFREG|S_IRUGO;
+	r->i_op = &ntfs_inode_operations_nobmap;
+	r->i_fop = &ntfs_file_operations_nommap,
+	r->i_mode = S_IFREG | S_IRUGO;
 #ifdef CONFIG_NTFS_RW
-	r->i_mode|=S_IWUGO;
+	r->i_mode |= S_IWUGO;
 #endif
 	r->i_mode &= ~vol->umask;
-
 	insert_inode_hash(r);
-	d_instantiate(d,r);
+	d_instantiate(d, r);
 	return 0;
  fail:
-	#ifndef NTFS_IN_LINUX_KERNEL
-	if(ino)ntfs_free(ino);
-	#endif
-	if(r)iput(r);
-	return -error;
+	if (r)
+		iput(r);
+	return error;
 }
 
-static int
-_linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode)
+static int _linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode)
 {
 	int error;
 	struct inode *r = 0;
@@ -494,45 +477,35 @@
 	ntfs_inode *ino;
 	ntfs_attribute *si;
 
-	ntfs_debug (DEBUG_DIR1, "mkdir %s in %x\n",d->d_name.name, dir->i_ino);
-	error = ENAMETOOLONG;
-	if (d->d_name.len > /* FIXME */255)
+	ntfs_debug (DEBUG_DIR1, "mkdir %s in %x\n", d->d_name.name, dir->i_ino);
+	error = -ENAMETOOLONG;
+	if (d->d_name.len > /* FIXME: */ 255)
 		goto out;
-
-	error = EIO;
+	error = -EIO;
 	r = new_inode(dir->i_sb);
 	if (!r)
 		goto out;
-	
 	vol = NTFS_INO2VOL(dir);
-#ifdef NTFS_IN_LINUX_KERNEL
 	ino = NTFS_LINO2NINO(r);
-#else
-	ino = ntfs_malloc(sizeof(ntfs_inode));
-	error = ENOMEM;
-	if(!ino)
-		goto out;
-	r->u.generic_ip = ino;
-#endif
-	error = ntfs_mkdir(NTFS_LINO2NINO(dir), 
-			   d->d_name.name, d->d_name.len, ino);
-	if(error)
+	error = ntfs_mkdir(NTFS_LINO2NINO(dir), d->d_name.name, d->d_name.len,
+			   ino);
+	if (error)
 		goto out;
 	r->i_uid = vol->uid;
 	r->i_gid = vol->gid;
-	si = ntfs_find_attr(ino,vol->at_standard_information,NULL);
-	if(si){
+	si = ntfs_find_attr(ino, vol->at_standard_information, NULL);
+	if (si) {
 		char *attr = si->d.data;
-		r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));
+		r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 0x18));
 		r->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr));
-		r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));
+		r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8));
 	}
-	/* It's a directory */
+	/* It's a directory. */
 	r->i_op = &ntfs_dir_inode_operations;
 	r->i_fop = &ntfs_dir_operations;
-	r->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+	r->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
 #ifdef CONFIG_NTFS_RW
-	r->i_mode|=S_IWUGO;
+	r->i_mode |= S_IWUGO;
 #endif
 	r->i_mode &= ~vol->umask;	
 	
@@ -540,24 +513,23 @@
 	d_instantiate(d, r);
 	error = 0;
  out:
- 	ntfs_debug (DEBUG_DIR1, "mkdir returns %d\n", -error);
-	return -error;
+ 	ntfs_debug (DEBUG_DIR1, "mkdir returns %d\n", error);
+	return error;
 }
 #endif
 
 #if 0
-static int 
-ntfs_bmap(struct inode *ino,int block)
+static int ntfs_bmap(struct inode *ino, int block)
 {
-	int ret=ntfs_vcn_to_lcn(NTFS_LINO2NINO(ino),block);
-	ntfs_debug(DEBUG_OTHER, "bmap of %lx,block %x is %x\n",
-	       ino->i_ino,block,ret);
-	return (ret==-1) ? 0:ret;
+	int ret = ntfs_vcn_to_lcn(NTFS_LINO2NINO(ino), block);
+	ntfs_debug(DEBUG_OTHER, "bmap of %lx, block %x is %x\n", ino->i_ino,
+		   block, ret);
+	return (ret == -1) ? 0 : ret;
 }
 #endif
 
 /* It's fscking broken. */
-/* FIXME: [bm]map code is disabled until ntfs_get_block gets sorted! */
+/* FIXME: [bm]map code is disabled until ntfs_get_block() gets sorted! */
 /*
 static int ntfs_get_block(struct inode *inode, long block, struct buffer_head *bh, int create)
 {
@@ -594,19 +566,24 @@
 {
 	return block_write_full_page(page,ntfs_get_block);
 }
+
 static int ntfs_readpage(struct file *file, struct page *page)
 {
 	return block_read_full_page(page,ntfs_get_block);
 }
-static int ntfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+
+static int ntfs_prepare_write(struct file *file, struct page *page,
+			      unsigned from, unsigned to)
 {
-	return cont_prepare_write(page,from,to,ntfs_get_block,
-		&page->mapping->host->u.ntfs_i.mmu_private);
+	return cont_prepare_write(page, from, to, ntfs_get_block,
+				  &page->mapping->host->u.ntfs_i.mmu_private);
 }
+
 static int _ntfs_bmap(struct address_space *mapping, long block)
 {
-	return generic_block_bmap(mapping,block,ntfs_get_block);
+	return generic_block_bmap(mapping, block, ntfs_get_block);
 }
+
 struct address_space_operations ntfs_aops = {
 	readpage: ntfs_readpage,
 	writepage: ntfs_writepage,
@@ -617,84 +594,69 @@
 };
 */
 
-/* ntfs_read_inode is called by the Virtual File System (the kernel layer that
- * deals with filesystems) when iget is called requesting an inode not already
- * present in the inode table. Typically filesystems have separate
- * inode_operations for directories, files and symlinks.
- */
+/* ntfs_read_inode() is called by the Virtual File System (the kernel layer 
+ * that deals with filesystems) when iget is called requesting an inode not
+ * already present in the inode table. Typically filesystems have separate
+ * inode_operations for directories, files and symlinks. */
 static void ntfs_read_inode(struct inode* inode)
 {
 	ntfs_volume *vol;
-	int can_mmap=0;
+	int can_mmap = 0;
 	ntfs_inode *ino;
 	ntfs_attribute *data;
 	ntfs_attribute *si;
 
-	vol=NTFS_INO2VOL(inode);
-	inode->i_mode=0;
-	ntfs_debug(DEBUG_OTHER, "ntfs_read_inode %x\n",(unsigned)inode->i_ino);
-
-	switch(inode->i_ino)
-	{
-		/* those are loaded special files */
-	case FILE_MFT:
-		ntfs_error("Trying to open MFT\n");return;
+	vol = NTFS_INO2VOL(inode);
+	inode->i_mode = 0;
+	ntfs_debug(DEBUG_OTHER, "ntfs_read_inode %x\n", (unsigned)inode->i_ino);
+	switch (inode->i_ino) {
+		/* Those are loaded special files. */
+	case FILE_$Mft:
+		ntfs_error("Trying to open MFT\n");
+		return;
 	default:
-		#ifdef NTFS_IN_LINUX_KERNEL
-		ino=&inode->u.ntfs_i;
-		#else
-		/* FIXME: check for ntfs_malloc failure */
-		ino=(ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));
-		inode->u.generic_ip=ino;
-		#endif
-		if(!ino || ntfs_init_inode(ino,
-					   NTFS_INO2VOL(inode),inode->i_ino))
+		ino = &inode->u.ntfs_i;
+		if (!ino || ntfs_init_inode(ino, NTFS_INO2VOL(inode),
+								inode->i_ino))
 		{
-			ntfs_debug(DEBUG_OTHER, "NTFS:Error loading inode %x\n",
-			       (unsigned int)inode->i_ino);
+			ntfs_debug(DEBUG_OTHER, "NTFS :Error loading inode "
+					"%x\n", (unsigned int)inode->i_ino);
 			return;
 		}
 	}
 	/* Set uid/gid from mount options */
-	inode->i_uid=vol->uid;
-	inode->i_gid=vol->gid;
-	inode->i_nlink=1;
+	inode->i_uid = vol->uid;
+	inode->i_gid = vol->gid;
+	inode->i_nlink = 1;
 	/* Use the size of the data attribute as file size */
-	data = ntfs_find_attr(ino,vol->at_data,NULL);
-	if(!data)
-	{
-		inode->i_size=0;
-		can_mmap=0;
-	}
-	else
-	{
-		inode->i_size=data->size;
+	data = ntfs_find_attr(ino, vol->at_data, NULL);
+	if (!data) {
+		inode->i_size = 0;
+		can_mmap = 0;
+	} else {
+		inode->i_size = data->size;
 		/* FIXME: once ntfs_get_block is implemented, uncomment the
-		 * next line and remove the can_mmap = 0; */
-		/* can_mmap=!data->resident && !data->compressed;*/
+		 * next line and remove the "can_mmap = 0;". (AIA) */
+		/* can_mmap = !data->resident && !data->compressed; */
 		can_mmap = 0;
 	}
-	/* get the file modification times from the standard information */
-	si=ntfs_find_attr(ino,vol->at_standard_information,NULL);
-	if(si){
-		char *attr=si->d.data;
-		inode->i_atime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));
-		inode->i_ctime=ntfs_ntutc2unixutc(NTFS_GETU64(attr));
-		inode->i_mtime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));
+	/* Get the file modification times from the standard information. */
+	si = ntfs_find_attr(ino,vol->at_standard_information, NULL);
+	if (si) {
+		char *attr = si->d.data;
+		inode->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 0x18));
+		inode->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr));
+		inode->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8));
 	}
-	/* if it has an index root, it's a directory */
-	if(ntfs_find_attr(ino,vol->at_index_root,"$I30"))
-	{
+	/* If it has an index root, it's a directory. */
+	if (ntfs_find_attr(ino, vol->at_index_root, "$I30")) {
 		ntfs_attribute *at;
-		at = ntfs_find_attr (ino, vol->at_index_allocation, "$I30");
+		at = ntfs_find_attr(ino, vol->at_index_allocation, "$I30");
 		inode->i_size = at ? at->size : 0;
-	  
-		inode->i_op=&ntfs_dir_inode_operations;
-		inode->i_fop=&ntfs_dir_operations;
-		inode->i_mode=S_IFDIR|S_IRUGO|S_IXUGO;
-	}
-	else
-	{
+		inode->i_op = &ntfs_dir_inode_operations;
+		inode->i_fop = &ntfs_dir_operations;
+		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+	} else {
 		/* As long as ntfs_get_block() is just a call to BUG() do not
 	 	 * define any [bm]map ops or we get the BUG() whenever someone
 		 * runs mc or mpg123 on an ntfs partition!
@@ -706,25 +668,24 @@
 			inode->i_mapping->a_ops = &ntfs_aops;
 			inode->u.ntfs_i.mmu_private = inode->i_size;
 		} else */ {
-			inode->i_op=&ntfs_inode_operations_nobmap;
-			inode->i_fop=&ntfs_file_operations_nommap;
+			inode->i_op = &ntfs_inode_operations_nobmap;
+			inode->i_fop = &ntfs_file_operations_nommap;
 		}
-		inode->i_mode=S_IFREG|S_IRUGO;
+		inode->i_mode = S_IFREG | S_IRUGO;
 	}
 #ifdef CONFIG_NTFS_RW
-	if(!data || !data->compressed)
-		inode->i_mode|=S_IWUGO;
+	if (!data || !data->compressed)
+		inode->i_mode |= S_IWUGO;
 #endif
 	inode->i_mode &= ~vol->umask;
 }
 
 #ifdef CONFIG_NTFS_RW
-static void 
-ntfs_write_inode (struct inode *ino, int unused)
+static void ntfs_write_inode(struct inode *ino, int unused)
 {
 	lock_kernel();
-	ntfs_debug (DEBUG_LINUX, "ntfs:write inode %x\n", ino->i_ino);
-	ntfs_update_inode (NTFS_LINO2NINO (ino));
+	ntfs_debug(DEBUG_LINUX, "ntfs_write_inode %x\n", ino->i_ino);
+	ntfs_update_inode(NTFS_LINO2NINO(ino));
 	unlock_kernel();
 }
 #endif
@@ -732,41 +693,27 @@
 static void _ntfs_clear_inode(struct inode *ino)
 {
 	lock_kernel();
-	ntfs_debug(DEBUG_OTHER, "ntfs_clear_inode %lx\n",ino->i_ino);
-#ifdef NTFS_IN_LINUX_KERNEL
-	if(ino->i_ino!=FILE_MFT)
+	ntfs_debug(DEBUG_OTHER, "ntfs_clear_inode %lx\n", ino->i_ino);
+	if (ino->i_ino != FILE_$Mft)
 		ntfs_clear_inode(&ino->u.ntfs_i);
-#else
-	if(ino->i_ino!=FILE_MFT && ino->u.generic_ip)
-	{
-		ntfs_clear_inode(ino->u.generic_ip);
-		ntfs_free(ino->u.generic_ip);
-		ino->u.generic_ip=0;
-	}
-#endif
 	unlock_kernel();
 	return;
 }
 
-/* Called when umounting a filesystem by do_umount() in fs/super.c */
+/* Called when umounting a filesystem by do_umount() in fs/super.c. */
 static void ntfs_put_super(struct super_block *sb)
 {
 	ntfs_volume *vol;
 
 	ntfs_debug(DEBUG_OTHER, "ntfs_put_super\n");
-
-	vol=NTFS_SB2VOL(sb);
-
+	vol = NTFS_SB2VOL(sb);
 	ntfs_release_volume(vol);
-	if(vol->nls_map)
+	if (vol->nls_map)
 		unload_nls(vol->nls_map);
-#ifndef NTFS_IN_LINUX_KERNEL
-	ntfs_free(vol);
-#endif
 	ntfs_debug(DEBUG_OTHER, "ntfs_put_super: done\n");
 }
 
-/* Called by the kernel when asking for stats */
+/* Called by the kernel when asking for stats. */
 static int ntfs_statfs(struct super_block *sb, struct statfs *sf)
 {
 	struct inode *mft;
@@ -775,34 +722,31 @@
 	int error;
 
 	ntfs_debug(DEBUG_OTHER, "ntfs_statfs\n");
-	vol=NTFS_SB2VOL(sb);
-	sf->f_type=NTFS_SUPER_MAGIC;
-	sf->f_bsize=vol->clustersize;
-
-	error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &size );
-	if( error )
-		return -error;
-	sf->f_blocks = size;	/* volumesize is in clusters */
-	sf->f_bfree=ntfs_get_free_cluster_count(vol->bitmap);
-	sf->f_bavail=sf->f_bfree;
-
-	mft=iget(sb,FILE_MFT);
+	vol = NTFS_SB2VOL(sb);
+	sf->f_type = NTFS_SUPER_MAGIC;
+	sf->f_bsize = vol->clustersize;
+	error = ntfs_get_volumesize(NTFS_SB2VOL(sb), &size);
+	if (error)
+		return error;
+	sf->f_blocks = size;	/* Volumesize is in clusters. */
+	sf->f_bfree = ntfs_get_free_cluster_count(vol->bitmap);
+	sf->f_bavail = sf->f_bfree;
+	mft = iget(sb, FILE_$Mft);
 	if (!mft)
 		return -EIO;
-	/* So ... we lie... thus this following cast of loff_t value
-	   is ok here.. */
+	/* So ... we lie... thus this following cast of loff_t value is ok
+	 * here.. */
 	sf->f_files = (unsigned long)mft->i_size / vol->mft_recordsize;
 	iput(mft);
-
-	/* should be read from volume */
-	sf->f_namelen=255;
+	/* Should be read from volume. */
+	sf->f_namelen = 255;
 	return 0;
 }
 
-/* Called when remounting a filesystem by do_remount_sb() in fs/super.c */
+/* Called when remounting a filesystem by do_remount_sb() in fs/super.c. */
 static int ntfs_remount_fs(struct super_block *sb, int *flags, char *options)
 {
-	if(!parse_options(NTFS_SB2VOL(sb), options))
+	if (!parse_options(NTFS_SB2VOL(sb), options))
 		return -EINVAL;
 	return 0;
 }
@@ -819,144 +763,133 @@
 	clear_inode:	_ntfs_clear_inode,
 };
 
-/* Called to mount a filesystem by read_super() in fs/super.c
- * Return a super block, the main structure of a filesystem
+/* Called to mount a filesystem by read_super() in fs/super.c.
+ * Return a super block, the main structure of a filesystem.
  *
  * NOTE : Don't store a pointer to an option, as the page containing the
  * options is freed after ntfs_read_super() returns.
  *
  * NOTE : A context switch can happen in kernel code only if the code blocks
- * (= calls schedule() in kernel/sched.c).
- */
-struct super_block * ntfs_read_super(struct super_block *sb, 
-				     void *options, int silent)
+ * (= calls schedule() in kernel/sched.c). */
+struct super_block * ntfs_read_super(struct super_block *sb, void *options,
+				     int silent)
 {
 	ntfs_volume *vol;
 	struct buffer_head *bh;
 	int i;
 
 	ntfs_debug(DEBUG_OTHER, "ntfs_read_super\n");
-
-#ifdef NTFS_IN_LINUX_KERNEL
 	vol = NTFS_SB2VOL(sb);
-#else
-	if(!(vol = ntfs_malloc(sizeof(ntfs_volume))))
-		goto ntfs_read_super_dec;
-	NTFS_SB2VOL(sb)=vol;
-#endif
-	
-	if(!parse_options(vol,(char*)options))
+	if (!parse_options(vol, (char*)options))
 		goto ntfs_read_super_vol;
-
 #if 0
 	/* Set to read only, user option might reset it */
 	sb->s_flags |= MS_RDONLY;
 #endif
-
-	/* Assume a 512 bytes block device for now */
+	/* Assume a 512 bytes block device for now. */
 	set_blocksize(sb->s_dev, 512);
-	/* Read the super block (boot block) */
-	if(!(bh=bread(sb->s_dev,0,512))) {
+	/* Read the super block (boot block). */
+	if (!(bh = bread(sb->s_dev, 0, 512))) {
 		ntfs_error("Reading super block failed\n");
 		goto ntfs_read_super_unl;
 	}
 	ntfs_debug(DEBUG_OTHER, "Done reading boot block\n");
-
 	/* Check for 'NTFS' magic number */
-	if(!IS_NTFS_VOLUME(bh->b_data)){
+	if (!IS_NTFS_VOLUME(bh->b_data)) {
 		ntfs_debug(DEBUG_OTHER, "Not a NTFS volume\n");
 		brelse(bh);
 		goto ntfs_read_super_unl;
 	}
-
 	ntfs_debug(DEBUG_OTHER, "Going to init volume\n");
-	ntfs_init_volume(vol,bh->b_data);
-	ntfs_debug(DEBUG_OTHER, "MFT record at cluster 0x%X\n",vol->mft_cluster);
+	if (ntfs_init_volume(vol, bh->b_data) < 0) {
+		ntfs_debug(DEBUG_OTHER, "Init volume failed.\n");
+		brelse(bh);
+		goto ntfs_read_super_unl;
+	}
+	ntfs_debug(DEBUG_OTHER, "$Mft at cluster 0x%Lx\n", vol->mft_cluster);
 	brelse(bh);
-	NTFS_SB(vol)=sb;
+	NTFS_SB(vol) = sb;
 	ntfs_debug(DEBUG_OTHER, "Done to init volume\n");
-
-	/* Inform the kernel that a device block is a NTFS cluster */
-	sb->s_blocksize=vol->clustersize;
-	for(i=sb->s_blocksize,sb->s_blocksize_bits=0;i != 1;i>>=1)
+	/* Inform the kernel that a device block is a NTFS cluster. */
+	sb->s_blocksize = vol->clustersize;
+	if (sb->s_blocksize > PAGE_SIZE) {
+		ntfs_error("Partition cluster size is not supported yet (too "
+			   "large for kernel blocksize).\n");
+		goto ntfs_read_super_unl;
+	}
+	for (i = sb->s_blocksize, sb->s_blocksize_bits = 0; i != 1; i >>= 1)
 		sb->s_blocksize_bits++;
-	set_blocksize(sb->s_dev,sb->s_blocksize);
+	set_blocksize(sb->s_dev, sb->s_blocksize);
 	ntfs_debug(DEBUG_OTHER, "set_blocksize\n");
 
-	/* Allocate a MFT record (MFT record can be smaller than a cluster) */
-	if(!(vol->mft=ntfs_malloc(max(vol->mft_recordsize,vol->clustersize))))
+	/* Allocate a MFT record (MFT record can be smaller than a cluster). */
+	if (!(vol->mft = ntfs_malloc(max(vol->mft_recordsize,
+							   vol->clustersize))))
 		goto ntfs_read_super_unl;
 
-	/* Read at least the MFT record for $MFT */
-	for(i=0;i<max(vol->mft_clusters_per_record,1);i++){
-		if(!(bh=bread(sb->s_dev,vol->mft_cluster+i,vol->clustersize))) {
-			ntfs_error("Could not read MFT record 0\n");
+	/* Read at least the MFT record for $Mft. */
+	for (i = 0; i < max(vol->mft_clusters_per_record, 1); i++) {
+		if (!(bh = bread(sb->s_dev, vol->mft_cluster + i,
+							  vol->clustersize))) {
+			ntfs_error("Could not read $Mft record 0\n");
 			goto ntfs_read_super_mft;
 		}
-		ntfs_memcpy(vol->mft+i*vol->clustersize,bh->b_data,vol->clustersize);
+		ntfs_memcpy(vol->mft + i * vol->clustersize, bh->b_data,
+							     vol->clustersize);
 		brelse(bh);
-		ntfs_debug(DEBUG_OTHER, "Read cluster %x\n",vol->mft_cluster+i);
+		ntfs_debug(DEBUG_OTHER, "Read cluster %x\n",
+							 vol->mft_cluster + i);
 	}
-
 	/* Check and fixup this MFT record */
-	if(!ntfs_check_mft_record(vol,vol->mft)){
-		ntfs_error("Invalid MFT record 0\n");
+	if (!ntfs_check_mft_record(vol, vol->mft)){
+		ntfs_error("Invalid $Mft record 0\n");
 		goto ntfs_read_super_mft;
 	}
-
-	/* Inform the kernel about which super operations are available */
+	/* Inform the kernel about which super operations are available. */
 	sb->s_op = &ntfs_super_operations;
 	sb->s_magic = NTFS_SUPER_MAGIC;
-	
+	sb->s_maxbytes = ~0ULL;
 	ntfs_debug(DEBUG_OTHER, "Reading special files\n");
-	if(ntfs_load_special_files(vol)){
+	if (ntfs_load_special_files(vol)) {
 		ntfs_error("Error loading special files\n");
 		goto ntfs_read_super_mft;
 	}
-
 	ntfs_debug(DEBUG_OTHER, "Getting RootDir\n");
-	/* Get the root directory */
-	if(!(sb->s_root=d_alloc_root(iget(sb,FILE_ROOT)))){
+	/* Get the root directory. */
+	if (!(sb->s_root = d_alloc_root(iget(sb, FILE_$root)))) {
 		ntfs_error("Could not get root dir inode\n");
 		goto ntfs_read_super_mft;
 	}
 	ntfs_debug(DEBUG_OTHER, "read_super: done\n");
 	return sb;
-
 ntfs_read_super_mft:
 	ntfs_free(vol->mft);
 ntfs_read_super_unl:
 ntfs_read_super_vol:
-	#ifndef NTFS_IN_LINUX_KERNEL
-	ntfs_free(vol);
-ntfs_read_super_dec:
-	#endif
 	ntfs_debug(DEBUG_OTHER, "read_super: done\n");
 	return NULL;
 }
 
-/* Define the filesystem
- */
+/* Define the filesystem */
 static DECLARE_FSTYPE_DEV(ntfs_fs_type, "ntfs", ntfs_read_super);
 
 static int __init init_ntfs_fs(void)
 {
-	/* Comment this if you trust klogd. There are reasons not to trust it
-	 */
+	/* Comment this if you trust klogd. There are reasons not to trust it */
 #if defined(DEBUG) && !defined(MODULE)
 	console_verbose();
 #endif
 	printk(KERN_NOTICE "NTFS version " NTFS_VERSION "\n");
 	SYSCTL(1);
-	ntfs_debug(DEBUG_OTHER, "registering %s\n",ntfs_fs_type.name);
-	/* add this filesystem to the kernel table of filesystems */
+	ntfs_debug(DEBUG_OTHER, "registering %s\n", ntfs_fs_type.name);
+	/* Add this filesystem to the kernel table of filesystems. */
 	return register_filesystem(&ntfs_fs_type);
 }
 
 static void __exit exit_ntfs_fs(void)
 {
 	SYSCTL(0);
-	ntfs_debug(DEBUG_OTHER, "unregistering %s\n",ntfs_fs_type.name);
+	ntfs_debug(DEBUG_OTHER, "unregistering %s\n", ntfs_fs_type.name);
 	unregister_filesystem(&ntfs_fs_type);
 }
 
@@ -970,8 +903,4 @@
 
 module_init(init_ntfs_fs)
 module_exit(exit_ntfs_fs)
-/*
- * Local variables:
- *  c-file-style: "linux"
- * End:
- */
+
diff -urN linux-2.4.4-pre4/fs/ntfs/inode.c linux/fs/ntfs/inode.c
--- linux-2.4.4-pre4/fs/ntfs/inode.c	Fri Nov 17 11:35:27 2000
+++ linux/fs/ntfs/inode.c	Mon Dec  3 22:35:56 2001
@@ -1,23 +1,18 @@
-/*
- *  inode.c
+/*  inode.c
  *
  *  Copyright (C) 1995-1999 Martin von Löwis
  *  Copyright (C) 1996 Albert D. Cahalan
  *  Copyright (C) 1996-1997 Régis Duchesne
  *  Copyright (C) 1998 Joseph Malicki
  *  Copyright (C) 1999 Steve Dodd
- *  Copyright (C) 2000 Anton Altaparmakov
+ *  Copyright (C) 2000-2001 Anton Altaparmakov (AIA)
  */
 
 #include "ntfstypes.h"
 #include "ntfsendian.h"
 #include "struct.h"
 #include "inode.h"
-
 #include <linux/errno.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
 #include "macros.h"
 #include "attr.h"
 #include "super.h"
@@ -27,210 +22,229 @@
 
 typedef struct {
 	int recno;
-	unsigned char* record;
+	unsigned char *record;
 } ntfs_mft_record;
 
 typedef struct {
 	int size;
 	int count;
-	ntfs_mft_record* records;
+	ntfs_mft_record *records;
 } ntfs_disk_inode;
 
-void
-ntfs_fill_mft_header(ntfs_u8*mft,int record_size,int blocksize,
-		int sequence_number)
+void ntfs_fill_mft_header(ntfs_u8 *mft, int record_size, int blocksize,
+			  int sequence_number)
 {
 	int fixup_count = record_size / blocksize + 1;
 	int attr_offset = (0x2a + (2 * fixup_count) + 7) & ~7;
 	int fixup_offset = 0x2a;
 
 	NTFS_PUTU32(mft + 0x00, 0x454c4946);	     /* FILE */
-	NTFS_PUTU16(mft + 0x04, 0x2a);		     /* offset to fixup */
-	NTFS_PUTU16(mft + 0x06, fixup_count);	     /* Number of fixups */
-	NTFS_PUTU16(mft + 0x10, sequence_number);
-	NTFS_PUTU16(mft + 0x12, 1);                  /* hard link count */
-	NTFS_PUTU16(mft + 0x14, attr_offset);	     /* Offset to attributes */
-	NTFS_PUTU16(mft + 0x16, 1);                  /*FIXME: flags ?? */
-	NTFS_PUTU32(mft + 0x18, attr_offset + 0x08);	/* In use */
-	NTFS_PUTU32(mft + 0x1c, record_size);	     /* Total size */
-
-	NTFS_PUTU16(mft + fixup_offset, 1);		/* Fixup word */
-	NTFS_PUTU32(mft + attr_offset, 0xffffffff);	/* End marker */
-}
-
-/* Search in an inode an attribute by type and name */
-ntfs_attribute* 
-ntfs_find_attr(ntfs_inode *ino,int type,char *name)
+	NTFS_PUTU16(mft + 0x04, 0x2a);		     /* Offset to fixup. */
+	NTFS_PUTU16(mft + 0x06, fixup_count);	     /* Number of fixups. */
+	NTFS_PUTU16(mft + 0x10, sequence_number);    /* Sequence number. */
+	NTFS_PUTU16(mft + 0x12, 1);                  /* Hard link count. */
+	NTFS_PUTU16(mft + 0x14, attr_offset);	     /* Offset to attributes. */
+	NTFS_PUTU16(mft + 0x16, 1);                  /* Flags: 1 = In use,
+							       2 = Directory. */
+	NTFS_PUTU32(mft + 0x18, attr_offset + 0x08); /* Bytes in use. */
+	NTFS_PUTU32(mft + 0x1c, record_size);	     /* Total allocated size. */
+	NTFS_PUTU16(mft + fixup_offset, 1);	     /* Fixup word. */
+	NTFS_PUTU32(mft + attr_offset, 0xffffffff);  /* End marker. */
+}
+
+/* Search in an inode an attribute by type and name. 
+ * FIXME: Check that when attributes are inserted all attribute list
+ * attributes are expanded otherwise need to modify this function to deal
+ * with attribute lists. (AIA) */
+ntfs_attribute *ntfs_find_attr(ntfs_inode *ino, int type, char *name)
 {
 	int i;
-	if(!ino){
+	
+	if (!ino) {
 		ntfs_error("ntfs_find_attr: NO INODE!\n");
 		return 0;
 	}
-	for(i=0;i<ino->attr_count;i++)
-	{
-		if(type==ino->attrs[i].type)
-		{
-			if(!name && !ino->attrs[i].name)
-				return ino->attrs+i;
-			if(name && !ino->attrs[i].name)
-				return 0;
-			if(!name && ino->attrs[i].name)
-				return 0;
-			if(ntfs_ua_strncmp(ino->attrs[i].name,name,strlen(name))==0)
-				return ino->attrs+i;
-		}
-		if(type<ino->attrs[i].type)
+	for (i = 0; i < ino->attr_count; i++) {
+		if (type < ino->attrs[i].type)
 			return 0;
+		if (type == ino->attrs[i].type) {
+			if (!name) {
+				if (!ino->attrs[i].name)
+					return ino->attrs + i;
+			} else if (ino->attrs[i].name &&
+				   !ntfs_ua_strncmp(ino->attrs[i].name, name,
+						    strlen(name)))
+				return ino->attrs + i;
+		}
 	}
 	return 0;
 }
 
-/* FIXME: need better strategy to extend the MFT */
-static int 
-ntfs_extend_mft(ntfs_volume *vol)
-{
-	/* Try to allocate at least 0.1% of the remaining disk space
-	   for inodes. If the disk is almost full, make sure at least one
-	   inode is requested.
-	 */
-	int size,rcount,error,block;
-	ntfs_attribute* mdata,*bmp;
+/* FIXME: Need better strategy to extend the MFT. */
+static int ntfs_extend_mft(ntfs_volume *vol)
+{
+	/* Try to allocate at least 0.1% of the remaining disk space for
+	 * inodes. If the disk is almost full, make sure at least one inode is
+	 * requested. */
+	int size, rcount, error, block;
+	ntfs_attribute *mdata, *bmp;
 	ntfs_u8 *buf;
 	ntfs_io io;
 
-	mdata=ntfs_find_attr(vol->mft_ino,vol->at_data,0);
-	/* first check whether there is uninitialized space */
-	if(mdata->allocated<mdata->size+vol->mft_recordsize){
-		size=ntfs_get_free_cluster_count(vol->bitmap)*vol->clustersize;
-		block=vol->mft_recordsize;
-		size=max(size/1000,mdata->size+vol->mft_recordsize);
-		size=((size+block-1)/block)*block;
-		/* require this to be a single chunk */
-		error=ntfs_extend_attr(vol->mft_ino,mdata,&size,
-				       ALLOC_REQUIRE_SIZE);
-		/* Try again, now we have the largest available fragment */
-		if(error==ENOSPC){
-			/* round down to multiple of mft record size */
-			size=(size/vol->mft_recordsize)*vol->mft_recordsize;
-			if(!size)return ENOSPC;
-			error=ntfs_extend_attr(vol->mft_ino,mdata,&size,
-					       ALLOC_REQUIRE_SIZE);
+	mdata = ntfs_find_attr(vol->mft_ino, vol->at_data, 0);
+	/* First check whether there is uninitialized space. */
+	if (mdata->allocated < mdata->size + vol->mft_recordsize) {
+		size = ntfs_get_free_cluster_count(vol->bitmap) *
+							      vol->clustersize;
+		block = vol->mft_recordsize;
+		size = max(size / 1000, mdata->size + vol->mft_recordsize);
+		size = ((size + block - 1) / block) * block;
+		/* Require this to be a single chunk. */
+		error = ntfs_extend_attr(vol->mft_ino, mdata, &size,
+							   ALLOC_REQUIRE_SIZE);
+		/* Try again, now we have the largest available fragment. */
+		if (error == -ENOSPC) {
+			/* Round down to multiple of mft record size. */
+			size = (size / vol->mft_recordsize) *
+							   vol->mft_recordsize;
+			if (!size)
+				return -ENOSPC;
+			error = ntfs_extend_attr(vol->mft_ino, mdata, &size,
+							   ALLOC_REQUIRE_SIZE);
 		}
-		if(error)
+		if (error)
 			return error;
 	}
-	/* even though we might have allocated more than needed,
-	   we initialize only one record */
-	mdata->size+=vol->mft_recordsize;
-	
-	/* now extend the bitmap if necessary*/
-	rcount=mdata->size/vol->mft_recordsize;
-	bmp=ntfs_find_attr(vol->mft_ino,vol->at_bitmap,0);
-	if(bmp->size*8<rcount){ /* less bits than MFT records */
+	/* Even though we might have allocated more than needed, we initialize
+	 * only one record. */
+	mdata->size += vol->mft_recordsize;
+	/* Now extend the bitmap if necessary. */
+	rcount = mdata->size / vol->mft_recordsize;
+	bmp = ntfs_find_attr(vol->mft_ino, vol->at_bitmap, 0);
+	if (bmp->size * 8 < rcount) { /* Less bits than MFT records. */
 		ntfs_u8 buf[1];
-		/* extend bitmap by one byte */
-		error=ntfs_resize_attr(vol->mft_ino,bmp,bmp->size+1);
-		if(error)return error;
-		/* write the single byte */
-		buf[0]=0;
-		io.fn_put=ntfs_put;
-		io.fn_get=ntfs_get;
-		io.param=buf;
-		io.size=1;
-		error=ntfs_write_attr(vol->mft_ino,vol->at_bitmap,0,
-				      bmp->size-1,&io);
-		if(error)return error;
-		if(io.size!=1)return EIO;
-	}
-
-	/* now fill in the MFT header for the new block */
-	buf=ntfs_calloc(vol->mft_recordsize);
-	if(!buf)return ENOMEM;
-	ntfs_fill_mft_header(buf,vol->mft_recordsize,vol->blocksize,0);
-	ntfs_insert_fixups(buf,vol->blocksize);
-	io.param=buf;
-	io.size=vol->mft_recordsize;
+		/* Extend bitmap by one byte. */
+		error = ntfs_resize_attr(vol->mft_ino, bmp, bmp->size + 1);
+		if (error)
+			return error;
+		/* Write the single byte. */
+		buf[0] = 0;
+		io.fn_put = ntfs_put;
+		io.fn_get = ntfs_get;
+		io.param = buf;
+		io.size = 1;
+		error = ntfs_write_attr(vol->mft_ino, vol->at_bitmap, 0,
+					bmp->size - 1, &io);
+		if (error)
+			return error;
+		if (io.size != 1)
+			return -EIO;
+	}
+	/* Now fill in the MFT header for the new block. */
+	buf = ntfs_calloc(vol->mft_recordsize);
+	if (!buf)
+		return -ENOMEM;
+	ntfs_fill_mft_header(buf, vol->mft_recordsize, vol->blocksize, 0);
+	ntfs_insert_fixups(buf, vol->blocksize);
+	io.param = buf;
+	io.size = vol->mft_recordsize;
 	io.fn_put = ntfs_put;
 	io.fn_get = ntfs_get;
-	error=ntfs_write_attr(vol->mft_ino,vol->at_data,0,
-			      (rcount-1)*vol->mft_recordsize,&io);
-	if(error)return error;
-	if(io.size!=vol->mft_recordsize)return EIO;
-	error=ntfs_update_inode(vol->mft_ino);
-	if(error)return error;
+	error = ntfs_write_attr(vol->mft_ino, vol->at_data, 0,
+				(rcount - 1) * vol->mft_recordsize, &io);
+	if (error)
+		return error;
+	if (io.size != vol->mft_recordsize)
+		return -EIO;
+	error = ntfs_update_inode(vol->mft_ino);
+	if (error)
+		return error;
 	return 0;
 }
 
-/* Insert all attributes from the record mftno of the MFT in the inode ino */
-void ntfs_insert_mft_attributes(ntfs_inode* ino,char *mft,int mftno)
+/* Insert all attributes from the record mftno of the MFT in the inode ino.
+ * FIXME: We should be performing structural consistency checks. (AIA)
+ * Return 0 on success or -errno on error. */
+static int ntfs_insert_mft_attributes(ntfs_inode* ino, char *mft, int mftno)
 {
-	int i;
+	int i, error, type, len;
 	char *it;
-	int type,len;
-	/* check for duplicate */
-	for(i=0;i<ino->record_count;i++)
-		if(ino->records[i]==mftno)
-			return;
-	/* (re-)allocate space if necessary */
-	if(ino->record_count % 8==0)
-	{
+	
+	/* Check for duplicate. */
+	for(i = 0; i < ino->record_count; i++)
+		if (ino->records[i] == mftno)
+			return 0;
+	/* (re-)allocate space if necessary. */
+	if (ino->record_count % 8 == 0)	{
 		int *new;
-		new = ntfs_malloc((ino->record_count+8)*sizeof(int));
-		if( !new )
-			return;
-		if( ino->records ) {
-			for(i=0;i<ino->record_count;i++)
+
+		new = ntfs_malloc((ino->record_count + 8) * sizeof(int));
+		if (!new)
+			return -ENOMEM;
+		if (ino->records) {
+			for (i = 0; i < ino->record_count; i++)
 				new[i] = ino->records[i];
-			ntfs_free( ino->records );
+			ntfs_free(ino->records);
 		}
 		ino->records = new;
 	}
-	ino->records[ino->record_count]=mftno;
+	ino->records[ino->record_count] = mftno;
 	ino->record_count++;
 	it = mft + NTFS_GETU16(mft + 0x14);
-	do{
-		type=NTFS_GETU32(it);
-		len=NTFS_GETU32(it+4);
-		if(type!=-1) {
-			/* FIXME: check ntfs_insert_attribute for failure (e.g. no mem)? */
-			ntfs_insert_attribute(ino,it);
-		}
-		it+=len;
-	}while(type!=-1); /* attribute list ends with type -1 */
+	do {
+		type = NTFS_GETU32(it);
+		len = NTFS_GETU32(it + 4);
+		if (type != -1) {
+			error = ntfs_insert_attribute(ino, it);
+			if (error)
+				return error;
+		}
+		it += len;
+	} while (type != -1); /* Attribute list ends with type -1. */
+	return 0;
 }
 
-/* Read and insert all the attributes of an 'attribute list' attribute
-   Return the number of remaining bytes in *plen
-*/
+/* Read and insert all the attributes of an 'attribute list' attribute.
+ * Return the number of remaining bytes in *plen. */
 static int parse_attributes(ntfs_inode *ino, ntfs_u8 *alist, int *plen)
 {
 	char *mft;
-	int mftno,l,error;
-	int last_mft=-1;
-	int len=*plen;
-	mft=ntfs_malloc(ino->vol->mft_recordsize);
-	if( !mft )
-		return ENOMEM;
-	while(len>8)
-	{
-		l=NTFS_GETU16(alist+4);
-		if(l>len)break;
-	        /* process an attribute description */
-		mftno=NTFS_GETU32(alist+0x10); /* BUG: this is u64 */
-		if(mftno!=last_mft){
-			last_mft=mftno;
-			/* FIXME: avoid loading record if it's 
-			   already processed */
-			error=ntfs_read_mft_record(ino->vol,mftno,mft);
-			if(error)return error;
-			ntfs_insert_mft_attributes(ino,mft,mftno);
+	int mftno, l, error;
+	int last_mft = -1;
+	int len = *plen;
+	
+	mft = ntfs_malloc(ino->vol->mft_recordsize);
+	if (!mft)
+		return -ENOMEM;
+	while (len > 8)	{
+		l = NTFS_GETU16(alist + 4);
+		if (l > len)
+			break;
+	        /* Process an attribute description. */
+		mftno = NTFS_GETU32(alist + 0x10); 
+			/* FIXME: The mft reference (alist + 0x10) is __u64.
+			* - Not a problem unless we encounter a huge partition.
+			* - Should be consistency checking the sequence numbers
+			*   though! This should maybe happen in 
+			*   ntfs_read_mft_record() itself and a hotfix could
+			*   then occur there or the user notified to run
+			*   ntfsck. (AIA) */
+		if (mftno != last_mft){
+			last_mft = mftno;
+			/* FIXME: Avoid loading record if it's already
+			 * processed. */
+			error = ntfs_read_mft_record(ino->vol, mftno, mft);
+			if (error)
+				return error;
+			error = ntfs_insert_mft_attributes(ino, mft, mftno);
+			if (error)
+				return error;
 		}
-		len-=l;
-		alist+=l;
+		len -= l;
+		alist += l;
 	}
 	ntfs_free(mft);
-	*plen=len;
+	*plen = len;
 	return 0;
 }
 
@@ -238,167 +252,176 @@
 {
 	ntfs_attribute *alist;
 	int datasize;
-	int offset,len,delta;
+	int offset, len, delta;
 	char *buf;
-	ntfs_volume *vol=ino->vol;
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 1\n",ino->i_number);
-	ntfs_insert_mft_attributes(ino,ino->attr,ino->i_number);
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 2\n",ino->i_number);
-	alist=ntfs_find_attr(ino,vol->at_attribute_list,0);
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 3\n",ino->i_number);
-	if(!alist)
+	ntfs_volume *vol = ino->vol;
+	
+	ntfs_debug(DEBUG_FILE2, "load_attributes %x 1\n", ino->i_number);
+	if (ntfs_insert_mft_attributes(ino, ino->attr, ino->i_number))
 		return;
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 4\n",ino->i_number);
-	datasize=alist->size;
-	if(alist->resident)
-	{
-		parse_attributes(ino,alist->d.data,&datasize);
+	ntfs_debug(DEBUG_FILE2, "load_attributes %x 2\n", ino->i_number);
+	alist = ntfs_find_attr(ino, vol->at_attribute_list, 0);
+	ntfs_debug(DEBUG_FILE2, "load_attributes %x 3\n", ino->i_number);
+	if (!alist)
+		return;
+	ntfs_debug(DEBUG_FILE2, "load_attributes %x 4\n", ino->i_number);
+	datasize = alist->size;
+	if (alist->resident) {
+		parse_attributes(ino, alist->d.data, &datasize);
 		return;
 	}
-	buf=ntfs_malloc(1024);
-	if( !buf )
+	buf = ntfs_malloc(1024);
+	if (!buf)    /* FIXME: Should be passing error code to caller. (AIA) */
 		return;
-	delta=0;
-	for(offset=0;datasize;datasize-=len,offset+=len)
-	{
+	delta = 0;
+	for (offset = 0; datasize; datasize -= len, offset += len) {
 		ntfs_io io;
-		io.fn_put=ntfs_put;
-		io.fn_get=0;
-		io.param=buf+delta;
-		io.size=len=min(datasize,1024-delta);
-		if(ntfs_read_attr(ino,vol->at_attribute_list,0,offset,&io)){
+		
+		io.fn_put = ntfs_put;
+		io.fn_get = 0;
+		io.param = buf + delta;
+		io.size = len = min(datasize, 1024 - delta);
+		if (ntfs_read_attr(ino, vol->at_attribute_list, 0, offset,
+				   &io))
 			ntfs_error("error in load_attributes\n");
-		}
-		delta+=len;
-		parse_attributes(ino,buf,&delta);
-		if(delta)
-			/* move remaining bytes to buffer start */
-			ntfs_memmove(buf,buf+len-delta,delta);
+		delta += len;
+		parse_attributes(ino, buf, &delta);
+		if (delta)
+			/* Move remaining bytes to buffer start. */
+			ntfs_memmove(buf, buf + len - delta, delta);
 	}
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 5\n",ino->i_number);
+	ntfs_debug(DEBUG_FILE2, "load_attributes %x 5\n", ino->i_number);
 	ntfs_free(buf);
 }
 	
-int ntfs_init_inode(ntfs_inode *ino,ntfs_volume *vol,int inum)
+int ntfs_init_inode(ntfs_inode *ino, ntfs_volume *vol, int inum)
 {
 	char *buf;
 	int error;
 
-	ntfs_debug(DEBUG_FILE1, "Initializing inode %x\n",inum);
-	if(!vol)
+	ntfs_debug(DEBUG_FILE1, "Initializing inode %x\n", inum);
+	if (!vol)
 		ntfs_error("NO VOLUME!\n");
-	ino->i_number=inum;
-	ino->vol=vol;
-	ino->attr=buf=ntfs_malloc(vol->mft_recordsize);
-	if( !buf )
-		return ENOMEM;
-	error=ntfs_read_mft_record(vol,inum,ino->attr);
-	if(error){
-		ntfs_debug(DEBUG_OTHER, "init inode: %x failed\n",inum);
+	ino->i_number = inum;
+	ino->vol = vol;
+	ino->attr = buf = ntfs_malloc(vol->mft_recordsize);
+	if (!buf)
+		return -ENOMEM;
+	error = ntfs_read_mft_record(vol, inum, ino->attr);
+	if (error) {
+		ntfs_debug(DEBUG_OTHER, "Init inode: %x failed\n", inum);
 		return error;
 	}
-	ntfs_debug(DEBUG_FILE2, "Init: got mft %x\n",inum);
-	ino->sequence_number=NTFS_GETU16(buf+0x10);
-	ino->attr_count=0;
-	ino->record_count=0;
-	ino->records=0;
-	ino->attrs=0;
+	ntfs_debug(DEBUG_FILE2, "Init inode: got mft %x\n", inum);
+	ino->sequence_number = NTFS_GETU16(buf + 0x10);
+	ino->attr_count = 0;
+	ino->record_count = 0;
+	ino->records = 0;
+	ino->attrs = 0;
 	ntfs_load_attributes(ino);
-	ntfs_debug(DEBUG_FILE2, "Init: done %x\n",inum);
+	ntfs_debug(DEBUG_FILE2, "Init inode: done %x\n", inum);
 	return 0;
 }
 
 void ntfs_clear_inode(ntfs_inode *ino)
 {
 	int i;
-	if(!ino->attr){
+	if (!ino->attr) {
 		ntfs_error("ntfs_clear_inode: double free\n");
 		return;
 	}
 	ntfs_free(ino->attr);
-	ino->attr=0;
+	ino->attr = 0;
 	ntfs_free(ino->records);
-	ino->records=0;
-	for(i=0;i<ino->attr_count;i++)
-	{
-		if(ino->attrs[i].name)
+	ino->records = 0;
+	for (i = 0; i < ino->attr_count; i++) {
+		if (ino->attrs[i].name)
 			ntfs_free(ino->attrs[i].name);
-		if(ino->attrs[i].resident)
-		{
-			if(ino->attrs[i].d.data)
+		if (ino->attrs[i].resident) {
+			if (ino->attrs[i].d.data)
 				ntfs_free(ino->attrs[i].d.data);
-		}else{
-			if(ino->attrs[i].d.r.runlist)
+		} else {
+			if (ino->attrs[i].d.r.runlist)
 				ntfs_free(ino->attrs[i].d.r.runlist);
 		}
 	}
 	ntfs_free(ino->attrs);
-	ino->attrs=0;
+	ino->attrs = 0;
 }
 
-/* Check and fixup a MFT record */
-int ntfs_check_mft_record(ntfs_volume *vol,char *record)
+/* Check and fixup a MFT record. */
+int ntfs_check_mft_record(ntfs_volume *vol, char *record)
 {
 	return ntfs_fixup_record(vol, record, "FILE", vol->mft_recordsize);
 }
 
 /* Return (in result) the value indicating the next available attribute 
-   chunk number. Works for inodes w/o extension records only */
+ * chunk number. Works for inodes w/o extension records only. */
 int ntfs_allocate_attr_number(ntfs_inode *ino, int *result)
 {
-	if(ino->record_count!=1)
-		return EOPNOTSUPP;
-	*result=NTFS_GETU16(ino->attr+0x28);
-	NTFS_PUTU16(ino->attr+0x28, (*result)+1);
+	if (ino->record_count != 1)
+		return -EOPNOTSUPP;
+	*result = NTFS_GETU16(ino->attr + 0x28);
+	NTFS_PUTU16(ino->attr + 0x28, (*result) + 1);
 	return 0;
 }
 
-/* find the location of an attribute in the inode. A name of NULL indicates
-   unnamed attributes. Return pointer to attribute or NULL if not found */
-char *
-ntfs_get_attr(ntfs_inode *ino,int attr,char *name)
+/* Find the location of an attribute in the inode. A name of NULL indicates
+ * unnamed attributes. Return pointer to attribute or NULL if not found. */
+char *ntfs_get_attr(ntfs_inode *ino, int attr, char *name)
 {
-	/* location of first attribute */
-	char *it= ino->attr + NTFS_GETU16(ino->attr + 0x14);
+	/* Location of first attribute. */
+	char *it = ino->attr + NTFS_GETU16(ino->attr + 0x14);
 	int type;
 	int len;
-	/* Only check for magic DWORD here, fixup should have happened before */
-	if(!IS_MFT_RECORD(ino->attr))return 0;
-	do{
-		type=NTFS_GETU32(it);
-		len=NTFS_GETU16(it+4);
+	
+	/* Only check for magic DWORD here, fixup should have happened before.*/
+	if (!IS_MFT_RECORD(ino->attr))
+		return 0;
+	do {
+		type = NTFS_GETU32(it);
+		len = NTFS_GETU16(it + 4);
 		/* We found the attribute type. Is the name correct, too? */
-		if(type==attr)
-		{
-			int namelen=NTFS_GETU8(it+9);
-			char *name_it;
-			/* match given name and attribute name if present,
-			   make sure attribute name is Unicode */
-			for(name_it=it+NTFS_GETU16(it+10);namelen;
-			    name++,name_it+=2,namelen--)
-				if(*name_it!=*name || name_it[1])break;
-			if(!namelen)break;
-		}
-		it+=len;
-	}while(type!=-1); /* attribute list end with type -1 */
-	if(type==-1)return 0;
+		if (type == attr) {
+			int namelen = NTFS_GETU8(it + 9);
+			char *name_it, *n = name;
+			/* Match given name and attribute name if present.
+			   Make sure attribute name is Unicode. */
+			if (!name) {
+				goto check_namelen;
+			} else if (namelen) {
+				for (name_it = it + NTFS_GETU16(it + 10);
+				     namelen; n++, name_it += 2, namelen--)
+					if (*name_it != *n || name_it[1])
+						break;
+check_namelen:
+				if (!namelen)
+					break;
+			}
+		}
+		it += len;
+	} while (type != -1); /* List of attributes ends with type -1. */
+	if (type == -1)
+		return 0;
 	return it;
 }
 
-int 
-ntfs_get_attr_size(ntfs_inode*ino,int type,char*name)
+int ntfs_get_attr_size(ntfs_inode *ino, int type, char *name)
 {
-	ntfs_attribute *attr=ntfs_find_attr(ino,type,name);
-	if(!attr)return 0;
-	return attr->size;
+	ntfs_attribute *attr = ntfs_find_attr(ino, type, name);
+	if (!attr)
+		return 0;
+	return
+		attr->size;
 }
 	
-int 
-ntfs_attr_is_resident(ntfs_inode*ino,int type,char*name)
+int ntfs_attr_is_resident(ntfs_inode *ino, int type, char *name)
 {
-	ntfs_attribute *attr=ntfs_find_attr(ino,type,name);
-	if(!attr)return 0;
-	return attr->resident;
+	ntfs_attribute *attr = ntfs_find_attr(ino, type, name);
+	if (!attr)
+		return 0;
+	return
+		attr->resident;
 }
 	
 /*
@@ -413,489 +436,520 @@
  * This function decodes a run. Length is an output parameter, data and cluster
  * are in/out parameters.
  */
-int ntfs_decompress_run(unsigned char **data, int *length, ntfs_cluster_t *cluster,
-	int *ctype)
+int ntfs_decompress_run(unsigned char **data, int *length, 
+			ntfs_cluster_t *cluster, int *ctype)
 {
-	unsigned char type=*(*data)++;
-	*ctype=0;
-	switch(type & 0xF)
-	{
-	case 1: *length=NTFS_GETU8(*data);break;
-	case 2: *length=NTFS_GETU16(*data);break;
-	case 3: *length=NTFS_GETU24(*data);break;
-        case 4: *length=NTFS_GETU32(*data);break;
-        	/* Note: cases 5-8 are probably pointless to code,
-        	   since how many runs > 4GB of length are there?
-        	   at the most, cases 5 and 6 are probably necessary,
-        	   and would also require making length 64-bit
-        	   throughout */
+	unsigned char type = *(*data)++;
+	*ctype = 0;
+	switch (type & 0xF) {
+	case 1: 
+		*length = NTFS_GETS8(*data);
+		break;
+	case 2: 
+		*length = NTFS_GETS16(*data);
+		break;
+	case 3: 
+		*length = NTFS_GETS24(*data);
+		break;
+        case 4: 
+		*length = NTFS_GETS32(*data);
+		break;
+        	/* Note: cases 5-8 are probably pointless to code, since how
+		 * many runs > 4GB of length are there? At the most, cases 5
+		 * and 6 are probably necessary, and would also require making
+		 * length 64-bit throughout. */
 	default:
-		ntfs_error("Can't decode run type field %x\n",type);
+		ntfs_error("Can't decode run type field %x\n", type);
 		return -1;
 	}
-	*data+=(type & 0xF);
-
-	switch(type & 0xF0)
+	if (*length < 0)
 	{
-	case 0:	   *ctype=2; break;
-	case 0x10: *cluster += NTFS_GETS8(*data);break;
-	case 0x20: *cluster += NTFS_GETS16(*data);break;
-	case 0x30: *cluster += NTFS_GETS24(*data);break;
-	case 0x40: *cluster += NTFS_GETS32(*data);break;
-#if 0 /* Keep for future, in case ntfs_cluster_t ever becomes 64bit */
-	case 0x50: *cluster += NTFS_GETS40(*data);break;
-	case 0x60: *cluster += NTFS_GETS48(*data);break;
-	case 0x70: *cluster += NTFS_GETS56(*data);break;
-	case 0x80: *cluster += NTFS_GETS64(*data);break;	
+		ntfs_error("Negative run length decoded\n");
+		return -1;
+	}
+	*data += (type & 0xF);
+	switch (type & 0xF0) {
+	case 0:
+		*ctype = 2;
+		break;
+	case 0x10:
+		*cluster += NTFS_GETS8(*data);
+		break;
+	case 0x20:
+		*cluster += NTFS_GETS16(*data);
+		break;
+	case 0x30:
+		*cluster += NTFS_GETS24(*data);
+		break;
+	case 0x40:
+		*cluster += NTFS_GETS32(*data);
+		break;
+#if 0 /* Keep for future, in case ntfs_cluster_t ever becomes 64bit. */
+	case 0x50: 
+		*cluster += NTFS_GETS40(*data);
+		break;
+	case 0x60: 
+		*cluster += NTFS_GETS48(*data);
+		break;
+	case 0x70: 
+		*cluster += NTFS_GETS56(*data);
+		break;
+	case 0x80: 
+		*cluster += NTFS_GETS64(*data);
+		break;
 #endif
 	default:
-		ntfs_error("Can't decode run type field %x\n",type);
+		ntfs_error("Can't decode run type field %x\n", type);
 		return -1;
 	}
-	*data+=(type >> 4);
+	*data += (type >> 4);
 	return 0;
 }
 
-/* Reads l bytes of the attribute (attr,name) of ino starting at offset
-   on vol into buf. Returns the number of bytes read in the ntfs_io struct.
-   Returns 0 on success, errno on failure */
+/*
+ * FIXME: ntfs_readwrite_attr() has the effect of writing @dest to @offset of
+ * the attribute value of the attribute @attr in the in memory inode @ino.
+ * If the attribute value of @attr is non-resident the value's contents at
+ * @offset are actually written to disk (from @dest). The on disk mft record
+ * describing the non-resident attribute value is not updated!
+ * If the attribute value is resident then the value is written only in
+ * memory. The on disk mft record containing the value is not written to disk.
+ * A possible fix would be to call ntfs_update_inode() before returning. (AIA)
+ */
+/* Reads l bytes of the attribute (attr, name) of ino starting at offset on
+ * vol into buf. Returns the number of bytes read in the ntfs_io struct.
+ * Returns 0 on success, errno on failure */
 int ntfs_readwrite_attr(ntfs_inode *ino, ntfs_attribute *attr, int offset,
-	ntfs_io *dest)
+			ntfs_io *dest)
 {
 	int rnum;
-	ntfs_cluster_t cluster,s_cluster,vcn,len;
-	int l,chunk,copied;
+	ntfs_cluster_t cluster, s_cluster, vcn, len;
+	int l, chunk, copied;
 	int s_vcn;
 	int clustersize;
 	int error;
 
-	clustersize=ino->vol->clustersize;
-	l=dest->size;
-	if(l==0)
+	clustersize = ino->vol->clustersize;
+	l = dest->size;
+	if (l == 0)
 		return 0;
-	if(dest->do_read)
-	{
-		/* if read _starts_ beyond end of stream, return nothing */
-		if(offset>=attr->size){
-			dest->size=0;
+	if (dest->do_read) {
+		/* If read _starts_ beyond end of stream, return nothing. */
+		if (offset >= attr->size) {
+			dest->size = 0;
 			return 0;
 		}
-
-		/* if read _extends_ beyond end of stream, return as much
-			initialised data as we have */
-		if(offset+l>=attr->size) 
-			l=dest->size=attr->size-offset;
-
-	}else {
-		/* fixed by CSA: if writing beyond end, extend attribute */
-
-		/* if write extends beyond _allocated_ size, extend attrib */
-		if (offset+l>attr->allocated) {
-			error=ntfs_resize_attr(ino,attr,offset+l);
-			if(error)
+		/* If read _extends_ beyond end of stream, return as much
+		 * initialised data as we have. */
+		if (offset + l >= attr->size)
+			l = dest->size = attr->size - offset;
+	} else {
+		/* Fixed by CSA: If writing beyond end, extend attribute. */
+		/* If write extends beyond _allocated_ size, extend attrib. */
+		if (offset + l > attr->allocated) {
+			error = ntfs_resize_attr(ino, attr, offset + l);
+			if (error)
 				return error;
 		}
-
-		/* the amount of initialised data has increased; update */
-		/* FIXME: shouldn't we zero-out the section between the old
-			initialised length and the write start? */
-		if (offset+l > attr->initialized) {
-			attr->initialized = offset+l;
-			attr->size = offset+l;
+		/* The amount of initialised data has increased: update. */
+		/* FIXME: Shouldn't we zero-out the section between the old
+		 * 	  initialised length and the write start? */
+		if (offset + l > attr->initialized) {
+			attr->initialized = offset + l;
+			attr->size = offset + l;
 		}
 	}
-	if(attr->resident)
-	{
-		if(dest->do_read)
-			dest->fn_put(dest,(ntfs_u8*)attr->d.data+offset,l);
+	if (attr->resident) {
+		if (dest->do_read)
+			dest->fn_put(dest, (ntfs_u8*)attr->d.data + offset, l);
 		else
-			dest->fn_get((ntfs_u8*)attr->d.data+offset,dest,l);
-		dest->size=l;
+			dest->fn_get((ntfs_u8*)attr->d.data + offset, dest, l);
+		dest->size = l;
 		return 0;
 	}
-	/* read uninitialized data */
-	if(offset>=attr->initialized && dest->do_read)
-		return ntfs_read_zero(dest,l);
-	if(offset+l>attr->initialized && dest->do_read)
-	{
-		dest->size = chunk = offset+l - attr->initialized;
-		error = ntfs_readwrite_attr(ino,attr,offset,dest);
-		if(error)
+	/* Read uninitialized data. */
+	if (offset >= attr->initialized && dest->do_read)
+		return ntfs_read_zero(dest, l);
+	if (offset + l > attr->initialized && dest->do_read) {
+		dest->size = chunk = offset + l - attr->initialized;
+		error = ntfs_readwrite_attr(ino, attr, offset, dest);
+		if (error)
 			return error;		
-		return ntfs_read_zero(dest,l-chunk);
+		return ntfs_read_zero(dest, l - chunk);
 	}
-	if(attr->compressed){
-		if(dest->do_read)
-			return ntfs_read_compressed(ino,attr,offset,dest);
+	if (attr->compressed) {
+		if (dest->do_read)
+			return ntfs_read_compressed(ino, attr, offset, dest);
 		else
-			return ntfs_write_compressed(ino,attr,offset,dest);
+			return ntfs_write_compressed(ino, attr, offset, dest);
 	}
-	vcn=0;
-	s_vcn = offset/clustersize;
-	for(rnum=0;rnum<attr->d.r.len && 
-		    vcn+attr->d.r.runlist[rnum].len<=s_vcn;rnum++)
-		vcn+=attr->d.r.runlist[rnum].len;
-	if(rnum==attr->d.r.len)
-		/*FIXME: should extend runlist */
-		return EOPNOTSUPP;
-	
-	copied=0;
-	while(l)
-	{
-		s_vcn = offset/clustersize;
-		cluster=attr->d.r.runlist[rnum].cluster;
-		len=attr->d.r.runlist[rnum].len;
-
-		s_cluster = cluster+s_vcn-vcn;
-			
-		chunk=min((vcn+len)*clustersize-offset,l);
-		dest->size=chunk;
-		error=ntfs_getput_clusters(ino->vol,s_cluster,
-					   offset-s_vcn*clustersize,dest);
-		if(error)
-		{
-			ntfs_error("Read error\n");
-			dest->size=copied;
+	vcn = 0;
+	s_vcn = offset / clustersize;
+	for (rnum = 0; rnum < attr->d.r.len && 
+		       vcn + attr->d.r.runlist[rnum].len <= s_vcn; rnum++)
+		vcn += attr->d.r.runlist[rnum].len;
+	if (rnum == attr->d.r.len)
+		/*FIXME: Should extend runlist. */
+		return -EOPNOTSUPP;
+	copied = 0;
+	while (l) {
+		s_vcn = offset / clustersize;
+		cluster = attr->d.r.runlist[rnum].cluster;
+		len = attr->d.r.runlist[rnum].len;
+		s_cluster = cluster + s_vcn - vcn;
+		chunk = min((vcn + len) * clustersize - offset, l);
+		dest->size = chunk;
+		error = ntfs_getput_clusters(ino->vol, s_cluster, 
+					   offset - s_vcn * clustersize, dest);
+		if (error) {
+			ntfs_error("Read/write error\n");
+			dest->size = copied;
 			return error;
 		}
-		l-=chunk;
-		copied+=chunk;
-		offset+=chunk;
-		if(l && offset>=((vcn+len)*clustersize))
-		{
+		l -= chunk;
+		copied += chunk;
+		offset += chunk;
+		if (l && offset >= ((vcn + len) * clustersize))	{
 			rnum++;
-			vcn+=len;
+			vcn += len;
 			cluster = attr->d.r.runlist[rnum].cluster;
 			len = attr->d.r.runlist[rnum].len;
 		}
 	}
-	dest->size=copied;
+	dest->size = copied;
 	return 0;
 }
 
 int ntfs_read_attr(ntfs_inode *ino, int type, char *name, int offset,
-        ntfs_io *buf)
+		   ntfs_io *buf)
 {
 	ntfs_attribute *attr;
-	buf->do_read=1;
-	attr=ntfs_find_attr(ino,type,name);
-	if(!attr)
-		return EINVAL;
-	return ntfs_readwrite_attr(ino,attr,offset,buf);
+
+	buf->do_read = 1;
+	attr = ntfs_find_attr(ino, type, name);
+	if (!attr)
+		return -EINVAL;
+	return ntfs_readwrite_attr(ino, attr, offset, buf);
 }
 
 int ntfs_write_attr(ntfs_inode *ino, int type, char *name, int offset,
-		ntfs_io *buf)
+		    ntfs_io *buf)
 {
 	ntfs_attribute *attr;
-	buf->do_read=0;
-	attr=ntfs_find_attr(ino,type,name);
-	if(!attr)
-		return EINVAL;
-	return ntfs_readwrite_attr(ino,attr,offset,buf);
+	
+	buf->do_read = 0;
+	attr = ntfs_find_attr(ino, type, name);
+	if (!attr)
+		return -EINVAL;
+	return ntfs_readwrite_attr(ino, attr, offset, buf);
 }
 
-int ntfs_vcn_to_lcn(ntfs_inode *ino,int vcn)
+int ntfs_vcn_to_lcn(ntfs_inode *ino, int vcn)
 {
 	int rnum;
 	ntfs_attribute *data;
-	data=ntfs_find_attr(ino,ino->vol->at_data,0);
-	/* It's hard to give an error code */
-	if(!data)return -1;
-	if(data->resident)return -1;
-	if(data->compressed)return -1;
-	if(data->size <= vcn*ino->vol->clustersize)return -1;
-
-
+	
+	data = ntfs_find_attr(ino, ino->vol->at_data, 0);
+	/* It's hard to give an error code. */
+	if (!data || data->resident || data->compressed)
+		return -1;
+	if (data->size <= vcn*ino->vol->clustersize)
+		return -1;
 	/* For Linux, block number 0 represents a hole.
-	   Hopefully, nobody will attempt to bmap $Boot. */
-	if(data->initialized <= vcn*ino->vol->clustersize)
+	 * Hopefully, nobody will attempt to bmap $Boot. */
+	if (data->initialized <= vcn * ino->vol->clustersize)
 		return 0;
-
-	for(rnum=0;rnum<data->d.r.len && 
-		    vcn>=data->d.r.runlist[rnum].len;rnum++)
-		vcn-=data->d.r.runlist[rnum].len;
-	
-	return data->d.r.runlist[rnum].cluster+vcn;
+	for (rnum = 0; rnum < data->d.r.len &&
+		       vcn >= data->d.r.runlist[rnum].len; rnum++)
+		vcn -= data->d.r.runlist[rnum].len;
+	return data->d.r.runlist[rnum].cluster + vcn;
 }
 
-static int 
-allocate_store(ntfs_volume *vol,ntfs_disk_inode *store,int count)
+static int allocate_store(ntfs_volume *vol, ntfs_disk_inode *store, int count)
 {
 	int i;
-	if(store->count>count)
+	
+	if (store->count > count)
 		return 0;
-	if(store->size<count){
-		ntfs_mft_record* n=ntfs_malloc((count+4)*sizeof(ntfs_mft_record));
-		if(!n)
-			return ENOMEM;
-		if(store->size){
-			for(i=0;i<store->size;i++)
-				n[i]=store->records[i];
+	if (store->size < count) {
+		ntfs_mft_record *n = ntfs_malloc((count + 4) * 
+						 sizeof(ntfs_mft_record));
+		if (!n)
+			return -ENOMEM;
+		if (store->size) {
+			for (i = 0; i < store->size; i++)
+				n[i] = store->records[i];
 			ntfs_free(store->records);
 		}
-		store->size=count+4;
-		store->records=n;
+		store->size = count + 4;
+		store->records = n;
 	}
-	for(i=store->count;i<count;i++){
-		store->records[i].record=ntfs_malloc(vol->mft_recordsize);
-		if(!store->records[i].record)
-			return ENOMEM;
+	for (i = store->count; i < count; i++) {
+		store->records[i].record = ntfs_malloc(vol->mft_recordsize);
+		if (!store->records[i].record)
+			return -ENOMEM;
 		store->count++;
 	}
 	return 0;
 }
 
-static void 
-deallocate_store(ntfs_disk_inode* store)
+static void deallocate_store(ntfs_disk_inode* store)
 {
 	int i;
-	for(i=0;i<store->count;i++)
+	
+	for (i = 0; i < store->count; i++)
 		ntfs_free(store->records[i].record);
 	ntfs_free(store->records);
-	store->count=store->size=0;
-	store->records=0;
+	store->count = store->size = 0;
+	store->records = 0;
 }
 
-int 
-layout_runs(ntfs_attribute *attr,char* rec,int* offs,int size)
+/**
+ * layout_runs - compress runlist into mapping pairs array
+ * @attr:	attribute containing the runlist to compress
+ * @rec:	destination buffer to hold the mapping pairs array
+ * @offs:	current position in @rec (in/out variable)
+ * @size:	size of the buffer @rec
+ *
+ * layout_runs walks the runlist in @attr, compresses it and writes it out the
+ * resulting mapping pairs array into @rec (up to a maximum of @size bytes are
+ * written). On entry @offs is the offset in @rec at which to begin writting the
+ * mapping pairs array. On exit, it contains the offset in @rec of the first
+ * byte after the end of the mapping pairs array.
+ */
+static int layout_runs(ntfs_attribute *attr, char* rec, int* offs, int size)
 {
-	int i,len,offset,coffs;
-	ntfs_cluster_t cluster,rclus;
-	ntfs_runlist *rl=attr->d.r.runlist;
-	cluster=0;
-	offset=*offs;
-	for(i=0;i<attr->d.r.len;i++){
-		rclus=rl[i].cluster-cluster;
-		len=rl[i].len;
-		rec[offset]=0;
-		if(offset+8>size)
-			return E2BIG; /* it might still fit, but this simplifies testing */
-		if(len<0x100){
-			NTFS_PUTU8(rec+offset+1,len);
-			coffs=1;
-		}else if(len<0x10000){
-			NTFS_PUTU16(rec+offset+1,len);
-			coffs=2;
-		}else if(len<0x1000000){
-			NTFS_PUTU24(rec+offset+1,len);
-			coffs=3;
-		}else{
-			NTFS_PUTU32(rec+offset+1,len);
-			coffs=4;
-		}
-    
-		*(rec+offset)|=coffs++;
-
-		if(rl[i].cluster==MAX_CLUSTER_T) /*compressed run*/
-			/*nothing*/;
-		else if(rclus>-0x80 && rclus<0x7F){
-			*(rec+offset)|=0x10;
-			NTFS_PUTS8(rec+offset+coffs,rclus);
-			coffs+=1;
-		}else if(rclus>-0x8000 && rclus<0x7FFF){
-			*(rec+offset)|=0x20;
-			NTFS_PUTS16(rec+offset+coffs,rclus);
-			coffs+=2;
-		}else if(rclus>-0x800000 && rclus<0x7FFFFF){
-			*(rec+offset)|=0x30;
-			NTFS_PUTS24(rec+offset+coffs,rclus);
-			coffs+=3;
-		}else
-#if 0 /* In case ntfs_cluster_t ever becomes 64bit */
-	       	if (rclus>-0x80000000LL && rclus<0x7FFFFFFF)
+	int i, len, offset, coffs;
+	ntfs_cluster_t cluster, rclus;
+	ntfs_runlist *rl = attr->d.r.runlist;
+	cluster = 0;
+	offset = *offs;
+	for (i = 0; i < attr->d.r.len; i++) {
+		rclus = rl[i].cluster - cluster;
+		len = rl[i].len;
+		rec[offset] = 0;
+ 		if (offset + 9 > size)
+			return -E2BIG; /* It might still fit, but this
+					* simplifies testing. */
+		/* Run length is stored as signed number. */
+		if (len <= 0x7F) {
+			NTFS_PUTU8(rec + offset + 1, len);
+			coffs = 1;
+ 		} else if (len <= 0x7FFF) {
+			NTFS_PUTU16(rec + offset + 1, len);
+			coffs = 2;
+ 		} else if (len <= 0x7FFFFF) {
+			NTFS_PUTU24(rec + offset + 1, len);
+			coffs = 3;
+		} else {
+			NTFS_PUTU32(rec + offset + 1, len);
+			coffs = 4;
+		}
+    		*(rec + offset) |= coffs++;
+		if (rl[i].cluster == MAX_CLUSTER_T) /* Compressed run. */
+			/* Nothing */;
+		else if (rclus >= -0x80 && rclus <= 0x7F) {
+			*(rec + offset) |= 0x10;
+			NTFS_PUTS8(rec + offset + coffs, rclus);
+			coffs += 1;
+		} else if(rclus >= -0x8000 && rclus <= 0x7FFF) {
+			*(rec + offset) |= 0x20;
+			NTFS_PUTS16(rec + offset + coffs, rclus);
+			coffs += 2;
+		} else if(rclus >= -0x800000 && rclus <= 0x7FFFFF) {
+			*(rec + offset) |= 0x30;
+			NTFS_PUTS24(rec + offset + coffs, rclus);
+			coffs += 3;
+		} else
+#if 0 /* In case ntfs_cluster_t ever becomes 64bit. */
+	       	if (rclus >= -0x80000000LL && rclus <= 0x7FFFFFFF)
 #endif
 		{
-			*(rec+offset)|=0x40;
-			NTFS_PUTS32(rec+offset+coffs,rclus);
-			coffs+=4;
+			*(rec + offset) |= 0x40;
+			NTFS_PUTS32(rec + offset + coffs, rclus);
+			coffs += 4;
 		}
 #if 0 /* For 64-bit ntfs_cluster_t */
-		else if (rclus>-0x8000000000 && rclus<0x7FFFFFFFFF){
-			*(rec+offset)|=0x50;
-			NTFS_PUTS40(rec+offset+coffs,rclus);
-			coffs+=5;
-		}else if (rclus>-0x800000000000 && rclus<0x7FFFFFFFFFFF){
-			*(rec+offset)|=0x60;
-			NTFS_PUTS48(rec+offset+coffs,rclus);
-			coffs+=6;
-		}else if (rclus>-0x80000000000000 && rclus<0x7FFFFFFFFFFFFF){
-			*(rec+offset)|=0x70;
-			NTFS_PUTS56(rec+offset+coffs,rclus);
-			coffs+=7;
-		}else{
-			*(rec+offset)|=0x80;
-			NTFS_PUTS64(rec+offset+coffs,rclus);
-			coffs+=8;
+		else if (rclus >= -0x8000000000 && rclus <= 0x7FFFFFFFFF) {
+			*(rec + offset) |= 0x50;
+			NTFS_PUTS40(rec + offset + coffs, rclus);
+			coffs += 5;
+		} else if (rclus >= -0x800000000000 && 
+						rclus <= 0x7FFFFFFFFFFF) {
+			*(rec + offset) |= 0x60;
+			NTFS_PUTS48(rec + offset + coffs, rclus);
+			coffs += 6;
+		} else if (rclus >= -0x80000000000000 && 
+						rclus <= 0x7FFFFFFFFFFFFF) {
+			*(rec + offset) |= 0x70;
+			NTFS_PUTS56(rec + offset + coffs, rclus);
+			coffs += 7;
+		} else {
+			*(rec + offset) |= 0x80;
+			NTFS_PUTS64(rec + offset + coffs, rclus);
+			coffs += 8;
 		}
 #endif
-		offset+=coffs;
-		if(rl[i].cluster)
-			cluster=rl[i].cluster;
-	}
-	if(offset>=size)
-		return E2BIG;
-	/* terminating null */
-	*(rec+offset++)=0;
-	*offs=offset;
+		offset += coffs;
+		if (rl[i].cluster)
+			cluster = rl[i].cluster;
+	}
+	if (offset >= size)
+		return -E2BIG;
+	/* Terminating null. */
+	*(rec + offset++) = 0;
+	*offs = offset;
 	return 0;
 }
 
-static void 
-count_runs(ntfs_attribute *attr,char *buf)
+static void count_runs(ntfs_attribute *attr, char *buf)
 {
-	ntfs_u32 first,count,last,i;
-	first=0;
-	for(i=0,count=0;i<attr->d.r.len;i++)
-		count+=attr->d.r.runlist[i].len;
-	last=first+count-1;
-
-	NTFS_PUTU64(buf+0x10,first);
-	NTFS_PUTU64(buf+0x18,last);
+	ntfs_u32 first, count, last, i;
+	
+	first = 0;
+	for (i = 0, count = 0; i < attr->d.r.len; i++)
+		count += attr->d.r.runlist[i].len;
+	last = first + count - 1;
+	NTFS_PUTU64(buf + 0x10, first);
+	NTFS_PUTU64(buf + 0x18, last);
 } 
 
-static int
-layout_attr(ntfs_attribute* attr,char*buf, int size,int *psize)
+/**
+ * layout_attr - convert in memory attribute to on disk attribute record
+ * @attr:	in memory attribute to convert
+ * @buf:	destination buffer for on disk attribute record
+ * @size:	size of the destination buffer
+ * @psize:	size of converted on disk attribute record (out variable)
+ *
+ * layout_attr takes the attribute @attr and converts it into the appropriate
+ * on disk structure, writing it into @buf (up to @size bytes are written).
+ * On return, @psize contains the actual size of the on disk attribute written
+ * into @buf.
+ */
+static int layout_attr(ntfs_attribute* attr, char *buf, int size, int *psize)
 {
-	int asize,error;
-	if(size<10)return E2BIG;
-	NTFS_PUTU32(buf,attr->type);
-	/* fill in length later */
-	NTFS_PUTU8(buf+8,attr->resident ? 0:1);
-	NTFS_PUTU8(buf+9,attr->namelen);
-	/* fill in offset to name later */
-	NTFS_PUTU16(buf+0xA,0);
-	NTFS_PUTU16(buf+0xC,attr->compressed);
-	/* FIXME: assign attribute ID??? */
-	NTFS_PUTU16(buf+0xE,attr->attrno);
-	if(attr->resident){
-		if(size<attr->size+0x18+attr->namelen)return E2BIG;
-		asize=0x18;
-		NTFS_PUTU32(buf+0x10,attr->size);
-		NTFS_PUTU16(buf+0x16,attr->indexed);
-		if(attr->name){
-			ntfs_memcpy(buf+asize,attr->name,2*attr->namelen);
-			NTFS_PUTU16(buf+0xA,asize);
-			asize+=2*attr->namelen;
-			asize=(asize+7) & ~7;
-		}
-		NTFS_PUTU16(buf+0x14,asize);
-		ntfs_memcpy(buf+asize,attr->d.data,attr->size);
-		asize+=attr->size;
-	}else{
+	int asize, error;
+	if (size < 10)
+		return -E2BIG;
+	NTFS_PUTU32(buf, attr->type);
+	/* Fill in length later. */
+	NTFS_PUTU8(buf + 8, attr->resident ? 0 : 1);
+	NTFS_PUTU8(buf + 9, attr->namelen);
+	/* Fill in offset to name later. */
+	NTFS_PUTU16(buf + 0xA, 0);
+	NTFS_PUTU16(buf + 0xC, attr->compressed);
+	/* Assign attribute instance. */
+	NTFS_PUTU16(buf + 0xE, attr->attrno);
+	if (attr->resident) {
+		if (size < attr->size + 0x18 + attr->namelen)
+			return -E2BIG;
+		asize = 0x18;
+		NTFS_PUTU32(buf + 0x10, attr->size);
+		NTFS_PUTU16(buf + 0x16, attr->indexed);
+		if (attr->name) {
+			ntfs_memcpy(buf + asize, attr->name, 2 * attr->namelen);
+			NTFS_PUTU16(buf + 0xA, asize);
+			asize += 2 * attr->namelen;
+			asize = (asize + 7) & ~7;
+		}
+		NTFS_PUTU16(buf + 0x14, asize);
+		ntfs_memcpy(buf + asize, attr->d.data, attr->size);
+		asize += attr->size;
+	} else {
 		/* FIXME: fragments */
-		count_runs(attr,buf);
-		/* offset to data is added later */
-		NTFS_PUTU16(buf+0x22,attr->cengine);
-		NTFS_PUTU32(buf+0x24,0);
-		NTFS_PUTU64(buf+0x28,attr->allocated);
-		NTFS_PUTU64(buf+0x30,attr->size);
-		NTFS_PUTU64(buf+0x38,attr->initialized);
-		if(attr->compressed){
-			NTFS_PUTU64(buf+0x40,attr->compsize);
-			asize=0x48;
-		}else
-			asize=0x40;
-		if(attr->name){
-			NTFS_PUTU16(buf+0xA,asize);
-			ntfs_memcpy(buf+asize,attr->name,2*attr->namelen);
-			asize+=2*attr->namelen;
-			/* SRD: you whaaa?
-			asize=(asize+7) & ~7;*/
-		}
-		/* asize points at the beginning of the data */
-		NTFS_PUTU16(buf+0x20,asize);
-		error=layout_runs(attr,buf,&asize,size);
-		/* now asize pointes at the end of the data */
-		if(error)
+		count_runs(attr, buf);
+		/* Offset to data is added later. */
+		NTFS_PUTU16(buf + 0x22, attr->cengine);
+		NTFS_PUTU32(buf + 0x24, 0);
+		NTFS_PUTU64(buf + 0x28, attr->allocated);
+		NTFS_PUTU64(buf + 0x30, attr->size);
+		NTFS_PUTU64(buf + 0x38, attr->initialized);
+		if (attr->compressed) {
+			NTFS_PUTU64(buf + 0x40, attr->compsize);
+			asize = 0x48;
+		} else
+			asize = 0x40;
+		if (attr->name) {
+			NTFS_PUTU16(buf + 0xA, asize);
+			ntfs_memcpy(buf + asize, attr->name, 2 * attr->namelen);
+			asize += 2 * attr->namelen;
+			/* SRD: you whaaa? - AIA: Align to next 8 byte boundary
+			 * as required by NTFS design and implementation. */
+			asize = (asize + 7) & ~7;
+		}
+		/* asize points at the beginning of the data. */
+		NTFS_PUTU16(buf + 0x20, asize);
+		error = layout_runs(attr, buf, &asize, size);
+		/* Now asize points at the end of the data. */
+		if (error)
 			return error;
 	}
-	asize=(asize+7) & ~7;
-	NTFS_PUTU32(buf+4,asize);
-	*psize=asize;
+	asize = (asize + 7) & ~7;
+	NTFS_PUTU32(buf + 4, asize);
+	*psize = asize;
 	return 0;
 }
-		
-		
 
-/* Try to layout ino into store. Return 0 on success,
-   E2BIG if it does not fit, 
-   ENOMEM if memory allocation problem,
-   EOPNOTSUP if beyond our capabilities 
-*/
-int 
-layout_inode(ntfs_inode *ino,ntfs_disk_inode *store)
+/**
+ * layout_inode - convert an in memory inode into on disk mft record(s)
+ * @ino:	in memory inode to convert
+ * @store:	on disk inode, contain buffers for the on disk mft record(s)
+ *
+ * layout_inode takes the in memory inode @ino, converts it into a (sequence of)
+ * mft record(s) and writes them to the appropriate buffers in the @store.
+ *
+ * Return 0 on success,
+ * the required mft record count (>0) if the inode does not fit,
+ * -ENOMEM if memory allocation problem or
+ * -EOPNOTSUP if beyond our capabilities.
+ */
+int layout_inode(ntfs_inode *ino, ntfs_disk_inode *store)
 {
-	int offset,i;
+	int offset, i;
 	ntfs_attribute *attr;
 	unsigned char *rec;
-	int size,psize;
+	int size, psize;
 	int error;
 
-	if(ino->record_count>1)
-	{
+	if (ino->record_count > 1) {
 		ntfs_error("layout_inode: attribute lists not supported\n");
-		return EOPNOTSUPP;
+		return -EOPNOTSUPP;
 	}
-	error=allocate_store(ino->vol,store,1);
-	if(error)
+	error = allocate_store(ino->vol, store, 1);
+	if (error)
 		return error;
-	rec=store->records[0].record;
-	size=ino->vol->mft_recordsize;
-	store->records[0].recno=ino->records[0];
-	/* copy header */
-	offset=NTFS_GETU16(ino->attr+0x14);
-	ntfs_memcpy(rec,ino->attr,offset);
-	for(i=0;i<ino->attr_count;i++){
-		attr=ino->attrs+i;
-		error=layout_attr(attr,rec+offset,size-offset,&psize);
-		if(error)return error;
-		offset+=psize;
-#if 0
-		/* copy attribute header */
-		ntfs_memcpy(rec+offset,attr->header,
-			    min(sizeof(attr->header),size-offset)); /* consider overrun */
-		if(attr->namelen)
-			/* named attributes are added later */
-			return EOPNOTSUPP;
-		/* FIXME: assign attribute ID??? */
-		if(attr->resident){
-			asize=attr->size;
-			aoffset=NTFS_GETU16(rec+offset+0x14);
-			if(offset+aoffset+asize>size)
-				return E2BIG;
-			ntfs_memcpy(rec+offset+aoffset,attr->d.data,asize);
-			next=offset+aoffset+asize;
-		}else{
-			count_runs(attr,rec+offset);
-			aoffset=NTFS_GETU16(rec+offset+0x20);
-			next=offset+aoffset;
-			error=layout_runs(attr,rec,&next,size);
-			if(error)
-				return error;
-		}
-		/* SRD: umm..
-		next=(next+7) & ~7; */
-		/* is this setting the length? if so maybe we could get
-		   away with rounding up so long as we set the length first..
-		   ..except, is the length the only way to get to the next attr?
-		 */
-		NTFS_PUTU16(rec+offset+4,next-offset);
-		offset=next;
-#endif
+	rec = store->records[0].record;
+	size = ino->vol->mft_recordsize;
+	store->records[0].recno = ino->records[0];
+	/* Copy header. */
+	offset = NTFS_GETU16(ino->attr + 0x14);
+	ntfs_memcpy(rec, ino->attr, offset);
+	for (i = 0; i < ino->attr_count; i++) {
+		attr = ino->attrs + i;
+		error = layout_attr(attr, rec + offset, size - offset, &psize);
+		if (error)
+			return error;
+		offset += psize;
 	}
-	/* terminating attribute */
-	if(offset+8<size){
-		NTFS_PUTU32(rec+offset,0xFFFFFFFF);
-		offset+=4;
-		NTFS_PUTU32(rec+offset,0);
-		offset+=4;
-	}else
-		return E2BIG;
-	NTFS_PUTU32(rec+0x18,offset);
+	/* Terminating attribute. */
+	if (offset + 8 < size) {
+		NTFS_PUTU32(rec + offset, 0xFFFFFFFF);
+		offset += 4;
+		NTFS_PUTU32(rec + offset, 0);
+		offset += 4;
+	} else
+		return -E2BIG;
+	NTFS_PUTU32(rec + 0x18, offset);
 	return 0;
 }
-  
+
+/*
+ * FIXME: ntfs_update_inode() calls layout_inode() to create the mft record on
+ * disk structure corresponding to the inode @ino. After that, ntfs_write_attr()
+ * is called to write out the created mft record to disk.
+ * We shouldn't need to re-layout every single time we are updating an mft
+ * record. No wonder the ntfs driver is slow like hell. (AIA)
+ */
 int ntfs_update_inode(ntfs_inode *ino)
 {
 	int error;
@@ -903,218 +957,217 @@
 	ntfs_io io;
 	int i;
 
-	store.count=store.size=0;
-	store.records=0;
-	error=layout_inode(ino,&store);
-	if(error==E2BIG){
+	store.count = store.size = 0;
+	store.records = 0;
+	error = layout_inode(ino, &store);
+	if (error == -E2BIG) {
 		error = ntfs_split_indexroot(ino);
-		if(!error)
-			error = layout_inode(ino,&store);
+		if (!error)
+			error = layout_inode(ino, &store);
 	}
-	if(error == E2BIG){
+	if (error == -E2BIG) {
 		error = ntfs_attr_allnonresident(ino);
-		if(!error)
-			error = layout_inode(ino,&store);
+		if (!error)
+			error = layout_inode(ino, &store);
 	}
-	if(error == E2BIG){
-		/* should try:
-		   introduce extension records
-		   */
-		ntfs_error("cannot handle saving inode %x\n",ino->i_number);
+	if (error == -E2BIG) {
+		/* FIXME: should try: introduce extension records */
+		ntfs_error("cannot handle saving inode %x\n", ino->i_number);
 		deallocate_store(&store);
-		return EOPNOTSUPP;
+		return -EOPNOTSUPP;
 	}
-	if(error){
+	if (error) {
 		deallocate_store(&store);
 		return error;
 	}
-	io.fn_get=ntfs_get;
-	io.fn_put=0;
-	for(i=0;i<store.count;i++){
-		ntfs_insert_fixups(store.records[i].record,ino->vol->blocksize);
-		io.param=store.records[i].record;
-		io.size=ino->vol->mft_recordsize;
-		/* FIXME: is this the right way? */
-		error=ntfs_write_attr(
-			ino->vol->mft_ino,ino->vol->at_data,0,
-			store.records[i].recno*ino->vol->mft_recordsize,&io);
-		if(error || io.size!=ino->vol->mft_recordsize){
-			/* big trouble, partially written file */
-			ntfs_error("Please unmount: write error in inode %x\n",ino->i_number);
+	io.fn_get = ntfs_get;
+	io.fn_put = 0;
+	for (i = 0; i < store.count; i++) {
+		ntfs_insert_fixups(store.records[i].record,
+							  ino->vol->blocksize);
+		io.param = store.records[i].record;
+		io.size = ino->vol->mft_recordsize;
+		/* FIXME: Is this the right way? */
+		error = ntfs_write_attr(ino->vol->mft_ino, ino->vol->at_data,
+					0, store.records[i].recno * 
+					ino->vol->mft_recordsize, &io);
+		if (error || io.size != ino->vol->mft_recordsize) {
+			/* Big trouble, partially written file. */
+			ntfs_error("Please unmount: Write error in inode %x\n",
+				   ino->i_number);
 			deallocate_store(&store);
-			return error?error:EIO;
+			return error ? error : -EIO;
 		}
 	}
 	return 0;
 }	
 
-
 void ntfs_decompress(unsigned char *dest, unsigned char *src, ntfs_size_t l)
 {
-	int head,comp;
-	int copied=0;
+	int head, comp;
+	int copied = 0;
 	unsigned char *stop;
 	int bits;
-	int tag=0;
+	int tag = 0;
 	int clear_pos;
-	while(1)
-	{
+	
+	while (1) {
 		head = NTFS_GETU16(src) & 0xFFF;
-		/* high bit indicates that compression was performed */
+		/* High bit indicates that compression was performed. */
 		comp = NTFS_GETU16(src) & 0x8000;
 		src += 2;
-		stop = src+head;
+		stop = src + head;
 		bits = 0;
-		clear_pos=0;
-		if(head==0)
-			/* block is not used */
+		clear_pos = 0;
+		if (head == 0)
+			/* Block is not used. */
 			return;/* FIXME: copied */
-		if(!comp) /* uncompressible */
-		{
-			ntfs_memcpy(dest,src,0x1000);
-			dest+=0x1000;
-			copied+=0x1000;
-			src+=0x1000;
-			if(l==copied)
+		if (!comp) { /* uncompressible */
+			ntfs_memcpy(dest, src, 0x1000);
+			dest += 0x1000;
+			copied += 0x1000;
+			src += 0x1000;
+			if (l == copied)
 				return;
 			continue;
 		}
-		while(src<=stop)
-		{
-			if(clear_pos>4096)
-			{
+		while (src <= stop) {
+			if (clear_pos > 4096) {
 				ntfs_error("Error 1 in decompress\n");
 				return;
 			}
-			if(!bits){
-				tag=NTFS_GETU8(src);
-				bits=8;
+			if (!bits) {
+				tag = NTFS_GETU8(src);
+				bits = 8;
 				src++;
-				if(src>stop)
+				if (src > stop)
 					break;
 			}
-			if(tag & 1){
-				int i,len,delta,code,lmask,dshift;
+			if (tag & 1) {
+				int i, len, delta, code, lmask, dshift;
 				code = NTFS_GETU16(src);
-				src+=2;
-				if(!clear_pos)
-				{
+				src += 2;
+				if (!clear_pos) {
 					ntfs_error("Error 2 in decompress\n");
 					return;
 				}
-				for(i=clear_pos-1,lmask=0xFFF,dshift=12;i>=0x10;i>>=1)
-				{
+				for (i = clear_pos - 1, lmask = 0xFFF,
+				     dshift = 12; i >= 0x10; i >>= 1) {
 					lmask >>= 1;
 					dshift--;
 				}
 				delta = code >> dshift;
 				len = (code & lmask) + 3;
-				for(i=0; i<len; i++)
-				{
-					dest[clear_pos]=dest[clear_pos-delta-1];
+				for (i = 0; i < len; i++) {
+					dest[clear_pos] = dest[clear_pos - 
+								    delta - 1];
 					clear_pos++;
 					copied++;
-					if(copied==l)
+					if (copied==l)
 						return;
 				}
-			}else{
-				dest[clear_pos++]=NTFS_GETU8(src);
+			} else {
+				dest[clear_pos++] = NTFS_GETU8(src);
 				src++;
 				copied++;
-				if(copied==l)
+				if (copied==l)
 					return;
 			}
-			tag>>=1;
+			tag >>= 1;
 			bits--;
 		}
-		dest+=clear_pos;
+		dest += clear_pos;
 	}
 }
 
-/* Caveat: No range checking in either ntfs_set_bit or ntfs_clear_bit */
-void 
-ntfs_set_bit (unsigned char *byte, int bit)
+/* Caveat: No range checking in either ntfs_set_bit or ntfs_clear_bit. */
+void ntfs_set_bit(unsigned char *byte, int bit)
 {
 	byte += (bit >> 3);
 	bit &= 7;
 	*byte |= (1 << bit);
 }
 
-void 
-ntfs_clear_bit (unsigned char *byte, int bit)
+void ntfs_clear_bit(unsigned char *byte, int bit)
 {
 	byte += (bit >> 3);
 	bit &= 7;
 	*byte &= ~(1 << bit);
 }
 
-/* We have to skip the 16 metafiles and the 8 reserved entries */
-static int 
-ntfs_new_inode (ntfs_volume* vol,int* result)
+/**
+ * ntfs_new_inode - allocate an mft record
+ * @vol:	volume to allocate an mft record on
+ * @result:	the mft record number allocated
+ *
+ * Allocate a new mft record on disk by finding the first free mft record
+ * and allocating it in the mft bitmap.
+ * Return 0 on success or -ERRNO on error.
+ *
+ * TODO(AIA): Implement mft bitmap caching. Replace function by race safe one.
+ */
+static int ntfs_new_inode(ntfs_volume* vol, int* result)
 {
-	int byte,error;
+	int byte, error;
 	int bit;
-	int size,length;
+	int size, length;
 	unsigned char value;
 	ntfs_u8 *buffer;
 	ntfs_io io;
 	ntfs_attribute *data;
 
-	buffer=ntfs_malloc(2048);
-	if(!buffer)return ENOMEM;
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	io.param=buffer;
-	/* FIXME: bitmaps larger than 2048 bytes */
-	io.size=2048;
-	error=ntfs_read_attr(vol->mft_ino,vol->at_bitmap,0,0,&io);
-	if(error){
+	buffer = ntfs_malloc(2048);
+	if (!buffer)
+		return -ENOMEM;
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	io.param = buffer;
+	/* FIXME: Bitmaps larger than 2048 bytes. */
+	io.size = 2048;
+	error = ntfs_read_attr(vol->mft_ino, vol->at_bitmap, 0, 0, &io);
+	if (error) {
 		ntfs_free(buffer);
 		return error;
 	}
-	size=io.size;
-	data=ntfs_find_attr(vol->mft_ino,vol->at_data,0);
-	length=data->size/vol->mft_recordsize;
-
-	/* SRD: start at byte 0: bits for system files _are_ already set in bitmap */
-	for (byte = 0; 8*byte < length; byte++)
-	{
+	size = io.size;
+	data = ntfs_find_attr(vol->mft_ino, vol->at_data, 0);
+	length = data->size / vol->mft_recordsize;
+	/* SRD: Start at byte 0: bits for system files _are_ already set in 
+	 * bitmap. AIA: This includes the reserved entries as well. */
+	for (byte = 0; 8 * byte < length; byte++) {
 		value = buffer[byte];
-		if(value==0xFF)
+		if (value == 0xFF)
 			continue;
-		for (bit = 0; (bit < 8) && (8*byte+bit<length); 
-		     bit++, value >>= 1)
-		{
-			if (!(value & 1)){
-				*result=byte*8+bit;
+		for (bit = 0; (bit < 8) && (8 * byte + bit < length); 
+							 bit++, value >>= 1) {
+			if (!(value & 1)) {
+				*result = byte * 8 + bit;
 				return 0;
 			}
 		}
 	}
-	/* There is no free space.  We must first extend the MFT. */
-	return ENOSPC;
+	/* There is no free space. We must first extend the MFT. */
+	return -ENOSPC;
 }
 
-static int 
-add_mft_header (ntfs_inode *ino)
+static int add_mft_header(ntfs_inode *ino)
 {
-	unsigned char* mft;
-	ntfs_volume *vol=ino->vol;
-	mft=ino->attr;
+	unsigned char *mft;
+	ntfs_volume *vol = ino->vol;
 
+	mft = ino->attr;
 	ntfs_bzero(mft, vol->mft_recordsize);
-	ntfs_fill_mft_header(mft,vol->mft_recordsize,vol->blocksize,
-			ino->sequence_number);
+	ntfs_fill_mft_header(mft, vol->mft_recordsize, vol->blocksize,
+			     ino->sequence_number);
 	return 0;
 }
 
-/* We need 0x48 bytes in total */
-static int 
-add_standard_information (ntfs_inode *ino)
+/* We need 0x48 bytes in total. */
+static int add_standard_information(ntfs_inode *ino)
 {
 	ntfs_time64_t now;
 	char data[0x30];
-	char *position=data;
+	char *position = data;
 	int error;
 	ntfs_attribute *si;
 
@@ -1123,66 +1176,63 @@
 	NTFS_PUTU64(position + 0x08, now);		/* Last modification */
 	NTFS_PUTU64(position + 0x10, now);		/* Last mod for MFT */
 	NTFS_PUTU64(position + 0x18, now);		/* Last access */
-
-	NTFS_PUTU64(position + 0x20, 0x00);		/* MSDOS file perms */
-	NTFS_PUTU64(position + 0x28, 0);               /* unknown */
-	error=ntfs_create_attr(ino,ino->vol->at_standard_information,0,
-			       data,sizeof(data),&si);
-
+	NTFS_PUTU64(position + 0x20, 0);		/* MSDOS file perms */
+	NTFS_PUTU64(position + 0x28, 0);		/* unknown */
+	error = ntfs_create_attr(ino, ino->vol->at_standard_information, 0,
+				 data, sizeof(data), &si);
 	return error;
 }
 
-static int 
-add_filename (ntfs_inode* ino, ntfs_inode* dir, 
-	      const unsigned char *filename, int length, ntfs_u32 flags)
-{
-	unsigned char   *position;
-	unsigned int    size;
-	ntfs_time64_t   now;
-	int		count;
-	int error;
+/* FIXME: Need to pass in the size of the file (Data size) as well as the
+ * allocated size for file data on disk (Allocated size). (AIA) */
+static int add_filename(ntfs_inode* ino, ntfs_inode* dir, 
+			const unsigned char *filename, int length, 
+			ntfs_u32 flags)
+{
+	unsigned char *position;
+	unsigned int size;
+	ntfs_time64_t now;
+	int count, error;
 	unsigned char* data;
 	ntfs_attribute *fn;
 
-	/* work out the size */
+	/* Work out the size. */
 	size = 0x42 + 2 * length;
 	data = ntfs_malloc(size);
-	if( !data )
-		return ENOMEM;
-	ntfs_bzero(data,size);
-
-	/* search for a position */
+	if (!data)
+		return -ENOMEM;
+	ntfs_bzero(data, size);
+	/* Search for a position. */
 	position = data;
-
-	NTFS_PUTINUM(position, dir);	/* Inode num of dir */
-
+	NTFS_PUTINUM(position, dir);			/* Inode num of dir */
 	now = ntfs_now();
 	NTFS_PUTU64(position + 0x08, now);		/* File creation */
 	NTFS_PUTU64(position + 0x10, now);		/* Last modification */
 	NTFS_PUTU64(position + 0x18, now);		/* Last mod for MFT */
 	NTFS_PUTU64(position + 0x20, now);		/* Last access */
-
-	/* Don't know */
-	NTFS_PUTU32(position+0x38, flags);
-
-	NTFS_PUTU8(position + 0x40, length);	      /* Filename length */
-	NTFS_PUTU8(position + 0x41, 0x0);	      /* only long name */
-
+	/*NTFS_PUTU64(position + 0x28, 0);*/		/* Allocated size */
+	/*NTFS_PUTU64(position + 0x30, 0);*/		/* Data size */
+	NTFS_PUTU32(position + 0x38, flags);		/* File flags */
+	/*NTFS_PUTU32(position + 0x3c, 0);*/		/* We don't use these
+							 * features yet. */
+	NTFS_PUTU8(position + 0x40, length);		/* Filename length */
+	NTFS_PUTU8(position + 0x41, 0);			/* Only long name */
+		/* FIXME: This is madness. We are defining the POSIX namespace
+		 * for the filename here which can mean that the file will be
+		 * invisible when in Windows NT/2k! )-: (AIA) */
 	position += 0x42;
-	for (count = 0; count < length; count++)
-	{
+	for (count = 0; count < length; count++) {
 		NTFS_PUTU16(position + 2 * count, filename[count]);
 	}
-
-	error=ntfs_create_attr(ino,ino->vol->at_file_name,0,data,size,&fn);
-	if(!error)
-		error=ntfs_dir_add(dir,ino,fn);
+	error = ntfs_create_attr(ino, ino->vol->at_file_name, 0, data, size,
+				 &fn);
+	if (!error)
+		error = ntfs_dir_add(dir, ino, fn);
 	ntfs_free(data);
 	return error;
 }
 
-int 
-add_security (ntfs_inode* ino, ntfs_inode* dir)
+int add_security(ntfs_inode* ino, ntfs_inode* dir)
 {
 	int error;
 	char *buf;
@@ -1191,133 +1241,138 @@
 	ntfs_io io;
 	ntfs_attribute *se;
 
-	attr=ntfs_find_attr(dir,ino->vol->at_security_descriptor,0);
-	if(!attr)
-		return EOPNOTSUPP; /* need security in directory */
+	attr = ntfs_find_attr(dir, ino->vol->at_security_descriptor, 0);
+	if (!attr)
+		return -EOPNOTSUPP; /* Need security in directory. */
 	size = attr->size;
-	if(size>512)
-		return EOPNOTSUPP;
-	buf=ntfs_malloc(size);
-	if(!buf)
-		return ENOMEM;
-	io.fn_get=ntfs_get;
-	io.fn_put=ntfs_put;
-	io.param=buf;
-	io.size=size;
-	error=ntfs_read_attr(dir,ino->vol->at_security_descriptor,0,0,&io);
-	if(!error && io.size!=size)ntfs_error("wrong size in add_security");
-	if(error){
+	if (size > 512)
+		return -EOPNOTSUPP;
+	buf = ntfs_malloc(size);
+	if (!buf)
+		return -ENOMEM;
+	io.fn_get = ntfs_get;
+	io.fn_put = ntfs_put;
+	io.param = buf;
+	io.size = size;
+	error = ntfs_read_attr(dir, ino->vol->at_security_descriptor, 0, 0,&io);
+	if (!error && io.size != size)
+		ntfs_error("wrong size in add_security");
+	if (error) {
 		ntfs_free(buf);
 		return error;
 	}
-	/* FIXME: consider ACL inheritance */
-	error=ntfs_create_attr(ino,ino->vol->at_security_descriptor,
-			       0,buf,size,&se);
+	/* FIXME: Consider ACL inheritance. */
+	error = ntfs_create_attr(ino, ino->vol->at_security_descriptor,
+				 0, buf, size, &se);
 	ntfs_free(buf);
 	return error;
 }
 
-static int 
-add_data (ntfs_inode* ino, unsigned char *data, int length)
+static int add_data(ntfs_inode* ino, unsigned char *data, int length)
 {
 	int error;
 	ntfs_attribute *da;
-	error=ntfs_create_attr(ino,ino->vol->at_data,0,data,length,&da);
+	
+	error = ntfs_create_attr(ino, ino->vol->at_data, 0, data, length, &da);
 	return error;
 }
 
-/* We _could_ use 'dir' to help optimise inode allocation */
-int ntfs_alloc_inode (ntfs_inode *dir, ntfs_inode *result, 
-		      const char *filename, int namelen, ntfs_u32 flags)
+/* We _could_ use 'dir' to help optimise inode allocation. */
+int ntfs_alloc_inode(ntfs_inode *dir, ntfs_inode *result, const char *filename,
+		     int namelen, ntfs_u32 flags)
 {
 	ntfs_io io;
 	int error;
 	ntfs_u8 buffer[2];
-	ntfs_volume* vol=dir->vol;
-	int byte,bit;
+	ntfs_volume *vol = dir->vol;
+	int byte, bit;
 
-	error=ntfs_new_inode (vol,&(result->i_number));
-	if(error==ENOSPC){
-		error=ntfs_extend_mft(vol);
-		if(error)return error;
-		error=ntfs_new_inode(vol,&(result->i_number));
+	error = ntfs_new_inode(vol, &(result->i_number));
+	if (error == -ENOSPC) {
+		error = ntfs_extend_mft(vol);
+		if (error)
+			return error;
+		error = ntfs_new_inode(vol, &(result->i_number));
 	}
-	if(error){
-		ntfs_error ("ntfs_get_empty_inode: no free inodes\n");
+	if (error) {
+		ntfs_error("ntfs_get_empty_inode: no free inodes\n");
 		return error;
 	}
-	byte=result->i_number/8;
-	bit=result->i_number & 7;
-
+	byte = result->i_number / 8;
+	bit = result->i_number & 7;
 	io.fn_put = ntfs_put;
 	io.fn_get = ntfs_get;
 	io.param = buffer;
-	io.size=1;
-	/* set a single bit */
-	error=ntfs_read_attr(vol->mft_ino,vol->at_bitmap,0,byte,&io);
-	if(error)return error;
-	if(io.size!=1)
-		return EIO;
-	ntfs_set_bit (buffer, bit);
+	io.size = 1;
+	/* Set a single bit. */
+	error = ntfs_read_attr(vol->mft_ino, vol->at_bitmap, 0, byte, &io);
+	if (error)
+		return error;
+	if (io.size != 1)
+		return -EIO;
+	ntfs_set_bit(buffer, bit);
 	io.param = buffer;
 	io.size = 1;
- 	error = ntfs_write_attr (vol->mft_ino, vol->at_bitmap, 0, byte, &io);
-	if(error)return error;
+ 	error = ntfs_write_attr(vol->mft_ino, vol->at_bitmap, 0, byte, &io);
+	if (error)
+		return error;
 	if (io.size != 1)
-		return EIO;
-	/*FIXME: Should change MFT on disk
-	  error=ntfs_update_inode(vol->mft_ino);
-	  if(error)return error;
-	  */
-	/* get the sequence number */
+		return -EIO;
+	/* FIXME: Should change $Mft on disk.
+	 * error = ntfs_update_inode(vol->mft_ino);
+	 * if (error)
+	 * 	return error; 
+	 * FIXME: And don't forget $MftMirr, though this probably belongs
+	 * in ntfs_update_inode() (or even deeper). (AIA) */
+	/* Get the sequence number. */
 	io.param = buffer;
 	io.size = 2;
 	error = ntfs_read_attr(vol->mft_ino, vol->at_data, 0, 
-			       result->i_number*vol->mft_recordsize+0x10,&io);
-	if(error)
+			       result->i_number * vol->mft_recordsize + 0x10,
+			       &io);
+	if (error)
 		return error;
-	result->sequence_number=NTFS_GETU16(buffer)+1;
-	result->vol=vol;
-	result->attr=ntfs_malloc(vol->mft_recordsize);
-	if( !result->attr )
-		return ENOMEM;
-	result->attr_count=0;
-	result->attrs=0;
-	result->record_count=1;
-	result->records=ntfs_malloc(8*sizeof(int));
-	if( !result->records ) {
-		ntfs_free( result->attr );
+	/* Increment the sequence number skipping zero. */
+	if (NTFS_GETU16(buffer) == 0xffff)
+		result->sequence_number = 1;
+	else
+		result->sequence_number = NTFS_GETU16(buffer) + 1;
+	result->vol = vol;
+	result->attr = ntfs_malloc(vol->mft_recordsize);
+	if (!result->attr)
+		return -ENOMEM;
+	result->attr_count = 0;
+	result->attrs = 0;
+	result->record_count = 1;
+	result->records = ntfs_malloc(8 * sizeof(int));
+	if (!result->records) {
+		ntfs_free(result->attr);
 		result->attr = 0;
-		return ENOMEM;
+		return -ENOMEM;
 	}
-	result->records[0]=result->i_number;
-	error=add_mft_header(result);
-	if(error)
+	result->records[0] = result->i_number;
+	error = add_mft_header(result);
+	if (error)
+		return error;
+	error = add_standard_information(result);
+	if (error)
 		return error;
-	error=add_standard_information(result);
-	if(error)
+	error = add_filename(result, dir, filename, namelen, flags);
+	if (error)
 		return error;
-	error=add_filename(result,dir,filename,namelen,flags);
-	if(error)
+	error = add_security(result, dir);
+	if (error)
 		return error;
-	error=add_security(result,dir);
-	/*FIXME: check error */
 	return 0;
 }
 
-int
-ntfs_alloc_file(ntfs_inode *dir, ntfs_inode *result, char *filename,
-		int namelen)
+int ntfs_alloc_file(ntfs_inode *dir, ntfs_inode *result, char *filename,
+		    int namelen)
 {
-	int error = ntfs_alloc_inode(dir,result,filename,namelen,0);
-	if(error)
+	int error = ntfs_alloc_inode(dir, result, filename, namelen, 0);
+	if (error)
 		return error;
-	error = add_data(result,0,0);
+	error = add_data(result, 0, 0);
 	return error;
 }
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/ntfs/inode.h linux/fs/ntfs/inode.h
--- linux-2.4.4-pre4/fs/ntfs/inode.h	Mon Apr 12 10:05:58 1999
+++ linux/fs/ntfs/inode.h	Mon Dec  3 22:35:56 2001
@@ -1,30 +1,43 @@
-/*
- *  inode.h
- *  Header file for inode.c
+/*  inode.h -  Header file for inode.c
  *
  *  Copyright (C) 1997 Régis Duchesne
  *  Copyright (C) 1998 Martin von Löwis
  */
 
 ntfs_attribute *ntfs_find_attr(ntfs_inode *ino, int type, char *name);
+
 int ntfs_read_attr(ntfs_inode *ino, int type, char *name, int offset,
 		   ntfs_io *buf);
+
 int ntfs_write_attr(ntfs_inode *ino, int type, char *name, int offset,
 		    ntfs_io *buf);
-int ntfs_init_inode(ntfs_inode *ino,ntfs_volume *vol,int inum);
+
+int ntfs_init_inode(ntfs_inode *ino, ntfs_volume *vol, int inum);
+
 void ntfs_clear_inode(ntfs_inode *ino);
-int ntfs_check_mft_record(ntfs_volume *vol,char *record);
-int ntfs_alloc_inode (ntfs_inode *dir, ntfs_inode *result, 
-		      const char *filename, int namelen,ntfs_u32);
-int ntfs_alloc_file (ntfs_inode *dir, ntfs_inode *result, 
-		     char *filename, int namelen);
+
+int ntfs_check_mft_record(ntfs_volume *vol, char *record);
+
+int ntfs_alloc_inode(ntfs_inode *dir, ntfs_inode *result, const char *filename,
+		     int namelen, ntfs_u32);
+
+int ntfs_alloc_file(ntfs_inode *dir, ntfs_inode *result, char *filename,
+		    int namelen);
+
 int ntfs_update_inode(ntfs_inode *ino);
+
 int ntfs_vcn_to_lcn(ntfs_inode *ino, int vcn);
+
 int ntfs_readwrite_attr(ntfs_inode *ino, ntfs_attribute *attr, int offset,
 			ntfs_io *dest);
+
 int ntfs_allocate_attr_number(ntfs_inode *ino, int *result);
-int ntfs_decompress_run(unsigned char **data, int *length, ntfs_cluster_t *cluster,
-			int *ctype);
+
+int ntfs_decompress_run(unsigned char **data, int *length,
+			ntfs_cluster_t *cluster, int *ctype);
+
 void ntfs_decompress(unsigned char *dest, unsigned char *src, ntfs_size_t l);
-void ntfs_fill_mft_header( ntfs_u8 *mft, int recordsize, int blocksize,
-			int sequence_number );
+
+void ntfs_fill_mft_header(ntfs_u8 *mft, int recordsize, int blocksize,
+			  int sequence_number);
+
diff -urN linux-2.4.4-pre4/fs/ntfs/macros.h linux/fs/ntfs/macros.h
--- linux-2.4.4-pre4/fs/ntfs/macros.h	Sat Jan  2 10:24:46 1999
+++ linux/fs/ntfs/macros.h	Mon Dec  3 22:35:56 2001
@@ -1,5 +1,4 @@
-/*
- *  macros.h
+/*  macros.h
  *
  *  Copyright (C) 1995 Martin von Löwis
  *  Copyright (C) 1996 Régis Duchesne
@@ -7,23 +6,10 @@
 
 #define NTFS_FD(vol)		((vol)->u.fd)
 
-/* Linux */
-#ifdef NTFS_IN_LINUX_KERNEL
 #define NTFS_SB(vol)		((struct super_block*)(vol)->sb)
 #define NTFS_SB2VOL(sb)         (&(sb)->u.ntfs_sb)
 #define NTFS_INO2VOL(ino)	(&((ino)->i_sb->u.ntfs_sb))
 #define NTFS_LINO2NINO(ino)     (&((ino)->u.ntfs_i))
-#else
-#define NTFS_SB(vol)		((struct super_block*)(vol)->u.sb)
-#define NTFS_SB2VOL(sb)		((ntfs_volume*)(sb)->u.generic_sbp)
-#define NTFS_INO2VOL(ino)	((ntfs_volume*)((ino)->i_sb->u.generic_sbp))
-#define NTFS_LINO2NINO(ino)     ((ntfs_inode*)((ino)->u.generic_ip))
-#endif
-
-/* BSD */
-#define NTFS_MNT(vol)		((struct mount*)(vol)->u.sb)
-#define NTFS_MNT2VOL(sb)	((ntfs_volume*)(sb)->mnt_data)
-#define NTFS_V2INO(ino)		((ntfs_inode*)((ino)->v_data))
 
 /* Classical min and max macros still missing in standard headers... */
 #ifndef min
@@ -31,9 +17,9 @@
 #define max(a,b)	((a) >= (b) ? (a) : (b))
 #endif
 
-#define IS_MAGIC(a,b)		(*(int*)(a)==*(int*)(b))
+#define IS_MAGIC(a,b)		(*(int*)(a) == *(int*)(b))
 #define IS_MFT_RECORD(a)	IS_MAGIC((a),"FILE")
-#define IS_NTFS_VOLUME(a)	IS_MAGIC((a)+3,"NTFS")
+#define IS_NTFS_VOLUME(a)	IS_MAGIC((a) + 3,"NTFS")
 #define IS_INDEX_RECORD(a)	IS_MAGIC((a),"INDX")
 
 /* 'NTFS' in little endian */
@@ -46,8 +32,3 @@
 #define NTFS_AFLAG_COMPRESSED   0x800
 #define NTFS_AFLAG_DIR          0x10000000
 
-/*
- * Local variables:
- *  c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/ntfs/ntfsendian.h linux/fs/ntfs/ntfsendian.h
--- linux-2.4.4-pre4/fs/ntfs/ntfsendian.h	Mon Dec 11 13:26:39 2000
+++ linux/fs/ntfs/ntfsendian.h	Mon Dec  3 22:35:56 2001
@@ -1,17 +1,13 @@
-/*
- *  ntfsendian.h
+/*  ntfsendian.h
  *
  *  Copyright (C) 1998, 1999 Martin von Löwis
  *  Copyright (C) 1998 Joseph Malicki
  *  Copyright (C) 1999 Werner Seiler
+ *  Copyright (C) 2001 Anton Altaparmakov (AIA)
  */
 
-#ifdef __linux__
-/* This defines __cpu_to_le16 on Linux 2.1 and higher. */
 #include <asm/byteorder.h>
-#endif
 
-#ifdef __cpu_to_le16
 #define CPU_TO_LE16(a) __cpu_to_le16(a)
 #define CPU_TO_LE32(a) __cpu_to_le32(a)
 #define CPU_TO_LE64(a) __cpu_to_le64(a)
@@ -20,68 +16,44 @@
 #define LE32_TO_CPU(a) __cpu_to_le32(a)
 #define LE64_TO_CPU(a) __cpu_to_le64(a)
 
-#else
-
-#ifdef __LITTLE_ENDIAN
-
-#define CPU_TO_LE16(a) (a)
-#define CPU_TO_LE32(a) (a)
-#define CPU_TO_LE64(a) (a)
-#define LE16_TO_CPU(a) (a)
-#define LE32_TO_CPU(a) (a)
-#define LE64_TO_CPU(a) (a)
-
-#else
-
-/* Routines for big-endian machines */
-#ifdef __BIG_ENDIAN
-
-/* We hope its big-endian, not PDP-endian :) */
-#define CPU_TO_LE16(a) ((((a)&0xFF) << 8)|((a) >> 8))
-#define CPU_TO_LE32(a) ((((a) & 0xFF) << 24) | (((a) & 0xFF00) << 8) | \
-			(((a) & 0xFF0000) >> 8) | ((a) >> 24))
-#define CPU_TO_LE64(a) ((CPU_TO_LE32(a)<<32)|CPU_TO_LE32((a)>>32)
-
-#define LE16_TO_CPU(a) CPU_TO_LE16(a)
-#define LE32_TO_CPU(a) CPU_TO_LE32(a)
-#define LE64_TO_CPU(a) CPU_TO_LE64(a)
-
-#else
-
-#error Please define Endianness - __BIG_ENDIAN or __LITTLE_ENDIAN or add OS-specific macros
-
-#endif /* __BIG_ENDIAN */
-#endif /* __LITTLE_ENDIAN */
-#endif /* __cpu_to_le16 */
-
 #define NTFS_GETU8(p)      (*(ntfs_u8*)(p))
 #define NTFS_GETU16(p)     ((ntfs_u16)LE16_TO_CPU(*(ntfs_u16*)(p)))
-#define NTFS_GETU24(p)     ((ntfs_u32)NTFS_GETU16(p) | ((ntfs_u32)NTFS_GETU8(((char*)(p))+2)<<16))
+#define NTFS_GETU24(p)     ((ntfs_u32)NTFS_GETU16(p) | \
+			   ((ntfs_u32)NTFS_GETU8(((char*)(p)) + 2) << 16))
 #define NTFS_GETU32(p)     ((ntfs_u32)LE32_TO_CPU(*(ntfs_u32*)(p)))
-#define NTFS_GETU40(p)     ((ntfs_u64)NTFS_GETU32(p)|(((ntfs_u64)NTFS_GETU8(((char*)(p))+4))<<32))
-#define NTFS_GETU48(p)     ((ntfs_u64)NTFS_GETU32(p)|(((ntfs_u64)NTFS_GETU16(((char*)(p))+4))<<32))
-#define NTFS_GETU56(p)     ((ntfs_u64)NTFS_GETU32(p)|(((ntfs_u64)NTFS_GETU24(((char*)(p))+4))<<32))
+#define NTFS_GETU40(p)     ((ntfs_u64)NTFS_GETU32(p) | \
+			   (((ntfs_u64)NTFS_GETU8(((char*)(p)) + 4)) << 32))
+#define NTFS_GETU48(p)     ((ntfs_u64)NTFS_GETU32(p) | \
+			   (((ntfs_u64)NTFS_GETU16(((char*)(p)) + 4)) << 32))
+#define NTFS_GETU56(p)     ((ntfs_u64)NTFS_GETU32(p) | \
+			   (((ntfs_u64)NTFS_GETU24(((char*)(p)) + 4)) << 32))
 #define NTFS_GETU64(p)     ((ntfs_u64)LE64_TO_CPU(*(ntfs_u64*)(p)))
  
  /* Macros writing unsigned integers */
-#define NTFS_PUTU8(p,v)      ((*(ntfs_u8*)(p))=(v))
-#define NTFS_PUTU16(p,v)     ((*(ntfs_u16*)(p))=CPU_TO_LE16(v))
-#define NTFS_PUTU24(p,v)     NTFS_PUTU16(p,(v) & 0xFFFF);\
-                             NTFS_PUTU8(((char*)(p))+2,(v)>>16)
-#define NTFS_PUTU32(p,v)     ((*(ntfs_u32*)(p))=CPU_TO_LE32(v))
-#define NTFS_PUTU64(p,v)     ((*(ntfs_u64*)(p))=CPU_TO_LE64(v))
+#define NTFS_PUTU8(p,v)      ((*(ntfs_u8*)(p)) = (v))
+#define NTFS_PUTU16(p,v)     ((*(ntfs_u16*)(p)) = CPU_TO_LE16(v))
+#define NTFS_PUTU24(p,v)     NTFS_PUTU16(p, (v) & 0xFFFF);\
+                             NTFS_PUTU8(((char*)(p)) + 2, (v) >> 16)
+#define NTFS_PUTU32(p,v)     ((*(ntfs_u32*)(p)) = CPU_TO_LE32(v))
+#define NTFS_PUTU64(p,v)     ((*(ntfs_u64*)(p)) = CPU_TO_LE64(v))
  
  /* Macros reading signed integers */
 #define NTFS_GETS8(p)        ((*(ntfs_s8*)(p)))
 #define NTFS_GETS16(p)       ((ntfs_s16)LE16_TO_CPU(*(short*)(p)))
-#define NTFS_GETS24(p)       (NTFS_GETU24(p) < 0x800000 ? (int)NTFS_GETU24(p) : (int)(NTFS_GETU24(p) - 0x1000000))
+#define NTFS_GETS24(p)       (NTFS_GETU24(p) < 0x800000 ? \
+					(int)NTFS_GETU24(p) : \
+					(int)(NTFS_GETU24(p) - 0x1000000))
 #define NTFS_GETS32(p)       ((ntfs_s32)LE32_TO_CPU(*(int*)(p)))
-#define NTFS_GETS40(p)       (((ntfs_s64)NTFS_GETU32(p)) | (((ntfs_s64)NTFS_GETS8(((char*)(p))+4)) << 32))
-#define NTFS_GETS48(p)       (((ntfs_s64)NTFS_GETU32(p)) | (((ntfs_s64)NTFS_GETS16(((char*)(p))+4)) << 32))
-#define NTFS_GETS56(p)       (((ntfs_s64)NTFS_GETU32(p)) | (((ntfs_s64)NTFS_GETS24(((char*)(p))+4)) << 32))
+#define NTFS_GETS40(p)       (((ntfs_s64)NTFS_GETU32(p)) | \
+			     (((ntfs_s64)NTFS_GETS8(((char*)(p)) + 4)) << 32))
+#define NTFS_GETS48(p)       (((ntfs_s64)NTFS_GETU32(p)) | \
+			     (((ntfs_s64)NTFS_GETS16(((char*)(p)) + 4)) << 32))
+#define NTFS_GETS56(p)       (((ntfs_s64)NTFS_GETU32(p)) | \
+			     (((ntfs_s64)NTFS_GETS24(((char*)(p)) + 4)) << 32))
 #define NTFS_GETS64(p)	     ((ntfs_s64)NTFS_GETU64(p))
  
 #define NTFS_PUTS8(p,v)      NTFS_PUTU8(p,v)
 #define NTFS_PUTS16(p,v)     NTFS_PUTU16(p,v)
 #define NTFS_PUTS24(p,v)     NTFS_PUTU24(p,v)
 #define NTFS_PUTS32(p,v)     NTFS_PUTU32(p,v)
+
diff -urN linux-2.4.4-pre4/fs/ntfs/ntfstypes.h linux/fs/ntfs/ntfstypes.h
--- linux-2.4.4-pre4/fs/ntfs/ntfstypes.h	Mon Dec 11 13:26:39 2000
+++ linux/fs/ntfs/ntfstypes.h	Mon Dec  3 22:35:56 2001
@@ -1,26 +1,21 @@
-/*
- *  ntfstypes.h
- *  This file defines four things:
- *   - generic platform independent fixed-size types (e.g. ntfs_u32)
- *   - specific fixed-size types (e.g. ntfs_offset_t)
- *   - macros that read and write those types from and to byte arrays
- *   - types derived from OS specific ones
+/*  ntfstypes.h - This file defines four things:
+ *   - Generic platform independent fixed-size types (e.g. ntfs_u32).
+ *   - Specific fixed-size types (e.g. ntfs_offset_t).
+ *   - Macros that read and write those types from and to byte arrays.
+ *   - Types derived from OS specific ones.
  *
- *  Copyright (C) 1996,1998, 1999 Martin von Löwis
+ *  Copyright (C) 1996, 1998, 1999 Martin von Löwis
+ *  Copyright (C) 2001 Anton Altaparmakov (AIA)
  */
 
-#ifdef NTFS_IN_LINUX_KERNEL
-/* get installed types if we compile the kernel*/
 #include <linux/fs.h>
-#endif
 
 /* We don't need to define __LITTLE_ENDIAN, as we use
    <asm/byteorder>. */
-
 #include "ntfsendian.h"
 #include <asm/types.h>
 
-/* integral types */
+/* Integral types */
 #ifndef NTFS_INTEGRAL_TYPES
 #define NTFS_INTEGRAL_TYPES
 typedef u8  ntfs_u8;
@@ -33,12 +28,12 @@
 typedef s64 ntfs_s64;
 #endif
 
-/* unicode character type */
+/* Unicode character type */
 #ifndef NTFS_WCHAR_T
 #define NTFS_WCHAR_T
 typedef u16 ntfs_wchar_t;
 #endif
-/* file offset */
+/* File offset */
 #ifndef NTFS_OFFSET_T
 #define NTFS_OFFSET_T
 typedef u64 ntfs_offset_t;
@@ -48,7 +43,7 @@
 #define NTFS_TIME64_T
 typedef u64 ntfs_time64_t;
 #endif
-/* This is really unsigned long long. So we support only volumes up to 2 TB */
+/* This is really unsigned long long. So we support only volumes up to 2Tb. */
 #ifndef NTFS_CLUSTER_T
 #define NTFS_CLUSTER_T
 typedef u32 ntfs_cluster_t;
@@ -58,13 +53,13 @@
 #define MAX_CLUSTER_T (~((ntfs_cluster_t)0))
 #endif
 
-/* architecture independent macros */
+/* Architecture independent macros. */
 
-/* PUTU32 would not clear all bytes */
-#define NTFS_PUTINUM(p,i)    NTFS_PUTU64(p,i->i_number);\
-                             NTFS_PUTU16(((char*)p)+6,i->sequence_number)
+/* PUTU32 would not clear all bytes. */
+#define NTFS_PUTINUM(p,i)    NTFS_PUTU64(p, i->i_number); \
+                             NTFS_PUTU16(((char*)p) + 6, i->sequence_number)
 
-/* system dependent types */
+/* System dependent types. */
 #include <asm/posix_types.h>
 #ifndef NTMODE_T
 #define NTMODE_T
@@ -87,8 +82,3 @@
 typedef __kernel_time_t ntfs_time_t;
 #endif
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/ntfs/struct.h linux/fs/ntfs/struct.h
--- linux-2.4.4-pre4/fs/ntfs/struct.h	Tue May  2 13:46:53 2000
+++ linux/fs/ntfs/struct.h	Mon Dec  3 22:35:56 2001
@@ -1,143 +1,50 @@
-/*
- * struct.h
- * Structure definitions
+/*  struct.h - Structure definitions
  *
  *  Copyright (C) 1997 Régis Duchesne
- *  Copyright (C) 2000 Anton Altaparmakov
+ *  Copyright (C) 2000-2001 Anton Altaparmakov (AIA)
  */
 
-/* Necessary forward definition */
+/* Necessary forward definition. */
 struct ntfs_inode;
 
-#ifdef __FreeBSD__
-#include <sys/queue.h>
-/* Define the struct ntfs_head type */
-LIST_HEAD(ntfs_head,ntfs_inode);
-#endif
+/* Which files should be returned from a director listing. */
+#define ngt_dos   1	/* only short names, no hidden files */
+#define ngt_nt    2	/* only long names, all-uppercase becomes 
+			 * all-lowercase, no hidden files */
+#define ngt_posix 3	/* all names except hidden files */
+#define ngt_full  4	/* all entries */
 
-/* which files should be returned from a director listing */
-/* only short names, no hidden files */
-#define ngt_dos   1
-/* only long names, all-uppercase becomes all-lowercase, no hidden files */
-#define ngt_nt    2
-/* all names except hidden files */
-#define ngt_posix 3
-/* all entries */
-#define ngt_full  4
 
-#ifdef NTFS_IN_LINUX_KERNEL
 typedef struct ntfs_sb_info ntfs_volume;
-#else
-typedef struct _ntfs_volume{
-	/* NTFS_SB_INFO_START */
-	/* Configuration provided by user at mount time */
-	ntfs_uid_t uid;
-	ntfs_gid_t gid;
-	ntmode_t umask;
-        unsigned int nct;
-	void *nls_map;
-	unsigned int ngt;
-	/* Configuration provided by user with ntfstools */
-	ntfs_size_t partition_bias;	/* for access to underlying device */
-	/* Attribute definitions */
-	ntfs_u32 at_standard_information;
-	ntfs_u32 at_attribute_list;
-	ntfs_u32 at_file_name;
-	ntfs_u32 at_volume_version;
-	ntfs_u32 at_security_descriptor;
-	ntfs_u32 at_volume_name;
-	ntfs_u32 at_volume_information;
-	ntfs_u32 at_data;
-	ntfs_u32 at_index_root;
-	ntfs_u32 at_index_allocation;
-	ntfs_u32 at_bitmap;
-	ntfs_u32 at_symlink; /* aka SYMBOLIC_LINK or REPARSE_POINT */
-	/* Data read from the boot file */
-	int blocksize;
-	int clusterfactor;
-	int clustersize;
-	int mft_recordsize;
-	int mft_clusters_per_record;
-	int index_recordsize;
-	int index_clusters_per_record;
-	int mft_cluster;
-	/* data read from special files */
-	unsigned char *mft;
-	unsigned short *upcase;
-	unsigned int upcase_length;
-	/* inodes we always hold onto */
-	struct ntfs_inode *mft_ino;
-	struct ntfs_inode *mftmirr;
-	struct ntfs_inode *bitmap;
-	/* NTFS_SB_INFO_END */
-	union{
-		int fd;		/* file descriptor for the tools */
-		void *sb;	/* pointer to super block for the kernel */
-	}u;
-#ifdef __FreeBSD__
-	dev_t rdev;
-	struct vnode *devvp;
-	struct ntfs_head *inode_hash;   /* not really a hash */
-#endif
-}ntfs_volume;
-#endif
 
 typedef struct {
 	ntfs_cluster_t cluster;
 	ntfs_cluster_t len;
-}ntfs_runlist;
+} ntfs_runlist;
 
 typedef struct ntfs_attribute{
 	int type;
 	ntfs_u16 *name;
 	int namelen;
 	int attrno;
-	int size,allocated,initialized,compsize;
-	int compressed,resident,indexed;
+	int size, allocated, initialized, compsize;
+	int compressed, resident, indexed;
 	int cengine;
-	union{
+	union {
 		void *data;             /* if resident */
 		struct {
 			ntfs_runlist *runlist;
 			int len;
-		}r;
-	}d;
-}ntfs_attribute;
-
-/* Structure to define IO to user buffer. do_read means that
-   the destination has to be written using fn_put, do_write means
-   that the destination has to read using fn_get. So, do_read is
-   from a user's point of view, while put and get are from the driver's
-   point of view. The first argument is always the destination of the IO
-*/
-#ifdef NTFS_IN_LINUX_KERNEL
+		} r;
+	} d;
+} ntfs_attribute;
+
+/* Structure to define IO to user buffer. do_read means that the destination
+ * has to be written using fn_put, do_write means that the destination has to
+ * read using fn_get. So, do_read is from a user's point of view, while put and
+ * get are from the driver's point of view. The first argument is always the
+ * destination of the IO. */
 typedef struct ntfs_inode_info ntfs_inode;
-#else
-typedef struct ntfs_inode{
-	ntfs_volume *vol;
-	/* NTFS_INODE_INFO_START */
-	int i_number;                /* should be really 48 bits */
-	unsigned sequence_number;
-	unsigned char* attr;         /* array of the attributes */
-	int attr_count;              /* size of attrs[] */
-	struct ntfs_attribute *attrs;
-	int record_count;            /* size of records[] */
-	/* array of the record numbers of the MFT 
-	   whose attributes have been inserted in the inode */
-	int *records;
-	union{
-		struct{
-			int recordsize;
-			int clusters_per_record;
-		}index;
-	} u;	
-	/* NTFS_INODE_INFO_END */
-#ifdef __FreeBSD__
-	struct vnode *vp;
-	LIST_ENTRY(ntfs_inode) h_next;
-#endif
-}ntfs_inode;
-#endif
 
 typedef struct ntfs_io{
 	int do_read;
@@ -145,7 +52,7 @@
 	void (*fn_get)(void *buf, struct ntfs_io *src, ntfs_size_t len);
 	void *param;
 	int size;
-}ntfs_io;
+} ntfs_io;
 
 #if 0
 typedef struct {
@@ -157,3 +64,4 @@
 	int start_vcn;
 } ntfs_attrlist_item;
 #endif
+
diff -urN linux-2.4.4-pre4/fs/ntfs/super.c linux/fs/ntfs/super.c
--- linux-2.4.4-pre4/fs/ntfs/super.c	Tue Nov  7 11:22:35 2000
+++ linux/fs/ntfs/super.c	Mon Dec  3 22:35:56 2001
@@ -1,10 +1,9 @@
-/*
- *  super.c
+/*  super.c
  *
  *  Copyright (C) 1995-1997, 1999 Martin von Löwis
  *  Copyright (C) 1996-1997 Régis Duchesne
  *  Copyright (C) 1999 Steve Dodd
- *  Copyright (C) 2000 Anton Altparmakov
+ *  Copyright (C) 2000-2001 Anton Altparmakov (AIA)
  */
 
 #include "ntfstypes.h"
@@ -12,13 +11,13 @@
 #include "super.h"
 
 #include <linux/errno.h>
+#include <linux/bitops.h>
 #include "macros.h"
 #include "inode.h"
 #include "support.h"
 #include "util.h"
 
-/*
- * All important structures in NTFS use 2 consistency checks :
+/* All important structures in NTFS use 2 consistency checks:
  * . a magic structure identifier (FILE, INDX, RSTR, RCRD...)
  * . a fixup technique : the last word of each sector (called a fixup) of a
  *   structure's record should end with the word at offset <n> of the first
@@ -36,188 +35,204 @@
 	int start, count, offset;
 	ntfs_u16 fixup;
 
-	if(!IS_MAGIC(record,magic))
+	if (!IS_MAGIC(record, magic))
 		return 0;
-	start=NTFS_GETU16(record+4);
-	count=NTFS_GETU16(record+6);
+	start = NTFS_GETU16(record + 4);
+	count = NTFS_GETU16(record + 6);
 	count--;
-	if(size && vol->blocksize*count != size)
+	if(size && vol->blocksize * count != size)
 		return 0;
-	fixup = NTFS_GETU16(record+start);
-	start+=2;
-	offset=vol->blocksize-2;
-	while(count--){
-		if(NTFS_GETU16(record+offset)!=fixup)
+	fixup = NTFS_GETU16(record + start);
+	start += 2;
+	offset = vol->blocksize - 2;
+	while (count--){
+		if (NTFS_GETU16(record + offset) != fixup)
 			return 0;
-		NTFS_PUTU16(record+offset, NTFS_GETU16(record+start));
-		start+=2;
-		offset+=vol->blocksize;
+		NTFS_PUTU16(record + offset, NTFS_GETU16(record + start));
+		start += 2;
+		offset += vol->blocksize;
 	}
 	return 1;
 }
 
-/* Get vital informations about the ntfs partition from the boot sector */
-int ntfs_init_volume(ntfs_volume *vol,char *boot)
+/*
+ * Get vital informations about the ntfs partition from the boot sector.
+ * Return 0 on success or -1 on error.
+ */
+int ntfs_init_volume(ntfs_volume *vol, char *boot)
 {
-	/* Historical default values, in case we don't load $AttrDef */
-	vol->at_standard_information=0x10;
-	vol->at_attribute_list=0x20;
-	vol->at_file_name=0x30;
-	vol->at_volume_version=0x40;
-	vol->at_security_descriptor=0x50;
-	vol->at_volume_name=0x60;
-	vol->at_volume_information=0x70;
-	vol->at_data=0x80;
-	vol->at_index_root=0x90;
-	vol->at_index_allocation=0xA0;
-	vol->at_bitmap=0xB0;
-	vol->at_symlink=0xC0;
-
+	/* Historical default values, in case we don't load $AttrDef. */
+	vol->at_standard_information = 0x10;
+	vol->at_attribute_list = 0x20;
+	vol->at_file_name = 0x30;
+	vol->at_volume_version = 0x40;
+	vol->at_security_descriptor = 0x50;
+	vol->at_volume_name = 0x60;
+	vol->at_volume_information = 0x70;
+	vol->at_data = 0x80;
+	vol->at_index_root = 0x90;
+	vol->at_index_allocation = 0xA0;
+	vol->at_bitmap = 0xB0;
+	vol->at_symlink = 0xC0;
 	/* Sector size */
-	vol->blocksize=NTFS_GETU16(boot+0xB);
-	vol->clusterfactor=NTFS_GETU8(boot+0xD);
-	vol->mft_clusters_per_record=NTFS_GETS8(boot+0x40);
-	vol->index_clusters_per_record=NTFS_GETS8(boot+0x44);
-	
-	/* Just some consistency checks */
-	if(NTFS_GETU32(boot+0x40)>256)
+	vol->blocksize = NTFS_GETU16(boot + 0xB);
+	vol->clusterfactorbits = ffs(NTFS_GETU8(boot + 0xD)) - 1;
+	vol->mft_clusters_per_record = NTFS_GETS8(boot + 0x40);
+	vol->index_clusters_per_record = NTFS_GETS8(boot + 0x44);
+	/* Just some consistency checks. */
+	if (NTFS_GETU32(boot + 0x40) > 256)
 		ntfs_error("Unexpected data #1 in boot block\n");
-	if(NTFS_GETU32(boot+0x44)>256)
+	if (NTFS_GETU32(boot+ 0x44) > 256)
 		ntfs_error("Unexpected data #2 in boot block\n");
-	if(vol->index_clusters_per_record<0){
-		ntfs_error("Unexpected data #3 in boot block\n");
-		/* If this really means a fraction, setting it to 1
-		   should be safe. */
-		vol->index_clusters_per_record=1;
-	}
-	/* in some cases, 0xF6 meant 1024 bytes. Other strange values have not
-	   been observed */
-	if(vol->mft_clusters_per_record<0 && vol->mft_clusters_per_record!=-10)
-		ntfs_error("Unexpected data #4 in boot block\n");
-
-	vol->clustersize=vol->blocksize*vol->clusterfactor;
-	if(vol->mft_clusters_per_record>0)
-		vol->mft_recordsize=
-			vol->clustersize*vol->mft_clusters_per_record;
-	else
-		vol->mft_recordsize=1<<(-vol->mft_clusters_per_record);
-	vol->index_recordsize=vol->clustersize*vol->index_clusters_per_record;
+	vol->clustersize = vol->blocksize << vol->clusterfactorbits;
+	if (vol->mft_clusters_per_record > 0)
+		vol->mft_recordsize =
+			       vol->clustersize * vol->mft_clusters_per_record;
+	else {
+		/* If mft_recordsize < clustersize then mft_clusters_per_record
+		   = -log2(mft_recordsize) bytes. Mft_recordsize normaly equals
+		   1024 bytes, which is encoded as 0xF6. */
+		if (vol->mft_clusters_per_record < -31 ||
+					-9 < vol->mft_clusters_per_record) {
+			ntfs_error("Unexpected mft clusters per record value "
+				   "in boot block.\n");
+			return -1;
+		}
+		vol->mft_recordsize = 1 << (-vol->mft_clusters_per_record);
+	}
+	if (vol->index_clusters_per_record > 0)
+		vol->index_recordsize =
+			vol->clustersize * vol->index_clusters_per_record;
+	else {
+		/* If index_recordsize < clustersize then
+		   index_clusters_per_record = -log2(index_recordsize) bytes.
+		   Index_recordsize normaly equals 1024 bytes, which is
+		   encoded as 0xF6. */
+		if (vol->index_clusters_per_record < -31 ||
+					-9 < vol->index_clusters_per_record) {
+			ntfs_error("Unexpected index clusters per record "
+				   "value in boot block.\n");
+			return -1;
+		}
+		vol->index_recordsize = 1 << (-vol->index_clusters_per_record);
+	}
+	if (NTFS_GETU64(boot + 0x30) >= (1ULL << 32)) {
+		ntfs_error("Would require 64-bit inodes to mount partition.");
+		return -1;
+	}
 	/* FIXME: long long value */
-	vol->mft_cluster=NTFS_GETU64(boot+0x30);
-
-	/* This will be initialized later */
-	vol->upcase=0;
-	vol->upcase_length=0;
-	vol->mft_ino=0;
+	vol->mft_cluster = NTFS_GETU64(boot + 0x30);
+	/* This will be initialized later. */
+	vol->upcase = 0;
+	vol->upcase_length = 0;
+	vol->mft_ino = 0;
 	return 0;
 }
 
-static void 
-ntfs_init_upcase(ntfs_inode *upcase)
+static void ntfs_init_upcase(ntfs_inode *upcase)
 {
 	ntfs_io io;
 #define UPCASE_LENGTH  256
-	upcase->vol->upcase = ntfs_malloc(2*UPCASE_LENGTH);
-	if( !upcase->vol->upcase )
+	upcase->vol->upcase = ntfs_malloc(UPCASE_LENGTH << 1);
+	if (!upcase->vol->upcase)
 		return;
-	io.fn_put=ntfs_put;
-	io.fn_get=0;
-	io.param=(char*)upcase->vol->upcase;
-	io.size=2*UPCASE_LENGTH;
-	ntfs_read_attr(upcase,upcase->vol->at_data,0,0,&io);
-	upcase->vol->upcase_length = io.size / 2;
+	io.fn_put = ntfs_put;
+	io.fn_get = 0;
+	io.param = (char*)upcase->vol->upcase;
+	io.size = UPCASE_LENGTH << 1;
+	ntfs_read_attr(upcase, upcase->vol->at_data, 0, 0, &io);
+	upcase->vol->upcase_length = io.size >> 1;
 }
 
-static int
-process_attrdef(ntfs_inode* attrdef,ntfs_u8* def)
+static int process_attrdef(ntfs_inode* attrdef, ntfs_u8* def)
 {
 	int type = NTFS_GETU32(def+0x80);
 	int check_type = 0;
-	ntfs_volume *vol=attrdef->vol;
+	ntfs_volume *vol = attrdef->vol;
 	ntfs_u16* name = (ntfs_u16*)def;
 
-	if(ntfs_ua_strncmp(name,"$STANDARD_INFORMATION",64)==0){
-		vol->at_standard_information=type;
-		check_type=0x10;
-	}else if(ntfs_ua_strncmp(name,"$ATTRIBUTE_LIST",64)==0){
-		vol->at_attribute_list=type;
-		check_type=0x20;
-	}else if(ntfs_ua_strncmp(name,"$FILE_NAME",64)==0){
-		vol->at_file_name=type;
-		check_type=0x30;
-	}else if(ntfs_ua_strncmp(name,"$VOLUME_VERSION",64)==0){
-		vol->at_volume_version=type;
-		check_type=0x40;
-	}else if(ntfs_ua_strncmp(name,"$SECURITY_DESCRIPTOR",64)==0){
-		vol->at_security_descriptor=type;
-		check_type=0x50;
-	}else if(ntfs_ua_strncmp(name,"$VOLUME_NAME",64)==0){
-		vol->at_volume_name=type;
-		check_type=0x60;
-	}else if(ntfs_ua_strncmp(name,"$VOLUME_INFORMATION",64)==0){
-		vol->at_volume_information=type;
-		check_type=0x70;
-	}else if(ntfs_ua_strncmp(name,"$DATA",64)==0){
-		vol->at_data=type;
-		check_type=0x80;
-	}else if(ntfs_ua_strncmp(name,"$INDEX_ROOT",64)==0){
-		vol->at_index_root=type;
-		check_type=0x90;
-	}else if(ntfs_ua_strncmp(name,"$INDEX_ALLOCATION",64)==0){
-		vol->at_index_allocation=type;
-		check_type=0xA0;
-	}else if(ntfs_ua_strncmp(name,"$BITMAP",64)==0){
-		vol->at_bitmap=type;
-		check_type=0xB0;
-	}else if(ntfs_ua_strncmp(name,"$SYMBOLIC_LINK",64)==0 ||
-		 ntfs_ua_strncmp(name,"$REPARSE_POINT",64)==0){
-		vol->at_symlink=type;
-		check_type=0xC0;
-	}
-	if(check_type && check_type!=type){
-		ntfs_error("Unexpected type %x for %x\n",type,check_type);
-		return EINVAL;
+	if (ntfs_ua_strncmp(name, "$STANDARD_INFORMATION", 64) == 0) {
+		vol->at_standard_information = type;
+		check_type = 0x10;
+	} else if (ntfs_ua_strncmp(name, "$ATTRIBUTE_LIST", 64) == 0) {
+		vol->at_attribute_list = type;
+		check_type = 0x20;
+	} else if (ntfs_ua_strncmp(name, "$FILE_NAME", 64) == 0) {
+		vol->at_file_name = type;
+		check_type = 0x30;
+	} else if (ntfs_ua_strncmp(name, "$VOLUME_VERSION", 64) == 0) {
+		vol->at_volume_version = type;
+		check_type = 0x40;
+	} else if (ntfs_ua_strncmp(name, "$SECURITY_DESCRIPTOR", 64) == 0) {
+		vol->at_security_descriptor = type;
+		check_type = 0x50;
+	} else if (ntfs_ua_strncmp(name, "$VOLUME_NAME", 64) == 0) {
+		vol->at_volume_name = type;
+		check_type = 0x60;
+	} else if (ntfs_ua_strncmp(name, "$VOLUME_INFORMATION", 64) == 0) {
+		vol->at_volume_information = type;
+		check_type = 0x70;
+	} else if (ntfs_ua_strncmp(name, "$DATA", 64) == 0) {
+		vol->at_data = type;
+		check_type = 0x80;
+	} else if (ntfs_ua_strncmp(name, "$INDEX_ROOT", 64) == 0) {
+		vol->at_index_root = type;
+		check_type = 0x90;
+	} else if (ntfs_ua_strncmp(name, "$INDEX_ALLOCATION", 64) == 0) {
+		vol->at_index_allocation = type;
+		check_type = 0xA0;
+	} else if (ntfs_ua_strncmp(name, "$BITMAP", 64) == 0) {
+		vol->at_bitmap = type;
+		check_type = 0xB0;
+	} else if (ntfs_ua_strncmp(name, "$SYMBOLIC_LINK", 64) == 0 ||
+		 ntfs_ua_strncmp(name, "$REPARSE_POINT", 64) == 0) {
+		vol->at_symlink = type;
+		check_type = 0xC0;
+	}
+	if (check_type && check_type != type) {
+		ntfs_error("Unexpected type %x for %x\n", type, check_type);
+		return -EINVAL;
 	}
 	return 0;
 }
 
-int
-ntfs_init_attrdef(ntfs_inode* attrdef)
+int ntfs_init_attrdef(ntfs_inode* attrdef)
 {
 	ntfs_u8 *buf;
 	ntfs_io io;
-	int offset,error,i;
+	int offset, error,i;
 	ntfs_attribute *data;
-	buf=ntfs_malloc(4050); /* 90*45 */
-	if(!buf)return ENOMEM;
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	io.do_read=1;
-	offset=0;
-	data=ntfs_find_attr(attrdef,attrdef->vol->at_data,0);
-	if(!data){
+
+	buf = ntfs_malloc(4050); /* 90*45 */
+	if (!buf)
+		return -ENOMEM;
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	io.do_read = 1;
+	offset = 0;
+	data = ntfs_find_attr(attrdef, attrdef->vol->at_data, 0);
+	if (!data) {
 		ntfs_free(buf);
-		return EINVAL;
+		return -EINVAL;
 	}
-	do{
-		io.param=buf;
-		io.size=4050;
-		error=ntfs_readwrite_attr(attrdef,data,offset,&io);
-		for(i=0;!error && i<io.size-0xA0;i+=0xA0)
-			error=process_attrdef(attrdef,buf+i);
-		offset+=4096;
-	}while(!error && io.size);
+	do {
+		io.param = buf;
+		io.size = 4050;
+		error = ntfs_readwrite_attr(attrdef, data, offset, &io);
+		for (i = 0; !error && i < io.size - 0xA0; i += 0xA0)
+			error = process_attrdef(attrdef, buf + i);
+		offset += 4096;
+	} while (!error && io.size);
 	ntfs_free(buf);
 	return error;
 }
 
-/* ntfs_get_version will determine the NTFS version of the 
-   volume and will return the version in a BCD format, with
-   the MSB being the major version number and the LSB the
-   minor one. Otherwise return <0 on error. 
-   Example: version 3.1 will be returned as 0x0301.
-   This has the obvious limitation of not coping with version
-   numbers above 0x80 but that shouldn't be a problem... */
+/* ntfs_get_version will determine the NTFS version of the volume and will
+ * return the version in a BCD format, with the MSB being the major version
+ * number and the LSB the minor one. Otherwise return <0 on error.
+ * Example: version 3.1 will be returned as 0x0301. This has the obvious
+ * limitation of not coping with version numbers above 0x80 but that shouldn't
+ * be a problem... */
 int ntfs_get_version(ntfs_inode* volume)
 {
 	ntfs_attribute *volinfo;
@@ -229,7 +244,8 @@
 		ntfs_error("Volume information attribute is not resident!\n");
 		return -EINVAL;
 	}
-	return ((ntfs_u8*)volinfo->d.data)[8] << 8 | ((ntfs_u8*)volinfo->d.data)[9];
+	return ((ntfs_u8*)volinfo->d.data)[8] << 8 | 
+	       ((ntfs_u8*)volinfo->d.data)[9];
 }
 
 int ntfs_load_special_files(ntfs_volume *vol)
@@ -237,119 +253,120 @@
 	int error;
 	ntfs_inode upcase, attrdef, volume;
 
-	vol->mft_ino=(ntfs_inode*)ntfs_calloc(3*sizeof(ntfs_inode));
-	error=ENOMEM;
-	ntfs_debug(DEBUG_BSD,"Going to load MFT\n");
-	if(!vol->mft_ino || (error=ntfs_init_inode(vol->mft_ino,vol,FILE_MFT)))
+	vol->mft_ino = (ntfs_inode*)ntfs_calloc(3 * sizeof(ntfs_inode));
+	error = -ENOMEM;
+	ntfs_debug(DEBUG_BSD, "Going to load MFT\n");
+	if (!vol->mft_ino || (error = ntfs_init_inode(vol->mft_ino, vol,
+						      FILE_$Mft)))
 	{
 		ntfs_error("Problem loading MFT\n");
 		return error;
 	}
-	ntfs_debug(DEBUG_BSD,"Going to load MIRR\n");
-	vol->mftmirr=vol->mft_ino+1;
-	if((error=ntfs_init_inode(vol->mftmirr,vol,FILE_MFTMIRR))){
-		ntfs_error("Problem %d loading MFTMirr\n",error);
+	ntfs_debug(DEBUG_BSD, "Going to load MIRR\n");
+	vol->mftmirr = vol->mft_ino + 1;
+	if ((error = ntfs_init_inode(vol->mftmirr, vol, FILE_$MftMirr))) {
+		ntfs_error("Problem %d loading MFTMirr\n", error);
 		return error;
 	}
-	ntfs_debug(DEBUG_BSD,"Going to load BITMAP\n");
-	vol->bitmap=vol->mft_ino+2;
-	if((error=ntfs_init_inode(vol->bitmap,vol,FILE_BITMAP))){
+	ntfs_debug(DEBUG_BSD, "Going to load BITMAP\n");
+	vol->bitmap = vol->mft_ino + 2;
+	if ((error = ntfs_init_inode(vol->bitmap, vol, FILE_$BitMap))) {
 		ntfs_error("Problem loading Bitmap\n");
 		return error;
 	}
-	ntfs_debug(DEBUG_BSD,"Going to load UPCASE\n");
-	error=ntfs_init_inode(&upcase,vol,FILE_UPCASE);
-	if(error)return error;
+	ntfs_debug(DEBUG_BSD, "Going to load UPCASE\n");
+	error = ntfs_init_inode(&upcase, vol, FILE_$UpCase);
+	if (error)
+		return error;
 	ntfs_init_upcase(&upcase);
 	ntfs_clear_inode(&upcase);
-	ntfs_debug(DEBUG_BSD,"Going to load ATTRDEF\n");
-	error=ntfs_init_inode(&attrdef,vol,FILE_ATTRDEF);
-	if(error)return error;
-	error=ntfs_init_attrdef(&attrdef);
+	ntfs_debug(DEBUG_BSD, "Going to load ATTRDEF\n");
+	error = ntfs_init_inode(&attrdef, vol, FILE_$AttrDef);
+	if (error)
+		return error;
+	error = ntfs_init_attrdef(&attrdef);
 	ntfs_clear_inode(&attrdef);
-	if(error)return error;
+	if (error)
+		return error;
 
-	/* Check for NTFS version and if Win2k version (ie. 3.0+)
-	   do not allow write access since the driver write support
-	   is broken, especially for Win2k. */
-	ntfs_debug(DEBUG_BSD,"Going to load VOLUME\n");
-	error = ntfs_init_inode(&volume,vol,FILE_VOLUME);
-	if (error) return error;
-	if ((error = ntfs_get_version(&volume)) >= 0x0300) {
+	/* Check for NTFS version and if Win2k version (ie. 3.0+) do not allow
+	 * write access since the driver write support is broken. */
+	ntfs_debug(DEBUG_BSD, "Going to load VOLUME\n");
+	error = ntfs_init_inode(&volume, vol, FILE_$Volume);
+	if (error)
+		return error;
+	if ((error = ntfs_get_version(&volume)) >= 0x0300 &&
+	    !(NTFS_SB(vol)->s_flags & MS_RDONLY)) {
 		NTFS_SB(vol)->s_flags |= MS_RDONLY;
-		ntfs_error("Warning! NTFS volume version is Win2k+: Mounting read-only\n");
+		ntfs_error("Warning! NTFS volume version is Win2k+: Mounting "
+			   "read-only\n");
 	}
 	ntfs_clear_inode(&volume);
-	if (error < 0) return error;
-	ntfs_debug(DEBUG_BSD, "NTFS volume is version %d.%d\n", error >> 8, error & 0xff);
-
+	if (error < 0)
+		return error;
+	ntfs_debug(DEBUG_BSD, "NTFS volume is version %d.%d\n", error >> 8,
+								error & 0xff);
 	return 0;
 }
 
 int ntfs_release_volume(ntfs_volume *vol)
 {
-	if(vol->mft_ino){
+	if (vol->mft_ino) {
 		ntfs_clear_inode(vol->mft_ino);
 		ntfs_clear_inode(vol->mftmirr);
 		ntfs_clear_inode(vol->bitmap);
 		ntfs_free(vol->mft_ino);
-		vol->mft_ino=0;
+		vol->mft_ino = 0;
 	}
 	ntfs_free(vol->mft);
 	ntfs_free(vol->upcase);
 	return 0;
 }
 
-/*
- * Writes the volume size into vol_size. Returns 0 if successful
- * or error.
- */
-int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size )
+/* Writes the volume size into vol_size. Returns 0 if successful or error. */
+int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size)
 {
 	ntfs_io io;
 	char *cluster0;
 
-	if( !vol_size )
-		return EFAULT;
-
-	cluster0=ntfs_malloc(vol->clustersize);
-	if( !cluster0 )
-		return ENOMEM;
-
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	io.param=cluster0;
-	io.do_read=1;
-	io.size=vol->clustersize;
-	ntfs_getput_clusters(vol,0,0,&io);
-	*vol_size = NTFS_GETU64(cluster0+0x28);
+	if (!vol_size)
+		return -EFAULT;
+	cluster0 = ntfs_malloc(vol->clustersize);
+	if (!cluster0)
+		return -ENOMEM;
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	io.param = cluster0;
+	io.do_read = 1;
+	io.size = vol->clustersize;
+	ntfs_getput_clusters(vol, 0, 0, &io);
+	*vol_size = NTFS_GETU64(cluster0 + 0x28) >> vol->clusterfactorbits;
 	ntfs_free(cluster0);
 	return 0;
 }
 
 static int nc[16]={4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0};
 
-int 
-ntfs_get_free_cluster_count(ntfs_inode *bitmap)
+int ntfs_get_free_cluster_count(ntfs_inode *bitmap)
 {
 	unsigned char bits[2048];
-	int offset,error;
-	int clusters=0;
+	int offset, error;
+	int clusters = 0;
 	ntfs_io io;
 
-	offset=0;
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	while(1)
-	{
+	offset = 0;
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	while (1) {
 		register int i;
-		io.param=bits;
-		io.size=2048;
-		error=ntfs_read_attr(bitmap,bitmap->vol->at_data,0,
-				     offset,&io);
-		if(error || io.size==0)break;
+		io.param = bits;
+		io.size = 2048;
+		error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, offset,
+									&io);
+		if (error || io.size == 0)
+			break;
 		/* I never thought I would do loop unrolling some day */
-		for(i=0;i<io.size-8;){
+		for (i = 0; i < io.size - 8; ) {
 			clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
 			clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
 			clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
@@ -359,261 +376,263 @@
 			clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
 			clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
 		}
-		for(;i<io.size;){
-			clusters+=nc[bits[i]>>4];clusters+=nc[bits[i++] & 0xF];
+		while (i < io.size) {
+			clusters += nc[bits[i] >> 4];
+			clusters += nc[bits[i++] & 0xF];
 		}
-		offset+=io.size;
+		offset += io.size;
 	}
 	return clusters;
 }
 
-/* Insert the fixups for the record. The number and location of the fixes 
-   is obtained from the record header */
+/* Insert the fixups for the record. The number and location of the fixes
+ * is obtained from the record header */
 void ntfs_insert_fixups(unsigned char *rec, int secsize)
 {
-	int first=NTFS_GETU16(rec+4);
-	int count=NTFS_GETU16(rec+6);
-	int offset=-2;
-	ntfs_u16 fix=NTFS_GETU16(rec+first);
-	fix=fix+1;
-	NTFS_PUTU16(rec+first,fix);
+	int first = NTFS_GETU16(rec + 4);
+	int count = NTFS_GETU16(rec + 6);
+	int offset = -2;
+	ntfs_u16 fix = NTFS_GETU16(rec + first);
+	
+	fix++;
+	if (fix == 0xffff || !fix)
+		fix = 1;
+	NTFS_PUTU16(rec + first, fix);
 	count--;
-	while(count--){
-		first+=2;
-		offset+=secsize;
-		NTFS_PUTU16(rec+first,NTFS_GETU16(rec+offset));
-		NTFS_PUTU16(rec+offset,fix);
+	while (count--) {
+		first += 2;
+		offset += secsize;
+		NTFS_PUTU16(rec + first, NTFS_GETU16(rec + offset));
+		NTFS_PUTU16(rec + offset, fix);
 	};
 }
 
-/* search the bitmap bits of l bytes for *cnt zero bits. Return the bit
-   number in *loc, which is initially set to the number of the first bit.
-   Return the largest block found in *cnt. Return 0 on success, ENOSPC if
-   all bits are used */
-static int 
-search_bits(unsigned char* bits,ntfs_cluster_t *loc,int *cnt,int l)
-{
-	unsigned char c=0;
-	int bc=0;
-	int bstart=0,bstop=0,found=0;
-	int start,stop=0,in=0;
+/* Search the bitmap bits of l bytes for *cnt zero bits. Return the bit number
+ * in *loc, which is initially set to the number of the first bit. Return the
+ * largest block found in *cnt. Return 0 on success, -ENOSPC if all bits are
+ * used. */
+static int search_bits(unsigned char* bits, ntfs_cluster_t *loc, int *cnt,int l)
+{
+	unsigned char c = 0;
+	int bc = 0;
+	int bstart = 0, bstop = 0, found = 0;
+	int start, stop = 0, in = 0;
 	/* special case searching for a single block */
-	if(*cnt==1){
-		while(l && *bits==0xFF){
+	if (*cnt == 1) {
+		while (l && *bits == 0xFF) {
 			bits++;
-			*loc+=8;
+			*loc += 8;
 			l--;
 		}
-		if(!l)return ENOSPC;
-		for(c=*bits;c & 1;c>>=1)
+		if (!l)
+			return -ENOSPC;
+		for (c = *bits; c & 1; c >>= 1)
 			(*loc)++;
 		return 0;
 	}
-	start=*loc;
-	while(l || bc){
-		if(bc==0){
-			c=*bits;
-			if(l){
-				l--;bits++;
+	start = *loc;
+	while (l || bc) {
+		if (bc == 0) {
+			c = *bits;
+			if (l) {
+				l--;
+				bits++;
 			}
-			bc=8;
+			bc = 8;
 		}
-		if(in){
-			if((c&1)==0)
+		if (in) {
+			if ((c & 1) == 0)
 				stop++;
-			else{ /* end of sequence of zeroes */
-				in=0;
-				if(!found || bstop-bstart<stop-start){
-					bstop=stop;bstart=start;found=1;
-					if(bstop-bstart>*cnt)
+			else { /* end of sequence of zeroes */
+				in = 0;
+				if (!found || bstop-bstart < stop-start) {
+					bstop = stop; bstart = start;
+					found = 1;
+					if (bstop - bstart > *cnt)
 						break;
 				}
-				start=stop+1;
+				start = stop + 1;
 			}
-		}else{
-			if(c&1)
+		} else {
+			if (c & 1)
 				start++;
-			else{ /*start of sequence*/
-				in=1;
-				stop=start+1;
+			else { /*start of sequence*/
+				in = 1;
+				stop = start + 1;
 			}
 		}
 		bc--;
-		c>>=1;
+		c >>= 1;
 	}
-	if(in && (!found || bstop-bstart<stop-start)){
-		bstop=stop;bstart=start;found=1;
+	if (in && (!found || bstop - bstart < stop - start)) {
+		bstop = stop; bstart = start; found = 1;
 	}
-	if(!found)return ENOSPC;
-	*loc=bstart;
-	if(*cnt>bstop-bstart)
-		*cnt=bstop-bstart;
+	if (!found)
+		return -ENOSPC;
+	*loc = bstart;
+	if (*cnt > bstop - bstart)
+		*cnt = bstop - bstart;
 	return 0;
 }
 
-int 
-ntfs_set_bitrange(ntfs_inode* bitmap,ntfs_cluster_t loc,int cnt,int bit)
+int ntfs_set_bitrange(ntfs_inode* bitmap, ntfs_cluster_t loc, int cnt, int bit)
 {
-	int bsize,locit,error;
-	unsigned char *bits,*it;
+	int bsize, locit, error;
+	unsigned char *bits, *it;
 	ntfs_io io;
 
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	bsize=(cnt+(loc & 7)+7) >> 3; /* round up to multiple of 8*/
-	bits=ntfs_malloc(bsize);
-	io.param=bits;
-	io.size=bsize;
-	if(!bits)
-		return ENOMEM;
-	error=ntfs_read_attr(bitmap,bitmap->vol->at_data,0,loc>>3,&io);
-	if(error || io.size!=bsize){
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	bsize = (cnt + (loc & 7) + 7) >> 3; /* round up to multiple of 8*/
+	bits = ntfs_malloc(bsize);
+	if (!bits)
+		return -ENOMEM;
+	io.param = bits;
+	io.size = bsize;
+	error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, loc >> 3, &io);
+	if (error || io.size != bsize){
 		ntfs_free(bits);
-		return error?error:EIO;
+		return error ? error : -EIO;
 	}
-	/* now set the bits */
-	it=bits;
-	locit=loc;
-	while(locit%8 && cnt){ /* process first byte */
-		if(bit)
-			*it |= 1<<(locit%8);
+	/* Now set the bits. */
+	it = bits;
+	locit = loc;
+	while (locit % 8 && cnt) { /* process first byte */
+		if (bit)
+			*it |= 1 << (locit % 8);
 		else
-			*it &= ~(1<<(locit%8));
-		cnt--;locit++;
-		if(locit%8==0)
+			*it &= ~(1 << (locit % 8));
+		cnt--;
+		locit++;
+		if (locit % 8 == 0)
 			it++;
 	}
-	while(cnt>8){ /*process full bytes */
-		*it= bit ? 0xFF : 0;
-		cnt-=8;
-		locit+=8;
+	while (cnt > 8) { /*process full bytes */
+		*it = bit ? 0xFF : 0;
+		cnt -= 8;
+		locit += 8;
 		it++;
 	}
-	while(cnt){ /*process last byte */
-		if(bit)
-			*it |= 1<<(locit%8);
+	while (cnt) { /*process last byte */
+		if (bit)
+			*it |= 1 << (locit % 8);
 		else
-			*it &= ~(1<<(locit%8));
-		cnt--;locit++;
+			*it &= ~(1 << (locit % 8));
+		cnt--;
+		locit++;
 	}
 	/* reset to start */
-	io.param=bits;
-	io.size=bsize;
-	error=ntfs_write_attr(bitmap,bitmap->vol->at_data,0,loc>>3,&io);
+	io.param = bits;
+	io.size = bsize;
+	error = ntfs_write_attr(bitmap, bitmap->vol->at_data, 0, loc >> 3, &io);
 	ntfs_free(bits);
-	if(error)return error;
-	if(io.size!=bsize)
-		return EIO;
+	if (error)
+		return error;
+	if (io.size != bsize)
+		return -EIO;
 	return 0;
 }
-  
-  
 	
-/* allocate count clusters around location. If location is -1,
-   it does not matter where the clusters are. Result is 0 if
-   success, in which case location and count says what they really got */
-int 
-ntfs_search_bits(ntfs_inode* bitmap, ntfs_cluster_t *location, int *count, int flags)
+/* Allocate count clusters around location. If location is -1, it does not
+ * matter where the clusters are. Result is 0 if success, in which case
+ * location and count says what they really got. */
+int ntfs_search_bits(ntfs_inode* bitmap, ntfs_cluster_t *location, int *count,
+		     int flags)
 {
 	unsigned char *bits;
 	ntfs_io io;
-	int error=0,found=0;
-	int cnt,bloc=-1,bcnt=0;
+	int error = 0, found = 0;
+	int cnt, bloc = -1, bcnt = 0;
 	int start;
 	ntfs_cluster_t loc;
 
-	bits=ntfs_malloc(2048);
-	if( !bits )
-		return ENOMEM;
-	io.fn_put=ntfs_put;
-	io.fn_get=ntfs_get;
-	io.param=bits;
+	bits = ntfs_malloc(2048);
+	if (!bits)
+		return -ENOMEM;
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	io.param = bits;
 
 	/* first search within +/- 8192 clusters */
-	start=*location>>3;
-	start= start>1024 ? start-1024 : 0;
-	io.size=2048;
-	error=ntfs_read_attr(bitmap,bitmap->vol->at_data,0,start,&io);
-	if(error)goto fail;
-	loc=start*8;
-	cnt=*count;
-	error=search_bits(bits,&loc,&cnt,io.size);
-	if(error)
+	start = *location >> 3;
+	start = start > 1024 ? start - 1024 : 0;
+	io.size = 2048;
+	error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, start, &io);
+	if (error)
 		goto fail;
-	if(*count==cnt){
-		bloc=loc;
-		bcnt=cnt;
+	loc = start * 8;
+	cnt = *count;
+	error = search_bits(bits, &loc, &cnt, io.size);
+	if (error)
+		goto fail;
+	if (*count == cnt){
+		bloc = loc;
+		bcnt = cnt;
 		goto success;
 	}
-
-	/* now search from the beginning */
-	for(start=0;1;start+=2048)
-	{
-		io.param=bits;
-		io.size=2048;
-		error=ntfs_read_attr(bitmap,bitmap->vol->at_data,
-				     0,start,&io);
-		if(error)goto fail;
-		if(io.size==0){
+	/* Now search from the beginning. */
+	for (start = 0; 1; start += 2048) {
+		io.param = bits;
+		io.size = 2048;
+		error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, start,
+									&io);
+		if (error)
+			goto fail;
+		if (io.size == 0) {
 			if(found)
 				goto success;
-			else{
-				error=ENOSPC;
+			else {
+				error = -ENOSPC;
 				goto fail;
 			}
 		}
-		loc=start*8;
-		cnt=*count;
-		error=search_bits(bits,&loc,&cnt,io.size);
-		if(error)
+		loc = start * 8;
+		cnt = *count;
+		error = search_bits(bits, &loc, &cnt, io.size);
+		if (error)
 			goto fail;
-		if(*count==cnt)
+		if (*count == cnt)
 			goto success;
-		if(bcnt<cnt){
-			bcnt=cnt;
-			bloc=loc;
-			found=1;
+		if (bcnt < cnt) {
+			bcnt = cnt;
+			bloc = loc;
+			found = 1;
 		}
 	}
  success:
 	ntfs_free(bits);
 	/* check flags */
-	if((flags & ALLOC_REQUIRE_LOCATION) && *location!=bloc)
-		error=ENOSPC;
-	else if((flags & ALLOC_REQUIRE_SIZE) && *count!=bcnt)
-		error=ENOSPC;
-	else ntfs_set_bitrange(bitmap,bloc,bcnt,1);
-	/* If allocation failed due to the flags, tell the caller what he
-	   could have gotten */
-	*location=bloc;
-	*count=bcnt;
+	if ((flags & ALLOC_REQUIRE_LOCATION) && *location != bloc)
+		error = -ENOSPC;
+	else if ((flags & ALLOC_REQUIRE_SIZE) && *count != bcnt)
+		error = -ENOSPC;
+	else
+		ntfs_set_bitrange(bitmap, bloc, bcnt, 1);
+	/* If allocation failed due to the flags, tell the caller what he could
+	 * have gotten */
+	*location = bloc;
+	*count = bcnt;
 	return 0;
  fail:
-	*location=-1;
-	*count=0;
+	*location = -1;
+	*count = 0;
 	ntfs_free(bits);
 	return error;
 }
 
-int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location, int *count,
-	int flags)
+int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location,
+			   int *count, int flags)
 {
 	int error;
-	error=ntfs_search_bits(vol->bitmap,location,count,flags);
+	error = ntfs_search_bits(vol->bitmap, location, count, flags);
 	return error;
 }
 
-int ntfs_deallocate_clusters(ntfs_volume *vol, ntfs_cluster_t location, int count)
+int ntfs_deallocate_clusters(ntfs_volume *vol, ntfs_cluster_t location,
+			     int count)
 {
 	int error;
-	error=ntfs_set_bitrange(vol->bitmap,location,count,0);
+	error = ntfs_set_bitrange(vol->bitmap, location, count, 0);
 	return error;
 }
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
-
 
diff -urN linux-2.4.4-pre4/fs/ntfs/super.h linux/fs/ntfs/super.h
--- linux-2.4.4-pre4/fs/ntfs/super.h	Thu Dec  9 13:14:30 1999
+++ linux/fs/ntfs/super.h	Mon Dec  3 22:35:56 2001
@@ -1,6 +1,4 @@
-/*
- *  super.h
- *  Header file for super.c
+/*  super.h - Header file for super.c
  *
  *  Copyright (C) 1995-1997 Martin von Löwis
  *  Copyright (C) 1996-1997 Régis Duchesne
@@ -10,12 +8,22 @@
 #define ALLOC_REQUIRE_SIZE     2
 
 int ntfs_get_free_cluster_count(ntfs_inode *bitmap);
+
 int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size );
-int ntfs_init_volume(ntfs_volume *vol,char *boot);
+
+int ntfs_init_volume(ntfs_volume *vol, char *boot);
+
 int ntfs_load_special_files(ntfs_volume *vol);
+
 int ntfs_release_volume(ntfs_volume *vol);
+
 void ntfs_insert_fixups(unsigned char *rec, int secsize);
+
 int ntfs_fixup_record(ntfs_volume *vol, char *record, char *magic, int size);
-int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location, int *count,
-  int flags);
-int ntfs_deallocate_clusters(ntfs_volume *vol, ntfs_cluster_t location, int count);
+
+int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location,
+			   int *count, int flags);
+
+int ntfs_deallocate_clusters(ntfs_volume *vol, ntfs_cluster_t location,
+			     int count);
+
diff -urN linux-2.4.4-pre4/fs/ntfs/support.c linux/fs/ntfs/support.c
--- linux-2.4.4-pre4/fs/ntfs/support.c	Tue Sep  5 14:07:30 2000
+++ linux/fs/ntfs/support.c	Mon Dec  3 22:35:56 2001
@@ -1,15 +1,10 @@
-/*
- *  support.c
- *  Specific support functions
+/*  support.c -  Specific support functions
  *
  *  Copyright (C) 1997 Martin von Löwis
  *  Copyright (C) 1997 Régis Duchesne
- *
+ *  Copyright (C) 2001 Anton Altaparmakov (AIA)
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
 #include "ntfstypes.h"
 #include "struct.h"
 #include "support.h"
@@ -64,7 +59,7 @@
 	kfree(block);
 }
 #endif
-#else
+#else /* End of DEBUG functions. Normal ones below... */
 void ntfs_debug(int mask, const char *fmt, ...)
 {
 }
@@ -102,7 +97,7 @@
 	memmove(dest, src, n);
 }
 
-/* Warn that an error occured. */
+/* Warn that an error occurred. */
 void ntfs_error(const char *fmt,...)
 {
         va_list ap;
@@ -120,68 +115,72 @@
 	ntfs_io io;
 
 	ntfs_debug(DEBUG_OTHER, "read_mft_record %x\n",mftno);
-	if(mftno==FILE_MFT)
+	if(mftno == FILE_$Mft)
 	{
-		ntfs_memcpy(buf,vol->mft,vol->mft_recordsize);
+		ntfs_memcpy(buf, vol->mft, vol->mft_recordsize);
 		return 0;
 	}
 	if(!vol->mft_ino)
 	{
-		printk("ntfs:something is terribly wrong here\n");
-		return ENODATA;
+		printk(KERN_ERR "NTFS: mft_ino is NULL. Something is terribly "
+				"wrong here!\n");
+		return -ENODATA;
 	}
- 	io.fn_put=ntfs_put;
-	io.fn_get=0;
-	io.param=buf;
-	io.size=vol->mft_recordsize;
-	error=ntfs_read_attr(vol->mft_ino,vol->at_data,NULL,
-			     mftno*vol->mft_recordsize,&io);
-	if(error || (io.size!=vol->mft_recordsize))
+ 	io.fn_put = ntfs_put;
+	io.fn_get = 0;
+	io.param = buf;
+	io.size = vol->mft_recordsize;
+	error = ntfs_read_attr(vol->mft_ino, vol->at_data, NULL,
+					mftno * vol->mft_recordsize, &io);
+	if (error || (io.size != vol->mft_recordsize))
 	{
-		ntfs_debug(DEBUG_OTHER, "read_mft_record: read %x failed (%d,%d,%d)\n",
-			   mftno,error,io.size,vol->mft_recordsize);
-		return error?error:ENODATA;
+		ntfs_debug(DEBUG_OTHER, "read_mft_record: read %x failed "
+				   	"(%d,%d,%d)\n", mftno, error, io.size,
+				   	vol->mft_recordsize);
+		return error ? error : -ENODATA;
 	}
-	ntfs_debug(DEBUG_OTHER, "read_mft_record: finished read %x\n",mftno);
-	if(!ntfs_check_mft_record(vol,buf))
+	ntfs_debug(DEBUG_OTHER, "read_mft_record: finished read %x\n", mftno);
+	if(!ntfs_check_mft_record(vol, buf))
 	{
-		printk("Invalid MFT record for %x\n",mftno);
-		return EINVAL;
+		/* FIXME: This is incomplete behaviour. We might be able to
+		 * recover at this stage. ntfs_check_mft_record() is too
+		 * conservative at aborting it's operations. It is OK for
+		 * now as we just can't handle some on disk structures
+		 * this way. (AIA) */
+		printk(KERN_WARNING "NTFS: Invalid MFT record for %x\n", mftno);
+		return -EINVAL;
 	}
-	ntfs_debug(DEBUG_OTHER, "read_mft_record: Done %x\n",mftno);
+	ntfs_debug(DEBUG_OTHER, "read_mft_record: Done %x\n", mftno);
 	return 0;
 }
 
 int ntfs_getput_clusters(ntfs_volume *vol, int cluster,	ntfs_size_t start_offs,
-	 ntfs_io *buf)
+			 ntfs_io *buf)
 {
-	struct super_block *sb=NTFS_SB(vol);
+	struct super_block *sb = NTFS_SB(vol);
 	struct buffer_head *bh;
 	ntfs_size_t to_copy;
-	int length=buf->size;
-	if(buf->do_read)
-		ntfs_debug(DEBUG_OTHER, "get_clusters %d %d %d\n",cluster,start_offs,length);
-	else
-		ntfs_debug(DEBUG_OTHER, "put_clusters %d %d %d\n",cluster,start_offs,length);
-	while(length)
-	{
-		if(!(bh=bread(sb->s_dev,cluster,vol->clustersize)))
-		{
-			ntfs_debug(DEBUG_OTHER, "%s failed\n", buf->do_read?"Reading":"Writing");
-			return EIO;
+	int length = buf->size;
+
+	ntfs_debug(DEBUG_OTHER, "%s_clusters %d %d %d\n", 
+		   buf->do_read ? "get" : "put", cluster, start_offs, length);
+	while (length) {
+		if (!(bh = bread(sb->s_dev, cluster, vol->clustersize))) {
+			ntfs_debug(DEBUG_OTHER, "%s failed\n",
+				   buf->do_read ? "Reading" : "Writing");
+			return -EIO;
 		}
-		to_copy=min(vol->clustersize-start_offs,length);
+		to_copy = min(vol->clustersize - start_offs, length);
 		lock_buffer(bh);
-		if(buf->do_read)
-			buf->fn_put(buf,bh->b_data+start_offs,to_copy);
-		else
-		{
-			buf->fn_get(bh->b_data+start_offs,buf,to_copy);
+		if (buf->do_read)
+			buf->fn_put(buf, bh->b_data + start_offs, to_copy);
+		else {
+			buf->fn_get(bh->b_data + start_offs, buf, to_copy);
 			mark_buffer_dirty(bh);
 		}
 		unlock_buffer(bh);
-		length-=to_copy;
-		start_offs=0;
+		length -= to_copy;
+		start_offs = 0;
 		cluster++;
 		brelse(bh);
 	}
@@ -193,152 +192,147 @@
 	return ntfs_unixutc2ntutc(CURRENT_TIME);
 }
 
-/* when printing unicode characters base64, use this table.
-   It is not strictly base64, but the Linux vfat encoding.
-   base64 has the disadvantage of using the slash.
-*/
-static char uni2esc[64]=
-  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-";
-
-static unsigned char
-esc2uni(char c)
-{
-	if(c<'0')return 255;
-	if(c<='9')return c-'0';
-	if(c<'A')return 255;
-	if(c<='Z')return c-'A'+10;
-	if(c<'a')return 255;
-	if(c<='z')return c-'a'+36;
-	if(c=='+')return 62;
-	if(c=='-')return 63;
+/* When printing unicode characters base64, use this table. It is not strictly
+ * base64, but the Linux vfat encoding. base64 has the disadvantage of using
+ * the slash. */
+static char uni2esc[64] = 
+	    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-";
+
+static unsigned char esc2uni(char c)
+{
+	if (c <  '0') return 255;
+	if (c <= '9') return c - '0';
+	if (c <  'A') return 255;
+	if (c <= 'Z') return c - 'A' + 10;
+	if (c <  'a') return 255;
+	if (c <= 'z') return c - 'a' + 36;
+	if (c == '+') return 62;
+	if (c == '-') return 63;
 	return 255;
 }
 
 int ntfs_dupuni2map(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out,
-  int *out_len)
+		    int *out_len)
 {
-	int i,o,val,chl, chi;
-	char *result,*buf,charbuf[NLS_MAX_CHARSET_SIZE];
-	struct nls_table* nls=vol->nls_map;
-
-	result=ntfs_malloc(in_len+1);
-	if(!result)return ENOMEM;
-	*out_len=in_len;
-	result[in_len]='\0';
-	for(i=o=0;i<in_len;i++){
-		int cl,ch;
+	int i, o, val, chl, chi;
+	char *result, *buf, charbuf[NLS_MAX_CHARSET_SIZE];
+	struct nls_table* nls = vol->nls_map;
+
+	result = ntfs_malloc(in_len + 1);
+	if (!result)
+		return -ENOMEM;
+	*out_len = in_len;
+	result[in_len] = '\0';
+	for (i = o = 0; i < in_len; i++) {
+		int cl, ch;
 		/* FIXME: byte order? */
-		cl=in[i] & 0xFF;
-		ch=(in[i] >> 8) & 0xFF;
-		if(!nls){
-			if(!ch){
-				result[o++]=cl;
+		cl = in[i] & 0xFF;
+		ch = (in[i] >> 8) & 0xFF;
+		if (!nls) {
+			if (!ch) {
+				result[o++] = cl;
 				continue;
 			}
-		}else{
+		} else {
 			/* FIXME: byte order? */
 			wchar_t uni = in[i];
-			if ( (chl = nls->uni2char(uni, charbuf, NLS_MAX_CHARSET_SIZE)) > 0){
+			if ((chl = nls->uni2char(uni, charbuf,
+						NLS_MAX_CHARSET_SIZE)) > 0) {
 				/* adjust result buffer */
-				if (chl > 1){
-					buf=ntfs_malloc(*out_len + chl - 1);
+				if (chl > 1) {
+					buf = ntfs_malloc(*out_len + chl - 1);
 					memcpy(buf, result, o);
 					ntfs_free(result);
-					result=buf;
-					*out_len+=(chl-1);
+					result = buf;
+					*out_len += (chl - 1);
 				}
-				for (chi=0;chi<chl;chi++)
+				for (chi = 0; chi < chl; chi++)
 					result[o++] = charbuf[chi];
 			} else
 				result[o++] = '?';
 			continue;
-
 		}
-		if(!(vol->nct & nct_uni_xlate))goto inval;
+		if (!(vol->nct & nct_uni_xlate))
+			goto inval;
 		/* realloc */
-		buf=ntfs_malloc(*out_len+3);
-		if( !buf ) {
-			ntfs_free( result );
-			return ENOMEM;
+		buf = ntfs_malloc(*out_len + 3);
+		if (!buf) {
+			ntfs_free(result);
+			return -ENOMEM;
 		}
-		memcpy(buf,result,o);
+		memcpy(buf, result, o);
 		ntfs_free(result);
-		result=buf;
-		*out_len+=3;
-		result[o++]=':';
-		if(vol->nct & nct_uni_xlate_vfat){
-			val=(cl<<8)+ch;
-			result[o+2]=uni2esc[val & 0x3f];
-			val>>=6;
-			result[o+1]=uni2esc[val & 0x3f];
-			val>>=6;
-			result[o]=uni2esc[val & 0x3f];
-			o+=3;
-		}else{
-			val=(ch<<8)+cl;
-			result[o++]=uni2esc[val & 0x3f];
-			val>>=6;
-			result[o++]=uni2esc[val & 0x3f];
-			val>>=6;
-			result[o++]=uni2esc[val & 0x3f];
+		result = buf;
+		*out_len += 3;
+		result[o++] = ':';
+		if (vol->nct & nct_uni_xlate_vfat) {
+			val = (cl << 8) + ch;
+			result[o+2] = uni2esc[val & 0x3f];
+			val >>= 6;
+			result[o+1] = uni2esc[val & 0x3f];
+			val >>= 6;
+			result[o] = uni2esc[val & 0x3f];
+			o += 3;
+		} else {
+			val = (ch << 8) + cl;
+			result[o++] = uni2esc[val & 0x3f];
+			val >>= 6;
+			result[o++] = uni2esc[val & 0x3f];
+			val >>= 6;
+			result[o++] = uni2esc[val & 0x3f];
 		}
 	}
-	*out=result;
+	*out = result;
 	return 0;
  inval:
 	ntfs_free(result);
-	*out=0;
-	return EILSEQ;
+	*out = 0;
+	return -EILSEQ;
 }
 
 int ntfs_dupmap2uni(ntfs_volume *vol, char* in, int in_len, ntfs_u16 **out,
-  int *out_len)
+		    int *out_len)
 {
-	int i,o;
+	int i, o;
 	ntfs_u16* result;
-	struct nls_table* nls=vol->nls_map;
+	struct nls_table* nls = vol->nls_map;
 
-	*out=result=ntfs_malloc(2*in_len);
-	if(!result)return ENOMEM;
-	*out_len=in_len;
-	for(i=o=0;i<in_len;i++,o++){
+	*out=result = ntfs_malloc(2 * in_len);
+	if (!result)
+		return -ENOMEM;
+	*out_len = in_len;
+	for (i = o = 0; i < in_len; i++, o++){
 		wchar_t uni;
-		if(in[i]!=':' || (vol->nct & nct_uni_xlate)==0){
+		if (in[i] != ':' || (vol->nct & nct_uni_xlate) == 0){
 			int charlen;
-			/* FIXME: is this error handling ok? */
 			charlen = nls->char2uni(&in[i], in_len-i, &uni);
 			if (charlen < 0)
 				return charlen;
-			*out_len -= (charlen-1);
-			i += (charlen-1);
-		}else{
-			unsigned char c1,c2,c3;
-			*out_len-=3;
-			c1=esc2uni(in[++i]);
-			c2=esc2uni(in[++i]);
-			c3=esc2uni(in[++i]);
-			if(c1==255 || c2==255 || c3==255)
+			*out_len -= (charlen - 1);
+			i += (charlen - 1);
+		} else {
+			unsigned char c1, c2, c3;
+			*out_len -= 3;
+			c1 = esc2uni(in[++i]);
+			c2 = esc2uni(in[++i]);
+			c3 = esc2uni(in[++i]);
+			if (c1 == 255 || c2 == 255 || c3 == 255)
 				uni = 0;
-			else if(vol->nct & nct_uni_xlate_vfat){
+			else if (vol->nct & nct_uni_xlate_vfat) {
 				uni = (((c2 & 0x3) << 6) + c3) << 8 |
-					((c1 << 4) + (c2 >> 2));
-			}else{
+				      ((c1 << 4) + (c2 >> 2));
+			} else {
 				uni = ((c3 << 4) + (c2 >> 2)) << 8 |
-					(((c2 & 0x3) << 6) + c1);
+				      (((c2 & 0x3) << 6) + c1);
 			}
 		}
 		/* FIXME: byte order? */
 		result[o] = uni;
-		if(!result[o]){
+		if (!result[o]) {
 			ntfs_free(result);
-			return EILSEQ;
+			return -EILSEQ;
 		}
 	}
 	return 0;
 }
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/ntfs/support.h linux/fs/ntfs/support.h
--- linux-2.4.4-pre4/fs/ntfs/support.h	Mon Dec 11 13:26:39 2000
+++ linux/fs/ntfs/support.h	Mon Dec  3 22:35:56 2001
@@ -1,6 +1,4 @@
-/*
- *  support.h
- *  Header file for specific support.c
+/*  support.h - Header file for specific support.c
  *
  *  Copyright (C) 1997 Régis Duchesne
  */
@@ -20,29 +18,31 @@
 #define DEBUG_NAME2  2048
 
 void ntfs_debug(int mask, const char *fmt, ...);
-#ifdef NTFS_IN_LINUX_KERNEL
+
 #include <linux/slab.h>
-#define ntfs_malloc(size)  kmalloc(size,GFP_KERNEL)
+
+#define ntfs_malloc(size)  kmalloc(size, GFP_KERNEL)
+
 #define ntfs_free(ptr)     kfree(ptr)
-#else
-void *ntfs_malloc(int size);
-void ntfs_free(void *block);
-#endif
+
 void ntfs_bzero(void *s, int n);
+
 void ntfs_memcpy(void *dest, const void *src, ntfs_size_t n);
+
 void ntfs_memmove(void *dest, const void *src, ntfs_size_t n);
+
 void ntfs_error(const char *fmt,...);
+
 int ntfs_read_mft_record(ntfs_volume *vol, int mftno, char *buf);
+
 int ntfs_getput_clusters(ntfs_volume *pvol, int cluster, ntfs_size_t offs,
-        ntfs_io *buf);
+			 ntfs_io *buf);
+
 ntfs_time64_t ntfs_now(void);
+
 int ntfs_dupuni2map(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out,
-        int *out_len);
+		    int *out_len);
+
 int ntfs_dupmap2uni(ntfs_volume *vol, char* in, int in_len, ntfs_u16 **out,
-        int *out_len);
+		    int *out_len);
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/ntfs/sysctl.h linux/fs/ntfs/sysctl.h
--- linux-2.4.4-pre4/fs/ntfs/sysctl.h	Sat Jan  2 10:24:46 1999
+++ linux/fs/ntfs/sysctl.h	Mon Dec  3 22:35:56 2001
@@ -1,28 +1,17 @@
-/*
- *  sysctl.h
- *  Header file for sysctl.c
+/*  sysctl.h - Header file for sysctl.c
  *
  *  Copyright (C) 1997 Martin von Löwis
  *  Copyright (C) 1997 Régis Duchesne
  *
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #ifdef DEBUG
-extern int ntdebug;
+	extern int ntdebug;
 
-void ntfs_sysctl(int add);
+	void ntfs_sysctl(int add);
 
-#define SYSCTL(x)	ntfs_sysctl(x)
+	#define SYSCTL(x)	ntfs_sysctl(x)
 #else
-#define SYSCTL(x)
+	#define SYSCTL(x)
 #endif /* DEBUG */
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/ntfs/util.c linux/fs/ntfs/util.c
--- linux-2.4.4-pre4/fs/ntfs/util.c	Tue May  2 13:46:53 2000
+++ linux/fs/ntfs/util.c	Mon Dec  3 22:35:56 2001
@@ -1,9 +1,8 @@
-/*
- *  util.c
- *  Miscellaneous support
+/*  util.c -  Miscellaneous support
  *
  *  Copyright (C) 1997,1999 Martin von Löwis
  *  Copyright (C) 1997 Régis Duchesne
+ *  Copyright (C) 2001 Anton Altaparmakov (AIA)
  *
  *  The utf8 routines are copied from Python wstrop module.
  */
@@ -14,75 +13,66 @@
 
 #include <linux/string.h>
 #include <linux/errno.h>
-/* FreeBSD doesn't seem to have EILSEQ in errno.h */
-#ifndef EILSEQ
-# define EILSEQ	EINVAL
-#endif
 #include "support.h"
 
 /* Converts a single wide character to a sequence of utf8 bytes.
  * The character is represented in host byte order.
- * Returns the number of bytes, or 0 on error.
- */
-static int
-to_utf8(ntfs_u16 c,unsigned char* buf)
+ * Returns the number of bytes, or 0 on error. */
+static int to_utf8(ntfs_u16 c, unsigned char* buf)
 {
-	if(c==0)
-		return 0; /* No support for embedded 0 runes */
-	if(c<0x80){
-		if(buf)buf[0]=(unsigned char)c;
+	if (c == 0)
+		return 0; /* No support for embedded 0 runes. */
+	if (c < 0x80) {
+		if (buf)
+			buf[0] = (unsigned char)c;
 		return 1;
 	}
-	if(c<0x800){
-		if(buf){
-			buf[0] = 0xc0 | (c>>6);
+	if (c < 0x800) {
+		if (buf) {
+			buf[0] = 0xc0 | (c >> 6);
 			buf[1] = 0x80 | (c & 0x3f);
 		}
 		return 2;
 	}
-	if(c<0x10000){
-		if(buf){
-			buf[0] = 0xe0 | (c>>12);
-			buf[1] = 0x80 | ((c>>6) & 0x3f);
+	if (c < 0x10000) {
+		if (buf) {
+			buf[0] = 0xe0 | (c >> 12);
+			buf[1] = 0x80 | ((c >> 6) & 0x3f);
 			buf[2] = 0x80 | (c & 0x3f);
 		}
 		return 3;
 	}
-	/* We don't support characters above 0xFFFF in NTFS */
+	/* We don't support characters above 0xFFFF in NTFS. */
 	return 0;
 }
 
 /* Decodes a sequence of utf8 bytes into a single wide character.
  * The character is returned in host byte order.
- * Returns the number of bytes consumed, or 0 on error.
- */
-static int
-from_utf8(const unsigned char* str,ntfs_u16 *c)
+ * Returns the number of bytes consumed, or 0 on error. */
+static int from_utf8(const unsigned char* str, ntfs_u16 *c)
 {
-	int l=0,i;
+	int l = 0, i;
 
-	if(*str<0x80){
+	if (*str < 0x80) {
 		*c = *str;
 		return 1;
 	}
-	if(*str<0xc0) /* lead byte must not be 10xxxxxx */
-		return 0;   /* is c0 a possible lead byte? */
-	if(*str<0xe0){         /* 110xxxxx */
+	if (*str < 0xc0)	/* Lead byte must not be 10xxxxxx. */
+		return 0;	/* Is c0 a possible lead byte? */
+	if (*str < 0xe0) {		/* 110xxxxx */
 		*c = *str & 0x1f;
-		l=2;
-	}else if(*str<0xf0){   /* 1110xxxx */
+		l = 2;
+	} else if (*str < 0xf0) {	/* 1110xxxx */
 		*c = *str & 0xf;
-		l=3;
-	}else if(*str<0xf8){   /* 11110xxx */
+		l = 3;
+	} else if (*str < 0xf8) {   	/* 11110xxx */
 		*c = *str & 7;
-		l=4;
-	}else /* We don't support characters above 0xFFFF in NTFS */
+		l = 4;
+	} else /* We don't support characters above 0xFFFF in NTFS. */
 		return 0;
-	 
-
-	for(i=1;i<l;i++){
-		/* all other bytes must be 10xxxxxx */
-		if((str[i] & 0xc0) != 0x80)
+	for (i = 1; i < l; i++) {
+		/* All other bytes must be 10xxxxxx. */
+		if ((str[i] & 0xc0) != 0x80)
 			return 0;
 		*c <<= 6;
 		*c |= str[i] & 0x3f;
@@ -93,196 +83,195 @@
 /* Converts wide string to UTF-8. Expects two in- and two out-parameters.
  * Returns 0 on success, or error code. 
  * The caller has to free the result string.
- * There is no support for UTF-16, yet
- */
-static int ntfs_dupuni2utf8(ntfs_u16* in, int in_len,char **out,int *out_len)
+ * There is no support for UTF-16, yet. */
+static int ntfs_dupuni2utf8(ntfs_u16* in, int in_len, char **out, int *out_len)
 {
-	int i,tmp;
+	int i, tmp;
 	int len8;
 	unsigned char *result;
 
-	ntfs_debug(DEBUG_NAME1,"converting l=%d\n",in_len);
-	/* count the length of the resulting UTF-8 */
-	for(i=len8=0;i<in_len;i++){
-		tmp=to_utf8(NTFS_GETU16(in+i),0);
-		if(!tmp)
+	ntfs_debug(DEBUG_NAME1, "converting l = %d\n", in_len);
+	/* Count the length of the resulting UTF-8. */
+	for (i = len8 = 0; i < in_len; i++){
+		tmp = to_utf8(NTFS_GETU16(in + i), 0);
+		if (!tmp)
 			/* invalid character */
-			return EILSEQ;
-		len8+=tmp;
+			return -EILSEQ;
+		len8 += tmp;
 	}
-	*out=result=ntfs_malloc(len8+1); /* allow for zero-termination */
+	*out = result = ntfs_malloc(len8 + 1); /* allow for zero-termination */
 
-	if(!result)
-		return ENOMEM;
-	result[len8]='\0';
-	*out_len=len8;
-	for(i=len8=0;i<in_len;i++)
-		len8+=to_utf8(NTFS_GETU16(in+i),result+len8);
-	ntfs_debug(DEBUG_NAME1,"result %p:%s\n",result,result);
+	if (!result)
+		return -ENOMEM;
+	result[len8] = '\0';
+	*out_len = len8;
+	for (i = len8 = 0; i < in_len; i++)
+		len8 += to_utf8(NTFS_GETU16(in + i), result + len8);
+	ntfs_debug(DEBUG_NAME1, "result %p:%s\n", result, result);
 	return 0;
 }
 
 /* Converts an UTF-8 sequence to a wide string. Same conventions as the
- * previous function
- */
-static int ntfs_duputf82uni(unsigned char* in, int in_len,ntfs_u16** out,int *out_len)
+ * previous function. */
+static int ntfs_duputf82uni(unsigned char* in, int in_len, ntfs_u16** out,
+			    int *out_len)
 {
-	int i,tmp;
+	int i, tmp;
 	int len16;
-
 	ntfs_u16* result;
 	ntfs_u16 wtmp;
-	for(i=len16=0;i<in_len;i+=tmp,len16++){
-		tmp=from_utf8(in+i,&wtmp);
-		if(!tmp)
-			return EILSEQ;
-	}
-	*out=result=ntfs_malloc(2*(len16+1));
-	if(!result)
-		return ENOMEM;
-	result[len16]=0;
-	*out_len=len16;
-	for(i=len16=0;i<in_len;i+=tmp,len16++)
+
+	for (i = len16 = 0; i < in_len; i += tmp, len16++) {
+		tmp = from_utf8(in + i, &wtmp);
+		if (!tmp)
+			return -EILSEQ;
+	}
+	*out = result = ntfs_malloc(2 * (len16 + 1));
+	if (!result)
+		return -ENOMEM;
+	result[len16] = 0;
+	*out_len = len16;
+	for (i = len16 = 0; i < in_len; i += tmp, len16++)
 	{
-		tmp=from_utf8(in+i, &wtmp);
-		NTFS_PUTU16(result+len16, wtmp);
+		tmp = from_utf8(in + i, &wtmp);
+		NTFS_PUTU16(result + len16, wtmp);
 	}
 	return 0;
 }
 
-/* See above. Produces ISO-8859-1 from wide strings */
-static int ntfs_dupuni288591(ntfs_u16* in,int in_len,char** out,int *out_len)
+/* See above. Produces ISO-8859-1 from wide strings. */
+static int ntfs_dupuni288591(ntfs_u16* in, int in_len, char** out, int *out_len)
 {
 	int i;
 	char *result;
 
-	/* check for characters out of range */
-	for(i=0;i<in_len;i++)
-		if(NTFS_GETU16(in+i)>=256)
-			return EILSEQ;
-	*out=result=ntfs_malloc(in_len+1);
-	if(!result)
-		return ENOMEM;
-	result[in_len]='\0';
-	*out_len=in_len;
-	for(i=0;i<in_len;i++)
-		result[i]=(unsigned char)NTFS_GETU16(in+i);
+	/* Check for characters out of range. */
+	for (i = 0; i < in_len; i++)
+		if (NTFS_GETU16(in + i) >= 256)
+			return -EILSEQ;
+	*out = result = ntfs_malloc(in_len + 1);
+	if (!result)
+		return -ENOMEM;
+	result[in_len] = '\0';
+	*out_len = in_len;
+	for (i = 0; i < in_len; i++)
+		result[i] = (unsigned char)NTFS_GETU16(in + i);
 	return 0;
 }
 
-/* See above */
-static int ntfs_dup885912uni(unsigned char* in,int in_len,ntfs_u16 **out,int *out_len)
+/* See above. */
+static int ntfs_dup885912uni(unsigned char* in, int in_len, ntfs_u16 **out,
+			     int *out_len)
 {
 	int i;
 
 	ntfs_u16* result;
-	*out=result=ntfs_malloc(2*in_len);
-	if(!result)
-		return ENOMEM;
-	*out_len=in_len;
-	for(i=0;i<in_len;i++)
-		NTFS_PUTU16(result+i,in[i]);
+	*out = result = ntfs_malloc(2 * in_len);
+	if (!result)
+		return -ENOMEM;
+	*out_len = in_len;
+	for (i = 0; i < in_len; i++)
+		NTFS_PUTU16(result + i, in[i]);
 	return 0;
 }
 
 /* Encodings dispatcher */
-int ntfs_encodeuni(ntfs_volume *vol,ntfs_u16 *in, int in_len,
-		   char **out, int *out_len)
+int ntfs_encodeuni(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out,
+		   int *out_len)
 {
-	if(vol->nct & nct_utf8)
-		return ntfs_dupuni2utf8(in,in_len,out,out_len);
-	else if(vol->nct & nct_iso8859_1)
-		return ntfs_dupuni288591(in,in_len,out,out_len);
-	else if(vol->nct & (nct_map|nct_uni_xlate))
-		/* uni_xlate is handled inside map */
-		return ntfs_dupuni2map(vol,in,in_len,out,out_len);
+	if (vol->nct & nct_utf8)
+		return ntfs_dupuni2utf8(in, in_len, out, out_len);
+	else if (vol->nct & nct_iso8859_1)
+		return ntfs_dupuni288591(in, in_len, out, out_len);
+	else if(vol->nct & (nct_map | nct_uni_xlate))
+		/* uni_xlate is handled inside map. */
+		return ntfs_dupuni2map(vol, in, in_len, out, out_len);
 	else
-		return EINVAL; /* unknown encoding */
+		return -EINVAL; /* unknown encoding */
 }
 
-int ntfs_decodeuni(ntfs_volume *vol,char *in, int in_len,
-		   ntfs_u16 **out, int *out_len)
+int ntfs_decodeuni(ntfs_volume *vol, char *in, int in_len, ntfs_u16 **out,
+		   int *out_len)
 {
-	if(vol->nct & nct_utf8)
-		return ntfs_duputf82uni(in,in_len,out,out_len);
-	else if(vol->nct & nct_iso8859_1)
-		return ntfs_dup885912uni(in,in_len,out,out_len);
-	else if(vol->nct & (nct_map | nct_uni_xlate))
-		return ntfs_dupmap2uni(vol,in,in_len,out,out_len);
+	if (vol->nct & nct_utf8)
+		return ntfs_duputf82uni(in, in_len, out, out_len);
+	else if (vol->nct & nct_iso8859_1)
+		return ntfs_dup885912uni(in, in_len, out, out_len);
+	else if (vol->nct & (nct_map | nct_uni_xlate))
+		return ntfs_dupmap2uni(vol, in, in_len, out, out_len);
 	else
-		return EINVAL;
+		return -EINVAL;
 }
 
-/* Same address space copies */
-void ntfs_put(ntfs_io *dest,void *src,ntfs_size_t n)
+/* Same address space copies. */
+void ntfs_put(ntfs_io *dest, void *src, ntfs_size_t n)
 {
-	ntfs_memcpy(dest->param,src,n);
-	((char*)dest->param)+=n;
+	ntfs_memcpy(dest->param, src, n);
+	((char*)dest->param) += n;
 }
 
-void ntfs_get(void* dest,ntfs_io *src,ntfs_size_t n)
+void ntfs_get(void* dest, ntfs_io *src, ntfs_size_t n)
 {
-	ntfs_memcpy(dest,src->param,n);
-	((char*)src->param)+=n;
+	ntfs_memcpy(dest, src->param, n);
+	((char*)src->param) += n;
 }
 
 void *ntfs_calloc(int size)
 {
-	void *result=ntfs_malloc(size);
-	if(result)
-		ntfs_bzero(result,size);
+	void *result = ntfs_malloc(size);
+	if (result)
+		ntfs_bzero(result, size);
 	return result;
 }
 
 #if 0
-/* copy len unicode characters from from to to :) */
-void ntfs_uni2ascii(char *to,char *from,int len)
+/* Copy len unicode characters from from to to. :) */
+void ntfs_uni2ascii(char *to, short int *from, int len)
 {
 	int i;
 
-	for(i=0;i<len;i++)
-		to[i]=from[2*i];
-	to[i]='\0';
+	for (i = 0; i < len; i++)
+		to[i] = NTFS_GETU16(from + i);
+	to[i] = '\0';
 }
 #endif
 
-/* copy len asci characters from from to to :) */
-void ntfs_ascii2uni(short int *to,char *from,int len)
+/* Copy len ascii characters from from to to. :) */
+void ntfs_ascii2uni(short int *to, char *from, int len)
 {
 	int i;
 
-	for(i=0;i<len;i++)
-		to[i]=from[i];
-	to[i]=0;
+	for (i = 0; i < len; i++)
+		NTFS_PUTU16(to + i, from[i]);
+	to[i] = 0;
 }
 
-/* strncmp for Unicode strings */
-int ntfs_uni_strncmp(short int* a,short int *b,int n)
+/* strncmp for Unicode strings. */
+int ntfs_uni_strncmp(short int* a, short int *b, int n)
 {
 	int i;
 
-	for(i=0;i<n;i++)
+	for(i = 0; i < n; i++)
 	{
-		if(a[i]<b[i])
+		if (NTFS_GETU16(a + i) < NTFS_GETU16(b + i))
 			return -1;
-		if(b[i]<a[i])
+		if (NTFS_GETU16(b + i) < NTFS_GETU16(a + i))
 			return 1;
-		if (a[i] == 0)
+		if (NTFS_GETU16(a + i) == 0)
 			return 0;
 	}
 	return 0;
 }
 
-/* strncmp between Unicode and ASCII strings */
-int ntfs_ua_strncmp(short int* a,char* b,int n)
+/* strncmp between Unicode and ASCII strings. */
+int ntfs_ua_strncmp(short int* a, char* b, int n)
 {
 	int i;
 
-	for(i=0;i<n;i++)
-	{
-		if(NTFS_GETU16(a+i)<b[i])
+	for (i = 0; i < n; i++)	{
+		if(NTFS_GETU16(a + i) < b[i])
 			return -1;
-		if(b[i]<NTFS_GETU16(a+i))
+		if(b[i] < NTFS_GETU16(a + i))
 			return 1;
 		if (b[i] == 0)
 			return 0;
@@ -291,16 +280,13 @@
 }
 
 /* Convert the NT UTC (based 1.1.1601, in hundred nanosecond units)
- * into Unix UTC (based 1.1.1970, in seconds)
- */
+ * into Unix UTC (based 1.1.1970, in seconds). */
 ntfs_time_t ntfs_ntutc2unixutc(ntfs_time64_t ntutc)
 {
-/*
- * This is very gross because
- * 1: We must do 64-bit division on a 32-bit machine
- * 2: We can't use libgcc for long long operations in the kernel
- * 3: Floating point math in the kernel would corrupt user data
- */
+/* This is very gross because:
+ * 1: We must do 64-bit division on a 32-bit machine.
+ * 2: We can't use libgcc for long long operations in the kernel.
+ * 3: Floating point math in the kernel would corrupt user data. */
 	const unsigned int D = 10000000;
 	unsigned int H = (unsigned int)(ntutc >> 32);
 	unsigned int L = (unsigned int)ntutc;
@@ -310,63 +296,55 @@
 
 	/* It is best to subtract 0x019db1ded53e8000 first. */
 	/* Then the 1601-based date becomes a 1970-based date. */
-	if(L < (unsigned)0xd53e8000) H--;
+	if (L < (unsigned)0xd53e8000)
+		H--;
 	L -= (unsigned)0xd53e8000;
 	H -= (unsigned)0x019db1de;
 
-	/*
-	 * Now divide 64-bit numbers on a 32-bit machine :-)
+	/* Now divide 64-bit numbers on a 32-bit machine. :-)
 	 * With the subtraction already done, the result fits in 32 bits.
 	 * The numerator fits in 56 bits and the denominator fits
-	 * in 24 bits, so we can shift by 8 bits to make this work.
-	 */
+	 * in 24 bits, so we can shift by 8 bits to make this work. */
 
-	numerator2  = (H<<8) | (L>>24);
+	numerator2  = (H << 8) | (L >> 24);
 	result      = (numerator2 / D);   /* shifted 24 right!! */
 	lowseconds  = result << 24;
 
-	numerator2  = ((numerator2-result*D)<<8) | ((L>>16)&0xff);
+	numerator2  = ((numerator2 - result * D) << 8) | ((L >> 16) & 0xff);
 	result      = (numerator2 / D);   /* shifted 16 right!! */
 	lowseconds |= result << 16;
 
-	numerator2  = ((numerator2-result*D)<<8) | ((L>>8)&0xff);
+	numerator2  = ((numerator2 - result * D) << 8) | ((L >> 8) & 0xff);
 	result      = (numerator2 / D);   /* shifted 8 right!! */
 	lowseconds |= result << 8;
 
-	numerator2  = ((numerator2-result*D)<<8) | (L&0xff);
+	numerator2  = ((numerator2 - result * D) << 8) | (L & 0xff);
 	result      = (numerator2 / D);   /* not shifted */
 	lowseconds |= result;
 
 	return lowseconds;
 }
 
-/* Convert the Unix UTC into NT UTC */
+/* Convert the Unix UTC into NT UTC. */
 ntfs_time64_t ntfs_unixutc2ntutc(ntfs_time_t t)
 {
-	return ((t + (ntfs_time64_t)(369*365+89)*24*3600) * 10000000);
+	return ((t + (ntfs_time64_t)(369 * 365 + 89) * 24 * 3600) * 10000000);
 }
 
 /* Fill index name. */
-
-void
-ntfs_indexname(char *buf, int type)
+void ntfs_indexname(char *buf, int type)
 {
-	char hex[]="0123456789ABCDEF";
+	char hex[] = "0123456789ABCDEF";
 	int index;
-	*buf++='$';
-	*buf++='I';
-	for (index=24; index>0; index-=4)
-		if((0xF << index) & type)
+	*buf++ = '$';
+	*buf++ = 'I';
+	for (index = 24; index > 0; index -= 4)
+		if ((0xF << index) & type)
 			break;
-	while(index>=0) {
+	while (index >= 0) {
 		*buf++ = hex[(type >> index) & 0xF];
-		index-=4;
+		index -= 4;
 	}
-	*buf='\0';
+	*buf = '\0';
 }
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/ntfs/util.h linux/fs/ntfs/util.h
--- linux-2.4.4-pre4/fs/ntfs/util.h	Sat Jan  2 10:24:46 1999
+++ linux/fs/ntfs/util.h	Mon Dec  3 22:35:56 2001
@@ -1,55 +1,64 @@
-/*
- *  util.h
- *  Header file for util.c
+/*  util.h - Header file for util.c
  *
  *  Copyright (C) 1997 Régis Duchesne
+ *  Copyright (C) 2001 Anton Altaparmakov
  */
 
-/* Which character set is used for file names */
-/*  Translate everything to UTF-8 */
+/* Which character set is used for file names. */
+/*  Translate everything to UTF-8. */
 #define nct_utf8             1
-/*  Translate to 8859-1 */
+/*  Translate to 8859-1. */
 #define nct_iso8859_1        2
-/*  Quote unprintables with : */
+/*  Quote unprintables with ":". */
 #define nct_uni_xlate        4
-/*  Do that in the vfat way instead of the documented way */
+/*  Do that in the vfat way instead of the documented way. */
 #define nct_uni_xlate_vfat   8
-/*  Use a mapping table to determine printables */
+/*  Use a mapping table to determine printables. */
 #define nct_map              16
 
-/* The first 11 inodes correspond to special files */
-#define FILE_MFT      0
-#define FILE_MFTMIRR  1
-#define FILE_LOGFILE  2
-#define FILE_VOLUME   3
-#define FILE_ATTRDEF  4
-#define FILE_ROOT     5
-#define FILE_BITMAP   6
-#define FILE_BOOT     7
-#define FILE_BADCLUS  8
-#define FILE_QUOTA    9
-#define FILE_UPCASE  10
-
+/* The first 16 inodes correspond to NTFS special files */
+typedef enum {
+	FILE_$Mft	= 0,
+	FILE_$MftMirr	= 1,
+	FILE_$LogFile	= 2,
+	FILE_$Volume	= 3,
+	FILE_$AttrDef	= 4,
+	FILE_$root	= 5,
+	FILE_$BitMap	= 6,
+	FILE_$Boot	= 7,
+	FILE_$BadClus	= 8,
+	FILE_$Secure	= 9,
+	FILE_$UpCase	= 10,
+	FILE_$Extend	= 11,
+	FILE_Reserved12	= 12,
+	FILE_Reserved13	= 13,
+	FILE_Reserved14	= 14,
+	FILE_Reserved15	= 15,
+} NTFS_SYSTEM_FILES;
+ 
 /* Memory management */
 void *ntfs_calloc(int size);
 
 /* String operations */
 /*  Copy Unicode <-> ASCII */
 #if 0
-void ntfs_uni2ascii(char *to,char *from,int len);
+void ntfs_uni2ascii(char *to, char *from, int len);
 #endif
-void ntfs_ascii2uni(short int *to,char *from,int len);
+void ntfs_ascii2uni(short int *to, char *from, int len);
+
 /*  Comparison */
-int ntfs_uni_strncmp(short int* a,short int *b,int n);
-int ntfs_ua_strncmp(short int* a,char* b,int n);
+int ntfs_uni_strncmp(short int* a, short int *b, int n);
+int ntfs_ua_strncmp(short int* a, char* b, int n);
 
 /* Same address space copies */
 void ntfs_put(ntfs_io *dest, void *src, ntfs_size_t n);
 void ntfs_get(void* dest, ntfs_io *src, ntfs_size_t n);
 
 /* Charset conversion */
-int ntfs_encodeuni(ntfs_volume *vol,ntfs_u16 *in, int in_len,char **out, int *out_len);
-int ntfs_decodeuni(ntfs_volume *vol,char *in, int in_len, ntfs_u16 **out, int *out_len);
+int ntfs_encodeuni(ntfs_volume *vol, ntfs_u16 *in, int in_len, char **out,
+		   int *out_len);
+int ntfs_decodeuni(ntfs_volume *vol, char *in, int in_len, ntfs_u16 **out,
+		   int *out_len);
 
 /* Time conversion */
 /*  NT <-> Unix */
@@ -59,8 +68,3 @@
 /* Attribute names */
 void ntfs_indexname(char *buf, int type);
 
-/*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -urN linux-2.4.4-pre4/fs/proc/inode.c linux/fs/proc/inode.c
--- linux-2.4.4-pre4/fs/proc/inode.c	Fri Mar  2 11:12:12 2001
+++ linux/fs/proc/inode.c	Mon Dec  3 22:35:56 2001
@@ -188,7 +188,6 @@
 	s->s_blocksize_bits = 10;
 	s->s_magic = PROC_SUPER_MAGIC;
 	s->s_op = &proc_sops;
-	s->s_maxbytes = MAX_NON_LFS;
 	
 	root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
 	if (!root_inode)
diff -urN linux-2.4.4-pre4/fs/qnx4/inode.c linux/fs/qnx4/inode.c
--- linux-2.4.4-pre4/fs/qnx4/inode.c	Fri Mar  2 11:12:12 2001
+++ linux/fs/qnx4/inode.c	Mon Dec  3 22:35:56 2001
@@ -369,7 +369,6 @@
 	}
 	s->s_op = &qnx4_sops;
 	s->s_magic = QNX4_SUPER_MAGIC;
-	s->s_maxbytes = MAX_NON_LFS;
 #ifndef CONFIG_QNX4FS_RW
 	s->s_flags |= MS_RDONLY;	/* Yup, read-only yet */
 #endif
diff -urN linux-2.4.4-pre4/fs/reiserfs/journal.c linux/fs/reiserfs/journal.c
--- linux-2.4.4-pre4/fs/reiserfs/journal.c	Mon Jan 15 15:31:19 2001
+++ linux/fs/reiserfs/journal.c	Mon Dec  3 22:35:56 2001
@@ -2052,7 +2052,7 @@
 	sleep_on(&(SB_JOURNAL(p_s_sb)->j_join_wait)) ;
       }
     }
-    lock_journal(p_s_sb) ; /* relock to continue */
+    goto relock ;
   }
 
   if (SB_JOURNAL(p_s_sb)->j_trans_start_time == 0) { /* we are the first writer, set trans_id */
diff -urN linux-2.4.4-pre4/fs/reiserfs/super.c linux/fs/reiserfs/super.c
--- linux-2.4.4-pre4/fs/reiserfs/super.c	Mon Dec  3 22:35:46 2001
+++ linux/fs/reiserfs/super.c	Fri Mar  2 11:12:12 2001
@@ -412,7 +412,6 @@
     SB_BUFFER_WITH_SB (s) = bh;
     SB_DISK_SUPER_BLOCK (s) = rs;
     s->s_op = &reiserfs_sops;
-    s->s_maxbytes = MAX_NON_LFS;
     return 0;
 }
 #endif
diff -urN linux-2.4.4-pre4/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- linux-2.4.4-pre4/fs/smbfs/inode.c	Tue Mar  6 19:14:59 2001
+++ linux/fs/smbfs/inode.c	Mon Dec  3 22:35:56 2001
@@ -392,7 +392,6 @@
 	sb->s_magic = SMB_SUPER_MAGIC;
 	sb->s_flags = 0;
 	sb->s_op = &smb_sops;
-	sb->s_maxbytes = MAX_NON_LFS;	/* client support missing */
 
 	sb->u.smbfs_sb.mnt = NULL;
 	sb->u.smbfs_sb.sock_file = NULL;
diff -urN linux-2.4.4-pre4/fs/stat.c linux/fs/stat.c
--- linux-2.4.4-pre4/fs/stat.c	Mon Dec  3 22:35:46 2001
+++ linux/fs/stat.c	Mon Dec  3 22:35:56 2001
@@ -4,6 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/file.h>
@@ -126,7 +127,7 @@
 }
 
 
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(__s390__) && !defined(__hppa__)
+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__)
 /*
  * For backward compatibility?  Maybe this should be moved
  * into arch/i386 instead?
@@ -162,7 +163,7 @@
 	return error;
 }
 
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(__s390__) && !defined(__hppa__)
+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__)
 
 /*
  * For backward compatibility?  Maybe this should be moved
@@ -200,7 +201,7 @@
 	return error;
 }
 
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(__s390__) && !defined(__hppa__)
+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__)
 
 /*
  * For backward compatibility?  Maybe this should be moved
@@ -267,7 +268,7 @@
 
 
 /* ---------- LFS-64 ----------- */
-#if !defined(__alpha__) && !defined (__ia64__) && !defined(__mips64)
+#if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips64) && !defined(CONFIG_ARCH_S390X)
 
 static long cp_new_stat64(struct inode * inode, struct stat64 * statbuf)
 {
diff -urN linux-2.4.4-pre4/fs/sysv/inode.c linux/fs/sysv/inode.c
--- linux-2.4.4-pre4/fs/sysv/inode.c	Fri Mar  2 11:12:12 2001
+++ linux/fs/sysv/inode.c	Mon Dec  3 22:35:56 2001
@@ -365,7 +365,6 @@
 		panic("sysv fs: bad i-node size");
 	set_blocksize(dev,BLOCK_SIZE);
 	sb->sv_block_base = 0;
-	sb->s_maxbytes = MAX_NON_LFS;
 
 	/* Try to read Xenix superblock */
 	if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) {
diff -urN linux-2.4.4-pre4/fs/udf/super.c linux/fs/udf/super.c
--- linux-2.4.4-pre4/fs/udf/super.c	Fri Mar  2 11:12:12 2001
+++ linux/fs/udf/super.c	Mon Dec  3 22:35:56 2001
@@ -344,8 +344,7 @@
 udf_set_blocksize(struct super_block *sb, int bsize)
 {
 	/* Use specified block size if specified */
-	if (!(sb->s_blocksize = get_hardblocksize(sb->s_dev)))
-		sb->s_blocksize = 2048;
+	sb->s_blocksize = get_hardsect_size(sb->s_dev);
 	if (bsize > sb->s_blocksize)
 		sb->s_blocksize = bsize;
 
diff -urN linux-2.4.4-pre4/fs/ufs/super.c linux/fs/ufs/super.c
--- linux-2.4.4-pre4/fs/ufs/super.c	Fri Mar  2 11:12:12 2001
+++ linux/fs/ufs/super.c	Mon Dec  3 22:35:56 2001
@@ -489,12 +489,10 @@
 	if (!uspi)
 		goto failed;
 
-	/* Set a 2Gig file limit. Some UFS variants need to override 
+	/* Keep 2Gig file limit. Some UFS variants need to override 
 	   this but as I don't know which I'll let those in the know loosen
 	   the rules */
 	   
-	sb->s_maxbytes = MAX_NON_LFS;
-
 	switch (sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) {
 	case UFS_MOUNT_UFSTYPE_44BSD:
 		UFSD(("ufstype=44bsd\n"))
diff -urN linux-2.4.4-pre4/fs/umsdos/ioctl.c linux/fs/umsdos/ioctl.c
--- linux-2.4.4-pre4/fs/umsdos/ioctl.c	Tue Sep  5 14:05:46 2000
+++ linux/fs/umsdos/ioctl.c	Mon Dec  3 22:35:56 2001
@@ -95,7 +95,7 @@
 	    && cmd != UMSDOS_DOS_SETUP)
 		return fat_dir_ioctl (dir, filp, cmd, data_ptr);
 
-	/* #Specification: ioctl / acces
+	/* #Specification: ioctl / access
 	 * Only root (effective id) is allowed to do IOCTL on directory
 	 * in UMSDOS. EPERM is returned for other user.
 	 */
diff -urN linux-2.4.4-pre4/include/asm-i386/rwsem-spin.h linux/include/asm-i386/rwsem-spin.h
--- linux-2.4.4-pre4/include/asm-i386/rwsem-spin.h	Mon Dec  3 22:35:46 2001
+++ linux/include/asm-i386/rwsem-spin.h	Mon Dec  3 22:35:56 2001
@@ -58,17 +58,13 @@
 #define __RWSEM_DEBUG_MINIT(name)	/* */
 #endif
 
-#define __RWSEM_INITIALIZER(name,count) \
+#define __RWSEM_INITIALIZER(name) \
 { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
 	__WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
 	__RWSEM_DEBUG_INIT __RWSEM_DEBUG_MINIT(name) }
 
-#define __DECLARE_RWSEM_GENERIC(name,count) \
-	struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
-
-#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS)
-#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
-#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
+#define DECLARE_RWSEM(name) \
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
 
 static inline void init_rwsem(struct rw_semaphore *sem)
 {
diff -urN linux-2.4.4-pre4/include/asm-i386/rwsem-xadd.h linux/include/asm-i386/rwsem-xadd.h
--- linux-2.4.4-pre4/include/asm-i386/rwsem-xadd.h	Mon Dec  3 22:35:46 2001
+++ linux/include/asm-i386/rwsem-xadd.h	Mon Dec  3 22:35:56 2001
@@ -51,16 +51,12 @@
 #define __RWSEM_DEBUG_MINIT(name)	/* */
 #endif
 
-#define __RWSEM_INITIALIZER(name,count) \
+#define __RWSEM_INITIALIZER(name) \
 { RWSEM_UNLOCKED_VALUE, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
 	__RWSEM_DEBUG_INIT __RWSEM_DEBUG_MINIT(name) }
 
-#define __DECLARE_RWSEM_GENERIC(name,count) \
-	struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
-
-#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS)
-#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
-#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
+#define DECLARE_RWSEM(name) \
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
 
 static inline void init_rwsem(struct rw_semaphore *sem)
 {
diff -urN linux-2.4.4-pre4/include/asm-i386/uaccess.h linux/include/asm-i386/uaccess.h
--- linux-2.4.4-pre4/include/asm-i386/uaccess.h	Mon Mar 26 15:48:13 2001
+++ linux/include/asm-i386/uaccess.h	Mon Dec  3 22:35:56 2001
@@ -542,6 +542,8 @@
 {
 	if (access_ok(VERIFY_READ, from, n))
 		__constant_copy_user_zeroing(to,from,n);
+	else
+		memset(to, 0, n);
 	return n;
 }
 
diff -urN linux-2.4.4-pre4/include/asm-m68k/bootinfo.h linux/include/asm-m68k/bootinfo.h
--- linux-2.4.4-pre4/include/asm-m68k/bootinfo.h	Wed Jan 26 12:44:21 2000
+++ linux/include/asm-m68k/bootinfo.h	Mon Dec  3 22:35:56 2001
@@ -163,7 +163,7 @@
 #define BI_MAC_SCCTYPE		0x801c	/* Mac SCC serial type (normal, IOP) */
 #define BI_MAC_ETHTYPE		0x801d	/* Mac builtin ethernet type (Sonic, MACE */
 #define BI_MAC_ETHBASE		0x801e	/* Mac builtin ethernet base address */
-#define BI_MAC_PMU		0x801f	/* Mac power managment / poweroff hardware */
+#define BI_MAC_PMU		0x801f	/* Mac power management / poweroff hardware */
 #define BI_MAC_IOP_SWIM		0x8020	/* Mac SWIM floppy IOP */
 #define BI_MAC_IOP_ADB		0x8021	/* Mac ADB IOP */
 
diff -urN linux-2.4.4-pre4/include/asm-m68k/mac_iop.h linux/include/asm-m68k/mac_iop.h
--- linux-2.4.4-pre4/include/asm-m68k/mac_iop.h	Sat Sep  4 13:06:41 1999
+++ linux/include/asm-m68k/mac_iop.h	Mon Dec  3 22:35:56 2001
@@ -54,7 +54,7 @@
 #define IOP_MSGSTATUS_COMPLETE	3	/* message complete and reply rcvd */
 #define IOP_MSGSTATUS_UNSOL	6	/* message is unsolicited          */
 
-/* IOP memory addresses of the members of the the mac_iop_kernel structure. */
+/* IOP memory addresses of the members of the mac_iop_kernel structure. */
 
 #define IOP_ADDR_MAX_SEND_CHAN	0x0200
 #define IOP_ADDR_SEND_STATE	0x0201
diff -urN linux-2.4.4-pre4/include/asm-m68k/serial.h linux/include/asm-m68k/serial.h
--- linux-2.4.4-pre4/include/asm-m68k/serial.h	Thu Jan  4 13:00:55 2001
+++ linux/include/asm-m68k/serial.h	Mon Dec  3 22:35:56 2001
@@ -1,7 +1,7 @@
 /*
  * include/asm-m68k/serial.h
  *
- * currently this seems usefull only for a Q40,
+ * currently this seems useful only for a Q40,
  * its an almost exact copy of ../asm/alpha/serial.h 
  *
  */
diff -urN linux-2.4.4-pre4/include/asm-sparc64/rwsem.h linux/include/asm-sparc64/rwsem.h
--- linux-2.4.4-pre4/include/asm-sparc64/rwsem.h	Mon Dec  3 22:35:46 2001
+++ linux/include/asm-sparc64/rwsem.h	Mon Dec  3 22:35:56 2001
@@ -1,4 +1,9 @@
-/* $Id: rwsem.h,v 1.1 2001/04/14 01:12:16 davem Exp $ */
+/* $Id: rwsem.h,v 1.2 2001/04/19 01:52:04 davem Exp $
+ * rwsem.h: R/W semaphores implemented using CAS
+ *
+ * Written by David S. Miller (davem@redhat.com), 2001.
+ * Derived from asm-i386/rwsem-xadd.h
+ */
 #ifndef _SPARC64_RWSEM_H
 #define _SPARC64_RWSEM_H
 
@@ -6,6 +11,207 @@
 #error please dont include asm/rwsem.h directly, use linux/rwsem.h instead
 #endif
 
-#undef __HAVE_ARCH_SPECIFIC_RWSEM_IMPLEMENTATION
+#ifdef __KERNEL__
+
+struct rw_semaphore {
+	signed int count;
+#define RWSEM_UNLOCKED_VALUE		0x00000000
+#define RWSEM_ACTIVE_BIAS		0x00000001
+#define RWSEM_ACTIVE_MASK		0x0000ffff
+#define RWSEM_WAITING_BIAS		0xffff0000
+#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+	wait_queue_head_t wait;
+#define RWSEM_WAITING_FOR_READ	WQ_FLAG_CONTEXT_0	/* bits to use in wait_queue_t.flags */
+#define RWSEM_WAITING_FOR_WRITE	WQ_FLAG_CONTEXT_1
+};
+
+#define __RWSEM_INITIALIZER(name) \
+{ RWSEM_UNLOCKED_VALUE, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
+
+#define DECLARE_RWSEM(name) \
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+
+static inline void init_rwsem(struct rw_semaphore *sem)
+{
+	sem->count = RWSEM_UNLOCKED_VALUE;
+	init_waitqueue_head(&sem->wait);
+}
+
+static inline void __down_read(struct rw_semaphore *sem)
+{
+	__asm__ __volatile__(
+		"! beginning __down_read\n"
+		"1:\tlduw	[%0], %%g5\n\t"
+		"add		%%g5, 1, %%g7\n\t"
+		"cas		[%0], %%g5, %%g7\n\t"
+		"cmp		%%g5, %%g7\n\t"
+		"bne,pn		%%icc, 1b\n\t"
+		" add		%%g7, 1, %%g7\n\t"
+		"cmp		%%g7, 0\n\t"
+		"bl,pn		%%icc, 3f\n\t"
+		" membar	#StoreStore\n"
+		"2:\n\t"
+		".subsection	2\n"
+		"3:\tmov	%0, %%g5\n\t"
+		"save		%%sp, -160, %%sp\n\t"
+		"mov		%%g1, %%l1\n\t"
+		"mov		%%g2, %%l2\n\t"
+		"mov		%%g3, %%l3\n\t"
+		"call		%1\n\t"
+		" mov		%%g5, %%o0\n\t"
+		"mov		%%l1, %%g1\n\t"
+		"mov		%%l2, %%g2\n\t"
+		"ba,pt		%%xcc, 2b\n\t"
+		" restore	%%l3, %%g0, %%g3\n\t"
+		".previous\n\t"
+		"! ending __down_read"
+		: : "r" (sem), "i" (rwsem_down_read_failed)
+		: "g5", "g7", "memory", "cc");
+}
+
+static inline void __down_write(struct rw_semaphore *sem)
+{
+	__asm__ __volatile__(
+		"! beginning __down_write\n\t"
+		"sethi		%%hi(%2), %%g1\n\t"
+		"or		%%g1, %%lo(%2), %%g1\n"
+		"1:\tlduw	[%0], %%g5\n\t"
+		"add		%%g5, %%g1, %%g7\n\t"
+		"cas		[%0], %%g5, %%g7\n\t"
+		"cmp		%%g5, %%g7\n\t"
+		"bne,pn		%%icc, 1b\n\t"
+		" cmp		%%g7, 0\n\t"
+		"bne,pn		%%icc, 3f\n\t"
+		" membar	#StoreStore\n"
+		"2:\n\t"
+		".subsection	2\n"
+		"3:\tmov	%0, %%g5\n\t"
+		"save		%%sp, -160, %%sp\n\t"
+		"mov		%%g2, %%l2\n\t"
+		"mov		%%g3, %%l3\n\t"
+		"call		%1\n\t"
+		" mov		%%g5, %%o0\n\t"
+		"mov		%%l2, %%g2\n\t"
+		"ba,pt		%%xcc, 2b\n\t"
+		" restore	%%l3, %%g0, %%g3\n\t"
+		".previous\n\t"
+		"! ending __down_write"
+		: : "r" (sem), "i" (rwsem_down_write_failed),
+		    "i" (RWSEM_ACTIVE_WRITE_BIAS)
+		: "g1", "g5", "g7", "memory", "cc");
+}
+
+static inline void __up_read(struct rw_semaphore *sem)
+{
+	__asm__ __volatile__(
+		"! beginning __up_read\n\t"
+		"1:\tlduw	[%0], %%g5\n\t"
+		"sub		%%g5, 1, %%g7\n\t"
+		"cas		[%0], %%g5, %%g7\n\t"
+		"cmp		%%g5, %%g7\n\t"
+		"bne,pn		%%icc, 1b\n\t"
+		" cmp		%%g7, 0\n\t"
+		"bl,pn		%%icc, 3f\n\t"
+		" membar	#StoreStore\n"
+		"2:\n\t"
+		".subsection	2\n"
+		"3:\tsethi	%%hi(%2), %%g1\n\t"
+		"sub		%%g7, 1, %%g7\n\t"
+		"or		%%g1, %%lo(%2), %%g1\n\t"
+		"andcc		%%g7, %%g1, %%g0\n\t"
+		"bne,pn		%%icc, 2b\n\t"
+		" mov		%0, %%g5\n\t"
+		"save		%%sp, -160, %%sp\n\t"
+		"mov		%%g2, %%l2\n\t"
+		"mov		%%g3, %%l3\n\t"
+		"call		%1\n\t"
+		" mov		%%g5, %%o0\n\t"
+		"mov		%%l2, %%g2\n\t"
+		"ba,pt		%%xcc, 2b\n\t"
+		" restore	%%l3, %%g0, %%g3\n\t"
+		".previous\n\t"
+		"! ending __up_read"
+		: : "r" (sem), "i" (rwsem_wake),
+		    "i" (RWSEM_ACTIVE_MASK)
+		: "g1", "g5", "g7", "memory", "cc");
+}
+
+static inline void __up_write(struct rw_semaphore *sem)
+{
+	__asm__ __volatile__(
+		"! beginning __up_write\n\t"
+		"sethi		%%hi(%2), %%g1\n\t"
+		"or		%%g1, %%lo(%2), %%g1\n"
+		"1:\tlduw	[%0], %%g5\n\t"
+		"sub		%%g5, %%g1, %%g7\n\t"
+		"cas		[%0], %%g5, %%g7\n\t"
+		"cmp		%%g5, %%g7\n\t"
+		"bne,pn		%%icc, 1b\n\t"
+		" sub		%%g7, %%g1, %%g7\n\t"
+		"cmp		%%g7, 0\n\t"
+		"bl,pn		%%icc, 3f\n\t"
+		" membar	#StoreStore\n"
+		"2:\n\t"
+		".subsection 2\n"
+		"3:\tmov	%0, %%g5\n\t"
+		"save		%%sp, -160, %%sp\n\t"
+		"mov		%%g2, %%l2\n\t"
+		"mov		%%g3, %%l3\n\t"
+		"call		%1\n\t"
+		" mov		%%g5, %%o0\n\t"
+		"mov		%%l2, %%g2\n\t"
+		"ba,pt		%%xcc, 2b\n\t"
+		" restore	%%l3, %%g0, %%g3\n\t"
+		".previous\n\t"
+		"! ending __up_write"
+		: : "r" (sem), "i" (rwsem_wake),
+		    "i" (RWSEM_ACTIVE_WRITE_BIAS)
+		: "g1", "g5", "g7", "memory", "cc");
+}
+
+static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+{
+	int tmp = delta;
+
+	__asm__ __volatile__(
+		"1:\tlduw	[%2], %%g5\n\t"
+		"add		%%g5, %1, %%g7\n\t"
+		"cas		[%2], %%g5, %%g7\n\t"
+		"cmp		%%g5, %%g7\n\t"
+		"bne,pn		%%icc, 1b\n\t"
+		" nop\n\t"
+		"mov		%%g7, %0\n\t"
+		: "=&r" (tmp)
+		: "0" (tmp), "r" (sem)
+		: "g5", "g7", "memory");
+
+	return tmp + delta;
+}
+
+static inline __u16 rwsem_cmpxchgw(struct rw_semaphore *sem, __u16 __old, __u16 __new)
+{
+	u32 old = (sem->count & 0xffff0000) | (u32) __old;
+	u32 new = (old & 0xffff0000) | (u32) __new;
+	u32 prev;
+
+again:
+	__asm__ __volatile__("cas	[%2], %3, %0\n\t"
+			     "membar	#StoreStore | #StoreLoad"
+			     : "=&r" (prev)
+			     : "0" (new), "r" (sem), "r" (old)
+			     : "memory");
+
+	/* To give the same semantics as x86 cmpxchgw, keep trying
+	 * if only the upper 16-bits changed.
+	 */
+	if (prev != old &&
+	    ((prev & 0xffff) == (old & 0xffff)))
+		goto again;
+
+	return prev & 0xffff;
+}
+
+#endif /* __KERNEL__ */
 
 #endif /* _SPARC64_RWSEM_H */
diff -urN linux-2.4.4-pre4/include/linux/etherdevice.h linux/include/linux/etherdevice.h
--- linux-2.4.4-pre4/include/linux/etherdevice.h	Sun Mar 25 18:24:31 2001
+++ linux/include/linux/etherdevice.h	Mon Dec  3 22:35:56 2001
@@ -51,7 +51,8 @@
  * @addr: Pointer to a six-byte array containing the Ethernet address
  *
  * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
- * a multicast address, and is not FF:FF:FF:FF:FF:FF.
+ * a multicast address, and is not FF:FF:FF:FF:FF:FF.  The multicast
+ * and FF:FF:... tests are combined into the single test "!(addr[0]&1)".
  *
  * Return true if the address is valid.
  */
diff -urN linux-2.4.4-pre4/include/linux/ethtool.h linux/include/linux/ethtool.h
--- linux-2.4.4-pre4/include/linux/ethtool.h	Sun Mar 25 18:24:31 2001
+++ linux/include/linux/ethtool.h	Mon Dec  3 22:35:56 2001
@@ -2,6 +2,7 @@
  * ethtool.h: Defines for Linux ethtool.
  *
  * Copyright (C) 1998 David S. Miller (davem@redhat.com)
+ * Copyright 2001 Jeff Garzik <jgarzik@mandrakesoft.com>
  */
 
 #ifndef _LINUX_ETHTOOL_H
diff -urN linux-2.4.4-pre4/include/linux/fs.h linux/include/linux/fs.h
--- linux-2.4.4-pre4/include/linux/fs.h	Mon Dec  3 22:35:46 2001
+++ linux/include/linux/fs.h	Mon Dec  3 22:35:56 2001
@@ -1252,7 +1252,6 @@
 		__bforget(buf);
 }
 extern void set_blocksize(kdev_t, int);
-extern unsigned int get_hardblocksize(kdev_t);
 extern struct buffer_head * bread(kdev_t, int, int);
 extern void wakeup_bdflush(int wait);
 
diff -urN linux-2.4.4-pre4/include/linux/if_ec.h linux/include/linux/if_ec.h
--- linux-2.4.4-pre4/include/linux/if_ec.h	Thu Mar  9 06:57:17 2000
+++ linux/include/linux/if_ec.h	Mon Dec  3 22:35:56 2001
@@ -60,9 +60,6 @@
   unsigned char station, net;		/* Econet protocol address */
 };
 
-extern struct sock *ec_listening_socket(unsigned char port, unsigned char
-				 station, unsigned char net);
-
 #endif
 
 #endif
diff -urN linux-2.4.4-pre4/include/linux/if_ether.h linux/include/linux/if_ether.h
--- linux-2.4.4-pre4/include/linux/if_ether.h	Fri Oct 27 11:03:14 2000
+++ linux/include/linux/if_ether.h	Mon Dec  3 22:35:56 2001
@@ -37,12 +37,14 @@
  */
 
 #define ETH_P_LOOP	0x0060		/* Ethernet Loopback packet	*/
-#define ETH_P_ECHO	0x0200		/* Ethernet Echo packet		*/
-#define ETH_P_PUP	0x0400		/* Xerox PUP packet		*/
+#define ETH_P_PUP	0x0200		/* Xerox PUP packet		*/
+#define ETH_P_PUPAT	0x0201		/* Xerox PUP Addr Trans packet	*/
 #define ETH_P_IP	0x0800		/* Internet Protocol packet	*/
 #define ETH_P_X25	0x0805		/* CCITT X.25			*/
 #define ETH_P_ARP	0x0806		/* Address Resolution packet	*/
 #define	ETH_P_BPQ	0x08FF		/* G8BPQ AX.25 Ethernet Packet	[ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_IEEEPUP	0x0a00		/* Xerox IEEE802.3 PUP packet */
+#define ETH_P_IEEEPUPAT	0x0a01		/* Xerox IEEE802.3 PUP Addr Trans packet */
 #define ETH_P_DEC       0x6000          /* DEC Assigned proto           */
 #define ETH_P_DNA_DL    0x6001          /* DEC DNA Dump/Load            */
 #define ETH_P_DNA_RC    0x6002          /* DEC DNA Remote Console       */
diff -urN linux-2.4.4-pre4/include/linux/netdevice.h linux/include/linux/netdevice.h
--- linux-2.4.4-pre4/include/linux/netdevice.h	Mon Dec  3 22:35:46 2001
+++ linux/include/linux/netdevice.h	Mon Dec  3 22:35:57 2001
@@ -565,7 +565,7 @@
 
 static inline void dev_init_buffers(struct net_device *dev)
 {
-	/* DO NOTHING */
+	/* WILL BE REMOVED IN 2.5.0 */
 }
 
 extern int netdev_finish_unregister(struct net_device *dev);
diff -urN linux-2.4.4-pre4/include/linux/ntfs_fs_i.h linux/include/linux/ntfs_fs_i.h
--- linux-2.4.4-pre4/include/linux/ntfs_fs_i.h	Thu Feb 10 12:17:00 2000
+++ linux/include/linux/ntfs_fs_i.h	Mon Dec  3 22:35:57 2001
@@ -60,24 +60,23 @@
 typedef unsigned int ntfs_cluster_t;
 #endif
 
-/* Definition of NTFS in-memory inode structure */
+/* Definition of the NTFS in-memory inode structure. */
 struct ntfs_inode_info{
 	unsigned long mmu_private;
 	struct ntfs_sb_info *vol;
-	int i_number;                /* should be really 48 bits */
-	unsigned sequence_number;
-	unsigned char* attr;         /* array of the attributes */
-	int attr_count;              /* size of attrs[] */
+	int i_number;                /* Should be really 48 bits. */
+	__u16 sequence_number;	     /* The current sequence number. */
+	unsigned char* attr;         /* Array of the attributes. */
+	int attr_count;              /* Size of attrs[]. */
 	struct ntfs_attribute *attrs;
-	int record_count;            /* size of records[] */
-	/* array of the record numbers of the MFT 
-	   whose attributes have been inserted in the inode */
-	int *records;
-	union{
-		struct{
+	int record_count;            /* Size of records[]. */
+	int *records; /* Array of the record numbers of the $Mft whose 
+		       * attributes have been inserted in the inode. */
+	union {
+		struct {
 			int recordsize;
 			int clusters_per_record;
-		}index;
+		} index;
 	} u;	
 };
 
diff -urN linux-2.4.4-pre4/include/linux/ntfs_fs_sb.h linux/include/linux/ntfs_fs_sb.h
--- linux-2.4.4-pre4/include/linux/ntfs_fs_sb.h	Tue May  2 13:46:53 2000
+++ linux/include/linux/ntfs_fs_sb.h	Mon Dec  3 22:35:57 2001
@@ -2,16 +2,17 @@
 #define _LINUX_NTFS_FS_SB_H
 
 struct ntfs_sb_info{
-	/* Configuration provided by user at mount time */
+	/* Configuration provided by user at mount time. */
 	ntfs_uid_t uid;
 	ntfs_gid_t gid;
 	ntmode_t umask;
         unsigned int nct;
 	void *nls_map;
 	unsigned int ngt;
-	/* Configuration provided by user with ntfstools */
-	ntfs_size_t partition_bias;	/* for access to underlying device */
-	/* Attribute definitions */
+	/* Configuration provided by user with the ntfstools.
+	 * FIXME: This is no longer possible. What is this good for? (AIA) */
+	ntfs_size_t partition_bias;	/* For access to underlying device. */
+	/* Attribute definitions. */
 	ntfs_u32 at_standard_information;
 	ntfs_u32 at_attribute_list;
 	ntfs_u32 at_file_name;
@@ -24,20 +25,20 @@
 	ntfs_u32 at_index_allocation;
 	ntfs_u32 at_bitmap;
 	ntfs_u32 at_symlink; /* aka SYMBOLIC_LINK or REPARSE_POINT */
-	/* Data read from the boot file */
+	/* Data read / calculated from the boot file. */
 	int blocksize;
-	int clusterfactor;
+	int clusterfactorbits;
 	int clustersize;
 	int mft_recordsize;
 	int mft_clusters_per_record;
 	int index_recordsize;
 	int index_clusters_per_record;
 	int mft_cluster;
-	/* data read from special files */
+	/* Data read from special files. */
 	unsigned char *mft;
 	unsigned short *upcase;
 	unsigned int upcase_length;
-	/* inodes we always hold onto */
+	/* Inodes we always hold onto. */
 	struct ntfs_inode_info *mft_ino;
 	struct ntfs_inode_info *mftmirr;
 	struct ntfs_inode_info *bitmap;
diff -urN linux-2.4.4-pre4/include/linux/pci.h linux/include/linux/pci.h
--- linux-2.4.4-pre4/include/linux/pci.h	Mon Mar 26 15:48:46 2001
+++ linux/include/linux/pci.h	Mon Dec  3 22:35:57 2001
@@ -525,7 +525,9 @@
 int pci_write_config_word(struct pci_dev *dev, int where, u16 val);
 int pci_write_config_dword(struct pci_dev *dev, int where, u32 val);
 
+#define HAVE_PCI_DISABLE_DEVICE
 int pci_enable_device(struct pci_dev *dev);
+void pci_disable_device(struct pci_dev *dev);
 void pci_set_master(struct pci_dev *dev);
 int pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask);
 int pci_set_power_state(struct pci_dev *dev, int state);
@@ -552,6 +554,14 @@
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
 const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation, int flags);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 #endif /* CONFIG_PCI */
 
 /* Include architecture-dependent settings and functions */
@@ -594,6 +604,7 @@
 
 static inline void pci_set_master(struct pci_dev *dev) { }
 static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
+static inline void pci_disable_device(struct pci_dev *dev) { }
 static inline int pci_module_init(struct pci_driver *drv) { return -ENODEV; }
 static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;}
 static inline int pci_register_driver(struct pci_driver *drv) { return 0;}
diff -urN linux-2.4.4-pre4/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- linux-2.4.4-pre4/include/linux/pci_ids.h	Sun Mar 25 18:14:20 2001
+++ linux/include/linux/pci_ids.h	Mon Dec  3 22:35:57 2001
@@ -174,14 +174,62 @@
 #define PCI_DEVICE_ID_ATI_215LG		0x4c47
 #define PCI_DEVICE_ID_ATI_264LT		0x4c54
 #define PCI_DEVICE_ID_ATI_264VT		0x5654
+/* Rage128 Pro GL */
+#define PCI_DEVICE_ID_ATI_Rage128_PA	0x5041
+#define PCI_DEVICE_ID_ATI_Rage128_PB	0x5042
+#define PCI_DEVICE_ID_ATI_Rage128_PC	0x5043
+#define PCI_DEVICE_ID_ATI_Rage128_PD	0x5044
+#define PCI_DEVICE_ID_ATI_Rage128_PE	0x5045
+#define PCI_DEVICE_ID_ATI_RAGE128_PF	0x5046
+/* Rage128 Pro VR */
+#define PCI_DEVICE_ID_ATI_RAGE128_PG	0x5047
+#define PCI_DEVICE_ID_ATI_RAGE128_PH	0x5048
+#define PCI_DEVICE_ID_ATI_RAGE128_PI	0x5049
+#define PCI_DEVICE_ID_ATI_RAGE128_PJ	0x504A
+#define PCI_DEVICE_ID_ATI_RAGE128_PK	0x504B
+#define PCI_DEVICE_ID_ATI_RAGE128_PL	0x504C
+#define PCI_DEVICE_ID_ATI_RAGE128_PM	0x504D
+#define PCI_DEVICE_ID_ATI_RAGE128_PN	0x504E
+#define PCI_DEVICE_ID_ATI_RAGE128_PO	0x504F
+#define PCI_DEVICE_ID_ATI_RAGE128_PP	0x5050
+#define PCI_DEVICE_ID_ATI_RAGE128_PQ	0x5051
+#define PCI_DEVICE_ID_ATI_RAGE128_PR	0x5052
+#define PCI_DEVICE_ID_ATI_RAGE128_PS	0x5053
+#define PCI_DEVICE_ID_ATI_RAGE128_PT	0x5054
+#define PCI_DEVICE_ID_ATI_RAGE128_PU	0x5055
+#define PCI_DEVICE_ID_ATI_RAGE128_PV	0x5056
+#define PCI_DEVICE_ID_ATI_RAGE128_PW	0x5057
+#define PCI_DEVICE_ID_ATI_RAGE128_PX	0x5058
+/* Rage128 GL */
 #define PCI_DEVICE_ID_ATI_RAGE128_RE	0x5245
 #define PCI_DEVICE_ID_ATI_RAGE128_RF	0x5246
+#define PCI_DEVICE_ID_ATI_RAGE128_RG	0x534b
+#define PCI_DEVICE_ID_ATI_RAGE128_RH	0x534c
+#define PCI_DEVICE_ID_ATI_RAGE128_RI	0x534d
+/* Rage128 VR */
 #define PCI_DEVICE_ID_ATI_RAGE128_RK	0x524b
 #define PCI_DEVICE_ID_ATI_RAGE128_RL	0x524c
-#define PCI_DEVICE_ID_ATI_RAGE128_PF	0x5046
-#define PCI_DEVICE_ID_ATI_RAGE128_PR	0x5052
+#define PCI_DEVICE_ID_ATI_RAGE128_RM	0x5345
+#define PCI_DEVICE_ID_ATI_RAGE128_RN	0x5346
+#define PCI_DEVICE_ID_ATI_RAGE128_RO	0x5347
+/* Rage128 M3 */
 #define PCI_DEVICE_ID_ATI_RAGE128_LE	0x4c45
 #define PCI_DEVICE_ID_ATI_RAGE128_LF	0x4c46
+/* Rage128 Pro Ultra */
+#define PCI_DEVICE_ID_ATI_RAGE128_U1	0x5446
+#define PCI_DEVICE_ID_ATI_RAGE128_U2	0x544C
+#define PCI_DEVICE_ID_ATI_RAGE128_U3	0x5452
+/* Radeon M4 */
+#define PCI_DEVICE_ID_ATI_RADEON_LE	0x4d45
+#define PCI_DEVICE_ID_ATI_RADEON_LF	0x4d46
+/* Radeon NV-100 */
+#define PCI_DEVICE_ID_ATI_RADEON_N1	0x5159
+#define PCI_DEVICE_ID_ATI_RADEON_N2	0x515a
+/* Radeon */
+#define PCI_DEVICE_ID_ATI_RADEON_RA	0x5144
+#define PCI_DEVICE_ID_ATI_RADEON_RB	0x5145
+#define PCI_DEVICE_ID_ATI_RADEON_RC	0x5146
+#define PCI_DEVICE_ID_ATI_RADEON_RD	0x5147
 
 #define PCI_VENDOR_ID_VLSI		0x1004
 #define PCI_DEVICE_ID_VLSI_82C592	0x0005
@@ -376,8 +424,15 @@
 #define PCI_DEVICE_ID_SI_7001		0x7001
 
 #define PCI_VENDOR_ID_HP		0x103c
+#define PCI_DEVICE_ID_HP_DONNER_GFX	0x1008
+#define PCI_DEVICE_ID_HP_TACHYON	0x1028
+#define PCI_DEVICE_ID_HP_TACHLITE	0x1029
 #define PCI_DEVICE_ID_HP_J2585A		0x1030
 #define PCI_DEVICE_ID_HP_J2585B		0x1031
+#define PCI_DEVICE_ID_HP_SAS		0x1048
+#define PCI_DEVICE_ID_HP_DIVA1		0x1049
+#define PCI_DEVICE_ID_HP_DIVA2		0x104A
+#define PCI_DEVICE_ID_HP_SP2_0		0x104B
 
 #define PCI_VENDOR_ID_PCTECH		0x1042
 #define PCI_DEVICE_ID_PCTECH_RZ1000	0x1000
@@ -408,6 +463,10 @@
 #define PCI_DEVICE_ID_ELSA_MICROLINK	0x1000
 #define PCI_DEVICE_ID_ELSA_QS3000	0x3000
 
+#define PCI_VENDOR_ID_ELSA		0x1048
+#define PCI_DEVICE_ID_ELSA_MICROLINK	0x1000
+#define PCI_DEVICE_ID_ELSA_QS3000	0x3000
+
 #define PCI_VENDOR_ID_SGS		0x104a
 #define PCI_DEVICE_ID_SGS_2000		0x0008
 #define PCI_DEVICE_ID_SGS_1764		0x0009
@@ -658,6 +717,11 @@
 #define PCI_DEVICE_ID_AL_M1531		0x1531
 #define PCI_DEVICE_ID_AL_M1533		0x1533
 #define PCI_DEVICE_ID_AL_M1541		0x1541
+#define PCI_DEVICE_ID_AL_M1621          0x1621
+#define PCI_DEVICE_ID_AL_M1631          0x1631
+#define PCI_DEVICE_ID_AL_M1641          0x1641
+#define PCI_DEVICE_ID_AL_M1647          0x1647
+#define PCI_DEVICE_ID_AL_M1651          0x1651
 #define PCI_DEVICE_ID_AL_M1543		0x1543
 #define PCI_DEVICE_ID_AL_M3307		0x3307
 #define PCI_DEVICE_ID_AL_M4803		0x5215
@@ -811,6 +875,9 @@
 #define PCI_DEVICE_ID_VIA_8633_1	0xB091
 #define PCI_DEVICE_ID_VIA_8367_1	0xB099
 
+#define PCI_VENDOR_ID_SIEMENS           0x110A
+#define PCI_DEVICE_ID_SIEMENS_DSCC4     0x2102
+
 #define PCI_VENDOR_ID_SMC2		0x1113
 #define PCI_DEVICE_ID_SMC2_1211TX	0x1211
 
@@ -962,6 +1029,10 @@
 #define PCI_VENDOR_ID_OMEGA		0x119b
 #define PCI_DEVICE_ID_OMEGA_82C092G	0x1221
 
+#define PCI_VENDOR_ID_FUJITSU_ME	0x119e
+#define PCI_DEVICE_ID_FUJITSU_FS155	0x0001
+#define PCI_DEVICE_ID_FUJITSU_FS50	0x0003
+
 #define PCI_SUBVENDOR_ID_KEYSPAN	0x11a9
 #define PCI_SUBDEVICE_ID_KEYSPAN_SX2	0x5334
 
@@ -993,6 +1064,9 @@
 #define PCI_VENDOR_ID_AURAVISION	0x11d1
 #define PCI_DEVICE_ID_AURAVISION_VXP524	0x01f7
 
+#define PCI_VENDOR_ID_ANALOG_DEVICES	0x11d4
+#define PCI_DEVICE_ID_AD1889JS		0x1889
+
 #define PCI_VENDOR_ID_IKON		0x11d5
 #define PCI_DEVICE_ID_IKON_10115	0x0115
 #define PCI_DEVICE_ID_IKON_10117	0x0117
@@ -1087,7 +1161,8 @@
 #define PCI_DEVICE_ID_HUGHES_DIRECPC	0x0002
 
 #define PCI_VENDOR_ID_ENSONIQ		0x1274
-#define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI	0x5000
+#define PCI_DEVICE_ID_ENSONIQ_CT5880	0x5880
+#define PCI_DEVICE_ID_ENSONIQ_ES1370	0x5000
 #define PCI_DEVICE_ID_ENSONIQ_ES1371	0x1371
 
 #define PCI_VENDOR_ID_ROCKWELL		0x127A
@@ -1345,6 +1420,7 @@
 
 #define PCI_VENDOR_ID_DCI		0x6666
 #define PCI_DEVICE_ID_DCI_PCCOM4	0x0001
+#define PCI_DEVICE_ID_DCI_PCCOM8	0x0002
 
 #define PCI_VENDOR_ID_GENROCO		0x5555
 #define PCI_DEVICE_ID_GENROCO_HFP832	0x0003
diff -urN linux-2.4.4-pre4/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- linux-2.4.4-pre4/include/linux/proc_fs.h	Mon Mar 26 15:48:15 2001
+++ linux/include/linux/proc_fs.h	Mon Dec  3 22:35:57 2001
@@ -132,7 +132,7 @@
 		struct proc_dir_entry *,kdev_t);
 extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
 
-extern inline struct proc_dir_entry *create_proc_read_entry(const char *name,
+static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
 	mode_t mode, struct proc_dir_entry *base, 
 	read_proc_t *read_proc, void * data)
 {
@@ -144,7 +144,7 @@
 	return res;
 }
  
-extern inline struct proc_dir_entry *create_proc_info_entry(const char *name,
+static inline struct proc_dir_entry *create_proc_info_entry(const char *name,
 	mode_t mode, struct proc_dir_entry *base, get_info_t *get_info)
 {
 	struct proc_dir_entry *res=create_proc_entry(name,mode,base);
@@ -152,44 +152,44 @@
 	return res;
 }
  
-extern inline struct proc_dir_entry *proc_net_create(const char *name,
+static inline struct proc_dir_entry *proc_net_create(const char *name,
 	mode_t mode, get_info_t *get_info)
 {
 	return create_proc_info_entry(name,mode,proc_net,get_info);
 }
 
-extern inline void proc_net_remove(const char *name)
+static inline void proc_net_remove(const char *name)
 {
 	remove_proc_entry(name,proc_net);
 }
 
 #else
 
-extern inline struct proc_dir_entry *proc_net_create(const char *name, mode_t mode, 
+static inline struct proc_dir_entry *proc_net_create(const char *name, mode_t mode, 
 	get_info_t *get_info) {return NULL;}
-extern inline void proc_net_remove(const char *name) {}
+static inline void proc_net_remove(const char *name) {}
 
-extern inline struct proc_dir_entry *create_proc_entry(const char *name,
+static inline struct proc_dir_entry *create_proc_entry(const char *name,
 	mode_t mode, struct proc_dir_entry *parent) { return NULL; }
 
-extern inline void remove_proc_entry(const char *name, struct proc_dir_entry *parent) {};
-extern inline struct proc_dir_entry *proc_symlink(const char *name,
+static inline void remove_proc_entry(const char *name, struct proc_dir_entry *parent) {};
+static inline struct proc_dir_entry *proc_symlink(const char *name,
 		struct proc_dir_entry *parent,char *dest) {return NULL;}
-extern inline struct proc_dir_entry *proc_mknod(const char *name,mode_t mode,
+static inline struct proc_dir_entry *proc_mknod(const char *name,mode_t mode,
 		struct proc_dir_entry *parent,kdev_t rdev) {return NULL;}
-extern inline struct proc_dir_entry *proc_mkdir(const char *name,
+static inline struct proc_dir_entry *proc_mkdir(const char *name,
 	struct proc_dir_entry *parent) {return NULL;}
 
-extern inline struct proc_dir_entry *create_proc_read_entry(const char *name,
+static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
 	mode_t mode, struct proc_dir_entry *base, 
 	int (*read_proc)(char *, char **, off_t, int, int *, void *),
 	void * data) { return NULL; }
-extern inline struct proc_dir_entry *create_proc_info_entry(const char *name,
+static inline struct proc_dir_entry *create_proc_info_entry(const char *name,
 	mode_t mode, struct proc_dir_entry *base, get_info_t *get_info)
 	{ return NULL; }
 
-extern inline void proc_tty_register_driver(struct tty_driver *driver) {};
-extern inline void proc_tty_unregister_driver(struct tty_driver *driver) {};
+static inline void proc_tty_register_driver(struct tty_driver *driver) {};
+static inline void proc_tty_unregister_driver(struct tty_driver *driver) {};
 
 extern struct proc_dir_entry proc_root;
 
diff -urN linux-2.4.4-pre4/include/linux/rwsem-spinlock.h linux/include/linux/rwsem-spinlock.h
--- linux-2.4.4-pre4/include/linux/rwsem-spinlock.h	Mon Dec  3 22:35:46 2001
+++ linux/include/linux/rwsem-spinlock.h	Mon Dec  3 22:35:57 2001
@@ -54,17 +54,13 @@
 #define __RWSEM_DEBUG_MINIT(name)	/* */
 #endif
 
-#define __RWSEM_INITIALIZER(name,count) \
+#define __RWSEM_INITIALIZER(name) \
 { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
 	__WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
 	__RWSEM_DEBUG_INIT __RWSEM_DEBUG_MINIT(name) }
 
-#define __DECLARE_RWSEM_GENERIC(name,count) \
-	struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
-
-#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS)
-#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
-#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
+#define DECLARE_RWSEM(name) \
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
 
 static inline void init_rwsem(struct rw_semaphore *sem)
 {
diff -urN linux-2.4.4-pre4/include/linux/rwsem.h linux/include/linux/rwsem.h
--- linux-2.4.4-pre4/include/linux/rwsem.h	Mon Dec  3 22:35:46 2001
+++ linux/include/linux/rwsem.h	Mon Dec  3 22:35:57 2001
@@ -42,20 +42,20 @@
 #include <asm/atomic.h>
 #include <linux/wait.h>
 
-#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
-#include <linux/rwsem-spinlock.h> /* use a generic implementation */
-#else
-#include <asm/rwsem.h> /* use an arch-specific implementation */
-#endif
-
 /* defined contention handler functions for the generic case
  * - these are also used for the exchange-and-add based algorithm
  */
-#if defined(CONFIG_RWSEM_GENERIC) || defined(CONFIG_RWSEM_XCHGADD_ALGORITHM)
+#if defined(CONFIG_RWSEM_GENERIC_SPINLOCK) || defined(CONFIG_RWSEM_XCHGADD_ALGORITHM)
 /* we use FASTCALL convention for the helpers */
 extern struct rw_semaphore *FASTCALL(rwsem_down_read_failed(struct rw_semaphore *sem));
 extern struct rw_semaphore *FASTCALL(rwsem_down_write_failed(struct rw_semaphore *sem));
 extern struct rw_semaphore *FASTCALL(rwsem_wake(struct rw_semaphore *sem));
+#endif
+
+#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
+#include <linux/rwsem-spinlock.h> /* use a generic implementation */
+#else
+#include <asm/rwsem.h> /* use an arch-specific implementation */
 #endif
 
 #ifndef rwsemtrace
diff -urN linux-2.4.4-pre4/include/linux/sched.h linux/include/linux/sched.h
--- linux-2.4.4-pre4/include/linux/sched.h	Mon Dec  3 22:35:46 2001
+++ linux/include/linux/sched.h	Mon Dec  3 22:35:57 2001
@@ -239,7 +239,7 @@
 	mm_users:	ATOMIC_INIT(2), 		\
 	mm_count:	ATOMIC_INIT(1), 		\
 	map_count:	1, 				\
-	mmap_sem:	__RWSEM_INITIALIZER(name.mmap_sem, RW_LOCK_BIAS), \
+	mmap_sem:	__RWSEM_INITIALIZER(name.mmap_sem), \
 	page_table_lock: SPIN_LOCK_UNLOCKED, 		\
 	mmlist:		LIST_HEAD_INIT(name.mmlist),	\
 }
diff -urN linux-2.4.4-pre4/include/net/sock.h linux/include/net/sock.h
--- linux-2.4.4-pre4/include/net/sock.h	Mon Dec  3 22:35:46 2001
+++ linux/include/net/sock.h	Mon Dec  3 22:35:57 2001
@@ -739,12 +739,12 @@
 };
 
 /* Called with local bh disabled */
-static void __inline__ sock_prot_inc_use(struct proto *prot)
+static __inline__ void sock_prot_inc_use(struct proto *prot)
 {
 	prot->stats[smp_processor_id()].inuse++;
 }
 
-static void __inline__ sock_prot_dec_use(struct proto *prot)
+static __inline__ void sock_prot_dec_use(struct proto *prot)
 {
 	prot->stats[smp_processor_id()].inuse--;
 }
diff -urN linux-2.4.4-pre4/include/net/tcp.h linux/include/net/tcp.h
--- linux-2.4.4-pre4/include/net/tcp.h	Mon Dec  3 22:35:46 2001
+++ linux/include/net/tcp.h	Mon Dec  3 22:35:57 2001
@@ -19,7 +19,7 @@
 #define _TCP_H
 
 #define TCP_DEBUG 1
-#define FASTRETRANS_DEBUG 2
+#define FASTRETRANS_DEBUG 1
 
 /* Cancel timers, when they are not required. */
 #undef TCP_CLEAR_TIMERS
diff -urN linux-2.4.4-pre4/init/main.c linux/init/main.c
--- linux-2.4.4-pre4/init/main.c	Mon Dec  3 22:35:46 2001
+++ linux/init/main.c	Mon Dec  3 22:35:57 2001
@@ -27,6 +27,7 @@
 #include <linux/hdreg.h>
 #include <linux/iobuf.h>
 #include <linux/bootmem.h>
+#include <linux/tty.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
diff -urN linux-2.4.4-pre4/kernel/ksyms.c linux/kernel/ksyms.c
--- linux-2.4.4-pre4/kernel/ksyms.c	Mon Dec  3 22:35:46 2001
+++ linux/kernel/ksyms.c	Mon Dec  3 22:35:57 2001
@@ -46,6 +46,8 @@
 #include <linux/brlock.h>
 #include <linux/fs.h>
 #include <linux/tty.h>
+#include <linux/in6.h>
+#include <asm/checksum.h>
 
 #if defined(CONFIG_PROC_FS)
 #include <linux/proc_fs.h>
@@ -181,7 +183,6 @@
 EXPORT_SYMBOL(inode_change_ok);
 EXPORT_SYMBOL(write_inode_now);
 EXPORT_SYMBOL(notify_change);
-EXPORT_SYMBOL(get_hardblocksize);
 EXPORT_SYMBOL(set_blocksize);
 EXPORT_SYMBOL(getblk);
 EXPORT_SYMBOL(bdget);
@@ -463,6 +464,7 @@
 EXPORT_SYMBOL(securebits);
 EXPORT_SYMBOL(cap_bset);
 EXPORT_SYMBOL(daemonize);
+EXPORT_SYMBOL(csum_partial); /* for networking and md */
 
 /* Program loader interfaces */
 EXPORT_SYMBOL(setup_arg_pages);
diff -urN linux-2.4.4-pre4/net/atm/clip.c linux/net/atm/clip.c
--- linux-2.4.4-pre4/net/atm/clip.c	Thu Jul  6 21:37:24 2000
+++ linux/net/atm/clip.c	Mon Dec  3 22:35:57 2001
@@ -571,7 +571,6 @@
 	    /* compromise between decent burst-tolerance and protection */
 	    /* against memory hogs. */
 	dev->flags = 0;
-	dev_init_buffers(dev); /* is this ever supposed to be used ? */
 	return 0;
 }
 
diff -urN linux-2.4.4-pre4/net/bridge/br_stp_if.c linux/net/bridge/br_stp_if.c
--- linux-2.4.4-pre4/net/bridge/br_stp_if.c	Mon May  8 22:21:58 2000
+++ linux/net/bridge/br_stp_if.c	Mon Dec  3 22:35:57 2001
@@ -5,7 +5,7 @@
  *	Authors:
  *	Lennert Buytenhek		<buytenh@gnu.org>
  *
- *	$Id: br_stp_if.c,v 1.3 2000/05/05 02:17:17 davem Exp $
+ *	$Id: br_stp_if.c,v 1.4 2001/04/14 21:14:39 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -203,7 +203,10 @@
 /* called under bridge lock */
 void br_stp_set_port_priority(struct net_bridge_port *p, int newprio)
 {
-	int new_port_id = ((newprio & 0xFF) << 8) | p->port_no;
+	__u16 new_port_id;
+
+	p->priority = newprio & 0xFF;
+	new_port_id = br_make_port_id(p);
 
 	if (br_is_designated_port(p))
 		p->designated_port = new_port_id;
diff -urN linux-2.4.4-pre4/net/core/dev.c linux/net/core/dev.c
--- linux-2.4.4-pre4/net/core/dev.c	Mon Dec  3 22:35:46 2001
+++ linux/net/core/dev.c	Mon Dec  3 22:35:57 2001
@@ -1363,7 +1363,7 @@
 void (*br_handle_frame_hook)(struct sk_buff *skb) = NULL;
 #endif
 
-static int __inline__ handle_bridge(struct sk_buff *skb,
+static __inline__ int handle_bridge(struct sk_buff *skb,
 				     struct packet_type *pt_prev)
 {
 	int ret = NET_RX_DROP;
diff -urN linux-2.4.4-pre4/net/econet/Makefile linux/net/econet/Makefile
--- linux-2.4.4-pre4/net/econet/Makefile	Fri Dec 29 14:07:24 2000
+++ linux/net/econet/Makefile	Mon Dec  3 22:35:57 2001
@@ -9,7 +9,8 @@
 
 O_TARGET := econet.o
 
-obj-y := af_econet.o sysctl_net_ec.o
+obj-y := af_econet.o
 obj-m := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.4-pre4/net/econet/af_econet.c linux/net/econet/af_econet.c
--- linux-2.4.4-pre4/net/econet/af_econet.c	Mon Dec  3 22:35:46 2001
+++ linux/net/econet/af_econet.c	Mon Dec  3 22:35:57 2001
@@ -695,8 +695,8 @@
 }
 
 static struct net_proto_family econet_family_ops = {
-	PF_ECONET,
-	econet_create
+	family:		PF_ECONET,
+	create:		econet_create,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
@@ -727,7 +727,7 @@
  *	Find the listening socket, if any, for the given data.
  */
 
-struct sock *ec_listening_socket(unsigned char port, unsigned char
+static struct sock *ec_listening_socket(unsigned char port, unsigned char
 				 station, unsigned char net)
 {
 	struct sock *sk = econet_sklist;
@@ -1065,18 +1065,13 @@
 			       hdr->port);
 }
 
-struct packet_type econet_packet_type=
-{
-	0,
-	NULL,
-	econet_rcv,
-	NULL,
-	NULL
+static struct packet_type econet_packet_type = {
+	type:		__constant_htons(ETH_P_ECONET),
+	func:		econet_rcv,
 };
 
 static void econet_hw_initialise(void)
 {
-	econet_packet_type.type = htons(ETH_P_ECONET);
 	dev_add_pack(&econet_packet_type);
 }
 
@@ -1105,15 +1100,12 @@
 	return NOTIFY_DONE;
 }
 
-struct notifier_block econet_netdev_notifier={
-	econet_notifier,
-	NULL,
-	0
+static struct notifier_block econet_netdev_notifier = {
+	notifier_call:	econet_notifier,
 };
 
-void __exit econet_proto_exit(void)
+static void __exit econet_proto_exit(void)
 {
-	extern void econet_sysctl_unregister(void);
 #ifdef CONFIG_ECONET_AUNUDP
 	del_timer(&ab_cleanup_timer);
 	if (udpsock)
@@ -1121,14 +1113,10 @@
 #endif
 	unregister_netdevice_notifier(&econet_netdev_notifier);
 	sock_unregister(econet_family_ops.family);
-#ifdef CONFIG_SYSCTL
-	econet_sysctl_unregister();
-#endif
 }
 
-int __init econet_proto_init(void)
+static int __init econet_proto_init(void)
 {
-	extern void econet_sysctl_register(void);
 	sock_register(&econet_family_ops);
 #ifdef CONFIG_ECONET_AUNUDP
 	spin_lock_init(&aun_queue_lock);
@@ -1138,9 +1126,6 @@
 	econet_hw_initialise();
 #endif
 	register_netdevice_notifier(&econet_netdev_notifier);
-#ifdef CONFIG_SYSCTL
-	econet_sysctl_register();
-#endif
 	return 0;
 }
 
diff -urN linux-2.4.4-pre4/net/econet/sysctl_net_ec.c linux/net/econet/sysctl_net_ec.c
--- linux-2.4.4-pre4/net/econet/sysctl_net_ec.c	Thu Mar  9 06:57:17 2000
+++ linux/net/econet/sysctl_net_ec.c	Wed Dec 31 16:00:00 1969
@@ -1,43 +0,0 @@
-/*
- *	An implementation of the Acorn Econet and AUN protocols.
- *	Philip Blundell <philb@gnu.org>
- *
- *	Fixes:
- *
- *	This program is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License
- *	as published by the Free Software Foundation; either version
- *	2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/mm.h>
-#include <linux/sysctl.h>
-
-ctl_table econet_table[] = {
-	{0}
-};
-
-static struct ctl_table_header *econet_sysctl_header;
-
-static ctl_table econet_net_table[] = {
-	{NET_ECONET, "econet", NULL, 0, 0555, econet_table},
-        {0}
-};
-
-static ctl_table econet_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, econet_net_table},
-        {0}
-};
-
-void econet_sysctl_register(void)
-{
-	econet_sysctl_header = register_sysctl_table(econet_root_table, 0);
-}
-
-#ifdef MODULE
-void econet_sysctl_unregister(void)
-{
-	unregister_sysctl_table(econet_sysctl_header);
-}
-#endif	/* MODULE */
diff -urN linux-2.4.4-pre4/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- linux-2.4.4-pre4/net/ipv4/icmp.c	Mon Dec  3 22:35:46 2001
+++ linux/net/ipv4/icmp.c	Mon Dec  3 22:35:57 2001
@@ -3,7 +3,7 @@
  *	
  *		Alan Cox, <alan@redhat.com>
  *
- *	Version: $Id: icmp.c,v 1.73 2000/12/13 18:31:48 davem Exp $
+ *	Version: $Id: icmp.c,v 1.74 2001/04/16 23:58:51 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -668,7 +668,7 @@
 
 		ipprot = nextip;
   	}
-out:
+out:;
 }
 
 
@@ -879,7 +879,7 @@
 	case CHECKSUM_NONE:
 		if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))
 			goto error;
-	default:
+	default:;
 	}
 
 	if (!pskb_pull(skb, sizeof(struct icmphdr)))
diff -urN linux-2.4.4-pre4/net/ipv4/ip_gre.c linux/net/ipv4/ip_gre.c
--- linux-2.4.4-pre4/net/ipv4/ip_gre.c	Mon Dec  3 22:35:46 2001
+++ linux/net/ipv4/ip_gre.c	Mon Dec  3 22:35:57 2001
@@ -1147,8 +1147,6 @@
 	dev->do_ioctl		= ipgre_tunnel_ioctl;
 	dev->change_mtu		= ipgre_tunnel_change_mtu;
 
-	dev_init_buffers(dev);
-
 	dev->type		= ARPHRD_IPGRE;
 	dev->hard_header_len 	= LL_MAX_HEADER + sizeof(struct iphdr) + 4;
 	dev->mtu		= 1500 - sizeof(struct iphdr) - 4;
diff -urN linux-2.4.4-pre4/net/ipv4/ipip.c linux/net/ipv4/ipip.c
--- linux-2.4.4-pre4/net/ipv4/ipip.c	Mon Dec  3 22:35:46 2001
+++ linux/net/ipv4/ipip.c	Mon Dec  3 22:35:57 2001
@@ -794,8 +794,6 @@
 	dev->do_ioctl		= ipip_tunnel_ioctl;
 	dev->change_mtu		= ipip_tunnel_change_mtu;
 
-	dev_init_buffers(dev);
-
 	dev->type		= ARPHRD_TUNNEL;
 	dev->hard_header_len 	= LL_MAX_HEADER + sizeof(struct iphdr);
 	dev->mtu		= 1500 - sizeof(struct iphdr);
diff -urN linux-2.4.4-pre4/net/ipv4/netfilter/ip_conntrack_core.c linux/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.4.4-pre4/net/ipv4/netfilter/ip_conntrack_core.c	Mon Dec  3 22:35:46 2001
+++ linux/net/ipv4/netfilter/ip_conntrack_core.c	Mon Dec  3 22:35:57 2001
@@ -1081,10 +1081,14 @@
 	int ret;
 
 	/* Idea from tcp.c: use 1/16384 of memory.  On i386: 32MB
-	 * machine has 256 buckets.  1GB machine has 8192 buckets. */
+	 * machine has 256 buckets.  >= 1GB machines have 8192 buckets. */
 	ip_conntrack_htable_size
 		= (((num_physpages << PAGE_SHIFT) / 16384)
 		   / sizeof(struct list_head));
+	if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
+		ip_conntrack_htable_size = 8192;
+	if (ip_conntrack_htable_size < 16)
+		ip_conntrack_htable_size = 16;
 	ip_conntrack_max = 8 * ip_conntrack_htable_size;
 
 	printk("ip_conntrack (%u buckets, %d max)\n",
diff -urN linux-2.4.4-pre4/net/ipv6/ip6_output.c linux/net/ipv6/ip6_output.c
--- linux-2.4.4-pre4/net/ipv6/ip6_output.c	Mon Dec  3 22:35:46 2001
+++ linux/net/ipv6/ip6_output.c	Mon Dec  3 22:35:57 2001
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: ip6_output.c,v 1.30 2001/03/03 01:20:10 davem Exp $
+ *	$Id: ip6_output.c,v 1.31 2001/04/17 20:39:51 davem Exp $
  *
  *	Based on linux/net/ipv4/ip_output.c
  *
@@ -22,6 +22,7 @@
  *				etc.
  *
  *      H. von Brand    :       Added missing #include <linux/string.h>
+ *	Imran Patel	: 	frag id should be in NBO
  */
 
 #include <linux/config.h>
@@ -55,7 +56,7 @@
 	static spinlock_t ip6_id_lock = SPIN_LOCK_UNLOCKED;
 
 	spin_lock_bh(&ip6_id_lock);
-	fhdr->identification = ipv6_fragmentation_id;
+	fhdr->identification = htonl(ipv6_fragmentation_id);
 	if (++ipv6_fragmentation_id == 0)
 		ipv6_fragmentation_id = 1;
 	spin_unlock_bh(&ip6_id_lock);
diff -urN linux-2.4.4-pre4/net/ipv6/netfilter/Makefile linux/net/ipv6/netfilter/Makefile
--- linux-2.4.4-pre4/net/ipv6/netfilter/Makefile	Mon Jan 22 13:30:21 2001
+++ linux/net/ipv6/netfilter/Makefile	Mon Dec  3 22:35:57 2001
@@ -9,7 +9,6 @@
 
 O_TARGET := netfilter.o
 
-multi-objs :=
 export-objs :=
 
 # Link order matters here.
diff -urN linux-2.4.4-pre4/net/ipv6/sit.c linux/net/ipv6/sit.c
--- linux-2.4.4-pre4/net/ipv6/sit.c	Mon Dec  3 22:35:46 2001
+++ linux/net/ipv6/sit.c	Mon Dec  3 22:35:57 2001
@@ -747,8 +747,6 @@
 	dev->do_ioctl		= ipip6_tunnel_ioctl;
 	dev->change_mtu		= ipip6_tunnel_change_mtu;
 
-	dev_init_buffers(dev);
-
 	dev->type		= ARPHRD_SIT;
 	dev->hard_header_len 	= LL_MAX_HEADER + sizeof(struct iphdr);
 	dev->mtu		= 1500 - sizeof(struct iphdr);
diff -urN linux-2.4.4-pre4/net/ipx/af_spx.c linux/net/ipx/af_spx.c
--- linux-2.4.4-pre4/net/ipx/af_spx.c	Mon Dec  3 22:35:46 2001
+++ linux/net/ipx/af_spx.c	Mon Dec  3 22:35:57 2001
@@ -31,8 +31,6 @@
  *	This material is provided "as is" and at no charge.
  */
 
-#include <linux/config.h>
-#if defined(CONFIG_SPX) || defined(CONFIG_SPX_MODULE)
 #include <linux/module.h>
 #include <net/ipx.h>
 #include <net/spx.h>
@@ -907,15 +905,14 @@
 #include <linux/smp_lock.h>
 SOCKOPS_WRAP(spx, PF_IPX);
 
-
-static struct net_proto_family spx_family_ops=
-{
-	PF_IPX,
-	spx_create
+static struct net_proto_family spx_family_ops = {
+	family:		PF_IPX,
+	create:		spx_create,
 };
 
+static const char banner[] __initdata = KERN_INFO "NET4: Sequenced Packet eXchange (SPX) 0.02 for Linux NET4.0\n";
 
-void spx_proto_init(void)
+static int __init spx_proto_init(void)
 {
 	int error;
 
@@ -927,29 +924,14 @@
 
 	/* route socket(PF_IPX, SOCK_SEQPACKET) calls through spx_create() */
 
-	printk(KERN_INFO "NET4: Sequenced Packet eXchange (SPX) 0.02 for Linux NET4.0\n");
-	return;
+	printk(banner);
+	return 0;
 }
+module_init(spx_proto_init);
 
-void spx_proto_finito(void)
+static void __exit spx_proto_finito(void)
 {
 	ipx_unregister_spx();
 	return;
 }
-
-#ifdef MODULE
-
-int init_module(void)
-{
-        spx_proto_init();
-        return 0;
-}
-
-void cleanup_module(void)
-{
-        spx_proto_finito();
-        return;
-}
-
-#endif /* MODULE */
-#endif /* CONFIG_SPX || CONFIG_SPX_MODULE */
+module_exit(spx_proto_finito);
diff -urN linux-2.4.4-pre4/net/irda/irda_device.c linux/net/irda/irda_device.c
--- linux-2.4.4-pre4/net/irda/irda_device.c	Tue Nov 28 21:53:45 2000
+++ linux/net/irda/irda_device.c	Mon Dec  3 22:35:57 2001
@@ -430,7 +430,6 @@
 	memset(dev->broadcast, 0xff, 4);
 
 	dev->mtu = 2048;
-	dev_init_buffers(dev);
 	dev->flags = IFF_NOARP;
 	return 0;
 }
diff -urN linux-2.4.4-pre4/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
--- linux-2.4.4-pre4/net/netrom/af_netrom.c	Mon Dec  3 22:35:46 2001
+++ linux/net/netrom/af_netrom.c	Mon Dec  3 22:35:57 2001
@@ -1268,7 +1268,7 @@
 {
 	int i;
 
-	if (nr_ndevs * sizeof(struct net_device) >= KMALLOC_MAXSIZE) {
+	if (nr_ndevs > 0x7fffffff/sizeof(struct net_device)) {
 		printk(KERN_ERR "NET/ROM: nr_proto_init - nr_ndevs parameter to large\n");
 		return -1;
 	}
diff -urN linux-2.4.4-pre4/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c
--- linux-2.4.4-pre4/net/netrom/nr_dev.c	Fri Dec 29 14:35:47 2000
+++ linux/net/netrom/nr_dev.c	Mon Dec  3 22:35:57 2001
@@ -231,7 +231,5 @@
 
 	dev->get_stats = nr_get_stats;
 
-	dev_init_buffers(dev);
-
 	return 0;
 };
diff -urN linux-2.4.4-pre4/net/netsyms.c linux/net/netsyms.c
--- linux-2.4.4-pre4/net/netsyms.c	Mon Dec  3 22:35:46 2001
+++ linux/net/netsyms.c	Mon Dec  3 22:35:57 2001
@@ -202,7 +202,6 @@
 EXPORT_SYMBOL(scm_fp_dup);
 EXPORT_SYMBOL(files_stat);
 EXPORT_SYMBOL(memcpy_toiovec);
-EXPORT_SYMBOL(csum_partial);
 
 #ifdef CONFIG_IPX_MODULE
 EXPORT_SYMBOL(make_8023_client);
diff -urN linux-2.4.4-pre4/net/rose/af_rose.c linux/net/rose/af_rose.c
--- linux-2.4.4-pre4/net/rose/af_rose.c	Mon Dec  3 22:35:46 2001
+++ linux/net/rose/af_rose.c	Mon Dec  3 22:35:57 2001
@@ -1395,8 +1395,8 @@
 } 
 
 static struct net_proto_family rose_family_ops = {
-	PF_ROSE,
-	rose_create
+	family:		PF_ROSE,
+	create:		rose_create,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(rose_proto_ops) = {
@@ -1424,18 +1424,24 @@
 SOCKOPS_WRAP(rose_proto, PF_ROSE);
 
 static struct notifier_block rose_dev_notifier = {
-	rose_device_event,
-	0
+	notifier_call:	rose_device_event,
 };
 
 static struct net_device *dev_rose;
 
+static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62 for AX25.037 Linux 2.4\n";
+
 static int __init rose_proto_init(void)
 {
 	int i;
 
 	rose_callsign = null_ax25_address;
 
+	if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device)) {
+		printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter to large\n");
+		return -1;
+	}
+
 	if ((dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device), GFP_KERNEL)) == NULL) {
 		printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n");
 		return -1;
@@ -1451,7 +1457,7 @@
 
 	sock_register(&rose_family_ops);
 	register_netdevice_notifier(&rose_dev_notifier);
-	printk(KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62 for AX25.037 Linux 2.4\n");
+	printk(banner);
 
 	ax25_protocol_register(AX25_P_ROSE, rose_route_frame);
 	ax25_linkfail_register(rose_link_failed);
diff -urN linux-2.4.4-pre4/net/rose/rose_dev.c linux/net/rose/rose_dev.c
--- linux-2.4.4-pre4/net/rose/rose_dev.c	Fri Dec 29 14:35:47 2000
+++ linux/net/rose/rose_dev.c	Mon Dec  3 22:35:57 2001
@@ -200,7 +200,5 @@
 
 	dev->get_stats = rose_get_stats;
 
-	dev_init_buffers(dev);
-
 	return 0;
 };
diff -urN linux-2.4.4-pre4/net/sunrpc/clnt.c linux/net/sunrpc/clnt.c
--- linux-2.4.4-pre4/net/sunrpc/clnt.c	Fri Feb  9 11:29:44 2001
+++ linux/net/sunrpc/clnt.c	Mon Dec  3 22:35:57 2001
@@ -694,9 +694,14 @@
 	}
 
 	if (task->tk_status < 12) {
-		printk(KERN_WARNING "%s: too small RPC reply size (%d bytes)\n",
-			clnt->cl_protname, task->tk_status);
-		rpc_exit(task, -EIO);
+		if (!clnt->cl_softrtry) {
+			task->tk_action = call_transmit;
+			clnt->cl_stats->rpcretrans++;
+		} else {
+			printk(KERN_WARNING "%s: too small RPC reply size (%d bytes)\n",
+				clnt->cl_protname, task->tk_status);
+			rpc_exit(task, -EIO);
+		}
 		return;
 	}
 
diff -urN linux-2.4.4-pre4/net/sysctl_net.c linux/net/sysctl_net.c
--- linux-2.4.4-pre4/net/sysctl_net.c	Sun Mar 25 18:14:25 2001
+++ linux/net/sysctl_net.c	Mon Dec  3 22:35:57 2001
@@ -34,10 +34,6 @@
 extern ctl_table tr_table[];
 #endif
 
-#ifdef CONFIG_ECONET
-extern ctl_table econet_table[];
-#endif
-
 ctl_table net_table[] = {
 	{NET_CORE,   "core",      NULL, 0, 0555, core_table},      
 #ifdef CONFIG_NET
@@ -52,9 +48,6 @@
 #endif
 #ifdef CONFIG_TR
 	{NET_TR, "token-ring", NULL, 0, 0555, tr_table},
-#endif
-#ifdef CONFIG_ECONET
-	{NET_ECONET, "econet",    NULL, 0, 0555, econet_table},
 #endif
 	{0}
 };
