diff -u --recursive --new-file v2.4.6/linux/CREDITS linux/CREDITS
--- v2.4.6/linux/CREDITS	Tue Jul  3 17:08:18 2001
+++ linux/CREDITS	Wed Jul  4 14:41:33 2001
@@ -78,8 +78,8 @@
 D: Unix98 pty support.
 D: APM update to 1.2 spec.
 D: /devfs hacking.
-S: 322 N. Riverside Dr.
-S: Neptune, NJ 07753
+S: 7 Kiwi Loop
+S: Howell, NJ 07731
 S: USA
 
 N: Erik Andersen
@@ -679,6 +679,14 @@
 S: K1N 6Z9
 S: CANADA
 
+N: Jeff Dike
+E: jdike@karaya.com
+W: http://user-mode-linux.sourceforge.net
+D: User mode kernel port
+S: RR1 Box 67C
+S: Deering NH 03244
+S: USA
+
 N: Eddie C. Dost
 E: ecd@skynet.be
 D: Linux/Sparc kernel hacker
@@ -957,6 +965,12 @@
 S: New South Wales, 2121
 S: Australia
 
+N: Carlos E. Gorges 
+E: carlos@techlinux.com.br
+D: fix smp support on cmpci driver
+P: 2048G/EA3C4B19 FF31 33A6 0362 4915 B7EB  E541 17D0 0379 EA3C 4B19
+S: Brazil
+
 N: Dmitry S. Gorodchanin
 E: pgmdsg@ibi.com
 D: RISCom/8 driver, misc kernel fixes.
@@ -1056,6 +1070,11 @@
 S: 2400 AG, Alphen aan den Rijn
 S: The Netherlands
 
+N: Enver Haase
+E: ehaase@inf.fu-berlin.de
+W: http://www.inf.fu-berlin.de/~ehaase
+D: Driver for the Commodore A2232 serial board
+
 N: Bruno Haible
 E: haible@ma2s2.mathematik.uni-karlsruhe.de
 D: SysV FS, shm swapping, memory management fixes
@@ -1269,12 +1288,11 @@
 S: USA
 
 N: Gareth Hughes
-E: gareth@valinux.com
-E: gareth@precisioninsight.com
+E: gareth.hughes@acm.org
 D: Pentium III FXSR, SSE support
-S: 11/187 West Street
-S: Crows Nest NSW 2065
-S: Australia
+D: Author/maintainer of most DRM drivers (especially ATI, MGA)
+D: Core DRM templates, general DRM and 3D-related hacking
+S: No fixed address
 
 N: Kenn Humborg
 E: kenn@wombat.ie
@@ -2253,6 +2271,15 @@
 E: ken@halcyon.com
 D: CDROM driver "sonycd535" (Sony CDU-535/531)
 
+N: Stelian Pop
+E: stelian.pop@fr.alcove.com
+P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0  D3F7 7185 9E7A EDBB 6147
+D: sonypi, meye drivers, mct_u232 usb serial hacks
+S: Alcôve
+S: 153, bd. Anatole France 
+S: 93200 Saint Denis
+S: France
+
 N: Frederic Potter 
 E: fpotter@cirpack.com
 D: Some PCI kernel support
@@ -2349,14 +2376,15 @@
 S: France
 
 N: Rik van Riel
-E: riel@nl.linux.org
-W: http://www.nl.linux.org/~riel/
+E: riel@conectiva.com.br
+W: http://www.surriel.com/
 D: Linux-MM site, Documentation/sysctl/*, swap/mm readaround
 D: clustering contributor, kswapd fixes, random kernel hacker,
-D: nl.linux.org maintainer, minor scheduler additions
-S: IJsselstraat 23a
-S: 9725 GA  Groningen
-S: The Netherlands
+D: nl.linux.org administrator, minor scheduler additions
+S: Conectiva S.A.
+S: R. Tocantins, 89 - Cristo Rei
+S: 80050-430 - Curitiba - Paraná
+S: Brazil
 
 N: Pekka Riikonen
 E: priikone@poseidon.pspt.fi
@@ -2862,6 +2890,7 @@
 N: Petr Vandrovec
 E: vandrove@vc.cvut.cz
 D: Small contributions to ncpfs
+D: Matrox framebuffer driver
 S: Chudenicka 8
 S: 10200 Prague 10, Hostivar
 S: Czech Republic
diff -u --recursive --new-file v2.4.6/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.4.6/linux/Documentation/Configure.help	Tue Jul  3 17:08:18 2001
+++ linux/Documentation/Configure.help	Tue Jul 17 18:53:55 2001
@@ -3372,6 +3372,30 @@
   As this card technology is 15 years old, most people will answer N
   here.
 
+NEC PowerVR 2 display support
+CONFIG_FB_PVR2
+  Say Y here if you have a PowerVR 2 card in your box. If you plan to
+  run linux on your Dreamcast, you will have to say Y here. This driver
+  may or may not work on other PowerVR 2 cards, but is totally untested.
+  Use at your own risk. If unsure, say N.
+
+  This driver is also available as a module ( = code which can be
+  inserted and removed from the running kernel whenever you want).
+  The module will be called pvr2fb.o. If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
+
+  You can pass several parameters to the driver at boot time or at
+  module load time. The parameters look like "video=pvr2:XXX", where
+  the meaning of XXX can be found at the end of the main source file
+  (drivers/video/pvr2fb.c). Please see the file
+  Documentation/fb/pvr2fb.txt.
+
+Debug pvr2fb
+CONFIG_FB_PVR2_DEBUG
+  Say Y here if you wish for the pvr2fb driver to print out debugging
+  messages. Most people will want to say N here. If unsure, you will
+  also want to say N.
+
 Matrox unified accelerated driver (EXPERIMENTAL)
 CONFIG_FB_MATROX
   Say Y here if you have a Matrox Millennium, Matrox Millennium II,
@@ -3712,6 +3736,12 @@
   
   If unsure, say Y.
 
+Parallel+serial PCI card support
+CONFIG_PARPORT_SERIAL
+  This adds support for multi-IO PCI cards that have parallel and serial
+  ports.  You should say Y or M here.  If you say M, the module will be
+  called parport_serial.o.
+
 Use FIFO/DMA if available
 CONFIG_PARPORT_PC_FIFO
   Many parallel port chipsets provide hardware that can speed up
@@ -8842,6 +8872,18 @@
   say M here and read Documentation/modules.txt. This is recommended.
   The module will be called myri_sbus.o.
 
+D-Link 2000-based Gigabit Ethernet support
+CONFIG_DL2K
+  This driver supports D-Link 2000-based gigabit ethernet cards, which
+  includes
+	D-Link DGE-550T Gigabit Ethernet Adapter.
+	D-Link DL2000-based Gigabit Ethernet Adapter.
+
+  If you want to compile this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. This is recommended.
+  The module will be called dl2k.o.
+
 AMD LANCE and PCnet (AT1500 and NE2100) support
 CONFIG_LANCE
   If you have a network (Ethernet) card of this type, say Y and read
@@ -12162,34 +12204,38 @@
   The module is called freevxfs.o. If you want to compile it as a module,
   say M here and read Documentation/modules.txt. If unsure, say N.
 
-NTFS support (read only)
+NTFS file system support (read-only)
 CONFIG_NTFS_FS
   NTFS is the file system of Microsoft Windows NT. Say Y if you want
   to get read access to files on NTFS partitions of your hard drive.
   The Linux NTFS driver supports most of the mount options of the VFAT
-  driver, see Documentation/filesystems/ntfs.txt. Saying Y here will
-  give you read-only access to NTFS partitions.
+  driver, see <file:Documentation/filesystems/ntfs.txt>. Saying Y here
+  will give you read-only access to NTFS partitions.
 
   This code 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 ntfs.o. If you want to compile it as a
-  module, say M here and read Documentation/modules.txt.
+  module, say M here and read <file:Documentation/modules.txt>.
 
 NTFS write support (DANGEROUS)
 CONFIG_NTFS_RW
   If you say Y here, you will (maybe) be able to write to NTFS file
-  systems as well as read from them. The read-write support in
-  NTFS is far from being complete and is not well tested. If you
-  say Y here, back up your NTFS volume first since it may get
-  damaged. Also, make sure to run chkdsk from within Microsoft
-  Windows NT after having performed any writes to a NTFS partition
-  from Linux to detect any problems as early as possible.
+  systems as well as read from them. The read-write support in NTFS
+  is far from being complete and is not well tested. If you say Y
+  here, back up your NTFS volume first, since it will probably get
+  damaged. Also, download the Linux-NTFS project distribution from
+  Sourceforge at <http://linux-ntfs.sf.net/> and always run the
+  included ntfsfix utility after writing to an NTFS partition from
+  Linux to fix some of the damage done by the driver. You should run
+  ntfsfix _after_ unmounting the partition in Linux but _before_
+  rebooting into Windows. When Windows next boots, chkdsk will be
+  run automatically to fix the remaining damage.
   Please note that write support is limited to Windows NT4 and
   earlier versions.
 
   If unsure, say N.
 
-System V, Version 7, Xenix and Coherent filesystem support (read only)
+System V, Version 7, Xenix and Coherent filesystem support
 CONFIG_SYSV_FS
   SCO, Xenix and Coherent are commercial Unix systems for Intel
   machines, and Version 7 was used on the DEC PDP-11. Saying Y
@@ -12199,14 +12245,12 @@
 
   If you have floppies or hard disk partitions like that, it is likely
   that they contain binaries from those other Unix systems; in order
-  to run these binaries, you will want to install iBCS2 (Intel Binary
-  Compatibility Standard is a kernel module which lets you run SCO,
-  Xenix, Wyse, UnixWare, Dell Unix and System V programs under Linux
-  and is often needed to run commercial software that's only available
-  for those systems. It's available via FTP (user: anonymous) from
-  ftp://tsx-11.mit.edu/pub/linux/BETA ). NOTE: that will work only for
-  binaries from Intel-based systems; PDP ones will have to wait until
-  somebody ports Linux to -11 ;-)
+  to run these binaries, you will want to install linux-abi which is a
+  a set of kernel modules that lets you run SCO, Xenix, Wyse, UnixWare,
+  Dell Unix and System V programs under Linux.  It's available via FTP
+  (user: ftp) from ftp://ftp.openlinux.org/pub/people/hch/linux-abi).
+  NOTE: that will work only for binaries from Intel-based systems;
+  PDP ones will have to wait until somebody ports Linux to -11 ;-)
 
   If you only intend to mount files from some other Unix over the
   network using NFS, you don't need the System V file system support
@@ -12227,15 +12271,6 @@
 
   If you haven't heard about all of this before, it's safe to say N.
 
-SYSV file system write support (DANGEROUS)
-CONFIG_SYSV_FS_WRITE
-  If you say Y here, you will be able to write to hard drive
-  partitions and floppy disks which carry a SYSV file system used the
-  commercial Unixes SCO, Xenix and Coherent. 
-
-  This support is experimental and you may destroy your data. If
-  unsure, say N.
-
 Amiga FFS file system support
 CONFIG_AFFS_FS
   The Fast File System (FFS) is the common file system used on hard
@@ -13480,10 +13515,12 @@
   doing that; to actually get it to happen you need to pass the
   option "console=lp0" to the kernel at boot time.
 
-  Note that kernel messages can get lost if the printer is out of
-  paper (or off, or unplugged, or too busy..), but this behaviour
-  can be changed. See drivers/char/lp.c (do this at your own risk).
-
+  If the printer is out of paper (or off, or unplugged, or too
+  busy..) the kernel will stall until the printer is ready again.
+  By defining CONSOLE_LP_STRICT to 0 (at your own risk) you
+  can make the kernel continue when this happens,
+  but it'll lose the kernel messages.
+  
   If unsure, say N.
 
 Support for user-space parallel port device drivers
@@ -15587,9 +15624,18 @@
 VIA 82Cxxx Audio Codec
 CONFIG_SOUND_VIA82CXXX
   Say Y here to include support for the audio codec found on VIA
-  82Cxxx-based chips. Typically these are built into a motherboard. DO
-  NOT select Sound Blaster or Adlib with this driver, unless you have
-  a Sound Blaster or Adlib card in addition to your VIA audio chip.
+  82Cxxx-based chips. Typically these are built into a motherboard.
+
+  DO NOT select Sound Blaster or Adlib with this driver, unless
+  you have a Sound Blaster or Adlib card in addition to your VIA
+  audio chip.
+
+VIA 82C686 MIDI
+CONFIG_MIDI_VIA82CXXX
+   Answer Y to use the MIDI interface of the Via686. You may need to
+   enable this in the BIOS before it will work. This is for connection
+   to external MIDI hardware, and is not required for software playback
+   of MIDI files.
 
 NeoMagic 256AV/256ZX sound chipsets
 CONFIG_SOUND_NM256
diff -u --recursive --new-file v2.4.6/linux/Documentation/DocBook/Makefile linux/Documentation/DocBook/Makefile
--- v2.4.6/linux/Documentation/DocBook/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/Documentation/DocBook/Makefile	Sun Jul  8 13:13:47 2001
@@ -1,7 +1,7 @@
 BOOKS	:= wanbook.sgml z8530book.sgml mcabook.sgml videobook.sgml \
 	   kernel-api.sgml parportbook.sgml kernel-hacking.sgml \
 	   kernel-locking.sgml via-audio.sgml mousedrivers.sgml sis900.sgml \
-	   deviceiobook.sgml procfs-guide.sgml
+	   deviceiobook.sgml procfs-guide.sgml tulip-user.sgml
 
 PS	:=	$(patsubst %.sgml, %.ps, $(BOOKS))
 PDF	:=	$(patsubst %.sgml, %.pdf, $(BOOKS))
@@ -61,6 +61,9 @@
 via-audio.sgml: via-audio.tmpl $(TOPDIR)/drivers/sound/via82cxxx_audio.c
 	$(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/sound/via82cxxx_audio.c \
 		<via-audio.tmpl >via-audio.sgml
+
+tulip-user.sgml: tulip-user.tmpl
+	$(TOPDIR)/scripts/docgen <$< >$@
 
 sis900.sgml: sis900.tmpl $(TOPDIR)/drivers/net/sis900.c
 	$(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/net/sis900.c \
diff -u --recursive --new-file v2.4.6/linux/Documentation/DocBook/via-audio.tmpl linux/Documentation/DocBook/via-audio.tmpl
--- v2.4.6/linux/Documentation/DocBook/via-audio.tmpl	Mon Oct 30 12:24:22 2000
+++ linux/Documentation/DocBook/via-audio.tmpl	Sun Jul  8 13:14:00 2001
@@ -17,7 +17,7 @@
   </authorgroup>
 
   <copyright>
-   <year>2000</year>
+   <year>1999-2001</year>
    <holder>Jeff Garzik</holder>
   </copyright>
 
@@ -149,23 +149,6 @@
      <title>Known Bugs And Assumptions</title>
   <para>
   <variablelist>
-    <varlistentry><term>MMAP support</term>
-    <listitem>
-    <para>
-    	MMAP support is currently missing.  Make sure to
-	test with Quake.
-    </para>
-    </listitem></varlistentry>
-
-    <varlistentry><term>AC97 codec timeout during init</term>
-    <listitem>
-    <para>
-    	A warning message "via82cxxx: timeout while reading AC97
-	codec" is printed during driver initialization.  This
-	message can safely be ignored.
-    </para>
-    </listitem></varlistentry>
-
     <varlistentry><term>Low volume</term>
     <listitem>
     <para>
@@ -198,6 +181,16 @@
   <para>
 	AC97 mixer interface fixes and debugging by Ron Cemer <email>roncemer@gte.net</email>.
   </para>
+  <para>
+	Rui Sousa <email>rui.sousa@conexant.com</email>, for bugfixing
+	MMAP support, and several other notable fixes that resulted from
+	his hard work and testing.
+  </para>
+  <para>
+	Adrian Cox <email>adrian@humboldt.co.uk</email>, for bugfixing
+	MMAP support, and several other notable fixes that resulted from
+	his hard work and testing.
+  </para>
   </chapter>
   
   <chapter id="notes">
@@ -219,7 +212,10 @@
 	and device ids are not examined.
   </para>
   <para>
-	GNU indent formatting options:  -kr -i8 -pcs
+	GNU indent formatting options:
+  <programlisting>
+-kr -i8 -ts8 -br -ce -bap -sob -l80 -pcs -cs -ss -bs -di1 -nbc -lp -psl
+  </programlisting>
   </para>
   <para>
 	Via has graciously donated e-mail support and source code to help further
@@ -237,6 +233,79 @@
 
   <chapter id="changelog">
       <title>Driver ChangeLog</title>
+
+<sect1 id="version1115"><title>
+Version 1.1.15
+</title>
+  <itemizedlist spacing=compact>
+   <listitem>
+    <para>
+    Support for variable fragment size and variable fragment number (Rui
+    Sousa)
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+    Fixes for the SPEED, STEREO, CHANNELS, FMT ioctls when in read &
+    write mode (Rui Sousa)
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+    Mmaped sound is now fully functional. (Rui Sousa)
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+    Make sure to enable PCI device before reading any of its PCI
+    config information. (fixes potential hotplug problems)
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+    Clean up code a bit and add more internal function documentation.
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+    AC97 codec access fixes (Adrian Cox)
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+    Big endian fixes (Adrian Cox)
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+    MIDI support (Adrian Cox)
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+    Detect and report locked-rate AC97 codecs.  If your hardware only
+    supports 48Khz (locked rate), then your recording/playback software
+    must upsample or downsample accordingly.  The hardware cannot do it.
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+    Use new pci_request_regions and pci_disable_device functions in
+    kernel 2.4.6.
+    </para>
+   </listitem>
+
+  </itemizedlist>
+</sect1>
 
 <sect1 id="version1114"><title>
 Version 1.1.14
diff -u --recursive --new-file v2.4.6/linux/Documentation/DocBook/videobook.tmpl linux/Documentation/DocBook/videobook.tmpl
--- v2.4.6/linux/Documentation/DocBook/videobook.tmpl	Thu Jan  4 12:50:12 2001
+++ linux/Documentation/DocBook/videobook.tmpl	Sun Jul 15 16:15:44 2001
@@ -179,23 +179,23 @@
    <tgroup cols=3 align=left>
    <tbody>
    <row>
-        <entry>VFL_TYPE_RADIO</><>/dev/radio{n}</><>
+        <entry>VFL_TYPE_RADIO</><entry>/dev/radio{n}</><entry>
 
         Radio devices are assigned in this block. As with all of these
         selections the actual number assignment is done by the video layer
         accordijng to what is free.</entry>
 	</row><row>
-        <entry>VFL_TYPE_GRABBER</><>/dev/video{n}</><>
+        <entry>VFL_TYPE_GRABBER</><entry>/dev/video{n}</><entry>
         Video capture devices and also -- counter-intuitively for the name --
         hardware video playback devices such as MPEG2 cards.</entry>
 	</row><row>
-        <entry>VFL_TYPE_VBI</><>/dev/vbi{n}</><>
+        <entry>VFL_TYPE_VBI</><entry>/dev/vbi{n}</><entry>
         The VBI devices capture the hidden lines on a television picture
         that carry further information like closed caption data, teletext
         (primarily in Europe) and now Intercast and the ATVEC internet
         television encodings.</entry>
 	</row><row>
-        <entry>VFL_TYPE_VTX</><>/dev/vtx[n}</><>
+        <entry>VFL_TYPE_VTX</><entry>/dev/vtx[n}</><entry>
         VTX is 'Videotext' also known as 'Teletext'. This is a system for
         sending numbered, 40x25, mostly textual page images over the hidden
         lines. Unlike the /dev/vbi interfaces, this is for 'smart' decoder 
@@ -302,25 +302,25 @@
    <tgroup cols=2 align=left>
    <tbody>
    <row>
-        <entry>name</><>The device text name. This is intended for the user.</>
+        <entry>name</><entry>The device text name. This is intended for the user.</>
 	</row><row>
-        <entry>channels</><>The number of different channels you can tune on
+        <entry>channels</><entry>The number of different channels you can tune on
                         this card. It could even by zero for a card that has
                         no tuning capability. For our simple FM radio it is 1. 
                         An AM/FM radio would report 2.</entry>
 	</row><row>
-        <entry>audios</><>The number of audio inputs on this device. For our
+        <entry>audios</><entry>The number of audio inputs on this device. For our
                         radio there is only one audio input.</entry>
 	</row><row>
-        <entry>minwidth,minheight</><>The smallest size the card is capable of capturing
+        <entry>minwidth,minheight</><entry>The smallest size the card is capable of capturing
 		        images in. We set these to zero. Radios do not
                         capture pictures</entry>
 	</row><row>
-        <entry>maxwidth,maxheight</><>The largest image size the card is capable of
+        <entry>maxwidth,maxheight</><entry>The largest image size the card is capable of
                                       capturing. For our radio we report 0.
 				</entry>
 	</row><row>
-        <entry>type</><>This reports the capabilities of the device, and
+        <entry>type</><entry>This reports the capabilities of the device, and
                         matches the field we filled in in the struct
                         video_device when registering.</entry>
     </row>
@@ -415,7 +415,7 @@
 	</row><row>
         <entry>VIDEO_TUNER_SECAM</><entry>A SECAM (French) TV tuner</entry>
 	</row><row>
-        <entry>VIDEO_TUNER_LOW</><>
+        <entry>VIDEO_TUNER_LOW</><entry>
              The tuner frequency is scaled in 1/16th of a KHz
              steps. If not it is in 1/16th of a MHz steps
 	</entry>
@@ -432,13 +432,13 @@
    <tgroup cols=2 align=left>
    <tbody>
    <row>
-                <entry>VIDEO_MODE_PAL</><>PAL Format</entry>
+                <entry>VIDEO_MODE_PAL</><entry>PAL Format</entry>
    </row><row>
-                <entry>VIDEO_MODE_NTSC</><>NTSC Format (USA)</entry>
+                <entry>VIDEO_MODE_NTSC</><entry>NTSC Format (USA)</entry>
    </row><row>
-                <entry>VIDEO_MODE_SECAM</><>French Format</entry>
+                <entry>VIDEO_MODE_SECAM</><entry>French Format</entry>
    </row><row>
-                <entry>VIDEO_MODE_AUTO</><>A device that does not need to do
+                <entry>VIDEO_MODE_AUTO</><entry>A device that does not need to do
                                         TV format switching</entry>
    </row>
     </tbody>
@@ -583,30 +583,30 @@
    <tgroup cols=2 align=left>
    <tbody>
    <row>
-   <entry>audio</><>The input the user wishes to query</>
+   <entry>audio</><entry>The input the user wishes to query</>
    </row><row>
-   <entry>volume</><>The volume setting on a scale of 0-65535</>
+   <entry>volume</><entry>The volume setting on a scale of 0-65535</>
    </row><row>
-   <entry>base</><>The base level on a scale of 0-65535</>
+   <entry>base</><entry>The base level on a scale of 0-65535</>
    </row><row>
-   <entry>treble</><>The treble level on a scale of 0-65535</>
+   <entry>treble</><entry>The treble level on a scale of 0-65535</>
    </row><row>
-   <entry>flags</><>The features this audio device supports
+   <entry>flags</><entry>The features this audio device supports
    </entry>
    </row><row>
-   <entry>name</><>A text name to display to the user. We picked 
+   <entry>name</><entry>A text name to display to the user. We picked 
                         "Radio" as it explains things quite nicely.</>
    </row><row>
-   <entry>mode</><>The current reception mode for the audio
+   <entry>mode</><entry>The current reception mode for the audio
 
                 We report MONO because our card is too stupid to know if it is in
                 mono or stereo. 
    </entry>
    </row><row>
-   <entry>balance</><>The stereo balance on a scale of 0-65535, 32768 is
+   <entry>balance</><entry>The stereo balance on a scale of 0-65535, 32768 is
                         middle.</>
    </row><row>
-   <entry>step</><>The step by which the volume control jumps. This is
+   <entry>step</><entry>The step by which the volume control jumps. This is
                         used to help make it easy for applications to set 
                         slider behaviour.</>   
    </row>
@@ -618,15 +618,15 @@
    <tgroup cols=2 align=left>
    <tbody>
    <row>
-                <entry>VIDEO_AUDIO_MUTE</><>The audio is currently muted. We
+                <entry>VIDEO_AUDIO_MUTE</><entry>The audio is currently muted. We
                                         could fake this in our driver but we
                                         choose not to bother.</entry>
    </row><row>
-                <entry>VIDEO_AUDIO_MUTABLE</><>The input has a mute option</entry>
+                <entry>VIDEO_AUDIO_MUTABLE</><entry>The input has a mute option</entry>
    </row><row>
-                <entry>VIDEO_AUDIO_TREBLE</><>The  input has a treble control</entry>
+                <entry>VIDEO_AUDIO_TREBLE</><entry>The  input has a treble control</entry>
    </row><row>
-                <entry>VIDEO_AUDIO_BASS</><>The input has a base control</entry>
+                <entry>VIDEO_AUDIO_BASS</><entry>The input has a base control</entry>
    </row>
    </tbody>
    </tgroup>
@@ -636,13 +636,13 @@
    <tgroup cols=2 align=left>
    <tbody>
    <row>
-                <entry>VIDEO_SOUND_MONO</><>Mono sound</entry>
+                <entry>VIDEO_SOUND_MONO</><entry>Mono sound</entry>
    </row><row>
-                <entry>VIDEO_SOUND_STEREO</><>Stereo sound</entry>
+                <entry>VIDEO_SOUND_STEREO</><entry>Stereo sound</entry>
    </row><row>
-                <entry>VIDEO_SOUND_LANG1</><>Alternative language 1 (TV specific)</entry>
+                <entry>VIDEO_SOUND_LANG1</><entry>Alternative language 1 (TV specific)</entry>
    </row><row>
-                <entry>VIDEO_SOUND_LANG2</><>Alternative language 2 (TV specific)</entry>
+                <entry>VIDEO_SOUND_LANG2</><entry>Alternative language 2 (TV specific)</entry>
    </row>
    </tbody>
    </tgroup>
@@ -867,33 +867,33 @@
    <tgroup cols=2 align=left>
    <tbody>
    <row>
-<entry>VID_TYPE_CAPTURE</><>We support image capture</>
+<entry>VID_TYPE_CAPTURE</><entry>We support image capture</>
 </row><row>
-<entry>VID_TYPE_TELETEXT</><>A teletext capture device (vbi{n])</>
+<entry>VID_TYPE_TELETEXT</><entry>A teletext capture device (vbi{n])</>
 </row><row>
-<entry>VID_TYPE_OVERLAY</><>The image can be directly overlaid onto the
+<entry>VID_TYPE_OVERLAY</><entry>The image can be directly overlaid onto the
                                 frame buffer</>
 </row><row>
-<entry>VID_TYPE_CHROMAKEY</><>Chromakey can be used to select which parts
+<entry>VID_TYPE_CHROMAKEY</><entry>Chromakey can be used to select which parts
                                 of the image to display</>
 </row><row>
-<entry>VID_TYPE_CLIPPING</><>It is possible to give the board a list of
+<entry>VID_TYPE_CLIPPING</><entry>It is possible to give the board a list of
                                 rectangles to draw around. </>
 </row><row>
-<entry>VID_TYPE_FRAMERAM</><>The video capture goes into the video memory
+<entry>VID_TYPE_FRAMERAM</><entry>The video capture goes into the video memory
                                 and actually changes it. Applications need
                                 to know this so they can clean up after the
                                 card</>
 </row><row>
-<entry>VID_TYPE_SCALES</><>The image can be scaled to various sizes,
+<entry>VID_TYPE_SCALES</><entry>The image can be scaled to various sizes,
                                 rather than being a single fixed size.</>
 </row><row>
-<entry>VID_TYPE_MONOCHROME</><>The capture will be monochrome. This isn't a 
+<entry>VID_TYPE_MONOCHROME</><entry>The capture will be monochrome. This isn't a 
                                 complete answer to the question since a mono
                                 camera on a colour capture card will still
                                 produce mono output.</>
 </row><row>
-<entry>VID_TYPE_SUBCAPTURE</><>The card allows only part of its field of
+<entry>VID_TYPE_SUBCAPTURE</><entry>The card allows only part of its field of
                                 view to be captured. This enables
                                 applications to avoid copying all of a large
                                 image into memory when only some section is
@@ -1209,18 +1209,18 @@
    <tbody>
    <row>
 
-   <entry>channel</><>The channel number we are selecting</entry>
+   <entry>channel</><entry>The channel number we are selecting</entry>
    </row><row>
-   <entry>name</><>The name for this channel. This is intended
+   <entry>name</><entry>The name for this channel. This is intended
                    to describe the port to the user.
                    Appropriate names are therefore things like
                    "Camera" "SCART input"</entry>
    </row><row>
-   <entry>flags</><>Channel properties</entry>
+   <entry>flags</><entry>Channel properties</entry>
    </row><row>
-   <entry>type</><>Input type</entry>
+   <entry>type</><entry>Input type</entry>
    </row><row>
-   <entry>norm</><>The current television encoding being used
+   <entry>norm</><entry>The current television encoding being used
                    if relevant for this channel.
     </entry>
     </row>
@@ -1231,9 +1231,9 @@
     <tgroup cols=2 align=left>
     <tbody>
     <row>
-        <entry>VIDEO_VC_TUNER</><>Channel has a tuner.</entry>
+        <entry>VIDEO_VC_TUNER</><entry>Channel has a tuner.</entry>
    </row><row>
-        <entry>VIDEO_VC_AUDIO</><>Channel has audio.</entry>
+        <entry>VIDEO_VC_AUDIO</><entry>Channel has audio.</entry>
     </row>
     </tbody>
     </tgroup>
@@ -1242,11 +1242,11 @@
     <tgroup cols=2 align=left>
     <tbody>
     <row>
-        <entry>VIDEO_TYPE_TV</><>Television input.</entry>
+        <entry>VIDEO_TYPE_TV</><entry>Television input.</entry>
    </row><row>
-        <entry>VIDEO_TYPE_CAMERA</><>Fixed camera input.</entry>
+        <entry>VIDEO_TYPE_CAMERA</><entry>Fixed camera input.</entry>
    </row><row>
-	<entry>0</><>Type is unknown.</entry>
+	<entry>0</><entry>Type is unknown.</entry>
     </row>
     </tbody>
     </tgroup>
@@ -1255,13 +1255,13 @@
     <tgroup cols=2 align=left>
     <tbody>
     <row>
-        <entry>VIDEO_MODE_PAL</><>PAL encoded Television</entry>
+        <entry>VIDEO_MODE_PAL</><entry>PAL encoded Television</entry>
    </row><row>
-        <entry>VIDEO_MODE_NTSC</><>NTSC (US) encoded Television</entry>
+        <entry>VIDEO_MODE_NTSC</><entry>NTSC (US) encoded Television</entry>
    </row><row>
-        <entry>VIDEO_MODE_SECAM</><>SECAM (French) Television </entry>
+        <entry>VIDEO_MODE_SECAM</><entry>SECAM (French) Television </entry>
    </row><row>
-        <entry>VIDEO_MODE_AUTO</><>Automatic switching, or format does not
+        <entry>VIDEO_MODE_AUTO</><entry>Automatic switching, or format does not
                                 matter</entry>
     </row>
     </tbody>
@@ -1341,13 +1341,13 @@
    <tgroup cols=2 align=left>
    <tbody>
    <row>
-   <entry>GREY</><>Linear greyscale. This is for simple cameras and the
+   <entry>GREY</><entry>Linear greyscale. This is for simple cameras and the
                         like</>
    </row><row>
-   <entry>RGB565</><>The top 5 bits hold 32 red levels, the next six bits 
+   <entry>RGB565</><entry>The top 5 bits hold 32 red levels, the next six bits 
                         hold green and the low 5 bits hold blue. </>
    </row><row>
-   <entry>RGB555</><>The top bit is clear. The red green and blue levels
+   <entry>RGB555</><entry>The top bit is clear. The red green and blue levels
                         each occupy five bits.</>
     </row>
     </tbody>
@@ -1479,32 +1479,32 @@
    <tgroup cols=2 align=left>
    <tbody>
    <row>
-        <entry>width</><>The width in pixels of the desired image. The card
+        <entry>width</><entry>The width in pixels of the desired image. The card
                         may use a smaller size if this size is not available</>
 	</row><row>
-        <entry>height</><>The height of the image. The card may use a smaller
+        <entry>height</><entry>The height of the image. The card may use a smaller
                         size if this size is not available.</>
 	</row><row>
-        <entry>x</><>   The X position of the top left of the window. This
+        <entry>x</><entry>   The X position of the top left of the window. This
                         is in pixels relative to the left hand edge of the
                         picture. Not all cards can display images aligned on
                         any pixel boundary. If the position is unsuitable
                         the card adjusts the image right and reduces the
                         width.</>
 	</row><row>
-        <entry>y</><>   The Y position of the top left of the window. This
+        <entry>y</><entry>   The Y position of the top left of the window. This
                         is counted in pixels relative to the top edge of the
                         picture. As with the width if the card cannot
                         display  starting on this line it will adjust the
                         values.</>
 	</row><row>
-        <entry>chromakey</><>The colour (expressed in RGB32 format) for the
+        <entry>chromakey</><entry>The colour (expressed in RGB32 format) for the
                         chromakey colour if chroma keying is being used. </>
 	</row><row>
-        <entry>clips</><>An array of rectangles that must not be drawn
+        <entry>clips</><entry>An array of rectangles that must not be drawn
 			over.</>
 	</row><row>
-        <entry>clipcount</><>The number of clips in this array.</>
+        <entry>clipcount</><entry>The number of clips in this array.</>
     </row>
     </tbody>
     </tgroup>
@@ -1516,11 +1516,11 @@
    <tgroup cols=2 align=left>
    <tbody>
    <row>
-        <entry>x, y</><>Co-ordinates relative to the display</>
+        <entry>x, y</><entry>Co-ordinates relative to the display</>
 	</row><row>
-        <entry>width, height</><>Width and height in pixels</>
+        <entry>width, height</><entry>Width and height in pixels</>
 	</row><row>
-        <entry>next</><>A spare field for the application to use</>
+        <entry>next</><entry>A spare field for the application to use</>
     </row>
     </tbody>
     </tgroup>
diff -u --recursive --new-file v2.4.6/linux/Documentation/README.nsp_cs.eng linux/Documentation/README.nsp_cs.eng
--- v2.4.6/linux/Documentation/README.nsp_cs.eng	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/README.nsp_cs.eng	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,127 @@
+
+         WorkBiT NinjaSCSI-3/32Bi driver for Linux
+
+1. Comment
+ This is Workbit corp.'s(http://www.workbit.co.jp/) NinjaSCSI-3
+(http://www.workbit.co.jp/ts/z_nj3r.html) and NinjaSCSI-32Bi
+(http://www.workbit.co.jp/ts/z_njsc32bi.html) PCMCIA card driver module
+for Linux.
+
+2. My Linux environment
+Linux kernel: 2.4.0 / 2.2.18
+pcmcia-cs:    3.1.24
+gcc:          gcc-2.95.2
+PC card:      I-O data PCSC-F (NinjaSCSI-3)
+              I-O data CBSC-II in 16 bit mode (NinjaSCSI-32Bi)
+SCSI device:  I-O data CDPS-PX24 (CD-ROM drive)
+              Media Intelligent MMO-640GT (Optical disk drive)
+
+3. Install
+[1] Check your PC card is true "NinjaSCSI-3" card.
+    If you installed pcmcia-cs already, pcmcia reports your card as UNKNOWN
+    card, and write ["WBT", "NinjaSCSI-3", "R1.0"] or some other string to
+    your console or log file.
+    You can also use "cardctl" program (this program is in pcmcia-cs source
+    code) to get more info.
+
+# cat /var/log/messgaes
+...
+Jan  2 03:45:06 lindberg cardmgr[78]: unsupported card in socket 1
+Jan  2 03:45:06 lindberg cardmgr[78]:   product info: "WBT", "NinjaSCSI-3", "R1.0"
+...
+# cardctl ident
+Socket 0:
+  no product info available
+Socket 1:
+  product info: "IO DATA", "CBSC16       ", "1"
+
+
+[2] Get Linux kernel source, and extract it to /usr/src.
+    Because NinjaSCSI driver requiers some SCSI header files in Linux kernel
+    source.
+    I recomend rebuilding your kernel. This eliminate some versioning problem.
+$ cd /usr/src
+$ tar -zxvf linux-x.x.x.tar.gz
+$ cd linux
+$ make config
+...
+
+[3] If you use this driver with Kernel 2.2, Unpack pcmcia-cs in some directory
+    and make & install. This driver requies pcmcia-cs header file.
+$ cd /usr/src
+$ tar zxvf cs-pcmcia-cs-3.x.x.tar.gz
+...
+
+[4] Extract this driver's archive somewhere, and edit Makefile, then do make.
+$ tar -zxvf nsp_cs-x.x.tar.gz
+$ cd nsp_cs-x.x
+$ make
+
+[5] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
+
+[6] Add these lines to /etc/pcmcia/config .
+    If you yse pcmcia-cs-3.1.8 or later, we can use "nsp_cs.conf" file.
+    So, you don't need to edit file. Just copy to /etc/pcmcia/ .
+
+-------------------------------------
+device "nsp_cs"
+  class "scsi" module "nsp_cs"
+
+card "WorkBit NinjaSCSI-3"
+  version "WBT", "NinjaSCSI-3", "R1.0"
+  bind "nsp_cs"
+
+card "WorkBit NinjaSCSI-32Bi (16bit)"
+  version "WORKBIT", "UltraNinja-16", "1"
+  bind "nsp_cs"
+
+# OEM
+card "WorkBit NinjaSCSI-32Bi (16bit) / IO-DATA"
+  version "IO DATA", "CBSC16       ", "1"
+  bind "nsp_cs"
+
+# OEM
+card "WorkBit NinjaSCSI-32Bi (16bit) / KME-1"
+  version "KME    ", "SCSI-CARD-001", "1"
+  bind "nsp_cs"
+card "WorkBit NinjaSCSI-32Bi (16bit) / KME-2"
+  version "KME    ", "SCSI-CARD-002", "1"
+  bind "nsp_cs"
+card "WorkBit NinjaSCSI-32Bi (16bit) / KME-3"
+  version "KME    ", "SCSI-CARD-003", "1"
+  bind "nsp_cs"
+card "WorkBit NinjaSCSI-32Bi (16bit) / KME-4"
+  version "KME    ", "SCSI-CARD-004", "1"
+  bind "nsp_cs"
+-------------------------------------
+
+[7] Boot (or reboot) pcmcia-cs.
+# /etc/rc.d/rc.pcmcia start        (BSD style)
+or
+# /etc/init.d/pcmcia start         (SYSV style)
+
+
+4. History
+See README.nin_cs .
+
+5. Caution
+ If you eject card when doing some operation for your SCSI device or suspend
+your computer, you encount some *BAD* error like disk crash.
+ It works good when I using this driver right way. But I'm not guarantee
+your data. Please backup your data when you use this driver.
+
+6. Known Bugs
+ Some write error occurs when you use slow device.
+
+7. Testing
+ Please send me some reports(bug reports etc..) of this software.
+When you send report, please tell me these or more.
+	card name
+	kernel version
+	your SCSI device name(hard drive, CD-ROM, etc...)
+
+8. Copyright
+ See GPL.
+
+
+2001/02/01 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
diff -u --recursive --new-file v2.4.6/linux/Documentation/fb/00-INDEX linux/Documentation/fb/00-INDEX
--- v2.4.6/linux/Documentation/fb/00-INDEX	Tue Jul 18 22:54:33 2000
+++ linux/Documentation/fb/00-INDEX	Tue Jul 10 20:16:30 2001
@@ -17,6 +17,8 @@
 	- info on the Cirrus Logic frame buffer driver
 matroxfb.txt
 	- info on the Matrox frame buffer driver
+pvr2fb.txt
+	- info on the PowerVR 2 frame buffer driver
 tgafb.txt
 	- info on the TGA (DECChip 21030) frame buffer driver
 vesafb.txt
diff -u --recursive --new-file v2.4.6/linux/Documentation/fb/pvr2fb.txt linux/Documentation/fb/pvr2fb.txt
--- v2.4.6/linux/Documentation/fb/pvr2fb.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/fb/pvr2fb.txt	Tue Jul 10 20:16:30 2001
@@ -0,0 +1,61 @@
+$Id: pvr2fb.txt,v 1.1 2001/05/24 05:09:16 mrbrown Exp $
+
+What is pvr2fb?
+===============
+
+This is a driver for PowerVR 2 based graphics frame buffers, such as the
+one found in the Dreamcast.
+
+Advantages:
+
+ * It provides a nice large console (128 cols + 48 lines with 1024x768)
+   without using tiny, unreadable fonts.
+ * You can run XF86_FBDev on top of /dev/fb0
+ * Most important: boot logo :-)
+
+Disadvantages:
+
+ * Driver is currently limited to the Dreamcast PowerVR 2 implementation
+   at the time of this writing.
+
+Configuration
+=============
+
+You can pass kernel command line options to pvr2fb with
+`video=pvr2:option1,option2:value2,option3' (multiple options should be
+separated by comma, values are separated from options by `:').
+Accepted options:
+
+font:X    - default font to use. All fonts are supported, including the
+            SUN12x22 font which is very nice at high resolutions.
+
+mode:X    - default video mode. The following video modes are supported:
+            640x240-60, 640x480-60.
+	    
+            Note: the 640x240 mode is currently broken, and should not be
+            used for any reason. It is only mentioned as a reference.
+
+inverse   - invert colors on screen (for LCD displays)
+
+nomtrr    - disables write combining on frame buffer. This slows down driver
+            but there is reported minor incompatibility between GUS DMA and
+            XFree under high loads if write combining is enabled (sound
+            dropouts). MTRR is enabled by default on systems that have it
+            configured and that support it.
+
+cable:X   - cable type. This can be any of the following: vga, rgb, and
+            composite. If none is specified, we guess.
+
+output:X  - output type. This can be any of the following: pal, ntsc, and
+            vga. If none is specified, we guess.
+
+X11
+===
+
+XF86_FBDev should work, in theory. At the time of this writing it is
+totally untested and may or may not even portray the beginnings of
+working. If you end up testing this, please let me know!
+
+--
+Paul Mundt <lethal@linuxdc.org>
+
diff -u --recursive --new-file v2.4.6/linux/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog
--- v2.4.6/linux/Documentation/filesystems/devfs/ChangeLog	Tue Jul  3 17:08:18 2001
+++ linux/Documentation/filesystems/devfs/ChangeLog	Wed Jul 11 14:55:41 2001
@@ -1661,3 +1661,17 @@
 - Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc
 
 - Simplified locking in <devfsd_ioctl> and fixed memory leak
+===============================================================================
+Changes for patch v182
+
+- Created <devfs_*alloc_major> and <devfs_*alloc_devnum>
+
+- Removed broken devnum allocation and use <devfs_alloc_devnum>
+
+- Fixed old devnum leak by calling new <devfs_dealloc_devnum>
+
+- Created <devfs_*alloc_unique_number>
+
+- Fixed number leak for /dev/cdroms/cdrom%d
+
+- Fixed number leak for /dev/discs/disc%d
diff -u --recursive --new-file v2.4.6/linux/Documentation/filesystems/ext2.txt linux/Documentation/filesystems/ext2.txt
--- v2.4.6/linux/Documentation/filesystems/ext2.txt	Fri Apr 20 16:18:35 2001
+++ linux/Documentation/filesystems/ext2.txt	Wed Jul 11 15:44:45 2001
@@ -299,6 +299,8 @@
 so 8kB blocks are only allowed on Alpha systems (and other architectures
 which support larger pages).
 
+There is an upper limit of 32768 subdirectories in a single directory.
+
 There is a "soft" upper limit of about 10-15k files in a single directory
 with the current linear linked-list directory implementation.  This limit
 stems from performance problems when creating and deleting (and also
diff -u --recursive --new-file v2.4.6/linux/Documentation/filesystems/ntfs.txt linux/Documentation/filesystems/ntfs.txt
--- v2.4.6/linux/Documentation/filesystems/ntfs.txt	Fri Feb 16 15:53:08 2001
+++ linux/Documentation/filesystems/ntfs.txt	Mon Jul 16 15:14:10 2001
@@ -1,6 +1,9 @@
 NTFS Overview
 =============
 
+Driver development has as of recently (since June '01) been sponsored
+by Legato Systems, Inc. (http://www.legato.com)
+
 To mount an NTFS volume, use the filesystem type 'ntfs'. The driver
 currently works only in read-only mode, with no fault-tolerance supported.
 
@@ -9,9 +12,18 @@
 distribution from Sourceforge at http://sourceforge.net/projects/linux-ntfs/
 and always run the included ntfsfix utility after performing a write to an
 NTFS partition from Linux to fix some of the damage done by the Linux NTFS
-driver. You should run ntfsfix _after_ unmounting the partition in Linux but
-_before_ rebooting into Windows. During the next reboot into Windows, chkdsk
-will be run automatically to fix the remaining damage.
+driver and to schedule an automatic chkdsk when Windows reboots. You should
+run ntfsfix _after_ unmounting the partition in Linux but _before_ rebooting
+into Windows. During the next reboot into Windows, chkdsk will be run
+automatically fixing the remaining damage. If no errors are found it is a
+good indication that the driver + ntfsfix together worked to full
+satisfaction. (-;
+
+Please note that the experimental write support is limited to Windows NT4 and
+earlier versions at the moment.
+
+If you think you have discovered a bug please have look at the "Known bugs"
+section below to see whether it isn't known already.
 
 For ftdisk support, limited success was reported with volume sets on top of
 the md driver, although mirror and stripe sets should work as well - if the
@@ -19,25 +31,78 @@
 using the md driver will fail if any of your NTFS partitions have an odd
 number of sectors.
 
-Please note that the experimental write support is limited to
-Windows NT4 and earlier versions at the moment.
+Supported mount options
+=======================
+
+iocharset=name		Character set to use when returning file names.
+			Unlike VFAT, NTFS suppresses names that contain
+			unconvertible characters
+
+utf8=<bool>		Use UTF-8 for converting file names
+
+uni_xlate=<bool>,2	Use the VFAT-style encoding for file names outside
+			the current character set. A boolean value will
+			enable the feature, a value of 2 will enable the
+			encoding as documented in vfat.txt:
+				':', (u & 0x3f), ((u>>6) & 0x3f), (u>>12),
 
-The ntfs driver supports the following mount options:
-iocharset=name      Character set to use when returning file names.
-                    Unlike VFAT, NTFS suppresses names that contain
-		    unconvertible characters
-utf8=<bool>	    Use UTF-8 for converting file names
-uni_xlate=<bool>,2  Use the VFAT-style encoding for file names outside
-		    the current character set. A boolean value will
-		    enable the feature, a value of 2 will enable the
-		    encoding as documented in vfat.txt:
-		    ':', (u & 0x3f), ((u>>6) & 0x3f), (u>>12),
 uid=
 gid=
-umask=              These options work as documented in mount(8).
-		    By default, the files are owned by root and
-		    not readable by somebody else.
-posix=<bool>	    If enabled, the file system distinguishes between
-		    upper and lower case. The 8.3 alias names are presented
-		    as hard links instead of being suppressed.
+umask=			These options work as documented in mount(8).
+			By default, the files are owned by root and
+			not readable by anyone else.
+
+posix=<bool>		If enabled, the file system distinguishes between
+			upper and lower case. The 8.3 alias names are presented
+			as hard links instead of being suppressed.
+
+show_sys_files=<bool>	If enabled, show all system files as normal files. Note
+			that $MFT does not appear unless specifically
+			requested. For example in bash, use: "ls -l \$MFT".
+			Be careful not to write anything to them or you could
+			crash the kernel and/or corrupt your file system!
+
+Known bugs and (mis-)features
+=============================
+
+- Do not use the driver for writing as it corrupts the file system. If you do
+  use it, get the Linux-NTFS tools and use the ntfsfix utility after
+  dismounting a partition you wrote to.
+
+- Use the show_sys_files mount option which should make things work generally
+  better. (It results in both the short and long file names being shown as well
+  as the sytem files.)
+
+- Writing of extension records is not supported properly.
+
+Please send bug reports/comments/feed back/abuse to the Linux-NTFS development
+list at sourceforge: linux-ntfs-dev@lists.sourceforge.net
+
+ChangeLog
+=========
+
+NTFS 1.1.15 (changes since kernel 2.4.4's NTFS driver):
+
+	- New mount option show_sys_files=<bool> to show all system files as
+	  normal files.
+	- Support for files and in general any attributes up to the full 2TiB
+	  size supported by the NTFS filesystem. Note we only support up to
+	  32-bits worth of inodes/clusters at this point.
+	- Support for more than 128kiB sized runlists (using vmalloc_32()
+	  instead of kmalloc()).
+	- Fixed races in allocation of clusters and mft records.
+	- Fixed major bugs in attribute handling / searching / collation.
+	- Fixed major bugs in compressing a run list into a mapping pairs array.
+	- Fixed major bugs in inode allocation. Especially file create and
+	  mkdir.
+	- Fixed memory leaks.
+	- Fixed major bug in inode layout assignment of sequence numbers.
+	- Lots of other bug fixes I can't think of right now...
+	- Fixed NULL bug found by the Stanford checker in ntfs_dupuni2map().
+	- Convert large stack variable to dynamically allocated one in
+	  ntfs_get_free_cluster_count() (found by Stanford checker).
+
+Kernel 2.4.4:
+
+	- Started ChangeLog.
 
diff -u --recursive --new-file v2.4.6/linux/Documentation/ioctl-number.txt linux/Documentation/ioctl-number.txt
--- v2.4.6/linux/Documentation/ioctl-number.txt	Sat May 19 17:54:14 2001
+++ linux/Documentation/ioctl-number.txt	Wed Jul 11 16:35:37 2001
@@ -187,3 +187,5 @@
 0xB1	00-1F	PPPoX			<mailto:mostrows@styx.uwaterloo.ca>
 0xCB	00-1F	CBM serial IEC bus	in development:
 					<mailto:michael.klein@puffin.lb.shuttle.de>
+
+0xFE	00-9F	Logical Volume Manager	<mailto:linux-lvm@sistina.com>
diff -u --recursive --new-file v2.4.6/linux/Documentation/networking/8139too.txt linux/Documentation/networking/8139too.txt
--- v2.4.6/linux/Documentation/networking/8139too.txt	Mon May  7 14:13:19 2001
+++ linux/Documentation/networking/8139too.txt	Sun Jul  8 13:17:30 2001
@@ -185,6 +185,20 @@
 Change History
 --------------
 
+Version 0.9.18 - July 6, 2001
+
+* Fix race leading to crashes on some machines.
+* Minimize race leading to low performance.
+* Correct interrupt acknowledgement to cover all three
+  relevant Rx events.
+* Add ethtool driver info support.
+* Collect additional driver-internal statistics.
+* Add descriptions for module parameters.
+* Support new SIOCxMIIxxx ioctls added in kernel 2.4.6.
+* Multicast filter big endian fix.
+* Support new PCI PM API added in kernel 2.4.6.
+
+
 Version 0.9.17 - May 7, 2001
 
 * Fix chipset wakeup bug which prevent media connection for 8139B
diff -u --recursive --new-file v2.4.6/linux/Documentation/networking/dl2k.txt linux/Documentation/networking/dl2k.txt
--- v2.4.6/linux/Documentation/networking/dl2k.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/networking/dl2k.txt	Tue Jul 17 18:53:55 2001
@@ -0,0 +1,246 @@
+
+    D-Link DL2000-based Gigabit Ethernet Adapter Installation
+    for Linux
+    July 5, 2001
+
+Contents
+========
+ - Compatibility List
+ - Quick Install
+ - Compiling the Driver
+ - Installing the Driver
+ - Option parameter
+ - Configuration Script Sample
+ - Troubleshooting
+
+
+Compatiblity List
+=================
+Adapter Support:
+
+D-Link DGE-550T Gigabit Ethernet Adapter.
+D-Link DL2000-based Gigabit Ethernet Adapter.
+
+
+The driver support Linux kernal 2.4.x later. We had tested it
+on the environments below.
+
+ . Red Hat v6.2 (update to kernel 2.4.4)
+ . Red Hat v7.0 (update to kernel 2.4.4)
+ . Red Hat v7.1 (kernel 2.4.2-2)
+
+
+Quick Install
+=============
+Install linux driver as following command:
+
+1. make all
+2. insmod dl2x.o
+3. ifconfig eth0 up 10.xxx.xxx.xxx netmask 255.0.0.0
+		    ^^^^^^^^^^^^^^^\	    ^^^^^^^^\
+				    IP		     NETMASK
+Now eth0 bring up, you can test it by "ping" or get more information by
+"ifconfig". If test ok, then continue next step.
+
+4. cp dl2x.o /lib/modules/`uname -r`/kernel/drivers/net
+5. Add the following lines to /etc/modules.conf:
+	alias eth0 dl2x
+6. Run "netconfig" or "netconf" to create configuration script ifcfg-eth0
+   located at /etc/sysconfig/network-scripts or create it manually.
+   [see - Configuration Script Sample]
+7. Driver will automatically load and configure at next boot time.
+
+Compiling the Driver
+====================
+  In Linux, NIC drivers are most commonly configured as loadable modules.
+The approach of building a monolithic kernel has become obsolete. The driver
+can be compiled as part of a monolithic kernel, but is strongly discouraged.
+The remainder of this section assumes the driver is built as a loadable module.
+In the Linux environment, it is a good idea to rebuild the driver from the
+source instead of relying on a precompiled version. This approach provides
+better reliability since a precompiled driver might depend on libraries or
+kernel features that are not present in a given Linux installation.
+
+The 3 files necessary to build Linux device driver are dl2x.c, dl2x.h and
+Makefile. To compile, the Linux installation must include the gcc compiler,
+the kernel source, and the kernel headers. The Linux driver supports Linux
+Kernels 2.4.x. Copy the files to a directory and enter the following command
+to compile and link the driver:
+
+CD-ROM drive
+------------
+
+[root@XXX /] mkdir cdrom
+[root@XXX /] mount -r -t iso9660 -o conv=auto /dev/cdrom /cdrom
+[root@XXX /] cd root
+[root@XXX /root] mkdir dl2x
+[root@XXX /root] cd dl2x
+[root@XXX dl2x] cp /cdrom/linux/dl2x.tgz /root/dl2x
+[root@XXX dl2x] tar xfvz dl2x.tgz
+[root@XXX dl2x] make all
+
+Floppy disc drive
+-----------------
+
+[root@XXX /] cd root
+[root@XXX /root] mkdir dl2x
+[root@XXX /root] cd dl2x
+[root@XXX dl2x] mcopy a:/linux/dl2x.tgz /root/dl2x
+[root@XXX dl2x] tar xfvz dl2x.tgz
+[root@XXX dl2x] make all
+
+Installing the Driver
+=====================
+
+  Manual Installation
+  -------------------
+  Once the driver has been compiled, it must be loaded, enabled, and bound
+  to a protocol stack in order to establish network connectivity. To load a
+  module enter the command:
+
+  insmod dl2x.o
+
+
+  or
+
+  insmod dl2x.o <optional parameter>	; add parameter
+
+  ===============================================================
+   example: insmod dl2x.o media=100mbps_hd
+   or	    insmod dl2x.o media=3
+   or	    insmod dl2x.o media=3 2	; for 2 cards
+  ===============================================================
+
+  Please reference the list of the command line parameters supported by
+  the Linux device driver below.
+
+  The insmod command only loads the driver and gives it a name of the form
+  eth0, eth1, etc. To bring the NIC into an operational state,
+  it is necessary to issue the following command:
+
+  ifconfig eth0 up
+
+  Finally, to bind the driver to the active protocol (e.g., TCP/IP with
+  Linux), enter the following command:
+
+  ifup eth0
+
+  Note that this is meaningful only if the system can find a configuration
+  script that contains the necessary network information. A sample will be
+  given in the next paragraph.
+
+  The commands to unload a driver are as follows:
+
+  ifdown eth0
+  ifconfig eth0 down
+  rmmod dl2x.o
+
+  The following are the commands to list the currently loaded modules and
+  to see the current network configuration.
+
+  lsmod
+  ifconfig
+
+
+  Automated Installation
+  ----------------------
+  This section describes how to install the driver such that it is
+  automatically loaded and configured at boot time. The following description
+  is based on a Red Hat 6.0/7.0 distribution, but it can easily be ported to
+  other distributions as well.
+
+  Red Hat v6.x/v7.x
+  -----------------
+  1. Copy dl2x.o to the network modules directory, typically
+     /lib/modules/2.x.x-xx/net or /lib/modules/2.x.x/kernel/drivers/net.
+  2. Locate the boot module configuration file, most commonly modules.conf
+     or conf.modules in the /etc directory. Add the following lines:
+
+     alias ethx dl2x
+     options dl2x <optional parameters>
+
+     where ethx will be eth0 if the NIC is the only ethernet adapter, eth1 if
+     one other ethernet adapter is installed, etc. Refer to the table in the
+     previous section for the list of optional parameters.
+  3. Locate the network configuration scripts, normally the
+     /etc/sysconfig/network-scripts directory, and create a configuration
+     script named ifcfg-ethx that contains network information.
+  4. Note that for most Linux distributions, Red Hat included, a configuration
+     utility with a graphical user interface is provided to perform steps 2
+     and 3 above.
+
+
+Parameter Description
+=====================
+You can install this driver without any addtional parameter. However, if you
+are going to have extensive functions then it is necessary to set extra
+parameter. Below is a list of the command line parameters supported by the
+Linux device
+driver.
+
+mtu=packet_size			- Specifies the maximum packet size. default
+				  is 1500.
+
+media=xxxxxxxxx			- Specifies the media type the NIC operates at.
+				  autosense	Autosensing active media.
+				  10mbps_hd	10Mbps half duplex.
+				  10mbps_fd	10Mbps full duplex.
+				  100mbps_hd	100Mbps half duplex.
+				  100mbps_fd	100Mbps full duplex.
+				  1000mbps_fd	1000Mbps full duplex.
+				  1000mbps_hd	1000Mbps half duplex.
+				  0		Autosensing active media.
+				  1		10Mbps half duplex.
+				  2		10Mbps full duplex.
+				  3		100Mbps half duplex.
+				  4		100Mbps full duplex.
+				  5		1000Mbps full duplex.
+				  6		1000Mbps half duplex.
+				  By default, the NIC operates at autosense.
+
+vlan=x				- Specifies the VLAN ID. If vlan=0, the
+				  Virtual Local Area Network (VLAN) function is
+				  disable.
+
+jumbo=x				- Specifies the jumbo frame support. If jumbo=1,
+				  the NIC accept jumbo frames. By default, this
+				  function is disabled.
+
+Configuration Script Sample
+===========================
+Here is a sample of a simple configuration script:
+
+DEVICE=eth0
+USERCTL=no
+ONBOOT=yes
+POOTPROTO=none
+BROADCAST=207.200.5.255
+NETWORK=207.200.5.0
+NETMASK=255.255.255.0
+IPADDR=207.200.5.2
+
+
+Troubleshooting
+===============
+Q1. Source files contain behind every line.
+	Make sure all files are Unix file format (no LF). Try the following
+    shell command to convert files.
+
+	cat dl2k.c | col -b > dl2k.tmp
+	mv dl2k.tmp dl2k.c
+
+	OR
+
+	cat dl2k.c | tr -d "\r" > dl2k.tmp
+	mv dl2k.tmp dl2k.c
+
+Q2: Could not find header files (*.h) ?
+	To compile the driver, you need kernel header files. After
+    installing the kernel source, the header files are usually located in
+    /usr/src/linux/include, which is the default include directory configured
+    in Makefile. For some distributions, there is a copy of header files in
+    /usr/src/include/linux and /usr/src/include/asm, that you can change the
+    INCLUDEDIR in Makefile to /usr/include without installing kernel source.
+	Note that RH 7.0 didn't provide correct header files in /usr/include,
+    including those files will make a wrong version driver.
+
diff -u --recursive --new-file v2.4.6/linux/Documentation/networking/multicast.txt linux/Documentation/networking/multicast.txt
--- v2.4.6/linux/Documentation/networking/multicast.txt	Mon Aug  9 10:23:09 1999
+++ linux/Documentation/networking/multicast.txt	Wed Jul  4 11:50:38 2001
@@ -39,11 +39,13 @@
 hp		YES		YES		YES		Hardware
 hp100		YES		YES		YES		Hardware
 ibmtr		NO		NO		NO		N/A
+ioc3-eth	YES		YES		YES		Hardware
 lance		YES		YES		YES		Software(#)
 ne		YES		YES		YES		Hardware
 ni52		<------------------ Buggy ------------------>
 ni65		YES		YES		YES		Software(#)
 seeq		NO		NO		NO		N/A
+sgiseek		<------------------ Buggy ------------------>
 sk_g16		NO		NO		YES		N/A
 smc-ultra	YES		YES		YES		Hardware
 sunlance	YES		YES		YES		Hardware
diff -u --recursive --new-file v2.4.6/linux/Documentation/sonypi.txt linux/Documentation/sonypi.txt
--- v2.4.6/linux/Documentation/sonypi.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/sonypi.txt	Wed Jul  4 14:41:33 2001
@@ -0,0 +1,70 @@
+Sony Programmable I/O Control Device Driver Readme
+--------------------------------------------------
+	Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
+	Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
+	Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp>
+	Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp>
+	Copyright (C) 2000 Andrew Tridgell <tridge@samba.org>
+
+This driver enables access to the Sony Programmable I/O Control Device which
+can be found in many (all ?) Sony Vaio laptops.
+
+It will give access (through a user space utility) to some events those laptops
+generate, like:
+	- jogdial events (the small wheel on the side of Vaios)
+	- capture button events (only on Vaio Picturebook series)
+	- Fn keys
+	- bluetooth button (only on C1VR model)
+
+Those events (see linux/sonypi.h) can be polled using the character device node
+/dev/sonypi (major 10, minor auto allocated or specified as a option).
+
+A simple daemon which translates the jogdial movements into mouse wheel events
+can be downloaded at: <http://www.alcove-labs.org/en/software/sonypi/>
+
+This driver supports also some ioctl commands for setting the LCD screen
+brightness (some more commands may be added in the future).
+
+This driver can also be used to set the camera controls on Picturebook series
+(brightness, contrast etc), and is used by the video4linux driver for the 
+Motion Eye camera.
+
+Please note that this driver was created by reverse engineering the Windows
+driver and the ACPI BIOS, because Sony doesn't agree to release any programming
+specs for its laptops. If someone convinces them to do so, drop me a note.
+
+Module options:
+---------------
+
+	minor: 		minor number of the misc device /dev/sonypi, 
+			default is -1 (automatic allocation, see /proc/misc
+			or kernel logs)
+
+	camera:		if you have a PictureBook series Vaio (with the
+			integrated MotionEye camera), set this parameter to 1
+			in order to let the driver access to the camera
+
+	fnkeyinit:	on some Vaios (C1VE, C1VR etc), the Fn key events don't
+			get enabled unless you set this parameter to 1
+
+	verbose:	print unknown events from the sonypi device
+
+Module use:
+-----------
+
+In order to automatically load the sonypi module on use, you can put those
+lines in your /etc/modules.conf file:
+
+	alias char-major-10-250 sonypi
+	options sonypi minor=250 fnkeyinit=1
+
+This supposes the use of minor 250 for the sonypi device:
+
+	# mknod /dev/sonypi c 10 250
+
+Bugs:
+-----
+
+	- since all development was done by reverse engineering, there is
+	  _absolutely no guarantee_ that this driver will not crash your
+	  laptop. Permanently.
diff -u --recursive --new-file v2.4.6/linux/Documentation/sound/CMI8338 linux/Documentation/sound/CMI8338
--- v2.4.6/linux/Documentation/sound/CMI8338	Fri Jul 28 12:50:52 2000
+++ linux/Documentation/sound/CMI8338	Wed Jul  4 11:50:38 2001
@@ -8,59 +8,80 @@
 On-board C-Media chips
 
 
-WHAT'S NEW
+STEPS TO BUILD DRIVER
 ================================================================================
 
-  1. Support modem interface for 8738. (select in kernel configuration)
-  2. Enable S/PDIF-in to S/PDIF-out (S/PDIF loop).
-  3. Enable 4 channels analog duplicate mode on 3 jack or 4 jack
-     configuration.
+  1. Backup the Config.in and Makefile in the sound driver directory
+     (/usr/src/linux/driver/sound).
+     The Configure.help provide help when you config driver in step
+     4, please backup the original one (/usr/src/linux/Document) and
+     copy this file.
+     The cmpci is document for the driver in detail, please copy it
+     to /usr/src/linux/Document/sound so you can refer it. Backup if
+     there is already one.
 
+  2. Extract the tar file by 'tar xvzf cmpci-xx.tar.gz' in the above
+     directory.
 
-   Be aware: C-Media Electronics Inc. is basically an IC design house,
-   and whose development of software drivers is mainly for use by its OEM
-   customers in their products. C-Media Electronics Inc. itself does not
-   manufacture end-user products, such as PC or sound cards, so it can
-   not fully control the drivers provided to consumers. Drivers provided
-   at this site, therefore, MAY NOT BE APPLICABLE to all sound cards.
-   Drivers you download from this site may function well at certain
-   situation, but C-Media Electronics Inc. does not give any guarantee or
-   assurances. Please be aware that these drivers might cause some
-   technical difficulties when installed
+  3. Change directory to /usr/src/linux
 
+  4. Config cm8338 driver by 'make menuconfig', 'make config' or
+     'make xconfig' command.
 
-1. Config cm8338 driver by 'make menuconfig' or 'make config' command.
+  5. Please select Sound Card (CONFIG_SOUND=m) support and CMPCI
+     driver (CONFIG_SOUND_CMPCI=m) as modules. Resident mode not tested.
+     For driver option, please refer 'DRIVER PARAMETER'
 
-2. Please select Sound Card (CONFIG_SOUND=m) support and CMPCI driver (CONFIG_SOUND_CMPCI=m) as modules. Resident mode not tested.
+  6. Compile the kernel if necessary.
 
-3. Compile the kernel if necessary.
+  7. Compile the modules by 'make modules'.
 
-4. Compile the modules by 'make modules'.
+  8. Install the modules by 'make modules_install'
 
-5. Install the modules by 'make modules_install'
 
-6. Before first time to run the driver, create module dependency by 'depmod -a'
+INSTALL DRIVER
+================================================================================
+
+  1. Before first time to run the driver, create module dependency by
+     'depmod -a'
+
+  2. To install the driver manually, enter 'modprobe cmpci'.
+
+  3. Driver installation for various distributions:
 
-7. To install the driver, enter 'modprobe cmpci'.
+    a. Slackware 4.0
+       Add the 'modprobe cmpci' command in your /etc/rc.d/rc.modules
+       file.so you can start the driver automatically each time booting.
 
+    b. Caldera OpenLinux 2.2
+       Use LISA to load the cmpci module.
 
-DRIVER PARAMETERS
+    c. RedHat 6.0 and S.u.S.E. 6.1
+       Add following command in /etc/conf.modules:
+
+       alias sound cmpci
+
+	also visit http://www.cmedia.com.tw for installation instruction.
+
+DRIVER PARAMETER
 ================================================================================
 
   Some functions for the cm8738 can be configured in Kernel Configuration
   or modules parameters. Set these parameters to 1 to enable.
 
+  mpu_io:	I/O ports base for MPU-401, 0 if disabled.
+  fm_io:	I/O ports base for OPL-3, 0 if disabled.
+  spdif_inverse:Inverse the S/PDIF-in signal, this depends on your
+		CD-ROM or DVD-ROM.
   spdif_loop:   Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out
                 directly.
-  four_ch:      Enable 4 channels mode, rear-out or line-in will output
-                the same as line-out.
-  rear_out:     Enable this if you have independent rear-out jacket on
-                your sound card, otherwise line-in will be used as
+  speakers:     Number of speakers used.
+  use_line_as_rear:Enable this if you want to use line-in as
                 rear-out.
+  use_line_as_bass:Enable this if you want to use line-in as
+                bass-out.
   modem:	You will need to set this parameter if you want to use
 		the HSP modem. You need install the pctel.o, the modem
 		driver itself.
-
-  (You will need to get the pctel driver (binary only) and the support for
-  this option from the CMI site. It is not included in the Linux kernel 
-  proper as it is non-free).
+  joystick:	Enable joystick. You will need to install Linux joystick
+		driver.
diff -u --recursive --new-file v2.4.6/linux/Documentation/sound/OPL3-SA2 linux/Documentation/sound/OPL3-SA2
--- v2.4.6/linux/Documentation/sound/OPL3-SA2	Sun Feb  4 10:05:29 2001
+++ linux/Documentation/sound/OPL3-SA2	Wed Jul 18 07:14:01 2001
@@ -21,7 +21,7 @@
 different chipset, the OPL3-SAx.  After an email exhange with
 Yamaha, however, it turns out that the 719 is just a re-badged
 715, and the chipsets are identical.  The chipset detection code
-has been updated to refkect this.
+has been updated to reflect this.
 
 Anyways, all of these chipsets implement the following devices:
 
diff -u --recursive --new-file v2.4.6/linux/Documentation/usb/philips.txt linux/Documentation/usb/philips.txt
--- v2.4.6/linux/Documentation/usb/philips.txt	Tue May 22 10:25:36 2001
+++ linux/Documentation/usb/philips.txt	Wed Jul  4 11:50:38 2001
@@ -34,6 +34,10 @@
    specificly, red and blue are swapped), try palette=bgr24 or
    palette=rgb24.
 
+   Only the native yuv420/yuv420p format is supported by the in kernel driver. 
+   If you want to use other formats with in-kernel conversion download the
+   driver from the URL given. [Alan]
+
 fbufs
    This paramter specifies the number of internal buffers to use for storing 
    frames from the cam. This will help if the process that reads images from 
diff -u --recursive --new-file v2.4.6/linux/Documentation/video4linux/Zoran linux/Documentation/video4linux/Zoran
--- v2.4.6/linux/Documentation/video4linux/Zoran	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/video4linux/Zoran	Wed Jul  4 14:41:33 2001
@@ -0,0 +1,517 @@
+DC10/DC10plus/LML33/Buz  Driver for Linux
+=========================================
+
+by Rainer Johanni <Rainer@Johanni.de> (for Iomega Buz Driver)
+
+Adapted for DC10/DC10plus by Wolfgang Scherr <scherr@net4you.net>
+
+Further changes for DC10/DC10plus and LML33 cards by
+Serguei Miridonov <mirsev@cicese.mx>
+
+Current homepage: http://www.cicese.mx/~mirsev/Linux/DC10plus/
+Current maintainer: Serguei Miridonov <mirsev@cicese.mx>
+
+  This is a driver for DC10plus capture cards from Pinnacle Systems
+  Inc., LML33 cards from Linux Media Labs and Buz from Iomega.
+  It also works with many old Miro DC10 cards with SAA7110A TV decoder
+  and ADV7176 TV encoder (please, make sure that your card has these
+  chips, otherwise the driver will not work).
+
+  The driver is Video4Linux compliant and contains extensions to
+  provide hardware support for full motion MJPEG compression and
+  decompression. Since this driver is a derivative from the driver for
+  Buz Iomega cards written by Dr. Rainer Johanni,
+  http://www.johanni.de/munich-vision/buz/ they both have compatible
+  API. I hope that this API will become a part of V4L standard.
+
+Copyright: This driver is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License. Please,
+check http://www.gnu.org/ for details.
+
+No warranty: This software is provided on AN "AS-IS" basis WITHOUT
+WARRANTY OF ANY KIND. YOU USE IT AT YOUR OWN RISK.
+
+
+
+CONTENTS
+~~~~~~~~
+
+Supported Formats
+Hardware compression
+Compiling and Loading the Driver
+Driver Options
+Tested applications
+Programming interface
+Features for testing
+Mailing lists
+Bug Reports
+
+
+Supported Formats
+=================
+
+Card:              DC10/DC10plus             LML33/Buz
+
+TV standard:       NTSC/PAL/SECAM(*)         NTSC/PAL
+
+Format:            Square pixel              CCIR.601
+                   640x480 NTSC              720x480 NTSC
+                   768x576 PAL/SECAM(*)      720x576 PAL
+
+Frame rates: 30 frames/60 fields per second NTSC
+             25 frames/50 fields per second PAL/SECAM(*)
+
+(*) - SECAM is supported for input only in DC10/DC10plus cards. The
+output of the recorded SECAM video stream will be in PAL standard.
+Also, please, note that monitoring of the SECAM input signal at the
+DC10/DC10plus analog output may not be available. Please, use
+appropriate application like XawTV to watch full color SECAM video at
+the card input.
+
+Hardware compression
+====================
+
+Since the card provides hardware compression, even low end machines can
+be successfully used for movie capture and playback. I'm testing the
+driver with with 2.2.16 kernel running on 233 MHz Pentium MMX with 64M
+RAM on 430TX motherboard and with 10GB IDE drive from Western Digital
+Corp.
+
+On one test run with DC10plus card I've got 0 frames dropped during
+about 20 minutes of full motion NTSC (I live in Mexico) video capture
+with fully synchronized audio. The command was
+
+  lavrec -fa -in -d1 -l -1 -q30 -w /dos/g/capture/Linux/test%03d.avi
+
+for recording, and
+
+  lavplay -n128 /dos/g/capture/Linux/test*.avi
+
+for playback. (See lavtools distribution for more information).
+
+Typical run of similar test can provide as few as 6-8 dropped frames per
+half of an hour. You mileage may vary, though.
+
+Compiling and Loading the Driver
+================================
+
+You should run a 2.2.x kernel in order to use this driver. The driver
+was also tested with 2.4-test6 kernel, so hopefully it will work
+with 2.4 kernels too.
+
+I would recommend to use only official kernels from www.kernel.org and
+its mirrors. Kernels supplied with some Linux distributions may be
+patched in some way to meet specific needs of particular Linux
+distributor and could be incompatible with this driver. As a driver
+maintainer, I am not able to follow every unofficial kernel release,
+and no unofficial kernels will be supported.
+
+Besides the files in this directory, the driver needs the 'videodev'
+and the 'i2c' module from the Linux kernel (i2c-old for 2.4 kernels).
+In order to get these modules available, enable module support for
+VIDEODEV and BTTV (which implies i2c) in your 2.2.x kernel
+configuration. You will find these devices in the menu "Character
+Devices" in your Kernel Configuration.
+
+In newer kernels (2.4) instead of BTTV you should enable support for
+Iomega Buz cards and for Zoran 36060/36067 chipset. This will include
+i2c or i2c-old modules and Buz/LML33 driver. However, instead of
+modules for Buz/LML33 driver from the kernel, use modules from _this_
+driver.
+
+To compile the driver, just type make.
+
+Before you load the driver you must have a video device at major device
+node 81. If you don't have it yet, do the following (as root!):
+
+cd /dev
+mknod video0 c 81 0
+ln -s video0 video
+
+If you have more than one card, add more nodes in /dev directory:
+
+mknod video1 c 81 1
+mknod video2 c 81 2
+...
+
+The driver should operate properly with several cards. It was tested
+with one DC10plus and one LML33 cards installed together and the driver
+correctly identifies both cards and works with both of them.
+
+Currently the driver does not support LML33 and Buz cards installed
+together in the same system. This will be fixed in future versions.
+
+Edit the 'update' script if you want to give the driver special options
+(see below for options descriptions) and then type (as root)
+
+./update <card_list>
+
+to insert all necessary modules into the kernel. <card_list> is a list of
+cards installed in your system separated by white space. Supported cards 
+are dc10, dc10plus, lml33, and buz. For example, if you have both dc10plus
+and lml33 cards, please type
+
+./update dc10 lml33
+
+If you want to make full use of the Video for Linux _uncompressed_
+grabbing facilities, you must either
+
+- obtain and install the "big_physarea patch" for your kernel and
+  set aside the necessary memory during boot time. There seem to be
+  several versions of this patch against various kernel versions
+  floating around in the net, you may obtain one e.g. from:
+  http://www.polyware.nl/~middelin/patch/bigphysarea-2.2.1.tar.gz You
+  also have to compile your driver AFTER installing that patch in order
+  to get it working
+
+  or
+
+- start your kernel with the mem=xxx option, where xxx is your
+  real memory minus the memory needed for the buffers.
+  For doing this add an entry in lilo.conf (if you use lilo):
+    append "mem=xxxM"
+  or add a line in your linux.par file (if you use loadlin):
+    mem=xxxM
+
+The second method is by far easier, however it is dangerous if more
+than one driver at a time has the idea to use the memory leftover by
+setting the mem=xxx parameter below the actual memory size.
+
+Read also below how to use this memory!
+
+
+  If you use only MJPEG compressed capture provided by the driver, you
+  should not need large memory areas for DMA. In this case, you will be
+  able to capture and playback movies with lavtools, however you will
+  not be able to use capture features of XawTV and other similar
+  programs (you can still watch video on the screen).
+
+
+
+Driver Options
+==============
+
+You are able to customize the behavior of the driver by giving
+it some options at start time.
+
+default_input, default_norm
+---------------------------
+
+As soon as the driver is loaded, the Buz samples video signals
+from one of its input ports and displays it on its output.
+The driver uses the Composite Input and the video norm PAL for this.
+If you want to change this default behavior, set default_input=1
+(for S-VHS input) or default_norm=1 for NTSC or default_norm=2
+for SECAM (DC10/DC10plus only).
+
+lock_norm
+---------
+
+This option was introduced to disable norm (TV standard) change by some
+not well behaving programs. For example, if you have some application
+which was written by somebody who lives in a country with PAL standard,
+this program may not have NTSC option and may always try to set the
+driver to PAL. In this case, you may load the driver with
+default_norm=1 and lock_norm=1 and the card will be forced to work in
+NTSC standard only.
+
+  Options:
+  
+  lock_norm=0   default, TV standard change is enabled;
+  lock_norm=1   TV standard change is disabled but the driver
+                will not notify the application about any error;
+  lock_norm=2   TV standard change is disabled and the driver
+                will notify the program that TV standards other
+                than set by default_norm=X option are not 
+                supported.
+
+pass_through
+------------
+
+When the driver is not in use (device is not opened by any program) and
+pass_through=0 (default) the driver will set the TV encoder to produce
+color bar signal at the output. If the driver was loaded with
+pass_through=1, the color bar will be disabled and input signal will be
+sent to the output even if the driver not in use. If you have LML33 card
+and wish the color bar signal at the output, you will also need to set
+lml33dpath=1 (please, see next section).
+
+lml33dpath
+----------
+
+LML33 card normally (lml33dpath=0) connects its output to the input
+using analog switch. Additionally, it also allows real-time monitoring
+of digitized video using TV monitor connected to the output. This
+"digital path" option can be enabled setting lml33dpath=1. In this
+mode, the input is connected only to the TV decoder, digital video data
+is sent via internal video bus to the TV encoder and resulting analog
+signal is sent to the output. This mode could be very useful for testing and
+picture adjustment while watching video at the TV monitor connected to
+the output. However, because of lack of 75 ohm terminating resistors at
+TV decoder input, the signal will suffer serious distortions.
+
+# These distortions could be eliminated by soldering two 75 ohm resistors
+# in LML33 card: in parallel to capacitors C73 and C82 (see schematics of
+# H33 board available at www.linuxmedialabs.com and www.zoran.com). Be
+# aware, however, that doing so will void card warranty and the card,
+# after this change, must always be used with loading option lml33dpath=1.
+# 
+# WARNING: I DID NOT TRY THIS CARD CHANGE YET, THIS IS JUST AN ASSUMPTION
+# AND I WILL NOT BE RESPONSIBLE FOR ANY DAMAGE ASSOCIATED WITH THIS
+# CHANGE. IF YOU WISH TO TRY IT, DO IT AT YOUR OWN RISK.
+
+Please, note that DC10/DC10plus cards always use "digital path" for
+signal monitoring. Its input and output are both properly terminated
+and the digitized signal quality does not depend on the connection of
+the output load.
+
+
+v4l_nbufs, v4l_bufsize
+----------------------
+
+In order to make to make full use of the Video for Linux uncompressed
+picture grabbing facilities of the driver (which are needed by many
+Video for Linux applications), the driver needs a set of physically
+contiguous buffers for grabbing. These parameters determine how many
+buffers of which size the driver will allocate at open (the open will
+fail if it is unable to do so!).
+
+These values do not affect the MJPEG grabbing facilities of the driver,
+they are needed for uncompressed image grabbing only!!!
+
+v4l_nbufs is the number of buffers to allocate, a value of 2 (the default)
+should be sufficient in almost all cases. Only special applications
+(streaming captures) will need more buffers and then mostly the
+MJPEG capturing features of the Buz will be more appropriate.
+So leave this parameter at it's default unless you know what you do.
+
+The things for v4l_bufsize are more complicated: v4l_bufsize is set by
+default to 128 [KB] which is the maximum amount of physically
+contiguous memory Linux is able to allocate without kernel changes.
+This is sufficient for grabbing 24 bit color images up to sizes of
+approx. 240x180 pixels (240*180*3 = 129600, 128 KB = 131072).
+
+In order to be able to capture bigger images you have either to
+- obtain and install the "big_physarea patch" and set aside
+  the necessary memory during boot time or
+- start your kernel with the mem=xxx option, where xxx is your
+  real memory minus the memory needed for the buffers.
+In that case, useful settings for v4l_bufsize are
+- 1296 [Kb] for grabbing 24 bit images of max size 768*576
+- 1728 [Kb] for 32bit images of same size (4*768*576 = 1728 Kb!)
+You may reduce these numbers accordingly if you know you are only
+grabbing 720 pixels wide images or NTSC images (max height 480).
+
+In some cases it may happen that Linux isn't even able to obtain
+the default 128 KB buffers. If you don't need uncompressed image
+grabbing at all, set v4l_bufsize to an arbitrary small value (e.g. 4)
+in order to be able to open the video device.
+
+triton, natoma
+--------------
+
+The driver tries to detect if you have a triton or natoma chipset
+in order to take special measures for these chipsets.
+If this detection fails but you are sure you have such a chipset,
+set the corresponding variable to 1.
+This is a very special option and may go away in the future.
+
+
+Tested applications
+===================
+
+  XawTV         to watch video on your computer monitor.
+
+  kwintv        the same (you might need to use option lock_norm=1).
+  
+  lavtools      To record and playback AVI or Quicktime files. Note: you
+                will need patched version, lavtools-1.2p2 to support new
+                features of this driver. Please visit driver homepage for
+                more info.
+
+  Broadcast2000 reportedly (I didn't try that) can accept movies recorded
+                by lavrec in Quicktime format for editing and then edited
+                movie can be played back by lavplay program.
+
+  MainActor 3.5x also can accept movies recorded by lavrec for editing.
+
+
+The driver can to be used by two programs at the same time
+(please, see warning note below regarding this feature). Using XawTV
+you can watch what you are recording or playing back with lavtools.
+I've tested the following sequence and it worked for me:
+
+* start xawtv and switch inputs, TV standards, and adjust video
+  (contrast, saturation, etc.). You may also run your favorite
+  audio mixer application to adjust audio inputs.
+
+* run lavrec with options: 
+
+    -i<set your input and norm here> (to choose proper input
+                                      and TV standard)
+
+    -l -1  (to use audio mixer settings)
+
+    Other lavrec option can be added at your choice.
+
+* watch the movie in xawtv window while recording it as AVI or
+  Quicktime file.
+
+* when recording is finished, run lavplay or xlav and watch your
+  clip in xawtv window.
+
+* Note: you should not quit xawtv during recording or playing back.
+  If you quit xawtv during recording or playback, another lavtools
+  program will stop and may even crash.
+
+I'm not sure that the same will work for you. You can try but,
+please, be careful.
+
+WARNING! This is an experimental feature and I'm not sure if it will be
+supported in the future. The original driver was not designed to be
+used like this and it has no protection against any interference
+between two running programs. THEREFORE, IT IS POTENTIALLY DANGEROUS
+AND SINCE THE DRIVER OPERATES IN KERNEL SPACE, USING THIS FEATURE MAY
+CRASH YOUR ENTIRE SYSTEM.
+
+
+Programming interface
+=====================
+
+This driver should be fully compliant to Video for Linux, so all
+tools working with Video for Linux should work with (hopefully)
+no problems.
+
+A description of the Video for Linux programming interface can be found at:
+http://roadrunner.swansea.linux.org.uk/v4lapi.shtml
+
+Besides the Video for Linux interface, the driver has a "proprietary"
+interface for accessing the Buz's MJPEG capture and playback facilities.
+
+For a full description of all members and ioctls see "zoran.h" (used to
+be buz.h or dc10.h in previous versions, so, please, update your
+programs accordingly).
+
+The ioctls for that interface are as follows:
+
+BUZIOC_G_PARAMS
+BUZIOC_S_PARAMS
+
+Get and set the parameters of the buz. The user should always do a
+BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
+settings, change what he likes and then make a BUZIOC_S_PARAMS call.
+
+BUZIOC_REQBUFS
+
+Before being able to capture/playback, the user has to request
+the buffers he is wanting to use. Fill the structure
+zoran_requestbuffers with the size (recommended: 256*1024) and
+the number (recommended 32 up to 256). There are no such restrictions
+as for the Video for Linux buffers, you should LEAVE SUFFICIENT
+MEMORY for your system however, else strange things will happen ....
+On return, the zoran_requestbuffers structure contains number and
+size of the actually allocated buffers.
+You should use these numbers for doing a mmap of the buffers
+into the user space.
+The BUZIOC_REQBUFS ioctl also makes it happen, that the next mmap
+maps the MJPEG buffer instead of the V4L buffers.
+
+BUZIOC_QBUF_CAPT
+BUZIOC_QBUF_PLAY
+
+Queue a buffer for capture or playback. The first call also starts
+streaming capture. When streaming capture is going on, you may
+only queue further buffers or issue syncs until streaming
+capture is switched off again with a argument of -1 to
+a BUZIOC_QBUF_CAPT/BUZIOC_QBUF_PLAY ioctl.
+
+BUZIOC_SYNC
+
+Issue this ioctl when all buffers are queued. This ioctl will
+block until the first buffer becomes free for saving its
+data to disk (after BUZIOC_QBUF_CAPT) or for reuse (after BUZIOC_QBUF_PLAY).
+
+BUZIOC_G_STATUS
+
+Get the status of the input lines (video source connected/norm).
+This ioctl may be subject to change.
+
+For programming example, please, look at lavrec.c and lavplay.c code in
+lavtools-1.2p2 package (URL: http://www.cicese.mx/~mirsev/DC10plus/)
+and the 'examples' directory in the original Buz driver distribution.
+
+Additional notes for software developers:
+
+   The driver returns maxwidth and maxheight parameters according to
+   the current TV standard (norm). Therefore, the software which
+   communicates with the driver and "asks" for these parameters should
+   first set the correct norm. Well, it seems logically correct: TV
+   standard is "more constant" for current country than geometry
+   settings of a variety of TV capture cards which may work in ITU or
+   square pixel format. Remember that users now can lock the norm to
+   avoid any ambiguity.
+
+Features for testing
+====================
+
+When loaded, the driver creates a /proc/zoranX entry for each card:
+using 'cat /proc/zoran0' for your first card you can see the contents
+of ZR36057/67 chip registers. It is also possible to modify the
+contents of some registers directly. WARNING: modified contents is not
+stored in the driver memory, if you restart any program which uses this
+driver or even change position or cause redraw of a window of xawtv or
+other program, the original registers contents will be restored by the
+driver. However, it can be used to change ZR36067 registers on the fly
+for fine tuning and then to include these changes into driver code.
+This feature is very limited and still requires some documentation.
+However, if you are impatient, look at zoran_procfs.c code and
+(IMPORTANT!) read ZR36057/67 manual. To set TopField bit, for example,
+you need to type as root:
+
+echo TopField=1 > /proc/zoranX # change X to 0 for your first card,
+                               # 1 for second and so on...
+
+If you use this feature and have found some interesting result, please, let
+me know.
+
+Mailing lists
+=============
+
+There are two mailing lists available to discuss application issues and
+suggest driver improvements:
+
+1. A mailing list buz-linux was set up to discuss Iomega Buz driver.
+Since this driver is derivative of that driver, you can also post your
+questions and suggestions there. Subscribe with a message (with
+"subscribe" in the subject) to  buz-linux-subscribe@webmages.com.
+Unsubscribe with a message (with "unsubscribe" in the subject) to
+buz-linux-unsubscribe@webmages.com. The mailing list archive can be
+found at http://buz.webmages.com/list/. 
+
+2. Video4Linux mailing list is set for more general discussions related
+to uncompressed video capture, V4L and V4L2 API, many Video4Linux
+applications, etc. to subscribe to this mailing list, please, visit
+https://listman.redhat.com/mailman/listinfo/video4linux-list
+
+Bug Reports
+===========
+
+If you have found a bug, please, do the following:
+
+1. Edit first line of zoran.c file and set DEBUGLEVEL to 3;
+2. Recompile the driver and install it running update script
+   in the driver directory;
+3. Run the application(s) which you used when you had found a
+   suspisious behavior;
+4. When application stops, look at you /var/log/messages file
+   (or whatever file you use to log kernel messages) and copy
+   all lines related to the driver activity to a separate file
+   in the same order of their appearence in your log file.
+5. Mail a message to <mirsev@cicese.mx> with a subject
+   "Linux DC10(plus)/LML33/Buz driver bug report" with a detailed
+   description of your problem, kernel version, application name and
+   attach that file with kernel messages as plain text (please, don't
+   attach it using base64, uuencode, or any other encoding).
+   
+   If you have a Buz card, please, also mail the same message to
+   Wolfgang Scherr <scherr@net4you.net>
diff -u --recursive --new-file v2.4.6/linux/Documentation/video4linux/meye.txt linux/Documentation/video4linux/meye.txt
--- v2.4.6/linux/Documentation/video4linux/meye.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/video4linux/meye.txt	Wed Jul  4 14:41:33 2001
@@ -0,0 +1,102 @@
+Vaio Picturebook Motion Eye Camera Driver Readme
+------------------------------------------------
+	Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
+	Copyright (C) 2000 Andrew Tridgell <tridge@samba.org>
+
+This driver enable the use of video4linux compatible applications with the
+Motion Eye camera.
+
+It can do at maximum 30 fps @ 320x240 or 15 fps @ 640x480.
+
+Grabbing is supported in packed YUV colorspace only.
+
+MJPEG hardware grabbing is supported via a private API (see below).
+
+Module options:
+---------------
+
+	gbuffers:	number of capture buffers, default is 2 (32 max)
+
+	gbufsize:	size of each capture buffer, default is 614400
+
+	video_nr:	video device to register (0 = /dev/video0, etc)
+
+Module use:
+-----------
+
+In order to automatically load the meye module on use, you can put those lines
+in your /etc/modules.conf file:
+
+	alias char-major-81 videodev
+	alias char-major-81-0 meye
+	options meye gbuffers=32
+
+Usage:
+------
+
+	xawtv >= 3.49 (<http://bytesex.org/xawtv/>)
+		for display and uncompressed video capture:
+
+			xawtv -c /dev/video0 -geometry 640x480
+				or
+			xawtv -c /dev/video0 -geometry 320x240
+
+	motioneye (<http://www.alcove-labs.org/en/software/meye/>)
+		for getting ppm or jpg snapshots, mjpeg video
+
+Private API:
+------------
+
+	The driver supports frame grabbing with the video4linux API, so
+	all video4linux tools (like xawtv) should work with this driver.
+
+	Besides the video4linux interface, the driver has a private interface
+	for accessing the Motion Eye extended parameters (camera sharpness,
+	agc, video framerate), the shapshot and the MJPEG capture facilities.
+
+	This interface consists of several ioctls (prototypes and structures
+	can be found in include/linux/meye.h):
+
+	MEYEIOC_G_PARAMS
+	MEYEIOC_S_PARAMS
+		Get and set the extended parameters of the motion eye camera.
+		The user should always query the current parameters with
+		MEYEIOC_G_PARAMS, change what he likes and then issue the
+		MEYEIOC_S_PARAMS call (checking for -EINVAL). The extended
+		parameters are described by the meye_params structure.
+
+
+	MEYEIOC_QBUF_CAPT
+		Queue a buffer for capture (the buffers must have been
+		obtained with a VIDIOCGMBUF call and mmap'ed by the
+		application). The argument to MEYEIOC_QBUF_CAPT is the
+		buffer number to queue (or -1 to end capture). The first
+		call to MEYEIOC_QBUF_CAPT starts the streaming capture.
+
+	MEYEIOC_SYNC
+		Takes as an argument the buffer number you want to sync.
+		This ioctl blocks untils the buffer is filled and ready
+		for the application to use. It returns the buffer size.
+
+	MEYEIOC_STILLCAPT
+	MEYEIOC_STILLJCAPT
+		Takes a snapshot in an uncompressed or compressed jpeg format.
+		This ioctl blocks until the snapshot is done and returns (for
+		jpeg snapshot) the size of the image. The image data is 
+		available from the first mmap'ed buffer.
+
+	Look at the 'motioneye' application code for an actual example.
+
+Bugs / Todo:
+------------
+
+	- overlay output is not supported (although the camera is capable of).
+	  	(it should not be too hard to to it, provided we found how...)
+		
+	- mjpeg hardware playback doesn't work (depends on overlay...)
+
+	- rewrite the driver to use some commun video4linux API for snapshot
+	  and mjpeg capture. Unfortunately, video4linux1 does not permit it,
+	  the BUZ API seems to be targeted to TV cards only. The video4linux 2
+	  API may be an option, if it goes into the kernel (maybe 2.5 
+	  material ?).
diff -u --recursive --new-file v2.4.6/linux/Documentation/video4linux/w9966.txt linux/Documentation/video4linux/w9966.txt
--- v2.4.6/linux/Documentation/video4linux/w9966.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/video4linux/w9966.txt	Wed Jul  4 14:41:33 2001
@@ -0,0 +1,37 @@
+
+W9966 Camera driver, written by Jakob Kemi (jakob.kemi@post.utfors.se)
+
+Ok, after a lot of work in softice, wdasm, reading pdf-files
+and trial-and-error work I've finally got everything to work.
+Since I needed some vision for a robotics project I borrowed
+this camera from a friend and started hacking. Anyway I've
+converted my original code from the AVR 8bit RISC C/asm
+into a working linux driver. I would really appreciate _any_
+kind of feedback regarding this driver.
+
+To get it working quickly configure your kernel
+to support parport, ieee1284, video4linux, experimental drivers
+and w9966
+
+If w9966 is statically linked it will perform aggressive probing
+for the camera. If built as a module you'll have more configuration options.
+
+Options:
+modprobe w9966.o pardev=parport0(or whatever) parmode=0 (0=auto, 1=ecp, 2=epp)
+ 
+voila!
+
+you can also type 'modinfo -p w9966.o' for option usage
+(or checkout w9966.c)
+
+I've only tested it with custom built testprograms
+(http://hem.fyristorg.com/mogul/w9966.html) and with gqcam.
+(you'll need to tweak the code to qcam a bit to make it work,
+dimensions and such)
+
+The slow framerate is due to missing DMA ECP read support in the 
+parport drivers. I might add working EPP support later.
+
+Good luck!
+
+    /Jakob
diff -u --recursive --new-file v2.4.6/linux/MAINTAINERS linux/MAINTAINERS
--- v2.4.6/linux/MAINTAINERS	Tue Jul  3 17:08:18 2001
+++ linux/MAINTAINERS	Sun Jul 15 16:15:44 2001
@@ -106,6 +106,12 @@
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
+ACENIC DRIVER
+P:	Jes Sorensen
+M:	jes@trained-monkey.org
+L:	linux-acenic@sunsite.dk
+S:	Maintained
+
 ACI MIXER DRIVER
 P:	Robert Siemer
 M:	Robert.Siemer@gmx.de
@@ -566,8 +572,8 @@
 
 HIPPI
 P:	Jes Sorensen
-M:	jes@linuxcare.com
-L:	linux-hippi@sunsite.auc.dk
+M:	jes@trained-monkey.org
+L:	linux-hippi@sunsite.dk
 S:	Maintained
 
 HP100:	Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
@@ -812,7 +818,7 @@
 
 M68K
 P:	Jes Sorensen
-M:	jes@linuxcare.com
+M:	jes@trained-monkey.org
 W:	http://www.clark.net/pub/lawrencc/linux/index.html
 L:	linux-m68k@lists.linux-m68k.org
 S:	Maintained
@@ -835,6 +841,12 @@
 M:	zab@zabbo.net
 S:	Odd Fixes
 
+MATROX FRAMEBUFFER DRIVER
+P:	Petr Vandrovec
+M:	vandrove@vc.cvut.cz
+L:	linux-fbdev-devel@lists.sourceforge.net
+S:	Maintained
+
 MEMORY TECHNOLOGY DEVICES
 P:	David Woodhouse
 M:	dwmw2@redhat.com
@@ -1298,10 +1310,11 @@
 S:	Maintained
 
 TOKEN-RING NETWORK DRIVER
-P:	Paul Norton
-M:	pnorton@ieee.org
+P:	Mike Phillips
+M:	mikep@linuxtr.net
 L:	linux-net@vger.kernel.org
 L:	linux-tr@linuxtr.net
+W:	http://www.linuxtr.net
 S:	Maintained
 
 TRIDENT 4DWAVE/SIS 7018 PCI AUDIO CORE
diff -u --recursive --new-file v2.4.6/linux/Makefile linux/Makefile
--- v2.4.6/linux/Makefile	Tue Jul  3 17:08:18 2001
+++ linux/Makefile	Wed Jul 18 07:56:37 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 6
-EXTRAVERSION =
+SUBLEVEL = 7
+EXTRAVERSION =-pre8
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -88,7 +88,7 @@
 CPPFLAGS := -D__KERNEL__ -I$(HPATH)
 
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
-          -fomit-frame-pointer -fno-strict-aliasing
+	  -fomit-frame-pointer -fno-strict-aliasing -fno-common
 AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
 
 #
@@ -147,6 +147,7 @@
 DRIVERS-$(CONFIG_ATM) += drivers/atm/atm.o
 DRIVERS-$(CONFIG_IDE) += drivers/ide/idedriver.o
 DRIVERS-$(CONFIG_SCSI) += drivers/scsi/scsidrv.o
+DRIVERS-$(CONFIG_FUSION_BOOT) += drivers/message/fusion/fusion.o
 DRIVERS-$(CONFIG_IEEE1394) += drivers/ieee1394/ieee1394drv.o
 
 ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),)
@@ -333,14 +334,14 @@
 TAGS: dummy
 	etags `find include/asm-$(ARCH) -name '*.h'`
 	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print | xargs etags -a
-	find $(SUBDIRS) init -name '*.c' | xargs etags -a
+	find $(SUBDIRS) init -name '*.[ch]' | xargs etags -a
 
 # Exuberant ctags works better with -I
 tags: dummy
 	CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
 	ctags $$CTAGSF `find include/asm-$(ARCH) -name '*.h'` && \
 	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print | xargs ctags $$CTAGSF -a && \
-	find $(SUBDIRS) init -name '*.c' | xargs ctags $$CTAGSF -a
+	find $(SUBDIRS) init -name '*.[ch]' | xargs ctags $$CTAGSF -a
 
 ifdef CONFIG_MODULES
 ifdef CONFIG_MODVERSIONS
diff -u --recursive --new-file v2.4.6/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.4.6/linux/arch/alpha/config.in	Tue Jul  3 17:08:18 2001
+++ linux/arch/alpha/config.in	Tue Jul 10 20:08:51 2001
@@ -5,8 +5,8 @@
 
 define_bool CONFIG_ALPHA y
 define_bool CONFIG_UID16 n
-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
 
 mainmenu_name "Kernel configuration of Linux for Alpha machines"
 
diff -u --recursive --new-file v2.4.6/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.4.6/linux/arch/alpha/kernel/alpha_ksyms.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Tue Jul 10 20:08:51 2001
@@ -178,10 +178,6 @@
 EXPORT_SYMBOL(down_interruptible);
 EXPORT_SYMBOL(down_trylock);
 EXPORT_SYMBOL(up);
-EXPORT_SYMBOL(down_read);
-EXPORT_SYMBOL(down_write);
-EXPORT_SYMBOL(up_read);
-EXPORT_SYMBOL(up_write);
 
 /* 
  * SMP-specific symbols.
diff -u --recursive --new-file v2.4.6/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- v2.4.6/linux/arch/alpha/kernel/entry.S	Tue Jul  3 17:08:18 2001
+++ linux/arch/alpha/kernel/entry.S	Mon Jul  9 14:47:39 2001
@@ -576,17 +576,6 @@
 .align 3
 ret_from_sys_call:
 	cmovne	$26,0,$19		/* $19 = 0 => non-restartable */
-#ifdef CONFIG_SMP
-	ldl	$3,TASK_PROCESSOR($8)
-	sll	$3,L1_CACHE_SHIFT,$3
-#endif
-	lda	$4,irq_stat
-#ifdef CONFIG_SMP
-	addq	$3,$4,$4
-#endif
-	ldq	$4,0($4)		/* __softirq_pending */
-	bne	$4,handle_softirq
-ret_from_softirq:
 	ldq	$0,SP_OFF($30)
 	and	$0,8,$0
 	beq	$0,restore_all
@@ -664,17 +653,6 @@
 	mov	$31,$26		/* tell "ret_from_sys_call" we can restart */
 	br	ret_from_sys_call
 
-	.align 3
-handle_softirq:
-	subq	$30,16,$30
-	stq	$19,0($30)	/* save syscall nr */
-	stq	$20,8($30)	/* and error indication (a3) */
-	jsr	$26,do_softirq
-	ldq	$19,0($30)
-	ldq	$20,8($30)
-	addq	$30,16,$30
-	br	ret_from_softirq
-	
 	.align 3
 syscall_error:
 	/*
diff -u --recursive --new-file v2.4.6/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- v2.4.6/linux/arch/alpha/kernel/time.c	Sun Nov 12 19:27:11 2000
+++ linux/arch/alpha/kernel/time.c	Wed Jul  4 11:50:46 2001
@@ -169,6 +169,77 @@
 	init_rtc_irq();
 }
 
+/*
+ * Calibrate CPU clock using legacy 8254 timer/counter. Stolen from
+ * arch/i386/time.c.
+ */
+
+#define CALIBRATE_LATCH	(52 * LATCH)
+#define CALIBRATE_TIME	(52 * 1000020 / HZ)
+
+static unsigned long __init
+calibrate_cc_with_pic(void)
+{
+	int cc;
+	unsigned long count = 0;
+
+	/* Set the Gate high, disable speaker */
+	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+
+	/*
+	 * Now let's take care of CTC channel 2
+	 *
+	 * Set the Gate high, program CTC channel 2 for mode 0,
+	 * (interrupt on terminal count mode), binary count,
+	 * load 5 * LATCH count, (LSB and MSB) to begin countdown.
+	 */
+	outb(0xb0, 0x43);		/* binary, mode 0, LSB/MSB, Ch 2 */
+	outb(CALIBRATE_LATCH & 0xff, 0x42);	/* LSB of count */
+	outb(CALIBRATE_LATCH >> 8, 0x42);	/* MSB of count */
+
+	cc = rpcc();
+	do {
+		count++;
+	} while ((inb(0x61) & 0x20) == 0);
+	cc = rpcc() - cc;
+
+	/* Error: ECTCNEVERSET */
+	if (count <= 1)
+		goto bad_ctc;
+
+	/* Error: ECPUTOOFAST */
+	if (count >> 32)
+		goto bad_ctc;
+
+	/* Error: ECPUTOOSLOW */
+	if (cc <= CALIBRATE_TIME)
+		goto bad_ctc;
+
+	return ((long)cc * 1000000) / CALIBRATE_TIME;
+
+	/*
+	 * The CTC wasn't reliable: we got a hit on the very first read,
+	 * or the CPU was so fast/slow that the quotient wouldn't fit in
+	 * 32 bits..
+	 */
+ bad_ctc:
+	return 0;
+}
+
+/* The Linux interpretation of the CMOS clock register contents:
+   When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+   RTC registers show the second which has precisely just started.
+   Let's hope other operating systems interpret the RTC the same way.  */
+
+static unsigned long __init
+rpcc_after_update_in_progress(void)
+{
+	do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
+	do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
+
+	return rpcc();
+}
+
 void __init
 time_init(void)
 {
@@ -176,24 +247,15 @@
 	unsigned long cycle_freq, one_percent;
 	long diff;
 
-	/*
-	 * The Linux interpretation of the CMOS clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-	do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
-	do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
+	/* Calibrate CPU clock -- attempt #1.  */
+	if (!est_cycle_freq)
+		est_cycle_freq = calibrate_cc_with_pic();
 
-	/* Read cycle counter exactly on falling edge of update flag */
-	cc1 = rpcc();
+	cc1 = rpcc_after_update_in_progress();
 
+	/* Calibrate CPU clock -- attempt #2.  */
 	if (!est_cycle_freq) {
-		/* Sometimes the hwrpb->cycle_freq value is bogus. 
-		   Go another round to check up on it and see.  */
-		do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
-		do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
-		cc2 = rpcc();
+		cc2 = rpcc_after_update_in_progress();
 		est_cycle_freq = cc2 - cc1;
 		cc1 = cc2;
 	}
diff -u --recursive --new-file v2.4.6/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v2.4.6/linux/arch/alpha/kernel/traps.c	Thu May 24 15:24:37 2001
+++ linux/arch/alpha/kernel/traps.c	Wed Jul  4 11:50:38 2001
@@ -61,202 +61,6 @@
 			   "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
 			   "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"};
 
-static char * inst_name[] = {"call_pal", "", "", "", "", "", "", "",
-	"lda", "ldah", "ldbu", "ldq_u", "ldwu", "stw", "stb", "stq_u",
-	"ALU", "ALU", "ALU", "ALU", "SQRT", "FVAX", "FIEEE", "FLOAT",
-	"MISC", "PAL19", "JMP", "PAL1B", "GRAPH", "PAL1D", "PAL1E", "PAL1F",
-	"ldf", "ldg", "lds", "ldt", "stf", "stg", "sts", "stt",
-	"ldl", "ldq", "ldl_l", "ldq_l", "stl", "stq", "stl_c", "stq_c",
-	"br", "fbeq", "fblt", "fble", "bsr", "fbne", "fbge", "fbgt"
-	"blbc", "beq", "blt", "ble", "blbs", "bne", "bge", "bgt"
-};
-
-static char * jump_name[] = {"jmp", "jsr", "ret", "jsr_coroutine"};
-
-typedef struct {int func; char * text;} alist;
-
-static alist inta_name[] = {{0, "addl"}, {2, "s4addl"}, {9, "subl"},
-	{0xb, "s4subl"}, {0xf, "cmpbge"}, {0x12, "s8addl"}, {0x1b, "s8subl"},
-	{0x1d, "cmpult"}, {0x20, "addq"}, {0x22, "s4addq"}, {0x29, "subq"},
-	{0x2b, "s4subq"}, {0x2d, "cmpeq"}, {0x32, "s8addq"}, {0x3b, "s8subq"},
-	{0x3d, "cmpule"}, {0x40, "addl/v"}, {0x49, "subl/v"}, {0x4d, "cmplt"},
-	{0x60, "addq/v"}, {0x69, "subq/v"}, {0x6d, "cmple"}, {-1, 0}};
-
-static alist intl_name[] = {{0, "and"}, {8, "andnot"}, {0x14, "cmovlbs"},
-	{0x16, "cmovlbc"}, {0x20, "or"}, {0x24, "cmoveq"}, {0x26, "cmovne"},
-	{0x28, "ornot"}, {0x40, "xor"}, {0x44, "cmovlt"}, {0x46, "cmovge"},
-	{0x48, "eqv"}, {0x61, "amask"}, {0x64, "cmovle"}, {0x66, "cmovgt"},
-	{0x6c, "implver"}, {-1, 0}};
-
-static alist ints_name[] = {{2, "mskbl"}, {6, "extbl"}, {0xb, "insbl"},
-	{0x12, "mskwl"}, {0x16, "extwl"}, {0x1b, "inswl"}, {0x22, "mskll"},
-	{0x26, "extll"}, {0x2b, "insll"}, {0x30, "zap"}, {0x31, "zapnot"},
-	{0x32, "mskql"}, {0x34, "srl"}, {0x36, "extql"}, {0x39, "sll"},
-	{0x3b, "insql"}, {0x3c, "sra"}, {0x52, "mskwh"}, {0x57, "inswh"},
-	{0x5a, "extwh"}, {0x62, "msklh"}, {0x67, "inslh"}, {0x6a, "extlh"},
-	{0x72, "mskqh"}, {0x77, "insqh"}, {0x7a, "extqh"}, {-1, 0}};
-
-static alist intm_name[] = {{0, "mull"}, {0x20, "mulq"}, {0x30, "umulh"},
-	{0x40, "mull/v"}, {0x60, "mulq/v"}, {-1, 0}};
-
-static alist * int_name[] = {inta_name, intl_name, ints_name, intm_name};
-
-static char *
-assoc(int fcode, alist * a)
-{
-	while ((fcode != a->func) && (a->func != -1))
-		++a;
-	return a->text;
-}
-
-static char *
-iname(unsigned int instr)
-{
-	int opcode = instr >> 26;
-	char * name = inst_name[opcode];
-
-	switch (opcode) {
-		default:
-			break;
-
-		case 0x10:
-		case 0x11:
-		case 0x12:
-		case 0x13: {
-			char * specific_name
-			  = assoc((instr >> 5) & 0x3f, int_name[opcode - 0x10]);
-			if (specific_name)
-				name = specific_name;
-			break;
-		}
-
-		case 0x1a:
-			name = jump_name[(instr >> 14) & 3];
-			break;
-	}
-	
-	return name;
-}
-
-static enum {NOT_INST, PAL, BRANCH, MEMORY, JUMP, OPERATE, FOPERATE, MISC}
-iformat(int opcode)
-{
-	if (opcode >= 0x30)
-		return BRANCH;
-	if (opcode >= 0x20)
-		return MEMORY;
-	if (opcode == 0)
-		return PAL;
-	if (opcode < 8)
-		return NOT_INST;
-	if (opcode < 0x10)
-		return MEMORY;
-	if (opcode < 0x14)
-		return OPERATE;
-	if (opcode < 0x18)
-		return FOPERATE;
-	switch (opcode) {
-		case 0x18:
-			return MISC;
-		case 0x1A:
-			return JUMP;
-		case 0x1C:
-			return OPERATE;
-		default:
-			return NOT_INST;
-	}
-}
-
-/*
- * The purpose here is to provide useful clues about a kernel crash, so
- * less likely instructions, e.g. floating point, aren't fully decoded.
- */
-static void
-disassemble(unsigned int instr)
-{
-	int optype = instr >> 26;
-	char buf[40], *s = buf;
-
-	s += sprintf(buf, "%08x  %s ", instr, iname(instr));
-	switch (iformat(optype)) {
-		default:
-		case NOT_INST:
-		case MISC:
-			break;
-
-		case PAL:
-			s += sprintf(s, "%d", instr);
-			break;
-
-		case BRANCH: {
-			int reg = (instr >> 21) & 0x1f;
-			int offset = instr & 0x1fffff;
-
-			if (offset >= 0x100000)
-				offset -= 0x200000;
-			if (((optype & 3) == 0) || (optype >= 0x38)) {
-				if ((optype != 0x30) || (reg != 0x1f))
-					s += sprintf(s, "%s,", ireg_name[reg]);
-			} else
-				s += sprintf(s, "f%d,", reg);
-			s += sprintf(s, ".%+d", (offset + 1) << 2);
-			break;
-		}
-
-		case MEMORY: {
-			int addr_reg = (instr >> 16) & 0x1f;
-			int value_reg = (instr >> 21) & 0x1f;
-			int offset = instr & 0xffff;
-
-			if (offset >= 0x8000)
-				offset -= 0x10000;
-			if ((optype >= 0x20) && (optype < 0x28))
-				s += sprintf(s, "f%d", value_reg);
-			else
-				s += sprintf(s, "%s", ireg_name[value_reg]);
-
-			s += sprintf(s, ",%d(%s)", offset, ireg_name[addr_reg]);
-			break;
-		}
-
-		case JUMP: {
-			int target_reg = (instr >> 16) & 0x1f;
-			int return_reg = (instr >> 21) & 0x1f;
-
-			s += sprintf(s, "%s,", ireg_name[return_reg]);
-			s += sprintf(s, "(%s)", ireg_name[target_reg]);
-			break;
-		}
-
-		case OPERATE: {
-			int areg = (instr >> 21) & 0x1f;
-			int breg = (instr >> 16) & 0x1f;
-			int creg = instr & 0x1f;
-			int litflag = instr & (1<<12);
-			int lit = (instr >> 13) & 0xff;
-
-			s += sprintf(s, "%s,", ireg_name[areg]);
-			if (litflag)
-				s += sprintf(s, "%d", lit);
-			else
-				s += sprintf(s, "%s", ireg_name[breg]);
-			s += sprintf(s, ",%s", ireg_name[creg]);
-			break;
-		}
-
-		case FOPERATE: {
-			int areg = (instr >> 21) & 0x1f;
-			int breg = (instr >> 16) & 0x1f;
-			int creg = instr & 0x1f;
-
-			s += sprintf(s, "f%d,f%d,f%d", areg, breg, creg);
-			break;
-		}
-	}
-	buf[s-buf] = 0;
-	printk("%s\n", buf);
-}
-
 static void
 dik_show_code(unsigned int *pc)
 {
@@ -267,8 +71,7 @@
 		unsigned int insn;
 		if (__get_user(insn, pc+i))
 			break;
-		printk("%c", i ? ' ' : '*');
-		disassemble(insn);
+		printk("%c%08x%c", i ? ' ' : '<', insn, i ? ' ' : '>');
 	}
 	printk("\n");
 }
@@ -286,17 +89,11 @@
 			continue;
 		if (tmp >= (unsigned long) &_etext)
 			continue;
-		/*
-		 * Assume that only the low 24-bits of a kernel text address
-		 * is interesting.
-		 */
-		printk("%6x%c", (int)tmp & 0xffffff, (++i % 11) ? ' ' : '\n');
-#if 0
+		printk("%lx%c", tmp, ' ');
 		if (i > 40) {
 			printk(" ...");
 			break;
 		}
-#endif
 	}
 	printk("\n");
 }
@@ -337,8 +134,8 @@
 #endif
 	printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
 	dik_show_regs(regs, r9_15);
-	dik_show_code((unsigned int *)regs->pc);
 	dik_show_trace((unsigned long *)(regs+1));
+	dik_show_code((unsigned int *)regs->pc);
 
 	if (current->thread.flags & (1UL << 63)) {
 		printk("die_if_kernel recursion detected.\n");
diff -u --recursive --new-file v2.4.6/linux/arch/arm/kernel/bios32.c linux/arch/arm/kernel/bios32.c
--- v2.4.6/linux/arch/arm/kernel/bios32.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/kernel/bios32.c	Wed Jul  4 15:43:05 2001
@@ -8,6 +8,7 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include <asm/page.h> /* for BUG() */
@@ -18,6 +19,20 @@
 static int debug_pci;
 int have_isa_bridge;
 
+struct pci_sys_data {
+	/*
+	 * The hardware we are attached to
+	 */
+	struct hw_pci	*hw;
+
+	unsigned long	mem_offset;
+
+	/*
+	 * These are the resources for the root bus.
+	 */
+	struct resource *resource[3];
+};
+
 void pcibios_report_status(u_int status_mask, int warn)
 {
 	struct pci_dev *dev;
@@ -118,19 +133,22 @@
 }
 
 /*
- * Prevent the PCI layer from seeing the resources
- * allocated to this device.  These resources are
- * of no consequence to the PCI layer (they are
- * handled elsewhere).
+ * Prevent the PCI layer from seeing the resources allocated to this device
+ * if it is the host bridge by marking it as such.  These resources are of
+ * no consequence to the PCI layer (they are handled elsewhere).
  */
-static void __init pci_fixup_disable(struct pci_dev *dev)
+static void __init pci_fixup_dec21285(struct pci_dev *dev)
 {
 	int i;
 
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		dev->resource[i].start = 0;
-		dev->resource[i].end   = 0;
-		dev->resource[i].flags = 0;
+	if (dev->devfn == 0) {
+		dev->class &= 0xff;
+		dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags = 0;
+		}
 	}
 }
 
@@ -167,7 +185,7 @@
 	{
 		PCI_FIXUP_HEADER,
 		PCI_VENDOR_ID_DEC,	PCI_DEVICE_ID_DEC_21285,
-		pci_fixup_disable
+		pci_fixup_dec21285
 	}, {
 		PCI_FIXUP_HEADER,
 		PCI_VENDOR_ID_WINBOND,	PCI_DEVICE_ID_WINBOND_83C553,
@@ -187,27 +205,11 @@
 	}, { 0 }
 };
 
-/*
- * Allocate resources for all PCI devices that have been enabled.
- * We need to do that before we try to fix up anything.
- */
-static void __init pcibios_claim_resources(void)
-{
-	struct pci_dev *dev;
-	int idx;
-
-	pci_for_each_dev(dev) {
-		for (idx = 0; idx < PCI_NUM_RESOURCES; idx++)
-			if (dev->resource[idx].flags &&
-			    dev->resource[idx].start)
-				pci_claim_resource(dev, idx);
-	}
-}
-
 void __init
 pcibios_update_resource(struct pci_dev *dev, struct resource *root,
 			struct resource *res, int resource)
 {
+	struct pci_sys_data *sys = dev->sysdata;
 	u32 val, check;
 	int reg;
 
@@ -216,12 +218,9 @@
 			res->flags & IORESOURCE_IO ? "IO" : "MEM",
 			res->start, dev->name);
 
-	val = res->start | (res->flags & PCI_REGION_FLAG_MASK);
 	if (resource < 6) {
 		reg = PCI_BASE_ADDRESS_0 + 4*resource;
 	} else if (resource == PCI_ROM_RESOURCE) {
-		res->flags |= PCI_ROM_ADDRESS_ENABLE;
-		val |= PCI_ROM_ADDRESS_ENABLE;
 		reg = dev->rom_base_reg;
 	} else {
 		/* Somebody might have asked allocation of a
@@ -229,6 +228,12 @@
 		 */
 		return;
 	}
+
+	val = res->start;
+	if (res->flags & IORESOURCE_MEM)
+		val -= sys->mem_offset;
+	val |= res->flags & PCI_REGION_FLAG_MASK;
+
 	pci_write_config_dword(dev, reg, val);
 	pci_read_config_dword(dev, reg, &check);
 	if ((val ^ check) & ((val & PCI_BASE_ADDRESS_SPACE_IO) ?
@@ -246,77 +251,93 @@
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 }
 
-/**
- * pcibios_fixup_bus - Called after each bus is probed, but before its children
- * are examined.
+/*
+ * If the bus contains any of these devices, then we must not turn on
+ * parity checking of any kind.  Currently this is CyberPro 20x0 only.
  */
-void __init pcibios_fixup_bus(struct pci_bus *bus)
+static inline int pdev_bad_for_parity(struct pci_dev *dev)
+{
+	return (dev->vendor == PCI_VENDOR_ID_INTERG &&
+		(dev->device == PCI_DEVICE_ID_INTERG_2000 ||
+		 dev->device == PCI_DEVICE_ID_INTERG_2010));
+}
+
+/*
+ * Adjust the device resources from bus-centric to Linux-centric.
+ */
+static void __init
+pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		if (dev->resource[i].start == 0)
+			continue;
+		if (dev->resource[i].flags & IORESOURCE_MEM) {
+			dev->resource[i].start += root->mem_offset;
+			dev->resource[i].end   += root->mem_offset;
+		}
+	}
+}
+
+static void __init
+pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
 {
-	struct list_head *walk = &bus->devices;
-	struct arm_pci_sysdata *sysdata =
-			(struct arm_pci_sysdata *)bus->sysdata;
-	struct arm_bus_sysdata *busdata;
-
-	if (bus->number >= MAX_NR_BUS)
-		BUG();
-
-	if (bus->self) {
-		struct pci_dev *dev = bus->self;
-		int i;
+	struct pci_dev *dev = bus->self;
+	int i;
 
+	if (dev) {
 		for (i = 0; i < 3; i++) {
-			bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES + i];
-			bus->resource[i]->name = bus->name;
+			bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+			bus->resource[i]->name  = bus->name;
 		}
-		bus->resource[0]->start = ioport_resource.start;
-		bus->resource[0]->end   = ioport_resource.end;
 		bus->resource[0]->flags |= pci_bridge_check_io(dev);
-		bus->resource[1]->start = iomem_resource.start;
-		bus->resource[1]->end   = iomem_resource.end;
 		bus->resource[1]->flags |= IORESOURCE_MEM;
 
-		/* Turn off downsteam prefetchable memory address range */
-		bus->resource[2]->start = 1024*1024;
-		bus->resource[2]->end   = bus->resource[2]->start - 1;
+		if (root->resource[2])
+			bus->resource[2]->flags = root->resource[2]->flags;
+		else {
+			/* no prefetchable memory region - disable it */
+			bus->resource[2]->start = 1024*1024;
+			bus->resource[2]->end   = bus->resource[2]->start - 1;
+		}
+	} else {
+		/*
+		 * Assign root bus resources.
+		 */
+		for (i = 0; i < 3; i++)
+			bus->resource[i] = root->resource[i];
 	}
+}
 
-	busdata = sysdata->bus + bus->number;
-	busdata->max_lat = 255;
+/*
+ * pcibios_fixup_bus - Called after each bus is probed,
+ * but before its children are examined.
+ */
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_sys_data *root = bus->sysdata;
+	struct list_head *walk;
+	u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
+	u16 all_status = -1;
+
+	pbus_assign_bus_resources(bus, root);
 
 	/*
 	 * Walk the devices on this bus, working out what we can
 	 * and can't support.
 	 */
-	for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
+	for (walk = bus->devices.next; walk != &bus->devices; walk = walk->next) {
 		struct pci_dev *dev = pci_dev_b(walk);
 		u16 status;
-		u8 max_lat, min_gnt;
-
-		pci_read_config_word(dev, PCI_STATUS, &status);
 
-		/*
-		 * If this device does not support fast back to back
-		 * transfers, the bus as a whole cannot support them.
-		 */
-		if (!(status & PCI_STATUS_FAST_BACK))
-			busdata->features &= ~PCI_COMMAND_FAST_BACK;
+		pdev_fixup_device_resources(root, dev);
 
-		/*
-		 * If we encounter a CyberPro 2000, then we disable
-		 * SERR and PERR reporting - this chip doesn't drive the
-		 * parity line correctly.
-		 */
-		if (dev->vendor == PCI_VENDOR_ID_INTERG &&
-		    (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
-		     dev->device == PCI_DEVICE_ID_INTERG_2010))
-			busdata->features &= ~(PCI_COMMAND_SERR |
-					       PCI_COMMAND_PARITY);
+		pci_read_config_word(dev, PCI_STATUS, &status);
+		all_status &= status;
 
-		/*
-		 * Calculate the maximum devsel latency.
-		 */
-		if (busdata->maxdevsel < (status & PCI_STATUS_DEVSEL_MASK))
-			busdata->maxdevsel = (status & PCI_STATUS_DEVSEL_MASK);
+		if (pdev_bad_for_parity(dev))
+			features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
 
 		/*
 		 * If this device is an ISA bridge, set the have_isa_bridge
@@ -326,63 +347,48 @@
 		if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA ||
 		    dev->class >> 8 == PCI_CLASS_BRIDGE_EISA)
 			have_isa_bridge = !0;
-
-		/*
-		 * Calculate the maximum latency on this bus.  Note
-		 * that we ignore any device which reports its max
-		 * latency is the same as its use.
-		 */
-		pci_read_config_byte(dev, PCI_MAX_LAT, &max_lat);
-		pci_read_config_byte(dev, PCI_MIN_GNT, &min_gnt);
-		if (max_lat && max_lat != min_gnt && max_lat < busdata->max_lat)
-			busdata->max_lat = max_lat;
 	}
 
 	/*
+	 * If any device on this bus does not support fast back to back
+	 * transfers, then the bus as a whole is not able to support them.
+	 * Having fast back to back transfers on saves us one PCI cycle
+	 * per transaction.
+	 */
+	if (all_status & PCI_STATUS_FAST_BACK)
+		features |= PCI_COMMAND_FAST_BACK;
+
+	/*
 	 * Now walk the devices again, this time setting them up.
 	 */
-	walk = &bus->devices;
-	for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
+	for (walk = bus->devices.next; walk != &bus->devices; walk = walk->next) {
 		struct pci_dev *dev = pci_dev_b(walk);
 		u16 cmd;
-		u8 min_gnt, latency;
-
-		/*
-		 * Calculate this masters latency timer value.
-		 * This is rather primitive - it does not take
-		 * account of the number of masters in a system
-		 * wanting to use the bus.
-		 */
-		pci_read_config_byte(dev, PCI_MIN_GNT, &min_gnt);
-		if (min_gnt) {
-			if (min_gnt > busdata->max_lat)
-				min_gnt = busdata->max_lat;
-
-			latency = (int)min_gnt * 25 / 3;
-		} else
-			latency = 32; /* 1us */
-
-		pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
 
-		/*
-		 * Set the cache line size to 32 bytes.
-		 * Also, set system error enable, parity error enable.
-		 * Disable ROM.
-		 */
-		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
 		pci_read_config_word(dev, PCI_COMMAND, &cmd);
-
-		cmd |= busdata->features;
-
+		cmd |= features;
 		pci_write_config_word(dev, PCI_COMMAND, cmd);
-		pci_read_config_word(dev, PCI_COMMAND, &cmd);
-		pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
 	}
+
+	/*
+	 * Report what we did for this bus
+	 */
+	printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
+		bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
 }
 
+/*
+ * Convert from Linux-centric to bus-centric addresses for bridge devices.
+ */
 void __init
 pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
 {
+	struct pci_sys_data *root = bus->sysdata;
+
+	ranges->mem_start -= root->mem_offset;
+	ranges->mem_end -= root->mem_offset;
+	ranges->prefetch_start -= root->mem_offset;
+	ranges->prefetch_end -= root->mem_offset;
 }
 
 u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
@@ -400,81 +406,90 @@
 
 void __init pcibios_init(void)
 {
-	struct hw_pci *hw_pci = NULL;
-	struct arm_pci_sysdata sysdata;
-	int i;
+	struct pci_sys_data *root;
+	struct hw_pci *hw = NULL;
 
 	do {
 #ifdef CONFIG_ARCH_EBSA285
 		if (machine_is_ebsa285()) {
-			hw_pci = &ebsa285_pci;
+			hw = &ebsa285_pci;
 			break;
 		}
 #endif
 #ifdef CONFIG_ARCH_SHARK
 		if (machine_is_shark()) {
-			hw_pci = &shark_pci;
+			hw = &shark_pci;
 			break;
 		}
 #endif
 #ifdef CONFIG_ARCH_CATS
 		if (machine_is_cats()) {
-			hw_pci = &cats_pci;
+			hw = &cats_pci;
 			break;
 		}
 #endif
 #ifdef CONFIG_ARCH_NETWINDER
 		if (machine_is_netwinder()) {
-			hw_pci = &netwinder_pci;
+			hw = &netwinder_pci;
 			break;
 		}
 #endif
 #ifdef CONFIG_ARCH_PERSONAL_SERVER
 		if (machine_is_personal_server()) {
-			hw_pci = &personal_server_pci;
+			hw = &personal_server_pci;
 			break;
 		}
 #endif
 #ifdef CONFIG_ARCH_FTVPCI
 		if (machine_is_ftvpci()) {
-			hw_pci = &ftv_pci;
+			hw = &ftv_pci;
 			break;
 		}
 #endif
 #ifdef CONFIG_ARCH_INTEGRATOR
 		if (machine_is_integrator()) {
-			hw_pci = &integrator_pci;
+			hw = &integrator_pci;
 			break;
 		}
 #endif
 	} while (0);
 
-	if (hw_pci == NULL)
+	if (hw == NULL)
 		return;
 
-	for (i = 0; i < MAX_NR_BUS; i++) {
-		sysdata.bus[i].features  = PCI_COMMAND_FAST_BACK |
-					   PCI_COMMAND_SERR |
-					   PCI_COMMAND_PARITY;
-		sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST;
+	root = kmalloc(sizeof(*root), GFP_KERNEL);
+	if (!root)
+		panic("PCI: unable to allocate root data!");
+
+	root->hw = hw;
+	root->mem_offset = hw->mem_offset;
+
+	memset(root->resource, 0, sizeof(root->resource));
+
+	/*
+	 * Setup the resources for this bus.
+	 *   resource[0] - IO ports
+	 *   resource[1] - non-prefetchable memory
+	 *   resource[2] - prefetchable memory
+	 */
+	if (root->hw->setup_resources)
+		root->hw->setup_resources(root->resource);
+	else {
+		root->resource[0] = &ioport_resource;
+		root->resource[1] = &iomem_resource;
+		root->resource[2] = NULL;
 	}
 
 	/*
 	 * Set up the host bridge, and scan the bus.
 	 */
-	hw_pci->init(&sysdata);
-
-	/*
-	 * Claim the currently allocated resources.  This ensures
-	 * that we will not allocate an already inuse region.
-	 */
-	pcibios_claim_resources();
+	root->hw->init(root);
 
 	/*
 	 * Assign any unassigned resources.
 	 */
 	pci_assign_unassigned_resources();
-	pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq);
+	pci_fixup_irqs(root->hw->swizzle, root->hw->map_irq);
 }
 
 char * __init pcibios_setup(char *str)
@@ -499,7 +514,7 @@
  * is reserved for motherboard devices that decode all 16
  * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
  * but we want to try to avoid allocating at 0x2900-0x2bff
- * which might have be mirrored at 0x0100-0x03ff..
+ * which might be mirrored at 0x0100-0x03ff..
  */
 void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
 {
diff -u --recursive --new-file v2.4.6/linux/arch/arm/kernel/dec21285.c linux/arch/arm/kernel/dec21285.c
--- v2.4.6/linux/arch/arm/kernel/dec21285.c	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/kernel/dec21285.c	Wed Jul  4 15:43:05 2001
@@ -13,6 +13,7 @@
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 
@@ -24,6 +25,11 @@
 
 #define MAX_SLOTS		21
 
+#define PCICMD_ERROR_BITS ((PCI_STATUS_DETECTED_PARITY | \
+			PCI_STATUS_REC_MASTER_ABORT | \
+			PCI_STATUS_REC_TARGET_ABORT | \
+			PCI_STATUS_PARITY) << 16)
+
 extern int setup_arm_irq(int, struct irqaction *);
 extern void pcibios_report_status(u_int status_mask, int warn);
 extern void register_isa_ports(unsigned int, unsigned int, unsigned int);
@@ -255,12 +261,33 @@
 	add_timer(timer);
 }
 
-void __init dc21285_init(struct arm_pci_sysdata *sysdata)
+void __init dc21285_setup_resources(struct resource **resource)
+{
+	struct resource *busmem, *busmempf;
+
+	busmem = kmalloc(sizeof(*busmem), GFP_KERNEL);
+	busmempf = kmalloc(sizeof(*busmempf), GFP_KERNEL);
+	memset(busmem, 0, sizeof(*busmem));
+	memset(busmempf, 0, sizeof(*busmempf));
+
+	busmem->flags = IORESOURCE_MEM;
+	busmem->name  = "Footbridge non-prefetch";
+	busmempf->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+	busmempf->name  = "Footbridge prefetch";
+
+	allocate_resource(&iomem_resource, busmempf, 0x20000000,
+			  0x80000000, 0xffffffff, 0x20000000, NULL, NULL);
+	allocate_resource(&iomem_resource, busmem, 0x40000000,
+			  0x80000000, 0xffffffff, 0x40000000, NULL, NULL);
+
+	resource[0] = &ioport_resource;
+	resource[1] = busmem;
+	resource[2] = busmempf;
+}
+
+void __init dc21285_init(void *sysdata)
 {
-	unsigned long cntl;
 	unsigned int mem_size, mem_mask;
-	unsigned int pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-				PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
 	int cfn_mode;
 
 	mem_size = (unsigned int)high_memory - PAGE_OFFSET;
@@ -286,26 +313,17 @@
 		"central function" : "addin");
 
 	if (cfn_mode) {
-		static struct resource csrmem, csrio, busmem, busmempf;
-		struct pci_bus *bus;
+		static struct resource csrmem, csrio;
 
-		csrio.flags = IORESOURCE_IO;
-		csrio.name  = "Footbridge";
+		csrio.flags  = IORESOURCE_IO;
+		csrio.name   = "Footbridge";
 		csrmem.flags = IORESOURCE_MEM;
 		csrmem.name  = "Footbridge";
-		busmem.flags = IORESOURCE_MEM;
-		busmem.name  = "Footbridge non-prefetch";
-		busmempf.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
-		busmempf.name  = "Footbridge prefetch";
 
 		allocate_resource(&ioport_resource, &csrio, 128,
 				  0xff00, 0xffff, 128, NULL, NULL);
 		allocate_resource(&iomem_resource, &csrmem, 128,
 				  0xf4000000, 0xf8000000, 128, NULL, NULL);
-		allocate_resource(&iomem_resource, &busmempf, 0x20000000,
-				  0x00000000, 0x80000000, 0x20000000, NULL, NULL);
-		allocate_resource(&iomem_resource, &busmem, 0x40000000,
-				  0x00000000, 0x80000000, 0x40000000, NULL, NULL);
 
 		/*
 		 * Map our SDRAM at a known address in PCI space, just in case
@@ -313,37 +331,23 @@
 		 * necessary, since some VGA cards forcefully use PCI addresses
 		 * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
 		 */
-		*CSR_PCICACHELINESIZE = 0x00002008;
 		*CSR_PCICSRBASE       = csrmem.start;
 		*CSR_PCICSRIOBASE     = csrio.start;
 		*CSR_PCISDRAMBASE     = __virt_to_bus(PAGE_OFFSET);
 		*CSR_PCIROMBASE       = 0;
-		*CSR_PCICMD           = pci_cmd |
-				(1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
-
-		bus = pci_scan_bus(0, &dc21285_ops, sysdata);
-		/*
-		 * bus->resource[0] is the IO resource for this bus
-		 * bus->resource[1] is the mem resource for this bus
-		 * bus->resource[2] is the prefetch mem resource for this bus
-		 */
-		bus->resource[1] = &busmem;
-		bus->resource[2] = &busmempf;
-
-		pci_cmd |= sysdata->bus[0].features;
+		*CSR_PCICMD = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+			      PCI_COMMAND_INVALIDATE | PCICMD_ERROR_BITS;
 
-		printk("PCI: Fast back to back transfers %sabled\n",
-		       (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ?
-			"en" : "dis");
+		pci_scan_bus(0, &dc21285_ops, sysdata);
 
 		/*
 		 * Clear any existing errors - we aren't
 		 * interested in historical data...
 		 */
-		cntl		= *CSR_SA110_CNTL & 0xffffde07;
-		*CSR_SA110_CNTL	= cntl | SA110_CNTL_RXSERR;
-		*CSR_PCICMD	= pci_cmd | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24;
-	} else {
+		*CSR_SA110_CNTL	= (*CSR_SA110_CNTL & 0xffffde07) |
+				  SA110_CNTL_RXSERR;
+		*CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS;
+	} else if (footbridge_cfn_mode() != 0) {
 		/*
 		 * If we are not compiled to accept "add-in" mode, then
 		 * we are using a constant virt_to_bus translation which
diff -u --recursive --new-file v2.4.6/linux/arch/arm/kernel/dma-arc.c linux/arch/arm/kernel/dma-arc.c
--- v2.4.6/linux/arch/arm/kernel/dma-arc.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/arm/kernel/dma-arc.c	Wed Jul  4 14:56:44 2001
@@ -155,7 +155,7 @@
 	}
 	memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length);
 	regs.ARM_r9 = dma->buf.length;
-	regs.ARM_r10 = dma->buf.address;
+	regs.ARM_r10 = (unsigned long)dma->buf.address;
 	regs.ARM_fp = FLOPPYDMA_BASE;
 	set_fiq_regs(&regs);
 	enable_fiq(dma->dma_irq);
diff -u --recursive --new-file v2.4.6/linux/arch/arm/kernel/head-armv.S linux/arch/arm/kernel/head-armv.S
--- v2.4.6/linux/arch/arm/kernel/head-armv.S	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/kernel/head-armv.S	Wed Jul  4 14:56:44 2001
@@ -79,7 +79,7 @@
  *     ideal, but in this case, it should ONLY set r0 and r1 to the
  *     appropriate value.
  */
-#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_INTEGRATOR)
+#if defined(CONFIG_ARCH_NETWINDER)
 /*
  * Compatability cruft for old NetWinder NeTTroms.  This
  * code is currently scheduled for destruction in 2.5.xx
@@ -124,8 +124,6 @@
  * FIXME - No bootloader, so manually set 'r1' with our architecture number.
  */
 		mov	r1, #MACH_TYPE_L7200
-#elif defined(CONFIG_ARCH_INTEGRATOR)
-		mov	r1, #MACH_TYPE_INTEGRATOR
 #endif
 
 		mov	r0, #F_BIT | I_BIT | MODE_SVC	@ make sure svc mode
@@ -236,14 +234,16 @@
 		 * nearest megabyte boundary.
 		 */
 		add	r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel
+		bic	r2, r3, #0x00f00000
+		str	r2, [r0]			@ PAGE_OFFSET + 0MB
 		add	r0, r0, #(TEXTADDR & 0x00f00000) >> 18
-		str	r3, [r0], #4			@ PAGE_OFFSET + 0MB
+		str	r3, [r0], #4			@ KERNEL + 0MB
 		add	r3, r3, #1 << 20
-		str	r3, [r0], #4			@ PAGE_OFFSET + 1MB
+		str	r3, [r0], #4			@ KERNEL + 1MB
 		add	r3, r3, #1 << 20
-		str	r3, [r0], #4			@ PAGE_OFFSET + 2MB
+		str	r3, [r0], #4			@ KERNEL + 2MB
 		add	r3, r3, #1 << 20
-		str	r3, [r0], #4			@ PAGE_OFFSET + 3MB
+		str	r3, [r0], #4			@ KERNEL + 3MB
 
 		/*
 		 * Ensure that the first section of RAM is present.
diff -u --recursive --new-file v2.4.6/linux/arch/arm/kernel/irq.c linux/arch/arm/kernel/irq.c
--- v2.4.6/linux/arch/arm/kernel/irq.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/kernel/irq.c	Wed Jul  4 14:56:44 2001
@@ -216,7 +216,7 @@
 
 	irq_exit(cpu, irq);
 
-	if (softirq_active(cpu) & softirq_mask(cpu))
+	if (softirq_pending(cpu))
 		do_softirq();
 	return;
 
diff -u --recursive --new-file v2.4.6/linux/arch/arm/kernel/oldlatches.c linux/arch/arm/kernel/oldlatches.c
--- v2.4.6/linux/arch/arm/kernel/oldlatches.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/kernel/oldlatches.c	Wed Jul  4 14:56:44 2001
@@ -50,13 +50,14 @@
 		BUG();
 }
 
-static void __init oldlatch_init(void)
+static int __init oldlatch_init(void)
 {
 	if (machine_is_archimedes()) {
 		oldlatch_aupdate(0xff, 0xff);
 		/* Thats no FDC reset...*/
 		oldlatch_bupdate(0xff, LATCHB_FDCRESET);
 	}
+	return 0;
 }
 
 __initcall(oldlatch_init);
diff -u --recursive --new-file v2.4.6/linux/arch/arm/kernel/plx90x0.c linux/arch/arm/kernel/plx90x0.c
--- v2.4.6/linux/arch/arm/kernel/plx90x0.c	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/kernel/plx90x0.c	Wed Jul  4 15:43:05 2001
@@ -129,8 +129,6 @@
 	static const unsigned long int base = PLX_BASE;
 	char *what;
 	unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET);
-	unsigned int pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-				PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
 
 	/* Have a sniff around and see which PLX device is present. */
 	unsigned long id = __raw_readl(base + 0xf0);
@@ -189,10 +187,4 @@
 		    "system error", NULL);
 
 	pci_scan_bus(0, &plx90x0_ops, sysdata);
-
-	pci_cmd |= sysdata->bus[0].features;
-
-	printk("PCI: Fast back to back transfers %sabled\n",
-	       (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ?
-	       "en" : "dis");
 }
diff -u --recursive --new-file v2.4.6/linux/arch/arm/kernel/sys_arm.c linux/arch/arm/kernel/sys_arm.c
--- v2.4.6/linux/arch/arm/kernel/sys_arm.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/arm/kernel/sys_arm.c	Wed Jul  4 14:56:44 2001
@@ -28,9 +28,9 @@
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
 
-/*
- * Constant strings used in inlined functions in header files
- */
+extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
+			       unsigned long new_len, unsigned long flags,
+			       unsigned long new_addr);
 
 /*
  * sys_pipe() is the normal C calling standard for creating
diff -u --recursive --new-file v2.4.6/linux/arch/arm/mach-footbridge/cats-pci.c linux/arch/arm/mach-footbridge/cats-pci.c
--- v2.4.6/linux/arch/arm/mach-footbridge/cats-pci.c	Sun Sep  3 11:19:11 2000
+++ linux/arch/arm/mach-footbridge/cats-pci.c	Wed Jul  4 15:43:05 2001
@@ -11,6 +11,7 @@
 
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
+#include <asm/hardware/dec21285.h>
 
 /* cats host-specific stuff */
 static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
@@ -31,7 +32,9 @@
 }
 
 struct hw_pci cats_pci __initdata = {
-	init:		dc21285_init,
-	swizzle:	no_swizzle,
-	map_irq:	cats_map_irq,
+	setup_resources:	dc21285_setup_resources,
+	init:			dc21285_init,
+	mem_offset:		DC21285_PCI_MEM,
+	swizzle:		no_swizzle,
+	map_irq:		cats_map_irq,
 };
diff -u --recursive --new-file v2.4.6/linux/arch/arm/mach-footbridge/ebsa285-pci.c linux/arch/arm/mach-footbridge/ebsa285-pci.c
--- v2.4.6/linux/arch/arm/mach-footbridge/ebsa285-pci.c	Sun Sep  3 11:19:11 2000
+++ linux/arch/arm/mach-footbridge/ebsa285-pci.c	Wed Jul  4 15:43:05 2001
@@ -11,6 +11,7 @@
 
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
+#include <asm/hardware/dec21285.h>
 
 static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
 
@@ -33,7 +34,9 @@
 }
 
 struct hw_pci ebsa285_pci __initdata = {
-	init:		dc21285_init,
-	swizzle:	ebsa285_swizzle,
-	map_irq:	ebsa285_map_irq,
+	setup_resources:	dc21285_setup_resources,
+	init:			dc21285_init,
+	mem_offset:		DC21285_PCI_MEM,
+	swizzle:		ebsa285_swizzle,
+	map_irq:		ebsa285_map_irq,
 };
diff -u --recursive --new-file v2.4.6/linux/arch/arm/mach-footbridge/netwinder-pci.c linux/arch/arm/mach-footbridge/netwinder-pci.c
--- v2.4.6/linux/arch/arm/mach-footbridge/netwinder-pci.c	Sun Sep  3 11:19:11 2000
+++ linux/arch/arm/mach-footbridge/netwinder-pci.c	Wed Jul  4 15:43:05 2001
@@ -11,6 +11,7 @@
 
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
+#include <asm/hardware/dec21285.h>
 
 /* netwinder host-specific stuff */
 static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
@@ -48,7 +49,9 @@
 }
 
 struct hw_pci netwinder_pci __initdata = {
-	init:		dc21285_init,
-	swizzle:	no_swizzle,
-	map_irq:	netwinder_map_irq,
+	setup_resources:	dc21285_setup_resources,
+	init:			dc21285_init,
+	mem_offset:		DC21285_PCI_MEM,
+	swizzle:		no_swizzle,
+	map_irq:		netwinder_map_irq,
 };
diff -u --recursive --new-file v2.4.6/linux/arch/arm/mach-footbridge/personal-pci.c linux/arch/arm/mach-footbridge/personal-pci.c
--- v2.4.6/linux/arch/arm/mach-footbridge/personal-pci.c	Sun Sep  3 11:19:11 2000
+++ linux/arch/arm/mach-footbridge/personal-pci.c	Wed Jul  4 15:43:05 2001
@@ -11,6 +11,7 @@
 
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
+#include <asm/hardware/dec21285.h>
 
 static int irqmap_personal_server[] __initdata = {
 	IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
@@ -37,7 +38,9 @@
 }
 
 struct hw_pci personal_server_pci __initdata = {
-	init:		dc21285_init,
-	swizzle:	no_swizzle,
-	map_irq:	personal_server_map_irq,
+	setup_resources:	dc21285_setup_resources,
+	init:			dc21285_init,
+	mem_offset:		DC21285_PCI_MEM,
+	swizzle:		no_swizzle,
+	map_irq:		personal_server_map_irq,
 };
diff -u --recursive --new-file v2.4.6/linux/arch/arm/tools/mach-types linux/arch/arm/tools/mach-types
--- v2.4.6/linux/arch/arm/tools/mach-types	Tue Jul  3 17:08:18 2001
+++ linux/arch/arm/tools/mach-types	Wed Jul  4 14:56:44 2001
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Sun Jun 17 00:53:17 2001
+# Last update: Wed Jul 4 20:04:11 2001
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -91,12 +91,17 @@
 empeg			SA1100_EMPEG		EMPEG			79
 adi_eb			ARCH_I80200FCC		I80200FCC		80
 itt_cpb			SA1100_ITT_CPB		ITT_CPB			81
-sa1110_svc		ARCH_SA1110_SVC		SA1110_SVC		82
+svc			SA1100_SVC		SVC			82
 alpha2			SA1100_ALPHA2		ALPHA2			84
 alpha1			SA1100_ALPHA1		ALPHA1			85
 netarm			ARCH_NETARM		NETARM			86
 simpad			SA1100_SIMPAD		SIMPAD			87
 pda1			ARCH_PDA1		PDA1			88
 lubbock			ARCH_LUBBOCK		LUBBOCK			89
+aniko			ARCH_ANIKO		ANIKO			90
+clep7212		ARCH_CLEP7212		CLEP7212		91
+cs89712			ARCH_CS89712		CS89712			92
+weararm			SA1100_WEARARM		WEARARM			93
+possio_px		SA1100_POSSIO_PX	POSSIO_PX		94
 
 # The following are unallocated
diff -u --recursive --new-file v2.4.6/linux/arch/cris/Makefile linux/arch/cris/Makefile
--- v2.4.6/linux/arch/cris/Makefile	Tue May  1 16:04:56 2001
+++ linux/arch/cris/Makefile	Wed Jul  4 11:50:38 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.18 2001/04/17 13:58:38 orjanf Exp $
+# $Id: Makefile,v 1.19 2001/06/11 12:06:40 bjornw Exp $
 # cris/Makefile
 #
 # This file is included by the global makefile so that you can add your own
@@ -49,7 +49,12 @@
 
 HEAD := arch/cris/kernel/head.o
 
-SUBDIRS += arch/cris/kernel arch/cris/mm arch/cris/lib arch/cris/drivers arch/cris/boot/rescue
+SUBDIRS += arch/cris/kernel arch/cris/mm arch/cris/lib arch/cris/drivers
+ifdef CONFIG_ETRAX_AXISFLASHMAP
+# only build this if axis flash map is used, because they depend on
+# each others config options
+SUBDIRS += arch/cris/boot/rescue
+endif
 CORE_FILES += arch/cris/kernel/kernel.o arch/cris/mm/mm.o arch/cris/drivers/drivers.o
 LIBGCC = $(shell $(CC) $(CFLAGS) -print-file-name=libgcc.a)
 LIBS := $(TOPDIR)/arch/cris/lib/lib.a $(LIBS) $(TOPDIR)/arch/cris/lib/lib.a $(LIBGCC)
diff -u --recursive --new-file v2.4.6/linux/arch/cris/config.in linux/arch/cris/config.in
--- v2.4.6/linux/arch/cris/config.in	Tue May  1 16:04:56 2001
+++ linux/arch/cris/config.in	Wed Jul  4 11:50:38 2001
@@ -18,11 +18,10 @@
 
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
 
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
-fi
 
 bool 'Use kernel gdb debugger' CONFIG_ETRAX_KGDB
 
@@ -38,9 +37,9 @@
 	 Etrax-100-LX-v2	CONFIG_ETRAX100LX_V2	\
 	 Etrax-100-LX-for-xsim-simulator   CONFIG_SVINTO_SIM" Etrax-100-LX-v1
 
-# For both LX version 1 and the current simulator we enable the low VM mapping
+# Etrax100 LX v1 has a MMU "feature" requiring a low mapping
 
-if [ "$CONFIG_ETRAX100LX" = "y" -o "$CONFIG_SVINTO_SIM" = "y" ]; then
+if [ "$CONFIG_ETRAX100LX" = "y" ]; then
 	define_bool CONFIG_CRIS_LOW_MAP y
 	define_hex  CONFIG_ETRAX_DRAM_VIRTUAL_BASE 60000000
 else
@@ -98,7 +97,7 @@
 hex 'R_WAITSTATES' CONFIG_ETRAX_DEF_R_WAITSTATES 95a6
 hex 'R_BUS_CONFIG' CONFIG_ETRAX_DEF_R_BUS_CONFIG 104
 
-bool 'SDRAM support' CONFIG_ETRAX_SDRAM n
+bool 'SDRAM support' CONFIG_ETRAX_SDRAM
 if [ "$CONFIG_ETRAX_SDRAM" = "n" ]; then
 	hex 'R_DRAM_CONFIG' CONFIG_ETRAX_DEF_R_DRAM_CONFIG 1a200040
 	hex 'R_DRAM_TIMING' CONFIG_ETRAX_DEF_R_DRAM_TIMING 5611
@@ -115,6 +114,12 @@
 hex 'R_PORT_PB_DIR' CONFIG_ETRAX_DEF_R_PORT_PB_DIR 00
 hex 'R_PORT_PB_DATA' CONFIG_ETRAX_DEF_R_PORT_PB_DATA ff
 
+bool 'Software Shutdown Support' CONFIG_ETRAX_SOFT_SHUTDOWN
+if [ "$CONFIG_ETRAX_SOFT_SHUTDOWN" = "y" ]; then
+   int 'Shutdown bit on port CSP0' CONFIG_ETRAX_SHUTDOWN_BIT 12
+   int 'Power button bit on port G' CONFIG_ETRAX_POWERBUTTON_BIT 25
+fi
+
 endmenu
 
 # bring in Etrax built-in drivers
@@ -164,7 +169,7 @@
 
 source drivers/ieee1394/Config.in
 
-source drivers/i2o/Config.in
+source drivers/message/i2o/Config.in
 
 if [ "$CONFIG_NET" = "y" ]; then
   mainmenu_option next_comment
@@ -214,8 +219,6 @@
 source drivers/media/Config.in
 
 source fs/Config.in
-
-source drivers/char/Config.in
 
 mainmenu_option next_comment
 comment 'Sound'
diff -u --recursive --new-file v2.4.6/linux/arch/cris/defconfig linux/arch/cris/defconfig
--- v2.4.6/linux/arch/cris/defconfig	Tue May  1 16:04:56 2001
+++ linux/arch/cris/defconfig	Wed Jul  4 11:50:38 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 
 #
 # Code maturity level options
@@ -13,8 +15,9 @@
 #
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_JAVA is not set
 # CONFIG_ETRAX_KGDB is not set
 # CONFIG_ETRAX_WATCHDOG is not set
 
@@ -27,16 +30,30 @@
 CONFIG_CRIS_LOW_MAP=y
 CONFIG_ETRAX_DRAM_VIRTUAL_BASE=60000000
 CONFIG_ETRAX_DRAM_SIZE=8
-CONFIG_ETRAX_FLASH_LENGTH=2
 CONFIG_ETRAX_FLASH_BUSWIDTH=2
 CONFIG_ETRAX_PA_LEDS=y
 # CONFIG_ETRAX_PB_LEDS is not set
-# CONFIG_ETRAX_90000000_LEDS is not set
+# CONFIG_ETRAX_CSP0_LEDS is not set
 # CONFIG_ETRAX_NO_LEDS is not set
 CONFIG_ETRAX_LED1G=2
 CONFIG_ETRAX_LED1R=2
 CONFIG_ETRAX_LED2G=2
 CONFIG_ETRAX_LED2R=2
+CONFIG_ETRAX_LED3R=2
+CONFIG_ETRAX_LED3G=2
+CONFIG_ETRAX_LED4R=2
+CONFIG_ETRAX_LED4G=2
+CONFIG_ETRAX_LED5R=2
+CONFIG_ETRAX_LED5G=2
+CONFIG_ETRAX_LED6R=2
+CONFIG_ETRAX_LED6G=2
+CONFIG_ETRAX_LED7R=2
+CONFIG_ETRAX_LED7G=2
+CONFIG_ETRAX_LED8Y=2
+CONFIG_ETRAX_LED9Y=2
+CONFIG_ETRAX_LED10Y=2
+CONFIG_ETRAX_LED11Y=2
+CONFIG_ETRAX_LED12R=2
 CONFIG_ETRAX_DEBUG_PORT0=y
 # CONFIG_ETRAX_DEBUG_PORT1 is not set
 # CONFIG_ETRAX_DEBUG_PORT2 is not set
@@ -55,13 +72,17 @@
 CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=00
 CONFIG_ETRAX_DEF_R_PORT_PB_DIR=1e
 CONFIG_ETRAX_DEF_R_PORT_PB_DATA=f3
+# CONFIG_ETRAX_SOFT_SHUTDOWN is not set
 
 #
-# Drivers for Etrax built-in interfaces
+# Drivers for ETRAX 100LX built-in interfaces
 #
 CONFIG_ETRAX_ETHERNET=y
 CONFIG_NET_ETHERNET=y
-CONFIG_ETRAX_SERIAL=y
+# CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set
+CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y
+C# CONFIG_ETRAX_ETHERNET_LPSLAVE is not set
+ONFIG_ETRAX_SERIAL=y
 # CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set
 CONFIG_ETRAX_SERIAL_PORT1=y
 # CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB is not set
@@ -71,6 +92,7 @@
 # CONFIG_ETRAX_SYNCHRONOUS_SERIAL is not set
 # CONFIG_ETRAX_IDE is not set
 CONFIG_ETRAX_AXISFLASHMAP=y
+CONFIG_ETRAX_PTABLE_SECTOR=65536
 CONFIG_MTD=y
 CONFIG_MTD_CFI=y
 # CONFIG_MTD_CFI_INTELEXT is not set
@@ -80,6 +102,7 @@
 CONFIG_MTD_BLOCK=y
 CONFIG_ETRAX_I2C=y
 CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
+# CONFIG_ETRAX_I2C_EEPROM is not set
 CONFIG_ETRAX_GPIO=y
 CONFIG_ETRAX_PA_BUTTON_BITMASK=02
 CONFIG_ETRAX_PA_CHANGEABLE_DIR=00
@@ -87,21 +110,35 @@
 CONFIG_ETRAX_PB_CHANGEABLE_DIR=00
 CONFIG_ETRAX_PB_CHANGEABLE_BITS=FF
 # CONFIG_ETRAX_USB_HOST is not set
+# CONFIG_USB is not set
+# CONFIG_ETRAX_DS1302 is not set
 
 #
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
 # CONFIG_MTD_DOC1000 is not set
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOCPROBE is not set
+
+#
+# RAM/ROM Device Drivers
+#
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_MTDRAM is not set
+
+#
+# Linearly Mapped Flash Device Drivers
+#
 CONFIG_MTD_CFI=y
 # CONFIG_MTD_CFI_GEOMETRY is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
@@ -112,6 +149,7 @@
 # CONFIG_MTD_NORA is not set
 # CONFIG_MTD_PNC2000 is not set
 # CONFIG_MTD_RPXLITE is not set
+# CONFIG_MTD_SC520CDP is not set
 # CONFIG_MTD_SBC_MEDIAGX is not set
 # CONFIG_MTD_ELAN_104NC is not set
 # CONFIG_MTD_SA1100 is not set
@@ -121,8 +159,16 @@
 # CONFIG_MTD_MIXMEM is not set
 # CONFIG_MTD_OCTAGON is not set
 # CONFIG_MTD_VMAX is not set
+
+#
+# NAND Flash Device Drivers
+#
 # CONFIG_MTD_NAND is not set
 # CONFIG_MTD_NAND_SPIA is not set
+
+#
+# User Modules And Translation Layers
+#
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/Config.in linux/arch/cris/drivers/Config.in
--- v2.4.6/linux/arch/cris/drivers/Config.in	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/Config.in	Wed Jul  4 11:50:38 2001
@@ -6,10 +6,21 @@
 # this is just so that the user does not have to go into the
 # normal ethernet driver section just to enable ethernetworking
   define_bool CONFIG_NET_ETHERNET y
+  
+  choice 'Network LED behavior' \
+  "LED_on_when_link      CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK    \
+   LED_on_when_activity  CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY" \
+     LED_on_when_activity
+
 else
   define_bool CONFIG_NET_ETHERNET n
 fi
 
+bool 'Etrax Ethernet slave support (over lp0/1)' CONFIG_ETRAX_ETHERNET_LPSLAVE
+if [ "$CONFIG_ETRAX_ETHERNET_LPSLAVE" = "y" ]; then
+  bool '  Slave has its own LEDs' CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+fi 
+
 bool 'Serial-port support' CONFIG_ETRAX_SERIAL
 if [ "$CONFIG_ETRAX_SERIAL" = "y" ]; then
   comment '  Port 0 is always enabled'
@@ -99,7 +110,7 @@
 	define_bool CONFIG_BLK_DEV_IDEDMA y
 	define_bool CONFIG_DMA_NONPCI y
 	
-	int 'Delay for drives to regain consciousness' CONFIG_IDE_DELAY 15
+	int 'Delay for drives to regain consciousness' CONFIG_ETRAX_IDE_DELAY 15
 	
 	choice 'IDE reset pin' \
   	"Port_PB_Bit_7  CONFIG_ETRAX_IDE_PB7_RESET\
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/Makefile linux/arch/cris/drivers/Makefile
--- v2.4.6/linux/arch/cris/drivers/Makefile	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/Makefile	Wed Jul  4 11:50:38 2001
@@ -7,18 +7,21 @@
 obj-y :=
 
 
-obj-$(CONFIG_ETRAX_ETHERNET)           += ethernet.o
-obj-$(CONFIG_ETRAX_SERIAL)             += serial.o
-obj-$(CONFIG_ETRAX_IDE)                += ide.o
-obj-$(CONFIG_ETRAX_AXISFLASHMAP)       += axisflashmap.o
-obj-$(CONFIG_ETRAX_I2C) 	       += i2c.o
-obj-$(CONFIG_ETRAX_I2C_EEPROM)         += eeprom.o
-obj-$(CONFIG_ETRAX_GPIO) 	       += gpio.o
-obj-$(CONFIG_ETRAX_USB_HOST)           += usb-host.o
-obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
-obj-$(CONFIG_ETRAX_PARPORT)            += parport.o
-obj-$(CONFIG_ETRAX_DS1302)             += ds1302.o
+obj-$(CONFIG_ETRAX_ETHERNET)            += ethernet.o
+obj-$(CONFIG_ETRAX_SERIAL)              += serial.o
+obj-$(CONFIG_ETRAX_IDE)                 += ide.o
+obj-$(CONFIG_ETRAX_AXISFLASHMAP)        += axisflashmap.o
+obj-$(CONFIG_ETRAX_I2C) 	        += i2c.o
+obj-$(CONFIG_ETRAX_I2C_EEPROM)          += eeprom.o
+obj-$(CONFIG_ETRAX_GPIO) 	        += gpio.o
+obj-$(CONFIG_ETRAX_USB_HOST)            += usb-host.o
+obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL)  += sync_serial.o
+obj-$(CONFIG_ETRAX_PARPORT)             += parport.o
+obj-$(CONFIG_ETRAX_DS1302)              += ds1302.o
 
 
+obj-$(CONFIG_ETRAX_ETHERNET_LPSLAVE)    += lpslave/lpslavedrivers.o
+subdir-$(CONFIG_ETRAX_ETHERNET_LPSLAVE) += lpslave
 
 include $(TOPDIR)/Rules.make
+
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/axisflashmap.c linux/arch/cris/drivers/axisflashmap.c
--- v2.4.6/linux/arch/cris/drivers/axisflashmap.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/axisflashmap.c	Wed Jul  4 11:50:38 2001
@@ -11,6 +11,23 @@
  * partition split defined below.
  *
  * $Log: axisflashmap.c,v $
+ * Revision 1.12  2001/06/11 09:50:30  jonashg
+ * Oops, 2MB is 0x200000 bytes.
+ *
+ * Revision 1.11  2001/06/08 11:39:44  jonashg
+ * Changed sizes and offsets in axis_default_partitions to use
+ * CONFIG_ETRAX_PTABLE_SECTOR.
+ *
+ * Revision 1.10  2001/05/29 09:42:03  jonashg
+ * Use macro for end marker length instead of sizeof.
+ *
+ * Revision 1.9  2001/05/29 08:52:52  jonashg
+ * Gave names to the magic fours (size of the ptable end marker).
+ *
+ * Revision 1.8  2001/05/28 15:36:20  jonashg
+ * * Removed old comment about ptable location in flash (it's a CONFIG_ option).
+ * * Variable ptable was initialized twice to the same value.
+ *
  * Revision 1.7  2001/04/05 13:41:46  markusl
  * Updated according to review remarks
  *
@@ -130,6 +147,10 @@
 #define MAX_PARTITIONS         7  
 #define NUM_DEFAULT_PARTITIONS 3
 
+/* Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
+ * size of one flash block and "filesystem"-partition needs 5 blocks to be able
+ * to use JFFS.
+ */
 static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
 	{
 		name: "boot firmware",
@@ -138,13 +159,13 @@
 	},
 	{
 		name: "kernel",
-		size: 0x1a0000,
+		size: 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
 		offset: CONFIG_ETRAX_PTABLE_SECTOR
 	},
 	{
 		name: "filesystem",
-		size: 0x50000,
-		offset: (0x1a0000 + CONFIG_ETRAX_PTABLE_SECTOR)
+		size: 5 * CONFIG_ETRAX_PTABLE_SECTOR,
+		offset: 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
 	}
 };
 
@@ -223,21 +244,17 @@
 
 	mymtd->module = THIS_MODULE;
 
-	/* The partition-table is at an offset within the second 
-	 * sector of the flash. We _define_ this to be at offset 64k
-	 * even if the actual sector-size in the flash changes.. for
-	 * now at least.
-	 */
-
 	ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR +
 		CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET);
 	pidx++;  /* first partition is always set to the default */
 
 	if ((ptable_head->magic == PARTITION_TABLE_MAGIC)
 	    && (ptable_head->size <
-		(MAX_PARTITIONS * sizeof(struct partitiontable_entry) + 4))
+		(MAX_PARTITIONS * sizeof(struct partitiontable_entry) +
+		PARTITIONTABLE_END_MARKER_SIZE))
 	    && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) +
-				  ptable_head->size - 4)
+				  ptable_head->size -
+				  PARTITIONTABLE_END_MARKER_SIZE)
 		== PARTITIONTABLE_END_MARKER)) {
 		/* Looks like a start, sane length and end of a
 		 * partition table, lets check csum etc.
@@ -268,9 +285,6 @@
 		ptable_ok = (csum == ptable_head->checksum);
 
 		/* Read the entries and use/show the info.  */
-		ptable = (struct partitiontable_entry *)
-			((unsigned long)ptable_head + sizeof(*ptable_head));
-		
 		printk(" Found %s partition table at 0x%08lX-0x%08lX.\n",
 		       (ptable_ok ? "valid" : "invalid"),
 		       (unsigned long)ptable_head,
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/ds1302.c linux/arch/cris/drivers/ds1302.c
--- v2.4.6/linux/arch/cris/drivers/ds1302.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/ds1302.c	Wed Jul  4 11:50:38 2001
@@ -7,6 +7,32 @@
 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
 *!
 *! $Log: ds1302.c,v $
+*! Revision 1.11  2001/06/14 12:35:52  jonashg
+*! The ATA hack is back. It is unfortunately the only way to set g27 to output.
+*!
+*! Revision 1.9  2001/06/14 10:00:14  jonashg
+*! No need for tempudelay to be inline anymore (had to adjust the usec to
+*! loops conversion because of this to make it slow enough to be a udelay).
+*!
+*! Revision 1.8  2001/06/14 08:06:32  jonashg
+*! Made tempudelay delay usecs (well, just a tad more).
+*!
+*! Revision 1.7  2001/06/13 14:18:11  jonashg
+*! Only allow processes with SYS_TIME capability to set time and charge.
+*!
+*! Revision 1.6  2001/06/12 15:22:07  jonashg
+*! * Made init function __init.
+*! * Parameter to out_byte() is unsigned char.
+*! * The magic number 42 has got a name.
+*! * Removed comment about /proc (nothing is exported there).
+*!
+*! Revision 1.5  2001/06/12 14:35:13  jonashg
+*! Gave the module a name and added it to printk's.
+*!
+*! Revision 1.4  2001/05/31 14:53:40  jonashg
+*! Made tempudelay() inline so that the watchdog doesn't reset (see
+*! function comment).
+*!
 *! Revision 1.3  2001/03/26 16:03:06  bjornw
 *! Needs linux/config.h
 *!
@@ -56,13 +82,14 @@
 *!
 *! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
 *!
-*! $Id: ds1302.c,v 1.3 2001/03/26 16:03:06 bjornw Exp $
+*! $Id: ds1302.c,v 1.11 2001/06/14 12:35:52 jonashg Exp $
 *!
 *!***************************************************************************/
 
 #include <linux/config.h>
 
 #include <linux/fs.h>
+#include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/miscdevice.h>
@@ -76,13 +103,15 @@
 
 #define RTC_MAJOR_NR 121 /* local major, change later */
 
+static const char ds1302_name[] = "ds1302";
+
 /* The DS1302 might be connected to different bits on different products. 
  * It has three signals - SDA, SCL and RST. RST and SCL are always outputs,
  * but SDA can have a selected direction.
  * For now, only PORT_PB is hardcoded.
  */
 
-/* The RST bit may be on either the Generic Port or Port PB */
+/* The RST bit may be on either the Generic Port or Port PB. */
 #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
 #define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_G_DATA,  port_g_data_shadow,  CONFIG_ETRAX_DS1302_RSTBIT, x)
 #define TK_RST_DIR(x)
@@ -106,21 +135,23 @@
  * (used in udelay) is not set when functions here are called from time.c 
  */
 
-static void tempudelay(int time) 
+static void tempudelay(int usecs) 
 {
-	int i;
-	for(i = 0; i < time * 10000; i++);	
+	volatile int loops;
+
+	for(loops = usecs * 12; loops > 0; loops--)
+		/* nothing */;	
 }
 
 
-/* send 8 bits */
+/* Send 8 bits. */
 static void
-out_byte(int x) 
+out_byte(unsigned char x) 
 {
 	int i;
 	TK_SDA_DIR(1);
 	for (i = 8; i--;) {
-		/* the chip latches incoming bits on the rising edge of SCL */
+		/* The chip latches incoming bits on the rising edge of SCL. */
 		TK_SCL_OUT(0);
 		TK_SDA_OUT(x & 1);
 		tempudelay(1);
@@ -138,7 +169,7 @@
 	int i;
 
 	/* Read byte. Bits come LSB first, on the falling edge of SCL.
-	 * Assume SDA is in input direction already
+	 * Assume SDA is in input direction already.
 	 */
 	TK_SDA_DIR(0);
 
@@ -154,7 +185,7 @@
 	return x;
 }
 
-/* prepares for a transaction by de-activating RST (active-low) */
+/* Prepares for a transaction by de-activating RST (active-low). */
 
 static void
 start(void) 
@@ -166,7 +197,7 @@
 	TK_RST_OUT(1);	
 }
 
-/* ends a transaction by taking RST active again */
+/* Ends a transaction by taking RST active again. */
 
 static void
 stop(void) 
@@ -175,7 +206,7 @@
 	TK_RST_OUT(0);
 }
 
-/* enable writing */
+/* Enable writing. */
 
 static void
 ds1302_wenable(void) 
@@ -186,7 +217,7 @@
 	stop();
 }
 
-/* disable writing */
+/* Disable writing. */
 
 static void
 ds1302_wdisable(void) 
@@ -197,7 +228,9 @@
 	stop();
 }
 
-/* probe for the chip by writing something to its RAM and try reading it back */
+/* Probe for the chip by writing something to its RAM and try reading it back. */
+
+#define MAGIC_PATTERN 0x42
 
 static int
 ds1302_probe(void) 
@@ -208,36 +241,36 @@
 	TK_SCL_DIR(1);
 	TK_SDA_DIR(0);
 	
-	/* try to talk to timekeeper */
+	/* Try to talk to timekeeper. */
 
 	ds1302_wenable();  
 	start();
 	out_byte(0xc0); /* write RAM byte 0 */	
-	out_byte(0x42); /* write something magic */
+	out_byte(MAGIC_PATTERN); /* write something magic */
 	start();
 	out_byte(0xc1); /* read RAM byte 0 */
 
-	if((res = in_byte()) == 0x42) {
+	if((res = in_byte()) == MAGIC_PATTERN) {
 		char buf[100];
 		stop();
 		ds1302_wdisable();
-		printk("DS1302 RTC found.\n");
-                printk("SDA, SCL, RST on PB%i, PB%i, %s%i\n",
-                       CONFIG_ETRAX_DS1302_SDABIT,
-                       CONFIG_ETRAX_DS1302_SCLBIT,
+		printk("%s: RTC found.\n", ds1302_name);
+		printk("%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n",
+		       ds1302_name,
+		       CONFIG_ETRAX_DS1302_SDABIT,
+		       CONFIG_ETRAX_DS1302_SCLBIT,
 #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
-                       "GENIO",
+		       "GENIO",
 #else
-                       "PB",
+		       "PB",
 #endif
-                       CONFIG_ETRAX_DS1302_RSTBIT
-                       );
+		       CONFIG_ETRAX_DS1302_RSTBIT);
                 get_rtc_status(buf);
                 printk(buf);
 		retval = 1;
 	} else {
 		stop();
-		printk("DS1302 RTC not found.\n");
+		printk("%s: RTC not found.\n", ds1302_name);
 		retval = 0;
 	}
 
@@ -245,7 +278,7 @@
 }
 
 
-/* read a byte from the selected register in the DS1302 */
+/* Read a byte from the selected register in the DS1302. */
 
 unsigned char
 ds1302_readreg(int reg) 
@@ -253,21 +286,21 @@
 	unsigned char x;
 
 	start();
-	out_byte(0x81 | (reg << 1)); /* Read register */
+	out_byte(0x81 | (reg << 1)); /* read register */
 	x = in_byte();
 	stop();
 
 	return x;
 }
 
-/* write a byte to the selected register */
+/* Write a byte to the selected register. */
 
 void
 ds1302_writereg(int reg, unsigned char val) 
 {
 	ds1302_wenable();
 	start();
-	out_byte(0x80 | (reg << 1)); /* Write register */
+	out_byte(0x80 | (reg << 1)); /* write register */
 	out_byte(val);
 	stop();
 	ds1302_wdisable();
@@ -311,7 +344,7 @@
 static unsigned char days_in_mo[] = 
     {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
-/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date) */
+/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */
 
 static int
 rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
@@ -320,7 +353,7 @@
         unsigned long flags;
 
 	switch(cmd) {
-		case RTC_RD_TIME:	/* Read the time/date from RTC	*/
+		case RTC_RD_TIME:	/* read the time/date from RTC	*/
 		{
 			struct rtc_time rtc_tm;
 						
@@ -330,16 +363,16 @@
 			return 0;
 		}
 
-		case RTC_SET_TIME:	/* Set the RTC */
+		case RTC_SET_TIME:	/* set the RTC */
 		{
 			struct rtc_time rtc_tm;
 			unsigned char mon, day, hrs, min, sec, leap_yr;
 			unsigned char save_control, save_freq_select;
 			unsigned int yrs;
-#if 0
-			if (!suser())
-				return -EACCES;
-#endif			
+
+			if (!capable(CAP_SYS_TIME))
+				return -EPERM;
+
 			if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
 				return -EFAULT;    	
 
@@ -387,21 +420,21 @@
 			CMOS_WRITE(sec, RTC_SECONDS);
 			restore_flags(flags);
 
-			/* notice that at this point, the RTC is updated but the kernel
-			 * is still running with the old time. you need to set that
-			 * separately with settimeofday or adjtimex.
+			/* Notice that at this point, the RTC is updated but
+			 * the kernel is still running with the old time.
+			 * You need to set that separately with settimeofday
+			 * or adjtimex.
 			 */
 			return 0;
 		}
 
-		case RTC_SET_CHARGE: /* Set the RTC TRICKLE CHARGE register */
+		case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
 		{
 			int tcs_val;                        
 			unsigned char save_control, save_freq_select;
-#if 0
-			if (!suser())
-				return -EACCES;
-#endif
+
+			if (!capable(CAP_SYS_TIME))
+				return -EPERM;
 			
 			if(copy_from_user(&tcs_val, (int*)arg, sizeof(int)))
 				return -EFAULT;
@@ -415,10 +448,6 @@
 	}
 }
 
-/*
- *	Info exported via "/proc/rtc".
- */
-
 int
 get_rtc_status(char *buf) 
 {
@@ -444,45 +473,41 @@
 }
 
 
-/*
- *	The various file operations we support.
- */
+/* The various file operations we support. */
 
 static struct file_operations rtc_fops = {
         owner:          THIS_MODULE,
         ioctl:          rtc_ioctl,	
 }; 
 
-/* just probe for the RTC and register the device to handle the ioctl needed */
+/* Just probe for the RTC and register the device to handle the ioctl needed. */
 
-int
+int __init
 ds1302_init(void) 
 { 
-  
- /* Ugly hack to handle both 2100 and 2400 hardware.
-    Remove...
- */
-	if(!ds1302_probe()) {
+	if (!ds1302_probe()) {
 #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
-    	/*
-     	* Make sure that R_GEN_CONFIG is 
-     	* setup correct.
-     	*/
-    		genconfig_shadow = ( (genconfig_shadow & ~IO_MASK(R_GEN_CONFIG, ata) ) | 
-                           ( IO_STATE( R_GEN_CONFIG, ata, select ) ) );    
+		/*
+		 * The only way to set g27 to output is to enable ATA.
+		 *
+		 * Make sure that R_GEN_CONFIG is setup correct.
+		 */
+    		genconfig_shadow = ((genconfig_shadow &
+				     ~IO_MASK(R_GEN_CONFIG, ata))
+				   | 
+				   (IO_STATE(R_GEN_CONFIG, ata, select)));    
     		*R_GEN_CONFIG = genconfig_shadow;
-    		if(!ds1302_probe())
+    		if (!ds1302_probe())
       			return -1;
 #else
     		return -1;
 #endif
   	}
   
-	if (register_chrdev(RTC_MAJOR_NR, "rtc", &rtc_fops)) {
-		printk("unable to get major %d for rtc\n", RTC_MAJOR_NR);
+	if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) {
+		printk(KERN_INFO "%s: unable to get major %d for rtc\n", 
+		       ds1302_name, RTC_MAJOR_NR);
 		return -1;
 	}
 	return 0;
 }
-
-
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/eeprom.c linux/arch/cris/drivers/eeprom.c
--- v2.4.6/linux/arch/cris/drivers/eeprom.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/eeprom.c	Wed Jul  4 11:50:38 2001
@@ -1,32 +1,12 @@
-/*!**************************************************************************
+/*!*****************************************************************************
 *!
-*!  FILE NAME:      e100eeprom.c
-*!
-*!  DESCRIPTION:    Implements an interface for i2c compatible eeproms to run
-*!                  under linux.
-*!                  Supports 2k, 8k(?) and 16k
-*!                  Uses adaptive timing adjustents by Johan.Adolfsson@axis.com
-*!                  Probing results:
-*!                    8k or not is detected (the assumes 2k or 16k)
-*!                    2k or 16k detected using test reads and writes.
-*!
-*!  FUNCTIONS:
-*!
-*!  (Exported)
-*!              eeprom_init()
-*!
-*!  (Local)
-*!
-*!              eeprom_open()
-*!              eeprom_lseek()
-*!              eeprom_read()
-*!              eeprom_write()
-*!              eeprom_close()
-*!              eeprom_address()
-*!              eeprom_disable_write_protect()
-*!
-*!
-*!  $Id: eeprom.c,v 1.3 2001/03/19 16:04:46 markusl Exp $
+*!  Implements an interface for i2c compatible eeproms to run under linux.
+*!  Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustents by
+*!  Johan.Adolfsson@axis.com
+*!
+*!  Probing results:
+*!    8k or not is detected (the assumes 2k or 16k)
+*!    2k or 16k detected using test reads and writes.
 *!
 *!------------------------------------------------------------------------
 *!  HISTORY
@@ -40,6 +20,13 @@
 *!                                  in the spin-lock.
 *!
 *!  $Log: eeprom.c,v $
+*!  Revision 1.5  2001/06/14 14:39:51  jonashg
+*!  Forgot to use name when registering the driver.
+*!
+*!  Revision 1.4  2001/06/14 14:35:47  jonashg
+*!  * Gave driver a name and used it in printk's.
+*!  * Cleanup.
+*!
 *!  Revision 1.3  2001/03/19 16:04:46  markusl
 *!  Fixed init of fops struct
 *!
@@ -64,9 +51,7 @@
 *!
 *!
 *!        (c) 1999 Axis Communications AB, Lund, Sweden
-*!**************************************************************************/
-
-/********************** INCLUDE FILES SECTION ******************************/
+*!*****************************************************************************/
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -76,7 +61,6 @@
 #include <linux/delay.h>
 #include "i2c.h"
 
-/********************** CONSTANT AND MACRO SECTION *************************/
 #define D(x) 
 
 /* If we should use adaptive timing or not: */
@@ -86,9 +70,8 @@
 #define EEPROM_MINOR_NR 0
 
 #define MAX_WRITEDELAY_US 10000 /* 10 ms according to spec for 2KB EEPROM */
-/*
- *  this one defines how many times to try when eeprom fails.
- */
+
+/* This one defines how many times to try when eeprom fails. */
 #define EEPROM_RETRIES 10
 
 #define EEPROM_2KB (2 * 1024)
@@ -98,8 +81,6 @@
 
 #define i2c_delay(x) udelay(x)
 
-/********************** TYPE DEFINITION SECTION ****************************/
-
 /*
  *  This structure describes the attached eeprom chip.
  *  The values are probed for.
@@ -110,51 +91,42 @@
   unsigned long size;
   unsigned long sequential_write_pagesize;
   unsigned char select_cmd;
-  unsigned long usec_delay_writecycles; /* Min time between write cycles (up to 10ms for some models) */
-  unsigned long int usec_delay_step; /* For adaptive algorithm */
+  unsigned long usec_delay_writecycles; /* Min time between write cycles
+					   (up to 10ms for some models) */
+  unsigned long usec_delay_step; /* For adaptive algorithm */
   int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */
   
   /* this one is to keep the read/write operations atomic */
   wait_queue_head_t wait_q;
   int busy;
   int retry_cnt_addr; /* Used to keep track of number of retries for
-                     adaptive timing adjustments */
+                         adaptive timing adjustments */
   int retry_cnt_read;
-
-  
-  
 };
 
-/********************** LOCAL FUNCTION DECLARATION SECTION *****************/
-
-static int  eeprom_open (struct inode * inode, struct file * file);
+static int  eeprom_open(struct inode * inode, struct file * file);
 static loff_t  eeprom_lseek(struct file * file, loff_t offset, int orig);
-static ssize_t  eeprom_read (struct file * file, char * buf, size_t count, loff_t *off);
-static ssize_t  eeprom_write(struct file * file, const char * buf, size_t count, loff_t *off);
+static ssize_t  eeprom_read(struct file * file, char * buf, size_t count,
+                            loff_t *off);
+static ssize_t  eeprom_write(struct file * file, const char * buf, size_t count,
+                             loff_t *off);
 static int eeprom_close(struct inode * inode, struct file * file);
 
 static int  eeprom_address(unsigned long addr);
 static int  read_from_eeprom(char * buf, int count);
-static int eeprom_write_buf(unsigned long int addr,
-                            const char * buf, int count);
+static int eeprom_write_buf(unsigned long addr, const char * buf, int count);
 static int eeprom_read_buf(unsigned long addr,
                            char * buf, int count);
 
 static void eeprom_disable_write_protect(void);
 
 
-/********************** GLOBAL VARIABLE DECLARATION SECTION ****************/
-
-/********************** LOCAL VARIABLE DECLARATION SECTION *****************/
+static const char eeprom_name[] = "eeprom";
 
 /* chip description */
 static struct eeprom_type eeprom;
 
-/*
- *  This is the exported file-operations structure
- *  for this device.
- */
-
+/* This is the exported file-operations structure for this device. */
 struct file_operations eeprom_fops =
 {
   llseek:  eeprom_lseek,
@@ -164,29 +136,7 @@
   release: eeprom_close
 };
 
-/********************** FUNCTION DEFINITION SECTION ************************/
-
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_init
-*#                                                            
-*# PARAMETERS   : none
-*#                                                            
-*# RETURNS      : 0 if OK
-*#                                                            
-*# SIDE EFFECTS : 
-*#                                                            
-*# DESCRIPTION  : eeprom init call. Probes for different eeprom models.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Sep 03 1999  Edgar Iglesias  Updated probing. Added forced values.
-*#
-*#**************************************************************************/
+/* eeprom init call. Probes for different eeprom models. */
 
 int __init eeprom_init(void)
 {
@@ -198,9 +148,10 @@
 #else
 #define EETEXT "Assuming"
 #endif
-  if (register_chrdev(EEPROM_MAJOR_NR, "mem", &eeprom_fops))
+  if (register_chrdev(EEPROM_MAJOR_NR, eeprom_name, &eeprom_fops))
   {
-    printk("unable to get major %d for eeprom device\n", EEPROM_MAJOR_NR);
+    printk(KERN_INFO "%s: unable to get major %d for eeprom device\n",
+           eeprom_name, EEPROM_MAJOR_NR);
     return -1;
   }
   
@@ -213,7 +164,6 @@
    *        for all models. If you encounter problems the easiest way
    *        is probably to define your model within #ifdef's, and hard-
    *        code it.
-   *
    */
 
   eeprom.size = 0;
@@ -240,7 +190,6 @@
      * 2. if it doesn't differ - write diferent value to one of the locations,
      *    check the other - if content still is the same it's a 2k EEPROM,
      *    restore original data.
-     *    
      */
 #define LOC1 8
 #define LOC2 (0x1fb) /*1fb, 3ed, 5df, 7d1 */
@@ -256,7 +205,7 @@
     }
     else
     {
-      printk("Failed to read in 2k mode!\n");  
+      printk(KERN_INFO "%s: Failed to read in 2k mode!\n", eeprom_name);  
     }
     
     /* 16k settings */
@@ -276,7 +225,7 @@
           if (memcmp(loc1, loc2, 4) != 0 )
           {
             /* It's 16k */
-            printk("16k detected in step 1\n");
+            printk(KERN_INFO "%s: 16k detected in step 1\n", eeprom_name);
             eeprom.size = EEPROM_16KB;     
             success = 1;
           }
@@ -299,7 +248,8 @@
                          LOC1, loc1, tmp));
                 if (memcmp(loc1, tmp, 4) != 0 )
                 {
-                  printk("read and write differs! Not 16kB\n");
+                  printk(KERN_INFO "%s: read and write differs! Not 16kB\n",
+                         eeprom_name);
                   loc1[0] = ~loc1[0];
                   
                   if (eeprom_write_buf(LOC1, loc1, 1) == 1)
@@ -308,7 +258,8 @@
                   }
                   else
                   {
-                    printk("eeprom: Restore 2k failed during probe EEPROM might be corrupt!\n");
+                    printk(KERN_INFO "%s: Restore 2k failed during probe,"
+                           " EEPROM might be corrupt!\n", eeprom_name);
                     
                   }
                   i2c_stop();
@@ -321,7 +272,8 @@
                   }
                   else
                   {
-                    printk("Failed to write back 2k start!\n");
+                    printk(KERN_INFO "%s: Failed to write back 2k start!\n",
+                           eeprom_name);
                   }
                   
                   eeprom.size = EEPROM_2KB;
@@ -338,7 +290,7 @@
                   {
                     /* Data the same, must be mirrored -> 2k */
                     /* Restore data */
-                    printk("2k detected in step 2\n");
+                    printk(KERN_INFO "%s: 2k detected in step 2\n", eeprom_name);
                     loc1[0] = ~loc1[0];
                     if (eeprom_write_buf(LOC1, loc1, 1) == 1)
                     {
@@ -346,7 +298,8 @@
                     }
                     else
                     {
-                      printk("eeprom: Restore 2k failed during probe EEPROM might be corrupt!\n");
+                      printk(KERN_INFO "%s: Restore 2k failed during probe,"
+                             " EEPROM might be corrupt!\n", eeprom_name);
                       
                     }
                     
@@ -354,7 +307,8 @@
                   }
                   else
                   {
-                    printk("16k detected in step 2\n");
+                    printk(KERN_INFO "%s: 16k detected in step 2\n",
+                           eeprom_name);
                     loc1[0] = ~loc1[0];
                     /* Data differs, assume 16k */
                     /* Restore data */
@@ -364,7 +318,8 @@
                     }
                     else
                     {
-                      printk("eeprom: Restore 16k failed during probe EEPROM might be corrupt!\n");
+                      printk(KERN_INFO "%s: Restore 16k failed during probe,"
+                             " EEPROM might be corrupt!\n", eeprom_name);
                     }
                     
                     eeprom.size = EEPROM_16KB;
@@ -376,7 +331,7 @@
         } /* address LOC1 */
         if (!success)
         {
-          printk("eeprom: Probing failed!, using 2KB!\n");
+          printk(KERN_INFO "%s: Probing failed!, using 2KB!\n", eeprom_name);
           eeprom.size = EEPROM_2KB;               
         }
       } /* read */
@@ -418,23 +373,23 @@
   switch(eeprom.size)
   {
    case (EEPROM_2KB):
-     printk("e100eeprom: " EETEXT " i2c compatible 2Kb eeprom.\n");
+     printk("%s: " EETEXT " i2c compatible 2Kb eeprom.\n", eeprom_name);
      eeprom.sequential_write_pagesize = 16;
      eeprom.select_cmd = 0xA0;
      break;
    case (EEPROM_8KB):
-     printk("e100eeprom: " EETEXT " i2c compatible 8Kb eeprom.\n");
+     printk("%s: " EETEXT " i2c compatible 8Kb eeprom.\n", eeprom_name);
      eeprom.sequential_write_pagesize = 16;
      eeprom.select_cmd = 0x80;
      break;
    case (EEPROM_16KB):
-     printk("e100eeprom: " EETEXT " i2c compatible 16Kb eeprom.\n");
+     printk("%s: " EETEXT " i2c compatible 16Kb eeprom.\n", eeprom_name);
      eeprom.sequential_write_pagesize = 64;
      eeprom.select_cmd = 0xA0;     
      break;
    default:
      eeprom.size = 0;
-     printk("e100eeprom: Did not find a supported eeprom\n");
+     printk("%s: Did not find a supported eeprom\n", eeprom_name);
      break;
   }
 
@@ -445,28 +400,7 @@
   return 0;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_open
-*#                                                            
-*# PARAMETERS   : inode    : Pointer to the inode
-*#                file     : Pointer to the file
-*#                                                            
-*# RETURNS      : 0 if OK
-*#                                                            
-*# SIDE EFFECTS : 
-*#                                                            
-*# DESCRIPTION  : Opens the device.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Sep 03 1999  Edgar Iglesias  Removed users check.
-*#
-*#**************************************************************************/
+/* Opens the device. */
 
 static int eeprom_open(struct inode * inode, struct file * file)
 {
@@ -486,29 +420,7 @@
   return -EFAULT;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_lseek
-*#                                                            
-*# PARAMETERS   : file     : Pointer to the file
-*#                offset   : The offset (in bytes)
-*#                orig     : look at the note
-*#                                                            
-*# RETURNS      : 0 if OK
-*#                                                            
-*# SIDE EFFECTS : 
-*#                                                            
-*# DESCRIPTION  : Changes the current file position.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version
-*# Sep 03 1999  Edgar Iglesias  Return -EOVERFLOW when beyond eeprom size.
-*#
-*#**************************************************************************/
+/* Changes the current file position. */
 
 static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig)
 {
@@ -549,29 +461,8 @@
   return ( file->f_pos );
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_read
-*#                                                            
-*# PARAMETERS   : inode    : Pointer to the inode
-*#                file     : Pointer to the file
-*#                buf      : Destination buffer
-*#                count    : max nr bytes to read
-*#                                                            
-*# RETURNS      : number of read bytes.
-*#                                                            
-*# SIDE EFFECTS : updates file->f_pos
-*#                                                            
-*# DESCRIPTION  : Reads data from eeprom.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Jan 17 2000  Johan Adolfsson Initial version
-*#
-*#**************************************************************************/
+/* Reads data from eeprom. */
+
 static int eeprom_read_buf(unsigned long addr,
                            char * buf, int count)
 {
@@ -583,31 +474,7 @@
 
 
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_read
-*#                                                            
-*# PARAMETERS   : file     : Pointer to the file
-*#                buf      : Destination buffer
-*#                count    : max nr bytes to read
-*#                                                            
-*# RETURNS      : number of read bytes.
-*#                                                            
-*# SIDE EFFECTS : updates file->f_pos
-*#                                                            
-*# DESCRIPTION  : Reads data from eeprom.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Aug 31 1999  Edgar Iglesias  Made operation atomic with wait queues
-*# Sep 03 1999  Edgar Iglesias  Added bail-out stuff if we get interrupted
-*#                              in the spin-lock.
-*#
-*#**************************************************************************/
+/* Reads data from eeprom. */
 
 static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off)
 {
@@ -636,8 +503,8 @@
   
   if(!eeprom_address(p))
   {
-    printk("eeprom: Read failed to address the eeprom: "
-           "0x%08X (%i) page: %i\n", p, p, page);
+    printk(KERN_INFO "%s: Read failed to address the eeprom: "
+           "0x%08X (%i) page: %i\n", eeprom_name, p, p, page);
     i2c_stop();
     
     /* don't forget to wake them up */
@@ -674,30 +541,9 @@
   return read;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_write_buf
-*#                                                            
-*# PARAMETERS   : addr     : Address to write to
-*#                buf      : Data buffer to write from
-*#                count    : number bytes to write
-*#                                                            
-*# RETURNS      : number of bytes actualy written.
-*#                                                            
-*# SIDE EFFECTS : None
-*#             
-*# DESCRIPTION  : Writes data to eeprom.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Jan 17 2000  Johan Adolfsson Initial vesion
-*#
-*#**************************************************************************/
-static int eeprom_write_buf(unsigned long int addr,
-                            const char * buf, int count)
+/* Writes data to eeprom. */
+
+static int eeprom_write_buf(unsigned long addr, const char * buf, int count)
 {
   struct file f;
 
@@ -707,33 +553,7 @@
 }
 
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_write
-*#                                                            
-*# PARAMETERS   : file     : Pointer to the file
-*#                buf      : Data buffer to write from
-*#                count    : number bytes to write
-*#                                                            
-*# RETURNS      : number of bytes actualy written.
-*#                                                            
-*# SIDE EFFECTS : updates file->f_pos
-*#             
-*# DESCRIPTION  : Writes data to eeprom.
-*#                                                            
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#                                                            
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Aug 31 1999  Edgar Iglesias  Made operation atomic with wait queues
-*# Sep 03 1999  Edgar Iglesias  Moved the actual reading to read_from_eeprom
-*# Sep 03 1999  Edgar Iglesias  Added bail-out stuff if we get interrupted
-*#                              in the spin-lock.
-*# May 18 2000  Edgar Iglesias  Make sure to end write cycle after every write.
-*#
-*#**************************************************************************/
+/* Writes data to eeprom. */
 
 static ssize_t eeprom_write(struct file * file, const char * buf, size_t count,
                             loff_t *off)
@@ -761,8 +581,8 @@
       /* address the eeprom */
       if(!eeprom_address(p))
       {
-        printk("eeprom: Write failed to address the eeprom: 0x%08X (%i) \n", 
-               p, p);
+        printk(KERN_INFO "%s: Write failed to address the eeprom: "
+               "0x%08X (%i) \n", eeprom_name, p, p);
         i2c_stop();
         
         /* don't forget to wake them up */
@@ -868,7 +688,7 @@
         if(!i2c_getack())
         {
           restart=1;
-          printk("eeprom: write error, retrying. %d\n", i);
+          printk(KERN_INFO "%s: write error, retrying. %d\n", eeprom_name, i);
           i2c_stop();
           break;
         }
@@ -891,28 +711,7 @@
   return written;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_close
-*#                                                            
-*# PARAMETERS   : inode    : Pointer to the inode
-*#                file     : Pointer to the file
-*#
-*# RETURNS      : nothing
-*#
-*# SIDE EFFECTS :
-*#
-*# DESCRIPTION  : Closes the device.
-*#
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Sep 03 1999  Edgar Iglesias  Removed eeprom.users stuff.
-*#
-*#**************************************************************************/
+/* Closes the device. */
 
 static int eeprom_close(struct inode * inode, struct file * file)
 {
@@ -920,27 +719,7 @@
   return 0;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_address
-*#                                                            
-*# PARAMETERS   : addr     : Address to be given to eeprom
-*#
-*# RETURNS      : 1 if OK, 0 if failure.
-*#
-*# SIDE EFFECTS :
-*#
-*# DESCRIPTION  : Sets the current address of the eeprom.
-*#
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Aug 28 1999  Edgar Iglesias  Initial version               
-*# Sep 03 1999  Edgar Iglesias  Corrected typo.
-*#
-*#**************************************************************************/
+/* Sets the current address of the eeprom. */
 
 static int eeprom_address(unsigned long addr)
 {
@@ -999,27 +778,7 @@
   return 1;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: read_from_eeprom
-*#                                                            
-*# PARAMETERS   : buf      : Destination buffer.
-*#                count    : Number of bytes to read.
-*#
-*# RETURNS      : number of read bytes or -EFAULT.
-*#
-*# SIDE EFFECTS :
-*#
-*# DESCRIPTION  : Reads from current adress.
-*#
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Sep 03 1999  Edgar Iglesias  Initial version               
-*#
-*#**************************************************************************/
+/* Reads from current adress. */
 
 static int read_from_eeprom(char * buf, int count)
 {
@@ -1040,7 +799,7 @@
   
   if(i == EEPROM_RETRIES)
   {
-    printk("eeprom: failed to read from eeprom\n");
+    printk(KERN_INFO "%s: failed to read from eeprom\n", eeprom_name);
     i2c_stop();
     
     return -EFAULT;
@@ -1066,26 +825,8 @@
   return read;
 }
 
-/*#**************************************************************************
-*#                                                            
-*# FUNCTION NAME: eeprom_disable_write_protect
-*#                                                            
-*# PARAMETERS   : None
-*#
-*# RETURNS      : Nothing
-*#
-*# SIDE EFFECTS :
-*#
-*# DESCRIPTION  : Disables write protection if applicable
-*#
-*#---------------------------------------------------------------------------
-*# HISTORY                                                    
-*#
-*# DATE         NAME            CHANGES                       
-*# ----         ----            -------                       
-*# Jan 14 2000  Johan Adolfsson Initial version (from PS pareerom.c)
-*#
-*#**************************************************************************/
+/* Disables write protection if applicable. */
+
 #define DBP_SAVE(x)
 #define ax_printf printk
 static void eeprom_disable_write_protect(void)
@@ -1133,7 +874,7 @@
     }
     i2c_stop();
     
-    /* Step 3 Set BP1, BP0, and/or WPEN bits (write 00000110 to address 1FFFh*/
+    /* Step 3 Set BP1, BP0, and/or WPEN bits (write 00000110 to address 1FFFh */
     i2c_start();
     i2c_outbyte(0xbe);
     if(!i2c_getack())
@@ -1157,5 +898,3 @@
 }
 
 module_init(eeprom_init);
-
-/********************** END OF FILE e100eeprom.c *****************************/
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/ethernet.c linux/arch/cris/drivers/ethernet.c
--- v2.4.6/linux/arch/cris/drivers/ethernet.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/ethernet.c	Wed Jul  4 11:50:38 2001
@@ -1,4 +1,4 @@
-/* $Id: ethernet.c,v 1.12 2001/04/05 11:43:11 tobiasa Exp $
+/* $Id: ethernet.c,v 1.17 2001/06/11 12:43:46 olof Exp $
  *
  * e100net.c: A network driver for the ETRAX 100LX network controller.
  *
@@ -7,6 +7,23 @@
  * The outline of this driver comes from skeleton.c.
  *
  * $Log: ethernet.c,v $
+ * Revision 1.17  2001/06/11 12:43:46  olof
+ * Modified defines for network LED behavior
+ *
+ * Revision 1.16  2001/05/30 06:12:46  markusl
+ * TxDesc.next should not be set to NULL
+ *
+ * Revision 1.15  2001/05/29 10:27:04  markusl
+ * Updated after review remarks:
+ * +Use IO_EXTRACT
+ * +Handle underrun
+ *
+ * Revision 1.14  2001/05/29 09:20:14  jonashg
+ * Use driver name on printk output so one can tell which driver that complains.
+ *
+ * Revision 1.13  2001/05/09 12:35:59  johana
+ * Use DMA_NBR and IRQ_NBR defines from dma.h and irq.h
+ *
  * Revision 1.12  2001/04/05 11:43:11  tobiasa
  * Check dev before panic.
  *
@@ -80,6 +97,7 @@
 
 #include <asm/svinto.h>     /* DMA and register descriptions */
 #include <asm/io.h>         /* LED_* I/O functions */
+#include <asm/irq.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -87,8 +105,6 @@
 //#define ETHDEBUG
 #define D(x)
 
-#define ETH_TX_DMA 0
-#define ETH_RX_DMA 1
 
 /*
  * The name of the card. Is used for messages and in the requests for
@@ -116,9 +132,6 @@
 	spinlock_t lock;
 };
 
-#define NETWORK_DMARX_IRQ 17  /* irq 17 is the DMA1 irq */
-#define NETWORK_DMATX_IRQ 16  /* irq 16 is the DMA0 irq */
-#define NETWORK_STATUS_IRQ 6  /* irq 6 is the network irq */
 
 /* Dma descriptors etc. */
 
@@ -231,7 +244,8 @@
 	/* make Linux aware of the new hardware  */
 
 	if (!dev) {
-		printk("dev == NULL. Should this happen?\n");
+		printk(KERN_WARNING "%s: dev == NULL. Should this happen?\n",
+		       cardname);
 		dev = init_etherdev(dev, sizeof(struct net_local));
 		if (!dev)
 			panic("init_etherdev failed\n");
@@ -250,8 +264,8 @@
 
 	/* now setup our etrax specific stuff */
 
-	dev->irq = NETWORK_DMARX_IRQ; /* we really use DMATX as well... */
-	dev->dma = 1;
+	dev->irq = NETWORK_DMA_RX_IRQ_NBR; /* we really use DMATX as well... */
+	dev->dma = NETWORK_RX_DMA_NBR;
 
 	/* fill in our handlers so the network layer can talk to us in the future */
 
@@ -381,30 +395,30 @@
 
 	/* Reset and wait for the DMA channels */
 
-	RESET_DMA(0);
-	RESET_DMA(1);
-	WAIT_DMA(0);
-	WAIT_DMA(1);
+	RESET_DMA(NETWORK_TX_DMA_NBR);
+	RESET_DMA(NETWORK_RX_DMA_NBR);
+	WAIT_DMA(NETWORK_TX_DMA_NBR);
+	WAIT_DMA(NETWORK_RX_DMA_NBR);
 
 	/* Initialise the etrax network controller */
 
 	/* allocate the irq corresponding to the receiving DMA */
 
-	if (request_irq(NETWORK_DMARX_IRQ, e100rx_interrupt, 0,
+	if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rx_interrupt, 0,
 			cardname, (void *)dev)) {
 		goto grace_exit;
 	}
 
 	/* allocate the irq corresponding to the transmitting DMA */
 
-	if (request_irq(NETWORK_DMATX_IRQ, e100tx_interrupt, 0,
+	if (request_irq(NETWORK_DMA_TX_IRQ_NBR, e100tx_interrupt, 0,
 			cardname, (void *)dev)) {
 		goto grace_exit;
 	}
 
 	/* allocate the irq corresponding to the network errors etc */
 
-	if (request_irq(NETWORK_STATUS_IRQ, e100nw_interrupt, 0,
+	if (request_irq(NETWORK_STATUS_IRQ_NBR, e100nw_interrupt, 0,
 			cardname, (void *)dev)) {
 		goto grace_exit;
 	}
@@ -414,17 +428,17 @@
 	 * and clean up on failure.
 	 */
 
-	if(request_dma(ETH_TX_DMA, cardname)) {
+	if(request_dma(NETWORK_TX_DMA_NBR, cardname)) {
 		goto grace_exit;
 	}
 
-	if(request_dma(ETH_RX_DMA, cardname)) {
+	if(request_dma(NETWORK_RX_DMA_NBR, cardname)) {
 	grace_exit:
 		/* this will cause some 'trying to free free irq' but what the heck... */
-		free_dma(ETH_TX_DMA);
-		free_irq(NETWORK_DMARX_IRQ, (void *)dev);
-		free_irq(NETWORK_DMATX_IRQ, (void *)dev);
-		free_irq(NETWORK_STATUS_IRQ, (void *)dev);
+		free_dma(NETWORK_TX_DMA_NBR);
+		free_irq(NETWORK_DMA_RX_IRQ_NBR, (void *)dev);
+		free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev);
+		free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev);
 		return -EAGAIN;
 	}
 
@@ -625,8 +639,8 @@
 	
 	/* reset the TX DMA in case it has hung on something */
 	
-	RESET_DMA(0);
-	WAIT_DMA(0);
+	RESET_DMA(NETWORK_TX_DMA_NBR);
+	WAIT_DMA(NETWORK_TX_DMA_NBR);
 	
 	/* Reset the tranceiver. */
 	
@@ -751,7 +765,8 @@
 			tx_skb = 0;
 			netif_wake_queue(dev);
 		} else {
-			printk("tx weird interrupt\n");
+			printk(KERN_WARNING "%s: tx weird interrupt\n",
+			       cardname);
 		}
 
 		spin_unlock(&np->lock);
@@ -765,6 +780,13 @@
 	struct net_local *np = (struct net_local *)dev->priv;
 	unsigned long irqbits = *R_IRQ_MASK0_RD;
 
+	/* check for underrun irq */
+	if(irqbits & IO_STATE(R_IRQ_MASK0_RD, underrun, active)) { 
+		*R_NETWORK_TR_CTRL = IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr);
+		np->stats.tx_errors++;
+		D(printk("ethernet receiver underrun!\n"));
+	}
+
 	/* check for overrun irq */
 	if(irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) { 
 		update_rx_stats(&np->stats); /* this will ack the irq */
@@ -900,17 +922,17 @@
 
 	/* Stop the receiver and the transmitter */
 
-	RESET_DMA(0);
-	RESET_DMA(1);
+	RESET_DMA(NETWORK_TX_DMA_NBR);
+	RESET_DMA(NETWORK_RX_DMA_NBR);
 
 	/* Flush the Tx and disable Rx here. */
 
-	free_irq(NETWORK_DMARX_IRQ, (void *)dev);
-	free_irq(NETWORK_DMATX_IRQ, (void *)dev);
-	free_irq(NETWORK_STATUS_IRQ, (void *)dev);
+	free_irq(NETWORK_DMA_RX_IRQ_NBR, (void *)dev);
+	free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev);
+	free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev);
 
-	free_dma(ETH_TX_DMA);
-	free_dma(ETH_RX_DMA);
+	free_dma(NETWORK_TX_DMA_NBR);
+	free_dma(NETWORK_RX_DMA_NBR);
 
 	/* Update the statistics here. */
 
@@ -925,10 +947,10 @@
 {
 	unsigned long r = *R_REC_COUNTERS;
 	/* update stats relevant to reception errors */
-	es->rx_fifo_errors += r >> 24;            /* fifo overrun */
-	es->rx_crc_errors += r & 0xff;            /* crc error */
-	es->rx_frame_errors += (r >> 8) & 0xff;   /* alignment error */
-	es->rx_length_errors += (r >> 16) & 0xff; /* oversized frames */
+	es->rx_fifo_errors += IO_EXTRACT(R_REC_COUNTERS, congestion, r);
+	es->rx_crc_errors += IO_EXTRACT(R_REC_COUNTERS, crc_error, r);
+	es->rx_frame_errors += IO_EXTRACT(R_REC_COUNTERS, alignment_error, r);
+	es->rx_length_errors += IO_EXTRACT(R_REC_COUNTERS, oversize, r);
 }
 
 static void
@@ -936,8 +958,10 @@
 {
 	unsigned long r = *R_TR_COUNTERS;
 	/* update stats relevant to transmission errors */
-	es->collisions += (r & 0xff) + ((r >> 8) & 0xff); /* single_col + multiple_col */
-	es->tx_errors += (r >> 24) & 0xff; /* deferred transmit frames */
+	es->collisions +=
+		IO_EXTRACT(R_TR_COUNTERS, single_col, r) +
+		IO_EXTRACT(R_TR_COUNTERS, multiple_col, r);
+	es->tx_errors += IO_EXTRACT(R_TR_COUNTERS, deferred, r);
 }
 
 /*
@@ -1082,10 +1106,12 @@
 static void
 e100_set_network_leds(int active)
 {
-#ifdef CONFIG_LED_OFF_DURING_ACTIVITY
+#if defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK)
 	int light_leds = (active == NO_NETWORK_ACTIVITY);
-#else
+#elif defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY)
 	int light_leds = (active == NETWORK_ACTIVITY);
+#else
+#error "Define either CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK or CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY"
 #endif
 
 	if (!current_speed) {
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/gpio.c linux/arch/cris/drivers/gpio.c
--- v2.4.6/linux/arch/cris/drivers/gpio.c	Sat May 19 17:43:05 2001
+++ linux/arch/cris/drivers/gpio.c	Wed Jul  4 11:50:38 2001
@@ -1,4 +1,4 @@
-/* $Id: gpio.c,v 1.7 2001/04/04 13:30:08 matsfg Exp $
+/* $Id: gpio.c,v 1.9 2001/05/04 14:16:07 matsfg Exp $
  *
  * Etrax general port I/O device
  *
@@ -9,6 +9,14 @@
  *             Johan Adolfsson  (read/set directions)
  *
  * $Log: gpio.c,v $
+ * Revision 1.9  2001/05/04 14:16:07  matsfg
+ * Corrected spelling error
+ *
+ * Revision 1.8  2001/04/27 13:55:26  matsfg
+ * Moved initioremap.
+ * Turns off all LEDS on init.
+ * Added support for shutdown and powerbutton.
+ *
  * Revision 1.7  2001/04/04 13:30:08  matsfg
  * Added bitset and bitclear for leds. Calls init_ioremap to set up memmapping
  *
@@ -247,6 +255,16 @@
 			*priv->dir = *priv->dir_shadow |= 
 			  ((unsigned char)arg & priv->changeable_dir);
 			return *priv->dir_shadow;
+                case IO_SHUTDOWN:
+                       SOFT_SHUTDOWN();
+                       break;
+                case IO_GET_PWR_BT:
+#if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
+                       return (*R_PORT_G_DATA & 
+                               ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
+#else
+                       return 0;
+#endif
 		default:
 			if(priv->minor == LEDS)
 				return gpio_leds_ioctl(cmd, arg);
@@ -262,12 +280,6 @@
 {
 	unsigned char green;
 	unsigned char red;
-        static int initialized = 0;
-        if(!initialized)
-        {
-          initialized = 1;
-          init_ioremap();
-        }
 	switch (_IOC_NR(cmd)) {
 		case IO_LEDACTIVE_SET:
 			green = ((unsigned char) arg) & 1;
@@ -298,7 +310,7 @@
 static __init int
 gpio_init(void)
 {
-	int res;
+	int res,i;
 
 	/* do the formalities */
 
@@ -307,6 +319,24 @@
 		printk(KERN_ERR "gpio: couldn't get a major number.\n");
 		return res;
 	}
+
+        /* Clear all leds */
+#if defined (CONFIG_ETRAX_CSP0_LEDS) ||  defined (CONFIG_ETRAX_PA_LEDS)         || defined (CONFIG_ETRAX_PB_LEDS) 
+
+        init_ioremap();
+        LED_NETWORK_SET(0);
+        LED_ACTIVE_SET(0);
+        LED_DISK_READ(0);
+        LED_DISK_WRITE(0);        
+
+#if defined (CONFIG_ETRAX_CSP0_LEDS)
+        for( i = 0; i < 32; i ++)
+        {
+            LED_BIT_SET(i);
+        }
+#endif
+
+#endif
 	
 	printk("ETRAX 100LX GPIO driver v2.1, (c) 2001 Axis Communications AB\n");
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- v2.4.6/linux/arch/cris/drivers/ide.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/cris/drivers/ide.c	Wed Jul  4 11:50:38 2001
@@ -1,4 +1,4 @@
-/* $Id: ide.c,v 1.16 2001/04/05 08:30:07 matsfg Exp $
+/* $Id: ide.c,v 1.19 2001/05/09 12:53:16 johana Exp $
  *
  * Etrax specific IDE functions, like init and PIO-mode setting etc.
  * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
@@ -8,6 +8,15 @@
  *             Mikael Starvik     (pio setup stuff)
  *
  * $Log: ide.c,v $
+ * Revision 1.19  2001/05/09 12:53:16  johana
+ * Added #include <asm/dma.h>
+ *
+ * Revision 1.18  2001/05/09 12:37:00  johana
+ * Use DMA_NBR macros from dma.h.
+ *
+ * Revision 1.17  2001/04/23 13:36:30  matsfg
+ * Changed CONFIG_IDE_DELAY to CONFIG_ETRAX_IDE_DELAY
+ *
  * Revision 1.16  2001/04/05 08:30:07  matsfg
  * Corrected cse1 and csp0 reset.
  *
@@ -98,6 +107,7 @@
 
 #include <asm/io.h>
 #include <asm/svinto.h>
+#include <asm/dma.h>
 
 /* number of Etrax DMA descriptors */
 #define MAX_DMA_DESCRS 64
@@ -341,17 +351,17 @@
 			     IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) |
 			     IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) );
 
-	printk("ide: waiting %d seconds for drives to regain consciousness\n", CONFIG_IDE_DELAY);
+	printk("ide: waiting %d seconds for drives to regain consciousness\n", CONFIG_ETRAX_IDE_DELAY);
 
-	h = jiffies + (CONFIG_IDE_DELAY * HZ);
+	h = jiffies + (CONFIG_ETRAX_IDE_DELAY * HZ);
 	while(jiffies < h) ;
 
   /* reset the dma channels we will use */
 
-	RESET_DMA(2);
-	RESET_DMA(3);
-	WAIT_DMA(2);
-	WAIT_DMA(3);
+	RESET_DMA(ATA_TX_DMA_NBR);
+	RESET_DMA(ATA_RX_DMA_NBR);
+	WAIT_DMA(ATA_TX_DMA_NBR);
+	WAIT_DMA(ATA_RX_DMA_NBR);
 
 }
 
@@ -378,8 +388,8 @@
 	}
 	
 	/* make sure the DMA channel is available */
-	RESET_DMA(3);
-	WAIT_DMA(3); 
+	RESET_DMA(ATA_RX_DMA_NBR);
+	WAIT_DMA(ATA_RX_DMA_NBR); 
 	
 	/* setup DMA descriptor */
 	
@@ -406,7 +416,7 @@
 	/* wait for completion */
 	
 	LED_DISK_READ(1);
-	WAIT_DMA(3);
+	WAIT_DMA(ATA_RX_DMA_NBR);
 	LED_DISK_READ(0);
 
 #if 0
@@ -457,8 +467,8 @@
 	}
 
 	/* make sure the DMA channel is available */
-	RESET_DMA(2);
-	WAIT_DMA(2); 
+	RESET_DMA(ATA_TX_DMA_NBR);
+	WAIT_DMA(ATA_TX_DMA_NBR); 
 	
 	/* setup DMA descriptor */
 	
@@ -485,7 +495,7 @@
 	/* wait for completion */
 	
 	LED_DISK_WRITE(1);
-	WAIT_DMA(2);
+	WAIT_DMA(ATA_TX_DMA_NBR);
 	LED_DISK_WRITE(0);
 
 #if 0
@@ -794,8 +804,8 @@
 
 	if(reading) {
 
-		RESET_DMA(3); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(3);
+		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_RX_DMA_NBR);
 
 		/* set up the Etrax DMA descriptors */
 		
@@ -837,8 +847,8 @@
 	} else {
 		/* writing */
 
-		RESET_DMA(2); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(2);
+		RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_TX_DMA_NBR);
 
 		/* set up the Etrax DMA descriptors */
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/Makefile linux/arch/cris/drivers/lpslave/Makefile
--- v2.4.6/linux/arch/cris/drivers/lpslave/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/Makefile	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,20 @@
+#
+# Makefile for parallel port slave drivers
+#
+
+O_TARGET := lpslavedrivers.o
+
+obj-y = e100lpslavenet.o e100lpslave_code.o
+
+
+include $(TOPDIR)/Rules.make
+
+e100lpslave_code.o:	e100lpslave.o e100lpslaveld 
+	$(CROSS_COMPILE)ld -qmagic -Te100lpslaveld e100lpslave.o -o e100lpslave
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.data --remove-section=.bss e100lpslave e100lpslave.text
+	$(CROSS_COMPILE)objcopy -O binary --remove-section=.text --remove-section=.bss e100lpslave e100lpslave.data
+	cat e100lpslave.text e100lpslave.data |\
+	./bintocarr.pl e100lpslaveprog |\
+	$(CC) $(CFLAGS) -pipe -o e100lpslave_code.o -c -x c -
+	ls -l e100lpslave.text e100lpslave.data
+	rm -f e100lpslave e100lpslave.text e100lpslave.data
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/bintocarr.pl linux/arch/cris/drivers/lpslave/bintocarr.pl
--- v2.4.6/linux/arch/cris/drivers/lpslave/bintocarr.pl	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/bintocarr.pl	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+# $Id: bintocarr.pl,v 1.3 2001/06/08 08:46:50 olof Exp $
+# Copy of mkjulbin.pl made by Olof
+# convert a binary stdin to a C-file containing a char array of the input
+# first argument is the symbol name
+
+$symbol = shift @ARGV;
+
+print "#include <linux/init.h>\n\n";
+print "unsigned char $symbol", "[] __initdata = {\n";
+
+my $char;
+
+$bcount = 0;
+
+while(read STDIN, $char, 1) {
+    printf("0x%x, ", ord($char));
+    $bcount++;
+    if(!($bcount % 16)) {
+	print "\n";
+    }
+}
+
+print "\n};\n";
+
+$lensymb = ("_" . ($symbol . "_length"));
+
+print "__asm__(\"\\t.globl $lensymb\\n$lensymb = $bcount\\n\");\n";
+  
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.README linux/arch/cris/drivers/lpslave/e100lpslave.README
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.README	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslave.README	Wed Jul  4 11:50:38 2001
@@ -0,0 +1,54 @@
+***** MODIFICATIONS
+To use a 5600 as a slave device it has to somewhat modified.
+This has to be done on a 5600 (art no 16144 R2) to automatically set it to parallel port boot mode:
+
+1)
+Close to the LPT1 connector there are two resistors, between the "Pulse" inductor and
+the LS245. The one closest to the LS245 is a 4k7 pull up (R105). Remove it.
+
+2)
+Between the other "Pulse" inductor and Etrax there is a black 5-pin inverter
+(D15). Short connectors 2 and 3 with a solder blob.
+
+
+***** PINOUT
+To use this driver use cables connected like this:
+DSUB25-Male                DSUB25Male
+
+1	10
+2-9	2-9
+10 	1
+11	14
+12	18
+13	NC
+14	11
+15	NC
+16	NC	
+17	NC
+18	12
+19	NC
+20-25	20-25
+
+Thus the cables are symmetrical with most cables straight through,
+some crossed (1-10, 11-14 and 12-18) 
+and some Not connected (NC 13,15,16,17 and 19).
+
+
+******* Only for reference
+To ease the use of flat-cable connectors, here are the notes of wich wires to cross and cut with pin 1 being cable 1:
+Cross:
+1	19
+2	21
+10	23
+Cut:
+4
+6
+8
+12
+25
+
+jonas.dellenvall@axis.com
+
+
+
+
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.S linux/arch/cris/drivers/lpslave/e100lpslave.S
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslave.S	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,429 @@
+	;; $Id: e100lpslave.S,v 1.2 2001/06/11 12:50:01 olof Exp $
+	;;
+	;; Etrax100 slave network<->parport forwarder
+	;;
+	;; Copyright (c) 1999 Bjorn Wesen, Axis Communications AB
+	;;
+	;; We got 784 bytes (par loader size) to do DMA forwarding
+	;; between DMA0/1 (ethernet) and DMA3/4 (par port 0 RX/1 TX)
+	;;
+
+#include <linux/config.h>
+#if 0
+#define ASSEMBLER_MACROS_ONLY
+#endif
+#include <asm/sv_addr_ag.h>
+
+#define BUFSIZE 0x600
+
+	;; R_IRQ_READ2
+
+#define DMA1EOPBIT 3
+#define DMA0EOPBIT 1
+#define DMA3EOPBIT 7
+#define DMA4DESCBIT 8
+
+	;; R_IRQ_READ0
+
+#define PAR0ECPCMDBIT 11
+
+	;; get host CMDs
+
+#include "e100lpslave.h"
+
+start:
+	;; disable interrupts. we are not going to use them at all.
+
+	di
+
+	;; setup DMA connections and port configuration
+
+	movu.w	0x84, r0	; DMA2/3/4/5 to par ports
+	move.d	r0, [R_GEN_CONFIG]
+
+	;; setup port PA dirs and turn on the LED to show were alive
+
+	movu.w	0x0cfb, r0	; PA2-PA3 out, PA2 inactive
+	move.d	r0, [R_PORT_PA_SET]
+
+	;; enable MDIO output pin
+	moveq IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable), r0
+	move.d	r0, [R_NETWORK_MGM_CTRL]
+
+	;; accept broadcast frames, and enable station address 0
+	moveq	IO_STATE(R_NETWORK_REC_CONFIG, broadcast, receive) | \
+		IO_STATE(R_NETWORK_REC_CONFIG, ma0, enable), r0
+	move.d	r0, [R_NETWORK_REC_CONFIG]
+
+	;; use MII CLK mode, and enable the controller
+	moveq	IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) | \
+		IO_STATE(R_NETWORK_GEN_CONFIG, enable, on), r0
+	move.d	r0, [R_NETWORK_GEN_CONFIG]
+
+	move.d	IO_STATE(R_PAR0_CONFIG, ioe,     noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iseli,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iautofd, noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, istrb,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iinit,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iperr,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, iack,    noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, ibusy,   noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, ifault,  noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, isel,    noninv)    |  \
+		IO_STATE(R_PAR0_CONFIG, dma, enable)        |  \
+		IO_STATE(R_PAR0_CONFIG, rle_in, disable)    |  \
+		IO_STATE(R_PAR0_CONFIG, rle_out, disable)   |  \
+		IO_STATE(R_PAR0_CONFIG, enable, on)         |  \
+		IO_STATE(R_PAR0_CONFIG, force, on)          |  \
+		IO_STATE(R_PAR0_CONFIG, mode, ecp_rev), r0	; Reverse ECP - PAR0 is RX
+
+	move.d	r0, [R_PAR0_CONFIG]
+
+	move.d	IO_STATE(R_PAR1_CONFIG, ioe,     noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, iseli,   noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, iautofd, noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, istrb,   noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, iinit,   noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, iperr,   inv)       |  \
+		IO_STATE(R_PAR1_CONFIG, iack,    noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, ibusy,   noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, ifault,  noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, isel,    noninv)    |  \
+		IO_STATE(R_PAR1_CONFIG, dma, enable)        |  \
+		IO_STATE(R_PAR1_CONFIG, rle_in, disable)    |  \
+		IO_STATE(R_PAR1_CONFIG, rle_out, disable)   |  \
+		IO_STATE(R_PAR1_CONFIG, enable, on)         |  \
+		IO_STATE(R_PAR1_CONFIG, force, on)          |  \
+		IO_STATE(R_PAR1_CONFIG, mode, ecp_fwd), r0	; Forward ECP - PAR1 is TX
+
+	move.d	r0, [R_PAR1_CONFIG]
+
+	moveq	IO_FIELD(R_PAR1_DELAY, setup, 1), r0    ; setup time of value * 160 + 20
+	move.d	r0, [R_PAR1_DELAY]
+
+	;; we got four descriptors, that can be active at the same time:
+	;; 1) from network
+	;; 2) to parport
+	;; 3) from parport
+	;; 4) to network
+	;;
+	;; we got four buffers, each can hold a max packet (we use 1536 bytes)
+	;; buffers 1 and 2 are used from network to parport, while
+	;; buffers 3 and 4 are used from parport to network.
+	;; 
+	;; a double buffering scheme is used, so that new data can be read
+	;; into a buffer pair while the last data is written out from the
+	;; last buffer. if the read buffer is done before the write buffer,
+	;; the reading will halt until the writing is done, at which point
+	;; writing starts from the newly read and reading can start with
+	;; the newly written.
+	;; 
+
+	move.d	R_DMA_CH0_FIRST, r1   ; we use this as base for subsequent DMA ops
+	moveq	IO_STATE(R_DMA_CH1_CMD, cmd, start), r6
+	move.d	FN1desc, r7
+	move.d	R_IRQ_READ0, r9
+
+	;; start receiving from network
+
+	jsr	startdmaFPTN
+	jsr	startdmaFNTP
+
+	
+
+	;; ------------------- MAIN LOOP
+
+	;; IRQ bits:	parport rcv is par0_ecp_cmd, then dma3_eop
+	;;              network rcv is dma1_eop
+	;;              parport tx  is dma4_desc
+	;;              network tx  is dma0_eop
+
+mainloop:
+
+	;; ------- first handle the parport -> network link
+
+	;; check if we got something from the parport
+
+	move.d	[r9], r0	; r0 <- *R_IRQ_READ0
+	btstq	PAR0ECPCMDBIT, r0
+	bpl	noparecp
+	nop
+
+	;; ack it by reading PAR0_STATUS_DATA
+
+	move.d	[R_PAR0_STATUS_DATA], r0
+
+	;; trigger EOP on DMA3 (par0 incoming channel)
+
+	moveq	IO_STATE(R_SET_EOP, ch3_eop, set), r0
+	move.d	r0, [R_SET_EOP]
+
+noparecp:
+
+	;; if we simultaneously have parport rx EOP and
+	;; network TX eop, we can swap buffers and start a new RX/TX
+
+	move.d	[r9 + (R_IRQ_READ2 - R_IRQ_READ0)], r0
+	btstq	DMA3EOPBIT, r0	; check parport rx
+	bpl	noswap1
+	btstq	DMA0EOPBIT, r0	; check network tx
+	bpl	noswap1
+	nop
+
+	;; prepare to swap buffer ptrs (FN3b <-> TN4b)
+
+	move.d	[r4 = r7 + 56], r0; FP3b
+	move.d	[r3 = r7 + 72], r2; TN4b
+
+	;; but first check if this was a Host Command Packet
+
+	move.d	[r0], r5	; r5 <- first 4 bytes in PAR-received packet
+	bne	handle_command	; if non-zero, it was a host command
+	addq	4, r0		; skip command (in delay slot - handle_command requires this)
+	move.d	r0, [r3]	; write to To Network descriptor
+	subq	4, r2		; undo the skipping done last swap
+	move.d	r2, [r4]	; write to From Parport descriptor
+
+	;; clear the interrupts
+
+	moveq	IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do), r0
+	move.b	r0, [r1 + (R_DMA_CH0_CLR_INTR - R_DMA_CH0_FIRST)]
+	move.b	r0, [r1 + (R_DMA_CH3_CLR_INTR - R_DMA_CH0_FIRST)]
+
+	;; copy received length to outgoing network length
+
+	move.w	[r7 + 60], r0	; FPhlen
+	subq	4, r0		; skip command
+	move.w	r0, [r7 + 64]	; TN4desc
+
+	;; restart DMAs
+
+	jsr	startdmaFPTN
+
+#ifdef CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+#if defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK)
+	;; Turn off the LED signaling an outgoing network packet
+	movu.b	[LEDOff], r0
+#elif defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY)
+	;; Light the LED signaling an outgoing network packet
+	movu.b	[LEDAmber], r0
+#else
+#error "Define either CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK or CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY"	
+#endif 
+	move.b	r0, [R_PORT_PA_DATA]
+	move.d	0x00011000, r0
+	move.d	r0,[LEDCount]
+#endif
+
+noswap1:
+	;; ----- now check the network -> parport link
+
+
+	;; if we simultaneously have network rx EOP and
+	;; parport TX desc, we can swap buffers and start a new RX/TX
+
+	move.d	[r9 + (R_IRQ_READ2 - R_IRQ_READ0)], r0
+	btstq	DMA1EOPBIT, r0	; check network rx
+	bpl	noswap2
+	btstq	DMA4DESCBIT, r0	; check parport tx
+	bpl	noswap2
+	nop
+
+	;; prepare to swap buffer ptrs (FP1b <-> TP2b)
+
+	move.d	[r4 = r7 +  8], r0; FN1b
+	move.d	[r3 = r7 + 24], r2; TP2b
+	move.d	r0, [r3]	; write to To Parport descriptor
+	move.d	r2, [r4]	; write to From Network descriptor
+
+	;; clear the interrupts
+
+	moveq	IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do) | \
+		IO_STATE(R_DMA_CH1_CLR_INTR, clr_descr, do), r0
+	move.b	r0, [r1 + (R_DMA_CH1_CLR_INTR - R_DMA_CH0_FIRST)]
+	move.b	r0, [r1 + (R_DMA_CH4_CLR_INTR - R_DMA_CH0_FIRST)]
+
+	;; copy received network length to outgoing parport length
+
+	move.w	[r7 + 12], r0	; FNhlen
+	move.w	r0, [r7 + 16]	; TP2desc
+
+	;; restart DMAs
+
+	jsr	startdmaFNTP
+#if 0
+#ifdef CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+	;; Light the LED signaling an incoming networkpacket
+	movu.b	0xFB, r0
+	move.b	r0, [R_PORT_PA_DATA]
+	move.d	0x00010000, r0
+	move.d	r0,[LEDCount]
+#endif
+#endif
+
+noswap2:
+#ifdef CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+
+	;; Count down LED counter, and turn off the network LED if required
+	move.d	[LEDCount], r0
+	beq	mainloop
+	nop
+
+	subq	1, r0
+	move.d	r0, [LEDCount]	
+	bne	mainloop
+	nop
+
+#if defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK)	
+	;; Light the network LED , and start over the main loop
+	movu.b	[LEDAmber], r0
+#elif defined(CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY)		
+	;; Turn off the network LED, and start over the main loop
+	movu.b	[LEDOff], r0
+#else
+#error "Define either CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK or CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY"	
+#endif
+	move.b	r0, [R_PORT_PA_DATA]
+#endif
+
+	ba	mainloop
+	nop
+
+	;; --- some useful subroutines.
+
+handle_command:
+	;; handle command. we also need to clear the PAR0 RX EOP IRQ, and 
+	;; restart the PAR0 dma. command is in R5, packet after cmd is in R0
+
+	moveq	IO_STATE(R_DMA_CH3_CLR_INTR, clr_eop, do), r2
+	move.b	r2, [r1 + (R_DMA_CH3_CLR_INTR - R_DMA_CH0_FIRST)]
+
+	cmpq	HOST_CMD_SETMAC, r5
+	bne	no_setmac
+	nop
+
+	;; copy station address (6 bytes) from packet to hardware
+
+	move.d	[r0+], r2
+	move.d	R_NETWORK_SA_0, r3
+	move.d	r2, [r3]
+	move.w	[r0], r2
+	move.w	r2, [r3 + 4] 
+
+no_setmac:
+	move	noswap1, SRP
+	ba	startdmaFP
+	nop
+
+	;; start DMAs, from parport and to network
+
+startdmaFPTN:
+
+	;; start transmitting to the network (CH0)
+
+	move.d	TN4desc, r8
+	move.d	r8, [r1]					; TN4desc -> FIRST0
+	move.b	r6, [r1 + (R_DMA_CH0_CMD - R_DMA_CH0_FIRST)]	; start -> CMD0
+
+startdmaFP:
+
+	;; start receiving from parport (CH3)
+
+	move.d	FP3desc, r8
+	move.d	r8, [r1 + (R_DMA_CH3_FIRST - R_DMA_CH0_FIRST)]  ; FP3desc -> FIRST3
+	move.b	r6, [r1 + (R_DMA_CH3_CMD - R_DMA_CH0_FIRST)]	; start -> CMD3
+
+	ret
+	nop
+
+	;; start DMAs, from network and to parport
+
+startdmaFNTP:
+
+	;; start transmitting to the parport (CH4)
+
+	move.d	TP2desc, r8
+	move.d	r8, [r1 + (R_DMA_CH4_FIRST - R_DMA_CH0_FIRST)]	; TP2desc -> FIRST4
+	move.b	r6, [r1 + (R_DMA_CH4_CMD - R_DMA_CH0_FIRST)]	; start -> CMD4
+
+	;; start receiving from network (CH1) (r7 already contains FN1desc)
+
+	move.d	r7, [r1 + (R_DMA_CH1_FIRST - R_DMA_CH0_FIRST)]  ; FN1desc -> FIRST1
+	move.b	r6, [r1 + (R_DMA_CH1_CMD - R_DMA_CH0_FIRST)]	; start -> CMD1
+
+	ret
+	nop
+
+	;; --- DMA descriptors - each descriptor is 4 longwords (16 bytes)
+	;; DONT MOVE THESE AROUND. Due to the as/ld "hole-in-the-head",
+	;; we cant write stuff like (TP2b - TP2desc) but the offsets
+	;; have to be hardcoded.
+
+	.data
+
+	;; 0 from network
+FN1desc:
+	.word	BUFSIZE		; sw_len
+	.word	0x0001		; ctrl, d_eol is only flag we need
+	.dword	0		; next
+FN1b:	.dword	buffers		; buffer 1 8
+	.word	0		; hw_len
+	.word	0		; status
+
+	;; 16 to parport
+TP2desc:
+	.word	2		; sw_len, filled in by code 
+	.word	0x0004		; ctrl, d_wait because ecp cmd in next
+	.dword	TP2desc2	; next
+TP2b:	.dword	buffers + BUFSIZE ; buffer 2 24
+	.word	0		; hw_len
+	.word	0		; status
+
+	;; 32 to parport second descriptor, for the ECP command
+TP2desc2:
+	.word	0x0001		; sw_len, 1 byte (ecp command) 
+	.word	0x0019		; ctrl, d_ecp | d_eol | d_int
+	.dword	0		; next
+	.dword	TP2desc2	; buffer, dont care
+	.word	0		; hw_len
+	.word	0		; status
+
+	;; 48 from parport
+FP3desc:
+	.word	BUFSIZE		; sw_len
+	.word	0x0001		; ctrl, d_eol is only flag we need
+	.dword	0		; next
+FP3b:	.dword	buffers + BUFSIZE * 2 ; 56 buffer 3
+FPhlen:	.word	0		; 60 hw_len
+	.word	0		; status
+
+	;; 64 to network
+TN4desc:
+	.word	2		; sw_len, filled in by code 
+	.word	0x0007		; ctrl, d_eop | d_eol | d_wait
+	.dword	0		; next
+TN4b:	.dword	buffers + BUFSIZE * 3 + 4	; 72 buffer 4 (the +4 is to offset the anti-skipping)
+	.word	0		; hw_len
+	.word	0		; status
+
+#ifdef CONFIG_ETRAX_ETHERNET_LPSLAVE_HAS_LEDS
+LEDCount:
+	.dword	0
+LEDOff:	
+	.word	0xff
+LEDGreen:
+	.word	0xfb
+LEDRed:
+	.word	0xf7
+LEDAmber:
+	.word	0xf3
+LED:
+	.word	0xf7
+#endif
+
+	;; after the prog we put the buffers. not in the asm program, we just use
+	;; the address generated
+
+buffers:
+
+	;; END
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.h linux/arch/cris/drivers/lpslave/e100lpslave.h
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslave.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslave.h	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,2 @@
+#define HOST_CMD_SENDPACK 0
+#define HOST_CMD_SETMAC 1
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslaveld linux/arch/cris/drivers/lpslave/e100lpslaveld
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslaveld	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslaveld	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,22 @@
+MEMORY 
+	{
+	cache : ORIGIN = 0x380000f0,
+	       	LENGTH = 784
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		*(.text)
+	} > cache
+	.data :
+	{
+		*(.data)
+		*(COMMON)
+	} > cache
+	.bss :
+	{
+		*(.bss)
+	} > cache
+}
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslavenet.c linux/arch/cris/drivers/lpslave/e100lpslavenet.c
--- v2.4.6/linux/arch/cris/drivers/lpslave/e100lpslavenet.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/lpslave/e100lpslavenet.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,1031 @@
+/* $Id: e100lpslavenet.c,v 1.2 2001/06/11 15:39:52 olof Exp $
+ *
+ * e100lpslavenet.c: A network driver for the ETRAX 100LX slave controller.
+ *
+ * Copyright (c) 1998-2001 Axis Communications AB.
+ *
+ * The outline of this driver comes from skeleton.c.
+ *
+ * $Log: e100lpslavenet.c,v $
+ * Revision 1.2  2001/06/11 15:39:52  olof
+ * Clean up and sync with ethernet.c rev 1.16. Increased reset time of slave.
+ *
+ * Revision 1.1  2001/06/06 08:56:26  olof
+ * Added support for slave Etrax defined by CONFIG_ETRAX_ETHERNET_LPSLAVE
+ *
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/svinto.h>     /* DMA and register descriptions */
+#include <asm/io.h>         /* LED_* I/O functions */
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include "e100lpslave.h"
+
+/* #define ETHDEBUG */
+#define D(x)
+
+/*
+ * The name of the card. Is used for messages and in the requests for
+ * io regions, irqs and dma channels
+ */
+
+static const char* cardname = "Etrax 100LX ethernet slave controller";
+
+/* A default ethernet address. Highlevel SW will set the real one later */
+
+static struct sockaddr default_mac = {
+	0,
+        { 0x00, 0x40, 0x8C, 0xCD, 0x00, 0x00 }
+};
+
+/* Information that need to be kept for each board. */
+struct net_local {
+	struct net_device_stats stats;
+
+	/* Tx control lock.  This protects the transmit buffer ring
+	 * state along with the "tx full" state of the driver.  This
+	 * means all netif_queue flow control actions are protected
+	 * by this lock as well.
+	 */
+	spinlock_t lock;
+};
+
+/* Dma descriptors etc. */
+
+#define RX_BUF_SIZE 32768
+#define ETHER_HEAD_LEN      14
+
+#define PAR0_ECP_IRQ_NBR    4
+
+#define RX_DESC_BUF_SIZE   256
+#define NBR_OF_RX_DESC     (RX_BUF_SIZE / \
+			    RX_DESC_BUF_SIZE)
+
+/* Size of slave etrax boot image */
+#define ETRAX_PAR_BOOT_LENGTH 784
+
+static etrax_dma_descr *myNextRxDesc;  /* Points to the next descriptor to
+					  to be processed */
+static etrax_dma_descr *myLastRxDesc;  /* The last processed descriptor */
+static etrax_dma_descr *myPrevRxDesc;  /* The descriptor right before myNextRxDesc */
+
+static unsigned char RxBuf[RX_BUF_SIZE];
+
+static etrax_dma_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(4)));
+static etrax_dma_descr TxDescList[3] __attribute__ ((aligned(4)));
+                       /* host command, data, bogus ECP command */
+
+static struct sk_buff *tx_skb;
+
+/* Index to functions, as function prototypes. */
+
+static int etrax_ethernet_lpslave_init(struct net_device *dev);
+
+static int e100_open(struct net_device *dev);
+static int e100_set_mac_address(struct net_device *dev, void *addr);
+static int e100_send_packet(struct sk_buff *skb, struct net_device *dev);
+static void e100rx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void e100tx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void ecp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void e100_rx(struct net_device *dev);
+static int e100_close(struct net_device *dev);
+static struct net_device_stats *e100_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void e100_hardware_send_packet(unsigned long hostcmd, char *buf, int length);
+static void update_rx_stats(struct net_device_stats *);
+static void update_tx_stats(struct net_device_stats *);
+static void e100_reset_tranceiver(void);
+
+static void boot_slave(unsigned char *code);
+
+#ifdef ETHDEBUG
+static void dump_parport_status(void);
+#endif
+
+#define tx_done(dev) (*R_DMA_CH0_CMD == 0)
+
+static unsigned long host_command;
+extern unsigned char e100lpslaveprog;
+
+/*
+ * This driver uses PAR0 to recevice data from slave ETRAX and PAR1 to boot
+ * and send data to slave ETRAX.
+ * Used ETRAX100 DMAchannels with corresponding IRQ:
+ * PAR0 RX : DMA3 - IRQ 19
+ * PAR1 TX : DMA4 - IRQ 20
+ * IRQ 4 is used to detect ECP commands from slave ETRAX
+ *
+ * NOTE! PAR0 and PAR1 shares DMA and IRQ numbers with SER2 and SER3 
+ */
+
+
+/*
+ * Check for a network adaptor of this type, and return '0' if one exists.
+ * If dev->base_addr == 0, probe all likely locations.
+ * If dev->base_addr == 1, always return failure.
+ * If dev->base_addr == 2, allocate space for the device and return success
+ * (detachable devices only).
+ */
+static int __init
+etrax_ethernet_lpslave_init(struct net_device *dev)
+{
+	int i;
+	int anOffset = 0;
+
+	printk("Etrax/100 lpslave ethernet driver v0.3, (c) 1999 Axis Communications AB\n");
+
+	dev->base_addr = 2;
+
+	printk("%s initialized\n", dev->name);
+
+	/* make Linux aware of the new hardware  */
+
+	if (!dev) {
+		printk(KERN_WARNING "%s: dev == NULL. Should this happen?\n",
+                       cardname);
+		dev = init_etherdev(dev, sizeof(struct net_local));
+		if (!dev)
+			panic("init_etherdev failed\n");
+	}
+
+	/* setup generic handlers and stuff in the dev struct */
+
+	ether_setup(dev);
+
+	/* make room for the local structure containing stats etc */
+
+	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+	if (dev->priv == NULL)
+		return -ENOMEM;
+	memset(dev->priv, 0, sizeof(struct net_local));
+
+	/* now setup our etrax specific stuff */
+
+	dev->irq = DMA3_RX_IRQ_NBR; /* we really use DMATX as well... */
+        dev->dma = PAR0_RX_DMA_NBR;
+
+	/* fill in our handlers so the network layer can talk to us in the future */
+
+	dev->open               = e100_open;
+	dev->hard_start_xmit    = e100_send_packet;
+	dev->stop               = e100_close;
+	dev->get_stats          = e100_get_stats;
+	dev->set_multicast_list = set_multicast_list;
+	dev->set_mac_address    = e100_set_mac_address;
+        
+        /* set the default MAC address */
+
+	e100_set_mac_address(dev, &default_mac);
+
+	/* Initialise the list of Etrax DMA-descriptors */
+
+	/* Initialise receive descriptors */
+
+	for(i = 0; i < (NBR_OF_RX_DESC - 1); i++) {
+		RxDescList[i].ctrl   = 0;
+		RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
+		RxDescList[i].next   = virt_to_phys(&RxDescList[i + 1]);
+		RxDescList[i].buf    = virt_to_phys(RxBuf + anOffset);
+		RxDescList[i].status = 0;
+		RxDescList[i].hw_len = 0;
+		anOffset += RX_DESC_BUF_SIZE;
+	}
+
+	RxDescList[i].ctrl   = d_eol;
+	RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
+	RxDescList[i].next   = virt_to_phys(&RxDescList[0]);
+	RxDescList[i].buf    = virt_to_phys(RxBuf + anOffset);
+	RxDescList[i].status = 0;
+	RxDescList[i].hw_len = 0;
+
+	/* Initialise initial pointers */
+
+	myNextRxDesc = &RxDescList[0];
+	myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
+	myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
+
+        /* setup some TX descriptor data */
+
+	TxDescList[0].sw_len = 4;
+	TxDescList[0].ctrl = 0;
+	TxDescList[0].buf = virt_to_phys(&host_command);
+	TxDescList[0].next = virt_to_phys(&TxDescList[1]);
+
+	return 0;
+}
+
+/* set MAC address of the interface. called from the core after a
+ * SIOCSIFADDR ioctl, and from the bootup above.
+ */
+
+static int
+e100_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	int i;
+
+	/* remember it */
+
+        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	/* Write it to the hardware.
+	 * Note the way the address is wrapped:
+	 * *R_NETWORK_SA_0 = a0_0 | (a0_1 << 8) | (a0_2 << 16) | (a0_3 << 24);
+	 * *R_NETWORK_SA_1 = a0_4 | (a0_5 << 8);
+	 */
+
+        tx_skb = 0;
+	e100_hardware_send_packet(HOST_CMD_SETMAC, dev->dev_addr, 6);
+
+	/* show it in the log as well */
+
+	printk("%s: changed MAC to ", dev->name);
+
+	for (i = 0; i < 5; i++)
+		printk("%02X:", dev->dev_addr[i]);
+
+	printk("%02X\n", dev->dev_addr[i]);
+
+	return 0;
+}
+
+/*
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ */
+
+static int
+e100_open(struct net_device *dev)
+{
+	unsigned long flags;
+
+	/* configure the PAR0 (RX) and PAR1 (TX) ports
+	 *
+	 * perror is nAckReverse, which must be 1 at the TX side,
+         * and 0 at the RX side
+         *
+	 * select is XFlag, which must be 1 at both sides
+	 */
+#ifdef ETHDEBUG        
+        printk("Setting up PAR ports\n");
+#endif
+        *R_PAR0_CONFIG =
+          /* We do not have an external buffer, don't care */
+		IO_STATE(R_PAR0_CONFIG, ioe,     noninv)    |
+          /* Not connected, don't care */
+		IO_STATE(R_PAR0_CONFIG, iseli,   noninv)    |
+          /* iautofd is not inverted, noninv */
+		IO_STATE(R_PAR0_CONFIG, iautofd, noninv)    |
+          /* Not used in reverse direction, don't care */
+		IO_STATE(R_PAR0_CONFIG, istrb,   noninv)    |
+          /* Not connected, don't care /
+		IO_STATE(R_PAR0_CONFIG, iinit,   noninv)    |
+          /* perror is GND and reverse wants 0, noninv */
+		IO_STATE(R_PAR0_CONFIG, iperr,   noninv)    |
+          /* ack is not inverted, noninv */
+		IO_STATE(R_PAR0_CONFIG, iack,    noninv)    |
+          /* busy is not inverted, noninv */
+		IO_STATE(R_PAR0_CONFIG, ibusy,   noninv)    |
+          /* fault is not inverted, noninv */
+		IO_STATE(R_PAR0_CONFIG, ifault,  noninv)    |
+          /* select is Vcc and we want 1, noninv */
+		IO_STATE(R_PAR0_CONFIG, isel,    noninv)    |
+          /* We will run dma, enable */
+		IO_STATE(R_PAR0_CONFIG, dma, enable)        |
+          /* No run length encoding, disable */
+		IO_STATE(R_PAR0_CONFIG, rle_in, disable)    |
+          /* No run length encoding, disable */
+		IO_STATE(R_PAR0_CONFIG, rle_out, disable)   |
+          /* Enable parallel port */
+		IO_STATE(R_PAR0_CONFIG, enable, on)         |
+          /* Force mode regardless of pin status */
+		IO_STATE(R_PAR0_CONFIG, force, on)          |
+          /* We want ECP forward mode since PAR0 is RX */
+		IO_STATE(R_PAR0_CONFIG, mode, ecp_rev);       
+
+        *R_PAR1_CONFIG =
+          /* We do not have an external buffer, don't care */
+		IO_STATE(R_PAR1_CONFIG, ioe,     noninv)    |
+          
+          /* Not connected, don't care */
+		IO_STATE(R_PAR1_CONFIG, iseli,   noninv)    |
+          
+          /* HostAck must indicate data cycle, noninv */
+		IO_STATE(R_PAR1_CONFIG, iautofd, noninv)    |
+          
+          /* HostClk has no external inverter, noninv */
+		IO_STATE(R_PAR1_CONFIG, istrb,   noninv)    |
+          
+          /* Not connected, don't care */
+		IO_STATE(R_PAR1_CONFIG, iinit,   noninv)    |
+          
+          /* nAckReverse must be 1 in forward mode but is grounded, inv */ 
+		IO_STATE(R_PAR1_CONFIG, iperr,   inv)       |
+          
+          /* PeriphClk must be 1 in forward mode, noninv */
+		IO_STATE(R_PAR1_CONFIG, iack,    noninv)    |
+          
+          /* PeriphAck has no external inverter, noninv */
+		IO_STATE(R_PAR1_CONFIG, ibusy,   noninv)    |
+          
+          /* nPerihpRequest has no external inverter, noniv */
+		IO_STATE(R_PAR1_CONFIG, ifault,  noninv)    |
+          
+          /* Select is VCC and we want 1, noninv */
+		IO_STATE(R_PAR1_CONFIG, isel,    noninv)    |
+          
+          /* No EPP mode, disable */
+                IO_STATE(R_PAR1_CONFIG, ext_mode, disable)  |
+          
+          /* We will run dma, enable */
+                IO_STATE(R_PAR1_CONFIG, dma, enable)        |
+          
+          /* No run length encoding, disable */
+		IO_STATE(R_PAR1_CONFIG, rle_in, disable)    |
+          
+          /* No run length encoding, disable */
+		IO_STATE(R_PAR1_CONFIG, rle_out, disable)   |
+          
+          /* Enable parallel port */
+		IO_STATE(R_PAR1_CONFIG, enable, on)         |
+          
+          /* Force mode regardless of pin status */
+		IO_STATE(R_PAR1_CONFIG, force, on)          |
+          
+          /* We want ECP forward mode since PAR1 is TX */
+	 	IO_STATE(R_PAR1_CONFIG, mode, ecp_fwd);        
+
+        /* Setup time of value * 160 + 20 ns == 180 ns below */
+        *R_PAR1_DELAY = IO_FIELD(R_PAR1_DELAY, setup, 1);  
+
+        *R_PAR1_CTRL = 0;
+
+        while ((((*R_PAR1_STATUS)&0xE000) >> 13) != 5); /* Wait for ECP_FWD mode */
+#ifdef ETHDEBUG
+        dump_parport_status();
+#endif
+        
+        /* make sure ECP irq is acked when we enable it below */
+
+	(void)*R_PAR0_STATUS_DATA;
+	(void)*R_PAR1_STATUS_DATA;
+
+	/* Reset and wait for the DMA channels */
+
+        RESET_DMA(4); /* PAR1_TX_DMA_NBR */
+	RESET_DMA(3); /* PAR0_RX_DMA_NBR */
+	WAIT_DMA(4);  
+	WAIT_DMA(3);
+        
+        /* boot the slave Etrax, by sending code on PAR1.
+	 * do this before we start up the IRQ handlers and stuff,
+	 * beacuse we simply poll for completion in boot_slave.
+	 */
+        
+	boot_slave(&e100lpslaveprog);
+
+	/* allocate the irq corresponding to the receiving DMA */
+
+	if (request_irq(DMA3_RX_IRQ_NBR, e100rx_interrupt, 0,
+			cardname, (void *)dev)) {
+          printk("Failed to allocate DMA3_RX_IRQ_NBR\n");
+		goto grace_exit;
+	}
+
+	/* allocate the irq corresponding to the transmitting DMA */
+
+	if (request_irq(DMA4_TX_IRQ_NBR, e100tx_interrupt, 0,
+			cardname, (void *)dev)) {
+          printk("Failed to allocate DMA4_TX_IRQ_NBR\n");
+          goto grace_exit;
+	}
+        
+        /* allocate the irq used for detecting ECP commands on the RX port (PAR0) */
+
+	if (request_irq(PAR0_ECP_IRQ_NBR, ecp_interrupt, 0,
+			cardname, (void *)dev)) {
+          printk("Failed to allocate PAR0_ECP_IRQ_NBR\n");
+          grace_exit:          
+                free_irq(PAR0_ECP_IRQ_NBR, (void *)dev);
+                free_irq(DMA4_TX_IRQ_NBR, (void *)dev);
+		free_irq(DMA3_RX_IRQ_NBR, (void *)dev);
+                
+		return -EAGAIN;
+	}
+
+#if 0
+        /* We are not allocating DMA since DMA4 is reserved for 'cascading'
+         * and will always fail with the current dma.c
+         */
+        
+	/*
+	 * Always allocate the DMA channels after the IRQ,
+	 * and clean up on failure.
+	 */
+
+	if(request_dma(PAR0_RX_DMA_NBR, cardname)) {
+          printk("Failed to allocate PAR0_RX_DMA_NBR\n");
+		goto grace_exit;
+	}
+
+	if(request_dma(PAR1_TX_DMA_NBR, cardname)) {
+          printk("Failed to allocate PAR1_TX_DMA_NBR\n");
+	grace_exit:
+		/* this will cause some 'trying to free free irq' but what the heck... */
+
+		free_dma(PAR1_TX_DMA_NBR);
+                free_dma(PAR0_RX_DMA_NBR);
+                free_irq(PAR0_ECP_IRQ_NBR, (void *)dev);
+                free_irq(DMA4_TX_IRQ_NBR, (void *)dev);
+		free_irq(DMA3_RX_IRQ_NBR, (void *)dev);
+		
+		return -EAGAIN;
+	}
+#endif
+        
+#ifdef ETHDEBUG
+        printk("Par port IRQ and DMA allocated\n");
+#endif
+	save_flags(flags);
+	cli();
+
+	/* enable the irq's for PAR0/1 DMA */
+
+	*R_IRQ_MASK2_SET =
+		IO_STATE(R_IRQ_MASK2_SET, dma3_eop, set) |
+		IO_STATE(R_IRQ_MASK2_SET, dma4_descr, set);
+
+        *R_IRQ_MASK0_SET =
+		IO_STATE(R_IRQ_MASK0_SET, par0_ecp_cmd, set);
+
+	tx_skb = 0;
+
+	/* make sure the irqs are cleared */
+
+	*R_DMA_CH3_CLR_INTR = IO_STATE(R_DMA_CH3_CLR_INTR, clr_eop, do);
+	*R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
+
+        /* Write the MAC address to the slave HW */
+	udelay(5000);
+	e100_hardware_send_packet(HOST_CMD_SETMAC, dev->dev_addr, 6);
+        
+	/* make sure the rec and transmit error counters are cleared */
+
+	(void)*R_REC_COUNTERS;  /* dummy read */
+	(void)*R_TR_COUNTERS;   /* dummy read */
+
+	/* start the receiving DMA channel so we can receive packets from now on */
+
+	*R_DMA_CH3_FIRST = virt_to_phys(myNextRxDesc);
+	*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, start);
+
+	restore_flags(flags);
+	
+	/* We are now ready to accept transmit requeusts from
+	 * the queueing layer of the networking.
+	 */
+#ifdef ETHDEBUG
+        printk("Starting slave network transmit queue\n");
+#endif
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static void 
+e100_reset_tranceiver(void)
+{
+  /* To do: Reboot and setup slave Etrax */
+}
+
+/* Called by upper layers if they decide it took too long to complete
+ * sending a packet - we need to reset and stuff.
+ */
+
+static void
+e100_tx_timeout(struct net_device *dev)
+{
+	struct net_local *np = (struct net_local *)dev->priv;
+
+	printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
+	       tx_done(dev) ? "IRQ problem" : "network cable problem");
+	
+	/* remember we got an error */
+	
+	np->stats.tx_errors++; 
+	
+	/* reset the TX DMA in case it has hung on something */
+	
+	RESET_DMA(4);
+	WAIT_DMA(4);
+	
+	/* Reset the tranceiver. */
+	
+	e100_reset_tranceiver();
+	
+	/* and get rid of the packet that never got an interrupt */
+	
+	dev_kfree_skb(tx_skb);
+	tx_skb = 0;
+	
+	/* tell the upper layers we're ok again */
+	
+	netif_wake_queue(dev);
+}
+
+
+/* This will only be invoked if the driver is _not_ in XOFF state.
+ * What this means is that we need not check it, and that this
+ * invariant will hold if we make sure that the netif_*_queue()
+ * calls are done at the proper times.
+ */
+
+static int
+e100_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_local *np = (struct net_local *)dev->priv;
+	int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+	unsigned char *buf = skb->data;
+	
+#ifdef ETHDEBUG
+        unsigned char *temp_data_ptr = buf;
+        int i;
+        
+	printk("Sending a packet of length %d:\n", length);
+	/* dump the first bytes in the packet */
+	for(i = 0; i < 8; i++) {
+		printk("%d: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", i * 8,
+		       temp_data_ptr[0],temp_data_ptr[1],temp_data_ptr[2],
+                       temp_data_ptr[3],temp_data_ptr[4],temp_data_ptr[5],
+                       temp_data_ptr[6],temp_data_ptr[7]);
+		temp_data_ptr += 8;
+	}
+#endif
+	spin_lock_irq(&np->lock);  /* protect from tx_interrupt */
+
+	tx_skb = skb; /* remember it so we can free it in the tx irq handler later */
+	dev->trans_start = jiffies;
+	
+	e100_hardware_send_packet(HOST_CMD_SENDPACK, buf, length);
+
+	/* this simple TX driver has only one send-descriptor so we're full
+	 * directly. If this had a send-ring instead, we would only do this if
+	 * the ring got full.
+	 */
+
+	netif_stop_queue(dev);
+        
+	spin_unlock_irq(&np->lock);
+
+	return 0;
+}
+
+/*
+ * The typical workload of the driver:
+ *   Handle the network interface interrupts.
+ */
+
+static void
+e100rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	unsigned long irqbits = *R_IRQ_MASK2_RD;
+        
+	if(irqbits & IO_STATE(R_IRQ_MASK2_RD, dma3_eop, active)) {
+
+		/* acknowledge the eop interrupt */
+
+		*R_DMA_CH3_CLR_INTR = IO_STATE(R_DMA_CH3_CLR_INTR, clr_eop, do);
+
+		/* check if one or more complete packets were indeed received */
+
+		while(*R_DMA_CH3_FIRST != virt_to_phys(myNextRxDesc)) {
+			/* Take out the buffer and give it to the OS, then
+			 * allocate a new buffer to put a packet in.
+			 */
+			e100_rx(dev);
+			((struct net_local *)dev->priv)->stats.rx_packets++;
+			/* restart/continue on the channel, for safety */
+			*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, restart);
+			/* clear dma channel 3 eop/descr irq bits */
+			*R_DMA_CH3_CLR_INTR =
+				IO_STATE(R_DMA_CH3_CLR_INTR, clr_eop, do) |
+				IO_STATE(R_DMA_CH3_CLR_INTR, clr_descr, do);
+			
+			/* now, we might have gotten another packet
+			   so we have to loop back and check if so */
+		}
+	}
+}
+
+/* the transmit dma channel interrupt
+ *
+ * this is supposed to free the skbuff which was pending during transmission,
+ * and inform the kernel that we can send one more buffer
+ */
+
+static void
+e100tx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	unsigned long irqbits = *R_IRQ_MASK2_RD;
+	struct net_local *np = (struct net_local *)dev->priv;
+
+#ifdef ETHDEBUG
+        printk("We got tx interrupt\n");
+#endif
+	/* check for a dma4_eop interrupt */
+	if(irqbits & IO_STATE(R_IRQ_MASK2_RD, dma4_descr, active)) {
+		/* This protects us from concurrent execution of
+		 * our dev->hard_start_xmit function above.
+		 */
+
+		spin_lock(&np->lock);
+		
+		/* acknowledge the eop interrupt */
+                
+		*R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
+
+                /* skip *R_DMA_CH4_FIRST == 0 test since we use d_wait... */
+		if(tx_skb) {
+
+			np->stats.tx_bytes += tx_skb->len;
+			np->stats.tx_packets++;
+			/* dma is ready with the transmission of the data in tx_skb, so now we can release the skb memory */
+			dev_kfree_skb_irq(tx_skb);
+			tx_skb = 0;
+			netif_wake_queue(dev);
+		} else {
+			printk(KERN_WARNING "%s: tx weird interrupt\n",
+                               cardname);
+		}
+
+		spin_unlock(&np->lock);
+	}
+}
+
+static void
+ecp_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct net_local *lp = (struct net_local *)dev->priv;
+	unsigned long temp, irqbits = *R_IRQ_MASK0_RD;
+
+        /* check for ecp irq */
+	if(irqbits & IO_MASK(R_IRQ_MASK0_RD, par0_ecp_cmd)) { 
+		/* acknowledge by reading the bit */
+		temp = *R_PAR0_STATUS_DATA;
+		/* force an EOP on the incoming channel, so we'll get an rx interrupt */
+		*R_SET_EOP = IO_STATE(R_SET_EOP, ch3_eop, set);
+	}
+}
+
+/* We have a good packet(s), get it/them out of the buffers. */
+static void
+e100_rx(struct net_device *dev)
+{
+	struct sk_buff *skb;
+	int length=0;
+	int i;
+	struct net_local *np = (struct net_local *)dev->priv;
+	struct etrax_dma_descr *mySaveRxDesc = myNextRxDesc;
+	unsigned char *skb_data_ptr;
+
+	/* If the packet is broken down in many small packages then merge
+	 * count how much space we will need to alloc with skb_alloc() for
+	 * it to fit.
+	 */
+
+	while (!(myNextRxDesc->status & d_eop)) {
+		length += myNextRxDesc->sw_len; /* use sw_len for the first descs */
+		myNextRxDesc->status = 0;
+		myNextRxDesc = phys_to_virt(myNextRxDesc->next);
+	}
+
+	length += myNextRxDesc->hw_len; /* use hw_len for the last descr */
+
+#ifdef ETHDEBUG
+	printk("Got a packet of length %d:\n", length);
+	/* dump the first bytes in the packet */
+	skb_data_ptr = (unsigned char *)phys_to_virt(mySaveRxDesc->buf);
+	for(i = 0; i < 8; i++) {
+		printk("%d: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", i * 8,
+		       skb_data_ptr[0],skb_data_ptr[1],skb_data_ptr[2],skb_data_ptr[3],
+		       skb_data_ptr[4],skb_data_ptr[5],skb_data_ptr[6],skb_data_ptr[7]);
+		skb_data_ptr += 8;
+	}
+#endif
+
+	skb = dev_alloc_skb(length - ETHER_HEAD_LEN);
+	if (!skb) {
+		np->stats.rx_errors++;
+		printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
+		       dev->name);
+		return;
+	}
+
+	skb_put(skb, length - ETHER_HEAD_LEN);        /* allocate room for the packet body */
+	skb_data_ptr = skb_push(skb, ETHER_HEAD_LEN); /* allocate room for the header */
+
+#ifdef ETHDEBUG
+	printk("head = 0x%x, data = 0x%x, tail = 0x%x, end = 0x%x\n",
+	       skb->head, skb->data, skb->tail, skb->end);
+	printk("copying packet to 0x%x.\n", skb_data_ptr);
+#endif
+
+	/* this loop can be made using max two memcpy's if optimized */
+
+	while(mySaveRxDesc != myNextRxDesc) {
+		memcpy(skb_data_ptr, phys_to_virt(mySaveRxDesc->buf),
+		       mySaveRxDesc->sw_len);
+		skb_data_ptr += mySaveRxDesc->sw_len;
+		mySaveRxDesc = phys_to_virt(mySaveRxDesc->next);
+	}
+
+	memcpy(skb_data_ptr, phys_to_virt(mySaveRxDesc->buf),
+	       mySaveRxDesc->hw_len);
+
+	skb->dev = dev;
+	skb->protocol = eth_type_trans(skb, dev);
+
+	/* Send the packet to the upper layers */
+
+	netif_rx(skb);
+
+	/* Prepare for next packet */
+
+	myNextRxDesc->status = 0;
+	myPrevRxDesc = myNextRxDesc;
+	myNextRxDesc = phys_to_virt(myNextRxDesc->next);
+
+	myPrevRxDesc->ctrl |= d_eol;
+	myLastRxDesc->ctrl &= ~d_eol;
+	myLastRxDesc = myPrevRxDesc;
+
+	return;
+}
+
+/* The inverse routine to net_open(). */
+static int
+e100_close(struct net_device *dev)
+{
+	struct net_local *np = (struct net_local *)dev->priv;
+
+	printk("Closing %s.\n", dev->name);
+
+	netif_stop_queue(dev);
+
+	*R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, par0_ecp_cmd, clr);
+
+	*R_IRQ_MASK2_CLR =
+		IO_STATE(R_IRQ_MASK2_CLR, dma3_eop, clr) |
+		IO_STATE(R_IRQ_MASK2_CLR, dma4_descr, clr);	
+
+	/* Stop the receiver and the transmitter */
+
+	RESET_DMA(3);
+	RESET_DMA(4);
+
+	/* Flush the Tx and disable Rx here. */
+
+	free_irq(DMA3_RX_IRQ_NBR, (void *)dev);
+	free_irq(DMA4_TX_IRQ_NBR, (void *)dev);
+	free_irq(PAR0_ECP_IRQ_NBR, (void *)dev);
+
+	free_dma(PAR1_TX_DMA_NBR);
+	free_dma(PAR0_RX_DMA_NBR);
+
+	/* Update the statistics here. */
+
+	update_rx_stats(&np->stats);
+	update_tx_stats(&np->stats);
+
+	return 0;
+}
+
+static void
+update_rx_stats(struct net_device_stats *es)
+{
+	unsigned long r = *R_REC_COUNTERS;
+	/* update stats relevant to reception errors */
+	es->rx_fifo_errors += r >> 24;            /* fifo overrun */
+	es->rx_crc_errors += r & 0xff;            /* crc error */
+	es->rx_frame_errors += (r >> 8) & 0xff;   /* alignment error */
+	es->rx_length_errors += (r >> 16) & 0xff; /* oversized frames */
+}
+
+static void
+update_tx_stats(struct net_device_stats *es)
+{
+	unsigned long r = *R_TR_COUNTERS;
+	/* update stats relevant to transmission errors */
+	es->collisions += (r & 0xff) + ((r >> 8) & 0xff); /* single_col + multiple_col */
+	es->tx_errors += (r >> 24) & 0xff; /* deferred transmit frames */
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *
+e100_get_stats(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+
+	update_rx_stats(&lp->stats);
+	update_tx_stats(&lp->stats);
+
+	return &lp->stats;
+}
+
+/*
+ * Set or clear the multicast filter for this adaptor.
+ * num_addrs == -1	Promiscuous mode, receive all packets
+ * num_addrs == 0	Normal mode, clear multicast list
+ * num_addrs > 0	Multicast mode, receive normal and MC packets,
+ *			and do best-effort filtering.
+ */
+static void
+set_multicast_list(struct net_device *dev)
+{
+  /* To do */
+}
+
+void
+e100_hardware_send_packet(unsigned long hostcmd, char *buf, int length)
+{
+  static char bogus_ecp[] = { 42, 42 };
+  int i;
+  
+
+#ifdef ETHDEBUG
+	printk("e100 send pack, buf 0x%x len %d\n", buf, length);
+#endif
+        
+        host_command = hostcmd;
+
+	/* Configure the tx dma descriptor. Desc 0 is already configured.*/
+
+        TxDescList[1].sw_len = length;
+	/* bug workaround - etrax100 needs d_wait on the descriptor _before_
+	 * a descriptor containing an ECP command
+	 */
+	TxDescList[1].ctrl = d_wait;
+	TxDescList[1].buf = virt_to_phys(buf);
+	TxDescList[1].next = virt_to_phys(&TxDescList[2]);
+
+        /* append the ecp dummy descriptor - its only purpose is to 
+	 * make the receiver generate an irq due to the ecp command
+	 * so the receiver knows where packets end
+	 */
+
+	TxDescList[2].sw_len = 1;
+	TxDescList[2].ctrl = d_ecp | d_eol | d_int;
+	TxDescList[2].buf = virt_to_phys(bogus_ecp);
+        
+
+	/* setup the dma channel and start it */
+
+        *R_DMA_CH4_FIRST = virt_to_phys(TxDescList);
+	*R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, start);
+        
+#ifdef ETHDEBUG         
+         printk("done\n");
+#endif
+}
+
+/* send a chunk of code to the slave chip to boot it. */
+
+static void
+boot_slave(unsigned char *code)
+{
+  int i;
+
+#ifdef ETHDEBUG
+	printk("  booting slave ETRAX...\n");
+#endif
+        *R_PORT_PB_DATA = 0x7F; /* Reset slave */
+        udelay(15); /* Time enough to reset WAN tranciever */
+        *R_PORT_PB_DATA = 0xFF; /* Reset slave */
+
+	/* configure the tx dma data descriptor */
+
+	TxDescList[1].sw_len = ETRAX_PAR_BOOT_LENGTH;
+	TxDescList[1].ctrl = d_eol | d_int; 
+                                                      
+	TxDescList[1].buf = virt_to_phys(code);
+        /*TxDescList[1].buf = code;*/
+	TxDescList[1].next = 0;
+        
+        /* setup the dma channel and start it */
+ 	*R_DMA_CH4_FIRST = virt_to_phys(&TxDescList[1]);
+	*R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, start);
+
+	/* wait for completion */
+	while(!(*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma4_descr)));
+
+	/* ack the irq */
+
+	*R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do);
+
+#if 0
+        /* manual transfer of boot code - requires dma turned off */
+        for (i=0; i<ETRAX_PAR_BOOT_LENGTH; i++)
+        {
+          printk("  sending byte: %u value: %x\n",i,code[i]);
+          while (((*R_PAR1_STATUS)&0x02) == 0); /* Wait while tr_rdy is busy*/
+          *R_PAR1_CTRL_DATA = code[i];
+        }
+#endif
+
+#ifdef ETHDEBUG
+	printk("  done\n");
+#endif
+}
+
+#ifdef ETHDEBUG
+/* debug code to check the current status of PAR1 */
+static void
+dump_parport_status(void)
+{
+  unsigned long temp;
+  
+  printk("Parport1 status:\n");
+  
+  temp = (*R_PAR1_STATUS)&0xE000;
+  temp = temp >> 13;
+  printk("Reg mode: %u (ecp_fwd(5), ecp_rev(6))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x1000;
+  temp = temp >> 12;
+  printk("Reg perr: %u (ecp_rev(0))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x0800;
+  temp = temp >> 11;
+  printk("Reg ack: %u (inactive (1), active (0))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x0400;
+  temp = temp >> 10;
+  printk("Reg busy: %u (inactive (0), active (1))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x0200;
+  temp = temp >> 9;
+  printk("Reg fault: %u (inactive (1), active (0))\n", temp);
+  
+  temp = (*R_PAR1_STATUS)&0x0100;
+  temp = temp >> 8;
+  printk("Reg sel: %u (inactive (0), active (1), xflag(1))\n", temp);
+
+  temp = (*R_PAR1_STATUS)&0x02;
+  temp = temp >> 1;
+  printk("Reg tr_rdy: %u (busy (0), ready (1))\n", temp);
+
+}
+#endif /* ETHDEBUG */
+
+static struct net_device dev_etrax_slave_ethernet;
+
+static int
+etrax_init_module(void)
+{
+	struct net_device *d = &dev_etrax_slave_ethernet;
+
+	d->init = etrax_ethernet_lpslave_init;
+
+	if(register_netdev(d) == 0)
+		return 0;
+	else
+		return -ENODEV;
+}
+
+module_init(etrax_init_module);
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/parport.c linux/arch/cris/drivers/parport.c
--- v2.4.6/linux/arch/cris/drivers/parport.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/parport.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: parport.c,v 1.4 2001/04/06 13:04:02 hugo Exp $
+/* $Id: parport.c,v 1.5 2001/05/09 12:38:42 johana Exp $
  * 
  * Elinux parallel port driver
  * NOTE!
@@ -501,8 +501,8 @@
 
 #ifdef CONFIG_ETRAX_PARALLEL_PORT0
 #ifdef CONFIG_ETRAX_PAR0_DMA
-	RESET_DMA(2);
-	WAIT_DMA(2);
+	RESET_DMA(PAR0_TX_DMA_NBR);
+	WAIT_DMA(PAR0_TX_DMA_NBR);
 #ifdef CONFIG_ETRAX_SERIAL_PORT2
 	printk(" Warning - DMA clash with ser2!\n");
 #endif /* SERIAL_PORT2 */
@@ -511,8 +511,8 @@
 
 #ifdef CONFIG_ETRAX_PARALLEL_PORT1
 #ifdef CONFIG_ETRAX_PAR1_DMA
-	RESET_DMA(4);
-	WAIT_DMA(4);
+	RESET_DMA(PAR1_TX_DMA_NBR);
+	WAIT_DMA(PAR1_TX_DMA_NBR);
 #ifdef CONFIG_ETRAX_SERIAL_PORT3
 	printk(" Warning - DMA clash with ser3!\n");
 #endif /* SERIAL_PORT3 */
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/serial.c linux/arch/cris/drivers/serial.c
--- v2.4.6/linux/arch/cris/drivers/serial.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/serial.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: serial.c,v 1.12 2001/04/19 12:23:07 bjornw Exp $
+/* $Id: serial.c,v 1.13 2001/05/09 12:40:31 johana Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
@@ -7,6 +7,9 @@
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.13  2001/05/09 12:40:31  johana
+ * Use DMA_NBR and IRQ_NBR defines from dma.h and irq.h
+ *
  * Revision 1.12  2001/04/19 12:23:07  bjornw
  * CONFIG_RS485 -> CONFIG_ETRAX_RS485
  *
@@ -199,7 +202,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.12 $";
+static char *serial_version = "$Revision: 1.13 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -495,7 +498,6 @@
 #endif
 
 #ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
-#define TIMER1_IRQ_NBR 3
 
 /* clock select 10 for timer 1 gives 230400 Hz */
 #define FASTTIMER_SELECT (10)
@@ -3049,32 +3051,32 @@
 #ifndef CONFIG_SVINTO_SIM
 	/* Not needed in simulator.  May only complicate stuff. */
 	/* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */
-	if(request_irq(22, tr_interrupt, SA_INTERRUPT, "serial 0 dma tr", NULL))
+	if(request_irq(SER0_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 0 dma tr", NULL))
 		panic("irq22");
-	if(request_irq(23, rec_interrupt, SA_INTERRUPT, "serial 0 dma rec", NULL))
+	if(request_irq(SER0_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 0 dma rec", NULL))
 		panic("irq23");
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
-	if(request_irq(8, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
+	if(request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
 		panic("irq8");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT1
-	if(request_irq(24, tr_interrupt, SA_INTERRUPT, "serial 1 dma tr", NULL))
+	if(request_irq(SER1_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 1 dma tr", NULL))
 		panic("irq24");
-	if(request_irq(25, rec_interrupt, SA_INTERRUPT, "serial 1 dma rec", NULL))
+	if(request_irq(SER1_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 1 dma rec", NULL))
 		panic("irq25");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT2
 	/* DMA Shared with par0 (and SCSI0 and ATA) */
-	if(request_irq(18, tr_interrupt, SA_SHIRQ, "serial 2 dma tr", NULL))
+	if(request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 2 dma tr", NULL))
 		panic("irq18");
-	if(request_irq(19, rec_interrupt, SA_SHIRQ, "serial 2 dma rec", NULL))
+	if(request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 2 dma rec", NULL))
 		panic("irq19");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT3
 	/* DMA Shared with par1 (and SCSI1 and Extern DMA 0) */
-	if(request_irq(20, tr_interrupt, SA_SHIRQ, "serial 3 dma tr", NULL))
+	if(request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 3 dma tr", NULL))
 		panic("irq20");
-	if(request_irq(21, rec_interrupt, SA_SHIRQ, "serial 3 dma rec", NULL))
+	if(request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 3 dma rec", NULL))
 		panic("irq21");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
diff -u --recursive --new-file v2.4.6/linux/arch/cris/drivers/usb-host.c linux/arch/cris/drivers/usb-host.c
--- v2.4.6/linux/arch/cris/drivers/usb-host.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/usb-host.c	Wed Jul  4 11:50:39 2001
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2001 Axis Communications AB.
  *
- * $Id: usb-host.c,v 1.8 2001/02/27 13:52:48 bjornw Exp $
+ * $Id: usb-host.c,v 1.9 2001/05/09 12:54:12 johana Exp $
  *
  */
 
@@ -23,17 +23,18 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/svinto.h>
 
 #include <linux/usb.h>
 #include "usb-host.h"
 
-#define ETRAX_USB_HC_IRQ 31
-#define ETRAX_USB_RX_IRQ 25
-#define ETRAX_USB_TX_IRQ 24
+#define ETRAX_USB_HC_IRQ USB_HC_IRQ_NBR
+#define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR
+#define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR
 
-static const char *usb_hcd_version = "$Revision: 1.8 $";
+static const char *usb_hcd_version = "$Revision: 1.9 $";
 
 #undef KERN_DEBUG
 #define KERN_DEBUG ""
@@ -2034,21 +2035,21 @@
 		OK (4);		/* hub power ** */
 		
 	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
-                if (wIndex == 1) {
+		if (wIndex == 1) {
 			*((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_1);
 			*((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_1);
-                }
-                else if (wIndex == 2) {
+		}
+		else if (wIndex == 2) {
 			*((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_2);
 			*((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_2);
-                }
-                else {
+		}
+		else {
 			dbg_rh("RH_GET_STATUS whith invalid wIndex !!");
 			OK(0);
-                }
+		}
 		
-                OK(4);
-                
+		OK(4);
+
 	case RH_CLEAR_FEATURE | RH_ENDPOINT:
 		switch (wValue) {
 		case (RH_ENDPOINT_STALL):
@@ -2114,16 +2115,16 @@
 			OK (0);	/* port power ** */
 		case (RH_C_PORT_CONNECTION):
 			
-                        if (wIndex == 1) {
+			if (wIndex == 1) {
 				hc->rh.wPortChange_1 &= ~(1 << RH_PORT_CONNECTION);
-                        }
-                        else if (wIndex == 2) {
+			}
+			else if (wIndex == 2) {
 				hc->rh.wPortChange_2 &= ~(1 << RH_PORT_CONNECTION);
-                        }
-                        else {
+			}
+			else {
 				dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_CONNECTION "
 				       "with invalid wIndex == %d!!", wIndex);
-                        }
+			}
 
 			OK (0);
 		case (RH_C_PORT_ENABLE):
@@ -2182,7 +2183,7 @@
 
 			OK (0);
 		case (RH_PORT_RESET):
-                        if (wIndex == 1) {
+			if (wIndex == 1) {
 				int port1_retry;
 				
 			port1_redo:
@@ -2205,8 +2206,8 @@
 				   not even schedule() works !!! WHY ?? */
 
 				udelay(15000);
-                        }
-                        else if (wIndex == 2) {
+			}
+			else if (wIndex == 2) {
 				int port2_retry;
 				
 			port2_redo:
@@ -2229,7 +2230,7 @@
 				   not even schedule() works !!! WHY ?? */
 
 				udelay(15000);
-                        }
+			}
 
 			/* Try to bring the HC into running state */
 			*R_USB_COMMAND =
@@ -2237,21 +2238,21 @@
 			
 			nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
 			
-                        dbg_rh("...Done");
-                        OK(0);
-                        
+			dbg_rh("...Done");
+			OK(0);
+
 		case (RH_PORT_POWER):
 			OK (0);	/* port power ** */
 		case (RH_PORT_ENABLE):
 			/* There is no rh port enable command in the Etrax USB interface!!!! */
 			OK (0);
-                        
+
 		}
 		break;
 		
 	case RH_SET_ADDRESS:
 		hc->rh.devnum = wValue;
-                dbg_rh("RH address set to: %d", hc->rh.devnum);
+		dbg_rh("RH address set to: %d", hc->rh.devnum);
 		OK (0);
 		
 	case RH_GET_DESCRIPTOR:
@@ -2324,7 +2325,7 @@
 	etrax_usb_bus = bus = usb_alloc_bus(&etrax_usb_device_operations);
 	hc->bus = bus;
 	bus->hcpriv = hc;
-        
+
 	/* Initalize RH to the default address.
 	   And make sure that we have no status change indication */
 	hc->rh.numports = 2;  /* The RH has two ports */
@@ -2339,7 +2340,7 @@
 	/* Initialize the intr-traffic flags */
 	hc->intr.sleeping = 0;
 	hc->intr.wq = NULL;
-        
+
 	/* Initially all ep's are free except ep 0 */
 	ep_usage_bitmask = 0;
 	set_bit(0, (void *)&ep_usage_bitmask);
@@ -2349,20 +2350,20 @@
 
 	/* This code should really be moved */
 
-        if (request_dma(8, "ETRAX 100LX built-in USB (Tx)")) {
+	if (request_dma(USB_TX_DMA_NBR, "ETRAX 100LX built-in USB (Tx)")) {
 		err("Could not allocate DMA ch 8 for USB");
 		etrax_usb_hc_cleanup();
 		DBFEXIT;
 		return -1;
 	}
 	
-	if (request_dma(9, "ETRAX 100LX built-in USB (Rx)")) {
+	if (request_dma(USB_RX_DMA_NBR, "ETRAX 100LX built-in USB (Rx)")) {
 		err("Could not allocate DMA ch 9 for USB");
 		etrax_usb_hc_cleanup();
 		DBFEXIT;
 		return -1;
 	}	
-#if 0  /* Moved to head.S */        
+#if 0  /* Moved to head.S */
 	*R_GEN_CONFIG = genconfig_shadow =
 		(genconfig_shadow & ~(IO_MASK(R_GEN_CONFIG, usb1) |
 				      IO_MASK(R_GEN_CONFIG, usb2) |
@@ -2490,8 +2491,8 @@
 	free_irq(ETRAX_USB_RX_IRQ, NULL);
 	free_irq(ETRAX_USB_TX_IRQ, NULL);
 
-	free_dma(8);
-	free_dma(9);
+	free_dma(USB_TX_DMA_NBR);
+	free_dma(USB_RX_DMA_NBR);
 	usb_deregister_bus(etrax_usb_bus);
 
 	DBFEXIT;
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/Makefile linux/arch/cris/kernel/Makefile
--- v2.4.6/linux/arch/cris/kernel/Makefile	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/Makefile	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.4 2001/04/17 13:58:39 orjanf Exp $
+# $Id: Makefile,v 1.5 2001/05/15 05:10:00 hp Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -19,6 +19,11 @@
 	   debugport.o semaphore.o
 
 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
+
+entry.o: entryoffsets.s
+
+entryoffsets.s: entryoffsets.c
+	$(CC) $(CFLAGS) -S -c $<
 
 clean:
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
--- v2.4.6/linux/arch/cris/kernel/entry.S	Sun May 20 12:11:38 2001
+++ linux/arch/cris/kernel/entry.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.22 2001/04/17 13:58:39 orjanf Exp $
+/* $Id: entry.S,v 1.27 2001/05/29 11:25:27 markusl Exp $
  *
  *  linux/arch/cris/entry.S
  *
@@ -7,6 +7,21 @@
  *  Authors:	Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: entry.S,v $
+ *  Revision 1.27  2001/05/29 11:25:27  markusl
+ *  In case of "spurious_interrupt", do hard_reset instead of hanging system in a loop...
+ *
+ *  Revision 1.26  2001/05/15 15:46:03  bjornw
+ *  Include config.h now that we use some CONFIG_ options
+ *
+ *  Revision 1.25  2001/05/15 05:38:47  hp
+ *  Tweaked code in _ret_from_sys_call
+ *
+ *  Revision 1.24  2001/05/15 05:27:49  hp
+ *  Save r9 in r1 over function call rather than on stack.
+ *
+ *  Revision 1.23  2001/05/15 05:10:00  hp
+ *  Generate entry.S structure offsets from C
+ *
  *  Revision 1.22  2001/04/17 13:58:39  orjanf
  *  * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
  *
@@ -140,39 +155,21 @@
 	
 LENOSYS = 38
 
-	;; offsets into the task_struct (found at sp aligned to THREAD_SIZE, 8192)
-	;; linux/sched.h
-	
-LTASK_SIGPENDING  =  8
-LTASK_NEEDRESCHED = 20
-LTASK_PTRACE      = 24
-LTASK_PID         = 105
+	;; Get offsets into various structs.
+	.include "entryoffsets.s"
 
-	;; process bits for ptrace
+	;; process bits for ptrace.  FIXME: Should be in a header file.
 
 PT_TRACESYS_BIT	  = 1
 
-	;; some pt_regs offsets (from ptrace.h)
-	
-LORIG_R10	= 4
-LR13		= 8
-LR12		= 12
-LR11		= 16
-LR10		= 20
-LR9		= 24
-LMOF		= 64
-LDCCR		= 68
-LSRP		= 72
-LIRP		= 76
-
 	;; below are various parts of system_call which are not in the fast-path
 	
 	;; handle software irqs
 				
 handle_softirq:
-	push	r9
+	move.d	r9,r1
 	jsr	_do_softirq		; call the C routine for softirq handling
-	pop	r9
+	move.d	r1,r9
 
 	;; fall-through
 	
@@ -188,11 +185,10 @@
 
 reschedule:
 	;; keep r9 intact
-	push	r9
+	move.d	r9,r1
 	jsr	_schedule
-	pop	r9
 	ba	_ret_from_sys_call
-	nop
+	move.d	r1,r9
 
 	;; return but call do_signal first
 signal_return:
@@ -275,8 +271,9 @@
 		
 	;; check if any bottom halves need service
 	
-	move.d	[_irq_stat],r0	       ; softirq_active
-	and.d	[_irq_stat+4],r0       ; softirq_mask
+	move.d	_irq_stat,r10
+	move.d	[r10+],r0	       ; softirq_active
+	and.d	[r10],r0	       ; softirq_mask
 	bne	handle_softirq
 	nop
 
@@ -378,12 +375,6 @@
 	ba	_ret_from_sys_call
 	nop
 		
-	;; from asm/processor.h, the thread_struct
-	
-LTHREAD_KSP	= 0
-LTHREAD_USP	= 4
-LTHREAD_DCCR	= 8
-	
 	;; _resume performs the actual task-switching, by switching stack pointers
 	;; input arguments: r10 = prev, r11 = next, r12 = thread offset in task struct
 	;; returns old current in r10
@@ -495,7 +486,7 @@
 _IRQ1_interrupt:
 _spurious_interrupt:	
 	di
-basse2:	ba	basse2
+	jsr _hard_reset_now
 	nop
 
 	;; this handles the case when multiple interrupts arrive at the same time
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/entryoffsets.c linux/arch/cris/kernel/entryoffsets.c
--- v2.4.6/linux/arch/cris/kernel/entryoffsets.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/kernel/entryoffsets.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,54 @@
+/* linux/arch/cris/entryoffsets.c
+ *
+ * Copyright (C) 2001 Axis Communications AB
+ *
+ * Generate structure offsets for use in entry.S.  No extra processing
+ * needed more than compiling this file to assembly code.  Horrendous
+ * assembly code will be generated, so don't look at that.
+ *
+ * Authors:	Hans-Peter Nilsson (hp@axis.com)
+ */
+
+/* There can be string constants fallout from inline functions, so we'd
+   better make sure we don't assemble anything emitted from inclusions.  */
+__asm__ (".if 0");
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <asm/processor.h>
+
+/* Exclude everything except the assembly by wrapping it in ".if 0".  */
+#undef OF
+#define OF(NAME, TYPE, MEMBER)			\
+void NAME ## _fun (void)			\
+ {						\
+  __asm__ (".endif \n"				\
+	   #NAME " = %0 \n"			\
+	   ".if 0\n"				\
+	   : : "i" (offsetof (TYPE, MEMBER)));	\
+ }
+
+/* task_struct offsets.  */
+OF (LTASK_SIGPENDING, struct task_struct, sigpending)
+OF (LTASK_NEEDRESCHED, struct task_struct, need_resched)
+OF (LTASK_PTRACE, struct task_struct, ptrace)
+OF (LTASK_PID, struct task_struct, pid)
+
+/* pt_regs offsets.  */
+OF (LORIG_R10, struct pt_regs, orig_r10)
+OF (LR13, struct pt_regs, r13)
+OF (LR12, struct pt_regs, r12)
+OF (LR11, struct pt_regs, r11)
+OF (LR10, struct pt_regs, r10)
+OF (LR9, struct pt_regs, r9)
+OF (LMOF, struct pt_regs, mof)
+OF (LDCCR, struct pt_regs, dccr)
+OF (LSRP, struct pt_regs, srp)
+OF (LIRP, struct pt_regs, irp)
+
+/* thread_struct offsets.  */
+OF (LTHREAD_KSP, struct thread_struct, ksp)
+OF (LTHREAD_USP, struct thread_struct, usp)
+OF (LTHREAD_DCCR, struct thread_struct, dccr)
+
+__asm__ (".endif");
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/head.S linux/arch/cris/kernel/head.S
--- v2.4.6/linux/arch/cris/kernel/head.S	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/head.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.29 2001/04/18 12:51:59 orjanf Exp $
+/* $Id: head.S,v 1.34 2001/05/15 07:08:14 hp Exp $
  * 
  * Head of the kernel - alter with care
  *
@@ -7,6 +7,21 @@
  * Authors:	Bjorn Wesen (bjornw@axis.com)
  * 
  * $Log: head.S,v $
+ * Revision 1.34  2001/05/15 07:08:14  hp
+ * Tweak "notice" to reflect that both r8 r9 are used
+ *
+ * Revision 1.33  2001/05/15 06:40:05  hp
+ * Put bulk of code in .text.init, data in .data.init
+ *
+ * Revision 1.32  2001/05/15 06:18:56  hp
+ * Execute review comment: s/bcc/bhs/g; s/bcs/blo/g
+ *
+ * Revision 1.31  2001/05/15 06:08:40  hp
+ * Add sentence about autodetecting the bit31-MMU-bug
+ *
+ * Revision 1.30  2001/05/15 06:00:05  hp
+ * Update comment: LOW_MAP is not forced on xsim anymore.
+ *
  * Revision 1.29  2001/04/18 12:51:59  orjanf
  * * Reverted review change regarding the use of bcs/bcc.
  * * Removed non-working LED-clearing code.
@@ -127,9 +142,9 @@
 	;; since etrax actually starts at address 2 when booting from flash, we
 	;; put a nop (2 bytes) here first so we dont accidentally skip the di
 	;;
-	;; NOTICE! The registers r8 and r9 are used as a parameter carrying
+	;; NOTICE! The registers r8 and r9 are used as parameters carrying
 	;; information from the decompressor (if the kernel was compressed). 
-	;; They should not be used in the code below until it is read.
+	;; They should not be used in the code below until read.
 	
 	nop	
 	di
@@ -143,8 +158,11 @@
 	;; temporarily map those segments linearily.
 	;;
 	;; Due to a bug in Etrax-100 LX version 1 we need to map the memory
-	;; slightly different. We also let the simulator get this mapping for now.
-	;; (The bug is that you can't remap bit 31.)
+	;; slightly different.  The bug is that you can't remap bit 31 of
+	;; an address.  Though we can check the version register for
+	;; whether the bug is present, some constants would then have to
+	;; be variables, so we don't.  The drawback is that you can "only" map
+	;; 1G per process with CONFIG_CRIS_LOW_MAP.
 
 #ifdef CONFIG_CRIS_LOW_MAP
 	move.d	0x0004b098, r0	; kseg mappings, temporary map of 0xc0->0x40
@@ -190,11 +208,18 @@
 	move.d	pc,r0
 	and.d	0x7fffffff,r0	; get rid of the non-cache bit
 	cmp.d	0x10000,r0	; arbitrary... just something above this code
-	bcs	inflash
+	blo	inflash0
 	nop
 
 	jump	inram		; enter cached ram
-	
+
+	;; Jumpgate for branches.
+inflash0:
+	jump	inflash
+
+	;; Put this in a suitable section where we can reclaim storage
+	;; after init.
+	.section ".text.init"
 inflash:
 	;; We need to initialze DRAM registers before we start using the DRAM
 
@@ -225,7 +250,7 @@
 1:	move.w	[r0+], r3
 	move.w	r3, [r1+]
 	cmp.d	r2, r1
-	bcs	1b
+	blo	1b
 	nop
 
 	;; We keep the cramfs in the flash.
@@ -271,7 +296,7 @@
 	;;  to a cramfs magic is small.. )
 	
 	cmp.d	0x0ffffff8, r9
-	bcc	no_romfs_in_flash	; r9 points outside the flash area
+	bhs	no_romfs_in_flash	; r9 points outside the flash area
 	nop
 	move.d	[r9], r0	; cramfs_super.magic
 	cmp.d	CRAMFS_MAGIC, r0
@@ -353,7 +378,7 @@
 	move.d	_end, r1
 1:	clear.d	[r0+]
 	cmp.d	r1, r0
-	bcs	1b
+	blo	1b
 	nop
 	
 #ifdef CONFIG_BLK_DEV_ETRAXIDE
@@ -575,5 +600,6 @@
 #else	
 _swapper_pg_dir = 0xc0002000
 #endif
-	
+
+	.section ".data.init"
 #include "../lib/hw_settings.S"
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/irq.c linux/arch/cris/kernel/irq.c
--- v2.4.6/linux/arch/cris/kernel/irq.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/irq.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.14 2001/04/17 13:58:39 orjanf Exp $
+/* $Id: irq.c,v 1.15 2001/06/10 11:18:46 bjornw Exp $
  *
  *	linux/arch/cris/kernel/irq.c
  *
@@ -485,3 +485,10 @@
 #endif
 
 }
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+/* Used by other archs to show/control IRQ steering during SMP */
+void init_irq_proc(void)
+{
+}
+#endif
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/process.c linux/arch/cris/kernel/process.c
--- v2.4.6/linux/arch/cris/kernel/process.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/process.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.13 2001/03/20 19:44:06 bjornw Exp $
+/* $Id: process.c,v 1.14 2001/05/29 11:27:59 markusl Exp $
  * 
  *  linux/arch/cris/kernel/process.c
  *
@@ -8,6 +8,9 @@
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: process.c,v $
+ *  Revision 1.14  2001/05/29 11:27:59  markusl
+ *  Fixed so that hard_reset_now will do reset even if watchdog wasn't enabled
+ *
  *  Revision 1.13  2001/03/20 19:44:06  bjornw
  *  Use the 7th syscall argument for regs instead of current_regs
  *
@@ -90,12 +93,21 @@
 
 /* if the watchdog is enabled, we can simply disable interrupts and go
  * into an eternal loop, and the watchdog will reset the CPU after 0.1s
+ * if on the other hand the watchdog wasn't enabled, we just enable it and wait
  */
 
 void hard_reset_now (void)
 {
 	printk("*** HARD RESET ***\n");
 	cli();
+
+#ifndef CONFIG_ETRAX_WATCHDOG
+	/* Since we dont plan to keep on reseting the watchdog,
+	   the key can be arbitrary hence three */
+	*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
+		IO_STATE(R_WATCHDOG, enable, start);
+#endif
+
 	while(1) /* waiting for RETRIBUTION! */ ;
 }
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/setup.c linux/arch/cris/kernel/setup.c
--- v2.4.6/linux/arch/cris/kernel/setup.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/setup.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.14 2001/04/03 12:54:12 starvik Exp $
+/* $Id: setup.c,v 1.16 2001/05/15 01:23:13 hp Exp $
  *
  *  linux/arch/cris/kernel/setup.c
  *
@@ -190,14 +190,10 @@
 	unsigned short cache;
 	unsigned short flags;
 } cpu_info[] = {
+	/* The first four models will never ever run this code and are
+	   only here for display.  */
 	{ "ETRAX 1",   0, 0 },
-	{ "ETRAX 2",   0, 0 },	/* Don't say it HAS_TOKENRING - there are
-				   lethal bugs in that chip that
-				   prevents T-R from ever working.
-				   Never go there, and never lead anyone
-				   into believing it can work.  BTW:
-				   Anyone working on a T-R network
-				   driver? :-) :-) :-) :-/ */
+	{ "ETRAX 2",   0, 0 },
 	{ "ETRAX 3",   0, HAS_TOKENRING },
 	{ "ETRAX 4",   0, HAS_TOKENRING | HAS_SCSI },
 	{ "Unknown",   0, 0 },
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/signal.c linux/arch/cris/kernel/signal.c
--- v2.4.6/linux/arch/cris/kernel/signal.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/signal.c	Wed Jul  4 11:50:39 2001
@@ -7,7 +7,7 @@
  *
  *  Ideas also taken from arch/arm.
  *
- *  Copyright (C) 2000 Axis Communications AB
+ *  Copyright (C) 2000, 2001 Axis Communications AB
  *
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
@@ -101,7 +101,14 @@
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
 		if (do_signal(0, &saveset, regs))
-			return -EINTR;
+			/* We will get here twice: once to call the signal
+			   handler, then again to return from the
+			   sigsuspend system call.  When calling the
+			   signal handler, R10 holds the signal number as
+			   set through do_signal.  The sigsuspend call
+			   will return with the restored value set above;
+			   always -EINTR.  */
+			return regs->r10;
 	}
 }
 
@@ -133,7 +140,14 @@
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
 		if (do_signal(0, &saveset, regs))
-			return -EINTR;
+			/* We will get here twice: once to call the signal
+			   handler, then again to return from the
+			   sigsuspend system call.  When calling the
+			   signal handler, R10 holds the signal number as
+			   set through do_signal.  The sigsuspend call
+			   will return with the restored value set above;
+			   always -EINTR.  */
+			return regs->r10;
 	}
 }
 
@@ -413,6 +427,7 @@
 
 	regs->irp = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
 	regs->srp = return_ip;                          /* what we enter LATER */
+	regs->r10 = sig;                                /* first argument is signo */
 
 	/* actually move the usp to reflect the stacked frame */
 
@@ -462,7 +477,6 @@
 		/* trampoline - the desired return ip is the retcode itself */
 		return_ip = (unsigned long)&frame->retcode;
 		/* This is movu.w __NR_sigreturn, r9; break 13; */
-		/* TODO: check byteorder */
 		err |= __put_user(0x9c5f,         (short *)(frame->retcode+0));
 		err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
 		err |= __put_user(0xe93d,         (short *)(frame->retcode+4));
@@ -477,6 +491,7 @@
 
 	regs->irp = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
 	regs->srp = return_ip;                          /* what we enter LATER */
+	regs->r10 = sig;                                /* first argument is signo */
 
 	/* actually move the usp to reflect the stacked frame */
 
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/sys_cris.c linux/arch/cris/kernel/sys_cris.c
--- v2.4.6/linux/arch/cris/kernel/sys_cris.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/kernel/sys_cris.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_cris.c,v 1.7 2001/04/17 11:52:15 orjanf Exp $
+/* $Id: sys_cris.c,v 1.9 2001/05/30 06:20:26 markusl Exp $
  *
  * linux/arch/cris/kernel/sys_cris.c
  *
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/time.c linux/arch/cris/kernel/time.c
--- v2.4.6/linux/arch/cris/kernel/time.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/time.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.4 2000/10/17 14:44:58 bjornw Exp $
+/* $Id: time.c,v 1.6 2001/05/29 11:29:42 markusl Exp $
  *
  *  linux/arch/cris/kernel/time.c
  *
@@ -83,12 +83,9 @@
 	 * avoiding timer inconsistencies (they are rare, but they happen)...
 	 * there are three kinds of problems that must be avoided here:
 	 *  1. the timer counter underflows
-	 *  2. hardware problem with the timer, not giving us continuous time,
-	 *     the counter does small "jumps" upwards on some Pentium systems,
-	 *     thus causes time warps
-	 *  3. we are after the timer interrupt, but the bottom half handler
+	 *  2. we are after the timer interrupt, but the bottom half handler
 	 *     hasn't executed yet.
-	 */
+ */
 	if( jiffies_t == jiffies_p ) {
 		if( count > count_p ) {
 		}
@@ -195,7 +192,7 @@
 	return retval;
 }
 
-/* Except from the Etrax100 HSDD about the built-in watchdog:
+/* Excerpt from the Etrax100 HSDD about the built-in watchdog:
  *
  * 3.10.4 Watchdog timer
 
@@ -231,14 +228,12 @@
 
 #define WATCHDOG_MIN_FREE_PAGES 8
 
-extern int nr_free_pages;
-
 static inline void
 reset_watchdog(void)
 {
 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
 	/* only keep watchdog happy as long as we have memory left! */
-	if(nr_free_pages > WATCHDOG_MIN_FREE_PAGES) {
+	if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
 		/* reset the watchdog with the inverse of the old key */
 		watchdog_key ^= 0x7; /* invert key, which is 3 bits */
 		*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) |
diff -u --recursive --new-file v2.4.6/linux/arch/cris/kernel/traps.c linux/arch/cris/kernel/traps.c
--- v2.4.6/linux/arch/cris/kernel/traps.c	Sun May 20 12:11:38 2001
+++ linux/arch/cris/kernel/traps.c	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.11 2001/04/04 09:43:31 orjanf Exp $
+/* $Id: traps.c,v 1.12 2001/05/15 15:46:40 bjornw Exp $
  *
  *  linux/arch/cris/traps.c
  *
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/checksum.S linux/arch/cris/lib/checksum.S
--- v2.4.6/linux/arch/cris/lib/checksum.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/lib/checksum.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: checksum.S,v 1.4 2001/02/19 11:11:33 bjornw Exp $
+/* $Id: checksum.S,v 1.5 2001/05/29 11:40:14 markusl Exp $
  * A fast checksum routine using movem
  * Copyright (c) 1998-2001 Axis Communications AB
  *
@@ -13,6 +13,8 @@
 	;; r12 - checksum
 
 	;; check for breakeven length between movem and normal word looping versions
+	;; we also do _NOT_ want to compute a checksum over more than the 
+	;; actual length when length < 40
 	
 	cmpu.w	80,r11
 	blo	word_loop
@@ -20,6 +22,8 @@
 
 	;; need to save the registers we use below in the movem loop
 	;; this overhead is why we have a check above for breakeven length
+	;; only r0 - r8 have to be saved, the other ones are clobber-able
+	;; according to the ABI
 	
 	subq	9*4,sp
 	movem	r8,[sp]
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/checksumcopy.S linux/arch/cris/lib/checksumcopy.S
--- v2.4.6/linux/arch/cris/lib/checksumcopy.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/lib/checksumcopy.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: checksumcopy.S,v 1.4 2001/02/19 11:11:34 bjornw Exp $
+/* $Id: checksumcopy.S,v 1.5 2001/05/29 11:40:14 markusl Exp $
  * A fast checksum+copy routine using movem
  * Copyright (c) 1998, 2001 Axis Communications AB
  *
@@ -17,6 +17,8 @@
 	;; r13 - checksum
 
 	;; check for breakeven length between movem and normal word looping versions
+	;; we also do _NOT_ want to compute a checksum over more than the 
+	;; actual length when length < 40
 	
 	cmpu.w	80,r12
 	blo	word_loop
@@ -24,6 +26,8 @@
 
 	;; need to save the registers we use below in the movem loop
 	;; this overhead is why we have a check above for breakeven length
+	;; only r0 - r8 have to be saved, the other ones are clobber-able
+	;; according to the ABI
 	
 	subq	9*4,sp
 	movem	r8,[sp]
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/dram_init.S linux/arch/cris/lib/dram_init.S
--- v2.4.6/linux/arch/cris/lib/dram_init.S	Tue May  1 16:04:56 2001
+++ linux/arch/cris/lib/dram_init.S	Wed Jul  4 11:50:39 2001
@@ -1,4 +1,4 @@
-/* $Id: dram_init.S,v 1.7 2001/04/18 12:05:39 bjornw Exp $
+/* $Id: dram_init.S,v 1.8 2001/05/15 07:12:45 hp Exp $
  * 
  * DRAM/SDRAM initialization - alter with care
  * This file is intended to be included from other assembler files
@@ -11,6 +11,9 @@
  * Authors:  Mikael Starvik (starvik@axis.com)	
  * 
  * $Log: dram_init.S,v $
+ * Revision 1.8  2001/05/15 07:12:45  hp
+ * Copy warning from head.S about r8 and r9
+ *
  * Revision 1.7  2001/04/18 12:05:39  bjornw
  * Fixed comments, and explicitely include config.h to be sure its there
  *
@@ -44,6 +47,9 @@
 
 #include <linux/config.h>
 
+	;; WARNING! The registers r8 and r9 are used as parameters carrying
+	;; information from the decompressor (if the kernel was compressed). 
+	;; They should not be used in the code below.
 
 #ifndef CONFIG_SVINTO_SIM	
 	move.d   CONFIG_ETRAX_DEF_R_WAITSTATES, r0
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/hw_settings.S linux/arch/cris/lib/hw_settings.S
--- v2.4.6/linux/arch/cris/lib/hw_settings.S	Sun May 20 12:11:38 2001
+++ linux/arch/cris/lib/hw_settings.S	Wed Jul  4 11:50:39 2001
@@ -1,14 +1,15 @@
-	;; $Id: hw_settings.S,v 1.2 2001/04/03 11:11:09 starvik Exp $
-	;; 
-	;; This table is used by some tools to extract hardware parameters.
-	;; The table should be included in the kernel and the decompressor.
-	;; Don't forget to update the tools if you change this table.
-	;;
-	;; Copyright (C) 2001 Axis Communications AB
-	;;
-	;; Authors:  Mikael Starvik (starvik@axis.com)	
+/*
+ * $Id: hw_settings.S,v 1.3 2001/04/21 17:02:46 bjornw Exp $
+ * 
+ * This table is used by some tools to extract hardware parameters.
+ * The table should be included in the kernel and the decompressor.
+ * Don't forget to update the tools if you change this table.
+ *
+ * Copyright (C) 2001 Axis Communications AB
+ *
+ * Authors:  Mikael Starvik (starvik@axis.com)	
+ */
 
-	
 #define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \
 		(CONFIG_ETRAX_DEF_R_PORT_PA_DATA))
 #define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \
diff -u --recursive --new-file v2.4.6/linux/arch/cris/lib/usercopy.c linux/arch/cris/lib/usercopy.c
--- v2.4.6/linux/arch/cris/lib/usercopy.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/lib/usercopy.c	Wed Jul  4 11:50:39 2001
@@ -273,20 +273,27 @@
 	movem	r10,[r13+]
 
 	addq   44,r12  ;; compensate for last loop underflowing n
-
+8:
 	;; Restore registers from stack
 	movem [sp+],r10
 
 	.section .fixup,\"ax\"
 
-; To provide a correct count in r10 of bytes that failed to be copied,
-; we jump back into the loop if the loop-branch was taken.
-;  There is no performance penalty; the program will segfault soon
-; enough.
+;; Do not jump back into the loop if we fail.  For some uses, we get a
+;; page fault but for performance reasons we care to not get further
+;; faults.  For example, fs/super.c at one time did
+;;  i = size - copy_from_user((void *)page, data, size);
+;; which would cause repeated faults while clearing the remainder of
+;; the SIZE bytes at PAGE after the first fault.
 
 3:
 	move.d [sp],r10
+
+;; Number of remaining bytes, cleared but not copied, is r12 + 44.
+
+	add.d r12,r10
 	addq 44,r10
+
 	move.d r10,[sp]
 	clear.d r0
 	clear.d r1
@@ -299,7 +306,40 @@
 	clear.d r8
 	clear.d r9
 	clear.d r10
-	jump 1b
+
+;; Perform clear similar to the copy-loop.
+
+4:
+	subq 44,r12
+	bge 4b
+	movem r10,[r13+]
+
+;; Clear by four for the remaining multiples.
+
+	addq 40,r12
+	bmi 6f
+	nop
+5:
+	subq 4,r12
+	bpl 5b
+	clear.d [r13+]
+6:
+	addq 4,r12
+	beq 7f
+	nop
+
+	subq 1,r12
+	beq 7f
+	clear.b [r13+]
+
+	subq 1,r12
+	beq 7f
+	clear.b [r13+]
+
+	clear.d r12
+	clear.b [r13+]
+7:
+	jump 8b
 
 	.previous
 	.section __ex_table,\"a\"
diff -u --recursive --new-file v2.4.6/linux/arch/cris/mm/fault.c linux/arch/cris/mm/fault.c
--- v2.4.6/linux/arch/cris/mm/fault.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/mm/fault.c	Wed Jul  4 11:50:39 2001
@@ -6,6 +6,19 @@
  *  Authors:  Bjorn Wesen 
  * 
  *  $Log: fault.c,v $
+ *  Revision 1.16  2001/06/13 00:06:08  bjornw
+ *  current_pgd should be volatile
+ *
+ *  Revision 1.15  2001/06/13 00:02:23  bjornw
+ *  Use a separate variable to store the current pgd to avoid races in schedule
+ *
+ *  Revision 1.14  2001/05/16 17:41:07  hp
+ *  Last comment tweak further tweaked.
+ *
+ *  Revision 1.13  2001/05/15 00:58:44  hp
+ *  Expand a bit on the comment why we compare address >= TASK_SIZE rather
+ *  than >= VMALLOC_START.
+ *
  *  Revision 1.12  2001/04/04 10:51:14  bjornw
  *  mmap_sem is grabbed for reading
  *
@@ -59,6 +72,10 @@
 /* debug of higher-level faults */
 #define DPG(x)
 
+/* current active page directory */
+
+volatile pgd_t *current_pgd;
+
 /* fast TLB-fill fault handler */
 
 void
@@ -94,9 +111,11 @@
 
 	if(miss) {
 
-		/* see if the pte exists at all */
+		/* see if the pte exists at all
+		 * refer through current_pgd, dont use mm->pgd
+		 */
 		
-		pmd = (pmd_t *)pgd_offset(mm, address);
+		pmd = (pmd_t *)(current_pgd + pgd_index(address));
 		if(pmd_none(*pmd))
 			goto dofault;
 		if(pmd_bad(*pmd)) {
@@ -206,7 +225,9 @@
 	 * should really be >= VMALLOC_START, however, kernel fixup errors
 	 * will be handled more quickly by going through vmalloc_fault and then
 	 * into bad_area_nosemaphore than falling through the find_vma user-mode
-	 * tests.
+	 * tests.  As an aside can be mentioned that the difference in
+	 * compiled code is neglibible; the instruction is the same, just a
+	 * comparison with a different address of the same size.
          */
 
         if (address >= TASK_SIZE)
@@ -384,12 +405,17 @@
                 /*
                  * Synchronize this task's top level page-table
                  * with the 'reference' page table.
+		 *
+		 * Use current_pgd instead of tsk->active_mm->pgd
+		 * since the latter might be unavailable if this
+		 * code is executed in a misfortunately run irq
                  */
+
                 int offset = pgd_index(address);
                 pgd_t *pgd, *pgd_k;
                 pmd_t *pmd, *pmd_k;
 
-                pgd = tsk->active_mm->pgd + offset;
+                pgd = current_pgd + offset;
                 pgd_k = init_mm.pgd + offset;
 
                 if (!pgd_present(*pgd)) {
diff -u --recursive --new-file v2.4.6/linux/arch/cris/mm/init.c linux/arch/cris/mm/init.c
--- v2.4.6/linux/arch/cris/mm/init.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/mm/init.c	Wed Jul  4 11:50:39 2001
@@ -7,6 +7,12 @@
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: init.c,v $
+ *  Revision 1.25  2001/06/13 00:02:23  bjornw
+ *  Use a separate variable to store the current pgd to avoid races in schedule
+ *
+ *  Revision 1.24  2001/05/15 00:52:20  hp
+ *  Only map segment 0xa as seg if CONFIG_JULIETTE
+ *
  *  Revision 1.23  2001/04/04 14:35:40  bjornw
  *  * Removed get_pte_slow and friends (2.4.3 change)
  *  * Removed bad_pmd handling (2.4.3 change)
@@ -85,6 +91,7 @@
 #include <asm/dma.h>
 #include <asm/svinto.h>
 #include <asm/io.h>
+#include <asm/mmu_context.h>
 
 static unsigned long totalram_pages;
 
@@ -177,6 +184,13 @@
 
 	for(i = 0; i < PTRS_PER_PGD; i++)
 		swapper_pg_dir[i] = __pgd(0);
+	
+	/* make sure the current pgd table points to something sane
+	 * (even if it is most probably not used until the next 
+	 *  switch_mm)
+	 */
+
+	current_pgd = init_mm.pgd;
 
 	/* initialise the TLB (tlb.c) */
 
@@ -241,7 +255,11 @@
 			IO_STATE(R_MMU_KSEG, seg_d, page ) | 
 			IO_STATE(R_MMU_KSEG, seg_c, page ) |   
 			IO_STATE(R_MMU_KSEG, seg_b, seg  ) |  /* kernel reg area */
+#ifdef CONFIG_JULIETTE
 			IO_STATE(R_MMU_KSEG, seg_a, seg  ) |  /* ARTPEC etc. */
+#else
+			IO_STATE(R_MMU_KSEG, seg_a, page ) |
+#endif
 			IO_STATE(R_MMU_KSEG, seg_9, seg  ) |  /* LED's on some boards */
 			IO_STATE(R_MMU_KSEG, seg_8, seg  ) |  /* CSE0/1, flash and I/O */
 			IO_STATE(R_MMU_KSEG, seg_7, page ) |  /* kernel vmalloc area */
@@ -258,7 +276,11 @@
 			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
+#ifdef CONFIG_JULIETTE
 			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0xa ) |
+#else
+			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
+#endif
 			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x9 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x8 ) );
 	
@@ -442,7 +464,7 @@
 
 	i = max_mapnr;
 	val->totalram = 0;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	while (i-- > 0)  {
diff -u --recursive --new-file v2.4.6/linux/arch/cris/mm/tlb.c linux/arch/cris/mm/tlb.c
--- v2.4.6/linux/arch/cris/mm/tlb.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/mm/tlb.c	Wed Jul  4 11:50:39 2001
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/cris/mm/tlb.c
  *
- *  Copyright (C) 2000  Axis Communications AB
+ *  Copyright (C) 2000, 2001  Axis Communications AB
  *  
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
  *
@@ -21,6 +21,7 @@
 #include <asm/segment.h>
 #include <asm/pgtable.h>
 #include <asm/svinto.h>
+#include <asm/mmu_context.h>
 
 #define D(x)
 
@@ -252,6 +253,15 @@
 
 	get_mmu_context(next);
 
+	/* remember the pgd for the fault handlers
+	 * this is similar to the pgd register in some other CPU's.
+	 * we need our own copy of it because current and active_mm
+	 * might be invalid at points where we still need to derefer
+	 * the pgd.
+	 */
+
+	current_pgd = next->pgd;
+
 	/* switch context in the MMU */
 	
 	D(printk("switching mmu_context to %d (%p)\n", next->context, next));
@@ -288,7 +298,7 @@
 
 	/* clear the page_id map */
 
-	for(i = 0; i < NUM_PAGEID; i++)
+	for (i = 1; i < sizeof (page_id_map) / sizeof (page_id_map[0]); i++)
 		page_id_map[i] = NULL;
 	
 	/* invalidate the entire TLB */
diff -u --recursive --new-file v2.4.6/linux/arch/i386/boot/video.S linux/arch/i386/boot/video.S
--- v2.4.6/linux/arch/i386/boot/video.S	Sun Nov 21 00:09:51 1999
+++ linux/arch/i386/boot/video.S	Thu Jul  5 11:28:16 2001
@@ -496,7 +496,7 @@
 	jnc	setbad
 	
 	addw	%bx, %bx
-	.word	0xa7ff, spec_inits		# JMP [BX+spec_inits]
+	jmp	*spec_inits(%bx)
 
 setmenu:
 	orb	%al, %al			# 80x25 is an exception
@@ -1008,7 +1008,7 @@
 vesa1:
 # gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
 # XXX:	lodsw	%gs:(%si), %ax			# Get next mode in the list
-	.byte	0x65, 0xAD			# %gs seg prefix + lodsw
+	gs; lodsw
 	cmpw	$0xffff, %ax			# End of the table?
 	jz	vesar
 	
diff -u --recursive --new-file v2.4.6/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.4.6/linux/arch/i386/config.in	Tue Jul  3 17:08:18 2001
+++ linux/arch/i386/config.in	Sun Jul 15 16:15:44 2001
@@ -303,6 +303,8 @@
 fi
 endmenu
 
+source drivers/message/fusion/Config.in
+
 source drivers/ieee1394/Config.in
 
 source drivers/i2o/Config.in
diff -u --recursive --new-file v2.4.6/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.4.6/linux/arch/i386/defconfig	Tue Jul  3 17:08:18 2001
+++ linux/arch/i386/defconfig	Mon Jul 16 10:45:15 2001
@@ -335,6 +335,15 @@
 # CONFIG_SCSI_PCMCIA is not set
 
 #
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_BOOT is not set
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
 # I2O device support
 #
 # CONFIG_I2O is not set
@@ -414,6 +423,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff -u --recursive --new-file v2.4.6/linux/arch/i386/kernel/dmi_scan.c linux/arch/i386/kernel/dmi_scan.c
--- v2.4.6/linux/arch/i386/kernel/dmi_scan.c	Tue Feb 13 14:13:43 2001
+++ linux/arch/i386/kernel/dmi_scan.c	Wed Jul 18 09:43:27 2001
@@ -1,8 +1,10 @@
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/apm_bios.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 struct dmi_header
@@ -13,6 +15,7 @@
 };
 
 #define dmi_printk(x)
+//#define dmi_printk(x) printk(x)
 
 static char * __init dmi_string(struct dmi_header *dm, u8 s)
 {
@@ -90,9 +93,254 @@
 }
 
 
+enum
+{
+	DMI_BIOS_VENDOR,
+	DMI_BIOS_VERSION,
+	DMI_BIOS_DATE,
+	DMI_SYS_VENDOR,
+	DMI_PRODUCT_NAME,
+	DMI_PRODUCT_VERSION,
+	DMI_BOARD_VENDOR,
+	DMI_BOARD_NAME,
+	DMI_BOARD_VERSION,
+	DMI_STRING_MAX
+};
+
+static char *dmi_ident[DMI_STRING_MAX];
+
+/*
+ *	Save a DMI string
+ */
+ 
+static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
+{
+	char *d = (char*)dm;
+	char *p = dmi_string(dm, d[string]);
+	if(p==NULL || *p == 0)
+		return;
+	if (dmi_ident[slot])
+		return;
+	dmi_ident[slot] = kmalloc(strlen(p)+1, GFP_KERNEL);
+	if(dmi_ident[slot])
+		strcpy(dmi_ident[slot], p);
+	else
+		printk(KERN_ERR "dmi_save_ident: out of memory.\n");
+}
+
+/*
+ *	DMI callbacks for problem boards
+ */
+
+struct dmi_strmatch
+{
+	u8 slot;
+	char *substr;
+};
+
+#define NONE	255
+
+struct dmi_blacklist
+{
+	int (*callback)(struct dmi_blacklist *);
+	char *ident;
+	struct dmi_strmatch matches[4];
+};
+
+#define NO_MATCH	{ NONE, NULL}
+#define MATCH(a,b)	{ a, b }
+
+/*
+ *	We have problems with IDE DMA on some platforms. In paticular the
+ *	KT7 series. On these it seems the newer BIOS has fixed them. The
+ *	rule needs to be improved to match specific BIOS revisions with
+ *	corruption problems
+ */ 
+ 
+static __init int disable_ide_dma(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_BLK_DEV_IDE
+	extern int noautodma;
+	if(noautodma == 0)
+	{
+		noautodma = 1;
+		printk(KERN_INFO "%s series board detected. Disabling IDE DMA.\n", d->ident);
+	}
+#endif	
+	return 0;
+}
+
+/* 
+ * Some machines require the "reboot=b"  commandline option, this quirk makes that automatic.
+ */
+static __init int set_bios_reboot(struct dmi_blacklist *d)
+{
+	extern int reboot_thru_bios;
+	if (reboot_thru_bios == 0)
+	{
+		reboot_thru_bios = 1;
+		printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident);
+	}
+	return 0;
+}
+
+/*
+ * Some bioses have a broken protected mode poweroff and need to use realmode
+ */
+
+static __init int set_realmode_power_off(struct dmi_blacklist *d)
+{
+       if (apm_info.realmode_power_off == 0)
+       {
+               apm_info.realmode_power_off = 1;
+               printk(KERN_INFO "%s bios detected. Using realmode poweroff only.\n", d->ident);
+       }
+       return 0;
+}
+
+
+/* 
+ * Some laptops require interrupts to be enabled during APM calls 
+ */
+
+static __init int set_apm_ints(struct dmi_blacklist *d)
+{
+	if (apm_info.allow_ints == 0)
+	{
+		apm_info.allow_ints = 1;
+		printk(KERN_INFO "%s machine detected. Enabling interrupts during APM calls.\n", d->ident);
+	}
+	return 0;
+}
+
+/* 
+ * Some APM bioses corrupt memory or just plain do not work
+ */
+
+static __init int apm_is_horked(struct dmi_blacklist *d)
+{
+	if (apm_info.disabled == 0)
+	{
+		apm_info.disabled = 1;
+		printk(KERN_INFO "%s machine detected. Disabling APM.\n", d->ident);
+	}
+	return 0;
+}
+
+
+/*
+ *  Check for clue free BIOS implementations who use
+ *  the following QA technique
+ *
+ *      [ Write BIOS Code ]<------
+ *               |                ^
+ *      < Does it Compile >----N--
+ *               |Y               ^
+ *	< Does it Boot Win98 >-N--
+ *               |Y
+ *           [Ship It]
+ *
+ *	Phoenix A04  08/24/2000 is known bad (Dell Inspiron 5000e)
+ *	Phoenix A07  09/29/2000 is known good (Dell Inspiron 5000)
+ */
+
+static __init int broken_apm_power(struct dmi_blacklist *d)
+{
+	apm_info.get_power_status_broken = 1;
+	printk(KERN_WARNING "BIOS strings suggest APM bugs, disabling power status reporting.\n");
+	return 0;
+}		
+
+/*
+ *	Process the DMI blacklists
+ */
+ 
+
+/*
+ *	This will be expanded over time to force things like the APM 
+ *	interrupt mask settings according to the laptop
+ */
+ 
+static __initdata struct dmi_blacklist dmi_blacklist[]={
+#if 0
+	{ disable_ide_dma, "KT7", {	/* Overbroad right now - kill DMA on problem KT7 boards */
+			MATCH(DMI_PRODUCT_NAME, "KT7-RAID"),
+			NO_MATCH, NO_MATCH, NO_MATCH
+			} },
+#endif			
+	{ broken_apm_power, "Dell Inspiron 5000e", {	/* Handle problems with APM on Inspiron 5000e */
+			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION, "A04"),
+			MATCH(DMI_BIOS_DATE, "08/24/2000"), NO_MATCH
+			} },
+	{ set_realmode_power_off, "Award Software v4.60 PGMA", {	/* broken PM poweroff bios */
+			MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
+			MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
+			MATCH(DMI_BIOS_DATE, "134526184"), NO_MATCH
+			} },
+	{ set_bios_reboot, "PowerEdge 1300/500", {	/* Handle problems with rebooting on Dell 1300's */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/500"),
+			NO_MATCH, NO_MATCH
+			} },
+	{ set_bios_reboot, "PowerEdge 1300/550", {	/* Handle problems with rebooting on Dell 1300's */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/550"),
+			NO_MATCH, NO_MATCH
+			} },
+	{ set_apm_ints, "IBM", {	/* Allow interrupts during suspend on IBM laptops */
+			MATCH(DMI_SYS_VENDOR, "IBM"),
+			NO_MATCH, NO_MATCH, NO_MATCH
+			} },
+	{ set_apm_ints, "ASUSTeK", {   /* Allow interrupts during APM or the clock goes slow */
+			MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+			MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"),
+			NO_MATCH, NO_MATCH
+			} },					
+	{ apm_is_horked, "Trigem Delhi3", { /* APM crashes */
+			MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
+			MATCH(DMI_PRODUCT_NAME, "Delhi3"),
+			NO_MATCH, NO_MATCH,
+			} },
+	{ NULL, }
+};
+	
+	
+/*
+ *	Walk the blacklist table running matching functions until someone 
+ *	returns 1 or we hit the end.
+ */
+ 
+static __init void dmi_check_blacklist(void)
+{
+	struct dmi_blacklist *d;
+	int i;
+		
+	d=&dmi_blacklist[0];
+	while(d->callback)
+	{
+		for(i=0;i<4;i++)
+		{
+			int s = d->matches[i].slot;
+			if(s==NONE)
+				continue;
+			if(dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
+				continue;
+			/* No match */
+			goto fail;
+		}
+		if(d->callback(d))
+			return;
+fail:			
+		d++;
+	}
+}
+
+	
+
 /*
  *	Process a DMI table entry. Right now all we care about are the BIOS
- *	and machine entries. For 2.4 we should pull the smbus controller info
+ *	and machine entries. For 2.5 we should pull the smbus controller info
  *	out of here.
  */
 
@@ -105,66 +353,47 @@
 	{
 		case  0:
 			p=dmi_string(dm,data[4]);
-
-			if(*p && *p!=' ')
+			if(*p)
 			{
 				dmi_printk(("BIOS Vendor: %s\n", p));
+				dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
 				dmi_printk(("BIOS Version: %s\n", 
 					dmi_string(dm, data[5])));
+				dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
 				dmi_printk(("BIOS Release: %s\n",
 					dmi_string(dm, data[8])));
-			}
-				
-			/*
-			 *  Check for clue free BIOS implementations who use
-			 *  the following QA technique
-			 *
-			 *      [ Write BIOS Code ]<------
-			 *               |                ^
-			 *      < Does it Compile >----N--
-			 *               |Y               ^
-			 *	< Does it Boot Win98 >-N--
-			 *               |Y
-			 *           [Ship It]
-			 *
-			 *	Phoenix A04  08/24/2000 is known bad (Dell Inspiron 5000e)
-			 *	Phoenix A07  09/29/2000 is known good (Dell Inspiron 5000)
-			 */
-			 
-			if(strcmp(dmi_string(dm, data[4]), "Phoenix Technologies LTD")==0)
-			{
-				if(strcmp(dmi_string(dm, data[5]), "A04")==0 
-					&& strcmp(dmi_string(dm, data[8]), "08/24/2000")==0)
-				{
-				   	apm_info.get_power_status_broken = 1;
-					printk(KERN_WARNING "BIOS strings suggest APM bugs, disabling power status reporting.\n");
-				}
+				dmi_save_ident(dm, DMI_BIOS_DATE, 8);
 			}
 			break;
+			
 		case 1:
 			p=dmi_string(dm,data[4]);
-
-			if(*p && *p!=' ')
+			if(*p)
 			{
 				dmi_printk(("System Vendor: %s.\n",p));
+				dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
 				dmi_printk(("Product Name: %s.\n",
 					dmi_string(dm, data[5])));
+				dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
 				dmi_printk(("Version %s.\n",
 					dmi_string(dm, data[6])));
+				dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
 				dmi_printk(("Serial Number %s.\n",
 					dmi_string(dm, data[7])));
 			}
 			break;
 		case 2:
 			p=dmi_string(dm,data[4]);
-
-			if(*p && *p!=' ')
+			if(*p)
 			{
 				dmi_printk(("Board Vendor: %s.\n",p));
+				dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
 				dmi_printk(("Board Name: %s.\n",
 					dmi_string(dm, data[5])));
+				dmi_save_ident(dm, DMI_BOARD_NAME, 5);
 				dmi_printk(("Board Version: %s.\n",
 					dmi_string(dm, data[6])));
+				dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
 			}
 			break;
 		case 3:
@@ -177,7 +406,10 @@
 
 static int __init dmi_scan_machine(void)
 {
-	return dmi_iterate(dmi_decode);
+	int err = dmi_iterate(dmi_decode);
+	if(err == 0)
+		dmi_check_blacklist();
+	return err;
 }
 
 module_init(dmi_scan_machine);
diff -u --recursive --new-file v2.4.6/linux/arch/i386/kernel/pci-irq.c linux/arch/i386/kernel/pci-irq.c
--- v2.4.6/linux/arch/i386/kernel/pci-irq.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/i386/kernel/pci-irq.c	Wed Jul  4 15:39:28 2001
@@ -391,6 +391,38 @@
 	return 1;
 }
 
+/* Support for AMD756 PCI IRQ Routing
+ * Jhon H. Caicedo <jhcaiced@osso.org.co>
+ * Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced)
+ * Jun/19/2001 Alpha Release 0.1.0 (jhcaiced)
+ * The AMD756 pirq rules are nibble-based
+ * offset 0x56 0-3 PIRQA  4-7  PIRQB
+ * offset 0x57 0-3 PIRQC  4-7  PIRQD
+ */
+static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	u8 irq;
+	irq = 0;
+	if (pirq <= 4)
+	{
+		irq = read_config_nybble(router, 0x56, pirq - 1);
+	}
+	printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n",
+		dev->vendor, dev->device, pirq, irq);
+	return irq;
+}
+
+static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", 
+		dev->vendor, dev->device, pirq, irq);
+	if (pirq <= 4)
+	{
+		write_config_nybble(router, 0x56, pirq - 1, irq);
+	}
+	return 1;
+}
+
 #ifdef CONFIG_PCI_BIOS
 
 static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
@@ -426,6 +458,8 @@
 	{ "VLSI 82C534", PCI_VENDOR_ID_VLSI, PCI_DEVICE_ID_VLSI_82C534, pirq_vlsi_get, pirq_vlsi_set },
 	{ "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4,
 	  pirq_serverworks_get, pirq_serverworks_set },
+	{ "AMD756 VIPER", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B,
+		pirq_amd756_get, pirq_amd756_set },
 
 	{ "default", 0, 0, NULL, NULL }
 };
diff -u --recursive --new-file v2.4.6/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.4.6/linux/arch/i386/kernel/process.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/i386/kernel/process.c	Wed Jul  4 14:41:33 2001
@@ -152,7 +152,7 @@
 
 static long no_idt[2];
 static int reboot_mode;
-static int reboot_thru_bios;
+int reboot_thru_bios;
 
 static int __init reboot_setup(char *str)
 {
diff -u --recursive --new-file v2.4.6/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.4.6/linux/arch/i386/kernel/setup.c	Fri May 25 17:07:09 2001
+++ linux/arch/i386/kernel/setup.c	Wed Jul 11 09:31:44 2001
@@ -1123,7 +1123,6 @@
 static int __init init_amd(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
-	unsigned long flags;
 	int mbytes = max_mapnr >> (20-PAGE_SHIFT);
 	int r;
 
@@ -1187,14 +1186,13 @@
 					mbytes=508;
 					
 				rdmsr(0xC0000082, l, h);
-				if((l&0x0000FFFF)==0)
-				{		
+				if ((l&0x0000FFFF)==0) {
+					unsigned long flags;
 					l=(1<<0)|((mbytes/4)<<1);
-					save_flags(flags);
-					__cli();
+					local_irq_save(flags);
 					__asm__ __volatile__ ("wbinvd": : :"memory");
 					wrmsr(0xC0000082, l, h);
-					restore_flags(flags);
+					local_irq_restore(flags);
 					printk(KERN_INFO "Enabling old style K6 write allocation for %d Mb\n",
 						mbytes);
 					
@@ -1209,14 +1207,13 @@
 					mbytes=4092;
 
 				rdmsr(0xC0000082, l, h);
-				if((l&0xFFFF0000)==0)
-				{
+				if ((l&0xFFFF0000)==0) {
+					unsigned long flags;
 					l=((mbytes>>2)<<22)|(1<<16);
-					save_flags(flags);
-					__cli();
+					local_irq_save(flags);
 					__asm__ __volatile__ ("wbinvd": : :"memory");
 					wrmsr(0xC0000082, l, h);
-					restore_flags(flags);
+					local_irq_restore(flags);
 					printk(KERN_INFO "Enabling new style K6 write allocation for %d Mb\n",
 						mbytes);
 				}
@@ -1243,12 +1240,13 @@
 /*
  * Read Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
  */
-static inline void do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+static void do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
 {
 	unsigned char ccr2, ccr3;
+	unsigned long flags;
 
 	/* we test for DEVID by checking whether CCR3 is writable */
-	cli();
+	local_irq_save(flags);
 	ccr3 = getCx86(CX86_CCR3);
 	setCx86(CX86_CCR3, ccr3 ^ 0x80);
 	getCx86(0xc0);   /* dummy to change bus */
@@ -1272,7 +1270,7 @@
 		*dir0 = getCx86(CX86_DIR0);
 		*dir1 = getCx86(CX86_DIR1);
 	}
-	sti();
+	local_irq_restore(flags);
 }
 
 /*
@@ -1316,15 +1314,16 @@
 {
 	if (Cx86_dir0_msb == 3) {
 		unsigned char ccr3, ccr5;
+		unsigned long flags;
 
-		cli();
+		local_irq_save(flags);
 		ccr3 = getCx86(CX86_CCR3);
 		setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
 		ccr5 = getCx86(CX86_CCR5);
 		if (ccr5 & 2)
 			setCx86(CX86_CCR5, ccr5 & 0xfd);  /* reset SLOP */
 		setCx86(CX86_CCR3, ccr3);                 /* disable MAPEN */
-		sti();
+		local_irq_restore(flags);
 
 		if (ccr5 & 2) { /* possible wrong calibration done */
 			printk(KERN_INFO "Recalibrating delay loop with SLOP bit reset\n");
@@ -1438,8 +1437,16 @@
 		break;
 
         case 5: /* 6x86MX/M II */
-		if (dir1 > 7) dir0_msn++;  /* M II */
-		else c->coma_bug = 1;      /* 6x86MX, it has the bug. */
+		if (dir1 > 7)
+		{
+			dir0_msn++;  /* M II */
+			/* Enable MMX extensions (App note 108) */
+			setCx86(CX86_CCR7, getCx86(CX86_CCR7)|1);
+		}
+		else
+		{
+			c->coma_bug = 1;      /* 6x86MX, it has the bug. */
+		}
 		tmp = (!(dir0_lsn & 7) || dir0_lsn & 1) ? 2 : 0;
 		Cx86_cb[tmp] = cyrix_model_mult2[dir0_lsn & 7];
 		p = Cx86_cb+tmp;
@@ -1987,6 +1994,9 @@
 		wrmsr(0x119,lo,hi);
 		printk(KERN_NOTICE "CPU serial number disabled.\n");
 		clear_bit(X86_FEATURE_PN, &c->x86_capability);
+
+		/* Disabling the serial number may affect the cpuid level */
+		c->cpuid_level = cpuid_eax(0);
 	}
 }
 
@@ -2092,15 +2102,16 @@
    	        if (dir0 == 5 || dir0 == 3)
    	        {
 			unsigned char ccr3, ccr4;
+			unsigned long flags;
 
 			printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n");
-			cli();
+			local_irq_save(flags);
 			ccr3 = getCx86(CX86_CCR3);
 			setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
 			ccr4 = getCx86(CX86_CCR4);
 			setCx86(CX86_CCR4, ccr4 | 0x80);          /* enable cpuid  */
 			setCx86(CX86_CCR3, ccr3);                 /* disable MAPEN */
-			sti();
+			local_irq_restore(flags);
 		}
 	} else
 
diff -u --recursive --new-file v2.4.6/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
--- v2.4.6/linux/arch/i386/kernel/signal.c	Tue Feb 13 13:15:04 2001
+++ linux/arch/i386/kernel/signal.c	Wed Jul  4 14:41:33 2001
@@ -370,7 +370,7 @@
 
 	/* This is the X/Open sanctioned signal stack switching.  */
 	if (ka->sa.sa_flags & SA_ONSTACK) {
-		if (! on_sig_stack(esp))
+		if (sas_ss_flags(esp) == 0)
 			esp = current->sas_ss_sp + current->sas_ss_size;
 	}
 
diff -u --recursive --new-file v2.4.6/linux/arch/i386/kernel/vm86.c linux/arch/i386/kernel/vm86.c
--- v2.4.6/linux/arch/i386/kernel/vm86.c	Sun Oct  1 20:35:15 2000
+++ linux/arch/i386/kernel/vm86.c	Fri Jul  6 17:05:07 2001
@@ -456,7 +456,7 @@
 	if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \
 		pushw(ssp,sp,popw(ssp,sp) | TF_MASK);
 #define VM86_FAULT_RETURN \
-	if (VMPI.force_return_for_pic  && (VEFLAGS & IF_MASK)) \
+	if (VMPI.force_return_for_pic  && (VEFLAGS & (IF_MASK | VIF_MASK))) \
 		return_to_32bit(regs, VM86_PICRETURN); \
 	return;
 	                                   
diff -u --recursive --new-file v2.4.6/linux/arch/i386/math-emu/reg_u_div.S linux/arch/i386/math-emu/reg_u_div.S
--- v2.4.6/linux/arch/i386/math-emu/reg_u_div.S	Fri Apr  6 10:42:47 2001
+++ linux/arch/i386/math-emu/reg_u_div.S	Wed Jul  4 14:41:33 2001
@@ -89,10 +89,8 @@
 	movl	REGB,%ebx
 	movl	DEST,%edi
 
-	movw	EXP(%esi),%dx
-	movw	EXP(%ebx),%ax
-	.byte	0x0f,0xbf,0xc0	/* movsx	%ax,%eax */
-	.byte	0x0f,0xbf,0xd2	/* movsx	%dx,%edx */
+	movswl	EXP(%esi),%edx
+	movswl	EXP(%ebx),%eax
 	subl	%eax,%edx
 	addl	EXP_BIAS,%edx
 
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/andes.c linux/arch/mips/mm/andes.c
--- v2.4.6/linux/arch/mips/mm/andes.c	Thu Jul 27 18:36:54 2000
+++ linux/arch/mips/mm/andes.c	Wed Jul  4 11:50:39 2001
@@ -119,6 +119,17 @@
 	/* XXX */
 }
 
+static void __andes_flush_icache_range(unsigned long start, unsigned long end)
+{
+	/* XXX */
+}
+
+static void andes_flush_icache_page(struct vm_area_struct *vma,
+                                    struct page *page)
+{
+	/* XXX */
+}
+
 static void andes_flush_cache_sigtramp(unsigned long page)
 {
 	/* XXX */
@@ -146,10 +157,6 @@
 	/* XXX */
 }
 
-void load_pgd(unsigned long pg_dir)
-{
-}
-
 void pgd_init(unsigned long page)
 {
 }
@@ -166,11 +173,14 @@
 	_copy_page = andes_copy_page;
 
 	_flush_cache_all = andes_flush_cache_all;
+	___flush_cache_all = andes_flush_cache_all;
 	_flush_cache_mm = andes_flush_cache_mm;
 	_flush_cache_range = andes_flush_cache_range;
 	_flush_cache_page = andes_flush_cache_page;
 	_flush_cache_sigtramp = andes_flush_cache_sigtramp;
 	_flush_page_to_ram = andes_flush_page_to_ram;
+	_flush_icache_page = andes_flush_icache_page;
+	_flush_icache_range = andes_flush_icache_range;
 
 	flush_cache_all();
 	flush_tlb_all();
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/extable.c linux/arch/mips/mm/extable.c
--- v2.4.6/linux/arch/mips/mm/extable.c	Thu Feb 24 22:52:30 2000
+++ linux/arch/mips/mm/extable.c	Wed Jul  4 11:50:39 2001
@@ -3,6 +3,7 @@
  */
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 
 extern const struct exception_table_entry __start___ex_table[];
@@ -29,26 +30,33 @@
 	return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 unsigned long
 search_exception_table(unsigned long addr)
 {
-	unsigned long ret;
-
+	unsigned long ret = 0;
+	
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-	if (ret) return ret;
+	return ret;
 #else
+	unsigned long flags;
+
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
+
+	spin_lock_irqsave(&modlist_lock, flags);
 	for (mp = module_list; mp != NULL; mp = mp->next) {
-		if (mp->ex_table_start == NULL)
+		if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
 			continue;
 		ret = search_one_table(mp->ex_table_start,
 				       mp->ex_table_end - 1, addr);
-		if (ret) return ret;
+		if (ret)
+			break;
 	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
 #endif
-
-	return 0;
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/fault.c linux/arch/mips/mm/fault.c
--- v2.4.6/linux/arch/mips/mm/fault.c	Mon Mar 19 12:35:09 2001
+++ linux/arch/mips/mm/fault.c	Wed Jul  4 11:50:39 2001
@@ -49,6 +49,18 @@
 	unsigned long fixup;
 	siginfo_t info;
 
+	/*
+	 * We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 *
+	 * NOTE! We MUST NOT take any locks for this case. We may
+	 * be in an interrupt or a critical region, and should
+	 * only copy the information from the master page table,
+	 * nothing more.
+	 */
+	if (address >= TASK_SIZE)
+		goto vmalloc_fault;
+
 	info.si_code = SEGV_MAPERR;
 	/*
 	 * If we're in an interrupt or have no user
@@ -113,6 +125,8 @@
 bad_area:
 	up_read(&mm->mmap_sem);
 
+bad_area_nosemaphore:
+	/* User mode accesses just cause a SIGSEGV */
 	if (user_mode(regs)) {
 		tsk->thread.cp0_badvaddr = address;
 		tsk->thread.error_code = write;
@@ -186,4 +200,34 @@
 	/* Kernel mode? Handle exceptions or die */
 	if (!user_mode(regs))
 		goto no_context;
+
+	return;
+
+vmalloc_fault:
+	{
+		/*
+		 * Synchronize this task's top level page-table
+		 * with the 'reference' page table.
+		 */
+		int offset = pgd_index(address);
+		pgd_t *pgd, *pgd_k;
+		pmd_t *pmd, *pmd_k;
+
+		pgd = tsk->active_mm->pgd + offset;
+		pgd_k = init_mm.pgd + offset;
+
+		if (!pgd_present(*pgd)) {
+			if (!pgd_present(*pgd_k))
+				goto bad_area_nosemaphore;
+			set_pgd(pgd, *pgd_k);
+			return;
+		}
+
+		pmd = pmd_offset(pgd, address);
+		pmd_k = pmd_offset(pgd_k, address);
+
+		if (pmd_present(*pmd) || !pmd_present(*pmd_k))
+			goto bad_area_nosemaphore;
+		set_pmd(pmd, *pmd_k);
+	}
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/init.c linux/arch/mips/mm/init.c
--- v2.4.6/linux/arch/mips/mm/init.c	Mon Oct 16 12:58:51 2000
+++ linux/arch/mips/mm/init.c	Wed Jul  4 11:50:39 2001
@@ -1,11 +1,13 @@
-/* $Id: init.c,v 1.26 2000/02/23 00:41:00 ralf Exp $
- *
+/*
  * 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.
  *
  * Copyright (C) 1994 - 2000 by Ralf Baechle
  * Copyright (C) 2000 Silicon Graphics, Inc.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -29,6 +31,7 @@
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
+#include <asm/cpu.h>
 #include <asm/dma.h>
 #include <asm/jazzdma.h>
 #include <asm/system.h>
@@ -38,74 +41,20 @@
 #include <asm/sgialib.h>
 #endif
 #include <asm/mmu_context.h>
+#include <asm/tlb.h>
+
+mmu_gather_t mmu_gathers[NR_CPUS];
 
 static unsigned long totalram_pages;
 
-extern void prom_fixup_mem_map(unsigned long start, unsigned long end);
 extern void prom_free_prom_memory(void);
 
 
-void __bad_pte_kernel(pmd_t *pmd)
-{
-	printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
-	pmd_set(pmd, BAD_PAGETABLE);
-}
-
-void __bad_pte(pmd_t *pmd)
-{
-	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-	pmd_set(pmd, BAD_PAGETABLE);
-}
-
-pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
-{
-	pte_t *page;
-
-	page = (pte_t *) __get_free_page(GFP_USER);
-	if (pmd_none(*pmd)) {
-		if (page) {
-			clear_page(page);
-			pmd_val(*pmd) = (unsigned long)page;
-			return page + offset;
-		}
-		pmd_set(pmd, BAD_PAGETABLE);
-		return NULL;
-	}
-	free_page((unsigned long)page);
-	if (pmd_bad(*pmd)) {
-		__bad_pte_kernel(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
-	pte_t *page;
-
-	page = (pte_t *) __get_free_page(GFP_KERNEL);
-	if (pmd_none(*pmd)) {
-		if (page) {
-			clear_page(page);
-			pmd_val(*pmd) = (unsigned long)page;
-			return page + offset;
-		}
-		pmd_set(pmd, BAD_PAGETABLE);
-		return NULL;
-	}
-	free_page((unsigned long)page);
-	if (pmd_bad(*pmd)) {
-		__bad_pte(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-
 asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
 {
-	/* XXX Just get it working for now... */
-	flush_cache_all();
+	/* This should flush more selectivly ...  */
+	__flush_cache_all();
+
 	return 0;
 }
 
@@ -122,17 +71,10 @@
 {
 	unsigned long order, size;
 	struct page *page;
-
-	switch (mips_cputype) {
-	case CPU_R4000SC:
-	case CPU_R4000MC:
-	case CPU_R4400SC:
-	case CPU_R4400MC:
+	if(mips_cpu.options & MIPS_CPU_VCE) 
 		order = 3;
-		break;
-	default:
+	else 
 		order = 0;
-	}
 
 	empty_zero_page = __get_free_pages(GFP_KERNEL, order);
 	if (!empty_zero_page)
@@ -169,48 +111,6 @@
 	return freed;
 }
 
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
- */
-pte_t * __bad_pagetable(void)
-{
-	extern char empty_bad_page_table[PAGE_SIZE];
-	unsigned long page, dummy1, dummy2;
-
-	page = (unsigned long) empty_bad_page_table;
-	__asm__ __volatile__(
-		".set\tnoreorder\n"
-		"1:\tsw\t%2,(%0)\n\t"
-		"subu\t%1,1\n\t"
-		"bnez\t%1,1b\n\t"
-		"addiu\t%0,4\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2)
-		:"r" (pte_val(BAD_PAGE)), "0" (page), "1" (PAGE_SIZE/4)
-		:"$1");
-
-	return (pte_t *)page;
-}
-
-pte_t __bad_page(void)
-{
-	extern char empty_bad_page[PAGE_SIZE];
-	unsigned long page = (unsigned long) empty_bad_page;
-
-	clear_page((void *)page);
-	return pte_mkdirty(mk_pte_phys(__pa(page), PAGE_SHARED));
-}
-
 void show_mem(void)
 {
 	int i, free = 0, total = 0, reserved = 0;
@@ -271,7 +171,30 @@
 	free_area_init(zones_size);
 }
 
-extern int page_is_ram(unsigned long pagenr);
+#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+
+static inline int page_is_ram(unsigned long pagenr)
+{
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long addr, end;
+
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			/* not usable memory */
+			continue;
+
+		addr = PFN_UP(boot_mem_map.map[i].addr);
+		end = PFN_DOWN(boot_mem_map.map[i].addr
+			       + boot_mem_map.map[i].size);
+
+		if (pagenr >= addr && pagenr < end)
+			return 1;
+	}
+
+	return 0;
+}
 
 void __init mem_init(void)
 {
@@ -309,13 +232,16 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
+	if (start < end)
+		printk("Freeing initrd memory: %ldk freed\n",
+		       (end - start) >> 10);
+
 	for (; start < end; start += PAGE_SIZE) {
 		ClearPageReserved(virt_to_page(start));
 		set_page_count(virt_to_page(start), 1);
 		free_page(start);
 		totalram_pages++;
 	}
-	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 }
 #endif
 
@@ -343,7 +269,7 @@
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/ioremap.c linux/arch/mips/mm/ioremap.c
--- v2.4.6/linux/arch/mips/mm/ioremap.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/ioremap.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ * (C) Copyright 2001 Ralf Baechle
+ */
+#include <linux/module.h>
+#include <asm/addrspace.h>
+#include <asm/byteorder.h>
+
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+	unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+	pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
+	                           | __WRITEABLE | flags);
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	if (address >= end)
+		BUG();
+	do {
+		if (!pte_none(*pte)) {
+			printk("remap_area_pte: page already exists\n");
+			BUG();
+		}
+		set_pte(pte, mk_pte_phys(phys_addr, pgprot));
+		address += PAGE_SIZE;
+		phys_addr += PAGE_SIZE;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
+	unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	if (address >= end)
+		BUG();
+	do {
+		pte_t * pte = pte_alloc(&init_mm, pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+static int remap_area_pages(unsigned long address, unsigned long phys_addr,
+				 unsigned long size, unsigned long flags)
+{
+	int error;
+	pgd_t * dir;
+	unsigned long end = address + size;
+
+	phys_addr -= address;
+	dir = pgd_offset(&init_mm, address);
+	flush_cache_all();
+	if (address >= end)
+		BUG();
+	spin_lock(&init_mm.page_table_lock);
+	do {
+		pmd_t *pmd;
+		pmd = pmd_alloc(&init_mm, dir, address);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		if (remap_area_pmd(pmd, address, end - address,
+					 phys_addr + address, flags))
+			break;
+		error = 0;
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (address && (address < end));
+	spin_unlock(&init_mm.page_table_lock);
+	flush_tlb_all();
+	return error;
+}
+
+/*
+ * Generic mapping function (not visible outside):
+ */
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+
+#define IS_LOW512(addr) (!((unsigned long)(addr) & ~0x1fffffffUL))
+
+void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+{
+	void * addr;
+	struct vm_struct * area;
+	unsigned long offset, last_addr;
+
+	/* Don't allow wraparound or zero size */
+	last_addr = phys_addr + size - 1;
+	if (!size || last_addr < phys_addr)
+		return NULL;
+
+	/*
+	 * Map objects in the low 512mb of address space using KSEG1, otherwise
+	 * map using page tables.
+	 */
+	if (IS_LOW512(phys_addr) && IS_LOW512(phys_addr + size - 1))
+		return (void *) KSEG1ADDR(phys_addr);
+
+	/*
+	 * Don't allow anybody to remap normal RAM that we're using..
+	 */
+	if (phys_addr < virt_to_phys(high_memory)) {
+		char *t_addr, *t_end;
+		struct page *page;
+
+		t_addr = __va(phys_addr);
+		t_end = t_addr + (size - 1);
+	   
+		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
+			if(!PageReserved(page))
+				return NULL;
+	}
+
+	/*
+	 * Mappings have to be page-aligned
+	 */
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(last_addr) - phys_addr;
+
+	/*
+	 * Ok, go for it..
+	 */
+	area = get_vm_area(size, VM_IOREMAP);
+	if (!area)
+		return NULL;
+	addr = area->addr;
+	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+		vfree(addr);
+		return NULL;
+	}
+
+	return (void *) (offset + (char *)addr);
+}
+
+#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == KSEG1)
+
+void iounmap(void *addr)
+{
+	if (!IS_KSEG1(addr))
+		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+}
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/loadmmu.c linux/arch/mips/mm/loadmmu.c
--- v2.4.6/linux/arch/mips/mm/loadmmu.c	Sat May 13 08:29:14 2000
+++ linux/arch/mips/mm/loadmmu.c	Wed Jul  4 11:50:39 2001
@@ -2,8 +2,8 @@
  * loadmmu.c: Setup cpu/cache specific function ptrs at boot time.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: loadmmu.c,v 1.17 2000/03/13 10:33:05 raiko Exp $
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -11,10 +11,11 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/bootinfo.h>
 
 /* memory functions */
 void (*_clear_page)(void * page);
@@ -22,84 +23,79 @@
 
 /* Cache operations. */
 void (*_flush_cache_all)(void);
+void (*___flush_cache_all)(void);
 void (*_flush_cache_mm)(struct mm_struct *mm);
 void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
 			  unsigned long end);
 void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
 void (*_flush_cache_sigtramp)(unsigned long addr);
 void (*_flush_page_to_ram)(struct page * page);
+void (*_flush_icache_range)(unsigned long start, unsigned long end);
+void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page);
 
 /* DMA cache operations. */
 void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
 void (*_dma_cache_wback)(unsigned long start, unsigned long size);
 void (*_dma_cache_inv)(unsigned long start, unsigned long size);
 
-#ifdef CONFIG_CPU_R3000
-extern void ld_mmu_r2300(void);
-#endif
-#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_R4300) || \
-    defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
+extern void ld_mmu_r23000(void);
 extern void ld_mmu_r4xx0(void);
-#endif
-#ifdef CONFIG_CPU_R6000
+extern void ld_mmu_r5432(void);
 extern void ld_mmu_r6000(void);
-#endif
-#ifdef CONFIG_CPU_R8000
+extern void ld_mmu_rm7k(void);
 extern void ld_mmu_tfp(void);
-#endif
-#ifdef CONFIG_CPU_R10000
 extern void ld_mmu_andes(void);
-#endif
+extern void ld_mmu_sb1(void);
+extern void ld_mmu_mips32(void);
 
 void __init loadmmu(void)
 {
-	switch(mips_cputype) {
-#ifdef CONFIG_CPU_R3000
-	case CPU_R2000:
-	case CPU_R3000:
-	case CPU_R3000A:
-	case CPU_R3081E:
-		printk("Loading R[23]00 MMU routines.\n");
-		ld_mmu_r2300();
-		break;
-#endif
 
+	if (mips_cpu.options & MIPS_CPU_4KTLB) {
 #if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_R4300) || \
     defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
-	case CPU_R4000PC:
-	case CPU_R4000SC:
-	case CPU_R4000MC:
-	case CPU_R4200:
-	case CPU_R4300:
-	case CPU_R4400PC:
-	case CPU_R4400SC:
-	case CPU_R4400MC:
-	case CPU_R4600:
-	case CPU_R4640:
-	case CPU_R4650:
-	case CPU_R4700:
-	case CPU_R5000:
-	case CPU_R5000A:
-	case CPU_NEVADA:
 		printk("Loading R4000 MMU routines.\n");
 		ld_mmu_r4xx0();
-		break;
+#endif
+#if defined(CONFIG_CPU_RM7000)
+               printk("Loading RM7000 MMU routines.\n");
+               ld_mmu_rm7k();
+#endif
+#if defined(CONFIG_CPU_R5432)
+		printk("Loading R5432 MMU routines.\n");
+		ld_mmu_r5432();
 #endif
 
+#if defined(CONFIG_CPU_MIPS32)
+		printk("Loading MIPS32 MMU routines.\n");
+		ld_mmu_mips32();
+#endif
+	} else switch(mips_cpu.cputype) {
+#ifdef CONFIG_CPU_R3000
+	case CPU_R2000:
+	case CPU_R3000:
+	case CPU_R3000A:
+	case CPU_TX3912:
+	case CPU_TX3922:
+	case CPU_TX3927:
+	case CPU_R3081E:
+		printk("Loading R[23]000 MMU routines.\n");
+		ld_mmu_r23000();
+		break;
+#endif
 #ifdef CONFIG_CPU_R10000
 	case CPU_R10000:
 		printk("Loading R10000 MMU routines.\n");
 		ld_mmu_andes();
 		break;
 #endif
-
+#ifdef CONFIG_CPU_SB1
+	case CPU_SB1:
+		printk("Loading SB1 MMU routines.\n");
+		ld_mmu_sb1();
+		break;
+#endif
 	default:
-		/* XXX We need an generic routine in the MIPS port
-		 * XXX to jabber stuff onto the screen on all machines
-		 * XXX before the console is setup.  The ARCS prom
-		 * XXX routines look good for this, but only the SGI
-		 * XXX code has a full library for that at this time.
-		 */
 		panic("Yeee, unsupported mmu/cache architecture.");
 	}
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/mips32.c linux/arch/mips/mm/mips32.c
--- v2.4.6/linux/arch/mips/mm/mips32.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/mips32.c	Wed Jul  4 11:50:39 2001
@@ -0,0 +1,1078 @@
+/*
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.
+ *
+ * MIPS32 CPU variant specific MMU/Cache routines.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/bcache.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+/* Primary cache parameters. */
+static int icache_size, dcache_size; /* Size in bytes */
+static int ic_lsize, dc_lsize;       /* LineSize in bytes */
+
+/* Secondary cache (if present) parameters. */
+static unsigned int scache_size, sc_lsize;	/* Again, in bytes */
+
+#include <asm/cacheops.h>
+#include <asm/mips32_cache.h>
+
+#undef DEBUG_CACHE
+
+/*
+ * Dummy cache handling routines for machines without boardcaches
+ */
+static void no_sc_noop(void) {}
+
+static struct bcache_ops no_sc_ops = {
+	(void *)no_sc_noop, (void *)no_sc_noop,
+	(void *)no_sc_noop, (void *)no_sc_noop
+};
+
+struct bcache_ops *bcops = &no_sc_ops;
+
+
+/*
+ * Zero an entire page.
+ */
+
+static void mips32_clear_page_dc(unsigned long page)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=page; i<page+PAGE_SIZE; i+=dc_lsize)
+		{
+		        __asm__ __volatile__(
+			        ".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_D));
+		}
+	}
+	for (i=page; i<page+PAGE_SIZE; i+=4)
+	        *(unsigned long *)(i) = 0;
+}
+
+static void mips32_clear_page_sc(unsigned long page)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=page; i<page+PAGE_SIZE; i+=sc_lsize)
+		{
+		        __asm__ __volatile__(
+				".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_SD));
+		}
+	}
+	for (i=page; i<page+PAGE_SIZE; i+=4)
+	        *(unsigned long *)(i) = 0;
+}
+
+static void mips32_copy_page_dc(unsigned long to, unsigned long from)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=to; i<to+PAGE_SIZE; i+=dc_lsize)
+		{
+		        __asm__ __volatile__(
+			        ".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_D));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=4)
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
+
+static void mips32_copy_page_sc(unsigned long to, unsigned long from)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=to; i<to+PAGE_SIZE; i+=sc_lsize)
+		{
+		        __asm__ __volatile__(
+				".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				".set\tmips3\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tmips0\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_SD));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=4)
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
+
+static inline void mips32_flush_cache_all_sc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache(); blast_scache();
+	__restore_flags(flags);
+}
+
+static inline void mips32_flush_cache_all_pc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache();
+	__restore_flags(flags);
+}
+
+static void
+mips32_flush_cache_range_sc(struct mm_struct *mm,
+			 unsigned long start,
+			 unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			mips32_flush_cache_all_sc();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			__save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache_page(start);
+				start += PAGE_SIZE;
+			}
+			__restore_flags(flags);
+		}
+	}
+}
+
+static void mips32_flush_cache_range_pc(struct mm_struct *mm,
+				     unsigned long start,
+				     unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		__save_and_cli(flags);
+		blast_dcache(); blast_icache();
+		__restore_flags(flags);
+	}
+}
+
+/*
+ * On architectures like the Sparc, we could get rid of lines in
+ * the cache created only by a certain context, but on the MIPS
+ * (and actually certain Sparc's) we cannot.
+ */
+static void mips32_flush_cache_mm_sc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips32_flush_cache_all_sc();
+	}
+}
+
+static void mips32_flush_cache_mm_pc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips32_flush_cache_all_pc();
+	}
+}
+
+
+
+
+
+static void mips32_flush_cache_page_sc(struct vm_area_struct *vma,
+				    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache_page_indexed(page);
+		blast_scache_page_indexed(page);
+	} else
+		blast_scache_page(page);
+out:
+	__restore_flags(flags);
+}
+
+static void mips32_flush_cache_page_pc(struct vm_area_struct *vma,
+				    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since Mips32 caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm == current->active_mm) {
+		blast_dcache_page(page);
+	} else {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (dcache_size - 1)));
+		blast_dcache_page_indexed(page);
+	}
+out:
+	__restore_flags(flags);
+}
+
+/* If the addresses passed to these routines are valid, they are
+ * either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those
+ *    addresses all the time in kernel mode we can do a direct
+ *    flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void mips32_flush_page_to_ram_sc(struct page *page)
+{
+	blast_scache_page((unsigned long)page_address(page));
+}
+
+static void mips32_flush_page_to_ram_pc(struct page *page)
+{
+	blast_dcache_page((unsigned long)page_address(page));
+}
+
+static void
+mips32_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
+{
+	/*
+	 * We did an scache flush therefore PI is already clean.
+	 */
+}
+
+static void
+mips32_flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+static void
+mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	int address;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & (dcache_size - 1));
+	blast_icache_page_indexed(address);
+}
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ */
+static void
+mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+	bc_wback_inv(addr, size);
+}
+
+static void
+mips32_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= dcache_size) {
+		flush_cache_all();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+
+	bc_inv(addr, size);
+}
+
+static void
+mips32_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		flush_cache_all();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a); /* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+mips32_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("mips32_dma_cache called - should not happen.\n");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void mips32_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long daddr, iaddr;
+
+	daddr = addr & ~(dc_lsize - 1);
+	protected_writeback_dcache_line(daddr);
+	protected_writeback_dcache_line(daddr + dc_lsize);
+	iaddr = addr & ~(ic_lsize - 1);
+	protected_flush_icache_line(iaddr);
+	protected_flush_icache_line(iaddr + ic_lsize);
+}
+
+#undef DEBUG_TLB
+#undef DEBUG_TLBUPDATE
+
+void flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+#ifdef DEBUG_TLB
+	printk("[tlball]");
+#endif
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = (get_entryhi() & 0xff);
+	set_entryhi(KSEG0);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	BARRIER;
+
+	entry = get_wired();
+
+	/* Blast 'em all away. */
+	while(entry < mips_cpu.tlbsize) {
+	        /* Make sure all entries differ. */  
+	        set_entryhi(KSEG0+entry*0x2000);
+		set_index(entry);
+		BARRIER;
+		tlb_write_indexed();
+		BARRIER;
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	if (mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%d>]", mm->context);
+#endif
+		__save_and_cli(flags);
+		get_new_mmu_context(mm, asid_cache);
+		if (mm == current->active_mm)
+			set_entryhi(mm->context & 0xff);
+		__restore_flags(flags);
+	}
+}
+
+void flush_tlb_range(struct mm_struct *mm, unsigned long start,
+				unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+		int size;
+
+#ifdef DEBUG_TLB
+		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+		       start, end);
+#endif
+		__save_and_cli(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if(size <= mips_cpu.tlbsize/2) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (mm->context & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				BARRIER;
+				tlb_probe();
+				BARRIER;
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				if(idx < 0)
+					continue;
+				/* Make sure all entries differ. */
+				set_entryhi(KSEG0+idx*0x2000);
+				BARRIER;
+				tlb_write_indexed();
+				BARRIER;
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, asid_cache);
+			if (mm == current->active_mm)
+				set_entryhi(mm->context & 0xff);
+		}
+		__restore_flags(flags);
+	}
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if (vma->vm_mm->context != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+		newpid = (vma->vm_mm->context & 0xff);
+		page &= (PAGE_MASK << 1);
+		__save_and_cli(flags);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi(page | newpid);
+		BARRIER;
+		tlb_probe();
+		BARRIER;
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		if(idx < 0)
+			goto finish;
+		/* Make sure all entries differ. */  
+		set_entryhi(KSEG0+idx*0x2000);
+		BARRIER;
+		tlb_write_indexed();
+
+	finish:
+		BARRIER;
+		set_entryhi(oldpid);
+		__restore_flags(flags);
+	}
+}
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
+
+/* 
+ * Updates the TLB with the new pte(s).
+ */
+void update_mmu_cache(struct vm_area_struct * vma,
+		      unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = get_entryhi() & 0xff;
+
+#ifdef DEBUG_TLB
+	if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       (int) (vma->vm_mm->context & 0xff), pid);
+	}
+#endif
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	BARRIER;
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	BARRIER;
+	if(idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	BARRIER;
+	set_entryhi(pid);
+	BARRIER;
+	__restore_flags(flags);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	/* Saved main processor registers. */
+	printk("$0 : %08lx %08lx %08lx %08lx\n",
+	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
+	printk("$4 : %08lx %08lx %08lx %08lx\n",
+               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+	printk("$8 : %08lx %08lx %08lx %08lx\n",
+	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+	printk("$12: %08lx %08lx %08lx %08lx\n",
+               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+	printk("$16: %08lx %08lx %08lx %08lx\n",
+	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+	printk("$20: %08lx %08lx %08lx %08lx\n",
+               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+	printk("$24: %08lx %08lx\n",
+	       regs->regs[24], regs->regs[25]);
+	printk("$28: %08lx %08lx %08lx %08lx\n",
+	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+
+	/* Saved cp0 registers. */
+	printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+}
+			
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+				      unsigned long entryhi, unsigned long pagemask)
+{
+        unsigned long flags;
+        unsigned long wired;
+        unsigned long old_pagemask;
+        unsigned long old_ctx;
+
+        __save_and_cli(flags);
+        /* Save old context and create impossible VPN2 value */
+        old_ctx = (get_entryhi() & 0xff);
+        old_pagemask = get_pagemask();
+        wired = get_wired();
+        set_wired (wired + 1);
+        set_index (wired);
+        BARRIER;    
+        set_pagemask (pagemask);
+        set_entryhi(entryhi);
+        set_entrylo0(entrylo0);
+        set_entrylo1(entrylo1);
+        BARRIER;    
+        tlb_write_indexed();
+        BARRIER;    
+    
+        set_entryhi(old_ctx);
+        BARRIER;    
+        set_pagemask (old_pagemask);
+        flush_tlb_all();    
+        __restore_flags(flags);
+}
+
+/* Detect and size the various caches. */
+static void __init probe_icache(unsigned long config)
+{
+        unsigned long config1;
+	unsigned int lsize;
+
+        if (!(config & (1 << 31))) {
+	        /* 
+		 * Not a MIPS32 complainant CPU. 
+		 * Config 1 register not supported, we assume R4k style.
+		 */
+	        icache_size = 1 << (12 + ((config >> 9) & 7));
+		ic_lsize = 16 << ((config >> 5) & 1);
+		mips_cpu.icache.linesz = ic_lsize;
+		
+		/* 
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1;
+		mips_cpu.icache.sets = 
+			(icache_size / ic_lsize) / mips_cpu.icache.ways;
+	} else {
+	       config1 = read_mips32_cp0_config1(); 
+
+	       if ((lsize = ((config1 >> 19) & 7)))
+		       mips_cpu.icache.linesz = 2 << lsize;
+	       else 
+		       mips_cpu.icache.linesz = lsize;
+	       mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7);
+	       mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7);
+
+	       ic_lsize = mips_cpu.icache.linesz;
+	       icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * 
+		             ic_lsize;
+	}
+	printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n",
+	       icache_size >> 10, ic_lsize, mips_cpu.icache.ways);
+}
+
+static void __init probe_dcache(unsigned long config)
+{
+        unsigned long config1;
+	unsigned int lsize;
+
+        if (!(config & (1 << 31))) {
+	        /* 
+		 * Not a MIPS32 complainant CPU. 
+		 * Config 1 register not supported, we assume R4k style.
+		 */  
+		dcache_size = 1 << (12 + ((config >> 6) & 7));
+		dc_lsize = 16 << ((config >> 4) & 1);
+		mips_cpu.dcache.linesz = dc_lsize;
+		/* 
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1;
+		mips_cpu.dcache.sets = 
+			(dcache_size / dc_lsize) / mips_cpu.dcache.ways;
+	} else {
+	        config1 = read_mips32_cp0_config1();
+
+		if ((lsize = ((config1 >> 10) & 7)))
+		        mips_cpu.dcache.linesz = 2 << lsize;
+		else 
+		        mips_cpu.dcache.linesz= lsize;
+		mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7);
+		mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7);
+
+		dc_lsize = mips_cpu.dcache.linesz;
+		dcache_size = 
+			mips_cpu.dcache.sets * mips_cpu.dcache.ways
+			* dc_lsize;
+	}
+	printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n",
+	       dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways);
+}
+
+
+/* If you even _breathe_ on this function, look at the gcc output
+ * and make sure it does not pop things on and off the stack for
+ * the cache sizing loop that executes in KSEG1 space or else
+ * you will crash and burn badly.  You have been warned.
+ */
+static int __init probe_scache(unsigned long config)
+{
+	extern unsigned long stext;
+	unsigned long flags, addr, begin, end, pow2;
+	int tmp;
+
+	if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT)
+		return 0;
+
+	tmp = ((config >> 17) & 1);
+	if(tmp)
+		return 0;
+	tmp = ((config >> 22) & 3);
+	switch(tmp) {
+	case 0:
+		sc_lsize = 16;
+		break;
+	case 1:
+		sc_lsize = 32;
+		break;
+	case 2:
+		sc_lsize = 64;
+		break;
+	case 3:
+		sc_lsize = 128;
+		break;
+	}
+
+	begin = (unsigned long) &stext;
+	begin &= ~((4 * 1024 * 1024) - 1);
+	end = begin + (4 * 1024 * 1024);
+
+	/* This is such a bitch, you'd think they would make it
+	 * easy to do this.  Away you daemons of stupidity!
+	 */
+	__save_and_cli(flags);
+
+	/* Fill each size-multiple cache line with a valid tag. */
+	pow2 = (64 * 1024);
+	for(addr = begin; addr < end; addr = (begin + pow2)) {
+		unsigned long *p = (unsigned long *) addr;
+		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
+		pow2 <<= 1;
+	}
+
+	/* Load first line with zero (therefore invalid) tag. */
+	set_taglo(0);
+	set_taghi(0);
+	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 8, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 9, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     ".set mips3\n\t"
+			     "cache 11, (%0)\n\t"
+			     ".set mips0\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+
+	/* Now search for the wrap around point. */
+	pow2 = (128 * 1024);
+	tmp = 0;
+	for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
+		__asm__ __volatile__("\n\t.set noreorder\n\t"
+				     ".set mips3\n\t"
+				     "cache 7, (%0)\n\t"
+				     ".set mips0\n\t"
+				     ".set reorder\n\t" : : "r" (addr));
+		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+		if(!get_taglo())
+			break;
+		pow2 <<= 1;
+	}
+	__restore_flags(flags);
+	addr -= begin;
+	printk("Secondary cache sized at %dK linesize %d bytes.\n",
+	       (int) (addr >> 10), sc_lsize);
+	scache_size = addr;
+	return 1;
+}
+
+static void __init setup_noscache_funcs(void)
+{
+	_clear_page = (void *)mips32_clear_page_dc;
+	_copy_page = (void *)mips32_copy_page_dc;
+	_flush_cache_all = mips32_flush_cache_all_pc;
+	___flush_cache_all = mips32_flush_cache_all_pc;
+	_flush_cache_mm = mips32_flush_cache_mm_pc;
+	_flush_cache_range = mips32_flush_cache_range_pc;
+	_flush_cache_page = mips32_flush_cache_page_pc;
+	_flush_page_to_ram = mips32_flush_page_to_ram_pc;
+
+	_flush_icache_page = mips32_flush_icache_page;
+
+	_dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc;
+	_dma_cache_wback = mips32_dma_cache_wback;
+	_dma_cache_inv = mips32_dma_cache_inv_pc;
+}
+
+static void __init setup_scache_funcs(void)
+{
+        _flush_cache_all = mips32_flush_cache_all_sc;
+        ___flush_cache_all = mips32_flush_cache_all_sc;
+	_flush_cache_mm = mips32_flush_cache_mm_sc;
+	_flush_cache_range = mips32_flush_cache_range_sc;
+	_flush_cache_page = mips32_flush_cache_page_sc;
+	_flush_page_to_ram = mips32_flush_page_to_ram_sc;
+	_clear_page = (void *)mips32_clear_page_sc;
+	_copy_page = (void *)mips32_copy_page_sc;
+
+	_flush_icache_page = mips32_flush_icache_page_s;
+
+	_dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc;
+	_dma_cache_wback = mips32_dma_cache_wback;
+	_dma_cache_inv = mips32_dma_cache_inv_sc;
+}
+
+typedef int (*probe_func_t)(unsigned long);
+
+static inline void __init setup_scache(unsigned int config)
+{
+	probe_func_t probe_scache_kseg1;
+	int sc_present = 0;
+
+	/* Maybe the cpu knows about a l2 cache? */
+	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
+	sc_present = probe_scache_kseg1(config);
+
+	if (sc_present) {
+	  	mips_cpu.scache.linesz = sc_lsize;
+		/* 
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1;
+		mips_cpu.scache.sets = 
+		  (scache_size / sc_lsize) / mips_cpu.scache.ways;
+
+		setup_scache_funcs();
+		return;
+	}
+
+	setup_noscache_funcs();
+}
+
+static void __init probe_tlb(unsigned long config)
+{
+        unsigned long config1;
+
+        if (!(config & (1 << 31))) {
+	        /* 
+		 * Not a MIPS32 complainant CPU. 
+		 * Config 1 register not supported, we assume R4k style.
+		 */  
+	        mips_cpu.tlbsize = 48;
+	} else {
+	        config1 = read_mips32_cp0_config1();
+		if (!((config >> 7) & 3))
+		        panic("No MMU present");
+		else
+		        mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1;
+	}	
+
+	printk("Number of TLB entries %d.\n", mips_cpu.tlbsize);
+}
+
+void __init ld_mmu_mips32(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
+
+#ifdef CONFIG_MIPS_UNCACHED
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+#else
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+#endif
+
+	probe_icache(config);
+	probe_dcache(config);
+	setup_scache(config);
+	probe_tlb(config);
+
+	_flush_cache_sigtramp = mips32_flush_cache_sigtramp;
+	_flush_icache_range = mips32_flush_icache_range;	/* Ouch */
+
+	__flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+
+	/*
+	 * You should never change this register:
+	 *   - The entire mm handling assumes the c0_pagemask register to
+	 *     be set for 4kb pages.
+	 */
+	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+	flush_tlb_all();
+}
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c
--- v2.4.6/linux/arch/mips/mm/r2300.c	Thu Jul 27 18:36:54 2000
+++ linux/arch/mips/mm/r2300.c	Wed Jul  4 11:50:39 2001
@@ -4,7 +4,8 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *
  * with a lot of changes to make this thing work for R3000s
- * Copyright (C) 1998, 2000 Harald Koerfgen
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  */
 #include <linux/init.h>
@@ -19,6 +20,8 @@
 #include <asm/isadep.h>
 #include <asm/io.h>
 #include <asm/wbflush.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
 
 /*
  * According to the paper written by D. Miller about Linux cache & TLB
@@ -27,15 +30,17 @@
  * Define this if driver does not handle cache consistency during DMA ops.
  */
 
-/* Primary cache parameters. */
-static int icache_size, dcache_size; /* Size in bytes */
-/* the linesizes are usually fixed on R3000s */
+/* For R3000 cores with R4000 style caches */
+static unsigned long icache_size, dcache_size;		/* Size in bytes */
+static unsigned long icache_lsize, dcache_lsize;	/* Size in bytes */
+static unsigned long scache_size = 0;
+
+#include <asm/cacheops.h>
+#include <asm/r4kcache.h>
 
 #undef DEBUG_TLB
 #undef DEBUG_CACHE
 
-#define NTLB_ENTRIES       64  /* Fixed on all R23000 variants... */
-
 /* page functions */
 void r3k_clear_page(void * page)
 {
@@ -120,7 +125,7 @@
 
 	p = (volatile unsigned long *) KSEG0;
 
-	save_and_cli(flags);
+	flags = read_32bit_cp0_register(CP0_STATUS);
 
 	/* isolate cache space */
 	write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC);
@@ -142,34 +147,30 @@
 		if (size > 0x40000)
 			size = 0;
 	}
-	restore_flags(flags);
+	write_32bit_cp0_register(CP0_STATUS, flags);
 
 	return size * sizeof(*p);
 }
 
-static void __init probe_dcache(void)
+static void __init r3k_probe_cache(void)
 {
 	dcache_size = r3k_cache_size(ST0_ISC);
-	printk("Primary data cache %dkb, linesize 4 bytes\n",
-		dcache_size >> 10);
-}
+	dcache_lsize = 4;
 
-static void __init probe_icache(void)
-{
 	icache_size = r3k_cache_size(ST0_ISC|ST0_SWC);
-	printk("Primary instruction cache %dkb, linesize 4 bytes\n",
-		icache_size >> 10);
+	icache_lsize = 4;
 }
 
-static void r3k_flush_icache_range(unsigned long start, unsigned long size)
+static void r3k_flush_icache_range(unsigned long start, unsigned long end)
 {
-	unsigned long i, flags;
+	unsigned long size, i, flags;
 	volatile unsigned char *p = (char *)start;
 
+	size = end - start;
 	if (size > icache_size)
 		size = icache_size;
 
-	save_and_cli(flags);
+	flags = read_32bit_cp0_register(CP0_STATUS);
 
 	/* isolate cache space */
 	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
@@ -211,18 +212,19 @@
 		p += 0x080;
 	}
 
-	restore_flags(flags);
+	write_32bit_cp0_register(CP0_STATUS,flags);
 }
 
-static void r3k_flush_dcache_range(unsigned long start, unsigned long size)
+static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
 {
-	unsigned long i, flags;
+	unsigned long size, i, flags;
 	volatile unsigned char *p = (char *)start;
 
+	size = end - start;
 	if (size > dcache_size)
 		size = dcache_size;
 
-	save_and_cli(flags);
+	flags = read_32bit_cp0_register(CP0_STATUS);
 
 	/* isolate cache space */
 	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|flags)&~ST0_IEC);
@@ -264,7 +266,7 @@
 		p += 0x080;
 	}
 
-	restore_flags(flags);
+	write_32bit_cp0_register(CP0_STATUS,flags);
 }
 
 static inline unsigned long get_phys_page (unsigned long addr,
@@ -279,15 +281,15 @@
 	pmd = pmd_offset(pgd, addr);
 	pte = pte_offset(pmd, addr);
 
-	if((physpage = pte_val(*pte)) & _PAGE_VALID)
-		return KSEG1ADDR(physpage & PAGE_MASK);
-	else
-		return 0;
+	if ((physpage = pte_val(*pte)) & _PAGE_VALID)
+		return KSEG0ADDR(physpage & PAGE_MASK);
+
+	return 0;
 }
 
 static inline void r3k_flush_cache_all(void)
 {
-	r3k_flush_icache_range(KSEG0, icache_size);
+	r3k_flush_icache_range(KSEG0, KSEG0 + icache_size);
 }
  
 static void r3k_flush_cache_mm(struct mm_struct *mm)
@@ -301,9 +303,8 @@
 	}
 }
 
-static void r3k_flush_cache_range(struct mm_struct *mm,
-				    unsigned long start,
-				    unsigned long end)
+static void r3k_flush_cache_range(struct mm_struct *mm, unsigned long start,
+				  unsigned long end)
 {
 	struct vm_area_struct *vma;
 
@@ -315,21 +316,22 @@
 	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
 	vma = find_vma(mm, start);
-	if (vma) {
-		if (mm->context != current->active_mm->context) {
-			flush_cache_all();
-		} else {
-			unsigned long flags, physpage;
+	if (!vma)
+		return;
 
-			save_and_cli(flags);
-			while (start < end) {
-				if ((physpage = get_phys_page(start, mm)))
-					r3k_flush_icache_range(physpage, PAGE_SIZE);
-		
-				start += PAGE_SIZE;
-			}
-			restore_flags(flags);
+	if (mm->context != current->active_mm->context) {
+		flush_cache_all();
+	} else {
+		unsigned long flags, physpage;
+
+		save_and_cli(flags);
+		while (start < end) {
+			if ((physpage = get_phys_page(start, mm)))
+				r3k_flush_icache_range(physpage,
+				                       physpage + PAGE_SIZE);
+			start += PAGE_SIZE;
 		}
+		restore_flags(flags);
 	}
 }
 
@@ -348,8 +350,7 @@
 		unsigned long physpage;
 
 		if ((physpage = get_phys_page(page, vma->vm_mm)))
-			r3k_flush_icache_range(physpage, PAGE_SIZE);
-
+			r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
 	}
 }
 
@@ -360,6 +361,26 @@
 	 */
 }
 
+static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long physpage;
+
+	if (mm->context == 0)
+		return;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+
+	physpage = (unsigned long) page_address(page);
+	if (physpage)
+		r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
+}
+
 static void r3k_flush_cache_sigtramp(unsigned long addr)
 {
 	unsigned long flags;
@@ -367,26 +388,23 @@
 #ifdef DEBUG_CACHE
 	printk("csigtramp[%08lx]", addr);
 #endif
-	/*
-	 * I am assuming an 8 Byte cacheline here. HK
-	 */
-	addr &= ~7;
 
-	save_and_cli(flags);
+	flags = read_32bit_cp0_register(CP0_STATUS);
 
 	write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
 
 	asm ( 	"sb\t$0,0x000(%0)\n\t"
+		"sb\t$0,0x004(%0)\n\t"
 		"sb\t$0,0x008(%0)\n\t"
 		: : "r" (addr) );
 
-	restore_flags(flags);
+	write_32bit_cp0_register(CP0_STATUS, flags);
 }
 
 static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
 {
 	wbflush();
-	r3k_flush_dcache_range(start, size);
+	r3k_flush_dcache_range(start, start + size);
 }
 
 /* TLB operations. */
@@ -403,7 +421,7 @@
 	save_and_cli(flags);
 	old_ctx = (get_entryhi() & 0xfc0);
 	write_32bit_cp0_register(CP0_ENTRYLO0, 0);
-	for(entry = 0; entry < NTLB_ENTRIES; entry++) {
+	for (entry = 8; entry < mips_cpu.tlbsize; entry++) {
 		write_32bit_cp0_register(CP0_INDEX, entry << 8);
 		write_32bit_cp0_register(CP0_ENTRYHI, ((entry | 0x80000) << 12));
 		__asm__ __volatile__("tlbwi");
@@ -418,7 +436,7 @@
 		unsigned long flags;
 
 #ifdef DEBUG_TLB
-		printk("[tlbmm<%d>]", mm->context);
+		printk("[tlbmm<%lu>]", (unsigned long) mm->context);
 #endif
 		save_and_cli(flags);
 		get_new_mmu_context(mm, asid_cache);
@@ -429,19 +447,19 @@
 }
 
 void flush_tlb_range(struct mm_struct *mm, unsigned long start,
-				  unsigned long end)
+                     unsigned long end)
 {
 	if (mm->context != 0) {
 		unsigned long flags;
 		int size;
 
 #ifdef DEBUG_TLB
-		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xfc0),
-		       start, end);
+		printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
+			(mm->context & 0xfc0), start, end);
 #endif
 		save_and_cli(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-		if(size <= NTLB_ENTRIES) {
+		if(size <= mips_cpu.tlbsize) {
 			int oldpid = (get_entryhi() & 0xfc0);
 			int newpid = (mm->context & 0xfc0);
 
@@ -478,7 +496,7 @@
 		int oldpid, newpid, idx;
 
 #ifdef DEBUG_TLB
-		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+		printk("[tlbpage<%lu,0x%08lx>]", vma->vm_mm->context, page);
 #endif
 		newpid = (vma->vm_mm->context & 0xfc0);
 		page &= PAGE_MASK;
@@ -531,8 +549,8 @@
 		 "1" (PAGE_SIZE/(sizeof(pmd_t)*8)));
 }
 
-void update_mmu_cache(struct vm_area_struct * vma,
-				   unsigned long address, pte_t pte)
+void update_mmu_cache(struct vm_area_struct * vma, unsigned long address,
+                      pte_t pte)
 {
 	unsigned long flags;
 	pgd_t *pgdp;
@@ -550,8 +568,8 @@
 
 #ifdef DEBUG_TLB
 	if((pid != (vma->vm_mm->context & 0xfc0)) || (vma->vm_mm->context == 0)) {
-		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
-		       (int) (vma->vm_mm->context & 0xfc0), pid);
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n",
+		       (vma->vm_mm->context & 0xfc0), pid);
 	}
 #endif
 
@@ -576,19 +594,6 @@
 		printk("[HIT]");
 #endif
 	}
-#if 0
-	if(!strcmp(current->comm, "args")) {
-		printk("<");
-		for(idx = 0; idx < NTLB_ENTRIES; idx++) {
-			set_index(idx);
-			tlb_read();
-			address = get_entryhi();
-			if((address & 0xfc0) != 0)
-				printk("[%08lx]", address);
-		}
-		printk(">\n");
-	}
-#endif
 	set_entryhi(pid);
 	restore_flags(flags);
 }
@@ -626,33 +631,135 @@
 	       (unsigned int) regs->cp0_cause);
 }
 
+/* Todo: handle r4k-style TX39 TLB */
 void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-				  unsigned long entryhi, unsigned long pagemask)
+                     unsigned long entryhi, unsigned long pagemask)
 {
-printk("r3k_add_wired_entry");
-        /*
-	 * FIXME, to be done
-	 */
+	unsigned long flags;
+	unsigned long old_ctx;
+	static unsigned long wired = 0;
+	
+	if (wired < 8) {
+		save_and_cli(flags);
+		old_ctx = get_entryhi() & 0xfc0;
+		set_entrylo0(entrylo0);
+		set_entryhi(entryhi);
+		set_index(wired);
+		wired++;
+		tlb_write_indexed();
+		set_entryhi(old_ctx);
+	        flush_tlb_all();    
+		restore_flags(flags);
+	}
 }
 
-void __init ld_mmu_r2300(void)
+static void tx39_flush_icache_all(void )
 {
+
+	unsigned long start = KSEG0;
+	unsigned long end = (start + icache_size);
+	unsigned long dummy = 0;
+
+	/* disable icache and stop streaming */
+	__asm__ __volatile__(
+	".set\tnoreorder\n\t"
+	"mfc0\t%0,$3\n\t"
+	"xori\t%0,32\n\t"
+	"mtc0\t%0,$3\n\t"
+	"j\t1f\n\t"
+	"nop\n\t"
+	"1:\t.set\treorder\n\t"
+	: : "r"(dummy));
+
+	/* invalidate icache */
+	while (start < end) {
+		cache16_unroll32(start,Index_Invalidate_I);
+		start += 0x200;
+	}
+
+	/* enable icache */
+	__asm__ __volatile__(
+	".set\tnoreorder\n\t"
+	"mfc0\t%0,$3\n\t"
+	"xori\t%0,32\n\t"
+	"mtc0\t%0,$3\n\t"
+	".set\treorder\n\t"
+	: : "r"(dummy));
+}
+
+static __init void tx39_probe_cache(void)
+{
+	unsigned long	config;
+
+	config = read_32bit_cp0_register(CP0_CONF);
+
+	icache_size = 1 << (10 + ((config >> 19) & 3));
+	icache_lsize = 16;
+
+	dcache_size = 1 << (10 + ((config >> 16) & 3));
+	dcache_lsize = 4;
+}
+
+void __init ld_mmu_r23000(void)
+{
+	unsigned long config;
+
 	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
 
 	_clear_page = r3k_clear_page;
 	_copy_page = r3k_copy_page;
 
-	probe_icache();
-	probe_dcache();
-
-	_flush_cache_all = r3k_flush_cache_all;
-	_flush_cache_mm = r3k_flush_cache_mm;
-	_flush_cache_range = r3k_flush_cache_range;
-	_flush_cache_page = r3k_flush_cache_page;
-	_flush_cache_sigtramp = r3k_flush_cache_sigtramp;
-	_flush_page_to_ram = r3k_flush_page_to_ram;
-
-        _dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+	switch (mips_cpu.cputype) {
+	case CPU_R2000:
+	case CPU_R3000:
+	case CPU_R3000A:
+	case CPU_R3081:
+	case CPU_R3081E:
+
+		r3k_probe_cache();
+
+		_flush_cache_all = r3k_flush_cache_all;
+		___flush_cache_all = r3k_flush_cache_all;
+		_flush_cache_mm = r3k_flush_cache_mm;
+		_flush_cache_range = r3k_flush_cache_range;
+		_flush_cache_page = r3k_flush_cache_page;
+		_flush_cache_sigtramp = r3k_flush_cache_sigtramp;
+		_flush_page_to_ram = r3k_flush_page_to_ram;
+		_flush_icache_page = r3k_flush_icache_page;
+		_flush_icache_range = r3k_flush_icache_range;
+
+		_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+		break;
+
+	case CPU_TX3912:
+	case CPU_TX3922:
+	case CPU_TX3927:
+
+		config=read_32bit_cp0_register(CP0_CONF);
+		config &= ~TX39_CONF_WBON;
+		write_32bit_cp0_register(CP0_CONF, config);
+
+		tx39_probe_cache();
+
+		_flush_cache_all = tx39_flush_icache_all;
+		___flush_cache_all = tx39_flush_icache_all;
+		_flush_cache_mm = tx39_flush_icache_all;
+		_flush_cache_range = tx39_flush_icache_all;
+		_flush_cache_page = tx39_flush_icache_all;
+		_flush_cache_sigtramp = tx39_flush_icache_all;
+		_flush_page_to_ram = r3k_flush_page_to_ram;
+		_flush_icache_page = tx39_flush_icache_all;
+		_flush_icache_range = tx39_flush_icache_all;
+
+		_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+
+		break;
+	}
+
+	printk("Primary instruction cache %dkb, linesize %d bytes\n",
+		(int) (icache_size >> 10), (int) icache_lsize);
+	printk("Primary data cache %dkb, linesize %d bytes\n",
+		(int) (dcache_size >> 10), (int) dcache_lsize);
 
 	flush_tlb_all();
 }
diff -u --recursive --new-file v2.4.6/linux/arch/mips/mm/r4xx0.c linux/arch/mips/mm/r4xx0.c
--- v2.4.6/linux/arch/mips/mm/r4xx0.c	Sun Aug  6 11:43:17 2000
+++ linux/arch/mips/mm/r4xx0.c	Wed Jul  4 11:50:39 2001
@@ -19,12 +19,13 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
 #include <asm/bcache.h>
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/bootinfo.h>
 #include <asm/mmu_context.h>
 
 /* CP0 hazard avoidance. */
@@ -208,7 +209,7 @@
 {
 	unsigned int flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	*(volatile unsigned int *)KSEG1;
 	__asm__ __volatile__(
 		".set\tnoreorder\n\t"
@@ -235,7 +236,7 @@
 		 "I" (PAGE_SIZE),
 		 "i" (Create_Dirty_Excl_D)
 		:"$1","memory");
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 /*
@@ -626,7 +627,7 @@
 		:"0" (to), "1" (from),
 		 "I" (PAGE_SIZE),
 		 "i" (Create_Dirty_Excl_D));
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 /*
@@ -910,81 +911,81 @@
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache16();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d16i16(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache32();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d16i16(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache64();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d16i16(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16(); blast_scache128();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s32d32i32(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32(); blast_scache32();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s64d32i32(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32(); blast_scache64();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_s128d32i32(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32(); blast_scache128();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_d16i16(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache16(); blast_icache16();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_d32i32(void)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	__save_and_cli(flags);
 	blast_dcache32(); blast_icache32();
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 static void
@@ -101
+	__rek_flush_cache_all_d32ieturn;
+
+	if (!(vma->vm_fi(flags);
 	blast_dcach->vm_fi(flags);
 	blast_dcach->vm_fi(flags);
 	blast,d flags);
 	blast,d flags);
 	blast,d flags);
 	blast,d flags);
 	blast,d flags);
 	blast,d flags);
 	blast,d fl void (*_dma_cache_wback_inv)(unm_fi(flaainv)(ucache_sigtramp;
 	_flush_p
 static inline unsige_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_d32i32(voi void r4k_flush_cache_all_d32i32gs(flags);
+	__restoreext & 0xff);
+		__restore_flags(flags);
+	}
+}
+
+void flush_tlb_range(struct mm_struct *mm, unsigned long sta%0)\n\
+ */
+static int __init probe_scache(unsigned long config)
+{
+	extern unsigned long stext;
+	unsigned long flags, addr, begin, end, pow2;
+	int tmp;
+
+	if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT)
+		return 0;
+
+ flags);
 	blast,d fl void (*_dma_cache_wback_inv)(unm_fi(flaainv)(ucache_sigtramp;
 	_flush_p
 stati
+        unsigned long config1;
+	unsigned int lsize;
+
+	unsigned lore_fl
+	probe_func_t probe_scache_kseg1;
+	int sc_present = 0;
+
+	/* Ma 
-void update_mmu_cache(struct vm_area_struct * vma,
-				   unsigned long address, pte_t pte)
+new-file v2.4.6/linux/arch/i386/math-emu/reg_u_div.S linux/arch/i386/math-emu/reg_u_div.S
--- v2.4.6/linux/arch/i386/math-t,d fl koil(*p/* There is only the ki_t probe_scache_kreg1;
+	int sc_pryt = search_one_table(mp->ex_table_start,
 				       mp->ex_table_end - 1, addr);
-		if (ret) return ret;
+		if (ret)
+			break;
 	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
 #endif
-
-	return 0;
 }
diff -u --recur Now search for the wradk_inv)(unm_fi(flaainv)(ucascache_kseg1;~(dc_lsize - 1);
+	protected_writeback_dcache_line(daddr);
+	protected_2();n (bjoreturn ret;
 #endif
-
-	return 0;
 }
diff -u --recur Now search for the wradk_inv)(unm_fi(flaainv)(ucascache_kseg1;~(dc_lsize - 1);
+	prov)(ucascache_kseg1;~(dc_lsize - 1);
+	prov)(ucascache_kseg1;~(dc_lsize - 1);
+	prov)(ucas@
 		unsigned long physpage;
 
 		if ((physpage = get_physnpage(page, vma->vm_mm)))
-			r3k_flush_icache_range(physpage, PAGE_SIZE);
-
+			r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);r3k_flush_icache_range(idx < NTLB_ENTRIES; idx++)3{
+	}
+}cur Now n*/
+		page = (KSEG0 + (page & (scache_size - 1)));
+		bla+		page = (KSEG0 + (page & (scache_size - 1estore_flags(flags);
 }
 
 static inline void r4k_flush_cache_all_d32i32(void)
 {
 	unsigned long flags;
 
-	save_and_cli2
+void flush_tlb_rang+	while correctgy.
+7l_D));
-	restore_fla search for the wradk_inv)(unm_fi(fl oldpid = (get_entryhi() & 0xfc0);
 			int rov)(ucascache_kseg1;~(dc_lsize - 1);
+	prov)(ucascache_kseg1;~(dc_lsize - 1);
+	prov)(ucas@
 		unsigned long physpage;
 
 		if ((physpage = get_physnpage(page, vma->vm_mm)))
-	+	r3k_flush_icache_range(physpage, PAGE_SIZE);
-
+		+N3k_flush_icache0iIZE);
-
+		+N3k_flush_E);
-
+		+N3k_flush_icache0iIZEage;
 
 page_address(page));
+}
+
+statiget_physnpage(page, vma->vm_mm)))
-	+	r3k_flush_icache_range(physpage, PAGE_SIZE);
-
+		+N3k_flush_icache0iIZE);
-
+		+N3k_flush_E);
-
+		+N3k_flush_icache0iIZEage;
 
 page_address(page));
+}
+
+statiget_physnpage(page, vma->vm_mm)))
-	+	r3k_flflagsize - 1;
+v1 has a MMU "feature" requiring a low mapping
 
-if [ "$CONFIG_ETRAX100LX" = "y" -o "$CONFIG_SVINTO_SIM" = "y" ]; +
+ flags);
 	blast,d fl void (*_dma_cache_wback_inv)(unm_fi(flaainv)(ucache_sigtramp;
 	_flush_p
 stati
+      unsigned long physpage;
 
 		if ((physpage = get_physnpage(page, vma->vm_mm)))
-	+	r3k_flush_icachunsigned long flags;
+	unsigned long old_ctx;
+	sta 
 page_address(pag* 
+		 * We cannot pvolatile__("tlbwi");
@@ -418,7 +436,7 @@
 		unsigned long flags;
 
 #ifdef DEBUG_TLB
-		printk("[
 #ifdef DEBUG_TLB
 &     __aoffset(pmdp, address);
+	BARRIER;
+	set_entrylo0(pte_val(CPU_NEVAD	printk("CPU revision et_entrylo0(pte_val(CPU
-		printk("[
 #ifdef n et_entrylo0(pte_val(CPU
-		printk("[
 #if]; +
ef DEBUG_TLB
+#undef Dd_ctx 51>e.c,v 1.6 2001/05/29 11(49;&pping
 
-if [ "$CONFIG_ETRAX100L)
+{
+	uIG_ETRAX100L)
+{
+	uIG_&pping
 
-if [ "$CONFIG_ETRAX100L)
+{
+	uIG_ETRAX100L)
+{
+	uIG_&pping
 
-if [ "$CON0L)
+{
+	uIG_ETRAX100L)
+{
+	uIG_&pping
 
-if [ "$CON0L)
+{
+	uIG_ETRAX100L)
+{
+	uIG_&pping
 
-if [ "$CON0L)
+{
+	+IG_ETRAX100L7 +xnd) {
+				pgd = pgd_offset(mm, start";
_lsize - 1);
+	while (1) {
+		flush_scache_line(a); /* Hit_Writeback_Inv_SD */
+		if (a =cach		     unsxed oine(a); /* Hit_Writeba_Inv_SD */
+		if (a =cach		     unsxed oine(a); /* Hit_Writeba_Inv_SD */
+		if (a =cach		     unsxed oine(a); /* Hiriteba_Inv_SD */
+		if (a =cach		    nnot pvolatile__("tl     unsxed oine(a)(a =cach	Writeba_Inv_SD */
+		if (a =cach		     unsxed oine(a); /* Hit_W1) {
+		flush_scache_linble_lock);
+	do {
+
+) {
+		flush_scache_lidp;
+	pte_t *ptep;
+
+	/*
+	 * If owRAX100L)
+{
+	uIG_&ppin-	printk(+
+	/*
+	 * If owRAX100L)
+{
+	uIG_&ppin-	prRAX100L)
+{
+	uIG100L)
+{
+	uIG100L)
+{
+	uIG100L)
+{
+	uIG100L)
+{
+	uIG100L)
+{
+	uIG100L)
+{
+	uIG100L)
+{
+	uIG100L)
+{
+	uIG100L)
+er_t mmu_che_range(physpage, physpage + PAGE_S00L)
+{
+	uIGh_icache_range(idx _icach mmu_che_range(physpage, physpage + PAGE_S00L)
+{
+	uIGh_icache_range(idx _icach mmu_che_range(physpage, physpage + PAG		if (a =h_i+	while (1) {
+		flolatile__("tl     unsxed oine(a)(a =cach	Writeba_Inv_SD */
+		if (a =cach		     unsxed oine(a)	Writeba_Inv_SD */
+(a =cach		     unsxed oine(a)	WritebaWriteba_Inv_SD */
+(a =cach		     unsxed oine(a)	WritebaWriteba_Inv_SD */
+(a =cach		     unsxed oine(a)	WritebaWriteba_In("CPU revision et_e)	WritebaWriteba_Inv_Sv_SDmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache_page(start);
+				start += PAGE_SIZE;
+			}
+			__restor _PAGE_VALID)
+		re@
 	unsigned long flagsac   unsxed oine(a)	WritebaWriteba_In("CPU revilush_page_to_ram_pc(stchunsigned long flags;
+	u)signed long old_cdx;
+	sta 
 page_sddress(pag*)a 
 page_sddress(pag*)a 
 page_sddreshdx;
+	sta 
 page_sddress(p+	sta 
 page_sddress(p+
+	sta 
 page_sddress(p+	sta 
 page_sdflush_p
 stati
+      unsigned long physpage;
 
 		if ((physpage = get_physnpage(page, vma->vm_mm)))
-	+	r3k_flush_icachunsv_SDmd, start);
+
+				if(pte_valr3k_flush_icachunsv_SDmd, start);
+
+				if(pte_valr3k_flush_icachunsv_SDmd, start);
+
+				if(d)gsac   unsxep VLne(a)	Wt\<to+PAGE_SIlagsac   unsxed oine(a)	WritebaWriteba__page_to_ram_pc(stchunsigned l_cdx;
+	sta 
 page_sddress(pag*)a 
 pahunsigned l_cdx;
+	ses
+_S00L)
+{
+	uIGh_icache_range(idx _icach mmu_che_range(physpage, physpage + PAGE_S00L)
+{
+	uIGh_icache_range	}
+ouess(pag*)a 
 page_sn_kseg1;~(dc_lsize - 1);
+	prov,iucascache_kseg1;~(d	prov;
+	st92(d	prov;
+	st92(d	prov;
+	st92(d	prov;
+	st92(d	prov;
+	st92(d	prov;
+	s* Updates the TLB with the new pte(s).
+ */
+void update_mmu_cache(stre_mmu_cache(stre_mmu_ce, vma->vm_mm)))
-	+	r3k_flush_icachunsv_SDmd, start);
+
+				if(pte_valr3k_flush_icachunsv_SDmd, start);
+
+				if(pte_valr3k_flush_icachunsv_SD);
+			int newpid = (mm->context & 0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			aWriteba_In("CPU revil1);
+			end &= (PAGE_MASK << 1);
+			aWriteba_In("CPU revil1);
+			end &= (PAGE_MASK << 1);
8>		aWriteba_In("CPU revil1);
+			end &= (PAGE_MASK << 1);
8>		aWriteba_In("CPU revil1);
+			end &= (PAGE_MASK << 1);
8>		aWriteba_In("CPU(4624”µ492(d	prov;
+	st92(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	start &= (PAGEstar.
+ */
+void update_mmu_cache(stre_mmu_cache(stre_mmu_ce, i_l,a µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	startd	prov;
+µ49;
+	st92(	startd	prov;
+µ49;
+	st92(	startd	prov;
+µ49;
+	st92(	startd	prov;
+µ49;
+	st9	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”áGb2(d	prov
+#endif
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address 3 %1i3D);
+	pgdp = pgd_offset(vma->vm_mm, address);
+	BARRIER;
+	tlb_pefbe();
+	BARRIER;
+	    unsigned long physpage;
 
 		if ((physpage = b[c_physnpage(page(ivma->vm_mm*3j
-	+	r3k_flushstatic inline void r4k_flu_offset(pmdstart);
(d	prov;
+	st92(d	pr("CPg flag-	+	r3k_flushstatic inline void r4k_flu_offset(pmdstart);
(d	prov;
+	st92(d	pr("CPgµ49;
+	st9	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	start &= (PAG pgd_offset(vma-mdstart);
(d	prov;
+	st92(d	pr("CPgµ49;
+	st9	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	start &= (PAG pgd_offset(vma-mdstart);
(drt);
(d	prov;
+	st92(d	pr("CPg flag-	+	r3k_flushl w92(	start &= (PAGEstart)(d	prov;;
+	ses
+_S00L)
+{
+	uIGGEstart)(d	prov;;
+	ses
+_S00
+_S00;
+	ses
+_S00L)
+{
+	+	uIGGEstart)(d	prov;;;
+	st92(d	prt92(d	prt92*d	prt92*d	prt92*d	prt92*d	prt92*d	prt92*d	prt92*d	prt92*d	prt92*d	prt92*d	prt92)o	prt92)o	prt92)o	prt92)or("CPU(4624”µ492(d	prov;
24”µ492(d	prov;
+	st92(	start &= (PAG pgd_offset(vma-mdstart);
(drt);
(d	prov;
+	st92(d	p	st92(	start &= (PAG pgd_offset(vma-mdstart);
(drt);
(d	prov;
+	st98(_S00L)
+
(dm0L)
-G pgd_offsettart);
(drt);
(d	prov;
+	samdstaAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ492(d	prov;
+	st92(	start &= (PAGEstart);
(d	prov;
+	st92(d	pr("CPU(4624”µ4 k"CPU(4624”µ4 k"CPU(46666666666666666666666666666666666666 flag-	+	r3k_flushl w92(	start &&&&&&&&&&& flag-	+	r3k_flushl w92(	start &&&&&&&&&&& flag-	+	r3k_flushl w92(	start &&&&&&&&&&& flag-	+	r3k_flushl w92(	start &&&&&&&&&&& flag-	+	r3k_flushl w92(	start &&&&&&&&&&& flag-	+	r3k_flushl w92(	d	p	s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2s);
+	__save_and_cli(f&s2(	start &s2(	start &s2(	start &s2(	start &s2s);
+	__save_and_cli(f&s2(	start &s2(	start &s2(	start &s2(	start start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2s);
+	__save_acache_range(physpage, TIGE_SIZE);
-		
-			start += a k1save_acache_range(physpage, &&& flag-	+	r3k_flushl w92(	start &&&&&&&&&&& flag-	+	r3k_flushl w92(	start &&&&&&&&&&& flag-	+	r3k_flushl w92(	start &&&&&&&&&&& flag-	+	r3k_flushl w92(	start &&&&&&&&&&& flag-	+	r3k_flushl w92(	d	p	s2(	start &s2(	start &s2(	start &s2(	start &s2(	start &s2(	s2(	stastart &s2(	start s);
+	__save_and_cli(f&s2(	start &s2(	starg &s2(	start &s2(	stage,start &&&&&&&&&&& flag-	+	s2(	start &s2(	stage,start &&&&&&&&&&& flag-	+	s2(	start &s2(	stage,start &&&&&&&&&&& flag-	+	s2(	start &s2(	stage,starrntart &s2(	start s);
+	__save_and_cli(f&s2(	start &s2(	starg &s2(	start &s2(	stage,start &&&&&&&&&&& flagext != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%d>]", mm->context);
+#endif
+		__save_and_cli(flags);
+		get_new_mmu_context(mm, asid_ca_cli(fuags);
+		get_new		get_nl 2001
@@ -0,0 +1,1078 @@
+/*
+ * Kevin D. Kissell, kevssell,&&&&& flag-	+	r3k_flushl w92(	d	p	s2(xt);
+#endif
+		__save_and_cli(flags);
+		get_new_mmu_context(mm, asid_ca_cli(fuags);
+		get_new		get_nl 2001
@@ -0,0 +1,1078 X@
+/*
+ * Kevin P.-6þ